/* ================== BotMatch_Kill ================== */ void BotMatch_Kill(bot_state_t *bs, bot_match_t *match) { char enemy[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; int playernum; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; BotMatchVariable(match, ENEMY, enemy, sizeof(enemy)); // playernum = FindEnemyByName(bs, enemy); if (playernum < 0) { BotAI_BotInitialChat(bs, "whois", enemy, NULL); BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, CHAT_TELL); return; } bs->teamgoal.entitynum = playernum; //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); BotPrintTeamGoal(bs); }
/* ============== BotTeamLeader ============== */ int BotTeamLeader(bot_state_t *bs) { int leader; leader = PlayerFromName(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) { BotMatchVariable(match, FLAG, flag, sizeof(flag)); if (match->subtype & ST_GOTFLAG) { if (!Q_stricmp(flag, "red")) { bs->redflagstatus = 1; if (BotTeam(bs) == TEAM_BLUE) { BotMatchVariable(match, NETNAME, netname, sizeof(netname)); bs->flagcarrier = PlayerFromName(netname); } } else { bs->blueflagstatus = 1; if (BotTeam(bs) == TEAM_RED) { BotMatchVariable(match, NETNAME, netname, sizeof(netname)); bs->flagcarrier = PlayerFromName(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) { BotMatchVariable(match, NETNAME, netname, sizeof(netname)); bs->flagcarrier = PlayerFromName(netname); bs->lastflagcapture_time = FloatTime(); } } #endif }
/* ================== BotMatch_CheckPoint ================== */ void BotMatch_CheckPoint(bot_state_t *bs, bot_match_t *match) { int areanum, playernum; char buf[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; vec3_t position; bot_waypoint_t *cp; if (!TeamPlayIsOn()) return; // BotMatchVariable(match, POSITION, buf, MAX_MESSAGE_SIZE); VectorClear(position); // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(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); BotEnterChat(bs->cs, playernum, CHAT_TELL); } return; } // 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); BotEnterChat(bs->cs, playernum, CHAT_TELL); } }
/* ================== BotMatch_Suicide ================== */ void BotMatch_Suicide(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // EA_Command(bs->playernum, "kill"); // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); // BotVoiceChat(bs, playernum, VOICECHAT_TAUNT); EA_Action(bs->playernum, ACTION_AFFIRMATIVE); }
/* ================== BotMatch_LeaveSubteam ================== */ void BotMatch_LeaveSubteam(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; 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); BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, CHAT_TELL); } //end if strcpy(bs->subteam, ""); }
/* ================== BotMatch_Dismiss ================== */ void BotMatch_Dismiss(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); // bs->decisionmaker = playernum; // bs->ltgtype = 0; bs->lead_time = 0; bs->lastgoal_ltgtype = 0; // BotAI_BotInitialChat(bs, "dismissed", NULL); BotEnterChat(bs->cs, playernum, CHAT_TELL); }
/* ================== BotMatch_JoinSubteam ================== */ void BotMatch_JoinSubteam(bot_state_t *bs, bot_match_t *match) { char teammate[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; int playernum; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; //get the sub team name BotMatchVariable(match, TEAMNAME, teammate, sizeof(teammate)); //set the sub team name strncpy(bs->subteam, teammate, 32); bs->subteam[31] = '\0'; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "joinedteam", teammate, NULL); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, CHAT_TELL); }
/* ================== 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; PlayerName(bs->playernum, netname, sizeof(netname)); if (Q_stricmp(netname, bs->teamleader) != 0) return; BotMatchVariable(match, NETNAME, teammatename, sizeof(teammatename)); teammate = PlayerFromName(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); // EasyPlayerName(teammate, teammatename, sizeof(teammatename)); BotAI_BotInitialChat(bs, "keepinmind", teammatename, NULL); BotEnterChat(bs->cs, teammate, CHAT_TELL); BotVoiceChatOnly(bs, teammate, VOICECHAT_YES); EA_Action(bs->playernum, ACTION_AFFIRMATIVE); }
/* ================== BotMatch_DefendKeyArea ================== */ void BotMatch_DefendKeyArea(bot_state_t *bs, bot_match_t *match) { char itemname[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; int playernum; if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; //get the match variable BotMatchVariable(match, KEYAREA, itemname, sizeof(itemname)); // if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) { //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL); //BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM); return; } // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = PlayerFromName(netname); //the team mate who ordered bs->decisionmaker = playernum; 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); BotPrintTeamGoal(bs); }
/* ================== BotMatch_Camp ================== */ void BotMatch_Camp(bot_state_t *bs, bot_match_t *match) { int playernum, 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; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); //asked for someone else playernum = FindPlayerByName(netname); //if there's no valid player with this name if (playernum < 0) { BotAI_BotInitialChat(bs, "whois", netname, NULL); BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM); return; } //get the match variable 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 (playernum == bs->playernum) return; // bs->teamgoal.entitynum = -1; BotEntityInfo(playernum, &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, playernum)) { bs->teamgoal.entitynum = playernum; 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); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, CHAT_TELL); return; } } else if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) { //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL); //playernum = PlayerFromName(netname); //BotEnterChat(bs->cs, playernum, CHAT_TELL); return; } // bs->decisionmaker = playernum; 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); BotPrintTeamGoal(bs); }
/* ================== BotMatch_HelpAccompany ================== */ void BotMatch_HelpAccompany(bot_state_t *bs, bot_match_t *match) { int playernum, other, areanum; char teammate[MAX_MESSAGE_SIZE]; char 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 BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate)); //get the player to help if (BotFindMatch(teammate, &teammatematch, MTCONTEXT_TEAMMATE) && //if someone asks for him or herself teammatematch.type == MSG_ME) { //get the netname BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); other = qfalse; } else { //asked for someone else playernum = FindPlayerByName(teammate); //if this is the bot self if (playernum == bs->playernum) { other = qfalse; } else if (!BotSameTeam(bs, playernum)) { //FIXME: say "I don't help the enemy" return; } else { other = qtrue; } } //if the bot doesn't know who to help (FindPlayerByName returned -1) if (playernum < 0) { if (other) BotAI_BotInitialChat(bs, "whois", teammate, NULL); else BotAI_BotInitialChat(bs, "whois", netname, NULL); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, CHAT_TELL); return; } //don't help or accompany yourself if (playernum == bs->playernum) { return; } // bs->teamgoal.entitynum = -1; BotEntityInfo(playernum, &entinfo); //if info is valid (in PVS) if (entinfo.valid) { areanum = BotPointAreaNum(entinfo.origin); if (areanum) {// && trap_AAS_AreaReachability(areanum)) { bs->teamgoal.entitynum = playernum; 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 BotMatchVariable(match, ITEM, itemname, sizeof(itemname)); // if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) { //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL); //BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM); return; } } } // if (bs->teamgoal.entitynum < 0) { if (other) BotAI_BotInitialChat(bs, "whereis", teammate, NULL); else BotAI_BotInitialChat(bs, "whereareyou", netname, NULL); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, CHAT_TEAM); return; } //the team mate bs->teammate = playernum; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = PlayerFromName(netname); //the team mate who ordered bs->decisionmaker = playernum; 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() + 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 = FloatTime() + TEAM_HELP_TIME; } else { bs->ltgtype = LTG_TEAMACCOMPANY; if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_ACCOMPANY_TIME; bs->formation_dist = 128; bs->arrive_time = 0; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); } BotPrintTeamGoal(bs); }
/* ================== 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 playernum, 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 BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate)); playernum = FindPlayerByName(teammate); //if this is the bot self if (playernum == bs->playernum) { other = qfalse; } else if (!BotSameTeam(bs, playernum)) { //FIXME: say "I don't help the enemy" return; } else { other = qtrue; } } else { //get the netname BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); other = qfalse; } //if the bot doesn't know who to help (FindPlayerByName returned -1) if (playernum < 0) { BotAI_BotInitialChat(bs, "whois", netname, NULL); BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM); return; } // bs->lead_teamgoal.entitynum = -1; BotEntityInfo(playernum, &entinfo); //if info is valid (in PVS) if (entinfo.valid) { areanum = BotPointAreaNum(entinfo.origin); if (areanum) { // && trap_AAS_AreaReachability(areanum)) { bs->lead_teamgoal.entitynum = playernum; 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); BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM); return; } bs->lead_teammate = playernum; bs->lead_time = FloatTime() + TEAM_LEAD_TIME; bs->leadvisible_time = 0; bs->leadmessage_time = -(FloatTime() + 2 * random()); }
/* ================== BotMatch_WhereAreYou ================== */ void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) { float dist, bestdist; int i, redtt, bluett, playernum; char *teamlocation; char *bestitemname; bot_goal_t goal; gitem_t *it; char netname[MAX_MESSAGE_SIZE]; char *nearbyitems[] = { #ifdef MISSIONPACK "Red Obelisk", "Blue Obelisk", "Neutral Obelisk", #endif NULL }; // if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; bestitemname = NULL; bestdist = 999999; for (i = 1; i < BG_NumItems(); i++) { it = BG_ItemForItemNum( i ); if ( !it->classname || !*it->classname ) { continue; } //ignore health, ammo, holdables, small armor, and Red Cube and Blue Cube if ( it->giType == IT_HEALTH || it->giType == IT_AMMO || it->giType == IT_HOLDABLE || ( it->giType == IT_ARMOR && it->quantity < 50 ) #ifdef MISSIONPACK || ( it->giType == IT_TEAM && it->giTag == 0 ) #endif ) { continue; } dist = BotNearestVisibleItem(bs, it->pickup_name, &goal); if (dist < bestdist) { bestdist = dist; bestitemname = it->pickup_name; } } for (i = 0; nearbyitems[i]; i++) { dist = BotNearestVisibleItem(bs, nearbyitems[i], &goal); if (dist < bestdist) { bestdist = dist; bestitemname = nearbyitems[i]; } } if (bestitemname) { if (gametype == GT_CTF #ifdef MISSIONPACK || gametype == GT_1FCTF || gametype == GT_OBELISK || gametype == GT_HARVESTER #endif ) { #ifdef MISSIONPACK 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); } else #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); } // unpatched q3 used 'ctflocation', some games still use it if ( BotNumInitialChats( bs->cs, "teamlocation" ) ) { teamlocation = "teamlocation"; } else { teamlocation = "ctflocation"; } if (redtt < (redtt + bluett) * 0.4) { BotAI_BotInitialChat(bs, teamlocation, bestitemname, "red", NULL); } else if (bluett < (redtt + bluett) * 0.4) { BotAI_BotInitialChat(bs, teamlocation, bestitemname, "blue", NULL); } else { BotAI_BotInitialChat(bs, "location", bestitemname, NULL); } } else { BotAI_BotInitialChat(bs, "location", bestitemname, NULL); } BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, 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 playernum; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // switch(bs->ltgtype) { case LTG_TEAMHELP: { EasyPlayerName(bs->teammate, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "helping", netname, NULL); break; } case LTG_TEAMACCOMPANY: { EasyPlayerName(bs->teammate, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "accompanying", netname, NULL); break; } case LTG_DEFENDKEYAREA: { BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname)); BotAI_BotInitialChat(bs, "defending", goalname, NULL); break; } case LTG_GETITEM: { BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname)); BotAI_BotInitialChat(bs, "gettingitem", goalname, NULL); break; } case LTG_KILL: { PlayerName(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 BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = PlayerFromName(netname); BotEnterChat(bs->cs, playernum, CHAT_TELL); }