Performance improvement

This commit is contained in:
RGreenlees 2024-03-13 23:29:09 +00:00 committed by pierow
parent b6ac4431ed
commit 1c78990e2a
8 changed files with 304 additions and 89 deletions

View file

@ -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; }

View file

@ -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;

View file

@ -42,6 +42,8 @@ vector<AvHAIOffMeshConnection> 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<NavHint> 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<NavHint*> NAV_GetHintsOfType(unsigned int HintType, bool bUnoccupiedOnly)
{
vector<NavHint*> 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<NavHint*> NAV_GetHintsOfTypeInRadius(unsigned int HintType, Vector SearchLocation, float Radius, bool bUnoccupiedOnly)
{
vector<NavHint*> 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;
}

View file

@ -498,5 +498,8 @@ void NAV_ClearMovementTask(AvHAIPlayer* pBot);
void NAV_ProgressMovementTask(AvHAIPlayer* pBot);
bool NAV_IsMovementTaskStillValid(AvHAIPlayer* pBot);
vector<NavHint*> NAV_GetHintsOfType(unsigned int HintType, bool bUnoccupiedOnly = false);
vector<NavHint*> NAV_GetHintsOfTypeInRadius(unsigned int HintType, Vector SearchLocation, float Radius, bool bUnoccupiedOnly = false);
#endif // BOT_NAVIGATION_H

View file

@ -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)

View file

@ -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<NavHint*> 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<NavHint*> 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<NavHint*> 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;
}

View file

@ -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();

View file

@ -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)
{