mirror of
https://github.com/ENSL/NS.git
synced 2024-11-25 05:51:11 +00:00
General improvements
* AI Commander will now attempt to place turret factories close to any existing turrets to prevent inactive turrets being left behind * Aliens will not try to pursue enemies who have teleported away (unless they teleported close by) * Fixed a bug where bots would not target the nearest sentry/OC to engage * Improved how marines attack OCs, particularly how they take cover to reload
This commit is contained in:
parent
a01d8a6708
commit
290ad067eb
7 changed files with 241 additions and 23 deletions
|
@ -4215,7 +4215,7 @@ void AICOMM_DeployBases(AvHAIPlayer* pBot)
|
||||||
{
|
{
|
||||||
// Make sure that our siege guy is somewhere we can build
|
// Make sure that our siege guy is somewhere we can build
|
||||||
Vector ProjectedPoint = UTIL_ProjectPointToNavmesh(ThisPlayer->pev->origin, Vector(100.0f, 100.0f, 100.0f), GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
|
Vector ProjectedPoint = UTIL_ProjectPointToNavmesh(ThisPlayer->pev->origin, Vector(100.0f, 100.0f, 100.0f), GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
|
||||||
if (!vIsZero(ProjectedPoint))
|
if (!vIsZero(ProjectedPoint) && vDist2DSq(ProjectedPoint, ThisHive->Location) < sqrf(BALANCE_VAR(kSiegeTurretRange)))
|
||||||
{
|
{
|
||||||
AICOMM_AddNewBase(pBot, ProjectedPoint, MARINE_BASE_SIEGE);
|
AICOMM_AddNewBase(pBot, ProjectedPoint, MARINE_BASE_SIEGE);
|
||||||
}
|
}
|
||||||
|
@ -4982,6 +4982,8 @@ bool AICOMM_BuildOutMainBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
int NumTurrets = 0;
|
int NumTurrets = 0;
|
||||||
int NumIncomplete = 0;
|
int NumIncomplete = 0;
|
||||||
|
|
||||||
|
vector<Vector> TurretLocations;
|
||||||
|
|
||||||
int DesiredInfPortals = (int)ceilf((float)AIMGR_GetNumPlayersOnTeam(BotTeam) / 4.0f);
|
int DesiredInfPortals = (int)ceilf((float)AIMGR_GetNumPlayersOnTeam(BotTeam) / 4.0f);
|
||||||
|
|
||||||
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
||||||
|
@ -5056,6 +5058,7 @@ bool AICOMM_BuildOutMainBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
break;
|
break;
|
||||||
case STRUCTURE_MARINE_TURRET:
|
case STRUCTURE_MARINE_TURRET:
|
||||||
NumTurrets++;
|
NumTurrets++;
|
||||||
|
TurretLocations.push_back(StructureRef.Location);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -5209,6 +5212,30 @@ bool AICOMM_BuildOutMainBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
if (bSuccess) { return true; }
|
if (bSuccess) { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NumTurrets > 0)
|
||||||
|
{
|
||||||
|
Vector Centroid = ZERO_VECTOR;
|
||||||
|
|
||||||
|
for (auto tLocs = TurretLocations.begin(); tLocs != TurretLocations.end(); tLocs++)
|
||||||
|
{
|
||||||
|
Centroid = Centroid + *tLocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Centroid = Centroid / TurretLocations.size();
|
||||||
|
|
||||||
|
if (!vIsZero(Centroid))
|
||||||
|
{
|
||||||
|
Vector CentroidBuildLocation = UTIL_ProjectPointToNavmesh(Centroid, GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
|
||||||
|
|
||||||
|
if (!vIsZero(CentroidBuildLocation))
|
||||||
|
{
|
||||||
|
bool bSuccess = AICOMM_AddStructureToBase(pBot, STRUCTURE_MARINE_TURRETFACTORY, CentroidBuildLocation, BaseToBuildOut);
|
||||||
|
|
||||||
|
if (bSuccess) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumAttempts = 0;
|
int NumAttempts = 0;
|
||||||
|
|
||||||
while (NumAttempts < 5)
|
while (NumAttempts < 5)
|
||||||
|
@ -5475,6 +5502,8 @@ bool AICOMM_BuildOutOutpost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
int NumTurrets = 0;
|
int NumTurrets = 0;
|
||||||
int NumIncomplete = 0;
|
int NumIncomplete = 0;
|
||||||
|
|
||||||
|
vector<Vector> TurretLocations;
|
||||||
|
|
||||||
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
||||||
{
|
{
|
||||||
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
||||||
|
@ -5499,6 +5528,7 @@ bool AICOMM_BuildOutOutpost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
break;
|
break;
|
||||||
case STRUCTURE_MARINE_TURRET:
|
case STRUCTURE_MARINE_TURRET:
|
||||||
NumTurrets++;
|
NumTurrets++;
|
||||||
|
TurretLocations.push_back(StructureRef.Location);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -5584,6 +5614,33 @@ bool AICOMM_BuildOutOutpost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
if (bSuccess) { return true; }
|
if (bSuccess) { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StructureToDeploy == STRUCTURE_MARINE_TURRETFACTORY)
|
||||||
|
{
|
||||||
|
if (NumTurrets > 0)
|
||||||
|
{
|
||||||
|
Vector Centroid = ZERO_VECTOR;
|
||||||
|
|
||||||
|
for (auto tLocs = TurretLocations.begin(); tLocs != TurretLocations.end(); tLocs++)
|
||||||
|
{
|
||||||
|
Centroid = Centroid + *tLocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Centroid = Centroid / TurretLocations.size();
|
||||||
|
|
||||||
|
if (!vIsZero(Centroid))
|
||||||
|
{
|
||||||
|
Vector CentroidBuildLocation = UTIL_ProjectPointToNavmesh(Centroid, GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
|
||||||
|
|
||||||
|
if (!vIsZero(CentroidBuildLocation))
|
||||||
|
{
|
||||||
|
bool bSuccess = AICOMM_AddStructureToBase(pBot, StructureToDeploy, CentroidBuildLocation, BaseToBuildOut);
|
||||||
|
|
||||||
|
if (bSuccess) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumAttempts = 0;
|
int NumAttempts = 0;
|
||||||
|
|
||||||
while (NumAttempts < 5)
|
while (NumAttempts < 5)
|
||||||
|
@ -5624,6 +5681,8 @@ bool AICOMM_BuildOutSiege(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
int NumTurrets = 0;
|
int NumTurrets = 0;
|
||||||
int NumIncomplete = 0;
|
int NumIncomplete = 0;
|
||||||
|
|
||||||
|
vector<Vector> TurretLocations;
|
||||||
|
|
||||||
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
||||||
{
|
{
|
||||||
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
||||||
|
@ -5651,6 +5710,7 @@ bool AICOMM_BuildOutSiege(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
break;
|
break;
|
||||||
case STRUCTURE_MARINE_SIEGETURRET:
|
case STRUCTURE_MARINE_SIEGETURRET:
|
||||||
NumTurrets++;
|
NumTurrets++;
|
||||||
|
TurretLocations.push_back(StructureRef.Location);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -5710,6 +5770,30 @@ bool AICOMM_BuildOutSiege(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||||
|
|
||||||
int NumAttempts = 0;
|
int NumAttempts = 0;
|
||||||
|
|
||||||
|
if (NumTurrets > 0)
|
||||||
|
{
|
||||||
|
Vector Centroid = ZERO_VECTOR;
|
||||||
|
|
||||||
|
for (auto tLocs = TurretLocations.begin(); tLocs != TurretLocations.end(); tLocs++)
|
||||||
|
{
|
||||||
|
Centroid = Centroid + *tLocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Centroid = Centroid / TurretLocations.size();
|
||||||
|
|
||||||
|
if (!vIsZero(Centroid))
|
||||||
|
{
|
||||||
|
Vector BuildLocation = UTIL_ProjectPointToNavmesh(Centroid, GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
|
||||||
|
|
||||||
|
if (!vIsZero(BuildLocation))
|
||||||
|
{
|
||||||
|
bool bSuccess = AICOMM_AddStructureToBase(pBot, StructureToDeploy, BuildLocation, BaseToBuildOut);
|
||||||
|
|
||||||
|
if (bSuccess) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (NumAttempts < 5)
|
while (NumAttempts < 5)
|
||||||
{
|
{
|
||||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseToBuildOut->BaseLocation, UTIL_MetresToGoldSrcUnits(2.0f + NumAttempts));
|
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseToBuildOut->BaseLocation, UTIL_MetresToGoldSrcUnits(2.0f + NumAttempts));
|
||||||
|
@ -5820,6 +5904,8 @@ bool AICOMM_BuildOutGuardPost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut
|
||||||
int NumTurrets = 0;
|
int NumTurrets = 0;
|
||||||
int NumIncomplete = 0;
|
int NumIncomplete = 0;
|
||||||
|
|
||||||
|
vector<Vector> TurretLocations;
|
||||||
|
|
||||||
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
||||||
{
|
{
|
||||||
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
||||||
|
@ -5839,6 +5925,7 @@ bool AICOMM_BuildOutGuardPost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut
|
||||||
else if (StructureRef.StructureType == STRUCTURE_MARINE_TURRET)
|
else if (StructureRef.StructureType == STRUCTURE_MARINE_TURRET)
|
||||||
{
|
{
|
||||||
NumTurrets++;
|
NumTurrets++;
|
||||||
|
TurretLocations.push_back(StructureRef.Location);
|
||||||
}
|
}
|
||||||
else if (StructureRef.StructureType == STRUCTURE_MARINE_OBSERVATORY)
|
else if (StructureRef.StructureType == STRUCTURE_MARINE_OBSERVATORY)
|
||||||
{
|
{
|
||||||
|
@ -5919,6 +6006,33 @@ bool AICOMM_BuildOutGuardPost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut
|
||||||
if (bSuccess) { return true; }
|
if (bSuccess) { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StructureToDeploy == STRUCTURE_MARINE_TURRETFACTORY)
|
||||||
|
{
|
||||||
|
if (NumTurrets > 0)
|
||||||
|
{
|
||||||
|
Vector Centroid = ZERO_VECTOR;
|
||||||
|
|
||||||
|
for (auto tLocs = TurretLocations.begin(); tLocs != TurretLocations.end(); tLocs++)
|
||||||
|
{
|
||||||
|
Centroid = Centroid + *tLocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Centroid = Centroid / TurretLocations.size();
|
||||||
|
|
||||||
|
if (!vIsZero(Centroid))
|
||||||
|
{
|
||||||
|
Vector CentroidBuildLocation = UTIL_ProjectPointToNavmesh(Centroid, GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE));
|
||||||
|
|
||||||
|
if (!vIsZero(CentroidBuildLocation))
|
||||||
|
{
|
||||||
|
bool bSuccess = AICOMM_AddStructureToBase(pBot, StructureToDeploy, CentroidBuildLocation, BaseToBuildOut);
|
||||||
|
|
||||||
|
if (bSuccess) { return true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumAttempts = 0;
|
int NumAttempts = 0;
|
||||||
|
|
||||||
while (NumAttempts < 5)
|
while (NumAttempts < 5)
|
||||||
|
@ -5953,7 +6067,7 @@ AvHAIMarineBase* AICOMM_AddNewBase(AvHAIPlayer* pBot, Vector NewBaseLocation, Ma
|
||||||
|
|
||||||
bool AICOMM_AddStructureToBase(AvHAIPlayer* pBot, AvHAIDeployableStructureType StructureToDeploy, Vector BuildLocation, AvHAIMarineBase* BaseToAdd)
|
bool AICOMM_AddStructureToBase(AvHAIPlayer* pBot, AvHAIDeployableStructureType StructureToDeploy, Vector BuildLocation, AvHAIMarineBase* BaseToAdd)
|
||||||
{
|
{
|
||||||
if (vIsZero(BuildLocation)) { return false; }
|
if (!BaseToAdd || vIsZero(BuildLocation)) { return false; }
|
||||||
|
|
||||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, BuildLocation);
|
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, BuildLocation);
|
||||||
|
|
||||||
|
@ -5961,6 +6075,18 @@ bool AICOMM_AddStructureToBase(AvHAIPlayer* pBot, AvHAIDeployableStructureType S
|
||||||
{
|
{
|
||||||
BaseToAdd->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
BaseToAdd->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||||
BaseToAdd->bBaseInitialised = true;
|
BaseToAdd->bBaseInitialised = true;
|
||||||
|
if (BaseToAdd->BaseType == MARINE_BASE_MAINBASE)
|
||||||
|
{
|
||||||
|
DeployedStructure->Purpose = STRUCTURE_PURPOSE_BASE;
|
||||||
|
}
|
||||||
|
else if (BaseToAdd->BaseType == MARINE_BASE_SIEGE)
|
||||||
|
{
|
||||||
|
DeployedStructure->Purpose = STRUCTURE_PURPOSE_SIEGE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeployedStructure->Purpose = STRUCTURE_PURPOSE_FORTIFY;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -768,6 +768,8 @@ typedef struct AVH_AI_PLAYER
|
||||||
|
|
||||||
float LastRequestTime = 0.0f; // When bot last used a voice line to request something. Prevents spam
|
float LastRequestTime = 0.0f; // When bot last used a voice line to request something. Prevents spam
|
||||||
|
|
||||||
|
float LastTeleportTime = 0.0f; // Last time the bot teleported somewhere
|
||||||
|
|
||||||
Vector DesiredLookDirection = g_vecZero; // What view angle is the bot currently turning towards
|
Vector DesiredLookDirection = g_vecZero; // What view angle is the bot currently turning towards
|
||||||
Vector InterpolatedLookDirection = g_vecZero; // Used to smoothly interpolate the bot's view rather than snap instantly like an aimbot
|
Vector InterpolatedLookDirection = g_vecZero; // Used to smoothly interpolate the bot's view rather than snap instantly like an aimbot
|
||||||
edict_t* LookTarget = nullptr; // Used to work out what view angle is needed to look at the desired entity
|
edict_t* LookTarget = nullptr; // Used to work out what view angle is needed to look at the desired entity
|
||||||
|
|
|
@ -3771,10 +3771,19 @@ void BlockedMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoi
|
||||||
vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
vForward = UTIL_GetVectorNormal2D(EndPoint - StartPoint);
|
||||||
|
|
||||||
if (vIsZero(vForward))
|
if (vIsZero(vForward))
|
||||||
|
{
|
||||||
|
if (pBot->BotNavInfo.CurrentPathPoint < pBot->BotNavInfo.CurrentPath.size() - 1)
|
||||||
|
{
|
||||||
|
bot_path_node NextPathNode = pBot->BotNavInfo.CurrentPath[pBot->BotNavInfo.CurrentPathPoint + 1];
|
||||||
|
|
||||||
|
vForward = UTIL_GetVectorNormal2D(NextPathNode.Location - pBot->Edict->v.origin);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
vForward = UTIL_GetForwardVector2D(pBot->Edict->v.angles);
|
vForward = UTIL_GetForwardVector2D(pBot->Edict->v.angles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pBot->desiredMovementDir = vForward;
|
pBot->desiredMovementDir = vForward;
|
||||||
|
|
||||||
|
@ -6831,6 +6840,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
||||||
|
|
||||||
if (!bSucceeded)
|
if (!bSucceeded)
|
||||||
{
|
{
|
||||||
|
const char* botName = STRING(pBot->Edict->v.netname);
|
||||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
|
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
|
||||||
|
|
||||||
if (!UTIL_PointIsOnNavmesh(pBot->CollisionHullBottomLocation, pBot->BotNavInfo.NavProfile))
|
if (!UTIL_PointIsOnNavmesh(pBot->CollisionHullBottomLocation, pBot->BotNavInfo.NavProfile))
|
||||||
|
@ -6839,7 +6849,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
||||||
{
|
{
|
||||||
MoveDirectlyTo(pBot, BotNavInfo->LastNavMeshPosition);
|
MoveDirectlyTo(pBot, BotNavInfo->LastNavMeshPosition);
|
||||||
|
|
||||||
if (vDist2DSq(pBot->CurrentFloorPosition, BotNavInfo->LastNavMeshPosition) < sqrf(8.0f))
|
if (vDist2DSq(pBot->CurrentFloorPosition, BotNavInfo->LastNavMeshPosition) < 1.0f)
|
||||||
{
|
{
|
||||||
BotNavInfo->LastNavMeshPosition = g_vecZero;
|
BotNavInfo->LastNavMeshPosition = g_vecZero;
|
||||||
}
|
}
|
||||||
|
@ -6848,7 +6858,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!vIsZero(BotNavInfo->UnstuckMoveLocation) && vDist2DSq(pBot->CurrentFloorPosition, BotNavInfo->UnstuckMoveLocation) < sqrf(8.0f))
|
if (!vIsZero(BotNavInfo->UnstuckMoveLocation) && vDist2DSq(pBot->CurrentFloorPosition, BotNavInfo->UnstuckMoveLocation) < 1.0f)
|
||||||
{
|
{
|
||||||
BotNavInfo->UnstuckMoveLocation = ZERO_VECTOR;
|
BotNavInfo->UnstuckMoveLocation = ZERO_VECTOR;
|
||||||
}
|
}
|
||||||
|
@ -6866,8 +6876,28 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!vIsZero(BotNavInfo->UnstuckMoveLocation) && vDist2DSq(pBot->CurrentFloorPosition, BotNavInfo->UnstuckMoveLocation) < 1.0f)
|
||||||
|
{
|
||||||
|
BotNavInfo->UnstuckMoveLocation = ZERO_VECTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vIsZero(BotNavInfo->UnstuckMoveLocation))
|
||||||
|
{
|
||||||
|
BotNavInfo->UnstuckMoveLocation = FindClosestPointBackOnPath(pBot, Destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vIsZero(BotNavInfo->UnstuckMoveLocation))
|
||||||
|
{
|
||||||
|
MoveDirectlyTo(pBot, BotNavInfo->UnstuckMoveLocation);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
MoveDirectlyTo(pBot, Destination);
|
MoveDirectlyTo(pBot, Destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1433,6 +1433,20 @@ void BotUpdateView(AvHAIPlayer* pBot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detect if a player has teleported away. Basically, if the player has moved significantly far away from where they were last detected in a very short space of time
|
||||||
|
// then they've teleported and we should clear their tracking info. This should work for phase gates, but also any trigger_teleport in the map (e.g. co_daimos phase gates)
|
||||||
|
if (!vIsZero(TrackingInfo->LastDetectedLocation) && gpGlobals->time - TrackingInfo->LastDetectedTime < 1.0f)
|
||||||
|
{
|
||||||
|
if (vDist2DSq(PlayerEdict->v.origin, TrackingInfo->LastDetectedLocation) > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||||
|
{
|
||||||
|
if (!UTIL_PlayerHasLOSToEntity(pBot->Edict, PlayerEdict, UTIL_MetresToGoldSrcUnits(20.0f), false))
|
||||||
|
{
|
||||||
|
BotClearEnemyTrackingInfo(TrackingInfo);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector VisiblePoint = GetVisiblePointOnPlayerFromObserver(pBot->Edict, PlayerEdict);
|
Vector VisiblePoint = GetVisiblePointOnPlayerFromObserver(pBot->Edict, PlayerEdict);
|
||||||
TrackingInfo->VisiblePointOnPlayer = VisiblePoint;
|
TrackingInfo->VisiblePointOnPlayer = VisiblePoint;
|
||||||
|
|
||||||
|
@ -1518,7 +1532,7 @@ void BotUpdateView(AvHAIPlayer* pBot)
|
||||||
AvHAIBuildableStructure ThisTurret = (*it);
|
AvHAIBuildableStructure ThisTurret = (*it);
|
||||||
AvHTurret* TurretRef = dynamic_cast<AvHTurret*>(ThisTurret.EntityRef);
|
AvHTurret* TurretRef = dynamic_cast<AvHTurret*>(ThisTurret.EntityRef);
|
||||||
|
|
||||||
if (TurretRef && TurretRef->GetIsValidTarget(pBot->Player))
|
if (TurretRef && TurretRef->GetIsValidTarget(pBot->Player) && !vIsZero(GetVisiblePointOnPlayerFromObserver(ThisTurret.edict, pBot->Edict)))
|
||||||
{
|
{
|
||||||
bIsInRangeOfEnemyTurret = true;
|
bIsInRangeOfEnemyTurret = true;
|
||||||
pBot->DangerTurrets.push_back(ThisTurret);
|
pBot->DangerTurrets.push_back(ThisTurret);
|
||||||
|
@ -1723,11 +1737,17 @@ void StartNewBotFrame(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
pBot->CurrentFloorPosition = NewFloorPosition;
|
pBot->CurrentFloorPosition = NewFloorPosition;
|
||||||
|
|
||||||
if (vDist3DSq(pBot->BotNavInfo.LastNavMeshCheckPosition, pBot->CurrentFloorPosition) > sqrf(16.0f))
|
Vector ProjectPoint = (IsPlayerLerk(pBot->Edict)) ? pBot->CurrentFloorPosition : pBot->CollisionHullBottomLocation;
|
||||||
|
|
||||||
|
if (vDist3DSq(pBot->BotNavInfo.LastNavMeshCheckPosition, ProjectPoint) > sqrf(16.0f))
|
||||||
{
|
{
|
||||||
if (UTIL_PointIsReachable(pBot->BotNavInfo.NavProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), pBot->CurrentFloorPosition, 16.0f))
|
if (UTIL_PointIsReachable(pBot->BotNavInfo.NavProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), ProjectPoint, 16.0f))
|
||||||
{
|
{
|
||||||
pBot->BotNavInfo.LastNavMeshPosition = pBot->CurrentFloorPosition;
|
Vector NavPoint = UTIL_ProjectPointToNavmesh(ProjectPoint);
|
||||||
|
UTIL_AdjustPointAwayFromNavWall(NavPoint, 8.0f);
|
||||||
|
|
||||||
|
pBot->BotNavInfo.LastNavMeshPosition = NavPoint;
|
||||||
|
|
||||||
|
|
||||||
if (pBot->BotNavInfo.IsOnGround || IsPlayerLerk(pBot->Edict))
|
if (pBot->BotNavInfo.IsOnGround || IsPlayerLerk(pBot->Edict))
|
||||||
{
|
{
|
||||||
|
@ -1894,7 +1914,24 @@ void EndBotFrame(AvHAIPlayer* pBot)
|
||||||
|
|
||||||
void CustomThink(AvHAIPlayer* pBot)
|
void CustomThink(AvHAIPlayer* pBot)
|
||||||
{
|
{
|
||||||
MoveTo(pBot, UTIL_GetFloorUnderEntity(INDEXENT(1)), MOVESTYLE_NORMAL);
|
pBot->CurrentTask = &pBot->PrimaryBotTask;
|
||||||
|
|
||||||
|
AITASK_BotUpdateAndClearTasks(pBot);
|
||||||
|
|
||||||
|
if (pBot->CurrentTask->TaskType != TASK_ATTACK)
|
||||||
|
{
|
||||||
|
DeployableSearchFilter EnemyOCFilter;
|
||||||
|
EnemyOCFilter.DeployableTypes = STRUCTURE_ALIEN_OFFENCECHAMBER;
|
||||||
|
|
||||||
|
AvHAIBuildableStructure NearestOC = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &EnemyOCFilter);
|
||||||
|
|
||||||
|
if (NearestOC.IsValid())
|
||||||
|
{
|
||||||
|
AITASK_SetAttackTask(pBot, pBot->CurrentTask, NearestOC.edict, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BotProgressTask(pBot, pBot->CurrentTask);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4305,6 +4342,7 @@ void AIPlayerSetSecondaryMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
if (FNullEnt(NearestDangerTurret.edict) || ThisDist < MinDist)
|
if (FNullEnt(NearestDangerTurret.edict) || ThisDist < MinDist)
|
||||||
{
|
{
|
||||||
NearestDangerTurret = (*it);
|
NearestDangerTurret = (*it);
|
||||||
|
MinDist = ThisDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4615,6 +4653,9 @@ void AIPlayerNSAlienThink(AvHAIPlayer* pBot)
|
||||||
if (AlienCombatThink(pBot)) { return; }
|
if (AlienCombatThink(pBot)) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We've JUST tried placing a structure. Wait until we get confirmation of the structure being placed before doing anything else
|
||||||
|
if (pBot->CurrentTask && pBot->CurrentTask->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||||
|
|
||||||
bool bPlayerMustFinishPrimaryTask = AIPlayerMustFinishCurrentTask(pBot, &pBot->PrimaryBotTask);
|
bool bPlayerMustFinishPrimaryTask = AIPlayerMustFinishCurrentTask(pBot, &pBot->PrimaryBotTask);
|
||||||
|
|
||||||
if (!bPlayerMustFinishPrimaryTask)
|
if (!bPlayerMustFinishPrimaryTask)
|
||||||
|
@ -7124,6 +7165,7 @@ void AIPlayerSetSecondaryAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
if (FNullEnt(NearestDangerTurret.edict) || ThisDist < MinDist)
|
if (FNullEnt(NearestDangerTurret.edict) || ThisDist < MinDist)
|
||||||
{
|
{
|
||||||
NearestDangerTurret = (*it);
|
NearestDangerTurret = (*it);
|
||||||
|
MinDist = ThisDist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7521,7 +7563,10 @@ void AIPlayerSetWantsAndNeedsAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
bInMiddleOfMove = CurrentMove.flag != SAMPLE_POLYFLAGS_WALK;
|
bInMiddleOfMove = CurrentMove.flag != SAMPLE_POLYFLAGS_WALK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bInMiddleOfMove)
|
// Don't get upgrades if we're not in our regular desired life form, e.g. we've temporarily gone gorge to drop a res tower
|
||||||
|
bool bTempEvolved = (pBot->BotRole == BOT_ROLE_BUILDER && !IsPlayerGorge(pBot->Edict)) || (pBot->BotRole != BOT_ROLE_BUILDER && IsPlayerGorge(pBot->Edict));
|
||||||
|
|
||||||
|
if (!bInMiddleOfMove && !bTempEvolved)
|
||||||
{
|
{
|
||||||
if (!PlayerHasAlienUpgradeOfType(pBot->Edict, HIVE_TECH_DEFENCE) && AITAC_IsAlienUpgradeAvailableForTeam(pBot->Player->GetTeam(), HIVE_TECH_DEFENCE))
|
if (!PlayerHasAlienUpgradeOfType(pBot->Edict, HIVE_TECH_DEFENCE) && AITAC_IsAlienUpgradeAvailableForTeam(pBot->Player->GetTeam(), HIVE_TECH_DEFENCE))
|
||||||
{
|
{
|
||||||
|
@ -8894,4 +8939,5 @@ void OnBotTeleport(AvHAIPlayer* pBot)
|
||||||
ClearBotStuck(pBot);
|
ClearBotStuck(pBot);
|
||||||
ClearBotStuckMovement(pBot);
|
ClearBotStuckMovement(pBot);
|
||||||
pBot->BotNavInfo.LastOpenLocation = ZERO_VECTOR;
|
pBot->BotNavInfo.LastOpenLocation = ZERO_VECTOR;
|
||||||
|
pBot->LastTeleportTime = gpGlobals->time;
|
||||||
}
|
}
|
|
@ -644,6 +644,10 @@ void AIMGR_UpdateAIPlayers()
|
||||||
|
|
||||||
BotUpdateViewRotation(bot, FrameDelta);
|
BotUpdateViewRotation(bot, FrameDelta);
|
||||||
|
|
||||||
|
// Need to reset this since impulses generally should only be called once at a time, so this
|
||||||
|
// prevents it from being called on consecutive frames if this bot isn't running its think routine every frame
|
||||||
|
bot->Impulse = 0;
|
||||||
|
|
||||||
if (bHasRoundStarted)
|
if (bHasRoundStarted)
|
||||||
{
|
{
|
||||||
if (IsPlayerCommander(bot->Edict))
|
if (IsPlayerCommander(bot->Edict))
|
||||||
|
|
|
@ -1146,6 +1146,11 @@ void AITAC_PopulateHiveData()
|
||||||
|
|
||||||
void AITAC_RefreshHiveData()
|
void AITAC_RefreshHiveData()
|
||||||
{
|
{
|
||||||
|
if (ResourceNodes.size() == 0)
|
||||||
|
{
|
||||||
|
AITAC_PopulateResourceNodes();
|
||||||
|
}
|
||||||
|
|
||||||
if (Hives.size() == 0)
|
if (Hives.size() == 0)
|
||||||
{
|
{
|
||||||
AITAC_PopulateHiveData();
|
AITAC_PopulateHiveData();
|
||||||
|
@ -4827,7 +4832,7 @@ bool AITAC_ShouldBotBuildHive(AvHAIPlayer* pBot, AvHAIHiveDefinition** EligibleH
|
||||||
HiveCost += BALANCE_VAR(kGorgeCost);
|
HiveCost += BALANCE_VAR(kGorgeCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pBot->Player->GetResources() < HiveCost) { return false; }
|
if (pBot->Player->GetResources() < HiveCost - 10) { return false; }
|
||||||
|
|
||||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||||
|
|
|
@ -1007,8 +1007,6 @@ bool AITASK_IsMarineSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask*
|
||||||
|
|
||||||
if (!HiveToSecure || HiveToSecure->Status != HIVE_STATUS_UNBUILT) { return false; }
|
if (!HiveToSecure || HiveToSecure->Status != HIVE_STATUS_UNBUILT) { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// A marine bot will consider their "secure hive" task completed if the following structures have been fully built:
|
// A marine bot will consider their "secure hive" task completed if the following structures have been fully built:
|
||||||
// Phase gate (only if tech available)
|
// Phase gate (only if tech available)
|
||||||
// Turret factory (regular or advanced)
|
// Turret factory (regular or advanced)
|
||||||
|
@ -1380,6 +1378,7 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
// 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 (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED || Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_SUCCESS)
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED || Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_SUCCESS)
|
||||||
{
|
{
|
||||||
|
pBot->Impulse = 0;
|
||||||
Task->TaskStartedTime = gpGlobals->time;
|
Task->TaskStartedTime = gpGlobals->time;
|
||||||
Task->TaskLocation = ZERO_VECTOR;
|
Task->TaskLocation = ZERO_VECTOR;
|
||||||
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
||||||
|
@ -1817,7 +1816,7 @@ void BotProgressAttackTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
AvHTurret* TurretRef = dynamic_cast<AvHTurret*>(CBaseEntity::Instance(Task->TaskTarget));
|
AvHTurret* TurretRef = dynamic_cast<AvHTurret*>(CBaseEntity::Instance(Task->TaskTarget));
|
||||||
|
|
||||||
if (TurretRef && TurretRef->GetIsValidTarget(pBot->Player))
|
if (TurretRef && TurretRef->GetIsValidTarget(pBot->Player) && !vIsZero(GetVisiblePointOnPlayerFromObserver(Task->TaskTarget, pBot->Edict)))
|
||||||
{
|
{
|
||||||
if (vIsZero(pBot->LastSafeLocation))
|
if (vIsZero(pBot->LastSafeLocation))
|
||||||
{
|
{
|
||||||
|
@ -1825,6 +1824,7 @@ void BotProgressAttackTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
}
|
}
|
||||||
|
|
||||||
MoveTo(pBot, pBot->LastSafeLocation, MOVESTYLE_NORMAL);
|
MoveTo(pBot, pBot->LastSafeLocation, MOVESTYLE_NORMAL);
|
||||||
|
BotLookAt(pBot, Task->TaskTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2908,7 +2908,6 @@ void MarineProgressSecureHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
StructureFilter.ReachabilityTeam = BotTeam;
|
StructureFilter.ReachabilityTeam = BotTeam;
|
||||||
StructureFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
StructureFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||||
StructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
StructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_FORTIFY;
|
|
||||||
|
|
||||||
vector<AvHAIBuildableStructure> BuildableStructures = AITAC_FindAllDeployables(Hive->FloorLocation, &StructureFilter);
|
vector<AvHAIBuildableStructure> BuildableStructures = AITAC_FindAllDeployables(Hive->FloorLocation, &StructureFilter);
|
||||||
|
|
||||||
|
@ -2988,10 +2987,10 @@ void MarineProgressSecureHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
{
|
{
|
||||||
DeployableSearchFilter EnemyStructures;
|
DeployableSearchFilter EnemyStructures;
|
||||||
EnemyStructures.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
EnemyStructures.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||||
EnemyStructures.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
|
||||||
EnemyStructures.DeployableTeam = EnemyTeam;
|
EnemyStructures.DeployableTeam = EnemyTeam;
|
||||||
EnemyStructures.ReachabilityTeam = BotTeam;
|
EnemyStructures.ReachabilityTeam = BotTeam;
|
||||||
EnemyStructures.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
EnemyStructures.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||||
|
EnemyStructures.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
||||||
|
|
||||||
AvHAIBuildableStructure EnemyStructure = AITAC_FindClosestDeployableToLocation(Hive->FloorLocation, &EnemyStructures);
|
AvHAIBuildableStructure EnemyStructure = AITAC_FindClosestDeployableToLocation(Hive->FloorLocation, &EnemyStructures);
|
||||||
|
|
||||||
|
@ -3113,8 +3112,6 @@ void MarineProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
|
||||||
BotGuardLocation(pBot, Task->TaskLocation);
|
BotGuardLocation(pBot, Task->TaskLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotProgressAssaultMarineBaseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
void BotProgressAssaultMarineBaseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||||
|
@ -3809,7 +3806,13 @@ void AITASK_SetMoveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const Vector L
|
||||||
|
|
||||||
void AITASK_SetBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const AvHAIDeployableStructureType StructureType, const Vector Location, const bool bIsUrgent)
|
void AITASK_SetBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, const AvHAIDeployableStructureType StructureType, const Vector Location, const bool bIsUrgent)
|
||||||
{
|
{
|
||||||
if (Task->TaskType == TASK_BUILD && Task->StructureType == StructureType && vDist2DSq(Task->TaskLocation, Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f))) { return; }
|
if (Task->TaskType == TASK_BUILD && Task->StructureType == StructureType && vDist2DSq(Task->TaskLocation, Location) < sqrf(UTIL_MetresToGoldSrcUnits(1.0f)))
|
||||||
|
{
|
||||||
|
Task->bTaskIsUrgent = bIsUrgent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||||
|
|
||||||
AITASK_ClearBotTask(pBot, Task);
|
AITASK_ClearBotTask(pBot, Task);
|
||||||
|
|
||||||
|
@ -4028,6 +4031,8 @@ void AITASK_SetReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||||
|
|
||||||
AITASK_ClearBotTask(pBot, Task);
|
AITASK_ClearBotTask(pBot, Task);
|
||||||
|
|
||||||
if (FNullEnt(Target) || Target->v.deadflag != DEAD_NO) { return; }
|
if (FNullEnt(Target) || Target->v.deadflag != DEAD_NO) { return; }
|
||||||
|
|
Loading…
Reference in a new issue