/* ================== BotMatch_GetItem ================== */ void BotMatch_GetItem(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, 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; } trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname)); client = ClientOnSameTeamFromName(bs, netname); // 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_GETITEM; //set the team goal time bs->teamgoal_time = FloatTime() + TEAM_GETITEM_TIME; // BotSetTeamStatus(bs); #ifdef DEBUG BotPrintTeamGoal(bs); #endif //DEBUG }
/* ======================================================================================================================================= BotMatch_GetItem ======================================================================================================================================= */ void BotMatch_GetItem(bot_state_t *bs, bot_match_t *match) { char itemname[MAX_MESSAGE_SIZE]; if (!TeamPlayIsOn()) { return; } // if not addressed to this bot if (!BotAddressedToBot(bs, match)) { return; } // 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; } // set the time to send a message to the team mates bs->teammessage_time = trap_AAS_Time() + 2 * random(); // set the ltg type bs->ltgtype = LTG_GETITEM; // set the team goal time bs->teamgoal_time = trap_AAS_Time() + TEAM_GETITEM_TIME; #ifdef DEBUG BotPrintTeamGoal(bs); #endif // DEBUG }
/* ================== 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_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 cheat and 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); trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } } else if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) { // BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL); // trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); return; } // set the time to send a message to the team mates bs->teammessage_time = trap_AAS_Time() + 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 = trap_AAS_Time() + TEAM_CAMP_TIME; } // the teammate that requested the camping bs->teammate = client; // not arrived yet bs->arrive_time = 0; #ifdef DEBUG BotPrintTeamGoal(bs); #endif // DEBUG }
/* ======================================================================================================================================= 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 }
/* ======================================================================================================================================= BotGetPatrolWaypoints ======================================================================================================================================= */ int BotGetPatrolWaypoints(bot_state_t *bs, bot_match_t *match) { char keyarea[MAX_MESSAGE_SIZE]; int patrolflags; bot_waypoint_t *wp, *newwp, *newpatrolpoints; bot_match_t keyareamatch; bot_goal_t goal; newpatrolpoints = NULL; patrolflags = 0; trap_BotMatchVariable(match, KEYAREA, keyarea, MAX_MESSAGE_SIZE); while (1) { if (!trap_BotFindMatch(keyarea, &keyareamatch, MTCONTEXT_PATROLKEYAREA)) { trap_EA_SayTeam(bs->client, "what do you say?"); BotFreeWaypoints(newpatrolpoints); bs->patrolpoints = NULL; return qfalse; } trap_BotMatchVariable(&keyareamatch, KEYAREA, keyarea, MAX_MESSAGE_SIZE); if (!BotGetMessageTeamGoal(bs, keyarea, &goal)) { // BotAI_BotInitialChat(bs, "cannotfind", keyarea, NULL); // trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM); BotFreeWaypoints(newpatrolpoints); bs->patrolpoints = NULL; return qfalse; } // create a new waypoint newwp = BotCreateWayPoint(keyarea, goal.origin, goal.areanum); // add the waypoint to the patrol points newwp->next = NULL; for (wp = newpatrolpoints; wp && wp->next; wp = wp->next); if (!wp) { newpatrolpoints = newwp; newwp->prev = NULL; } else { wp->next = newwp; newwp->prev = wp; } if (keyareamatch.subtype & ST_BACK) { patrolflags = PATROL_LOOP; break; } else if (keyareamatch.subtype & ST_REVERSE) { patrolflags = PATROL_REVERSE; break; } else if (keyareamatch.subtype & ST_MORE) { trap_BotMatchVariable(&keyareamatch, MORE, keyarea, MAX_MESSAGE_SIZE); } else { break; } } if (!newpatrolpoints || !newpatrolpoints->next) { trap_EA_SayTeam(bs->client, "I need more key points to patrol\n"); BotFreeWaypoints(newpatrolpoints); newpatrolpoints = NULL; return qfalse; } BotFreeWaypoints(bs->patrolpoints); bs->patrolpoints = newpatrolpoints; bs->curpatrolpoint = bs->patrolpoints; bs->patrolflags = patrolflags; return qtrue; }
/* ================== 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); }