Alien coordinated base attacks

* Aliens will now gang up to attack the marine base
* Aliens will spread out more when attacking in a group, rather than all going for the same buildings
This commit is contained in:
RGreenlees 2024-05-15 15:21:17 +01:00 committed by pierow
parent c0bef7cb05
commit 5beb313546
7 changed files with 247 additions and 55 deletions

View file

@ -415,7 +415,7 @@ typedef enum
TASK_REINFORCE_STRUCTURE, TASK_REINFORCE_STRUCTURE,
TASK_SECURE_HIVE, TASK_SECURE_HIVE,
TASK_PLACE_MINE, TASK_PLACE_MINE,
TASK_ATTACK_BASE TASK_ASSAULT_MARINE_BASE
} }
BotTaskType; BotTaskType;
@ -821,6 +821,7 @@ typedef struct _AVH_AI_SQUAD
vector<AvHAIPlayer*> SquadMembers; // Which bots are assigned to this vector<AvHAIPlayer*> SquadMembers; // Which bots are assigned to this
Vector SquadGatherLocation = g_vecZero; // Where should the squad gather before attempting the objective? Vector SquadGatherLocation = g_vecZero; // Where should the squad gather before attempting the objective?
edict_t* SquadTarget = nullptr; // The target of the objective edict_t* SquadTarget = nullptr; // The target of the objective
Vector ObjectiveLocation = g_vecZero;
BotTaskType SquadObjective = TASK_NONE; // What to do with the objective BotTaskType SquadObjective = TASK_NONE; // What to do with the objective
bool bExecuteObjective = false; // Are we at the gather or execute phase? bool bExecuteObjective = false; // Are we at the gather or execute phase?

View file

@ -680,8 +680,8 @@ char* UTIL_TaskTypeToChar(const BotTaskType TaskType)
return "Touch Trigger"; return "Touch Trigger";
case TASK_WELD: case TASK_WELD:
return "Weld Target"; return "Weld Target";
case TASK_ATTACK_BASE: case TASK_ASSAULT_MARINE_BASE:
return "Attack Enemy Base"; return "Assault Marine Base";
default: default:
return "None"; return "None";
} }

View file

@ -1878,19 +1878,17 @@ void EndBotFrame(AvHAIPlayer* pBot)
void CustomThink(AvHAIPlayer* pBot) void CustomThink(AvHAIPlayer* pBot)
{ {
pBot->CurrentEnemy = BotGetNextEnemyTarget(pBot); AvHTeamNumber BotTeam = pBot->Player->GetTeam();
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
if (pBot->CurrentEnemy > -1) if (AIMGR_GetTeamType(EnemyTeam) == AVH_CLASS_TYPE_MARINE)
{ {
if (IsPlayerMarine(pBot->Player)) AITASK_SetAssaultMarineBaseTask(pBot, &pBot->PrimaryBotTask, AITAC_GetTeamStartingLocation(EnemyTeam), true);
{
if (MarineCombatThink(pBot)) { return; }
}
else
{
if (AlienCombatThink(pBot)) { return; }
}
} }
pBot->CurrentTask = &pBot->PrimaryBotTask;
BotProgressTask(pBot, pBot->CurrentTask);
} }
void DroneThink(AvHAIPlayer* pBot) void DroneThink(AvHAIPlayer* pBot)
@ -2240,18 +2238,18 @@ void AIPlayerNSThink(AvHAIPlayer* pBot)
{ {
AvHTeam* BotTeam = GetGameRules()->GetTeam(pBot->Player->GetTeam()); 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) if (BotTeam->GetTeamType() == AVH_CLASS_TYPE_MARINE)
{ {
AIPlayerNSMarineThink(pBot); AIPlayerNSMarineThink(pBot);
} }
else else
{ {
AIPlayerNSAlienThink(pBot); AIPlayerNSAlienThink(pBot);
} }
} }
int BotGetNextEnemyTarget(AvHAIPlayer* pBot) int BotGetNextEnemyTarget(AvHAIPlayer* pBot)
@ -5935,13 +5933,11 @@ void AIPlayerReceiveMoveOrder(AvHAIPlayer* pBot, Vector Destination)
{ {
if (UTIL_QuickTrace(pBot->Edict, Destination + Vector(0.0f, 0.0f, 32.0f), HiveRef->Location)) if (UTIL_QuickTrace(pBot->Edict, Destination + Vector(0.0f, 0.0f, 32.0f), HiveRef->Location))
{ {
AITASK_SetAttackTask(pBot, &pBot->CommanderTask, HiveRef->HiveEdict, false); AITASK_SetSecureHiveTask(pBot, &pBot->CommanderTask, HiveRef->HiveEdict, ActualMoveLocation, false);
pBot->CommanderTask.bIssuedByCommander = true; pBot->CommanderTask.bIssuedByCommander = true;
return; return;
} }
} }
} }
// Otherwise, treat as a normal move order. Go there and wait a bit to see what the commander wants to do next // Otherwise, treat as a normal move order. Go there and wait a bit to see what the commander wants to do next
@ -6778,12 +6774,14 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
int MaxHiveStrength = 0; int MaxHiveStrength = 0;
AvHAIHiveDefinition* HiveToSecure = nullptr; AvHAIHiveDefinition* HiveToSecure = nullptr;
EnemyStuffFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
for (auto it = AllHives.begin(); it != AllHives.end(); it++) for (auto it = AllHives.begin(); it != AllHives.end(); it++)
{ {
AvHAIHiveDefinition* ThisHive = (*it); AvHAIHiveDefinition* ThisHive = (*it);
if (ThisHive->OwningTeam == BotTeam) { continue; } if (ThisHive->OwningTeam == BotTeam) { continue; }
vector<AvHAIBuildableStructure> EnemyStructures = AITAC_FindAllDeployables(ThisHive->FloorLocation, &EnemyStuffFilter); vector<AvHAIBuildableStructure> EnemyStructures = AITAC_FindAllDeployables(ThisHive->FloorLocation, &EnemyStuffFilter);
// Enemy hasn't built anything here, so doesn't need clearing // Enemy hasn't built anything here, so doesn't need clearing
@ -6825,32 +6823,29 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
return; return;
} }
// ATTACK THE ENEMY BASE // ATTACK THE ENEMY BASE IF AGAINST MARINES
DeployableSearchFilter EnemyInfPortalFilter; // AvA is handled above in securing hives: this will cause aliens to attack and eliminate all enemy hives
EnemyInfPortalFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL; // So this is only needed for marines where their base could be anywhere outside of hives
EnemyInfPortalFilter.DeployableTeam = EnemyTeam; if (AIMGR_GetTeamType(EnemyTeam) == AVH_CLASS_TYPE_MARINE)
EnemyInfPortalFilter.ReachabilityTeam = BotTeam;
EnemyInfPortalFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
EnemyInfPortalFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
EnemyInfPortalFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
AvHAIBuildableStructure EnemyInfPortal = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &EnemyInfPortalFilter);
if (EnemyInfPortal.IsValid())
{ {
AITASK_SetAttackTask(pBot, Task, EnemyInfPortal.edict, false); if (Task->TaskType == TASK_ASSAULT_MARINE_BASE) { return; }
return;
}
// TODO: Attack enemy hive/base Vector EnemyBaseLocation = AITAC_GetTeamStartingLocation(EnemyTeam);
edict_t* EnemyChair = AITAC_GetCommChair(EnemyTeam);
if (!FNullEnt(EnemyChair)) if (!vIsZero(EnemyBaseLocation))
{ {
AITASK_SetAttackTask(pBot, Task, EnemyChair, false); EnemyStuffFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
return; EnemyStuffFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
if (AITAC_DeployableExistsAtLocation(EnemyBaseLocation, &EnemyStuffFilter))
{
AITASK_SetAssaultMarineBaseTask(pBot, Task, EnemyBaseLocation, false);
return;
}
}
} }
// FIND ANY LAST ENEMIES TO KILL AND END GAME // FIND ANY LAST ENEMIES TO KILL AND END GAME

View file

