bool G_BotSetDefaults( int clientNum, team_t team, int skill, const char* behavior ) { botMemory_t *botMind; gentity_t *self = &g_entities[ clientNum ]; botMind = self->botMind = &g_botMind[clientNum]; botMind->botTeam = team; BotSetNavmesh( self, (class_t) self->client->ps.stats[ STAT_CLASS ] ); memset( botMind->runningNodes, 0, sizeof( botMind->runningNodes ) ); botMind->numRunningNodes = 0; botMind->currentNode = nullptr; memset( &botMind->nav, 0, sizeof( botMind->nav ) ); BotResetEnemyQueue( &botMind->enemyQueue ); botMind->behaviorTree = ReadBehaviorTree( behavior, &treeList ); if ( !botMind->behaviorTree ) { Log::Warn( "Problem when loading behavior tree %s, trying default", behavior ); botMind->behaviorTree = ReadBehaviorTree( "default", &treeList ); if ( !botMind->behaviorTree ) { Log::Warn( "Problem when loading default behavior tree" ); return false; } } BotSetSkillLevel( &g_entities[clientNum], skill ); g_entities[clientNum].r.svFlags |= SVF_BOT; if ( team != TEAM_NONE ) { level.clients[clientNum].sess.restartTeam = team; } self->pain = BotPain; return true; }
AIGenericNode_t *ReadBehaviorTreeInclude( pc_token_list **tokenlist ) { pc_token_list *first = *tokenlist; pc_token_list *current = first; AIBehaviorTree_t *behavior; if ( !expectToken( "behavior", ¤t, true ) ) { return nullptr; } if ( !current ) { Log::Warn( "Unexpected end of file after line %d", first->token.line ); *tokenlist = current; return nullptr; } behavior = ReadBehaviorTree( current->token.string, currentList ); if ( !behavior ) { Log::Warn( "Could not load behavior %s on line %d", current->token.string, current->token.line ); *tokenlist = current->next; return nullptr; } if ( !behavior->root ) { Log::Warn( "Recursive behavior %s on line %d", current->token.string, current->token.line ); *tokenlist = current->next; return nullptr; } *tokenlist = current->next; return ( AIGenericNode_t * ) behavior; }