mirror of
https://github.com/ENSL/NS.git
synced 2024-11-10 07:11:38 +00:00
Improved commander placement and tactical refresh
This commit is contained in:
parent
9e0b42dbf4
commit
261caa1c55
10 changed files with 241 additions and 148 deletions
|
@ -911,17 +911,19 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
||||||
StructureFilter.DeployableTeam = TeamNumber;
|
StructureFilter.DeployableTeam = TeamNumber;
|
||||||
StructureFilter.ReachabilityFlags = AI_REACHABILITY_MARINE;
|
StructureFilter.ReachabilityFlags = AI_REACHABILITY_MARINE;
|
||||||
StructureFilter.ReachabilityTeam = TeamNumber;
|
StructureFilter.ReachabilityTeam = TeamNumber;
|
||||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
|
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
||||||
|
|
||||||
int NumInfantryPortals = AITAC_GetNumDeployablesNearLocation(CommChair->v.origin, &StructureFilter);
|
int NumInfantryPortals = AITAC_GetNumDeployablesNearLocation(CommChair->v.origin, &StructureFilter);
|
||||||
|
|
||||||
if (NumInfantryPortals < 2)
|
if (NumInfantryPortals < 2)
|
||||||
{
|
{
|
||||||
bool bSuccess = AICOMM_BuildInfantryPortal(pBot, CommChair);
|
bool bEnemyInBase = NumInfantryPortals > 1 && AITAC_AnyPlayerOnTeamWithLOS(AIMGR_GetEnemyTeam(TeamNumber), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||||
|
|
||||||
|
bool bSuccess = !bEnemyInBase && AICOMM_BuildInfantryPortal(pBot, CommChair);
|
||||||
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kInfantryPortalCost) + 5);
|
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kInfantryPortalCost) + 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY;
|
StructureFilter.DeployableTypes = (STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY);
|
||||||
|
|
||||||
AvHAIBuildableStructure* BaseArmoury = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter);
|
AvHAIBuildableStructure* BaseArmoury = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter);
|
||||||
|
|
||||||
|
@ -929,7 +931,6 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
||||||
{
|
{
|
||||||
|
|
||||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL;
|
StructureFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL;
|
||||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(5.0f);
|
|
||||||
|
|
||||||
AvHAIBuildableStructure* NearestInfantryPortal = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter);
|
AvHAIBuildableStructure* NearestInfantryPortal = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter);
|
||||||
|
|
||||||
|
@ -982,7 +983,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (!vIsZero(BuildLocation))
|
if (!vIsZero(BuildLocation))
|
||||||
{
|
{
|
||||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation);
|
bool bEnemyInBase = AITAC_AnyPlayerOnTeamWithLOS(AIMGR_GetEnemyTeam(TeamNumber), BuildLocation + Vector(0.0f, 0.0f, 32.0f), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||||
|
|
||||||
|
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation);
|
||||||
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kPhaseGateCost) + 5);
|
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kPhaseGateCost) + 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1020,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (!vIsZero(BuildLocation))
|
if (!vIsZero(BuildLocation))
|
||||||
{
|
{
|
||||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation);
|
bool bEnemyInBase = AITAC_AnyPlayerOnTeamWithLOS(AIMGR_GetEnemyTeam(TeamNumber), BuildLocation + Vector(0.0f, 0.0f, 32.0f), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||||
|
|
||||||
|
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation);
|
||||||
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kArmsLabCost) + 5);
|
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kArmsLabCost) + 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1037,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (!vIsZero(BuildLocation))
|
if (!vIsZero(BuildLocation))
|
||||||
{
|
{
|
||||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation);
|
bool bEnemyInBase = AITAC_AnyPlayerOnTeamWithLOS(AIMGR_GetEnemyTeam(TeamNumber), BuildLocation + Vector(0.0f, 0.0f, 32.0f), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||||
|
|
||||||
|
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation);
|
||||||
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kObservatoryCost) + 5);
|
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kObservatoryCost) + 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1096,10 +1103,10 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (!vIsZero(BuildLocation))
|
if (!vIsZero(BuildLocation))
|
||||||
{
|
{
|
||||||
if (AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation))
|
bool bEnemyInBase = AITAC_AnyPlayerOnTeamWithLOS(AIMGR_GetEnemyTeam(TeamNumber), BuildLocation + Vector(0.0f, 0.0f, 32.0f), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||||
{
|
|
||||||
return true;
|
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation);
|
||||||
}
|
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kPrototypeLabCost) + 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1718,6 +1725,8 @@ const AvHAIResourceNode* AICOMM_GetNearestResourceNodeCapOpportunity(const AvHTe
|
||||||
|
|
||||||
if (!AITAC_AnyPlayerOnTeamWithLOS(Team, (ResNode->Location + Vector(0.0f, 0.0f, 32.0f)), UTIL_MetresToGoldSrcUnits(5.0f))) { continue; }
|
if (!AITAC_AnyPlayerOnTeamWithLOS(Team, (ResNode->Location + Vector(0.0f, 0.0f, 32.0f)), UTIL_MetresToGoldSrcUnits(5.0f))) { continue; }
|
||||||
|
|
||||||
|
if (AITAC_AnyPlayerOnTeamWithLOS(AIMGR_GetEnemyTeam(Team), (ResNode->Location + Vector(0.0f, 0.0f, 32.0f)), UTIL_MetresToGoldSrcUnits(10.0f))) { continue; }
|
||||||
|
|
||||||
float ThisDist = vDist2DSq(ResNode->Location, SearchLocation);
|
float ThisDist = vDist2DSq(ResNode->Location, SearchLocation);
|
||||||
|
|
||||||
if (!Result || ThisDist < MinDist)
|
if (!Result || ThisDist < MinDist)
|
||||||
|
@ -1805,12 +1814,16 @@ bool AICOMM_PerformNextSiegeHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefinit
|
||||||
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ExistingPG && !(ExistingPG->StructureStatusFlags & STRUCTURE_STATUS_COMPLETED)) { return false; }
|
||||||
|
|
||||||
if (!ExistingTF)
|
if (!ExistingTF)
|
||||||
{
|
{
|
||||||
if (vDist2DSq(NextBuildPosition, HiveToSiege->Location) > sqrf(UTIL_MetresToGoldSrcUnits(20.0f))) { return true; }
|
if (vDist2DSq(NextBuildPosition, HiveToSiege->Location) > sqrf(UTIL_MetresToGoldSrcUnits(20.0f))) { return true; }
|
||||||
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ExistingTF && !(ExistingTF->StructureStatusFlags & STRUCTURE_STATUS_COMPLETED)) { return false; }
|
||||||
|
|
||||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY;
|
StructureFilter.DeployableTypes = STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY;
|
||||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
|
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
|
||||||
|
|
||||||
|
|
|
@ -483,6 +483,16 @@ typedef struct _BOT_SKILL
|
||||||
|
|
||||||
} bot_skill;
|
} bot_skill;
|
||||||
|
|
||||||
|
typedef struct _AVH_AI_BUILD_ATTEMPT
|
||||||
|
{
|
||||||
|
AvHAIDeployableStructureType AttemptedStructureType = STRUCTURE_NONE;
|
||||||
|
Vector AttemptedLocation = g_vecZero;
|
||||||
|
int NumAttempts = 0;
|
||||||
|
BotBuildAttemptStatus BuildStatus = BUILD_ATTEMPT_NONE;
|
||||||
|
float BuildAttemptTime = 0.0f;
|
||||||
|
AvHAIBuildableStructure* LinkedStructure = nullptr;
|
||||||
|
} AvHAIBuildAttempt;
|
||||||
|
|
||||||
// A bot task is a goal the bot wants to perform, such as attacking a structure, placing a structure etc. NOT USED BY COMMANDER
|
// A bot task is a goal the bot wants to perform, such as attacking a structure, placing a structure etc. NOT USED BY COMMANDER
|
||||||
typedef struct _AVH_AI_PLAYER_TASK
|
typedef struct _AVH_AI_PLAYER_TASK
|
||||||
{
|
{
|
||||||
|
@ -500,19 +510,9 @@ typedef struct _AVH_AI_PLAYER_TASK
|
||||||
int BuildAttempts = 0; // How many attempts the Gorge has tried to place it, so it doesn't keep trying forever
|
int BuildAttempts = 0; // How many attempts the Gorge has tried to place it, so it doesn't keep trying forever
|
||||||
AvHMessageID Evolution = MESSAGE_NULL; // Used by TASK_EVOLVE to determine what to evolve into
|
AvHMessageID Evolution = MESSAGE_NULL; // Used by TASK_EVOLVE to determine what to evolve into
|
||||||
float TaskLength = 0.0f; // If a task has gone on longer than this time, it will be considered completed
|
float TaskLength = 0.0f; // If a task has gone on longer than this time, it will be considered completed
|
||||||
|
AvHAIBuildAttempt ActiveBuildInfo; // If gorge, the current status of any recent attempt to place a structure
|
||||||
} AvHAIPlayerTask;
|
} AvHAIPlayerTask;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _AVH_AI_BUILD_ATTEMPT
|
|
||||||
{
|
|
||||||
AvHAIDeployableStructureType AttemptedStructureType = STRUCTURE_NONE;
|
|
||||||
Vector AttemptedLocation = g_vecZero;
|
|
||||||
int NumAttempts = 0;
|
|
||||||
BotBuildAttemptStatus BuildStatus = BUILD_ATTEMPT_NONE;
|
|
||||||
float BuildAttemptTime = 0.0f;
|
|
||||||
AvHAIBuildableStructure* LinkedStructure = nullptr;
|
|
||||||
} AvHAIBuildAttempt;
|
|
||||||
|
|
||||||
typedef struct _DOOR_TRIGGER
|
typedef struct _DOOR_TRIGGER
|
||||||
{
|
{
|
||||||
CBaseEntity* Entity = nullptr;
|
CBaseEntity* Entity = nullptr;
|
||||||
|
@ -727,8 +727,6 @@ typedef struct AVH_AI_PLAYER
|
||||||
|
|
||||||
nav_status BotNavInfo; // Bot's movement information, their current path, where in the path they are etc.
|
nav_status BotNavInfo; // Bot's movement information, their current path, where in the path they are etc.
|
||||||
|
|
||||||
AvHAIBuildAttempt ActiveBuildInfo; // If gorge, the current status of any recent attempt to place a structure
|
|
||||||
|
|
||||||
vector<ai_commander_request> ActiveRequests;
|
vector<ai_commander_request> ActiveRequests;
|
||||||
vector<ai_commander_order> ActiveOrders;
|
vector<ai_commander_order> ActiveOrders;
|
||||||
|
|
||||||
|
|
|
@ -1838,7 +1838,8 @@ dtStatus FindPathClosestToPoint(AvHAIPlayer* pBot, const BotMoveStyle MoveStyle,
|
||||||
if (CurrFlags == SAMPLE_POLYFLAGS_WALLCLIMB || CurrFlags == SAMPLE_POLYFLAGS_LADDER)
|
if (CurrFlags == SAMPLE_POLYFLAGS_WALLCLIMB || CurrFlags == SAMPLE_POLYFLAGS_LADDER)
|
||||||
{
|
{
|
||||||
int HullNum = GetPlayerHullIndex(pBot->Edict, false);
|
int HullNum = GetPlayerHullIndex(pBot->Edict, false);
|
||||||
float NewRequiredZ = UTIL_FindZHeightForWallClimb(path.back().Location, NextPathNode.Location, HullNum);
|
Vector FromLocation = (path.size() > 0) ? path.back().Location : pBot->CurrentFloorPosition;
|
||||||
|
float NewRequiredZ = UTIL_FindZHeightForWallClimb(FromLocation, NextPathNode.Location, HullNum);
|
||||||
NextPathNode.requiredZ = fmaxf(NewRequiredZ, NextPathNode.Location.z);
|
NextPathNode.requiredZ = fmaxf(NewRequiredZ, NextPathNode.Location.z);
|
||||||
|
|
||||||
if (CurrFlags == SAMPLE_POLYFLAGS_LADDER)
|
if (CurrFlags == SAMPLE_POLYFLAGS_LADDER)
|
||||||
|
@ -3054,27 +3055,38 @@ void GroundMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoin
|
||||||
|
|
||||||
void FallMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
void FallMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
||||||
{
|
{
|
||||||
Vector vForward = UTIL_GetVectorNormal2D(EndPoint - pBot->Edict->v.origin);
|
Vector vBotOrientation = UTIL_GetVectorNormal2D(EndPoint - pBot->Edict->v.origin);
|
||||||
|
Vector vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
||||||
|
|
||||||
if (vIsZero(vForward))
|
if (pBot->BotNavInfo.IsOnGround)
|
||||||
{
|
{
|
||||||
vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
if (vDist2DSq(pBot->Edict->v.origin, EndPoint) > sqrf(GetPlayerRadius(pBot->Player)))
|
||||||
|
{
|
||||||
|
pBot->desiredMovementDir = vBotOrientation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pBot->desiredMovementDir = vForward;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bCanDuck = (IsPlayerMarine(pBot->Edict) || IsPlayerFade(pBot->Edict) || IsPlayerOnos(pBot->Edict));
|
||||||
|
|
||||||
|
if (!bCanDuck) { return; }
|
||||||
|
|
||||||
|
Vector HeadLocation = GetPlayerTopOfCollisionHull(pBot->Edict, false);
|
||||||
|
|
||||||
|
if (!UTIL_QuickTrace(pBot->Edict, HeadLocation, (HeadLocation + (pBot->desiredMovementDir * 50.0f))))
|
||||||
|
{
|
||||||
|
pBot->Button |= IN_DUCK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pBot->desiredMovementDir = vBotOrientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBot->desiredMovementDir = vForward;
|
|
||||||
|
|
||||||
if (UTIL_PointIsDirectlyReachable(pBot, EndPoint)) { return; }
|
|
||||||
|
|
||||||
bool bCanDuck = (IsPlayerMarine(pBot->Edict) || IsPlayerFade(pBot->Edict) || IsPlayerOnos(pBot->Edict));
|
|
||||||
|
|
||||||
if (!bCanDuck) { return; }
|
|
||||||
|
|
||||||
Vector HeadLocation = GetPlayerTopOfCollisionHull(pBot->Edict, false);
|
|
||||||
|
|
||||||
if (!UTIL_QuickTrace(pBot->Edict, HeadLocation, (HeadLocation + (pBot->desiredMovementDir * 50.0f))))
|
|
||||||
{
|
|
||||||
pBot->Button |= IN_DUCK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructureBlockedMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
void StructureBlockedMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
|
||||||
|
@ -3858,7 +3870,7 @@ bool IsBotOffPath(const AvHAIPlayer* pBot)
|
||||||
|
|
||||||
Vector vForward = UTIL_GetVectorNormal2D(MoveTo - MoveFrom);
|
Vector vForward = UTIL_GetVectorNormal2D(MoveTo - MoveFrom);
|
||||||
|
|
||||||
Vector PointOnPath = vClosestPointOnLine2D(MoveFrom, MoveTo, pBot->CurrentFloorPosition);
|
Vector PointOnPath = vClosestPointOnLine2D(MoveFrom, MoveTo, pBot->Edict->v.origin);
|
||||||
|
|
||||||
if (pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_WALLCLIMB)
|
if (pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_WALLCLIMB)
|
||||||
{
|
{
|
||||||
|
@ -3871,16 +3883,7 @@ bool IsBotOffPath(const AvHAIPlayer* pBot)
|
||||||
if (pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_WALK)
|
if (pBot->BotNavInfo.CurrentPathPoint->flag == SAMPLE_POLYFLAGS_WALK)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!UTIL_PointIsDirectlyReachable(pBot->CurrentFloorPosition, MoveTo))
|
if (vDist2DSq(pBot->Edict->v.origin, PointOnPath) > sqrf(100.0f)) { return true; }
|
||||||
{
|
|
||||||
Vector TraceEnd = MoveTo;
|
|
||||||
TraceEnd.z = pBot->Edict->v.origin.z;
|
|
||||||
|
|
||||||
if (!UTIL_QuickHullTrace(pBot->Edict, pBot->Edict->v.origin, TraceEnd, GetPlayerHullIndex(pBot->Edict)))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bAtMoveStart = vEquals(PointOnPath, MoveFrom, 2.0f);
|
bool bAtMoveStart = vEquals(PointOnPath, MoveFrom, 2.0f);
|
||||||
|
|
||||||
|
@ -4964,7 +4967,7 @@ bool AbortCurrentMove(AvHAIPlayer* pBot, const Vector NewDestination)
|
||||||
|
|
||||||
if (flag == SAMPLE_POLYFLAGS_LIFT)
|
if (flag == SAMPLE_POLYFLAGS_LIFT)
|
||||||
{
|
{
|
||||||
if (pBot->BotNavInfo.MovementTask.TaskType != MOVE_TASK_NONE)
|
if (pBot->BotNavInfo.MovementTask.TaskType != MOVE_TASK_NONE && !vEquals(NewDestination, pBot->BotNavInfo.MovementTask.TaskLocation))
|
||||||
{
|
{
|
||||||
if (NAV_IsMovementTaskStillValid(pBot))
|
if (NAV_IsMovementTaskStillValid(pBot))
|
||||||
{
|
{
|
||||||
|
@ -5132,7 +5135,7 @@ void UpdateBotStuck(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (!vIsZero(pBot->desiredMovementDir))
|
if (!vIsZero(pBot->desiredMovementDir))
|
||||||
{
|
{
|
||||||
//BotJump(pBot);
|
BotJump(pBot);
|
||||||
|
|
||||||
if (!IsPlayerSkulk(pBot->Edict))
|
if (!IsPlayerSkulk(pBot->Edict))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1641,27 +1641,49 @@ void StartNewBotFrame(AvHAIPlayer* pBot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we tried placing a building as gorge, and nothing has appeared within the expected time, then mark it as a failed attempt.
|
// If we tried placing a building as gorge, and nothing has appeared within the expected time, then mark it as a failed attempt.
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
if (pBot->PrimaryBotTask.ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||||
{
|
{
|
||||||
if (pBot->ActiveBuildInfo.AttemptedStructureType == STRUCTURE_ALIEN_HIVE)
|
if (pBot->PrimaryBotTask.ActiveBuildInfo.AttemptedStructureType == STRUCTURE_ALIEN_HIVE)
|
||||||
{
|
{
|
||||||
// Give a 3-second grace period to check if the hive placement was successful
|
// Give a 3-second grace period to check if the hive placement was successful
|
||||||
if ((gpGlobals->time - pBot->ActiveBuildInfo.BuildAttemptTime) > 3.0f)
|
if ((gpGlobals->time - pBot->PrimaryBotTask.ActiveBuildInfo.BuildAttemptTime) > 3.0f)
|
||||||
{
|
{
|
||||||
const AvHAIHiveDefinition* NearestHive = AITAC_GetHiveNearestLocation(pBot->ActiveBuildInfo.AttemptedLocation);
|
const AvHAIHiveDefinition* NearestHive = AITAC_GetHiveNearestLocation(pBot->PrimaryBotTask.ActiveBuildInfo.AttemptedLocation);
|
||||||
|
|
||||||
pBot->ActiveBuildInfo.BuildStatus = (NearestHive->Status != HIVE_STATUS_UNBUILT) ? BUILD_ATTEMPT_SUCCESS : BUILD_ATTEMPT_FAILED;
|
pBot->PrimaryBotTask.ActiveBuildInfo.BuildStatus = (NearestHive->Status != HIVE_STATUS_UNBUILT) ? BUILD_ATTEMPT_SUCCESS : BUILD_ATTEMPT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// All other structures should appear near-instantly
|
// All other structures should appear near-instantly
|
||||||
if ((gpGlobals->time - pBot->ActiveBuildInfo.BuildAttemptTime) > 0.5f)
|
if ((gpGlobals->time - pBot->PrimaryBotTask.ActiveBuildInfo.BuildAttemptTime) > 0.5f)
|
||||||
{
|
{
|
||||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_FAILED;
|
pBot->PrimaryBotTask.ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we tried placing a building as gorge, and nothing has appeared within the expected time, then mark it as a failed attempt.
|
||||||
|
if (pBot->SecondaryBotTask.ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||||
|
{
|
||||||
|
if (pBot->SecondaryBotTask.ActiveBuildInfo.AttemptedStructureType == STRUCTURE_ALIEN_HIVE)
|
||||||
|
{
|
||||||
|
// Give a 3-second grace period to check if the hive placement was successful
|
||||||
|
if ((gpGlobals->time - pBot->SecondaryBotTask.ActiveBuildInfo.BuildAttemptTime) > 3.0f)
|
||||||
|
{
|
||||||
|
const AvHAIHiveDefinition* NearestHive = AITAC_GetHiveNearestLocation(pBot->SecondaryBotTask.ActiveBuildInfo.AttemptedLocation);
|
||||||
|
|
||||||
|
pBot->SecondaryBotTask.ActiveBuildInfo.BuildStatus = (NearestHive->Status != HIVE_STATUS_UNBUILT) ? BUILD_ATTEMPT_SUCCESS : BUILD_ATTEMPT_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// All other structures should appear near-instantly
|
||||||
|
if ((gpGlobals->time - pBot->SecondaryBotTask.ActiveBuildInfo.BuildAttemptTime) > 0.5f)
|
||||||
|
{
|
||||||
|
pBot->SecondaryBotTask.ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2553,6 +2575,11 @@ void AIPlayerNSMarineThink(AvHAIPlayer* pBot)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pBot->CurrentEnemy > -1)
|
||||||
|
{
|
||||||
|
if (MarineCombatThink(pBot)) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
if (!pBot->CurrentTask) { pBot->CurrentTask = &pBot->PrimaryBotTask; }
|
if (!pBot->CurrentTask) { pBot->CurrentTask = &pBot->PrimaryBotTask; }
|
||||||
|
|
||||||
if (gpGlobals->time >= pBot->BotNextTaskEvaluationTime)
|
if (gpGlobals->time >= pBot->BotNextTaskEvaluationTime)
|
||||||
|
@ -2568,11 +2595,6 @@ void AIPlayerNSMarineThink(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
pBot->CurrentTask = AIPlayerGetNextTask(pBot);
|
pBot->CurrentTask = AIPlayerGetNextTask(pBot);
|
||||||
|
|
||||||
if (pBot->CurrentEnemy > -1)
|
|
||||||
{
|
|
||||||
if (MarineCombatThink(pBot)) { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pBot->CurrentTask && pBot->CurrentTask->TaskType != TASK_NONE)
|
if (pBot->CurrentTask && pBot->CurrentTask->TaskType != TASK_NONE)
|
||||||
{
|
{
|
||||||
BotProgressTask(pBot, pBot->CurrentTask);
|
BotProgressTask(pBot, pBot->CurrentTask);
|
||||||
|
@ -2983,6 +3005,8 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
BotShootTarget(pBot, DesiredCombatWeapon, CurrentEnemy);
|
BotShootTarget(pBot, DesiredCombatWeapon, CurrentEnemy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -3732,7 +3756,7 @@ bool AIPlayerMustFinishCurrentTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
{
|
{
|
||||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return true; }
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return true; }
|
||||||
|
|
||||||
// If we're already capping a node, are at the node and there is an unfinished tower on there, then finish the job and don't move on yet
|
// If we're already capping a node, are at the node and there is an unfinished tower on there, then finish the job and don't move on yet
|
||||||
if (Task->TaskType == TASK_CAP_RESNODE)
|
if (Task->TaskType == TASK_CAP_RESNODE)
|
||||||
|
@ -3773,7 +3797,15 @@ void AIPlayerNSAlienThink(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
if (AITAC_ShouldBotBuildHive(pBot, &HiveToBuild))
|
if (AITAC_ShouldBotBuildHive(pBot, &HiveToBuild))
|
||||||
{
|
{
|
||||||
BotAlienBuildHive(pBot, HiveToBuild);
|
if (pBot->PrimaryBotTask.TaskType != TASK_BUILD || pBot->PrimaryBotTask.StructureType != STRUCTURE_ALIEN_HIVE)
|
||||||
|
{
|
||||||
|
pBot->PrimaryBotTask.TaskType = TASK_BUILD;
|
||||||
|
pBot->PrimaryBotTask.StructureType = STRUCTURE_ALIEN_HIVE;
|
||||||
|
char msg[64];
|
||||||
|
sprintf(msg, "I'm going to drop the hive at %s", HiveToBuild->HiveName);
|
||||||
|
BotSay(pBot, true, 1.0f, msg);
|
||||||
|
}
|
||||||
|
BotAlienBuildHive(pBot, &pBot->PrimaryBotTask, HiveToBuild);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3858,6 +3890,16 @@ void AIPlayerThink(AvHAIPlayer* pBot)
|
||||||
bool bBreak = true;
|
bool bBreak = true;
|
||||||
|
|
||||||
AIDEBUG_DrawBotPath(pBot);
|
AIDEBUG_DrawBotPath(pBot);
|
||||||
|
|
||||||
|
if (pBot->BotNavInfo.CurrentPathPoint != pBot->BotNavInfo.CurrentPath.end())
|
||||||
|
{
|
||||||
|
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->BotNavInfo.CurrentPathPoint->Location, 0, 255, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBot->PrimaryBotTask.TaskType == TASK_BUILD)
|
||||||
|
{
|
||||||
|
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->PrimaryBotTask.TaskLocation, 0, 255, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (GetGameRules()->GetMapMode())
|
switch (GetGameRules()->GetMapMode())
|
||||||
|
@ -4261,7 +4303,7 @@ void AIPlayerSetAlienBuilderPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
||||||
if (!TowerToReinforce || ThisDist < MinDist)
|
if (!TowerToReinforce || ThisDist < MinDist)
|
||||||
{
|
{
|
||||||
TowerToReinforce = ThisResTower->edict;
|
TowerToReinforce = ThisResTower->edict;
|
||||||
MaxDist = ThisDist;
|
MinDist = ThisDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ int BotNameIndex = 0;
|
||||||
float AIStartedTime = 0.0f; // Used to give 5-second grace period before adding bots
|
float AIStartedTime = 0.0f; // Used to give 5-second grace period before adding bots
|
||||||
|
|
||||||
bool bHasRoundStarted = false;
|
bool bHasRoundStarted = false;
|
||||||
|
bool bMapDataInitialised = false;
|
||||||
|
|
||||||
extern int m_spriteTexture;
|
extern int m_spriteTexture;
|
||||||
|
|
||||||
|
@ -622,7 +623,7 @@ void AIMGR_UpdateAIPlayers()
|
||||||
|
|
||||||
UpdateBotChat(bot);
|
UpdateBotChat(bot);
|
||||||
|
|
||||||
DroneThink(bot);
|
AIPlayerThink(bot);
|
||||||
|
|
||||||
EndBotFrame(bot);
|
EndBotFrame(bot);
|
||||||
|
|
||||||
|
@ -837,26 +838,19 @@ void AIMGR_ResetRound()
|
||||||
UTIL_PopulateDoors();
|
UTIL_PopulateDoors();
|
||||||
UTIL_PopulateWeldableObstacles();
|
UTIL_PopulateWeldableObstacles();
|
||||||
|
|
||||||
ALERT(at_console, "AI Manager Reset Round\n");
|
|
||||||
|
|
||||||
bHasRoundStarted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AIMGR_RoundStarted()
|
|
||||||
{
|
|
||||||
AITAC_PopulateResourceNodes();
|
|
||||||
AITAC_PopulateHiveData();
|
|
||||||
|
|
||||||
AITAC_RefreshResourceNodes();
|
|
||||||
|
|
||||||
AITAC_RefreshHiveData();
|
|
||||||
|
|
||||||
UTIL_UpdateDoors(true);
|
UTIL_UpdateDoors(true);
|
||||||
|
|
||||||
UTIL_UpdateTileCache();
|
UTIL_UpdateTileCache();
|
||||||
|
|
||||||
|
ALERT(at_console, "AI Manager Reset Round\n");
|
||||||
|
|
||||||
|
bHasRoundStarted = false;
|
||||||
|
bMapDataInitialised = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIMGR_RoundStarted()
|
||||||
|
{
|
||||||
bHasRoundStarted = true;
|
bHasRoundStarted = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIMGR_ClearBotData()
|
void AIMGR_ClearBotData()
|
||||||
|
@ -891,12 +885,16 @@ void AIMGR_NewMap()
|
||||||
{
|
{
|
||||||
if (avh_botsenabled.value == 0) { return; } // Do nothing if we're not using bots
|
if (avh_botsenabled.value == 0) { return; } // Do nothing if we're not using bots
|
||||||
|
|
||||||
|
bMapDataInitialised = false;
|
||||||
|
|
||||||
ActiveAIPlayers.clear();
|
ActiveAIPlayers.clear();
|
||||||
|
|
||||||
AIStartedTime = gpGlobals->time;
|
AIStartedTime = gpGlobals->time;
|
||||||
LastAIPlayerCountUpdate = 0.0f;
|
LastAIPlayerCountUpdate = 0.0f;
|
||||||
ALERT(at_console, "AI Manager New Map\n");
|
ALERT(at_console, "AI Manager New Map\n");
|
||||||
|
|
||||||
|
AITAC_ClearMapAIData();
|
||||||
|
|
||||||
if (NavmeshLoaded())
|
if (NavmeshLoaded())
|
||||||
{
|
{
|
||||||
UnloadNavigationData();
|
UnloadNavigationData();
|
||||||
|
@ -1025,9 +1023,12 @@ vector<AvHPlayer*> AIMGR_GetNonAIPlayersOnTeam(AvHTeamNumber Team)
|
||||||
|
|
||||||
void AIMGR_UpdateAIMapData()
|
void AIMGR_UpdateAIMapData()
|
||||||
{
|
{
|
||||||
AITAC_UpdateMapAIData();
|
if (bMapDataInitialised && gpGlobals->time - AIStartedTime > AI_GRACE_PERIOD)
|
||||||
UTIL_UpdateTileCache();
|
{
|
||||||
AITAC_CheckNavMeshModified();
|
AITAC_UpdateMapAIData();
|
||||||
|
UTIL_UpdateTileCache();
|
||||||
|
AITAC_CheckNavMeshModified();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIMGR_BotPrecache()
|
void AIMGR_BotPrecache()
|
||||||
|
|
|
@ -1389,6 +1389,7 @@ AvHAIResourceNode* AITAC_GetRandomResourceNode(AvHTeamNumber SearchingTeam, cons
|
||||||
|
|
||||||
void AITAC_UpdateMapAIData()
|
void AITAC_UpdateMapAIData()
|
||||||
{
|
{
|
||||||
|
|
||||||
AITAC_RefreshHiveData();
|
AITAC_RefreshHiveData();
|
||||||
|
|
||||||
UTIL_UpdateDoors(false);
|
UTIL_UpdateDoors(false);
|
||||||
|
@ -2220,15 +2221,25 @@ void AITAC_LinkStructureToPlayer(AvHAIBuildableStructure* NewStructure)
|
||||||
{
|
{
|
||||||
AvHAIPlayer* Player = (*it);
|
AvHAIPlayer* Player = (*it);
|
||||||
|
|
||||||
if (Player->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING && Player->ActiveBuildInfo.AttemptedStructureType == NewStructure->StructureType)
|
if (Player->PrimaryBotTask.ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING && Player->PrimaryBotTask.ActiveBuildInfo.AttemptedStructureType == NewStructure->StructureType)
|
||||||
{
|
{
|
||||||
if (vDist2DSq(NewStructure->Location, Player->ActiveBuildInfo.AttemptedLocation) < sqrf(UTIL_MetresToGoldSrcUnits(2.0f)))
|
if (vDist2DSq(NewStructure->Location, Player->PrimaryBotTask.ActiveBuildInfo.AttemptedLocation) < sqrf(UTIL_MetresToGoldSrcUnits(2.0f)))
|
||||||
{
|
{
|
||||||
Player->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_SUCCESS;
|
Player->PrimaryBotTask.ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_SUCCESS;
|
||||||
Player->ActiveBuildInfo.LinkedStructure = NewStructure;
|
Player->PrimaryBotTask.ActiveBuildInfo.LinkedStructure = NewStructure;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Player->SecondaryBotTask.ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING && Player->SecondaryBotTask.ActiveBuildInfo.AttemptedStructureType == NewStructure->StructureType)
|
||||||
|
{
|
||||||
|
if (vDist2DSq(NewStructure->Location, Player->SecondaryBotTask.ActiveBuildInfo.AttemptedLocation) < sqrf(UTIL_MetresToGoldSrcUnits(2.0f)))
|
||||||
|
{
|
||||||
|
Player->SecondaryBotTask.ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_SUCCESS;
|
||||||
|
Player->SecondaryBotTask.ActiveBuildInfo.LinkedStructure = NewStructure;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2996,6 +3007,32 @@ int AITAC_GetNumPlayersOfTeamInArea(const AvHTeamNumber Team, const Vector Searc
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AITAC_AnyPlayersOfTeamInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 IgnoreClass)
|
||||||
|
{
|
||||||
|
float MaxRadiusSq = sqrf(SearchRadius);
|
||||||
|
|
||||||
|
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||||
|
{
|
||||||
|
edict_t* PlayerEdict = INDEXENT(i);
|
||||||
|
|
||||||
|
if (FNullEnt(PlayerEdict) || PlayerEdict->free || PlayerEdict == IgnorePlayer) { continue; }
|
||||||
|
|
||||||
|
AvHPlayer* PlayerRef = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(PlayerEdict));
|
||||||
|
|
||||||
|
if (PlayerRef != nullptr && GetPlayerActiveClass(PlayerRef) != IgnoreClass && (Team == TEAM_IND || PlayerRef->GetTeam() == Team) && IsPlayerActiveInGame(PlayerEdict))
|
||||||
|
{
|
||||||
|
float Dist = (bConsiderPhaseDist) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(PlayerEdict->v.origin, SearchLocation)) : vDist2DSq(PlayerEdict->v.origin, SearchLocation);
|
||||||
|
|
||||||
|
if (Dist <= MaxRadiusSq)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int AITAC_GetNumPlayersOnTeamOfClass(const AvHTeamNumber Team, const AvHUser3 SearchClass, const edict_t* IgnorePlayer)
|
int AITAC_GetNumPlayersOnTeamOfClass(const AvHTeamNumber Team, const AvHUser3 SearchClass, const edict_t* IgnorePlayer)
|
||||||
{
|
{
|
||||||
int Result = 0;
|
int Result = 0;
|
||||||
|
|
|
@ -122,6 +122,7 @@ AvHAIWeapon UTIL_GetWeaponTypeFromEdict(const edict_t* ItemEdict);
|
||||||
|
|
||||||
int AITAC_GetNumActivePlayersOnTeam(const AvHTeamNumber Team);
|
int AITAC_GetNumActivePlayersOnTeam(const AvHTeamNumber Team);
|
||||||
int AITAC_GetNumPlayersOfTeamInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 IgnoreClass);
|
int AITAC_GetNumPlayersOfTeamInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 IgnoreClass);
|
||||||
|
bool AITAC_AnyPlayersOfTeamInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 IgnoreClass);
|
||||||
vector<AvHPlayer*> AITAC_GetAllPlayersOfTeamInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 IgnoreClass);
|
vector<AvHPlayer*> AITAC_GetAllPlayersOfTeamInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 IgnoreClass);
|
||||||
int AITAC_GetNumPlayersOfTeamAndClassInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 SearchClass);
|
int AITAC_GetNumPlayersOfTeamAndClassInArea(const AvHTeamNumber Team, const Vector SearchLocation, const float SearchRadius, const bool bConsiderPhaseDist, const edict_t* IgnorePlayer, const AvHUser3 SearchClass);
|
||||||
int AITAC_GetNumPlayersOnTeamOfClass(const AvHTeamNumber Team, const AvHUser3 SearchClass, const edict_t* IgnorePlayer);
|
int AITAC_GetNumPlayersOnTeamOfClass(const AvHTeamNumber Team, const AvHUser3 SearchClass, const edict_t* IgnorePlayer);
|
||||||
|
|
|
@ -137,7 +137,7 @@ void AITASK_ClearBotTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
Task->BuildAttempts = 0;
|
Task->BuildAttempts = 0;
|
||||||
Task->StructureType = STRUCTURE_NONE;
|
Task->StructureType = STRUCTURE_NONE;
|
||||||
|
|
||||||
memset(&pBot->ActiveBuildInfo, 0, sizeof(AvHAIBuildAttempt));
|
memset(&Task->ActiveBuildInfo, 0, sizeof(AvHAIBuildAttempt));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AITASK_IsTaskUrgent(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
bool AITASK_IsTaskUrgent(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
@ -585,11 +585,11 @@ bool AITASK_IsAlienBuildTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
if (Task->StructureType == STRUCTURE_NONE) { return false; }
|
if (Task->StructureType == STRUCTURE_NONE) { return false; }
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return true; }
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return true; }
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED && pBot->ActiveBuildInfo.NumAttempts >= 3) { return false; }
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED && Task->ActiveBuildInfo.NumAttempts >= 3) { return false; }
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.LinkedStructure && (UTIL_StructureIsFullyBuilt(pBot->ActiveBuildInfo.LinkedStructure->edict) || !UTIL_IsBuildableStructureStillReachable(pBot, pBot->ActiveBuildInfo.LinkedStructure->edict))) { return false; }
|
if (Task->ActiveBuildInfo.LinkedStructure && (UTIL_StructureIsFullyBuilt(Task->ActiveBuildInfo.LinkedStructure->edict) || !UTIL_IsBuildableStructureStillReachable(pBot, Task->ActiveBuildInfo.LinkedStructure->edict))) { return false; }
|
||||||
|
|
||||||
if (Task->StructureType == STRUCTURE_ALIEN_HIVE)
|
if (Task->StructureType == STRUCTURE_ALIEN_HIVE)
|
||||||
{
|
{
|
||||||
|
@ -1129,14 +1129,14 @@ void BotProgressPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
void BotProgressMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void BotProgressMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
{
|
{
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus != BUILD_ATTEMPT_NONE)
|
if (Task->ActiveBuildInfo.BuildStatus != BUILD_ATTEMPT_NONE)
|
||||||
{
|
{
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED)
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED)
|
||||||
{
|
{
|
||||||
float Size = fmaxf(Task->TaskTarget->v.size.x, Task->TaskTarget->v.size.y);
|
float Size = fmaxf(Task->TaskTarget->v.size.x, Task->TaskTarget->v.size.y);
|
||||||
Size += 8.0f;
|
Size += 8.0f;
|
||||||
|
@ -1147,7 +1147,7 @@ void BotProgressMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
Task->TaskLocation = ZERO_VECTOR;
|
Task->TaskLocation = ZERO_VECTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vIsZero(Task->TaskLocation))
|
if (vIsZero(Task->TaskLocation))
|
||||||
|
@ -1184,11 +1184,11 @@ void BotProgressMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
if (LookDot > 0.95f)
|
if (LookDot > 0.95f)
|
||||||
{
|
{
|
||||||
pBot->Button |= IN_ATTACK;
|
pBot->Button |= IN_ATTACK;
|
||||||
pBot->ActiveBuildInfo.AttemptedLocation = Task->TaskLocation;
|
Task->ActiveBuildInfo.AttemptedLocation = Task->TaskLocation;
|
||||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_PENDING;
|
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_PENDING;
|
||||||
pBot->ActiveBuildInfo.BuildAttemptTime = gpGlobals->time;
|
Task->ActiveBuildInfo.BuildAttemptTime = gpGlobals->time;
|
||||||
pBot->ActiveBuildInfo.AttemptedStructureType = STRUCTURE_MARINE_DEPLOYEDMINE;
|
Task->ActiveBuildInfo.AttemptedStructureType = STRUCTURE_MARINE_DEPLOYEDMINE;
|
||||||
pBot->ActiveBuildInfo.NumAttempts++;
|
Task->ActiveBuildInfo.NumAttempts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1199,13 +1199,13 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
{
|
{
|
||||||
if (FNullEnt(Task->TaskTarget)) { return; }
|
if (FNullEnt(Task->TaskTarget)) { return; }
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||||
|
|
||||||
// We had a go, whether it succeeded or not we should try a new location
|
// We had a go, whether it succeeded or not we should try a new location
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED || pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_SUCCESS)
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED || Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_SUCCESS)
|
||||||
{
|
{
|
||||||
Task->TaskLocation = ZERO_VECTOR;
|
Task->TaskLocation = ZERO_VECTOR;
|
||||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||||
|
@ -1312,7 +1312,7 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
if (pBot->Player->GetResources() >= ResourceCost)
|
if (pBot->Player->GetResources() >= ResourceCost)
|
||||||
{
|
{
|
||||||
BotAlienPlaceChamber(pBot, Task->TaskLocation, NextStructure);
|
BotAlienPlaceChamber(pBot, Task, NextStructure);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1872,7 +1872,7 @@ void AlienProgressHealTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
{
|
{
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1899,13 +1899,13 @@ void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BotAlienBuildHive(pBot, Hive);
|
BotAlienBuildHive(pBot, Task, Hive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
{
|
{
|
||||||
// We tried and failed to place the structure
|
// We tried and failed to place the structure
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1916,9 +1916,9 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.LinkedStructure)
|
if (Task->ActiveBuildInfo.LinkedStructure)
|
||||||
{
|
{
|
||||||
edict_t* LinkedEdict = pBot->ActiveBuildInfo.LinkedStructure->edict;
|
edict_t* LinkedEdict = Task->ActiveBuildInfo.LinkedStructure->edict;
|
||||||
|
|
||||||
if (UTIL_StructureIsFullyBuilt(LinkedEdict)) { return; }
|
if (UTIL_StructureIsFullyBuilt(LinkedEdict)) { return; }
|
||||||
|
|
||||||
|
@ -1938,10 +1938,10 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We tried and failed to place the structure
|
// We tried and failed to place the structure
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED)
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED)
|
||||||
{
|
{
|
||||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ResRequired = UTIL_GetCostOfStructureType(Task->StructureType);
|
int ResRequired = UTIL_GetCostOfStructureType(Task->StructureType);
|
||||||
|
@ -1980,34 +1980,35 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BotAlienPlaceChamber(pBot, Task->TaskLocation, Task->StructureType);
|
BotAlienPlaceChamber(pBot, Task, Task->StructureType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStructureType DesiredStructure)
|
void BotAlienPlaceChamber(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, AvHAIDeployableStructureType DesiredStructure)
|
||||||
{
|
{
|
||||||
if (vIsZero(Location) || DesiredStructure == STRUCTURE_NONE) { return; }
|
if (vIsZero(Task->TaskLocation) || DesiredStructure == STRUCTURE_NONE) { return; }
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
|
||||||
|
|
||||||
float DistFromBuildLocation = vDist2DSq(pBot->Edict->v.origin, Location);
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||||
|
|
||||||
|
float DistFromBuildLocation = vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation);
|
||||||
|
|
||||||
if (DistFromBuildLocation > sqrf(UTIL_MetresToGoldSrcUnits(1.0f)))
|
if (DistFromBuildLocation > sqrf(UTIL_MetresToGoldSrcUnits(1.0f)))
|
||||||
{
|
{
|
||||||
MoveTo(pBot, Location, MOVESTYLE_NORMAL);
|
MoveTo(pBot, Task->TaskLocation, MOVESTYLE_NORMAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DistFromBuildLocation < sqrf(UTIL_MetresToGoldSrcUnits(0.5f)))
|
if (DistFromBuildLocation < sqrf(UTIL_MetresToGoldSrcUnits(0.5f)))
|
||||||
{
|
{
|
||||||
BotLookAt(pBot, Location);
|
BotLookAt(pBot, Task->TaskLocation);
|
||||||
Vector Orientation = UTIL_GetVectorNormal2D(pBot->Edict->v.origin - Location);
|
Vector Orientation = UTIL_GetVectorNormal2D(pBot->Edict->v.origin - Task->TaskLocation);
|
||||||
Vector NewMoveLoc = Location + (Orientation * UTIL_MetresToGoldSrcUnits(2.0f));
|
Vector NewMoveLoc = Task->TaskLocation + (Orientation * UTIL_MetresToGoldSrcUnits(2.0f));
|
||||||
MoveToWithoutNav(pBot, NewMoveLoc);
|
MoveToWithoutNav(pBot, NewMoveLoc);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector LookLocation = Location;
|
Vector LookLocation = Task->TaskLocation;
|
||||||
LookLocation.z += 10.0f;
|
LookLocation.z += 10.0f;
|
||||||
|
|
||||||
BotLookAt(pBot, LookLocation);
|
BotLookAt(pBot, LookLocation);
|
||||||
|
@ -2035,15 +2036,15 @@ void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStr
|
||||||
if (LookDot > 0.9f)
|
if (LookDot > 0.9f)
|
||||||
{
|
{
|
||||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(DesiredStructure);
|
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(DesiredStructure);
|
||||||
RegisterBotAlienBuildAttempt(pBot, Location, DesiredStructure);
|
RegisterBotAlienBuildAttempt(pBot, Task, Task->TaskLocation, DesiredStructure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap)
|
void BotAlienBuildResTower(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const AvHAIResourceNode* NodeToCap)
|
||||||
{
|
{
|
||||||
if (NodeToCap->bIsOccupied) { return; }
|
if (NodeToCap->bIsOccupied) { return; }
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||||
|
|
||||||
float CurrDist = vDist2DSq(pBot->CurrentFloorPosition, NodeToCap->Location);
|
float CurrDist = vDist2DSq(pBot->CurrentFloorPosition, NodeToCap->Location);
|
||||||
|
|
||||||
|
@ -2090,17 +2091,17 @@ void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap
|
||||||
if (LookDot > 0.9f)
|
if (LookDot > 0.9f)
|
||||||
{
|
{
|
||||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(STRUCTURE_ALIEN_RESTOWER);
|
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(STRUCTURE_ALIEN_RESTOWER);
|
||||||
RegisterBotAlienBuildAttempt(pBot, NodeToCap->Location, STRUCTURE_ALIEN_RESTOWER);
|
RegisterBotAlienBuildAttempt(pBot, Task, NodeToCap->Location, STRUCTURE_ALIEN_RESTOWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild)
|
void BotAlienBuildHive(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const AvHAIHiveDefinition* HiveToBuild)
|
||||||
{
|
{
|
||||||
// Do nothing if the hive is already built / under construction
|
// Do nothing if the hive is already built / under construction
|
||||||
if (HiveToBuild->Status != HIVE_STATUS_UNBUILT) { return; }
|
if (HiveToBuild->Status != HIVE_STATUS_UNBUILT) { return; }
|
||||||
|
|
||||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||||
|
|
||||||
if (vDist2DSq(pBot->Edict->v.origin, HiveToBuild->Location) > sqrf(UTIL_MetresToGoldSrcUnits(7.5f)))
|
if (vDist2DSq(pBot->Edict->v.origin, HiveToBuild->Location) > sqrf(UTIL_MetresToGoldSrcUnits(7.5f)))
|
||||||
{
|
{
|
||||||
|
@ -2139,7 +2140,7 @@ void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild
|
||||||
}
|
}
|
||||||
|
|
||||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(STRUCTURE_ALIEN_HIVE);
|
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(STRUCTURE_ALIEN_HIVE);
|
||||||
RegisterBotAlienBuildAttempt(pBot, HiveToBuild->Location, STRUCTURE_ALIEN_HIVE);
|
RegisterBotAlienBuildAttempt(pBot, Task, HiveToBuild->Location, STRUCTURE_ALIEN_HIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2170,14 +2171,14 @@ void BotAlienHealTarget(AvHAIPlayer* pBot, edict_t* HealTarget)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure)
|
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure)
|
||||||
{
|
{
|
||||||
pBot->ActiveBuildInfo.AttemptedLocation = PlacementLocation;
|
Task->ActiveBuildInfo.AttemptedLocation = PlacementLocation;
|
||||||
pBot->ActiveBuildInfo.BuildAttemptTime = gpGlobals->time;
|
Task->ActiveBuildInfo.BuildAttemptTime = gpGlobals->time;
|
||||||
pBot->ActiveBuildInfo.LinkedStructure = nullptr;
|
Task->ActiveBuildInfo.LinkedStructure = nullptr;
|
||||||
pBot->ActiveBuildInfo.NumAttempts++;
|
Task->ActiveBuildInfo.NumAttempts++;
|
||||||
pBot->ActiveBuildInfo.AttemptedStructureType = DesiredStructure;
|
Task->ActiveBuildInfo.AttemptedStructureType = DesiredStructure;
|
||||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_PENDING;
|
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlienProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void AlienProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
@ -2252,7 +2253,7 @@ void AlienProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
// We have enough resources to place the tower (includes cost of evolving to gorge if necessary)
|
// We have enough resources to place the tower (includes cost of evolving to gorge if necessary)
|
||||||
if (pBot->Player->GetResources() >= NumResourcesRequired)
|
if (pBot->Player->GetResources() >= NumResourcesRequired)
|
||||||
{
|
{
|
||||||
BotAlienBuildResTower(pBot, ResNodeIndex);
|
BotAlienBuildResTower(pBot, Task, ResNodeIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,11 +109,11 @@ AvHAIPlayer* GetFirstBotWithReinforceTask(AvHTeamNumber Team, edict_t* Reinforce
|
||||||
|
|
||||||
void UTIL_ClearGuardInfo(AvHAIPlayer* pBot);
|
void UTIL_ClearGuardInfo(AvHAIPlayer* pBot);
|
||||||
|
|
||||||
void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStructureType DesiredStructure);
|
void BotAlienPlaceChamber(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, AvHAIDeployableStructureType DesiredStructure);
|
||||||
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild);
|
void BotAlienBuildHive(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const AvHAIHiveDefinition* HiveToBuild);
|
||||||
void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap);
|
void BotAlienBuildResTower(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const AvHAIResourceNode* NodeToCap);
|
||||||
void BotAlienHealTarget(AvHAIPlayer* pBot, edict_t* HealTarget);
|
void BotAlienHealTarget(AvHAIPlayer* pBot, edict_t* HealTarget);
|
||||||
|
|
||||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure);
|
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -3609,10 +3609,7 @@ void AvHGamerules::Think(void)
|
||||||
|
|
||||||
if (avh_botsenabled.value > 0)
|
if (avh_botsenabled.value > 0)
|
||||||
{
|
{
|
||||||
if (this->GetGameStarted())
|
AIMGR_UpdateAIMapData();
|
||||||
{
|
|
||||||
AIMGR_UpdateAIMapData();
|
|
||||||
}
|
|
||||||
|
|
||||||
AIMGR_UpdateAIPlayers();
|
AIMGR_UpdateAIPlayers();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue