📄 ai_team.c
字号:
}
}
}
/*
==================
Bot1FCTFOrders
==================
*/
void Bot1FCTFOrders(bot_state_t *bs) {
switch(bs->neutralflagstatus) {
case 0: Bot1FCTFOrders_FlagAtCenter(bs); break;
case 1: Bot1FCTFOrders_TeamHasFlag(bs); break;
case 2: Bot1FCTFOrders_EnemyHasFlag(bs); break;
case 3: Bot1FCTFOrders_EnemyDroppedFlag(bs); break;
}
}
/*
==================
BotObeliskOrders
X% in defence Y% in offence
==================
*/
void BotObeliskOrders(bot_state_t *bs) {
int numteammates, defenders, attackers, i;
int teammates[MAX_CLIENTS];
char name[MAX_NETNAME];
//sort team mates by travel time to base
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
//sort team mates by CTF preference
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
//passive strategy
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
//different orders based on the number of team mates
switch(numteammates) {
case 1: break;
case 2:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the other will attack the enemy base
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
break;
}
case 3:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the one second closest to the base also defends the base
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
//the other one attacks the enemy base
ClientName(teammates[2], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
BotSayTeamOrder(bs, teammates[2]);
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
break;
}
default:
{
//50% defend the base
defenders = (int) (float) numteammates * 0.5 + 0.5;
if (defenders > 5) defenders = 5;
//40% attack the enemy base
attackers = (int) (float) numteammates * 0.4 + 0.5;
if (attackers > 4) attackers = 4;
for (i = 0; i < defenders; i++) {
//
ClientName(teammates[i], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[i]);
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
}
for (i = 0; i < attackers; i++) {
//
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
}
//
break;
}
}
}
else {
//different orders based on the number of team mates
switch(numteammates) {
case 1: break;
case 2:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the other will attack the enemy base
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
break;
}
case 3:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the others attack the enemy base
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
//
ClientName(teammates[2], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
BotSayTeamOrder(bs, teammates[2]);
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
break;
}
default:
{
//30% defend the base
defenders = (int) (float) numteammates * 0.3 + 0.5;
if (defenders > 3) defenders = 3;
//70% attack the enemy base
attackers = (int) (float) numteammates * 0.7 + 0.5;
if (attackers > 7) attackers = 7;
for (i = 0; i < defenders; i++) {
//
ClientName(teammates[i], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[i]);
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
}
for (i = 0; i < attackers; i++) {
//
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_attackenemybase", name, NULL);
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
}
//
break;
}
}
}
}
/*
==================
BotHarvesterOrders
X% defend the base, Y% harvest
==================
*/
void BotHarvesterOrders(bot_state_t *bs) {
int numteammates, defenders, attackers, i;
int teammates[MAX_CLIENTS];
char name[MAX_NETNAME];
//sort team mates by travel time to base
numteammates = BotSortTeamMatesByBaseTravelTime(bs, teammates, sizeof(teammates));
//sort team mates by CTF preference
BotSortTeamMatesByTaskPreference(bs, teammates, numteammates);
//passive strategy
if (!(bs->ctfstrategy & CTFS_AGRESSIVE)) {
//different orders based on the number of team mates
switch(numteammates) {
case 1: break;
case 2:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the other will harvest
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
break;
}
case 3:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the one second closest to the base also defends the base
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_DEFEND);
//the other one goes harvesting
ClientName(teammates[2], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
BotSayTeamOrder(bs, teammates[2]);
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
break;
}
default:
{
//50% defend the base
defenders = (int) (float) numteammates * 0.5 + 0.5;
if (defenders > 5) defenders = 5;
//40% goes harvesting
attackers = (int) (float) numteammates * 0.4 + 0.5;
if (attackers > 4) attackers = 4;
for (i = 0; i < defenders; i++) {
//
ClientName(teammates[i], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[i]);
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
}
for (i = 0; i < attackers; i++) {
//
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
}
//
break;
}
}
}
else {
//different orders based on the number of team mates
switch(numteammates) {
case 1: break;
case 2:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the other will harvest
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
break;
}
case 3:
{
//the one closest to the base will defend the base
ClientName(teammates[0], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[0]);
BotSayVoiceTeamOrder(bs, teammates[0], VOICECHAT_DEFEND);
//the others go harvesting
ClientName(teammates[1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
BotSayTeamOrder(bs, teammates[1]);
BotSayVoiceTeamOrder(bs, teammates[1], VOICECHAT_OFFENSE);
//
ClientName(teammates[2], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
BotSayTeamOrder(bs, teammates[2]);
BotSayVoiceTeamOrder(bs, teammates[2], VOICECHAT_OFFENSE);
break;
}
default:
{
//30% defend the base
defenders = (int) (float) numteammates * 0.3 + 0.5;
if (defenders > 3) defenders = 3;
//70% go harvesting
attackers = (int) (float) numteammates * 0.7 + 0.5;
if (attackers > 7) attackers = 7;
for (i = 0; i < defenders; i++) {
//
ClientName(teammates[i], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_defendbase", name, NULL);
BotSayTeamOrder(bs, teammates[i]);
BotSayVoiceTeamOrder(bs, teammates[i], VOICECHAT_DEFEND);
}
for (i = 0; i < attackers; i++) {
//
ClientName(teammates[numteammates - i - 1], name, sizeof(name));
BotAI_BotInitialChat(bs, "cmd_harvest", name, NULL);
BotSayTeamOrder(bs, teammates[numteammates - i - 1]);
BotSayVoiceTeamOrder(bs, teammates[numteammates - i - 1], VOICECHAT_OFFENSE);
}
//
break;
}
}
}
}
#endif
/*
==================
FindHumanTeamLeader
==================
*/
int FindHumanTeamLeader(bot_state_t *bs) {
int i;
for (i = 0; i < MAX_CLIENTS; i++) {
if ( g_entities[i].inuse ) {
// if this player is not a bot
if ( !(g_entities[i].r.svFlags & SVF_BOT) ) {
// if this player is ok with being the leader
if (!notleader[i]) {
// if this player is on the same team
if ( BotSameTeam(bs, i) ) {
ClientName(i, bs->teamleader, sizeof(bs->teamleader));
// if not yet ordered to do anything
if ( !BotSetLastOrderedTask(bs) ) {
// go on defense by default
BotVoiceChat_Defend(bs, i, SAY_TELL);
}
return qtrue;
}
}
}
}
}
return qfalse;
}
/*
==================
BotTeamAI
==================
*/
void BotTeamAI(bot_state_t *bs) {
int numteammates;
char netname[MAX_NETNAME];
//
if ( gametype < GT_TEAM )
return;
// make sure we've got a valid team leader
if (!BotValidTeamLeader(bs)) {
//
if (!FindHumanTeamLeader(bs)) {
//
if (!bs->askteamleader_time && !bs->becometeamleader_time) {
if (bs->entergame_time + 10 > FloatTime()) {
bs->askteamleader_time = FloatTime() + 5 + random() * 10;
}
else {
bs->becometeamleader_time = FloatTime() + 5 + random() * 10;
}
}
if (bs->askteamleader_time && bs->askteamleader_time < FloatTime()) {
// if asked for a team leader and no response
BotAI_BotInitialChat(bs, "whoisteamleader", NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
bs->askteamleader_time = 0;
bs->becometeamleader_time = FloatTime() + 8 + random() * 10;
}
if (bs->becometeamleader_time && bs->becometeamleader_time < FloatTime()) {
BotAI_BotInitialChat(bs, "iamteamleader", NULL);
trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
BotSayVoiceTeamOrder(bs, -1, VOICECHAT_STARTLEADER);
ClientName(bs->client, netname, sizeof(netname));
strncpy(bs->teamleader, netname, sizeof(bs->teamleader));
bs->teamleader[sizeof(bs->teamleader)] = '\0';
bs->becometeamleader_time = 0;
}
return;
}
}
bs->askteamleader_time = 0;
bs->becometeamleader_time = 0;
//return if this bot is NOT the team leader
ClientName(bs->clien
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -