mirror of
https://github.com/ENSL/NS.git
synced 2024-11-21 12:11:04 +00:00
Started base system
* Commanders now think in terms of establishing and building bases rather than placing individual structures. Should help reduce duplication of structures, selling structures unnecessarily etc. * Incomplete implementation: not currently used but will be once finished
This commit is contained in:
parent
73ff332b68
commit
0897cf15a0
8 changed files with 754 additions and 124 deletions
|
@ -13,9 +13,9 @@
|
|||
#include "AvHSharedUtil.h"
|
||||
#include "AvHServerUtil.h"
|
||||
|
||||
bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureType StructureToDeploy, const Vector Location, StructurePurpose Purpose)
|
||||
AvHAIBuildableStructure* AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureType StructureToDeploy, const Vector Location, StructurePurpose Purpose, bool bPlacedByHuman)
|
||||
{
|
||||
if (vIsZero(Location)) { return false; }
|
||||
if (vIsZero(Location)) { return nullptr; }
|
||||
|
||||
nav_profile WelderProfile = GetBaseNavProfile(MARINE_BASE_NAV_PROFILE);
|
||||
WelderProfile.Filters.addIncludeFlags(SAMPLE_POLYFLAGS_WELD);
|
||||
|
@ -34,31 +34,32 @@ bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureTyp
|
|||
// 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;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
string theErrorMessage;
|
||||
int theCost = 0;
|
||||
bool thePurchaseAllowed = pBot->Player->GetPurchaseAllowed(StructureID, theCost, &theErrorMessage);
|
||||
|
||||
if (!thePurchaseAllowed) { return false; }
|
||||
if (!thePurchaseAllowed) { return nullptr; }
|
||||
|
||||
CBaseEntity* NewStructureEntity = AvHSUBuildTechForPlayer(StructureID, BuildLocation, pBot->Player);
|
||||
|
||||
if (!NewStructureEntity) { return false; }
|
||||
if (!NewStructureEntity) { return nullptr; }
|
||||
|
||||
AvHAIBuildableStructure* NewStructure = AITAC_UpdateBuildableStructure(NewStructureEntity);
|
||||
|
||||
if (NewStructure)
|
||||
{
|
||||
NewStructure->Purpose = Purpose;
|
||||
NewStructure->bPlacedByHuman = bPlacedByHuman;
|
||||
}
|
||||
|
||||
pBot->Player->PayPurchaseCost(theCost);
|
||||
|
||||
pBot->next_commander_action_time = gpGlobals->time + 1.0f;
|
||||
|
||||
return true;
|
||||
return NewStructure;
|
||||
}
|
||||
|
||||
bool AICOMM_DeployItem(AvHAIPlayer* pBot, const AvHAIDeployableItemType ItemToDeploy, const Vector Location)
|
||||
|
@ -1049,9 +1050,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1069,9 +1070,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1084,9 +1085,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1129,9 +1130,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1141,7 +1142,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
{
|
||||
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, STRUCTURE_PURPOSE_BASE);
|
||||
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_BASE) != nullptr;
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kPhaseGateCost) + 10) { return true; }
|
||||
}
|
||||
}
|
||||
|
@ -1151,9 +1152,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (CappableNode)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_RESTOWER, CappableNode->Location);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_RESTOWER, CappableNode->Location);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kResourceTowerCost) + 10) { return true; }
|
||||
if (DeployedStructure || pBot->Player->GetResources() <= BALANCE_VAR(kResourceTowerCost) + 10) { return true; }
|
||||
|
||||
}
|
||||
|
||||
|
@ -1184,9 +1185,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1196,7 +1197,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
{
|
||||
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_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_BASE) != nullptr;
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kTurretFactoryCost) + 5) { return true; }
|
||||
|
||||
|
@ -1217,18 +1218,18 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), TF.Location, (BALANCE_VAR(kTurretFactoryBuildDistance) * 0.8f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kSentryCost) + 5) { return true; }
|
||||
if (DeployedStructure || pBot->Player->GetResources() <= BALANCE_VAR(kSentryCost) + 5) { return true; }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1259,9 +1260,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1271,7 +1272,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
{
|
||||
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, STRUCTURE_PURPOSE_BASE);
|
||||
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation, STRUCTURE_PURPOSE_BASE) != nullptr;
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kArmsLabCost) + 10) { return true; }
|
||||
}
|
||||
|
@ -1293,9 +1294,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1305,7 +1306,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
{
|
||||
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, STRUCTURE_PURPOSE_BASE);
|
||||
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation, STRUCTURE_PURPOSE_BASE) != nullptr;
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kObservatoryCost) + 10) { return true; }
|
||||
|
||||
|
@ -1373,9 +1374,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1387,9 +1388,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1401,9 +1402,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() < BALANCE_VAR(kPrototypeLabCost) + 20) { return true; }
|
||||
if (DeployedStructure || pBot->Player->GetResources() < BALANCE_VAR(kPrototypeLabCost) + 20) { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2099,27 +2100,27 @@ bool AICOMM_PerformNextSiegeHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefinit
|
|||
|
||||
if (!vIsZero(NextBuildPosition) && vDist2DSq(NextBuildPosition, HiveToSiege->Location) < sqrf(UTIL_MetresToGoldSrcUnits(22.0f)))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, NextStructure, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, NextStructure, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
NextBuildPosition = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), SiegeLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (!vIsZero(NextBuildPosition) && vDist2DSq(NextBuildPosition, HiveToSiege->Location) < sqrf(UTIL_MetresToGoldSrcUnits(22.0f)))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, NextStructure, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, NextStructure, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
NextBuildPosition = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), SiegeLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (!vIsZero(NextBuildPosition) && vDist2DSq(NextBuildPosition, HiveToSiege->Location) < sqrf(UTIL_MetresToGoldSrcUnits(22.0f)))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, NextStructure, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, NextStructure, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2145,27 +2146,27 @@ bool AICOMM_PerformNextSiegeHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefinit
|
|||
|
||||
if (!vIsZero(NextBuildPosition) && vDist2DSq(NextBuildPosition, HiveToSiege->Location) <= sqrf(BALANCE_VAR(kSiegeTurretRange)))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
NextBuildPosition = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), ExistingTF.Location, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (!vIsZero(NextBuildPosition) && vDist2DSq(NextBuildPosition, HiveToSiege->Location) <= sqrf(BALANCE_VAR(kSiegeTurretRange)))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
NextBuildPosition = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), ExistingTF.Location, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (!vIsZero(NextBuildPosition) && vDist2DSq(NextBuildPosition, HiveToSiege->Location) <= sqrf(BALANCE_VAR(kSiegeTurretRange)))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, NextBuildPosition, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2227,27 +2228,27 @@ bool AICOMM_PerformNextSecureHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefini
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), OutpostLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), HiveToSecure->FloorLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2268,9 +2269,9 @@ bool AICOMM_PerformNextSecureHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefini
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
// That failed, now try expanding the radius a bit and ignoring reachability
|
||||
|
@ -2278,9 +2279,9 @@ bool AICOMM_PerformNextSecureHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefini
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
// That failed too, try putting it anywhere near the hive location
|
||||
|
@ -2288,9 +2289,9 @@ bool AICOMM_PerformNextSecureHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefini
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2308,18 +2309,18 @@ bool AICOMM_PerformNextSecureHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefini
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), ExistingTF.Location, (BALANCE_VAR(kCommandStationBuildDistance) * 0.8f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_FORTIFY);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2336,9 +2337,9 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
DeployableSearchFilter ExistingPortalFilter;
|
||||
|
@ -2357,9 +2358,9 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2391,9 +2392,9 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2402,7 +2403,7 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
if (vIsZero(BuildLocation)) { return false; }
|
||||
|
||||
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE) != nullptr;
|
||||
}
|
||||
|
||||
bool AICOMM_CheckForNextRecycleAction(AvHAIPlayer* pBot)
|
||||
|
@ -3239,9 +3240,9 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
|
|||
}
|
||||
}
|
||||
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, ProjectedDeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, ProjectedDeployLocation, STRUCTURE_PURPOSE_GENERAL, true);
|
||||
|
||||
if (bSuccess)
|
||||
if (DeployedStructure)
|
||||
{
|
||||
NextRequest->bResponded = true;
|
||||
return true;
|
||||
|
@ -3252,9 +3253,9 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!vIsZero(DeployLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
|
||||
if (bSuccess)
|
||||
if (DeployedStructure)
|
||||
{
|
||||
NextRequest->bResponded = true;
|
||||
return true;
|
||||
|
@ -3265,9 +3266,9 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!vIsZero(DeployLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, DeployLocation, STRUCTURE_PURPOSE_GENERAL);
|
||||
|
||||
if (bSuccess)
|
||||
if (DeployedStructure)
|
||||
{
|
||||
NextRequest->bResponded = true;
|
||||
return true;
|
||||
|
@ -4012,9 +4013,9 @@ bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (CappableNode)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_RESTOWER, CappableNode->Location);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_RESTOWER, CappableNode->Location);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kResourceTowerCost) + 10) { return true; }
|
||||
if (DeployedStructure || pBot->Player->GetResources() <= BALANCE_VAR(kResourceTowerCost) + 10) { return true; }
|
||||
|
||||
}
|
||||
|
||||
|
@ -4035,27 +4036,27 @@ bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!vIsZero(BuildPoint))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
BuildPoint = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
|
||||
if (!vIsZero(BuildPoint))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
BuildPoint = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->RelocationSpot, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (!vIsZero(BuildPoint))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_COMMCHAIR, BuildPoint, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
if (DeployedStructure) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -4092,4 +4093,337 @@ bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot)
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AICOMM_BuildOutBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||
{
|
||||
if (!pBot || !BaseToBuildOut) { return false; }
|
||||
|
||||
switch (BaseToBuildOut->BaseType)
|
||||
{
|
||||
case MARINE_BASE_SIEGE:
|
||||
return AICOMM_BuildOutSiege(pBot, BaseToBuildOut);
|
||||
case MARINE_BASE_OUTPOST:
|
||||
return AICOMM_BuildOutOutpost(pBot, BaseToBuildOut);
|
||||
case MARINE_BASE_MAINBASE:
|
||||
return AICOMM_BuildOutMainBase(pBot, BaseToBuildOut);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AICOMM_BuildOutMainBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AICOMM_BuildOutOutpost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||
{
|
||||
AvHAIDeployableStructureType StructureToDeploy = STRUCTURE_NONE;
|
||||
|
||||
AvHAIBuildableStructure PhaseGate;
|
||||
AvHAIBuildableStructure Armoury;
|
||||
AvHAIBuildableStructure TurretFactory;
|
||||
AvHAIBuildableStructure Observatory;
|
||||
int NumTurrets = 0;
|
||||
int NumIncomplete = 0;
|
||||
|
||||
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
||||
|
||||
if (!StructureRef.IsCompleted()) { NumIncomplete++; }
|
||||
|
||||
switch (StructureRef.StructureType)
|
||||
{
|
||||
case STRUCTURE_MARINE_PHASEGATE:
|
||||
PhaseGate = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRETFACTORY:
|
||||
case STRUCTURE_MARINE_ADVTURRETFACTORY:
|
||||
TurretFactory = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_ARMOURY:
|
||||
case STRUCTURE_MARINE_ADVARMOURY:
|
||||
Armoury = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_OBSERVATORY:
|
||||
Observatory = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRET:
|
||||
NumTurrets++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (NumIncomplete > 0)
|
||||
{
|
||||
int NumBuilders = AITAC_GetNumPlayersOfTeamInArea(pBot->Player->GetTeam(), BaseToBuildOut->BaseLocation, UTIL_MetresToGoldSrcUnits(10.0f), false, nullptr, AVH_USER3_COMMANDER_PLAYER);
|
||||
|
||||
// Don't spam too many structures
|
||||
if (NumIncomplete >= NumBuilders) { return false; }
|
||||
}
|
||||
|
||||
if (PhaseGate.IsValid() && !PhaseGate.IsCompleted()) { return false; }
|
||||
|
||||
if (TurretFactory.IsValid() && !TurretFactory.IsCompleted()) { return false; }
|
||||
|
||||
if (!PhaseGate.IsValid() && AITAC_ResearchIsComplete(pBot->Player->GetTeam(), TECH_RESEARCH_PHASETECH))
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_PHASEGATE;
|
||||
}
|
||||
else if (!TurretFactory.IsValid())
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_TURRETFACTORY;
|
||||
}
|
||||
else if (TurretFactory.IsCompleted() && NumTurrets < 5)
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_TURRET;
|
||||
}
|
||||
else if (!Armoury.IsValid())
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_ARMOURY;
|
||||
}
|
||||
else if (!Observatory.IsValid())
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_OBSERVATORY;
|
||||
}
|
||||
|
||||
if (StructureToDeploy == STRUCTURE_NONE) { return false; }
|
||||
|
||||
if (StructureToDeploy == STRUCTURE_MARINE_TURRET)
|
||||
{
|
||||
int NumAttempts = 0;
|
||||
|
||||
while (NumAttempts < 5)
|
||||
{
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), TurretFactory.Location, (BALANCE_VAR(kTurretFactoryBuildDistance) * 0.8f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (DeployedStructure)
|
||||
{
|
||||
BaseToBuildOut->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), TurretFactory.Location, (BALANCE_VAR(kTurretFactoryBuildDistance) * 0.8f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRET, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (DeployedStructure)
|
||||
{
|
||||
BaseToBuildOut->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||
}
|
||||
|
||||
if (DeployedStructure || pBot->Player->GetResources() <= BALANCE_VAR(kSentryCost) + 5) { return true; }
|
||||
}
|
||||
|
||||
NumAttempts++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int NumAttempts = 0;
|
||||
|
||||
while (NumAttempts < 5)
|
||||
{
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseToBuildOut->BaseLocation, UTIL_MetresToGoldSrcUnits(8.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (DeployedStructure)
|
||||
{
|
||||
BaseToBuildOut->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
NumAttempts++;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool AICOMM_BuildOutSiege(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut)
|
||||
{
|
||||
AvHAIDeployableStructureType StructureToDeploy = STRUCTURE_NONE;
|
||||
|
||||
AvHAIBuildableStructure PhaseGate;
|
||||
AvHAIBuildableStructure Armoury;
|
||||
AvHAIBuildableStructure TurretFactory;
|
||||
AvHAIBuildableStructure Observatory;
|
||||
int NumTurrets = 0;
|
||||
int NumIncomplete = 0;
|
||||
|
||||
for (auto it = BaseToBuildOut->PlacedStructures.begin(); it != BaseToBuildOut->PlacedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = AITAC_GetDeployableStructureByEntIndex(BaseToBuildOut->BaseTeam, *it);
|
||||
|
||||
if (!StructureRef.IsCompleted())
|
||||
{
|
||||
NumIncomplete++;
|
||||
}
|
||||
|
||||
switch (StructureRef.StructureType)
|
||||
{
|
||||
case STRUCTURE_MARINE_PHASEGATE:
|
||||
PhaseGate = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRETFACTORY:
|
||||
case STRUCTURE_MARINE_ADVTURRETFACTORY:
|
||||
TurretFactory = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_ARMOURY:
|
||||
case STRUCTURE_MARINE_ADVARMOURY:
|
||||
Armoury = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_OBSERVATORY:
|
||||
Observatory = StructureRef;
|
||||
break;
|
||||
case STRUCTURE_MARINE_SIEGETURRET:
|
||||
NumTurrets++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (NumIncomplete > 0)
|
||||
{
|
||||
int NumBuilders = AITAC_GetNumPlayersOfTeamInArea(pBot->Player->GetTeam(), BaseToBuildOut->BaseLocation, UTIL_MetresToGoldSrcUnits(10.0f), false, nullptr, AVH_USER3_COMMANDER_PLAYER);
|
||||
|
||||
// Don't spam too many structures
|
||||
if (NumIncomplete >= NumBuilders) { return false; }
|
||||
}
|
||||
|
||||
// Don't place any more structures until we have the phase gate up
|
||||
if (PhaseGate.IsValid() && !PhaseGate.IsCompleted()) { return false; }
|
||||
|
||||
if (!PhaseGate.IsValid() && AITAC_ResearchIsComplete(BaseToBuildOut->BaseTeam, TECH_RESEARCH_PHASETECH))
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_PHASEGATE;
|
||||
}
|
||||
else if (!TurretFactory.IsValid())
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_TURRETFACTORY;
|
||||
}
|
||||
else if (TurretFactory.IsCompleted() && TurretFactory.IsIdle() && TurretFactory.StructureType != STRUCTURE_MARINE_ADVTURRETFACTORY)
|
||||
{
|
||||
return AICOMM_UpgradeStructure(pBot, &TurretFactory);
|
||||
}
|
||||
else if (TurretFactory.StructureType == STRUCTURE_MARINE_ADVTURRETFACTORY && NumTurrets < 3)
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_SIEGETURRET;
|
||||
}
|
||||
else if (!Armoury.IsValid())
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_ARMOURY;
|
||||
}
|
||||
else if (!Observatory.IsValid())
|
||||
{
|
||||
StructureToDeploy = STRUCTURE_MARINE_OBSERVATORY;
|
||||
}
|
||||
|
||||
if (StructureToDeploy == STRUCTURE_NONE) { return false; }
|
||||
|
||||
if (StructureToDeploy == STRUCTURE_MARINE_SIEGETURRET)
|
||||
{
|
||||
int NumAttempts = 0;
|
||||
|
||||
while (NumAttempts < 5)
|
||||
{
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), TurretFactory.Location, (BALANCE_VAR(kTurretFactoryBuildDistance) * 0.4f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, BuildLocation, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (DeployedStructure)
|
||||
{
|
||||
BaseToBuildOut->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), TurretFactory.Location, (BALANCE_VAR(kTurretFactoryBuildDistance) * 0.6f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_SIEGETURRET, BuildLocation, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (DeployedStructure)
|
||||
{
|
||||
BaseToBuildOut->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||
}
|
||||
|
||||
if (DeployedStructure || pBot->Player->GetResources() <= BALANCE_VAR(kSentryCost) + 5) { return true; }
|
||||
}
|
||||
|
||||
NumAttempts++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int NumAttempts = 0;
|
||||
|
||||
while (NumAttempts < 5)
|
||||
{
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseToBuildOut->BaseLocation, UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, BuildLocation, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (DeployedStructure)
|
||||
{
|
||||
BaseToBuildOut->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BaseToBuildOut->BaseLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
AvHAIBuildableStructure* DeployedStructure = AICOMM_DeployStructure(pBot, StructureToDeploy, BuildLocation, STRUCTURE_PURPOSE_SIEGE);
|
||||
|
||||
if (DeployedStructure)
|
||||
{
|
||||
BaseToBuildOut->PlacedStructures.push_back(DeployedStructure->EntIndex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
NumAttempts++;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void AICOMM_AddNewBase(AvHAIPlayer* pBot, Vector NewBaseLocation, MarineBaseType NewBaseType)
|
||||
{
|
||||
AvHAIMarineBase NewBase;
|
||||
NewBase.BaseLocation = NewBaseLocation;
|
||||
NewBase.BaseType = NewBaseType;
|
||||
NewBase.BaseTeam = pBot->Player->GetTeam();
|
||||
|
||||
pBot->Bases.push_back(NewBase);
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
static const float MIN_COMMANDER_REMIND_TIME = 20.0f; // How frequently the commander can nag a player to do something, if they don't think they're doing it
|
||||
|
||||
bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureType StructureToDeploy, const Vector Location, StructurePurpose Purpose = STRUCTURE_PURPOSE_GENERAL);
|
||||
AvHAIBuildableStructure* AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureType StructureToDeploy, const Vector Location, StructurePurpose Purpose = STRUCTURE_PURPOSE_GENERAL, bool bPlacedByHuman = false);
|
||||
bool AICOMM_DeployItem(AvHAIPlayer* pBot, const AvHAIDeployableItemType ItemToDeploy, const Vector Location);
|
||||
bool AICOMM_UpgradeStructure(AvHAIPlayer* pBot, AvHAIBuildableStructure* StructureToUpgrade);
|
||||
bool AICOMM_ResearchTech(AvHAIPlayer* pBot, AvHAIBuildableStructure* StructureToResearch, AvHMessageID Research);
|
||||
|
@ -76,4 +76,11 @@ bool AICOMM_ShouldCommanderRelocate(AvHAIPlayer* pBot);
|
|||
|
||||
bool AICOMM_GetRelocationMessage(Vector RelocationPoint, char* MessageBuffer);
|
||||
|
||||
void AICOMM_AddNewBase(AvHAIPlayer* pBot, Vector NewBaseLocation, MarineBaseType NewBaseType);
|
||||
|
||||
bool AICOMM_BuildOutBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
bool AICOMM_BuildOutMainBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
bool AICOMM_BuildOutOutpost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
bool AICOMM_BuildOutSiege(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
|
||||
#endif // AVH_AI_COMMANDER_H
|
|
@ -20,6 +20,7 @@ bot_skill BotSkillLevels[4];
|
|||
|
||||
std::vector<AvHMessageID> ChamberSequence;
|
||||
|
||||
std::default_random_engine rng;
|
||||
bool bRNGSeeded = false;
|
||||
|
||||
string DefaultBotNames[MAX_PLAYERS] = { "MrRobot",
|
||||
|
@ -186,7 +187,6 @@ void CONFIG_PopulateBotNames()
|
|||
|
||||
if (BotNames.size() > 2)
|
||||
{
|
||||
auto rng = std::default_random_engine{};
|
||||
std::shuffle(begin(BotNames), end(BotNames), rng);
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,6 @@ void CONFIG_PopulateBotNames()
|
|||
|
||||
if (DefaultNames.size() > 2)
|
||||
{
|
||||
auto rng = std::default_random_engine{};
|
||||
std::shuffle(begin(DefaultNames), end(DefaultNames), rng);
|
||||
}
|
||||
|
||||
|
@ -274,12 +273,10 @@ void CONFIG_ParseConfigFile()
|
|||
ChamberSequence.push_back(ALIEN_BUILD_MOVEMENT_CHAMBER);
|
||||
ChamberSequence.push_back(ALIEN_BUILD_SENSORY_CHAMBER);
|
||||
|
||||
auto rng = std::default_random_engine{};
|
||||
|
||||
if (!bRNGSeeded)
|
||||
{
|
||||
srand(time(NULL));
|
||||
rng.seed(time(NULL));
|
||||
srand(time(0));
|
||||
rng.seed(time(0));
|
||||
bRNGSeeded = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -341,6 +341,7 @@ typedef struct _AVH_AI_GUARD_INFO
|
|||
typedef struct _AVH_AI_BUILDABLE_STRUCTURE
|
||||
{
|
||||
AvHBaseBuildable* EntityRef = nullptr;
|
||||
int EntIndex = -1;
|
||||
edict_t* edict = nullptr; // Reference to structure edict
|
||||
Vector Location = g_vecZero; // origin of the structure edict
|
||||
float healthPercent = 0.0f; // Current health of the building
|
||||
|
@ -356,9 +357,11 @@ typedef struct _AVH_AI_BUILDABLE_STRUCTURE
|
|||
Vector LastSuccessfulCommanderAngle = g_vecZero; // Tracks the last commander input angle ("click" location) used to successfully place or select building
|
||||
StructurePurpose Purpose = STRUCTURE_PURPOSE_NONE;
|
||||
bool bReachabilityMarkedDirty = false; // If true, reachability flags will be recalculated for this structure
|
||||
bool bPlacedByHuman = true; // This structure was placed by a human: AI commander will not recycle these unless it absolutely makes sense to
|
||||
|
||||
bool IsValid() { return !FNullEnt(edict) && !edict->free && !(edict->v.flags & EF_NODRAW) && edict->v.deadflag == DEAD_NO; }
|
||||
bool IsCompleted() { return (StructureStatusFlags & STRUCTURE_STATUS_COMPLETED); }
|
||||
bool IsIdle() { return !(StructureStatusFlags & STRUCTURE_STATUS_RESEARCHING); }
|
||||
|
||||
} AvHAIBuildableStructure;
|
||||
|
||||
|
@ -471,6 +474,24 @@ enum NavDoorType
|
|||
DOORTYPE_TRAIN // Door activated by touching a trigger_once or trigger_multiple
|
||||
};
|
||||
|
||||
// The type of base a marine outpost could be. Used to help the AI establish and expand outposts across the map
|
||||
enum MarineBaseType
|
||||
{
|
||||
MARINE_BASE_MAINBASE, // The main marine base, where the CC, infantry portals and stuff like arms labs go
|
||||
MARINE_BASE_OUTPOST, // A permanent outpost designed to control an area of the map, but not the main marine base
|
||||
MARINE_BASE_SIEGE // A siege base designed to take down an enemy base
|
||||
};
|
||||
|
||||
typedef struct _AI_MARINE_BASE
|
||||
{
|
||||
AvHTeamNumber BaseTeam = TEAM_IND;
|
||||
MarineBaseType BaseType = MARINE_BASE_OUTPOST; // The purpose of the base. Determines what structures the commander will place
|
||||
Vector BaseLocation = ZERO_VECTOR; // Where the base should be located. The base will be grown around this location
|
||||
vector<int> PlacedStructures; // Which structures are part of this base.
|
||||
bool bRecycleBase = false; // Should the commander pack up and remove this base?
|
||||
bool bBaseInitialised = false; // Has the commander started building this base? Will be true once a structure has been placed
|
||||
} AvHAIMarineBase;
|
||||
|
||||
// Bot path node. A path will be several of these strung together to lead the bot to its destination
|
||||
typedef struct _BOT_PATH_NODE
|
||||
{
|
||||
|
@ -818,6 +839,8 @@ typedef struct AVH_AI_PLAYER
|
|||
|
||||
Vector RelocationSpot = ZERO_VECTOR; // If the bot is commanding and wants to relocate, then this is where they plan to go
|
||||
|
||||
vector<AvHAIMarineBase> Bases;
|
||||
|
||||
} AvHAIPlayer;
|
||||
|
||||
typedef struct _AVH_AI_SQUAD
|
||||
|
|
|
@ -3490,6 +3490,7 @@ void NewMove(AvHAIPlayer* pBot)
|
|||
FallMove(pBot, MoveFrom, MoveTo);
|
||||
break;
|
||||
case SAMPLE_POLYFLAGS_JUMP:
|
||||
case SAMPLE_POLYFLAGS_DUCKJUMP:
|
||||
JumpMove(pBot, MoveFrom, MoveTo);
|
||||
break;
|
||||
case SAMPLE_POLYFLAGS_BLOCKED:
|
||||
|
|
|
@ -1887,45 +1887,21 @@ void EndBotFrame(AvHAIPlayer* pBot)
|
|||
|
||||
void CustomThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
if (pBot->Player->GetResources() < 80.0f)
|
||||
if (IsPlayerAlien(pBot->Edict)) { return; }
|
||||
|
||||
if (!IsPlayerCommander(pBot->Edict))
|
||||
{
|
||||
pBot->Player->GiveResources(10.0f);
|
||||
BotProgressTakeCommandTask(pBot);
|
||||
return;
|
||||
}
|
||||
|
||||
pBot->CurrentTask = &pBot->PrimaryBotTask;
|
||||
|
||||
AITASK_BotUpdateAndClearTasks(pBot);
|
||||
|
||||
if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_MINES))
|
||||
for (auto it = pBot->Bases.begin(); it != pBot->Bases.end(); it++)
|
||||
{
|
||||
if (pBot->CurrentTask->TaskType != TASK_GET_WEAPON)
|
||||
if (AITAC_CanBuildOutBase(&(*it)))
|
||||
{
|
||||
AvHAIDroppedItem Mines = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_MINES, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, false);
|
||||
|
||||
if (Mines.IsValid())
|
||||
{
|
||||
AITASK_SetPickupTask(pBot, pBot->CurrentTask, Mines.edict, true);
|
||||
}
|
||||
if (AICOMM_BuildOutBase(pBot, &(*it))) { return; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pBot->CurrentTask->TaskType != TASK_PLACE_MINE)
|
||||
{
|
||||
|
||||
DeployableSearchFilter TFFilter;
|
||||
TFFilter.DeployableTypes = STRUCTURE_MARINE_TURRETFACTORY;
|
||||
|
||||
AvHAIBuildableStructure NearestTF = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &TFFilter);
|
||||
|
||||
if (NearestTF.IsValid())
|
||||
{
|
||||
AITASK_SetMineStructureTask(pBot, pBot->CurrentTask, NearestTF.edict, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BotProgressTask(pBot, pBot->CurrentTask);
|
||||
}
|
||||
|
||||
void DroneThink(AvHAIPlayer* pBot)
|
||||
|
|
|
@ -74,6 +74,9 @@ float LastSeenLerkTeamBTime = 0.0f;
|
|||
|
||||
vector<AvHAISquad> ActiveSquads;
|
||||
|
||||
vector<AvHAIMarineBase> ActiveTeamABases; // If Team A are marines, any active bases they have established around the map
|
||||
vector<AvHAIMarineBase> ActiveTeamBBases; // If Team B are marines, any active bases they have established around the map
|
||||
|
||||
std::vector<AvHAIBuildableStructure> AITAC_FindAllDeployables(const Vector& Location, const DeployableSearchFilter* Filter)
|
||||
{
|
||||
std::vector<AvHAIBuildableStructure> Result;
|
||||
|
@ -876,6 +879,16 @@ AvHAIBuildableStructure AITAC_GetNearestDeployableDirectlyReachable(AvHAIPlayer*
|
|||
return Result;
|
||||
}
|
||||
|
||||
AvHAIBuildableStructure AITAC_GetDeployableStructureByEntIndex(AvHTeamNumber Team, int EntIndex)
|
||||
{
|
||||
return (Team == AIMGR_GetTeamANumber()) ? TeamAStructureMap[EntIndex] : TeamBStructureMap[EntIndex];
|
||||
}
|
||||
|
||||
AvHAIBuildableStructure* AITAC_GetDeployableStructureRefByEntIndex(AvHTeamNumber Team, int EntIndex)
|
||||
{
|
||||
return (Team == AIMGR_GetTeamANumber()) ? &TeamAStructureMap[EntIndex] : &TeamBStructureMap[EntIndex];
|
||||
}
|
||||
|
||||
AvHAIBuildableStructure* AITAC_GetNearestDeployableDirectlyReachableByRef(AvHAIPlayer* pBot, const Vector Location, const DeployableSearchFilter* Filter)
|
||||
{
|
||||
AvHTeamNumber TeamA = GetGameRules()->GetTeamANumber();
|
||||
|
@ -2452,6 +2465,7 @@ AvHAIBuildableStructure* AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
if (StructureRef->LastSeen == 0)
|
||||
{
|
||||
StructureRef->Location = BuildingEdict->v.origin;
|
||||
StructureRef->EntIndex = EntIndex;
|
||||
StructureRef->edict = BuildingEdict;
|
||||
StructureRef->healthPercent = 1.0f;
|
||||
StructureRef->EntityRef = nullptr;
|
||||
|
@ -2480,6 +2494,7 @@ AvHAIBuildableStructure* AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
{
|
||||
StructureRef->EntityRef = BaseBuildable;
|
||||
StructureRef->edict = BuildingEdict;
|
||||
StructureRef->EntIndex = EntIndex;
|
||||
|
||||
StructureRef->OffMeshConnections.clear();
|
||||
StructureRef->Obstacles.clear();
|
||||
|
@ -5945,4 +5960,269 @@ void AITAC_DetermineRelocationEnabled()
|
|||
|
||||
bEnableRelocation = (RandomRoll <= CONFIG_GetRelocationChance());
|
||||
}
|
||||
}
|
||||
|
||||
bool AITAC_IsMarineBaseValid(AvHAIMarineBase* Base)
|
||||
{
|
||||
if (Base->PlacedStructures.size() > 0) { return true; }
|
||||
|
||||
if ((Base->bRecycleBase || Base->bBaseInitialised) && Base->PlacedStructures.size() == 0) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AITAC_ManageActiveMarineBases()
|
||||
{
|
||||
for (auto it = ActiveTeamABases.begin(); it != ActiveTeamABases.end();)
|
||||
{
|
||||
for (auto structIt = it->PlacedStructures.begin(); structIt != it->PlacedStructures.end();)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = TeamAStructureMap[*structIt];
|
||||
|
||||
if (!StructureRef.IsValid() || (StructureRef.StructureStatusFlags & STRUCTURE_STATUS_RECYCLING))
|
||||
{
|
||||
structIt = it->PlacedStructures.erase(structIt);
|
||||
}
|
||||
else
|
||||
{
|
||||
structIt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!AITAC_IsMarineBaseValid(&(*it)))
|
||||
{
|
||||
it = ActiveTeamABases.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = ActiveTeamBBases.begin(); it != ActiveTeamBBases.end();)
|
||||
{
|
||||
for (auto structIt = it->PlacedStructures.begin(); structIt != it->PlacedStructures.end();)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = TeamBStructureMap[*structIt];
|
||||
|
||||
if (!StructureRef.IsValid() || (StructureRef.StructureStatusFlags & STRUCTURE_STATUS_RECYCLING))
|
||||
{
|
||||
structIt = it->PlacedStructures.erase(structIt);
|
||||
}
|
||||
else
|
||||
{
|
||||
structIt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!AITAC_IsMarineBaseValid(&(*it)))
|
||||
{
|
||||
it = ActiveTeamBBases.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AITAC_AddNewBase(AvHTeamNumber Team, Vector NewBaseLocation, MarineBaseType NewBaseType)
|
||||
{
|
||||
vector<AvHAIMarineBase>& BaseList = (Team == AIMGR_GetTeamANumber()) ? ActiveTeamABases : ActiveTeamBBases;
|
||||
|
||||
AvHAIMarineBase NewBase;
|
||||
NewBase.BaseLocation = NewBaseLocation;
|
||||
NewBase.BaseType = NewBaseType;
|
||||
NewBase.BaseTeam = Team;
|
||||
|
||||
BaseList.push_back(NewBase);
|
||||
}
|
||||
|
||||
bool AITAC_CanBuildOutBase(const AvHAIMarineBase* Base)
|
||||
{
|
||||
if (!Base) { return false; }
|
||||
|
||||
switch (Base->BaseType)
|
||||
{
|
||||
case MARINE_BASE_MAINBASE:
|
||||
return AITAC_CanBuildOutMainBase(Base);
|
||||
case MARINE_BASE_OUTPOST:
|
||||
return AITAC_CanBuildOutOutpost(Base);
|
||||
case MARINE_BASE_SIEGE:
|
||||
return AITAC_CanBuildOutSiege(Base);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AITAC_CanBuildOutMainBase(const AvHAIMarineBase* Base)
|
||||
{
|
||||
bool bHasCommChair = false;
|
||||
int NumInfPortals = 0;
|
||||
bool bHasArmoury = false;
|
||||
bool bHasAdvArmoury = false;
|
||||
bool bArmouryCompleted = false;
|
||||
bool bHasArmsLab = false;
|
||||
bool bArmsLabCompleted = false;
|
||||
bool bHasProtoLab = false;
|
||||
bool bHasObs = false;
|
||||
bool bHasPhase = false;
|
||||
bool bHasTF = false;
|
||||
int NumTurrets = 0;
|
||||
|
||||
std::unordered_map<int, AvHAIBuildableStructure>& BuildingMap = (Base->BaseTeam == AIMGR_GetTeamANumber()) ? TeamAStructureMap : TeamBStructureMap;
|
||||
|
||||
for (auto it = Base->PlacedStructures.begin(); it != Base->PlacedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = BuildingMap[*it];
|
||||
|
||||
switch (StructureRef.StructureType)
|
||||
{
|
||||
case STRUCTURE_MARINE_COMMCHAIR:
|
||||
bHasCommChair = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_INFANTRYPORTAL:
|
||||
NumInfPortals++;
|
||||
break;
|
||||
case STRUCTURE_MARINE_ARMOURY:
|
||||
bArmouryCompleted = (StructureRef.StructureStatusFlags & STRUCTURE_STATUS_COMPLETED);
|
||||
bHasArmoury = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_ADVARMOURY:
|
||||
bArmouryCompleted = (StructureRef.StructureStatusFlags & STRUCTURE_STATUS_COMPLETED);
|
||||
bHasArmoury = true;
|
||||
bHasAdvArmoury = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_ARMSLAB:
|
||||
bHasArmsLab = true;
|
||||
bArmsLabCompleted = (StructureRef.StructureStatusFlags & STRUCTURE_STATUS_COMPLETED);
|
||||
break;
|
||||
case STRUCTURE_MARINE_PROTOTYPELAB:
|
||||
bHasProtoLab = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_OBSERVATORY:
|
||||
bHasObs = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_PHASEGATE:
|
||||
bHasPhase = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRETFACTORY:
|
||||
case STRUCTURE_MARINE_ADVTURRETFACTORY:
|
||||
bHasTF = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRET:
|
||||
NumTurrets++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (!bHasCommChair
|
||||
|| NumInfPortals < 2
|
||||
|| !bHasArmoury
|
||||
|| !bHasAdvArmoury
|
||||
|| (!bHasArmsLab && bArmouryCompleted)
|
||||
|| (!bHasProtoLab && bHasAdvArmoury && bArmsLabCompleted)
|
||||
|| (!bHasObs && bArmouryCompleted)
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_PHASE_GATE))
|
||||
|| !bHasTF
|
||||
|| NumTurrets < 5);
|
||||
|
||||
}
|
||||
|
||||
bool AITAC_CanBuildOutOutpost(const AvHAIMarineBase* Base)
|
||||
{
|
||||
bool bHasArmoury = false;
|
||||
bool bHasObs = false;
|
||||
bool bHasPhase = false;
|
||||
bool bHasTF = false;
|
||||
int NumTurrets = 0;
|
||||
|
||||
std::unordered_map<int, AvHAIBuildableStructure>& BuildingMap = (Base->BaseTeam == AIMGR_GetTeamANumber()) ? TeamAStructureMap : TeamBStructureMap;
|
||||
|
||||
for (auto it = Base->PlacedStructures.begin(); it != Base->PlacedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = BuildingMap[*it];
|
||||
|
||||
switch (StructureRef.StructureType)
|
||||
{
|
||||
case STRUCTURE_MARINE_ARMOURY:
|
||||
case STRUCTURE_MARINE_ADVARMOURY:
|
||||
bHasArmoury = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_OBSERVATORY:
|
||||
bHasObs = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_PHASEGATE:
|
||||
bHasPhase = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRETFACTORY:
|
||||
case STRUCTURE_MARINE_ADVTURRETFACTORY:
|
||||
bHasTF = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRET:
|
||||
NumTurrets++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (!bHasArmoury
|
||||
|| !bHasObs
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_PHASE_GATE))
|
||||
|| !bHasTF
|
||||
|| NumTurrets < 5);
|
||||
|
||||
}
|
||||
|
||||
bool AITAC_CanBuildOutSiege(const AvHAIMarineBase* Base)
|
||||
{
|
||||
bool bHasArmoury = false;
|
||||
bool bHasObs = false;
|
||||
bool bHasPhase = false;
|
||||
bool bHasTF = false;
|
||||
int NumTurrets = 0;
|
||||
|
||||
std::unordered_map<int, AvHAIBuildableStructure>& BuildingMap = (Base->BaseTeam == AIMGR_GetTeamANumber()) ? TeamAStructureMap : TeamBStructureMap;
|
||||
|
||||
for (auto it = Base->PlacedStructures.begin(); it != Base->PlacedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = BuildingMap[*it];
|
||||
|
||||
switch (StructureRef.StructureType)
|
||||
{
|
||||
case STRUCTURE_MARINE_ARMOURY:
|
||||
case STRUCTURE_MARINE_ADVARMOURY:
|
||||
bHasArmoury = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_OBSERVATORY:
|
||||
bHasObs = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_PHASEGATE:
|
||||
bHasPhase = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_ADVTURRETFACTORY:
|
||||
bHasTF = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_SIEGETURRET:
|
||||
NumTurrets++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (!bHasArmoury
|
||||
|| !bHasObs
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_PHASE_GATE))
|
||||
|| !bHasTF
|
||||
|| NumTurrets < 3);
|
||||
|
||||
}
|
||||
|
||||
vector<AvHAIMarineBase>& AITAC_GetTeamBases(AvHTeamNumber Team)
|
||||
{
|
||||
return (Team == AIMGR_GetTeamANumber()) ? ActiveTeamABases : ActiveTeamBBases;
|
||||
}
|
|
@ -31,6 +31,8 @@ AvHAIBuildableStructure AITAC_GetDeployableFromEdict(const edict_t* Structure);
|
|||
AvHAIBuildableStructure* AITAC_GetDeployableRefFromEdict(const edict_t* Structure);
|
||||
AvHAIBuildableStructure AITAC_GetNearestDeployableDirectlyReachable(AvHAIPlayer* pBot, const Vector Location, const DeployableSearchFilter* Filter);
|
||||
AvHAIBuildableStructure* AITAC_GetNearestDeployableDirectlyReachableByRef(AvHAIPlayer* pBot, const Vector Location, const DeployableSearchFilter* Filter);
|
||||
AvHAIBuildableStructure AITAC_GetDeployableStructureByEntIndex(AvHTeamNumber Team, int EntIndex);
|
||||
AvHAIBuildableStructure* AITAC_GetDeployableStructureRefByEntIndex(AvHTeamNumber Team, int EntIndex);
|
||||
int AITAC_GetNumDeployablesNearLocation(const Vector& Location, const DeployableSearchFilter* Filter);
|
||||
void AITAC_PopulateHiveData();
|
||||
void AITAC_RefreshHiveData();
|
||||
|
@ -220,4 +222,14 @@ bool AITAC_IsRelocationEnabled();
|
|||
|
||||
void AITAC_DetermineRelocationEnabled();
|
||||
|
||||
bool AITAC_IsMarineBaseValid(AvHAIMarineBase* Base);
|
||||
void AITAC_ManageActiveMarineBases();
|
||||
void AITAC_AddNewBase(AvHTeamNumber Team, Vector NewBaseLocation, MarineBaseType NewBaseType);
|
||||
bool AITAC_CanBuildOutBase(const AvHAIMarineBase* Base);
|
||||
bool AITAC_CanBuildOutMainBase(const AvHAIMarineBase* Base);
|
||||
bool AITAC_CanBuildOutOutpost(const AvHAIMarineBase* Base);
|
||||
bool AITAC_CanBuildOutSiege(const AvHAIMarineBase* Base);
|
||||
|
||||
vector<AvHAIMarineBase>& AITAC_GetTeamBases(AvHTeamNumber Team);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue