Skip to content

Commit

Permalink
Add files via upload (alliedmodders#37)
Browse files Browse the repository at this point in the history
Added serverplugin_sample from source sdk as well as VC2010 project to build a working VSP sample

Co-authored-by: hackspider <[email protected]>
  • Loading branch information
hackspider and hackspider authored Nov 4, 2021
1 parent 259877e commit e2e62c5
Show file tree
Hide file tree
Showing 4 changed files with 1,501 additions and 0 deletions.
390 changes: 390 additions & 0 deletions utils/serverplugin_sample/serverplugin_bot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,390 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Basic BOT handling.
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//

#include "interface.h"
#include "filesystem.h"
#undef VECTOR_NO_SLOW_OPERATIONS
#include "mathlib/vector.h"

#include "eiface.h"
#include "edict.h"
#include "game/server/iplayerinfo.h"
#include "igameevents.h"
#include "convar.h"
#include "vstdlib/random.h"
#include "../../game/shared/in_buttons.h"
#include "../../game/shared/shareddefs.h"
//#include "../../game_shared/util_shared.h"
#include "engine/IEngineTrace.h"

extern IBotManager *botmanager;
extern IUniformRandomStream *randomStr;
extern IPlayerInfoManager *playerinfomanager;
extern IVEngineServer *engine;
extern IEngineTrace *enginetrace;
extern IPlayerInfoManager *playerinfomanager; // game dll interface to interact with players
extern IServerPluginHelpers *helpers; // special 3rd party plugin helpers from the engine

extern CGlobalVars *gpGlobals;

ConVar bot_forcefireweapon( "plugin_bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
ConVar bot_forceattack2( "plugin_bot_forceattack2", "0", 0, "When firing, use attack2." );
ConVar bot_forceattackon( "plugin_bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
ConVar bot_flipout( "plugin_bot_flipout", "0", 0, "When on, all bots fire their guns." );
ConVar bot_changeclass( "plugin_bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
static ConVar bot_mimic( "plugin_bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
static ConVar bot_mimic_yaw_offset( "plugin_bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." );

ConVar bot_sendcmd( "plugin_bot_sendcmd", "", 0, "Forces bots to send the specified command." );
ConVar bot_crouch( "plugin_bot_crouch", "0", 0, "Bot crouches" );

inline edict_t *PEntityOfEntIndex(int iEntIndex)
{
if(iEntIndex >= 0 && iEntIndex < gpGlobals->maxEntities)
return (edict_t *)(gpGlobals->pEdicts + iEntIndex);

return NULL;
}

// This is our bot class.
class CPluginBot
{
public:
CPluginBot() :
m_bBackwards(0),
m_flNextTurnTime(0),
m_bLastTurnToRight(0),
m_flNextStrafeTime(0),
m_flSideMove(0),
m_ForwardAngle(),
m_LastAngles()
{
}

bool m_bBackwards;

float m_flNextTurnTime;
bool m_bLastTurnToRight;

float m_flNextStrafeTime;
float m_flSideMove;

QAngle m_ForwardAngle;
QAngle m_LastAngles;

IBotController *m_BotInterface;
IPlayerInfo *m_PlayerInfo;
edict_t *m_BotEdict;
};

CUtlVector<CPluginBot> s_Bots;

void Bot_Think( CPluginBot *pBot );

// Handler for the "bot" command.
void BotAdd_f()
{
if ( !botmanager )
return;

static int s_BotNum = 0;
char botName[64];
Q_snprintf( botName, sizeof(botName), "Bot_%i", s_BotNum );
s_BotNum++;

edict_t *botEdict = botmanager->CreateBot( botName );
if ( botEdict )
{
int botIndex = s_Bots.AddToTail();
CPluginBot & bot = s_Bots[ botIndex ];
bot.m_BotInterface = botmanager->GetBotController( botEdict );
bot.m_PlayerInfo = playerinfomanager->GetPlayerInfo( botEdict );
bot.m_BotEdict = botEdict;
Assert( bot.m_BotInterface );
}
}

ConCommand cc_Bot( "plugin_bot_add", BotAdd_f, "Add a bot." );


//-----------------------------------------------------------------------------
// Purpose: Run through all the Bots in the game and let them think.
//-----------------------------------------------------------------------------
void Bot_RunAll( void )
{
if ( !botmanager )
return;

for ( int i = 0; i < s_Bots.Count(); i++ )
{
CPluginBot & bot = s_Bots[i];
if ( bot.m_BotEdict->IsFree() || !bot.m_BotEdict->GetUnknown()|| !bot.m_PlayerInfo->IsConnected() )
{
s_Bots.Remove(i);
--i;
}
else
{
Bot_Think( &bot );
}
}
}

bool Bot_RunMimicCommand( CBotCmd& cmd )
{
if ( bot_mimic.GetInt() <= 0 )
return false;

if ( bot_mimic.GetInt() > gpGlobals->maxClients )
return false;

IPlayerInfo *playerInfo = playerinfomanager->GetPlayerInfo( PEntityOfEntIndex( bot_mimic.GetInt() ) );
if ( !playerInfo )
return false;

cmd = playerInfo->GetLastUserCommand();
cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();

if( bot_crouch.GetInt() )
cmd.buttons |= IN_DUCK;

return true;
}

void Bot_UpdateStrafing( CPluginBot *pBot, CBotCmd &cmd )
{
if ( gpGlobals->curtime >= pBot->m_flNextStrafeTime )
{
pBot->m_flNextStrafeTime = gpGlobals->curtime + 1.0f;

if ( randomStr->RandomInt( 0, 5 ) == 0 )
{
pBot->m_flSideMove = -600.0f + 1200.0f * randomStr->RandomFloat( 0, 2 );
}
else
{
pBot->m_flSideMove = 0;
}
cmd.sidemove = pBot->m_flSideMove;

if ( randomStr->RandomInt( 0, 20 ) == 0 )
{
pBot->m_bBackwards = true;
}
else
{
pBot->m_bBackwards = false;
}
}
}

void Bot_UpdateDirection( CPluginBot *pBot )
{
float angledelta = 15.0;

int maxtries = (int)360.0/angledelta;

if ( pBot->m_bLastTurnToRight )
{
angledelta = -angledelta;
}

QAngle angle( pBot->m_BotInterface->GetLocalAngles() );

trace_t trace;
Vector vecSrc, vecEnd, forward;
while ( --maxtries >= 0 )
{
AngleVectors( angle, &forward );

vecSrc = pBot->m_BotInterface->GetLocalOrigin() + Vector( 0, 0, 36 );
vecEnd = vecSrc + forward * 10;

Ray_t ray;
ray.Init( vecSrc, vecEnd, Vector(-16, -16, 0 ), Vector( 16, 16, 72 ) );
CTraceFilterWorldAndPropsOnly traceFilter;
enginetrace->TraceRay( ray, MASK_PLAYERSOLID, &traceFilter, &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 = randomStr->RandomInt( 0, 1 ) == 0 ? true : false;

pBot->m_ForwardAngle = angle;
pBot->m_LastAngles = angle;
}

pBot->m_BotInterface->SetLocalAngles( angle );
}


void Bot_FlipOut( CPluginBot *pBot, CBotCmd &cmd )
{
if ( bot_flipout.GetInt() > 0 && !pBot->m_PlayerInfo->IsDead() )
{
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->m_BotInterface->SetLocalAngles( pBot->m_LastAngles );
}
}
}


void Bot_HandleSendCmd( CPluginBot *pBot )
{
if ( strlen( bot_sendcmd.GetString() ) > 0 )
{
//send the cmd from this bot
helpers->ClientCommand( pBot->m_BotEdict, bot_sendcmd.GetString() );

bot_sendcmd.SetValue("");
}
}


// If bots are being forced to fire a weapon, see if I have it
void Bot_ForceFireWeapon( CPluginBot *pBot, CBotCmd &cmd )
{
if ( Q_strlen( bot_forcefireweapon.GetString() ) > 0 )
{
pBot->m_BotInterface->SetActiveWeapon( bot_forcefireweapon.GetString() );
bot_forcefireweapon.SetValue( "" );
// 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( CPluginBot *pBot, CBotCmd &cmd )
{
if ( !pBot->m_BotInterface->IsEFlagSet(EFL_BOT_FROZEN) )
{
if ( pBot->m_PlayerInfo->GetHealth() == 100 )
{
cmd.forwardmove = 600 * ( pBot->m_bBackwards ? -1 : 1 );
if ( pBot->m_flSideMove != 0.0f )
{
cmd.forwardmove *= randomStr->RandomFloat( 0.1, 1.0f );
}
}
else
{
// Stop when shot
cmd.forwardmove = 0;
}
}
}


void Bot_HandleRespawn( CPluginBot *pBot, CBotCmd &cmd )
{
// Wait for Reinforcement wave
if ( pBot->m_PlayerInfo->IsDead() )
{
if ( pBot->m_PlayerInfo->GetTeamIndex() == 0 )
{
helpers->ClientCommand( pBot->m_BotEdict, "joingame" );
helpers->ClientCommand( pBot->m_BotEdict, "jointeam 3" );
helpers->ClientCommand( pBot->m_BotEdict, "joinclass 0" );
}
}
}


//-----------------------------------------------------------------------------
// Run this Bot's AI for one frame.
//-----------------------------------------------------------------------------
void Bot_Think( CPluginBot *pBot )
{
CBotCmd 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->m_PlayerInfo->IsDead() )
{
Bot_SetForwardMovement( pBot, cmd );

// Only turn if I haven't been hurt
if ( !pBot->m_BotInterface->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_PlayerInfo->GetHealth() == 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->m_BotInterface->GetLocalAngles();
cmd.upmove = 0;
cmd.impulse = 0;
}

pBot->m_BotInterface->RunPlayerMove( &cmd );
}


Loading

0 comments on commit e2e62c5

Please sign in to comment.