📄 ai_dmq3.c
字号:
}
//if already a CTF or team goal
if (bs->ltgtype == LTG_TEAMHELP ||
bs->ltgtype == LTG_TEAMACCOMPANY ||
bs->ltgtype == LTG_DEFENDKEYAREA ||
bs->ltgtype == LTG_GETFLAG ||
bs->ltgtype == LTG_RUSHBASE ||
bs->ltgtype == LTG_RETURNFLAG ||
bs->ltgtype == LTG_CAMPORDER ||
bs->ltgtype == LTG_PATROL ||
bs->ltgtype == LTG_ATTACKENEMYBASE ||
bs->ltgtype == LTG_GETITEM ||
bs->ltgtype == LTG_MAKELOVE_UNDER ||
bs->ltgtype == LTG_MAKELOVE_ONTOP) {
return;
}
//
if (BotSetLastOrderedTask(bs))
return;
//
if (bs->owndecision_time > FloatTime())
return;;
//if the bot is roaming
if (bs->ctfroam_time > FloatTime())
return;
//if the bot has anough aggression to decide what to do
if (BotAggression(bs) < 50)
return;
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//
if (bs->teamtaskpreference & (TEAMTP_ATTACKER|TEAMTP_DEFENDER)) {
if (bs->teamtaskpreference & TEAMTP_ATTACKER) {
l1 = 0.7f;
}
else {
l1 = 0.2f;
}
l2 = 0.9f;
}
else {
l1 = 0.4f;
l2 = 0.7f;
}
//get the flag or defend the base
rnd = random();
if (rnd < l1 && ctf_neutralflag.areanum) {
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
bs->ltgtype = LTG_GETFLAG;
//set the time the bot will stop getting the flag
bs->teamgoal_time = FloatTime() + CTF_GETFLAG_TIME;
BotSetTeamStatus(bs);
}
else if (rnd < l2 && ctf_redflag.areanum && ctf_blueflag.areanum) {
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
//
if (BotTeam(bs) == TEAM_RED) memcpy(&bs->teamgoal, &ctf_redflag, sizeof(bot_goal_t));
else memcpy(&bs->teamgoal, &ctf_blueflag, sizeof(bot_goal_t));
//set the ltg type
bs->ltgtype = LTG_DEFENDKEYAREA;
//set the time the bot stops defending the base
bs->teamgoal_time = FloatTime() + TEAM_DEFENDKEYAREA_TIME;
bs->defendaway_time = 0;
BotSetTeamStatus(bs);
}
else {
bs->ltgtype = 0;
//set the time the bot will stop roaming
bs->ctfroam_time = FloatTime() + CTF_ROAM_TIME;
BotSetTeamStatus(bs);
}
bs->owndecision_time = FloatTime() + 5;
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
Bot1FCTFRetreatGoals
==================
*/
void Bot1FCTFRetreatGoals(bot_state_t *bs) {
//when carrying a flag in ctf the bot should rush to the enemy base
if (Bot1FCTFCarryingFlag(bs)) {
//if not already rushing to the base
if (bs->ltgtype != LTG_RUSHBASE) {
BotRefuseOrder(bs);
bs->ltgtype = LTG_RUSHBASE;
bs->teamgoal_time = FloatTime() + CTF_RUSHBASE_TIME;
bs->rushbaseaway_time = 0;
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
//get an alternative route goal towards the enemy base
BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs));
BotSetTeamStatus(bs);
}
}
}
/*
==================
BotObeliskSeekGoals
==================
*/
void BotObeliskSeekGoals(bot_state_t *bs) {
float rnd, l1, l2;
// don't just do something wait for the bot team leader to give orders
if (BotTeamLeader(bs)) {
return;
}
// if the bot is ordered to do something
if ( bs->lastgoal_ltgtype ) {
bs->teamgoal_time += 60;
}
//if already a team goal
if (bs->ltgtype == LTG_TEAMHELP ||
bs->ltgtype == LTG_TEAMACCOMPANY ||
bs->ltgtype == LTG_DEFENDKEYAREA ||
bs->ltgtype == LTG_GETFLAG ||
bs->ltgtype == LTG_RUSHBASE ||
bs->ltgtype == LTG_RETURNFLAG ||
bs->ltgtype == LTG_CAMPORDER ||
bs->ltgtype == LTG_PATROL ||
bs->ltgtype == LTG_ATTACKENEMYBASE ||
bs->ltgtype == LTG_GETITEM ||
bs->ltgtype == LTG_MAKELOVE_UNDER ||
bs->ltgtype == LTG_MAKELOVE_ONTOP) {
return;
}
//
if (BotSetLastOrderedTask(bs))
return;
//if the bot is roaming
if (bs->ctfroam_time > FloatTime())
return;
//if the bot has anough aggression to decide what to do
if (BotAggression(bs) < 50)
return;
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//
if (bs->teamtaskpreference & (TEAMTP_ATTACKER|TEAMTP_DEFENDER)) {
if (bs->teamtaskpreference & TEAMTP_ATTACKER) {
l1 = 0.7f;
}
else {
l1 = 0.2f;
}
l2 = 0.9f;
}
else {
l1 = 0.4f;
l2 = 0.7f;
}
//get the flag or defend the base
rnd = random();
if (rnd < l1 && redobelisk.areanum && blueobelisk.areanum) {
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
//
if (BotTeam(bs) == TEAM_RED) memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t));
else memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t));
//set the ltg type
bs->ltgtype = LTG_ATTACKENEMYBASE;
//set the time the bot will stop attacking the enemy base
bs->teamgoal_time = FloatTime() + TEAM_ATTACKENEMYBASE_TIME;
//get an alternate route goal towards the enemy base
BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs));
BotSetTeamStatus(bs);
}
else if (rnd < l2 && redobelisk.areanum && blueobelisk.areanum) {
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
//
if (BotTeam(bs) == TEAM_RED) memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t));
else memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t));
//set the ltg type
bs->ltgtype = LTG_DEFENDKEYAREA;
//set the time the bot stops defending the base
bs->teamgoal_time = FloatTime() + TEAM_DEFENDKEYAREA_TIME;
bs->defendaway_time = 0;
BotSetTeamStatus(bs);
}
else {
bs->ltgtype = 0;
//set the time the bot will stop roaming
bs->ctfroam_time = FloatTime() + CTF_ROAM_TIME;
BotSetTeamStatus(bs);
}
}
/*
==================
BotGoHarvest
==================
*/
void BotGoHarvest(bot_state_t *bs) {
//
if (BotTeam(bs) == TEAM_RED) memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t));
else memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t));
//set the ltg type
bs->ltgtype = LTG_HARVEST;
//set the time the bot will stop harvesting
bs->teamgoal_time = FloatTime() + TEAM_HARVEST_TIME;
bs->harvestaway_time = 0;
BotSetTeamStatus(bs);
}
/*
==================
BotObeliskRetreatGoals
==================
*/
void BotObeliskRetreatGoals(bot_state_t *bs) {
//nothing special
}
/*
==================
BotHarvesterSeekGoals
==================
*/
void BotHarvesterSeekGoals(bot_state_t *bs) {
aas_entityinfo_t entinfo;
float rnd, l1, l2;
int c;
//when carrying cubes in harvester the bot should rush to the base
if (BotHarvesterCarryingCubes(bs)) {
//if not already rushing to the base
if (bs->ltgtype != LTG_RUSHBASE) {
BotRefuseOrder(bs);
bs->ltgtype = LTG_RUSHBASE;
bs->teamgoal_time = FloatTime() + CTF_RUSHBASE_TIME;
bs->rushbaseaway_time = 0;
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
//get an alternative route goal towards the enemy base
BotGetAlternateRouteGoal(bs, BotOppositeTeam(bs));
//
BotSetTeamStatus(bs);
}
return;
}
// don't just do something wait for the bot team leader to give orders
if (BotTeamLeader(bs)) {
return;
}
// if the bot decided to follow someone
if ( bs->ltgtype == LTG_TEAMACCOMPANY && !bs->ordered ) {
// if the team mate being accompanied no longer carries the flag
BotEntityInfo(bs->teammate, &entinfo);
if (!EntityCarriesCubes(&entinfo)) {
bs->ltgtype = 0;
}
}
// if the bot is ordered to do something
if ( bs->lastgoal_ltgtype ) {
bs->teamgoal_time += 60;
}
//if not yet doing something
if (bs->ltgtype == LTG_TEAMHELP ||
bs->ltgtype == LTG_TEAMACCOMPANY ||
bs->ltgtype == LTG_DEFENDKEYAREA ||
bs->ltgtype == LTG_GETFLAG ||
bs->ltgtype == LTG_CAMPORDER ||
bs->ltgtype == LTG_PATROL ||
bs->ltgtype == LTG_ATTACKENEMYBASE ||
bs->ltgtype == LTG_HARVEST ||
bs->ltgtype == LTG_GETITEM ||
bs->ltgtype == LTG_MAKELOVE_UNDER ||
bs->ltgtype == LTG_MAKELOVE_ONTOP) {
return;
}
//
if (BotSetLastOrderedTask(bs))
return;
//if the bot is roaming
if (bs->ctfroam_time > FloatTime())
return;
//if the bot has anough aggression to decide what to do
if (BotAggression(bs) < 50)
return;
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//
c = BotEnemyCubeCarrierVisible(bs);
if (c >= 0) {
//FIXME: attack enemy cube carrier
}
if (bs->ltgtype != LTG_TEAMACCOMPANY) {
//if there is a visible team mate carrying cubes
c = BotTeamCubeCarrierVisible(bs);
if (c >= 0) {
//follow the team mate carrying cubes
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
//the team mate
bs->teammate = c;
//last time the team mate was visible
bs->teammatevisible_time = FloatTime();
//no message
bs->teammessage_time = 0;
//no arrive message
bs->arrive_time = 1;
//
BotVoiceChat(bs, bs->teammate, VOICECHAT_ONFOLLOW);
//get the team goal time
bs->teamgoal_time = FloatTime() + TEAM_ACCOMPANY_TIME;
bs->ltgtype = LTG_TEAMACCOMPANY;
bs->formation_dist = 3.5 * 32; //3.5 meter
BotSetTeamStatus(bs);
return;
}
}
//
if (bs->teamtaskpreference & (TEAMTP_ATTACKER|TEAMTP_DEFENDER)) {
if (bs->teamtaskpreference & TEAMTP_ATTACKER) {
l1 = 0.7f;
}
else {
l1 = 0.2f;
}
l2 = 0.9f;
}
else {
l1 = 0.4f;
l2 = 0.7f;
}
//
rnd = random();
if (rnd < l1 && redobelisk.areanum && blueobelisk.areanum) {
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
BotGoHarvest(bs);
}
else if (rnd < l2 && redobelisk.areanum && blueobelisk.areanum) {
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
//
if (BotTeam(bs) == TEAM_RED) memcpy(&bs->teamgoal, &redobelisk, sizeof(bot_goal_t));
else memcpy(&bs->teamgoal, &blueobelisk, sizeof(bot_goal_t));
//set the ltg type
bs->ltgtype = LTG_DEFENDKEYAREA;
//set the time the bot stops defending the base
bs->teamgoal_time = FloatTime() + TEAM_DEFENDKEYAREA_TIME;
bs->defendaway_time = 0;
BotSetTeamStatus(bs);
}
else {
bs->ltgtype = 0;
//set the time the bot will stop roaming
bs->ctfroam_time = FloatTime() + CTF_ROAM_TIME;
BotSetTeamStatus(bs);
}
}
/*
==================
BotHarvesterRetreatGoals
==================
*/
void BotHarvesterRetreatGoals(bot_state_t *bs) {
//when carrying cubes in harvester the bot should rush to the base
if (BotHarvesterCarryingCubes(bs)) {
//if not already rushing to the base
if (bs->ltgtype != LTG_RUSHBASE) {
BotRefuseOrder(bs);
bs->ltgtype = LTG_RUSHBASE;
bs->teamgoal_time = FloatTime() + CTF_RUSHBASE_TIME;
bs->rushbaseaway_time = 0;
bs->decisionmaker = bs->client;
bs->ordered = qfalse;
BotSetTeamStatus(bs);
}
return;
}
}
#endif
/*
==================
BotTeamGoals
==================
*/
void BotTeamGoals(bot_state_t *bs, int retreat) {
if ( retreat ) {
if (gametype == GT_CTF) {
BotCTFRetreatGoals(bs);
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
Bot1FCTFRetreatGoals(bs);
}
else if (gametype == GT_OBELISK) {
BotObeliskRetreatGoals(bs);
}
else if (gametype == GT_HARVESTER) {
BotHarvesterRetreatGoals(bs);
}
#endif
}
else {
if (gametype == GT_CTF) {
//decide what to do in CTF mode
BotCTFSeekGoals(bs);
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
Bot1FCTFSeekGoals(bs);
}
else if (gametype == GT_OBELISK) {
BotObeliskSeekGoals(bs);
}
else if (gametype == GT_HARVESTER) {
BotHarvesterSeekGoals(bs);
}
#endif
}
// reset the order time which is used to see if
// we decided to refuse an order
bs->order_time = 0;
}
/*
==================
BotPointAreaNum
==================
*/
int BotPointAreaNum(vec3_t origin) {
int areanum, numareas, areas[10];
vec3_t end;
areanum = trap_AAS_PointAreaNum(origin);
if (areanum) return areanum;
VectorCopy(origin, end);
end[2] += 10;
numareas = trap_AAS_TraceAreas(origin, end, areas, NULL, 10);
if (numareas > 0) return areas[0];
return 0;
}
/*
==================
ClientName
==================
*/
char *ClientName(int client, char *name, int size) {
char buf[MAX_INFO_STRING];
if (client < 0 || client >= MAX_CLIENTS) {
BotAI_Print(PRT_ERROR, "ClientName: client out of range\n");
return "[client out of range]";
}
trap_GetConfigstring(CS_PLAYERS+client, buf, sizeof(buf));
strncpy(name, Info_ValueForKey(buf, "n"), size-1);
name[size-1] = '\0';
Q_CleanStr( name );
return name;
}
/*
==================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -