From e4208cf5a7abf3e55ace2a460e8fd2f24135b739 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Wed, 12 Sep 2018 15:47:03 -0500 Subject: [PATCH] Improve finding obelisk entitynum for bot AI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BotSetEntityNumForGoal() was checking all entities that are not team_redobelisk (which is the obelisk visual entity) to find the untitled obelisk collision entity. This may fail in rare cases where there is an another entity within 10 units of the obelisk origin. Failing to find the correct entity may cause bots to not attack the obelisk. Instead add BotSetEntityNumForGoalWithActivator() for looking for the obelisk collision entity by activator classname (team_redobelisk) which should be less likely to find the wrong entity. This doesn't affect official Team Arena maps (unknown if it affects any others). Reversed strcmp check was reported by Thomas Köppe. --- code/game/ai_dmq3.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/code/game/ai_dmq3.c b/code/game/ai_dmq3.c index dbc68b4a..30df7acb 100644 --- a/code/game/ai_dmq3.c +++ b/code/game/ai_dmq3.c @@ -5346,7 +5346,33 @@ void BotSetEntityNumForGoal(bot_goal_t *goal, char *classname) { if ( !ent->inuse ) { continue; } - if ( !Q_stricmp(ent->classname, classname) ) { + if ( Q_stricmp(ent->classname, classname) != 0 ) { + continue; + } + VectorSubtract(goal->origin, ent->s.origin, dir); + if (VectorLengthSquared(dir) < Square(10)) { + goal->entitynum = i; + return; + } + } +} + +/* +================== +BotSetEntityNumForGoalWithActivator +================== +*/ +void BotSetEntityNumForGoalWithActivator(bot_goal_t *goal, char *classname) { + gentity_t *ent; + int i; + vec3_t dir; + + ent = &g_entities[0]; + for (i = 0; i < level.num_entities; i++, ent++) { + if ( !ent->inuse || !ent->activator ) { + continue; + } + if ( Q_stricmp(ent->activator->classname, classname) != 0 ) { continue; } VectorSubtract(goal->origin, ent->s.origin, dir); @@ -5427,21 +5453,21 @@ void BotSetupDeathmatchAI(void) { else if (gametype == GT_OBELISK) { if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) BotAI_Print(PRT_WARNING, "Overload without Red Obelisk\n"); - BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); + BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk"); if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) BotAI_Print(PRT_WARNING, "Overload without Blue Obelisk\n"); - BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); + BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk"); } else if (gametype == GT_HARVESTER) { if (trap_BotGetLevelItemGoal(-1, "Red Obelisk", &redobelisk) < 0) BotAI_Print(PRT_WARNING, "Harvester without Red Obelisk\n"); - BotSetEntityNumForGoal(&redobelisk, "team_redobelisk"); + BotSetEntityNumForGoalWithActivator(&redobelisk, "team_redobelisk"); if (trap_BotGetLevelItemGoal(-1, "Blue Obelisk", &blueobelisk) < 0) BotAI_Print(PRT_WARNING, "Harvester without Blue Obelisk\n"); - BotSetEntityNumForGoal(&blueobelisk, "team_blueobelisk"); + BotSetEntityNumForGoalWithActivator(&blueobelisk, "team_blueobelisk"); if (trap_BotGetLevelItemGoal(-1, "Neutral Obelisk", &neutralobelisk) < 0) BotAI_Print(PRT_WARNING, "Harvester without Neutral Obelisk\n"); - BotSetEntityNumForGoal(&neutralobelisk, "team_neutralobelisk"); + BotSetEntityNumForGoalWithActivator(&neutralobelisk, "team_neutralobelisk"); } #endif