258 lines
8.0 KiB
Lua
Executable File
258 lines
8.0 KiB
Lua
Executable File
|
|
require( "aghanim_utility_functions" )
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
function Spawn( entityKeyValues )
|
|
if thisEntity == nil then
|
|
return
|
|
end
|
|
|
|
thisEntity.hSummonEggsAbility = thisEntity:FindAbilityByName( "kidnap_spider_summon_eggs" )
|
|
thisEntity.hLassoAbility = thisEntity:FindAbilityByName( "aghsfort_batrider_flaming_lasso" )
|
|
|
|
thisEntity:AddNewModifier( thisEntity, nil, "modifier_phased", { duration = -1 } )
|
|
|
|
thisEntity.vCurrentRunAwayPos = nil
|
|
thisEntity.nLassoDragDistance = thisEntity.hLassoAbility:GetSpecialValueFor( "drag_distance" )
|
|
|
|
thisEntity.hEntityKilledGameEvent = ListenToGameEvent( "entity_killed", Dynamic_Wrap( thisEntity:GetPrivateScriptScope(), "OnEntityKilled" ), nil )
|
|
|
|
thisEntity:SetContextThink( "KidnapSpiderThink", KidnapSpiderThink, 1 )
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
function UpdateOnRemove()
|
|
StopListeningToGameEvent( thisEntity.hEntityKilledGameEvent )
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
function KidnapSpiderThink()
|
|
if thisEntity == nil or thisEntity:IsNull() or ( not thisEntity:IsAlive() ) then
|
|
return -1
|
|
end
|
|
|
|
if GameRules:IsGamePaused() == true then
|
|
return 0.1
|
|
end
|
|
|
|
if not IsServer() then
|
|
return
|
|
end
|
|
|
|
-- This script was being broken by SetInitialGoalEntity in the encounter's OnSpawnerFinished
|
|
if not thisEntity.bGoalEntCleared then
|
|
thisEntity:SetInitialGoalEntity( nil )
|
|
thisEntity.bGoalEntCleared = true
|
|
end
|
|
|
|
local hEnemies = FindUnitsInRadius( thisEntity:GetTeamNumber(), thisEntity:GetOrigin(), nil, 5000,
|
|
DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_NONE, FIND_CLOSEST, false
|
|
)
|
|
|
|
if #hEnemies == 0 then
|
|
return 0.1
|
|
end
|
|
|
|
-- Summon Eggs
|
|
if thisEntity.hSummonEggsAbility and thisEntity.hSummonEggsAbility:IsFullyCastable() then
|
|
return CastSummonEggs()
|
|
end
|
|
|
|
-- Try to Lasso
|
|
if thisEntity.hLassoAbility and thisEntity.hLassoAbility:IsFullyCastable() then
|
|
for _, hEnemy in pairs( hEnemies ) do
|
|
if hEnemy ~= nil and hEnemy:IsRealHero() and hEnemy:IsAlive() and ( not hEnemy:HasModifier( "modifier_batrider_flaming_lasso" ) ) then
|
|
-- Ensure I have vision
|
|
local hVisionBuff = hEnemy:FindModifierByName( "modifier_provide_vision" )
|
|
if hVisionBuff == nil then
|
|
hVisionBuff = hEnemy:AddNewModifier( thisEntity, nil, "modifier_provide_vision", { duration = 15 } )
|
|
end
|
|
|
|
return CastLasso( hEnemy )
|
|
end
|
|
end
|
|
end
|
|
|
|
if thisEntity.vCurrentRunAwayPos ~= nil then
|
|
--printf( "Have I arrived?" )
|
|
local fDistToRunAwayPos = ( thisEntity.vCurrentRunAwayPos - thisEntity:GetAbsOrigin() ):Length2D()
|
|
--printf( "fDistToRunAwayPos: %d", fDistToRunAwayPos )
|
|
local nDistThreshold = 50
|
|
if fDistToRunAwayPos <= nDistThreshold then
|
|
--printf( "I've arrived close enough to current RunAway position: %s", thisEntity.vCurrentRunAwayPos )
|
|
thisEntity.vCurrentRunAwayPos = nil
|
|
return 3.0
|
|
else
|
|
--printf( "Have not arrived at current RunAway position of: %s", thisEntity.vCurrentRunAwayPos )
|
|
return 0.1
|
|
end
|
|
end
|
|
|
|
-- Find eggs at appropriate distances
|
|
local nMinEggDistance = 1400
|
|
local nMinEggFarDistance = 2800
|
|
local nMaxEggDistance = 4500
|
|
local hEggs = {}
|
|
local hFarEggs = {}
|
|
local hAllies = FindUnitsInRadius( thisEntity:GetTeamNumber(), thisEntity:GetOrigin(), nil, nMaxEggDistance,
|
|
DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_ALL, DOTA_UNIT_TARGET_FLAG_INVULNERABLE, FIND_FARTHEST, false
|
|
)
|
|
|
|
for _, hAlly in pairs( hAllies ) do
|
|
if hAlly:GetUnitName() == "npc_dota_spider_sac" then
|
|
--printf( "found \"npc_dota_spider_sac\" ally" )
|
|
local fDistToEgg = ( hAlly:GetOrigin() - thisEntity:GetOrigin() ):Length2D()
|
|
if fDistToEgg >= nMinEggFarDistance then
|
|
table.insert( hFarEggs, hAlly )
|
|
elseif fDistToEgg >= nMinEggDistance then
|
|
table.insert( hEggs, hAlly )
|
|
end
|
|
end
|
|
end
|
|
|
|
-- I can't cast Lasso, and whether I currently have a hero Lasso'd or not I want to run away
|
|
-- First try to find a good position using any distant eggs I found
|
|
local vRunTargetPos = nil
|
|
|
|
ShuffleListInPlace( hFarEggs )
|
|
|
|
if #hFarEggs > 0 then
|
|
--printf( "we have %d far egg candidates within %d-%d range", #hFarEggs, nMinEggDistance, nMaxEggDistance )
|
|
for _, hEgg in pairs( hFarEggs ) do
|
|
local vToEgg = hEgg:GetOrigin() - thisEntity:GetOrigin()
|
|
local fDistToEgg = vToEgg:Length2D()
|
|
vToEgg.z = 0.0
|
|
vToEgg = vToEgg:Normalized()
|
|
|
|
local nDistPastEgg = thisEntity.nLassoDragDistance
|
|
vRunTargetPos = thisEntity:GetAbsOrigin() + ( vToEgg * ( fDistToEgg + nDistPastEgg ) )
|
|
|
|
--printf( "evaluating far egg position's pathability" )
|
|
if GridNav:CanFindPath( thisEntity:GetOrigin(), vRunTargetPos ) then
|
|
--printf( "found valid far egg position, so break early -- %s", vRunTargetPos )
|
|
break
|
|
end
|
|
end
|
|
else
|
|
--printf( "no far egg candidates" )
|
|
end
|
|
|
|
-- If I didn't get a good distant egg position, look through any medium-range eggs
|
|
if vRunTargetPos == nil then
|
|
ShuffleListInPlace( hEggs )
|
|
|
|
if #hEggs > 0 then
|
|
--printf( "we have %d egg candidates within %d-%d range", #hEggs, nMinEggDistance, nMaxEggDistance )
|
|
for _, hEgg in pairs( hEggs ) do
|
|
local vToEgg = hEgg:GetOrigin() - thisEntity:GetOrigin()
|
|
local fDistToEgg = vToEgg:Length2D()
|
|
vToEgg.z = 0.0
|
|
vToEgg = vToEgg:Normalized()
|
|
|
|
local nDistPastEgg = thisEntity.nLassoDragDistance
|
|
vRunTargetPos = thisEntity:GetAbsOrigin() + ( vToEgg * ( fDistToEgg + nDistPastEgg ) )
|
|
|
|
--printf( "evaluating egg position's pathability" )
|
|
if GridNav:CanFindPath( thisEntity:GetOrigin(), vRunTargetPos ) then
|
|
--printf( "found valid egg position, so break early -- %s", vRunTargetPos )
|
|
break
|
|
end
|
|
end
|
|
else
|
|
--printf( "no medium distance egg candidates" )
|
|
end
|
|
end
|
|
|
|
-- If I didn't find any egg positions at all
|
|
if vRunTargetPos == nil then
|
|
vRunTargetPos = FindRandomPointInRoom( thisEntity:GetAbsOrigin(), 1500, 3000 )
|
|
--printf( "had no vRunTargetPos after all the egg searching, so trying random point in room: %s", vRunTargetPos )
|
|
end
|
|
|
|
if vRunTargetPos then
|
|
--printf( " going to position: %s", vRunTargetPos )
|
|
return RunAway( vRunTargetPos )
|
|
end
|
|
|
|
return 0.1
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
function CastSummonEggs()
|
|
ExecuteOrderFromTable({
|
|
UnitIndex = thisEntity:entindex(),
|
|
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
|
|
AbilityIndex = thisEntity.hSummonEggsAbility:entindex(),
|
|
Queue = false,
|
|
})
|
|
|
|
local fReturnTime = thisEntity.hSummonEggsAbility:GetCastPoint() + 0.2
|
|
return fReturnTime
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
function CastLasso( unit )
|
|
--printf( "kidnap_spider - CastLasso" )
|
|
|
|
ExecuteOrderFromTable({
|
|
UnitIndex = thisEntity:entindex(),
|
|
OrderType = DOTA_UNIT_ORDER_CAST_TARGET,
|
|
TargetIndex = unit:entindex(),
|
|
AbilityIndex = thisEntity.hLassoAbility:entindex(),
|
|
Queue = false,
|
|
})
|
|
|
|
thisEntity.vCurrentRunAwayPos = nil -- find a new destination
|
|
|
|
return thisEntity.hLassoAbility:GetCastPoint() + 0.2
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
function RunAway( vPos )
|
|
--printf( "kidnap_spider - RunAway" )
|
|
|
|
ExecuteOrderFromTable({
|
|
UnitIndex = thisEntity:entindex(),
|
|
OrderType = DOTA_UNIT_ORDER_MOVE_TO_POSITION,
|
|
Position = vPos,
|
|
Queue = true,
|
|
})
|
|
|
|
thisEntity.vCurrentRunAwayPos = vPos
|
|
|
|
return 1 --11
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
function OnEntityKilled( event )
|
|
local hVictim = nil
|
|
if event.entindex_killed ~= nil then
|
|
hVictim = EntIndexToHScript( event.entindex_killed )
|
|
end
|
|
|
|
if hVictim ~= thisEntity then
|
|
return
|
|
end
|
|
|
|
-- Cleanup
|
|
for nPlayerID = 0, ( AGHANIM_PLAYERS - 1 ) do
|
|
local hPlayerHero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
|
|
if hPlayerHero then
|
|
local hMyBuff = hPlayerHero:FindModifierByNameAndCaster( "modifier_provide_vision", thisEntity )
|
|
if hMyBuff then
|
|
hMyBuff:Destroy()
|
|
--printf( "kidnap_spider - OnEntityKilled: removing vision buff" )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|