diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/server/sdk/sdk_bot_temp.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/server/sdk/sdk_bot_temp.cpp')
| -rw-r--r-- | mp/src/game/server/sdk/sdk_bot_temp.cpp | 944 |
1 files changed, 472 insertions, 472 deletions
diff --git a/mp/src/game/server/sdk/sdk_bot_temp.cpp b/mp/src/game/server/sdk/sdk_bot_temp.cpp index e8990919..cfc57644 100644 --- a/mp/src/game/server/sdk/sdk_bot_temp.cpp +++ b/mp/src/game/server/sdk/sdk_bot_temp.cpp @@ -1,472 +1,472 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Basic BOT handling.
-//
-// $Workfile: $
-// $Date: $
-//
-//-----------------------------------------------------------------------------
-// $Log: $
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "player.h"
-#include "sdk_player.h"
-#include "in_buttons.h"
-#include "movehelper_server.h"
-#include "gameinterface.h"
-
-
-class CSDKBot;
-void Bot_Think( CSDKBot *pBot );
-
-
-ConVar bot_forcefireweapon( "bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
-ConVar bot_forceattack2( "bot_forceattack2", "0", 0, "When firing, use attack2." );
-ConVar bot_forceattackon( "bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
-ConVar bot_flipout( "bot_flipout", "0", 0, "When on, all bots fire their guns." );
-ConVar bot_changeclass( "bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
-static ConVar bot_mimic( "bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
-static ConVar bot_mimic_yaw_offset( "bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." );
-
-ConVar bot_sendcmd( "bot_sendcmd", "", 0, "Forces bots to send the specified command." );
-
-ConVar bot_crouch( "bot_crouch", "0", 0, "Bot crouches" );
-
-static int g_CurBotNumber = 1;
-
-
-// This is our bot class.
-class CSDKBot : public CSDKPlayer
-{
-public:
- bool m_bBackwards;
-
- float m_flNextTurnTime;
- bool m_bLastTurnToRight;
-
- float m_flNextStrafeTime;
- float m_flSideMove;
-
- QAngle m_ForwardAngle;
- QAngle m_LastAngles;
-};
-
-LINK_ENTITY_TO_CLASS( sdk_bot, CSDKBot );
-
-class CBotManager
-{
-public:
- static CBasePlayer* ClientPutInServerOverride_Bot( edict_t *pEdict, const char *playername )
- {
- // This tells it which edict to use rather than creating a new one.
- CBasePlayer::s_PlayerEdict = pEdict;
-
- CSDKBot *pPlayer = static_cast<CSDKBot *>( CreateEntityByName( "sdk_bot" ) );
- if ( pPlayer )
- {
- pPlayer->SetPlayerName( playername );
- }
-
- return pPlayer;
- }
-};
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Create a new Bot and put it in the game.
-// Output : Pointer to the new Bot, or NULL if there's no free clients.
-//-----------------------------------------------------------------------------
-CBasePlayer *BotPutInServer( bool bFrozen )
-{
- char botname[ 64 ];
- Q_snprintf( botname, sizeof( botname ), "Bot%02i", g_CurBotNumber );
-
-
- // This trick lets us create a CSDKBot for this client instead of the CSDKPlayer
- // that we would normally get when ClientPutInServer is called.
- ClientPutInServerOverride( &CBotManager::ClientPutInServerOverride_Bot );
- edict_t *pEdict = engine->CreateFakeClient( botname );
- ClientPutInServerOverride( NULL );
-
- if (!pEdict)
- {
- Msg( "Failed to create Bot.\n");
- return NULL;
- }
-
- // Allocate a player entity for the bot, and call spawn
- CSDKBot *pPlayer = ((CSDKBot*)CBaseEntity::Instance( pEdict ));
-
- pPlayer->ClearFlags();
- pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT );
-
- if ( bFrozen )
- pPlayer->AddEFlags( EFL_BOT_FROZEN );
-
- pPlayer->ChangeTeam( TEAM_UNASSIGNED );
- pPlayer->RemoveAllItems( true );
- pPlayer->Spawn();
-
- g_CurBotNumber++;
-
- return pPlayer;
-}
-
-// Handler for the "bot" command.
-CON_COMMAND_F( "bot_add", "Add a bot.", FCVAR_CHEAT )
-{
- // Look at -count.
- int count = args.FindArgInt( "-count", 1 );
- count = clamp( count, 1, 16 );
-
- // Look at -frozen.
- bool bFrozen = !!args.FindArg( "-frozen" );
-
- // Ok, spawn all the bots.
- while ( --count >= 0 )
- {
- BotPutInServer( bFrozen );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Run through all the Bots in the game and let them think.
-//-----------------------------------------------------------------------------
-void Bot_RunAll( void )
-{
- for ( int i = 1; i <= gpGlobals->maxClients; i++ )
- {
- CSDKPlayer *pPlayer = ToSDKPlayer( UTIL_PlayerByIndex( i ) );
-
- if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
- {
- CSDKBot *pBot = dynamic_cast< CSDKBot* >( pPlayer );
- if ( pBot )
- Bot_Think( pBot );
- }
- }
-}
-
-bool Bot_RunMimicCommand( CUserCmd& cmd )
-{
- if ( bot_mimic.GetInt() <= 0 )
- return false;
-
- if ( bot_mimic.GetInt() > gpGlobals->maxClients )
- return false;
-
-
- CBasePlayer *pPlayer = UTIL_PlayerByIndex( bot_mimic.GetInt() );
- if ( !pPlayer )
- return false;
-
- if ( !pPlayer->GetLastUserCommand() )
- return false;
-
- cmd = *pPlayer->GetLastUserCommand();
- cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();
-
- if( bot_crouch.GetInt() )
- cmd.buttons |= IN_DUCK;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Simulates a single frame of movement for a player
-// Input : *fakeclient -
-// *viewangles -
-// forwardmove -
-// m_flSideMove -
-// upmove -
-// buttons -
-// impulse -
-// msec -
-// Output : virtual void
-//-----------------------------------------------------------------------------
-static void RunPlayerMove( CSDKPlayer *fakeclient, CUserCmd &cmd, float frametime )
-{
- if ( !fakeclient )
- return;
-
- // Store off the globals.. they're gonna get whacked
- float flOldFrametime = gpGlobals->frametime;
- float flOldCurtime = gpGlobals->curtime;
-
- float flTimeBase = gpGlobals->curtime + gpGlobals->frametime - frametime;
- fakeclient->SetTimeBase( flTimeBase );
-
- MoveHelperServer()->SetHost( fakeclient );
- fakeclient->PlayerRunCommand( &cmd, MoveHelperServer() );
-
- // save off the last good usercmd
- fakeclient->SetLastUserCommand( cmd );
-
- // Clear out any fixangle that has been set
- fakeclient->pl.fixangle = FIXANGLE_NONE;
-
- // Restore the globals..
- gpGlobals->frametime = flOldFrametime;
- gpGlobals->curtime = flOldCurtime;
-}
-
-
-
-void Bot_UpdateStrafing( CSDKBot *pBot, CUserCmd &cmd )
-{
- if ( gpGlobals->curtime >= pBot->m_flNextStrafeTime )
- {
- pBot->m_flNextStrafeTime = gpGlobals->curtime + 1.0f;
-
- if ( random->RandomInt( 0, 5 ) == 0 )
- {
- pBot->m_flSideMove = -600.0f + 1200.0f * random->RandomFloat( 0, 2 );
- }
- else
- {
- pBot->m_flSideMove = 0;
- }
- cmd.sidemove = pBot->m_flSideMove;
-
- if ( random->RandomInt( 0, 20 ) == 0 )
- {
- pBot->m_bBackwards = true;
- }
- else
- {
- pBot->m_bBackwards = false;
- }
- }
-}
-
-
-void Bot_UpdateDirection( CSDKBot *pBot )
-{
- float angledelta = 15.0;
- QAngle angle;
-
- int maxtries = (int)360.0/angledelta;
-
- if ( pBot->m_bLastTurnToRight )
- {
- angledelta = -angledelta;
- }
-
- angle = pBot->GetLocalAngles();
-
- trace_t trace;
- Vector vecSrc, vecEnd, forward;
- while ( --maxtries >= 0 )
- {
- AngleVectors( angle, &forward );
-
- vecSrc = pBot->GetLocalOrigin() + Vector( 0, 0, 36 );
-
- vecEnd = vecSrc + forward * 10;
-
- UTIL_TraceHull( vecSrc, vecEnd, VEC_HULL_MIN_SCALED( pBot ), VEC_HULL_MAX_SCALED( pBot ),
- MASK_PLAYERSOLID, pBot, COLLISION_GROUP_NONE, &trace );
-
- if ( trace.fraction == 1.0 )
- {
- if ( gpGlobals->curtime < pBot->m_flNextTurnTime )
- {
- break;
- }
- }
-
- angle.y += angledelta;
-
- if ( angle.y > 180 )
- angle.y -= 360;
- else if ( angle.y < -180 )
- angle.y += 360;
-
- pBot->m_flNextTurnTime = gpGlobals->curtime + 2.0;
- pBot->m_bLastTurnToRight = random->RandomInt( 0, 1 ) == 0 ? true : false;
-
- pBot->m_ForwardAngle = angle;
- pBot->m_LastAngles = angle;
- }
-
- pBot->SetLocalAngles( angle );
-}
-
-
-void Bot_FlipOut( CSDKBot *pBot, CUserCmd &cmd )
-{
- if ( bot_flipout.GetInt() > 0 && pBot->IsAlive() )
- {
- if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
- {
- cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
- }
-
- if ( bot_flipout.GetInt() >= 2 )
- {
- QAngle angOffset = RandomAngle( -1, 1 );
-
- pBot->m_LastAngles += angOffset;
-
- for ( int i = 0 ; i < 2; i++ )
- {
- if ( fabs( pBot->m_LastAngles[ i ] - pBot->m_ForwardAngle[ i ] ) > 15.0f )
- {
- if ( pBot->m_LastAngles[ i ] > pBot->m_ForwardAngle[ i ] )
- {
- pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] + 15;
- }
- else
- {
- pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] - 15;
- }
- }
- }
-
- pBot->m_LastAngles[ 2 ] = 0;
-
- pBot->SetLocalAngles( pBot->m_LastAngles );
- }
- }
-}
-
-
-void Bot_HandleSendCmd( CSDKBot *pBot )
-{
- if ( strlen( bot_sendcmd.GetString() ) > 0 )
- {
- //send the cmd from this bot
- pBot->ClientCommand( bot_sendcmd.GetString() );
-
- bot_sendcmd.SetValue("");
- }
-}
-
-
-// If bots are being forced to fire a weapon, see if I have it
-void Bot_ForceFireWeapon( CSDKBot *pBot, CUserCmd &cmd )
-{
- if ( bot_forcefireweapon.GetString() )
- {
- CBaseCombatWeapon *pWeapon = pBot->Weapon_OwnsThisType( bot_forcefireweapon.GetString() );
- if ( pWeapon )
- {
- // Switch to it if we don't have it out
- CBaseCombatWeapon *pActiveWeapon = pBot->GetActiveWeapon();
-
- // Switch?
- if ( pActiveWeapon != pWeapon )
- {
- pBot->Weapon_Switch( pWeapon );
- }
- else
- {
- // Start firing
- // Some weapons require releases, so randomise firing
- if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
- {
- cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
- }
- }
- }
- }
-}
-
-
-void Bot_SetForwardMovement( CSDKBot *pBot, CUserCmd &cmd )
-{
- if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) )
- {
- if ( pBot->m_iHealth == 100 )
- {
- cmd.forwardmove = 600 * ( pBot->m_bBackwards ? -1 : 1 );
- if ( pBot->m_flSideMove != 0.0f )
- {
- cmd.forwardmove *= random->RandomFloat( 0.1, 1.0f );
- }
- }
- else
- {
- // Stop when shot
- cmd.forwardmove = 0;
- }
- }
-}
-
-
-void Bot_HandleRespawn( CSDKBot *pBot, CUserCmd &cmd )
-{
- // Wait for Reinforcement wave
- if ( !pBot->IsAlive() )
- {
- // Try hitting my buttons occasionally
- if ( random->RandomInt( 0, 100 ) > 80 )
- {
- // Respawn the bot
- if ( random->RandomInt( 0, 1 ) == 0 )
- {
- cmd.buttons |= IN_JUMP;
- }
- else
- {
- cmd.buttons = 0;
- }
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Run this Bot's AI for one frame.
-//-----------------------------------------------------------------------------
-void Bot_Think( CSDKBot *pBot )
-{
- // Make sure we stay being a bot
- pBot->AddFlag( FL_FAKECLIENT );
-
-
- CUserCmd cmd;
- Q_memset( &cmd, 0, sizeof( cmd ) );
-
-
- // Finally, override all this stuff if the bot is being forced to mimic a player.
- if ( !Bot_RunMimicCommand( cmd ) )
- {
- cmd.sidemove = pBot->m_flSideMove;
-
- if ( pBot->IsAlive() && (pBot->GetSolid() == SOLID_BBOX) )
- {
- Bot_SetForwardMovement( pBot, cmd );
-
- // Only turn if I haven't been hurt
- if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_iHealth == 100 )
- {
- Bot_UpdateDirection( pBot );
- Bot_UpdateStrafing( pBot, cmd );
- }
-
- // Handle console settings.
- Bot_ForceFireWeapon( pBot, cmd );
- Bot_HandleSendCmd( pBot );
- }
- else
- {
- Bot_HandleRespawn( pBot, cmd );
- }
-
- Bot_FlipOut( pBot, cmd );
-
- cmd.viewangles = pBot->GetLocalAngles();
- cmd.upmove = 0;
- cmd.impulse = 0;
- }
-
- float frametime = gpGlobals->frametime;
- RunPlayerMove( pBot, cmd, frametime );
-}
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Basic BOT handling. +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "player.h" +#include "sdk_player.h" +#include "in_buttons.h" +#include "movehelper_server.h" +#include "gameinterface.h" + + +class CSDKBot; +void Bot_Think( CSDKBot *pBot ); + + +ConVar bot_forcefireweapon( "bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." ); +ConVar bot_forceattack2( "bot_forceattack2", "0", 0, "When firing, use attack2." ); +ConVar bot_forceattackon( "bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." ); +ConVar bot_flipout( "bot_flipout", "0", 0, "When on, all bots fire their guns." ); +ConVar bot_changeclass( "bot_changeclass", "0", 0, "Force all bots to change to the specified class." ); +static ConVar bot_mimic( "bot_mimic", "0", 0, "Bot uses usercmd of player by index." ); +static ConVar bot_mimic_yaw_offset( "bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." ); + +ConVar bot_sendcmd( "bot_sendcmd", "", 0, "Forces bots to send the specified command." ); + +ConVar bot_crouch( "bot_crouch", "0", 0, "Bot crouches" ); + +static int g_CurBotNumber = 1; + + +// This is our bot class. +class CSDKBot : public CSDKPlayer +{ +public: + bool m_bBackwards; + + float m_flNextTurnTime; + bool m_bLastTurnToRight; + + float m_flNextStrafeTime; + float m_flSideMove; + + QAngle m_ForwardAngle; + QAngle m_LastAngles; +}; + +LINK_ENTITY_TO_CLASS( sdk_bot, CSDKBot ); + +class CBotManager +{ +public: + static CBasePlayer* ClientPutInServerOverride_Bot( edict_t *pEdict, const char *playername ) + { + // This tells it which edict to use rather than creating a new one. + CBasePlayer::s_PlayerEdict = pEdict; + + CSDKBot *pPlayer = static_cast<CSDKBot *>( CreateEntityByName( "sdk_bot" ) ); + if ( pPlayer ) + { + pPlayer->SetPlayerName( playername ); + } + + return pPlayer; + } +}; + + +//----------------------------------------------------------------------------- +// Purpose: Create a new Bot and put it in the game. +// Output : Pointer to the new Bot, or NULL if there's no free clients. +//----------------------------------------------------------------------------- +CBasePlayer *BotPutInServer( bool bFrozen ) +{ + char botname[ 64 ]; + Q_snprintf( botname, sizeof( botname ), "Bot%02i", g_CurBotNumber ); + + + // This trick lets us create a CSDKBot for this client instead of the CSDKPlayer + // that we would normally get when ClientPutInServer is called. + ClientPutInServerOverride( &CBotManager::ClientPutInServerOverride_Bot ); + edict_t *pEdict = engine->CreateFakeClient( botname ); + ClientPutInServerOverride( NULL ); + + if (!pEdict) + { + Msg( "Failed to create Bot.\n"); + return NULL; + } + + // Allocate a player entity for the bot, and call spawn + CSDKBot *pPlayer = ((CSDKBot*)CBaseEntity::Instance( pEdict )); + + pPlayer->ClearFlags(); + pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT ); + + if ( bFrozen ) + pPlayer->AddEFlags( EFL_BOT_FROZEN ); + + pPlayer->ChangeTeam( TEAM_UNASSIGNED ); + pPlayer->RemoveAllItems( true ); + pPlayer->Spawn(); + + g_CurBotNumber++; + + return pPlayer; +} + +// Handler for the "bot" command. +CON_COMMAND_F( "bot_add", "Add a bot.", FCVAR_CHEAT ) +{ + // Look at -count. + int count = args.FindArgInt( "-count", 1 ); + count = clamp( count, 1, 16 ); + + // Look at -frozen. + bool bFrozen = !!args.FindArg( "-frozen" ); + + // Ok, spawn all the bots. + while ( --count >= 0 ) + { + BotPutInServer( bFrozen ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Run through all the Bots in the game and let them think. +//----------------------------------------------------------------------------- +void Bot_RunAll( void ) +{ + for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CSDKPlayer *pPlayer = ToSDKPlayer( UTIL_PlayerByIndex( i ) ); + + if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) ) + { + CSDKBot *pBot = dynamic_cast< CSDKBot* >( pPlayer ); + if ( pBot ) + Bot_Think( pBot ); + } + } +} + +bool Bot_RunMimicCommand( CUserCmd& cmd ) +{ + if ( bot_mimic.GetInt() <= 0 ) + return false; + + if ( bot_mimic.GetInt() > gpGlobals->maxClients ) + return false; + + + CBasePlayer *pPlayer = UTIL_PlayerByIndex( bot_mimic.GetInt() ); + if ( !pPlayer ) + return false; + + if ( !pPlayer->GetLastUserCommand() ) + return false; + + cmd = *pPlayer->GetLastUserCommand(); + cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat(); + + if( bot_crouch.GetInt() ) + cmd.buttons |= IN_DUCK; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Simulates a single frame of movement for a player +// Input : *fakeclient - +// *viewangles - +// forwardmove - +// m_flSideMove - +// upmove - +// buttons - +// impulse - +// msec - +// Output : virtual void +//----------------------------------------------------------------------------- +static void RunPlayerMove( CSDKPlayer *fakeclient, CUserCmd &cmd, float frametime ) +{ + if ( !fakeclient ) + return; + + // Store off the globals.. they're gonna get whacked + float flOldFrametime = gpGlobals->frametime; + float flOldCurtime = gpGlobals->curtime; + + float flTimeBase = gpGlobals->curtime + gpGlobals->frametime - frametime; + fakeclient->SetTimeBase( flTimeBase ); + + MoveHelperServer()->SetHost( fakeclient ); + fakeclient->PlayerRunCommand( &cmd, MoveHelperServer() ); + + // save off the last good usercmd + fakeclient->SetLastUserCommand( cmd ); + + // Clear out any fixangle that has been set + fakeclient->pl.fixangle = FIXANGLE_NONE; + + // Restore the globals.. + gpGlobals->frametime = flOldFrametime; + gpGlobals->curtime = flOldCurtime; +} + + + +void Bot_UpdateStrafing( CSDKBot *pBot, CUserCmd &cmd ) +{ + if ( gpGlobals->curtime >= pBot->m_flNextStrafeTime ) + { + pBot->m_flNextStrafeTime = gpGlobals->curtime + 1.0f; + + if ( random->RandomInt( 0, 5 ) == 0 ) + { + pBot->m_flSideMove = -600.0f + 1200.0f * random->RandomFloat( 0, 2 ); + } + else + { + pBot->m_flSideMove = 0; + } + cmd.sidemove = pBot->m_flSideMove; + + if ( random->RandomInt( 0, 20 ) == 0 ) + { + pBot->m_bBackwards = true; + } + else + { + pBot->m_bBackwards = false; + } + } +} + + +void Bot_UpdateDirection( CSDKBot *pBot ) +{ + float angledelta = 15.0; + QAngle angle; + + int maxtries = (int)360.0/angledelta; + + if ( pBot->m_bLastTurnToRight ) + { + angledelta = -angledelta; + } + + angle = pBot->GetLocalAngles(); + + trace_t trace; + Vector vecSrc, vecEnd, forward; + while ( --maxtries >= 0 ) + { + AngleVectors( angle, &forward ); + + vecSrc = pBot->GetLocalOrigin() + Vector( 0, 0, 36 ); + + vecEnd = vecSrc + forward * 10; + + UTIL_TraceHull( vecSrc, vecEnd, VEC_HULL_MIN_SCALED( pBot ), VEC_HULL_MAX_SCALED( pBot ), + MASK_PLAYERSOLID, pBot, COLLISION_GROUP_NONE, &trace ); + + if ( trace.fraction == 1.0 ) + { + if ( gpGlobals->curtime < pBot->m_flNextTurnTime ) + { + break; + } + } + + angle.y += angledelta; + + if ( angle.y > 180 ) + angle.y -= 360; + else if ( angle.y < -180 ) + angle.y += 360; + + pBot->m_flNextTurnTime = gpGlobals->curtime + 2.0; + pBot->m_bLastTurnToRight = random->RandomInt( 0, 1 ) == 0 ? true : false; + + pBot->m_ForwardAngle = angle; + pBot->m_LastAngles = angle; + } + + pBot->SetLocalAngles( angle ); +} + + +void Bot_FlipOut( CSDKBot *pBot, CUserCmd &cmd ) +{ + if ( bot_flipout.GetInt() > 0 && pBot->IsAlive() ) + { + if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) ) + { + cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK; + } + + if ( bot_flipout.GetInt() >= 2 ) + { + QAngle angOffset = RandomAngle( -1, 1 ); + + pBot->m_LastAngles += angOffset; + + for ( int i = 0 ; i < 2; i++ ) + { + if ( fabs( pBot->m_LastAngles[ i ] - pBot->m_ForwardAngle[ i ] ) > 15.0f ) + { + if ( pBot->m_LastAngles[ i ] > pBot->m_ForwardAngle[ i ] ) + { + pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] + 15; + } + else + { + pBot->m_LastAngles[ i ] = pBot->m_ForwardAngle[ i ] - 15; + } + } + } + + pBot->m_LastAngles[ 2 ] = 0; + + pBot->SetLocalAngles( pBot->m_LastAngles ); + } + } +} + + +void Bot_HandleSendCmd( CSDKBot *pBot ) +{ + if ( strlen( bot_sendcmd.GetString() ) > 0 ) + { + //send the cmd from this bot + pBot->ClientCommand( bot_sendcmd.GetString() ); + + bot_sendcmd.SetValue(""); + } +} + + +// If bots are being forced to fire a weapon, see if I have it +void Bot_ForceFireWeapon( CSDKBot *pBot, CUserCmd &cmd ) +{ + if ( bot_forcefireweapon.GetString() ) + { + CBaseCombatWeapon *pWeapon = pBot->Weapon_OwnsThisType( bot_forcefireweapon.GetString() ); + if ( pWeapon ) + { + // Switch to it if we don't have it out + CBaseCombatWeapon *pActiveWeapon = pBot->GetActiveWeapon(); + + // Switch? + if ( pActiveWeapon != pWeapon ) + { + pBot->Weapon_Switch( pWeapon ); + } + else + { + // Start firing + // Some weapons require releases, so randomise firing + if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) ) + { + cmd.buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK; + } + } + } + } +} + + +void Bot_SetForwardMovement( CSDKBot *pBot, CUserCmd &cmd ) +{ + if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) ) + { + if ( pBot->m_iHealth == 100 ) + { + cmd.forwardmove = 600 * ( pBot->m_bBackwards ? -1 : 1 ); + if ( pBot->m_flSideMove != 0.0f ) + { + cmd.forwardmove *= random->RandomFloat( 0.1, 1.0f ); + } + } + else + { + // Stop when shot + cmd.forwardmove = 0; + } + } +} + + +void Bot_HandleRespawn( CSDKBot *pBot, CUserCmd &cmd ) +{ + // Wait for Reinforcement wave + if ( !pBot->IsAlive() ) + { + // Try hitting my buttons occasionally + if ( random->RandomInt( 0, 100 ) > 80 ) + { + // Respawn the bot + if ( random->RandomInt( 0, 1 ) == 0 ) + { + cmd.buttons |= IN_JUMP; + } + else + { + cmd.buttons = 0; + } + } + } +} + + +//----------------------------------------------------------------------------- +// Run this Bot's AI for one frame. +//----------------------------------------------------------------------------- +void Bot_Think( CSDKBot *pBot ) +{ + // Make sure we stay being a bot + pBot->AddFlag( FL_FAKECLIENT ); + + + CUserCmd cmd; + Q_memset( &cmd, 0, sizeof( cmd ) ); + + + // Finally, override all this stuff if the bot is being forced to mimic a player. + if ( !Bot_RunMimicCommand( cmd ) ) + { + cmd.sidemove = pBot->m_flSideMove; + + if ( pBot->IsAlive() && (pBot->GetSolid() == SOLID_BBOX) ) + { + Bot_SetForwardMovement( pBot, cmd ); + + // Only turn if I haven't been hurt + if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_iHealth == 100 ) + { + Bot_UpdateDirection( pBot ); + Bot_UpdateStrafing( pBot, cmd ); + } + + // Handle console settings. + Bot_ForceFireWeapon( pBot, cmd ); + Bot_HandleSendCmd( pBot ); + } + else + { + Bot_HandleRespawn( pBot, cmd ); + } + + Bot_FlipOut( pBot, cmd ); + + cmd.viewangles = pBot->GetLocalAngles(); + cmd.upmove = 0; + cmd.impulse = 0; + } + + float frametime = gpGlobals->frametime; + RunPlayerMove( pBot, cmd, frametime ); +} + + |