//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int BotChooseBestFightWeapon(int weaponstate, int *inventory) { int i, index, bestweapon; float weight, bestweight; weaponconfig_t *wc; bot_weaponstate_t *ws; ws = BotWeaponStateFromHandle(weaponstate); if (!ws) return 0; wc = weaponconfig; if (!weaponconfig) return 0; //if the bot has no weapon weight configuration if (!ws->weaponweightconfig) return 0; bestweight = 0; bestweapon = 0; for (i = 0; i < wc->numweapons; i++) { if (!wc->weaponinfo[i].valid) continue; index = ws->weaponweightindex[i]; if (index < 0) continue; weight = FuzzyWeight(inventory, ws->weaponweightconfig, index); if (weight > bestweight) { bestweight = weight; bestweapon = i; } //end if } //end for return bestweapon; } //end of the function BotChooseBestFightWeapon
//=========================================================================== // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== int BotChooseNBGItem( int goalstate, vec3_t origin, int *inventory, int travelflags, bot_goal_t *ltg, float maxtime ) { int areanum, t, weightnum, ltg_time; float weight, bestweight, avoidtime; iteminfo_t *iteminfo; itemconfig_t *ic; levelitem_t *li, *bestitem; bot_goal_t goal; bot_goalstate_t *gs; gs = BotGoalStateFromHandle( goalstate ); if ( !gs ) { return qfalse; } if ( !gs->itemweightconfig ) { return qfalse; } //get the area the bot is in areanum = BotReachabilityArea( origin, gs->client ); //if the bot is in solid or if the area the bot is in has no reachability links if ( !areanum || !AAS_AreaReachability( areanum ) ) { //use the last valid area the bot was in areanum = gs->lastreachabilityarea; } //end if //remember the last area with reachabilities the bot was in gs->lastreachabilityarea = areanum; //if still in solid if ( !areanum ) { return qfalse; } // if ( ltg ) { ltg_time = AAS_AreaTravelTimeToGoalArea( areanum, origin, ltg->areanum, travelflags ); } else { ltg_time = 99999;} //the item configuration ic = itemconfig; if ( !itemconfig ) { return qfalse; } //best weight and item so far bestweight = 0; bestitem = NULL; memset( &goal, 0, sizeof( bot_goal_t ) ); //go through the items in the level for ( li = levelitems; li; li = li->next ) { if ( g_gametype == GT_SINGLE_PLAYER ) { if ( li->notsingle ) { continue; } } else if ( g_gametype >= GT_TEAM ) { if ( li->notteam ) { continue; } } else { if ( li->notfree ) { continue; } } //if the item is in a possible goal area if ( !li->goalareanum ) { continue; } //get the fuzzy weight function for this item iteminfo = &ic->iteminfo[li->iteminfo]; weightnum = gs->itemweightindex[iteminfo->number]; if ( weightnum < 0 ) { continue; } //if this goal is in the avoid goals if ( BotAvoidGoalTime( goalstate, li->number ) > 0 ) { continue; } // #ifdef UNDECIDEDFUZZY weight = FuzzyWeightUndecided( inventory, gs->itemweightconfig, weightnum ); #else weight = FuzzyWeight( inventory, gs->itemweightconfig, weightnum ); #endif //UNDECIDEDFUZZY #ifdef DROPPEDWEIGHT //HACK: to make dropped items more attractive if ( li->timeout ) { weight += 1000; } #endif //DROPPEDWEIGHT if ( weight > 0 ) { //get the travel time towards the goal area t = AAS_AreaTravelTimeToGoalArea( areanum, origin, li->goalareanum, travelflags ); //if the goal is reachable if ( t > 0 && t < maxtime ) { weight /= (float) t * TRAVELTIME_SCALE; // if ( weight > bestweight ) { t = 0; if ( ltg && !li->timeout ) { //get the travel time from the goal to the long term goal t = AAS_AreaTravelTimeToGoalArea( li->goalareanum, li->goalorigin, ltg->areanum, travelflags ); } //end if //if the travel back is possible and doesn't take too long if ( t <= ltg_time ) { bestweight = weight; bestitem = li; } //end if } //end if } //end if } //end if } //end for //if no goal item found if ( !bestitem ) { return qfalse; } //create a bot goal for this item iteminfo = &ic->iteminfo[bestitem->iteminfo]; VectorCopy( bestitem->goalorigin, goal.origin ); VectorCopy( iteminfo->mins, goal.mins ); VectorCopy( iteminfo->maxs, goal.maxs ); goal.areanum = bestitem->goalareanum; goal.entitynum = bestitem->entitynum; goal.number = bestitem->number; goal.flags = GFL_ITEM; goal.iteminfo = bestitem->iteminfo; //add the chosen goal to the goals to avoid for a while avoidtime = iteminfo->respawntime * 0.5; if ( avoidtime < 10 ) { avoidtime = AVOID_TIME; } //if it's a dropped item if ( bestitem->timeout ) { avoidtime = AVOIDDROPPED_TIME; } BotAddToAvoidGoals( gs, bestitem->number, avoidtime ); //push the goal on the stack BotPushGoal( goalstate, &goal ); // #ifdef DEBUG_AI_GOAL if ( bestitem->timeout ) { botimport.Print( PRT_MESSAGE, "new nbg dropped item %s\n", ic->iteminfo[bestitem->iteminfo].classname ); } //end if iteminfo = &ic->iteminfo[bestitem->iteminfo]; botimport.Print( PRT_MESSAGE, "new nbg \"%s\"\n", iteminfo->classname ); #endif //DEBUG_AI_GOAL return qtrue; } //end of the function BotChooseNBGItem