mirror of
https://github.com/ENSL/NS.git
synced 2024-11-10 15:21:54 +00:00
Implement gorge building behaviours
This commit is contained in:
parent
083f1ad3ac
commit
07f488af9a
7 changed files with 227 additions and 213 deletions
|
@ -647,7 +647,7 @@ typedef struct AVH_AI_PLAYER
|
|||
|
||||
nav_status BotNavInfo; // Bot's movement information, their current path, where in the path they are etc.
|
||||
|
||||
AvHAIBuildAttempt BuildAttempts;
|
||||
AvHAIBuildAttempt ActiveBuildInfo; // If gorge, the current status of any recent attempt to place a structure
|
||||
|
||||
vector<ai_commander_request> ActiveRequests;
|
||||
vector<ai_commander_order> ActiveOrders;
|
||||
|
|
|
@ -1560,20 +1560,43 @@ void StartNewBotFrame(AvHAIPlayer* pBot)
|
|||
UpdateCommanderOrders(pBot);
|
||||
}
|
||||
|
||||
// If we tried placing a building as gorge, and nothing has appeared within 0.5s, the placement failed.
|
||||
if (pBot->BuildAttempts.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||
// If we tried placing a building as gorge, and nothing has appeared within the expected time, then mark it as a failed attempt.
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||
{
|
||||
if ((gpGlobals->time - pBot->BuildAttempts.BuildAttemptTime) > 0.5f)
|
||||
if (pBot->ActiveBuildInfo.AttemptedStructureType == STRUCTURE_ALIEN_HIVE)
|
||||
{
|
||||
pBot->BuildAttempts.BuildStatus = BUILD_ATTEMPT_FAILED;
|
||||
// Give a 3-second grace period to check if the hive placement was successful
|
||||
if ((gpGlobals->time - pBot->ActiveBuildInfo.BuildAttemptTime) > 3.0f)
|
||||
{
|
||||
const AvHAIHiveDefinition* NearestHive = AITAC_GetHiveNearestLocation(pBot->ActiveBuildInfo.AttemptedLocation);
|
||||
|
||||
pBot->ActiveBuildInfo.BuildStatus = (NearestHive->Status != HIVE_STATUS_UNBUILT) ? BUILD_ATTEMPT_SUCCESS : BUILD_ATTEMPT_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// All other structures should appear near-instantly
|
||||
if ((gpGlobals->time - pBot->ActiveBuildInfo.BuildAttemptTime) > 0.5f)
|
||||
{
|
||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CustomThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
AICOMM_CommanderThink(pBot);
|
||||
if (IsPlayerAlien(pBot->Edict))
|
||||
{
|
||||
if (!vIsZero(AIDEBUG_GetDebugVector1()))
|
||||
{
|
||||
const AvHAIHiveDefinition* Hive = AITAC_GetHiveNearestLocation(AIDEBUG_GetDebugVector1());
|
||||
|
||||
BotAlienBuildHive(pBot, Hive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DroneThink(AvHAIPlayer* pBot)
|
||||
|
@ -2124,7 +2147,6 @@ void AIPlayerThink(AvHAIPlayer* pBot)
|
|||
if (pBot == AIMGR_GetDebugAIPlayer())
|
||||
{
|
||||
bool bBreak = true;
|
||||
|
||||
}
|
||||
|
||||
switch (GetGameRules()->GetMapMode())
|
||||
|
|
|
@ -513,6 +513,16 @@ void AIDEBUG_SetDebugVector2(const Vector NewVector)
|
|||
DebugVector2 = NewVector;
|
||||
}
|
||||
|
||||
Vector AIDEBUG_GetDebugVector1()
|
||||
{
|
||||
return DebugVector1;
|
||||
}
|
||||
|
||||
Vector AIDEBUG_GetDebugVector2()
|
||||
{
|
||||
return DebugVector2;
|
||||
}
|
||||
|
||||
void AIDEBUG_TestPathFind()
|
||||
{
|
||||
if (vIsZero(DebugVector1) || vIsZero(DebugVector2)) { return; }
|
||||
|
@ -573,7 +583,7 @@ void AIMGR_UpdateAIPlayers()
|
|||
|
||||
UpdateBotChat(bot);
|
||||
|
||||
DroneThink(bot);
|
||||
CustomThink(bot);
|
||||
|
||||
BotUpdateDesiredViewRotation(bot);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ void AIMGR_UpdateAIMapData();
|
|||
|
||||
AvHAICommanderMode AIMGR_GetCommanderMode();
|
||||
|
||||
Vector AIDEBUG_GetDebugVector1();
|
||||
Vector AIDEBUG_GetDebugVector2();
|
||||
void AIDEBUG_SetDebugVector1(const Vector NewVector);
|
||||
void AIDEBUG_SetDebugVector2(const Vector NewVector);
|
||||
void AIDEBUG_TestPathFind();
|
||||
|
|
|
@ -1880,12 +1880,12 @@ void AITAC_LinkAlienStructureToPlayer(AvHAIBuildableStructure* NewStructure)
|
|||
{
|
||||
AvHAIPlayer* Player = (*it);
|
||||
|
||||
if (Player->BuildAttempts.BuildStatus == BUILD_ATTEMPT_PENDING && Player->BuildAttempts.AttemptedStructureType == NewStructure->StructureType)
|
||||
if (Player->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING && Player->ActiveBuildInfo.AttemptedStructureType == NewStructure->StructureType)
|
||||
{
|
||||
if (vDist2DSq(NewStructure->Location, Player->BuildAttempts.AttemptedLocation) < sqrf(UTIL_MetresToGoldSrcUnits(2.0f)))
|
||||
if (vDist2DSq(NewStructure->Location, Player->ActiveBuildInfo.AttemptedLocation) < sqrf(UTIL_MetresToGoldSrcUnits(2.0f)))
|
||||
{
|
||||
Player->BuildAttempts.BuildStatus = BUILD_ATTEMPT_SUCCESS;
|
||||
Player->BuildAttempts.LinkedStructure = NewStructure;
|
||||
Player->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_SUCCESS;
|
||||
Player->ActiveBuildInfo.LinkedStructure = NewStructure;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -133,12 +133,11 @@ void AITASK_ClearBotTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
Task->bIssuedByCommander = false;
|
||||
Task->bTargetIsPlayer = false;
|
||||
Task->bTaskIsUrgent = false;
|
||||
Task->bIsWaitingForBuildLink = false;
|
||||
Task->LastBuildAttemptTime = 0.0f;
|
||||
Task->BuildAttempts = 0;
|
||||
Task->StructureType = STRUCTURE_NONE;
|
||||
|
||||
memset(&pBot->BuildAttempts, 0, sizeof(AvHAIBuildAttempt));
|
||||
memset(&pBot->ActiveBuildInfo, 0, sizeof(AvHAIBuildAttempt));
|
||||
}
|
||||
|
||||
bool AITASK_IsTaskUrgent(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
|
@ -586,9 +585,9 @@ bool AITASK_IsAlienBuildTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (Task->StructureType == STRUCTURE_NONE) { return false; }
|
||||
|
||||
if (Task->BuildAttempts >= 3) { return false; }
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return true; }
|
||||
|
||||
if (Task->bIsWaitingForBuildLink) { return true; }
|
||||
if (pBot->ActiveBuildInfo.NumAttempts >= 3) { return false; }
|
||||
|
||||
if (!FNullEnt(Task->TaskTarget) && !UTIL_IsBuildableStructureStillReachable(pBot, Task->TaskTarget)) { return false; }
|
||||
|
||||
|
@ -1523,32 +1522,9 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation) > sqrf(max_player_use_reach))
|
||||
{
|
||||
MoveTo(pBot, Task->TaskLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
BotEvolveLifeform(pBot, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO);
|
||||
return;
|
||||
}
|
||||
BotAlienPlaceChamber(pBot, Task->TaskLocation, Task->StructureType);
|
||||
|
||||
Vector LookLocation = Task->TaskLocation;
|
||||
LookLocation.z += 10.0f;
|
||||
|
||||
BotLookAt(pBot, LookLocation);
|
||||
|
||||
float LookDot = UTIL_GetDotProduct2D(UTIL_GetForwardVector2D(pBot->Edict->v.v_angle), UTIL_GetVectorNormal2D(LookLocation - pBot->Edict->v.origin));
|
||||
|
||||
if (LookDot > 0.9f)
|
||||
{
|
||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(Task->StructureType);
|
||||
Task->LastBuildAttemptTime = gpGlobals->time;
|
||||
Task->BuildAttempts++;
|
||||
Task->bIsWaitingForBuildLink = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -2048,7 +2024,7 @@ void AlienProgressHealTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
if (gpGlobals->time - Task->LastBuildAttemptTime < 1.0f)
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2061,30 +2037,7 @@ void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (Task->bIsWaitingForBuildLink)
|
||||
{
|
||||
Task->TaskLocation = FindClosestNavigablePointToDestination(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], pBot->Edict->v.origin, Hive->FloorLocation, UTIL_MetresToGoldSrcUnits(7.5f));
|
||||
|
||||
if (vIsZero(Task->TaskLocation))
|
||||
{
|
||||
AITASK_ClearBotTask(pBot, Task);
|
||||
return;
|
||||
}
|
||||
|
||||
float Dist = vDist2D(Task->TaskLocation, Hive->Location);
|
||||
|
||||
float MaxDist = (UTIL_MetresToGoldSrcUnits(7.5f) - Dist);
|
||||
|
||||
Vector AltLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, MaxDist);
|
||||
|
||||
if (AltLocation != g_vecZero)
|
||||
{
|
||||
Task->TaskLocation = AltLocation;
|
||||
}
|
||||
|
||||
Task->bIsWaitingForBuildLink = false;
|
||||
}
|
||||
|
||||
|
||||
int ResRequired = UTIL_GetCostOfStructureType(Task->StructureType);
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
|
@ -2098,44 +2051,7 @@ void AlienProgressBuildHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (vDist2DSq(pBot->Edict->v.origin, Hive->Location) > sqrf(UTIL_MetresToGoldSrcUnits(7.5f)))
|
||||
{
|
||||
MoveTo(pBot, Task->TaskLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
if (pBot->WantsAndNeedsTask.TaskType != TASK_EVOLVE || pBot->WantsAndNeedsTask.Evolution != ALIEN_LIFEFORM_TWO)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, &pBot->WantsAndNeedsTask, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BotMoveLookAt(pBot, Hive->Location);
|
||||
|
||||
Vector TraceStart = GetPlayerEyePosition(pBot->Edict);
|
||||
Vector TraceEnd = TraceStart + (UTIL_GetForwardVector(pBot->Edict->v.v_angle) * 60.0f);
|
||||
|
||||
if (UTIL_QuickTrace(pBot->Edict, TraceStart, TraceEnd))
|
||||
{
|
||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(Task->StructureType);
|
||||
|
||||
if (vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation) > sqrf(max_player_use_reach))
|
||||
{
|
||||
MoveTo(pBot, Task->TaskLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task->LastBuildAttemptTime = gpGlobals->time;
|
||||
Task->BuildAttempts++;
|
||||
Task->bIsWaitingForBuildLink = true;
|
||||
Task->bTaskIsUrgent = true;
|
||||
}
|
||||
}
|
||||
BotAlienBuildHive(pBot, Hive);
|
||||
}
|
||||
|
||||
void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
|
@ -2146,8 +2062,9 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!FNullEnt(Task->TaskTarget))
|
||||
if (pBot->ActiveBuildInfo.LinkedStructure)
|
||||
{
|
||||
if (UTIL_StructureIsFullyBuilt(pBot->ActiveBuildInfo.LinkedStructure->edict)) { return; }
|
||||
|
||||
if (IsPlayerInUseRange(pBot->Edict, Task->TaskTarget))
|
||||
{
|
||||
|
@ -2164,46 +2081,11 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (Task->StructureType == STRUCTURE_ALIEN_RESTOWER)
|
||||
// We tried and failed to place the structure
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED)
|
||||
{
|
||||
const AvHAIResourceNode* ResNodeIndex = AITAC_GetNearestResourceNodeToLocation(Task->TaskLocation);
|
||||
|
||||
if (ResNodeIndex)
|
||||
{
|
||||
if (ResNodeIndex->bIsOccupied && !ResNodeIndex->OwningTeam == pBot->Player->GetTeam())
|
||||
{
|
||||
Task->TaskTarget = ResNodeIndex->ActiveTowerEntity;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gpGlobals->time - Task->LastBuildAttemptTime < 1.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Task->bIsWaitingForBuildLink)
|
||||
{
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[GORGE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
Task->bIsWaitingForBuildLink = false;
|
||||
}
|
||||
|
||||
// If we are building a chamber
|
||||
if (Task->StructureType != STRUCTURE_ALIEN_RESTOWER)
|
||||
{
|
||||
dtPolyRef Poly = UTIL_GetNavAreaAtLocation(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskLocation);
|
||||
|
||||
if (Poly != SAMPLE_POLYAREA_GROUND)
|
||||
{
|
||||
Vector NewLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
|
||||
if (NewLocation != g_vecZero)
|
||||
{
|
||||
Task->TaskLocation = NewLocation;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[STRUCTURE_BASE_NAV_PROFILE], Task->TaskLocation, UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
||||
}
|
||||
|
||||
int ResRequired = UTIL_GetCostOfStructureType(Task->StructureType);
|
||||
|
@ -2219,46 +2101,180 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
return;
|
||||
}
|
||||
|
||||
if (vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation) > sqrf(max_player_use_reach))
|
||||
BotAlienPlaceChamber(pBot, Task->TaskLocation, Task->StructureType);
|
||||
}
|
||||
|
||||
void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStructureType DesiredStructure)
|
||||
{
|
||||
if (vIsZero(Location) || DesiredStructure == STRUCTURE_NONE) { return; }
|
||||
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||
|
||||
float DistFromBuildLocation = vDist2DSq(pBot->Edict->v.origin, Location);
|
||||
|
||||
if (DistFromBuildLocation > sqrf(UTIL_MetresToGoldSrcUnits(1.0f)))
|
||||
{
|
||||
MoveTo(pBot, Location, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DistFromBuildLocation < sqrf(UTIL_MetresToGoldSrcUnits(0.5f)))
|
||||
{
|
||||
BotLookAt(pBot, Location);
|
||||
Vector Orientation = UTIL_GetVectorNormal2D(pBot->Edict->v.origin - Location);
|
||||
Vector NewMoveLoc = Location + (Orientation * UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
MoveToWithoutNav(pBot, NewMoveLoc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Vector LookLocation = Location;
|
||||
LookLocation.z += 10.0f;
|
||||
|
||||
BotLookAt(pBot, LookLocation);
|
||||
|
||||
int ResRequired = UTIL_GetCostOfStructureType(DesiredStructure);
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
ResRequired += BALANCE_VAR(kGorgeCost);
|
||||
}
|
||||
|
||||
if (pBot->Player->GetResources() < ResRequired)
|
||||
{
|
||||
MoveTo(pBot, Task->TaskLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, &pBot->WantsAndNeedsTask, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO, true);
|
||||
|
||||
BotEvolveLifeform(pBot, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector LookLocation = Task->TaskLocation;
|
||||
LookLocation.z += 10.0f;
|
||||
|
||||
if (Task->StructureType == STRUCTURE_ALIEN_RESTOWER)
|
||||
{
|
||||
const AvHAIResourceNode* ResNode = AITAC_GetNearestResourceNodeToLocation(Task->TaskLocation);
|
||||
|
||||
if (ResNode)
|
||||
{
|
||||
LookLocation = ResNode->Location;
|
||||
}
|
||||
}
|
||||
|
||||
BotLookAt(pBot, LookLocation);
|
||||
|
||||
|
||||
float LookDot = UTIL_GetDotProduct2D(UTIL_GetForwardVector2D(pBot->Edict->v.v_angle), UTIL_GetVectorNormal2D(LookLocation - pBot->Edict->v.origin));
|
||||
|
||||
if (LookDot > 0.9f)
|
||||
{
|
||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(Task->StructureType);
|
||||
Task->LastBuildAttemptTime = gpGlobals->time;
|
||||
Task->BuildAttempts++;
|
||||
Task->bIsWaitingForBuildLink = true;
|
||||
Task->bTaskIsUrgent = true;
|
||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(DesiredStructure);
|
||||
RegisterBotAlienBuildAttempt(pBot, Location, DesiredStructure);
|
||||
}
|
||||
}
|
||||
|
||||
void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap)
|
||||
{
|
||||
if (NodeToCap->bIsOccupied) { return; }
|
||||
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||
|
||||
float CurrDist = vDist2DSq(pBot->CurrentFloorPosition, NodeToCap->Location);
|
||||
|
||||
// Get close enough to place the tower if we aren't
|
||||
if (CurrDist > sqrf(UTIL_MetresToGoldSrcUnits(3.0f)))
|
||||
{
|
||||
MoveTo(pBot, NodeToCap->Location, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
// Back up a bit if we're too close
|
||||
if (CurrDist < sqrf(UTIL_MetresToGoldSrcUnits(1.0f)))
|
||||
{
|
||||
BotLookAt(pBot, NodeToCap->Location);
|
||||
Vector Orientation = UTIL_GetVectorNormal2D(pBot->Edict->v.origin - NodeToCap->Location);
|
||||
Vector NewMoveLoc = NodeToCap->Location + (Orientation * UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
MoveToWithoutNav(pBot, NewMoveLoc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int ResRequired = UTIL_GetCostOfStructureType(STRUCTURE_ALIEN_RESTOWER);
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
ResRequired += BALANCE_VAR(kGorgeCost);
|
||||
}
|
||||
|
||||
BotLookAt(pBot, NodeToCap->Location);
|
||||
|
||||
if (pBot->Player->GetResources() < ResRequired)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
BotEvolveLifeform(pBot, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO);
|
||||
return;
|
||||
}
|
||||
|
||||
float LookDot = UTIL_GetDotProduct2D(UTIL_GetForwardVector2D(pBot->Edict->v.v_angle), UTIL_GetVectorNormal2D(NodeToCap->Location - pBot->Edict->v.origin));
|
||||
|
||||
if (LookDot > 0.9f)
|
||||
{
|
||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(STRUCTURE_ALIEN_RESTOWER);
|
||||
RegisterBotAlienBuildAttempt(pBot, NodeToCap->Location, STRUCTURE_ALIEN_RESTOWER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild)
|
||||
{
|
||||
// Do nothing if the hive is already built / under construction
|
||||
if (HiveToBuild->Status != HIVE_STATUS_UNBUILT) { return; }
|
||||
|
||||
if (pBot->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||
|
||||
if (vDist2DSq(pBot->Edict->v.origin, HiveToBuild->Location) > sqrf(UTIL_MetresToGoldSrcUnits(7.5f)))
|
||||
{
|
||||
MoveTo(pBot, HiveToBuild->FloorLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
BotLookAt(pBot, HiveToBuild->Location);
|
||||
|
||||
Vector TraceStart = GetPlayerEyePosition(pBot->Edict);
|
||||
Vector TraceEnd = TraceStart + (UTIL_GetForwardVector(pBot->Edict->v.v_angle) * 60.0f);
|
||||
|
||||
if (!UTIL_QuickTrace(pBot->Edict, TraceStart, TraceEnd))
|
||||
{
|
||||
MoveTo(pBot, HiveToBuild->FloorLocation, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ResRequired = UTIL_GetCostOfStructureType(STRUCTURE_ALIEN_HIVE);
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
ResRequired += BALANCE_VAR(kGorgeCost);
|
||||
}
|
||||
|
||||
if (pBot->Player->GetResources() < ResRequired)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
BotEvolveLifeform(pBot, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO);
|
||||
return;
|
||||
}
|
||||
|
||||
pBot->Impulse = UTIL_StructureTypeToImpulseCommand(STRUCTURE_ALIEN_HIVE);
|
||||
RegisterBotAlienBuildAttempt(pBot, HiveToBuild->Location, STRUCTURE_ALIEN_HIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure)
|
||||
{
|
||||
pBot->ActiveBuildInfo.AttemptedLocation = PlacementLocation;
|
||||
pBot->ActiveBuildInfo.BuildAttemptTime = gpGlobals->time;
|
||||
pBot->ActiveBuildInfo.LinkedStructure = nullptr;
|
||||
pBot->ActiveBuildInfo.NumAttempts++;
|
||||
pBot->ActiveBuildInfo.AttemptedStructureType = DesiredStructure;
|
||||
pBot->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_PENDING;
|
||||
}
|
||||
|
||||
void AlienProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
|
@ -2333,50 +2349,8 @@ void AlienProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
// We have enough resources to place the tower (includes cost of evolving to gorge if necessary)
|
||||
if (pBot->Player->GetResources() >= NumResourcesRequired)
|
||||
{
|
||||
float CurrDist = vDist2DSq(pBot->CurrentFloorPosition, ResNodeIndex->Location);
|
||||
|
||||
// Get close enough to place the tower if we aren't
|
||||
if (CurrDist > sqrf(UTIL_MetresToGoldSrcUnits(3.0f)))
|
||||
{
|
||||
MoveTo(pBot, ResNodeIndex->Location, MOVESTYLE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Back up a bit if we're too close
|
||||
if (CurrDist < sqrf(UTIL_MetresToGoldSrcUnits(1.0f)))
|
||||
{
|
||||
BotLookAt(pBot, ResNodeIndex->Location);
|
||||
Vector Orientation = UTIL_GetVectorNormal2D(pBot->Edict->v.origin - ResNodeIndex->Location);
|
||||
Vector NewMoveLoc = ResNodeIndex->Location + (Orientation * UTIL_MetresToGoldSrcUnits(2.0f));
|
||||
MoveToWithoutNav(pBot, NewMoveLoc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
BotEvolveLifeform(pBot, pBot->Edict->v.origin, ALIEN_LIFEFORM_TWO);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
BotLookAt(pBot, Task->TaskLocation);
|
||||
|
||||
if (gpGlobals->time - Task->LastBuildAttemptTime < 1.0f) { return; }
|
||||
|
||||
float LookDot = UTIL_GetDotProduct2D(UTIL_GetForwardVector2D(pBot->Edict->v.v_angle), UTIL_GetVectorNormal2D(Task->TaskLocation - pBot->Edict->v.origin));
|
||||
|
||||
if (LookDot > 0.9f)
|
||||
{
|
||||
|
||||
pBot->Impulse = ALIEN_BUILD_RESOURCES;
|
||||
Task->LastBuildAttemptTime = gpGlobals->time + 1.0f;
|
||||
Task->bIsWaitingForBuildLink = true;
|
||||
Task->BuildAttempts++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
BotAlienBuildResTower(pBot, ResNodeIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,4 +109,10 @@ AvHAIPlayer* GetFirstBotWithReinforceTask(AvHTeamNumber Team, edict_t* Reinforce
|
|||
|
||||
void UTIL_ClearGuardInfo(AvHAIPlayer* pBot);
|
||||
|
||||
void BotAlienPlaceChamber(AvHAIPlayer* pBot, Vector Location, AvHAIDeployableStructureType DesiredStructure);
|
||||
void BotAlienBuildHive(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToBuild);
|
||||
void BotAlienBuildResTower(AvHAIPlayer* pBot, const AvHAIResourceNode* NodeToCap);
|
||||
|
||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue