Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

ai_team.c File Reference

#include "g_local.h"
#include "botlib.h"
#include "be_aas.h"
#include "be_ea.h"
#include "be_ai_char.h"
#include "be_ai_chat.h"
#include "be_ai_gen.h"
#include "be_ai_goal.h"
#include "be_ai_move.h"
#include "be_ai_weap.h"
#include "ai_main.h"
#include "ai_dmq3.h"
#include "ai_chat.h"
#include "ai_cmd.h"
#include "ai_dmnet.h"
#include "ai_team.h"
#include "ai_vcmd.h"
#include "match.h"
#include "../../ui/menudef.h"

Include dependency graph for ai_team.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  bot_ctftaskpreference_s

Typedefs

typedef bot_ctftaskpreference_s bot_ctftaskpreference_t

Functions

int BotClientTravelTimeToGoal (int client, bot_goal_t *goal)
void BotCreateGroup (bot_state_t *bs, int *teammates, int groupsize)
void BotCTFOrders (bot_state_t *bs)
void BotCTFOrders_BothFlagsAtBase (bot_state_t *bs)
void BotCTFOrders_BothFlagsNotAtBase (bot_state_t *bs)
void BotCTFOrders_EnemyFlagNotAtBase (bot_state_t *bs)
void BotCTFOrders_FlagNotAtBase (bot_state_t *bs)
int BotGetTeamMateTaskPreference (bot_state_t *bs, int teammate)
int BotNumTeamMates (bot_state_t *bs)
void BotSayTeamOrder (bot_state_t *bs, int toclient)
void BotSayTeamOrderAlways (bot_state_t *bs, int toclient)
void BotSayVoiceTeamOrder (bot_state_t *bs, int toclient, char *voicechat)
void BotSetTeamMateTaskPreference (bot_state_t *bs, int teammate, int preference)
int BotSortTeamMatesByBaseTravelTime (bot_state_t *bs, int *teammates, int maxteammates)
int BotSortTeamMatesByTaskPreference (bot_state_t *bs, int *teammates, int numteammates)
void BotTeamAI (bot_state_t *bs)
void BotTeamOrders (bot_state_t *bs)
int BotValidTeamLeader (bot_state_t *bs)
void BotVoiceChat (bot_state_t *bs, int toclient, char *voicechat)
void BotVoiceChatOnly (bot_state_t *bs, int toclient, char *voicechat)
int FindHumanTeamLeader (bot_state_t *bs)

Variables

bot_ctftaskpreference_t ctftaskpreferences [MAX_CLIENTS]


Typedef Documentation

typedef struct bot_ctftaskpreference_s bot_ctftaskpreference_t
 


Function Documentation

int BotClientTravelTimeToGoal int  client,
bot_goal_t goal
 

Definition at line 111 of file ai_team.c.

References bot_goal_s::areanum, bot_goal_t, BotAI_GetClientState(), BotPointAreaNum(), playerState_s::origin, playerState_t, TFL_DEFAULT, and trap_AAS_AreaTravelTimeToGoalArea().

Referenced by BotSortTeamMatesByBaseTravelTime().

00111                                                             {
00112     playerState_t ps;
00113     int areanum;
00114 
00115     BotAI_GetClientState(client, &ps);
00116     areanum = BotPointAreaNum(ps.origin);
00117     if (!areanum) return 1;
00118     return trap_AAS_AreaTravelTimeToGoalArea(areanum, ps.origin, goal->areanum, TFL_DEFAULT);
00119 }

Here is the call graph for this function:

void BotCreateGroup bot_state_t bs,
int *  teammates,
int  groupsize
 

Definition at line 853 of file ai_team.c.

References bot_state_t, BotAI_BotInitialChat(), BotSayTeamOrderAlways(), bot_state_s::client, ClientName(), i, name, and NULL.

Referenced by BotTeamOrders().

00853                                                                     {
00854     char name[MAX_NETNAME], leadername[MAX_NETNAME];
00855     int i;
00856 
00857     // the others in the group will follow the teammates[0]
00858     ClientName(teammates[0], leadername, sizeof(leadername));
00859     for (i = 1; i < groupsize; i++)
00860     {
00861         ClientName(teammates[i], name, sizeof(name));
00862         if (teammates[0] == bs->client) {
00863             BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
00864         }
00865         else {
00866             BotAI_BotInitialChat(bs, "cmd_accompany", name, leadername, NULL);
00867         }
00868         BotSayTeamOrderAlways(bs, teammates[i]);
00869     }
00870 }

