initial commit
This commit is contained in:
206
aghanim_singleplayer/scripts/vscripts/ai/boss_base.lua
Executable file
206
aghanim_singleplayer/scripts/vscripts/ai/boss_base.lua
Executable file
@@ -0,0 +1,206 @@
|
||||
require( "ai/shared" )
|
||||
require( "ai/basic_spell_casting_ai" )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
if CBossBase == nil then
|
||||
CBossBase = class({})
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:constructor( hUnit, flInterval )
|
||||
self.me = hUnit
|
||||
self.flDefaultInterval = flInterval
|
||||
self.AbilityPriority = {}
|
||||
self.hPlayerHeroes = {}
|
||||
self.QueuedOrders = {}
|
||||
self.Encounter = nil
|
||||
self.bSeenAnyEnemy = false
|
||||
self.nLastHealthPct = 10000
|
||||
self.flInitialAcquireRange = 1800
|
||||
self.flAggroAcquireRange = 4500
|
||||
|
||||
self:SetupAbilitiesAndItems()
|
||||
|
||||
self.nAbilityListener = ListenToGameEvent( "dota_non_player_used_ability", Dynamic_Wrap( getclass( self ), 'OnNonPlayerUsedAbility' ), self )
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:SetupAbilitiesAndItems()
|
||||
--empty
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:SetEncounter( Encounter )
|
||||
self.Encounter = Encounter
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:OnBaseThink()
|
||||
if self.me == nil or self.me:IsNull() or self.me:IsAlive() == false then
|
||||
StopListeningToGameEvent( self.nAbilityListener )
|
||||
return -1
|
||||
end
|
||||
|
||||
Order = nil
|
||||
|
||||
if self.Encounter == nil or self.Encounter:HasStarted() == false then
|
||||
return 0.01
|
||||
end
|
||||
|
||||
if GameRules:IsGamePaused() then
|
||||
return 0.01
|
||||
end
|
||||
|
||||
local flRange = self.flInitialAcquireRange
|
||||
if self.bSeenAnyEnemy == true then
|
||||
flRange = self.flAggroAcquireRange
|
||||
end
|
||||
self.hPlayerHeroes = GetVisibleEnemyHeroesInRange( self.me, flRange )
|
||||
|
||||
if #self.hPlayerHeroes == 0 then
|
||||
goto autoattack
|
||||
elseif self.bSeenAnyEnemy == false then
|
||||
self.bSeenAnyEnemy = true
|
||||
self:OnFirstSeen()
|
||||
end
|
||||
|
||||
if self.nLastHealthPct > self.me:GetHealthPercent() then
|
||||
self.nLastHealthPct = self.me:GetHealthPercent()
|
||||
self:OnHealthPercentThreshold( self.nLastHealthPct )
|
||||
end
|
||||
|
||||
AbilitiesReady = self:GetReadyAbilitiesAndItems()
|
||||
if #AbilitiesReady == 0 then
|
||||
goto autoattack
|
||||
end
|
||||
|
||||
if #self.QueuedOrders > 0 then
|
||||
Order = self.QueuedOrders[ 1 ]
|
||||
table.remove( self.QueuedOrders, 1 )
|
||||
goto execute_order
|
||||
else
|
||||
for _,Ability in pairs ( AbilitiesReady ) do
|
||||
if Ability.Evaluate ~= nil then
|
||||
local TryOrder = Ability.Evaluate( self )
|
||||
if TryOrder ~= nil then
|
||||
Order = TryOrder
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
::autoattack::
|
||||
|
||||
NonAbilityOrder = nil
|
||||
if Order == nil then
|
||||
NonAbilityOrder = self:GetNonAbilityOrder()
|
||||
if NonAbilityOrder ~= nil then
|
||||
--print( 'NON ABILITY ORDER' )
|
||||
Order = NonAbilityOrder
|
||||
end
|
||||
end
|
||||
|
||||
if Order == nil and #self.hPlayerHeroes > 0 then
|
||||
--print( 'autoattack for ' .. self.flDefaultInterval )
|
||||
Order =
|
||||
{
|
||||
UnitIndex = self.me:entindex(),
|
||||
OrderType = DOTA_UNIT_ORDER_ATTACK_MOVE,
|
||||
Position = self.hPlayerHeroes[ 1 ]:GetAbsOrigin(),
|
||||
}
|
||||
Order.flOrderInterval = self.flDefaultInterval
|
||||
end
|
||||
|
||||
::execute_order::
|
||||
if Order then
|
||||
--print( 'Executing Order ' .. Order.OrderType .. ' and sleeping for ' .. Order.flOrderInterval )
|
||||
ExecuteOrderFromTable( Order )
|
||||
return Order.flOrderInterval
|
||||
end
|
||||
|
||||
::idle::
|
||||
return self.flDefaultInterval
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:GetReadyAbilitiesAndItems()
|
||||
local AbilitiesReady = {}
|
||||
for n=0,self.me:GetAbilityCount() - 1 do
|
||||
local hAbility = self.me:GetAbilityByIndex( n )
|
||||
if hAbility and hAbility:IsFullyCastable() and not hAbility:IsPassive() and not hAbility:IsHidden() and hAbility:IsActivated() then
|
||||
--print( 'Adding ABILITY ' .. hAbility:GetAbilityName() )
|
||||
if self.AbilityPriority[ hAbility:GetAbilityName() ] ~= nil then
|
||||
table.insert( AbilitiesReady, hAbility )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i = 0, DOTA_ITEM_MAX - 1 do
|
||||
local hItem = self.me:GetItemInSlot( i )
|
||||
if hItem and hItem:IsFullyCastable() and not hItem:IsPassive() and not hItem:IsHidden() and hItem:IsActivated() then
|
||||
--print( 'Adding ITEM ' .. hItem:GetAbilityName() )
|
||||
if self.AbilityPriority[ hItem:GetAbilityName() ] ~= nil then
|
||||
table.insert( AbilitiesReady, hItem )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if #AbilitiesReady > 1 then
|
||||
table.sort( AbilitiesReady, function( h1, h2 )
|
||||
local nAbility1Priority = self.AbilityPriority[ h1:GetAbilityName() ]
|
||||
local nAbility2Priority = self.AbilityPriority[ h2:GetAbilityName() ]
|
||||
return nAbility1Priority > nAbility2Priority
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
return AbilitiesReady
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:GetNonAbilityOrder()
|
||||
return nil
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:OnFirstSeen()
|
||||
-- empty
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:OnHealthPercentThreshold( nPct )
|
||||
-- empty
|
||||
end
|
||||
---------------------------------------------------------
|
||||
-- dota_non_player_used_ability
|
||||
-- * abilityname
|
||||
-- * caster_entindex
|
||||
---------------------------------------------------------
|
||||
function CBossBase:OnNonPlayerUsedAbility( event )
|
||||
|
||||
local hCaster = nil
|
||||
if event.caster_entindex ~= nil and event.abilityname ~= nil then
|
||||
hCaster = EntIndexToHScript( event.caster_entindex )
|
||||
if hCaster ~= nil and hCaster == self.me then
|
||||
self:OnBossUsedAbility( event.abilityname )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function CBossBase:OnBossUsedAbility( szAbilityName )
|
||||
-- empty
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user