📄 ai_dmq3.c
字号:
case TEAM_RED: goal = &blueobelisk; break;
default: goal = &redobelisk; break;
}
//if the obelisk is visible
VectorCopy(goal->origin, target);
target[2] += 1;
VectorSubtract(bs->origin, target, dir);
if (VectorLengthSquared(dir) < Square(KAMIKAZE_DIST * 0.9)) {
BotAI_Trace(&trace, bs->eye, NULL, NULL, target, bs->client, CONTENTS_SOLID);
if (trace.fraction >= 1 || trace.ent == goal->entitynum) {
trap_EA_Use(bs->client);
return;
}
}
}
else if (gametype == GT_HARVESTER) {
//
if (BotHarvesterCarryingCubes(bs))
return;
//never use kamikaze if a team mate carrying cubes is visible
c = BotTeamCubeCarrierVisible(bs);
if (c >= 0) {
BotEntityInfo(c, &entinfo);
VectorSubtract(entinfo.origin, bs->origin, dir);
if (VectorLengthSquared(dir) < Square(KAMIKAZE_DIST))
return;
}
c = BotEnemyCubeCarrierVisible(bs);
if (c >= 0) {
BotEntityInfo(c, &entinfo);
VectorSubtract(entinfo.origin, bs->origin, dir);
if (VectorLengthSquared(dir) < Square(KAMIKAZE_DIST)) {
trap_EA_Use(bs->client);
return;
}
}
}
//
BotVisibleTeamMatesAndEnemies(bs, &teammates, &enemies, KAMIKAZE_DIST);
//
if (enemies > 2 && enemies > teammates+1) {
trap_EA_Use(bs->client);
return;
}
}
/*
==================
BotUseInvulnerability
==================
*/
void BotUseInvulnerability(bot_state_t *bs) {
int c;
vec3_t dir, target;
bot_goal_t *goal;
bsp_trace_t trace;
//if the bot has no invulnerability
if (bs->inventory[INVENTORY_INVULNERABILITY] <= 0)
return;
if (bs->invulnerability_time > FloatTime())
return;
bs->invulnerability_time = FloatTime() + 0.2;
if (gametype == GT_CTF) {
//never use kamikaze if the team flag carrier is visible
if (BotCTFCarryingFlag(bs))
return;
c = BotEnemyFlagCarrierVisible(bs);
if (c >= 0)
return;
//if near enemy flag and the flag is visible
switch(BotTeam(bs)) {
case TEAM_RED: goal = &ctf_blueflag; break;
default: goal = &ctf_redflag; break;
}
//if the obelisk is visible
VectorCopy(goal->origin, target);
target[2] += 1;
VectorSubtract(bs->origin, target, dir);
if (VectorLengthSquared(dir) < Square(200)) {
BotAI_Trace(&trace, bs->eye, NULL, NULL, target, bs->client, CONTENTS_SOLID);
if (trace.fraction >= 1 || trace.ent == goal->entitynum) {
trap_EA_Use(bs->client);
return;
}
}
}
else if (gametype == GT_1FCTF) {
//never use kamikaze if the team flag carrier is visible
if (Bot1FCTFCarryingFlag(bs))
return;
c = BotEnemyFlagCarrierVisible(bs);
if (c >= 0)
return;
//if near enemy flag and the flag is visible
switch(BotTeam(bs)) {
case TEAM_RED: goal = &ctf_blueflag; break;
default: goal = &ctf_redflag; break;
}
//if the obelisk is visible
VectorCopy(goal->origin, target);
target[2] += 1;
VectorSubtract(bs->origin, target, dir);
if (VectorLengthSquared(dir) < Square(200)) {
BotAI_Trace(&trace, bs->eye, NULL, NULL, target, bs->client, CONTENTS_SOLID);
if (trace.fraction >= 1 || trace.ent == goal->entitynum) {
trap_EA_Use(bs->client);
return;
}
}
}
else if (gametype == GT_OBELISK) {
switch(BotTeam(bs)) {
case TEAM_RED: goal = &blueobelisk; break;
default: goal = &redobelisk; break;
}
//if the obelisk is visible
VectorCopy(goal->origin, target);
target[2] += 1;
VectorSubtract(bs->origin, target, dir);
if (VectorLengthSquared(dir) < Square(300)) {
BotAI_Trace(&trace, bs->eye, NULL, NULL, target, bs->client, CONTENTS_SOLID);
if (trace.fraction >= 1 || trace.ent == goal->entitynum) {
trap_EA_Use(bs->client);
return;
}
}
}
else if (gametype == GT_HARVESTER) {
//
if (BotHarvesterCarryingCubes(bs))
return;
c = BotEnemyCubeCarrierVisible(bs);
if (c >= 0)
return;
//if near enemy base and enemy base is visible
switch(BotTeam(bs)) {
case TEAM_RED: goal = &blueobelisk; break;
default: goal = &redobelisk; break;
}
//if the obelisk is visible
VectorCopy(goal->origin, target);
target[2] += 1;
VectorSubtract(bs->origin, target, dir);
if (VectorLengthSquared(dir) < Square(200)) {
BotAI_Trace(&trace, bs->eye, NULL, NULL, target, bs->client, CONTENTS_SOLID);
if (trace.fraction >= 1 || trace.ent == goal->entitynum) {
trap_EA_Use(bs->client);
return;
}
}
}
}
#endif
/*
==================
BotBattleUseItems
==================
*/
void BotBattleUseItems(bot_state_t *bs) {
if (bs->inventory[INVENTORY_HEALTH] < 40) {
if (bs->inventory[INVENTORY_TELEPORTER] > 0) {
if (!BotCTFCarryingFlag(bs)
#ifdef MISSIONPACK
&& !Bot1FCTFCarryingFlag(bs)
&& !BotHarvesterCarryingCubes(bs)
#endif
) {
trap_EA_Use(bs->client);
}
}
}
if (bs->inventory[INVENTORY_HEALTH] < 60) {
if (bs->inventory[INVENTORY_MEDKIT] > 0) {
trap_EA_Use(bs->client);
}
}
#ifdef MISSIONPACK
BotUseKamikaze(bs);
BotUseInvulnerability(bs);
#endif
}
/*
==================
BotSetTeleportTime
==================
*/
void BotSetTeleportTime(bot_state_t *bs) {
if ((bs->cur_ps.eFlags ^ bs->last_eFlags) & EF_TELEPORT_BIT) {
bs->teleport_time = FloatTime();
}
bs->last_eFlags = bs->cur_ps.eFlags;
}
/*
==================
BotIsDead
==================
*/
qboolean BotIsDead(bot_state_t *bs) {
return (bs->cur_ps.pm_type == PM_DEAD);
}
/*
==================
BotIsObserver
==================
*/
qboolean BotIsObserver(bot_state_t *bs) {
char buf[MAX_INFO_STRING];
if (bs->cur_ps.pm_type == PM_SPECTATOR) return qtrue;
trap_GetConfigstring(CS_PLAYERS+bs->client, buf, sizeof(buf));
if (atoi(Info_ValueForKey(buf, "t")) == TEAM_SPECTATOR) return qtrue;
return qfalse;
}
/*
==================
BotIntermission
==================
*/
qboolean BotIntermission(bot_state_t *bs) {
//NOTE: we shouldn't be looking at the game code...
if (level.intermissiontime) return qtrue;
return (bs->cur_ps.pm_type == PM_FREEZE || bs->cur_ps.pm_type == PM_INTERMISSION);
}
/*
==================
BotInLavaOrSlime
==================
*/
qboolean BotInLavaOrSlime(bot_state_t *bs) {
vec3_t feet;
VectorCopy(bs->origin, feet);
feet[2] -= 23;
return (trap_AAS_PointContents(feet) & (CONTENTS_LAVA|CONTENTS_SLIME));
}
/*
==================
BotCreateWayPoint
==================
*/
bot_waypoint_t *BotCreateWayPoint(char *name, vec3_t origin, int areanum) {
bot_waypoint_t *wp;
vec3_t waypointmins = {-8, -8, -8}, waypointmaxs = {8, 8, 8};
wp = botai_freewaypoints;
if ( !wp ) {
BotAI_Print( PRT_WARNING, "BotCreateWayPoint: Out of waypoints\n" );
return NULL;
}
botai_freewaypoints = botai_freewaypoints->next;
Q_strncpyz( wp->name, name, sizeof(wp->name) );
VectorCopy(origin, wp->goal.origin);
VectorCopy(waypointmins, wp->goal.mins);
VectorCopy(waypointmaxs, wp->goal.maxs);
wp->goal.areanum = areanum;
wp->next = NULL;
wp->prev = NULL;
return wp;
}
/*
==================
BotFindWayPoint
==================
*/
bot_waypoint_t *BotFindWayPoint(bot_waypoint_t *waypoints, char *name) {
bot_waypoint_t *wp;
for (wp = waypoints; wp; wp = wp->next) {
if (!Q_stricmp(wp->name, name)) return wp;
}
return NULL;
}
/*
==================
BotFreeWaypoints
==================
*/
void BotFreeWaypoints(bot_waypoint_t *wp) {
bot_waypoint_t *nextwp;
for (; wp; wp = nextwp) {
nextwp = wp->next;
wp->next = botai_freewaypoints;
botai_freewaypoints = wp;
}
}
/*
==================
BotInitWaypoints
==================
*/
void BotInitWaypoints(void) {
int i;
botai_freewaypoints = NULL;
for (i = 0; i < MAX_WAYPOINTS; i++) {
botai_waypoints[i].next = botai_freewaypoints;
botai_freewaypoints = &botai_waypoints[i];
}
}
/*
==================
TeamPlayIsOn
==================
*/
int TeamPlayIsOn(void) {
return ( gametype >= GT_TEAM );
}
/*
==================
BotAggression
==================
*/
float BotAggression(bot_state_t *bs) {
//if the bot has quad
if (bs->inventory[INVENTORY_QUAD]) {
//if the bot is not holding the gauntlet or the enemy is really nearby
if (bs->weaponnum != WP_GAUNTLET ||
bs->inventory[ENEMY_HORIZONTAL_DIST] < 80) {
return 70;
}
}
//if the enemy is located way higher than the bot
if (bs->inventory[ENEMY_HEIGHT] > 200) return 0;
//if the bot is very low on health
if (bs->inventory[INVENTORY_HEALTH] < 60) return 0;
//if the bot is low on health
if (bs->inventory[INVENTORY_HEALTH] < 80) {
//if the bot has insufficient armor
if (bs->inventory[INVENTORY_ARMOR] < 40) return 0;
}
//if the bot can use the bfg
if (bs->inventory[INVENTORY_BFG10K] > 0 &&
bs->inventory[INVENTORY_BFGAMMO] > 7) return 100;
//if the bot can use the railgun
if (bs->inventory[INVENTORY_RAILGUN] > 0 &&
bs->inventory[INVENTORY_SLUGS] > 5) return 95;
//if the bot can use the lightning gun
if (bs->inventory[INVENTORY_LIGHTNING] > 0 &&
bs->inventory[INVENTORY_LIGHTNINGAMMO] > 50) return 90;
//if the bot can use the rocketlauncher
if (bs->inventory[INVENTORY_ROCKETLAUNCHER] > 0 &&
bs->inventory[INVENTORY_ROCKETS] > 5) return 90;
//if the bot can use the plasmagun
if (bs->inventory[INVENTORY_PLASMAGUN] > 0 &&
bs->inventory[INVENTORY_CELLS] > 40) return 85;
//if the bot can use the grenade launcher
if (bs->inventory[INVENTORY_GRENADELAUNCHER] > 0 &&
bs->inventory[INVENTORY_GRENADES] > 10) return 80;
//if the bot can use the shotgun
if (bs->inventory[INVENTORY_SHOTGUN] > 0 &&
bs->inventory[INVENTORY_SHELLS] > 10) return 50;
//otherwise the bot is not feeling too good
return 0;
}
/*
==================
BotFeelingBad
==================
*/
float BotFeelingBad(bot_state_t *bs) {
if (bs->weaponnum == WP_GAUNTLET) {
return 100;
}
if (bs->inventory[INVENTORY_HEALTH] < 40) {
return 100;
}
if (bs->weaponnum == WP_MACHINEGUN) {
return 90;
}
if (bs->inventory[INVENTORY_HEALTH] < 60) {
return 80;
}
return 0;
}
/*
==================
BotWantsToRetreat
==================
*/
int BotWantsToRetreat(bot_state_t *bs) {
aas_entityinfo_t entinfo;
if (gametype == GT_CTF) {
//always retreat when carrying a CTF flag
if (BotCTFCarryingFlag(bs))
return qtrue;
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
//if carrying the flag then always retreat
if (Bot1FCTFCarryingFlag(bs))
return qtrue;
}
else if (gametype == GT_OBELISK) {
//the bots should be dedicated to attacking the enemy obelisk
if (bs->ltgtype == LTG_ATTACKENEMYBASE) {
if (bs->enemy != redobelisk.entitynum ||
bs->enemy != blueobelisk.entitynum) {
return qtrue;
}
}
if (BotFeelingBad(bs) > 50) {
return qtrue;
}
return qfalse;
}
else if (gametype == GT_HARVESTER) {
//if carrying cubes then always retreat
if (BotHarvesterCarryingCubes(bs)) return qtrue;
}
#endif
//
if (bs->enemy >= 0) {
//if the enemy is carrying a flag
BotEntityInfo(bs->enemy, &entinfo);
if (EntityCarriesFlag(&entinfo))
return qfalse;
}
//if the bot is getting the flag
if (bs->ltgtype == LTG_GETFLAG)
return qtrue;
//
if (BotAggression(bs) < 50)
return qtrue;
return qfalse;
}
/*
==================
BotWantsToChase
==================
*/
int BotWantsToChase(bot_state_t *bs) {
aas_entityinfo_t entinfo;
if (gametype == GT_CTF) {
//never chase when carrying a CTF flag
if (BotCTFCarryingFlag(bs))
return qfalse;
//always chase if the enemy is carrying a flag
BotEntityInfo(bs->enemy, &entinfo);
if (EntityCarriesFlag(&entinfo))
return qtrue;
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
//never chase if carrying the flag
if (Bot1FCTFCarryingFlag(bs))
return qfalse;
/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -