mirror of
https://github.com/ENSL/NS.git
synced 2024-11-21 12:11:04 +00:00
New base building setup
* Improved base strategy and planning * Bot is better at taking over from a human - less likely to sell up stuff unnecessarily
This commit is contained in:
parent
0897cf15a0
commit
6f263d400b
7 changed files with 2105 additions and 899 deletions
File diff suppressed because it is too large
Load diff
|
@ -27,15 +27,17 @@ bool AICOMM_IssueSiegeHiveOrder(AvHAIPlayer* pBot, edict_t* Recipient, const AvH
|
|||
bool AICOMM_IssueSecureResNodeOrder(AvHAIPlayer* pBot, edict_t* Recipient, const AvHAIResourceNode* ResNode);
|
||||
|
||||
void AICOMM_AssignNewPlayerOrder(AvHAIPlayer* pBot, edict_t* Assignee, edict_t* TargetEntity, AvHAIOrderPurpose OrderPurpose);
|
||||
void AICOMM_AssignNewPlayerOrder(AvHAIPlayer* pBot, edict_t* Assignee, Vector OrderLocation, AvHAIOrderPurpose OrderPurpose);
|
||||
int AICOMM_GetNumPlayersAssignedToOrder(AvHAIPlayer* pBot, edict_t* TargetEntity, AvHAIOrderPurpose OrderPurpose);
|
||||
int AICOMM_GetNumPlayersAssignedToOrderType(AvHAIPlayer* pBot, AvHAIOrderPurpose OrderPurpose);
|
||||
int AICOMM_GetNumPlayersAssignedToOrderLocation(AvHAIPlayer* pBot, Vector OrderLocation, AvHAIOrderPurpose OrderPurpose);
|
||||
bool AICOMM_IsOrderStillValid(AvHAIPlayer* pBot, ai_commander_order* Order);
|
||||
void AICOMM_UpdatePlayerOrders(AvHAIPlayer* pBot);
|
||||
edict_t* AICOMM_GetPlayerWithNoOrderNearestLocation(AvHAIPlayer* pBot, Vector SearchLocation);
|
||||
edict_t* AICOMM_GetPlayerWithoutSpecificOrderNearestLocation(AvHAIPlayer* pBot, Vector SearchLocation, AvHAIOrderPurpose OrderPurpose);
|
||||
bool AICOMM_DoesPlayerOrderNeedReminder(AvHAIPlayer* pBot, ai_commander_order* Order);
|
||||
void AICOMM_IssueOrderForAssignedJob(AvHAIPlayer* pBot, ai_commander_order* Order);
|
||||
|
||||
void AICOMM_ClearAction(commander_action* Action);
|
||||
|
||||
bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot);
|
||||
bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot);
|
||||
bool AICOMM_CheckForNextRecycleAction(AvHAIPlayer* pBot);
|
||||
|
@ -43,10 +45,7 @@ bool AICOMM_CheckForNextResearchAction(AvHAIPlayer* pBot);
|
|||
bool AICOMM_CheckForNextSupplyAction(AvHAIPlayer* pBot);
|
||||
bool AICOMM_CheckForNextRelocationAction(AvHAIPlayer* pBot);
|
||||
|
||||
void AICOMM_SetDropHealthAction(AvHAIPlayer* pBot, commander_action* Action, edict_t* Recipient);
|
||||
void AICOMM_SetDropAmmoAction(AvHAIPlayer* pBot, commander_action* Action, edict_t* Recipient);
|
||||
void AICOMM_SetDeployStructureAction(AvHAIPlayer* pBot, commander_action* Action, AvHAIDeployableStructureType StructureToBuild, const Vector Location, bool bIsUrgent);
|
||||
void AICOMM_SetDeployItemAction(AvHAIPlayer* pBot, commander_action* Action, AvHAIDeployableItemType ItemToBuild, const Vector Location, bool bIsUrgent);
|
||||
Vector AICOMM_GetNextScanLocation(AvHAIPlayer* pBot);
|
||||
|
||||
void AICOMM_CommanderThink(AvHAIPlayer* pBot);
|
||||
|
||||
|
@ -76,11 +75,26 @@ bool AICOMM_ShouldCommanderRelocate(AvHAIPlayer* pBot);
|
|||
|
||||
bool AICOMM_GetRelocationMessage(Vector RelocationPoint, char* MessageBuffer);
|
||||
|
||||
void AICOMM_AddNewBase(AvHAIPlayer* pBot, Vector NewBaseLocation, MarineBaseType NewBaseType);
|
||||
AvHAIMarineBase* AICOMM_AddNewBase(AvHAIPlayer* pBot, Vector NewBaseLocation, MarineBaseType NewBaseType);
|
||||
bool AICOMM_AddStructureToBase(AvHAIPlayer* pBot, AvHAIDeployableStructureType StructureToDeploy, Vector BuildLocation, AvHAIMarineBase* BaseToAdd);
|
||||
|
||||
void AICOMM_ManageActiveBases(AvHAIPlayer* pBot);
|
||||
bool AICOMM_IsMarineBaseValid(AvHAIMarineBase* Base);
|
||||
void AICOMM_DeployBases(AvHAIPlayer* pBot);
|
||||
vector<AvHAIBuildableStructure> AICOMM_GetBaseStructures(AvHAIMarineBase* Base);
|
||||
|
||||
void AICOMM_UpdateBaseStatus(AvHAIPlayer* pBot, AvHAIMarineBase* Base);
|
||||
void AICOMM_UpdateSiegeBaseStatus(AvHAIPlayer* pBot, AvHAIMarineBase* Base);
|
||||
void AICOMM_UpdateOutpostStatus(AvHAIPlayer* pBot, AvHAIMarineBase* Base);
|
||||
void AICOMM_UpdateGuardpostStatus(AvHAIPlayer* pBot, AvHAIMarineBase* Base);
|
||||
void AICOMM_UpdateMainBaseStatus(AvHAIPlayer* pBot, AvHAIMarineBase* Base);
|
||||
|
||||
bool AICOMM_BuildOutBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
bool AICOMM_BuildOutMainBase(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
bool AICOMM_BuildOutOutpost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
bool AICOMM_BuildOutSiege(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
bool AICOMM_BuildOutGuardPost(AvHAIPlayer* pBot, AvHAIMarineBase* BaseToBuildOut);
|
||||
|
||||
AvHAIMarineBase* AICOMM_GetNearestBaseToLocation(AvHAIPlayer* pBot, Vector SearchLocation);
|
||||
|
||||
#endif // AVH_AI_COMMANDER_H
|
|
@ -274,7 +274,7 @@ typedef struct _HIVE_DEFINITION_T
|
|||
AvHTeamNumber OwningTeam = TEAM_IND; // Which team owns this hive currently (TEAM_IND if empty)
|
||||
unsigned int TeamAReachabilityFlags = AI_REACHABILITY_NONE; // Who on team A can reach this node?
|
||||
unsigned int TeamBReachabilityFlags = AI_REACHABILITY_NONE; // Who on team B can reach this node?
|
||||
char HiveName[64];
|
||||
char HiveName[64] = {'\0'};
|
||||
} AvHAIHiveDefinition;
|
||||
|
||||
// A nav profile combines a nav mesh reference (indexed into NavMeshes) and filters to determine how a bot should find paths
|
||||
|
@ -479,7 +479,8 @@ enum MarineBaseType
|
|||
{
|
||||
MARINE_BASE_MAINBASE, // The main marine base, where the CC, infantry portals and stuff like arms labs go
|
||||
MARINE_BASE_OUTPOST, // A permanent outpost designed to control an area of the map, but not the main marine base
|
||||
MARINE_BASE_SIEGE // A siege base designed to take down an enemy base
|
||||
MARINE_BASE_SIEGE, // A siege base designed to take down an enemy base
|
||||
MARINE_BASE_GUARDPOST // A cut-down version of an outpost with just sentry turrets and an observatory
|
||||
};
|
||||
|
||||
typedef struct _AI_MARINE_BASE
|
||||
|
@ -488,8 +489,13 @@ typedef struct _AI_MARINE_BASE
|
|||
MarineBaseType BaseType = MARINE_BASE_OUTPOST; // The purpose of the base. Determines what structures the commander will place
|
||||
Vector BaseLocation = ZERO_VECTOR; // Where the base should be located. The base will be grown around this location
|
||||
vector<int> PlacedStructures; // Which structures are part of this base.
|
||||
int NumBuilders = 0; // How many potential builders are there, able to construct stuff?
|
||||
int NumEnemies = 0; // How many enemies are in and around the base?
|
||||
bool bRecycleBase = false; // Should the commander pack up and remove this base?
|
||||
bool bIsActive = true; // Should the commander actively build and maintain this base?
|
||||
bool bBaseInitialised = false; // Has the commander started building this base? Will be true once a structure has been placed
|
||||
bool bCanBeBuiltOut = false; // Can this base be built out currently?
|
||||
bool bIsBaseEstablished = false; // Have enough key structures been placed to consider this "established", even if it's not finished yet?
|
||||
} AvHAIMarineBase;
|
||||
|
||||
// Bot path node. A path will be several of these strung together to lead the bot to its destination
|
||||
|
@ -658,61 +664,16 @@ typedef struct _NAV_STATUS
|
|||
AvHAIPlayerMoveTask MovementTask;
|
||||
} nav_status;
|
||||
|
||||
// Type of goal the commander wants to achieve
|
||||
typedef enum _COMMANDERACTIONTYPE
|
||||
{
|
||||
ACTION_NONE = 0,
|
||||
ACTION_UPGRADE,
|
||||
ACTION_RESEARCH,
|
||||
ACTION_RECYCLE,
|
||||
ACTION_GIVEORDER,
|
||||
ACTION_DEPLOY // Deploy a structure or item into the map
|
||||
|
||||
} CommanderActionType;
|
||||
|
||||
// Some commander actions are multi-step (e.g. click to select building, release to complete selection, input recycle command etc). Tracks where the commander is in the process
|
||||
typedef enum _COMMANDERACTIONSTEP
|
||||
{
|
||||
ACTION_STEP_NONE = 0,
|
||||
ACTION_STEP_BEGIN_SELECT, // Click mouse button down to start select
|
||||
ACTION_STEP_END_SELECT, // Release mouse button to complete select
|
||||
|
||||
} CommanderActionStep;
|
||||
|
||||
|
||||
// Used by the AI commander instead of bot_task. Has data specifically to handle commander-specific stuff
|
||||
typedef struct _COMMANDER_ACTION
|
||||
{
|
||||
bool bIsActive = false;
|
||||
CommanderActionType ActionType = ACTION_NONE; // What action to perform (e.g. build, recycle, drop item etc)
|
||||
CommanderActionStep ActionStep = ACTION_STEP_NONE; // Used for multi-stage processes such as selecting a building, issuing recycle command etc.
|
||||
AvHAIDeployableStructureType StructureToBuild = STRUCTURE_NONE; // What structure to build if build action
|
||||
AvHAIDeployableItemType ItemToPlace = DEPLOYABLE_ITEM_NONE;
|
||||
int NumInstances = 0;
|
||||
int NumDesiredInstances = 0;
|
||||
StructurePurpose ActionPurpose = STRUCTURE_PURPOSE_NONE;
|
||||
Vector BuildLocation = g_vecZero; // Where to build the structure
|
||||
Vector DesiredCommanderLocation = g_vecZero; // To perform this action, where does the commander's view need to be? For building, usually directly above location, but could be off to side if obstructed by geometry
|
||||
Vector LastAttemptedCommanderLocation = g_vecZero; // The position of the commander's view at the last action attempt
|
||||
Vector LastAttemptedCommanderAngle = g_vecZero; // The click angle of the last action attempt
|
||||
int AssignedPlayer = 0; // Which player index is assigned to perform the action (e.g. build structure)? Will send orders to that player (move here, build this structure etc.)
|
||||
edict_t* StructureOrItem = nullptr; // Reference the structure edict. If a structure has been successfully placed but not yet fully built, it will be referenced here
|
||||
edict_t* ActionTarget = nullptr; // Mostly used for dropping health packs and ammo for players where the drop location might be moving around
|
||||
bool bHasAttemptedAction = false; // Has the commander tried placing a structure or item at the build location? If so, and it didn't appear, will try to adjust view around until it works
|
||||
float StructureBuildAttemptTime = 0.0f; // When the commander tried placing a structure. Commander will wait a short while to confirm if the building appeared or if it should try again
|
||||
int NumActionAttempts = 0; // Commander will give up after a certain number of attempts to place structure/item
|
||||
AvHMessageID ResearchId = MESSAGE_NULL; // What research to perform if research action
|
||||
bool bIsAwaitingBuildLink = false; // The AI has tried placing a structure or item and is waiting to confirm it worked or not
|
||||
bool bIsActionUrgent = false;
|
||||
|
||||
} commander_action;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ORDERPURPOSE_NONE,
|
||||
ORDERPURPOSE_SECURE_HIVE,
|
||||
ORDERPURPOSE_SIEGE_HIVE,
|
||||
ORDERPURPOSE_SECURE_RESNODE
|
||||
ORDERPURPOSE_SECURE_RESNODE,
|
||||
ORDERPURPOSE_BUILD_MAINBASE,
|
||||
ORDERPURPOSE_BUILD_SIEGE,
|
||||
ORDERPURPOSE_BUILD_OUTPOST,
|
||||
ORDERPURPOSE_BUILD_GUARDPOST
|
||||
} AvHAIOrderPurpose;
|
||||
|
||||
typedef struct _AI_COMMANDER_ORDER
|
||||
|
|
|
@ -1897,7 +1897,7 @@ void CustomThink(AvHAIPlayer* pBot)
|
|||
|
||||
for (auto it = pBot->Bases.begin(); it != pBot->Bases.end(); it++)
|
||||
{
|
||||
if (AITAC_CanBuildOutBase(&(*it)))
|
||||
if (it->bCanBeBuiltOut)
|
||||
{
|
||||
if (AICOMM_BuildOutBase(pBot, &(*it))) { return; }
|
||||
}
|
||||
|
@ -5718,6 +5718,8 @@ void AIPlayerDMThink(AvHAIPlayer* pBot)
|
|||
void AIPlayerThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
|
||||
StartNewBotFrame(pBot);
|
||||
|
||||
#ifdef BOTDEBUG
|
||||
for (int i = 0; i < gpGlobals->maxClients; i++)
|
||||
{
|
||||
|
@ -5752,9 +5754,7 @@ void AIPlayerThink(AvHAIPlayer* pBot)
|
|||
ClearBotInputs(pBot);
|
||||
pBot->bIsInactive = true;
|
||||
return;
|
||||
}
|
||||
|
||||
StartNewBotFrame(pBot);
|
||||
}
|
||||
|
||||
if (avh_botdebugmode.value == 1)
|
||||
{
|
||||
|
@ -7477,19 +7477,19 @@ void AIPlayerSetWantsAndNeedsAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
if (!PlayerHasAlienUpgradeOfType(pBot->Edict, HIVE_TECH_DEFENCE) && AITAC_IsAlienUpgradeAvailableForTeam(pBot->Player->GetTeam(), HIVE_TECH_DEFENCE))
|
||||
{
|
||||
pBot->Edict->v.impulse = AlienGetDesiredUpgrade(pBot, HIVE_TECH_DEFENCE);
|
||||
pBot->Impulse = AlienGetDesiredUpgrade(pBot, HIVE_TECH_DEFENCE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PlayerHasAlienUpgradeOfType(pBot->Edict, HIVE_TECH_MOVEMENT) && AITAC_IsAlienUpgradeAvailableForTeam(pBot->Player->GetTeam(), HIVE_TECH_MOVEMENT))
|
||||
{
|
||||
pBot->Edict->v.impulse = AlienGetDesiredUpgrade(pBot, HIVE_TECH_MOVEMENT);
|
||||
pBot->Impulse = AlienGetDesiredUpgrade(pBot, HIVE_TECH_MOVEMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PlayerHasAlienUpgradeOfType(pBot->Edict, HIVE_TECH_SENSORY) && AITAC_IsAlienUpgradeAvailableForTeam(pBot->Player->GetTeam(), HIVE_TECH_SENSORY))
|
||||
{
|
||||
pBot->Edict->v.impulse = AlienGetDesiredUpgrade(pBot, HIVE_TECH_SENSORY);
|
||||
pBot->Impulse = AlienGetDesiredUpgrade(pBot, HIVE_TECH_SENSORY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6040,7 +6040,7 @@ void AITAC_AddNewBase(AvHTeamNumber Team, Vector NewBaseLocation, MarineBaseType
|
|||
|
||||
bool AITAC_CanBuildOutBase(const AvHAIMarineBase* Base)
|
||||
{
|
||||
if (!Base) { return false; }
|
||||
if (!Base || Base->bRecycleBase || !Base->bIsActive) { return false; }
|
||||
|
||||
switch (Base->BaseType)
|
||||
{
|
||||
|
@ -6050,6 +6050,8 @@ bool AITAC_CanBuildOutBase(const AvHAIMarineBase* Base)
|
|||
return AITAC_CanBuildOutOutpost(Base);
|
||||
case MARINE_BASE_SIEGE:
|
||||
return AITAC_CanBuildOutSiege(Base);
|
||||
case MARINE_BASE_GUARDPOST:
|
||||
return AITAC_CanBuildOutGuardPost(Base);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -6125,7 +6127,7 @@ bool AITAC_CanBuildOutMainBase(const AvHAIMarineBase* Base)
|
|||
|| (!bHasArmsLab && bArmouryCompleted)
|
||||
|| (!bHasProtoLab && bHasAdvArmoury && bArmsLabCompleted)
|
||||
|| (!bHasObs && bArmouryCompleted)
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_PHASE_GATE))
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_RESEARCH_PHASETECH))
|
||||
|| !bHasTF
|
||||
|| NumTurrets < 5);
|
||||
|
||||
|
@ -6171,7 +6173,7 @@ bool AITAC_CanBuildOutOutpost(const AvHAIMarineBase* Base)
|
|||
|
||||
return (!bHasArmoury
|
||||
|| !bHasObs
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_PHASE_GATE))
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_RESEARCH_PHASETECH))
|
||||
|| !bHasTF
|
||||
|| NumTurrets < 5);
|
||||
|
||||
|
@ -6216,12 +6218,46 @@ bool AITAC_CanBuildOutSiege(const AvHAIMarineBase* Base)
|
|||
|
||||
return (!bHasArmoury
|
||||
|| !bHasObs
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_PHASE_GATE))
|
||||
|| (!bHasPhase && AITAC_ResearchIsComplete(Base->BaseTeam, TECH_RESEARCH_PHASETECH))
|
||||
|| !bHasTF
|
||||
|| NumTurrets < 3);
|
||||
|
||||
}
|
||||
|
||||
bool AITAC_CanBuildOutGuardPost(const AvHAIMarineBase* Base)
|
||||
{
|
||||
bool bHasObs = false;
|
||||
bool bHasTF = false;
|
||||
int NumTurrets = 0;
|
||||
|
||||
std::unordered_map<int, AvHAIBuildableStructure>& BuildingMap = (Base->BaseTeam == AIMGR_GetTeamANumber()) ? TeamAStructureMap : TeamBStructureMap;
|
||||
|
||||
for (auto it = Base->PlacedStructures.begin(); it != Base->PlacedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure StructureRef = BuildingMap[*it];
|
||||
|
||||
switch (StructureRef.StructureType)
|
||||
{
|
||||
case STRUCTURE_MARINE_OBSERVATORY:
|
||||
bHasObs = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRETFACTORY:
|
||||
case STRUCTURE_MARINE_ADVTURRETFACTORY:
|
||||
bHasTF = true;
|
||||
break;
|
||||
case STRUCTURE_MARINE_TURRET:
|
||||
NumTurrets++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (!bHasObs
|
||||
|| !bHasTF
|
||||
|| NumTurrets < 5);
|
||||
}
|
||||
|
||||
vector<AvHAIMarineBase>& AITAC_GetTeamBases(AvHTeamNumber Team)
|
||||
{
|
||||
return (Team == AIMGR_GetTeamANumber()) ? ActiveTeamABases : ActiveTeamBBases;
|
||||
|
|
|
@ -229,6 +229,7 @@ bool AITAC_CanBuildOutBase(const AvHAIMarineBase* Base);
|
|||
bool AITAC_CanBuildOutMainBase(const AvHAIMarineBase* Base);
|
||||
bool AITAC_CanBuildOutOutpost(const AvHAIMarineBase* Base);
|
||||
bool AITAC_CanBuildOutSiege(const AvHAIMarineBase* Base);
|
||||
bool AITAC_CanBuildOutGuardPost(const AvHAIMarineBase* Base);
|
||||
|
||||
vector<AvHAIMarineBase>& AITAC_GetTeamBases(AvHTeamNumber Team);
|
||||
|
||||
|
|
|
@ -1351,7 +1351,11 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
if (FNullEnt(Task->TaskTarget)) { return; }
|
||||
|
||||
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||
{
|
||||
pBot->Impulse = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// We had a go, whether it succeeded or not we should try a new location
|
||||
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_FAILED || Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_SUCCESS)
|
||||
|
@ -1361,7 +1365,7 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
Task->ActiveBuildInfo.BuildStatus = BUILD_ATTEMPT_NONE;
|
||||
}
|
||||
|
||||
if (gpGlobals->time - Task->TaskStartedTime < 1.0f) { return; }
|
||||
if (gpGlobals->time - Task->TaskStartedTime < 0.5f) { return; }
|
||||
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
|
||||
|
@ -2160,6 +2164,7 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
// We tried and failed to place the structure
|
||||
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||
{
|
||||
pBot->Impulse = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2173,6 +2178,8 @@ void AlienProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
edict_t* LinkedEdict = Task->ActiveBuildInfo.LinkedStructure->edict;
|
||||
|
||||
Task->TaskTarget = LinkedEdict;
|
||||
|
||||
if (UTIL_StructureIsFullyBuilt(LinkedEdict)) { return; }
|
||||
|
||||
if (IsPlayerInUseRange(pBot->Edict, LinkedEdict))
|
||||
|
@ -2240,7 +2247,11 @@ void BotAlienPlaceChamber(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, AvHAIDeploya
|
|||
{
|
||||
if (vIsZero(Task->TaskLocation) || DesiredStructure == STRUCTURE_NONE) { return; }
|
||||
|
||||
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING) { return; }
|
||||
if (Task->ActiveBuildInfo.BuildStatus == BUILD_ATTEMPT_PENDING)
|
||||
{
|
||||
pBot->Impulse = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
float DistFromBuildLocation = vDist2DSq(pBot->Edict->v.origin, Task->TaskLocation);
|
||||
|
||||
|
|
Loading…
Reference in a new issue