initial commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
|
||||
aghanim_announcer_passive = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_aghanim_announcer_passive", "modifiers/creatures/modifier_aghanim_announcer_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_announcer_passive:GetIntrinsicModifierName()
|
||||
return "modifier_aghanim_announcer_passive"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
75
aghanim_singleplayer/scripts/vscripts/abilities/creatures/aghanim_blink.lua
Executable file
75
aghanim_singleplayer/scripts/vscripts/abilities/creatures/aghanim_blink.lua
Executable file
@@ -0,0 +1,75 @@
|
||||
aghanim_blink = class{}
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_blink:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_preimage.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_faceless_void.vsndevts", context )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_blink:OnSpellStart()
|
||||
if IsServer() == false then
|
||||
return
|
||||
end
|
||||
|
||||
local vPos = self:GetCursorPosition()
|
||||
local vDirection = vPos - self:GetCaster():GetOrigin()
|
||||
local flDist = vDirection:Length2D()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
--local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_preimage.vpcf", PATTACH_CUSTOMORIGIN, nil )--
|
||||
--ParticleManager:SetParticleControl( nFXIndex, 0, self:GetCaster():GetAbsOrigin() )
|
||||
--ParticleManager:SetParticleControl( nFXIndex, 1, vPos )
|
||||
--ParticleManager:SetParticleControlEnt( nFXIndex, 2, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetAbsOrigin(), true )
|
||||
--ParticleManager:SetParticleFoWProperties( nFXIndex, 0, 2, 64.0 )
|
||||
--ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
self.vStartLocation = self:GetCaster():GetAbsOrigin()
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetOrigin(),
|
||||
fStartRadius = 0,
|
||||
fEndRadius = 0,
|
||||
vVelocity = vDirection * flDist,
|
||||
fDistance = flDist,
|
||||
Source = self:GetCaster(),
|
||||
--iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_NONE,
|
||||
--iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
EmitSoundOn( "Hero_FacelessVoid.TimeWalk", self:GetCaster() )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_blink:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
local vDirection = vLocation - self:GetCaster():GetAbsOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
EmitSoundOn( "Hero_FacelessVoid.TimeWalk", self:GetCaster() )
|
||||
|
||||
FindClearSpaceForUnit( self:GetCaster(), vLocation, true )
|
||||
--self:GetCaster():FaceTowards( self:GetCaster().vHomePosition )
|
||||
|
||||
ProjectileManager:ProjectileDodge( self:GetCaster() )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_preimage.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, self.vStartLocation )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, self:GetCaster():GetAbsOrigin() )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 2, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self.vStartLocation, true )
|
||||
ParticleManager:SetParticleFoWProperties( nFXIndex, 0, 2, 64.0 )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,170 @@
|
||||
aghanim_crystal_attack = class({})
|
||||
|
||||
_G.CRYSTAL_ATTACKS_PHASE = {}
|
||||
_G.CRYSTAL_ATTACKS_PHASE[1] = 0
|
||||
_G.CRYSTAL_ATTACKS_PHASE[2] = 1
|
||||
_G.CRYSTAL_ATTACKS_PHASE[3] = 2
|
||||
_G.CRYSTAL_ATTACKS_PHASE[4] = 0
|
||||
_G.CRYSTAL_ATTACKS_PHASE[5] = 1
|
||||
_G.CRYSTAL_ATTACKS_PHASE[6] = 2
|
||||
|
||||
|
||||
_G.CRYSTAL_ATTACKS_COOLDOWN = 10.0
|
||||
|
||||
|
||||
LinkLuaModifier( "modifier_aghanim_crystal_attack_active", "modifiers/creatures/modifier_aghanim_crystal_attack_active", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_aghanim_crystal_attack_debuff", "modifiers/creatures/modifier_aghanim_crystal_attack_debuff", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_crystal_attack:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_attack.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_attack_telegraph.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_attack_impact.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_iceblast.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ancient_apparition/ancient_apparition_ice_blast_debuff.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_winter_wyvern.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_mars.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_leshrac.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_lich.vsndevts", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_self_dmg.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_pulse_nova.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_pulse_ambient.vpcf", context )
|
||||
self.nPhase = 1
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_crystal_attack:OnSpellStart()
|
||||
if IsServer() then
|
||||
if self.nPhase == 1 then
|
||||
self.hActiveBuff = self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_aghanim_crystal_attack_active", {} )
|
||||
end
|
||||
|
||||
self.attack_time = self:GetSpecialValueFor( "attack_time" )
|
||||
self.attack_damage = self:GetSpecialValueFor( "attack_damage" )
|
||||
self.explosion_radius = self:GetSpecialValueFor( "explosion_radius" )
|
||||
self.pulse_radius = self:GetSpecialValueFor( "pulse_radius" )
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetAbsOrigin(), nil, 10000, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_FARTHEST, false )
|
||||
|
||||
local nCrystalsLeft = CRYSTAL_ATTACKS_PHASE[ self.nPhase ] + 1
|
||||
for _,enemy in pairs( enemies ) do
|
||||
local flDist = ( enemy:GetAbsOrigin() - self:GetCaster():GetAbsOrigin() ):Length2D()
|
||||
if flDist > self.pulse_radius then
|
||||
self:LaunchCrystals( enemy:GetAbsOrigin() + ( enemy:GetForwardVector() * self.pulse_radius * 0.5 ) )
|
||||
nCrystalsLeft = nCrystalsLeft - 1
|
||||
if nCrystalsLeft == 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.nPhase = self.nPhase + 1
|
||||
if self.hActiveBuff then
|
||||
self.hActiveBuff:Pulse()
|
||||
end
|
||||
|
||||
if self.nPhase > 6 then
|
||||
self.nPhase = 1
|
||||
self:StartCooldown( CRYSTAL_ATTACKS_COOLDOWN )
|
||||
self.hActiveBuff:Destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_crystal_attack:LaunchCrystals( vPos )
|
||||
local vDirection = vPos - self:GetCaster():GetAttachmentOrigin( self:GetCaster():ScriptLookupAttachment( "attach_staff_fx" ) )
|
||||
local flDist2d = vDirection:Length2D()
|
||||
local flDist = vDirection:Length()
|
||||
vDirection = vDirection:Normalized()
|
||||
vDirection.z = 0.0
|
||||
|
||||
local flSpeed = flDist / self.attack_time
|
||||
|
||||
local info =
|
||||
{
|
||||
EffectName = "particles/creatures/aghanim/aghanim_crystal_attack.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetAttachmentOrigin( self:GetCaster():ScriptLookupAttachment( "attach_staff_fx" ) ),
|
||||
fStartRadius = 0,
|
||||
fEndRadius = 0,
|
||||
vVelocity = vDirection * flSpeed,
|
||||
fDistance = flDist2d,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
EmitSoundOn( "Hero_Winter_Wyvern.SplinterBlast.Splinter", self:GetCaster() )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_crystal_attack_telegraph.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, vPos )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( self.explosion_radius, self.attack_time, self.attack_time ) )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 15, Vector( 214, 236, 239 ) )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 16, Vector( 1, 0, 0 ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_crystal_attack:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if hTarget ~= nil then
|
||||
return false
|
||||
end
|
||||
|
||||
local knockback_duration = self:GetSpecialValueFor( "knockback_duration" )
|
||||
local knockback_distance = self:GetSpecialValueFor( "knockback_distance" )
|
||||
local knockback_height = self:GetSpecialValueFor( "knockback_height" )
|
||||
local debuff_duration = self:GetSpecialValueFor( "debuff_duration" )
|
||||
|
||||
local vPosOnGround = GetGroundPosition( vLocation, self:GetCaster() )
|
||||
|
||||
EmitSoundOnLocationWithCaster( vPosOnGround, "Hero_Winter_Wyvern.SplinterBlast.Target", self:GetCaster() )
|
||||
|
||||
local nDetonationFX = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_crystal_attack_impact.vpcf", PATTACH_WORLDORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nDetonationFX, 0, vPosOnGround )
|
||||
ParticleManager:SetParticleControl( nDetonationFX, 1, Vector( self.explosion_radius, self.explosion_radius, self.explosion_radius ) )
|
||||
ParticleManager:ReleaseParticleIndex( nDetonationFX )
|
||||
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), vPosOnGround, nil, self.explosion_radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
|
||||
for _,enemy in pairs( enemies ) do
|
||||
if enemy ~= nil and enemy:IsInvulnerable() == false and enemy:IsMagicImmune() == false then
|
||||
local kv =
|
||||
{
|
||||
center_x = vPosOnGround.x,
|
||||
center_y = vPosOnGround.y,
|
||||
center_z = vPosOnGround.z,
|
||||
should_stun = true,
|
||||
duration = knockback_duration,
|
||||
knockback_duration = knockback_duration,
|
||||
knockback_distance = knockback_distance,
|
||||
knockback_height = knockback_height,
|
||||
}
|
||||
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_knockback", kv )
|
||||
--enemy:AddNewModifier( self:GetCaster(), self, "modifier_aghanim_crystal_attack_debuff", { duration = debuff_duration } )
|
||||
|
||||
local damage = {
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.attack_damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
ability = self
|
||||
}
|
||||
|
||||
ApplyDamage( damage )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,17 @@
|
||||
aghanim_passive = class( {} )
|
||||
|
||||
LinkLuaModifier( "modifier_aghanim_passive", "modifiers/creatures/modifier_aghanim_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_passive:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_outro_linger.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_passive:GetIntrinsicModifierName()
|
||||
return "modifier_aghanim_passive"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -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
|
||||
146
aghanim_singleplayer/scripts/vscripts/abilities/creatures/aghanim_spell_swap.lua
Executable file
146
aghanim_singleplayer/scripts/vscripts/abilities/creatures/aghanim_spell_swap.lua
Executable file
@@ -0,0 +1,146 @@
|
||||
|
||||
aghanim_spell_swap = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_aghanim_spell_swap", "modifiers/creatures/modifier_aghanim_spell_swap", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_aghanim_spell_swap_crystal", "modifiers/creatures/modifier_aghanim_spell_swap_crystal", LUA_MODIFIER_MOTION_BOTH )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_spell_swap:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_beam_channel.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_spell_swap_beam.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_wisp/wisp_tether_hit.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_wisp/wisp_guardian_explosion.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_spellswap_replenish.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_spellswap_ambient.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_destroy.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_impact.vpcf", context )
|
||||
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_warlock.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_pugna.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_wisp.vsndevts", context )
|
||||
|
||||
PrecacheResource( "model", "models/gameplay/aghanim_crystal.vmdl", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_spell_swap:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_spell_swap:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nChannelFX = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_beam_channel.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_spell_swap:GetChannelTime()
|
||||
if IsServer() then
|
||||
local flChannelTime = self.BaseClass.GetChannelTime( self )
|
||||
local nHealthPct = self:GetCaster():GetHealthPercent()
|
||||
if nHealthPct < 50 then
|
||||
flChannelTime = flChannelTime - 1.0
|
||||
end
|
||||
if nHealthPct < 25 then
|
||||
flChannelTime = flChannelTime - 1.0
|
||||
end
|
||||
return flChannelTime
|
||||
end
|
||||
return self.BaseClass.GetChannelTime( self )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_spell_swap:OnChannelThink( flInterval )
|
||||
if IsServer() then
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_spell_swap:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nChannelFX, false )
|
||||
|
||||
for _,nFXIndex in pairs ( self.nBeamFXIndices ) do
|
||||
ParticleManager:DestroyParticle( nFXIndex, true )
|
||||
end
|
||||
|
||||
StopSoundOn( "Hero_Pugna.LifeDrain.Loop", self:GetCaster() )
|
||||
|
||||
for k,hHero in pairs ( self.Heroes ) do
|
||||
if hHero ~= nil and hHero:IsRealHero() then
|
||||
hHero:RemoveModifierByName( "modifier_arc_warden_spark_wraith_purge" )
|
||||
hHero:AddNewModifier( self:GetCaster(), self, "modifier_aghanim_spell_swap", {} )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_spell_swap:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.nBeamFXIndices = {}
|
||||
|
||||
local hSummonPortals = self:GetCaster():FindAbilityByName( "aghanim_summon_portals" )
|
||||
if hSummonPortals then
|
||||
local kv =
|
||||
{
|
||||
duration = self:GetChannelTime(),
|
||||
mode = hSummonPortals.PORTAL_MODE_ALL_ENEMIES,
|
||||
depth = 0,
|
||||
target_entindex = -1,
|
||||
}
|
||||
|
||||
local vRightPos = self:GetCaster():GetAbsOrigin() + self:GetCaster():GetRightVector() * 300
|
||||
local vLeftPos = self:GetCaster():GetAbsOrigin() - self:GetCaster():GetRightVector() * 300
|
||||
CreateModifierThinker( self:GetCaster(), self, "modifier_aghanim_summon_portals_thinker", kv, vRightPos, self:GetCaster():GetTeamNumber(), false )
|
||||
CreateModifierThinker( self:GetCaster(), self, "modifier_aghanim_summon_portals_thinker", kv, vLeftPos, self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
|
||||
EmitSoundOn( "Hero_Pugna.LifeDrain.Cast", self:GetCaster() )
|
||||
EmitSoundOn( "Hero_Pugna.LifeDrain.Loop", self:GetCaster() )
|
||||
|
||||
self.Heroes = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetAbsOrigin(), nil, 5000, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_CLOSEST, false )
|
||||
for k,hHero in pairs ( self.Heroes ) do
|
||||
if hHero ~= nil and hHero:IsRealHero() then
|
||||
|
||||
local nNumAghDummies = 0
|
||||
for j=1,4 do
|
||||
local szName = tostring( "aghanim_empty_spell" .. j )
|
||||
local hDummyAbility = hHero:FindAbilityByName( szName )
|
||||
if hDummyAbility then
|
||||
nNumAghDummies = nNumAghDummies + 1
|
||||
end
|
||||
end
|
||||
|
||||
if nNumAghDummies == 4 then
|
||||
print( "I have 4 agh dummies! Getting slowed." )
|
||||
hHero:AddNewModifier( self:GetCaster(), self, "modifier_arc_warden_spark_wraith_purge", { duration = self:GetChannelTime() } )
|
||||
end
|
||||
|
||||
local nBeamFX = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_spell_swap_beam.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
|
||||
local szAttachment = "attach_hand_R"
|
||||
if RandomInt( 0, 1 ) == 1 then
|
||||
szAttachment = "attach_lower_hand_R"
|
||||
end
|
||||
ParticleManager:SetParticleControlEnt( nBeamFX, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, szAttachment, self:GetCaster():GetAbsOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nBeamFX, 1, hHero, PATTACH_POINT_FOLLOW, "attach_hitloc", hHero:GetAbsOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nBeamFX, 11, Vector( 1, 0, 0 ) )
|
||||
|
||||
table.insert( self.nBeamFXIndices, nBeamFX )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,147 @@
|
||||
|
||||
aghanim_staff_beams = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_aghanim_staff_beams_thinker", "modifiers/creatures/modifier_aghanim_staff_beams_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_aghanim_staff_beams_linger_thinker", "modifiers/creatures/modifier_aghanim_staff_beams_linger_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_aghanim_staff_beams_debuff", "modifiers/creatures/modifier_aghanim_staff_beams_debuff", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_staff_beams:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/staff_beam.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_beam_channel.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_beam_burn.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/staff_beam_linger.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/staff_beam_tgt_ring.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_debug_ring.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_phoenix.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_huskar.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_jakiro.vsndevts", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_staff_beams:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_staff_beams:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
StartSoundEventFromPositionReliable( "Aghanim.StaffBeams.WindUp", self:GetCaster():GetAbsOrigin() )
|
||||
self.nChannelFX = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_beam_channel.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
self.vecTargets = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetAbsOrigin(), nil, 5000, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_CLOSEST, false )
|
||||
for k,enemy in pairs ( self.vecTargets ) do
|
||||
if enemy ~= nil then
|
||||
enemy.nWarningFXIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_debug_ring.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( enemy.nWarningFXIndex, 0, enemy:GetAbsOrigin() )
|
||||
enemy.vSourceLoc = enemy:GetAbsOrigin()
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_staff_beams:OnSpellStart()
|
||||
if IsServer() then
|
||||
--EmitSoundOn( "Aghanim.ShardAttack.Channel", self:GetCaster() )
|
||||
EmitSoundOn( "Hero_Phoenix.SunRay.Cast", self:GetCaster() )
|
||||
EmitSoundOn( "Hero_Phoenix.SunRay.Loop", self:GetCaster() )
|
||||
|
||||
self.Projectiles = {}
|
||||
|
||||
for k,enemy in pairs ( self.vecTargets ) do
|
||||
if enemy ~= nil then
|
||||
local hBeamThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_aghanim_staff_beams_thinker", { duration = self:GetChannelTime() }, enemy.vSourceLoc, self:GetCaster():GetTeamNumber(), false )
|
||||
ParticleManager:DestroyParticle( enemy.nWarningFXIndex, false )
|
||||
local projectile =
|
||||
{
|
||||
Target = enemy,
|
||||
Source = hBeamThinker,
|
||||
Ability = self,
|
||||
EffectName = "",
|
||||
iMoveSpeed = self:GetSpecialValueFor( "beam_speed" ),
|
||||
vSourceLoc = enemy.vSourceLoc,
|
||||
bDodgeable = false,
|
||||
bProvidesVision = false,
|
||||
flExpireTime = GameRules:GetGameTime() + self:GetChannelTime(),
|
||||
bIgnoreObstructions = true,
|
||||
bSuppressTargetCheck = true,
|
||||
}
|
||||
|
||||
projectile.hThinker = hBeamThinker
|
||||
|
||||
local nProjectileHandle = ProjectileManager:CreateTrackingProjectile( projectile )
|
||||
projectile.nProjectileHandle = nProjectileHandle
|
||||
|
||||
local nBeamFXIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/staff_beam.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( nBeamFXIndex, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_staff_fx", self:GetCaster():GetAbsOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nBeamFXIndex, 1, projectile.hThinker, PATTACH_ABSORIGIN_FOLLOW, nil, projectile.hThinker:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nBeamFXIndex, 2, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, projectile.hThinker:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nBeamFXIndex, 9, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_hitloc", self:GetCaster():GetAbsOrigin(), true )
|
||||
projectile.nFXIndex = nBeamFXIndex
|
||||
|
||||
table.insert( self.Projectiles, projectile )
|
||||
end
|
||||
end
|
||||
--self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_aghanim_staff_beams", kv )
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_staff_beams:OnProjectileThinkHandle( nProjectileHandle )
|
||||
if IsServer() then
|
||||
local Projectile = nil
|
||||
for k,v in pairs( self.Projectiles ) do
|
||||
if v.nProjectileHandle == nProjectileHandle then
|
||||
Projectile = v
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if Projectile == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local vLocation = ProjectileManager:GetTrackingProjectileLocation( nProjectileHandle )
|
||||
if Projectile.hThinker ~= nil and not Projectile.hThinker:IsNull() then
|
||||
vLocation = GetGroundPosition( vLocation, Projectile.hThinker )
|
||||
Projectile.hThinker:SetOrigin( vLocation )
|
||||
|
||||
ParticleManager:SetParticleControlFallback( Projectile.nFXIndex, 0, self:GetCaster():GetAbsOrigin() )
|
||||
ParticleManager:SetParticleControlFallback( Projectile.nFXIndex, 1, vLocation )
|
||||
ParticleManager:SetParticleControlFallback( Projectile.nFXIndex, 9, self:GetCaster():GetAbsOrigin() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_staff_beams:OnChannelThink( flInterval )
|
||||
if IsServer() then
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_staff_beams:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nChannelFX, false )
|
||||
StopSoundOn( "Hero_Phoenix.SunRay.Cast", self:GetCaster() )
|
||||
StopSoundOn( "Hero_Phoenix.SunRay.Loop", self:GetCaster() )
|
||||
EmitSoundOn( "Hero_Phoenix.SunRay.Stop", self:GetCaster() )
|
||||
|
||||
for _,v in pairs ( self.Projectiles ) do
|
||||
ParticleManager:DestroyParticle( v.nFXIndex, false )
|
||||
if v.hThinker and v.hThinker:IsNull() == false then
|
||||
UTIL_Remove( v.hThinker )
|
||||
end
|
||||
end
|
||||
--self:GetCaster():RemoveModifierByName( "modifier_aghanim_staff_beams" )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,315 @@
|
||||
aghanim_summon_portals = class( {} )
|
||||
|
||||
LinkLuaModifier( "modifier_aghanim_portal_spawn_effect", "modifiers/creatures/modifier_aghanim_portal_spawn_effect", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_aghanim_summon_portals_thinker", "modifiers/creatures/modifier_aghanim_summon_portals_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:Precache( context )
|
||||
PrecacheResource( "particle", "particles/econ/events/ti10/portal/portal_open_bad.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/portal_summon.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_portal_summon.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_portal_emit.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/econ/events/ti10/portal/portal_emit_large.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_pugna/pugna_decrepify.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_ghost.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_stomp_magical.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_elder_titan/elder_titan_echo_stomp_impact_magical.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_elder_titan.vsndevts", context )
|
||||
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_aghanim_minion", context, -1 )
|
||||
PrecacheUnitByNameSync( "npc_dota_boss_aghanim_spear", context, -1 )
|
||||
|
||||
self.PORTAL_MODE_ALL_SPEARS = 0
|
||||
self.PORTAL_MODE_ALL_ENEMIES = 1
|
||||
self.PORTAL_MODE_BOTH = 2
|
||||
|
||||
self.nLastPortalMode = self.PORTAL_MODE_ALL_ENEMIES
|
||||
self.nMode = 0
|
||||
self.nDepthRemaining = 20
|
||||
self.nPortals = 0
|
||||
self.nNumPortalsThisCast = 0
|
||||
self.flPortalSummmonTime = self:GetSpecialValueFor( "portal_time" )
|
||||
self.flStartGestureTime = 999999999999
|
||||
|
||||
self.bSynchedPortalRelease = false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPortals = self:GetPortalCount()
|
||||
self.flPortalSummmonTime = self:GetSpecialValueFor( "portal_time" )
|
||||
|
||||
self.nChannelFX = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_portal_summon.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
EmitSoundOn( "Hero_ElderTitan.EchoStomp.Channel", self:GetCaster() )
|
||||
|
||||
self.staff_crush_radius = self:GetSpecialValueFor( "staff_crush_radius" )
|
||||
self.staff_crush_damage = self:GetSpecialValueFor( "staff_crush_damage" )
|
||||
self.staff_crush_stun_duration = self:GetSpecialValueFor( "staff_crush_stun_duration" )
|
||||
self.staff_crush_delay = self:GetSpecialValueFor( "staff_crush_delay" )
|
||||
|
||||
|
||||
local vToTarget = self:GetCursorPosition() - self:GetCaster():GetAbsOrigin()
|
||||
vToTarget.z = 0
|
||||
vToTarget = vToTarget:Normalized()
|
||||
|
||||
self.vStaffEndPos = self:GetCaster():GetAbsOrigin() + ( vToTarget * 200.0 )--+ ( self:GetCaster():GetRightVector() * -30 )
|
||||
self.vStaffEndPos = GetGroundPosition( self.vStaffEndPos, self:GetCaster() )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_crystal_attack_telegraph.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, self.vStaffEndPos )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( self.staff_crush_radius, 1.6, 1.6 ) )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 15, Vector( 255, 0, 0 ) )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 16, Vector( 1, 0, 0 ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:OnChannelThink( flInterval )
|
||||
if IsServer() then
|
||||
if self.nPortals > 0 and GameRules:GetGameTime() > self.flNextPortalTime then
|
||||
self.flNextPortalTime = GameRules:GetGameTime() + self.flPortalInterval
|
||||
if self.nNumPortalsInLine > 0 then
|
||||
self:CreateNextPortalAlongLine()
|
||||
self.nNumPortalsInLine = self.nNumPortalsInLine - 1
|
||||
self.nNumPortalsThisCast = self.nNumPortalsThisCast + 1
|
||||
end
|
||||
|
||||
if self.nNumPortalsNearHeroes > 0 then
|
||||
self:CreateNearHeroPortal()
|
||||
self.nNumPortalsNearHeroes = self.nNumPortalsNearHeroes - 1
|
||||
self.nNumPortalsThisCast = self.nNumPortalsThisCast + 1
|
||||
end
|
||||
end
|
||||
|
||||
if self.bHasStaffCrushed == false then
|
||||
self.staff_crush_delay = self.staff_crush_delay - flInterval
|
||||
if self.staff_crush_delay < 0 then
|
||||
self.bHasStaffCrushed = true
|
||||
self:StaffCrush()
|
||||
end
|
||||
end
|
||||
|
||||
if GameRules:GetGameTime() > self.flStartGestureTime then
|
||||
self:GetCaster():StartGesture( ACT_DOTA_IDLE )
|
||||
self.flStartGestureTime = 9999999999999
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nChannelFX, false )
|
||||
self:GetCaster():RemoveGesture( ACT_DOTA_IDLE )
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.flStartGestureTime = GameRules:GetGameTime() + 2.5
|
||||
self.bHasStaffCrushed = false
|
||||
|
||||
self.flPortalInterval = self:GetChannelTime() / self.nPortals
|
||||
self.flNextPortalTime = -1
|
||||
self.nDepthRemaining = self:GetSpecialValueFor( "total_portal_depth" )
|
||||
self.nLastPortalMode = self.nMode
|
||||
self.nMode = self:GetPortalMode()
|
||||
|
||||
self.nNumPortalsThisCast = 0
|
||||
|
||||
self.nNumPortalsInLine = self:GetSpecialValueFor( "base_portals" )
|
||||
self.nNumPortalsNearHeroes = self.nPortals - self.nNumPortalsInLine
|
||||
|
||||
if self.nMode == self.PORTAL_MODE_ALL_SPEARS then
|
||||
local vMidPoint = nil
|
||||
|
||||
local vLineDir = nil
|
||||
self.Heroes = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetAbsOrigin(), nil, 5000, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_CLOSEST, false )
|
||||
|
||||
vMidPoint = self:GetCaster():GetAbsOrigin() + self:GetCaster():GetForwardVector() * 500
|
||||
vLineDir = self:GetCaster():GetRightVector()
|
||||
|
||||
vLineDir.z = 0.0
|
||||
vLineDir = vLineDir:Normalized()
|
||||
|
||||
local nPortalsRemaining = self.nNumPortalsInLine - 1
|
||||
local flLineStep = 450
|
||||
local flTotalLineDist = flLineStep * self.nNumPortalsInLine
|
||||
local vFirstPortalPos = vMidPoint - ( vLineDir * ( flLineStep * nPortalsRemaining / 2 ) )
|
||||
|
||||
self.SpearLinePositions = {}
|
||||
table.insert( self.SpearLinePositions, vFirstPortalPos )
|
||||
|
||||
for i=1,nPortalsRemaining do
|
||||
local vNewPortalPos = vFirstPortalPos + ( vLineDir * i * flLineStep )
|
||||
table.insert( self.SpearLinePositions, vNewPortalPos )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:StaffCrush()
|
||||
if IsServer() then
|
||||
|
||||
local nFXCastIndex = ParticleManager:CreateParticle( "particles/creatures/aghanim/aghanim_stomp_magical.vpcf", PATTACH_WORLDORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXCastIndex, 0, self.vStaffEndPos )
|
||||
ParticleManager:SetParticleControl( nFXCastIndex, 1, Vector( self.radius, self.radius, self.radius ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXCastIndex )
|
||||
|
||||
EmitSoundOn( "Hero_ElderTitan.EchoStomp", self:GetCaster() )
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self.vStaffEndPos, self:GetCaster(), self.staff_crush_radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, 0, false )
|
||||
for _,enemy in pairs( enemies ) do
|
||||
if enemy ~= nil and enemy:IsInvulnerable() == false then
|
||||
local damageInfo =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.staff_crush_damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
ability = self,
|
||||
}
|
||||
|
||||
ApplyDamage( damageInfo )
|
||||
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_stunned", { duration = self.staff_crush_stun_duration } )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_elder_titan/elder_titan_echo_stomp_impact_magical.vpcf", PATTACH_ABSORIGIN_FOLLOW, enemy )
|
||||
local vDirection = enemy:GetOrigin() - self.vStaffEndPos
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, enemy:GetOrigin() )
|
||||
ParticleManager:SetParticleControlForward( nFXIndex, 1, vDirection )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:GetPortalCount()
|
||||
if IsServer() then
|
||||
local nBasePortals = self:GetSpecialValueFor( "base_portals" )
|
||||
local nHealthPctPerPortal = self:GetSpecialValueFor( "portal_health_pct" )
|
||||
local nAdditionalPortals = math.floor( ( 100 - self:GetCaster():GetHealthPercent() ) / nHealthPctPerPortal )
|
||||
|
||||
return nBasePortals + nAdditionalPortals
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:GetPortalMode()
|
||||
if IsServer() then
|
||||
return self.PORTAL_MODE_ALL_SPEARS
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:CreateNearHeroPortal()
|
||||
if IsServer() then
|
||||
local nCountLeft = self.nNumPortalsNearHeroes
|
||||
if nCountLeft <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local Heroes = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetAbsOrigin(), nil, 5000, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_CLOSEST, false )
|
||||
if #Heroes == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local hTarget = Heroes[ RandomInt( 1, #Heroes ) ]
|
||||
if hTarget == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local vToAghanim = self:GetCaster():GetAbsOrigin() - hTarget:GetAbsOrigin()
|
||||
vToAghanim.z = 0.0
|
||||
vToAghanim = vToAghanim:Normalized()
|
||||
|
||||
local vPos = hTarget:GetAbsOrigin() - vToAghanim * RandomFloat( self:GetSpecialValueFor( "min_portal_offset" ), self:GetSpecialValueFor( "max_portal_offset" ) )
|
||||
if GridNav:CanFindPath( hTarget:GetAbsOrigin(), vPos ) == false then
|
||||
return
|
||||
end
|
||||
|
||||
local flDuration = 0.5 + ( self:GetChannelStartTime() + self:GetChannelTime() ) - GameRules:GetGameTime() - ( nCountLeft * 0.3 )
|
||||
|
||||
local kv =
|
||||
{
|
||||
duration = flDuration,
|
||||
mode = self.PORTAL_MODE_ALL_SPEARS,
|
||||
depth = 0,
|
||||
target_entindex = hTarget:entindex(),
|
||||
}
|
||||
|
||||
CreateModifierThinker( self:GetCaster(), self, "modifier_aghanim_summon_portals_thinker", kv, vPos, self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function aghanim_summon_portals:CreateNextPortalAlongLine()
|
||||
if IsServer() then
|
||||
local nCountLeft = #self.SpearLinePositions
|
||||
if nCountLeft == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local vPos = self.SpearLinePositions[ 1 ]
|
||||
|
||||
local hTarget = nil
|
||||
if #self.Heroes == 0 then
|
||||
local Heroes = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetAbsOrigin(), nil, 5000, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_CLOSEST, false )
|
||||
if #Heroes == 0 then
|
||||
return
|
||||
end
|
||||
hTarget = Heroes[ RandomInt( 1, #Heroes ) ]
|
||||
else
|
||||
local nIndex = RandomInt( 1, #self.Heroes )
|
||||
hTarget = self.Heroes[ nIndex ]
|
||||
table.remove( self.Heroes, nIndex )
|
||||
end
|
||||
|
||||
if hTarget == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local flDuration = 0.5 + ( self:GetChannelStartTime() + self:GetChannelTime() ) - GameRules:GetGameTime() - ( nCountLeft * 0.3 )
|
||||
table.remove( self.SpearLinePositions, 1 )
|
||||
|
||||
local kv =
|
||||
{
|
||||
duration = flDuration,
|
||||
mode = self.PORTAL_MODE_ALL_SPEARS,
|
||||
depth = 0,
|
||||
target_entindex = hTarget:entindex(),
|
||||
}
|
||||
|
||||
CreateModifierThinker( self:GetCaster(), self, "modifier_aghanim_summon_portals_thinker", kv, vPos, self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,37 @@
|
||||
aghsfort_brewmaster_primal_split = class({})
|
||||
LinkLuaModifier( "modifier_brewmaster_split", "modifiers/creatures/modifier_brewmaster_split", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_primal_split:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_brewmaster/brewmaster_primal_split.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_brewmaster_earth_unit", context, -1 )
|
||||
PrecacheUnitByNameSync( "npc_dota_brewmaster_storm_unit", context, -1 )
|
||||
PrecacheUnitByNameSync( "npc_dota_brewmaster_fire_unit", context, -1 )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_primal_split:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
local hLines = { "Hero_Brewmaster.PrimalSplit.VO6", "Hero_Brewmaster.PrimalSplit.VO7", "Hero_Brewmaster.PrimalSplit.VO8", }
|
||||
local nRandomInt = RandomInt(1,3)
|
||||
local hSplitLine = hLines[nRandomInt]
|
||||
EmitSoundOn( hSplitLine, self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_primal_split:OnSpellStart()
|
||||
if IsServer() == false then
|
||||
return
|
||||
end
|
||||
|
||||
EmitSoundOn( "Hero_Brewmaster.PrimalSplit.Cast", self:GetCaster() )
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_brewmaster_split", { duration = self:GetSpecialValueFor( "split_duration" ) } )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,76 @@
|
||||
aghsfort_brewmaster_thunderclap = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_thunderclap:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_brewmaster/brewmaster_thunder_clap.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_thunderclap:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.radius = self:GetSpecialValueFor( "radius" )
|
||||
self.duration = self:GetSpecialValueFor( "duration" )
|
||||
self.damage = self:GetSpecialValueFor( "damage" )
|
||||
self.speed = self:GetSpecialValueFor( "speed" )
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( radius, radius, radius ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 26, 26 ) )
|
||||
|
||||
EmitSoundOn( "Hero_Brewmaster.ThunderClap.Target", self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_thunderclap:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_thunderclap:GetPlaybackRateOverride()
|
||||
return 0.5
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_brewmaster_thunderclap:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_brewmaster/brewmaster_thunder_clap.vpcf", PATTACH_ABSORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( self.radius, self.radius, self.radius ) )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 2, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_attack1", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
EmitSoundOn( "Hero_Brewmaster.ThunderClap", self:GetCaster() )
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), nil, self.radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
|
||||
for _,enemy in pairs( enemies ) do
|
||||
if enemy ~= nil and enemy:IsInvulnerable() == false then
|
||||
local damageInfo =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.damage,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
ability = self,
|
||||
}
|
||||
ApplyDamage( damageInfo )
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_polar_furbolg_ursa_warrior_thunder_clap", { duration = self.duration } )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
aghsfort_elemental_tiny_create_io = class({})
|
||||
LinkLuaModifier( "modifier_elemental_tiny_create_io_dummy", "modifiers/creatures/modifier_elemental_tiny_create_io_dummy", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_create_io:Precache( context )
|
||||
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_elemental_io", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_create_io:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_create_io:OnSpellStart()
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
|
||||
if self:GetCaster() == nil or self:GetCaster():IsNull() then
|
||||
return
|
||||
end
|
||||
|
||||
local nSummonCount = self:GetSpecialValueFor( "spawn_count" )
|
||||
local nMaxSummons = self:GetSpecialValueFor( "max_summons" )
|
||||
local flSpawnDistance = self:GetSpecialValueFor( "spawn_distance" )
|
||||
|
||||
local flDeltaAngle = 360 / nSummonCount
|
||||
local vAngles = QAngle( 0, math.random( 0, flDeltaAngle ), 0 )
|
||||
|
||||
--first time we spawn, create 2 the hIos
|
||||
if not self:GetCaster():FindModifierByName( "modifier_elemental_tiny_create_io_dummy" ) then
|
||||
nSummonCount = 2
|
||||
local kv2 = {}
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_elemental_tiny_create_io_dummy", kv2 )
|
||||
end
|
||||
|
||||
for i = 1,nSummonCount do
|
||||
|
||||
local vSpawnPosition = nil
|
||||
for s = 1,36 do
|
||||
|
||||
local vDir = AnglesToVector( vAngles )
|
||||
local vTest = self:GetCaster():GetAbsOrigin() + vDir * flSpawnDistance + math.random( -25, 25 )
|
||||
|
||||
if GameRules.Aghanim:GetCurrentRoom():IsValidSpawnPoint( vTest ) then
|
||||
vSpawnPosition = vTest
|
||||
break
|
||||
end
|
||||
|
||||
vAngles.y = vAngles.y + 10
|
||||
|
||||
end
|
||||
|
||||
vAngles.y = vAngles.y + flDeltaAngle + math.random( -20, 20 )
|
||||
|
||||
if vSpawnPosition ~= nil then
|
||||
|
||||
local kv =
|
||||
{
|
||||
vLocX = vSpawnPosition.x,
|
||||
vLocY = vSpawnPosition.y,
|
||||
vLocZ = vSpawnPosition.z,
|
||||
}
|
||||
local hIo = CreateUnitByName( "npc_dota_creature_elemental_io", self:GetCaster():GetAbsOrigin(), true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
if hIo ~= nil then
|
||||
hIo:AddNewModifier( self:GetCaster(), self, "modifier_frostivus2018_broodbaby_launch", kv )
|
||||
hIo:SetOwner(self:GetCaster())
|
||||
table.insert( self:GetCaster().hIos, hIo )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,129 @@
|
||||
|
||||
aghsfort_elemental_tiny_toss = class({})
|
||||
LinkLuaModifier( "modifier_elemental_tiny_grab", "modifiers/creatures/modifier_elemental_tiny_grab", LUA_MODIFIER_MOTION_HORIZONTAL )
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_toss:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_tiny/tiny_toss_blur.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/aghanim/aghanim_crystal_attack_telegraph.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_wisp/wisp_tether.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_wisp/wisp_tether_hit.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/target_telegraph_attack.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/elemental_tiny_ping.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_toss:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_toss:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 50, 50, 50 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 0, 0 ) )
|
||||
|
||||
self.hProjectile = nil
|
||||
-- We want to find an Io to toss
|
||||
self:FindProjectile()
|
||||
if self.hProjectile ~= nil then
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
return false
|
||||
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_toss:OnAbilityPhaseInterrupted()
|
||||
|
||||
if IsServer() then
|
||||
-- We were interrupted. Drop our Io and stop our warnings
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
self.hProjectile:RemoveModifierByName( "modifier_elemental_tiny_grab" )
|
||||
self.hProjectile = nil
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_toss:FindProjectile()
|
||||
|
||||
if IsServer() then
|
||||
self.grab_radius = self:GetSpecialValueFor( "grab_radius" )
|
||||
|
||||
local entities = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), self:GetCaster(), self.grab_radius, DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_CREEP, DOTA_UNIT_TARGET_FLAG_NO_INVIS + DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_NOT_ANCIENTS, FIND_CLOSEST, false )
|
||||
|
||||
for _, hAlly in pairs( entities ) do
|
||||
if hAlly ~= nil and not hAlly:IsNull() and hAlly:IsAlive() == true and hAlly:GetUnitName() == "npc_dota_creature_elemental_io" then
|
||||
if not hAlly:FindModifierByName("modifier_tiny_toss") and not hAlly:FindModifierByName("modifier_elemental_tiny_grab") then
|
||||
-- We found an Io, it's going to be our projectile
|
||||
self.hProjectile = hAlly
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.hProjectile ~= nil then
|
||||
-- Position Io into our hand
|
||||
self.hProjectile:AddNewModifier( self:GetCaster(), self, "modifier_elemental_tiny_grab", nil )
|
||||
|
||||
local nDestinationPreviewFX = ParticleManager:CreateParticle( "particles/creatures/elemental_tiny_ping.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
--local nDestinationPreviewFX = ParticleManager:CreateParticle( "particles/ui_mouseactions/ping_retreat.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nDestinationPreviewFX, 0, self:GetCaster():GetCursorPosition() )
|
||||
--ParticleManager:SetParticleControl( nDestinationPreviewFX, 1, Vector( 275, 1.8, 1.8 ) )
|
||||
ParticleManager:SetParticleControl( nDestinationPreviewFX, 7, Vector( 255, 10, 10 ) )
|
||||
--ParticleManager:SetParticleControl( nDestinationPreviewFX, 16, Vector( 1, 0, 0 ) )
|
||||
ParticleManager:ReleaseParticleIndex( nDestinationPreviewFX )
|
||||
EmitSoundOnLocationWithCaster( self:GetCaster():GetCursorPosition(), "General.PingWarning", self:GetCaster() )
|
||||
|
||||
AddFOWViewer( DOTA_TEAM_GOODGUYS, self:GetCaster():GetCursorPosition(), self:GetSpecialValueFor( "radius" ), self:GetSpecialValueFor( "duration" ) + 0.5, false )
|
||||
|
||||
|
||||
else
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
self:StartCooldown(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_elemental_tiny_toss:OnSpellStart()
|
||||
|
||||
if IsServer() then
|
||||
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
local vPos = nil
|
||||
if self:GetCursorTarget() then
|
||||
vPos = self:GetCursorTarget():GetOrigin()
|
||||
else
|
||||
vPos = self:GetCursorPosition()
|
||||
end
|
||||
|
||||
local kv = {
|
||||
x = vPos.x,
|
||||
y = vPos.y,
|
||||
z = vPos.z
|
||||
}
|
||||
if self.hProjectile ~= nil and self.hProjectile:IsAlive() then
|
||||
-- Leave our hand, Io
|
||||
self.hProjectile:RemoveModifierByName( "modifier_elemental_tiny_grab" )
|
||||
-- And fly like the wind!
|
||||
self.hProjectile:AddNewModifier( self:GetCaster(), self, "modifier_tiny_toss", kv )
|
||||
self:GetCaster():StartGesture( ACT_TINY_TOSS )
|
||||
|
||||
|
||||
|
||||
EmitSoundOn( "Ability.TossThrow", self:GetCaster() )
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,150 @@
|
||||
aghsfort_enraged_wildwing_tornado_blast = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_enraged_wildwing_tornado_blast:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_invoker/invoker_tornado.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/wildwing_tornado_blast_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_enraged_wildwing_tornado_blast:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 175, 175, 175 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 140, 0 ) )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_enraged_wildwing_tornado_blast:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_enraged_wildwing_tornado_blast:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
local vDirection = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
self.travel_speed = self:GetSpecialValueFor( "travel_speed" )
|
||||
self.area_of_effect = self:GetSpecialValueFor( "area_of_effect" )
|
||||
self.damage = self:GetSpecialValueFor( "damage" )
|
||||
self.disable_duration = self:GetSpecialValueFor( "disable_duration" )
|
||||
self.travel_distance = self:GetSpecialValueFor( "travel_distance" )
|
||||
self.spawns_per_blast = self:GetSpecialValueFor( "spawns_per_blast" )
|
||||
self.harpy_spawn_amount = self:GetSpecialValueFor( "harpy_spawn_amount" )
|
||||
|
||||
self.spawn_interval = (self.travel_distance / self.travel_speed) / self.harpy_spawn_amount - 0.1
|
||||
|
||||
local info = {
|
||||
EffectName = "particles/units/heroes/hero_invoker/invoker_tornado.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetOrigin(),
|
||||
fStartRadius = self.area_of_effect,
|
||||
fEndRadius = self.area_of_effect,
|
||||
vVelocity = vDirection * self.travel_speed,
|
||||
fDistance = self.travel_distance,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_CREEP,
|
||||
iUnitTargetFlags = DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES
|
||||
}
|
||||
|
||||
|
||||
self.flLastThinkTime = GameRules:GetGameTime()
|
||||
self.nProjID = ProjectileManager:CreateLinearProjectile( info )
|
||||
EmitSoundOn( "Ability.TornadoBlast.Cast" , self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_enraged_wildwing_tornado_blast:OnProjectileThink( vLocation )
|
||||
if GameRules:GetGameTime() - self.flLastThinkTime >= self.spawn_interval then
|
||||
self.flLastThinkTime = GameRules:GetGameTime()
|
||||
|
||||
if self:GetCaster().Encounter and self:GetCaster().Encounter:GetRoom() and self:GetCaster().Encounter:GetRoom():IsInRoomBounds( vLocation ) then
|
||||
self:SpawnHarpy(vLocation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_enraged_wildwing_tornado_blast:OnProjectileHit( hTarget, vLocation )
|
||||
if hTarget ~= nil then
|
||||
local damage = {
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.damage,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
ability = this,
|
||||
}
|
||||
|
||||
ApplyDamage( damage )
|
||||
if not hTarget:FindModifierByName("modifier_aghsfort_wildwing_tornado_blast_debuff") then
|
||||
hTarget:AddNewModifier( self:GetCaster(), self, "modifier_aghsfort_wildwing_tornado_blast_debuff", { duration = self.disable_duration} )
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_enraged_wildwing_tornado_blast:SpawnHarpy( vLocation )
|
||||
if IsServer() then
|
||||
|
||||
for i = 1, self.harpy_spawn_amount do
|
||||
local hHarpy = CreateUnitByName( "npc_aghsfort_creature_tornado_harpy", vLocation, true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
local nMaxDistance = 200
|
||||
local vLoc = FindPathablePositionNearby(vLocation, 150, nMaxDistance )
|
||||
if hHarpy ~= nil then
|
||||
hHarpy:SetInitialGoalEntity( self:GetCaster().hInitialGoalEntity )
|
||||
hHarpy:SetDeathXP( 0 )
|
||||
hHarpy:SetMinimumGoldBounty( 0 )
|
||||
hHarpy:SetMaximumGoldBounty( 0 )
|
||||
|
||||
local kv =
|
||||
{
|
||||
vLocX = vLoc.x,
|
||||
vLocY = vLoc.y,
|
||||
vLocZ = vLoc.z,
|
||||
}
|
||||
hHarpy:AddNewModifier( self:GetCaster(), self, "modifier_frostivus2018_broodbaby_launch", kv )
|
||||
end
|
||||
end
|
||||
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_CUSTOMORIGIN, nil, vLocation, true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 100, 100, 100 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 29, 55, 184 ) )
|
||||
|
||||
|
||||
self.flLastHarpyTime = GameRules:GetGameTime()
|
||||
EmitSoundOn( "Creature_Bomb_Squad.LandMine.Plant", hHarpy )
|
||||
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,37 @@
|
||||
aghsfort_naga_siren_mirror_image = class({})
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_naga_siren_mirror_image:Precache( context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_naga_siren_mirror_image:OnSpellStart()
|
||||
print("Mirror Image")
|
||||
local caster = self:GetCaster()
|
||||
local vPos = caster:GetOrigin()
|
||||
|
||||
local effect_name = "particles/units/heroes/hero_siren/naga_siren_mirror_image.vpcf"
|
||||
local hEffects = ParticleManager:CreateParticle( effect_name, PATTACH_CUSTOMORIGIN, caster )
|
||||
caster:SetContextThink( "KillEffects", function() return self:KillEffects( hEffects ) end, 2 )
|
||||
EmitSoundOn( "Hero_NagaSiren.MirrorImage", self:GetCaster() )
|
||||
local enemies = FindUnitsInRadius( DOTA_TEAM_BADGUYS, vPos, nil, FIND_UNITS_EVERYWHERE, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_FOW_VISIBLE, FIND_CLOSEST, false )
|
||||
|
||||
local illusion_name = "npc_dota_creature_naga_siren_illusion"
|
||||
local illusion_origin = vPos
|
||||
local illusion = CreateUnitByName(illusion_name, illusion_origin, true, caster, nil, DOTA_TEAM_BADGUYS)
|
||||
illusion:SetInitialGoalEntity( enemies )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_naga_siren_mirror_image:KillEffects( hEffects )
|
||||
if hEffects ~= nil then
|
||||
ParticleManager:DestroyParticle( hEffects, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,69 @@
|
||||
|
||||
aghsfort_waveblaster_summon_ghost = class({})
|
||||
LinkLuaModifier( "modifier_aghsfort_waveblaster_summon_ghost_thinker", "modifiers/creatures/modifier_aghsfort_waveblaster_summon_ghost_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_waveblaster_summon_ghost:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/themed_fx/tower_dragon_black_smokering.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/nyx_swarm_explosion/nyx_swarm_explosion.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow_exit.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_zealot_mound", context, -1 )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_zealot_scarab", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_waveblaster_summon_ghost:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_waveblaster_summon_ghost:OnSpellStart()
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
|
||||
if self:GetCaster() == nil or self:GetCaster():IsNull() then
|
||||
return
|
||||
end
|
||||
|
||||
local nSummonCount = self:GetSpecialValueFor( "spawn_count" )
|
||||
local flSpawnDistance = self:GetSpecialValueFor( "spawn_distance" )
|
||||
local flDuration = self:GetSpecialValueFor( "spawn_delay" )
|
||||
local flDeltaAngle = 360 / nSummonCount
|
||||
local vAngles = QAngle( 0, math.random( 0, flDeltaAngle ), 0 )
|
||||
|
||||
for i = 1,nSummonCount do
|
||||
|
||||
local vSpawnPosition = nil
|
||||
for s = 1,36 do
|
||||
|
||||
local vDir = AnglesToVector( vAngles )
|
||||
local vTest = self:GetCaster():GetAbsOrigin() + vDir * flSpawnDistance + math.random( -25, 25 )
|
||||
|
||||
if GameRules.Aghanim:GetCurrentRoom():IsValidSpawnPoint( vTest ) then
|
||||
vSpawnPosition = vTest
|
||||
break
|
||||
end
|
||||
|
||||
vAngles.y = vAngles.y + 10
|
||||
|
||||
end
|
||||
|
||||
vAngles.y = vAngles.y + flDeltaAngle + math.random( -20, 20 )
|
||||
|
||||
if vSpawnPosition ~= nil then
|
||||
|
||||
CreateModifierThinker( self:GetCaster(), self, "modifier_aghsfort_waveblaster_summon_ghost_thinker", {duration = flDuration }, self:GetCaster():GetAbsOrigin(), self:GetCaster():GetTeamNumber(), false )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
aghsfort_wisp_autoattack = class({})
|
||||
LinkLuaModifier( "modifier_aghsfort_wisp_autoattack", "modifiers/creatures/modifier_aghsfort_wisp_autoattack", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function aghsfort_wisp_autoattack:GetIntrinsicModifierName()
|
||||
return "modifier_aghsfort_wisp_autoattack"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
baby_broodmother_passive = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_baby_broodmother_passive", "modifiers/creatures/modifier_baby_broodmother_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
--LinkLuaModifier( "modifier_baby_broodmother_venom_pool", "modifiers/creatures/modifier_baby_broodmother_venom_pool", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function baby_broodmother_passive:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/baby_brood_venom_pool.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_viper/viper_nethertoxin_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/generic_gameplay/generic_silenced_lanecreeps.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/generic_gameplay/generic_silenced.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/generic_gameplay/generic_break.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function baby_broodmother_passive:GetIntrinsicModifierName()
|
||||
return "modifier_baby_broodmother_passive"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
baby_ogre_magi_area_ignite = class ({})
|
||||
LinkLuaModifier( "modifier_ogre_magi_area_ignite_thinker", "modifiers/creatures/modifier_ogre_magi_area_ignite_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_magi_area_ignite:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/neutral_fx/black_dragon_fireball.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_burn.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_magi_area_ignite:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_magi_area_ignite_thinker", { duration = -1 }, self:GetCursorPosition(), self:GetCaster():GetTeamNumber(), false )
|
||||
if self.hThinker ~= nil then
|
||||
local projectile =
|
||||
{
|
||||
Target = self.hThinker,
|
||||
Source = self:GetCaster(),
|
||||
Ability = self,
|
||||
EffectName = "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite.vpcf",
|
||||
iMoveSpeed = self:GetSpecialValueFor( "projectile_speed" ),
|
||||
vSourceLoc = self:GetCaster():GetOrigin(),
|
||||
bDodgeable = false,
|
||||
bProvidesVision = false,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateTrackingProjectile( projectile )
|
||||
|
||||
EmitSoundOn( "OgreMagi.Ignite.Cast", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_magi_area_ignite:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if self.hThinker ~= nil then
|
||||
local hBuff = self.hThinker:FindModifierByName( "modifier_ogre_magi_area_ignite_thinker" )
|
||||
if hBuff ~= nil then
|
||||
hBuff:OnIntervalThink()
|
||||
end
|
||||
self.hThinker = nil;
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
baby_ogre_tank_jump_smash = class({})
|
||||
LinkLuaModifier( "modifier_ogre_tank_melee_smash_thinker", "modifiers/creatures/modifier_ogre_tank_melee_smash_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_jump_smash:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_jump_smash:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_jump_smash:GetPlaybackRateOverride()
|
||||
return 0.75
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_jump_smash:OnSpellStart()
|
||||
if IsServer() then
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_tank_melee_smash_thinker", { duration = self:GetSpecialValueFor( "jump_speed") }, self:GetCaster():GetOrigin(), self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
baby_ogre_tank_melee_smash = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_melee_smash:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_melee_smash:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_melee_smash:GetCooldown( iLevel )
|
||||
return self.BaseClass.GetCooldown( self, self:GetLevel() ) / self:GetCaster():GetHasteFactor()
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_melee_smash:GetPlaybackRateOverride()
|
||||
return math.min( 2.0, math.max( self:GetCaster():GetHasteFactor(), 0.75 ) )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function baby_ogre_tank_melee_smash:OnSpellStart()
|
||||
if IsServer() then
|
||||
EmitSoundOn( "OgreTank.Grunt", self:GetCaster() )
|
||||
local flSpeed = self:GetSpecialValueFor( "base_swing_speed" ) / self:GetPlaybackRateOverride()
|
||||
local vToTarget = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
vToTarget = vToTarget:Normalized()
|
||||
local vTarget = self:GetCaster():GetOrigin() + vToTarget * self:GetCastRange( self:GetCaster():GetOrigin(), nil )
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_tank_melee_smash_thinker", { duration = flSpeed }, vTarget, self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,137 @@
|
||||
|
||||
bandit_archer_arrow = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_bandit_archer_arrow_debuff", "modifiers/creatures/modifier_bandit_archer_arrow_debuff", LUA_MODIFIER_MOTION_BOTH )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_archer_arrow:Precache( context )
|
||||
PrecacheResource( "particle", "particles/dungeon_bandit_archer_crescent_arrow.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_archer_arrow:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_archer_arrow:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
--[[
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 60, 60, 60 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 188, 26, 26 ) )
|
||||
]]
|
||||
|
||||
--EmitSoundOn( "Dungeon.ArcherPullArrow", self:GetCaster() )
|
||||
|
||||
--self:GetCaster():AddNewModifier( self:GetCaster(), nil, "modifier_provide_vision", { duration = 1.5 } )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_archer_arrow:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
--ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
--StopSoundOn( "Dungeon.ArcherPullArrow", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
--[[
|
||||
function bandit_archer_arrow:GetPlaybackRateOverride()
|
||||
return 0.75
|
||||
end
|
||||
]]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_archer_arrow:OnSpellStart()
|
||||
if IsServer() then
|
||||
--ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
--StopSoundOn( "Dungeon.ArcherPullArrow", self:GetCaster() )
|
||||
|
||||
self.attack_speed = self:GetSpecialValueFor( "attack_speed" )
|
||||
self.attack_width_initial = self:GetSpecialValueFor( "attack_width_initial" )
|
||||
self.attack_width_end = self:GetSpecialValueFor( "attack_width_end" )
|
||||
self.attack_distance = self:GetSpecialValueFor( "attack_distance" )
|
||||
self.attack_damage = self:GetSpecialValueFor( "attack_damage" )
|
||||
self.duration = self:GetSpecialValueFor( "duration" )
|
||||
self.break_duration = self:GetSpecialValueFor( "break_duration" )
|
||||
|
||||
local vPos = nil
|
||||
if self:GetCursorTarget() then
|
||||
vPos = self:GetCursorTarget():GetOrigin()
|
||||
else
|
||||
vPos = self:GetCursorPosition()
|
||||
end
|
||||
|
||||
local vDirection = vPos - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
self.attack_speed = self.attack_speed * ( self.attack_distance / ( self.attack_distance - self.attack_width_initial ) )
|
||||
|
||||
local info = {
|
||||
EffectName = "particles/dungeon_bandit_archer_crescent_arrow.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetOrigin(),
|
||||
fStartRadius = self.attack_width_initial,
|
||||
fEndRadius = self.attack_width_end,
|
||||
vVelocity = vDirection * self.attack_speed,
|
||||
fDistance = self.attack_distance,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
|
||||
EmitSoundOn( "Dungeon.ArcherShootArrow", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_archer_arrow:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if hTarget ~= nil and ( not hTarget:IsMagicImmune() ) and ( not hTarget:IsInvulnerable() ) then
|
||||
local damage = {
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.attack_damage,
|
||||
damage_type = self:GetAbilityDamageType(),
|
||||
ability = self
|
||||
}
|
||||
ApplyDamage( damage )
|
||||
|
||||
hTarget:AddNewModifier( self:GetCaster(), nil, "modifier_bandit_archer_arrow_debuff", { duration = self.break_duration } )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, hTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", hTarget:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, hTarget:GetOrigin() )
|
||||
if self:GetCaster() then
|
||||
ParticleManager:SetParticleControlForward( nFXIndex, 1, -self:GetCaster():GetForwardVector() )
|
||||
end
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 10, hTarget, PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
EmitSoundOn( "Dungeon.BloodSplatterImpact", hTarget )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
|
||||
bandit_stifling_dagger = class({})
|
||||
LinkLuaModifier( "modifier_phantom_assassin_stiflingdagger_caster", "modifiers/creatures/modifier_phantom_assassin_stiflingdagger_caster", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_phantom_assassin_stiflingdagger", "modifiers/creatures/modifier_phantom_assassin_stiflingdagger", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_stifling_dagger:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/bandit_captain/phantom_assassin_linear_dagger.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_stifling_dagger:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
local nRadius = 100
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( nRadius, nRadius, nRadius ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 26, 26 ) )
|
||||
|
||||
EmitSoundOn( "Creature.StartCast", self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_stifling_dagger:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
StopSoundOn( "Creature.StartCast", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_stifling_dagger:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
StopSoundOn( "Creature.StartCast", self:GetCaster() )
|
||||
end
|
||||
|
||||
self.duration = self:GetSpecialValueFor( "duration" )
|
||||
self.dagger_speed = self:GetSpecialValueFor( "dagger_speed" )
|
||||
self.dagger_offset = self:GetSpecialValueFor( "dagger_offset" )
|
||||
self.dagger_count = self:GetSpecialValueFor( "dagger_count" )
|
||||
self.dagger_rate = self:GetSpecialValueFor( "dagger_rate" )
|
||||
self.dagger_range = self:GetSpecialValueFor( "dagger_range" )
|
||||
|
||||
self.vTargetLocation = self:GetCursorPosition()
|
||||
self.flAccumulatedTime = 0.0
|
||||
self.vDirection = self.vTargetLocation - self:GetCaster():GetOrigin()
|
||||
self.nDaggersThrown = 0
|
||||
|
||||
local vDirection = self.vTargetLocation - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
self:ThrowDagger( vDirection )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_stifling_dagger:OnChannelThink( flInterval )
|
||||
self.flAccumulatedTime = self.flAccumulatedTime + flInterval
|
||||
if self.flAccumulatedTime >= self.dagger_rate then
|
||||
self.flAccumulatedTime = self.flAccumulatedTime - self.dagger_rate
|
||||
|
||||
local vOffset = RandomVector( self.dagger_offset )
|
||||
vOffset.z = 0.0
|
||||
|
||||
local vDirection = ( self.vTargetLocation + vOffset ) - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
self:ThrowDagger( vDirection )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_stifling_dagger:OnProjectileHit( hTarget, vLocation )
|
||||
if hTarget ~= nil and ( not hTarget:IsInvulnerable() ) then
|
||||
local kv = {}
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_phantom_assassin_stiflingdagger_caster", kv )
|
||||
self:GetCaster():PerformAttack( hTarget, false, true, true, true, true, false, true )
|
||||
self:GetCaster():RemoveModifierByName( "modifier_phantom_assassin_stiflingdagger_caster" )
|
||||
|
||||
local kv =
|
||||
{
|
||||
duration = self.duration,
|
||||
}
|
||||
|
||||
hTarget:AddNewModifier( self:GetCaster(), self, "modifier_phantom_assassin_stiflingdagger", kv)
|
||||
EmitSoundOn( "Dungeon.BanditDagger.Target", hTarget )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bandit_stifling_dagger:ThrowDagger( vDirection )
|
||||
local info =
|
||||
{
|
||||
EffectName = "particles/creatures/bandit_captain/phantom_assassin_linear_dagger.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetOrigin(),
|
||||
fStartRadius = 50.0,
|
||||
fEndRadius = 50.0,
|
||||
vVelocity = vDirection * self.dagger_speed,
|
||||
fDistance = self.dagger_range,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
EmitSoundOn( "Dungeon.BanditDagger.Cast", self:GetCaster() )
|
||||
|
||||
self.nDaggersThrown = self.nDaggersThrown + 1
|
||||
if self.nDaggersThrown >= self.dagger_count then
|
||||
self:EndChannel( false )
|
||||
else
|
||||
self:GetCaster():StartGestureWithPlaybackRate( ACT_DOTA_CAST_ABILITY_1, 1.33 )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,26 @@
|
||||
bomb_squad_landmine_detonate = class({})
|
||||
LinkLuaModifier( "modifier_bomb_squad_landmine_detonate", "modifiers/creatures/modifier_bomb_squad_landmine_detonate", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_bomb_squad_landmine_intrinsic", "modifiers/creatures/modifier_bomb_squad_landmine_intrinsic", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_landmine_detonate:Precache( context )
|
||||
PrecacheResource( "particle", "particles/econ/events/darkmoon_2017/darkmoon_calldown_marker_ring.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_techies/techies_land_mine_explode.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_landmine_detonate:GetIntrinsicModifierName()
|
||||
return "modifier_bomb_squad_landmine_intrinsic"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_landmine_detonate:OnSpellStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_bomb_squad_landmine_detonate", { duration = self:GetSpecialValueFor( "duration" ) } )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
bomb_squad_mine_charge = class({})
|
||||
LinkLuaModifier( "modifier_bomb_squad_mine_charge", "modifiers/creatures/modifier_bomb_squad_mine_charge", LUA_MODIFIER_MOTION_HORIZONTAL )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_mine_charge:Precache( context )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_mine_charge:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():StartGesture( ACT_DOTA_CAST_ABILITY_2 )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_mine_charge:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveGesture( ACT_DOTA_CAST_ABILITY_2 )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_mine_charge:OnSpellStart()
|
||||
if IsServer() then
|
||||
local vTarget = self:GetCursorPosition()
|
||||
local flDist = (vTarget - self:GetCaster():GetOrigin()):Length2D()
|
||||
self.speed = self:GetSpecialValueFor( "speed" )
|
||||
local flDuration = flDist / self.speed
|
||||
|
||||
local kv =
|
||||
{
|
||||
vLocX = vTarget.x,
|
||||
vLocY = vTarget.y,
|
||||
vLocZ = vTarget.z,
|
||||
duration = flDuration
|
||||
}
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_bomb_squad_mine_charge", kv )
|
||||
EmitSoundOn( "OgreTank.Grunt", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
--
|
||||
|
||||
bomb_squad_self_cast = class({})
|
||||
LinkLuaModifier( "modifier_bomb_squad_self_cast", "modifiers/creatures/modifier_bomb_squad_self_cast", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_self_cast:OnSpellStart()
|
||||
if IsServer() then
|
||||
local kv
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_bomb_squad_self_cast", kv )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,38 @@
|
||||
bomb_squad_stasis_launch = class({})
|
||||
LinkLuaModifier( "modifier_bomb_squad_stasis_trap", "modifiers/creatures/modifier_bomb_squad_stasis_trap", LUA_MODIFIER_MOTION_NONE )
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function bomb_squad_stasis_launch:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_techies/techies_stasis_trap_plant.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_techies/techies_stasis_trap_explode.vpcf", context )
|
||||
PrecacheResource("model", "models/heroes/techies/fx_techiesfx_stasis.vmdl", context)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function bomb_squad_stasis_launch:OnSpellStart()
|
||||
if IsServer() then
|
||||
|
||||
self.vTarget = self:GetCursorPosition()
|
||||
local hMine = CreateUnitByName( "npc_aghsfort_creature_bomb_squad_stasis_trap", self:GetCaster():GetAbsOrigin(), true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
hMine:AddNewModifier( self:GetCaster(), self, "modifier_bomb_squad_stasis_trap", { duration = self:GetSpecialValueFor( "mine_lifetime" ) } )
|
||||
|
||||
|
||||
hMine:SetDeathXP( 0 )
|
||||
hMine:SetMinimumGoldBounty( 0 )
|
||||
hMine:SetMaximumGoldBounty( 0 )
|
||||
|
||||
local kv =
|
||||
{
|
||||
vLocX = self.vTarget.x,
|
||||
vLocY = self.vTarget.y,
|
||||
vLocZ = self.vTarget.z,
|
||||
}
|
||||
hMine:SetAbsAngles( 0 , self.vTarget.y, 0 )
|
||||
hMine:AddNewModifier( self:GetCaster(), self, "modifier_frostivus2018_broodbaby_launch", kv )
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
bomber_death_explosion = class({})
|
||||
LinkLuaModifier( "modifier_bomber_death_explosion_trigger", "modifiers/creatures/modifier_bomber_death_explosion_trigger", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_bomber_death_explosion", "modifiers/creatures/modifier_bomber_death_explosion", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function bomber_death_explosion:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_techies/techies_remote_mines_detonate.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_calldown_marker_ring.vpcf", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function bomber_death_explosion:GetIntrinsicModifierName()
|
||||
return "modifier_bomber_death_explosion_trigger"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
bomber_suicide_on_attack = class({})
|
||||
LinkLuaModifier( "modifier_bomber_suicide_on_attack", "modifiers/creatures/modifier_bomber_suicide_on_attack", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function bomber_suicide_on_attack:GetIntrinsicModifierName()
|
||||
return "modifier_bomber_suicide_on_attack"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,143 @@
|
||||
|
||||
require( "utility_functions" )
|
||||
|
||||
boss_timbersaw_chakram_dance = class({})
|
||||
LinkLuaModifier( "modifier_boss_timbersaw_chakram_dance", "modifiers/creatures/modifier_boss_timbersaw_chakram_dance", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_chakram_aghs.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/test_particle/dungeon_sand_king_channel.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_chakram_hit.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_iceblast_half.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_chakram.vpcf", context )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
--EmitSoundOn( "SandKingBoss.Epicenter.spell", self:GetCaster() )
|
||||
if IsGlobalAscensionCaster( self:GetCaster() ) == false then
|
||||
self.nChannelFX = ParticleManager:CreateParticle( "particles/test_particle/dungeon_sand_king_channel.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
if self.nChannelFX ~= nil then
|
||||
ParticleManager:DestroyParticle( self.nChannelFX, false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:GetChannelAnimation()
|
||||
return ACT_DOTA_GENERIC_CHANNEL_1
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:GetPlaybackRateOverride()
|
||||
return 1
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.hChakramAbility = self:GetCaster():FindAbilityByName( "shredder_chakram" )
|
||||
if self.hChakramAbility == nil then
|
||||
self.hChakramAbility = self
|
||||
end
|
||||
self.pass_slow_duration = self.hChakramAbility:GetSpecialValueFor( "pass_slow_duration" )
|
||||
self.pass_damage = self.hChakramAbility:GetSpecialValueFor( "pass_damage" )
|
||||
self.radius = self.hChakramAbility:GetSpecialValueFor( "radius" )
|
||||
self.is_ascension_ability = 0
|
||||
if IsGlobalAscensionCaster( self:GetCaster() ) == true then
|
||||
self.is_ascension_ability = 1
|
||||
end
|
||||
|
||||
local kv = {}
|
||||
kv[ "is_ascension_ability" ] = self.is_ascension_ability
|
||||
kv[ "radius"] = self.radius
|
||||
self.hBuff = self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_boss_timbersaw_chakram_dance", kv )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_boss_timbersaw_chakram_dance" )
|
||||
self.hBuff = nil
|
||||
if self.nChannelFX ~= nil then
|
||||
ParticleManager:DestroyParticle( self.nChannelFX, false )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:OnProjectileThink( vLocation )
|
||||
if IsServer() then
|
||||
GridNav:DestroyTreesAroundPoint( vLocation, self.radius, true )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_chakram_dance:OnProjectileHitHandle( hTarget, vLocation, nProjectileHandle )
|
||||
if IsServer() then
|
||||
if hTarget == nil then
|
||||
if self.hBuff == nil then
|
||||
return true
|
||||
end
|
||||
local Chakram = self.hBuff:GetChakram( nProjectileHandle )
|
||||
if Chakram == nil then
|
||||
-- print( "error, chakram is nil? ")
|
||||
return true
|
||||
end
|
||||
if Chakram.bReturning == false then
|
||||
self.hBuff:ReturnChakram( Chakram, vLocation )
|
||||
return true
|
||||
end
|
||||
elseif hTarget:IsMagicImmune() == false and hTarget:IsInvulnerable() == false then
|
||||
local damageInfo =
|
||||
{
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.pass_damage,
|
||||
damage_type = DAMAGE_TYPE_PURE,
|
||||
ability = self.hChakramAbility,
|
||||
}
|
||||
if self.is_ascension_ability == 1 then
|
||||
damageInfo.damage = damageInfo.damage * hTarget:GetMaxHealth() / 100.0
|
||||
end
|
||||
|
||||
ApplyDamage( damageInfo )
|
||||
|
||||
hTarget:AddNewModifier( self:GetCaster(), self.hChakramAbility, "modifier_shredder_chakram_debuff", { duration = self.pass_slow_duration } )
|
||||
EmitSoundOn( "Boss_Timbersaw.Chakram.Target", hTarget )
|
||||
if hTarget:IsHero() then
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_shredder/shredder_chakram_hit.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, hTarget, PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetAbsOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 1, hTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", hTarget:GetAbsOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
ascension_timbersaw_chakram_dance = boss_timbersaw_chakram_dance
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
boss_timbersaw_reactive_armor = class({})
|
||||
LinkLuaModifier( "modifier_boss_timbersaw_reactive_armor", "modifiers/creatures/modifier_boss_timbersaw_reactive_armor", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_reactive_armor:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/items2_fx/vanguard_active_launch.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/items2_fx/pipe_of_insight_launch.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/items2_fx/vanguard_active.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/items2_fx/pipe_of_insight.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/boss_timbersaw/shredder_armor_lyr1.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/boss_timbersaw/shredder_armor_lyr2.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/boss_timbersaw/shredder_armor_lyr3.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/boss_timbersaw/shredder_armor_lyr4.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_reactive_hit.vpcf", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_reactive_armor:GetIntrinsicModifierName()
|
||||
return "modifier_boss_timbersaw_reactive_armor"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,181 @@
|
||||
boss_timbersaw_timber_chain = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_timber_chain:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_timberchain.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_timber_chain_tree.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_timber_chain_trail.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_timber_dmg.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_tree_dmg.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
--[[
|
||||
function boss_timbersaw_timber_chain:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.chain_radius = self:GetSpecialValueFor( "chain_radius" )
|
||||
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( self.chain_radius, self.chain_radius, self.chain_radius ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 0, 0, 200 ) )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_timber_chain:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
]]--
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_timber_chain:OnSpellStart()
|
||||
if IsServer() then
|
||||
--ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
self.chain_radius = self:GetSpecialValueFor( "chain_radius" )
|
||||
self.radius = self:GetSpecialValueFor( "radius" )
|
||||
self.speed = self:GetSpecialValueFor( "speed" )
|
||||
self.range = self:GetSpecialValueFor( "range" )
|
||||
self.stun_duration = self:GetSpecialValueFor( "stun_duration" )
|
||||
self.bRetracting = false
|
||||
self.hHitTargets = {}
|
||||
|
||||
local vDirection = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
local vTargetPos = self:GetCaster():GetAbsOrigin() + ( vDirection * self.range ) + Vector( 0, 0, 96 )
|
||||
self.vVelocity = vDirection * self.speed
|
||||
local info =
|
||||
{
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetAbsOrigin(),
|
||||
fStartRadius = self.chain_radius,
|
||||
fEndRadius = self.chain_radius,
|
||||
vVelocity = self.vVelocity,
|
||||
fDistance = self.range,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_BOTH,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_TREE,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
|
||||
self.nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_shredder/shredder_timberchain.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nFXIndex, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_attack1", self:GetCaster():GetAbsOrigin() + Vector( 0, 0, 96 ), true )
|
||||
ParticleManager:SetParticleControl( self.nFXIndex, 1, vTargetPos )
|
||||
ParticleManager:SetParticleControl( self.nFXIndex, 2, Vector( self.speed, 0, 0 ) )
|
||||
ParticleManager:SetParticleControl( self.nFXIndex, 3, Vector( 10, 0, 0 ) )
|
||||
|
||||
EmitSoundOn( "Hero_Shredder.TimberChain.Cast", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_timber_chain:OnProjectileThink( vLocation )
|
||||
if IsServer() then
|
||||
|
||||
if self.bRetracting == false then
|
||||
local hTrees = GridNav:GetAllTreesAroundPoint( vLocation, self.chain_radius, true )
|
||||
if #hTrees > 0 then
|
||||
for _,Tree in pairs ( hTrees ) do
|
||||
if Tree and Tree:IsStanding() then
|
||||
local vTreeOrigin = Tree:GetAbsOrigin()
|
||||
if self:GetCaster().Encounter and self:GetCaster().Encounter:GetRoom() and self:GetCaster().Encounter:GetRoom():IsInRoomBounds( vTreeOrigin ) then
|
||||
self:OnProjectileHit( Tree, vTreeOrigin )
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if self:GetCaster():FindModifierByName( "modifier_shredder_timber_chain" ) then
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), me, self.radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, 0, 0, false )
|
||||
if #enemies > 0 then
|
||||
for _,enemy in pairs( enemies ) do
|
||||
if enemy and self:HasHitTarget( enemy ) == false then
|
||||
table.insert( self.hHitTargets, enemy )
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_stunned", { duration = self.stun_duration } )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_timber_chain:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if self.bRetracting == false then
|
||||
StopSoundOn( "Hero_Shredder.TimberChain.Cast", self:GetCaster() )
|
||||
|
||||
if hTarget ~= nil then
|
||||
print( "found a tree" )
|
||||
EmitSoundOnLocationWithCaster( vLocation, "Hero_Shredder.TimberChain.Impact", self:GetCaster() )
|
||||
local nTreeFX = ParticleManager:CreateParticle( "particles/units/heroes/hero_shredder/shredder_timber_chain_tree.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nTreeFX, 0, vLocation + Vector( 0, 0, 96 ) )
|
||||
ParticleManager:ReleaseParticleIndex( nTreeFX )
|
||||
|
||||
local flDist = ( vLocation - self:GetCaster():GetAbsOrigin() ):Length2D()
|
||||
local flDuration = flDist / self.speed
|
||||
local kv = {}
|
||||
kv[ "duration" ] = flDuration
|
||||
kv[ "tree_index" ] = hTarget:entindex()
|
||||
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_shredder_timber_chain", kv )
|
||||
ParticleManager:SetParticleControl( self.nFXIndex, 1, vLocation + Vector( 0, 0, 96 ) )
|
||||
ParticleManager:SetParticleControl( self.nFXIndex, 3, Vector( flDuration * 2 - 0.1, 0, 0 ) )
|
||||
else
|
||||
ParticleManager:SetParticleControlEnt( self.nFXIndex, 1, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, "attach_attack1", self:GetCaster():GetAbsOrigin() + Vector( 0, 0, 96 ), true )
|
||||
|
||||
local flFailChainDuration = ( self.range * 2 ) / self.speed
|
||||
ParticleManager:SetParticleControl( self.nFXIndex, 3, Vector( flFailChainDuration - 0.1, 0, 0 ) )
|
||||
end
|
||||
|
||||
EmitSoundOn( "Hero_Shredder.TimberChain.Retract", self:GetCaster() )
|
||||
|
||||
self.bRetracting = true
|
||||
ParticleManager:ReleaseParticleIndex( self.nFXIndex )
|
||||
|
||||
local info =
|
||||
{
|
||||
Ability = self,
|
||||
vSpawnOrigin = vLocation,
|
||||
vVelocity = self.vVelocity * -1,
|
||||
fDistance = self.range,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_BOTH,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_TREE,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
else
|
||||
self.hHitTargets = {}
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_timber_chain:HasHitTarget( hTarget )
|
||||
for _, target in pairs( self.hHitTargets ) do
|
||||
if target == hTarget then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
@@ -0,0 +1,84 @@
|
||||
boss_timbersaw_whirling_death = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_whirling_death:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/boss_timbersaw/boss_timbersaw_whirling_death.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_shredder/shredder_whirling_death_debuff.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_whirling_death:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.whirling_radius = self:GetSpecialValueFor( "whirling_radius" )
|
||||
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( self.whirling_radius, self.whirling_radius, self.whirling_radius ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 26, 26 ) )
|
||||
|
||||
EmitSoundOn( "Hero_Shredder.WhirlingDeath.Cast", self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_whirling_death:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_timbersaw_whirling_death:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
self.duration = self:GetSpecialValueFor( "duration" )
|
||||
self.whirling_damage = self:GetSpecialValueFor( "whirling_damage" )
|
||||
self.tree_damage_scale = self:GetSpecialValueFor( "tree_damage_scale" )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/boss_timbersaw/boss_timbersaw_whirling_death.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_hitloc", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 1, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 2, Vector( self.whirling_radius, self.whirling_radius, self.whirling_radius ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
EmitSoundOn( "Hero_Shredder.WhirlingDeath.Cast", self:GetCaster() )
|
||||
|
||||
local nTreeBonusDmg = 0
|
||||
local hTrees = GridNav:GetAllTreesAroundPoint( self:GetCaster():GetAbsOrigin(), self.whirling_radius, true )
|
||||
for _,Tree in pairs ( hTrees ) do
|
||||
if Tree.IsStanding and Tree:IsStanding() then
|
||||
nTreeBonusDmg = nTreeBonusDmg + self.tree_damage_scale
|
||||
Tree:CutDown( self:GetTeamNumber() )
|
||||
end
|
||||
end
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), nil, self.whirling_radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
|
||||
for _,enemy in pairs( enemies ) do
|
||||
if enemy ~= nil and enemy:IsInvulnerable() == false then
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_shredder_whirling_death_debuff", { duration = self.duration } )
|
||||
local damageInfo =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.whirling_damage + nTreeBonusDmg,
|
||||
damage_type = DAMAGE_TYPE_PURE,
|
||||
ability = self,
|
||||
}
|
||||
ApplyDamage( damageInfo )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
boss_visage_familiar_stone_form = class({})
|
||||
LinkLuaModifier( "modifier_boss_visage_familiar_stone_form_buff", "modifiers/creatures/modifier_boss_visage_familiar_stone_form_buff", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_boss_visage_familiar_statue_stone_form", "modifiers/creatures/modifier_boss_visage_familiar_statue_stone_form", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_boss_visage_familiar_passive", "modifiers/creatures/modifier_boss_visage_familiar_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_familiar_stone_form:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_stone_form.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_earth_spirit_petrify.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_visage.vsndevts", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_familiar_stone_form:GetIntrinsicModifierName()
|
||||
return "modifier_boss_visage_familiar_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_familiar_stone_form:OnSpellStart()
|
||||
if IsServer() then
|
||||
local szBuffName = "modifier_boss_visage_familiar_stone_form_buff"
|
||||
if self:GetCaster():GetUnitName() == "npc_dota_boss_visage_familiar_statue" then
|
||||
szBuffName = "modifier_boss_visage_familiar_statue_stone_form"
|
||||
end
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, szBuffName, {} )
|
||||
self:GetCaster():StartGesture( ACT_DOTA_CAST_ABILITY_1 )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,145 @@
|
||||
boss_visage_grave_chill = class({})
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_grave_chill:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_base_attack.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_visage.vsndevts", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_necrolyte/necrolyte_pulse_enemy.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_vengeful/vengeful_wave_of_terror.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_grave_chill:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
EmitSoundOn( "Hero_Visage.preAttack", self:GetCaster() )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_grave_chill:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.chill_speed = self:GetSpecialValueFor( "chill_speed" )
|
||||
self.chill_radius = self:GetSpecialValueFor( "chill_radius" )
|
||||
self.chill_count = self:GetSpecialValueFor( "chill_count" )
|
||||
self.chill_damage = self:GetSpecialValueFor( "chill_damage" )
|
||||
|
||||
if self:GetCaster():GetHealthPercent() < 60 then
|
||||
self.chill_speed = self.chill_speed * 2
|
||||
self.chill_count = self.chill_count + 2
|
||||
end
|
||||
|
||||
if self.bStatuesInit == nil then
|
||||
--print( "setting statue pairs ")
|
||||
--print ( "Num east statues " .. #self:GetCaster().EastStatues )
|
||||
--print ( "Num west statues " .. #self:GetCaster().WestStatues )
|
||||
for k,v in pairs ( self:GetCaster().EastStatues ) do
|
||||
local flShortestDist = 9999999
|
||||
local nPairIndex = nil
|
||||
for i,j in pairs ( self:GetCaster().WestStatues ) do
|
||||
local flDist = ( v:GetAbsOrigin() - j:GetAbsOrigin() ):Length2D()
|
||||
if flDist < flShortestDist then
|
||||
flShortestDist = flDist
|
||||
nPairIndex = i
|
||||
end
|
||||
end
|
||||
--print( "East statue at key " .. k .. " has partner in west at key " .. nPairIndex )
|
||||
v.nTargetPairIndex = nPairIndex
|
||||
self:GetCaster().WestStatues[ nPairIndex ].nTargetPairIndex = k
|
||||
end
|
||||
self.bStatuesInit = true
|
||||
end
|
||||
|
||||
local bEast = true
|
||||
local EastStatues = deepcopy( self:GetCaster().EastStatues )
|
||||
local WestStatues = deepcopy( self:GetCaster().WestStatues )
|
||||
for i=1,self.chill_count do
|
||||
local hSource = nil
|
||||
local hTarget = nil
|
||||
local k = nil
|
||||
if bEast then
|
||||
k = RandomInt( 1, #EastStatues )
|
||||
hSource = EastStatues[ k ]
|
||||
hTarget = WestStatues[ hSource.nTargetPairIndex ]
|
||||
table.remove( EastStatues, k )
|
||||
table.remove( WestStatues, hSource.nTargetPairIndex )
|
||||
else
|
||||
k = RandomInt( 1, #WestStatues )
|
||||
hSource = WestStatues[ k ]
|
||||
hTarget = EastStatues[ hSource.nTargetPairIndex ]
|
||||
table.remove( WestStatues, k )
|
||||
table.remove( EastStatues, hSource.nTargetPairIndex )
|
||||
end
|
||||
|
||||
if hTarget ~= nil and hSource ~= nil then
|
||||
local vDirection = hTarget:GetAbsOrigin() - hSource:GetAbsOrigin()
|
||||
local flDist = vDirection:Length2D()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
local info =
|
||||
{
|
||||
EffectName = "particles/units/heroes/hero_vengeful/vengeful_wave_of_terror.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = hSource:GetAbsOrigin(),
|
||||
fStartRadius = self.chill_radius,
|
||||
fEndRadius = self.chill_radius,
|
||||
vVelocity = vDirection * self.chill_speed,
|
||||
fDistance = flDist,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
EmitSoundOn( "Hero_Visage.Attack", hSource )
|
||||
end
|
||||
|
||||
bEast = not bEast
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_grave_chill:OnProjectileThinkHandle( nProjectileHandle )
|
||||
if IsServer() then
|
||||
local vLocation = ProjectileManager:GetTrackingProjectileLocation( nProjectileHandle )
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), vLocation, nil, self.chill_radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_CLOSEST, false )
|
||||
if #enemies == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
ProjectileManager:DestroyTrackingProjectile( nProjectileHandle )
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_grave_chill:OnProjectileHitHandle( hTarget, vLocation, nProjectileHandle )
|
||||
if IsServer() then
|
||||
if hTarget and hTarget:IsMagicImmune() == false and hTarget:IsInvulnerable() == false then
|
||||
self.chill_duration = self:GetSpecialValueFor( "chill_duration" )
|
||||
hTarget:AddNewModifier( self:GetCaster(), self, "modifier_visage_grave_chill_debuff", { duration = self.chill_duration } )
|
||||
EmitSoundOn( "Hero_Visage.GraveChill.Target", hTarget )
|
||||
|
||||
local damage =
|
||||
{
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.chill_damage,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
ability = self,
|
||||
}
|
||||
|
||||
ApplyDamage( damage )
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
boss_visage_passive = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_boss_visage_passive", "modifiers/creatures/modifier_boss_visage_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_passive:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_soul_assumption_bolt6.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_earth_spirit_petrify.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/act_2/storegga_channel.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_visage.vsndevts", context )
|
||||
PrecacheResource( "soundfile", "soundevents/voscripts/game_sounds_vo_visage.vsndevts", context )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_passive:GetIntrinsicModifierName()
|
||||
return "modifier_boss_visage_passive"
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_passive:OnProjectileThinkHandle( nProjectileHandle )
|
||||
if IsServer() and self:GetCaster() ~= nil then
|
||||
self.soul_assumption_radius = self:GetSpecialValueFor( "soul_assumption_radius" )
|
||||
local vLocation = ProjectileManager:GetTrackingProjectileLocation( nProjectileHandle )
|
||||
local hFamiliars = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), vLocation, nil, self.soul_assumption_radius, DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_CLOSEST, false )
|
||||
for _,Familiar in pairs ( hFamiliars ) do
|
||||
if Familiar ~= nil and Familiar:GetUnitName() == "npc_dota_boss_visage_familiar" then
|
||||
self:WakeFamiliar( Familiar )
|
||||
ProjectileManager:DestroyTrackingProjectile( nProjectileHandle )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_passive:WakeFamiliar( hFamiliar )
|
||||
if IsServer() then
|
||||
print( "Waking familiar!" )
|
||||
hFamiliar:RemoveModifierByName( "modifier_boss_visage_familiar_stone_form_buff" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_passive:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() == false or hTarget == nil then
|
||||
return true
|
||||
end
|
||||
|
||||
if hTarget:IsMagicImmune() == false and hTarget:IsInvulnerable() == false then
|
||||
local damageInfo =
|
||||
{
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self:GetSpecialValueFor( "soul_assumption_damage" ),
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
ability = self,
|
||||
}
|
||||
|
||||
ApplyDamage( damageInfo )
|
||||
|
||||
EmitSoundOn( "Hero_Visage.SoulAssumption.Target", hTarget )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
@@ -0,0 +1,93 @@
|
||||
boss_visage_ranged_attack = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_ranged_attack:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/visage_boss_base_attack.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/quill_beast/test_model_cluster_linear_projectile.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_bristleback/bristleback_quill_spray_impact.vpcf", context )
|
||||
PrecacheResource( "soundfile", "soundevents/game_sounds_heroes/game_sounds_visage.vsndevts", context )
|
||||
|
||||
self.Projectiles = {}
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_ranged_attack:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
EmitSoundOn( "Hero_Visage.preAttack", self:GetCaster() )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_ranged_attack:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.attack_speed = self:GetSpecialValueFor( "attack_speed" )
|
||||
self.attack_width_initial = self:GetSpecialValueFor( "attack_width_initial" )
|
||||
self.attack_width_end = self:GetSpecialValueFor( "attack_width_end" )
|
||||
self.attack_distance = self:GetSpecialValueFor( "attack_distance" )
|
||||
self.attack_damage = self:GetSpecialValueFor( "attack_damage" )
|
||||
|
||||
local vPos = nil
|
||||
if self:GetCursorTarget() then
|
||||
vPos = self:GetCursorTarget():GetOrigin()
|
||||
else
|
||||
vPos = self:GetCursorPosition()
|
||||
end
|
||||
|
||||
local vDirection = vPos - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
self.attack_speed = self.attack_speed * ( self.attack_distance / ( self.attack_distance - self.attack_width_initial ) )
|
||||
|
||||
local info = {
|
||||
EffectName = "particles/creatures/quill_beast/test_model_cluster_linear_projectile.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetAttachmentOrigin( self:GetCaster():ScriptLookupAttachment( "attach_attack1" ) ),
|
||||
fStartRadius = self.attack_width_initial,
|
||||
fEndRadius = self.attack_width_end,
|
||||
vVelocity = vDirection * self.attack_speed,
|
||||
fDistance = self.attack_distance,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
EmitSoundOn( "Hero_Visage.Attack", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function boss_visage_ranged_attack:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if hTarget ~= nil and ( not hTarget:IsMagicImmune() ) and ( not hTarget:IsInvulnerable() ) then
|
||||
local damage = {
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.attack_damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
ability = self
|
||||
}
|
||||
|
||||
ApplyDamage( damage )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_bristleback/bristleback_quill_spray_impact.vpcf", PATTACH_CUSTOMORIGIN, hTarget );
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, hTarget, PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 1, hTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", hTarget:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 2, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetOrigin(), true );
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex );
|
||||
|
||||
EmitSoundOn( "Hero_Visage.projectileImpact", hTarget )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
brewmaster_unit_passive = class({})
|
||||
LinkLuaModifier( "modifier_brewmaster_unit_passive", "modifiers/creatures/modifier_brewmaster_unit_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function brewmaster_unit_passive:GetIntrinsicModifierName()
|
||||
return "modifier_brewmaster_unit_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
broodmother_accrue_children = class({})
|
||||
LinkLuaModifier( "modifier_broodmother_accrue_children", "modifiers/creatures/modifier_broodmother_accrue_children", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_broodmother_generate_children", "modifiers/creatures/modifier_broodmother_generate_children", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_accrue_children:Precache( context )
|
||||
|
||||
PrecacheUnitByNameSync( "npc_dota_dummy_caster", context, -1 )
|
||||
PrecacheResource( "particle", "particles/baby_brood_venom_pool.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_broodmother_baby_c", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_accrue_children:GetIntrinsicModifierName()
|
||||
return "modifier_broodmother_accrue_children"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
-- Note: this ability gets added by hand to the dummy unit that Broodmother creates.
|
||||
|
||||
broodmother_generate_children = class({})
|
||||
LinkLuaModifier( "modifier_broodmother_generate_children", "modifiers/creatures/modifier_broodmother_generate_children", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_generate_children:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/baby_brood_venom_pool.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_broodmother_baby_c", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_generate_children:GetIntrinsicModifierName()
|
||||
return "modifier_broodmother_generate_children"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
123
aghanim_singleplayer/scripts/vscripts/abilities/creatures/broodmother_web.lua
Executable file
123
aghanim_singleplayer/scripts/vscripts/abilities/creatures/broodmother_web.lua
Executable file
@@ -0,0 +1,123 @@
|
||||
|
||||
broodmother_web = class({})
|
||||
LinkLuaModifier( "modifier_broodmother_web", "modifiers/creatures/modifier_broodmother_web", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_web:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_venomancer/venomancer_venomous_gale.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_venomancer/venomancer_venomous_gale_impact.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/items2_fx/rod_of_atos.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_web:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_web:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 100, 100, 100 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 0, 100 ) )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_web:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_web:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
self.projectile_distance = self:GetSpecialValueFor( "projectile_distance" )
|
||||
self.projectile_speed = self:GetSpecialValueFor( "projectile_speed" )
|
||||
self.projectile_radius = self:GetSpecialValueFor( "projectile_radius" )
|
||||
self.damage = self:GetSpecialValueFor( "damage" )
|
||||
self.root_duration = self:GetSpecialValueFor( "root_duration" )
|
||||
|
||||
self.knockback_distance = self:GetSpecialValueFor( "knockback_distance" )
|
||||
self.knockback_height = self:GetSpecialValueFor( "knockback_height" )
|
||||
self.knockback_duration = self:GetSpecialValueFor( "knockback_duration" )
|
||||
|
||||
local vPos = self:GetCursorPosition()
|
||||
local vDirection = vPos - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
local info = {
|
||||
EffectName = "particles/units/heroes/hero_venomancer/venomancer_venomous_gale.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetOrigin(),
|
||||
fStartRadius = self.projectile_radius,
|
||||
fEndRadius = self.projectile_radius,
|
||||
vVelocity = vDirection * self.projectile_speed,
|
||||
fDistance = self.projectile_distance,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = self:GetAbilityTargetTeam(),
|
||||
iUnitTargetType = self:GetAbilityTargetType(),
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
|
||||
EmitSoundOn( "Spider.PoisonSpit", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function broodmother_web:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if hTarget ~= nil and ( not hTarget:IsMagicImmune() ) and ( not hTarget:IsInvulnerable() ) then
|
||||
local damage =
|
||||
{
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.damage,
|
||||
damage_type = self:GetAbilityDamageType(),
|
||||
ability = self,
|
||||
}
|
||||
ApplyDamage( damage )
|
||||
|
||||
local kv_knockback =
|
||||
{
|
||||
center_x = vLocation.x,
|
||||
center_y = vLocation.y,
|
||||
center_z = vLocation.z,
|
||||
should_stun = false,
|
||||
duration = self.knockback_duration,
|
||||
knockback_duration = self.knockback_duration,
|
||||
knockback_distance = self.knockback_distance,
|
||||
knockback_height = self.knockback_height,
|
||||
}
|
||||
hTarget:AddNewModifier( self:GetCaster(), self, "modifier_knockback", kv_knockback )
|
||||
|
||||
hTarget:AddNewModifier( self:GetCaster(), self, "modifier_broodmother_web", { duration = self.root_duration } )
|
||||
|
||||
ParticleManager:ReleaseParticleIndex( ParticleManager:CreateParticle( "particles/units/heroes/hero_venomancer/venomancer_venomous_gale_impact.vpcf", PATTACH_ABSORIGIN_FOLLOW, hTarget ) )
|
||||
|
||||
EmitSoundOn( "Spider.PoisonSpit.Impact", self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
burrower_big_explosion = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function burrower_big_explosion:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/nyx_swarm_explosion/nyx_swarm_explosion.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function burrower_big_explosion:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.radius = self:GetSpecialValueFor( "radius" )
|
||||
--self.duration = self:GetSpecialValueFor( "duration" )
|
||||
self.damage = self:GetSpecialValueFor( "damage" )
|
||||
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( radius, radius, radius ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 26, 26 ) )
|
||||
|
||||
EmitSoundOn( "Burrower.PreSuicide", self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function burrower_big_explosion:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function burrower_big_explosion:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
local nFXIndex2 = ParticleManager:CreateParticle( "particles/nyx_swarm_explosion/nyx_swarm_explosion.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex2, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_hitloc", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex2, 1, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex2, 2, Vector( self.radius, self.radius, self.radius ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex2 )
|
||||
|
||||
EmitSoundOn( "Burrower.Explosion", self:GetCaster() )
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), nil, self.radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BUILDING, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_FOW_VISIBLE, FIND_CLOSEST, false )
|
||||
for _,hEnemy in pairs( enemies ) do
|
||||
if hEnemy ~= nil and hEnemy:IsAlive() and hEnemy:IsInvulnerable() == false then
|
||||
local damageInfo =
|
||||
{
|
||||
victim = hEnemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.damage,
|
||||
--damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
damage_type = self:GetAbilityDamageType(),
|
||||
ability = self,
|
||||
}
|
||||
ApplyDamage( damageInfo )
|
||||
--hEnemy:AddNewModifier( self:GetCaster(), self, "modifier_polar_furbolg_ursa_warrior_thunder_clap", { duration = self.duration } )
|
||||
end
|
||||
end
|
||||
|
||||
self:GetCaster():ForceKill( false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,14 @@
|
||||
creature_bonus_chicken = class({})
|
||||
LinkLuaModifier( "modifier_creature_bonus_chicken", "modifiers/modifier_creature_bonus_chicken", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_bonus_chicken:Precache( context )
|
||||
PrecacheItemByNameSync( "item_bag_of_gold", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_bonus_chicken:GetIntrinsicModifierName()
|
||||
return "modifier_creature_bonus_chicken"
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
creature_bonus_greevil = class({})
|
||||
LinkLuaModifier( "modifier_creature_bonus_greevil", "modifiers/modifier_creature_bonus_greevil", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_bonus_greevil:Precache( context )
|
||||
PrecacheItemByNameSync( "item_bag_of_gold", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_bonus_greevil:GetIntrinsicModifierName()
|
||||
return "modifier_creature_bonus_greevil"
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
creature_generic_high_status_resist_passive = class({})
|
||||
LinkLuaModifier( "modifier_creature_generic_high_status_resist_passive", "modifiers/creatures/modifier_creature_generic_high_status_resist_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_generic_high_status_resist_passive:GetIntrinsicModifierName()
|
||||
return "modifier_creature_generic_high_status_resist_passive"
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
creature_landmine_detonate = class({})
|
||||
LinkLuaModifier( "modifier_creature_landmine_detonate", "modifiers/creatures/modifier_creature_landmine_detonate", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_landmine_detonate:OnSpellStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_creature_landmine_detonate", { duration = self:GetSpecialValueFor( "duration" ) } )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
creature_pudge_miniboss_passive = class({})
|
||||
LinkLuaModifier( "modifier_creature_pudge_miniboss_passive", "modifiers/creatures/modifier_creature_pudge_miniboss_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_pudge_miniboss_passive:GetIntrinsicModifierName()
|
||||
return "modifier_creature_pudge_miniboss_passive"
|
||||
end
|
||||
@@ -0,0 +1,156 @@
|
||||
creature_shadow_wave = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function creature_shadow_wave:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_dazzle/dazzle_shadow_wave.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_dazzle/dazzle_shadow_wave_impact_damage.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_shadow_wave:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 75, 75, 75 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 230, 100, 223 ) )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_shadow_wave:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_shadow_wave:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
local hTarget = self:GetCursorTarget()
|
||||
if hTarget ~= nil then
|
||||
self.bounce_radius = self:GetSpecialValueFor( "bounce_radius" )
|
||||
self.damage_radius = self:GetSpecialValueFor( "damage_radius" )
|
||||
self.damage = self:GetSpecialValueFor( "damage" )
|
||||
self.max_targets = self:GetSpecialValueFor( "max_targets" )
|
||||
|
||||
self.nCurJumpCount = 1
|
||||
self.hHitEntities = {}
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_dazzle/dazzle_shadow_wave.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_attack1", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 1, hTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", hTarget:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 2, Vector( self.damage_radius, 0, 0 ) )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 3, hTarget, PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
self.vTargetLoc = self:GetCaster():GetOrigin()
|
||||
|
||||
self:DoHealAndDamage( self:GetCaster() )
|
||||
table.insert( self.hHitEntities, self:GetCaster() )
|
||||
|
||||
EmitSoundOn( "Wildwing.Shadow_Wave", self:GetCaster() )
|
||||
|
||||
local nFXIndex2 = ParticleManager:CreateParticle( "particles/units/heroes/hero_dazzle/dazzle_shadow_wave.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex2, 0, self:GetCaster():GetOrigin() )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex2, 1, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_hitloc", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex2, 2, Vector( self.damage_radius, 0, 0 ) )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex2, 3, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex2 )
|
||||
|
||||
self.vTargetLoc = hTarget:GetOrigin()
|
||||
if self:GetCaster() ~= hTarget then
|
||||
self:DoHealAndDamage( hTarget )
|
||||
|
||||
local nFXIndex3 = ParticleManager:CreateParticle( "particles/units/heroes/hero_dazzle/dazzle_shadow_wave.vpcf", PATTACH_CUSTOMORIGIN, hTarget )
|
||||
ParticleManager:SetParticleControl( nFXIndex3, 0, self.vTargetLoc )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex3, 1, hTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", hTarget:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex3, 2, Vector( self.damage_radius, 0, 0 ) )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex3, 3, hTarget, PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex3 )
|
||||
|
||||
self.vTargetLoc = hTarget:GetOrigin()
|
||||
table.insert( self.hHitEntities, hTarget )
|
||||
else
|
||||
self.nCurJumpCount = self.nCurJumpCount - 1
|
||||
end
|
||||
|
||||
while self.nCurJumpCount < self.max_targets do
|
||||
local hBestJumpTarget = nil
|
||||
|
||||
local friendlies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self.vTargetLoc, self:GetCaster(), self.bounce_radius, DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, 0, false )
|
||||
for _,friendly in pairs(friendlies) do
|
||||
if friendly ~= nil and not self:HasHitTarget( friendly ) then
|
||||
hBestJumpTarget = friendly
|
||||
end
|
||||
end
|
||||
|
||||
if hBestJumpTarget ~= nil then
|
||||
|
||||
self:DoHealAndDamage( hBestJumpTarget )
|
||||
|
||||
local nFXIndex4 = ParticleManager:CreateParticle( "particles/units/heroes/hero_dazzle/dazzle_shadow_wave.vpcf", PATTACH_CUSTOMORIGIN, hBestJumpTarget )
|
||||
ParticleManager:SetParticleControl( nFXIndex4, 0, self.vTargetLoc )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex4, 1, hBestJumpTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", hBestJumpTarget:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex4, 2, Vector( self.damage_radius, 0, 0 ) )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex4, 3, hBestJumpTarget, PATTACH_ABSORIGIN_FOLLOW, nil, hBestJumpTarget:GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex4 )
|
||||
|
||||
self.vTargetLoc = hBestJumpTarget:GetOrigin()
|
||||
table.insert( self.hHitEntities, hTarget )
|
||||
end
|
||||
self.nCurJumpCount = self.nCurJumpCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_shadow_wave:DoHealAndDamage( hTarget )
|
||||
if IsServer() then
|
||||
hTarget:Heal( self.damage, self )
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), hTarget:GetOrigin(), self:GetCaster(), self.damage_radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, 0, false )
|
||||
if #enemies > 0 then
|
||||
for _,enemy in pairs(enemies) do
|
||||
if enemy ~= nil then
|
||||
local damage =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
damage_flags = DOTA_DAMAGE_FLAG_BYPASSES_BLOCK,
|
||||
ability = self
|
||||
}
|
||||
ApplyDamage( damage )
|
||||
local vDir = enemy:GetOrigin() - hTarget:GetOrigin()
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_dazzle/dazzle_shadow_wave_impact_damage.vpcf", PATTACH_CUSTOMORIGIN, enemy )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, enemy, PATTACH_POINT_FOLLOW, "attach_hitloc", enemy:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, vDir )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_shadow_wave:HasHitTarget( hTarget )
|
||||
for _,hHitTarget in pairs ( self.hHitEntities ) do
|
||||
if hHitTarget == hTarget then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
creature_techies_land_mine = class({})
|
||||
LinkLuaModifier( "modifier_creature_techies_land_mine", "modifiers/creatures/modifier_creature_techies_land_mine", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function creature_techies_land_mine:OnSpellStart()
|
||||
if IsServer() then
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
dummy_caster_passive = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_dummy_caster_passive", "modifiers/creatures/modifier_dummy_caster_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function dummy_caster_passive:GetIntrinsicModifierName()
|
||||
return "modifier_dummy_caster_passive"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
dummy_target_passive = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_dummy_target_passive", "modifiers/creatures/modifier_dummy_target_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function dummy_target_passive:GetIntrinsicModifierName()
|
||||
return "modifier_dummy_target_passive"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
earth_spirit_statue_passive = class({})
|
||||
LinkLuaModifier( "modifier_earth_spirit_statue_passive", "modifiers/creatures/modifier_earth_spirit_statue_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_earth_spirit_statue_stoneform", "modifiers/creatures/modifier_earth_spirit_statue_stoneform", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function earth_spirit_statue_passive:Precache( context )
|
||||
PrecacheModel( "models/heroes/attachto_ghost/attachto_ghost.vmdl", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function earth_spirit_statue_passive:GetIntrinsicModifierName()
|
||||
return "modifier_earth_spirit_statue_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
elemental_tiny_tree_attack = class({})
|
||||
|
||||
|
||||
function elemental_tiny_tree_attack:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_tiny/tiny_craggy_cleave.vpcf", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function elemental_tiny_tree_attack:GetIntrinsicModifierName()
|
||||
return "modifier_tiny_tree_grab"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
ember_spirit_fireball = class({})
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ember_spirit_fireball:Precache( context )
|
||||
PrecacheResource( "particle", "particles/lycanboss_ruptureball_gale.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ember_spirit_fireball:GetPlaybackRateOverride()
|
||||
return 0.3333
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ember_spirit_fireball:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
--EmitSoundOn( "lycan_lycan_attack_09", self:GetCaster() )
|
||||
|
||||
self.preview_fx_radius = self:GetSpecialValueFor( "preview_fx_radius" )
|
||||
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( self.preview_fx_radius, self.preview_fx_radius, self.preview_fx_radius ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 247, 86, 9 ) )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ember_spirit_fireball:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ember_spirit_fireball:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
self.projectile_speed = self:GetSpecialValueFor( "projectile_speed" )
|
||||
self.projectile_width_initial = self:GetSpecialValueFor( "projectile_width_initial" )
|
||||
self.projectile_width_end = self:GetSpecialValueFor( "projectile_width_end" )
|
||||
self.projectile_distance = self:GetSpecialValueFor( "projectile_distance" )
|
||||
self.impact_damage = self:GetSpecialValueFor( "impact_damage" )
|
||||
|
||||
local vPos = nil
|
||||
if self:GetCursorTarget() then
|
||||
vPos = self:GetCursorTarget():GetOrigin()
|
||||
else
|
||||
vPos = self:GetCursorPosition()
|
||||
end
|
||||
|
||||
local vDirection = vPos - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
self.projectile_speed = self.projectile_speed * ( self.projectile_distance / ( self.projectile_distance - self.projectile_width_initial ) )
|
||||
|
||||
local info = {
|
||||
EffectName = "particles/lycanboss_ruptureball_gale.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetOrigin(),
|
||||
fStartRadius = self.projectile_width_initial,
|
||||
fEndRadius = self.projectile_width_end,
|
||||
vVelocity = vDirection * self.projectile_speed,
|
||||
fDistance = self.projectile_distance,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
--EmitSoundOn( "Lycan.RuptureBall", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ember_spirit_fireball:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if hTarget ~= nil and ( not hTarget:IsMagicImmune() ) and ( not hTarget:IsInvulnerable() ) then
|
||||
--EmitSoundOn( "Lycan.RuptureBall.Impact", hTarget );
|
||||
|
||||
hTarget:AddNewModifier( self:GetCaster(), self, "modifier_disarmed", { duration = self:GetSpecialValueFor( "disarm_duration" ) } )
|
||||
|
||||
local damage = {
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.impact_damage,
|
||||
damage_type = self:GetAbilityDamageType(),
|
||||
ability = self
|
||||
}
|
||||
ApplyDamage( damage )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
enraged_wildkin_tornado_passive = class({})
|
||||
LinkLuaModifier( "modifier_enraged_wildkin_tornado_passive", "modifiers/creatures/modifier_enraged_wildkin_tornado_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function enraged_wildkin_tornado_passive:GetIntrinsicModifierName()
|
||||
return "modifier_enraged_wildkin_tornado_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,95 @@
|
||||
|
||||
enraged_wildwing_create_tornado = class({})
|
||||
LinkLuaModifier( "modifier_enraged_wildkin_tornado_passive", "modifiers/creatures/modifier_enraged_wildkin_tornado_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_enraged_wildkin_tornado_passive_debuff", "modifiers/creatures/modifier_enraged_wildkin_tornado_passive_debuff", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
require( "aghanim_utility_functions" )
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function enraged_wildwing_create_tornado:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/neutral_fx/tornado_ambient.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/enraged_wildkin/enraged_wildkin_tornado.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_aghsfort_creature_enraged_wildwing_tornado", context, -1 )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function enraged_wildwing_create_tornado:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 175, 175, 175 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 140, 0 ) )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function enraged_wildwing_create_tornado:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
--ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--function enraged_wildwing_create_tornado:GetChannelAnimation()
|
||||
-- return ACT_DOTA_CHANNEL_ABILITY_1
|
||||
--end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function enraged_wildwing_create_tornado:OnSpellStart()
|
||||
if IsServer() then
|
||||
|
||||
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
local vPos = self:GetCaster():GetAbsOrigin()
|
||||
for i=1,32 do
|
||||
local vLoc = FindPathablePositionNearby(self:GetCaster():GetAbsOrigin(), 400, 800 )
|
||||
|
||||
if GameRules.Aghanim:GetCurrentRoom():IsInRoomBounds( vLoc ) then
|
||||
vPos = vLoc
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local hTornado = CreateUnitByName( "npc_aghsfort_creature_enraged_wildwing_tornado", vPos, true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
hTornado:EmitSound( "n_creep_Wildkin.Tornado" )
|
||||
|
||||
local szAbilityName = "enraged_wildkin_tornado_passive"
|
||||
local hAbility = hTornado:FindAbilityByName(szAbilityName)
|
||||
if hAbility == nil then
|
||||
hAbility = hTornado:AddAbility(szAbilityName)
|
||||
end
|
||||
hAbility:UpgradeAbility( true )
|
||||
|
||||
|
||||
|
||||
--local kv = {
|
||||
-- movespeed_pct = self:GetSpecialValueFor( "movespeed_pct" ),
|
||||
-- damage = self:GetSpecialValueFor( "damage" ),
|
||||
--}
|
||||
--hTornado:AddNewModifier( self:GetCaster(), self, "modifier_enraged_wildkin_tornado_passive", kv )
|
||||
|
||||
--self.m_hTornado = hTornado
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
--
|
||||
--function enraged_wildwing_create_tornado:OnChannelFinish( bInterrupted )
|
||||
-- if IsServer() then
|
||||
-- if self.m_hTornado ~= nil then
|
||||
-- self.m_hTornado:StopSound( "n_creep_Wildkin.Tornado" )
|
||||
-- self.m_hTornado:RemoveModifierByName("modifier_enraged_wildkin_tornado_passive")
|
||||
-- self.m_hTornado:ForceKill( false )
|
||||
-- end
|
||||
-- ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
-- end
|
||||
--end
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
evil_greevil_passive = class({})
|
||||
LinkLuaModifier( "modifier_evil_greevil_passive", "modifiers/creatures/modifier_evil_greevil_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function evil_greevil_passive:GetIntrinsicModifierName()
|
||||
return "modifier_evil_greevil_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
friendly_ogreseal_flop = class({})
|
||||
LinkLuaModifier( "modifier_ogreseal_flop", "modifiers/creatures/modifier_ogreseal_flop", LUA_MODIFIER_MOTION_BOTH )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function friendly_ogreseal_flop:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre_seal/ogre_seal_warcry.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function friendly_ogreseal_flop:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function friendly_ogreseal_flop:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():StartGesture( ACT_DOTA_CAST_ABILITY_2 )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function friendly_ogreseal_flop:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveGesture( ACT_DOTA_CAST_ABILITY_2 )
|
||||
self:GetCaster():RemoveModifierByName( "modifier_techies_suicide_leap_animation" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function friendly_ogreseal_flop:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.stun_duration = self:GetSpecialValueFor("stun_duration")
|
||||
|
||||
local vToTarget = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
vToTarget = vToTarget:Normalized()
|
||||
local vLocation = self:GetCaster():GetOrigin() + vToTarget * 25
|
||||
local kv =
|
||||
{
|
||||
vLocX = vLocation.x,
|
||||
vLocY = vLocation.y,
|
||||
vLocZ = vLocation.z
|
||||
}
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_ogreseal_flop", kv )
|
||||
EmitSoundOn( "OgreTank.Grunt", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function friendly_ogreseal_flop:TryToDamage()
|
||||
if IsServer() then
|
||||
local radius = self:GetSpecialValueFor( "radius" )
|
||||
local damage = self:GetSpecialValueFor( "damage" )
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), self:GetCaster(), radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_NOT_ANCIENTS, 0, false )
|
||||
if #enemies > 0 then
|
||||
for _,enemy in pairs(enemies) do
|
||||
if enemy ~= nil and enemy:IsNull() == false and ( not enemy:IsMagicImmune() ) and ( not enemy:IsInvulnerable() ) then
|
||||
local DamageInfo =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
ability = self,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
}
|
||||
ApplyDamage( DamageInfo )
|
||||
if enemy:IsAlive() == false then
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, enemy, PATTACH_POINT_FOLLOW, "attach_hitloc", enemy:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, enemy:GetOrigin() )
|
||||
ParticleManager:SetParticleControlForward( nFXIndex, 1, -self:GetCaster():GetForwardVector() )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 10, enemy, PATTACH_ABSORIGIN_FOLLOW, nil, enemy:GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
EmitSoundOn( "Dungeon.BloodSplatterImpact", enemy )
|
||||
else
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_stunned", { duration = self.stun_duration } )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EmitSoundOnLocationWithCaster( self:GetCaster():GetOrigin(), "OgreTank.GroundSmash", self:GetCaster() )
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/ogre/ogre_melee_smash.vpcf", PATTACH_WORLDORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, self:GetCaster():GetOrigin() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( self.radius, self.radius, self.radius ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
GridNav:DestroyTreesAroundPoint( self:GetCaster():GetOrigin(), radius, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
76
aghanim_singleplayer/scripts/vscripts/abilities/creatures/hellbear_smash.lua
Executable file
76
aghanim_singleplayer/scripts/vscripts/abilities/creatures/hellbear_smash.lua
Executable file
@@ -0,0 +1,76 @@
|
||||
hellbear_smash = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function hellbear_smash:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/neutral_fx/ursa_thunderclap.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function hellbear_smash:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.radius = self:GetSpecialValueFor( "radius" )
|
||||
self.duration = self:GetSpecialValueFor( "duration" )
|
||||
self.damage = self:GetSpecialValueFor( "damage" )
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( radius, radius, radius ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 26, 26 ) )
|
||||
|
||||
EmitSoundOn( "n_creep_Ursa.Clap", self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function hellbear_smash:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function hellbear_smash:GetPlaybackRateOverride()
|
||||
return 0.5
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function hellbear_smash:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/neutral_fx/ursa_thunderclap.vpcf", PATTACH_ABSORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( self.radius, self.radius, self.radius ) )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 2, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_attack1", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
EmitSoundOn( "Hellbear.Smash", self:GetCaster() )
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), nil, self.radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
|
||||
for _,enemy in pairs( enemies ) do
|
||||
if enemy ~= nil and enemy:IsInvulnerable() == false then
|
||||
local damageInfo =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.damage,
|
||||
damage_type = DAMAGE_TYPE_MAGICAL,
|
||||
ability = self,
|
||||
}
|
||||
ApplyDamage( damageInfo )
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_polar_furbolg_ursa_warrior_thunder_clap", { duration = self.duration } )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
huge_brood_passive = class({})
|
||||
LinkLuaModifier( "modifier_huge_brood_passive", "modifiers/creatures/modifier_huge_brood_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function huge_brood_passive:GetIntrinsicModifierName()
|
||||
return "modifier_huge_brood_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,132 @@
|
||||
|
||||
huge_brood_summon_eggs = class({})
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function huge_brood_summon_eggs:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", context )
|
||||
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_broodmother_baby_d", context, -1 )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function huge_brood_summon_eggs:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 150, 150, 150 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 26, 26 ) )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function huge_brood_summon_eggs:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function huge_brood_summon_eggs:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
if self.hSummonedUnits == nil then
|
||||
self.hSummonedUnits = {}
|
||||
end
|
||||
|
||||
self.egg_spawns = self:GetSpecialValueFor( "egg_spawns" )
|
||||
self.spider_spawns = self:GetSpecialValueFor( "spider_spawns" )
|
||||
self.max_summoned_units = self:GetSpecialValueFor( "max_summoned_units" )
|
||||
self.summon_radius = self:GetSpecialValueFor( "summon_radius" )
|
||||
|
||||
EmitSoundOn( "Creature.Summon", self:GetCaster() )
|
||||
|
||||
for i = 1, self.egg_spawns do
|
||||
if #self.hSummonedUnits + 1 < self.max_summoned_units then
|
||||
local nMaxDistance = self.summon_radius
|
||||
local vSpawnLoc = nil
|
||||
|
||||
local nMaxAttempts = 5
|
||||
local nAttempts = 0
|
||||
|
||||
repeat
|
||||
if nAttempts > nMaxAttempts then
|
||||
vSpawnLoc = nil
|
||||
printf( "WARNING - huge_brood_summon_eggs - failed to find valid spawn loc for egg" )
|
||||
break
|
||||
end
|
||||
|
||||
local vPos = self:GetCaster():GetAbsOrigin() + RandomVector( nMaxDistance )
|
||||
vSpawnLoc = FindPathablePositionNearby( vPos, 0, 50 )
|
||||
nAttempts = nAttempts + 1
|
||||
until ( GameRules.Aghanim:GetCurrentRoom():IsInRoomBounds( vSpawnLoc ) )
|
||||
|
||||
if vSpawnLoc == nil then
|
||||
vSpawnLoc = self:GetCaster():GetAbsOrigin()
|
||||
end
|
||||
|
||||
local hEgg = CreateUnitByName( "npc_dota_spider_sac", vSpawnLoc, true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
if hEgg ~= nil then
|
||||
table.insert( self.hSummonedUnits, hEgg )
|
||||
--local vRandomOffset = Vector( RandomInt( -self.summon_radius, self.summon_radius ), RandomInt( -self.summon_radius, self.summon_radius ), 0 )
|
||||
--local vSpawnPoint = self:GetCaster():GetAbsOrigin() + vRandomOffset
|
||||
FindClearSpaceForUnit( hEgg, vSpawnLoc, true )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, vSpawnLoc )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, self.spider_spawns do
|
||||
if #self.hSummonedUnits + 1 < self.max_summoned_units then
|
||||
local nMaxDistance = self.summon_radius
|
||||
local vSpawnLoc = nil
|
||||
|
||||
local nMaxAttempts = 5
|
||||
local nAttempts = 0
|
||||
|
||||
repeat
|
||||
if nAttempts > nMaxAttempts then
|
||||
vSpawnLoc = nil
|
||||
printf( "WARNING - huge_brood_summon_eggs - failed to find valid spawn loc for spider" )
|
||||
break
|
||||
end
|
||||
|
||||
local vPos = self:GetCaster():GetAbsOrigin() + RandomVector( nMaxDistance )
|
||||
vSpawnLoc = FindPathablePositionNearby( vPos, 0, 50 )
|
||||
nAttempts = nAttempts + 1
|
||||
until ( GameRules.Aghanim:GetCurrentRoom():IsInRoomBounds( vSpawnLoc ) )
|
||||
|
||||
if vSpawnLoc == nil then
|
||||
vSpawnLoc = self:GetCaster():GetAbsOrigin()
|
||||
end
|
||||
|
||||
if vSpawnLoc ~= nil then
|
||||
local hSummonedSpider = CreateUnitByName( "npc_dota_creature_broodmother_baby_d", vSpawnLoc, true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
if hSummonedSpider ~= nil then
|
||||
table.insert( self.hSummonedUnits, hSummonedSpider )
|
||||
hSummonedSpider:SetInitialGoalEntity( self:GetCaster():GetInitialGoalEntity() )
|
||||
|
||||
--local vRandomOffset = Vector( RandomInt( -600, 600 ), RandomInt( -600, 600 ), 0 )
|
||||
--local vSpawnPoint = self:GetCaster():GetAbsOrigin() + vRandomOffset
|
||||
FindClearSpaceForUnit( hSummonedSpider, vSpawnLoc, true )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, vSpawnLoc )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
huge_broodmother_accrue_children = class({})
|
||||
LinkLuaModifier( "modifier_huge_broodmother_accrue_children", "modifiers/creatures/modifier_huge_broodmother_accrue_children", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_huge_broodmother_generate_children_thinker", "modifiers/creatures/modifier_huge_broodmother_generate_children_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function huge_broodmother_accrue_children:Precache( context )
|
||||
|
||||
PrecacheUnitByNameSync( "npc_dota_dummy_caster", context, -1 )
|
||||
PrecacheResource( "particle", "particles/baby_brood_venom_pool.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_broodmother_baby_d", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function huge_broodmother_accrue_children:GetIntrinsicModifierName()
|
||||
return "modifier_huge_broodmother_accrue_children"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
-- Note: this ability gets added by hand to the dummy unit that Broodmother creates.
|
||||
|
||||
huge_broodmother_generate_children = class({})
|
||||
LinkLuaModifier( "modifier_huge_broodmother_generate_children_thinker", "modifiers/creatures/modifier_huge_broodmother_generate_children_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function huge_broodmother_generate_children:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/baby_brood_venom_pool.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_broodmother_baby_d", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function huge_broodmother_generate_children:GetIntrinsicModifierName()
|
||||
return "modifier_huge_broodmother_generate_children_thinker"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
kidnap_spider_summon_eggs = class({})
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function kidnap_spider_summon_eggs:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", context )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function kidnap_spider_summon_eggs:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 150, 150, 150 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 26, 26 ) )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function kidnap_spider_summon_eggs:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function kidnap_spider_summon_eggs:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
if self.hSummonedUnits == nil then
|
||||
self.hSummonedUnits = {}
|
||||
end
|
||||
|
||||
self.egg_spawns = self:GetSpecialValueFor( "egg_spawns" )
|
||||
self.spider_spawns = self:GetSpecialValueFor( "spider_spawns" )
|
||||
self.max_summoned_units = self:GetSpecialValueFor( "max_summoned_units" )
|
||||
self.summon_radius = self:GetSpecialValueFor( "summon_radius" )
|
||||
|
||||
EmitSoundOn( "Creature.Summon", self:GetCaster() )
|
||||
|
||||
for i = 1, self.egg_spawns do
|
||||
if #self.hSummonedUnits + 1 < self.max_summoned_units then
|
||||
local nMaxDistance = self.summon_radius
|
||||
local vSpawnLoc = nil
|
||||
|
||||
local nMaxAttempts = 5
|
||||
local nAttempts = 0
|
||||
|
||||
repeat
|
||||
if nAttempts > nMaxAttempts then
|
||||
vSpawnLoc = nil
|
||||
printf( "WARNING - kidnap_spider_summon_eggs - failed to find valid spawn loc for egg" )
|
||||
break
|
||||
end
|
||||
|
||||
local vPos = self:GetCaster():GetAbsOrigin() + RandomVector( nMaxDistance )
|
||||
vSpawnLoc = FindPathablePositionNearby( vPos, 0, 50 )
|
||||
nAttempts = nAttempts + 1
|
||||
until ( GameRules.Aghanim:GetCurrentRoom():IsInRoomBounds( vSpawnLoc ) )
|
||||
|
||||
if vSpawnLoc == nil then
|
||||
vSpawnLoc = self:GetCaster():GetAbsOrigin()
|
||||
end
|
||||
|
||||
local hEgg = CreateUnitByName( "npc_dota_spider_sac", vSpawnLoc, true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
if hEgg ~= nil then
|
||||
table.insert( self.hSummonedUnits, hEgg )
|
||||
--local vRandomOffset = Vector( RandomInt( -self.summon_radius, self.summon_radius ), RandomInt( -self.summon_radius, self.summon_radius ), 0 )
|
||||
--local vSpawnPoint = self:GetCaster():GetAbsOrigin() + vRandomOffset
|
||||
FindClearSpaceForUnit( hEgg, vSpawnLoc, true )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, vSpawnLoc )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
kunkka_torrent_dm = class({})
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function kunkka_torrent_dm:OnSpellStart()
|
||||
if IsServer() then
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_kunkka_torrent_thinker", {}, self:GetCursorPosition(), self:GetCaster():GetTeamNumber(), false )
|
||||
if hThinker ~= nil then
|
||||
local hBuff = hThinker:FindModifierByName( "modifier_kunkka_torrent_thinker" )
|
||||
if hBuff ~= nil then
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_kunkka/kunkka_spell_torrent_bubbles.vpcf", PATTACH_ABSORIGIN, hThinker )
|
||||
hBuff:AddParticle( nFXIndex, false, false, -1, false, false )
|
||||
end
|
||||
|
||||
EmitSoundOn( "Ability.pre.Torrent", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
lifestealer_passive = class({})
|
||||
LinkLuaModifier( "modifier_lifestealer_passive", "modifiers/creatures/modifier_lifestealer_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_lifestealer_damage_counter", "modifiers/creatures/modifier_lifestealer_damage_counter", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_lifestealer_enraged", "modifiers/creatures/modifier_lifestealer_enraged", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function lifestealer_passive:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_life_stealer/life_stealer_rage.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_life_stealer_rage.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/lifestealer/lifestealer_damage_counter_overhead.vpcf", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function lifestealer_passive:GetIntrinsicModifierName()
|
||||
return "modifier_lifestealer_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
mini_spider_slow_attack = class({})
|
||||
LinkLuaModifier( "modifier_mini_spider_slow_attack", "modifiers/creatures/modifier_mini_spider_slow_attack", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_mini_spider_slow_attack_debuff", "modifiers/creatures/modifier_mini_spider_slow_attack_debuff", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
function mini_spider_slow_attack:GetIntrinsicModifierName()
|
||||
return "modifier_mini_spider_slow_attack"
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
24
aghanim_singleplayer/scripts/vscripts/abilities/creatures/mushroom_split.lua
Executable file
24
aghanim_singleplayer/scripts/vscripts/abilities/creatures/mushroom_split.lua
Executable file
@@ -0,0 +1,24 @@
|
||||
mushroom_split = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_rock_golem_split", "modifiers/creatures/modifier_rock_golem_split", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function mushroom_split:Precache( context )
|
||||
|
||||
self.strSplitFx = "particles/creature_splitter/splitter_a.vpcf"
|
||||
self.strSummonedUnit = "npc_dota_creature_shroomling"
|
||||
|
||||
PrecacheResource( "particle", self.strSplitFx, context )
|
||||
PrecacheUnitByNameSync( self.strSummonedUnit, context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function mushroom_split:GetIntrinsicModifierName()
|
||||
return "modifier_rock_golem_split"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
nyx_suicide_heal = class({})
|
||||
LinkLuaModifier( "modifier_nyx_suicide_heal", "modifiers/creatures/modifier_nyx_suicide_heal", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function nyx_suicide_heal:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/items3_fx/fish_bones_active.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/nyx_swarm_explosion/nyx_swarm_explosion.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
function nyx_suicide_heal:GetIntrinsicModifierName()
|
||||
return "modifier_nyx_suicide_heal"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
function nyx_suicide_heal:OnSpellStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():ForceKill( false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
ogre_magi_area_ignite = class ({})
|
||||
LinkLuaModifier( "modifier_ogre_magi_area_ignite_thinker", "modifiers/creatures/modifier_ogre_magi_area_ignite_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_magi_area_ignite:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite_cast.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/neutral_fx/black_dragon_fireball.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_burn.vpcf", context )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_magi_area_ignite:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_magi_area_ignite_thinker", { duration = -1 }, self:GetCursorPosition(), self:GetCaster():GetTeamNumber(), false )
|
||||
if self.hThinker ~= nil then
|
||||
local projectile =
|
||||
{
|
||||
Target = self.hThinker,
|
||||
Source = self:GetCaster(),
|
||||
Ability = self,
|
||||
EffectName = "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite.vpcf",
|
||||
iMoveSpeed = self:GetSpecialValueFor( "projectile_speed" ),
|
||||
vSourceLoc = self:GetCaster():GetOrigin(),
|
||||
bDodgeable = false,
|
||||
bProvidesVision = false,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateTrackingProjectile( projectile )
|
||||
EmitSoundOn( "OgreMagi.Ignite.Cast", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_magi_area_ignite:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if self.hThinker ~= nil then
|
||||
local hBuff = self.hThinker:FindModifierByName( "modifier_ogre_magi_area_ignite_thinker" )
|
||||
if hBuff ~= nil then
|
||||
hBuff:OnIntervalThink()
|
||||
end
|
||||
self.hThinker = nil;
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
ogre_magi_channelled_bloodlust = class({})
|
||||
LinkLuaModifier( "modifier_ogre_magi_channelled_bloodlust", "modifiers/creatures/modifier_ogre_magi_channelled_bloodlust", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ogre_magi_channelled_bloodlust:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_bloodlust_cast.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_bloodlust_buff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_pugna/pugna_life_drain.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_magi_channelled_bloodlust:OnSpellStart()
|
||||
if IsServer() then
|
||||
local hTarget = self:GetCursorTarget()
|
||||
if hTarget ~= nil then
|
||||
self.hTarget = hTarget
|
||||
self.hTarget:AddNewModifier( self:GetCaster(), self, "modifier_ogre_magi_channelled_bloodlust", { duration = -1 } )
|
||||
|
||||
EmitSoundOn( "OgreMagi.Bloodlust.Target", self.hTarget )
|
||||
EmitSoundOn( "OgreMagi.Bloodlust.Target.FP", self.hTarget )
|
||||
EmitSoundOn( "OgreMagi.Bloodlust.Loop", self:GetCaster() )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_ogre_magi/ogre_magi_bloodlust_cast.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_attack1", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 1, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 2, self.hTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", self.hTarget:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 3, self.hTarget, PATTACH_ABSORIGIN_FOLLOW, nil, self.hTarget:GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_magi_channelled_bloodlust:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
if bInterrupted then
|
||||
self:StartCooldown( self:GetSpecialValueFor( "interrupted_cooldown" ) )
|
||||
end
|
||||
|
||||
if self.hTarget ~= nil then
|
||||
local hMyBuff = self.hTarget:FindModifierByNameAndCaster( "modifier_ogre_magi_channelled_bloodlust", self:GetCaster() )
|
||||
if hMyBuff then
|
||||
hMyBuff:Destroy()
|
||||
end
|
||||
StopSoundOn( "OgreMagi.Bloodlust.Loop", self:GetCaster() )
|
||||
self.hTarget = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
ogre_seer_area_ignite = class ({})
|
||||
LinkLuaModifier( "modifier_ogre_seer_area_ignite_thinker", "modifiers/creatures/modifier_ogre_seer_area_ignite_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_seer_area_ignite:Precache( context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite_cast.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/neutral_fx/black_dragon_fireball.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_burn.vpcf", context )
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_seer_area_ignite:OnSpellStart()
|
||||
if IsServer() then
|
||||
local vTargetPositions = { }
|
||||
vTargetPositions[ 1 ] = self:GetCursorPosition()
|
||||
vTargetPositions[ 2 ] = self:GetCursorPosition() + RandomVector( RandomFloat( 250, 300 ) )
|
||||
vTargetPositions[ 3 ] = self:GetCursorPosition() + RandomVector( RandomFloat( 250, 300 ) )
|
||||
|
||||
self.hThinkers = { }
|
||||
|
||||
for i, vTargetPos in ipairs( vTargetPositions ) do
|
||||
self.hThinkers[ i ] = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_seer_area_ignite_thinker", { duration = -1 }, vTargetPos, self:GetCaster():GetTeamNumber(), false )
|
||||
if self.hThinkers[ i ] ~= nil then
|
||||
local projectile =
|
||||
{
|
||||
Target = self.hThinkers[ i ],
|
||||
Source = self:GetCaster(),
|
||||
Ability = self,
|
||||
EffectName = "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite.vpcf",
|
||||
iMoveSpeed = self:GetSpecialValueFor( "projectile_speed" ),
|
||||
vSourceLoc = self:GetCaster():GetOrigin(),
|
||||
bDodgeable = false,
|
||||
bProvidesVision = false,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateTrackingProjectile( projectile )
|
||||
EmitSoundOn( "OgreMagi.Ignite.Cast", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_seer_area_ignite:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
for i, hThinker in pairs( self.hThinkers ) do
|
||||
if hThinker ~= nil then
|
||||
local hBuff = hThinker:FindModifierByName( "modifier_ogre_seer_area_ignite_thinker" )
|
||||
if hBuff ~= nil then
|
||||
hBuff:OnIntervalThink()
|
||||
end
|
||||
hThinker = nil;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
ogre_tank_boss_jump_smash = class({})
|
||||
LinkLuaModifier( "modifier_ogre_tank_melee_smash_thinker", "modifiers/creatures/modifier_ogre_tank_melee_smash_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_jump_smash:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_jump_smash:GetPlaybackRateOverride()
|
||||
return 0.9 -- keep this proportional to jump_speed
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_jump_smash:OnSpellStart()
|
||||
if IsServer() then
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_tank_melee_smash_thinker", { duration = self:GetSpecialValueFor( "jump_speed") }, self:GetCaster():GetOrigin(), self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
ogre_tank_boss_melee_smash = class({})
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_melee_smash:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_melee_smash:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_melee_smash:GetCooldown( iLevel )
|
||||
return self.BaseClass.GetCooldown( self, self:GetLevel() ) / self:GetCaster():GetHasteFactor()
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_melee_smash:GetPlaybackRateOverride()
|
||||
return math.min( 2.0, math.max( self:GetCaster():GetHasteFactor(), 1.0 ) )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_boss_melee_smash:OnSpellStart()
|
||||
if IsServer() then
|
||||
EmitSoundOn( "OgreTank.Grunt", self:GetCaster() )
|
||||
local flSpeed = self:GetSpecialValueFor( "base_swing_speed" ) / self:GetPlaybackRateOverride()
|
||||
local vToTarget = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
vToTarget = vToTarget:Normalized()
|
||||
local vTarget = self:GetCaster():GetOrigin() + vToTarget * self:GetCastRange( self:GetCaster():GetOrigin(), nil )
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_tank_melee_smash_thinker", { duration = flSpeed }, vTarget, self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
ogre_tank_jump_smash = class({})
|
||||
LinkLuaModifier( "modifier_ogre_tank_melee_smash_thinker", "modifiers/creatures/modifier_ogre_tank_melee_smash_thinker", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_jump_smash:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_jump_smash:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_jump_smash:GetPlaybackRateOverride()
|
||||
return 0.75
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_jump_smash:OnSpellStart()
|
||||
if IsServer() then
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_tank_melee_smash_thinker", { duration = self:GetSpecialValueFor( "jump_speed") }, self:GetCaster():GetOrigin(), self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
ogre_tank_melee_smash = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_melee_smash:Precache( context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_melee_smash:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_melee_smash:GetCooldown( iLevel )
|
||||
return self.BaseClass.GetCooldown( self, self:GetLevel() ) / self:GetCaster():GetHasteFactor()
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_melee_smash:GetPlaybackRateOverride()
|
||||
return math.min( 2.0, math.max( self:GetCaster():GetHasteFactor(), 0.75 ) )
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function ogre_tank_melee_smash:OnSpellStart()
|
||||
if IsServer() then
|
||||
EmitSoundOn( "OgreTank.Grunt", self:GetCaster() )
|
||||
local flSpeed = self:GetSpecialValueFor( "base_swing_speed" ) / self:GetPlaybackRateOverride()
|
||||
local vToTarget = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
vToTarget = vToTarget:Normalized()
|
||||
local vTarget = self:GetCaster():GetOrigin() + vToTarget * self:GetCastRange( self:GetCaster():GetOrigin(), nil )
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_ogre_tank_melee_smash_thinker", { duration = flSpeed }, vTarget, self:GetCaster():GetTeamNumber(), false )
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
106
aghanim_singleplayer/scripts/vscripts/abilities/creatures/ogreseal_flop.lua
Executable file
106
aghanim_singleplayer/scripts/vscripts/abilities/creatures/ogreseal_flop.lua
Executable file
@@ -0,0 +1,106 @@
|
||||
|
||||
ogreseal_flop = class({})
|
||||
LinkLuaModifier( "modifier_ogreseal_flop", "modifiers/creatures/modifier_ogreseal_flop", LUA_MODIFIER_MOTION_BOTH )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ogreseal_flop:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre_seal/ogre_seal_warcry.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ogreseal_flop:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ogreseal_flop:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():StartGesture( ACT_DOTA_CAST_ABILITY_2 )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ogreseal_flop:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveGesture( ACT_DOTA_CAST_ABILITY_2 )
|
||||
self:GetCaster():RemoveModifierByName( "modifier_techies_suicide_leap_animation" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ogreseal_flop:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.stun_duration = self:GetSpecialValueFor("stun_duration")
|
||||
|
||||
local vToTarget = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
vToTarget = vToTarget:Normalized()
|
||||
local vLocation = self:GetCaster():GetOrigin() + vToTarget * 25
|
||||
local kv =
|
||||
{
|
||||
vLocX = vLocation.x,
|
||||
vLocY = vLocation.y,
|
||||
vLocZ = vLocation.z
|
||||
}
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_ogreseal_flop", kv )
|
||||
EmitSoundOn( "OgreTank.Grunt", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ogreseal_flop:TryToDamage()
|
||||
if IsServer() then
|
||||
local radius = self:GetSpecialValueFor( "radius" )
|
||||
local damage = self:GetSpecialValueFor( "damage" )
|
||||
local silence_duration = self:GetSpecialValueFor( "silence_duration" )
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), self:GetCaster():GetOrigin(), self:GetCaster(), radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_NOT_ANCIENTS, 0, false )
|
||||
if #enemies > 0 then
|
||||
for _,enemy in pairs(enemies) do
|
||||
if enemy ~= nil and enemy:IsNull() == false and ( not enemy:IsMagicImmune() ) and ( not enemy:IsInvulnerable() ) then
|
||||
local DamageInfo =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
ability = self,
|
||||
damage = damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
}
|
||||
ApplyDamage( DamageInfo )
|
||||
if enemy:IsAlive() == false then
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_phantom_assassin/phantom_assassin_crit_impact.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, enemy, PATTACH_POINT_FOLLOW, "attach_hitloc", enemy:GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, enemy:GetOrigin() )
|
||||
ParticleManager:SetParticleControlForward( nFXIndex, 1, -self:GetCaster():GetForwardVector() )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 10, enemy, PATTACH_ABSORIGIN_FOLLOW, nil, enemy:GetOrigin(), true )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
EmitSoundOn( "Dungeon.BloodSplatterImpact", enemy )
|
||||
else
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_stunned", { duration = self.stun_duration } )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EmitSoundOnLocationWithCaster( self:GetCaster():GetOrigin(), "OgreTank.GroundSmash", self:GetCaster() )
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/ogre/ogre_melee_smash.vpcf", PATTACH_WORLDORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, self:GetCaster():GetOrigin() )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, Vector( self.radius, self.radius, self.radius ) )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
|
||||
GridNav:DestroyTreesAroundPoint( self:GetCaster():GetOrigin(), radius, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,11 @@
|
||||
phoenix_passive = class( {} )
|
||||
|
||||
LinkLuaModifier( "modifier_phoenix_passive", "modifiers/creatures/modifier_phoenix_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function phoenix_passive:GetIntrinsicModifierName()
|
||||
return "modifier_phoenix_passive"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
preview_intrinsic = class({})
|
||||
LinkLuaModifier( "modifier_ability_cast_warning", "modifiers/modifier_ability_cast_warning", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function preview_intrinsic:GetIntrinsicModifierName()
|
||||
return "modifier_ability_cast_warning"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
puck_flying_bomb = class({})
|
||||
LinkLuaModifier( "modifier_puck_flying_bomb", "modifiers/creatures/modifier_puck_flying_bomb", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function puck_flying_bomb:Precache( context )
|
||||
PrecacheResource( "particle", "particles/test_particle/generic_attack_charge.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/puck/puck_flying_bomb.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/puck/puck_bomb_detonation.vpcf", context )
|
||||
--PrecacheResource( "particle", "particles/test_particle/omniknight_wildaxe.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_beastmaster/beastmaster_wildaxes_hit.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_beastmaster_axe", context, -1 )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function puck_flying_bomb:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/test_particle/generic_attack_charge.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_attack2", self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 135, 192, 235 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 16, Vector( 1, 0, 0 ) )
|
||||
ParticleManager:ReleaseParticleIndex( self.nPreviewFX )
|
||||
|
||||
EmitSoundOn( "TempleGuardian.PreAttack", self:GetCaster() )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function puck_flying_bomb:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, true )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function puck_flying_bomb:GetPlaybackRateOverride()
|
||||
return 0.75
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function puck_flying_bomb:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
local vLocation = self:GetCursorPosition()
|
||||
|
||||
local kv =
|
||||
{
|
||||
x = vLocation.x,
|
||||
y = vLocation.y,
|
||||
duration = self:GetSpecialValueFor( "flight_duration" ),
|
||||
}
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_puck_flying_bomb", kv )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,85 @@
|
||||
ranged_quill_attack = class({})
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function ranged_quill_attack:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/creatures/quill_beast/test_model_cluster_linear_projectile.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/neutral_fx/black_dragon_fireball.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_ogre_magi/ogre_magi_ignite_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/status_fx/status_effect_burn.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_bristleback/bristleback_quill_spray_impact.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ranged_quill_attack:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.attack_speed = self:GetSpecialValueFor( "attack_speed" )
|
||||
self.attack_width_initial = self:GetSpecialValueFor( "attack_width_initial" )
|
||||
self.attack_width_end = self:GetSpecialValueFor( "attack_width_end" )
|
||||
self.attack_distance = self:GetSpecialValueFor( "attack_distance" )
|
||||
self.attack_damage = self:GetSpecialValueFor( "attack_damage" )
|
||||
|
||||
local vPos = nil
|
||||
if self:GetCursorTarget() then
|
||||
vPos = self:GetCursorTarget():GetOrigin()
|
||||
else
|
||||
vPos = self:GetCursorPosition()
|
||||
end
|
||||
|
||||
local vDirection = vPos - self:GetCaster():GetOrigin()
|
||||
vDirection.z = 0.0
|
||||
vDirection = vDirection:Normalized()
|
||||
|
||||
self.attack_speed = self.attack_speed * ( self.attack_distance / ( self.attack_distance - self.attack_width_initial ) )
|
||||
|
||||
local info = {
|
||||
EffectName = "particles/creatures/quill_beast/test_model_cluster_linear_projectile.vpcf",
|
||||
Ability = self,
|
||||
vSpawnOrigin = self:GetCaster():GetOrigin(),
|
||||
fStartRadius = self.attack_width_initial,
|
||||
fEndRadius = self.attack_width_end,
|
||||
vVelocity = vDirection * self.attack_speed,
|
||||
fDistance = self.attack_distance,
|
||||
Source = self:GetCaster(),
|
||||
iUnitTargetTeam = DOTA_UNIT_TARGET_TEAM_ENEMY,
|
||||
iUnitTargetType = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_BUILDING,
|
||||
}
|
||||
|
||||
ProjectileManager:CreateLinearProjectile( info )
|
||||
EmitSoundOn( "Hound.QuillAttack.Cast", self:GetCaster() )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ranged_quill_attack:OnProjectileHit( hTarget, vLocation )
|
||||
if IsServer() then
|
||||
if hTarget ~= nil and ( not hTarget:IsMagicImmune() ) and ( not hTarget:IsInvulnerable() ) then
|
||||
local damage = {
|
||||
victim = hTarget,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self.attack_damage,
|
||||
damage_type = DAMAGE_TYPE_PHYSICAL,
|
||||
ability = self
|
||||
}
|
||||
|
||||
ApplyDamage( damage )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_bristleback/bristleback_quill_spray_impact.vpcf", PATTACH_CUSTOMORIGIN, hTarget );
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 0, hTarget, PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 1, hTarget, PATTACH_POINT_FOLLOW, "attach_hitloc", hTarget:GetOrigin(), true );
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 2, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, hTarget:GetOrigin(), true );
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex );
|
||||
|
||||
EmitSoundOn( "Hound.QuillAttack.Target", hTarget );
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,26 @@
|
||||
rock_golem_split_a = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_rock_golem_split", "modifiers/creatures/modifier_rock_golem_split", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function rock_golem_split_a:Precache( context )
|
||||
|
||||
self.strSplitFx = "particles/creature_splitter/splitter_a.vpcf"
|
||||
self.strSummonedUnit = "npc_dota_creature_rock_golem_b"
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_caustic_finale_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_caustic_finale_explode.vpcf", context )
|
||||
PrecacheResource( "particle", self.strSplitFx, context )
|
||||
PrecacheUnitByNameSync( self.strSummonedUnit, context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function rock_golem_split_a:GetIntrinsicModifierName()
|
||||
return "modifier_rock_golem_split"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
rock_golem_split_b = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_rock_golem_split", "modifiers/creatures/modifier_rock_golem_split", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function rock_golem_split_b:Precache( context )
|
||||
|
||||
self.strSplitFx = "particles/units/heroes/hero_life_stealer/life_stealer_infest_cast_mid.vpcf"
|
||||
self.strSummonedUnit = "npc_dota_creature_rock_golem_c"
|
||||
|
||||
PrecacheResource( "particle", self.strSplitFx, context )
|
||||
PrecacheUnitByNameSync( self.strSummonedUnit, context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function rock_golem_split_b:GetIntrinsicModifierName()
|
||||
return "modifier_rock_golem_split"
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
sand_king_boss_burrow = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_boss_burrow", "modifiers/creatures/modifier_sand_king_boss_burrow", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrow:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow_inground.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_huskar/huskar_inner_vitality.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_healing_burrower", context, -1 )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_big_exploding_burrower", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrow:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
EmitSoundOn( "Hero_NyxAssassin.Burrow.In", self:GetCaster() )
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, self:GetCaster():GetOrigin() )
|
||||
ParticleManager:SetParticleControlForward( nFXIndex, 0, self:GetCaster():GetForwardVector() )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrow:GetPlaybackRateOverride()
|
||||
return 0.75
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrow:OnSpellStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_boss_burrow", {} )
|
||||
self:GetCaster().nBurrowFXIndex = ParticleManager:CreateParticle( "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow_inground.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControl( self:GetCaster().nBurrowFXIndex, 0, self:GetCaster():GetOrigin() )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
sand_king_boss_burrowstrike = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_boss_burrowstrike", "modifiers/creatures/modifier_sand_king_boss_burrowstrike", LUA_MODIFIER_MOTION_HORIZONTAL )
|
||||
LinkLuaModifier( "modifier_sand_king_boss_burrowstrike_end", "modifiers/creatures/modifier_sand_king_boss_burrowstrike_end", LUA_MODIFIER_MOTION_HORIZONTAL )
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrowstrike:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/test_particle/sandking_burrowstrike_no_models.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow_inground.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_elder_titan/elder_titan_echo_stomp_physical.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_elder_titan/elder_titan_echo_stomp_impact_physical.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrowstrike:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrowstrike:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrowstrike:GetCastPoint()
|
||||
return 1.0625 - ( 0.53125 * ( 1 - ( self:GetCaster():GetHealthPercent() / 100 ) ) )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrowstrike:GetPlaybackRateOverride()
|
||||
return 0.3045 + ( 0.3045 * ( 1 - ( self:GetCaster():GetHealthPercent() / 100 ) ) )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_burrowstrike:OnSpellStart()
|
||||
if IsServer() then
|
||||
local vToTarget = self:GetCursorPosition() - self:GetCaster():GetOrigin()
|
||||
local flDist = RandomFloat( 1000.0, 2000.0 )
|
||||
local vDir = vToTarget:Normalized()
|
||||
vDir.z = 0.0
|
||||
|
||||
local vTarget = self:GetCaster():GetOrigin() + vDir * flDist
|
||||
|
||||
local flHealthPct = self:GetCaster():GetHealthPercent() / 100
|
||||
local kv =
|
||||
{
|
||||
x = vTarget.x,
|
||||
y = vTarget.y,
|
||||
z = vTarget.z,
|
||||
duration = flDist / ( self:GetSpecialValueFor( "speed" ) + ( self:GetSpecialValueFor( "scaling_speed" ) * ( 1 - flHealthPct ) ) )
|
||||
}
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_boss_burrowstrike", kv )
|
||||
EmitSoundOn( "SandKingBoss.BurrowStrike", self:GetCaster() )
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/test_particle/sandking_burrowstrike_no_models.vpcf", PATTACH_WORLDORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, self:GetCaster():GetOrigin() + self:GetCaster():GetForwardVector() * 225 )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, self:GetCaster():GetOrigin() + self:GetCaster():GetForwardVector() * 225 )
|
||||
ParticleManager:ReleaseParticleIndex( nFXIndex )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,170 @@
|
||||
|
||||
sand_king_boss_epicenter = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_boss_epicenter", "modifiers/creatures/modifier_sand_king_boss_epicenter", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_epicenter_tell.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/test_particle/dungeon_sand_king_channel.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/test_particle/dungeon_sand_king_blocker.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/test_particle/sand_king_projectile.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/units/heroes/hero_sandking/sandking_epicenter_tell.vpcf", PATTACH_CUSTOMORIGIN, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_POINT_FOLLOW, "attach_tail", self:GetCaster():GetOrigin(), true )
|
||||
EmitSoundOn( "SandKingBoss.Epicenter.spell", self:GetCaster() )
|
||||
self.nChannelFX = ParticleManager:CreateParticle( "particles/test_particle/dungeon_sand_king_channel.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:GetChannelAnimation()
|
||||
return ACT_DOTA_CAST_ABILITY_4
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:GetPlaybackRateOverride()
|
||||
return 1
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:OnSpellStart()
|
||||
if IsServer() then
|
||||
self.Projectiles = {}
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_boss_epicenter", {} )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_boss_epicenter" )
|
||||
ParticleManager:DestroyParticle( self.nChannelFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:OnProjectileThinkHandle( nProjectileHandle )
|
||||
if IsServer() then
|
||||
local projectile = nil
|
||||
for _,proj in pairs( self.Projectiles ) do
|
||||
if proj ~= nil and proj.handle == nProjectileHandle then
|
||||
projectile = proj
|
||||
end
|
||||
end
|
||||
if projectile ~= nil then
|
||||
local flRadius = ProjectileManager:GetLinearProjectileRadius( nProjectileHandle )
|
||||
ParticleManager:SetParticleControl( projectile.nFXIndex, 2, Vector( flRadius, flRadius, 0 ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_epicenter:OnProjectileHitHandle( hTarget, vLocation, nProjectileHandle )
|
||||
if IsServer() then
|
||||
if hTarget ~= nil then
|
||||
local blocker_radius = self:GetSpecialValueFor( "blocker_radius" )
|
||||
|
||||
|
||||
local vFromCaster = vLocation - self:GetCaster():GetOrigin()
|
||||
vFromCaster = vFromCaster:Normalized()
|
||||
local vToCasterPerp = Vector( -vFromCaster.y, vFromCaster.x, 0 )
|
||||
|
||||
local vLoc1 = vLocation + vFromCaster * 200
|
||||
local vLoc2 = vLocation + vFromCaster * 200 + vToCasterPerp * 65
|
||||
local vLoc3 = vLocation + vFromCaster * 200 + vToCasterPerp * -65
|
||||
|
||||
local hThinker = CreateModifierThinker( self:GetCaster(), self, "modifier_earthshaker_fissure", {}, vLoc1, self:GetCaster():GetTeamNumber(), true )
|
||||
local hThinker2 = CreateModifierThinker( self:GetCaster(), self, "modifier_earthshaker_fissure", {}, vLoc2, self:GetCaster():GetTeamNumber(), true )
|
||||
local hThinker3 = CreateModifierThinker( self:GetCaster(), self, "modifier_earthshaker_fissure", {}, vLoc3, self:GetCaster():GetTeamNumber(), true )
|
||||
if hThinker ~= nil then
|
||||
hThinker:SetHullRadius( 65 )
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/test_particle/dungeon_sand_king_blocker.vpcf", PATTACH_WORLDORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, vLoc1 )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, vLoc1 )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 2, Vector( 99999, 0, 0 ) )
|
||||
|
||||
end
|
||||
if hThinker2 ~= nil then
|
||||
hThinker2:SetHullRadius( 65 )
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/test_particle/dungeon_sand_king_blocker.vpcf", PATTACH_WORLDORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, vLoc2 )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, vLoc2 )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 2, Vector( 99999, 0, 0 ) )
|
||||
end
|
||||
if hThinker3 ~= nil then
|
||||
hThinker3:SetHullRadius( 65 )
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/test_particle/dungeon_sand_king_blocker.vpcf", PATTACH_WORLDORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, vLoc3 )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 1, vLoc3 )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 2, Vector( 99999, 0, 0 ) )
|
||||
end
|
||||
EmitSoundOn( "SandKingBoss.Epicenter.Impact", hTarget )
|
||||
|
||||
|
||||
local enemies = FindUnitsInRadius( self:GetCaster():GetTeamNumber(), hTarget:GetOrigin(), self:GetCaster(), blocker_radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, 0, false )
|
||||
for _,enemy in pairs( enemies ) do
|
||||
if enemy ~= nil and enemy:IsInvulnerable() == false and enemy:IsMagicImmune() == false then
|
||||
local kv =
|
||||
{
|
||||
center_x = hTarget:GetOrigin().x,
|
||||
center_y = hTarget:GetOrigin().y,
|
||||
center_z = hTarget:GetOrigin().z,
|
||||
should_stun = true,
|
||||
duration = 0.25,
|
||||
knockback_duration = 0.25,
|
||||
knockback_distance = 250,
|
||||
knockback_height = 125,
|
||||
}
|
||||
enemy:AddNewModifier( self:GetCaster(), self, "modifier_knockback", kv )
|
||||
local damageInfo =
|
||||
{
|
||||
victim = enemy,
|
||||
attacker = self:GetCaster(),
|
||||
damage = self:GetSpecialValueFor( "damage" ),
|
||||
damage_type = DAMAGE_TYPE_PURE,
|
||||
ability = self,
|
||||
}
|
||||
ApplyDamage( damageInfo )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local projectile = nil
|
||||
for _,proj in pairs( self.Projectiles ) do
|
||||
if proj ~= nil and proj.handle == nProjectileHandle then
|
||||
projectile = proj
|
||||
end
|
||||
end
|
||||
if projectile ~= nil then
|
||||
ParticleManager:DestroyParticle( projectile.nFXIndex, false )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
sand_king_boss_move_back = class({})
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_back:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
local flMin = self:GetSpecialValueFor( "minimum_duration" )
|
||||
local flMax = self:GetSpecialValueFor( "maximum_duration" )
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_boss_directional_move", { duration = RandomFloat( flMin, flMax ) } )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_back:GetPlaybackRateOverride()
|
||||
return 0.6
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_back:OnSpellStart()
|
||||
if IsServer() then
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
sand_king_boss_move_left = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_boss_directional_move", "modifiers/creatures/modifier_sand_king_boss_directional_move", LUA_MODIFIER_MOTION_HORIZONTAL )
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_left:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
local flMin = self:GetSpecialValueFor( "minimum_duration" )
|
||||
local flMax = self:GetSpecialValueFor( "maximum_duration" )
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_boss_directional_move", { duration = RandomFloat( flMin, flMax ) } )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_left:GetPlaybackRateOverride()
|
||||
return 1
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_left:OnSpellStart()
|
||||
if IsServer() then
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
sand_king_boss_move_right = class({})
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_right:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
local flMin = self:GetSpecialValueFor( "minimum_duration" )
|
||||
local flMax = self:GetSpecialValueFor( "maximum_duration" )
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_boss_directional_move", { duration = RandomFloat( flMin, flMax ) } )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_right:GetPlaybackRateOverride()
|
||||
return 1
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_move_right:OnSpellStart()
|
||||
if IsServer() then
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
sand_king_boss_passive = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_boss_passive", "modifiers/creatures/modifier_sand_king_boss_passive", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_passive:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_caustic_finale_debuff.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_caustic_finale_explode.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_passive:GetIntrinsicModifierName()
|
||||
return "modifier_sand_king_boss_passive"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,191 @@
|
||||
|
||||
sand_king_boss_sandstorm = class({})
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/dark_moon/darkmoon_creep_warning.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/test_particle/sand_king_cyclone.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_sand_king_sandstorm", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.nPreviewFX = ParticleManager:CreateParticle( "particles/dark_moon/darkmoon_creep_warning.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetCaster() )
|
||||
ParticleManager:SetParticleControlEnt( self.nPreviewFX, 0, self:GetCaster(), PATTACH_ABSORIGIN_FOLLOW, nil, self:GetCaster():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 1, Vector( 325, 325, 325 ) )
|
||||
ParticleManager:SetParticleControl( self.nPreviewFX, 15, Vector( 255, 140, 0 ) )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:GetChannelAnimation()
|
||||
return ACT_DOTA_OVERRIDE_ABILITY_2
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:GetPlaybackRateOverride()
|
||||
return 0.5
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:OnSpellStart()
|
||||
if IsServer() then
|
||||
ParticleManager:DestroyParticle( self.nPreviewFX, false )
|
||||
|
||||
self:GetCaster().bInSandStorm = true
|
||||
|
||||
if self.nCastCount == nil then
|
||||
self.nCastCount = 0
|
||||
else
|
||||
self.nCastCount = self.nCastCount + 1
|
||||
end
|
||||
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sandking_sand_storm", { duration = self:GetSpecialValueFor( "channel_time" ) } )
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sandking_sand_storm_invis", { duration = self:GetSpecialValueFor( "channel_time" ) } )
|
||||
self.storm_count_per_player = self:GetSpecialValueFor( "storm_count_per_player" )
|
||||
self.storm_angle_step = self:GetSpecialValueFor( "storm_angle_step" )
|
||||
self.storm_speed = self:GetSpecialValueFor( "storm_speed" ) + self:GetSpecialValueFor( "storm_speed_step" ) * self.nCastCount
|
||||
self.spiral_storm_count = self:GetSpecialValueFor( "spiral_storm_count" )
|
||||
|
||||
local bReverse = RandomInt( 0, 1 )
|
||||
if bReverse == 1 then
|
||||
self.storm_angle_step = self.storm_angle_step * -1
|
||||
end
|
||||
|
||||
self.Storms = {}
|
||||
|
||||
local angle = QAngle( 0, 0, 0 )
|
||||
|
||||
local Heroes = HeroList:GetAllHeroes()
|
||||
for _,Hero in pairs( Heroes ) do
|
||||
if Hero ~= nil then
|
||||
for i=1,self.storm_count_per_player do
|
||||
local hStorm = CreateUnitByName( "npc_dota_sand_king_sandstorm", self:GetCaster():GetAbsOrigin(), true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
if hStorm ~= nil then
|
||||
if self:GetCaster().zone ~= nil then
|
||||
self:GetCaster().zone:AddEnemyToZone( hStorm )
|
||||
end
|
||||
hStorm.hParent = self:GetCaster()
|
||||
|
||||
hStorm:AddNewModifier( Hero, nil, "modifier_provides_vision", {} )
|
||||
hStorm.nFXIndex = ParticleManager:CreateParticle( "particles/test_particle/sand_king_cyclone.vpcf", PATTACH_ABSORIGIN_FOLLOW, hStorm )
|
||||
|
||||
hStorm:SetForceAttackTarget( Hero )
|
||||
hStorm.Target = Hero
|
||||
hStorm.storm_speed = self.storm_speed
|
||||
local vSpawnPoint = Hero:GetOrigin() + RandomVector( 1 ) * 2000
|
||||
FindClearSpaceForUnit( hStorm, vSpawnPoint, true )
|
||||
|
||||
|
||||
|
||||
hStorm:AddNewModifier( hStorm, hStorm:FindAbilityByName( "sand_king_boss_sandstorm_storm_passive" ), "modifier_sand_king_boss_sandstorm", {} )
|
||||
|
||||
table.insert( self.Storms, hStorm )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i=1, self.spiral_storm_count do
|
||||
local hStorm = CreateUnitByName( "npc_dota_sand_king_sandstorm", self:GetCaster():GetAbsOrigin(), true, self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
if hStorm ~= nil then
|
||||
if self:GetCaster().zone ~= nil then
|
||||
self:GetCaster().zone:AddEnemyToZone( hStorm )
|
||||
end
|
||||
hStorm.hParent = self:GetCaster()
|
||||
|
||||
hStorm:AddNewModifier( Hero, nil, "modifier_provides_vision", {} )
|
||||
hStorm.nFXIndex = ParticleManager:CreateParticle( "particles/test_particle/sand_king_cyclone.vpcf", PATTACH_ABSORIGIN_FOLLOW, hStorm )
|
||||
local vSpawnPoint = self:GetCaster():GetOrigin()
|
||||
FindClearSpaceForUnit( hStorm, vSpawnPoint, true )
|
||||
|
||||
local info =
|
||||
{
|
||||
EffectName = "",
|
||||
Ability = self,
|
||||
vSpawnOrigin = vSpawnPoint,
|
||||
fDistance = 5000,
|
||||
fStartRadius = 50,
|
||||
fEndRadius = 50,
|
||||
Source = self:GetCaster(),
|
||||
}
|
||||
|
||||
info.vVelocity = ( RotatePosition( Vector( 0, 0, 0 ), angle, Vector( 1, 0, 0 ) ) ) * self.storm_speed
|
||||
|
||||
hStorm.nProjHandle = ProjectileManager:CreateLinearProjectile( info )
|
||||
hStorm.y = angle.y
|
||||
angle.y = angle.y + self.storm_angle_step
|
||||
|
||||
hStorm.flAngleUpdate = 3.0
|
||||
if bReverse then
|
||||
hStorm.flAngleUpdate = hStorm.flAngleUpdate * -1
|
||||
hStorm.bReverse = bReverse
|
||||
end
|
||||
hStorm:AddNewModifier( hStorm, hStorm:FindAbilityByName( "sand_king_boss_sandstorm_storm_passive" ), "modifier_sand_king_boss_sandstorm", {} )
|
||||
table.insert( self.Storms, hStorm )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:OnProjectileThinkHandle( iProjectileHandle )
|
||||
if IsServer() then
|
||||
if self:GetCaster() and self:GetCaster():IsChanneling() == false then
|
||||
return
|
||||
end
|
||||
|
||||
for _,Storm in pairs( self.Storms ) do
|
||||
if Storm ~= nil and Storm.nProjHandle == iProjectileHandle then
|
||||
Storm.y = Storm.y + Storm.flAngleUpdate
|
||||
if Storm.bReverse then
|
||||
Storm.flAngleUpdate = math.min( Storm.flAngleUpdate + 0.03, -1 )
|
||||
else
|
||||
Storm.flAngleUpdate = math.max( Storm.flAngleUpdate - 0.03, 1 )
|
||||
end
|
||||
|
||||
local angle = QAngle( 0, Storm.y, 0 )
|
||||
local vVelocity = ( RotatePosition( Vector( 0, 0, 0 ), angle, Vector( 1, 0, 0 ) ) ) * self.storm_speed
|
||||
ProjectileManager:UpdateLinearProjectileDirection( iProjectileHandle, vVelocity, 5000 )
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm:OnChannelFinish( bInterrupted )
|
||||
if IsServer() then
|
||||
for _,Storm in pairs( self.Storms ) do
|
||||
if Storm ~= nil then
|
||||
if Storm.nProjHandle ~= nil then
|
||||
ProjectileManager:DestroyLinearProjectile( Storm.nProjHandle )
|
||||
end
|
||||
|
||||
ParticleManager:DestroyParticle( Storm.nFXIndex, false )
|
||||
Storm:ForceKill( false )
|
||||
end
|
||||
end
|
||||
|
||||
self:GetCaster().bInSandStorm = false
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
sand_king_boss_sandstorm_storm_passive = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_boss_sandstorm", "modifiers/creatures/modifier_sand_king_boss_sandstorm", LUA_MODIFIER_MOTION_HORIZONTAL )
|
||||
LinkLuaModifier( "modifier_sand_king_boss_sandstorm_effect", "modifiers/creatures/modifier_sand_king_boss_sandstorm_effect", LUA_MODIFIER_MOTION_NONE )
|
||||
LinkLuaModifier( "modifier_sand_king_boss_sandstorm_blind", "modifiers/creatures/modifier_sand_king_boss_sandstorm_blind", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_sandstorm_storm_passive:GetIntrinsicModifierName()
|
||||
return "modifier_sand_king_boss_sandstorm"
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
sand_king_boss_unburrow = class({})
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_unburrow:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow_exit.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_huskar/huskar_inner_vitality.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_unburrow:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
if self:GetCaster().nBurrowFXIndex == nil then
|
||||
return true
|
||||
end
|
||||
ParticleManager:DestroyParticle( self:GetCaster().nBurrowFXIndex, false )
|
||||
|
||||
EmitSoundOn( "Hero_NyxAssassin.Burrow.Out", self:GetCaster() )
|
||||
local nFXIndex = ParticleManager:CreateParticle("particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow_exit.vpcf", PATTACH_CUSTOMORIGIN, nil )
|
||||
ParticleManager:SetParticleControl( nFXIndex, 0, self:GetCaster():GetOrigin() )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_unburrow:GetPlaybackRateOverride()
|
||||
return 0.5
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_boss_unburrow:OnSpellStart()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_boss_burrow" )
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
sand_king_burrowed_backward_strike = class({})
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_backward_strike:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_epicenter_tell.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_backward_strike:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.animation_time = self:GetSpecialValueFor( "animation_time" )
|
||||
self.initial_delay = self:GetSpecialValueFor( "initial_delay" )
|
||||
|
||||
local kv = {}
|
||||
kv["duration"] = self.animation_time
|
||||
kv["initial_delay"] = self.initial_delay
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_tail_swipe", kv )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_backward_strike:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_tail_swipe" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_backward_strike:GetPlaybackRateOverride()
|
||||
return 0.38
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_backward_strike:GetCastRange( vLocation, hTarget )
|
||||
if IsServer() then
|
||||
if self:GetCaster():FindModifierByName( "modifier_sand_king_tail_swipe" ) ~= nil then
|
||||
return 99999
|
||||
end
|
||||
end
|
||||
|
||||
return self.BaseClass.GetCastRange( self, vLocation, hTarget )
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
sand_king_burrowed_forward_strike = class({})
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_forward_strike:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_epicenter_tell.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_forward_strike:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.animation_time = self:GetSpecialValueFor( "animation_time" )
|
||||
self.initial_delay = self:GetSpecialValueFor( "initial_delay" )
|
||||
|
||||
local kv = {}
|
||||
kv["duration"] = self.animation_time
|
||||
kv["initial_delay"] = self.initial_delay
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_tail_swipe", kv )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_forward_strike:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_tail_swipe" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_forward_strike:GetPlaybackRateOverride()
|
||||
return 0.70
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_burrowed_forward_strike:GetCastRange( vLocation, hTarget )
|
||||
if IsServer() then
|
||||
if self:GetCaster():FindModifierByName( "modifier_sand_king_tail_swipe" ) ~= nil then
|
||||
return 99999
|
||||
end
|
||||
end
|
||||
|
||||
return self.BaseClass.GetCastRange( self, vLocation, hTarget )
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
sand_king_claw_attack = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_claw_attack", "modifiers/creatures/modifier_sand_king_claw_attack", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_claw_attack:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.animation_time = self:GetSpecialValueFor( "animation_time" )
|
||||
self.initial_delay = self:GetSpecialValueFor( "initial_delay" )
|
||||
|
||||
local kv = {}
|
||||
kv["duration"] = self.animation_time
|
||||
kv["initial_delay"] = self.initial_delay
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_claw_attack", kv )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_claw_attack:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_claw_attack" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_claw_attack:GetPlaybackRateOverride()
|
||||
return 0.6
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_claw_attack:GetCastRange( vLocation, hTarget )
|
||||
if IsServer() then
|
||||
if self:GetCaster():FindModifierByName( "modifier_sand_king_claw_attack" ) ~= nil then
|
||||
return 99999
|
||||
end
|
||||
end
|
||||
|
||||
return self.BaseClass.GetCastRange( self, vLocation, hTarget )
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
sand_king_tail_swipe_left = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_tail_swipe", "modifiers/creatures/modifier_sand_king_tail_swipe", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_epicenter_tell.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.animation_time = self:GetSpecialValueFor( "animation_time" )
|
||||
self.initial_delay = self:GetSpecialValueFor( "initial_delay" )
|
||||
|
||||
local kv = {}
|
||||
kv["duration"] = self.animation_time
|
||||
kv["initial_delay"] = self.initial_delay
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_tail_swipe", kv )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_tail_swipe" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:GetPlaybackRateOverride()
|
||||
return 0.75
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:GetCastRange( vLocation, hTarget )
|
||||
if IsServer() then
|
||||
if self:GetCaster():FindModifierByName( "modifier_sand_king_tail_swipe" ) ~= nil then
|
||||
return 99999
|
||||
end
|
||||
end
|
||||
|
||||
return self.BaseClass.GetCastRange( self, vLocation, hTarget )
|
||||
end
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
sand_king_tail_swipe_left = class({})
|
||||
LinkLuaModifier( "modifier_sand_king_tail_swipe", "modifiers/creatures/modifier_sand_king_tail_swipe", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_epicenter_tell.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.animation_time = self:GetSpecialValueFor( "animation_time" )
|
||||
self.initial_delay = self:GetSpecialValueFor( "initial_delay" )
|
||||
|
||||
local kv = {}
|
||||
kv["duration"] = self.animation_time
|
||||
kv["initial_delay"] = self.initial_delay
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_tail_swipe", kv )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_tail_swipe" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:GetPlaybackRateOverride()
|
||||
return 0.6
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_left:GetCastRange( vLocation, hTarget )
|
||||
if IsServer() then
|
||||
if self:GetCaster():FindModifierByName( "modifier_sand_king_tail_swipe" ) ~= nil then
|
||||
return 99999
|
||||
end
|
||||
end
|
||||
|
||||
return self.BaseClass.GetCastRange( self, vLocation, hTarget )
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
sand_king_tail_swipe_right = class({})
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_right:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_sandking/sandking_epicenter_tell.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/creatures/ogre/ogre_melee_smash.vpcf", context )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_right:OnAbilityPhaseStart()
|
||||
if IsServer() then
|
||||
self.animation_time = self:GetSpecialValueFor( "animation_time" )
|
||||
self.initial_delay = self:GetSpecialValueFor( "initial_delay" )
|
||||
|
||||
local kv = {}
|
||||
kv["duration"] = self.animation_time
|
||||
kv["initial_delay"] = self.initial_delay
|
||||
self:GetCaster():AddNewModifier( self:GetCaster(), self, "modifier_sand_king_tail_swipe", kv )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_right:OnAbilityPhaseInterrupted()
|
||||
if IsServer() then
|
||||
self:GetCaster():RemoveModifierByName( "modifier_sand_king_tail_swipe" )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_right:GetPlaybackRateOverride()
|
||||
return 0.6
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function sand_king_tail_swipe_right:GetCastRange( vLocation, hTarget )
|
||||
if IsServer() then
|
||||
if self:GetCaster():FindModifierByName( "modifier_sand_king_tail_swipe" ) ~= nil then
|
||||
return 99999
|
||||
end
|
||||
end
|
||||
|
||||
return self.BaseClass.GetCastRange( self, vLocation, hTarget )
|
||||
end
|
||||
@@ -0,0 +1,85 @@
|
||||
|
||||
scarab_priest_summon_zealots = class({})
|
||||
LinkLuaModifier( "modifier_scarab_priest_summon_mound", "modifiers/creatures/modifier_scarab_priest_summon_mound", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
function scarab_priest_summon_zealots:Precache( context )
|
||||
|
||||
PrecacheResource( "particle", "particles/themed_fx/tower_dragon_black_smokering.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_visage/visage_summon_familiars.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/nyx_swarm_explosion/nyx_swarm_explosion.vpcf", context )
|
||||
PrecacheResource( "particle", "particles/units/heroes/hero_nyx_assassin/nyx_assassin_burrow_exit.vpcf", context )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_zealot_mound", context, -1 )
|
||||
PrecacheUnitByNameSync( "npc_dota_creature_zealot_scarab", context, -1 )
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function scarab_priest_summon_zealots:ProcsMagicStick()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function scarab_priest_summon_zealots:OnSpellStart()
|
||||
if not IsServer() then
|
||||
return
|
||||
end
|
||||
|
||||
if self:GetCaster() == nil or self:GetCaster():IsNull() then
|
||||
return
|
||||
end
|
||||
|
||||
-- print( "scarab_priest_summon_zealots:OnSpellStart " )
|
||||
|
||||
local nSummonCount = self:GetSpecialValueFor( "spawn_count" )
|
||||
local flSpawnDistance = self:GetSpecialValueFor( "spawn_distance" )
|
||||
local flDuration = self:GetSpecialValueFor( "mound_duration" )
|
||||
local flDeltaAngle = 360 / nSummonCount
|
||||
local vAngles = QAngle( 0, math.random( 0, flDeltaAngle ), 0 )
|
||||
|
||||
for i = 1,nSummonCount do
|
||||
|
||||
local vSpawnPosition = nil
|
||||
for s = 1,36 do
|
||||
|
||||
local vDir = AnglesToVector( vAngles )
|
||||
local vTest = self:GetCaster():GetAbsOrigin() + vDir * flSpawnDistance + math.random( -25, 25 )
|
||||
|
||||
if GameRules.Aghanim:GetCurrentRoom():IsValidSpawnPoint( vTest ) then
|
||||
vSpawnPosition = vTest
|
||||
break
|
||||
end
|
||||
|
||||
vAngles.y = vAngles.y + 10
|
||||
|
||||
end
|
||||
|
||||
vAngles.y = vAngles.y + flDeltaAngle + math.random( -20, 20 )
|
||||
|
||||
if vSpawnPosition ~= nil then
|
||||
|
||||
EmitSoundOn( "Hero_NyxAssassin.Vendetta", self:GetCaster() )
|
||||
|
||||
local hMound = CreateUnitByName( "npc_dota_creature_zealot_mound", vSpawnPosition, true,
|
||||
self:GetCaster(), self:GetCaster(), self:GetCaster():GetTeamNumber() )
|
||||
|
||||
if hMound ~= nil then
|
||||
hMound:AddNewModifier( self:GetCaster(), self, "modifier_scarab_priest_summon_mound",
|
||||
{
|
||||
duration = flDuration,
|
||||
summoned_unit = "npc_dota_creature_zealot_scarab"
|
||||
} )
|
||||
hMound:AddNewModifier( self:GetCaster(), self, "modifier_provides_fow_position", { duration = -1 } )
|
||||
hMound:AddNewModifier( self:GetCaster(), self, "modifier_fixed_number_of_hits_to_kill", { duration = -1 } )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
skeleton_king_run_passive = class({})
|
||||
|
||||
LinkLuaModifier( "modifier_skeleton_king_boss_run", "modifiers/creatures/modifier_skeleton_king_boss_run", LUA_MODIFIER_MOTION_NONE )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function skeleton_king_run_passive:GetIntrinsicModifierName()
|
||||
return "modifier_skeleton_king_boss_run"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user