mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-16 05:37:00 +00:00
1
This commit is contained in:
@@ -0,0 +1,656 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Bot radio chatter system
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
// Author: Michael S. Booth (mike@turtlerockstudios.com), 2003
|
||||
|
||||
#ifndef CS_BOT_CHATTER_H
|
||||
#define CS_BOT_CHATTER_H
|
||||
|
||||
#pragma warning( disable : 4786 ) // long STL names get truncated in browse info.
|
||||
|
||||
#include "nav_mesh.h"
|
||||
#include "cs_gamestate.h"
|
||||
|
||||
class CCSBot;
|
||||
class BotChatterInterface;
|
||||
|
||||
#define MAX_PLACES_PER_MAP 64
|
||||
|
||||
typedef unsigned int PlaceCriteria;
|
||||
|
||||
typedef unsigned int CountCriteria;
|
||||
#define UNDEFINED_COUNT 0xFFFF
|
||||
#define COUNT_CURRENT_ENEMIES 0xFF // use the number of enemies we see right when we speak
|
||||
#define COUNT_MANY 4 // equal to or greater than this is "many"
|
||||
|
||||
#define UNDEFINED_SUBJECT (-1)
|
||||
|
||||
/// @todo Make Place a class with member fuctions for this
|
||||
const Vector *GetRandomSpotAtPlace( Place place );
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* A meme is a unit information that bots use to
|
||||
* transmit information to each other via the radio
|
||||
*/
|
||||
class BotMeme
|
||||
{
|
||||
public:
|
||||
void Transmit( CCSBot *sender ) const; ///< transmit meme to other bots
|
||||
// It is a best practice to always have a virtual destructor in an interface
|
||||
// class. Otherwise if the derived classes have destructors they will not be
|
||||
// called.
|
||||
virtual ~BotMeme() {}
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const = 0; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotHelpMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
BotHelpMeme( Place place = UNDEFINED_PLACE )
|
||||
{
|
||||
m_place = place;
|
||||
}
|
||||
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
|
||||
private:
|
||||
Place m_place; ///< where the help is needed
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotBombsiteStatusMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
enum StatusType { CLEAR, PLANTED };
|
||||
|
||||
BotBombsiteStatusMeme( int zoneIndex, StatusType status )
|
||||
{
|
||||
m_zoneIndex = zoneIndex;
|
||||
m_status = status;
|
||||
}
|
||||
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
|
||||
private:
|
||||
int m_zoneIndex; ///< the bombsite
|
||||
StatusType m_status; ///< whether it is cleared or the bomb is there (planted)
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotBombStatusMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
BotBombStatusMeme( CSGameState::BombState state, const Vector &pos )
|
||||
{
|
||||
m_state = state;
|
||||
m_pos = pos;
|
||||
}
|
||||
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
|
||||
private:
|
||||
CSGameState::BombState m_state;
|
||||
Vector m_pos;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotFollowMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotDefendHereMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
BotDefendHereMeme( const Vector &pos )
|
||||
{
|
||||
m_pos = pos;
|
||||
}
|
||||
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
|
||||
private:
|
||||
Vector m_pos;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotWhereBombMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotRequestReportMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotAllHostagesGoneMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotHostageBeingTakenMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotHeardNoiseMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
class BotWarnSniperMeme : public BotMeme
|
||||
{
|
||||
public:
|
||||
virtual void Interpret( CCSBot *sender, CCSBot *receiver ) const; ///< cause the given bot to act on this meme
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
enum BotStatementType
|
||||
{
|
||||
REPORT_VISIBLE_ENEMIES,
|
||||
REPORT_ENEMY_ACTION,
|
||||
REPORT_MY_CURRENT_TASK,
|
||||
REPORT_MY_INTENTION,
|
||||
REPORT_CRITICAL_EVENT,
|
||||
REPORT_REQUEST_HELP,
|
||||
REPORT_REQUEST_INFORMATION,
|
||||
REPORT_ROUND_END,
|
||||
REPORT_MY_PLAN,
|
||||
REPORT_INFORMATION,
|
||||
REPORT_EMOTE,
|
||||
REPORT_ACKNOWLEDGE, ///< affirmative or negative
|
||||
REPORT_ENEMIES_REMAINING,
|
||||
REPORT_FRIENDLY_FIRE,
|
||||
REPORT_KILLED_FRIEND,
|
||||
REPORT_ENEMY_LOST,
|
||||
|
||||
NUM_BOT_STATEMENT_TYPES
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* BotSpeakables are the smallest unit of bot chatter.
|
||||
* They represent a specific wav file of a phrase, and the criteria for which it is useful
|
||||
*/
|
||||
class BotSpeakable
|
||||
{
|
||||
public:
|
||||
BotSpeakable();
|
||||
~BotSpeakable();
|
||||
char *m_phrase;
|
||||
float m_duration;
|
||||
PlaceCriteria m_place;
|
||||
CountCriteria m_count;
|
||||
};
|
||||
typedef CUtlVector< BotSpeakable * > BotSpeakableVector;
|
||||
typedef CUtlVector< BotSpeakableVector * > BotVoiceBankVector;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The BotPhrase class is a collection of Speakables associated with a name, ID, and criteria
|
||||
*/
|
||||
class BotPhrase
|
||||
{
|
||||
public:
|
||||
char *GetSpeakable( int bankIndex, float *duration = NULL ) const; ///< return a random speakable and its duration in seconds that meets the current criteria
|
||||
|
||||
// NOTE: Criteria must be set just before the GetSpeakable() call, since they are shared among all bots
|
||||
void ClearCriteria( void ) const;
|
||||
void SetPlaceCriteria( PlaceCriteria place ) const; ///< all returned phrases must have this place criteria
|
||||
void SetCountCriteria( CountCriteria count ) const; ///< all returned phrases must have this count criteria
|
||||
|
||||
const char *GetName( void ) const { return m_name; }
|
||||
const unsigned int GetPlace( void ) const { return m_place; }
|
||||
RadioType GetRadioEquivalent( void ) const { return m_radioEvent; } ///< return equivalent "standard radio" event
|
||||
bool IsImportant( void ) const { return m_isImportant; } ///< return true if this phrase is part of an important statement
|
||||
|
||||
bool IsPlace( void ) const { return m_isPlace; }
|
||||
|
||||
void Randomize( void ); ///< randomly shuffle the speakable order
|
||||
|
||||
private:
|
||||
friend class BotPhraseManager;
|
||||
BotPhrase( bool isPlace );
|
||||
~BotPhrase();
|
||||
|
||||
char *m_name;
|
||||
Place m_place;
|
||||
bool m_isPlace; ///< true if this is a Place phrase
|
||||
RadioType m_radioEvent; ///< equivalent radio event
|
||||
bool m_isImportant; ///< mission-critical statement
|
||||
|
||||
mutable BotVoiceBankVector m_voiceBank; ///< array of voice banks (arrays of speakables)
|
||||
CUtlVector< int > m_count; ///< number of speakables
|
||||
mutable CUtlVector< int > m_index; ///< index of next speakable to return
|
||||
int m_numVoiceBanks; ///< number of voice banks that have been initialized
|
||||
void InitVoiceBank( int bankIndex ); ///< sets up the vector of voice banks for the first bankIndex voice banks
|
||||
|
||||
mutable PlaceCriteria m_placeCriteria;
|
||||
mutable CountCriteria m_countCriteria;
|
||||
};
|
||||
typedef CUtlVector<BotPhrase *> BotPhraseList;
|
||||
|
||||
inline void BotPhrase::ClearCriteria( void ) const
|
||||
{
|
||||
m_placeCriteria = ANY_PLACE;
|
||||
m_countCriteria = UNDEFINED_COUNT;
|
||||
}
|
||||
|
||||
inline void BotPhrase::SetPlaceCriteria( PlaceCriteria place ) const
|
||||
{
|
||||
m_placeCriteria = place;
|
||||
}
|
||||
|
||||
inline void BotPhrase::SetCountCriteria( CountCriteria count ) const
|
||||
{
|
||||
m_countCriteria = count;
|
||||
}
|
||||
|
||||
enum BotChatterOutputType
|
||||
{
|
||||
BOT_CHATTER_RADIO,
|
||||
BOT_CHATTER_VOICE
|
||||
};
|
||||
typedef CUtlVector<BotChatterOutputType> BotOutputList;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The BotPhraseManager is a singleton that provides an interface to all BotPhrase collections
|
||||
*/
|
||||
class BotPhraseManager
|
||||
{
|
||||
public:
|
||||
BotPhraseManager( void );
|
||||
~BotPhraseManager();
|
||||
|
||||
bool Initialize( const char *filename, int bankIndex ); ///< initialize phrase system from database file for a specific voice bank (0 is the default voice bank)
|
||||
|
||||
void OnRoundRestart( void ); ///< invoked when round resets
|
||||
void OnMapChange( void ); ///< invoked when map changes
|
||||
void Reset( void );
|
||||
|
||||
const BotPhrase *GetPhrase( const char *name ) const; ///< given a name, return the associated phrase collection
|
||||
const BotPhrase *GetPainPhrase( void ) const { return m_painPhrase; } ///< optimization, replaces a static pointer to the phrase
|
||||
const BotPhrase *GetAgreeWithPlanPhrase( void ) const { return m_agreeWithPlanPhrase; } ///< optimization, replaces a static pointer to the phrase
|
||||
|
||||
const BotPhrase *GetPlace( const char *name ) const; ///< given a name, return the associated Place phrase collection
|
||||
const BotPhrase *GetPlace( unsigned int id ) const; ///< given an id, return the associated Place phrase collection
|
||||
|
||||
const BotPhraseList *GetPlaceList( void ) const { return &m_placeList; }
|
||||
|
||||
float GetPlaceStatementInterval( Place where ) const; ///< return time last statement of given type was emitted by a teammate for the given place
|
||||
void ResetPlaceStatementInterval( Place where ); ///< set time of last statement of given type was emitted by a teammate for the given place
|
||||
|
||||
BotChatterOutputType GetOutputType( int voiceBank ) const;
|
||||
|
||||
private:
|
||||
BotPhraseList m_list; ///< master list of all phrase collections
|
||||
BotPhraseList m_placeList; ///< master list of all Place phrases
|
||||
|
||||
BotOutputList m_output;
|
||||
|
||||
const BotPhrase *m_painPhrase;
|
||||
const BotPhrase *m_agreeWithPlanPhrase;
|
||||
|
||||
struct PlaceTimeInfo
|
||||
{
|
||||
Place placeID;
|
||||
IntervalTimer timer;
|
||||
};
|
||||
mutable PlaceTimeInfo m_placeStatementHistory[ MAX_PLACES_PER_MAP ];
|
||||
mutable int m_placeCount;
|
||||
int FindPlaceIndex( Place where ) const;
|
||||
};
|
||||
|
||||
inline int BotPhraseManager::FindPlaceIndex( Place where ) const
|
||||
{
|
||||
for( int i=0; i<m_placeCount; ++i )
|
||||
if (m_placeStatementHistory[i].placeID == where)
|
||||
return i;
|
||||
|
||||
// no such place - allocate it
|
||||
if (m_placeCount < MAX_PLACES_PER_MAP)
|
||||
{
|
||||
m_placeStatementHistory[ ++m_placeCount ].placeID = where;
|
||||
m_placeStatementHistory[ ++m_placeCount ].timer.Invalidate();
|
||||
return m_placeCount-1;
|
||||
}
|
||||
|
||||
// place directory is full
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return time last statement of given type was emitted by a teammate for the given place
|
||||
*/
|
||||
inline float BotPhraseManager::GetPlaceStatementInterval( Place place ) const
|
||||
{
|
||||
int index = FindPlaceIndex( place );
|
||||
|
||||
if (index < 0)
|
||||
return 999999.9f;
|
||||
|
||||
if (index >= m_placeCount)
|
||||
return 999999.9f;
|
||||
|
||||
return m_placeStatementHistory[ index ].timer.GetElapsedTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set time of last statement of given type was emitted by a teammate for the given place
|
||||
*/
|
||||
inline void BotPhraseManager::ResetPlaceStatementInterval( Place place )
|
||||
{
|
||||
int index = FindPlaceIndex( place );
|
||||
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (index >= m_placeCount)
|
||||
return;
|
||||
|
||||
// update entry
|
||||
m_placeStatementHistory[ index ].timer.Reset();
|
||||
}
|
||||
|
||||
extern BotPhraseManager *TheBotPhrases;
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* Statements are meaningful collections of phrases
|
||||
*/
|
||||
class BotStatement
|
||||
{
|
||||
public:
|
||||
BotStatement( BotChatterInterface *chatter, BotStatementType type, float expireDuration );
|
||||
~BotStatement();
|
||||
|
||||
BotChatterInterface *GetChatter( void ) const { return m_chatter; }
|
||||
CCSBot *GetOwner( void ) const;
|
||||
|
||||
BotStatementType GetType( void ) const { return m_type; } ///< return the type of statement this is
|
||||
bool IsImportant( void ) const; ///< return true if this statement is "important" and not personality chatter
|
||||
|
||||
bool HasSubject( void ) const { return (m_subject == UNDEFINED_SUBJECT) ? false : true; }
|
||||
void SetSubject( int playerID ) { m_subject = playerID; } ///< who this statement is about
|
||||
int GetSubject( void ) const { return m_subject; } ///< who this statement is about
|
||||
|
||||
bool HasPlace( void ) const { return (GetPlace()) ? true : false; }
|
||||
Place GetPlace( void ) const; ///< if this statement refers to a specific place, return that place
|
||||
void SetPlace( Place where ) { m_place = where; } ///< explicitly set place
|
||||
|
||||
bool HasCount( void ) const; ///< return true if this statement has an associated count
|
||||
|
||||
bool IsRedundant( const BotStatement *say ) const; ///< return true if this statement is the same as the given one
|
||||
bool IsObsolete( void ) const; ///< return true if this statement is no longer appropriate to say
|
||||
void Convert( const BotStatement *say ); ///< possibly change what were going to say base on what teammate is saying
|
||||
|
||||
void AppendPhrase( const BotPhrase *phrase );
|
||||
|
||||
void SetStartTime( float timestamp ) { m_startTime = timestamp; } ///< define the earliest time this statement can be spoken
|
||||
float GetStartTime( void ) const { return m_startTime; }
|
||||
|
||||
enum ConditionType
|
||||
{
|
||||
IS_IN_COMBAT,
|
||||
RADIO_SILENCE,
|
||||
ENEMIES_REMAINING,
|
||||
|
||||
NUM_CONDITIONS
|
||||
};
|
||||
|
||||
void AddCondition( ConditionType condition ); ///< conditions must be true for the statement to be spoken
|
||||
bool IsValid( void ) const; ///< verify all attached conditions
|
||||
|
||||
enum ContextType
|
||||
{
|
||||
CURRENT_ENEMY_COUNT,
|
||||
REMAINING_ENEMY_COUNT,
|
||||
SHORT_DELAY,
|
||||
LONG_DELAY,
|
||||
ACCUMULATE_ENEMIES_DELAY
|
||||
};
|
||||
void AppendPhrase( ContextType contextPhrase ); ///< special phrases that depend on the context
|
||||
|
||||
bool Update( void ); ///< emit statement over time, return false if statement is done
|
||||
bool IsSpeaking( void ) const { return m_isSpeaking; } ///< return true if this statement is currently being spoken
|
||||
float GetTimestamp( void ) const { return m_timestamp; } ///< get time statement was created (but not necessarily started talking)
|
||||
|
||||
void AttachMeme( BotMeme *meme ); ///< attach a meme to this statement, to be transmitted to other friendly bots when spoken
|
||||
|
||||
private:
|
||||
friend class BotChatterInterface;
|
||||
|
||||
BotChatterInterface *m_chatter; ///< the chatter system this statement is part of
|
||||
|
||||
BotStatement *m_next, *m_prev; ///< linked list hooks
|
||||
|
||||
BotStatementType m_type; ///< what kind of statement this is
|
||||
int m_subject; ///< who this subject is about
|
||||
Place m_place; ///< explicit place - note some phrases have implicit places as well
|
||||
BotMeme *m_meme; ///< a statement can only have a single meme for now
|
||||
|
||||
float m_timestamp; ///< time when message was created
|
||||
float m_startTime; ///< the earliest time this statement can be spoken
|
||||
float m_expireTime; ///< time when this statement is no longer valid
|
||||
float m_speakTimestamp; ///< time when message began being spoken
|
||||
bool m_isSpeaking; ///< true if this statement is current being spoken
|
||||
|
||||
float m_nextTime; ///< time for next phrase to begin
|
||||
|
||||
enum { MAX_BOT_PHRASES = 4 };
|
||||
struct
|
||||
{
|
||||
bool isPhrase;
|
||||
union
|
||||
{
|
||||
const BotPhrase *phrase;
|
||||
ContextType context;
|
||||
};
|
||||
}
|
||||
m_statement[ MAX_BOT_PHRASES ];
|
||||
|
||||
enum { MAX_BOT_CONDITIONS = 4 };
|
||||
ConditionType m_condition[ MAX_BOT_CONDITIONS ]; ///< conditions that must be true for the statement to be said
|
||||
int m_conditionCount;
|
||||
|
||||
int m_index; ///< m_index refers to the phrase currently being spoken, or -1 if we havent started yet
|
||||
int m_count;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* This class defines the interface to the bot radio chatter system
|
||||
*/
|
||||
class BotChatterInterface
|
||||
{
|
||||
public:
|
||||
BotChatterInterface( CCSBot *me );
|
||||
~BotChatterInterface( );
|
||||
|
||||
void Reset( void ); ///< reset to initial state
|
||||
void Update( void ); ///< process ongoing chatter
|
||||
|
||||
/// invoked when event occurs in the game (some events have NULL entities)
|
||||
void OnDeath( void ); ///< invoked when we die
|
||||
|
||||
enum VerbosityType
|
||||
{
|
||||
NORMAL, ///< full chatter
|
||||
MINIMAL, ///< only scenario-critical events
|
||||
RADIO, ///< use the standard radio instead
|
||||
OFF ///< no chatter at all
|
||||
};
|
||||
VerbosityType GetVerbosity( void ) const; ///< return our current level of verbosity
|
||||
|
||||
CCSBot *GetOwner( void ) const { return m_me; }
|
||||
|
||||
bool IsTalking( void ) const; ///< return true if we are currently talking
|
||||
float GetRadioSilenceDuration( void ); ///< return time since any teammate said anything
|
||||
void ResetRadioSilenceDuration( void );
|
||||
|
||||
enum { MUST_ADD = 1 };
|
||||
void AddStatement( BotStatement *statement, bool mustAdd = false ); ///< register a statement for speaking
|
||||
void RemoveStatement( BotStatement *statement ); ///< remove a statement
|
||||
|
||||
BotStatement *GetActiveStatement( void ); ///< returns the statement that is being spoken, or is next to be spoken if no-one is speaking now
|
||||
BotStatement *GetStatement( void ) const; ///< returns our current statement, or NULL if we aren't speaking
|
||||
|
||||
int GetPitch( void ) const { return m_pitch; }
|
||||
|
||||
|
||||
//-- things the bots can say ---------------------------------------------------------------------
|
||||
void Say( const char *phraseName, float lifetime = 3.0f, float delay = 0.0f );
|
||||
|
||||
void AnnouncePlan( const char *phraseName, Place where );
|
||||
void Affirmative( void );
|
||||
void Negative( void );
|
||||
|
||||
void EnemySpotted( void ); ///< report enemy sightings
|
||||
void KilledMyEnemy( int victimID );
|
||||
void EnemiesRemaining( void );
|
||||
|
||||
void SpottedSniper( void );
|
||||
void FriendSpottedSniper( void );
|
||||
|
||||
void Clear( Place where );
|
||||
|
||||
void ReportIn( void ); ///< ask for current situation
|
||||
void ReportingIn( void ); ///< report current situation
|
||||
|
||||
bool NeedBackup( void );
|
||||
void PinnedDown( void );
|
||||
void Scared( void );
|
||||
void HeardNoise( const Vector &pos );
|
||||
void FriendHeardNoise( void );
|
||||
|
||||
void TheyPickedUpTheBomb( void );
|
||||
void GoingToPlantTheBomb( Place where );
|
||||
void BombsiteClear( int zoneIndex );
|
||||
void FoundPlantedBomb( int zoneIndex );
|
||||
void PlantingTheBomb( Place where );
|
||||
void SpottedBomber( CBasePlayer *bomber );
|
||||
void SpottedLooseBomb( CBaseEntity *bomb );
|
||||
void GuardingLooseBomb( CBaseEntity *bomb );
|
||||
void RequestBombLocation( void );
|
||||
|
||||
#define IS_PLAN true
|
||||
void GuardingHostages( Place where, bool isPlan = false );
|
||||
void GuardingHostageEscapeZone( bool isPlan = false );
|
||||
void HostagesBeingTaken( void );
|
||||
void HostagesTaken( void );
|
||||
void TalkingToHostages( void );
|
||||
void EscortingHostages( void );
|
||||
void HostageDown( void );
|
||||
void GuardingBombsite( Place where );
|
||||
|
||||
void CelebrateWin( void );
|
||||
|
||||
void Encourage( const char *phraseName, float repeatInterval = 10.0f, float lifetime = 3.0f ); ///< "encourage" the player to do the scenario
|
||||
|
||||
void KilledFriend( void );
|
||||
void FriendlyFire( void );
|
||||
|
||||
bool SeesAtLeastOneEnemy( void ) const { return m_seeAtLeastOneEnemy; }
|
||||
|
||||
private:
|
||||
BotStatement *m_statementList; ///< list of all active/pending messages for this bot
|
||||
|
||||
void ReportEnemies( void ); ///< track nearby enemy count and generate enemy activity statements
|
||||
bool ShouldSpeak( void ) const; ///< return true if we speaking makes sense now
|
||||
|
||||
CCSBot *m_me; ///< the bot this chatter is for
|
||||
|
||||
bool m_seeAtLeastOneEnemy;
|
||||
float m_timeWhenSawFirstEnemy;
|
||||
bool m_reportedEnemies;
|
||||
bool m_requestedBombLocation; ///< true if we already asked where the bomb has been planted
|
||||
|
||||
int m_pitch;
|
||||
|
||||
static IntervalTimer m_radioSilenceInterval[ 2 ]; ///< one timer for each team
|
||||
|
||||
IntervalTimer m_needBackupInterval;
|
||||
IntervalTimer m_spottedBomberInterval;
|
||||
IntervalTimer m_scaredInterval;
|
||||
IntervalTimer m_planInterval;
|
||||
CountdownTimer m_spottedLooseBombTimer;
|
||||
CountdownTimer m_heardNoiseTimer;
|
||||
CountdownTimer m_escortingHostageTimer;
|
||||
CountdownTimer m_warnSniperTimer;
|
||||
static CountdownTimer m_encourageTimer; ///< timer to know when we can "encourage" the human player again - shared by all bots
|
||||
};
|
||||
|
||||
inline BotChatterInterface::VerbosityType BotChatterInterface::GetVerbosity( void ) const
|
||||
{
|
||||
const char *string = cv_bot_chatter.GetString();
|
||||
|
||||
if (string == NULL)
|
||||
return NORMAL;
|
||||
|
||||
if (string[0] == 'm' || string[0] == 'M')
|
||||
return MINIMAL;
|
||||
|
||||
if (string[0] == 'r' || string[0] == 'R')
|
||||
return RADIO;
|
||||
|
||||
if (string[0] == 'o' || string[0] == 'O')
|
||||
return OFF;
|
||||
|
||||
return NORMAL;
|
||||
}
|
||||
|
||||
|
||||
inline bool BotChatterInterface::IsTalking( void ) const
|
||||
{
|
||||
if (m_statementList)
|
||||
return m_statementList->IsSpeaking();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline BotStatement *BotChatterInterface::GetStatement( void ) const
|
||||
{
|
||||
return m_statementList;
|
||||
}
|
||||
|
||||
|
||||
inline void BotChatterInterface::Say( const char *phraseName, float lifetime, float delay )
|
||||
{
|
||||
BotStatement *say = new BotStatement( this, REPORT_MY_INTENTION, lifetime );
|
||||
|
||||
say->AppendPhrase( TheBotPhrases->GetPhrase( phraseName ) );
|
||||
|
||||
if (delay > 0.0f)
|
||||
say->SetStartTime( gpGlobals->curtime + delay );
|
||||
|
||||
AddStatement( say );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CS_BOT_CHATTER_H
|
||||
Reference in New Issue
Block a user