From ba0366bd71a697fabc76131e5d84b7d0a0a0879b Mon Sep 17 00:00:00 2001 From: themuffinator Date: Tue, 30 Dec 2025 21:29:09 +0000 Subject: [PATCH] Implement BotResetLastAvoidReach tracking --- src/botlib/ai_move/bot_move.c | 58 +++++++++++++++++++++++++++- src/botlib/ai_move/bot_move.h | 18 +++++---- src/botlib/interface/bot_interface.c | 19 ++++++++- src/q2bridge/botlib.h | 1 + 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/botlib/ai_move/bot_move.c b/src/botlib/ai_move/bot_move.c index 2b3d722..8b0693f 100644 --- a/src/botlib/ai_move/bot_move.c +++ b/src/botlib/ai_move/bot_move.c @@ -661,6 +661,8 @@ static void BotMove_RefreshAvoidReach(bot_movestate_t *ms) } float now = aasworld.time; + int latestIndex = -1; + float latestTime = 0.0f; for (int i = 0; i < MAX_AVOIDREACH; ++i) { if (ms->avoidreach[i] <= 0) @@ -673,8 +675,28 @@ static void BotMove_RefreshAvoidReach(bot_movestate_t *ms) ms->avoidreach[i] = 0; ms->avoidreachtimes[i] = 0.0f; ms->avoidreachtries[i] = 0; + continue; } - } + + if (ms->avoidreachtimes[i] > latestTime) + { + latestTime = ms->avoidreachtimes[i]; + latestIndex = i; + } + } + + ms->lastavoidreachindex = latestIndex; + ms->lastavoidreachtime = latestTime; + if (latestIndex >= 0) + { + ms->lastavoidreach = ms->avoidreach[latestIndex]; + ms->lastavoidreachtries = ms->avoidreachtries[latestIndex]; + } + else + { + ms->lastavoidreach = 0; + ms->lastavoidreachtries = 0; + } } static bool BotMove_ShouldAvoidReach(const bot_movestate_t *ms, int reachnum) @@ -1509,5 +1531,39 @@ void BotMove_ResetAvoidReach(int movestate) memset(ms->avoidreach, 0, sizeof(ms->avoidreach)); memset(ms->avoidreachtimes, 0, sizeof(ms->avoidreachtimes)); memset(ms->avoidreachtries, 0, sizeof(ms->avoidreachtries)); + ms->lastavoidreach = 0; + ms->lastavoidreachtime = 0.0f; + ms->lastavoidreachtries = 0; + ms->lastavoidreachindex = -1; } +/* +============= +BotMove_ResetLastAvoidReach + +Clears the most recently avoided reachability timer and decrements its tries. +============= +*/ +void BotMove_ResetLastAvoidReach(int movestate) +{ + bot_movestate_t *ms = BotMoveStateFromHandle(movestate); + if (ms == NULL) + { + return; + } + + if (ms->lastavoidreachtime <= 0.0f || + ms->lastavoidreachindex < 0 || + ms->lastavoidreachindex >= MAX_AVOIDREACH) + { + return; + } + + ms->avoidreachtimes[ms->lastavoidreachindex] = 0.0f; + if (ms->avoidreachtries[ms->lastavoidreachindex] > 0) + { + ms->avoidreachtries[ms->lastavoidreachindex]--; + } + + BotMove_RefreshAvoidReach(ms); +} diff --git a/src/botlib/ai_move/bot_move.h b/src/botlib/ai_move/bot_move.h index 8f2600c..67162c9 100644 --- a/src/botlib/ai_move/bot_move.h +++ b/src/botlib/ai_move/bot_move.h @@ -140,12 +140,16 @@ typedef struct bot_movestate_s float lastgrappledist; float reachability_time; - int avoidreach[MAX_AVOIDREACH]; - float avoidreachtimes[MAX_AVOIDREACH]; - int avoidreachtries[MAX_AVOIDREACH]; - - bot_avoidspot_t avoidspots[MAX_AVOIDSPOTS]; - int numavoidspots; + int avoidreach[MAX_AVOIDREACH]; + float avoidreachtimes[MAX_AVOIDREACH]; + int avoidreachtries[MAX_AVOIDREACH]; + int lastavoidreach; + float lastavoidreachtime; + int lastavoidreachtries; + int lastavoidreachindex; + + bot_avoidspot_t avoidspots[MAX_AVOIDSPOTS]; + int numavoidspots; } bot_movestate_t; int BotAllocMoveState(void); @@ -165,6 +169,7 @@ void BotMoveToGoal(bot_moveresult_t *result, int BotMoveInDirection(int movestate, const vec3_t dir, float speed, int type); void BotMove_ResetAvoidReach(int movestate); +void BotMove_ResetLastAvoidReach(int movestate); void AI_MoveFrame(bot_moveresult_t *result, int movestate, @@ -176,4 +181,3 @@ bot_moveresult_t BotTravel_Grapple(bot_movestate_t *ms, const struct aas_reachab #ifdef __cplusplus } /* extern "C" */ #endif - diff --git a/src/botlib/interface/bot_interface.c b/src/botlib/interface/bot_interface.c index c3d1bba..3831c21 100644 --- a/src/botlib/interface/bot_interface.c +++ b/src/botlib/interface/bot_interface.c @@ -3170,6 +3170,23 @@ static void BotInterface_BotResetAvoidReach(int movestate) BotMove_ResetAvoidReach(movestate); } +/* +============= +BotInterface_BotResetLastAvoidReach + +Resets the most recent avoid-reach entry in the movement state. +============= +*/ +static void BotInterface_BotResetLastAvoidReach(int movestate) +{ + if (!BotInterface_EnsureLibraryReady("BotResetLastAvoidReach")) + { + return; + } + + BotMove_ResetLastAvoidReach(movestate); +} + static int BotInterface_BotAllocWeaponState(void) { if (!BotInterface_EnsureLibraryReady("BotAllocWeaponState")) @@ -3454,6 +3471,7 @@ GLADIATOR_API bot_export_t *GetBotAPI(bot_import_t *import) exportTable.BotMoveToGoal = BotInterface_BotMoveToGoal; exportTable.BotMoveInDirection = BotInterface_BotMoveInDirection; exportTable.BotResetAvoidReach = BotInterface_BotResetAvoidReach; + exportTable.BotResetLastAvoidReach = BotInterface_BotResetLastAvoidReach; exportTable.BotLoadCharacter = BotLoadCharacter; exportTable.BotFreeCharacter = BotFreeCharacter; exportTable.BotLoadCharacterSkill = BotLoadCharacterSkill; @@ -3485,4 +3503,3 @@ GLADIATOR_API bot_export_t *GetBotAPI(bot_import_t *import) return &exportTable; } - diff --git a/src/q2bridge/botlib.h b/src/q2bridge/botlib.h index c5e92c3..4c34952 100644 --- a/src/q2bridge/botlib.h +++ b/src/q2bridge/botlib.h @@ -262,6 +262,7 @@ typedef struct bot_export_s { void (*BotMoveToGoal)(bot_moveresult_t *result, int movestate, const bot_goal_t *goal, int travelflags); int (*BotMoveInDirection)(int movestate, const vec3_t dir, float speed, int type); void (*BotResetAvoidReach)(int movestate); + void (*BotResetLastAvoidReach)(int movestate); int (*BotLoadCharacter)(const char *character_file, float skill); void (*BotFreeCharacter)(int handle); int (*BotLoadCharacterSkill)(const char *character_file, float skill);