// NextBotEventResponderInterface.h // Interface for propagating and responding to events // Author: Michael Booth, May 2006 //========= Copyright Valve Corporation, All rights reserved. ============// #ifndef _NEXT_BOT_EVENT_RESPONDER_INTERFACE_H_ #define _NEXT_BOT_EVENT_RESPONDER_INTERFACE_H_ class Path; class CTakeDamageInfo; class CBaseEntity; class CDOTABaseAbility; struct CSoundParameters; struct animevent_t; #include "ai_speech.h" //-------------------------------------------------------------------------------------------------------------------------- enum MoveToFailureType { FAIL_NO_PATH_EXISTS, FAIL_STUCK, FAIL_FELL_OFF, }; //-------------------------------------------------------------------------------------------------------------------------- /** * Events propagated to/between components. * To add an event, add its signature here and implement its propagation * to derived classes via FirstContainedResponder() and NextContainedResponder(). * NOTE: Also add a translator to the Action class in NextBotBehavior.h. */ class INextBotEventResponder { public: DECLARE_CLASS_NOBASE( INextBotEventResponder ); virtual ~INextBotEventResponder() { } // these methods are used by derived classes to define how events propagate virtual INextBotEventResponder *FirstContainedResponder( void ) const { return NULL; } virtual INextBotEventResponder *NextContainedResponder( INextBotEventResponder *current ) const { return NULL; } // // Events. All events must be 'extended' by calling the derived class explicitly to ensure propagation. // Each event must implement its propagation in this interface class. // virtual void OnLeaveGround( CBaseEntity *ground ); // invoked when bot leaves ground for any reason virtual void OnLandOnGround( CBaseEntity *ground ); // invoked when bot lands on the ground after being in the air virtual void OnContact( CBaseEntity *other, CGameTrace *result = NULL ); // invoked when bot touches 'other' virtual void OnMoveToSuccess( const Path *path ); // invoked when a bot reaches the end of the given Path virtual void OnMoveToFailure( const Path *path, MoveToFailureType reason ); // invoked when a bot fails to reach the end of the given Path virtual void OnStuck( void ); // invoked when bot becomes stuck while trying to move virtual void OnUnStuck( void ); // invoked when a previously stuck bot becomes un-stuck and can again move virtual void OnPostureChanged( void ); // when bot has assumed new posture (query IBody for posture) virtual void OnAnimationActivityComplete( int activity ); // when animation activity has finished playing virtual void OnAnimationActivityInterrupted( int activity );// when animation activity was replaced by another animation virtual void OnAnimationEvent( animevent_t *event ); // when a QC-file animation event is triggered by the current animation sequence virtual void OnIgnite( void ); // when bot starts to burn virtual void OnInjured( const CTakeDamageInfo &info ); // when bot is damaged by something virtual void OnKilled( const CTakeDamageInfo &info ); // when the bot's health reaches zero virtual void OnOtherKilled( CBaseCombatCharacter *victim, const CTakeDamageInfo &info ); // when someone else dies virtual void OnSight( CBaseEntity *subject ); // when subject initially enters bot's visual awareness virtual void OnLostSight( CBaseEntity *subject ); // when subject leaves enters bot's visual awareness virtual void OnSound( CBaseEntity *source, const Vector &pos, KeyValues *keys ); // when an entity emits a sound. "pos" is world coordinates of sound. "keys" are from sound's GameData virtual void OnSpokeConcept( CBaseCombatCharacter *who, AIConcept_t concept, AI_Response *response ); // when an Actor speaks a concept virtual void OnWeaponFired( CBaseCombatCharacter *whoFired, CBaseCombatWeapon *weapon ); // when someone fires a weapon virtual void OnNavAreaChanged( CNavArea *newArea, CNavArea *oldArea ); // when bot enters a new navigation area virtual void OnModelChanged( void ); // when the entity's model has been changed virtual void OnPickUp( CBaseEntity *item, CBaseCombatCharacter *giver ); // when something is added to our inventory virtual void OnDrop( CBaseEntity *item ); // when something is removed from our inventory virtual void OnActorEmoted( CBaseCombatCharacter *emoter, int emote ); // when "emoter" does an "emote" (ie: manual voice command, etc) virtual void OnCommandAttack( CBaseEntity *victim ); // attack the given entity virtual void OnCommandApproach( const Vector &pos, float range = 0.0f ); // move to within range of the given position virtual void OnCommandApproach( CBaseEntity *goal ); // follow the given leader virtual void OnCommandRetreat( CBaseEntity *threat, float range = 0.0f ); // retreat from the threat at least range units away (0 == infinite) virtual void OnCommandPause( float duration = 0.0f ); // pause for the given duration (0 == forever) virtual void OnCommandResume( void ); // resume after a pause virtual void OnCommandString( const char *command ); // for debugging: respond to an arbitrary string representing a generalized command virtual void OnShoved( CBaseEntity *pusher ); // 'pusher' has shoved me virtual void OnBlinded( CBaseEntity *blinder ); // 'blinder' has blinded me with a flash of light virtual void OnTerritoryContested( int territoryID ); // territory has been invaded and is changing ownership virtual void OnTerritoryCaptured( int territoryID ); // we have captured enemy territory virtual void OnTerritoryLost( int territoryID ); // we have lost territory to the enemy virtual void OnWin( void ); virtual void OnLose( void ); #ifdef DOTA_SERVER_DLL virtual void OnCommandMoveTo( const Vector &pos ); virtual void OnCommandMoveToAggressive( const Vector &pos ); virtual void OnCommandAttack( CBaseEntity *victim, bool bDeny ); virtual void OnCastAbilityNoTarget( CDOTABaseAbility *ability ); virtual void OnCastAbilityOnPosition( CDOTABaseAbility *ability, const Vector &pos ); virtual void OnCastAbilityOnTarget( CDOTABaseAbility *ability, CBaseEntity *target ); virtual void OnDropItem( const Vector &pos, CBaseEntity *item ); virtual void OnPickupItem( CBaseEntity *item ); virtual void OnPickupRune( CBaseEntity *item ); virtual void OnStop(); virtual void OnFriendThreatened( CBaseEntity *friendly, CBaseEntity *threat ); virtual void OnCancelAttack( CBaseEntity *pTarget ); virtual void OnDominated(); virtual void OnWarped( Vector vStartPos ); #endif }; inline void INextBotEventResponder::OnLeaveGround( CBaseEntity *ground ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnLeaveGround( ground ); } } inline void INextBotEventResponder::OnLandOnGround( CBaseEntity *ground ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnLandOnGround( ground ); } } inline void INextBotEventResponder::OnContact( CBaseEntity *other, CGameTrace *result ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnContact( other, result ); } } inline void INextBotEventResponder::OnMoveToSuccess( const Path *path ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnMoveToSuccess( path ); } } inline void INextBotEventResponder::OnMoveToFailure( const Path *path, MoveToFailureType reason ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnMoveToFailure( path, reason ); } } inline void INextBotEventResponder::OnStuck( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnStuck(); } } inline void INextBotEventResponder::OnUnStuck( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnUnStuck(); } } inline void INextBotEventResponder::OnPostureChanged( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnPostureChanged(); } } inline void INextBotEventResponder::OnAnimationActivityComplete( int activity ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnAnimationActivityComplete( activity ); } } inline void INextBotEventResponder::OnAnimationActivityInterrupted( int activity ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnAnimationActivityInterrupted( activity ); } } inline void INextBotEventResponder::OnAnimationEvent( animevent_t *event ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnAnimationEvent( event ); } } inline void INextBotEventResponder::OnIgnite( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnIgnite(); } } inline void INextBotEventResponder::OnInjured( const CTakeDamageInfo &info ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnInjured( info ); } } inline void INextBotEventResponder::OnKilled( const CTakeDamageInfo &info ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnKilled( info ); } } inline void INextBotEventResponder::OnOtherKilled( CBaseCombatCharacter *victim, const CTakeDamageInfo &info ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnOtherKilled( victim, info ); } } inline void INextBotEventResponder::OnSight( CBaseEntity *subject ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnSight( subject ); } } inline void INextBotEventResponder::OnLostSight( CBaseEntity *subject ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnLostSight( subject ); } } inline void INextBotEventResponder::OnSound( CBaseEntity *source, const Vector &pos, KeyValues *keys ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnSound( source, pos, keys ); } } inline void INextBotEventResponder::OnSpokeConcept( CBaseCombatCharacter *who, AIConcept_t concept, AI_Response *response ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnSpokeConcept( who, concept, response ); } } inline void INextBotEventResponder::OnWeaponFired( CBaseCombatCharacter *whoFired, CBaseCombatWeapon *weapon ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnWeaponFired( whoFired, weapon ); } } inline void INextBotEventResponder::OnNavAreaChanged( CNavArea *newArea, CNavArea *oldArea ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnNavAreaChanged( newArea, oldArea ); } } inline void INextBotEventResponder::OnModelChanged( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnModelChanged(); } } inline void INextBotEventResponder::OnPickUp( CBaseEntity *item, CBaseCombatCharacter *giver ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnPickUp( item, giver ); } } inline void INextBotEventResponder::OnDrop( CBaseEntity *item ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnDrop( item ); } } inline void INextBotEventResponder::OnActorEmoted( CBaseCombatCharacter *emoter, int emote ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnActorEmoted( emoter, emote ); } } inline void INextBotEventResponder::OnShoved( CBaseEntity *pusher ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnShoved( pusher ); } } inline void INextBotEventResponder::OnBlinded( CBaseEntity *blinder ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnBlinded( blinder ); } } inline void INextBotEventResponder::OnCommandAttack( CBaseEntity *victim ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandAttack( victim ); } } inline void INextBotEventResponder::OnCommandApproach( const Vector &pos, float range ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandApproach( pos, range ); } } inline void INextBotEventResponder::OnCommandApproach( CBaseEntity *goal ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandApproach( goal ); } } inline void INextBotEventResponder::OnCommandRetreat( CBaseEntity *threat, float range ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandRetreat( threat, range ); } } inline void INextBotEventResponder::OnCommandPause( float duration ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandPause( duration ); } } inline void INextBotEventResponder::OnCommandResume( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandResume(); } } inline void INextBotEventResponder::OnCommandString( const char *command ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandString( command ); } } inline void INextBotEventResponder::OnTerritoryContested( int territoryID ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnTerritoryContested( territoryID ); } } inline void INextBotEventResponder::OnTerritoryCaptured( int territoryID ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnTerritoryCaptured( territoryID ); } } inline void INextBotEventResponder::OnTerritoryLost( int territoryID ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnTerritoryLost( territoryID ); } } inline void INextBotEventResponder::OnWin( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnWin(); } } inline void INextBotEventResponder::OnLose( void ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnLose(); } } #ifdef DOTA_SERVER_DLL inline void INextBotEventResponder::OnCommandMoveTo( const Vector &pos ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandMoveTo( pos ); } } inline void INextBotEventResponder::OnCommandMoveToAggressive( const Vector &pos ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandMoveToAggressive( pos ); } } inline void INextBotEventResponder::OnCommandAttack( CBaseEntity *victim, bool bDeny ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCommandAttack( victim, bDeny ); } } inline void INextBotEventResponder::OnCastAbilityNoTarget( CDOTABaseAbility *ability ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCastAbilityNoTarget( ability ); } } inline void INextBotEventResponder::OnCastAbilityOnPosition( CDOTABaseAbility *ability, const Vector &pos ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCastAbilityOnPosition( ability, pos ); } } inline void INextBotEventResponder::OnCastAbilityOnTarget( CDOTABaseAbility *ability, CBaseEntity *target ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCastAbilityOnTarget( ability, target ); } } inline void INextBotEventResponder::OnDropItem( const Vector &pos, CBaseEntity *item ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnDropItem( pos, item ); } } inline void INextBotEventResponder::OnPickupItem( CBaseEntity *item ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnPickupItem( item ); } } inline void INextBotEventResponder::OnPickupRune( CBaseEntity *item ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnPickupRune( item ); } } inline void INextBotEventResponder::OnStop() { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnStop(); } } inline void INextBotEventResponder::OnFriendThreatened( CBaseEntity *friendly, CBaseEntity *threat ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnFriendThreatened( friendly, threat ); } } inline void INextBotEventResponder::OnCancelAttack( CBaseEntity *pTarget ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnCancelAttack( pTarget ); } } inline void INextBotEventResponder::OnDominated() { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnDominated(); } } inline void INextBotEventResponder::OnWarped( Vector vStartPos ) { for ( INextBotEventResponder *sub = FirstContainedResponder(); sub; sub = NextContainedResponder( sub ) ) { sub->OnWarped( vStartPos ); } } #endif #endif // _NEXT_BOT_EVENT_RESPONDER_INTERFACE_H_