// Bot_goal.h // #define MAX_BOT_ITEM_INFOS 2 #define MAX_BOT_ITEM_INFO 256 #define MAX_BOT_LEVEL_ITEMS 2048 //#define DEBUG_AI_GOAL #ifdef RANDOMIZE #define UNDECIDEDFUZZY #endif //RANDOMIZE #define DROPPEDWEIGHT //minimum avoid goal time #define AVOID_MINIMUM_TIME 10 //default avoid goal time #define AVOID_DEFAULT_TIME 30 //avoid dropped goal time #define AVOID_DROPPED_TIME 10 // #define TRAVELTIME_SCALE 0.01 //item flags #define IFL_NOTFREE 1 //not in free for all #define IFL_NOTTEAM 2 //not in team play #define IFL_NOTSINGLE 4 //not in single player #define IFL_NOTBOT 8 //bot should never go for this #define IFL_ROAM 16 //bot roam goal //a bot goal struct bot_goal_t { bot_goal_t() { Reset(); } void Reset() { origin.Zero(); areanum = 0; mins.Zero(); maxs.Zero(); entitynum = 0; number = 0; flags = 0; iteminfo = 0; framenum = -1; } int framenum; idVec3 origin; //origin of the goal int areanum; //area number of the goal idVec3 mins, maxs; //mins and maxs of the goal int entitynum; //number of the goal entity int number; //goal number int flags; //goal flags int iteminfo; //item information }; //location in the map "target_location" struct maplocation_t { maplocation_t() { Reset(); } void Reset() { origin.Zero(); areanum = 0; name = ""; next = nullptr; } idVec3 origin; int areanum; idStr name; maplocation_t* next; }; //camp spots "info_camp" struct campspot_t { campspot_t() { Reset(); } void Reset() { origin.Zero(); areanum = 0; name = ""; range = 0; weight = 0; random = 0; } idVec3 origin; int areanum; idStr name; float range; float weight; float wait; float random; }; struct levelitem_t { levelitem_t() { Reset(); } void Reset() { number = 0; iteminfo = 0; flags = 0; weight = 0; origin.Zero(); goalorigin.Zero(); item = nullptr; timeout = 0; prev = nullptr; next = nullptr; } idStr name; int number; //number of the level item int iteminfo; //index into the item info int flags; //item flags float weight; //fixed roam weight idVec3 origin; //origin of the item idVec3 goalorigin; //goal origin within the area //int entitynum; //entity number idItem* item; float timeout; //item is removed after this time levelitem_t* prev, * next; }; struct iteminfo_t { iteminfo_t() { Reset(); } void Reset() { classname = ""; name = ""; model = ""; modelindex = 0; type = 0; index = 0; respawntime = 0; mins.Zero(); maxs.Zero(); number = 0; } idStr classname; //classname of the item idStr name; //name of the item idStr model; //model of the item int modelindex; //model index int type; //item type int index; //index in the inventory float respawntime; //respawn time idVec3 mins; //mins of the item idVec3 maxs; //maxs of the item int number; //number of the item info }; // // itemconfig_t // struct itemconfig_t { itemconfig_t() { Reset(); } void Reset( void ) { numiteminfo = 0; for( int i = 0; i < MAX_BOT_ITEM_INFO; i++ ) { iteminfo[i].Reset(); } } int numiteminfo; iteminfo_t iteminfo[MAX_BOT_ITEM_INFO]; }; //goal state struct bot_goalstate_t { bot_goalstate_t() { itemweightindex = NULL; Reset(); } void Reset() { itemweightconfig = NULL; if( itemweightindex != NULL ) { delete itemweightindex; } itemweightindex = NULL; client = -1; lastreachabilityarea = 0; goalstacktop = 0; for( int i = 0; i < MAX_AVOIDGOALS; i++ ) { avoidgoals[i] = 0; avoidgoaltimes[i] = 0; } } ~bot_goalstate_t() { if( itemweightindex != NULL ) { delete itemweightindex; } itemweightindex = NULL; } bool InUse() { return client != -1; } weightconfig_t* itemweightconfig; //weight config int* itemweightindex; //index from item to weight int client; //client using this goal state int lastreachabilityarea; //last area with reachabilities the bot was in bot_goal_t goalstack[MAX_GOALSTACK]; //goal stack int goalstacktop; //the top of the goal stack int avoidgoals[MAX_AVOIDGOALS]; //goals to avoid float avoidgoaltimes[MAX_AVOIDGOALS]; //times to avoid the goals }; class idBotGoalManager { public: idBotGoalManager(); int BotSetupGoalAI( void ); void InitLevelItems( void ); void UpdateEntityItems( void ); void BotPushGoal( int goalstate, bot_goal_t* goal ); void BotPopGoal( int goalstate ); void BotEmptyGoalStack( int goalstate ); int BotLoadItemWeights( int goalstate, char* filename ); void BotResetGoalState( int goalstate ); int BotItemGoalInVisButNotVisible( int viewer, idVec3 eye, idAngles viewangles, bot_goal_t* goal ); int BotChooseLTGItem( int goalstate, idVec3 origin, int* inventory, int travelflags ); int BotChooseNBGItem( int goalstate, idVec3 origin, int* inventory, int travelflags, bot_goal_t* ltg, float maxtime ); int BotTouchingGoal( idVec3 origin, bot_goal_t* goal ); int BotAllocGoalState( int client ); void BotGoalName( int number, char* name, int size ); void BotFreeGoalState( int handle ); void BotShutdownGoalAI( void ); void BotFreeItemWeights( int goalstate ); public: bool BotNearGoal( idVec3 p1, idVec3 p2 ); int BotGetTopGoal( int goalstate, bot_goal_t* goal ); int BotGetSecondGoal( int goalstate, bot_goal_t* goal ); public: void BotDumpGoalStack( int goalstate ); public: int BotGetLevelItemGoal( int index, char* name, bot_goal_t* goal ); void BotSetAvoidGoalTime( int goalstate, int number, float avoidtime ); float BotAvoidGoalTime( int goalstate, int number ); void BotResetAvoidGoals( int goalstate ); void BotDumpAvoidGoals( int goalstate ); void BotAddToAvoidGoals( bot_goalstate_t* gs, int number, float avoidtime ); void BotRemoveFromAvoidGoals( int goalstate, int number ); int BotGetMapLocationGoal( char* name, bot_goal_t* goal ); int BotGetNextCampSpotGoal( int num, bot_goal_t* goal ); void BotFindEntityForLevelItem( levelitem_t* li ); private: levelitem_t* AllocLevelItem( void ); void FreeLevelItem( levelitem_t* li ); void AddLevelItemToList( levelitem_t* li ); void RemoveLevelItemFromList( levelitem_t* li ); void BotFreeInfoEntities( void ); void BotInitInfoEntities( void ); void InitLevelItemHeap( void ); int* ItemWeightIndex( weightconfig_t* iwc, itemconfig_t* ic ); itemconfig_t* LoadItemConfig( char* filename ); void BotSaveGoalFuzzyLogic( int goalstate, char* filename ); void BotMutateGoalFuzzyLogic( int goalstate, float range ); bot_goalstate_t* BotGoalStateFromHandle( int handle ); void BotInterbreedGoalFuzzyLogic( int parent1, int parent2, int child ); private: void ParseItemInfo( idParser& parser, iteminfo_t* itemInfo ); private: bot_goalstate_t botgoalstates[MAX_CLIENTS + 1]; //item configuration itemconfig_t itemconfiglocal; itemconfig_t* itemconfig; //level items levelitem_t levelitemheap[MAX_BOT_LEVEL_ITEMS]; levelitem_t* freelevelitems; levelitem_t* levelitems; int numlevelitems; //map locations idList maplocations; idList campspots; }; extern idBotGoalManager botGoalManager;