static int FindGoalAASArea(edict_t *ent) { AiAasWorld *aasWorld = AiAasWorld::Instance(); if (!aasWorld->IsLoaded()) return 0; Vec3 mins(ent->r.mins), maxs(ent->r.maxs); // Extend AABB XY dimensions ExtendDimension(mins.Data(), maxs.Data(), 0); ExtendDimension(mins.Data(), maxs.Data(), 1); // Z needs special extension rules float presentHeight = maxs.Z() - mins.Z(); float playerHeight = playerbox_stand_maxs[2] - playerbox_stand_mins[2]; if (playerHeight > presentHeight) maxs.Z() += playerHeight - presentHeight; // Find all areas in bounds int areas[16]; // Convert bounds to absolute ones mins += ent->s.origin; maxs += ent->s.origin; const int numAreas = aasWorld->BBoxAreas(mins, maxs, areas, 16); // Find hub areas (or use cached) FindHubAreas(); int bestArea = 0; int bestAreaReachCount = 0; AiAasRouteCache *routeCache = AiAasRouteCache::Shared(); for (int i = 0; i < numAreas; ++i) { const int areaNum = areas[i]; int areaReachCount = 0; for (const int hubAreaNum: hubAreas) { const aas_area_t &hubArea = aasWorld->Areas()[hubAreaNum]; Vec3 hubAreaPoint(hubArea.center); hubAreaPoint.Z() = hubArea.mins[2] + std::min(24.0f, hubArea.maxs[2] - hubArea.mins[2]); // Do not waste pathfinder cycles testing for preferred flags that may fail. constexpr int travelFlags = Bot::ALLOWED_TRAVEL_FLAGS; if (routeCache->ReachabilityToGoalArea(hubAreaNum, hubAreaPoint.Data(), areaNum, travelFlags)) { areaReachCount++; // Thats't enough, do not waste CPU cycles if (areaReachCount == 4) return areaNum; } } if (areaReachCount > bestAreaReachCount) { bestArea = areaNum; bestAreaReachCount = areaReachCount; } } if (bestArea) return bestArea; // Fall back to a default method and hope it succeeds return aasWorld->FindAreaNum(ent); }