Reworked the bot system

This commit is contained in:
smallmodel 2023-08-19 17:58:54 +02:00
parent d95cdcc142
commit 7a57a25c58
No known key found for this signature in database
GPG key ID: A96F163ED4891440
8 changed files with 152 additions and 50 deletions

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@ -24,8 +24,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "entity.h"
#include "playerbot.h"
#include "g_bot.h"
static gentity_t* firstBot = NULL;
static saved_bot_t* saved_bots = NULL;
static unsigned int current_bot_count = 0;
void G_BotBegin
(
@ -64,7 +67,7 @@ gentity_t* G_GetFirstBot()
return firstBot;
}
void G_AddBot(unsigned int num)
void G_AddBot(unsigned int num, saved_bot_t* saved)
{
int n;
int i;
@ -72,8 +75,10 @@ void G_AddBot(unsigned int num)
gentity_t *e;
char botName[ MAX_NETNAME ];
char challenge[ MAX_STRING_TOKENS ];
char userinfo[MAX_INFO_STRING]{ 0 };
Event* teamEv;
num = Q_min(num, maxbots->integer);
num = Q_min(num, sv_maxbots->integer);
for( n = 0; n < num; n++ )
{
for( i = maxclients->integer; i < game.maxclients; i++ )
@ -107,37 +112,67 @@ void G_AddBot(unsigned int num)
e->s.clientNum = clientNum;
e->s.number = clientNum;
Info_SetValueForKey( e->client->pers.userinfo, "name", botName );
Info_SetValueForKey( e->client->pers.userinfo, "dm_playermodel", "allied_pilot" );
Info_SetValueForKey( e->client->pers.userinfo, "dm_playergermanmodel", "german_afrika_officer" );
Info_SetValueForKey( e->client->pers.userinfo, "fov", "80" );
Info_SetValueForKey( e->client->pers.userinfo, "protocol", "8" );
Info_SetValueForKey( e->client->pers.userinfo, "ip", "0.0.0.0" );
Info_SetValueForKey( e->client->pers.userinfo, "qport", "0" );
Info_SetValueForKey( e->client->pers.userinfo, "challenge", challenge );
Info_SetValueForKey( e->client->pers.userinfo, "snaps", "1" );
Info_SetValueForKey( e->client->pers.userinfo, "rate", "1" );
Info_SetValueForKey( e->client->pers.userinfo, "dmprimary", "smg" );
if (saved) {
strncpy(userinfo, saved->pers.userinfo, ARRAY_LEN(userinfo));
} else {
Info_SetValueForKey(userinfo, "name", botName);
Info_SetValueForKey(userinfo, "dm_playermodel", "allied_pilot");
Info_SetValueForKey(userinfo, "dm_playergermanmodel", "german_afrika_officer");
Info_SetValueForKey(userinfo, "fov", "80");
Info_SetValueForKey(userinfo, "protocol", "8");
Info_SetValueForKey(userinfo, "ip", "0.0.0.0");
Info_SetValueForKey(userinfo, "qport", "0");
Info_SetValueForKey(userinfo, "challenge", challenge);
Info_SetValueForKey(userinfo, "snaps", "1");
Info_SetValueForKey(userinfo, "rate", "1");
Info_SetValueForKey(userinfo, "dmprimary", "smg");
}
G_BotConnect( clientNum );
current_bot_count++;
G_BotConnect( clientNum, userinfo );
if (saved) {
e->client->pers = saved->pers;
}
if( !firstBot )
firstBot = e;
G_BotBegin( e );
e->entity->PostEvent( EV_Player_AutoJoinDMTeam, level.frametime );
if (saved) {
/*
switch (saved->team)
{
case TEAM_ALLIES:
teamEv = new Event(EV_Player_JoinDMTeam);
teamEv->AddString("allies");
break;
case TEAM_AXIS:
teamEv = new Event(EV_Player_JoinDMTeam);
teamEv->AddString("axis");
break;
default:
teamEv = new Event(EV_Player_AutoJoinDMTeam);
break;
}
*/
} else {
teamEv = new Event(EV_Player_AutoJoinDMTeam);
e->entity->PostEvent(teamEv, level.frametime);
Event *ev = new Event( EV_Player_PrimaryDMWeapon );
ev->AddString( "smg" );
Event* ev = new Event(EV_Player_PrimaryDMWeapon);
ev->AddString("smg");
e->entity->PostEvent( ev, level.frametime );
e->entity->PostEvent(ev, level.frametime);
}
}
}
void G_RemoveBot(unsigned int num)
{
num = Q_min(atoi(gi.Argv(1)), maxbots->integer);
num = Q_min(atoi(gi.Argv(1)), sv_maxbots->integer);
for( int n = 0; n < num; n++ )
{
@ -145,6 +180,70 @@ void G_RemoveBot(unsigned int num)
if( e->inuse && e->client )
{
G_ClientDisconnect( e );
current_bot_count--;
}
}
}
void G_SaveBots() {
unsigned int n;
if (saved_bots) {
delete[] saved_bots;
saved_bots = NULL;
}
if (!current_bot_count) {
return;
}
saved_bots = new saved_bot_t[current_bot_count];
for (n = 0; n < current_bot_count; n++) {
gentity_t* e = &g_entities[game.maxclients - sv_maxbots->integer + n];
saved_bot_t& saved = saved_bots[n];
if (e->inuse && e->client)
{
Player* player = static_cast<Player*>(e->entity);
saved.bValid = true;
//saved.team = player->GetTeam();
saved.pers = player->client->pers;
}
}
}
void G_RestoreBots() {
unsigned int n;
if (!saved_bots) {
return;
}
for (n = 0; n < sv_numbots->integer; n++) {
saved_bot_t& saved = saved_bots[n];
G_AddBot(1, &saved);
}
delete[] saved_bots;
saved_bots = NULL;
}
void G_ResetBots() {
G_SaveBots();
current_bot_count = 0;
}
void G_SpawnBots() {
if (saved_bots) {
G_RestoreBots();
}
if (sv_numbots->integer > current_bot_count) {
G_AddBot(sv_numbots->integer - current_bot_count);
} else if (sv_numbots->integer < current_bot_count) {
G_RemoveBot(current_bot_count - sv_numbots->integer);
}
}