@ -5514,7 +5514,7 @@ bool AITAC_IsBotPursuingSquadObjective(AvHAIPlayer* pBot, AvHAISquad* Squad)
if (!IsPlayerActiveInGame(pBot->Edict) || pBot->Player->GetTeam() != Squad->SquadTeam) { return false; } if (!IsPlayerActiveInGame(pBot->Edict) || pBot->Player->GetTeam() != Squad->SquadTeam) { return false; }
// Bot no longer has this squad's objective as its primary task // Bot no longer has this squad's objective as its primary task
if (pBot->PrimaryBotTask.TaskType != Squad->SquadObjective || pBot->PrimaryBotTask.TaskTarget != Squad->SquadTarget) { return false; } if (pBot->PrimaryBotTask.TaskType != Squad->SquadObjective || (!FNullEnt(Squad->SquadTarget) && pBot->PrimaryBotTask.TaskTarget != Squad->SquadTarget) || (FNullEnt(Squad->SquadTarget) && !vEquals(pBot->PrimaryBotTask.TaskLocation, Squad->ObjectiveLocation))) { return false; }
// Bot is focused on the job at hand // Bot is focused on the job at hand
if (!pBot->CurrentTask || pBot->CurrentTask == &pBot->PrimaryBotTask) { return true; } if (!pBot->CurrentTask || pBot->CurrentTask == &pBot->PrimaryBotTask) { return true; }
@ -5565,7 +5565,9 @@ void AITAC_UpdateSquads()
{ {
vector<bot_path_node> TravelPath; vector<bot_path_node> TravelPath;
dtStatus PathFindResult = FindPathClosestToPoint(GetBaseNavProfile(ONOS_BASE_NAV_PROFILE), AITAC_GetTeamStartingLocation(it->SquadTeam), UTIL_GetEntityGroundLocation(it->SquadTarget), TravelPath, UTIL_MetresToGoldSrcUnits(20.0f)); Vector TargetLocation = (!FNullEnt(it->SquadTarget)) ? UTIL_GetEntityGroundLocation(it->SquadTarget) : it->ObjectiveLocation;
dtStatus PathFindResult = FindPathClosestToPoint(GetBaseNavProfile(ONOS_BASE_NAV_PROFILE), AITAC_GetTeamStartingLocation(it->SquadTeam), TargetLocation, TravelPath, UTIL_MetresToGoldSrcUnits(20.0f));
if (dtStatusSucceed(PathFindResult)) if (dtStatusSucceed(PathFindResult))
{ {
@ -5573,9 +5575,12 @@ void AITAC_UpdateSquads()
{ {
if (pIt->area != SAMPLE_POLYAREA_GROUND || pIt->flag != SAMPLE_POLYFLAGS_WALK) { continue; } if (pIt->area != SAMPLE_POLYAREA_GROUND || pIt->flag != SAMPLE_POLYFLAGS_WALK) { continue; }
if (UTIL_QuickTrace(nullptr, pIt->Location, it->SquadTarget->v.origin)) { continue; } if (!FNullEnt(it->SquadTarget))
{
if (UTIL_QuickTrace(nullptr, pIt->Location, it->SquadTarget->v.origin)) { continue; }
}
if (vDist2DSq(pIt->Location, it->SquadTarget->v.origin) > sqrf(UTIL_MetresToGoldSrcUnits(20.0f))) if (vDist2DSq(pIt->Location, TargetLocation) > sqrf(UTIL_MetresToGoldSrcUnits(20.0f)))
{ {
DeployableSearchFilter EnemyStuff; DeployableSearchFilter EnemyStuff;
EnemyStuff.DeployableTeam = AIMGR_GetEnemyTeam(it->SquadTeam); EnemyStuff.DeployableTeam = AIMGR_GetEnemyTeam(it->SquadTeam);
@ -5663,6 +5668,48 @@ AvHAISquad* AITAC_GetSquadForObjective(AvHAIPlayer* pBot, edict_t* TaskTarget, B
return nullptr; return nullptr;
} }
AvHAISquad* AITAC_GetSquadForObjective(AvHAIPlayer* pBot, Vector TaskLocation, BotTaskType ObjectiveType)
{
AvHAISquad* JoinSquad = nullptr;
for (auto it = ActiveSquads.begin(); it != ActiveSquads.end(); it++)
{
if (it->SquadTeam == pBot->Player->GetTeam() && vEquals(it->ObjectiveLocation, TaskLocation) && it->SquadObjective == ObjectiveType)
{
auto element = std::find(it->SquadMembers.begin(), it->SquadMembers.end(), pBot);
if (element != it->SquadMembers.end())
{
return &(*it);
}
else
{
if (!JoinSquad && !it->bExecuteObjective)
{
JoinSquad = &(*it);
}
}
}
}
if (JoinSquad)
{
JoinSquad->SquadMembers.push_back(pBot);
return JoinSquad;
}
AvHAISquad NewSquad;
NewSquad.SquadTeam = pBot->Player->GetTeam();
NewSquad.ObjectiveLocation = TaskLocation;
NewSquad.SquadObjective = ObjectiveType;
NewSquad.bExecuteObjective = false;
NewSquad.SquadGatherLocation = ZERO_VECTOR;
ActiveSquads.push_back(NewSquad);
return nullptr;
}
void AITAC_ClearSquads() void AITAC_ClearSquads()
{ {
ActiveSquads.clear(); ActiveSquads.clear();

View file

@ -208,6 +208,7 @@ void AITAC_UpdateSquads();
void AITAC_ManageSquads(); void AITAC_ManageSquads();
void AITAC_ClearSquads(); void AITAC_ClearSquads();
AvHAISquad* AITAC_GetSquadForObjective(AvHAIPlayer* pBot, edict_t* TaskTarget, BotTaskType ObjectiveType); AvHAISquad* AITAC_GetSquadForObjective(AvHAIPlayer* pBot, edict_t* TaskTarget, BotTaskType ObjectiveType);
AvHAISquad* AITAC_GetSquadForObjective(AvHAIPlayer* pBot, Vector TaskLocation, BotTaskType ObjectiveType);
Vector AITAC_GetGatherLocationForSquad(AvHAISquad* Squad); Vector AITAC_GetGatherLocationForSquad(AvHAISquad* Squad);
#endif #endif

View file

@ -395,8 +395,8 @@ bool AITASK_IsTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
return AITASK_IsAlienSecureHiveTaskStillValid(pBot, Task); return AITASK_IsAlienSecureHiveTaskStillValid(pBot, Task);
} }
} }
case TASK_ATTACK_BASE: case TASK_ASSAULT_MARINE_BASE:
return true; return AITASK_IsAssaultMarineBaseTaskStillValid(pBot, Task);
case TASK_DEFEND: case TASK_DEFEND:
return AITASK_IsDefendTaskStillValid(pBot, Task); return AITASK_IsDefendTaskStillValid(pBot, Task);
case TASK_WELD: case TASK_WELD:
@ -961,6 +961,24 @@ bool AITASK_IsAlienSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask*
return AITAC_DeployableExistsAtLocation(HiveToSecure->FloorLocation, &EnemyStuff); return AITAC_DeployableExistsAtLocation(HiveToSecure->FloorLocation, &EnemyStuff);
} }
bool AITASK_IsAssaultMarineBaseTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
{
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
if (AIMGR_GetTeamType(EnemyTeam) != AVH_CLASS_TYPE_MARINE) { return false; }
DeployableSearchFilter StructureFilter;
StructureFilter.DeployableTeam = EnemyTeam;
StructureFilter.DeployableTypes = (STRUCTURE_MARINE_OBSERVATORY | STRUCTURE_MARINE_ARMSLAB | STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY | STRUCTURE_MARINE_INFANTRYPORTAL | STRUCTURE_MARINE_COMMCHAIR | STRUCTURE_MARINE_PROTOTYPELAB);
StructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
StructureFilter.ReachabilityTeam = BotTeam;
StructureFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
StructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
return AITAC_DeployableExistsAtLocation(Task->TaskLocation, &StructureFilter);
}
bool AITASK_IsMarineSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task) bool AITASK_IsMarineSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
{ {
if (!Task || FNullEnt(Task->TaskTarget) || IsPlayerAlien(pBot->Edict)) { return false; } if (!Task || FNullEnt(Task->TaskTarget) || IsPlayerAlien(pBot->Edict)) { return false; }
@ -2577,6 +2595,9 @@ void BotProgressTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
} }
} }
break; break;
case TASK_ASSAULT_MARINE_BASE:
BotProgressAssaultMarineBaseTask(pBot, Task);
break;
default: default:
break; break;
@ -2997,6 +3018,115 @@ void MarineProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
} }
void BotProgressAssaultMarineBaseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
{
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
if (AIMGR_GetTeamType(BotTeam) == AVH_CLASS_TYPE_ALIEN)
{
AvHAISquad* ActiveSquad = AITAC_GetSquadForObjective(pBot, Task->TaskLocation, Task->TaskType);
if (ActiveSquad && !ActiveSquad->bExecuteObjective && !vIsZero(ActiveSquad->SquadGatherLocation))
{
BotGuardLocation(pBot, ActiveSquad->SquadGatherLocation);
return;
}
}
DeployableSearchFilter EnemyStructureFilter;
EnemyStructureFilter.DeployableTeam = EnemyTeam;
EnemyStructureFilter.ReachabilityTeam = BotTeam;
EnemyStructureFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
EnemyStructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(15.0f);
EnemyStructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
// First go for any TFs, to eliminate defences
EnemyStructureFilter.DeployableTypes = (STRUCTURE_MARINE_TURRETFACTORY | STRUCTURE_MARINE_ADVTURRETFACTORY);
vector<AvHAIBuildableStructure> Structures = AITAC_FindAllDeployables(Task->TaskLocation, &EnemyStructureFilter);
for (auto it = Structures.begin(); it != Structures.end(); it++)
{
float DistToStructure = vDist2D(pBot->Edict->v.origin, it->Location) - 5.0f;
if (AITAC_GetNumPlayersOfTeamInArea(BotTeam, it->Location, DistToStructure, false, pBot->Edict, AVH_USER3_NONE) < 2)
{
BotAttackNonPlayerTarget(pBot, it->edict);
return;
}
}
// First go for any observatory, to prevent beacon
EnemyStructureFilter.DeployableTypes = STRUCTURE_MARINE_OBSERVATORY;
Structures = AITAC_FindAllDeployables(Task->TaskLocation, &EnemyStructureFilter);
for (auto it = Structures.begin(); it != Structures.end(); it++)
{
float DistToStructure = vDist2D(pBot->Edict->v.origin, it->Location) - 5.0f;
if (AITAC_GetNumPlayersOfTeamInArea(BotTeam, it->Location, DistToStructure, false, pBot->Edict, AVH_USER3_NONE) < 2)
{
BotAttackNonPlayerTarget(pBot, it->edict);
return;
}
}
// Next go for any arms lab, to weaken the marines
EnemyStructureFilter.DeployableTypes = STRUCTURE_MARINE_ARMSLAB;
Structures = AITAC_FindAllDeployables(Task->TaskLocation, &EnemyStructureFilter);
for (auto it = Structures.begin(); it != Structures.end(); it++)
{
float DistToStructure = vDist2D(pBot->Edict->v.origin, it->Location) - 5.0f;
if (AITAC_GetNumPlayersOfTeamInArea(BotTeam, it->Location, DistToStructure, false, pBot->Edict, AVH_USER3_NONE) < 2)
{
BotAttackNonPlayerTarget(pBot, it->edict);
return;
}
}
// Next go for any infantry portals, to prevent reinforcements
EnemyStructureFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL;
Structures = AITAC_FindAllDeployables(Task->TaskLocation, &EnemyStructureFilter);
for (auto it = Structures.begin(); it != Structures.end(); it++)
{
float DistToStructure = vDist2D(pBot->Edict->v.origin, it->Location) - 5.0f;
if (AITAC_GetNumPlayersOfTeamInArea(BotTeam, it->Location, DistToStructure, false, pBot->Edict, AVH_USER3_NONE) < 2)
{
BotAttackNonPlayerTarget(pBot, it->edict);
return;
}
}
// Finally, any other structures
EnemyStructureFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
Structures = AITAC_FindAllDeployables(Task->TaskLocation, &EnemyStructureFilter);
for (auto it = Structures.begin(); it != Structures.end(); it++)
{
float DistToStructure = vDist2D(pBot->Edict->v.origin, it->Location) - 5.0f;
if (AITAC_GetNumPlayersOfTeamInArea(BotTeam, it->Location, DistToStructure, false, pBot->Edict, AVH_USER3_NONE) < 2)
{
BotAttackNonPlayerTarget(pBot, it->edict);
return;
}
}
// nothing to attack, just hang around
BotGuardLocation(pBot, Task->TaskLocation);
}
void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation) void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
{ {
float DistFromGuardLocation = vDist2DSq(pBot->Edict->v.origin, GuardLocation); float DistFromGuardLocation = vDist2DSq(pBot->Edict->v.origin, GuardLocation);
@ -3858,6 +3988,19 @@ void AITASK_SetMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict
Task->bTaskIsUrgent = bIsUrgent; Task->bTaskIsUrgent = bIsUrgent;
Task->TaskLocation = UTIL_GetNextMinePosition2(Target); Task->TaskLocation = UTIL_GetNextMinePosition2(Target);
Task->StructureType = STRUCTURE_MARINE_DEPLOYEDMINE; Task->StructureType = STRUCTURE_MARINE_DEPLOYEDMINE;
}
void AITASK_SetAssaultMarineBaseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, Vector BaseLocation, bool bIsUrgent)
{
if (Task->TaskType == TASK_ASSAULT_MARINE_BASE && vEquals(BaseLocation, Task->TaskLocation))
{
Task->bTaskIsUrgent = bIsUrgent;
return;
}
AITASK_ClearBotTask(pBot, Task);
Task->TaskType = TASK_ASSAULT_MARINE_BASE;
Task->TaskLocation = BaseLocation;
Task->bTaskIsUrgent = bIsUrgent;
} }

