mirror of
https://github.com/ENSL/NS.git
synced 2025-02-01 13:40:55 +00:00
More bug fixes
* Fixed bots getting stuck on top of railings sometimes. Also hopefully fixed issues with bots aborting wall climbs for no reason. * Fixed issue with duplicate base structures being dropped * Fixed an issue where marines would become listless if the aliens had 3 hives up and they didn't have phase tech researched. They should continue to attack regardless * Fixed issue where gorges would go nuts when trying to build defensive structures in an empty hive * Aliens should be much more focused on evolving into fade/onos, including ignoring a hive under attack to first evolve so they can defend more effectively
This commit is contained in:
parent
f6796ad025
commit
e8a85852e8
11 changed files with 489 additions and 168 deletions
|
@ -988,6 +988,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
StructureFilter.ReachabilityFlags = AI_REACHABILITY_MARINE;
|
||||
StructureFilter.ReachabilityTeam = TeamNumber;
|
||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
edict_t* BaseBuilder = AITAC_GetNearestHiddenPlayerInLocation(TeamNumber, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
|
@ -1002,6 +1003,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
}
|
||||
|
||||
StructureFilter.DeployableTypes = (STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY);
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
AvHAIBuildableStructure BaseArmoury = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
|
@ -1015,7 +1017,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1035,7 +1037,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1050,7 +1052,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1079,7 +1081,8 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
if (AITAC_PhaseGatesAvailable(TeamNumber))
|
||||
{
|
||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_PHASEGATE;
|
||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
bool bPhaseNearBase = AITAC_DeployableExistsAtLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
|
@ -1094,7 +1097,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1106,7 +1109,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);
|
||||
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PHASEGATE, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kPhaseGateCost) + 10) { return true; }
|
||||
}
|
||||
}
|
||||
|
@ -1133,8 +1136,84 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (AICOMM_ShouldCommanderPrioritiseNodes(pBot) && pBot->Player->GetResources() < 30) { return false; }
|
||||
|
||||
StructureFilter.DeployableTypes = (STRUCTURE_MARINE_TURRETFACTORY | STRUCTURE_MARINE_ADVTURRETFACTORY);
|
||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
AvHAIBuildableStructure TF = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
if (!TF.IsValid())
|
||||
{
|
||||
Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_TURRETFACTORY, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bEnemyInBase = AITAC_AnyPlayerOnTeamWithLOS(AIMGR_GetEnemyTeam(TeamNumber), BuildLocation + Vector(0.0f, 0.0f, 32.0f), UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (!vIsZero(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_TURRETFACTORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kTurretFactoryCost) + 5) { return true; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (TF.IsValid() && (TF.StructureStatusFlags & STRUCTURE_STATUS_COMPLETED))
|
||||
{
|
||||
StructureFilter.DeployableTypes = (STRUCTURE_MARINE_TURRET);
|
||||
StructureFilter.MaxSearchRadius = BALANCE_VAR(kTurretFactoryBuildDistance);
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
int NumTurrets = AITAC_GetNumDeployablesNearLocation(TF.Location, &StructureFilter);
|
||||
|
||||
if (NumTurrets < 5)
|
||||
{
|
||||
Vector BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_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);
|
||||
|
||||
if (bSuccess) { 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);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kSentryCost) + 5) { return true; }
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(TF.StructureStatusFlags & STRUCTURE_STATUS_ELECTRIFIED) && pBot->Player->GetResources() > 50)
|
||||
{
|
||||
bool bSuccess = AICOMM_ResearchTech(pBot, &TF, RESEARCH_ELECTRICAL);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_ARMSLAB;
|
||||
StructureFilter.MaxSearchRadius = 0.0f;
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
bool bHasArmsLab = AITAC_DeployableExistsAtLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
|
@ -1148,7 +1227,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1160,20 +1239,20 @@ 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);
|
||||
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMSLAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kArmsLabCost) + 10) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_OBSERVATORY;
|
||||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
bool bHasObservatory = AITAC_DeployableExistsAtLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
if (!bHasObservatory && !FNullEnt(BaseBuilder))
|
||||
{
|
||||
|
||||
|
||||
Vector BuildLocation = AITAC_GetRandomBuildHintInLocation(STRUCTURE_MARINE_OBSERVATORY, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(15.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
|
@ -1182,7 +1261,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1194,7 +1273,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);
|
||||
bool bSuccess = !bEnemyInBase && AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_OBSERVATORY, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kObservatoryCost) + 10) { return true; }
|
||||
|
||||
|
@ -1214,7 +1293,9 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
if (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kTurretFactoryCost) + 5) { return true; }
|
||||
}
|
||||
|
||||
StructureFilter.MaxSearchRadius = 0.0f;
|
||||
StructureFilter.DeployableTypes = STRUCTURE_MARINE_ADVARMOURY;
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
bool bHasAdvArmoury = AITAC_DeployableExistsAtLocation(CommChair->v.origin, &StructureFilter);
|
||||
bool bIsResearchingArmoury = false;
|
||||
|
@ -1225,7 +1306,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
||||
StructureFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
StructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING | STRUCTURE_STATUS_RESEARCHING;
|
||||
|
||||
|
||||
AvHAIBuildableStructure NearestArmoury = AITAC_FindClosestDeployableToLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
if (NearestArmoury.IsValid())
|
||||
|
@ -1246,6 +1327,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
StructureFilter.IncludeStatusFlags = STRUCTURE_STATUS_NONE;
|
||||
StructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_BASE;
|
||||
|
||||
bool bHasPrototypeLab = AITAC_DeployableExistsAtLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
|
@ -1259,7 +1341,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1273,7 +1355,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -1287,7 +1369,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bEnemyInBase)
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_PROTOTYPELAB, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess || pBot->Player->GetResources() < BALANCE_VAR(kPrototypeLabCost) + 20) { return true; }
|
||||
}
|
||||
|
@ -1302,6 +1384,7 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
StructureFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
StructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING | STRUCTURE_STATUS_ELECTRIFIED;
|
||||
StructureFilter.MaxSearchRadius = 0.0f;
|
||||
StructureFilter.PurposeFlags = STRUCTURE_PURPOSE_ANY;
|
||||
|
||||
AvHAIBuildableStructure ResTower = AITAC_FindFurthestDeployableFromLocation(CommChair->v.origin, &StructureFilter);
|
||||
|
||||
|
@ -2238,7 +2321,7 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -2272,7 +2355,7 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation);
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
@ -2284,7 +2367,7 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
if (vIsZero(BuildLocation)) { return false; }
|
||||
|
||||
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation);
|
||||
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
|
||||
}
|
||||
|
||||
bool AICOMM_CheckForNextRecycleAction(AvHAIPlayer* pBot)
|
||||
|
|
|
@ -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_NONE);
|
||||
bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureType StructureToDeploy, const Vector Location, StructurePurpose Purpose = STRUCTURE_PURPOSE_GENERAL);
|
||||
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);
|
||||
|
|
|
@ -169,8 +169,11 @@ typedef enum
|
|||
typedef enum _STRUCTUREPURPOSE
|
||||
{
|
||||
STRUCTURE_PURPOSE_NONE = 0,
|
||||
STRUCTURE_PURPOSE_SIEGE,
|
||||
STRUCTURE_PURPOSE_FORTIFY
|
||||
STRUCTURE_PURPOSE_GENERAL = 1u,
|
||||
STRUCTURE_PURPOSE_SIEGE = 1u << 1,
|
||||
STRUCTURE_PURPOSE_FORTIFY = 1u << 2,
|
||||
STRUCTURE_PURPOSE_BASE = 1u << 3,
|
||||
STRUCTURE_PURPOSE_ANY = -1
|
||||
|
||||
} StructurePurpose;
|
||||
|
||||
|
@ -308,6 +311,7 @@ typedef struct _DEPLOYABLE_SEARCH_FILTER
|
|||
bool bConsiderPhaseDistance = false;
|
||||
AvHTeamNumber DeployableTeam = TEAM_IND;
|
||||
AvHTeamNumber ReachabilityTeam = TEAM_IND;
|
||||
unsigned int PurposeFlags = STRUCTURE_PURPOSE_ANY;
|
||||
} DeployableSearchFilter;
|
||||
|
||||
// Pending message a bot wants to say. Allows for a delay in sending a message to simulate typing, or prevent too many messages on the same frame
|
||||
|
@ -350,7 +354,7 @@ typedef struct _AVH_AI_BUILDABLE_STRUCTURE
|
|||
vector<AvHAIOffMeshConnection> OffMeshConnections; // References to any off-mesh connections this structure is associated with
|
||||
Vector LastSuccessfulCommanderLocation = g_vecZero; // Tracks the last commander view location where it successfully placed or selected the building
|
||||
Vector LastSuccessfulCommanderAngle = g_vecZero; // Tracks the last commander input angle ("click" location) used to successfully place or select building
|
||||
StructurePurpose Purpose = STRUCTURE_PURPOSE_NONE;
|
||||
StructurePurpose Purpose = STRUCTURE_PURPOSE_GENERAL;
|
||||
bool bReachabilityMarkedDirty = false; // If true, reachability flags will be recalculated for this structure
|
||||
|
||||
bool IsValid() { return !FNullEnt(edict) && !edict->free && !(edict->v.flags & EF_NODRAW) && edict->v.deadflag == DEAD_NO; }
|
||||
|
@ -489,7 +493,7 @@ typedef struct _ENEMY_STATUS
|
|||
float LastDetectedTime = 0.0f; // When the bot last saw the enemy or they pinged on motion tracking
|
||||
float InitialAwarenessTime = 0.0f; // When the bot first became aware of the enemy
|
||||
float LastVisibleTime = 0.0f; // Last time the bot actually saw the enemy
|
||||
float EnemyThreatLevel = 0.0f;
|
||||
float EnemyThreatLevel = 0.0f; // Generally, >=3.0 means actively fighting them, >=2.0 means visible and close, >=1.0 means not visible but close and <1.0 means they can be heard but not close
|
||||
|
||||
bool bHasLOS = false; // Does the bot has LOS of the enemy?
|
||||
bool bEnemyHasLOS = false;
|
||||
|
|
|
@ -554,7 +554,7 @@ void UTIL_DrawHUDText(edict_t* pEntity, char channel, float x, float y, unsigned
|
|||
WRITE_BYTE(1); // effect ALPHA
|
||||
WRITE_SHORT(0); // fade-in time in seconds * 256
|
||||
WRITE_SHORT(0); // fade-out time in seconds * 256
|
||||
WRITE_SHORT(5); // hold time in seconds * 256
|
||||
WRITE_SHORT(20); // hold time in seconds * 256
|
||||
WRITE_STRING(string);//string); // send the string
|
||||
MESSAGE_END(); // end
|
||||
|
||||
|
@ -646,4 +646,78 @@ void UTIL_LocalizeText(const char* InputText, string& OutputText)
|
|||
|
||||
LocalizedLocationsMap[InputText] = OutputText;
|
||||
|
||||
}
|
||||
|
||||
char* UTIL_TaskTypeToChar(const BotTaskType TaskType)
|
||||
{
|
||||
switch (TaskType)
|
||||
{
|
||||
case TASK_ATTACK:
|
||||
return "Attack";
|
||||
case TASK_BUILD:
|
||||
return "Build";
|
||||
case TASK_CAP_RESNODE:
|
||||
return "Cap Res Node";
|
||||
case TASK_COMMAND:
|
||||
return "Take Command";
|
||||
case TASK_DEFEND:
|
||||
return "Defend Structure";
|
||||
case TASK_EVOLVE:
|
||||
return "Evolve";
|
||||
case TASK_GET_AMMO:
|
||||
return "Get Ammo Pack";
|
||||
case TASK_GET_EQUIPMENT:
|
||||
return "Get Equipment";
|
||||
case TASK_GET_HEALTH:
|
||||
return "Get Health Pack";
|
||||
case TASK_GET_WEAPON:
|
||||
return "Get Weapon";
|
||||
case TASK_GUARD:
|
||||
return "Guard";
|
||||
case TASK_HEAL:
|
||||
return "Heal Target";
|
||||
case TASK_MOVE:
|
||||
return "Move to Location";
|
||||
case TASK_PLACE_MINE:
|
||||
return "Place Mine";
|
||||
case TASK_REINFORCE_STRUCTURE:
|
||||
return "Reinforce Structure";
|
||||
case TASK_RESUPPLY:
|
||||
return "Resupply";
|
||||
case TASK_SECURE_HIVE:
|
||||
return "Secure Hive";
|
||||
case TASK_TOUCH:
|
||||
return "Touch Trigger";
|
||||
case TASK_WELD:
|
||||
return "Weld Target";
|
||||
default:
|
||||
return "None";
|
||||
}
|
||||
|
||||
return "None";
|
||||
}
|
||||
|
||||
char* UTIL_BotRoleToChar(const AvHAIBotRole Role)
|
||||
{
|
||||
switch (Role)
|
||||
{
|
||||
case BOT_ROLE_ASSAULT:
|
||||
return "Assault";
|
||||
case BOT_ROLE_BOMBARDIER:
|
||||
return "Bombardier";
|
||||
case BOT_ROLE_BUILDER:
|
||||
return "Builder";
|
||||
case BOT_ROLE_COMMAND:
|
||||
return "Commander";
|
||||
case BOT_ROLE_FIND_RESOURCES:
|
||||
return "Res Capper";
|
||||
case BOT_ROLE_HARASS:
|
||||
return "Harrasser";
|
||||
case BOT_ROLE_SWEEPER:
|
||||
return "Sweeper";
|
||||
default:
|
||||
return "None";
|
||||
}
|
||||
|
||||
return "None";
|
||||
}
|
|
@ -59,4 +59,8 @@ void UTIL_DrawHUDText(edict_t* pEntity, char channel, float x, float y, unsigned
|
|||
void UTIL_ClearLocalizations();
|
||||
void UTIL_LocalizeText(const char* InputText, string& OutputText);
|
||||
|
||||
char* UTIL_TaskTypeToChar(const BotTaskType TaskType);
|
||||
|
||||
char* UTIL_BotRoleToChar(const AvHAIBotRole Role);
|
||||
|
||||
#endif
|
|
@ -2069,7 +2069,17 @@ dtStatus FindPathClosestToPoint(AvHAIPlayer* pBot, const BotMoveStyle MoveStyle,
|
|||
|
||||
Vector FromLocation = pBot->CurrentFloorPosition;
|
||||
|
||||
Vector FromFloorLocation = AdjustPointForPathfinding(FromLocation);
|
||||
// Add a slight bias towards trying to move forward if on a railing or other narrow bit of navigable terrain
|
||||
// rather than potentially dropping back off it the wrong way
|
||||
Vector GeneralDir = UTIL_GetVectorNormal2D(ToLocation - pBot->CurrentFloorPosition);
|
||||
Vector CheckLocation = FromLocation + (GeneralDir * 16.0f);
|
||||
|
||||
Vector FromFloorLocation = AdjustPointForPathfinding(CheckLocation);
|
||||
|
||||
if (vIsZero(FromFloorLocation))
|
||||
{
|
||||
FromFloorLocation = AdjustPointForPathfinding(FromLocation);
|
||||
}
|
||||
|
||||
nav_door* LiftReference = UTIL_GetLiftReferenceByEdict(pBot->Edict->v.groundentity);
|
||||
bool bMustDisembarkLiftFirst = false;
|
||||
|
@ -4852,20 +4862,6 @@ void WallClimbMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndP
|
|||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(pBot->desiredMovementDir + (vRight * modifier));
|
||||
}
|
||||
|
||||
// Jump if we're on the floor, to give ourselves a boost and remove that momentary pause while "wall-sticking" mode activates if skulk
|
||||
if ((pEdict->v.flags & FL_ONGROUND) && !IsPlayerClimbingWall(pBot->Edict))
|
||||
{
|
||||
Vector CurrentVelocity = UTIL_GetVectorNormal2D(pBot->Edict->v.velocity);
|
||||
|
||||
float VelocityDot = UTIL_GetDotProduct2D(vForward, CurrentVelocity);
|
||||
|
||||
if (VelocityDot > 0.7f)
|
||||
{
|
||||
// This was causing issues in tight areas, rethink this
|
||||
//BotJump(pBot);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop holding crouch if we're a skulk so we can actually climb
|
||||
if (IsPlayerSkulk(pBot->Edict))
|
||||
{
|
||||
|
@ -4899,20 +4895,12 @@ void WallClimbMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndP
|
|||
else
|
||||
{
|
||||
LookLocation = DirectAheadView - Vector(0.0f, 0.0f, 20.0f);
|
||||
//LookLocation = pBot->CurrentEyePosition + (ClimbSurfaceNormal * 100.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ZDiff > 16.0f)
|
||||
{
|
||||
ClimbSurfaceNormal = ClimbSurfaceNormal;
|
||||
LookLocation = pBot->CurrentEyePosition + (ClimbSurfaceNormal * 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LookLocation = DirectAheadView + Vector(0.0f, 0.0f, 20.0f);
|
||||
}
|
||||
ClimbSurfaceNormal = ClimbSurfaceNormal;
|
||||
LookLocation = pBot->CurrentEyePosition + (ClimbSurfaceNormal * 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6437,12 +6425,12 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
bool bSucceeded = NAV_GenerateNewBasePath(pBot, Destination, MoveStyle, MaxAcceptableDist);
|
||||
|
||||
if (!bSucceeded)
|
||||
{
|
||||
if (pBot->BotNavInfo.CurrentPath.size() == 0)
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
|
||||
{
|
||||
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
|
||||
|
||||
if (!UTIL_PointIsOnNavmesh(pBot->CollisionHullBottomLocation, pBot->BotNavInfo.NavProfile) && !vIsZero(BotNavInfo->LastNavMeshPosition))
|
||||
if (!UTIL_PointIsOnNavmesh(pBot->CollisionHullBottomLocation, pBot->BotNavInfo.NavProfile))
|
||||
{
|
||||
if (!vIsZero(BotNavInfo->LastNavMeshPosition))
|
||||
{
|
||||
MoveDirectlyTo(pBot, BotNavInfo->LastNavMeshPosition);
|
||||
|
||||
|
@ -6451,7 +6439,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
BotNavInfo->LastNavMeshPosition = g_vecZero;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6462,19 +6450,20 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
|
||||
if (vIsZero(BotNavInfo->UnstuckMoveLocation))
|
||||
{
|
||||
BotNavInfo->UnstuckMoveLocation = FindClosestPointBackOnPath(pBot);
|
||||
BotNavInfo->UnstuckMoveLocation = FindClosestPointBackOnPath(pBot, Destination);
|
||||
}
|
||||
|
||||
if (!vIsZero(BotNavInfo->UnstuckMoveLocation))
|
||||
{
|
||||
MoveDirectlyTo(pBot, BotNavInfo->UnstuckMoveLocation);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BotFollowPath(pBot);
|
||||
MoveDirectlyTo(pBot, Destination);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -6486,17 +6475,6 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
|
||||
if (!bSucceeded)
|
||||
{
|
||||
if (!FNullEnt(pBot->Edict->v.groundentity))
|
||||
{
|
||||
nav_door* Door = UTIL_GetNavDoorByEdict(pBot->Edict->v.groundentity);
|
||||
|
||||
if (Door)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!FNullEnt(BotNavInfo->MovementTask.TaskTarget))
|
||||
{
|
||||
CBaseEntity* TargetEntity = CBaseEntity::Instance(BotNavInfo->MovementTask.TaskTarget);
|
||||
|
@ -6587,26 +6565,33 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
|
|||
|
||||
}
|
||||
|
||||
Vector FindClosestPointBackOnPath(AvHAIPlayer* pBot)
|
||||
Vector FindClosestPointBackOnPath(AvHAIPlayer* pBot, Vector Destination)
|
||||
{
|
||||
Vector GeneralMoveDir = UTIL_GetVectorNormal2D(Destination - pBot->Edict->v.origin);
|
||||
Vector CheckDir = pBot->Edict->v.origin + (GeneralMoveDir * 16.0f);
|
||||
|
||||
DeployableSearchFilter ResNodeFilter;
|
||||
ResNodeFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
|
||||
AvHAIResourceNode* NearestResNode = AITAC_FindNearestResourceNodeToLocation(pBot->Edict->v.origin, &ResNodeFilter);
|
||||
|
||||
Vector ValidNavmeshPoint = AITAC_GetTeamStartingLocation(pBot->Player->GetTeam());
|
||||
|
||||
if (NearestResNode && vDist2D(pBot->Edict->v.origin, NearestResNode->Location) < vDist2D(pBot->Edict->v.origin, ValidNavmeshPoint))
|
||||
{
|
||||
ValidNavmeshPoint = NearestResNode->Location;
|
||||
}
|
||||
|
||||
ValidNavmeshPoint = UTIL_ProjectPointToNavmesh(ValidNavmeshPoint, pBot->BotNavInfo.NavProfile);
|
||||
Vector ValidNavmeshPoint = AdjustPointForPathfinding(CheckDir);
|
||||
|
||||
if (vIsZero(ValidNavmeshPoint))
|
||||
{
|
||||
return g_vecZero;
|
||||
DeployableSearchFilter ResNodeFilter;
|
||||
ResNodeFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
|
||||
AvHAIResourceNode* NearestResNode = AITAC_FindNearestResourceNodeToLocation(pBot->Edict->v.origin, &ResNodeFilter);
|
||||
|
||||
Vector ValidNavmeshPoint = AITAC_GetTeamStartingLocation(pBot->Player->GetTeam());
|
||||
|
||||
if (NearestResNode && vDist2D(pBot->Edict->v.origin, NearestResNode->Location) < vDist2D(pBot->Edict->v.origin, ValidNavmeshPoint))
|
||||
{
|
||||
ValidNavmeshPoint = NearestResNode->Location;
|
||||
}
|
||||
|
||||
ValidNavmeshPoint = UTIL_ProjectPointToNavmesh(ValidNavmeshPoint, pBot->BotNavInfo.NavProfile);
|
||||
|
||||
if (vIsZero(ValidNavmeshPoint))
|
||||
{
|
||||
return g_vecZero;
|
||||
}
|
||||
}
|
||||
|
||||
vector<bot_path_node> BackwardsPath;
|
||||
|
@ -6829,9 +6814,6 @@ LerkFlightBehaviour BotFlightClimbMove(AvHAIPlayer* pBot, Vector FromLocation, V
|
|||
pBot->Edict->v.velocity.z = fmaxf(pBot->Edict->v.velocity.z, 10.0f);
|
||||
}
|
||||
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->Edict->v.origin + UTIL_GetVectorNormal(pBot->Edict->v.velocity) * 100.0f, 255, 0, 0);
|
||||
|
||||
|
||||
return FLIGHT_FLAP;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ dtStatus FindPathClosestToPoint(const nav_profile& NavProfile, const Vector From
|
|||
dtStatus DEBUG_TestFindPath(const nav_profile& NavProfile, const Vector FromLocation, const Vector ToLocation, vector<bot_path_node>& path, float MaxAcceptableDistance);
|
||||
|
||||
// If the bot is stuck and off the path or nav mesh, this will try to find a point it can directly move towards to get it back on track
|
||||
Vector FindClosestPointBackOnPath(AvHAIPlayer* pBot);
|
||||
Vector FindClosestPointBackOnPath(AvHAIPlayer* pBot, Vector Destination);
|
||||
|
||||
Vector FindClosestNavigablePointToDestination(const nav_profile& NavProfile, const Vector FromLocation, const Vector ToLocation, float MaxAcceptableDistance);
|
||||
|
||||
|
|
|
@ -392,9 +392,9 @@ bool BotReloadWeapons(AvHAIPlayer* pBot)
|
|||
if (IsPlayerReloading(pBot->Player))
|
||||
{
|
||||
pBot->DesiredCombatWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
AvHAIWeapon SecondaryWeapon = GetBotMarineSecondaryWeapon(pBot);
|
||||
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
|
@ -2172,8 +2172,25 @@ void UpdateAIMarinePlayerNSRole(AvHAIPlayer* pBot)
|
|||
|
||||
int NumSweeperBots = AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeamNumber, BOT_ROLE_SWEEPER, pBot);
|
||||
|
||||
int NumDesiredSweeperBots = 1;
|
||||
|
||||
if (NumSweeperBots < 2)
|
||||
{
|
||||
DeployableSearchFilter DefenceStructuresFilter;
|
||||
DefenceStructuresFilter.DeployableTeam = BotTeamNumber;
|
||||
DefenceStructuresFilter.DeployableTypes = (STRUCTURE_MARINE_TURRET | STRUCTURE_MARINE_OBSERVATORY);
|
||||
DefenceStructuresFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
DefenceStructuresFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
DefenceStructuresFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
|
||||
|
||||
if (!AITAC_DeployableExistsAtLocation(AITAC_GetTeamStartingLocation(BotTeamNumber), &DefenceStructuresFilter))
|
||||
{
|
||||
NumDesiredSweeperBots = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Always have a sweeper
|
||||
if (NumSweeperBots < 1)
|
||||
if (NumSweeperBots < NumDesiredSweeperBots)
|
||||
{
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_SWEEPER);
|
||||
return;
|
||||
|
@ -2208,18 +2225,18 @@ void AIPlayerNSThink(AvHAIPlayer* pBot)
|
|||
{
|
||||
AvHTeam* BotTeam = GetGameRules()->GetTeam(pBot->Player->GetTeam());
|
||||
|
||||
if (!BotTeam) { return; }
|
||||
if (!BotTeam) { return; }
|
||||
|
||||
pBot->CurrentEnemy = BotGetNextEnemyTarget(pBot);
|
||||
pBot->CurrentEnemy = BotGetNextEnemyTarget(pBot);
|
||||
|
||||
if (BotTeam->GetTeamType() == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
AIPlayerNSMarineThink(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIPlayerNSAlienThink(pBot);
|
||||
}
|
||||
if (BotTeam->GetTeamType() == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
AIPlayerNSMarineThink(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIPlayerNSAlienThink(pBot);
|
||||
}
|
||||
}
|
||||
|
||||
int BotGetNextEnemyTarget(AvHAIPlayer* pBot)
|
||||
|
@ -2266,18 +2283,18 @@ AvHAICombatStrategy GetAlienCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_sta
|
|||
|
||||
switch (PlayerUser3)
|
||||
{
|
||||
case AVH_USER3_ALIEN_PLAYER1:
|
||||
return GetSkulkCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER2:
|
||||
return GetGorgeCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER3:
|
||||
return GetLerkCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER4:
|
||||
return GetFadeCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER5:
|
||||
return GetOnosCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
default:
|
||||
return COMBAT_STRATEGY_IGNORE;
|
||||
case AVH_USER3_ALIEN_PLAYER1:
|
||||
return GetSkulkCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER2:
|
||||
return GetGorgeCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER3:
|
||||
return GetLerkCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER4:
|
||||
return GetFadeCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
case AVH_USER3_ALIEN_PLAYER5:
|
||||
return GetOnosCombatStrategyForTarget(pBot, CurrentEnemy);
|
||||
default:
|
||||
return COMBAT_STRATEGY_IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2305,7 +2322,15 @@ AvHAICombatStrategy GetSkulkCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_sta
|
|||
return COMBAT_STRATEGY_ATTACK;
|
||||
}
|
||||
|
||||
if (CurrentEnemy->EnemyThreatLevel < 2.0f && (gpGlobals->time - CurrentEnemy->LastVisibleTime > 5.0f))
|
||||
if (pBot->CurrentTask->TaskType == TASK_EVOLVE)
|
||||
{
|
||||
if (CurrentEnemy->EnemyThreatLevel < 3.0f || !CurrentEnemy->bHasLOS)
|
||||
{
|
||||
return COMBAT_STRATEGY_IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrentEnemy->EnemyThreatLevel < 2.0f && gpGlobals->time - CurrentEnemy->LastVisibleTime > 5.0f)
|
||||
{
|
||||
return COMBAT_STRATEGY_IGNORE;
|
||||
}
|
||||
|
@ -3698,10 +3723,43 @@ void AIPlayerSetMarineAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
{
|
||||
DeployableSearchFilter AnyEnemyStuff;
|
||||
AnyEnemyStuff.DeployableTeam = EnemyTeam;
|
||||
AnyEnemyStuff.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
AnyEnemyStuff.DeployableTypes = SEARCH_ANY_RES_TOWER;
|
||||
AnyEnemyStuff.ReachabilityTeam = BotTeam;
|
||||
AnyEnemyStuff.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
|
||||
AvHAIBuildableStructure EnemyRT = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &AnyEnemyStuff);
|
||||
|
||||
if (EnemyRT.IsValid())
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyRT.edict, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AIMGR_GetEnemyTeamType(EnemyTeam) == AVH_CLASS_TYPE_ALIEN)
|
||||
{
|
||||
const AvHAIHiveDefinition* ActiveHive = AITAC_GetActiveHiveNearestLocation(AIMGR_GetEnemyTeam(BotTeam), pBot->Edict->v.origin);
|
||||
|
||||
if (ActiveHive)
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, ActiveHive->HiveEdict, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AnyEnemyStuff.DeployableTypes = STRUCTURE_MARINE_COMMCHAIR;
|
||||
|
||||
AvHAIBuildableStructure EnemyCommChair = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &AnyEnemyStuff);
|
||||
|
||||
if (EnemyCommChair.IsValid())
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyCommChair.edict, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AnyEnemyStuff.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
|
||||
AvHAIBuildableStructure EnemyStructure = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &AnyEnemyStuff);
|
||||
|
||||
if (EnemyStructure.IsValid())
|
||||
|
@ -3723,10 +3781,6 @@ void AIPlayerSetMarineBombardierPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask*
|
|||
|
||||
void AIPlayerSetWantsAndNeedsCOMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
if (gpGlobals->time - pBot->LastCombatTime > 5.0f)
|
||||
{
|
||||
if (BotReloadWeapons(pBot)) { return; }
|
||||
}
|
||||
|
||||
if (Task->TaskType == TASK_RESUPPLY) { return; }
|
||||
|
||||
|
@ -3774,10 +3828,6 @@ void AIPlayerSetWantsAndNeedsCOMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Ta
|
|||
|
||||
void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
if (gpGlobals->time - pBot->LastCombatTime > 5.0f)
|
||||
{
|
||||
if (BotReloadWeapons(pBot)) { return; }
|
||||
}
|
||||
|
||||
if (Task->TaskType == TASK_RESUPPLY || Task->TaskType == TASK_GET_HEALTH || Task->TaskType == TASK_GET_AMMO) { return; }
|
||||
|
||||
|
@ -5479,25 +5529,8 @@ void AIPlayerThink(AvHAIPlayer* pBot)
|
|||
|
||||
AIDEBUG_DrawBotPath(pBot);
|
||||
|
||||
if (pBot->BotNavInfo.CurrentPath.size() > 0 && pBot->BotNavInfo.CurrentPathPoint < pBot->BotNavInfo.CurrentPath.size())
|
||||
{
|
||||
bot_path_node CurrentPathNode = pBot->BotNavInfo.CurrentPath[pBot->BotNavInfo.CurrentPathPoint];
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, CurrentPathNode.FromLocation, 255, 0, 0);
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, CurrentPathNode.Location, 0, 128, 0);
|
||||
}
|
||||
|
||||
if (pBot->CurrentTask && pBot->CurrentTask->TaskType != TASK_NONE)
|
||||
{
|
||||
if (!FNullEnt(pBot->CurrentTask->TaskTarget))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->CurrentTask->TaskTarget->v.origin, 255, 0, 0);
|
||||
}
|
||||
|
||||
if (!vIsZero(pBot->CurrentTask->TaskLocation))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->CurrentTask->TaskLocation, 255, 0, 0);
|
||||
}
|
||||
}
|
||||
DEBUG_PrintTaskInfo(pBot);
|
||||
//DEBUG_PrintCombatInfo(pBot);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -6987,6 +7020,12 @@ void AIPlayerSetSecondaryAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (pBot->PrimaryBotTask.TaskType == TASK_EVOLVE)
|
||||
{
|
||||
AITASK_ClearBotTask(pBot, &pBot->SecondaryBotTask);
|
||||
return;
|
||||
}
|
||||
|
||||
vector<AvHAIHiveDefinition*> AllHives = AITAC_GetAllTeamHives(BotTeam, false);
|
||||
|
||||
AvHAIHiveDefinition* HiveToDefend = nullptr;
|
||||
|
@ -7105,6 +7144,21 @@ void AIPlayerSetSecondaryAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
}
|
||||
}
|
||||
|
||||
if (pBot->PrimaryBotTask.TaskType == TASK_CAP_RESNODE)
|
||||
{
|
||||
float ResourceCost = BALANCE_VAR(kResourceTowerCost);
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
ResourceCost += BALANCE_VAR(kGorgeCost);
|
||||
}
|
||||
|
||||
if (pBot->Player->GetResources() >= ResourceCost)
|
||||
{
|
||||
AITASK_ClearBotTask(pBot, &pBot->SecondaryBotTask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DeployableSearchFilter AttackedStructuresFilter;
|
||||
AttackedStructuresFilter.DeployableTypes = (IsPlayerLerk(pBot->Edict)) ? SEARCH_ALL_STRUCTURES : STRUCTURE_ALIEN_RESTOWER;
|
||||
AttackedStructuresFilter.DeployableTeam = BotTeam;
|
||||
|
@ -7612,6 +7666,8 @@ bool GorgeCombatThink(AvHAIPlayer* pBot)
|
|||
|
||||
float CurrentHealthPercent = GetPlayerOverallHealthPercent(pBot->Edict);
|
||||
|
||||
bool bPlayerCloaked = UTIL_IsCloakedPlayerInvisible(CurrentEnemy, pBot->Player);
|
||||
|
||||
if (pBot->CurrentCombatStrategy == COMBAT_STRATEGY_RETREAT)
|
||||
{
|
||||
BotAttackResult AttackResult = PerformAttackLOSCheck(pBot, WEAPON_GORGE_SPIT, CurrentEnemy);
|
||||
|
@ -7631,19 +7687,24 @@ bool GorgeCombatThink(AvHAIPlayer* pBot)
|
|||
|
||||
if (!bInHealingRange)
|
||||
{
|
||||
pBot->BotNavInfo.bShouldWalk = bPlayerCloaked && TrackedEnemyRef->bEnemyHasLOS;
|
||||
|
||||
MoveTo(pBot, UTIL_GetEntityGroundLocation(NearestHealingSource), MOVESTYLE_NORMAL, DesiredDistFromHealingSource);
|
||||
|
||||
if (CurrentHealthPercent > 0.5f && AttackResult == ATTACK_SUCCESS)
|
||||
if (!bPlayerCloaked)
|
||||
{
|
||||
BotShootTarget(pBot, WEAPON_GORGE_SPIT, CurrentEnemy);
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->DesiredCombatWeapon = WEAPON_GORGE_HEALINGSPRAY;
|
||||
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == WEAPON_GORGE_HEALINGSPRAY)
|
||||
if (CurrentHealthPercent > 0.5f && AttackResult == ATTACK_SUCCESS)
|
||||
{
|
||||
pBot->Button |= IN_ATTACK;
|
||||
BotShootTarget(pBot, WEAPON_GORGE_SPIT, CurrentEnemy);
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->DesiredCombatWeapon = WEAPON_GORGE_HEALINGSPRAY;
|
||||
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == WEAPON_GORGE_HEALINGSPRAY)
|
||||
{
|
||||
pBot->Button |= IN_ATTACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7664,6 +7725,21 @@ bool GorgeCombatThink(AvHAIPlayer* pBot)
|
|||
return true;
|
||||
}
|
||||
|
||||
// If we're invisible and healing, do nothing. Don't give our position away
|
||||
if (bPlayerCloaked)
|
||||
{
|
||||
if (TrackedEnemyRef->bHasLOS)
|
||||
{
|
||||
BotLookAt(pBot, TrackedEnemyRef->LastDetectedLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
BotLookAt(pBot, TrackedEnemyRef->LastLOSPosition);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bOutOfEnemyLOS)
|
||||
{
|
||||
if (bInHealingRange)
|
||||
|
@ -8385,6 +8461,66 @@ bool OnosCombatThink(AvHAIPlayer* pBot)
|
|||
return true;
|
||||
}
|
||||
|
||||
void DEBUG_PrintTaskInfo(AvHAIPlayer* pBot)
|
||||
{
|
||||
char buf[511];
|
||||
char interbuf[164];
|
||||
|
||||
sprintf(buf, "Task info for %s:\n\n", STRING(pBot->Edict->v.netname));
|
||||
|
||||
sprintf(interbuf, "Role: %s\n\n", UTIL_BotRoleToChar(pBot->BotRole));
|
||||
strcat(buf, interbuf);
|
||||
|
||||
if (IsPlayerMarine(pBot->Edict))
|
||||
{
|
||||
const char* CommanderTask = UTIL_TaskTypeToChar(pBot->CommanderTask.TaskType);
|
||||
|
||||
sprintf(interbuf, "Commander-Issued: %s\n", CommanderTask);
|
||||
strcat(buf, interbuf);
|
||||
}
|
||||
|
||||
const char* PrimaryTask = UTIL_TaskTypeToChar(pBot->PrimaryBotTask.TaskType);
|
||||
|
||||
sprintf(interbuf, "Primary: %s\n", PrimaryTask);
|
||||
strcat(buf, interbuf);
|
||||
|
||||
const char* SecondaryTask = UTIL_TaskTypeToChar(pBot->SecondaryBotTask.TaskType);
|
||||
|
||||
sprintf(interbuf, "Secondary: %s\n", SecondaryTask);
|
||||
strcat(buf, interbuf);
|
||||
|
||||
const char* WantAndNeedTask = UTIL_TaskTypeToChar(pBot->WantsAndNeedsTask.TaskType);
|
||||
|
||||
sprintf(interbuf, "Want/Need: %s\n\n", WantAndNeedTask);
|
||||
strcat(buf, interbuf);
|
||||
|
||||
if (pBot->CurrentTask)
|
||||
{
|
||||
const char* CurrentTask = UTIL_TaskTypeToChar(pBot->CurrentTask->TaskType);
|
||||
|
||||
sprintf(interbuf, "Current: %s\n\n", CurrentTask);
|
||||
strcat(buf, interbuf);
|
||||
}
|
||||
|
||||
if (pBot->CurrentTask && pBot->CurrentTask->TaskType != TASK_NONE)
|
||||
{
|
||||
sprintf(interbuf, "Red = Target, Yellow = Location\n");
|
||||
strcat(buf, interbuf);
|
||||
|
||||
if (!FNullEnt(pBot->CurrentTask->TaskTarget))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->CurrentTask->TaskTarget->v.origin, 255, 0, 0);
|
||||
}
|
||||
|
||||
if (!vIsZero(pBot->CurrentTask->TaskLocation))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, pBot->CurrentTask->TaskLocation, 255, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
UTIL_DrawHUDText(INDEXENT(1), 0, 0.1f, 0.1f, 255, 255, 255, buf);
|
||||
}
|
||||
|
||||
void DEBUG_PrintCombatInfo(AvHAIPlayer* pBot)
|
||||
{
|
||||
char buf[511];
|
||||
|
@ -8396,18 +8532,18 @@ void DEBUG_PrintCombatInfo(AvHAIPlayer* pBot)
|
|||
|
||||
if (TrackedEnemy < 0)
|
||||
{
|
||||
sprintf(interbuf, "Biggest threat: NONE\n\n");
|
||||
sprintf(interbuf, "Main Threat: NONE\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(interbuf, "Biggest threat: %s\n\n", STRING(pBot->TrackedEnemies[TrackedEnemy].PlayerEdict->v.netname));
|
||||
sprintf(interbuf, "Main Threat: %s\n\n", STRING(pBot->TrackedEnemies[TrackedEnemy].PlayerEdict->v.netname));
|
||||
}
|
||||
|
||||
strcat(buf, interbuf);
|
||||
|
||||
if (TrackedEnemy < 0)
|
||||
{
|
||||
UTIL_DrawHUDText(INDEXENT(1), 0, 0.1f, 0.1f, 255, 255, 255, buf);
|
||||
UTIL_DrawHUDText(INDEXENT(1), 0, 0.6f, 0.1f, 255, 255, 255, buf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8434,24 +8570,40 @@ void DEBUG_PrintCombatInfo(AvHAIPlayer* pBot)
|
|||
|
||||
strcat(buf, interbuf);
|
||||
|
||||
sprintf(interbuf, "Threat: %.2f\n", TrackedInfo->EnemyThreatLevel);
|
||||
sprintf(interbuf, "Threat: %.2f\n\n", TrackedInfo->EnemyThreatLevel);
|
||||
strcat(buf, interbuf);
|
||||
|
||||
UTIL_DrawHUDText(INDEXENT(1), 0, 0.1f, 0.1f, 255, 255, 255, buf);
|
||||
AvHAICombatStrategy CurrentStrategy = GetBotCombatStrategyForTarget(pBot, TrackedInfo);
|
||||
|
||||
switch (CurrentStrategy)
|
||||
{
|
||||
case COMBAT_STRATEGY_AMBUSH:
|
||||
sprintf(interbuf, "Strategy: Ambush\n");
|
||||
break;
|
||||
case COMBAT_STRATEGY_ATTACK:
|
||||
sprintf(interbuf, "Strategy: Attack\n");
|
||||
break;
|
||||
case COMBAT_STRATEGY_IGNORE:
|
||||
sprintf(interbuf, "Strategy: Ignore\n");
|
||||
break;
|
||||
case COMBAT_STRATEGY_RETREAT:
|
||||
sprintf(interbuf, "Strategy: Retreat\n");
|
||||
break;
|
||||
case COMBAT_STRATEGY_SKIRMISH:
|
||||
sprintf(interbuf, "Strategy: Skirmish\n");
|
||||
break;
|
||||
default:
|
||||
sprintf(interbuf, "Strategy: None\n");
|
||||
break;
|
||||
}
|
||||
|
||||
strcat(buf, interbuf);
|
||||
|
||||
UTIL_DrawHUDText(INDEXENT(1), 0, 0.6f, 0.1f, 255, 255, 255, buf);
|
||||
|
||||
if (!vIsZero(TrackedInfo->LastDetectedLocation))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, TrackedInfo->LastDetectedLocation, 255, 0, 0);
|
||||
}
|
||||
|
||||
if (!vIsZero(TrackedInfo->LastLOSPosition))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, TrackedInfo->LastLOSPosition - Vector(0.0f, 0.0f, 5.0f), 255, 255, 0);
|
||||
}
|
||||
|
||||
if (!vIsZero(TrackedInfo->LastVisibleLocation))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, TrackedInfo->LastVisibleLocation + Vector(0.0f, 0.0f, 5.0f), 0, 0, 255);
|
||||
}
|
||||
|
||||
}
|
|
@ -184,6 +184,7 @@ bool OnosCombatThink(AvHAIPlayer* pBot);
|
|||
bool BombardierCombatThink(AvHAIPlayer* pBot);
|
||||
bool RegularMarineCombatThink(AvHAIPlayer* pBot);
|
||||
|
||||
void DEBUG_PrintTaskInfo(AvHAIPlayer* pBot);
|
||||
void DEBUG_PrintCombatInfo(AvHAIPlayer* pBot);
|
||||
|
||||
#endif
|
|
@ -89,6 +89,7 @@ std::vector<AvHAIBuildableStructure> AITAC_FindAllDeployables(const Vector& Loca
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE)
|
||||
{
|
||||
|
@ -122,6 +123,7 @@ std::vector<AvHAIBuildableStructure> AITAC_FindAllDeployables(const Vector& Loca
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE)
|
||||
{
|
||||
|
@ -173,6 +175,7 @@ std::vector<AvHAIBuildableStructure*> AITAC_FindAllDeployablesByRef(const Vector
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE)
|
||||
{
|
||||
|
@ -206,6 +209,7 @@ std::vector<AvHAIBuildableStructure*> AITAC_FindAllDeployablesByRef(const Vector
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE)
|
||||
{
|
||||
|
@ -253,6 +257,7 @@ bool AITAC_DeployableExistsAtLocation(const Vector& Location, const DeployableSe
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -283,6 +288,7 @@ bool AITAC_DeployableExistsAtLocation(const Vector& Location, const DeployableSe
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -331,6 +337,7 @@ AvHAIBuildableStructure AITAC_FindClosestDeployableToLocation(const Vector& Loca
|
|||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -360,6 +367,7 @@ AvHAIBuildableStructure AITAC_FindClosestDeployableToLocation(const Vector& Loca
|
|||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -405,7 +413,8 @@ AvHAIBuildableStructure* AITAC_FindClosestDeployableToLocationByRef(const Vector
|
|||
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -435,6 +444,7 @@ AvHAIBuildableStructure* AITAC_FindClosestDeployableToLocationByRef(const Vector
|
|||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -481,6 +491,7 @@ AvHAIBuildableStructure AITAC_FindFurthestDeployableFromLocation(const Vector& L
|
|||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -510,6 +521,7 @@ AvHAIBuildableStructure AITAC_FindFurthestDeployableFromLocation(const Vector& L
|
|||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -556,6 +568,7 @@ AvHAIBuildableStructure* AITAC_FindFurthestDeployableFromLocationByRef(const Vec
|
|||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -585,6 +598,7 @@ AvHAIBuildableStructure* AITAC_FindFurthestDeployableFromLocationByRef(const Vec
|
|||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -787,6 +801,7 @@ AvHAIBuildableStructure AITAC_GetNearestDeployableDirectlyReachable(AvHAIPlayer*
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -820,6 +835,7 @@ AvHAIBuildableStructure AITAC_GetNearestDeployableDirectlyReachable(AvHAIPlayer*
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -870,6 +886,7 @@ AvHAIBuildableStructure* AITAC_GetNearestDeployableDirectlyReachableByRef(AvHAIP
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -903,6 +920,7 @@ AvHAIBuildableStructure* AITAC_GetNearestDeployableDirectlyReachableByRef(AvHAIP
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -952,6 +970,7 @@ int AITAC_GetNumDeployablesNearLocation(const Vector& Location, const Deployable
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -982,6 +1001,7 @@ int AITAC_GetNumDeployablesNearLocation(const Vector& Location, const Deployable
|
|||
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (it.second.Purpose != Filter->PurposeFlags && (it.second.Purpose & Filter->PurposeFlags) != it.second.Purpose) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
|
|
@ -864,8 +864,9 @@ bool AITASK_IsReinforceStructureTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTas
|
|||
if (!FNullEnt(Task->TaskSecondaryTarget) && !UTIL_StructureIsFullyBuilt(Task->TaskSecondaryTarget)) { return true; }
|
||||
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||
|
||||
if (Task->TaskTarget->v.team != BotTeam) { return false; }
|
||||
if (Task->TaskTarget->v.team == EnemyTeam) { return false; }
|
||||
|
||||
// The reinforce structure task is true if we have an undecided hive available that we could build a new chamber with
|
||||
bool bActiveHiveWithoutTechExists = AITAC_TeamHiveWithTechExists(pBot->Player->GetTeam(), MESSAGE_NULL);
|
||||
|
|
Loading…
Reference in a new issue