Here is the call graph for this function:

void BotCTFOrders bot_state_t bs  ) 
 

Definition at line 832 of file ai_team.c.

References bot_state_s::blueflagstatus, bot_state_t, BotCTFOrders_BothFlagsAtBase(), BotCTFOrders_BothFlagsNotAtBase(), BotCTFOrders_EnemyFlagNotAtBase(), BotCTFOrders_FlagNotAtBase(), BotTeam(), and bot_state_s::redflagstatus.

Referenced by BotTeamAI().

00832                                    {
00833     int flagstatus;
00834 
00835     //
00836     if (BotTeam(bs) == TEAM_RED) flagstatus = bs->redflagstatus * 2 + bs->blueflagstatus;
00837     else flagstatus = bs->blueflagstatus * 2 + bs->redflagstatus;
00838     //
00839     switch(flagstatus) {
00840         case 0: BotCTFOrders_BothFlagsAtBase(bs); break;
00841         case 1: BotCTFOrders_EnemyFlagNotAtBase(bs); break;
00842         case 2: BotCTFOrders_FlagNotAtBase(bs); break;
00843         case 3: BotCTFOrders_BothFlagsNotAtBase(bs); break;
00844     }
00845 }

Here is the call graph for this function:

void BotCTFOrders_BothFlagsAtBase bot_state_t bs  ) 
 

Definition at line 691 of file ai_team.c.

References bot_state_t, BotAI_BotInitialChat(), BotSayTeamOrder(), BotSayVoiceTeamOrder(), BotSortTeamMatesByBaseTravelTime(), BotSortTeamMatesByTaskPreference(), ClientName(), bot_state_s::ctfstrategy, i, name, NULL, VOICECHAT_DEFEND, and VOICECHAT_GETFLAG.

Referenced by BotCTFOrders().

00691                                                    {
00692     int numteammates, defenders, attackers, i;
00693     int teammates[MAX_CLIENTS];
00694     char name[MAX_NETNAME];
00695 
00696     //sort team mates by travel time to base
00697     numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
00698     //sort team mates by CTF preference
00699     BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
00700     //passive strategy
00701     if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
00702         //different orders based on the number of team mates
00703         switch(numteammates) {
00704             case 1: break;
00705             case 2:
00706             {
00707                 //the one closest to the base will defend the base
00708                 ClientName(teammates[0], name, sizeof(name));
00709                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00710                 BotSayTeamOrder(bs, teammates[0]);
00711                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00712                 //the other will get the flag
00713                 ClientName(teammates[1], name, sizeof(name));
00714                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00715                 BotSayTeamOrder(bs, teammates[1]);
00716                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00717                 break;
00718             }
00719             case 3:
00720             {
00721                 //the one closest to the base will defend the base
00722                 ClientName(teammates[0], name, sizeof(name));
00723                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00724                 BotSayTeamOrder(bs, teammates[0]);
00725                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00726                 //the second one closest to the base will defend the base
00727                 ClientName(teammates[1], name, sizeof(name));
00728                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00729                 BotSayTeamOrder(bs, teammates[1]);
00730                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
00731                 //the other will get the flag
00732                 ClientName(teammates[2], name, sizeof(name));
00733                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00734                 BotSayTeamOrder(bs, teammates[2]);
00735                 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
00736                 break;
00737             }
00738             default:
00739             {
00740                 defenders = (int) (float) numteammates * 0.5 + 0.5;
00741                 if (defenders > 5) defenders = 5;
00742                 attackers = (int) (float) numteammates * 0.4 + 0.5;
00743                 if (attackers > 4) attackers = 4;
00744                 for (i = 0; i < defenders; i++) {
00745                     //
00746                     ClientName(teammates[i], name, sizeof(name));
00747                     BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00748                     BotSayTeamOrder(bs, teammates[i]);
00749                     BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
00750                 }
00751                 for (i = 0; i < attackers; i++) {
00752                     //
00753                     ClientName(teammates[numteammates - i - 1], name, sizeof(name));
00754                     BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00755                     BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
00756                     BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
00757                 }
00758                 //
00759                 break;
00760             }
00761         }
00762     }
00763     else {
00764         //different orders based on the number of team mates
00765         switch(numteammates) {
00766             case 1: break;
00767             case 2:
00768             {
00769                 //the one closest to the base will defend the base
00770                 ClientName(teammates[0], name, sizeof(name));
00771                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00772                 BotSayTeamOrder(bs, teammates[0]);
00773                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00774                 //the other will get the flag
00775                 ClientName(teammates[1], name, sizeof(name));
00776                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00777                 BotSayTeamOrder(bs, teammates[1]);
00778                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00779                 break;
00780             }
00781             case 3:
00782             {
00783                 //the one closest to the base will defend the base
00784                 ClientName(teammates[0], name, sizeof(name));
00785                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00786                 BotSayTeamOrder(bs, teammates[0]);
00787                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00788                 //the others should go for the enemy flag
00789                 ClientName(teammates[1], name, sizeof(name));
00790                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00791                 BotSayTeamOrder(bs, teammates[1]);
00792                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00793                 //
00794                 ClientName(teammates[2], name, sizeof(name));
00795                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00796                 BotSayTeamOrder(bs, teammates[2]);
00797                 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
00798                 break;
00799             }
00800             default:
00801             {
00802                 defenders = (int) (float) numteammates * 0.4 + 0.5;
00803                 if (defenders > 4) defenders = 4;
00804                 attackers = (int) (float) numteammates * 0.5 + 0.5;
00805                 if (attackers > 5) attackers = 5;
00806                 for (i = 0; i < defenders; i++) {
00807                     //
00808                     ClientName(teammates[i], name, sizeof(name));
00809                     BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00810                     BotSayTeamOrder(bs, teammates[i]);
00811                     BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
00812                 }
00813                 for (i = 0; i < attackers; i++) {
00814                     //
00815                     ClientName(teammates[numteammates - i - 1], name, sizeof(name));
00816                     BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00817                     BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
00818                     BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
00819                 }
00820                 //
00821                 break;
00822             }
00823         }
00824     }
00825 }

Here is the call graph for this function:

void BotCTFOrders_BothFlagsNotAtBase bot_state_t bs  ) 
 

Definition at line 333 of file ai_team.c.

References bot_state_t, BotAI_BotInitialChat(), BotSayTeamOrder(), BotSayVoiceTeamOrder(), BotSortTeamMatesByBaseTravelTime(), BotSortTeamMatesByTaskPreference(), bot_state_s::client, ClientName(), bot_state_s::flagcarrier, i, name, NULL, bot_state_s::numteammates, VOICECHAT_FOLLOWFLAGCARRIER, VOICECHAT_FOLLOWME, VOICECHAT_GETFLAG, and VOICECHAT_RETURNFLAG.

Referenced by BotCTFOrders().

00333                                                       {
00334     int numteammates, defenders, attackers, i, other;
00335     int teammates[MAX_CLIENTS];
00336     char name[MAX_NETNAME], carriername[MAX_NETNAME];
00337 
00338     numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
00339     BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
00340     //different orders based on the number of team mates
00341     switch(bs->numteammates) {
00342         case 1: break;
00343         case 2:
00344         {
00345             //tell the one not carrying the flag to attack the enemy base
00346             if (teammates[0] != bs->flagcarrier) other = teammates[0];
00347             else other = teammates[1];
00348             ClientName(other, name, sizeof(name));
00349             BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00350             BotSayTeamOrder(bs, other);
00351             BotSayVoiceTeamOrder(bs, other, VOICECHAT_GETFLAG);
00352             break;
00353         }
00354         case 3:
00355         {
00356             //tell the one closest to the base not carrying the flag to accompany the flag carrier
00357             if (teammates[0] != bs->flagcarrier) other = teammates[0];
00358             else other = teammates[1];
00359             ClientName(other, name, sizeof(name));
00360             if ( bs->flagcarrier != -1 ) {
00361                 ClientName(bs->flagcarrier, carriername, sizeof(carriername));
00362                 if (bs->flagcarrier == bs->client) {
00363                     BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
00364                     BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWME);
00365                 }
00366                 else {
00367                     BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
00368                     BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWFLAGCARRIER);
00369                 }
00370             }
00371             else {
00372                 //
00373                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00374                 BotSayVoiceTeamOrder(bs, other, VOICECHAT_GETFLAG);
00375             }
00376             BotSayTeamOrder(bs, other);
00377             //tell the one furthest from the the base not carrying the flag to get the enemy flag
00378             if (teammates[2] != bs->flagcarrier) other = teammates[2];
00379             else other = teammates[1];
00380             ClientName(other, name, sizeof(name));
00381             BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00382             BotSayTeamOrder(bs, other);
00383             BotSayVoiceTeamOrder(bs, other, VOICECHAT_RETURNFLAG);
00384             break;
00385         }
00386         default:
00387         {
00388             defenders = (int) (float) numteammates * 0.4 + 0.5;
00389             if (defenders > 4) defenders = 4;
00390             attackers = (int) (float) numteammates * 0.5 + 0.5;
00391             if (attackers > 5) attackers = 5;
00392             if (bs->flagcarrier != -1) {
00393                 ClientName(bs->flagcarrier, carriername, sizeof(carriername));
00394                 for (i = 0; i < defenders; i++) {
00395                     //
00396                     if (teammates[i] == bs->flagcarrier) {
00397                         continue;
00398                     }
00399                     //
00400                     ClientName(teammates[i], name, sizeof(name));
00401                     if (bs->flagcarrier == bs->client) {
00402                         BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
00403                         BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_FOLLOWME);
00404                     }
00405                     else {
00406                         BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
00407                         BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_FOLLOWFLAGCARRIER);
00408                     }
00409                     BotSayTeamOrder(bs, teammates[i]);
00410                 }
00411             }
00412             else {
00413                 for (i = 0; i < defenders; i++) {
00414                     //
00415                     if (teammates[i] == bs->flagcarrier) {
00416                         continue;
00417                     }
00418                     //
00419                     ClientName(teammates[i], name, sizeof(name));
00420                     BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00421                     BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_GETFLAG);
00422                     BotSayTeamOrder(bs, teammates[i]);
00423                 }
00424             }
00425             for (i = 0; i < attackers; i++) {
00426                 //
00427                 if (teammates[numteammates - i - 1] == bs->flagcarrier) {
00428                     continue;
00429                 }
00430                 //
00431                 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
00432                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00433                 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
00434                 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_RETURNFLAG);
00435             }
00436             //
00437             break;
00438         }
00439     }
00440 }

Here is the call graph for this function:

void BotCTFOrders_EnemyFlagNotAtBase bot_state_t bs  ) 
 

Definition at line 588 of file ai_team.c.

References bot_state_t, BotAI_BotInitialChat(), BotSayTeamOrder(), BotSayVoiceTeamOrder(), BotSortTeamMatesByBaseTravelTime(), BotSortTeamMatesByTaskPreference(), bot_state_s::client, ClientName(), bot_state_s::flagcarrier, i, name, NULL, VOICECHAT_DEFEND, VOICECHAT_FOLLOWFLAGCARRIER, VOICECHAT_FOLLOWME, and VOICECHAT_GETFLAG.

Referenced by BotCTFOrders().

00588                                                       {
00589     int numteammates, defenders, attackers, i, other;
00590     int teammates[MAX_CLIENTS];
00591     char name[MAX_NETNAME], carriername[MAX_NETNAME];
00592 
00593     numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
00594     BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
00595     //different orders based on the number of team mates
00596     switch(numteammates) {
00597         case 1: break;
00598         case 2:
00599         {
00600             //tell the one not carrying the flag to defend the base
00601             if (teammates[0] == bs->flagcarrier) other = teammates[1];
00602             else other = teammates[0];
00603             ClientName(other, name, sizeof(name));
00604             BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00605             BotSayTeamOrder(bs, other);
00606             BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
00607             break;
00608         }
00609         case 3:
00610         {
00611             //tell the one closest to the base not carrying the flag to defend the base
00612             if (teammates[0] != bs->flagcarrier) other = teammates[0];
00613             else other = teammates[1];
00614             ClientName(other, name, sizeof(name));
00615             BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00616             BotSayTeamOrder(bs, other);
00617             BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
00618             //tell the other also to defend the base
00619             if (teammates[2] != bs->flagcarrier) other = teammates[2];
00620             else other = teammates[1];
00621             ClientName(other, name, sizeof(name));
00622             BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00623             BotSayTeamOrder(bs, other);
00624             BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
00625             break;
00626         }
00627         default:
00628         {
00629             //60% will defend the base
00630             defenders = (int) (float) numteammates * 0.6 + 0.5;
00631             if (defenders > 6) defenders = 6;
00632             //30% accompanies the flag carrier
00633             attackers = (int) (float) numteammates * 0.3 + 0.5;
00634             if (attackers > 3) attackers = 3;
00635             for (i = 0; i < defenders; i++) {
00636                 //
00637                 if (teammates[i] == bs->flagcarrier) {
00638                     continue;
00639                 }
00640                 ClientName(teammates[i], name, sizeof(name));
00641                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00642                 BotSayTeamOrder(bs, teammates[i]);
00643                 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
00644             }
00645             // if we have a flag carrier
00646             if ( bs->flagcarrier != -1 ) {
00647                 ClientName(bs->flagcarrier, carriername, sizeof(carriername));
00648                 for (i = 0; i < attackers; i++) {
00649                     //
00650                     if (teammates[numteammates - i - 1] == bs->flagcarrier) {
00651                         continue;
00652                     }
00653                     //
00654                     ClientName(teammates[numteammates - i - 1], name, sizeof(name));
00655                     if (bs->flagcarrier == bs->client) {
00656                         BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
00657                         BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWME);
00658                     }
00659                     else {
00660                         BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
00661                         BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWFLAGCARRIER);
00662                     }
00663                     BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
00664                 }
00665             }
00666             else {
00667                 for (i = 0; i < attackers; i++) {
00668                     //
00669                     if (teammates[numteammates - i - 1] == bs->flagcarrier) {
00670                         continue;
00671                     }
00672                     //
00673                     ClientName(teammates[numteammates - i - 1], name, sizeof(name));
00674                     BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00675                     BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
00676                     BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
00677                 }
00678             }
00679             //
00680             break;
00681         }
00682     }
00683 }

Here is the call graph for this function:

void BotCTFOrders_FlagNotAtBase bot_state_t bs  ) 
 

Definition at line 447 of file ai_team.c.

References bot_state_t, BotAI_BotInitialChat(), BotSayTeamOrder(), BotSayVoiceTeamOrder(), BotSortTeamMatesByBaseTravelTime(), BotSortTeamMatesByTaskPreference(), ClientName(), bot_state_s::ctfstrategy, i, name, NULL, bot_state_s::numteammates, VOICECHAT_DEFEND, and VOICECHAT_GETFLAG.

Referenced by BotCTFOrders().

00447                                                  {
00448     int numteammates, defenders, attackers, i;
00449     int teammates[MAX_CLIENTS];
00450     char name[MAX_NETNAME];
00451 
00452     numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
00453     BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
00454     //passive strategy
00455     if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
00456         //different orders based on the number of team mates
00457         switch(bs->numteammates) {
00458             case 1: break;
00459             case 2:
00460             {
00461                 //both will go for the enemy flag
00462                 ClientName(teammates[0], name, sizeof(name));
00463                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00464                 BotSayTeamOrder(bs, teammates[0]);
00465                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
00466                 //
00467                 ClientName(teammates[1], name, sizeof(name));
00468                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00469                 BotSayTeamOrder(bs, teammates[1]);
00470                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00471                 break;
00472             }
00473             case 3:
00474             {
00475                 //keep one near the base for when the flag is returned
00476                 ClientName(teammates[0], name, sizeof(name));
00477                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00478                 BotSayTeamOrder(bs, teammates[0]);
00479                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00480                 //the other two get the flag
00481                 ClientName(teammates[1], name, sizeof(name));
00482                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00483                 BotSayTeamOrder(bs, teammates[1]);
00484                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00485                 //
00486                 ClientName(teammates[2], name, sizeof(name));
00487                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00488                 BotSayTeamOrder(bs, teammates[2]);
00489                 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
00490                 break;
00491             }
00492             default:
00493             {
00494                 //keep some people near the base for when the flag is returned
00495                 defenders = (int) (float) numteammates * 0.3 + 0.5;
00496                 if (defenders > 3) defenders = 3;
00497                 attackers = (int) (float) numteammates * 0.7 + 0.5;
00498                 if (attackers > 6) attackers = 6;
00499                 for (i = 0; i < defenders; i++) {
00500                     //
00501                     ClientName(teammates[i], name, sizeof(name));
00502                     BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00503                     BotSayTeamOrder(bs, teammates[i]);
00504                     BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
00505                 }
00506                 for (i = 0; i < attackers; i++) {
00507                     //
00508                     ClientName(teammates[numteammates - i - 1], name, sizeof(name));
00509                     BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00510                     BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
00511                     BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
00512                 }
00513                 //
00514                 break;
00515             }
00516         }
00517     }
00518     else {
00519         //different orders based on the number of team mates
00520         switch(bs->numteammates) {
00521             case 1: break;
00522             case 2:
00523             {
00524                 //both will go for the enemy flag
00525                 ClientName(teammates[0], name, sizeof(name));
00526                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00527                 BotSayTeamOrder(bs, teammates[0]);
00528                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
00529                 //
00530                 ClientName(teammates[1], name, sizeof(name));
00531                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00532                 BotSayTeamOrder(bs, teammates[1]);
00533                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00534                 break;
00535             }
00536             case 3:
00537             {
00538                 //everyone go for the flag
00539                 ClientName(teammates[0], name, sizeof(name));
00540                 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00541                 BotSayTeamOrder(bs, teammates[0]);
00542                 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
00543                 //
00544                 ClientName(teammates[1], name, sizeof(name));
00545                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00546                 BotSayTeamOrder(bs, teammates[1]);
00547                 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00548                 //
00549                 ClientName(teammates[2], name, sizeof(name));
00550                 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00551                 BotSayTeamOrder(bs, teammates[2]);
00552                 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
00553                 break;
00554             }
00555             default:
00556             {
00557                 //keep some people near the base for when the flag is returned
00558                 defenders = (int) (float) numteammates * 0.2 + 0.5;
00559                 if (defenders > 2) defenders = 2;
00560                 attackers = (int) (float) numteammates * 0.7 + 0.5;
00561                 if (attackers > 7) attackers = 7;
00562                 for (i = 0; i < defenders; i++) {
00563                     //
00564                     ClientName(teammates[i], name, sizeof(name));
00565                     BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00566                     BotSayTeamOrder(bs, teammates[i]);
00567                     BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
00568                 }
00569                 for (i = 0; i < attackers; i++) {
00570                     //
00571                     ClientName(teammates[numteammates - i - 1], name, sizeof(name));
00572                     BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00573                     BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
00574                     BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
00575                 }
00576                 //
00577                 break;
00578             }
00579         }
00580     }
00581 }

Here is the call graph for this function:

int BotGetTeamMateTaskPreference bot_state_t bs,
int  teammate
 

Definition at line 199 of file ai_team.c.

References bot_state_t, ClientName(), ctftaskpreferences, name, bot_ctftaskpreference_s::preference, and Q_stricmp().

Referenced by BotMatch_TaskPreference(), BotSortTeamMatesByTaskPreference(), BotVoiceChat_WantOnDefense(), and BotVoiceChat_WantOnOffense().

00199                                                                 {
00200     char teammatename[MAX_NETNAME];
00201 
00202     if (!ctftaskpreferences[teammate].preference) return 0;
00203     ClientName(teammate, teammatename, sizeof(teammatename));
00204     if (Q_stricmp(teammatename, ctftaskpreferences[teammate].name)) return 0;
00205     return ctftaskpreferences[teammate].preference;
00206 }

Here is the call graph for this function:

int BotNumTeamMates bot_state_t bs  ) 
 

Definition at line 83 of file ai_team.c.

References atoi, bot_state_t, BotSameTeam(), CS_PLAYERS, i, Info_ValueForKey(), maxclients, strlen(), trap_Cvar_VariableIntegerValue(), and trap_GetConfigstring().

Referenced by BotTeamAI().

00083                                      {
00084     int i, numplayers;
00085     char buf[MAX_INFO_STRING];
00086     static int maxclients;
00087 
00088     if (!maxclients)
00089         maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
00090 
00091     numplayers = 0;
00092     for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
00093         trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
00094         //if no config string or no name
00095         if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
00096         //skip spectators
00097         if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) continue;
00098         //
00099         if (BotSameTeam(bs, i)) {
00100             numplayers++;
00101         }
00102     }
00103     return numplayers;
00104 }

Here is the call graph for this function:

void BotSayTeamOrder bot_state_t bs,
int  toclient
 

Definition at line 274 of file ai_team.c.

References bot_state_t, BotSayTeamOrderAlways(), bot_state_s::cs, and trap_BotGetChatMessage().

Referenced by BotCTFOrders_BothFlagsAtBase(), BotCTFOrders_BothFlagsNotAtBase(), BotCTFOrders_EnemyFlagNotAtBase(), and BotCTFOrders_FlagNotAtBase().

00274                                                     {
00275 #ifdef MISSIONPACK
00276     // voice chats only
00277     char buf[MAX_MESSAGE_SIZE];
00278 
00279     trap_BotGetChatMessage(bs->cs, buf, sizeof(buf));
00280 #else
00281     BotSayTeamOrderAlways(bs, toclient);
00282 #endif
00283 }

Here is the call graph for this function:

void BotSayTeamOrderAlways bot_state_t bs,
int  toclient
 

Definition at line 251 of file ai_team.c.

References bot_state_t, CHAT_TELL, bot_state_s::client, ClientName(), CMS_CHAT, Com_sprintf(), bot_state_s::cs, EC, name, trap_BotEnterChat(), trap_BotGetChatMessage(), and trap_BotQueueConsoleMessage().

Referenced by BotCreateGroup(), and BotSayTeamOrder().

00251                                                           {
00252     char teamchat[MAX_MESSAGE_SIZE];
00253     char buf[MAX_MESSAGE_SIZE];
00254     char name[MAX_NETNAME];
00255 
00256     //if the bot is talking to itself
00257     if (bs->client == toclient) {
00258         //don't show the message just put it in the console message queue
00259         trap_BotGetChatMessage(bs->cs, buf, sizeof(buf));
00260         ClientName(bs->client, name, sizeof(name));
00261         Com_sprintf(teamchat, sizeof(teamchat), EC"(%s"EC")"EC": %s", name, buf);
00262         trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, teamchat);
00263     }
00264     else {
00265         trap_BotEnterChat(bs->cs, toclient, CHAT_TELL);
00266     }
00267 }

Here is the call graph for this function:

void BotSayVoiceTeamOrder bot_state_t bs,
int  toclient,
char *  voicechat
 

Definition at line 322 of file ai_team.c.

References bot_state_t, and BotVoiceChat().

Referenced by BotCTFOrders_BothFlagsAtBase(), BotCTFOrders_BothFlagsNotAtBase(), BotCTFOrders_EnemyFlagNotAtBase(), BotCTFOrders_FlagNotAtBase(), and BotTeamAI().

00322                                                                           {
00323 #ifdef MISSIONPACK
00324     BotVoiceChat(bs, toclient, voicechat);
00325 #endif
00326 }

Here is the call graph for this function:

void BotSetTeamMateTaskPreference bot_state_t bs,
int  teammate,
int  preference
 

Definition at line 186 of file ai_team.c.

References bot_state_t, ClientName(), ctftaskpreferences, name, bot_ctftaskpreference_s::preference, and strcpy().

Referenced by BotMatch_TaskPreference(), BotVoiceChat_WantOnDefense(), and BotVoiceChat_WantOnOffense().

00186                                                                                  {
00187     char teammatename[MAX_NETNAME];
00188 
00189     ctftaskpreferences[teammate].preference = preference;
00190     ClientName(teammate, teammatename, sizeof(teammatename));
00191     strcpy(ctftaskpreferences[teammate].name, teammatename);
00192 }

Here is the call graph for this function:

int BotSortTeamMatesByBaseTravelTime bot_state_t bs,
int *  teammates,
int  maxteammates
 

Definition at line 126 of file ai_team.c.

References atoi, bot_goal_t, bot_state_t, BotClientTravelTimeToGoal(), BotSameTeam(), BotTeam(), CS_PLAYERS, gametype, GT_CTF, i, Info_ValueForKey(), j, k, maxclients, strlen(), trap_Cvar_VariableIntegerValue(), and trap_GetConfigstring().

Referenced by BotCTFOrders_BothFlagsAtBase(), BotCTFOrders_BothFlagsNotAtBase(), BotCTFOrders_EnemyFlagNotAtBase(), and BotCTFOrders_FlagNotAtBase().

00126                                                                                         {
00127 
00128     int i, j, k, numteammates, traveltime;
00129     char buf[MAX_INFO_STRING];
00130     static int maxclients;
00131     int traveltimes[MAX_CLIENTS];
00132     bot_goal_t *goal = NULL;
00133 
00134     if (gametype == GT_CTF || gametype == GT_1FCTF) {
00135         if (BotTeam(bs) == TEAM_RED)
00136             goal = &ctf_redflag;
00137         else
00138             goal = &ctf_blueflag;
00139     }
00140 #ifdef MISSIONPACK
00141     else {
00142         if (BotTeam(bs) == TEAM_RED)
00143             goal = &redobelisk;
00144         else
00145             goal = &blueobelisk;
00146     }
00147 #endif
00148     if (!maxclients)
00149         maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
00150 
00151     numteammates = 0;
00152     for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
00153         trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
00154         //if no config string or no name
00155         if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
00156         //skip spectators
00157         if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) continue;
00158         //
00159         if (BotSameTeam(bs, i)) {
00160             //
00161             traveltime = BotClientTravelTimeToGoal(i, goal);
00162             //
00163             for (j = 0; j < numteammates; j++) {
00164                 if (traveltime < traveltimes[j]) {
00165                     for (k = numteammates; k > j; k--) {
00166                         traveltimes[k] = traveltimes[k-1];
00167                         teammates[k] = teammates[k-1];
00168                     }
00169                     break;
00170                 }
00171             }
00172             traveltimes[j] = traveltime;
00173             teammates[j] = i;
00174             numteammates++;
00175             if (numteammates >= maxteammates) break;
00176         }
00177     }
00178     return numteammates;
00179 }

Here is the call graph for this function:

int BotSortTeamMatesByTaskPreference bot_state_t bs,
int *  teammates,
int  numteammates
 

Definition at line 213 of file ai_team.c.

References bot_state_t, BotGetTeamMateTaskPreference(), i, and memcpy().

Referenced by BotCTFOrders_BothFlagsAtBase(), BotCTFOrders_BothFlagsNotAtBase(), BotCTFOrders_EnemyFlagNotAtBase(), and BotCTFOrders_FlagNotAtBase().

00213                                                                                         {
00214     int defenders[MAX_CLIENTS], numdefenders;
00215     int attackers[MAX_CLIENTS], numattackers;
00216     int roamers[MAX_CLIENTS], numroamers;
00217     int i, preference;
00218 
00219     numdefenders = numattackers = numroamers = 0;
00220     for (i = 0; i < numteammates; i++) {
00221         preference = BotGetTeamMateTaskPreference(bs, teammates[i]);
00222         if (preference & TEAMTP_DEFENDER) {
00223             defenders[numdefenders++] = teammates[i];
00224         }
00225         else if (preference & TEAMTP_ATTACKER) {
00226             attackers[numattackers++] = teammates[i];
00227         }
00228         else {
00229             roamers[numroamers++] = teammates[i];
00230         }
00231     }
00232     numteammates = 0;
00233     //defenders at the front of the list
00234     memcpy(&teammates[numteammates], defenders, numdefenders * sizeof(int));
00235     numteammates += numdefenders;
00236     //roamers in the middle
00237     memcpy(&teammates[numteammates], roamers, numroamers * sizeof(int));
00238     numteammates += numroamers;
00239     //attacker in the back of the list
00240     memcpy(&teammates[numteammates], attackers, numattackers * sizeof(int));
00241     numteammates += numattackers;
00242 
00243     return numteammates;
00244 }

Here is the call graph for this function:

void BotTeamAI bot_state_t bs  ) 
 

Definition at line 1930 of file ai_team.c.

References bot_state_s::askteamleader_time, bot_state_s::becometeamleader_time, bot_state_t, BotAI_BotInitialChat(), BotCTFOrders(), BotNumTeamMates(), BotSayVoiceTeamOrder(), BotTeamOrders(), BotValidTeamLeader(), CHAT_TEAM, bot_state_s::client, ClientName(), bot_state_s::cs, bot_state_s::ctfstrategy, bot_state_s::entergame_time, FindHumanTeamLeader(), bot_state_s::flagstatuschanged, FloatTime, bot_state_s::forceorders, gametype, GT_1FCTF, GT_CTF, GT_HARVESTER, GT_OBELISK, GT_TEAM, bot_state_s::lastflagcapture_time, NULL, bot_state_s::numteammates, Q_stricmp(), random, strncpy(), bot_state_s::teamgiveorders_time, bot_state_s::teamleader, trap_BotEnterChat(), and VOICECHAT_STARTLEADER.

Referenced by BotDeathmatchAI().

01930                                 {
01931     int numteammates;
01932     char netname[MAX_NETNAME];
01933 
01934     //
01935     if ( gametype < GT_TEAM  )
01936         return;
01937     // make sure we've got a valid team leader
01938     if (!BotValidTeamLeader(bs)) {
01939         //
01940         if (!FindHumanTeamLeader(bs)) {
01941             //
01942             if (!bs->askteamleader_time && !bs->becometeamleader_time) {
01943                 if (bs->entergame_time + 10 > FloatTime()) {
01944                     bs->askteamleader_time = FloatTime() + 5 + random() * 10;
01945                 }
01946                 else {
01947                     bs->becometeamleader_time = FloatTime() + 5 + random() * 10;
01948                 }
01949             }
01950             if (bs->askteamleader_time && bs->askteamleader_time < FloatTime()) {
01951                 // if asked for a team leader and no response
01952                 BotAI_BotInitialChat(bs, "whoisteamleader", NULL);
01953                 trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
01954                 bs->askteamleader_time = 0;
01955                 bs->becometeamleader_time = FloatTime() + 8 + random() * 10;
01956             }
01957             if (bs->