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 "chars.h"
00053 #include "inv.h"
00054 #include "syn.h"
00055 #include "match.h"
00056
00057
00058 #include "../../ui/menudef.h"
00059
00060
00061 typedef struct voiceCommand_s
00062 {
00063 char *cmd;
00064 void (*func)(bot_state_t *bs, int client, int mode);
00065 } voiceCommand_t;
00066
00067
00068
00069
00070
00071
00072 void BotVoiceChat_GetFlag(bot_state_t *bs, int client, int mode) {
00073
00074 if (gametype == GT_CTF) {
00075 if (!ctf_redflag.areanum || !ctf_blueflag.areanum)
00076 return;
00077 }
00078 #ifdef MISSIONPACK
00079 else if (gametype == GT_1FCTF) {
00080 if (!ctf_neutralflag.areanum || !ctf_redflag.areanum || !ctf_blueflag.areanum)
00081 return;
00082 }
00083 #endif
00084 else {
00085 return;
00086 }
00087
00088 bs->decisionmaker = client;
00089 bs->ordered = qtrue;
00090 bs->order_time = FloatTime();
00091
00092 bs->teammessage_time = FloatTime() + 2 * random();
00093
00094 bs->ltgtype = LTG_GETFLAG;
00095
00096 bs->teamgoal_time = FloatTime() + CTF_GETFLAG_TIME;
00097
00098 if (gametype == GT_CTF) {
00099
00100 BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs));
00101 }
00102
00103 BotSetTeamStatus(bs);
00104
00105 BotRememberLastOrderedTask(bs);
00106 #ifdef DEBUG
00107 BotPrintTeamGoal(bs);
00108 #endif //DEBUG
00109 }
00110
00111
00112
00113
00114
00115
00116 void BotVoiceChat_Offense(bot_state_t *bs, int client, int mode) {
00117 if ( gametype == GT_CTF
00118 #ifdef MISSIONPACK
00119 || gametype == GT_1FCTF
00120 #endif
00121 ) {
00122 BotVoiceChat_GetFlag(bs, client, mode);
00123 return;
00124 }
00125 #ifdef MISSIONPACK
00126 if (gametype == GT_HARVESTER) {
00127
00128 bs->decisionmaker = client;
00129 bs->ordered = qtrue;
00130 bs->order_time = FloatTime();
00131
00132 bs->teammessage_time = FloatTime() + 2 * random();
00133
00134 bs->ltgtype = LTG_HARVEST;
00135
00136 bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME;
00137 bs->harvestaway_time = 0;
00138
00139 BotSetTeamStatus(bs);
00140
00141 BotRememberLastOrderedTask(bs);
00142 }
00143 else
00144 #endif
00145 {
00146
00147 bs->decisionmaker = client;
00148 bs->ordered = qtrue;
00149 bs->order_time = FloatTime();
00150
00151 bs->teammessage_time = FloatTime() + 2 * random();
00152
00153 bs->ltgtype = LTG_ATTACKENEMYBASE;
00154
00155 bs->teamgoal_time = FloatTime() + TEAM_ATTACKENEMYBASE_TIME;
00156 bs->attackaway_time = 0;
00157
00158 BotSetTeamStatus(bs);
00159
00160 BotRememberLastOrderedTask(bs);
00161 }
00162 #ifdef DEBUG
00163 BotPrintTeamGoal(bs);
00164 #endif //DEBUG
00165 }
00166
00167
00168
00169
00170
00171
00172 void BotVoiceChat_Defend(bot_state_t *bs, int client, int mode) {
00173 #ifdef MISSIONPACK
00174 if ( gametype == GT_OBELISK || gametype == GT_HARVESTER) {
00175
00176 switch(BotTeam(bs)) {
00177 case TEAM_RED: memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t)); break;
00178 case TEAM_BLUE: memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t)); break;
00179 default: return;
00180 }
00181 }
00182 else
00183 #endif
00184 if (gametype == GT_CTF
00185 #ifdef MISSIONPACK
00186 || gametype == GT_1FCTF
00187 #endif
00188 ) {
00189
00190 switch(BotTeam(bs)) {
00191 case TEAM_RED: memcpy(&bs->teamgoal, &ctf_redflag, sizeof(bot_goal_t)); break;
00192 case TEAM_BLUE: memcpy(&bs->teamgoal, &ctf_blueflag, sizeof(bot_goal_t)); break;
00193 default: return;
00194 }
00195 }
00196 else {
00197 return;
00198 }
00199
00200 bs->decisionmaker = client;
00201 bs->ordered = qtrue;
00202 bs->order_time = FloatTime();
00203
00204 bs->teammessage_time = FloatTime() + 2 * random();
00205
00206 bs->ltgtype = LTG_DEFENDKEYAREA;
00207
00208 bs->teamgoal_time = FloatTime() + TEAM_DEFENDKEYAREA_TIME;
00209
00210 bs->defendaway_time = 0;
00211
00212 BotSetTeamStatus(bs);
00213
00214 BotRememberLastOrderedTask(bs);
00215 #ifdef DEBUG
00216 BotPrintTeamGoal(bs);
00217 #endif //DEBUG
00218 }
00219
00220
00221
00222
00223
00224
00225 void BotVoiceChat_DefendFlag(bot_state_t *bs, int client, int mode) {
00226 BotVoiceChat_Defend(bs, client, mode);
00227 }
00228
00229
00230
00231
00232
00233
00234 void BotVoiceChat_Patrol(bot_state_t *bs, int client, int mode) {
00235
00236 bs->decisionmaker = client;
00237
00238 bs->ltgtype = 0;
00239 bs->lead_time = 0;
00240 bs->lastgoal_ltgtype = 0;
00241
00242 BotAI_BotInitialChat(bs, "dismissed", NULL);
00243 trap_BotEnterChat(bs->cs, client, CHAT_TELL);
00244 BotVoiceChatOnly(bs, -1, VOICECHAT_ONPATROL);
00245
00246 BotSetTeamStatus(bs);
00247 #ifdef DEBUG
00248 BotPrintTeamGoal(bs);
00249 #endif //DEBUG
00250 }
00251
00252
00253
00254
00255
00256
00257 void BotVoiceChat_Camp(bot_state_t *bs, int client, int mode) {
00258 int areanum;
00259 aas_entityinfo_t entinfo;
00260 char netname[MAX_NETNAME];
00261
00262
00263 bs->teamgoal.entitynum = -1;
00264 BotEntityInfo(client, &entinfo);
00265
00266 if (entinfo.valid) {
00267 areanum = BotPointAreaNum(entinfo.origin);
00268 if (areanum) {
00269
00270
00271 bs->teamgoal.entitynum = client;
00272 bs->teamgoal.areanum = areanum;
00273 VectorCopy(entinfo.origin, bs->teamgoal.origin);
00274 VectorSet(bs->teamgoal.mins, -8, -8, -8);
00275 VectorSet(bs->teamgoal.maxs, 8, 8, 8);
00276
00277 }
00278 }
00279
00280 if (bs->teamgoal.entitynum < 0) {
00281 BotAI_BotInitialChat(bs, "whereareyou", EasyClientName(client, netname, sizeof(netname)), NULL);
00282 trap_BotEnterChat(bs->cs, client, CHAT_TELL);
00283 return;
00284 }
00285
00286 bs->decisionmaker = client;
00287 bs->ordered = qtrue;
00288 bs->order_time = FloatTime();
00289
00290 bs->teammessage_time = FloatTime() + 2 * random();
00291
00292 bs->ltgtype = LTG_CAMPORDER;
00293
00294 bs->teamgoal_time = FloatTime() + TEAM_CAMP_TIME;
00295
00296 bs->teammate = client;
00297
00298 bs->arrive_time = 0;
00299
00300 BotSetTeamStatus(bs);
00301
00302 BotRememberLastOrderedTask(bs);
00303 #ifdef DEBUG
00304 BotPrintTeamGoal(bs);
00305 #endif //DEBUG
00306 }
00307
00308
00309
00310
00311
00312
00313 void BotVoiceChat_FollowMe(bot_state_t *bs, int client, int mode) {
00314 int areanum;
00315 aas_entityinfo_t entinfo;
00316 char netname[MAX_NETNAME];
00317
00318 bs->teamgoal.entitynum = -1;
00319 BotEntityInfo(client, &entinfo);
00320
00321 if (entinfo.valid) {
00322 areanum = BotPointAreaNum(entinfo.origin);
00323 if (areanum) {
00324 bs->teamgoal.entitynum = client;
00325 bs->teamgoal.areanum = areanum;
00326 VectorCopy(entinfo.origin, bs->teamgoal.origin);
00327 VectorSet(bs->teamgoal.mins, -8, -8, -8);
00328 VectorSet(bs->teamgoal.maxs, 8, 8, 8);
00329 }
00330 }
00331
00332 if (bs->teamgoal.entitynum < 0) {
00333 BotAI_BotInitialChat(bs, "whereareyou", EasyClientName(client, netname, sizeof(netname)), NULL);
00334 trap_BotEnterChat(bs->cs, client, CHAT_TELL);
00335 return;
00336 }
00337
00338 bs->decisionmaker = client;
00339 bs->ordered = qtrue;
00340 bs->order_time = FloatTime();
00341
00342 bs->teammate = client;
00343
00344 bs->teammatevisible_time = FloatTime();
00345
00346 bs->teammessage_time = FloatTime() + 2 * random();
00347
00348 bs->teamgoal_time = FloatTime() + TEAM_ACCOMPANY_TIME;
00349
00350 bs->ltgtype = LTG_TEAMACCOMPANY;
00351 bs->formation_dist = 3.5 * 32;
00352 bs->arrive_time = 0;
00353
00354 BotSetTeamStatus(bs);
00355
00356 BotRememberLastOrderedTask(bs);
00357 #ifdef DEBUG
00358 BotPrintTeamGoal(bs);
00359 #endif //DEBUG
00360 }
00361
00362
00363
00364
00365
00366
00367 void BotVoiceChat_FollowFlagCarrier(bot_state_t *bs, int client, int mode) {
00368 int carrier;
00369
00370 carrier = BotTeamFlagCarrier(bs);
00371 if (carrier >= 0)
00372 BotVoiceChat_FollowMe(bs, carrier, mode);
00373 #ifdef DEBUG
00374 BotPrintTeamGoal(bs);
00375 #endif //DEBUG
00376 }
00377
00378
00379
00380
00381
00382
00383 void BotVoiceChat_ReturnFlag(bot_state_t *bs, int client, int mode) {
00384
00385 if (
00386 gametype != GT_CTF
00387 #ifdef MISSIONPACK
00388 && gametype != GT_1FCTF
00389 #endif
00390 ) {
00391 return;
00392 }
00393
00394 bs->decisionmaker = client;
00395 bs->ordered = qtrue;
00396 bs->order_time = FloatTime();
00397
00398 bs->teammessage_time = FloatTime() + 2 * random();
00399
00400 bs->ltgtype = LTG_RETURNFLAG;
00401
00402 bs->teamgoal_time = FloatTime() + CTF_RETURNFLAG_TIME;
00403 bs->rushbaseaway_time = 0;
00404 BotSetTeamStatus(bs);
00405 #ifdef DEBUG
00406 BotPrintTeamGoal(bs);
00407 #endif //DEBUG
00408 }
00409
00410
00411
00412
00413
00414
00415 void BotVoiceChat_StartLeader(bot_state_t *bs, int client, int mode) {
00416 ClientName(client, bs->teamleader, sizeof(bs->teamleader));
00417 }
00418
00419
00420
00421
00422
00423
00424 void BotVoiceChat_StopLeader(bot_state_t *bs, int client, int mode) {
00425 char netname[MAX_MESSAGE_SIZE];
00426
00427 if (!Q_stricmp(bs->teamleader, ClientName(client, netname, sizeof(netname)))) {
00428 bs->teamleader[0] = '\0';
00429 notleader[client] = qtrue;
00430 }
00431 }
00432
00433
00434
00435
00436
00437
00438 void BotVoiceChat_WhoIsLeader(bot_state_t *bs, int client, int mode) {
00439 char netname[MAX_MESSAGE_SIZE];
00440
00441 if (!TeamPlayIsOn()) return;
00442
00443 ClientName(bs->client, netname, sizeof(netname));
00444
00445 if (!Q_stricmp(netname, bs->teamleader)) {
00446 BotAI_BotInitialChat(bs, "iamteamleader", NULL);
00447 trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
00448 BotVoiceChatOnly(bs, -1, VOICECHAT_STARTLEADER);
00449 }
00450 }
00451
00452
00453
00454
00455
00456
00457 void BotVoiceChat_WantOnDefense(bot_state_t *bs, int client, int mode) {
00458 char netname[MAX_NETNAME];
00459 int preference;
00460
00461 preference = BotGetTeamMateTaskPreference(bs, client);
00462 preference &= ~TEAMTP_ATTACKER;
00463 preference |= TEAMTP_DEFENDER;
00464 BotSetTeamMateTaskPreference(bs, client, preference);
00465
00466 EasyClientName(client, netname, sizeof(netname));
00467 BotAI_BotInitialChat(bs, "keepinmind", netname, NULL);
00468 trap_BotEnterChat(bs->cs, client, CHAT_TELL);
00469 BotVoiceChatOnly(bs, client, VOICECHAT_YES);
00470 trap_EA_Action(bs->client, ACTION_AFFIRMATIVE);
00471 }
00472
00473
00474
00475
00476
00477
00478 void BotVoiceChat_WantOnOffense(bot_state_t *bs, int client, int mode) {
00479 char netname[MAX_NETNAME];
00480 int preference;
00481
00482 preference = BotGetTeamMateTaskPreference(bs, client);
00483 preference &= ~TEAMTP_DEFENDER;
00484 preference |= TEAMTP_ATTACKER;
00485 BotSetTeamMateTaskPreference(bs, client, preference);
00486
00487 EasyClientName(client, netname, sizeof(netname));
00488 BotAI_BotInitialChat(bs, "keepinmind", netname, NULL);
00489 trap_BotEnterChat(bs->cs, client, CHAT_TELL);
00490 BotVoiceChatOnly(bs, client, VOICECHAT_YES);
00491 trap_EA_Action(bs->client, ACTION_AFFIRMATIVE);
00492 }
00493
00494 void BotVoiceChat_Dummy(bot_state_t *bs, int client, int mode) {
00495 }
00496
00497 voiceCommand_t voiceCommands[] = {
00498 {VOICECHAT_GETFLAG, BotVoiceChat_GetFlag},
00499 {VOICECHAT_OFFENSE, BotVoiceChat_Offense },
00500 {VOICECHAT_DEFEND, BotVoiceChat_Defend },
00501 {VOICECHAT_DEFENDFLAG, BotVoiceChat_DefendFlag },
00502 {VOICECHAT_PATROL, BotVoiceChat_Patrol },
00503 {VOICECHAT_CAMP, BotVoiceChat_Camp },
00504 {VOICECHAT_FOLLOWME, BotVoiceChat_FollowMe },
00505 {VOICECHAT_FOLLOWFLAGCARRIER, BotVoiceChat_FollowFlagCarrier },
00506 {VOICECHAT_RETURNFLAG, BotVoiceChat_ReturnFlag },
00507 {VOICECHAT_STARTLEADER, BotVoiceChat_StartLeader },
00508 {VOICECHAT_STOPLEADER, BotVoiceChat_StopLeader },
00509 {VOICECHAT_WHOISLEADER, BotVoiceChat_WhoIsLeader },
00510 {VOICECHAT_WANTONDEFENSE, BotVoiceChat_WantOnDefense },
00511 {VOICECHAT_WANTONOFFENSE, BotVoiceChat_WantOnOffense },
00512 {NULL, BotVoiceChat_Dummy}
00513 };
00514
00515 int BotVoiceChatCommand(bot_state_t *bs, int mode, char *voiceChat) {
00516 int i, voiceOnly, clientNum, color;
00517 char *ptr, buf[MAX_MESSAGE_SIZE], *cmd;
00518
00519 if (!TeamPlayIsOn()) {
00520 return qfalse;
00521 }
00522
00523 if ( mode == SAY_ALL ) {
00524 return qfalse;
00525 }
00526
00527 Q_strncpyz(buf, voiceChat, sizeof(buf));
00528 cmd = buf;
00529 for (ptr = cmd; *cmd && *cmd > ' '; cmd++);
00530 while (*cmd && *cmd <= ' ') *cmd++ = '\0';
00531 voiceOnly = atoi(ptr);
00532 for (ptr = cmd; *cmd && *cmd > ' '; cmd++);
00533 while (*cmd && *cmd <= ' ') *cmd++ = '\0';
00534 clientNum = atoi(ptr);
00535 for (ptr = cmd; *cmd && *cmd > ' '; cmd++);
00536 while (*cmd && *cmd <= ' ') *cmd++ = '\0';
00537 color = atoi(ptr);
00538
00539 if (!BotSameTeam(bs, clientNum)) {
00540 return qfalse;
00541 }
00542
00543 for (i = 0; voiceCommands[i].cmd; i++) {
00544 if (!Q_stricmp(cmd, voiceCommands[i].cmd)) {
00545 voiceCommands[i].func(bs, clientNum, mode);
00546 return qtrue;
00547 }
00548 }
00549 return qfalse;
00550 }