mirror of
https://github.com/ENSL/NS.git
synced 2024-11-21 20:21:14 +00:00
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:
parent
c0bef7cb05
commit
5beb313546
7 changed files with 247 additions and 55 deletions
|
@ -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?
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue