2
===========================================================================
3
Copyright (C) 1999-2005 Id Software, Inc.
5
This file is part of Quake III Arena source code.
7
Quake III Arena source code is free software; you can redistribute it
8
and/or modify it under the terms of the GNU General Public License as
9
published by the Free Software Foundation; either version 2 of the License,
10
or (at your option) any later version.
12
Quake III Arena source code is distributed in the hope that it will be
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Quake III Arena source code; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
===========================================================================
24
/*****************************************************************************
29
* $Archive: /MissionPack/code/game/ai_team.c $
31
*****************************************************************************/
34
#include "../botlib/botlib.h"
35
#include "../botlib/be_aas.h"
36
#include "../botlib/be_ea.h"
37
#include "../botlib/be_ai_char.h"
38
#include "../botlib/be_ai_chat.h"
39
#include "../botlib/be_ai_gen.h"
40
#include "../botlib/be_ai_goal.h"
41
#include "../botlib/be_ai_move.h"
42
#include "../botlib/be_ai_weap.h"
54
// for the voice chats
55
#include "../../ui/menudef.h"
57
//ctf task preferences for a client
58
typedef struct bot_ctftaskpreference_s
62
} bot_ctftaskpreference_t;
64
bot_ctftaskpreference_t ctftaskpreferences[MAX_CLIENTS];
72
int BotValidTeamLeader(bot_state_t *bs) {
73
if (!strlen(bs->teamleader)) return qfalse;
74
if (ClientFromName(bs->teamleader) == -1) return qfalse;
83
int BotNumTeamMates(bot_state_t *bs) {
85
char buf[MAX_INFO_STRING];
86
static int maxclients;
89
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
92
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
93
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
94
//if no config string or no name
95
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
97
if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) continue;
99
if (BotSameTeam(bs, i)) {
108
BotClientTravelTimeToGoal
111
int BotClientTravelTimeToGoal(int client, bot_goal_t *goal) {
115
BotAI_GetClientState(client, &ps);
116
areanum = BotPointAreaNum(ps.origin);
117
if (!areanum) return 1;
118
return trap_AAS_AreaTravelTimeToGoalArea(areanum, ps.origin, goal->areanum, TFL_DEFAULT);
123
BotSortTeamMatesByBaseTravelTime
126
int BotSortTeamMatesByBaseTravelTime(bot_state_t *bs, int *teammates, int maxteammates) {
128
int i, j, k, numteammates, traveltime;
129
char buf[MAX_INFO_STRING];
130
static int maxclients;
131
int traveltimes[MAX_CLIENTS];
132
bot_goal_t *goal = NULL;
134
if (gametype == GT_CTF || gametype == GT_1FCTF) {
135
if (BotTeam(bs) == TEAM_RED)
138
goal = &ctf_blueflag;
142
if (BotTeam(bs) == TEAM_RED)
149
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
152
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
153
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
154
//if no config string or no name
155
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
157
if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) continue;
159
if (BotSameTeam(bs, i)) {
161
traveltime = BotClientTravelTimeToGoal(i, goal);
163
for (j = 0; j < numteammates; j++) {
164
if (traveltime < traveltimes[j]) {
165
for (k = numteammates; k > j; k--) {
166
traveltimes[k] = traveltimes[k-1];
167
teammates[k] = teammates[k-1];
172
traveltimes[j] = traveltime;
175
if (numteammates >= maxteammates) break;
183
BotSetTeamMateTaskPreference
186
void BotSetTeamMateTaskPreference(bot_state_t *bs, int teammate, int preference) {
187
char teammatename[MAX_NETNAME];
189
ctftaskpreferences[teammate].preference = preference;
190
ClientName(teammate, teammatename, sizeof(teammatename));
191
strcpy(ctftaskpreferences[teammate].name, teammatename);
196
BotGetTeamMateTaskPreference
199
int BotGetTeamMateTaskPreference(bot_state_t *bs, int teammate) {
200
char teammatename[MAX_NETNAME];
202
if (!ctftaskpreferences[teammate].preference) return 0;
203
ClientName(teammate, teammatename, sizeof(teammatename));
204
if (Q_stricmp(teammatename, ctftaskpreferences[teammate].name)) return 0;
205
return ctftaskpreferences[teammate].preference;
210
BotSortTeamMatesByTaskPreference
213
int BotSortTeamMatesByTaskPreference(bot_state_t *bs, int *teammates, int numteammates) {
214
int defenders[MAX_CLIENTS], numdefenders;
215
int attackers[MAX_CLIENTS], numattackers;
216
int roamers[MAX_CLIENTS], numroamers;
219
numdefenders = numattackers = numroamers = 0;
220
for (i = 0; i < numteammates; i++) {
221
preference = BotGetTeamMateTaskPreference(bs, teammates[i]);
222
if (preference & TEAMTP_DEFENDER) {
223
defenders[numdefenders++] = teammates[i];
225
else if (preference & TEAMTP_ATTACKER) {
226
attackers[numattackers++] = teammates[i];
229
roamers[numroamers++] = teammates[i];
233
//defenders at the front of the list
234
memcpy(&teammates[numteammates], defenders, numdefenders * sizeof(int));
235
numteammates += numdefenders;
236
//roamers in the middle
237
memcpy(&teammates[numteammates], roamers, numroamers * sizeof(int));
238
numteammates += numroamers;
239
//attacker in the back of the list
240
memcpy(&teammates[numteammates], attackers, numattackers * sizeof(int));
241
numteammates += numattackers;
251
void BotSayTeamOrderAlways(bot_state_t *bs, int toclient) {
252
char teamchat[MAX_MESSAGE_SIZE];
253
char buf[MAX_MESSAGE_SIZE];
254
char name[MAX_NETNAME];
256
//if the bot is talking to itself
257
if (bs->client == toclient) {
258
//don't show the message just put it in the console message queue
259
trap_BotGetChatMessage(bs->cs, buf, sizeof(buf));
260
ClientName(bs->client, name, sizeof(name));
261
Com_sprintf(teamchat, sizeof(teamchat), EC"(%s"EC")"EC": %s", name, buf);
262
trap_BotQueueConsoleMessage(bs->cs, CMS_CHAT, teamchat);
265
trap_BotEnterChat(bs->cs, toclient, CHAT_TELL);
274
void BotSayTeamOrder(bot_state_t *bs, int toclient) {
277
char buf[MAX_MESSAGE_SIZE];
279
trap_BotGetChatMessage(bs->cs, buf, sizeof(buf));
281
BotSayTeamOrderAlways(bs, toclient);
290
void BotVoiceChat(bot_state_t *bs, int toclient, char *voicechat) {
293
// voice only say team
294
trap_EA_Command(bs->client, va("vsay_team %s", voicechat));
296
// voice only tell single player
297
trap_EA_Command(bs->client, va("vtell %d %s", toclient, voicechat));
306
void BotVoiceChatOnly(bot_state_t *bs, int toclient, char *voicechat) {
309
// voice only say team
310
trap_EA_Command(bs->client, va("vosay_team %s", voicechat));
312
// voice only tell single player
313
trap_EA_Command(bs->client, va("votell %d %s", toclient, voicechat));
322
void BotSayVoiceTeamOrder(bot_state_t *bs, int toclient, char *voicechat) {
324
BotVoiceChat(bs, toclient, voicechat);
333
void BotCTFOrders_BothFlagsNotAtBase(bot_state_t *bs) {
334
int numteammates, defenders, attackers, i, other;
335
int teammates[MAX_CLIENTS];
336
char name[MAX_NETNAME], carriername[MAX_NETNAME];
338
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
339
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
340
//different orders based on the number of team mates
341
switch(bs->numteammates) {
345
//tell the one not carrying the flag to attack the enemy base
346
if (teammates[0] != bs->flagcarrier) other = teammates[0];
347
else other = teammates[1];
348
ClientName(other, name, sizeof(name));
349
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
350
BotSayTeamOrder(bs, other);
351
BotSayVoiceTeamOrder(bs, other, VOICECHAT_GETFLAG);
356
//tell the one closest to the base not carrying the flag to accompany the flag carrier
357
if (teammates[0] != bs->flagcarrier) other = teammates[0];
358
else other = teammates[1];
359
ClientName(other, name, sizeof(name));
360
if ( bs->flagcarrier != -1 ) {
361
ClientName(bs->flagcarrier, carriername, sizeof(carriername));
362
if (bs->flagcarrier == bs->client) {
363
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
364
BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWME);
367
BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
368
BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWFLAGCARRIER);
373
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
374
BotSayVoiceTeamOrder(bs, other, VOICECHAT_GETFLAG);
376
BotSayTeamOrder(bs, other);
377
//tell the one furthest from the the base not carrying the flag to get the enemy flag
378
if (teammates[2] != bs->flagcarrier) other = teammates[2];
379
else other = teammates[1];
380
ClientName(other, name, sizeof(name));
381
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
382
BotSayTeamOrder(bs, other);
383
BotSayVoiceTeamOrder(bs, other, VOICECHAT_RETURNFLAG);
388
defenders = (int) (float) numteammates * 0.4 + 0.5;
389
if (defenders > 4) defenders = 4;
390
attackers = (int) (float) numteammates * 0.5 + 0.5;
391
if (attackers > 5) attackers = 5;
392
if (bs->flagcarrier != -1) {
393
ClientName(bs->flagcarrier, carriername, sizeof(carriername));
394
for (i = 0; i < defenders; i++) {
396
if (teammates[i] == bs->flagcarrier) {
400
ClientName(teammates[i], name, sizeof(name));
401
if (bs->flagcarrier == bs->client) {
402
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
403
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_FOLLOWME);
406
BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
407
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_FOLLOWFLAGCARRIER);
409
BotSayTeamOrder(bs, teammates[i]);
413
for (i = 0; i < defenders; i++) {
415
if (teammates[i] == bs->flagcarrier) {
419
ClientName(teammates[i], name, sizeof(name));
420
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
421
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_GETFLAG);
422
BotSayTeamOrder(bs, teammates[i]);
425
for (i = 0; i < attackers; i++) {
427
if (teammates[numteammates - i - 1] == bs->flagcarrier) {
431
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
432
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
433
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
434
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_RETURNFLAG);
447
void BotCTFOrders_FlagNotAtBase(bot_state_t *bs) {
448
int numteammates, defenders, attackers, i;
449
int teammates[MAX_CLIENTS];
450
char name[MAX_NETNAME];
452
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
453
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
455
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
456
//different orders based on the number of team mates
457
switch(bs->numteammates) {
461
//both will go for the enemy flag
462
ClientName(teammates[0], name, sizeof(name));
463
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
464
BotSayTeamOrder(bs, teammates[0]);
465
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
467
ClientName(teammates[1], name, sizeof(name));
468
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
469
BotSayTeamOrder(bs, teammates[1]);
470
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
475
//keep one near the base for when the flag is returned
476
ClientName(teammates[0], name, sizeof(name));
477
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
478
BotSayTeamOrder(bs, teammates[0]);
479
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
480
//the other two get the flag
481
ClientName(teammates[1], name, sizeof(name));
482
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
483
BotSayTeamOrder(bs, teammates[1]);
484
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
486
ClientName(teammates[2], name, sizeof(name));
487
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
488
BotSayTeamOrder(bs, teammates[2]);
489
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
494
//keep some people near the base for when the flag is returned
495
defenders = (int) (float) numteammates * 0.3 + 0.5;
496
if (defenders > 3) defenders = 3;
497
attackers = (int) (float) numteammates * 0.7 + 0.5;
498
if (attackers > 6) attackers = 6;
499
for (i = 0; i < defenders; i++) {
501
ClientName(teammates[i], name, sizeof(name));
502
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
503
BotSayTeamOrder(bs, teammates[i]);
504
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
506
for (i = 0; i < attackers; i++) {
508
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
509
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
510
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
511
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
519
//different orders based on the number of team mates
520
switch(bs->numteammates) {
524
//both will go for the enemy flag
525
ClientName(teammates[0], name, sizeof(name));
526
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
527
BotSayTeamOrder(bs, teammates[0]);
528
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
530
ClientName(teammates[1], name, sizeof(name));
531
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
532
BotSayTeamOrder(bs, teammates[1]);
533
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
538
//everyone go for the flag
539
ClientName(teammates[0], name, sizeof(name));
540
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
541
BotSayTeamOrder(bs, teammates[0]);
542
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_GETFLAG);
544
ClientName(teammates[1], name, sizeof(name));
545
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
546
BotSayTeamOrder(bs, teammates[1]);
547
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
549
ClientName(teammates[2], name, sizeof(name));
550
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
551
BotSayTeamOrder(bs, teammates[2]);
552
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
557
//keep some people near the base for when the flag is returned
558
defenders = (int) (float) numteammates * 0.2 + 0.5;
559
if (defenders > 2) defenders = 2;
560
attackers = (int) (float) numteammates * 0.7 + 0.5;
561
if (attackers > 7) attackers = 7;
562
for (i = 0; i < defenders; i++) {
564
ClientName(teammates[i], name, sizeof(name));
565
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
566
BotSayTeamOrder(bs, teammates[i]);
567
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
569
for (i = 0; i < attackers; i++) {
571
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
572
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
573
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
574
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
588
void BotCTFOrders_EnemyFlagNotAtBase(bot_state_t *bs) {
589
int numteammates, defenders, attackers, i, other;
590
int teammates[MAX_CLIENTS];
591
char name[MAX_NETNAME], carriername[MAX_NETNAME];
593
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
594
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
595
//different orders based on the number of team mates
596
switch(numteammates) {
600
//tell the one not carrying the flag to defend the base
601
if (teammates[0] == bs->flagcarrier) other = teammates[1];
602
else other = teammates[0];
603
ClientName(other, name, sizeof(name));
604
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
605
BotSayTeamOrder(bs, other);
606
BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
611
//tell the one closest to the base not carrying the flag to defend the base
612
if (teammates[0] != bs->flagcarrier) other = teammates[0];
613
else other = teammates[1];
614
ClientName(other, name, sizeof(name));
615
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
616
BotSayTeamOrder(bs, other);
617
BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
618
//tell the other also to defend the base
619
if (teammates[2] != bs->flagcarrier) other = teammates[2];
620
else other = teammates[1];
621
ClientName(other, name, sizeof(name));
622
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
623
BotSayTeamOrder(bs, other);
624
BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
629
//60% will defend the base
630
defenders = (int) (float) numteammates * 0.6 + 0.5;
631
if (defenders > 6) defenders = 6;
632
//30% accompanies the flag carrier
633
attackers = (int) (float) numteammates * 0.3 + 0.5;
634
if (attackers > 3) attackers = 3;
635
for (i = 0; i < defenders; i++) {
637
if (teammates[i] == bs->flagcarrier) {
640
ClientName(teammates[i], name, sizeof(name));
641
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
642
BotSayTeamOrder(bs, teammates[i]);
643
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
645
// if we have a flag carrier
646
if ( bs->flagcarrier != -1 ) {
647
ClientName(bs->flagcarrier, carriername, sizeof(carriername));
648
for (i = 0; i < attackers; i++) {
650
if (teammates[numteammates - i - 1] == bs->flagcarrier) {
654
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
655
if (bs->flagcarrier == bs->client) {
656
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
657
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWME);
660
BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
661
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWFLAGCARRIER);
663
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
667
for (i = 0; i < attackers; i++) {
669
if (teammates[numteammates - i - 1] == bs->flagcarrier) {
673
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
674
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
675
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
676
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
691
void BotCTFOrders_BothFlagsAtBase(bot_state_t *bs) {
692
int numteammates, defenders, attackers, i;
693
int teammates[MAX_CLIENTS];
694
char name[MAX_NETNAME];
696
//sort team mates by travel time to base
697
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
698
//sort team mates by CTF preference
699
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
701
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
702
//different orders based on the number of team mates
703
switch(numteammates) {
707
//the one closest to the base will defend the base
708
ClientName(teammates[0], name, sizeof(name));
709
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
710
BotSayTeamOrder(bs, teammates[0]);
711
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
712
//the other will get the flag
713
ClientName(teammates[1], name, sizeof(name));
714
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
715
BotSayTeamOrder(bs, teammates[1]);
716
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
721
//the one closest to the base will defend the base
722
ClientName(teammates[0], name, sizeof(name));
723
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
724
BotSayTeamOrder(bs, teammates[0]);
725
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
726
//the second one closest to the base will defend the base
727
ClientName(teammates[1], name, sizeof(name));
728
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
729
BotSayTeamOrder(bs, teammates[1]);
730
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
731
//the other will get the flag
732
ClientName(teammates[2], name, sizeof(name));
733
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
734
BotSayTeamOrder(bs, teammates[2]);
735
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
740
defenders = (int) (float) numteammates * 0.5 + 0.5;
741
if (defenders > 5) defenders = 5;
742
attackers = (int) (float) numteammates * 0.4 + 0.5;
743
if (attackers > 4) attackers = 4;
744
for (i = 0; i < defenders; i++) {
746
ClientName(teammates[i], name, sizeof(name));
747
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
748
BotSayTeamOrder(bs, teammates[i]);
749
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
751
for (i = 0; i < attackers; i++) {
753
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
754
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
755
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
756
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
764
//different orders based on the number of team mates
765
switch(numteammates) {
769
//the one closest to the base will defend the base
770
ClientName(teammates[0], name, sizeof(name));
771
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
772
BotSayTeamOrder(bs, teammates[0]);
773
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
774
//the other will get the flag
775
ClientName(teammates[1], name, sizeof(name));
776
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
777
BotSayTeamOrder(bs, teammates[1]);
778
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
783
//the one closest to the base will defend the base
784
ClientName(teammates[0], name, sizeof(name));
785
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
786
BotSayTeamOrder(bs, teammates[0]);
787
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
788
//the others should go for the enemy flag
789
ClientName(teammates[1], name, sizeof(name));
790
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
791
BotSayTeamOrder(bs, teammates[1]);
792
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
794
ClientName(teammates[2], name, sizeof(name));
795
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
796
BotSayTeamOrder(bs, teammates[2]);
797
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
802
defenders = (int) (float) numteammates * 0.4 + 0.5;
803
if (defenders > 4) defenders = 4;
804
attackers = (int) (float) numteammates * 0.5 + 0.5;
805
if (attackers > 5) attackers = 5;
806
for (i = 0; i < defenders; i++) {
808
ClientName(teammates[i], name, sizeof(name));
809
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
810
BotSayTeamOrder(bs, teammates[i]);
811
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
813
for (i = 0; i < attackers; i++) {
815
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
816
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
817
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
818
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
832
void BotCTFOrders(bot_state_t *bs) {
836
if (BotTeam(bs) == TEAM_RED) flagstatus = bs->redflagstatus * 2 + bs->blueflagstatus;
837
else flagstatus = bs->blueflagstatus * 2 + bs->redflagstatus;
840
case 0: BotCTFOrders_BothFlagsAtBase(bs); break;
841
case 1: BotCTFOrders_EnemyFlagNotAtBase(bs); break;
842
case 2: BotCTFOrders_FlagNotAtBase(bs); break;
843
case 3: BotCTFOrders_BothFlagsNotAtBase(bs); break;
853
void BotCreateGroup(bot_state_t *bs, int *teammates, int groupsize) {
854
char name[MAX_NETNAME], leadername[MAX_NETNAME];
857
// the others in the group will follow the teammates[0]
858
ClientName(teammates[0], leadername, sizeof(leadername));
859
for (i = 1; i < groupsize; i++)
861
ClientName(teammates[i], name, sizeof(name));
862
if (teammates[0] == bs->client) {
863
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
866
BotAI_BotInitialChat(bs, "cmd_accompany", name, leadername, NULL);
868
BotSayTeamOrderAlways(bs, teammates[i]);
876
FIXME: defend key areas?
879
void BotTeamOrders(bot_state_t *bs) {
880
int teammates[MAX_CLIENTS];
882
char buf[MAX_INFO_STRING];
883
static int maxclients;
886
maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
889
for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
890
trap_GetConfigstring(CS_PLAYERS+i, buf, sizeof(buf));
891
//if no config string or no name
892
if (!strlen(buf) || !strlen(Info_ValueForKey(buf, "n"))) continue;
894
if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) continue;
896
if (BotSameTeam(bs, i)) {
897
teammates[numteammates] = i;
902
switch(numteammates) {
911
//have one follow another and one free roaming
912
BotCreateGroup(bs, teammates, 2);
917
BotCreateGroup(bs, teammates, 2); //a group of 2
918
BotCreateGroup(bs, &teammates[2], 2); //a group of 2
923
BotCreateGroup(bs, teammates, 2); //a group of 2
924
BotCreateGroup(bs, &teammates[2], 3); //a group of 3
929
if (numteammates <= 10) {
930
for (i = 0; i < numteammates / 2; i++) {
931
BotCreateGroup(bs, &teammates[i*2], 2); //groups of 2
943
Bot1FCTFOrders_FlagAtCenter
945
X% defend the base, Y% get the flag
948
void Bot1FCTFOrders_FlagAtCenter(bot_state_t *bs) {
949
int numteammates, defenders, attackers, i;
950
int teammates[MAX_CLIENTS];
951
char name[MAX_NETNAME];
953
//sort team mates by travel time to base
954
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
955
//sort team mates by CTF preference
956
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
958
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
959
//different orders based on the number of team mates
960
switch(numteammates) {
964
//the one closest to the base will defend the base
965
ClientName(teammates[0], name, sizeof(name));
966
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
967
BotSayTeamOrder(bs, teammates[0]);
968
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
969
//the other will get the flag
970
ClientName(teammates[1], name, sizeof(name));
971
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
972
BotSayTeamOrder(bs, teammates[1]);
973
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
978
//the one closest to the base will defend the base
979
ClientName(teammates[0], name, sizeof(name));
980
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
981
BotSayTeamOrder(bs, teammates[0]);
982
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
983
//the second one closest to the base will defend the base
984
ClientName(teammates[1], name, sizeof(name));
985
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
986
BotSayTeamOrder(bs, teammates[1]);
987
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
988
//the other will get the flag
989
ClientName(teammates[2], name, sizeof(name));
990
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
991
BotSayTeamOrder(bs, teammates[2]);
992
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
997
//50% defend the base
998
defenders = (int) (float) numteammates * 0.5 + 0.5;
999
if (defenders > 5) defenders = 5;
1001
attackers = (int) (float) numteammates * 0.4 + 0.5;
1002
if (attackers > 4) attackers = 4;
1003
for (i = 0; i < defenders; i++) {
1005
ClientName(teammates[i], name, sizeof(name));
1006
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1007
BotSayTeamOrder(bs, teammates[i]);
1008
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1010
for (i = 0; i < attackers; i++) {
1012
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1013
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1014
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1015
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
1023
//different orders based on the number of team mates
1024
switch(numteammates) {
1028
//the one closest to the base will defend the base
1029
ClientName(teammates[0], name, sizeof(name));
1030
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1031
BotSayTeamOrder(bs, teammates[0]);
1032
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1033
//the other will get the flag
1034
ClientName(teammates[1], name, sizeof(name));
1035
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1036
BotSayTeamOrder(bs, teammates[1]);
1037
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
1042
//the one closest to the base will defend the base
1043
ClientName(teammates[0], name, sizeof(name));
1044
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1045
BotSayTeamOrder(bs, teammates[0]);
1046
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1047
//the others should go for the enemy flag
1048
ClientName(teammates[1], name, sizeof(name));
1049
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1050
BotSayTeamOrder(bs, teammates[1]);
1051
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
1053
ClientName(teammates[2], name, sizeof(name));
1054
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1055
BotSayTeamOrder(bs, teammates[2]);
1056
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
1061
//30% defend the base
1062
defenders = (int) (float) numteammates * 0.3 + 0.5;
1063
if (defenders > 3) defenders = 3;
1065
attackers = (int) (float) numteammates * 0.6 + 0.5;
1066
if (attackers > 6) attackers = 6;
1067
for (i = 0; i < defenders; i++) {
1069
ClientName(teammates[i], name, sizeof(name));
1070
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1071
BotSayTeamOrder(bs, teammates[i]);
1072
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1074
for (i = 0; i < attackers; i++) {
1076
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1077
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1078
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1079
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
1090
Bot1FCTFOrders_TeamHasFlag
1092
X% towards neutral flag, Y% go towards enemy base and accompany flag carrier if visible
1095
void Bot1FCTFOrders_TeamHasFlag(bot_state_t *bs) {
1096
int numteammates, defenders, attackers, i, other;
1097
int teammates[MAX_CLIENTS];
1098
char name[MAX_NETNAME], carriername[MAX_NETNAME];
1100
//sort team mates by travel time to base
1101
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
1102
//sort team mates by CTF preference
1103
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
1105
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
1106
//different orders based on the number of team mates
1107
switch(numteammates) {
1111
//tell the one not carrying the flag to attack the enemy base
1112
if (teammates[0] == bs->flagcarrier) other = teammates[1];
1113
else other = teammates[0];
1114
ClientName(other, name, sizeof(name));
1115
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1116
BotSayTeamOrder(bs, other);
1117
BotSayVoiceTeamOrder(bs, other, VOICECHAT_OFFENSE);
1122
//tell the one closest to the base not carrying the flag to defend the base
1123
if (teammates[0] != bs->flagcarrier) other = teammates[0];
1124
else other = teammates[1];
1125
ClientName(other, name, sizeof(name));
1126
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1127
BotSayTeamOrder(bs, other);
1128
BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
1129
//tell the one furthest from the base not carrying the flag to accompany the flag carrier
1130
if (teammates[2] != bs->flagcarrier) other = teammates[2];
1131
else other = teammates[1];
1132
ClientName(other, name, sizeof(name));
1133
if ( bs->flagcarrier != -1 ) {
1134
ClientName(bs->flagcarrier, carriername, sizeof(carriername));
1135
if (bs->flagcarrier == bs->client) {
1136
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
1137
BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWME);
1140
BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
1141
BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWFLAGCARRIER);
1146
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1147
BotSayVoiceTeamOrder(bs, other, VOICECHAT_GETFLAG);
1149
BotSayTeamOrder(bs, other);
1154
//30% will defend the base
1155
defenders = (int) (float) numteammates * 0.3 + 0.5;
1156
if (defenders > 3) defenders = 3;
1157
//70% accompanies the flag carrier
1158
attackers = (int) (float) numteammates * 0.7 + 0.5;
1159
if (attackers > 7) attackers = 7;
1160
for (i = 0; i < defenders; i++) {
1162
if (teammates[i] == bs->flagcarrier) {
1165
ClientName(teammates[i], name, sizeof(name));
1166
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1167
BotSayTeamOrder(bs, teammates[i]);
1168
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1170
if (bs->flagcarrier != -1) {
1171
ClientName(bs->flagcarrier, carriername, sizeof(carriername));
1172
for (i = 0; i < attackers; i++) {
1174
if (teammates[numteammates - i - 1] == bs->flagcarrier) {
1178
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1179
if (bs->flagcarrier == bs->client) {
1180
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
1181
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWME);
1184
BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
1185
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWFLAGCARRIER);
1187
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1191
for (i = 0; i < attackers; i++) {
1193
if (teammates[numteammates - i - 1] == bs->flagcarrier) {
1197
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1198
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1199
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1200
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
1209
//different orders based on the number of team mates
1210
switch(numteammates) {
1214
//tell the one not carrying the flag to defend the base
1215
if (teammates[0] == bs->flagcarrier) other = teammates[1];
1216
else other = teammates[0];
1217
ClientName(other, name, sizeof(name));
1218
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1219
BotSayTeamOrder(bs, other);
1220
BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
1225
//tell the one closest to the base not carrying the flag to defend the base
1226
if (teammates[0] != bs->flagcarrier) other = teammates[0];
1227
else other = teammates[1];
1228
ClientName(other, name, sizeof(name));
1229
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1230
BotSayTeamOrder(bs, other);
1231
BotSayVoiceTeamOrder(bs, other, VOICECHAT_DEFEND);
1232
//tell the one furthest from the base not carrying the flag to accompany the flag carrier
1233
if (teammates[2] != bs->flagcarrier) other = teammates[2];
1234
else other = teammates[1];
1235
ClientName(other, name, sizeof(name));
1236
ClientName(bs->flagcarrier, carriername, sizeof(carriername));
1237
if (bs->flagcarrier == bs->client) {
1238
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
1239
BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWME);
1242
BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
1243
BotSayVoiceTeamOrder(bs, other, VOICECHAT_FOLLOWFLAGCARRIER);
1245
BotSayTeamOrder(bs, other);
1250
//20% will defend the base
1251
defenders = (int) (float) numteammates * 0.2 + 0.5;
1252
if (defenders > 2) defenders = 2;
1253
//80% accompanies the flag carrier
1254
attackers = (int) (float) numteammates * 0.8 + 0.5;
1255
if (attackers > 8) attackers = 8;
1256
for (i = 0; i < defenders; i++) {
1258
if (teammates[i] == bs->flagcarrier) {
1261
ClientName(teammates[i], name, sizeof(name));
1262
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1263
BotSayTeamOrder(bs, teammates[i]);
1264
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1266
ClientName(bs->flagcarrier, carriername, sizeof(carriername));
1267
for (i = 0; i < attackers; i++) {
1269
if (teammates[numteammates - i - 1] == bs->flagcarrier) {
1273
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1274
if (bs->flagcarrier == bs->client) {
1275
BotAI_BotInitialChat(bs, "cmd_accompanyme", name, NULL);
1276
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWME);
1279
BotAI_BotInitialChat(bs, "cmd_accompany", name, carriername, NULL);
1280
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_FOLLOWFLAGCARRIER);
1282
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1293
Bot1FCTFOrders_EnemyHasFlag
1295
X% defend the base, Y% towards neutral flag
1298
void Bot1FCTFOrders_EnemyHasFlag(bot_state_t *bs) {
1299
int numteammates, defenders, attackers, i;
1300
int teammates[MAX_CLIENTS];
1301
char name[MAX_NETNAME];
1303
//sort team mates by travel time to base
1304
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
1305
//sort team mates by CTF preference
1306
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
1308
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
1309
//different orders based on the number of team mates
1310
switch(numteammates) {
1314
//both defend the base
1315
ClientName(teammates[0], name, sizeof(name));
1316
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1317
BotSayTeamOrder(bs, teammates[0]);
1318
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1320
ClientName(teammates[1], name, sizeof(name));
1321
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1322
BotSayTeamOrder(bs, teammates[1]);
1323
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
1328
//the one closest to the base will defend the base
1329
ClientName(teammates[0], name, sizeof(name));
1330
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1331
BotSayTeamOrder(bs, teammates[0]);
1332
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1333
//the second one closest to the base will defend the base
1334
ClientName(teammates[1], name, sizeof(name));
1335
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1336
BotSayTeamOrder(bs, teammates[1]);
1337
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
1338
//the other will also defend the base
1339
ClientName(teammates[2], name, sizeof(name));
1340
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1341
BotSayTeamOrder(bs, teammates[2]);
1342
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_DEFEND);
1347
//80% will defend the base
1348
defenders = (int) (float) numteammates * 0.8 + 0.5;
1349
if (defenders > 8) defenders = 8;
1350
//10% will try to return the flag
1351
attackers = (int) (float) numteammates * 0.1 + 0.5;
1352
if (attackers > 2) attackers = 2;
1353
for (i = 0; i < defenders; i++) {
1355
ClientName(teammates[i], name, sizeof(name));
1356
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1357
BotSayTeamOrder(bs, teammates[i]);
1358
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1360
for (i = 0; i < attackers; i++) {
1362
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1363
BotAI_BotInitialChat(bs, "cmd_returnflag", name, NULL);
1364
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1365
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
1373
//different orders based on the number of team mates
1374
switch(numteammates) {
1378
//the one closest to the base will defend the base
1379
ClientName(teammates[0], name, sizeof(name));
1380
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1381
BotSayTeamOrder(bs, teammates[0]);
1382
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1383
//the other will get the flag
1384
ClientName(teammates[1], name, sizeof(name));
1385
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1386
BotSayTeamOrder(bs, teammates[1]);
1387
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
1392
//the one closest to the base will defend the base
1393
ClientName(teammates[0], name, sizeof(name));
1394
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1395
BotSayTeamOrder(bs, teammates[0]);
1396
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1397
//the others should go for the enemy flag
1398
ClientName(teammates[1], name, sizeof(name));
1399
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1400
BotSayTeamOrder(bs, teammates[1]);
1401
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
1403
ClientName(teammates[2], name, sizeof(name));
1404
BotAI_BotInitialChat(bs, "cmd_returnflag", name, NULL);
1405
BotSayTeamOrder(bs, teammates[2]);
1406
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
1411
//70% defend the base
1412
defenders = (int) (float) numteammates * 0.7 + 0.5;
1413
if (defenders > 8) defenders = 8;
1414
//20% try to return the flag
1415
attackers = (int) (float) numteammates * 0.2 + 0.5;
1416
if (attackers > 2) attackers = 2;
1417
for (i = 0; i < defenders; i++) {
1419
ClientName(teammates[i], name, sizeof(name));
1420
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1421
BotSayTeamOrder(bs, teammates[i]);
1422
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1424
for (i = 0; i < attackers; i++) {
1426
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1427
BotAI_BotInitialChat(bs, "cmd_returnflag", name, NULL);
1428
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1429
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
1440
Bot1FCTFOrders_EnemyDroppedFlag
1442
X% defend the base, Y% get the flag
1445
void Bot1FCTFOrders_EnemyDroppedFlag(bot_state_t *bs) {
1446
int numteammates, defenders, attackers, i;
1447
int teammates[MAX_CLIENTS];
1448
char name[MAX_NETNAME];
1450
//sort team mates by travel time to base
1451
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
1452
//sort team mates by CTF preference
1453
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
1455
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
1456
//different orders based on the number of team mates
1457
switch(numteammates) {
1461
//the one closest to the base will defend the base
1462
ClientName(teammates[0], name, sizeof(name));
1463
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1464
BotSayTeamOrder(bs, teammates[0]);
1465
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1466
//the other will get the flag
1467
ClientName(teammates[1], name, sizeof(name));
1468
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1469
BotSayTeamOrder(bs, teammates[1]);
1470
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
1475
//the one closest to the base will defend the base
1476
ClientName(teammates[0], name, sizeof(name));
1477
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1478
BotSayTeamOrder(bs, teammates[0]);
1479
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1480
//the second one closest to the base will defend the base
1481
ClientName(teammates[1], name, sizeof(name));
1482
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1483
BotSayTeamOrder(bs, teammates[1]);
1484
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
1485
//the other will get the flag
1486
ClientName(teammates[2], name, sizeof(name));
1487
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1488
BotSayTeamOrder(bs, teammates[2]);
1489
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
1494
//50% defend the base
1495
defenders = (int) (float) numteammates * 0.5 + 0.5;
1496
if (defenders > 5) defenders = 5;
1498
attackers = (int) (float) numteammates * 0.4 + 0.5;
1499
if (attackers > 4) attackers = 4;
1500
for (i = 0; i < defenders; i++) {
1502
ClientName(teammates[i], name, sizeof(name));
1503
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1504
BotSayTeamOrder(bs, teammates[i]);
1505
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1507
for (i = 0; i < attackers; i++) {
1509
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1510
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1511
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1512
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_GETFLAG);
1520
//different orders based on the number of team mates
1521
switch(numteammates) {
1525
//the one closest to the base will defend the base
1526
ClientName(teammates[0], name, sizeof(name));
1527
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1528
BotSayTeamOrder(bs, teammates[0]);
1529
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1530
//the other will get the flag
1531
ClientName(teammates[1], name, sizeof(name));
1532
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1533
BotSayTeamOrder(bs, teammates[1]);
1534
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
1539
//the one closest to the base will defend the base
1540
ClientName(teammates[0], name, sizeof(name));
1541
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1542
BotSayTeamOrder(bs, teammates[0]);
1543
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1544
//the others should go for the enemy flag
1545
ClientName(teammates[1], name, sizeof(name));
1546
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1547
BotSayTeamOrder(bs, teammates[1]);
1548
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_GETFLAG);
1550
ClientName(teammates[2], name, sizeof(name));
1551
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1552
BotSayTeamOrder(bs, teammates[2]);
1553
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_GETFLAG);
1558
//30% defend the base
1559
defenders = (int) (float) numteammates * 0.3 + 0.5;
1560
if (defenders > 3) defenders = 3;
1562
attackers = (int) (float) numteammates * 0.6 + 0.5;
1563
if (attackers > 6) attackers = 6;
1564
for (i = 0; i < defenders; i++) {
1566
ClientName(teammates[i], name, sizeof(name));
1567
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1568
BotSayTeamOrder(bs, teammates[i]);
1569
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1571
for (i = 0; i < attackers; i++) {
1573
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1574
BotAI_BotInitialChat(bs, "cmd_getflag", name, NULL);
1575
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1576
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_DEFEND);
1590
void Bot1FCTFOrders(bot_state_t *bs) {
1591
switch(bs->neutralflagstatus) {
1592
case 0: Bot1FCTFOrders_FlagAtCenter(bs); break;
1593
case 1: Bot1FCTFOrders_TeamHasFlag(bs); break;
1594
case 2: Bot1FCTFOrders_EnemyHasFlag(bs); break;
1595
case 3: Bot1FCTFOrders_EnemyDroppedFlag(bs); break;
1603
X% in defence Y% in offence
1606
void BotObeliskOrders(bot_state_t *bs) {
1607
int numteammates, defenders, attackers, i;
1608
int teammates[MAX_CLIENTS];
1609
char name[MAX_NETNAME];
1611
//sort team mates by travel time to base
1612
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
1613
//sort team mates by CTF preference
1614
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
1616
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
1617
//different orders based on the number of team mates
1618
switch(numteammates) {
1622
//the one closest to the base will defend the base
1623
ClientName(teammates[0], name, sizeof(name));
1624
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1625
BotSayTeamOrder(bs, teammates[0]);
1626
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1627
//the other will attack the enemy base
1628
ClientName(teammates[1], name, sizeof(name));
1629
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1630
BotSayTeamOrder(bs, teammates[1]);
1631
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
1636
//the one closest to the base will defend the base
1637
ClientName(teammates[0], name, sizeof(name));
1638
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1639
BotSayTeamOrder(bs, teammates[0]);
1640
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1641
//the one second closest to the base also defends the base
1642
ClientName(teammates[1], name, sizeof(name));
1643
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1644
BotSayTeamOrder(bs, teammates[1]);
1645
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
1646
//the other one attacks the enemy base
1647
ClientName(teammates[2], name, sizeof(name));
1648
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1649
BotSayTeamOrder(bs, teammates[2]);
1650
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
1655
//50% defend the base
1656
defenders = (int) (float) numteammates * 0.5 + 0.5;
1657
if (defenders > 5) defenders = 5;
1658
//40% attack the enemy base
1659
attackers = (int) (float) numteammates * 0.4 + 0.5;
1660
if (attackers > 4) attackers = 4;
1661
for (i = 0; i < defenders; i++) {
1663
ClientName(teammates[i], name, sizeof(name));
1664
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1665
BotSayTeamOrder(bs, teammates[i]);
1666
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1668
for (i = 0; i < attackers; i++) {
1670
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1671
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1672
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1673
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
1681
//different orders based on the number of team mates
1682
switch(numteammates) {
1686
//the one closest to the base will defend the base
1687
ClientName(teammates[0], name, sizeof(name));
1688
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1689
BotSayTeamOrder(bs, teammates[0]);
1690
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1691
//the other will attack the enemy base
1692
ClientName(teammates[1], name, sizeof(name));
1693
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1694
BotSayTeamOrder(bs, teammates[1]);
1695
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
1700
//the one closest to the base will defend the base
1701
ClientName(teammates[0], name, sizeof(name));
1702
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1703
BotSayTeamOrder(bs, teammates[0]);
1704
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1705
//the others attack the enemy base
1706
ClientName(teammates[1], name, sizeof(name));
1707
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1708
BotSayTeamOrder(bs, teammates[1]);
1709
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
1711
ClientName(teammates[2], name, sizeof(name));
1712
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1713
BotSayTeamOrder(bs, teammates[2]);
1714
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
1719
//30% defend the base
1720
defenders = (int) (float) numteammates * 0.3 + 0.5;
1721
if (defenders > 3) defenders = 3;
1722
//70% attack the enemy base
1723
attackers = (int) (float) numteammates * 0.7 + 0.5;
1724
if (attackers > 7) attackers = 7;
1725
for (i = 0; i < defenders; i++) {
1727
ClientName(teammates[i], name, sizeof(name));
1728
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1729
BotSayTeamOrder(bs, teammates[i]);
1730
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1732
for (i = 0; i < attackers; i++) {
1734
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1735
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
1736
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1737
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
1750
X% defend the base, Y% harvest
1753
void BotHarvesterOrders(bot_state_t *bs) {
1754
int numteammates, defenders, attackers, i;
1755
int teammates[MAX_CLIENTS];
1756
char name[MAX_NETNAME];
1758
//sort team mates by travel time to base
1759
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
1760
//sort team mates by CTF preference
1761
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
1763
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
1764
//different orders based on the number of team mates
1765
switch(numteammates) {
1769
//the one closest to the base will defend the base
1770
ClientName(teammates[0], name, sizeof(name));
1771
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1772
BotSayTeamOrder(bs, teammates[0]);
1773
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1774
//the other will harvest
1775
ClientName(teammates[1], name, sizeof(name));
1776
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
1777
BotSayTeamOrder(bs, teammates[1]);
1778
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
1783
//the one closest to the base will defend the base
1784
ClientName(teammates[0], name, sizeof(name));
1785
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1786
BotSayTeamOrder(bs, teammates[0]);
1787
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1788
//the one second closest to the base also defends the base
1789
ClientName(teammates[1], name, sizeof(name));
1790
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1791
BotSayTeamOrder(bs, teammates[1]);
1792
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
1793
//the other one goes harvesting
1794
ClientName(teammates[2], name, sizeof(name));
1795
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
1796
BotSayTeamOrder(bs, teammates[2]);
1797
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
1802
//50% defend the base
1803
defenders = (int) (float) numteammates * 0.5 + 0.5;
1804
if (defenders > 5) defenders = 5;
1805
//40% goes harvesting
1806
attackers = (int) (float) numteammates * 0.4 + 0.5;
1807
if (attackers > 4) attackers = 4;
1808
for (i = 0; i < defenders; i++) {
1810
ClientName(teammates[i], name, sizeof(name));
1811
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1812
BotSayTeamOrder(bs, teammates[i]);
1813
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1815
for (i = 0; i < attackers; i++) {
1817
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1818
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
1819
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1820
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
1828
//different orders based on the number of team mates
1829
switch(numteammates) {
1833
//the one closest to the base will defend the base
1834
ClientName(teammates[0], name, sizeof(name));
1835
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1836
BotSayTeamOrder(bs, teammates[0]);
1837
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1838
//the other will harvest
1839
ClientName(teammates[1], name, sizeof(name));
1840
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
1841
BotSayTeamOrder(bs, teammates[1]);
1842
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
1847
//the one closest to the base will defend the base
1848
ClientName(teammates[0], name, sizeof(name));
1849
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1850
BotSayTeamOrder(bs, teammates[0]);
1851
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
1852
//the others go harvesting
1853
ClientName(teammates[1], name, sizeof(name));
1854
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
1855
BotSayTeamOrder(bs, teammates[1]);
1856
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
1858
ClientName(teammates[2], name, sizeof(name));
1859
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
1860
BotSayTeamOrder(bs, teammates[2]);
1861
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
1866
//30% defend the base
1867
defenders = (int) (float) numteammates * 0.3 + 0.5;
1868
if (defenders > 3) defenders = 3;
1870
attackers = (int) (float) numteammates * 0.7 + 0.5;
1871
if (attackers > 7) attackers = 7;
1872
for (i = 0; i < defenders; i++) {
1874
ClientName(teammates[i], name, sizeof(name));
1875
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
1876
BotSayTeamOrder(bs, teammates[i]);
1877
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
1879
for (i = 0; i < attackers; i++) {
1881
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
1882
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
1883
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
1884
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
1899
int FindHumanTeamLeader(bot_state_t *bs) {
1902
for (i = 0; i < MAX_CLIENTS; i++) {
1903
if ( g_entities[i].inuse ) {
1904
// if this player is not a bot
1905
if ( !(g_entities[i].r.svFlags & SVF_BOT) ) {
1906
// if this player is ok with being the leader
1907
if (!notleader[i]) {
1908
// if this player is on the same team
1909
if ( BotSameTeam(bs, i) ) {
1910
ClientName(i, bs->teamleader, sizeof(bs->teamleader));
1911
// if not yet ordered to do anything
1912
if ( !BotSetLastOrderedTask(bs) ) {
1913
// go on defense by default
1914
BotVoiceChat_Defend(bs, i, SAY_TELL);
1930
void BotTeamAI(bot_state_t *bs) {
1932
char netname[MAX_NETNAME];
1935
if ( gametype < GT_TEAM )
1937
// make sure we've got a valid team leader
1938
if (!BotValidTeamLeader(bs)) {
1940
if (!FindHumanTeamLeader(bs)) {
1942
if (!bs->askteamleader_time && !bs->becometeamleader_time) {
1943
if (bs->entergame_time + 10 > FloatTime()) {
1944
bs->askteamleader_time = FloatTime() + 5 + random() * 10;
1947
bs->becometeamleader_time = FloatTime() + 5 + random() * 10;
1950
if (bs->askteamleader_time && bs->askteamleader_time < FloatTime()) {
1951
// if asked for a team leader and no response
1952
BotAI_BotInitialChat(bs, "whoisteamleader", NULL);
1953
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
1954
bs->askteamleader_time = 0;
1955
bs->becometeamleader_time = FloatTime() + 8 + random() * 10;
1957
if (bs->becometeamleader_time && bs->becometeamleader_time < FloatTime()) {
1958
BotAI_BotInitialChat(bs, "iamteamleader", NULL);
1959
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
1960
BotSayVoiceTeamOrder(bs, -1, VOICECHAT_STARTLEADER);
1961
ClientName(bs->client, netname, sizeof(netname));
1962
strncpy(bs->teamleader, netname, sizeof(bs->teamleader));
1963
bs->teamleader[sizeof(bs->teamleader)] = '\0';
1964
bs->becometeamleader_time = 0;
1969
bs->askteamleader_time = 0;
1970
bs->becometeamleader_time = 0;
1972
//return if this bot is NOT the team leader
1973
ClientName(bs->client, netname, sizeof(netname));
1974
if (Q_stricmp(netname, bs->teamleader) != 0) return;
1976
numteammates = BotNumTeamMates(bs);
1981
if (bs->numteammates != numteammates || bs->forceorders) {
1982
bs->teamgiveorders_time = FloatTime();
1983
bs->numteammates = numteammates;
1984
bs->forceorders = qfalse;
1986
//if it's time to give orders
1987
if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 5) {
1989
//give orders again after 120 seconds
1990
bs->teamgiveorders_time = FloatTime() + 120;
1996
//if the number of team mates changed or the flag status changed
1997
//or someone wants to know what to do
1998
if (bs->numteammates != numteammates || bs->flagstatuschanged || bs->forceorders) {
1999
bs->teamgiveorders_time = FloatTime();
2000
bs->numteammates = numteammates;
2001
bs->flagstatuschanged = qfalse;
2002
bs->forceorders = qfalse;
2004
//if there were no flag captures the last 3 minutes
2005
if (bs->lastflagcapture_time < FloatTime() - 240) {
2006
bs->lastflagcapture_time = FloatTime();
2007
//randomly change the CTF strategy
2008
if (random() < 0.4) {
2009
bs->ctfstrategy ^= CTFS_AGRESSIVE;
2010
bs->teamgiveorders_time = FloatTime();
2013
//if it's time to give orders
2014
if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 3) {
2017
bs->teamgiveorders_time = 0;
2024
if (bs->numteammates != numteammates || bs->flagstatuschanged || bs->forceorders) {
2025
bs->teamgiveorders_time = FloatTime();
2026
bs->numteammates = numteammates;
2027
bs->flagstatuschanged = qfalse;
2028
bs->forceorders = qfalse;
2030
//if there were no flag captures the last 4 minutes
2031
if (bs->lastflagcapture_time < FloatTime() - 240) {
2032
bs->lastflagcapture_time = FloatTime();
2033
//randomly change the CTF strategy
2034
if (random() < 0.4) {
2035
bs->ctfstrategy ^= CTFS_AGRESSIVE;
2036
bs->teamgiveorders_time = FloatTime();
2039
//if it's time to give orders
2040
if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 2) {
2043
bs->teamgiveorders_time = 0;
2049
if (bs->numteammates != numteammates || bs->forceorders) {
2050
bs->teamgiveorders_time = FloatTime();
2051
bs->numteammates = numteammates;
2052
bs->forceorders = qfalse;
2054
//if it's time to give orders
2055
if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 5) {
2056
BotObeliskOrders(bs);
2057
//give orders again after 30 seconds
2058
bs->teamgiveorders_time = FloatTime() + 30;
2064
if (bs->numteammates != numteammates || bs->forceorders) {
2065
bs->teamgiveorders_time = FloatTime();
2066
bs->numteammates = numteammates;
2067
bs->forceorders = qfalse;
2069
//if it's time to give orders
2070
if (bs->teamgiveorders_time && bs->teamgiveorders_time < FloatTime() - 5) {
2071
BotHarvesterOrders(bs);
2072
//give orders again after 30 seconds
2073
bs->teamgiveorders_time = FloatTime() + 30;