00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "g_local.h"
00034 #include "botlib.h"
00035 #include "be_aas.h"
00036 #include "be_ea.h"
00037 #include "be_ai_char.h"
00038 #include "be_ai_chat.h"
00039 #include "be_ai_gen.h"
00040 #include "be_ai_goal.h"
00041 #include "be_ai_move.h"
00042 #include "be_ai_weap.h"
00043
00044 #include "ai_main.h"
00045 #include "ai_dmq3.h"
00046 #include "ai_chat.h"
00047 #include "ai_cmd.h"
00048 #include "ai_dmnet.h"
00049 #include "ai_team.h"
00050 #include "ai_vcmd.h"
00051
00052 #include "match.h"
00053
00054
00055 #include "../../ui/menudef.h"
00056
00057
00058 typedef struct bot_ctftaskpreference_s
00059 {
00060 char name[36];
00061 int preference;
00062 } bot_ctftaskpreference_t;
00063
00064 bot_ctftaskpreference_t ctftaskpreferences[MAX_CLIENTS];
00065
00066
00067
00068
00069
00070
00071
00072 int BotValidTeamLeader(bot_state_t *bs) {
00073 if (!strlen(bs->teamleader)) return qfalse;
00074 if (ClientFromName(bs->teamleader) == -1) return qfalse;
00075 return qtrue;
00076 }
00077
00078
00079
00080
00081
00082
00083 int BotNumTeamMates(bot_state_t *bs) {
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
00095 if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
00096
00097 if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) continue;
00098
00099 if (BotSameTeam(bs, i)) {
00100 numplayers++;
00101 }
00102 }
00103 return numplayers;
00104 }
00105
00106
00107
00108
00109
00110
00111 int BotClientTravelTimeToGoal(int client, bot_goal_t *goal) {
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 }
00120
00121
00122
00123
00124
00125
00126 int BotSortTeamMatesByBaseTravelTime(bot_state_t *bs, int *teammates, int maxteammates) {
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
00155 if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
00156
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 }
00180
00181
00182
00183
00184
00185
00186 void BotSetTeamMateTaskPreference(bot_state_t *bs, int teammate, int preference) {
00187 char teammatename[MAX_NETNAME];
00188
00189 ctftaskpreferences[teammate].preference = preference;
00190 ClientName(teammate, teammatename, sizeof(teammatename));
00191 strcpy(ctftaskpreferences[teammate].name, teammatename);
00192 }
00193
00194
00195
00196
00197
00198
00199 int BotGetTeamMateTaskPreference(bot_state_t *bs, int teammate) {
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 }
00207
00208
00209
00210
00211
00212
00213 int BotSortTeamMatesByTaskPreference(bot_state_t *bs, int *teammates, int numteammates) {
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
00234 memcpy(&teammates[numteammates], defenders, numdefenders * sizeof(int));
00235 numteammates += numdefenders;
00236
00237 memcpy(&teammates[numteammates], roamers, numroamers * sizeof(int));
00238 numteammates += numroamers;
00239
00240 memcpy(&teammates[numteammates], attackers, numattackers * sizeof(int));
00241 numteammates += numattackers;
00242
00243 return numteammates;
00244 }
00245
00246
00247
00248
00249
00250
00251 void BotSayTeamOrderAlways(bot_state_t *bs, int toclient) {
00252 char teamchat[MAX_MESSAGE_SIZE];
00253 char buf[MAX_MESSAGE_SIZE];
00254 char name[MAX_NETNAME];
00255
00256
00257 if (bs->client == toclient) {
00258
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 }
00268
00269
00270
00271
00272
00273
00274 void BotSayTeamOrder(bot_state_t *bs, int toclient) {
00275 #ifdef MISSIONPACK
00276
00277 char buf[MAX_MESSAGE_SIZE];
00278
00279 trap_BotGetChatMessage(bs->cs, buf, sizeof(buf));
00280 #else
00281 BotSayTeamOrderAlways(bs, toclient);
00282 #endif
00283 }
00284
00285
00286
00287
00288
00289
00290 void BotVoiceChat(bot_state_t *bs, int toclient, char *voicechat) {
00291 #ifdef MISSIONPACK
00292 if (toclient == -1)
00293
00294 trap_EA_Command(bs->client, va("vsay_team %s", voicechat));
00295 else
00296
00297 trap_EA_Command(bs->client, va("vtell %d %s", toclient, voicechat));
00298 #endif
00299 }
00300
00301
00302
00303
00304
00305
00306 void BotVoiceChatOnly(bot_state_t *bs, int toclient, char *voicechat) {
00307 #ifdef MISSIONPACK
00308 if (toclient == -1)
00309
00310 trap_EA_Command(bs->client, va("vosay_team %s", voicechat));
00311 else
00312
00313 trap_EA_Command(bs->client, va("votell %d %s", toclient, voicechat));
00314 #endif
00315 }
00316
00317
00318
00319
00320
00321
00322 void BotSayVoiceTeamOrder(bot_state_t *bs, int toclient, char *voicechat) {
00323 #ifdef MISSIONPACK
00324 BotVoiceChat(bs, toclient, voicechat);
00325 #endif
00326 }
00327
00328
00329
00330
00331
00332
00333 void BotCTFOrders_BothFlagsNotAtBase(bot_state_t *bs) {
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
00341 switch(bs->numteammates) {
00342 case 1: break;
00343 case 2:
00344 {
00345
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
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
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 }
00441
00442
00443
00444
00445
00446
00447 void BotCTFOrders_FlagNotAtBase(bot_state_t *bs) {
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
00455 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
00456
00457 switch(bs->numteammates) {
00458 case 1: break;
00459 case 2:
00460 {
00461
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
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
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
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
00520 switch(bs->numteammates) {
00521 case 1: break;
00522 case 2:
00523 {
00524
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
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
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 }
00582
00583
00584
00585
00586
00587
00588 void BotCTFOrders_EnemyFlagNotAtBase(bot_state_t *bs) {
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
00596 switch(numteammates) {
00597 case 1: break;
00598 case 2:
00599 {
00600
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
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
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
00630 defenders = (int) (float) numteammates * 0.6 + 0.5;
00631 if (defenders > 6) defenders = 6;
00632
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
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 }
00684
00685
00686
00687
00688
00689
00690
00691 void BotCTFOrders_BothFlagsAtBase(bot_state_t *bs) {
00692 int numteammates, defenders, attackers, i;
00693 int teammates[MAX_CLIENTS];
00694 char name[MAX_NETNAME];
00695
00696
00697 numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
00698
00699 BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
00700
00701 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
00702
00703 switch(numteammates) {
00704 case 1: break;
00705 case 2:
00706 {
00707
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
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
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
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
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
00765 switch(numteammates) {
00766 case 1: break;
00767 case 2:
00768 {
00769
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
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
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
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 }
00826
00827
00828
00829
00830
00831
00832 void BotCTFOrders(bot_state_t *bs) {
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 }
00846
00847
00848
00849
00850
00851
00852
00853 void BotCreateGroup(bot_state_t *bs, int *teammates, int groupsize) {
00854 char name[MAX_NETNAME], leadername[MAX_NETNAME];
00855 int i;
00856
00857
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 }
00871
00872
00873
00874
00875
00876
00877
00878
00879 void BotTeamOrders(bot_state_t *bs) {
00880 int teammates[MAX_CLIENTS];
00881 int numteammates, i;
00882 char buf[MAX_INFO_STRING];
00883 static int maxclients;
00884
00885 if (!maxclients)
00886 maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
00887
00888 numteammates = 0;
00889 for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
00890 trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
00891
00892 if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
00893
00894 if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) continue;
00895
00896 if (BotSameTeam(bs, i)) {
00897 teammates[numteammates] = i;
00898 numteammates++;
00899 }
00900 }
00901
00902 switch(numteammates) {
00903 case 1: break;
00904 case 2:
00905 {
00906
00907 break;
00908 }
00909 case 3:
00910 {
00911
00912 BotCreateGroup(bs, teammates, 2);
00913 break;
00914 }
00915 case 4:
00916 {
00917 BotCreateGroup(bs, teammates, 2);
00918 BotCreateGroup(bs, &teammates[2], 2);
00919 break;
00920 }
00921 case 5:
00922 {
00923 BotCreateGroup(bs, teammates, 2);
00924 BotCreateGroup(bs, &teammates[2], 3);
00925 break;
00926 }
00927 default:
00928 {
00929 if (numteammates <= 10) {
00930 for (i = 0; i < numteammates / 2; i++) {
00931 BotCreateGroup(bs, &teammates[i*2], 2);
00932 }
00933 }
00934 break;
00935 }
00936 }
00937 }
00938
00939 #ifdef MISSIONPACK
00940
00941
00942
00943
00944
00945
00946
00947
00948 void Bot1FCTFOrders_FlagAtCenter(bot_state_t *bs) {
00949 int numteammates, defenders, attackers, i;
00950 int teammates[MAX_CLIENTS];
00951 char name[MAX_NETNAME];
00952
00953
00954 numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
00955
00956 BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
00957
00958 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
00959
00960 switch(numteammates) {
00961 case 1: break;
00962 case 2:
00963 {
00964
00965 ClientName(teammates[0], name, sizeof(name));
00966 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00967 BotSayTeamOrder(bs, teammates[0]);
00968 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00969
00970 ClientName(teammates[1], name, sizeof(name));
00971 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00972 BotSayTeamOrder(bs, teammates[1]);
00973 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
00974 break;
00975 }
00976 case 3:
00977 {
00978
00979 ClientName(teammates[0], name, sizeof(name));
00980 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00981 BotSayTeamOrder(bs, teammates[0]);
00982 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00983
00984 ClientName(teammates[1], name, sizeof(name));
00985 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
00986 BotSayTeamOrder(bs, teammates[1]);
00987 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
00988
00989 ClientName(teammates[2], name, sizeof(name));
00990 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
00991 BotSayTeamOrder(bs, teammates[2]);
00992 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
00993 break;
00994 }
00995 default:
00996 {
00997
00998 defenders = (int) (float) numteammates * 0.5 + 0.5;
00999 if (defenders > 5) defenders = 5;
01000
01001 attackers = (int) (float) numteammates * 0.4 + 0.5;
01002 if (attackers > 4) attackers = 4;
01003 for (i = 0; i < defenders; i++) {
01004
01005 ClientName(teammates[i], name, sizeof(name));
01006 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01007 BotSayTeamOrder(bs, teammates[i]);
01008 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01009 }
01010 for (i = 0; i < attackers; i++) {
01011
01012 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01013 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01014 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01015 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
01016 }
01017
01018 break;
01019 }
01020 }
01021 }
01022 else {
01023
01024 switch(numteammates) {
01025 case 1: break;
01026 case 2:
01027 {
01028
01029 ClientName(teammates[0], name, sizeof(name));
01030 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01031 BotSayTeamOrder(bs, teammates[0]);
01032 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01033
01034 ClientName(teammates[1], name, sizeof(name));
01035 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01036 BotSayTeamOrder(bs, teammates[1]);
01037 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
01038 break;
01039 }
01040 case 3:
01041 {
01042
01043 ClientName(teammates[0], name, sizeof(name));
01044 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01045 BotSayTeamOrder(bs, teammates[0]);
01046 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01047
01048 ClientName(teammates[1], name, sizeof(name));
01049 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01050 BotSayTeamOrder(bs, teammates[1]);
01051 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
01052
01053 ClientName(teammates[2], name, sizeof(name));
01054 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01055 BotSayTeamOrder(bs, teammates[2]);
01056 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
01057 break;
01058 }
01059 default:
01060 {
01061
01062 defenders = (int) (float) numteammates * 0.3 + 0.5;
01063 if (defenders > 3) defenders = 3;
01064
01065 attackers = (int) (float) numteammates * 0.6 + 0.5;
01066 if (attackers > 6) attackers = 6;
01067 for (i = 0; i < defenders; i++) {
01068
01069 ClientName(teammates[i], name, sizeof(name));
01070 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01071 BotSayTeamOrder(bs, teammates[i]);
01072 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01073 }
01074 for (i = 0; i < attackers; i++) {
01075
01076 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01077 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01078 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01079 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
01080 }
01081
01082 break;
01083 }
01084 }
01085 }
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095 void Bot1FCTFOrders_TeamHasFlag(bot_state_t *bs) {
01096 int numteammates, defenders, attackers, i, other;
01097 int teammates[MAX_CLIENTS];
01098 char name[MAX_NETNAME], carriername[MAX_NETNAME];
01099
01100
01101 numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
01102
01103 BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
01104
01105 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
01106
01107 switch(numteammates) {
01108 case 1: break;
01109 case 2:
01110 {
01111
01112 if (teammates[0] == bs->flagcarrier) other = teammates[1];
01113 else other = teammates[0];
01114 ClientName(other, name, sizeof(name));
01115 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01116 BotSayTeamOrder(bs, other);
01117 BotSayVoiceTeamOrder(bs, other, VOICECHAT_OFFENSE);
01118 break;
01119 }
01120 case 3:
01121 {
01122
01123 if (teammates[0] != bs->flagcarrier) other = teammates[0];
01124 else other = teammates[1];
01125 ClientName(other, name, sizeof(name));
01126 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01127 BotSayTeamOrder(bs, other);
01128 BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
01129
01130 if (teammates[2] != bs->flagcarrier) other = teammates[2];
01131 else other = teammates[1];
01132 ClientName(other, name, sizeof(name));
01133 if ( bs->flagcarrier != -1 ) {
01134 ClientName(bs->flagcarrier, carriername, sizeof(carriername));
01135 if (bs->flagcarrier == bs->client) {
01136 BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
01137 BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWME);
01138 }
01139 else {
01140 BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
01141 BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWFLAGCARRIER);
01142 }
01143 }
01144 else {
01145
01146 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01147 BotSayVoiceTeamOrder(bs, other, VOICECHAT_GETFLAG);
01148 }
01149 BotSayTeamOrder(bs, other);
01150 break;
01151 }
01152 default:
01153 {
01154
01155 defenders = (int) (float) numteammates * 0.3 + 0.5;
01156 if (defenders > 3) defenders = 3;
01157
01158 attackers = (int) (float) numteammates * 0.7 + 0.5;
01159 if (attackers > 7) attackers = 7;
01160 for (i = 0; i < defenders; i++) {
01161
01162 if (teammates[i] == bs->flagcarrier) {
01163 continue;
01164 }
01165 ClientName(teammates[i], name, sizeof(name));
01166 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01167 BotSayTeamOrder(bs, teammates[i]);
01168 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01169 }
01170 if (bs->flagcarrier != -1) {
01171 ClientName(bs->flagcarrier, carriername, sizeof(carriername));
01172 for (i = 0; i < attackers; i++) {
01173
01174 if (teammates[numteammates - i - 1] == bs->flagcarrier) {
01175 continue;
01176 }
01177
01178 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01179 if (bs->flagcarrier == bs->client) {
01180 BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
01181 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWME);
01182 }
01183 else {
01184 BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
01185 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWFLAGCARRIER);
01186 }
01187 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01188 }
01189 }
01190 else {
01191 for (i = 0; i < attackers; i++) {
01192
01193 if (teammates[numteammates - i - 1] == bs->flagcarrier) {
01194 continue;
01195 }
01196
01197 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01198 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01199 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01200 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
01201 }
01202 }
01203
01204 break;
01205 }
01206 }
01207 }
01208 else {
01209
01210 switch(numteammates) {
01211 case 1: break;
01212 case 2:
01213 {
01214
01215 if (teammates[0] == bs->flagcarrier) other = teammates[1];
01216 else other = teammates[0];
01217 ClientName(other, name, sizeof(name));
01218 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01219 BotSayTeamOrder(bs, other);
01220 BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
01221 break;
01222 }
01223 case 3:
01224 {
01225
01226 if (teammates[0] != bs->flagcarrier) other = teammates[0];
01227 else other = teammates[1];
01228 ClientName(other, name, sizeof(name));
01229 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01230 BotSayTeamOrder(bs, other);
01231 BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
01232
01233 if (teammates[2] != bs->flagcarrier) other = teammates[2];
01234 else other = teammates[1];
01235 ClientName(other, name, sizeof(name));
01236 ClientName(bs->flagcarrier, carriername, sizeof(carriername));
01237 if (bs->flagcarrier == bs->client) {
01238 BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
01239 BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWME);
01240 }
01241 else {
01242 BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
01243 BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWFLAGCARRIER);
01244 }
01245 BotSayTeamOrder(bs, other);
01246 break;
01247 }
01248 default:
01249 {
01250
01251 defenders = (int) (float) numteammates * 0.2 + 0.5;
01252 if (defenders > 2) defenders = 2;
01253
01254 attackers = (int) (float) numteammates * 0.8 + 0.5;
01255 if (attackers > 8) attackers = 8;
01256 for (i = 0; i < defenders; i++) {
01257
01258 if (teammates[i] == bs->flagcarrier) {
01259 continue;
01260 }
01261 ClientName(teammates[i], name, sizeof(name));
01262 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01263 BotSayTeamOrder(bs, teammates[i]);
01264 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01265 }
01266 ClientName(bs->flagcarrier, carriername, sizeof(carriername));
01267 for (i = 0; i < attackers; i++) {
01268
01269 if (teammates[numteammates - i - 1] == bs->flagcarrier) {
01270 continue;
01271 }
01272
01273 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01274 if (bs->flagcarrier == bs->client) {
01275 BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
01276 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWME);
01277 }
01278 else {
01279 BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
01280 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWFLAGCARRIER);
01281 }
01282 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01283 }
01284
01285 break;
01286 }
01287 }
01288 }
01289 }
01290
01291
01292
01293
01294
01295
01296
01297
01298 void Bot1FCTFOrders_EnemyHasFlag(bot_state_t *bs) {
01299 int numteammates, defenders, attackers, i;
01300 int teammates[MAX_CLIENTS];
01301 char name[MAX_NETNAME];
01302
01303
01304 numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
01305
01306 BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
01307
01308 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
01309
01310 switch(numteammates) {
01311 case 1: break;
01312 case 2:
01313 {
01314
01315 ClientName(teammates[0], name, sizeof(name));
01316 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01317 BotSayTeamOrder(bs, teammates[0]);
01318 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01319
01320 ClientName(teammates[1], name, sizeof(name));
01321 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01322 BotSayTeamOrder(bs, teammates[1]);
01323 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
01324 break;
01325 }
01326 case 3:
01327 {
01328
01329 ClientName(teammates[0], name, sizeof(name));
01330 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01331 BotSayTeamOrder(bs, teammates[0]);
01332 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01333
01334 ClientName(teammates[1], name, sizeof(name));
01335 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01336 BotSayTeamOrder(bs, teammates[1]);
01337 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
01338
01339 ClientName(teammates[2], name, sizeof(name));
01340 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01341 BotSayTeamOrder(bs, teammates[2]);
01342 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_DEFEND);
01343 break;
01344 }
01345 default:
01346 {
01347
01348 defenders = (int) (float) numteammates * 0.8 + 0.5;
01349 if (defenders > 8) defenders = 8;
01350
01351 attackers = (int) (float) numteammates * 0.1 + 0.5;
01352 if (attackers > 2) attackers = 2;
01353 for (i = 0; i < defenders; i++) {
01354
01355 ClientName(teammates[i], name, sizeof(name));
01356 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01357 BotSayTeamOrder(bs, teammates[i]);
01358 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01359 }
01360 for (i = 0; i < attackers; i++) {
01361
01362 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01363 BotAI_BotInitialChat(bs, "cmd_returnflag", name, NULL);
01364 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01365 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
01366 }
01367
01368 break;
01369 }
01370 }
01371 }
01372 else {
01373
01374 switch(numteammates) {
01375 case 1: break;
01376 case 2:
01377 {
01378
01379 ClientName(teammates[0], name, sizeof(name));
01380 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01381 BotSayTeamOrder(bs, teammates[0]);
01382 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01383
01384 ClientName(teammates[1], name, sizeof(name));
01385 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01386 BotSayTeamOrder(bs, teammates[1]);
01387 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
01388 break;
01389 }
01390 case 3:
01391 {
01392
01393 ClientName(teammates[0], name, sizeof(name));
01394 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01395 BotSayTeamOrder(bs, teammates[0]);
01396 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01397
01398 ClientName(teammates[1], name, sizeof(name));
01399 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01400 BotSayTeamOrder(bs, teammates[1]);
01401 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
01402
01403 ClientName(teammates[2], name, sizeof(name));
01404 BotAI_BotInitialChat(bs, "cmd_returnflag", name, NULL);
01405 BotSayTeamOrder(bs, teammates[2]);
01406 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
01407 break;
01408 }
01409 default:
01410 {
01411
01412 defenders = (int) (float) numteammates * 0.7 + 0.5;
01413 if (defenders > 8) defenders = 8;
01414
01415 attackers = (int) (float) numteammates * 0.2 + 0.5;
01416 if (attackers > 2) attackers = 2;
01417 for (i = 0; i < defenders; i++) {
01418
01419 ClientName(teammates[i], name, sizeof(name));
01420 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01421 BotSayTeamOrder(bs, teammates[i]);
01422 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01423 }
01424 for (i = 0; i < attackers; i++) {
01425
01426 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01427 BotAI_BotInitialChat(bs, "cmd_returnflag", name, NULL);
01428 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01429 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
01430 }
01431
01432 break;
01433 }
01434 }
01435 }
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445 void Bot1FCTFOrders_EnemyDroppedFlag(bot_state_t *bs) {
01446 int numteammates, defenders, attackers, i;
01447 int teammates[MAX_CLIENTS];
01448 char name[MAX_NETNAME];
01449
01450
01451 numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
01452
01453 BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
01454
01455 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
01456
01457 switch(numteammates) {
01458 case 1: break;
01459 case 2:
01460 {
01461
01462 ClientName(teammates[0], name, sizeof(name));
01463 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01464 BotSayTeamOrder(bs, teammates[0]);
01465 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01466
01467 ClientName(teammates[1], name, sizeof(name));
01468 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01469 BotSayTeamOrder(bs, teammates[1]);
01470 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
01471 break;
01472 }
01473 case 3:
01474 {
01475
01476 ClientName(teammates[0], name, sizeof(name));
01477 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01478 BotSayTeamOrder(bs, teammates[0]);
01479 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01480
01481 ClientName(teammates[1], name, sizeof(name));
01482 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01483 BotSayTeamOrder(bs, teammates[1]);
01484 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
01485
01486 ClientName(teammates[2], name, sizeof(name));
01487 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01488 BotSayTeamOrder(bs, teammates[2]);
01489 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
01490 break;
01491 }
01492 default:
01493 {
01494
01495 defenders = (int) (float) numteammates * 0.5 + 0.5;
01496 if (defenders > 5) defenders = 5;
01497
01498 attackers = (int) (float) numteammates * 0.4 + 0.5;
01499 if (attackers > 4) attackers = 4;
01500 for (i = 0; i < defenders; i++) {
01501
01502 ClientName(teammates[i], name, sizeof(name));
01503 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01504 BotSayTeamOrder(bs, teammates[i]);
01505 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01506 }
01507 for (i = 0; i < attackers; i++) {
01508
01509 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01510 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01511 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01512 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
01513 }
01514
01515 break;
01516 }
01517 }
01518 }
01519 else {
01520
01521 switch(numteammates) {
01522 case 1: break;
01523 case 2:
01524 {
01525
01526 ClientName(teammates[0], name, sizeof(name));
01527 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01528 BotSayTeamOrder(bs, teammates[0]);
01529 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01530
01531 ClientName(teammates[1], name, sizeof(name));
01532 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01533 BotSayTeamOrder(bs, teammates[1]);
01534 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
01535 break;
01536 }
01537 case 3:
01538 {
01539
01540 ClientName(teammates[0], name, sizeof(name));
01541 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01542 BotSayTeamOrder(bs, teammates[0]);
01543 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01544
01545 ClientName(teammates[1], name, sizeof(name));
01546 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01547 BotSayTeamOrder(bs, teammates[1]);
01548 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
01549
01550 ClientName(teammates[2], name, sizeof(name));
01551 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01552 BotSayTeamOrder(bs, teammates[2]);
01553 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
01554 break;
01555 }
01556 default:
01557 {
01558
01559 defenders = (int) (float) numteammates * 0.3 + 0.5;
01560 if (defenders > 3) defenders = 3;
01561
01562 attackers = (int) (float) numteammates * 0.6 + 0.5;
01563 if (attackers > 6) attackers = 6;
01564 for (i = 0; i < defenders; i++) {
01565
01566 ClientName(teammates[i], name, sizeof(name));
01567 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01568 BotSayTeamOrder(bs, teammates[i]);
01569 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01570 }
01571 for (i = 0; i < attackers; i++) {
01572
01573 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01574 BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
01575 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01576 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_DEFEND);
01577 }
01578
01579 break;
01580 }
01581 }
01582 }
01583 }
01584
01585
01586
01587
01588
01589
01590 void Bot1FCTFOrders(bot_state_t *bs) {
01591 switch(bs->neutralflagstatus) {
01592 case 0: Bot1FCTFOrders_FlagAtCenter(bs); break;
01593 case 1: Bot1FCTFOrders_TeamHasFlag(bs); break;
01594 case 2: Bot1FCTFOrders_EnemyHasFlag(bs); break;
01595 case 3: Bot1FCTFOrders_EnemyDroppedFlag(bs); break;
01596 }
01597 }
01598
01599
01600
01601
01602
01603
01604
01605
01606 void BotObeliskOrders(bot_state_t *bs) {
01607 int numteammates, defenders, attackers, i;
01608 int teammates[MAX_CLIENTS];
01609 char name[MAX_NETNAME];
01610
01611
01612 numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
01613
01614 BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
01615
01616 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
01617
01618 switch(numteammates) {
01619 case 1: break;
01620 case 2:
01621 {
01622
01623 ClientName(teammates[0], name, sizeof(name));
01624 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01625 BotSayTeamOrder(bs, teammates[0]);
01626 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01627
01628 ClientName(teammates[1], name, sizeof(name));
01629 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01630 BotSayTeamOrder(bs, teammates[1]);
01631 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
01632 break;
01633 }
01634 case 3:
01635 {
01636
01637 ClientName(teammates[0], name, sizeof(name));
01638 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01639 BotSayTeamOrder(bs, teammates[0]);
01640 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01641
01642 ClientName(teammates[1], name, sizeof(name));
01643 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01644 BotSayTeamOrder(bs, teammates[1]);
01645 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
01646
01647 ClientName(teammates[2], name, sizeof(name));
01648 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01649 BotSayTeamOrder(bs, teammates[2]);
01650 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
01651 break;
01652 }
01653 default:
01654 {
01655
01656 defenders = (int) (float) numteammates * 0.5 + 0.5;
01657 if (defenders > 5) defenders = 5;
01658
01659 attackers = (int) (float) numteammates * 0.4 + 0.5;
01660 if (attackers > 4) attackers = 4;
01661 for (i = 0; i < defenders; i++) {
01662
01663 ClientName(teammates[i], name, sizeof(name));
01664 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01665 BotSayTeamOrder(bs, teammates[i]);
01666 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01667 }
01668 for (i = 0; i < attackers; i++) {
01669
01670 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01671 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01672 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01673 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
01674 }
01675
01676 break;
01677 }
01678 }
01679 }
01680 else {
01681
01682 switch(numteammates) {
01683 case 1: break;
01684 case 2:
01685 {
01686
01687 ClientName(teammates[0], name, sizeof(name));
01688 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01689 BotSayTeamOrder(bs, teammates[0]);
01690 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01691
01692 ClientName(teammates[1], name, sizeof(name));
01693 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01694 BotSayTeamOrder(bs, teammates[1]);
01695 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
01696 break;
01697 }
01698 case 3:
01699 {
01700
01701 ClientName(teammates[0], name, sizeof(name));
01702 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01703 BotSayTeamOrder(bs, teammates[0]);
01704 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01705
01706 ClientName(teammates[1], name, sizeof(name));
01707 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01708 BotSayTeamOrder(bs, teammates[1]);
01709 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
01710
01711 ClientName(teammates[2], name, sizeof(name));
01712 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01713 BotSayTeamOrder(bs, teammates[2]);
01714 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
01715 break;
01716 }
01717 default:
01718 {
01719
01720 defenders = (int) (float) numteammates * 0.3 + 0.5;
01721 if (defenders > 3) defenders = 3;
01722
01723 attackers = (int) (float) numteammates * 0.7 + 0.5;
01724 if (attackers > 7) attackers = 7;
01725 for (i = 0; i < defenders; i++) {
01726
01727 ClientName(teammates[i], name, sizeof(name));
01728 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01729 BotSayTeamOrder(bs, teammates[i]);
01730 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01731 }
01732 for (i = 0; i < attackers; i++) {
01733
01734 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01735 BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
01736 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01737 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
01738 }
01739
01740 break;
01741 }
01742 }
01743 }
01744 }
01745
01746
01747
01748
01749
01750
01751
01752
01753 void BotHarvesterOrders(bot_state_t *bs) {
01754 int numteammates, defenders, attackers, i;
01755 int teammates[MAX_CLIENTS];
01756 char name[MAX_NETNAME];
01757
01758
01759 numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
01760
01761 BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
01762
01763 if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
01764
01765 switch(numteammates) {
01766 case 1: break;
01767 case 2:
01768 {
01769
01770 ClientName(teammates[0], name, sizeof(name));
01771 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01772 BotSayTeamOrder(bs, teammates[0]);
01773 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01774
01775 ClientName(teammates[1], name, sizeof(name));
01776 BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
01777 BotSayTeamOrder(bs, teammates[1]);
01778 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
01779 break;
01780 }
01781 case 3:
01782 {
01783
01784 ClientName(teammates[0], name, sizeof(name));
01785 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01786 BotSayTeamOrder(bs, teammates[0]);
01787 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01788
01789 ClientName(teammates[1], name, sizeof(name));
01790 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01791 BotSayTeamOrder(bs, teammates[1]);
01792 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
01793
01794 ClientName(teammates[2], name, sizeof(name));
01795 BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
01796 BotSayTeamOrder(bs, teammates[2]);
01797 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
01798 break;
01799 }
01800 default:
01801 {
01802
01803 defenders = (int) (float) numteammates * 0.5 + 0.5;
01804 if (defenders > 5) defenders = 5;
01805
01806 attackers = (int) (float) numteammates * 0.4 + 0.5;
01807 if (attackers > 4) attackers = 4;
01808 for (i = 0; i < defenders; i++) {
01809
01810 ClientName(teammates[i], name, sizeof(name));
01811 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01812 BotSayTeamOrder(bs, teammates[i]);
01813 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01814 }
01815 for (i = 0; i < attackers; i++) {
01816
01817 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01818 BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
01819 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01820 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
01821 }
01822
01823 break;
01824 }
01825 }
01826 }
01827 else {
01828
01829 switch(numteammates) {
01830 case 1: break;
01831 case 2:
01832 {
01833
01834 ClientName(teammates[0], name, sizeof(name));
01835 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01836 BotSayTeamOrder(bs, teammates[0]);
01837 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01838
01839 ClientName(teammates[1], name, sizeof(name));
01840 BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
01841 BotSayTeamOrder(bs, teammates[1]);
01842 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
01843 break;
01844 }
01845 case 3:
01846 {
01847
01848 ClientName(teammates[0], name, sizeof(name));
01849 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01850 BotSayTeamOrder(bs, teammates[0]);
01851 BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
01852
01853 ClientName(teammates[1], name, sizeof(name));
01854 BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
01855 BotSayTeamOrder(bs, teammates[1]);
01856 BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
01857
01858 ClientName(teammates[2], name, sizeof(name));
01859 BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
01860 BotSayTeamOrder(bs, teammates[2]);
01861 BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
01862 break;
01863 }
01864 default:
01865 {
01866
01867 defenders = (int) (float) numteammates * 0.3 + 0.5;
01868 if (defenders > 3) defenders = 3;
01869
01870 attackers = (int) (float) numteammates * 0.7 + 0.5;
01871 if (attackers > 7) attackers = 7;
01872 for (i = 0; i < defenders; i++) {
01873
01874 ClientName(teammates[i], name, sizeof(name));
01875 BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
01876 BotSayTeamOrder(bs, teammates[i]);
01877 BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
01878 }
01879 for (i = 0; i < attackers; i++) {
01880
01881 ClientName(teammates[numteammates - i - 1], name, sizeof(name));
01882 BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
01883 BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
01884 BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
01885 }
01886
01887 break;
01888 }
01889 }
01890 }
01891 }
01892 #endif
01893
01894
01895
01896
01897
01898
01899 int FindHumanTeamLeader(bot_state_t *bs) {
01900 int i;
01901
01902 for (i = 0; i < MAX_CLIENTS; i++) {
01903 if ( g_entities[i].inuse ) {
01904
01905 if ( !(g_entities[i].r.svFlags & SVF_BOT) ) {
01906
01907 if (!notleader[i]) {
01908
01909 if ( BotSameTeam(bs, i) ) {
01910 ClientName(i, bs->teamleader, sizeof(bs->teamleader));
01911
01912 if ( !BotSetLastOrderedTask(bs) ) {
01913
01914 BotVoiceChat_Defend(bs, i, SAY_TELL);
01915 }
01916 return qtrue;
01917 }
01918 }
01919 }
01920 }
01921 }
01922 return qfalse;
01923 }
01924
01925
01926
01927
01928
01929
01930 void BotTeamAI(bot_state_t *bs) {
01931 int numteammates;
01932 char netname[MAX_NETNAME];
01933
01934
01935 if ( gametype < GT_TEAM )
01936 return;
01937
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
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->becometeamleader_time && bs->becometeamleader_time < FloatTime()) {
01958 BotAI_BotInitialChat(bs, "iamteamleader", NULL);
01959 trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
01960 BotSayVoiceTeamOrder(bs, -1, VOICECHAT_STARTLEADER);
01961 ClientName(bs->client, netname, sizeof(netname));
01962 strncpy(bs->teamleader, netname, sizeof(bs->teamleader));
01963 bs->teamleader[sizeof(bs->teamleader)] = '\0';
01964 bs->becometeamleader_time = 0;
01965 }
01966 return;
01967 }
01968 }
01969 bs->askteamleader_time = 0;
01970 bs->becometeamleader_time = 0;
01971
01972
01973 ClientName(bs->client, netname, sizeof(netname));
01974 if (Q_stricmp(netname, bs->teamleader) != 0) return;
01975
01976 numteammates = BotNumTeamMates(bs);
01977
01978 switch(gametype) {
01979 case GT_TEAM:
01980 {
01981 if (bs->numteammates != numteammates || bs->forceorders) {
01982 bs->teamgiveorders_time = FloatTime();
01983 bs->numteammates = numteammates;
01984 bs->forceorders = qfalse;
01985 }
01986
01987 if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 5) {
01988 BotTeamOrders(bs);
01989
01990 bs->teamgiveorders_time = FloatTime() + 120;
01991 }
01992 break;
01993 }
01994 case GT_CTF:
01995 {
01996
01997
01998 if (bs->numteammates != numteammates || bs->flagstatuschanged || bs->forceorders) {
01999 bs->teamgiveorders_time = FloatTime();
02000 bs->numteammates = numteammates;
02001 bs->flagstatuschanged = qfalse;
02002 bs->forceorders = qfalse;
02003 }
02004
02005 if (bs->lastflagcapture_time < FloatTime() - 240) {
02006 bs->lastflagcapture_time = FloatTime();
02007
02008 if (random() < 0.4) {
02009 bs->ctfstrategy ^= CTFS_AGRESSIVE;
02010 bs->teamgiveorders_time = FloatTime();
02011 }
02012 }
02013
02014 if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 3) {
02015 BotCTFOrders(bs);
02016
02017 bs->teamgiveorders_time = 0;
02018 }
02019 break;
02020 }
02021 #ifdef MISSIONPACK
02022 case GT_1FCTF:
02023 {
02024 if (bs->numteammates != numteammates || bs->flagstatuschanged || bs->forceorders) {
02025 bs->teamgiveorders_time = FloatTime();
02026 bs->numteammates = numteammates;
02027 bs->flagstatuschanged = qfalse;
02028 bs->forceorders = qfalse;
02029 }
02030
02031 if (bs->lastflagcapture_time < FloatTime() - 240) {
02032 bs->lastflagcapture_time = FloatTime();
02033
02034 if (random() < 0.4) {
02035 bs->ctfstrategy ^= CTFS_AGRESSIVE;
02036 bs->teamgiveorders_time = FloatTime();
02037 }
02038 }
02039
02040 if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 2) {
02041 Bot1FCTFOrders(bs);
02042
02043 bs->teamgiveorders_time = 0;
02044 }
02045 break;
02046 }
02047 case GT_OBELISK:
02048 {
02049 if (bs->numteammates != numteammates || bs->forceorders) {
02050 bs->teamgiveorders_time = FloatTime();
02051 bs->numteammates = numteammates;
02052 bs->forceorders = qfalse;
02053 }
02054
02055 if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 5) {
02056 BotObeliskOrders(bs);
02057
02058 bs->teamgiveorders_time = FloatTime() + 30;
02059 }
02060 break;
02061 }
02062 case GT_HARVESTER:
02063 {
02064 if (bs->numteammates != numteammates || bs->forceorders) {
02065 bs->teamgiveorders_time = FloatTime();
02066 bs->numteammates = numteammates;
02067 bs->forceorders = qfalse;
02068 }
02069
02070 if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 5) {
02071 BotHarvesterOrders(bs);
02072
02073 bs->teamgiveorders_time = FloatTime() + 30;
02074 }
02075 break;
02076 }
02077 #endif
02078 }
02079 }
02080