From 1c78990e2a383529ca2e88a34c1cbe225b2d1b81 Mon Sep 17 00:00:00 2001 From: RGreenlees Date: Wed, 13 Mar 2024 23:29:09 +0000 Subject: [PATCH] Performance improvement --- main/source/mod/AIPlayers/AvHAICommander.cpp | 183 +++++++++++------- main/source/mod/AIPlayers/AvHAIConstants.h | 14 ++ main/source/mod/AIPlayers/AvHAINavigation.cpp | 124 +++++++++++- main/source/mod/AIPlayers/AvHAINavigation.h | 3 + .../source/mod/AIPlayers/AvHAIPlayerManager.h | 2 +- main/source/mod/AIPlayers/AvHAITactical.cpp | 53 ++++- main/source/mod/AIPlayers/AvHAITactical.h | 2 + main/source/mod/AIPlayers/AvHAITask.cpp | 12 +- 8 files changed, 304 insertions(+), 89 deletions(-) diff --git a/main/source/mod/AIPlayers/AvHAICommander.cpp b/main/source/mod/AIPlayers/AvHAICommander.cpp index cbef2a9c..ec370877 100644 --- a/main/source/mod/AIPlayers/AvHAICommander.cpp +++ b/main/source/mod/AIPlayers/AvHAICommander.cpp @@ -958,35 +958,43 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot) if (!BaseArmoury && !FNullEnt(BaseBuilder)) { - - StructureFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL; - - AvHAIBuildableStructure* NearestInfantryPortal = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter); - - Vector BuildLocation = ZERO_VECTOR; - + Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_ARMOURY, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + + bool bFoundLocation = !vIsZero(BuildLocation); bool bSuccess = false; - bool bFoundLocation = false; - if (NearestInfantryPortal) + if (bFoundLocation) { - BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestInfantryPortal->Location, UTIL_MetresToGoldSrcUnits(5.0f)); - - if (!vIsZero(BuildLocation)) - { - bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation); - bFoundLocation = true; - } + bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation); } if (!bSuccess) { - BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + StructureFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL; - if (!vIsZero(BuildLocation)) + AvHAIBuildableStructure* NearestInfantryPortal = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter); + + + if (NearestInfantryPortal) { - bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation); - bFoundLocation = true; + BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestInfantryPortal->Location, UTIL_MetresToGoldSrcUnits(5.0f)); + + if (!vIsZero(BuildLocation)) + { + bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation); + bFoundLocation = true; + } + } + + if (!bSuccess) + { + BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + + if (!vIsZero(BuildLocation)) + { + bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation); + bFoundLocation = true; + } } } @@ -1022,7 +1030,13 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot) if (!bPhaseNearBase && !FNullEnt(BaseBuilder)) { - Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + + Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_PHASEGATE, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + + if (vIsZero(BuildLocation)) + { + BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + } if (!vIsZero(BuildLocation)) { @@ -1059,7 +1073,12 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot) if (!bHasArmsLab && !FNullEnt(BaseBuilder)) { - Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_ARMSLAB, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(15.0f)); + + if (vIsZero(BuildLocation)) + { + BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + } if (!vIsZero(BuildLocation)) { @@ -1076,7 +1095,12 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot) if (!bHasObservatory && !FNullEnt(BaseBuilder)) { - Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_OBSERVATORY, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(15.0f)); + + if (vIsZero(BuildLocation)) + { + BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f)); + } if (!vIsZero(BuildLocation)) { @@ -1137,7 +1161,12 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot) if (!bHasPrototypeLab && bHasAdvArmoury && !FNullEnt(BaseBuilder)) { - Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseArmoury->Location, UTIL_MetresToGoldSrcUnits(3.0f), UTIL_MetresToGoldSrcUnits(5.0f)); + Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_PROTOTYPELAB, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(15.0f)); + + if (vIsZero(BuildLocation)) + { + BuildLocation = UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseArmoury->Location, UTIL_MetresToGoldSrcUnits(3.0f), UTIL_MetresToGoldSrcUnits(5.0f)); + } if (vIsZero(BuildLocation)) { @@ -2033,66 +2062,70 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair) { if (FNullEnt(CommChair) || !UTIL_StructureIsFullyBuilt(CommChair)) { return false; } - Vector BuildLocation = ZERO_VECTOR; + Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_INFANTRYPORTAL, CommChair->v.origin, BALANCE_VAR(kCommandStationBuildDistance)); - DeployableSearchFilter ExistingPortalFilter; - ExistingPortalFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL; - ExistingPortalFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f); - ExistingPortalFilter.DeployableTeam = pBot->Player->GetTeam(); - ExistingPortalFilter.ReachabilityFlags = AI_REACHABILITY_MARINE; - ExistingPortalFilter.ReachabilityTeam = pBot->Player->GetTeam(); - - AvHAIBuildableStructure* ExistingInfantryPortal = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &ExistingPortalFilter); - - // First see if we can place the next infantry portal next to the first one - if (ExistingInfantryPortal) + if (vIsZero(BuildLocation)) { - BuildLocation = UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), ExistingInfantryPortal->edict->v.origin, UTIL_MetresToGoldSrcUnits(2.0f), UTIL_MetresToGoldSrcUnits(3.0f)); + + DeployableSearchFilter ExistingPortalFilter; + ExistingPortalFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL; + ExistingPortalFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f); + ExistingPortalFilter.DeployableTeam = pBot->Player->GetTeam(); + ExistingPortalFilter.ReachabilityFlags = AI_REACHABILITY_MARINE; + ExistingPortalFilter.ReachabilityTeam = pBot->Player->GetTeam(); - if (!vIsZero(BuildLocation)) + AvHAIBuildableStructure* ExistingInfantryPortal = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &ExistingPortalFilter); + + // First see if we can place the next infantry portal next to the first one + if (ExistingInfantryPortal) { - bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation); + BuildLocation = UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), ExistingInfantryPortal->edict->v.origin, UTIL_MetresToGoldSrcUnits(2.0f), UTIL_MetresToGoldSrcUnits(3.0f)); - if (bSuccess) { return true; } - } - } + if (!vIsZero(BuildLocation)) + { + bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation); - Vector SearchPoint = ZERO_VECTOR; - - DeployableSearchFilter ResNodeFilter; - ResNodeFilter.ReachabilityFlags = AI_REACHABILITY_MARINE; - ResNodeFilter.ReachabilityTeam = pBot->Player->GetTeam(); - - const AvHAIResourceNode* ResNode = AITAC_FindNearestResourceNodeToLocation(CommChair->v.origin, &ResNodeFilter); - - if (ResNode) - { - SearchPoint = ResNode->Location; - } - else - { - return false; - } - - Vector NearestPointToChair = FindClosestNavigablePointToDestination(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), SearchPoint, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); - - if (!vIsZero(NearestPointToChair)) - { - float Distance = vDist2D(NearestPointToChair, CommChair->v.origin); - float RandomDist = UTIL_MetresToGoldSrcUnits(5.0f) - Distance; - - BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestPointToChair, RandomDist); - - if (!vIsZero(BuildLocation)) - { - bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation); - - if (bSuccess) { return true; } + if (bSuccess) { return true; } + } } + Vector SearchPoint = ZERO_VECTOR; + + DeployableSearchFilter ResNodeFilter; + ResNodeFilter.ReachabilityFlags = AI_REACHABILITY_MARINE; + ResNodeFilter.ReachabilityTeam = pBot->Player->GetTeam(); + + const AvHAIResourceNode* ResNode = AITAC_FindNearestResourceNodeToLocation(CommChair->v.origin, &ResNodeFilter); + + if (ResNode) + { + SearchPoint = ResNode->Location; + } + else + { + return false; + } + + Vector NearestPointToChair = FindClosestNavigablePointToDestination(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), SearchPoint, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); + + if (!vIsZero(NearestPointToChair)) + { + float Distance = vDist2D(NearestPointToChair, CommChair->v.origin); + float RandomDist = UTIL_MetresToGoldSrcUnits(5.0f) - Distance; + + BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestPointToChair, RandomDist); + + if (!vIsZero(BuildLocation)) + { + bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation); + + if (bSuccess) { return true; } + } + + } + + BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); } - - BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); if (vIsZero(BuildLocation)) { return false; } diff --git a/main/source/mod/AIPlayers/AvHAIConstants.h b/main/source/mod/AIPlayers/AvHAIConstants.h index 5956af0e..8d5a5948 100644 --- a/main/source/mod/AIPlayers/AvHAIConstants.h +++ b/main/source/mod/AIPlayers/AvHAIConstants.h @@ -274,6 +274,20 @@ typedef struct _NAV_PROFILE AvHAIReachabilityStatus ReachabilityFlag = AI_REACHABILITY_NONE; } nav_profile; +typedef struct _LOAD_NAV_HINT +{ + unsigned int id = 0; + unsigned int hintType = 0; + float position[3] = { 0.0f, 0.0f, 0.0f }; +} LoadNavHint; + +typedef struct _NAV_HINT +{ + unsigned int hintType = 0; + Vector Position = g_vecZero; + edict_t* OccupyingBuilding = nullptr; +} NavHint; + typedef struct _DEPLOYABLE_SEARCH_FILTER { unsigned int DeployableTypes = SEARCH_ALL_STRUCTURES; diff --git a/main/source/mod/AIPlayers/AvHAINavigation.cpp b/main/source/mod/AIPlayers/AvHAINavigation.cpp index 9481eb03..4f70c346 100644 --- a/main/source/mod/AIPlayers/AvHAINavigation.cpp +++ b/main/source/mod/AIPlayers/AvHAINavigation.cpp @@ -42,6 +42,8 @@ vector BaseMapConnections; nav_mesh NavMeshes[MAX_NAV_MESHES] = { }; // Array of nav meshes. Currently only 3 are used (building, onos, and regular) nav_profile BaseNavProfiles[MAX_NAV_PROFILES] = { }; // Array of nav profiles +vector MapNavHints; + extern bool bNavMeshModified; bool bTileCacheUpToDate = false; @@ -106,6 +108,9 @@ struct TileCacheBuildHeader int NumConvexVols; int ConvexVolOffset; + + int NumNavHints; + int NavHintOffset; }; struct TileCacheTileHeader @@ -800,6 +805,7 @@ void UnloadNavMeshes() } BaseMapConnections.clear(); + MapNavHints.clear(); } void UnloadNavigationData() @@ -819,6 +825,7 @@ bool LoadNavMesh(const char* mapname) { memset(NavMeshes, 0, sizeof(NavMeshes)); BaseMapConnections.clear(); + MapNavHints.clear(); char filename[256]; // Full path to BSP file @@ -1043,6 +1050,21 @@ bool LoadNavMesh(const char* mapname) BaseMapConnections.push_back(NewMapConnection); } + fseek(savedFile, header.NavHintOffset, SEEK_SET); + + for (int i = 0; i < header.NumNavHints; i++) + { + LoadNavHint LoadedHint; + fread(&LoadedHint, sizeof(LoadNavHint), 1, savedFile); + + NavHint NewHint; + NewHint.hintType = LoadedHint.hintType; + NewHint.Position = Vector(LoadedHint.position[0], -LoadedHint.position[2], LoadedHint.position[1]); + NewHint.OccupyingBuilding = nullptr; + + MapNavHints.push_back(NewHint); + } + fclose(savedFile); for (int i = 0; i <= BUILDING_NAV_MESH; i++) @@ -7511,6 +7533,8 @@ void UTIL_UpdateDoors(bool bInitial) nav_door* NavDoor = &(*it); DoorActivationType PrevType = it->ActivationType; + const char* DoorName = STRING(NavDoor->DoorEdict->v.targetname); + UTIL_UpdateDoorTriggers(NavDoor); CBaseToggle* DoorRef = it->DoorEntity; @@ -7596,7 +7620,25 @@ void UTIL_UpdateDoors(bool bInitial) } - UTIL_ApplyTempObstaclesToDoor(NavDoor, DT_TILECACHE_NULL_AREA); + Vector DoorCentre = UTIL_GetCentreOfEntity(it->DoorEdict); + + dtNavMeshQuery* Query = NavMeshes[BUILDING_NAV_MESH].navQuery; + nav_profile StructureProfile = GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE); + + dtPolyRef Polys[8]; + int polyCount; + + float DoorHalfExtents[3] = { it->DoorEdict->v.size.x, it->DoorEdict->v.size.z, it->DoorEdict->v.size.y }; + float DoorCentreFlt[3] = { DoorCentre.x, DoorCentre.z, -DoorCentre.y }; + + Query->queryPolygons(DoorCentreFlt, DoorHalfExtents, &StructureProfile.Filters, Polys, &polyCount, 8); + + if (polyCount > 0) + { + UTIL_ApplyTempObstaclesToDoor(NavDoor, DT_TILECACHE_NULL_AREA); + } + + } else if (it->ActivationType == DOOR_WELD) { @@ -7644,11 +7686,44 @@ void UTIL_UpdateDoors(bool bInitial) } - UTIL_ApplyTempObstaclesToDoor(NavDoor, DT_TILECACHE_WELD_AREA); + Vector DoorCentre = UTIL_GetCentreOfEntity(it->DoorEdict); + + dtNavMeshQuery* Query = NavMeshes[BUILDING_NAV_MESH].navQuery; + nav_profile StructureProfile = GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE); + + dtPolyRef Polys[8]; + int polyCount; + + float DoorHalfExtents[3] = {it->DoorEdict->v.size.x, it->DoorEdict->v.size.z, it->DoorEdict->v.size.y}; + float DoorCentreFlt[3] = { DoorCentre.x, DoorCentre.z, -DoorCentre.y }; + + Query->queryPolygons(DoorCentreFlt, DoorHalfExtents, &StructureProfile.Filters, Polys, &polyCount, 8); + + if (polyCount > 0) + { + UTIL_ApplyTempObstaclesToDoor(NavDoor, DT_TILECACHE_WELD_AREA); + } + } else { - UTIL_ApplyTempObstaclesToDoor(NavDoor, DT_TILECACHE_DOOR_AREA); + Vector DoorCentre = UTIL_GetCentreOfEntity(it->DoorEdict); + + dtNavMeshQuery* Query = NavMeshes[BUILDING_NAV_MESH].navQuery; + nav_profile StructureProfile = GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE); + + dtPolyRef Polys[8]; + int polyCount; + + float DoorHalfExtents[3] = { it->DoorEdict->v.size.x, it->DoorEdict->v.size.z, it->DoorEdict->v.size.y }; + float DoorCentreFlt[3] = { DoorCentre.x, DoorCentre.z, -DoorCentre.y }; + + Query->queryPolygons(DoorCentreFlt, DoorHalfExtents, &StructureProfile.Filters, Polys, &polyCount, 8); + + if (polyCount > 0) + { + UTIL_ApplyTempObstaclesToDoor(NavDoor, DT_TILECACHE_DOOR_AREA); + } } it->CurrentState = DoorRef->m_toggle_state; @@ -8463,4 +8538,47 @@ void NAV_SetPickupMovementTask(AvHAIPlayer* pBot, edict_t* ThingToPickup, DoorTr MoveTask->TaskTarget = ThingToPickup; MoveTask->TriggerToActivate = TriggerToActivate; MoveTask->TaskLocation = ThingToPickup->v.origin; +} + +vector NAV_GetHintsOfType(unsigned int HintType, bool bUnoccupiedOnly) +{ + vector Result; + + Result.clear(); + + for (auto it = MapNavHints.begin(); it != MapNavHints.end(); it++) + { + if (HintType != STRUCTURE_NONE && !(it->hintType & HintType)) { continue; } + + if (bUnoccupiedOnly && !FNullEnt(it->OccupyingBuilding)) { continue; } + + Result.push_back(&(*it)); + } + + return Result; + +} + +vector NAV_GetHintsOfTypeInRadius(unsigned int HintType, Vector SearchLocation, float Radius, bool bUnoccupiedOnly) +{ + vector Result; + + Result.clear(); + + float SearchRadius = sqrf(Radius); + + for (auto it = MapNavHints.begin(); it != MapNavHints.end(); it++) + { + if (HintType != STRUCTURE_NONE && !(it->hintType & HintType)) { continue; } + + if (bUnoccupiedOnly && !FNullEnt(it->OccupyingBuilding)) { continue; } + + if (vDist3DSq(it->Position, SearchLocation) < SearchRadius) + { + Result.push_back(&(*it)); + } + } + + return Result; + } \ No newline at end of file diff --git a/main/source/mod/AIPlayers/AvHAINavigation.h b/main/source/mod/AIPlayers/AvHAINavigation.h index 37b0f4e5..29cc1974 100644 --- a/main/source/mod/AIPlayers/AvHAINavigation.h +++ b/main/source/mod/AIPlayers/AvHAINavigation.h @@ -498,5 +498,8 @@ void NAV_ClearMovementTask(AvHAIPlayer* pBot); void NAV_ProgressMovementTask(AvHAIPlayer* pBot); bool NAV_IsMovementTaskStillValid(AvHAIPlayer* pBot); +vector NAV_GetHintsOfType(unsigned int HintType, bool bUnoccupiedOnly = false); +vector NAV_GetHintsOfTypeInRadius(unsigned int HintType, Vector SearchLocation, float Radius, bool bUnoccupiedOnly = false); + #endif // BOT_NAVIGATION_H diff --git a/main/source/mod/AIPlayers/AvHAIPlayerManager.h b/main/source/mod/AIPlayers/AvHAIPlayerManager.h index 52525c06..fb2c8b84 100644 --- a/main/source/mod/AIPlayers/AvHAIPlayerManager.h +++ b/main/source/mod/AIPlayers/AvHAIPlayerManager.h @@ -5,7 +5,7 @@ #include "AvHAIPlayer.h" // Max rate bot can run its logic, default is 1/60th second. WARNING: Increasing the rate past 100hz causes bots to move and turn slowly due to GoldSrc limits! -static const double BOT_MIN_FRAME_TIME = 0;// (1.0 / 60.0); +static const double BOT_MIN_FRAME_TIME = (1.0 / 100.0); // Once the first human player has joined the game, how long to wait before adding bots static const float AI_GRACE_PERIOD = 5.0f; // Max time to wait before spawning players if none connect (e.g. empty dedicated server) diff --git a/main/source/mod/AIPlayers/AvHAITactical.cpp b/main/source/mod/AIPlayers/AvHAITactical.cpp index c7e1cfa7..751dbce5 100644 --- a/main/source/mod/AIPlayers/AvHAITactical.cpp +++ b/main/source/mod/AIPlayers/AvHAITactical.cpp @@ -811,7 +811,7 @@ void AITAC_RefreshHiveData() it->NextFloorLocationCheck = gpGlobals->time + (5.0f + (0.1f * NextRefresh)); - AITAC_RefreshReachabilityForHive(&(*it)); + //AITAC_RefreshReachabilityForHive(&(*it)); } NextRefresh++; @@ -1398,7 +1398,7 @@ void AITAC_RefreshResourceNodes() if (it->NextReachabilityRefreshTime == 0.0f) { - it->NextReachabilityRefreshTime = gpGlobals->time + 1.0f; + it->NextReachabilityRefreshTime = gpGlobals->time + frandrange(0.5f, 1.5f); } else { @@ -1509,8 +1509,6 @@ void AITAC_CheckNavMeshModified() void AITAC_OnNavMeshModified() { - TeamAStartingLocation = ZERO_VECTOR; - TeamBStartingLocation = ZERO_VECTOR; for (auto it = TeamAStructureMap.begin(); it != TeamAStructureMap.end(); it++) { @@ -2172,6 +2170,18 @@ void AITAC_OnStructureCreated(AvHAIBuildableStructure* NewStructure) AITAC_RefreshReachabilityForStructure(NewStructure); + vector NavHints = NAV_GetHintsOfType(STRUCTURE_NONE); + + for (auto it = NavHints.begin(); it != NavHints.end(); it++) + { + NavHint* ThisHint = (*it); + + if (vDist2DSq(NewStructure->edict->v.origin, ThisHint->Position) < sqrf(32.0f) && fabsf(NewStructure->Location.z - ThisHint->Position.z) < 50.0f) + { + ThisHint->OccupyingBuilding = NewStructure->edict; + } + } + if (StructureTeam == TEAM_IND) { return; } AvHTeam* Team = GetGameRules()->GetTeam(StructureTeam); @@ -2320,6 +2330,18 @@ void AITAC_OnStructureDestroyed(AvHAIBuildableStructure* DestroyedStructure) AITAC_GetTeamStartingLocation(Team); // Force refresh of reachabilities and team starting locations } + + vector NavHints = NAV_GetHintsOfType(DestroyedStructure->StructureType); + + for (auto it = NavHints.begin(); it != NavHints.end(); it++) + { + NavHint* ThisHint = (*it); + + if (ThisHint->OccupyingBuilding == DestroyedStructure->edict) + { + ThisHint->OccupyingBuilding = nullptr; + } + } } void AITAC_LinkStructureToPlayer(AvHAIBuildableStructure* NewStructure) @@ -4952,4 +4974,27 @@ bool AITAC_IsStructureOfTypeNearLocation(AvHTeamNumber Team, unsigned int Struct SearchFilter.MaxSearchRadius = SearchRadius; return AITAC_DeployableExistsAtLocation(SearchLocation, &SearchFilter); +} + +Vector AITAC_GetRandomBuildHintInLocation(const unsigned int StructureType, const Vector SearchLocation, const float SearchRadius) +{ + Vector Result = ZERO_VECTOR; + + vector IPHints = NAV_GetHintsOfTypeInRadius(StructureType, SearchLocation, SearchRadius, true); + int WinningRoll = 0; + + for (auto it = IPHints.begin(); it != IPHints.end(); it++) + { + NavHint* ThisHint = (*it); + + int ThisRoll = irandrange(0, 10); + + if (vIsZero(Result) || ThisRoll > WinningRoll) + { + Result = ThisHint->Position; + WinningRoll = ThisRoll; + } + } + + return Result; } \ No newline at end of file diff --git a/main/source/mod/AIPlayers/AvHAITactical.h b/main/source/mod/AIPlayers/AvHAITactical.h index e1bba918..1d3d9fc1 100644 --- a/main/source/mod/AIPlayers/AvHAITactical.h +++ b/main/source/mod/AIPlayers/AvHAITactical.h @@ -67,6 +67,8 @@ int AITAC_GetNumItemsInLocation(const Vector& Location, const AvHAIDeploya AvHAIDroppedItem* AITAC_GetDroppedItemRefFromEdict(edict_t* ItemEdict); +Vector AITAC_GetRandomBuildHintInLocation(const unsigned int StructureType, const Vector SearchLocation, const float SearchRadius); + Vector AITAC_GetFloorLocationForHive(const AvHAIHiveDefinition* Hive); int AITAC_GetNumHives(); diff --git a/main/source/mod/AIPlayers/AvHAITask.cpp b/main/source/mod/AIPlayers/AvHAITask.cpp index 73eda79a..68150951 100644 --- a/main/source/mod/AIPlayers/AvHAITask.cpp +++ b/main/source/mod/AIPlayers/AvHAITask.cpp @@ -1807,11 +1807,11 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task) { if ((gpGlobals->time - Task->TaskStartedTime) > 1.0f) { - Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); + Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); if (vIsZero(Task->TaskLocation)) { - Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); + Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f)); } Task->TaskStartedTime = 0.0f; @@ -1819,7 +1819,7 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task) return; } - if (Task->TaskLocation != g_vecZero) + if (!vIsZero(Task->TaskLocation)) { if (vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation) > sqrf(32.0f)) @@ -1842,14 +1842,14 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task) } else { - if (vDist2DSq(pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget)) > sqrf(UTIL_MetresToGoldSrcUnits(10.0f)) || UTIL_GetNavAreaAtLocation(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin) != SAMPLE_POLYAREA_GROUND) + if (vDist2DSq(pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget)) > sqrf(UTIL_MetresToGoldSrcUnits(10.0f)) || UTIL_GetNavAreaAtLocation(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], pBot->Edict->v.origin) != SAMPLE_POLYAREA_GROUND) { MoveTo(pBot, UTIL_GetEntityGroundLocation(Task->TaskTarget), MOVESTYLE_NORMAL); return; } else { - Task->TaskLocation = FindClosestNavigablePointToDestination(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget), UTIL_MetresToGoldSrcUnits(10.0f)); + Task->TaskLocation = FindClosestNavigablePointToDestination(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_GetEntityGroundLocation(Task->TaskTarget), UTIL_MetresToGoldSrcUnits(10.0f)); if (vIsZero(Task->TaskLocation)) { @@ -1858,7 +1858,7 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task) if (Task->TaskLocation != g_vecZero) { - Vector FinalEvolveLoc = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(5.0f)); + Vector FinalEvolveLoc = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[ONOS_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(5.0f)); if (FinalEvolveLoc != g_vecZero) {