mirror of
https://github.com/ENSL/NS.git
synced 2025-03-14 06:34:33 +00:00
Bug fixing with navigation
This commit is contained in:
parent
f6982dbc0d
commit
451810e07b
11 changed files with 175 additions and 37 deletions
|
@ -154,6 +154,7 @@ dtStatus dtTileCache::init(const dtTileCacheParams* params,
|
|||
{
|
||||
m_offMeshConnections[i].salt = 1;
|
||||
m_offMeshConnections[i].next = m_nextFreeOffMeshConnection;
|
||||
m_offMeshConnections[i].userId = i;
|
||||
m_nextFreeOffMeshConnection = &m_offMeshConnections[i];
|
||||
}
|
||||
|
||||
|
@ -405,7 +406,9 @@ dtStatus dtTileCache::addOffMeshConnection(const float* spos, const float* epos,
|
|||
return DT_FAILURE | DT_OUT_OF_MEMORY;
|
||||
|
||||
unsigned short salt = con->salt;
|
||||
unsigned int userId = con->userId;
|
||||
memset(con, 0, sizeof(dtOffMeshConnection));
|
||||
con->userId = userId;
|
||||
con->salt = salt;
|
||||
con->state = DT_OFFMESH_NEW;
|
||||
dtVcopy(&con->pos[0], spos);
|
||||
|
@ -420,8 +423,6 @@ dtStatus dtTileCache::addOffMeshConnection(const float* spos, const float* epos,
|
|||
req->action = REQUEST_OFFMESH_ADD;
|
||||
req->ref = getOffMeshRef(con);
|
||||
|
||||
con->userId = req->ref;
|
||||
|
||||
if (result)
|
||||
*result = req->ref;
|
||||
|
||||
|
@ -676,6 +677,7 @@ dtStatus dtTileCache::update(const float /*dt*/, dtNavMesh* navmesh,
|
|||
if ((int)idx >= m_params.maxOffMeshConnections)
|
||||
continue;
|
||||
dtOffMeshConnection* con = &m_offMeshConnections[idx];
|
||||
con->userId = idx;
|
||||
unsigned int salt = decodeOffMeshIdSalt(req->ref);
|
||||
if (con->salt != salt)
|
||||
continue;
|
||||
|
@ -749,6 +751,10 @@ dtStatus dtTileCache::update(const float /*dt*/, dtNavMesh* navmesh,
|
|||
m_update[m_nupdate++] = TileRef;
|
||||
}
|
||||
}
|
||||
else if (req->action == REQUEST_OFFMESH_REFRESH)
|
||||
{
|
||||
con->state = DT_OFFMESH_DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
m_nOffMeshReqs = 0;
|
||||
|
|
|
@ -306,7 +306,7 @@ private:
|
|||
OffMeshRequest m_OffMeshReqs[MAX_REQUESTS];
|
||||
int m_nOffMeshReqs;
|
||||
|
||||
static const int MAX_UPDATE = 64;
|
||||
static const int MAX_UPDATE = 256;
|
||||
dtCompressedTileRef m_update[MAX_UPDATE];
|
||||
int m_nupdate;
|
||||
};
|
||||
|
|
|
@ -16,11 +16,18 @@ bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureTyp
|
|||
{
|
||||
if (vIsZero(Location)) { return false; }
|
||||
|
||||
nav_profile WelderProfile = GetBaseNavProfile(MARINE_BASE_NAV_PROFILE);
|
||||
WelderProfile.Filters.addIncludeFlags(SAMPLE_POLYFLAGS_WELD);
|
||||
|
||||
// Don't allow the commander to place a structure somewhere unreachable to marines
|
||||
if (!UTIL_PointIsReachable(WelderProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), Location, max_player_use_reach)) { return false; }
|
||||
|
||||
AvHMessageID StructureID = UTIL_StructureTypeToImpulseCommand(StructureToDeploy);
|
||||
|
||||
Vector BuildLocation = Location;
|
||||
BuildLocation.z += 4.0f;
|
||||
|
||||
// This would be rejected if a human was trying to build here, so don't let the bot do it
|
||||
if (!AvHSHUGetIsSiteValidForBuild(StructureID, &BuildLocation)) { return false; }
|
||||
|
||||
string theErrorMessage;
|
||||
|
@ -358,6 +365,8 @@ bool AICOMM_IsOrderStillValid(AvHAIPlayer* pBot, ai_commander_order* Order)
|
|||
break;
|
||||
case ORDERPURPOSE_SECURE_RESNODE:
|
||||
{
|
||||
if (!AICOMM_ShouldCommanderPrioritiseNodes(pBot)) { return false; }
|
||||
|
||||
const AvHAIResourceNode* ResNode = AITAC_GetResourceNodeFromEdict(Order->OrderTarget);
|
||||
|
||||
if (!ResNode) { return false; }
|
||||
|
@ -408,6 +417,8 @@ bool AICOMM_ShouldCommanderPrioritiseNodes(AvHAIPlayer* pBot)
|
|||
int NumEligibleNodes = 0;
|
||||
int NumFreeNodes = 0;
|
||||
|
||||
|
||||
|
||||
// First get ours and the enemy's ownership of all eligible nodes (we can reach them, and they're in the enemy base)
|
||||
vector<AvHAIResourceNode*> AllNodes = AITAC_GetAllReachableResourceNodes(BotTeam);
|
||||
|
||||
|
@ -428,11 +439,13 @@ bool AICOMM_ShouldCommanderPrioritiseNodes(AvHAIPlayer* pBot)
|
|||
if (ThisNode->OwningTeam == BotTeam) { NumOwnedNodes++; }
|
||||
}
|
||||
|
||||
int NumDesiredNodes = imini(4, (int)ceilf((float)NumEligibleNodes * 0.5f));
|
||||
|
||||
int NumNodesLeft = NumEligibleNodes - NumOwnedNodes;
|
||||
|
||||
if (NumNodesLeft == 0) { return false; }
|
||||
|
||||
return NumOwnedNodes < 3 || NumFreeNodes > 3;
|
||||
return NumOwnedNodes < NumDesiredNodes || NumFreeNodes > 1;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1076,6 +1089,11 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
{
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseArmoury->Location, UTIL_MetresToGoldSrcUnits(3.0f), UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (vIsZero(BuildLocation))
|
||||
{
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
}
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
if (AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation))
|
||||
|
|
|
@ -258,7 +258,7 @@ typedef struct _HIVE_DEFINITION_T
|
|||
AvHTeamNumber OwningTeam = TEAM_IND; // Which team owns this hive currently (TEAM_IND if empty)
|
||||
unsigned int TeamAReachabilityFlags = AI_REACHABILITY_NONE; // Who on team A can reach this node?
|
||||
unsigned int TeamBReachabilityFlags = AI_REACHABILITY_NONE; // Who on team B can reach this node?
|
||||
|
||||
char HiveName[64];
|
||||
} AvHAIHiveDefinition;
|
||||
|
||||
// A nav profile combines a nav mesh reference (indexed into NavMeshes) and filters to determine how a bot should find paths
|
||||
|
@ -542,6 +542,7 @@ typedef struct _AVH_AI_STUCK_TRACKER
|
|||
Vector LastBotPosition = g_vecZero;
|
||||
Vector MoveDestination = g_vecZero;
|
||||
float TotalStuckTime = 0.0f; // Total time the bot has spent stuck
|
||||
bool bPathFollowFailed = false;
|
||||
|
||||
} AvHAIPlayerStuckTracker;
|
||||
|
||||
|
@ -549,7 +550,7 @@ typedef struct _AVH_AI_STUCK_TRACKER
|
|||
typedef struct _NAV_STATUS
|
||||
{
|
||||
vector<bot_path_node> CurrentPath; // Bot's path nodes
|
||||
vector<bot_path_node>::iterator CurrentPathPoint;
|
||||
vector<bot_path_node>::iterator CurrentPathPoint = CurrentPath.end();
|
||||
|
||||
Vector TargetDestination = g_vecZero; // Desired destination
|
||||
Vector ActualMoveDestination = g_vecZero; // Actual destination on nav mesh
|
||||
|
|
|
@ -1665,7 +1665,7 @@ dtStatus FindPathClosestToPoint(const nav_profile& NavProfile, const Vector From
|
|||
|
||||
if (CurrFlags == SAMPLE_POLYFLAGS_WALLCLIMB || CurrFlags == SAMPLE_POLYFLAGS_LADDER)
|
||||
{
|
||||
float NewRequiredZ = UTIL_FindZHeightForWallClimb(path.back().Location, NextPathNode.Location, head_hull);
|
||||
float NewRequiredZ = UTIL_FindZHeightForWallClimb(NextPathNode.FromLocation, NextPathNode.Location, head_hull);
|
||||
//NextPathNode.requiredZ = fmaxf(NewRequiredZ, NextPathNode.Location.z);
|
||||
NextPathNode.requiredZ = NewRequiredZ;
|
||||
|
||||
|
@ -2003,6 +2003,8 @@ bool HasBotReachedPathPoint(const AvHAIPlayer* pBot)
|
|||
{
|
||||
if (!bIsAtFinalPathPoint)
|
||||
{
|
||||
if (pBot->BotNavInfo.IsOnGround && fabsf(pEdict->v.origin.z - MoveTo.z) > 50.0f) { return false; }
|
||||
|
||||
Vector thisMoveDir = UTIL_GetVectorNormal2D(MoveTo - MoveFrom);
|
||||
Vector nextMoveDir = UTIL_GetVectorNormal2D(next(pBot->BotNavInfo.CurrentPathPoint)->Location - MoveTo);
|
||||
|
||||
|
@ -2019,7 +2021,7 @@ bool HasBotReachedPathPoint(const AvHAIPlayer* pBot)
|
|||
}
|
||||
else
|
||||
{
|
||||
return (vDist2D(pEdict->v.origin, MoveTo) <= playerRadius && (pEdict->v.origin.z - MoveTo.z) < 50.0f && pBot->BotNavInfo.IsOnGround);
|
||||
return (vDist2D(pEdict->v.origin, MoveTo) <= playerRadius && fabsf(pEdict->v.origin.z - MoveTo.z) < 50.0f && pBot->BotNavInfo.IsOnGround);
|
||||
}
|
||||
}
|
||||
case SAMPLE_POLYFLAGS_WALLCLIMB:
|
||||
|
@ -5092,21 +5094,29 @@ bool AbortCurrentMove(AvHAIPlayer* pBot, const Vector NewDestination)
|
|||
|
||||
void UpdateBotStuck(AvHAIPlayer* pBot)
|
||||
{
|
||||
if (vIsZero(pBot->desiredMovementDir))
|
||||
if (vIsZero(pBot->desiredMovementDir) && !pBot->BotNavInfo.StuckInfo.bPathFollowFailed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool bIsFollowingPath = (pBot->BotNavInfo.CurrentPath.size() > 0 && pBot->BotNavInfo.CurrentPathPoint != pBot->BotNavInfo.CurrentPath.end());
|
||||
|
||||
bool bDist3D = pBot->BotNavInfo.NavProfile.bFlyingProfile || (bIsFollowingPath && (pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_LADDER || pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_WALLCLIMB));
|
||||
|
||||
float DistFromLastPoint = (bDist3D) ? vDist3DSq(pBot->Edict->v.origin, pBot->BotNavInfo.StuckInfo.LastBotPosition) : vDist2DSq(pBot->Edict->v.origin, pBot->BotNavInfo.StuckInfo.LastBotPosition);
|
||||
|
||||
if (DistFromLastPoint >= sqrf(8.0f))
|
||||
if (!pBot->BotNavInfo.StuckInfo.bPathFollowFailed)
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.TotalStuckTime = 0.0f;
|
||||
pBot->BotNavInfo.StuckInfo.LastBotPosition = pBot->Edict->v.origin;
|
||||
|
||||
bool bIsFollowingPath = (pBot->BotNavInfo.CurrentPath.size() > 0 && pBot->BotNavInfo.CurrentPathPoint != pBot->BotNavInfo.CurrentPath.end());
|
||||
|
||||
bool bDist3D = pBot->BotNavInfo.NavProfile.bFlyingProfile || (bIsFollowingPath && (pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_LADDER || pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_WALLCLIMB));
|
||||
|
||||
float DistFromLastPoint = (bDist3D) ? vDist3DSq(pBot->Edict->v.origin, pBot->BotNavInfo.StuckInfo.LastBotPosition) : vDist2DSq(pBot->Edict->v.origin, pBot->BotNavInfo.StuckInfo.LastBotPosition);
|
||||
|
||||
if (DistFromLastPoint >= sqrf(8.0f))
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.TotalStuckTime = 0.0f;
|
||||
pBot->BotNavInfo.StuckInfo.LastBotPosition = pBot->Edict->v.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.TotalStuckTime += AIMGR_GetBotDeltaTime();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5115,6 +5125,12 @@ void UpdateBotStuck(AvHAIPlayer* pBot)
|
|||
|
||||
if (pBot->BotNavInfo.StuckInfo.TotalStuckTime > 0.25f)
|
||||
{
|
||||
if (pBot->BotNavInfo.StuckInfo.TotalStuckTime > 15.0f)
|
||||
{
|
||||
BotSuicide(pBot);
|
||||
return;
|
||||
}
|
||||
|
||||
BotJump(pBot);
|
||||
if (!IsPlayerSkulk(pBot->Edict))
|
||||
{
|
||||
|
@ -5425,6 +5441,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
|
||||
if (dtStatusSucceed(PathFindingStatus))
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = false;
|
||||
ClearBotStuckMovement(pBot);
|
||||
pBot->BotNavInfo.TotalStuckTime = 0.0f;
|
||||
BotNavInfo->PathDestination = Destination;
|
||||
|
@ -5439,6 +5456,8 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
}
|
||||
else
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
|
||||
|
||||
if (!vIsZero(BotNavInfo->LastNavMeshPosition))
|
||||
{
|
||||
MoveDirectlyTo(pBot, BotNavInfo->LastNavMeshPosition);
|
||||
|
@ -5870,10 +5889,13 @@ void BotFollowPath(AvHAIPlayer* pBot)
|
|||
|
||||
if (IsBotOffPath(pBot))
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
|
||||
ClearBotPath(pBot);
|
||||
return;
|
||||
}
|
||||
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = false;
|
||||
|
||||
Vector MoveTo = BotNavInfo->CurrentPathPoint->Location;
|
||||
|
||||
NewMove(pBot);
|
||||
|
|
|
@ -115,7 +115,7 @@ static const int NAVMESHSET_MAGIC = 'M' << 24 | 'S' << 16 | 'E' << 8 | 'T'; //'M
|
|||
static const int NAVMESHSET_VERSION = 1;
|
||||
|
||||
static const int TILECACHESET_MAGIC = 'T' << 24 | 'S' << 16 | 'E' << 8 | 'T'; //'TSET', used to confirm the tile cache we're loading is compatible;
|
||||
static const int TILECACHESET_VERSION = 1;
|
||||
static const int TILECACHESET_VERSION = 2;
|
||||
|
||||
static const float pExtents[3] = { 400.0f, 50.0f, 400.0f }; // Default extents (in GoldSrc units) to find the nearest spot on the nav mesh
|
||||
static const float pReachableExtents[3] = { max_ai_use_reach, max_ai_use_reach, max_ai_use_reach }; // Extents (in GoldSrc units) to determine if something is on the nav mesh
|
||||
|
|
|
@ -3026,8 +3026,6 @@ void AIPlayerSetPrimaryMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
void AIPlayerSetMarineSweeperPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
if (Task->TaskType == TASK_GUARD) { return; }
|
||||
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
|
||||
Vector CommChairLocation = AITAC_GetCommChairLocation(BotTeam);
|
||||
|
@ -3041,7 +3039,7 @@ void AIPlayerSetMarineSweeperPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
StructureFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
StructureFilter.ExcludeStatusFlags = (STRUCTURE_STATUS_RECYCLING | STRUCTURE_STATUS_COMPLETED);
|
||||
|
||||
AvHAIBuildableStructure* UnbuiltIP = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &StructureFilter);
|
||||
AvHAIBuildableStructure* UnbuiltIP = AITAC_FindClosestDeployableToLocation(CommChairLocation, &StructureFilter);
|
||||
|
||||
if (UnbuiltIP)
|
||||
{
|
||||
|
@ -3049,6 +3047,49 @@ void AIPlayerSetMarineSweeperPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
return;
|
||||
}
|
||||
|
||||
StructureFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
||||
|
||||
AvHAIBuildableStructure* UnbuiltStructure = AITAC_FindClosestDeployableToLocation(CommChairLocation, &StructureFilter);
|
||||
|
||||
if (UnbuiltStructure)
|
||||
{
|
||||
AITASK_SetBuildTask(pBot, Task, UnbuiltStructure->edict, true);
|
||||
return;
|
||||
}
|
||||
|
||||
DeployableSearchFilter AttackedStructureFilter;
|
||||
AttackedStructureFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL;
|
||||
AttackedStructureFilter.DeployableTeam = BotTeam;
|
||||
AttackedStructureFilter.ReachabilityTeam = BotTeam;
|
||||
AttackedStructureFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
AttackedStructureFilter.IncludeStatusFlags = STRUCTURE_STATUS_UNDERATTACK;
|
||||
AttackedStructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
AttackedStructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
AttackedStructureFilter.bConsiderPhaseDistance = true;
|
||||
|
||||
AvHAIBuildableStructure* AttackedStructure = AITAC_FindClosestDeployableToLocation(CommChairLocation, &AttackedStructureFilter);
|
||||
|
||||
if (AttackedStructure)
|
||||
{
|
||||
AITASK_SetDefendTask(pBot, Task, AttackedStructure->edict, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerHasWeapon(pBot->Player, WEAPON_MARINE_WELDER))
|
||||
{
|
||||
AttackedStructureFilter.IncludeStatusFlags = STRUCTURE_STATUS_DAMAGED;
|
||||
|
||||
AvHAIBuildableStructure* AttackedStructure = AITAC_FindClosestDeployableToLocation(CommChairLocation, &AttackedStructureFilter);
|
||||
|
||||
if (AttackedStructure)
|
||||
{
|
||||
AITASK_SetWeldTask(pBot, Task, AttackedStructure->edict, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_PHASEGATE;
|
||||
StructureFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
StructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
|
@ -3482,7 +3523,7 @@ void AIPlayerRequestOrder(AvHAIPlayer* pBot)
|
|||
void AIPlayerSetSecondaryMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
// If we're building, finish that before doing anything else
|
||||
if (Task->TaskType == TASK_BUILD && vDist2DSq(pBot->Edict->v.origin, Task->TaskTarget->v.origin) < sqrf(UTIL_MetresToGoldSrcUnits(3.0f)))
|
||||
if (Task->TaskType == TASK_BUILD && (Task->StructureType == STRUCTURE_MARINE_INFANTRYPORTAL || vDist2DSq(pBot->Edict->v.origin, Task->TaskTarget->v.origin) < sqrf(UTIL_MetresToGoldSrcUnits(3.0f))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3491,13 +3532,29 @@ void AIPlayerSetSecondaryMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
// Find any nearby unbuilt structures
|
||||
DeployableSearchFilter UnbuiltFilter;
|
||||
UnbuiltFilter.DeployableTypes = SEARCH_ALL_MARINE_STRUCTURES;
|
||||
UnbuiltFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL;
|
||||
UnbuiltFilter.DeployableTeam = BotTeam;
|
||||
UnbuiltFilter.ReachabilityTeam = BotTeam;
|
||||
UnbuiltFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
UnbuiltFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING | STRUCTURE_STATUS_COMPLETED;
|
||||
UnbuiltFilter.ExcludeStatusFlags = (STRUCTURE_STATUS_RECYCLING | STRUCTURE_STATUS_COMPLETED);
|
||||
UnbuiltFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
|
||||
AvHAIBuildableStructure* UnbuiltIP = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &UnbuiltFilter);
|
||||
|
||||
if (UnbuiltIP)
|
||||
{
|
||||
float ThisDist = vDist2D(UnbuiltIP->Location, pBot->Edict->v.origin);
|
||||
int NumBuilders = AITAC_GetNumPlayersOfTeamInArea(BotTeam, UnbuiltIP->Location, ThisDist - 5.0f, false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
|
||||
|
||||
if (NumBuilders < 1)
|
||||
{
|
||||
AITASK_SetBuildTask(pBot, Task, UnbuiltIP->edict, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UnbuiltFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
|
||||
vector <AvHAIBuildableStructure*> BuildableStructures = AITAC_FindAllDeployables(pBot->Edict->v.origin, &UnbuiltFilter);
|
||||
|
||||
AvHAIBuildableStructure* NearestStructure = nullptr;
|
||||
|
|
|
@ -36,7 +36,7 @@ AvHAIPlayer* DebugAIPlayer = nullptr;
|
|||
|
||||
vector<bot_path_node> DebugPath;
|
||||
|
||||
string BotNames[MAX_PLAYERS] = { "MrRobot",
|
||||
string BotNames[MAX_PLAYERS] = { "MrRobot",
|
||||
"Wall-E",
|
||||
"BeepBoop",
|
||||
"Robotnik",
|
||||
|
@ -652,7 +652,7 @@ void AIMGR_UpdateAIPlayers()
|
|||
nav_profile NavProfile = GetBaseNavProfile(MARINE_BASE_NAV_PROFILE);
|
||||
NavProfile.Filters.addIncludeFlags(SAMPLE_POLYFLAGS_WELD);
|
||||
|
||||
dtStatus PathStatus = FindPathClosestToPoint(NavProfile, DebugVector1, DebugVector2, path, 100.0f);
|
||||
dtStatus PathStatus = FindPathClosestToPoint(NavProfile, DebugVector1, DebugVector2, path, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (dtStatusSucceed(PathStatus))
|
||||
{
|
||||
|
@ -828,6 +828,8 @@ void AIMGR_ResetRound()
|
|||
AIStartedTime = gpGlobals->time;
|
||||
}
|
||||
|
||||
LastAIPlayerCountUpdate = 0.0f;
|
||||
|
||||
AITAC_ClearMapAIData();
|
||||
|
||||
UTIL_PopulateDoors();
|
||||
|
@ -886,6 +888,7 @@ void AIMGR_NewMap()
|
|||
ActiveAIPlayers.clear();
|
||||
|
||||
AIStartedTime = gpGlobals->time;
|
||||
LastAIPlayerCountUpdate = 0.0f;
|
||||
ALERT(at_console, "AI Manager New Map\n");
|
||||
|
||||
if (NavmeshLoaded())
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "../AvHGamerules.h"
|
||||
#include "../AvHServerUtil.h"
|
||||
#include "../AvHSharedUtil.h"
|
||||
#include "../AvHMarineEquipment.h"
|
||||
|
||||
#include <float.h>
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
|
||||
|
||||
vector<AvHAIResourceNode> ResourceNodes;
|
||||
vector<AvHAIHiveDefinition> Hives;
|
||||
|
||||
|
@ -638,14 +640,18 @@ Vector AITAC_GetFloorLocationForHive(const AvHAIHiveDefinition* Hive)
|
|||
|
||||
Vector NearestNavigableLoc = ZERO_VECTOR;
|
||||
|
||||
FOR_ALL_ENTITIES(kesTeamStart, AvHTeamStartEntity*)
|
||||
if (NearestNavigableLoc == ZERO_VECTOR)
|
||||
{
|
||||
NearestNavigableLoc = FindClosestNavigablePointToDestination(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], theEntity->pev->origin, HiveFloorLoc, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
}
|
||||
END_FOR_ALL_ENTITIES(kesTeamStart);
|
||||
nav_profile TestNavProfile = GetBaseNavProfile(MARINE_BASE_NAV_PROFILE);
|
||||
TestNavProfile.Filters.addIncludeFlags(SAMPLE_POLYFLAGS_WELD);
|
||||
TestNavProfile.ReachabilityFlag = AI_REACHABILITY_WELDER;
|
||||
|
||||
if (NearestNavigableLoc != ZERO_VECTOR)
|
||||
FOR_ALL_ENTITIES(kwsTeamCommand, AvHCommandStation*)
|
||||
if (vIsZero(NearestNavigableLoc))
|
||||
{
|
||||
NearestNavigableLoc = FindClosestNavigablePointToDestination(TestNavProfile, theEntity->pev->origin, HiveFloorLoc, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
}
|
||||
END_FOR_ALL_ENTITIES(kwsTeamCommand);
|
||||
|
||||
if (!vIsZero(NearestNavigableLoc))
|
||||
{
|
||||
return NearestNavigableLoc;
|
||||
}
|
||||
|
@ -653,12 +659,15 @@ Vector AITAC_GetFloorLocationForHive(const AvHAIHiveDefinition* Hive)
|
|||
{
|
||||
return HiveFloorLoc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AITAC_PopulateHiveData()
|
||||
{
|
||||
Hives.clear();
|
||||
|
||||
const AvHBaseInfoLocationListType& theInfoLocations = GetGameRules()->GetInfoLocations();
|
||||
|
||||
FOR_ALL_ENTITIES(kesTeamHive, AvHHive*)
|
||||
|
||||
AvHAIHiveDefinition NewHive;
|
||||
|
@ -675,6 +684,17 @@ void AITAC_PopulateHiveData()
|
|||
|
||||
NewHive.FloorLocation = UTIL_GetFloorUnderEntity(theEntity->edict()); // Some hives are suspended in the air, this is the floor location directly beneath it
|
||||
|
||||
string HiveName;
|
||||
|
||||
string theLocationName;
|
||||
if (AvHSHUGetNameOfLocation(GetGameRules()->GetInfoLocations(), NewHive.Location, theLocationName))
|
||||
{
|
||||
HiveName = theLocationName;
|
||||
}
|
||||
|
||||
sprintf(NewHive.HiveName, HiveName.c_str(), "%s");
|
||||
|
||||
|
||||
Hives.push_back(NewHive);
|
||||
|
||||
END_FOR_ALL_ENTITIES(kesTeamHive)
|
||||
|
@ -734,7 +754,7 @@ void AITAC_RefreshHiveData()
|
|||
it->NextFloorLocationCheck = gpGlobals->time + 1.0f;
|
||||
}
|
||||
|
||||
if (it->NextFloorLocationCheck > 0.0f && gpGlobals->time >= it->NextFloorLocationCheck)
|
||||
if (gpGlobals->time >= it->NextFloorLocationCheck)
|
||||
{
|
||||
it->FloorLocation = AITAC_GetFloorLocationForHive(&(*it));
|
||||
|
||||
|
|
|
@ -2629,7 +2629,7 @@ void MarineProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
else
|
||||
{
|
||||
// If we're not at our destination yet, go there
|
||||
if (vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation) > UTIL_MetresToGoldSrcUnits(5.0f))
|
||||
if (vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation) > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
MoveTo(pBot, Task->TaskLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
|
@ -2697,7 +2697,7 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
{
|
||||
if (IsPlayerLerk(pBot->Edict))
|
||||
{
|
||||
MoveTo(pBot, pBot->GuardInfo.GuardStandPosition, MOVESTYLE_HIDE);
|
||||
MoveTo(pBot, pBot->GuardInfo.GuardStandPosition, MOVESTYLE_AMBUSH);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1542,6 +1542,17 @@ BOOL AvHGamerules::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
|
|||
|
||||
theSuccess = true;
|
||||
}
|
||||
else if (FStrEq(pcmd, "showhivefloors"))
|
||||
{
|
||||
vector<AvHAIHiveDefinition*> AllHives = AITAC_GetAllHives();
|
||||
|
||||
for (auto it = AllHives.begin(); it != AllHives.end(); it++)
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), INDEXENT(1)->v.origin, (*it)->FloorLocation, 20.0f, 255, 255, 0);
|
||||
}
|
||||
|
||||
theSuccess = true;
|
||||
}
|
||||
else if (FStrEq(pcmd, "testresearchavailable"))
|
||||
{
|
||||
AvHTeam* PlayerTeam = GetGameRules()->GetTeam(theAvHPlayer->GetTeam());
|
||||
|
|
Loading…
Reference in a new issue