/* ================== BotMatch_WhoIsTeamLeader ================== */ void BotMatch_WhoIsTeamLeader(bot_state_t *bs, bot_match_t *match) { char netname[MAX_MESSAGE_SIZE]; if (!TeamPlayIsOn()) return; ClientName(bs->client, netname, sizeof(netname)); //if this bot IS the team leader if (!Q_stricmp(netname, bs->teamleader)) { trap_EA_SayTeam(bs->client, "I'm the team leader\n"); } }
/* ================ BotMatch_Subteam ================ */ qboolean BotMatch_Subteam(bot_state_t *bs, bot_match_t *match, gentity_t *sender) { // Check information and simple request messages switch (match->type) { case MSG_JOINSUBTEAM: BotMatch_JoinSubteam(bs, match, sender); break; case MSG_LEAVESUBTEAM: BotMatch_LeaveSubteam(bs, match, sender); break; case MSG_WHICHTEAM: BotMatch_WhichTeam(bs, match); break; case MSG_FORMATIONSPACE: BotMatch_FormationSpace(bs, match); break; case MSG_DOFORMATION: case MSG_WAIT: break; case MSG_CREATENEWFORMATION: case MSG_FORMATIONPOSITION: trap_EA_SayTeam(bs->client, "The part of my brain to create formations has been damaged"); break; default: return qfalse; } return qtrue; }
/* ======================================================================================================================================= 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; }
/* ======================================================================================================================================= BotMatchMessage ======================================================================================================================================= */ int BotMatchMessage(bot_state_t *bs, char *message) { bot_match_t match; match.type = 0; // if it is an unknown message if (!trap_BotFindMatch(message, &match, MTCONTEXT_ENTERGAME |MTCONTEXT_INITIALTEAMCHAT |MTCONTEXT_CTF)) { return qfalse; } // react to the found message switch (match.type) { case MSG_HELP: // someone calling for help case MSG_ACCOMPANY: // someone calling for company { BotMatch_HelpAccompany(bs, &match); break; } case MSG_DEFENDKEYAREA: // teamplay defend a key area { BotMatch_DefendKeyArea(bs, &match); break; } case MSG_CAMP: // camp somewhere { BotMatch_Camp(bs, &match); break; } case MSG_PATROL: // patrol between several key areas { BotMatch_Patrol(bs, &match); break; } #ifdef CTF case MSG_GETFLAG: // ctf get the enemy flag { BotMatch_GetFlag(bs, &match); break; } case MSG_RUSHBASE: // ctf rush to the base { BotMatch_RushBase(bs, &match); break; } case MSG_RETURNFLAG: { BotMatch_ReturnFlag(bs, &match); break; } #endif // CTF case MSG_GETITEM: { BotMatch_GetItem(bs, &match); break; } case MSG_JOINSUBTEAM: // join a sub team { BotMatch_JoinSubteam(bs, &match); break; } case MSG_LEAVESUBTEAM: // leave a sub team { BotMatch_LeaveSubteam(bs, &match); break; } case MSG_WHICHTEAM: { BotMatch_WhichTeam(bs, &match); break; } case MSG_CHECKPOINT: // remember a check point { BotMatch_CheckPoint(bs, &match); break; } case MSG_CREATENEWFORMATION: // start the creation of a new formation { trap_EA_SayTeam(bs->client, "the part of my brain to create formations has been damaged"); break; } case MSG_FORMATIONPOSITION: // tell someone his / her position in the formation { trap_EA_SayTeam(bs->client, "the part of my brain to create formations has been damaged"); break; } case MSG_FORMATIONSPACE: // set the formation space { BotMatch_FormationSpace(bs, &match); break; } case MSG_DOFORMATION: // form a certain formation { break; } case MSG_DISMISS: // dismiss someone { BotMatch_Dismiss(bs, &match); break; } case MSG_STARTTEAMLEADERSHIP: // someone will become the team leader { BotMatch_StartTeamLeaderShip(bs, &match); break; } case MSG_STOPTEAMLEADERSHIP: // someone will stop being the team leader { BotMatch_StopTeamLeaderShip(bs, &match); break; } case MSG_WHOISTEAMLAEDER: { BotMatch_WhoIsTeamLeader(bs, &match); break; } case MSG_WHATAREYOUDOING: // ask a bot what he / she is doing { BotMatch_WhatAreYouDoing(bs, &match); break; } case MSG_WHATISMYCOMMAND: { BotMatch_WhatIsMyCommand(bs, &match); break; } case MSG_WHEREAREYOU: { BotMatch_WhereAreYou(bs, &match); break; } case MSG_LEADTHEWAY: { BotMatch_LeadTheWay(bs, &match); break; } case MSG_KILL: { BotMatch_Kill(bs, &match); break; } case MSG_ENTERGAME: // someone entered the game { // NOTE: eliza chats will catch this // BotMatchVariable(&match, NETNAME, netname); // Com_sprintf(buf, sizeof(buf), "heya %s", netname); // EA_Say(bs->client, buf); break; } case MSG_CTF: { BotMatch_CTF(bs, &match); break; } case MSG_WAIT: { break; } default: { BotAI_Print(PRT_MESSAGE, "unknown match type\n"); break; } } return qtrue; }
/* ======================== BotMatch_PatrolWaypoints ======================== */ qboolean BotMatch_PatrolWaypoints(bot_state_t *bs, bot_match_t *match, gentity_t *sender) { char keyarea[MAX_MESSAGE_SIZE]; int flags; bot_waypoint_t *new_wp, *last_wp, *new_patrol; bot_match_t keyareamatch; bot_goal_t goal; qboolean success; // Initialize new patrol to a zero length path last_wp = new_patrol = NULL; flags = 0; success = qfalse; // Match successive waypoints in the patrol path trap_BotMatchVariable(match, KEYAREA, keyarea, MAX_MESSAGE_SIZE); while (1) { // Fail if the bot can't match the area name if (!trap_BotFindMatch(keyarea, &keyareamatch, MTCONTEXT_PATROLKEYAREA)) { trap_EA_SayTeam(bs->client, "What did you say?"); break; } // Fail if the bot can't find the requested area trap_BotMatchVariable(&keyareamatch, KEYAREA, keyarea, MAX_MESSAGE_SIZE); if (!GoalFromName(&goal, keyarea, bs)) break; // Try to create a new waypoint new_wp = BotCreateWaypoint(keyarea); if (new_wp == NULL) break; // Copy the matched goal to the waypoint memcpy(&new_wp->goal, &goal, sizeof(bot_goal_t)); // Insert waypoint into patrol point list new_wp->next = NULL; if (last_wp) { last_wp->next = new_wp; new_wp->prev = last_wp; } else { // First waypoint in list new_patrol = new_wp; new_wp->prev = NULL; } last_wp = new_wp; // Check for waypoint message completion if (keyareamatch.subtype & ST_REVERSE) { success = qtrue; flags = PATROL_REVERSE; break; } if (keyareamatch.subtype & ST_BACK) { success = qtrue; flags = PATROL_LOOP; break; } if ( !(keyareamatch.subtype & ST_MORE) ) { success = qtrue; flags = PATROL_LOOP; break; } trap_BotMatchVariable(&keyareamatch, MORE, keyarea, MAX_MESSAGE_SIZE); } // Make sure the bot has at least two patrol points if (success && (!new_patrol || !new_patrol->next) ) { trap_EA_SayTeam(bs->client, "I need more key points to patrol\n"); success = qfalse; } // Check for message match failure if (!success) { BotFreeWaypoints(new_patrol); return qfalse; } // Free old waypoints and use new waypoints BotFreeWaypoints(bs->patrol); bs->patrol = new_patrol; bs->next_patrol = bs->patrol; bs->patrol_flags = flags; return qtrue; }