View file

@ -47,6 +47,8 @@ bool AITASK_IsReinforceStructureTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTas
bool AITASK_IsMarineSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task); bool AITASK_IsMarineSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
bool AITASK_IsAlienSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task); bool AITASK_IsAlienSecureHiveTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
bool AITASK_IsAssaultMarineBaseTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
bool AITASK_IsAlienGetHealthTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task); bool AITASK_IsAlienGetHealthTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
bool AITASK_IsAlienHealTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task); bool AITASK_IsAlienHealTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
@ -67,6 +69,7 @@ void AITASK_SetReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task,
void AITASK_SetReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const AvHAIDeployableStructureType FirstStructureType, bool bIsUrgent); void AITASK_SetReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const AvHAIDeployableStructureType FirstStructureType, bool bIsUrgent);
void AITASK_SetSecureHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const Vector WaitLocation, bool bIsUrgent); void AITASK_SetSecureHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const Vector WaitLocation, bool bIsUrgent);
void AITASK_SetMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, bool bIsUrgent); void AITASK_SetMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, bool bIsUrgent);
void AITASK_SetAssaultMarineBaseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, Vector BaseLocation, bool bIsUrgent);
void AITASK_SetWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const bool bIsUrgent); void AITASK_SetWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const bool bIsUrgent);
void AITASK_SetPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const bool bIsUrgent); void AITASK_SetPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Target, const bool bIsUrgent);
void AITASK_SetGetHealthTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* HealingSource, const bool bIsUrgent); void AITASK_SetGetHealthTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* HealingSource, const bool bIsUrgent);
@ -90,6 +93,8 @@ void MarineProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
void MarineProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task); void MarineProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
void BotProgressWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task); void BotProgressWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
void BotProgressAssaultMarineBaseTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
void AIPlayerBuildStructure(AvHAIPlayer* pBot, edict_t* BuildTarget); void AIPlayerBuildStructure(AvHAIPlayer* pBot, edict_t* BuildTarget);
void MarineProgressSecureHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task); void MarineProgressSecureHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);