/* ================== BotMatch_CTF ================== */ void BotMatch_CTF( bot_state_t *bs, bot_match_t *match ) { char flag[128], netname[MAX_NETNAME]; trap_BotMatchVariable( match, FLAG, flag, sizeof( flag ) ); if ( match->subtype & ST_GOTFLAG ) { if ( !Q_stricmp( flag, "red" ) ) { bs->redflagstatus = 1; if ( BotCTFTeam( bs ) == CTF_TEAM_BLUE ) { trap_BotMatchVariable( match, NETNAME, netname, sizeof( netname ) ); bs->flagcarrier = ClientFromName( netname ); } } else { bs->blueflagstatus = 1; if ( BotCTFTeam( bs ) == CTF_TEAM_RED ) { trap_BotMatchVariable( match, NETNAME, netname, sizeof( netname ) ); bs->flagcarrier = ClientFromName( netname ); } } bs->flagstatuschanged = 1; } else if ( match->subtype & ST_CAPTUREDFLAG ) { bs->redflagstatus = 0; bs->blueflagstatus = 0; bs->flagcarrier = 0; bs->flagstatuschanged = 1; } else if ( match->subtype & ST_RETURNEDFLAG ) { if ( !Q_stricmp( flag, "red" ) ) { bs->redflagstatus = 0; } else { bs->blueflagstatus = 0;} bs->flagstatuschanged = 1; } }
/* ================== BotMatch_Kill ================== */ void BotMatch_Kill(bot_state_t *bs, bot_match_t *match) { char enemy[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; int client; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; trap_BotMatchVariable(match, ENEMY, enemy, sizeof(enemy)); // client = FindEnemyByName(bs, enemy); if (client < 0) { BotAI_BotInitialChat(bs, "whois", enemy, NULL); trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TELL); return; } bs->teamgoal.entitynum = client; //set the time to send a message to the team mates bs->teammessage_time = FloatTime() + 2 * random(); //set the ltg type bs->ltgtype = LTG_KILL; //set the team goal time bs->teamgoal_time = FloatTime() + TEAM_KILL_SOMEONE; // BotSetTeamStatus(bs); #ifdef DEBUG BotPrintTeamGoal(bs); #endif //DEBUG }
void BotMatch_WrongWall(bot_state_t* bs, bot_match_t *match){ char netname[MAX_MESSAGE_SIZE]; char buf[MAX_INFO_STRING]; int client; if(gametype != GT_SPRAY) return; // talking about me ? (avoid clientfromname, its ambiguous) trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); trap_GetConfigstring(CS_PLAYERS + bs->client, buf, sizeof(buf)); Q_CleanStr( buf ); if (!Q_stricmp(Info_ValueForKey(buf, "n"), netname)){ // could be someone with same name, so make (more) sure if( ClientInSprayroom(bs->client) ){ bs->which_wall = BotChooseCorrectWall(bs); bs->enemy = -1; // chat BotAI_BotInitialChat(bs, "wall_missed", NULL); trap_BotEnterChat(bs->cs, 0, CHAT_ALL); return; } } // check if opposite team client = ClientFromName(netname); if(!BotSameTeam(bs, client)){ float rnd; // flame rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_INSULT, 0, 1); if(random() > rnd) return; BotAI_BotInitialChat(bs, "wall_insult", netname, NULL); trap_BotEnterChat(bs->cs, 0, CHAT_ALL); } }
/* ================== BotAddressedToBot ================== */ int BotAddressedToBot( bot_state_t *bs, bot_match_t *match ) { char addressedto[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; char name[MAX_MESSAGE_SIZE]; char botname[128]; int client; bot_match_t addresseematch; trap_BotMatchVariable( match, NETNAME, netname, sizeof( netname ) ); client = ClientFromName( netname ); if ( client < 0 ) { return qfalse; } if ( !BotSameTeam( bs, client ) ) { return qfalse; } //if the message is addressed to someone if ( match->subtype & ST_ADDRESSED ) { trap_BotMatchVariable( match, ADDRESSEE, addressedto, sizeof( addressedto ) ); //the name of this bot ClientName( bs->client, botname, 128 ); // while ( trap_BotFindMatch( addressedto, &addresseematch, MTCONTEXT_ADDRESSEE ) ) { if ( addresseematch.type == MSG_EVERYONE ) { return qtrue; } else if ( addresseematch.type == MSG_MULTIPLENAMES ) { trap_BotMatchVariable( &addresseematch, TEAMMATE, name, sizeof( name ) ); if ( strlen( name ) ) { if ( stristr( botname, name ) ) { return qtrue; } if ( stristr( bs->subteam, name ) ) { return qtrue; } } trap_BotMatchVariable( &addresseematch, MORE, addressedto, MAX_MESSAGE_SIZE ); } else { trap_BotMatchVariable( &addresseematch, TEAMMATE, name, MAX_MESSAGE_SIZE ); if ( strlen( name ) ) { if ( stristr( botname, name ) ) { return qtrue; } if ( stristr( bs->subteam, name ) ) { return qtrue; } } break; } } //Com_sprintf(buf, sizeof(buf), "not addressed to me but %s", addressedto); //trap_EA_Say(bs->client, buf); return qfalse; } else { //make sure not everyone reacts to this message if ( random() > (float ) 1.0 / ( NumPlayersOnSameTeam( bs ) - 1 ) ) { return qfalse; } } return qtrue; }
/* ============== BotTeamLeader ============== */ int BotTeamLeader(bot_state_t *bs) { int leader; leader = ClientFromName(bs->teamleader); if (leader < 0) return qfalse; if (!botstates[leader] || !botstates[leader]->inuse) return qfalse; return qtrue; }
/* ================== BotMatch_CTF ================== */ void BotMatch_CTF(bot_state_t *bs, bot_match_t *match) { char flag[128], netname[MAX_NETNAME]; if (gametype == GT_CTF) { trap_BotMatchVariable(match, FLAG, flag, sizeof(flag)); if (match->subtype & ST_GOTFLAG) { if (!Q_stricmp(flag, "red")) { bs->redflagstatus = 1; if (BotTeam(bs) == TEAM_BLUE) { trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); bs->flagcarrier = ClientFromName(netname); } } else { bs->blueflagstatus = 1; if (BotTeam(bs) == TEAM_RED) { trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); bs->flagcarrier = ClientFromName(netname); } } bs->flagstatuschanged = 1; bs->lastflagcapture_time = FloatTime(); } else if (match->subtype & ST_CAPTUREDFLAG) { bs->redflagstatus = 0; bs->blueflagstatus = 0; bs->flagcarrier = 0; bs->flagstatuschanged = 1; } else if (match->subtype & ST_RETURNEDFLAG) { if (!Q_stricmp(flag, "red")) bs->redflagstatus = 0; else bs->blueflagstatus = 0; bs->flagstatuschanged = 1; } } #ifdef MISSIONPACK else if (gametype == GT_1FCTF) { if (match->subtype & ST_1FCTFGOTFLAG) { trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); bs->flagcarrier = ClientFromName(netname); } } #endif }
/* ================== BotValidTeamLeader ================== */ int BotValidTeamLeader( bot_state_t *bs ) { if ( !strlen( bs->teamleader ) ) { return qfalse; } if ( ClientFromName( bs->teamleader ) == -1 ) { return qfalse; } return qtrue; }
int BotValidTeamLeader(bot_state_t *bs) { int leadclient; if (!strlen(bs->teamleader)) return qfalse; leadclient = ClientFromName(bs->teamleader); if (leadclient == -1) return qfalse; // client in unserem team ? if(!BotSameTeam(bs, leadclient)) return qfalse; // client bot ? // if this player is not a bot if ( !(g_entities[leadclient].r.svFlags & SVF_BOT) ) return qfalse; return qtrue; }
/* ================== BotMatch_CheckPoint ================== */ void BotMatch_CheckPoint(bot_state_t *bs, bot_match_t *match) { int areanum, client; char buf[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; vec3_t position; bot_waypoint_t *cp; if (!TeamPlayIsOn()) return; // trap_BotMatchVariable(match, POSITION, buf, MAX_MESSAGE_SIZE); VectorClear(position); // trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); //BotGPSToPosition(buf, position); sscanf(buf, "%f %f %f", &position[0], &position[1], &position[2]); position[2] += 0.5; areanum = BotPointAreaNum(position); if (!areanum) { if (BotAddressedToBot(bs, match)) { BotAI_BotInitialChat(bs, "checkpoint_invalid", NULL); trap_BotEnterChat(bs->cs, client, CHAT_TELL); } return; } // trap_BotMatchVariable(match, NAME, buf, MAX_MESSAGE_SIZE); //check if there already exists a checkpoint with this name cp = BotFindWayPoint(bs->checkpoints, buf); if (cp) { if (cp->next) cp->next->prev = cp->prev; if (cp->prev) cp->prev->next = cp->next; else bs->checkpoints = cp->next; cp->inuse = qfalse; } //create a new check point cp = BotCreateWayPoint(buf, position, areanum); //add the check point to the bot's known chech points cp->next = bs->checkpoints; if (bs->checkpoints) bs->checkpoints->prev = cp; bs->checkpoints = cp; // if (BotAddressedToBot(bs, match)) { Com_sprintf(buf, sizeof(buf), "%1.0f %1.0f %1.0f", cp->goal.origin[0], cp->goal.origin[1], cp->goal.origin[2]); BotAI_BotInitialChat(bs, "checkpoint_confirm", cp->name, buf, NULL); trap_BotEnterChat(bs->cs, client, CHAT_TELL); } }
/* ================== BotMatch_Suicide ================== */ void BotMatch_Suicide(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int client; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // trap_EA_Command(bs->client, "kill"); // trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); // BotVoiceChat(bs, client, VOICECHAT_TAUNT); trap_EA_Action(bs->client, ACTION_AFFIRMATIVE); }
/* ================== BotMatch_LeaveSubteam ================== */ void BotMatch_LeaveSubteam(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int client; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // if (strlen(bs->subteam)) { BotAI_BotInitialChat(bs, "leftteam", bs->subteam, NULL); trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TELL); } //end if strcpy(bs->subteam, ""); }
/* ================== BotMatch_JoinSubteam ================== */ void BotMatch_JoinSubteam(bot_state_t *bs, bot_match_t *match) { char teammate[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; int client; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; //get the sub team name trap_BotMatchVariable(match, TEAMNAME, teammate, sizeof(teammate)); //set the sub team name strncpy(bs->subteam, teammate, 32); bs->subteam[31] = '\0'; // trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "joinedteam", teammate, NULL); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TELL); }
/* ================== BotMatch_Dismiss ================== */ void BotMatch_Dismiss(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int client; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); // bs->decisionmaker = client; // bs->ltgtype = 0; bs->lead_time = 0; bs->lastgoal_ltgtype = 0; // BotAI_BotInitialChat(bs, "dismissed", NULL); trap_BotEnterChat(bs->cs, client, CHAT_TELL); }
/* ================== BotMatch_DefendKeyArea ================== */ void BotMatch_DefendKeyArea(bot_state_t *bs, bot_match_t *match) { char itemname[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; int client; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; //get the match variable trap_BotMatchVariable(match, KEYAREA, itemname, sizeof(itemname)); // if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) { //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL); //trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } // trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // client = ClientFromName(netname); //the team mate who ordered bs->decisionmaker = client; bs->ordered = qtrue; bs->order_time = FloatTime(); //set the time to send a message to the team mates bs->teammessage_time = FloatTime() + 2 * random(); //set the ltg type bs->ltgtype = LTG_DEFENDKEYAREA; //get the team goal time bs->teamgoal_time = BotGetTime(match); //set the team goal time if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_DEFENDKEYAREA_TIME; //away from defending bs->defendaway_time = 0; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); #ifdef DEBUG BotPrintTeamGoal(bs); #endif //DEBUG }
/* ================== BotMatch_TaskPreference ================== */ void BotMatch_TaskPreference(bot_state_t *bs, bot_match_t *match) { char netname[MAX_NETNAME]; char teammatename[MAX_MESSAGE_SIZE]; int teammate, preference; ClientName(bs->client, netname, sizeof(netname)); if (Q_stricmp(netname, bs->teamleader) != 0) return; trap_BotMatchVariable(match, NETNAME, teammatename, sizeof(teammatename)); teammate = ClientFromName(teammatename); if (teammate < 0) return; preference = BotGetTeamMateTaskPreference(bs, teammate); switch(match->subtype) { case ST_DEFENDER: { preference &= ~TEAMTP_ATTACKER; preference |= TEAMTP_DEFENDER; break; } case ST_ATTACKER: { preference &= ~TEAMTP_DEFENDER; preference |= TEAMTP_ATTACKER; break; } case ST_ROAMER: { preference &= ~(TEAMTP_ATTACKER|TEAMTP_DEFENDER); break; } } BotSetTeamMateTaskPreference(bs, teammate, preference); // EasyClientName(teammate, teammatename, sizeof(teammatename)); BotAI_BotInitialChat(bs, "keepinmind", teammatename, NULL); trap_BotEnterChat(bs->cs, teammate, CHAT_TELL); BotVoiceChatOnly(bs, teammate, VOICECHAT_YES); trap_EA_Action(bs->client, ACTION_AFFIRMATIVE); }
/* ======================================================================================================================================= BotMatch_HelpAccompany ======================================================================================================================================= */ void BotMatch_HelpAccompany(bot_state_t *bs, bot_match_t *match) { int client, other, areanum; char teammate[MAX_MESSAGE_SIZE], netname[MAX_MESSAGE_SIZE]; char itemname[MAX_MESSAGE_SIZE]; bot_match_t teammatematch; aas_entityinfo_t entinfo; if (!TeamPlayIsOn()) { return; } // if not addressed to this bot if (!BotAddressedToBot(bs, match)) { return; } // get the team mate name trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate)); // get the client to help if (trap_BotFindMatch(teammate, &teammatematch, MTCONTEXT_TEAMMATE) && // if someone asks for him or herself teammatematch.type == MSG_ME) { // get the netname trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); other = qfalse; } else { // asked for someone else client = FindClientByName(teammate); // if this is the bot self if (client == bs->client) { other = qfalse; } else if (!BotSameTeam(bs, client)) { // FIXME: say "I don't help the enemy" return; } else { other = qtrue; } } // if the bot doesn't know who to help (FindClientByName returned -1) if (client < 0) { if (other) { BotAI_BotInitialChat(bs, "whois", teammate, NULL); } else {BotAI_BotInitialChat(bs, "whois", netname, NULL);} trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } // don't help or accompany yourself if (client == bs->client) { return; } bs->teamgoal.entitynum = -1; BotEntityInfo(client, &entinfo); // if info is valid (in PVS) if (entinfo.valid) { areanum = BotPointAreaNum(entinfo.origin); if (areanum && trap_AAS_AreaReachability(areanum)) { bs->teamgoal.entitynum = client; bs->teamgoal.areanum = areanum; VectorCopy(entinfo.origin, bs->teamgoal.origin); VectorSet(bs->teamgoal.mins, -8, -8, -8); VectorSet(bs->teamgoal.maxs, 8, 8, 8); } } // if no teamgoal yet if (bs->teamgoal.entitynum < 0) { // if near an item if (match->subtype & ST_NEARITEM) { // get the match variable trap_BotMatchVariable(match, ITEM, itemname, sizeof(itemname)); if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) { // BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL); // trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } } } if (bs->teamgoal.entitynum < 0) { if (other) { BotAI_BotInitialChat(bs, "whereis", teammate, NULL); } else {BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);} trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } // the team mate bs->teammate = client; // last time the team mate was assumed visible bs->teammatevisible_time = trap_AAS_Time(); // set the time to send a message to the team mates bs->teammessage_time = trap_AAS_Time() + 2 * random(); // get the team goal time bs->teamgoal_time = BotGetTime(match); // set the ltg type if (match->type == MSG_HELP) { bs->ltgtype = LTG_TEAMHELP; if (!bs->teamgoal_time) { bs->teamgoal_time = trap_AAS_Time() + TEAM_HELP_TIME; } } else { bs->ltgtype = LTG_TEAMACCOMPANY; if (!bs->teamgoal_time) { bs->teamgoal_time = trap_AAS_Time() + TEAM_ACCOMPANY_TIME; } bs->formation_dist = 3.5 * 32; // 3.5 meter bs->arrive_time = 0; } #ifdef DEBUG BotPrintTeamGoal(bs); #endif // DEBUG }
/* ======================================================================================================================================= BotMatch_LeadTheWay ======================================================================================================================================= */ void BotMatch_LeadTheWay(bot_state_t *bs, bot_match_t *match) { aas_entityinfo_t entinfo; char netname[MAX_MESSAGE_SIZE], teammate[MAX_MESSAGE_SIZE]; int client, areanum, other; if (!TeamPlayIsOn()) { return; } // if not addressed to this bot if (!BotAddressedToBot(bs, match)) { return; } // if someone asks for someone else if (match->subtype & ST_SOMEONE) { // get the team mate name trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate)); client = FindClientByName(teammate); // if this is the bot self if (client == bs->client) { other = qfalse; } else if (!BotSameTeam(bs, client)) { // FIXME: say "I don't help the enemy" return; } else { other = qtrue; } } else { // get the netname trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); other = qfalse; } // if the bot doesn't know who to help (FindClientByName returned -1) if (client < 0) { BotAI_BotInitialChat(bs, "whois", netname, NULL); trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } bs->lead_teamgoal.entitynum = -1; BotEntityInfo(client, &entinfo); // if info is valid (in PVS) if (entinfo.valid) { areanum = BotPointAreaNum(entinfo.origin); if (areanum && trap_AAS_AreaReachability(areanum)) { bs->lead_teamgoal.entitynum = client; bs->lead_teamgoal.areanum = areanum; VectorCopy(entinfo.origin, bs->lead_teamgoal.origin); VectorSet(bs->lead_teamgoal.mins, -8, -8, -8); VectorSet(bs->lead_teamgoal.maxs, 8, 8, 8); } } if (bs->teamgoal.entitynum < 0) { if (other) { BotAI_BotInitialChat(bs, "whereis", teammate, NULL); } else {BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);} trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } bs->lead_teammate = client; bs->lead_time = trap_AAS_Time() + TEAM_LEAD_TIME; bs->leadvisible_time = 0; bs->leadmessage_time = -(trap_AAS_Time() + 2 * random()); }
static void G_AddBot( const char *name, int skill, const char *team, const char *spawnPoint, int playerClass, int playerWeapon, int characerIndex, const char *respawn, const char *scriptName, int rank, int skills[], qboolean pow ) { #define MAX_BOTNAMES 1024 int clientNum; char *botinfo; gentity_t *bot; char *key; char *s; char *botname; // char *model; char userinfo[MAX_INFO_STRING]; // get the botinfo from bots.txt botinfo = G_GetBotInfoByName( "wolfbot" ); if ( !botinfo ) { G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name ); return; } // create the bot's userinfo userinfo[0] = '\0'; botname = Info_ValueForKey( botinfo, "funname" ); if( !botname[0] ) { botname = Info_ValueForKey( botinfo, "name" ); } Info_SetValueForKey( userinfo, "name", botname ); Info_SetValueForKey( userinfo, "rate", "25000" ); Info_SetValueForKey( userinfo, "snaps", "20" ); Info_SetValueForKey( userinfo, "skill", va("%i", skill) ); s = Info_ValueForKey(botinfo, "aifile"); if (!*s ) { trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" ); return; } // have the server allocate a client slot clientNum = trap_BotAllocateClient( 0 ); // Arnout: 0 means no prefered clientslot if ( clientNum == -1 ) { G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" ); G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" ); return; } // initialize the bot settings if( !team || !*team ) { if( PickTeam(clientNum) == TEAM_AXIS) { team = "red"; } else { team = "blue"; } } Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) ); //Info_SetValueForKey( userinfo, "skill", va( "%i", skill ) ); Info_SetValueForKey( userinfo, "team", team ); if( spawnPoint && spawnPoint[0] ) { Info_SetValueForKey( userinfo, "spawnPoint", spawnPoint ); } if (scriptName && scriptName[0]) { Info_SetValueForKey( userinfo, "scriptName", scriptName ); } /* if (playerClass > 0) { Info_SetValueForKey( userinfo, "pClass", va("%i", playerClass) ); } if (playerWeapon) { Info_SetValueForKey( userinfo, "pWeapon", va("%i", playerWeapon) ); }*/ // END Mad Doc - TDF key = "wolfbot"; if (!Q_stricmp( (char *)name, key )) { // read the botnames file, and pick a name that doesnt exist fileHandle_t f; int len, i, j, k; qboolean setname = qfalse; char botnames[8192], *pbotnames, *listbotnames[MAX_BOTNAMES], *token, *oldpbotnames; int lengthbotnames[MAX_BOTNAMES]; len = trap_FS_FOpenFile( "botfiles/botnames.txt", &f, FS_READ ); if (len >= 0) { if (len > sizeof(botnames)) { G_Error( "botfiles/botnames.txt is too big (max = %i)", (int)sizeof(botnames) ); } memset( botnames, 0, sizeof(botnames) ); trap_FS_Read( botnames, len, f ); pbotnames = botnames; // read them in i = 0; oldpbotnames = pbotnames; while ((token = COM_Parse( &pbotnames ))) { if (!token[0]) break; listbotnames[i] = strstr( oldpbotnames, token ); lengthbotnames[i] = strlen(token); listbotnames[i][lengthbotnames[i]] = 0; oldpbotnames = pbotnames; if (++i == MAX_BOTNAMES) break; } // if (i > 2) { j = rand() % (i-1); // start at a random spot inthe list for( k = j + 1; k != j; k++ ) { if( k == i ) { k = -1; // gets increased on next loop continue; } if (ClientFromName( listbotnames[k] ) == -1) { // found an unused name Info_SetValueForKey( userinfo, "name", listbotnames[k] ); setname = qtrue; break; } } } // trap_FS_FCloseFile( f ); } if (!setname) { Info_SetValueForKey( userinfo, "name", va("wolfbot_%i", clientNum+1) ); } } else { Info_SetValueForKey( userinfo, "name", name ); } // if a character was specified, put the index of that character filename in the CS_CHARACTERS table in the userinfo if( characerIndex != -1 ) { Info_SetValueForKey( userinfo, "ch", va( "%i", characerIndex ) ); } // if a rank was specified, use that /* if (rank != -1) { Info_SetValueForKey(userinfo, "rank", va("%i", rank)); }*/ // END Mad Doc - TDF bot = &g_entities[ clientNum ]; bot->r.svFlags |= SVF_BOT; if( pow ) { bot->r.svFlags |= SVF_POW; } bot->inuse = qtrue; bot->aiName = bot->client->pers.netname; // register the userinfo trap_SetUserinfo( clientNum, userinfo ); // have it connect to the game as a normal client if ((s = ClientConnect( clientNum, qtrue, qtrue ))) { G_Printf( S_COLOR_RED "Unable to add bot: %s\n", s ); return; } SetTeam( bot, (char *)team, qtrue, -1, -1, qfalse ); /* if( skills ) { int i; for( i = 0; i < SK_NUM_SKILLS; i++ ) { bot->client->sess.skill[i] = skills[i]; } }*/ return; }
/* ================== BotMatch_Camp ================== */ void BotMatch_Camp(bot_state_t *bs, bot_match_t *match) { int client, areanum; char netname[MAX_MESSAGE_SIZE]; char itemname[MAX_MESSAGE_SIZE]; aas_entityinfo_t entinfo; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); //asked for someone else client = FindClientByName(netname); //if there's no valid client with this name if (client < 0) { BotAI_BotInitialChat(bs, "whois", netname, NULL); trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } //get the match variable trap_BotMatchVariable(match, KEYAREA, itemname, sizeof(itemname)); //in CTF it could be the base if (match->subtype & ST_THERE) { //camp at the spot the bot is currently standing bs->teamgoal.entitynum = bs->entitynum; bs->teamgoal.areanum = bs->areanum; VectorCopy(bs->origin, bs->teamgoal.origin); VectorSet(bs->teamgoal.mins, -8, -8, -8); VectorSet(bs->teamgoal.maxs, 8, 8, 8); } else if (match->subtype & ST_HERE) { //if this is the bot self if (client == bs->client) return; // bs->teamgoal.entitynum = -1; BotEntityInfo(client, &entinfo); //if info is valid (in PVS) if (entinfo.valid) { areanum = BotPointAreaNum(entinfo.origin); if (areanum) {// && trap_AAS_AreaReachability(areanum)) { //NOTE: just assume the bot knows where the person is //if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, client)) { bs->teamgoal.entitynum = client; bs->teamgoal.areanum = areanum; VectorCopy(entinfo.origin, bs->teamgoal.origin); VectorSet(bs->teamgoal.mins, -8, -8, -8); VectorSet(bs->teamgoal.maxs, 8, 8, 8); //} } } //if the other is not visible if (bs->teamgoal.entitynum < 0) { BotAI_BotInitialChat(bs, "whereareyou", netname, NULL); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TELL); return; } } else if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) { //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL); //client = ClientFromName(netname); //trap_BotEnterChat(bs->cs, client, CHAT_TELL); return; } // bs->decisionmaker = client; bs->ordered = qtrue; bs->order_time = FloatTime(); //set the time to send a message to the team mates bs->teammessage_time = FloatTime() + 2 * random(); //set the ltg type bs->ltgtype = LTG_CAMPORDER; //get the team goal time bs->teamgoal_time = BotGetTime(match); //set the team goal time if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_CAMP_TIME; //not arrived yet bs->arrive_time = 0; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); #ifdef DEBUG BotPrintTeamGoal(bs); #endif //DEBUG }
// cyr_drop{ void BotMatch_DropCart(bot_state_t *bs, bot_match_t *match) { int client, areanum; char netname[MAX_MESSAGE_SIZE]; aas_entityinfo_t entinfo; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; //get the netname trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); //if the bot doesn't know who to help (FindClientByName returned -1) if (client < 0) { BotAI_BotInitialChat(bs, "whois", netname, NULL); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TELL); return; } //don't help or accompany yourself if (client == bs->client) { return; } // bs->teamgoal.entitynum = -1; BotEntityInfo(client, &entinfo); //if info is valid (in PVS) if (entinfo.valid) { areanum = BotPointAreaNum(entinfo.origin); if (areanum) {// && trap_AAS_AreaReachability(areanum)) { bs->teamgoal.entitynum = client; bs->teamgoal.areanum = areanum; VectorCopy(entinfo.origin, bs->teamgoal.origin); VectorSet(bs->teamgoal.mins, -8, -8, -8); VectorSet(bs->teamgoal.maxs, 8, 8, 8); } } if (bs->teamgoal.entitynum < 0) { BotAI_BotInitialChat(bs, "whereareyou", netname, NULL); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TEAM); return; } //the team mate bs->teammate = client; // trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // client = ClientFromName(netname); //the team mate who ordered bs->decisionmaker = client; // bs->ordered = qtrue; //bs->order_time = FloatTime(); //last time the team mate was assumed visible bs->teammatevisible_time = FloatTime(); //set the time to send a message to the team mates bs->teammessage_time = FloatTime() + 1 * random(); //set the ltg type bs->ltgtype = LTG_GIVECART; //G_Printf("^4giving cart! \n"); // cyr 20055 bs->teamgoal_time = FloatTime() + SYC_CART_EXCHANGE_TIME; }
/* ================== BotMatch_WhereAreYou ================== */ void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) { float dist, bestdist; int i, bestitem, redtt, bluett, client; bot_goal_t goal; char netname[MAX_MESSAGE_SIZE]; char *nearbyitems[] = { "Shotgun", "Grenade Launcher", "Rocket Launcher", "Plasmagun", "Railgun", "Lightning Gun", "BFG10K", "Quad Damage", "Regeneration", "Battle Suit", "Speed", "Invisibility", "Flight", "Armor", "Heavy Armor", "Red Flag", "Blue Flag", #ifdef MISSIONPACK "Nailgun", "Prox Launcher", "Chaingun", "Scout", "Guard", "Doubler", "Ammo Regen", "Neutral Flag", "Red Obelisk", "Blue Obelisk", "Neutral Obelisk", #endif NULL }; // if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; bestitem = -1; bestdist = 999999; for (i = 0; nearbyitems[i]; i++) { dist = BotNearestVisibleItem(bs, nearbyitems[i], &goal); if (dist < bestdist) { bestdist = dist; bestitem = i; } } if (bestitem != -1) { if (gametype == GT_CTF #ifdef MISSIONPACK || gametype == GT_1FCTF #endif ) { redtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_redflag.areanum, TFL_DEFAULT); bluett = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_blueflag.areanum, TFL_DEFAULT); if (redtt < (redtt + bluett) * 0.4) { BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "red", NULL); } else if (bluett < (redtt + bluett) * 0.4) { BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "blue", NULL); } else { BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL); } } #ifdef MISSIONPACK else if (gametype == GT_OBELISK || gametype == GT_HARVESTER) { redtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, redobelisk.areanum, TFL_DEFAULT); bluett = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, blueobelisk.areanum, TFL_DEFAULT); if (redtt < (redtt + bluett) * 0.4) { BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "red", NULL); } else if (bluett < (redtt + bluett) * 0.4) { BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "blue", NULL); } else { BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL); } } #endif else { BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL); } trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TELL); } }
/* ================== BotMatch_WhatAreYouDoing ================== */ void BotMatch_WhatAreYouDoing(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; char goalname[MAX_MESSAGE_SIZE]; int client; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // switch(bs->ltgtype) { case LTG_TEAMHELP: { EasyClientName(bs->teammate, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "helping", netname, NULL); break; } case LTG_TEAMACCOMPANY: { EasyClientName(bs->teammate, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "accompanying", netname, NULL); break; } case LTG_DEFENDKEYAREA: { trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname)); BotAI_BotInitialChat(bs, "defending", goalname, NULL); break; } case LTG_GETITEM: { trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname)); BotAI_BotInitialChat(bs, "gettingitem", goalname, NULL); break; } case LTG_KILL: { ClientName(bs->teamgoal.entitynum, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "killing", netname, NULL); break; } case LTG_CAMP: case LTG_CAMPORDER: { BotAI_BotInitialChat(bs, "camping", NULL); break; } case LTG_PATROL: { BotAI_BotInitialChat(bs, "patrolling", NULL); break; } case LTG_GETFLAG: { BotAI_BotInitialChat(bs, "capturingflag", NULL); break; } case LTG_RUSHBASE: { BotAI_BotInitialChat(bs, "rushingbase", NULL); break; } case LTG_RETURNFLAG: { BotAI_BotInitialChat(bs, "returningflag", NULL); break; } #ifdef MISSIONPACK case LTG_ATTACKENEMYBASE: { BotAI_BotInitialChat(bs, "attackingenemybase", NULL); break; } case LTG_HARVEST: { BotAI_BotInitialChat(bs, "harvesting", NULL); break; } #endif default: { BotAI_BotInitialChat(bs, "roaming", NULL); break; } } //chat what the bot is doing trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientFromName(netname); trap_BotEnterChat(bs->cs, client, CHAT_TELL); }