Files
2HUCardTDGame/aghanim_singleplayer/scripts/vscripts/ai/kidnap_spider.lua
2021-10-24 15:36:18 -04:00

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
--------------------------------------------------------------------------------