diff options
Diffstat (limited to 'game/server/NextBot/simple_bot.cpp')
| -rw-r--r-- | game/server/NextBot/simple_bot.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/game/server/NextBot/simple_bot.cpp b/game/server/NextBot/simple_bot.cpp new file mode 100644 index 0000000..dbae239 --- /dev/null +++ b/game/server/NextBot/simple_bot.cpp @@ -0,0 +1,199 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// simple_bot.cpp +// A simple bot +// Michael Booth, February 2009 + +#include "cbase.h" +#include "simple_bot.h" +#include "nav_mesh.h" + + +//----------------------------------------------------------------------------------------------------- +// Command to add a Simple Bot where your crosshairs are aiming +//----------------------------------------------------------------------------------------------------- +CON_COMMAND_F( simple_bot_add, "Add a simple bot.", FCVAR_CHEAT ) +{ + CBasePlayer *player = UTIL_GetCommandClient(); + if ( !player ) + { + return; + } + + Vector forward; + player->EyeVectors( &forward ); + + trace_t result; + UTIL_TraceLine( player->EyePosition(), player->EyePosition() + 999999.9f * forward, MASK_BLOCKLOS_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE, player, COLLISION_GROUP_NONE, &result ); + if ( !result.DidHit() ) + { + return; + } + + CSimpleBot *bot = static_cast< CSimpleBot * >( CreateEntityByName( "simple_bot" ) ); + if ( bot ) + { + Vector forward = player->GetAbsOrigin() - result.endpos; + forward.z = 0.0f; + forward.NormalizeInPlace(); + + QAngle angles; + VectorAngles( forward, angles ); + + bot->SetAbsAngles( angles ); + bot->SetAbsOrigin( result.endpos + Vector( 0, 0, 10.0f ) ); + + DispatchSpawn( bot ); + } +} + + +//----------------------------------------------------------------------------------------------------- +// The Simple Bot +//----------------------------------------------------------------------------------------------------- +LINK_ENTITY_TO_CLASS( simple_bot, CSimpleBot ); + +#ifndef TF_DLL +PRECACHE_REGISTER( simple_bot ); +#endif + + +//----------------------------------------------------------------------------------------------------- +CSimpleBot::CSimpleBot() +{ + ALLOCATE_INTENTION_INTERFACE( CSimpleBot ); + + m_locomotor = new NextBotGroundLocomotion( this ); +} + + +//----------------------------------------------------------------------------------------------------- +CSimpleBot::~CSimpleBot() +{ + DEALLOCATE_INTENTION_INTERFACE; + + if ( m_locomotor ) + delete m_locomotor; +} + +//----------------------------------------------------------------------------------------------------- +void CSimpleBot::Precache() +{ + BaseClass::Precache(); + +#ifndef DOTA_DLL + PrecacheModel( "models/humans/group01/female_01.mdl" ); +#endif +} + + +//----------------------------------------------------------------------------------------------------- +void CSimpleBot::Spawn( void ) +{ + BaseClass::Spawn(); + +#ifndef DOTA_DLL + SetModel( "models/humans/group01/female_01.mdl" ); +#endif +} + + +//--------------------------------------------------------------------------------------------- +// The Simple Bot behaviors +//--------------------------------------------------------------------------------------------- +/** + * For use with TheNavMesh->ForAllAreas() + * Find the Nth area in the sequence + */ +class SelectNthAreaFunctor +{ +public: + SelectNthAreaFunctor( int count ) + { + m_count = count; + m_area = NULL; + } + + bool operator() ( CNavArea *area ) + { + m_area = area; + return ( m_count-- > 0 ); + } + + int m_count; + CNavArea *m_area; +}; + + +//--------------------------------------------------------------------------------------------- +/** + * This action causes the bot to pick a random nav area in the mesh and move to it, then + * pick another, etc. + * Actions usually each have their own .cpp/.h file and are organized into folders since there + * are often many of them. For this example, we're keeping everything to a single .cpp/.h file. + */ +class CSimpleBotRoam : public Action< CSimpleBot > +{ +public: + //---------------------------------------------------------------------------------- + // OnStart is called once when the Action first becomes active + virtual ActionResult< CSimpleBot > OnStart( CSimpleBot *me, Action< CSimpleBot > *priorAction ) + { + // smooth out the bot's path following by moving toward a point farther down the path + m_path.SetMinLookAheadDistance( 300.0f ); + + return Continue(); + } + + + //---------------------------------------------------------------------------------- + // Update is called repeatedly (usually once per server frame) while the Action is active + virtual ActionResult< CSimpleBot > Update( CSimpleBot *me, float interval ) + { + if ( m_path.IsValid() && !m_timer.IsElapsed() ) + { + // PathFollower::Update() moves the bot along the path using the bot's ILocomotion and IBody interfaces + m_path.Update( me ); + } + else + { + SelectNthAreaFunctor pick( RandomInt( 0, TheNavMesh->GetNavAreaCount() - 1 ) ); + TheNavMesh->ForAllAreas( pick ); + + if ( pick.m_area ) + { + CSimpleBotPathCost cost( me ); + m_path.Compute( me, pick.m_area->GetCenter(), cost ); + } + + // follow this path for a random duration (or until we reach the end) + m_timer.Start( RandomFloat( 5.0f, 10.0f ) ); + } + + return Continue(); + } + + + //---------------------------------------------------------------------------------- + // this is an event handler - many more are available (see declaration of Action< Actor > in NextBotBehavior.h) + virtual EventDesiredResult< CSimpleBot > OnStuck( CSimpleBot *me ) + { + // we are stuck trying to follow the current path - invalidate it so a new one is chosen + m_path.Invalidate(); + + return TryContinue(); + } + + + virtual const char *GetName( void ) const { return "Roam"; } // return name of this action + +private: + PathFollower m_path; + CountdownTimer m_timer; +}; + + +//--------------------------------------------------------------------------------------------- +/** + * Instantiate the bot's Intention interface and start the initial Action (CSimpleBotRoam in this case) + */ +IMPLEMENT_INTENTION_INTERFACE( CSimpleBot, CSimpleBotRoam ) |