Experimental bot simulation implementation

Simulate bot user commands on the server. The simulation system is experimental and only runs if cvar 'sv_simulateBots' is set, and bots are created on the server.
This commit is contained in:
Kawe Mazidjatari 2023-01-20 01:23:08 +01:00
parent e9f907638f
commit 4710b51fa3
8 changed files with 64 additions and 1 deletions

View File

@ -5,14 +5,41 @@
// $NoKeywords: $
//=============================================================================//
#include "core/stdafx.h"
#include "tier1/cvar.h"
#include "player.h"
#include "physics_main.h"
#include "engine/client/client.h"
#include "game/shared/util_shared.h"
//-----------------------------------------------------------------------------
// Purpose: Runs the command simulation for fake players
//-----------------------------------------------------------------------------
void Physics_RunBotSimulation(bool bSimulating)
{
if (!sv_simulateBots->GetBool())
return;
for (int i = 0; i < MAX_PLAYERS; i++)
{
CClient* pClient = g_pClient->GetClient(i);
if (!pClient)
continue;
if (pClient->IsActive() && pClient->IsFakeClient())
{
CPlayer* pPlayer = UTIL_PlayerByIndex(i + 1);
if (pPlayer)
pPlayer->RunNullCommand();
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Runs the main physics simulation loop against all entities ( except players )
//-----------------------------------------------------------------------------
void Physics_RunThinkFunctions(bool bSimulating)
{
Physics_RunBotSimulation(bSimulating);
v_Physics_RunThinkFunctions(bSimulating);
}

View File

@ -20,6 +20,13 @@
#include "basecombatcharacter.h"
#include <mathlib/vector4d.h>
enum PlayerConnectedState
{
PlayerConnected,
PlayerDisconnecting,
PlayerDisconnected,
};
// TODO: Move to separate header file!!
struct ThirdPersonViewData
@ -244,6 +251,9 @@ public:
void PlayerRunCommand(CUserCmd* pUserCmd, IMoveHelper* pMover);
void SetLastUserCommand(CUserCmd* pUserCmd);
bool IsConnected() const { return m_iConnected != PlayerDisconnected; }
bool IsDisconnecting() const { return m_iConnected == PlayerDisconnecting; }
private:
int m_StuckLast;
char gap_5a8c[4];

View File

@ -38,7 +38,7 @@ public:
CUserCmd* Copy(CUserCmd* pSource)
{
v_CUserCmd__Copy(this, pSource);
return v_CUserCmd__Copy(this, pSource);
}
int32_t command_number;

View File

@ -15,6 +15,11 @@
CPlayer* UTIL_PlayerByIndex(int nIndex)
{
if (nIndex < 1 || nIndex > g_pGlobals->m_nMaxClients || nIndex == FL_EDICT_INVALID)
return nullptr;
// !TODO: Improve this!!!
CPlayer* pPlayer = *reinterpret_cast<CPlayer**>(g_pGlobals->m_pInterlock + nIndex + 0x7808);
return pPlayer;
}
#endif // CLIENT_DLL

View File

@ -0,0 +1,16 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef UTIL_SHARED_H
#define UTIL_SHARED_H
#ifndef CLIENT_DLL
#include "game/server/player.h"
#endif
#ifndef CLIENT_DLL
CPlayer* UTIL_PlayerByIndex(int nIndex);
#endif // CLIENT_DLL
#endif // !UTIL_SHARED_H

View File

@ -107,6 +107,7 @@ void ConVar::Init(void)
sv_statusRefreshRate = ConVar::Create("sv_statusRefreshRate" , "0.5", FCVAR_RELEASE, "Server status refresh rate (seconds).", false, 0.f, false, 0.f, nullptr, nullptr);
sv_autoReloadRate = ConVar::Create("sv_autoReloadRate" , "0" , FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null). ", true, 0.f, false, 0.f, nullptr, nullptr);
sv_quota_stringCmdsPerSecond = ConVar::Create("sv_quota_stringCmdsPerSecond", "16", FCVAR_RELEASE, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands.", true, 0.f, false, 0.f, nullptr, nullptr);
sv_simulateBots = ConVar::Create("sv_simulateBots", "1", FCVAR_RELEASE, "Simulate user commands for bots on the server.", true, 0.f, false, 0.f, nullptr, nullptr);
#ifdef DEDICATED
sv_rcon_debug = ConVar::Create("sv_rcon_debug" , "0" , FCVAR_RELEASE, "Show rcon debug information ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
sv_rcon_sendlogs = ConVar::Create("sv_rcon_sendlogs" , "0" , FCVAR_RELEASE, "Network console logs to connected and authenticated sockets.", false, 0.f, false, 0.f, nullptr, nullptr);

View File

@ -74,6 +74,8 @@ ConVar* sv_forceChatToTeamOnly = nullptr;
ConVar* sv_autoReloadRate = nullptr;
ConVar* sv_quota_stringCmdsPerSecond = nullptr;
ConVar* sv_simulateBots = nullptr;
#ifdef DEDICATED
ConVar* sv_rcon_debug = nullptr;
ConVar* sv_rcon_sendlogs = nullptr;

View File

@ -70,6 +70,8 @@ extern ConVar* sv_forceChatToTeamOnly;
extern ConVar* sv_autoReloadRate;
extern ConVar* sv_quota_stringCmdsPerSecond;
extern ConVar* sv_simulateBots;
#ifdef DEDICATED
extern ConVar* sv_rcon_debug;
extern ConVar* sv_rcon_sendlogs;