-
Notifications
You must be signed in to change notification settings - Fork 6
3. Installing: Base Modifications
The Bot system is prepared however it is necessary to make some modifications to the base code of your mod to implement the operation of the artificial intelligence.
Bots use the CAI_Senses class to view entities and listen for sounds, and this class inherits from CAI_Component that works only for NPCs (CAI_BaseNPC) so it is necessary to modify it so that it can work with characters (CBaseCombatCharacter)
If you have made modifications to the files:
- ai_senses.cpp
- ai_component.h
It is then recommended to apply the modifications on your own, otherwise you can use these versions:
Some of the functions that we have to modify are in ai_basenpc.h so open the file and replace from line 2703 to 2825 by the following (Diff):
inline const Vector &CAI_Component::GetLocalOrigin() const
{
return GetCharacter()->GetLocalOrigin();
}
//-----------------------------------------------------------------------------
inline void CAI_Component::SetLocalOrigin(const Vector &origin)
{
GetCharacter()->SetLocalOrigin(origin);
}
//-----------------------------------------------------------------------------
inline const Vector &CAI_Component::GetAbsOrigin() const
{
return GetCharacter()->GetAbsOrigin();
}
//-----------------------------------------------------------------------------
inline const QAngle &CAI_Component::GetAbsAngles() const
{
return GetCharacter()->GetAbsAngles();
}
//-----------------------------------------------------------------------------
inline void CAI_Component::SetSolid( SolidType_t val )
{
GetCharacter()->SetSolid(val);
}
//-----------------------------------------------------------------------------
inline SolidType_t CAI_Component::GetSolid() const
{
return GetCharacter()->GetSolid();
}
//-----------------------------------------------------------------------------
inline const Vector &CAI_Component::WorldAlignMins() const
{
return GetCharacter()->WorldAlignMins();
}
//-----------------------------------------------------------------------------
inline const Vector &CAI_Component::WorldAlignMaxs() const
{
return GetCharacter()->WorldAlignMaxs();
}
//-----------------------------------------------------------------------------
inline CAI_Component::CAI_Component( CAI_BaseNPC * pOuter )
{
if ( pOuter ) {
m_pOuter = pOuter->MyCombatCharacterPointer();
}
}
inline CAI_BaseNPC * CAI_Component::GetOuter()
{
if ( m_pOuter == NULL )
return NULL;
return m_pOuter->MyNPCPointer();
}
inline const CAI_BaseNPC * CAI_Component::GetOuter() const
{
if ( m_pOuter == NULL )
return NULL;
return m_pOuter->MyNPCPointer();
}
inline Hull_t CAI_Component::GetHullType() const
{
return GetOuter()->GetHullType();
}
//-----------------------------------------------------------------------------
inline Vector CAI_Component::WorldSpaceCenter() const
{
return GetCharacter()->WorldSpaceCenter();
}
//-----------------------------------------------------------------------------
inline float CAI_Component::GetGravity() const
{
return GetCharacter()->GetGravity();
}
//-----------------------------------------------------------------------------
inline void CAI_Component::SetGravity( float flGravity )
{
GetCharacter()->SetGravity( flGravity );
}
//-----------------------------------------------------------------------------
inline float CAI_Component::GetHullWidth() const
{
return NAI_Hull::Width( GetCharacter()->GetHullType());
}
//-----------------------------------------------------------------------------
inline float CAI_Component::GetHullHeight() const
{
return NAI_Hull::Height( GetCharacter()->GetHullType());
}
//-----------------------------------------------------------------------------
inline const Vector &CAI_Component::GetHullMins() const
{
return NAI_Hull::Mins( GetCharacter()->GetHullType());
}
//-----------------------------------------------------------------------------
inline const Vector &CAI_Component::GetHullMaxs() const
{
return NAI_Hull::Maxs( GetCharacter()->GetHullType());
}
//-----------------------------------------------------------------------------
inline int CAI_Component::GetCollisionGroup() const
{
return GetCharacter()->GetCollisionGroup();
}
//-----------------------------------------------------------------------------
inline CBaseEntity *CAI_Component::GetEnemy()
{
return GetCharacter()->GetEnemy();
}
Now you need to implement the necessary CAI_Senses functions in CBaseCombatCharacter, so open the file basecombatcharacter.h and in the first few lines write:
#include "soundent.h"
Now somewhere inside the CBaseCombatCharacter class paste the following code block:
//-----------------------------------------------------
//
// Senses
//
//-----------------------------------------------------
virtual void SetDistLook( float flDistLook ) { }
virtual bool QueryHearSound( CSound *pSound ) {
return true;
}
virtual bool QuerySeeEntity( CBaseEntity *pEntity, bool bOnlyHateOrFearIfNPC = false ) {
return true;
}
virtual void OnLooked( int iDistance ) { }
virtual void OnListened() { }
virtual void OnSeeEntity( CBaseEntity *pEntity ) { }
// If true, AI will try to see this entity regardless of distance.
virtual bool ShouldNotDistanceCull() {
return false;
}
virtual int GetSoundInterests( void ) {
return ALL_SOUNDS;
}
virtual int GetSoundPriority( CSound *pSound ) {
return 1;
}
CSound * GetLoudestSoundOfType( int iType ) {
return NULL;
}
virtual CSound * GetBestSound( int validTypes = ALL_SOUNDS ) {
return NULL;
}
virtual CSound * GetBestScent( void ) {
return NULL;
}
virtual float HearingSensitivity( void ) {
return 1.0;
}
virtual bool ShouldIgnoreSound( CSound * ) {
return false;
}
virtual bool SoundIsVisible( CSound *pSound ) {
return false;
}
virtual bool OnlySeeAliveEntities( void ) {
return true;
}
The file will look like this: https://gist.github.com/Kolesias/05fddf175d0dc55476a5fbe05658375e (Diff)
NOTE: If you have modified 'typedef CBasePlayer CPlayer;
' in bot_defs.h by your own player class then incorporate these functions into it.
Now you have to implement the functions that are required by the Bot system in CBasePlayer.
Open the file player.h and in the first lines write:
#include "ai_senses.h"
#include "soundent.h"
Approximately on line 235 you will find this:
private:
CBasePlayer *m_pParent;
};
class CBasePlayer : public CBaseCombatCharacter
Change it to:
public:
CBasePlayer *m_pParent;
};
class IBot;
class CSquad;
class CBasePlayer : public CBaseCombatCharacter
Now find:
IBotController *GetBotController() { return &m_PlayerInfo; }
Change it to:
virtual IBot *GetBotController() {
return NULL;
}
virtual void SetBotController( IBot *pBot ) { }
virtual void SetUpBot() { }
virtual CAI_Senses *GetSenses() {
return NULL;
}
virtual const CAI_Senses *GetSenses() const {
return NULL;
}
virtual CSound *GetBestSound( int validTypes = ALL_SOUNDS ) {
return NULL;
}
virtual CSound *GetBestScent( void ) {
return NULL;
}
// Squad
virtual CSquad *GetSquad() {
return NULL;
}
virtual void SetSquad( CSquad *pSquad ) { }
virtual void SetSquad( const char *name ) { }
virtual void OnNewLeader( CBasePlayer *pMember ) { }
virtual void OnMemberTakeDamage( CBasePlayer *pMember, const CTakeDamageInfo &info ) { }
virtual void OnMemberDeath( CBasePlayer *pMember, const CTakeDamageInfo &info ) { }
virtual void OnMemberReportEnemy( CBasePlayer *pMember, CBaseEntity *pEnemy ) { }
The file will look like this: https://gist.github.com/Kolesias/cdf7eb1a63226c3c22580d6abc3ee773 (Diff)
Functions are self-explanatory, but just in case:
GetBotController()
: To obtain the object that processes the Bot Artificial Intelligence.
SetBotController()
: Set the Artificial Intelligence that the Bot should use.
SetUpBot()
: It should be called when creating a Bot, this is where you have to create the type of Artificial Intelligence you want and set it with SetBotController
Open the file playerinfomanager.cpp and in line 102 you will find this:
return pPlayer->GetBotController();
Change it to:
return NULL;
Open the file util_shared.h and inside IntervalTimer Class put this function:
float GetStartTime() const
{
return m_timestamp;
}