/* ================== 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_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); }
/* ================== BotVoiceChat_WhoIsLeader ================== */ void BotVoiceChat_WhoIsLeader(bot_state_t *bs, int playernum, int mode) { char netname[MAX_MESSAGE_SIZE]; if (!TeamPlayIsOn()) return; PlayerName(bs->playernum, netname, sizeof(netname)); //if this bot IS the team leader if (!Q_stricmp(netname, bs->teamleader)) { BotAI_BotInitialChat(bs, "iamteamleader", NULL); BotEnterChat(bs->cs, 0, CHAT_TEAM); BotVoiceChatOnly(bs, -1, VOICECHAT_STARTLEADER); } }
/* ================== BotMatch_LeaveSubteam ================== */ void BotMatch_WhichTeam(bot_state_t *bs, bot_match_t *match) { if (!TeamPlayIsOn()) return; //if not addressed to this bot if (!BotAddressedToBot(bs, match)) return; // if (strlen(bs->subteam)) { BotAI_BotInitialChat(bs, "inteam", bs->subteam, NULL); } else { BotAI_BotInitialChat(bs, "noteam", NULL); } BotEnterChat(bs->cs, bs->playernum, CHAT_TEAM); }
/* ================== BotVoiceChat_WantOnOffense ================== */ void BotVoiceChat_WantOnOffense(bot_state_t *bs, int playernum, int mode) { char netname[MAX_NETNAME]; int preference; preference = BotGetTeamMateTaskPreference(bs, playernum); preference &= ~TEAMTP_DEFENDER; preference |= TEAMTP_ATTACKER; BotSetTeamMateTaskPreference(bs, playernum, preference); // EasyPlayerName(playernum, netname, sizeof(netname)); BotAI_BotInitialChat(bs, "keepinmind", netname, NULL); BotEnterChat(bs->cs, playernum, CHAT_TELL); BotVoiceChatOnly(bs, playernum, VOICECHAT_YES); EA_Action(bs->playernum, ACTION_AFFIRMATIVE); }
/* ================== BotVoiceChat_Patrol ================== */ void BotVoiceChat_Patrol(bot_state_t *bs, int playernum, int mode) { // 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); BotVoiceChatOnly(bs, -1, VOICECHAT_ONPATROL); // BotSetTeamStatus(bs); BotPrintTeamGoal(bs); }
/* ================== BotVoiceChat_Camp ================== */ void BotVoiceChat_Camp(bot_state_t *bs, int playernum, int mode) { int areanum; aas_entityinfo_t entinfo; char netname[MAX_NETNAME]; // 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", EasyPlayerName(playernum, netname, sizeof(netname)), NULL); 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 = FloatTime() + TEAM_CAMP_TIME; //the teammate that requested the camping bs->teammate = playernum; //not arrived yet bs->arrive_time = 0; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); BotPrintTeamGoal(bs); }
/* ================== BotVoiceChat_FollowMe ================== */ void BotVoiceChat_FollowMe(bot_state_t *bs, int playernum, int mode) { int areanum; aas_entityinfo_t entinfo; char netname[MAX_NETNAME]; 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 the other is not visible if (bs->teamgoal.entitynum < 0) { BotAI_BotInitialChat(bs, "whereareyou", EasyPlayerName(playernum, netname, sizeof(netname)), NULL); BotEnterChat(bs->cs, playernum, CHAT_TELL); return; } // bs->decisionmaker = playernum; bs->ordered = qtrue; bs->order_time = FloatTime(); //the team mate bs->teammate = playernum; //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 = FloatTime() + TEAM_ACCOMPANY_TIME; //set the ltg type bs->ltgtype = LTG_TEAMACCOMPANY; bs->formation_dist = 128; bs->arrive_time = 0; // BotSetTeamStatus(bs); // remember last ordered task BotRememberLastOrderedTask(bs); BotPrintTeamGoal(bs); }
/* ================== 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_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_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); }
/* ============== BotAIShutdownPlayer ============== */ int BotAIShutdownPlayer(int playernum, qboolean restart) { bot_state_t *bs; bs = botstates[playernum]; if (!bs || !bs->inuse) { //BotAI_Print(PRT_ERROR, "BotAIShutdownPlayer: player %d already shutdown\n", playernum); return qfalse; } if (restart) { BotWriteSessionData(bs); } if (BotChat_ExitGame(bs)) { BotEnterChat(bs->cs, bs->playernum, CHAT_ALL); } trap_SetConfigstring(CS_BOTINFO + bs->playernum, ""); BotFreeMoveState(bs->ms); //free the goal state BotFreeGoalState(bs->gs); //free the chat file BotFreeChatState(bs->cs); //free the weapon weights BotFreeWeaponState(bs->ws); //free the bot character BotFreeCharacter(bs->character); // BotFreeWaypoints(bs->checkpoints); BotFreeWaypoints(bs->patrolpoints); //clear activate goal stack BotClearActivateGoalStack(bs); //clear the bot state memset(bs, 0, sizeof(bot_state_t)); //set the inuse flag to qfalse bs->inuse = qfalse; //there's one bot less numbots--; //everything went ok return qtrue; }
/* ================== 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_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); }
/* ================== 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_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_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_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); }
/* ================== BotChatTest ================== */ void BotChatTest(bot_state_t *bs) { char name[32]; char *weap; int num, i; num = BotNumInitialChats(bs->cs, "game_enter"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "game_enter", EasyPlayerName(bs->playernum, name, 32), // 0 BotRandomOpponentName(bs), // 1 "[invalid var]", // 2 "[invalid var]", // 3 BotMapTitle(), // 4 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "game_exit"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "game_exit", EasyPlayerName(bs->playernum, name, 32), // 0 BotRandomOpponentName(bs), // 1 "[invalid var]", // 2 "[invalid var]", // 3 BotMapTitle(), // 4 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "level_start"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "level_start", EasyPlayerName(bs->playernum, name, 32), // 0 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "level_end_victory"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "level_end_victory", EasyPlayerName(bs->playernum, name, 32), // 0 BotRandomOpponentName(bs), // 1 BotFirstPlayerInRankings(), // 2 BotLastPlayerInRankings(), // 3 BotMapTitle(), // 4 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "level_end_lose"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "level_end_lose", EasyPlayerName(bs->playernum, name, 32), // 0 BotRandomOpponentName(bs), // 1 BotFirstPlayerInRankings(), // 2 BotLastPlayerInRankings(), // 3 BotMapTitle(), // 4 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "level_end"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "level_end", EasyPlayerName(bs->playernum, name, 32), // 0 BotRandomOpponentName(bs), // 1 BotFirstPlayerInRankings(), // 2 BotLastPlayerInRankings(), // 3 BotMapTitle(), // 4 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } EasyPlayerName(bs->lastkilledby, name, sizeof(name)); num = BotNumInitialChats(bs->cs, "death_drown"); for (i = 0; i < num; i++) { // BotAI_BotInitialChat(bs, "death_drown", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_slime"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_slime", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_lava"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_lava", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_cratered"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_cratered", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_suicide"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_suicide", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_telefrag"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_telefrag", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_gauntlet"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_gauntlet", name, // 0 BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_rail"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_rail", name, // 0 BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_bfg"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_bfg", name, // 0 BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_insult"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_insult", name, // 0 BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "death_praise"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "death_praise", name, // 0 BotWeaponNameForMeansOfDeath(bs->botdeathtype), // 1 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } // EasyPlayerName(bs->lastkilledplayer, name, 32); // num = BotNumInitialChats(bs->cs, "kill_gauntlet"); for (i = 0; i < num; i++) { // BotAI_BotInitialChat(bs, "kill_gauntlet", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "kill_rail"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "kill_rail", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "kill_telefrag"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "kill_telefrag", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "kill_insult"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "kill_insult", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "kill_praise"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "kill_praise", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "enemy_suicide"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "enemy_suicide", name, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } PlayerName(g_entities[bs->playernum].player->lasthurt_player, name, sizeof(name)); weap = BotWeaponNameForMeansOfDeath(g_entities[bs->playernum].player->lasthurt_player); num = BotNumInitialChats(bs->cs, "hit_talking"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "hit_talking", name, weap, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "hit_nodeath"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "hit_nodeath", name, weap, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "hit_nokill"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "hit_nokill", name, weap, NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } // if (bs->lastkilledplayer == bs->playernum) { strcpy(name, BotRandomOpponentName(bs)); } else { EasyPlayerName(bs->lastkilledplayer, name, sizeof(name)); } // num = BotNumInitialChats(bs->cs, "random_misc"); for (i = 0; i < num; i++) { // BotAI_BotInitialChat(bs, "random_misc", BotRandomOpponentName(bs), // 0 name, // 1 "[invalid var]", // 2 "[invalid var]", // 3 BotMapTitle(), // 4 BotRandomWeaponName(), // 5 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } num = BotNumInitialChats(bs->cs, "random_insult"); for (i = 0; i < num; i++) { BotAI_BotInitialChat(bs, "random_insult", BotRandomOpponentName(bs), // 0 name, // 1 "[invalid var]", // 2 "[invalid var]", // 3 BotMapTitle(), // 4 BotRandomWeaponName(), // 5 NULL); BotEnterChat(bs->cs, 0, CHAT_ALL); } }