diff --git a/src/botlib/ai_goal/ai_goal.c b/src/botlib/ai_goal/ai_goal.c index dbeba51..d611f0d 100644 --- a/src/botlib/ai_goal/ai_goal.c +++ b/src/botlib/ai_goal/ai_goal.c @@ -198,6 +198,18 @@ void AI_GoalBotlib_UnregisterLevelItem(int number) BotGoal_UnregisterLevelItem(number); } +/* +============= +AI_GoalBotlib_GetLevelItemGoal + +Lookup level item goals by classname with a resumable index. +============= +*/ +int AI_GoalBotlib_GetLevelItemGoal(int index, char *classname, bot_goal_t *goal) +{ + return BotGetLevelItemGoal(index, classname, goal); +} + void AI_GoalBotlib_MarkItemTaken(int number, float respawn_delay) { BotGoal_MarkItemTaken(number, respawn_delay); diff --git a/src/botlib/ai_goal/ai_goal.h b/src/botlib/ai_goal/ai_goal.h index fc756f0..6e5687d 100644 --- a/src/botlib/ai_goal/ai_goal.h +++ b/src/botlib/ai_goal/ai_goal.h @@ -29,6 +29,7 @@ void AI_GoalBotlib_AddAvoidGoal(int handle, int number, float avoidtime); int AI_GoalBotlib_RegisterLevelItem(const bot_levelitem_setup_t *setup); void AI_GoalBotlib_UnregisterLevelItem(int number); void AI_GoalBotlib_MarkItemTaken(int number, float respawn_delay); +int AI_GoalBotlib_GetLevelItemGoal(int index, char *classname, bot_goal_t *goal); int AI_GoalBotlib_ChooseLTG(int handle, vec3_t origin, int *inventory, int travelflags); int AI_GoalBotlib_ChooseNBG(int handle, vec3_t origin, int *inventory, int travelflags, bot_goal_t *ltg, float maxtime); const bot_goalstate_t *AI_GoalBotlib_DebugPeek(int handle); @@ -36,4 +37,3 @@ const bot_goalstate_t *AI_GoalBotlib_DebugPeek(int handle); #ifdef __cplusplus } #endif - diff --git a/src/botlib/ai_goal/bot_goal.c b/src/botlib/ai_goal/bot_goal.c index 259f194..f088ae4 100644 --- a/src/botlib/ai_goal/bot_goal.c +++ b/src/botlib/ai_goal/bot_goal.c @@ -1039,6 +1039,68 @@ void BotGoalName(int number, char *name, int size) snprintf(name, (size_t)size, "%s", item->classname); } +/* +============= +BotGetLevelItemGoal + +Find the next level item goal matching the classname after the supplied index. +============= +*/ +int BotGetLevelItemGoal(int index, const char *classname, bot_goal_t *goal) +{ + if (classname == NULL || classname[0] == '\0' || goal == NULL) + { + return -1; + } + + int start_index = 0; + if (index >= 0) + { + bool found = false; + for (int i = 0; i < g_levelitem_count; ++i) + { + const bot_levelitem_t *item = &g_levelitems[i]; + if (!item->valid) + { + continue; + } + if (item->goal.number == index) + { + start_index = i + 1; + found = true; + break; + } + } + if (!found) + { + return -1; + } + } + + for (int i = start_index; i < g_levelitem_count; ++i) + { + const bot_levelitem_t *item = &g_levelitems[i]; + if (!item->valid) + { + continue; + } + if (Q_stricmp(classname, item->classname) != 0) + { + continue; + } + + *goal = item->goal; + goal->flags = GFL_ITEM; + if (item->goal.flags & GFL_DROPPED) + { + goal->flags |= GFL_DROPPED; + } + return item->goal.number; + } + + return -1; +} + void BotDumpAvoidGoals(int handle) { const bot_goalstate_t *gs = BotGoalStateFromHandle(handle); diff --git a/src/botlib/ai_goal/bot_goal.h b/src/botlib/ai_goal/bot_goal.h index eadd027..f59fed4 100644 --- a/src/botlib/ai_goal/bot_goal.h +++ b/src/botlib/ai_goal/bot_goal.h @@ -119,6 +119,7 @@ void BotDumpGoalStack(int handle); int BotGoal_RegisterLevelItem(const bot_levelitem_setup_t *setup); void BotGoal_UnregisterLevelItem(int number); void BotGoal_MarkItemTaken(int number, float respawn_delay); +int BotGetLevelItemGoal(int index, const char *classname, bot_goal_t *goal); void BotGoal_SetCurrentTime(float now); float BotGoal_CurrentTime(void); @@ -128,4 +129,3 @@ const bot_goalstate_t *BotGoalStatePeek(int handle); #ifdef __cplusplus } #endif - diff --git a/src/botlib/interface/bot_interface.c b/src/botlib/interface/bot_interface.c index c3d1bba..26fdd0f 100644 --- a/src/botlib/interface/bot_interface.c +++ b/src/botlib/interface/bot_interface.c @@ -3439,6 +3439,7 @@ GLADIATOR_API bot_export_t *GetBotAPI(bot_import_t *import) exportTable.BotRegisterLevelItem = AI_GoalBotlib_RegisterLevelItem; exportTable.BotUnregisterLevelItem = AI_GoalBotlib_UnregisterLevelItem; exportTable.BotMarkLevelItemTaken = AI_GoalBotlib_MarkItemTaken; + exportTable.BotGetLevelItemGoal = AI_GoalBotlib_GetLevelItemGoal; exportTable.BotTouchingGoal = BotInterface_BotTouchingGoal; exportTable.BotAllocWeightConfig = BotInterface_BotAllocWeightConfig; exportTable.BotFreeWeightConfig = BotInterface_BotFreeWeightConfig; @@ -3485,4 +3486,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..84e9bab 100644 --- a/src/q2bridge/botlib.h +++ b/src/q2bridge/botlib.h @@ -247,6 +247,7 @@ typedef struct bot_export_s { int (*BotRegisterLevelItem)(const bot_levelitem_setup_t *setup); void (*BotUnregisterLevelItem)(int number); void (*BotMarkLevelItemTaken)(int number, float respawn_delay); + int (*BotGetLevelItemGoal)(int index, char *classname, bot_goal_t *goal); int (*BotTouchingGoal)(const vec3_t origin, const bot_goal_t *goal); int (*BotAllocWeightConfig)(void); void (*BotFreeWeightConfig)(int handle);