mirror of
https://github.com/ENSL/NS.git
synced 2025-03-14 14:41:15 +00:00
More alien role work
This commit is contained in:
parent
9e4c531346
commit
bb810972c5
7 changed files with 369 additions and 134 deletions
|
@ -95,6 +95,7 @@ struct dtTileCacheParams
|
|||
float walkableHeight;
|
||||
float walkableRadius;
|
||||
float walkableClimb;
|
||||
float walkableSlope;
|
||||
float maxSimplificationError;
|
||||
int maxTiles;
|
||||
int maxObstacles;
|
||||
|
|
|
@ -289,6 +289,8 @@ typedef struct _BOT_GUARD_INFO
|
|||
Vector GuardLookLocation = g_vecZero; // Which area are we currently watching?
|
||||
float GuardStartLookTime = 0.0f; // When did we start watching the current area?
|
||||
float ThisGuardLookTime = 0.0f; // How long should we watch this area for?
|
||||
float ThisGuardStandTime = 0.0f; // How long should we watch this area for?
|
||||
float GuardStartStandTime = 0.0f; // How long should we watch this area for?
|
||||
|
||||
} AvHAIGuardInfo;
|
||||
|
||||
|
|
|
@ -2102,7 +2102,7 @@ void AIPlayerSetMarineAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
|
||||
if (AITAC_PhaseGatesAvailable(pBot->Player->GetTeam()))
|
||||
{
|
||||
const AvHAIHiveDefinition* ActiveHive = AITAC_GetActiveHiveNearestLocation(pBot->Edict->v.origin);
|
||||
const AvHAIHiveDefinition* ActiveHive = AITAC_GetActiveHiveNearestLocation(AIMGR_GetEnemyTeam(pBot->Player->GetTeam()), pBot->Edict->v.origin);
|
||||
|
||||
if (ActiveHive)
|
||||
{
|
||||
|
@ -2471,11 +2471,11 @@ void AIPlayerSetAlienBuilderPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
return;
|
||||
}
|
||||
|
||||
Vector ActualBuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BuildOrigin, UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
Vector ActualBuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), BuildOrigin, UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
|
||||
if (vIsZero(ActualBuildLocation))
|
||||
{
|
||||
ActualBuildLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(GORGE_BASE_NAV_PROFILE), BuildOrigin, UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
ActualBuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(GORGE_BASE_NAV_PROFILE), BuildOrigin, UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
}
|
||||
|
||||
AITASK_SetBuildTask(pBot, Task, MissingStructure, ActualBuildLocation, false);
|
||||
|
@ -2779,6 +2779,131 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
|
||||
void AIPlayerSetAlienHarasserPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
// If we aren't a lerk, go evolve into one. If we can't, then act like a regular assault alien until we can
|
||||
if (!IsPlayerLerk(pBot->Edict))
|
||||
{
|
||||
if (pBot->Player->GetResources() >= BALANCE_VAR(kLerkCost))
|
||||
{
|
||||
if (Task->TaskType == TASK_EVOLVE && Task->Evolution == ALIEN_LIFEFORM_THREE) { return; }
|
||||
|
||||
vector<AvHAIHiveDefinition*> AllTeamHives = AITAC_GetAllTeamHives(pBot->Player->GetTeam());
|
||||
|
||||
AvHAIHiveDefinition* NearestHive = nullptr;
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = AllTeamHives.begin(); it != AllTeamHives.end(); it++)
|
||||
{
|
||||
float ThisDist = vDist2DSq(pBot->Edict->v.origin, (*it)->FloorLocation);
|
||||
|
||||
if (!NearestHive || ThisDist < MinDist)
|
||||
{
|
||||
NearestHive = (*it);
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
||||
if (NearestHive)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEntity->edict(), ALIEN_LIFEFORM_THREE, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, pBot->Edict->v.origin, ALIEN_LIFEFORM_THREE, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
BotEvolveLifeform(pBot, pBot->Edict->v.origin, ALIEN_LIFEFORM_ONE);
|
||||
return;
|
||||
}
|
||||
|
||||
AIPlayerSetAlienAssaultPrimaryTask(pBot, Task);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||
|
||||
DeployableSearchFilter EnemyStructureFilter;
|
||||
EnemyStructureFilter.DeployableTeam = EnemyTeam;
|
||||
EnemyStructureFilter.ReachabilityTeam = BotTeam;
|
||||
EnemyStructureFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
|
||||
Vector EnemyBaseLocation = AITAC_GetTeamStartingLocation(EnemyTeam);
|
||||
|
||||
AvHAIBuildableStructure* EnemyStructureToAttack = nullptr;
|
||||
|
||||
bool bEnemyIsMarines = (AIMGR_GetTeamType(EnemyTeam) == AVH_CLASS_TYPE_MARINE);
|
||||
|
||||
if (bEnemyIsMarines)
|
||||
{
|
||||
EnemyStructureFilter.DeployableTypes = (STRUCTURE_MARINE_ARMSLAB | STRUCTURE_MARINE_OBSERVATORY | STRUCTURE_MARINE_INFANTRYPORTAL);
|
||||
EnemyStructureToAttack = AITAC_FindFurthestDeployableFromLocation(EnemyBaseLocation, &EnemyStructureFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnemyStructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
EnemyStructureFilter.DeployableTypes = (STRUCTURE_ALIEN_RESTOWER | STRUCTURE_ALIEN_DEFENCECHAMBER | STRUCTURE_ALIEN_MOVEMENTCHAMBER | STRUCTURE_ALIEN_SENSORYCHAMBER);
|
||||
EnemyStructureToAttack = AITAC_FindClosestDeployableToLocation(EnemyBaseLocation, &EnemyStructureFilter);
|
||||
}
|
||||
|
||||
if (EnemyStructureToAttack)
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyStructureToAttack->edict, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bEnemyIsMarines)
|
||||
{
|
||||
edict_t* CommChair = AITAC_GetCommChair(EnemyTeam);
|
||||
|
||||
if (!FNullEnt(CommChair))
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, CommChair, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const AvHAIHiveDefinition* EnemyHive = AITAC_GetActiveHiveNearestLocation(EnemyTeam, pBot->Edict->v.origin);
|
||||
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyHive->HiveEntity->edict(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
vector<AvHPlayer*> AllEnemyPlayers = AIMGR_GetAllPlayersOnTeam(EnemyTeam);
|
||||
edict_t* TargetPlayer = nullptr;
|
||||
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = AllEnemyPlayers.begin(); it != AllEnemyPlayers.end(); it++)
|
||||
{
|
||||
AvHPlayer* ThisPlayer = (*it);
|
||||
|
||||
if (!ThisPlayer) { continue; }
|
||||
|
||||
edict_t* PlayerEdict = ThisPlayer->edict();
|
||||
|
||||
if (!IsPlayerActiveInGame(PlayerEdict)) { continue; }
|
||||
|
||||
float ThisDist = vDist2DSq(PlayerEdict->v.origin, pBot->Edict->v.origin);
|
||||
|
||||
if (FNullEnt(TargetPlayer) || ThisDist < MinDist)
|
||||
{
|
||||
TargetPlayer = PlayerEdict;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FNullEnt(TargetPlayer))
|
||||
{
|
||||
MoveTo(pBot, UTIL_GetFloorUnderEntity(TargetPlayer), MOVESTYLE_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "../AvHGamerules.h"
|
||||
#include "../AvHServerUtil.h"
|
||||
#include "../AvHMarineEquipment.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
@ -695,8 +696,28 @@ void AITAC_RefreshHiveData()
|
|||
|
||||
it->TechStatus = theEntity->GetTechnology();
|
||||
it->bIsUnderAttack = GetGameRules()->GetIsEntityUnderAttack(theEntity->entindex());
|
||||
it->OwningTeam = theEntity->GetTeamNumber();
|
||||
it->Status = (theEntity->GetIsActive() ? HIVE_STATUS_BUILT : (theEntity->GetIsSpawning() ? HIVE_STATUS_BUILDING : HIVE_STATUS_UNBUILT));
|
||||
|
||||
AvHTeamNumber CurrentOwningTeam = theEntity->GetTeamNumber();
|
||||
HiveStatusType CurrentStatus = (theEntity->GetIsActive() ? HIVE_STATUS_BUILT : (theEntity->GetIsSpawning() ? HIVE_STATUS_BUILDING : HIVE_STATUS_UNBUILT));
|
||||
|
||||
bool bHiveDestroyed = (CurrentOwningTeam != it->OwningTeam) || (it->Status == HIVE_STATUS_BUILT && CurrentStatus != it->Status);
|
||||
|
||||
if (bHiveDestroyed)
|
||||
{
|
||||
if (it->OwningTeam == GetGameRules()->GetTeamANumber())
|
||||
{
|
||||
TeamAStartingLocation = ZERO_VECTOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
TeamBStartingLocation = ZERO_VECTOR;
|
||||
}
|
||||
|
||||
AITAC_GetTeamStartingLocation(it->OwningTeam); // Force refresh
|
||||
}
|
||||
|
||||
it->OwningTeam = CurrentOwningTeam;
|
||||
it->Status = CurrentStatus;
|
||||
|
||||
if (it->Status != HIVE_STATUS_UNBUILT && it->ObstacleRefs[REGULAR_NAV_MESH] == 0)
|
||||
{
|
||||
|
@ -718,13 +739,15 @@ void AITAC_RefreshHiveData()
|
|||
|
||||
NextRefresh++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vector AITAC_GetTeamStartingLocation(AvHTeamNumber Team)
|
||||
{
|
||||
if (vIsZero(TeamAStartingLocation) || vIsZero(TeamBStartingLocation))
|
||||
{
|
||||
AvHTeamNumber TeamANum = GetGameRules()->GetTeamANumber();
|
||||
AvHTeamNumber TeamBNum = GetGameRules()->GetTeamBNumber();
|
||||
|
||||
AvHTeam* AvHTeamARef = GetGameRules()->GetTeamA();
|
||||
AvHTeam* AvHTeamBRef = GetGameRules()->GetTeamB();
|
||||
|
||||
|
@ -734,13 +757,29 @@ Vector AITAC_GetTeamStartingLocation(AvHTeamNumber Team)
|
|||
|
||||
if (AvHTeamARef->GetTeamType() == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
TeamAStartingLocation = TeamStartLocation;
|
||||
DeployableSearchFilter IFFilter;
|
||||
IFFilter.DeployableTeam = TeamANum;
|
||||
IFFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL;
|
||||
IFFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
IFFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
|
||||
AvHAIBuildableStructure* InfantryPortal = AITAC_FindClosestDeployableToLocation(ZERO_VECTOR, &IFFilter);
|
||||
|
||||
if (InfantryPortal)
|
||||
{
|
||||
TeamAStartingLocation = InfantryPortal->Location;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector CommChairLocation = AITAC_GetCommChairLocation(TeamANum);
|
||||
TeamAStartingLocation = (!vIsZero(CommChairLocation)) ? CommChairLocation : TeamStartLocation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TeamAStartingLocation = TeamStartLocation;
|
||||
|
||||
const AvHAIHiveDefinition* Hive = AITAC_GetHiveNearestLocation(TeamStartLocation);
|
||||
const AvHAIHiveDefinition* Hive = AITAC_GetActiveHiveNearestLocation(TeamANum, TeamStartLocation);
|
||||
|
||||
if (Hive)
|
||||
{
|
||||
|
@ -759,13 +798,29 @@ Vector AITAC_GetTeamStartingLocation(AvHTeamNumber Team)
|
|||
|
||||
if (AvHTeamBRef->GetTeamType() == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
TeamBStartingLocation = TeamStartLocation;
|
||||
DeployableSearchFilter IFFilter;
|
||||
IFFilter.DeployableTeam = TeamBNum;
|
||||
IFFilter.DeployableTypes = STRUCTURE_MARINE_INFANTRYPORTAL;
|
||||
IFFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
IFFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
|
||||
AvHAIBuildableStructure* InfantryPortal = AITAC_FindClosestDeployableToLocation(ZERO_VECTOR, &IFFilter);
|
||||
|
||||
if (InfantryPortal)
|
||||
{
|
||||
TeamAStartingLocation = InfantryPortal->Location;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector CommChairLocation = AITAC_GetCommChairLocation(TeamBNum);
|
||||
TeamAStartingLocation = (!vIsZero(CommChairLocation)) ? CommChairLocation : TeamStartLocation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TeamBStartingLocation = TeamStartLocation;
|
||||
|
||||
const AvHAIHiveDefinition* Hive = AITAC_GetActiveHiveNearestLocation(TeamStartLocation);
|
||||
const AvHAIHiveDefinition* Hive = AITAC_GetActiveHiveNearestLocation(TeamBNum, TeamStartLocation);
|
||||
|
||||
if (Hive)
|
||||
{
|
||||
|
@ -777,6 +832,9 @@ Vector AITAC_GetTeamStartingLocation(AvHTeamNumber Team)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update reachabilities since team starting points have been modified
|
||||
bNavMeshModified = true;
|
||||
}
|
||||
|
||||
return (Team == GetGameRules()->GetTeamANumber()) ? TeamAStartingLocation : TeamBStartingLocation;
|
||||
|
@ -794,18 +852,11 @@ Vector AITAC_GetCommChairLocation(AvHTeamNumber Team)
|
|||
}
|
||||
}
|
||||
|
||||
DeployableSearchFilter ChairFilter;
|
||||
ChairFilter.DeployableTypes = STRUCTURE_MARINE_COMMCHAIR;
|
||||
ChairFilter.DeployableTeam = Team;
|
||||
ChairFilter.ReachabilityTeam = TEAM_IND;
|
||||
ChairFilter.bConsiderPhaseDistance = false;
|
||||
ChairFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
edict_t* Chair = AITAC_GetCommChair(Team);
|
||||
|
||||
AvHAIBuildableStructure* ChairRef = AITAC_FindClosestDeployableToLocation(ZERO_VECTOR, &ChairFilter);
|
||||
|
||||
if (ChairRef)
|
||||
if (!FNullEnt(Chair))
|
||||
{
|
||||
return ChairRef->Location;
|
||||
return Chair->v.origin;
|
||||
}
|
||||
|
||||
return ZERO_VECTOR;
|
||||
|
@ -1708,10 +1759,15 @@ AvHAIBuildableStructure* AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
|
||||
unsigned int NewFlags = STRUCTURE_STATUS_NONE;
|
||||
|
||||
bool bJustCompleted = false;
|
||||
bool bJustRecycled = false;
|
||||
bool bJustDestroyed = false;
|
||||
|
||||
if (BaseBuildable->GetIsBuilt())
|
||||
{
|
||||
if (!(BuildingMap[EntIndex].StructureStatusFlags & STRUCTURE_STATUS_COMPLETED)) {
|
||||
AITAC_OnStructureCompleted(&BuildingMap[EntIndex]);
|
||||
if (!(BuildingMap[EntIndex].StructureStatusFlags & STRUCTURE_STATUS_COMPLETED))
|
||||
{
|
||||
bJustCompleted = true;
|
||||
}
|
||||
NewFlags |= STRUCTURE_STATUS_COMPLETED;
|
||||
}
|
||||
|
@ -1730,7 +1786,7 @@ AvHAIBuildableStructure* AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
{
|
||||
if (!(BuildingMap[EntIndex].StructureStatusFlags & STRUCTURE_STATUS_RECYCLING))
|
||||
{
|
||||
AITAC_OnStructureBeginRecycling(&BuildingMap[EntIndex]);
|
||||
bJustRecycled = true;
|
||||
}
|
||||
NewFlags |= STRUCTURE_STATUS_RECYCLING;
|
||||
}
|
||||
|
@ -1757,6 +1813,16 @@ AvHAIBuildableStructure* AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
BuildingMap[EntIndex].StructureStatusFlags = NewFlags;
|
||||
BuildingMap[EntIndex].LastSeen = StructureRefreshFrame;
|
||||
|
||||
if (bJustCompleted)
|
||||
{
|
||||
AITAC_OnStructureCompleted(&BuildingMap[EntIndex]);
|
||||
}
|
||||
|
||||
if (bJustRecycled)
|
||||
{
|
||||
AITAC_OnStructureBeginRecycling(&BuildingMap[EntIndex]);
|
||||
}
|
||||
|
||||
return &BuildingMap[EntIndex];
|
||||
|
||||
}
|
||||
|
@ -1819,6 +1885,22 @@ void AITAC_OnStructureCompleted(AvHAIBuildableStructure* NewStructure)
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
if (NewStructure->StructureType == STRUCTURE_MARINE_INFANTRYPORTAL)
|
||||
{
|
||||
AvHTeamNumber Team = (AvHTeamNumber)NewStructure->edict->v.team;
|
||||
|
||||
if (Team == GetGameRules()->GetTeamANumber())
|
||||
{
|
||||
TeamAStartingLocation = ZERO_VECTOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
TeamBStartingLocation = ZERO_VECTOR;
|
||||
}
|
||||
|
||||
AITAC_GetTeamStartingLocation(Team); // Force refresh of reachabilities and team starting locations
|
||||
}
|
||||
}
|
||||
|
||||
void AITAC_RemovePhaseGateConnections(AvHAIBuildableStructure* SourceGate, AvHAIBuildableStructure* TargetGate)
|
||||
|
@ -1881,6 +1963,22 @@ void AITAC_OnStructureDestroyed(AvHAIBuildableStructure* DestroyedStructure)
|
|||
AITAC_RemovePhaseGateConnections(OtherPhaseGate, DestroyedStructure);
|
||||
}
|
||||
}
|
||||
|
||||
if (DestroyedStructure->StructureType == STRUCTURE_MARINE_INFANTRYPORTAL)
|
||||
{
|
||||
AvHTeamNumber Team = (AvHTeamNumber)DestroyedStructure->edict->v.team;
|
||||
|
||||
if (Team == GetGameRules()->GetTeamANumber())
|
||||
{
|
||||
TeamAStartingLocation = ZERO_VECTOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
TeamBStartingLocation = ZERO_VECTOR;
|
||||
}
|
||||
|
||||
AITAC_GetTeamStartingLocation(Team); // Force refresh of reachabilities and team starting locations
|
||||
}
|
||||
}
|
||||
|
||||
void AITAC_LinkAlienStructureToPlayer(AvHAIBuildableStructure* NewStructure)
|
||||
|
@ -2329,14 +2427,14 @@ const AvHAIHiveDefinition* AITAC_GetHiveNearestLocation(const Vector SearchLocat
|
|||
return Result;
|
||||
}
|
||||
|
||||
const AvHAIHiveDefinition* AITAC_GetActiveHiveNearestLocation(const Vector SearchLocation)
|
||||
const AvHAIHiveDefinition* AITAC_GetActiveHiveNearestLocation(AvHTeamNumber Team, const Vector SearchLocation)
|
||||
{
|
||||
AvHAIHiveDefinition* Result = nullptr;
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = Hives.begin(); it != Hives.end(); it++)
|
||||
{
|
||||
if (it->Status != HIVE_STATUS_BUILT) { continue; }
|
||||
if (it->Status != HIVE_STATUS_BUILT || it->OwningTeam != Team) { continue; }
|
||||
|
||||
float ThisDist = vDist3DSq(SearchLocation, it->Location);
|
||||
|
||||
|
@ -3133,23 +3231,30 @@ edict_t* AITAC_GetCommChair(AvHTeamNumber Team)
|
|||
ChairFilter.DeployableTeam = Team;
|
||||
ChairFilter.ReachabilityTeam = TEAM_IND;
|
||||
|
||||
AvHAIBuildableStructure* ChairStructure = AITAC_FindClosestDeployableToLocation(ZERO_VECTOR, &ChairFilter);
|
||||
vector<AvHAIBuildableStructure*> CommChairs = AITAC_FindAllDeployables(ZERO_VECTOR, &ChairFilter);
|
||||
|
||||
if (ChairStructure)
|
||||
edict_t* MainCommChair = nullptr;
|
||||
edict_t* BackupChair = nullptr;
|
||||
|
||||
// If the team has more than one comm chair, pick the one in use
|
||||
for (auto it = CommChairs.begin(); it != CommChairs.end(); it++)
|
||||
{
|
||||
return ChairStructure->edict;
|
||||
AvHCommandStation* ChairRef = dynamic_cast<AvHCommandStation*>((*it)->EntityRef);
|
||||
|
||||
// Idle animation will be 3 if the chair is in use (closed animation). See AvHCommandStation::GetIdleAnimation
|
||||
if (ChairRef && ChairRef->GetIdleAnimation() == 3)
|
||||
{
|
||||
MainCommChair = ChairRef->edict();
|
||||
}
|
||||
else
|
||||
{
|
||||
BackupChair = ChairRef->edict();
|
||||
}
|
||||
}
|
||||
|
||||
ChairFilter.DeployableTeam = TEAM_IND;
|
||||
if (!FNullEnt(MainCommChair)) { return MainCommChair;}
|
||||
|
||||
ChairStructure = AITAC_FindClosestDeployableToLocation(AITAC_GetTeamStartingLocation(Team), &ChairFilter);
|
||||
|
||||
if (ChairStructure)
|
||||
{
|
||||
return ChairStructure->edict;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return BackupChair;
|
||||
}
|
||||
|
||||
edict_t* AITAC_GetNearestHumanAtLocation(const AvHTeamNumber Team, const Vector Location, const float MaxSearchRadius)
|
||||
|
@ -3372,6 +3477,21 @@ const vector<AvHAIHiveDefinition*> AITAC_GetAllHives()
|
|||
return Results;
|
||||
}
|
||||
|
||||
const vector<AvHAIHiveDefinition*> AITAC_GetAllTeamHives(AvHTeamNumber Team)
|
||||
{
|
||||
vector<AvHAIHiveDefinition*> Results;
|
||||
|
||||
for (auto it = Hives.begin(); it != Hives.end(); it++)
|
||||
{
|
||||
if (it->OwningTeam == Team)
|
||||
{
|
||||
Results.push_back(&(*it));
|
||||
}
|
||||
}
|
||||
|
||||
return Results;
|
||||
}
|
||||
|
||||
bool AITAC_AnyPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, float SearchRadius)
|
||||
{
|
||||
float distSq = sqrf(SearchRadius);
|
||||
|
@ -3521,17 +3641,16 @@ bool AITAC_IsAlienCapperNeeded(AvHAIPlayer* pBot)
|
|||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||
|
||||
float ResNodeOwnership = AITAC_GetTeamResNodeOwnership(BotTeam, false);
|
||||
float EnemyNodeOwnership = AITAC_GetTeamResNodeOwnership(EnemyTeam, false);
|
||||
float ResNodeOwnership = AITAC_GetTeamResNodeOwnership(BotTeam, true);
|
||||
|
||||
if (ResNodeOwnership > 0.6f) { return false; }
|
||||
|
||||
int NumTeamPlayers = AIMGR_GetNumPlayersOnTeam(BotTeam);
|
||||
int MaxCappers = (int)ceilf((float)NumTeamPlayers * 0.5f);
|
||||
int MaxCappers = (int)ceilf((float)NumTeamPlayers * 0.4f);
|
||||
|
||||
int NumCurrentCappers = AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_FIND_RESOURCES, pBot);
|
||||
|
||||
int DesiredCappers = 0;
|
||||
|
||||
if (ResNodeOwnership > 0.6f) { return false; }
|
||||
int DesiredCappers = 0;
|
||||
|
||||
if (ResNodeOwnership < 0.25f)
|
||||
{
|
||||
|
@ -3549,7 +3668,7 @@ bool AITAC_IsAlienCapperNeeded(AvHAIPlayer* pBot)
|
|||
// If we're lerk/fade/onos, only go capper if we have lots of resources and can replace them easily, otherwise we can't afford to waste resources going back to gorge
|
||||
if (!IsPlayerSkulk(pBot->Edict) && !IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
if (pBot->Player->GetResources() < 75 || ResNodeOwnership < 0.4f) { return false; }
|
||||
if (pBot->Player->GetResources() < 75 || ResNodeOwnership >= 0.4f) { return false; }
|
||||
|
||||
int NumSkulks = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER1, nullptr);
|
||||
int NumGorges = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER2, nullptr);
|
||||
|
|
|
@ -50,7 +50,7 @@ float AITAC_GetPhaseDistanceBetweenPoints(const Vector StartPoint, const Ve
|
|||
|
||||
const AvHAIHiveDefinition* AITAC_GetHiveAtIndex(int Index);
|
||||
const AvHAIHiveDefinition* AITAC_GetHiveNearestLocation(const Vector SearchLocation);
|
||||
const AvHAIHiveDefinition* AITAC_GetActiveHiveNearestLocation(const Vector SearchLocation);
|
||||
const AvHAIHiveDefinition* AITAC_GetActiveHiveNearestLocation(AvHTeamNumber Team, const Vector SearchLocation);
|
||||
const AvHAIHiveDefinition* AITAC_GetNonEmptyHiveNearestLocation(const Vector SearchLocation);
|
||||
|
||||
Vector AITAC_GetCommChairLocation(AvHTeamNumber Team);
|
||||
|
@ -157,6 +157,7 @@ edict_t* AITAC_GetNearestHiddenPlayerInLocation(AvHTeamNumber Team, const Vector
|
|||
|
||||
const vector<AvHAIResourceNode*> AITAC_GetAllResourceNodes();
|
||||
const vector<AvHAIHiveDefinition*> AITAC_GetAllHives();
|
||||
const vector<AvHAIHiveDefinition*> AITAC_GetAllTeamHives(AvHTeamNumber Team);
|
||||
|
||||
bool AITAC_AnyPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, float SearchRadius);
|
||||
|
||||
|
|
|
@ -1893,10 +1893,15 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!vIsZero(Task->TaskLocation))
|
||||
{
|
||||
UTIL_DrawLine(INDEXENT(1), pBot->Edict->v.origin, Task->TaskLocation);
|
||||
}
|
||||
|
||||
// We tried and failed to place the structure
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED)
|
||||
{
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
||||
}
|
||||
|
||||
|
@ -1909,6 +1914,29 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (pBot->Player->GetResources() < ResRequired)
|
||||
{
|
||||
|
||||
if (IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
|
||||
DeployableSearchFilter UnfinishedFilter;
|
||||
UnfinishedFilter.DeployableTeam = BotTeam;
|
||||
UnfinishedFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
UnfinishedFilter.ReachabilityTeam = BotTeam;
|
||||
UnfinishedFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
UnfinishedFilter.ExcludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
UnfinishedFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
|
||||
|
||||
AvHAIBuildableStructure* UnfinishedStructure = AITAC_FindClosestDeployableToLocation(Task->TaskLocation, &UnfinishedFilter);
|
||||
|
||||
if (UnfinishedStructure)
|
||||
{
|
||||
AIPlayerBuildStructure(pBot, UnfinishedStructure->edict);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BotGuardLocation(pBot, Task->TaskLocation);
|
||||
return;
|
||||
}
|
||||
|
@ -2578,17 +2606,21 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
if (DistFromGuardLocation > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
pBot->GuardInfo.GuardLocation = g_vecZero;
|
||||
pBot->GuardInfo.GuardStartLookTime = 0.0f;
|
||||
pBot->GuardInfo.ThisGuardLookTime = 0.0f;
|
||||
pBot->GuardInfo.GuardStartStandTime = 0.0f;
|
||||
pBot->GuardInfo.ThisGuardStandTime = 0.0f;
|
||||
MoveTo(pBot, GuardLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pBot->GuardInfo.GuardLocation)
|
||||
if (vIsZero(pBot->GuardInfo.GuardLocation))
|
||||
{
|
||||
AITASK_GenerateGuardWatchPoints(pBot, GuardLocation);
|
||||
pBot->GuardInfo.GuardLocation = GuardLocation;
|
||||
}
|
||||
|
||||
if (gpGlobals->time - pBot->GuardInfo.GuardStartLookTime > pBot->GuardInfo.ThisGuardLookTime)
|
||||
if (gpGlobals->time > pBot->GuardInfo.ThisGuardLookTime)
|
||||
{
|
||||
if (pBot->GuardInfo.NumGuardPoints > 0)
|
||||
{
|
||||
|
@ -2603,36 +2635,28 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
pBot->GuardInfo.GuardLookLocation.z = pBot->CurrentEyePosition.z;
|
||||
}
|
||||
|
||||
Vector LookDir = UTIL_GetVectorNormal2D(pBot->GuardInfo.GuardLookLocation - GuardLocation);
|
||||
pBot->GuardInfo.ThisGuardLookTime = gpGlobals->time + frandrange(2.0f, 5.0f);
|
||||
}
|
||||
|
||||
Vector NewMoveCentre = GuardLocation - (LookDir * UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
if (gpGlobals->time > pBot->GuardInfo.ThisGuardStandTime)
|
||||
{
|
||||
pBot->GuardInfo.GuardStandPosition = UTIL_GetRandomPointOnNavmeshInRadius(pBot->BotNavInfo.NavProfile, GuardLocation, UTIL_MetresToGoldSrcUnits(4.0f));
|
||||
|
||||
Vector NewMoveLoc = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[MARINE_BASE_NAV_PROFILE], NewMoveCentre, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
pBot->GuardInfo.ThisGuardStandTime = gpGlobals->time + frandrange(5.0f, 10.0f);
|
||||
}
|
||||
|
||||
if (NewMoveLoc != g_vecZero)
|
||||
if (vDist2DSq(pBot->Edict->v.origin, pBot->GuardInfo.GuardStandPosition) > sqrf(32.0f))
|
||||
{
|
||||
if (IsPlayerLerk(pBot->Edict))
|
||||
{
|
||||
pBot->GuardInfo.GuardStandPosition = NewMoveLoc;
|
||||
MoveTo(pBot, pBot->GuardInfo.GuardStandPosition, MOVESTYLE_HIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->GuardInfo.GuardStandPosition = GuardLocation;
|
||||
MoveTo(pBot, pBot->GuardInfo.GuardStandPosition, MOVESTYLE_NORMAL);
|
||||
}
|
||||
|
||||
pBot->GuardInfo.ThisGuardLookTime = frandrange(2.0f, 5.0f);
|
||||
pBot->GuardInfo.GuardStartLookTime = gpGlobals->time;
|
||||
}
|
||||
|
||||
if (IsPlayerLerk(pBot->Edict))
|
||||
{
|
||||
MoveTo(pBot, pBot->GuardInfo.GuardStandPosition, MOVESTYLE_HIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveTo(pBot, pBot->GuardInfo.GuardStandPosition, MOVESTYLE_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BotLookAt(pBot, pBot->GuardInfo.GuardLookLocation);
|
||||
|
||||
|
||||
|
@ -2659,15 +2683,15 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
path.clear();
|
||||
|
||||
|
||||
for (int i = 0; i < AITAC_GetNumHives(); i++)
|
||||
vector<AvHAIHiveDefinition*> AllHives = AITAC_GetAllHives();
|
||||
|
||||
for (auto it = AllHives.begin(); it != AllHives.end(); it++)
|
||||
{
|
||||
const AvHAIHiveDefinition* Hive = AITAC_GetHiveAtIndex(i);
|
||||
const AvHAIHiveDefinition* ThisHive = (*it);
|
||||
|
||||
if (!Hive) { continue; }
|
||||
if (UTIL_QuickTrace(pEdict, GuardLocation + Vector(0.0f, 0.0f, 10.0f), ThisHive->Location) || vDist2DSq(GuardLocation, ThisHive->Location) < sqrf(UTIL_MetresToGoldSrcUnits(10.0f))) { continue; }
|
||||
|
||||
if (UTIL_QuickTrace(pEdict, GuardLocation + Vector(0.0f, 0.0f, 10.0f), Hive->Location) || vDist2DSq(GuardLocation, Hive->Location) < sqrf(UTIL_MetresToGoldSrcUnits(10.0f))) { continue; }
|
||||
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, Hive->FloorLocation, GuardLocation, path, 500.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, ThisHive->FloorLocation, GuardLocation, path, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult))
|
||||
{
|
||||
|
@ -2680,21 +2704,10 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
}
|
||||
}
|
||||
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(EnemyTeam), GuardLocation, path, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult))
|
||||
if (AIMGR_GetEnemyTeamType(pBot->Player->GetTeam()) == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
Vector FinalApproachDir = UTIL_GetVectorNormal2D(path.back().Location - prev(prev(path.end()))->Location);
|
||||
Vector ProspectiveNewGuardLoc = GuardLocation - (FinalApproachDir * 300.0f);
|
||||
|
||||
ProspectiveNewGuardLoc.z = prev(prev(path.end()))->Location.z;
|
||||
|
||||
pBot->GuardInfo.GuardPoints[pBot->GuardInfo.NumGuardPoints++] = ProspectiveNewGuardLoc;
|
||||
}
|
||||
|
||||
if (vDist2DSq(GuardLocation, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam())) > sqrf(UTIL_MetresToGoldSrcUnits(15.0f)))
|
||||
{
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), GuardLocation, path, 500.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(EnemyTeam), GuardLocation, path, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult))
|
||||
{
|
||||
|
@ -2707,6 +2720,24 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
}
|
||||
}
|
||||
|
||||
if (AIMGR_GetTeamType(pBot->Player->GetTeam()) == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
if (vDist2DSq(GuardLocation, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam())) > sqrf(UTIL_MetresToGoldSrcUnits(15.0f)))
|
||||
{
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), GuardLocation, path, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult))
|
||||
{
|
||||
Vector FinalApproachDir = UTIL_GetVectorNormal2D(path.back().Location - prev(prev(path.end()))->Location);
|
||||
Vector ProspectiveNewGuardLoc = GuardLocation - (FinalApproachDir * 300.0f);
|
||||
|
||||
ProspectiveNewGuardLoc.z = prev(prev(path.end()))->Location.z;
|
||||
|
||||
pBot->GuardInfo.GuardPoints[pBot->GuardInfo.NumGuardPoints++] = ProspectiveNewGuardLoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool BotWithBuildTaskExists(AvHTeamNumber Team, AvHAIDeployableStructureType StructureType)
|
||||
|
|
|
@ -1535,54 +1535,10 @@ BOOL AvHGamerules::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
|
|||
|
||||
theSuccess = true;
|
||||
}
|
||||
else if (FStrEq(pcmd, "getaliencomp"))
|
||||
else if (FStrEq(pcmd, "showteamstarts"))
|
||||
{
|
||||
vector<AvHAIPlayer*> AlienPlayers = AIMGR_GetAIPlayersOnTeam(TEAM_TWO);
|
||||
|
||||
int NumBuilders = 0;
|
||||
int NumCappers = 0;
|
||||
int NumHarassers = 0;
|
||||
int NumAssault = 0;
|
||||
|
||||
for (auto it = AlienPlayers.begin(); it != AlienPlayers.end(); it++)
|
||||
{
|
||||
AvHAIPlayer* NewCapper = (*it);
|
||||
|
||||
if (NewCapper)
|
||||
{
|
||||
switch (NewCapper->BotRole)
|
||||
{
|
||||
case BOT_ROLE_BUILDER:
|
||||
NumBuilders++;
|
||||
break;
|
||||
case BOT_ROLE_FIND_RESOURCES:
|
||||
NumCappers++;
|
||||
break;
|
||||
case BOT_ROLE_HARASS:
|
||||
NumHarassers++;
|
||||
break;
|
||||
case BOT_ROLE_ASSAULT:
|
||||
NumAssault++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[32];
|
||||
|
||||
sprintf(buf, "Builders: %d\n", NumBuilders);
|
||||
UTIL_SayText(buf, theAvHPlayer);
|
||||
|
||||
sprintf(buf, "Cappers: %d\n", NumCappers);
|
||||
UTIL_SayText(buf, theAvHPlayer);
|
||||
|
||||
sprintf(buf, "Harassers: %d\n", NumHarassers);
|
||||
UTIL_SayText(buf, theAvHPlayer);
|
||||
|
||||
sprintf(buf, "Assault: %d\n", NumAssault);
|
||||
UTIL_SayText(buf, theAvHPlayer);
|
||||
UTIL_DrawLine(INDEXENT(1), INDEXENT(1)->v.origin, AITAC_GetTeamStartingLocation(TEAM_ONE), 20.0f, 0, 0, 255);
|
||||
UTIL_DrawLine(INDEXENT(1), INDEXENT(1)->v.origin, AITAC_GetTeamStartingLocation(TEAM_TWO), 20.0f, 255, 255, 0);
|
||||
|
||||
theSuccess = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue