/* ================== BotMatch_Harvest ================== */ void BotMatch_Harvest(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; if (gametype == GT_HARVESTER) { if (!neutralobelisk.areanum || !redobelisk.areanum || !blueobelisk.areanum) return; } else { return; } //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = FindPlayerByName(netname); // 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_HARVEST; //set the team goal time bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME; bs->harvestaway_time = 0; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); BotPrintTeamGoal(bs); }
/* ================== BotMatch_ReturnFlag ================== */ void BotMatch_ReturnFlag(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; //if not in CTF mode if ( gametype != GT_CTF #ifdef MISSIONPACK && gametype != GT_1FCTF #endif ) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = FindPlayerByName(netname); // 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_RETURNFLAG; //set the team goal time bs->teamgoal_time = FloatTime() + CTF_RETURNFLAG_TIME; bs->rushbaseaway_time = 0; // BotSetTeamStatus(bs); BotPrintTeamGoal(bs); }
/* ================== BotMatch_Patrol ================== */ void BotMatch_Patrol(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; //get the patrol waypoints if (!BotGetPatrolWaypoints(bs, match)) return; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = FindPlayerByName(netname); // 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_PATROL; //get the team goal time bs->teamgoal_time = BotGetTime(match); //set the team goal time if not set already if (!bs->teamgoal_time) bs->teamgoal_time = FloatTime() + TEAM_PATROL_TIME; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); BotPrintTeamGoal(bs); }
void BotMatch_NewLeader(bot_state_t *bs, bot_match_t *match) { int playernum; char netname[MAX_NETNAME]; BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = FindPlayerByName(netname); if (!BotSameTeam(bs, playernum)) return; Q_strncpyz(bs->teamleader, netname, sizeof(bs->teamleader)); }
/* ================== BotMatch_StopTeamLeaderShip ================== */ void BotMatch_StopTeamLeaderShip(bot_state_t *bs, bot_match_t *match) { int playernum; char teammate[MAX_MESSAGE_SIZE]; char netname[MAX_MESSAGE_SIZE]; if (!TeamPlayIsOn()) return; //get the team mate that stops being the team leader BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate)); //if chats for him or herself if (match->subtype & ST_I) { BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = FindPlayerByName(netname); } //chats for someone else else { playernum = FindPlayerByName(teammate); } //end else if (playernum >= 0) { if (!Q_stricmp(bs->teamleader, PlayerName(playernum, netname, sizeof(netname)))) { bs->teamleader[0] = '\0'; notleader[playernum] = qtrue; } } }
void BotMatch_EnterGame(bot_state_t *bs, bot_match_t *match) { int playernum; char netname[MAX_NETNAME]; //char buf[MAX_SAY_TEXT]; BotMatchVariable(match, NETNAME, netname, sizeof(netname)); playernum = FindPlayerByName(netname); if (playernum >= 0) { notleader[playernum] = qfalse; } //NOTE: eliza chats will catch this //if (playernum != bs->playernum) { // Com_sprintf(buf, sizeof(buf), "heya %s", netname); // EA_Say(bs->playernum, buf); //} }
/* ================== BotMatch_GetFlag ================== */ void BotMatch_GetFlag(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; if (gametype == GT_CTF) { if (!ctf_redflag.areanum || !ctf_blueflag.areanum) return; } #ifdef MISSIONPACK else if (gametype == GT_1FCTF) { if (!ctf_neutralflag.areanum || !ctf_redflag.areanum || !ctf_blueflag.areanum) return; } #endif else { return; } //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = FindPlayerByName(netname); // 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_GETFLAG; //set the team goal time bs->teamgoal_time = FloatTime() + CTF_GETFLAG_TIME; // get an alternate route in ctf if (gametype == GT_CTF) { //get an alternative route goal towards the enemy base BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs)); } // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); BotPrintTeamGoal(bs); }
/* ================== BotMatch_StartTeamLeaderShip ================== */ void BotMatch_StartTeamLeaderShip(bot_state_t *bs, bot_match_t *match) { int playernum; char teammate[MAX_MESSAGE_SIZE]; if (!TeamPlayIsOn()) return; //if chats for him or herself if (match->subtype & ST_I) { //get the team mate that will be the team leader BotMatchVariable(match, NETNAME, teammate, sizeof(teammate)); strncpy(bs->teamleader, teammate, sizeof(bs->teamleader)); bs->teamleader[sizeof(bs->teamleader)-1] = '\0'; } //chats for someone else else { //get the team mate that will be the team leader BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate)); playernum = FindPlayerByName(teammate); if (playernum >= 0) PlayerName(playernum, bs->teamleader, sizeof(bs->teamleader)); } }
/* ================== BotMatch_AttackEnemyBase ================== */ void BotMatch_AttackEnemyBase(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; if (gametype == GT_CTF) { BotMatch_GetFlag(bs, match); } #ifdef MISSIONPACK else if (gametype == GT_1FCTF || gametype == GT_OBELISK || gametype == GT_HARVESTER) { if (!redobelisk.areanum || !blueobelisk.areanum) return; } #endif else { return; } //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = FindPlayerByName(netname); // 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_ATTACKENEMYBASE; //set the team goal time bs->teamgoal_time = FloatTime() + TEAM_ATTACKENEMYBASE_TIME; bs->attackaway_time = 0; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); BotPrintTeamGoal(bs); }
/* ================== BotMatch_RushBase ================== */ void BotMatch_RushBase(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; int playernum; if (gametype == GT_CTF) { if (!ctf_redflag.areanum || !ctf_blueflag.areanum) return; } #ifdef MISSIONPACK else if (gametype == GT_1FCTF || gametype == GT_HARVESTER) { if (!redobelisk.areanum || !blueobelisk.areanum) return; } #endif else { return; } //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // BotMatchVariable(match, NETNAME, netname, sizeof(netname)); // playernum = FindPlayerByName(netname); // 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_RUSHBASE; //set the team goal time bs->teamgoal_time = FloatTime() + CTF_RUSHBASE_TIME; bs->rushbaseaway_time = 0; // BotSetTeamStatus(bs); BotPrintTeamGoal(bs); }
/* * CommandGetPlayer: "getplayer" command */ void CommandGetPlayer(char *args) { ID player; char temp[MAXAMOUNT + 1]; if (*args == 0) return; player = FindPlayerByName(args); if (player == 0) { GameMessage(GetString(hInst, IDS_NOPLAYERNAME)); return; } if (player == INVALID_ID) { GameMessage(GetString(hInst, IDS_DUPLICATEPLAYERNAME)); return; } sprintf(temp, "%d", player); RequestDMCommand(DM_GET_PLAYER, temp); }
/* * GetPlayerName: Parse str, and return a pointer to the start of the first * player name in it, or NULL if there is none in str. * If next is non-NULL and we find a player name, fill next with * a pointer to the position in str just after the end of the first player name. * str and *next can be identical. * Modifies str by null terminating player name. */ char *GetPlayerName(char *str, char **next) { char *ptr, *retval, *last_ptr; Bool quoted = False; Bool ambiguous = False; if (str == NULL) return NULL; // Skip separators while (*str == ' ' || *str == ',') str++; if (*str == 0) return NULL; // See if name is quoted if (*str == '\"') { quoted = True; retval = str + 1; } else retval = str; ptr = retval; last_ptr = NULL; // Skip to end of name and null terminate do { if (quoted) { while (*ptr != '\"' && *ptr != 0) ptr++; } else { while (*ptr != ' ' && *ptr != ',' && *ptr != 0) ptr++; } if (*ptr == '\0') { if (next != NULL) *next = NULL; break; } else { if (next != NULL) *next = ptr + 1; // Null terminate player name *ptr = '\0'; } if (!quoted) { // if we're not quoted // Bool wasambiguous = ambiguous; ambiguous = (INVALID_ID == FindPlayerByName(retval)); if (ambiguous) { // restore player name and try again by appending next word last_ptr = ptr; *ptr++ = ' '; } else if (wasambiguous) { // String was ambiguous but now it's not. break; } } } while (ambiguous); // If we ran out of words before resolving ambiguity, remove the last word; // the caller may need it. if (ambiguous) { if (last_ptr == NULL) debug(("GetPlayerName found ambiguous name in bad case\n")); else { *last_ptr = 0; if (next != NULL) *next = last_ptr + 1; } } return retval; }
/* ================== 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()); }