|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "utlrbtree.h"
#include "saverestore_utlvector.h"
#include "ai_goalentity.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
//
// CAI_GoalEntity implementation
//
BEGIN_DATADESC( CAI_GoalEntity )
DEFINE_KEYFIELD( m_iszActor, FIELD_STRING, "Actor" ), DEFINE_KEYFIELD( m_iszGoal, FIELD_STRING, "Goal" ), DEFINE_KEYFIELD( m_fStartActive, FIELD_BOOLEAN, "StartActive" ), DEFINE_KEYFIELD( m_iszConceptModifiers, FIELD_STRING, "BaseConceptModifiers" ), DEFINE_KEYFIELD( m_SearchType, FIELD_INTEGER, "SearchType" ), DEFINE_UTLVECTOR( m_actors, FIELD_EHANDLE ), DEFINE_FIELD( m_hGoalEntity, FIELD_EHANDLE ), DEFINE_FIELD( m_flags, FIELD_INTEGER ),
DEFINE_THINKFUNC( DelayedRefresh ),
// Inputs
DEFINE_INPUTFUNC( FIELD_VOID, "Activate", InputActivate ), DEFINE_INPUTFUNC( FIELD_VOID, "UpdateActors", InputUpdateActors ), DEFINE_INPUTFUNC( FIELD_VOID, "Deactivate", InputDeactivate ),
END_DATADESC()
//-------------------------------------
void CAI_GoalEntity::Spawn() { SetContextThink( &CAI_GoalEntity::DelayedRefresh, gpGlobals->curtime + 0.1f, "Refresh" ); }
//-------------------------------------
void CAI_GoalEntity::OnRestore() { BaseClass::OnRestore();
ExitDormant();
if ( ( m_flags & ACTIVE ) ) gEntList.AddListenerEntity( this ); }
//-------------------------------------
void CAI_GoalEntity::DelayedRefresh() { inputdata_t ignored; if ( m_fStartActive ) { Assert( !(m_flags & ACTIVE) ); InputActivate( ignored ); m_fStartActive = false; } else InputUpdateActors( ignored ); SetContextThink( NULL, 0, "Refresh" ); }
//-------------------------------------
void CAI_GoalEntity::PruneActors() { for ( int i = m_actors.Count() - 1; i >= 0; i-- ) { if ( m_actors[i] == NULL || m_actors[i]->IsMarkedForDeletion() || m_actors[i]->GetState() == NPC_STATE_DEAD ) m_actors.FastRemove( i ); } }
//-------------------------------------
void CAI_GoalEntity::ResolveNames() { m_actors.SetCount( 0 ); CBaseEntity *pEntity = NULL; for (;;) { switch ( m_SearchType ) { case ST_ENTNAME: { pEntity = gEntList.FindEntityByName( pEntity, m_iszActor ); break; } case ST_CLASSNAME: { pEntity = gEntList.FindEntityByClassname( pEntity, STRING( m_iszActor ) ); break; } } if ( !pEntity ) break; CAI_BaseNPC *pActor = pEntity->MyNPCPointer(); if ( pActor && pActor->GetState() != NPC_STATE_DEAD ) { AIHANDLE temp; temp = pActor; m_actors.AddToTail( temp ); } } m_hGoalEntity = gEntList.FindEntityByName( NULL, m_iszGoal ); }
//-------------------------------------
void CAI_GoalEntity::InputActivate( inputdata_t &inputdata ) { if ( !( m_flags & ACTIVE ) ) { OnActivate();
gEntList.AddListenerEntity( this ); UpdateActors(); m_flags |= ACTIVE; for ( int i = 0; i < m_actors.Count(); i++ ) { EnableGoal( m_actors[i] ); } } }
//-------------------------------------
void CAI_GoalEntity::InputUpdateActors( inputdata_t &inputdata ) { int i; CUtlRBTree<CAI_BaseNPC *> prevActors; CUtlRBTree<CAI_BaseNPC *>::IndexType_t index;
SetDefLessFunc( prevActors ); PruneActors(); for ( i = 0; i < m_actors.Count(); i++ ) { prevActors.Insert( m_actors[i] ); } ResolveNames(); for ( i = 0; i < m_actors.Count(); i++ ) { index = prevActors.Find( m_actors[i] ); if ( index == prevActors.InvalidIndex() ) { if ( m_flags & ACTIVE ) EnableGoal( m_actors[i] ); } else prevActors.Remove( m_actors[i] ); } for ( index = prevActors.FirstInorder(); index != prevActors.InvalidIndex(); index = prevActors.NextInorder( index ) ) { if ( m_flags & ACTIVE ) DisableGoal( prevActors[ index ] ); } }
//-------------------------------------
void CAI_GoalEntity::InputDeactivate( inputdata_t &inputdata ) { if ( m_flags & ACTIVE ) { OnDeactivate();
gEntList.RemoveListenerEntity( this ); UpdateActors(); m_flags &= ~ACTIVE;
for ( int i = 0; i < m_actors.Count(); i++ ) { DisableGoal( m_actors[i] ); } } }
//-------------------------------------
void CAI_GoalEntity::EnterDormant( void ) { if ( m_flags & ACTIVE ) { m_flags |= DORMANT; for ( int i = 0; i < m_actors.Count(); i++ ) { DisableGoal( m_actors[i] ); } } }
//-------------------------------------
void CAI_GoalEntity::ExitDormant( void ) { if ( m_flags & DORMANT ) { m_flags &= ~DORMANT;
inputdata_t ignored; InputUpdateActors( ignored ); } }
//-------------------------------------
void CAI_GoalEntity::UpdateOnRemove() { if ( m_flags & ACTIVE ) { inputdata_t inputdata; InputDeactivate( inputdata ); } BaseClass::UpdateOnRemove(); }
//-------------------------------------
void CAI_GoalEntity::OnEntityCreated( CBaseEntity *pEntity ) { Assert( m_flags & ACTIVE ); if ( pEntity->MyNPCPointer() ) { SetContextThink( &CAI_GoalEntity::DelayedRefresh, gpGlobals->curtime + 0.1f, "Refresh" ); } }
//-------------------------------------
void CAI_GoalEntity::OnEntityDeleted( CBaseEntity *pEntity ) { Assert( pEntity != this ); }
//-----------------------------------------------------------------------------
int CAI_GoalEntity::DrawDebugTextOverlays() { char tempstr[512]; int offset = BaseClass::DrawDebugTextOverlays();
Q_snprintf( tempstr, sizeof(tempstr), "Active: %s", IsActive() ? "yes" : "no" ); EntityText( offset, tempstr, 0 ); offset++; return offset; }
|