/* ====================== BotCheckServerCommands ====================== */ void BotCheckServerCommands(bot_state_t *bs) { char buf[1024], *args; while (trap_BotGetServerCommand(bs->client, buf, sizeof(buf))) { //have buf point to the command and args to the command arguments args = strchr( buf, ' '); if (!args) continue; *args++ = '\0'; //remove color espace sequences from the arguments RemoveColorEscapeSequences( args ); if (!Q_stricmp(buf, "cp ")) { /*CenterPrintf*/ } else if (!Q_stricmp(buf, "cs")) { /*ConfigStringModified*/ } else if (!Q_stricmp(buf, "print")) { //remove first and last quote from the chat message memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; trap_BotQueueConsoleMessage(bs->cs, CMS_NORMAL, args); } else if (!Q_stricmp(buf, "chat")) { //remove first and last quote from the chat message memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args); } else if (!Q_stricmp(buf, "tchat")) { //remove first and last quote from the chat message memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args); } #ifdef MISSIONPACK else if (!Q_stricmp(buf, "vchat")) { BotVoiceChatCommand(bs, SAY_ALL, args); } else if (!Q_stricmp(buf, "vtchat")) { BotVoiceChatCommand(bs, SAY_TEAM, args); } else if (!Q_stricmp(buf, "vtell")) { BotVoiceChatCommand(bs, SAY_TELL, args); } #endif else if (!Q_stricmp(buf, "scores")) { /*FIXME: parse scores?*/ } else if (!Q_stricmp(buf, "clientLevelShot")) { /*ignore*/ } } }
/* ============== BotAI ============== */ int BotAI(int playernum, float thinktime) { bot_state_t *bs; char buf[1024], *args; int j; EA_ResetInput(playernum); // bs = botstates[playernum]; if (!bs || !bs->inuse) { BotAI_Print(PRT_FATAL, "BotAI: player %d is not setup\n", playernum); return qfalse; } //retrieve the current player state if (!BotAI_GetPlayerState( playernum, &bs->cur_ps )) { BotAI_Print(PRT_FATAL, "BotAI: failed to get player state for player %d\n", playernum); return qfalse; } //retrieve any waiting server commands while( trap_BotGetServerCommand(playernum, buf, sizeof(buf)) ) { //have buf point to the command and args to the command arguments args = strchr( buf, ' '); if (!args) continue; *args++ = '\0'; //remove color espace sequences from the arguments RemoveColorEscapeSequences( args ); if (!Q_stricmp(buf, "cp ")) { /*CenterPrintf*/ } else if (!Q_stricmp(buf, "cs")) { /*ConfigStringModified*/ } else if (!Q_stricmp(buf, "print")) { //remove first and last quote from the chat message memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; BotQueueConsoleMessage(bs->cs, CMS_NORMAL, args); } else if (!Q_stricmp(buf, "chat") || !Q_stricmp(buf, "tell")) { //remove first and last quote from the chat message memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; BotQueueConsoleMessage(bs->cs, CMS_CHAT, args); } else if (!Q_stricmp(buf, "tchat")) { //remove first and last quote from the chat message memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; BotQueueConsoleMessage(bs->cs, CMS_CHAT, args); } #ifdef MISSIONPACK else if (!Q_stricmp(buf, "vchat")) { BotVoiceChatCommand(bs, SAY_ALL, args); } else if (!Q_stricmp(buf, "vtchat")) { BotVoiceChatCommand(bs, SAY_TEAM, args); } else if (!Q_stricmp(buf, "vtell")) { BotVoiceChatCommand(bs, SAY_TELL, args); } #endif else if (!Q_stricmp(buf, "scores")) { /*FIXME: parse scores?*/ } else if (!Q_stricmp(buf, "clientLevelShot")) { /*ignore*/ } } //add the delta angles to the bot's current view angles for (j = 0; j < 3; j++) { bs->viewangles[j] = AngleMod(bs->viewangles[j] + SHORT2ANGLE(bs->cur_ps.delta_angles[j])); } //increase the local time of the bot bs->ltime += thinktime; // bs->thinktime = thinktime; //origin of the bot VectorCopy(bs->cur_ps.origin, bs->origin); //eye coordinates of the bot VectorCopy(bs->cur_ps.origin, bs->eye); bs->eye[2] += bs->cur_ps.viewheight; //get the area the bot is in bs->areanum = BotPointAreaNum(bs->origin); //the real AI BotDeathmatchAI(bs, thinktime); //set the weapon selection every AI frame EA_SelectWeapon(bs->playernum, bs->weaponnum); //subtract the delta angles for (j = 0; j < 3; j++) { bs->viewangles[j] = AngleMod(bs->viewangles[j] - SHORT2ANGLE(bs->cur_ps.delta_angles[j])); } //everything was ok return qtrue; }
/* ============== BotAI ============== */ int BotAI( int client, float thinktime ) { bot_state_t *bs; char buf[1024], *args; int j; trap_EA_ResetInput( client, NULL ); // bs = botstates[client]; if ( !bs || !bs->inuse ) { BotAI_Print( PRT_FATAL, "client %d hasn't been setup\n", client ); return BLERR_AICLIENTNOTSETUP; } //retrieve the current client state BotAI_GetClientState( client, &bs->cur_ps ); //retrieve any waiting console messages while ( trap_BotGetServerCommand( client, buf, sizeof( buf ) ) ) { //have buf point to the command and args to the command arguments args = strchr( buf, ' ' ); if ( !args ) { continue; } *args++ = '\0'; //remove color espace sequences from the arguments Q_CleanStr( args ); //botai_import.Print(PRT_MESSAGE, "ConsoleMessage: \"%s\"\n", buf); if ( !Q_stricmp( buf, "cp " ) ) { /*CenterPrintf*/ } else if ( !Q_stricmp( buf, "cs" ) ) { /*ConfigStringModified*/ } else if ( !Q_stricmp( buf, "print" ) ) { trap_BotQueueConsoleMessage( bs->cs, CMS_NORMAL, args ); } else if ( !Q_stricmp( buf, "chat" ) ) { trap_BotQueueConsoleMessage( bs->cs, CMS_CHAT, args ); } else if ( !Q_stricmp( buf, "tchat" ) ) { trap_BotQueueConsoleMessage( bs->cs, CMS_CHAT, args ); } else if ( !Q_stricmp( buf, "scores" ) ) { /*FIXME: parse scores?*/ } else if ( !Q_stricmp( buf, "clientLevelShot" ) ) { /*ignore*/ } } //add the delta angles to the bot's current view angles for ( j = 0; j < 3; j++ ) { bs->viewangles[j] = AngleMod( bs->viewangles[j] + SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) ); } //increase the local time of the bot bs->ltime += thinktime; // bs->thinktime = thinktime; //origin of the bot VectorCopy( bs->cur_ps.origin, bs->origin ); //eye coordinates of the bot VectorCopy( bs->cur_ps.origin, bs->eye ); bs->eye[2] += bs->cur_ps.viewheight; //get the area the bot is in bs->areanum = BotPointAreaNum( bs->origin ); //the real AI BotDeathmatchAI( bs, thinktime ); //set the weapon selection every AI frame trap_EA_SelectWeapon( bs->client, bs->weaponnum ); //subtract the delta angles for ( j = 0; j < 3; j++ ) { bs->viewangles[j] = AngleMod( bs->viewangles[j] - SHORT2ANGLE( bs->cur_ps.delta_angles[j] ) ); } //everything was ok return BLERR_NOERROR; }
void G_BotSpectatorThink( gentity_t *self ) { char buf[MAX_STRING_CHARS]; //hacky ping fix self->client->ps.ping = rand() % 50 + 50; //acknowledge recieved console messages //MUST be done while ( trap_BotGetServerCommand( self->client->ps.clientNum, buf, sizeof( buf ) ) ); if ( self->client->ps.pm_flags & PMF_QUEUED ) { //we're queued to spawn, all good //check for humans in the spawn que { spawnQueue_t *sq; if ( self->client->pers.team != TEAM_NONE ) { sq = &level.team[ self->client->pers.team ].spawnQueue; } else { sq = nullptr; } if ( sq && PlayersBehindBotInSpawnQueue( self ) ) { G_RemoveFromSpawnQueue( sq, self->s.number ); G_PushSpawnQueue( sq, self->s.number ); } } return; } //reset stuff BotSetTarget( &self->botMind->goal, nullptr, nullptr ); self->botMind->bestEnemy.ent = nullptr; BotResetEnemyQueue( &self->botMind->enemyQueue ); self->botMind->currentNode = nullptr; memset( &self->botMind->nav, 0, sizeof( self->botMind->nav ) ); self->botMind->futureAimTime = 0; self->botMind->futureAimTimeInterval = 0; self->botMind->numRunningNodes = 0; memset( self->botMind->runningNodes, 0, sizeof( self->botMind->runningNodes ) ); if ( self->client->sess.restartTeam == TEAM_NONE ) { int teamnum = self->client->pers.team; int clientNum = self->client->ps.clientNum; if ( teamnum == TEAM_HUMANS ) { self->client->pers.classSelection = PCL_HUMAN_NAKED; self->client->ps.stats[STAT_CLASS] = PCL_HUMAN_NAKED; BotSetNavmesh( self, PCL_HUMAN_NAKED ); //we want to spawn with rifle unless it is disabled or we need to build if ( g_bot_rifle.integer ) { self->client->pers.humanItemSelection = WP_MACHINEGUN; } else { self->client->pers.humanItemSelection = WP_HBUILD; } } else if ( teamnum == TEAM_ALIENS ) { self->client->pers.classSelection = PCL_ALIEN_LEVEL0; self->client->ps.stats[STAT_CLASS] = PCL_ALIEN_LEVEL0; BotSetNavmesh( self, PCL_ALIEN_LEVEL0 ); } G_PushSpawnQueue( &level.team[ teamnum ].spawnQueue, clientNum ); } }
void G_BotThink( gentity_t *self ) { char buf[MAX_STRING_CHARS]; usercmd_t *botCmdBuffer; vec3_t nudge; botRouteTarget_t routeTarget; self->botMind->cmdBuffer = self->client->pers.cmd; botCmdBuffer = &self->botMind->cmdBuffer; //reset command buffer usercmdClearButtons( botCmdBuffer->buttons ); // for nudges, e.g. spawn blocking nudge[0] = botCmdBuffer->doubleTap != dtType_t::DT_NONE ? botCmdBuffer->forwardmove : 0; nudge[1] = botCmdBuffer->doubleTap != dtType_t::DT_NONE ? botCmdBuffer->rightmove : 0; nudge[2] = botCmdBuffer->doubleTap != dtType_t::DT_NONE ? botCmdBuffer->upmove : 0; botCmdBuffer->forwardmove = 0; botCmdBuffer->rightmove = 0; botCmdBuffer->upmove = 0; botCmdBuffer->doubleTap = dtType_t::DT_NONE; //acknowledge recieved server commands //MUST be done while ( trap_BotGetServerCommand( self->client->ps.clientNum, buf, sizeof( buf ) ) ); BotSearchForEnemy( self ); BotFindClosestBuildings( self ); BotFindDamagedFriendlyStructure( self ); BotCalculateStuckTime( self ); //use medkit when hp is low if ( self->entity->Get<HealthComponent>()->Health() < BOT_USEMEDKIT_HP && BG_InventoryContainsUpgrade( UP_MEDKIT, self->client->ps.stats ) ) { BG_ActivateUpgrade( UP_MEDKIT, self->client->ps.stats ); } //infinite funds cvar if ( g_bot_infinite_funds.integer ) { G_AddCreditToClient( self->client, HUMAN_MAX_CREDITS, true ); } //hacky ping fix self->client->ps.ping = rand() % 50 + 50; if ( !self->botMind->behaviorTree ) { Log::Warn( "NULL behavior tree" ); return; } // always update the path corridor if ( self->botMind->goal.inuse ) { BotTargetToRouteTarget( self, self->botMind->goal, &routeTarget ); trap_BotUpdatePath( self->s.number, &routeTarget, &self->botMind->nav ); //BotClampPos( self ); } self->botMind->behaviorTree->run( self, ( AIGenericNode_t * ) self->botMind->behaviorTree ); // if we were nudged... VectorAdd( self->client->ps.velocity, nudge, self->client->ps.velocity ); self->client->pers.cmd = self->botMind->cmdBuffer; }
/* * BotAI */ int BotAI(int client, float thinktime) { bot_state_t *bs; char buf[1024], *args; int j; trap_EA_ResetInput(client); bs = botstates[client]; if(!bs || !bs->inuse){ BotAI_Print(PRT_FATAL, "BotAI: client %d is not setup\n", client); return qfalse; } /* retrieve the current client state */ BotAI_GetClientState(client, &bs->cur_ps); /* retrieve any waiting server commands */ while(trap_BotGetServerCommand(client, buf, sizeof(buf))){ /* have buf point to the command and args to the command arguments */ args = strchr(buf, ' '); if(!args) continue; *args++ = '\0'; /* remove color espace sequences from the arguments */ RemoveColorEscapeSequences(args); if(!Q_stricmp(buf, "cp ")){ /*CenterPrintf*/ }else if(!Q_stricmp(buf, "cs")){/*ConfigStringModified*/ }else if(!Q_stricmp(buf, "print")){ /* remove first and last quote from the chat message */ memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; trap_BotQueueConsoleMessage(bs->cs, CMS_NORMAL, args); }else if(!Q_stricmp(buf, "chat")){ /* remove first and last quote from the chat message */ memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args); }else if(!Q_stricmp(buf, "tchat")){ /* remove first and last quote from the chat message */ memmove(args, args+1, strlen(args)); args[strlen(args)-1] = '\0'; trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, args); } #ifdef MISSIONPACK else if(!Q_stricmp(buf, "vchat")) BotVoiceChatCommand(bs, SAY_ALL, args); else if(!Q_stricmp(buf, "vtchat")) BotVoiceChatCommand(bs, SAY_TEAM, args); else if(!Q_stricmp(buf, "vtell")) BotVoiceChatCommand(bs, SAY_TELL, args); #endif else if(!Q_stricmp(buf, "scores")){ /*FIXME: parse scores?*/ }else if(!Q_stricmp(buf, "clientLevelShot")){ /*ignore*/ } } /* add the delta angles to the bot's current view angles */ for(j = 0; j < 3; j++) bs->viewangles[j] = modeuler(bs->viewangles[j] + SHORT2ANGLE(bs->cur_ps.delta_angles[j])); /* increase the local time of the bot */ bs->ltime += thinktime; bs->thinktime = thinktime; /* origin of the bot */ copyv3(bs->cur_ps.origin, bs->origin); /* eye coordinates of the bot */ copyv3(bs->cur_ps.origin, bs->eye); bs->eye[2] += bs->cur_ps.viewheight; /* get the area the bot is in */ bs->areanum = BotPointAreaNum(bs->origin); /* the real AI */ BotDeathmatchAI(bs, thinktime); /* set the weapon selection every AI frame */ trap_EA_SelectWeapon(bs->client, bs->weaponnum); /* subtract the delta angles */ for(j = 0; j < 3; j++) bs->viewangles[j] = modeuler(bs->viewangles[j] - SHORT2ANGLE(bs->cur_ps.delta_angles[j])); /* everything was ok */ return qtrue; }
/* ============== BotAI ============== */ int BotAI(int client, float thinktime) { bot_state_t *bs; char buf[1024], *args; int j; #ifdef _DEBUG int start = 0; int end = 0; #endif trap_EA_ResetInput(client); // bs = botstates[client]; if (!bs || !bs->inuse) { return qfalse; } //retrieve the current client state BotAI_GetClientState( client, &bs->cur_ps ); //retrieve any waiting server commands while( trap_BotGetServerCommand(client, buf, sizeof(buf)) ) { //have buf point to the command and args to the command arguments args = strchr( buf, ' '); if (!args) continue; *args++ = '\0'; //remove color espace sequences from the arguments RemoveColorEscapeSequences( args ); if (!Q_stricmp(buf, "cp ")) { /*CenterPrintf*/ } else if (!Q_stricmp(buf, "cs")) { /*ConfigStringModified*/ } else if (!Q_stricmp(buf, "scores")) { /*FIXME: parse scores?*/ } else if (!Q_stricmp(buf, "clientLevelShot")) { /*ignore*/ } } //add the delta angles to the bot's current view angles for (j = 0; j < 3; j++) { bs->viewangles[j] = AngleMod(bs->viewangles[j] + SHORT2ANGLE(bs->cur_ps.delta_angles[j])); } //increase the local time of the bot bs->ltime += thinktime; // bs->thinktime = thinktime; //origin of the bot VectorCopy(bs->cur_ps.origin, bs->origin); //eye coordinates of the bot VectorCopy(bs->cur_ps.origin, bs->eye); bs->eye[2] += bs->cur_ps.viewheight; //get the area the bot is in #ifdef _DEBUG start = trap_Milliseconds(); #endif DOM_StandardBotAI(bs, thinktime); //DOM_StandardBotAI2(bs, thinktime); #ifdef _DEBUG end = trap_Milliseconds(); trap_Cvar_Update(&bot_debugmessages); if (bot_debugmessages.integer) { Com_Printf("Single AI frametime: %i\n", (end - start)); } #endif //subtract the delta angles for (j = 0; j < 3; j++) { bs->viewangles[j] = AngleMod(bs->viewangles[j] - SHORT2ANGLE(bs->cur_ps.delta_angles[j])); } //everything was ok return qtrue; }