View file

@ -786,11 +786,10 @@ void G_ClientUserinfoChanged(gentity_t *ent, const char *u)
Q_strncpyz(client->pers.userinfo, u, sizeof(client->pers.userinfo));
}
void G_BotConnect(int clientNum)
void G_BotConnect(int clientNum, const char* userinfo)
{
gclient_t *client;
gentity_t *ent;
char userinfo[MAX_INFO_STRING];
ent = &g_entities[clientNum];
@ -799,8 +798,6 @@ void G_BotConnect(int clientNum)
client = ent->client;
Q_strncpyz(userinfo, client->pers.userinfo, sizeof(userinfo));
// read the session data
memset(client, 0, sizeof(*client));
G_InitSessionData(client, userinfo);

View file

@ -423,7 +423,7 @@ void QDECL G_Error(errorParm_t type, const char *fmt, ...);
//
// g_client.c
//
void G_BotConnect(int clientNum);
void G_BotConnect(int clientNum, const char* userinfo);
const char *G_ClientConnect(int clientNum, qboolean firstTime);
void G_ClientUserinfoChanged(gentity_t *ent, const char *userinfo);
void G_ClientDisconnect(gentity_t *ent);
@ -457,7 +457,7 @@ void Svcmd_GameMem_f(void);
// g_session.c
//
void G_ReadSessionData(gclient_t *client);
void G_InitSessionData(gclient_t *client, char *userinfo);
void G_InitSessionData(gclient_t *client, const char *userinfo);
void G_InitWorldSession(void);
void G_WriteSessionData(void);
@ -472,11 +472,6 @@ void Svcmd_AbortPodium_f(void);
//
// g_bot.c
//
void G_BotBegin(gentity_t *ent);
void G_BotThink(gentity_t *ent, int msec);
gentity_t* G_GetFirstBot();
void G_AddBot(unsigned int num);
void G_RemoveBot(unsigned int num);
typedef struct mmove_s {
vec3_t origin;

View file

@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "lodthing.h"
#include "viewthing.h"
#include "playerbot.h"
#include "g_bot.h"
#include <tiki.h>
#ifdef WIN32
@ -270,7 +271,7 @@ void G_InitGame(int levelTime, int randomSeed)
game.maxentities = game.maxclients * 8;
}
game.maxclients = maxclients->integer + maxbots->integer;
game.maxclients = maxclients->integer + sv_maxbots->integer;
L_InitEvents();
@ -286,6 +287,8 @@ G_SpawnEntities
void G_SpawnEntities(char *entities, int svsTime)
{
level.SpawnEntities(entities, svsTime);
G_SpawnBots();
}
/*
@ -642,6 +645,9 @@ void G_RunFrame(int levelTime, int frameTime)
}
}
}
// Add or delete bots that were added using addbot/removebot
G_SpawnBots();
}
catch (const char *error) {

View file

@ -83,7 +83,7 @@ G_InitSessionData
Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo )
void G_InitSessionData( gclient_t *client, const char *userinfo )
{
G_WriteClientSessionData( client );
}

View file

@ -34,6 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <scriptcompiler.h>
#include "playerbot.h"
#include "consoleevent.h"
#include "g_bot.h"
typedef struct
{
@ -630,6 +631,7 @@ qboolean G_AddBotCommand
)
{
unsigned int numbots;
unsigned int totalnumbots;
int clientNum = -1;
if( gi.Argc() <= 1 )
@ -639,13 +641,15 @@ qboolean G_AddBotCommand
}
numbots = atoi( gi.Argv( 1 ) );
if(numbots > maxbots->integer)
if(numbots > sv_maxbots->integer)
{
gi.Printf( "addbot must be between 1-%d\n", maxbots->integer );
gi.Printf( "addbot must be between 1-%d\n", sv_maxbots->integer );
return qfalse;
}
G_AddBot(numbots);
totalnumbots = Q_min(numbots + sv_numbots->integer, sv_maxbots->integer);
gi.cvar_set("sv_numbots", va("%d", totalnumbots));
return qtrue;
}
@ -655,6 +659,7 @@ qboolean G_RemoveBotCommand
)
{
unsigned int numbots;
unsigned int totalnumbots;
if( gi.Argc() <= 1 )
{
@ -662,18 +667,10 @@ qboolean G_RemoveBotCommand
return qfalse;
}
numbots = Q_min(atoi(gi.Argv(1)), maxbots->integer);
numbots = atoi(gi.Argv(1));
totalnumbots = Q_min(numbots, sv_numbots->integer);
for( int n = 0; n < numbots; n++ )
{
gentity_t *e = &g_entities[ game.maxclients - 1 - n ];
if( e->inuse && e->client )
{
G_ClientDisconnect( e );
}
}
G_RemoveBot(numbots);
gi.cvar_set("sv_numbots", va("%d", totalnumbots));
return qtrue;
}

View file

@ -262,7 +262,8 @@ cvar_t* g_obituarylocation;
cvar_t *sv_scriptfiles;
cvar_t *maxbots;
cvar_t *sv_maxbots;
cvar_t *sv_numbots;
cvar_t *g_rankedserver;
cvar_t *g_spectatefollow_firstperson;
@ -596,7 +597,13 @@ void CVAR_Init(void)
}
sv_scriptfiles = gi.Cvar_Get("sv_scriptfiles", "0", 0);
maxbots = gi.Cvar_Get("sv_maxbots", "2", 0);
sv_maxbots = gi.Cvar_Get("sv_maxbots", "0", CVAR_LATCH);
sv_numbots = gi.Cvar_Get("sv_numbots", "0", CVAR_LATCH);
g_rankedserver = gi.Cvar_Get("g_rankedserver", "0", 0);
g_spectatefollow_firstperson = gi.Cvar_Get("g_spectatefollow_firstperson", "0", 0);
if (sv_numbots->integer > sv_maxbots->integer) {
gi.Printf("numbots overflow, setting to %d\n", sv_maxbots->integer);
gi.cvar_set("sv_numbots", sv_maxbots->string);
}
}

View file

@ -267,7 +267,8 @@ extern cvar_t* g_obituarylocation;
extern cvar_t *sv_scriptfiles;
extern cvar_t *maxbots;
extern cvar_t *sv_maxbots;
extern cvar_t * sv_numbots;
extern cvar_t *g_rankedserver;
extern cvar_t *g_spectatefollow_firstperson;