mirror of
https://github.com/ENSL/NS.git
synced 2025-04-20 16:30:56 +00:00
Re-implement commander AI
This commit is contained in:
parent
7440810699
commit
b78629738d
18 changed files with 2205 additions and 121 deletions
1438
main/source/mod/AIPlayers/AvHAICommander.cpp
Normal file
1438
main/source/mod/AIPlayers/AvHAICommander.cpp
Normal file
File diff suppressed because it is too large
Load diff
56
main/source/mod/AIPlayers/AvHAICommander.h
Normal file
56
main/source/mod/AIPlayers/AvHAICommander.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// EvoBot - Neoptolemus' Natural Selection bot, based on Botman's HPB bot template
|
||||
//
|
||||
// bot_navigation.h
|
||||
//
|
||||
// Handles all bot path finding and movement
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef AVH_AI_COMMANDER_H
|
||||
#define AVH_AI_COMMANDER_H
|
||||
|
||||
#include "AvHAIConstants.h"
|
||||
|
||||
bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureType StructureToDeploy, const Vector Location);
|
||||
bool AICOMM_DeployItem(AvHAIPlayer* pBot, const AvHAIDeployableItemType ItemToDeploy, const Vector Location);
|
||||
bool AICOMM_UpgradeStructure(AvHAIPlayer* pBot, AvHAIBuildableStructure* StructureToUpgrade);
|
||||
bool AICOMM_ResearchTech(AvHAIPlayer* pBot, AvHAIBuildableStructure* StructureToResearch, AvHMessageID Research);
|
||||
bool AICOMM_RecycleStructure(AvHAIPlayer* pBot, AvHAIBuildableStructure* StructureToRecycle);
|
||||
|
||||
bool AICOMM_IssueMovementOrder(AvHAIPlayer* pBot, edict_t* Recipient, const Vector MoveLocation);
|
||||
bool AICOMM_IssueBuildOrder(AvHAIPlayer* pBot, edict_t* Recipient, edict_t* TargetStructure);
|
||||
bool AICOMM_IssueSecureHiveOrder(AvHAIPlayer* pBot, edict_t* Recipient, const AvHAIHiveDefinition* HiveToSecure);
|
||||
bool AICOMM_IssueSiegeHiveOrder(AvHAIPlayer* pBot, edict_t* Recipient, const AvHAIHiveDefinition* HiveToSiege, const Vector SiegePosition);
|
||||
bool AICOMM_IssueSecureResNodeOrder(AvHAIPlayer* pBot, edict_t* Recipient, const AvHAIResourceNode* ResNode);
|
||||
|
||||
void AICOMM_ClearAction(commander_action* Action);
|
||||
bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot, commander_action* Action);
|
||||
bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot);
|
||||
bool AICOMM_CheckForNextResearchAction(AvHAIPlayer* pBot, commander_action* Action);
|
||||
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);
|
||||
|
||||
void AICOMM_CommanderThink(AvHAIPlayer* pBot);
|
||||
|
||||
const AvHAIHiveDefinition* AICOMM_GetEmptyHiveOpportunityNearestLocation(AvHAIPlayer* CommanderBot, const Vector SearchLocation);
|
||||
|
||||
bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair, commander_action* Action);
|
||||
bool AICOMM_PerformNextSiegeHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToSiege, commander_action* Action);
|
||||
bool AICOMM_PerformNextSecureHiveAction(AvHAIPlayer* pBot, const AvHAIHiveDefinition* HiveToSiege, commander_action* Action);
|
||||
|
||||
ai_commander_request* AICOMM_GetExistingRequestForPlayer(AvHAIPlayer* pBot, edict_t* Requestor);
|
||||
void AICOMM_CheckNewRequests(AvHAIPlayer* pBot);
|
||||
bool AICOMM_IsRequestValid(ai_commander_request* Request);
|
||||
|
||||
bool AICOMM_IsHiveFullySecured(AvHAIPlayer* CommanderBot, const AvHAIHiveDefinition* Hive);
|
||||
|
||||
bool AICOMM_ShouldCommanderLeaveChair(AvHAIPlayer* pBot);
|
||||
|
||||
const AvHAIResourceNode* AICOMM_GetNearestResourceNodeCapOpportunity(const AvHTeamNumber Team, const Vector SearchLocation);
|
||||
const AvHAIHiveDefinition* AICOMM_GetHiveSiegeOpportunityNearestLocation(AvHAIPlayer* CommanderBot, const Vector SearchLocation);
|
||||
|
||||
|
||||
#endif // AVH_AI_COMMANDER_H
|
|
@ -90,7 +90,7 @@ typedef enum _AI_REACHABILITY_STATUS
|
|||
AI_REACHABILITY_ONOS = 1u << 3,
|
||||
AI_REACHABILITY_WELDER = 1u << 4,
|
||||
|
||||
AI_REACHABILITY_ALL = 0xFFFF
|
||||
AI_REACHABILITY_ALL = -1
|
||||
} AvHAIReachabilityStatus;
|
||||
|
||||
typedef enum
|
||||
|
@ -101,8 +101,9 @@ typedef enum
|
|||
STRUCTURE_STATUS_RECYCLING = 1 << 2,
|
||||
STRUCTURE_STATUS_PARASITED = 1 << 3,
|
||||
STRUCTURE_STATUS_UNDERATTACK = 1 << 4,
|
||||
STRUCTURE_STATUS_RESEARCHING = 1 << 5,
|
||||
|
||||
STRUCTURE_STATUS_ALL = 0x7FFFFFFF
|
||||
STRUCTURE_STATUS_ALL = -1
|
||||
} AvHAIStructureStatus;
|
||||
|
||||
typedef enum
|
||||
|
@ -134,7 +135,7 @@ typedef enum
|
|||
SEARCH_ALL_ALIEN_STRUCTURES = 0xFC000,
|
||||
SEARCH_ANY_RES_TOWER = (STRUCTURE_MARINE_RESTOWER | STRUCTURE_ALIEN_RESTOWER),
|
||||
|
||||
SEARCH_ALL_STRUCTURES = 0x7FFFFFFF
|
||||
SEARCH_ALL_STRUCTURES = -1
|
||||
|
||||
} AvHAIDeployableStructureType;
|
||||
|
||||
|
@ -157,7 +158,7 @@ typedef enum
|
|||
DEPLOYABLE_ITEM_WEAPONS = 0xF80,
|
||||
DEPLOYABLE_ITEM_EQUIPMENT = 0x6,
|
||||
|
||||
DEPLOYABLE_ITEM_ALL = 0x7FFFFFFF
|
||||
DEPLOYABLE_ITEM_ALL = -1
|
||||
} AvHAIDeployableItemType;
|
||||
|
||||
// Type of goal the commander wants to achieve
|
||||
|
@ -513,6 +514,7 @@ typedef struct _COMMANDER_ACTION
|
|||
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;
|
||||
|
@ -520,18 +522,27 @@ typedef struct _COMMANDER_ACTION
|
|||
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 = -1; // 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.)
|
||||
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
|
||||
AvHTechID ResearchId = TECH_NULL; // What research to perform if research action
|
||||
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 struct _AI_COMMANDER_REQUEST
|
||||
{
|
||||
bool bNewRequest = false; // Is this a new request just come in?
|
||||
edict_t* Requestor = nullptr; // Who sent the request?
|
||||
AvHMessageID RequestType = MESSAGE_NULL; // What did they request?
|
||||
bool bResponded = false; // Have we already responded to this request?
|
||||
float RequestTime = 0.0f; // When the request came in
|
||||
} ai_commander_request;
|
||||
|
||||
typedef struct AVH_AI_PLAYER
|
||||
{
|
||||
AvHPlayer* Player = nullptr;
|
||||
|
@ -588,6 +599,8 @@ typedef struct AVH_AI_PLAYER
|
|||
commander_action RecycleAction;
|
||||
commander_action* CurrentAction;
|
||||
|
||||
vector<ai_commander_request> ActiveRequests;
|
||||
|
||||
float next_commander_action_time = 0.0f;
|
||||
|
||||
bot_msg ChatMessages[5]; // Bot can have up to 5 chat messages pending
|
||||
|
|
|
@ -2679,7 +2679,7 @@ void CheckAndHandleBreakableObstruction(AvHAIPlayer* pBot, const Vector MoveFrom
|
|||
|
||||
Vector ClosestPoint = UTIL_GetClosestPointOnEntityToLocation(pBot->Edict->v.origin, BlockingBreakableEdict);
|
||||
|
||||
AvHAIWeapon DesiredWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
AvHAIWeapon DesiredWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
|
||||
if (IsPlayerMarine(pBot->Player))
|
||||
{
|
||||
|
@ -2716,7 +2716,7 @@ void CheckAndHandleBreakableObstruction(AvHAIPlayer* pBot, const Vector MoveFrom
|
|||
|
||||
pBot->DesiredMoveWeapon = DesiredWeapon;
|
||||
|
||||
if (GetBotCurrentWeapon(pBot) == DesiredWeapon)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == DesiredWeapon)
|
||||
{
|
||||
pBot->Button |= IN_ATTACK;
|
||||
}
|
||||
|
@ -3757,7 +3757,6 @@ bool IsBotOffPath(const AvHAIPlayer* pBot)
|
|||
return (vEquals(PointOnPath, MoveTo, 2.0f) && !IsPlayerClimbingWall(pBot->Edict) && pBot->CollisionHullTopLocation.z < MoveTo.z);
|
||||
}
|
||||
|
||||
|
||||
// Give us a chance to land before deciding we're off the path
|
||||
if (!pBot->BotNavInfo.IsOnGround) { return false; }
|
||||
|
||||
|
@ -3845,7 +3844,7 @@ void BlinkClimbMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector End
|
|||
pBot->DesiredMoveWeapon = WEAPON_FADE_BLINK;
|
||||
|
||||
// Wait until we have blink equipped before proceeding
|
||||
if (GetBotCurrentWeapon(pBot) != WEAPON_FADE_BLINK) { return; }
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != WEAPON_FADE_BLINK) { return; }
|
||||
|
||||
// Only blink if we're below the target climb height
|
||||
if (pEdict->v.origin.z < RequiredClimbHeight)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "AvHAIWeaponHelper.h"
|
||||
#include "AvHAITactical.h"
|
||||
#include "AvHAITask.h"
|
||||
#include "AvHAICommander.h"
|
||||
|
||||
#include "../AvHMessage.h"
|
||||
|
||||
|
@ -134,7 +135,7 @@ void BotLookAt(AvHAIPlayer* pBot, edict_t* target)
|
|||
Vector TargetVelocity = (TrackedEnemyRef) ? TrackedEnemyRef->LastSeenVelocity : pBot->LookTarget->v.velocity;
|
||||
Vector TargetLocation = (TrackedEnemyRef) ? TrackedEnemyRef->LastSeenLocation : UTIL_GetCentreOfEntity(pBot->LookTarget);
|
||||
|
||||
AvHAIWeapon CurrentWeapon = GetBotCurrentWeapon(pBot);
|
||||
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
|
||||
Vector NewLoc = UTIL_GetAimLocationToLeadTarget(pBot->CurrentEyePosition, TargetLocation, TargetVelocity, GetProjectileVelocityForWeapon(CurrentWeapon));
|
||||
|
||||
|
@ -196,9 +197,9 @@ bool BotUseObject(AvHAIPlayer* pBot, edict_t* Target, bool bContinuous)
|
|||
return false;
|
||||
}
|
||||
|
||||
AvHAIWeapon GetBotCurrentWeapon(const AvHAIPlayer* pBot)
|
||||
AvHAIWeapon GetPlayerCurrentWeapon(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_pActiveItem);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_pActiveItem);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -248,7 +249,7 @@ void BotLeap(AvHAIPlayer* pBot, const Vector TargetLocation)
|
|||
|
||||
AvHAIWeapon LeapWeapon = (IsPlayerSkulk(pBot->Edict)) ? WEAPON_SKULK_LEAP : WEAPON_FADE_BLINK;
|
||||
|
||||
if (GetBotCurrentWeapon(pBot) != LeapWeapon)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != LeapWeapon)
|
||||
{
|
||||
pBot->DesiredMoveWeapon = LeapWeapon;
|
||||
return;
|
||||
|
@ -415,11 +416,11 @@ void BotReloadWeapons(AvHAIPlayer* pBot)
|
|||
|
||||
if (gpGlobals->time - pBot->LastCombatTime > 5.0f)
|
||||
{
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
AvHAIWeapon SecondaryWeapon = GetBotMarineSecondaryWeapon(pBot);
|
||||
AvHAIWeapon CurrentWeapon = GetBotCurrentWeapon(pBot);
|
||||
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
|
||||
if (WeaponCanBeReloaded(PrimaryWeapon) && BotGetPrimaryWeaponClipAmmo(pBot) < BotGetPrimaryWeaponMaxClipSize(pBot) && BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (WeaponCanBeReloaded(PrimaryWeapon) && UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) < UTIL_GetPlayerPrimaryWeaponMaxClipSize(pBot->Player) && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
pBot->DesiredCombatWeapon = PrimaryWeapon;
|
||||
|
||||
|
@ -590,7 +591,7 @@ void BotShootTarget(AvHAIPlayer* pBot, AvHAIWeapon AttackWeapon, edict_t* Target
|
|||
{
|
||||
if (FNullEnt(Target) || (Target->v.deadflag != DEAD_NO)) { return; }
|
||||
|
||||
AvHAIWeapon CurrentWeapon = GetBotCurrentWeapon(pBot);
|
||||
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
|
||||
pBot->DesiredCombatWeapon = AttackWeapon;
|
||||
|
||||
|
@ -686,15 +687,15 @@ void BotShootTarget(AvHAIPlayer* pBot, AvHAIWeapon AttackWeapon, edict_t* Target
|
|||
|
||||
if (WeaponCanBeReloaded(CurrentWeapon))
|
||||
{
|
||||
bool bShouldReload = (BotGetCurrentWeaponReserveAmmo(pBot) > 0);
|
||||
bool bShouldReload = (GetPlayerCurrentWeaponReserveAmmo(pBot->Player) > 0);
|
||||
|
||||
if (CurrentWeapon == WEAPON_MARINE_SHOTGUN && IsEdictStructure(Target))
|
||||
{
|
||||
bShouldReload = bShouldReload && ((float)BotGetCurrentWeaponClipAmmo(pBot) / (float)BotGetCurrentWeaponMaxClipAmmo(pBot) < 0.5f);
|
||||
bShouldReload = bShouldReload && ((float)GetPlayerCurrentWeaponClipAmmo(pBot->Player) / (float)GetPlayerCurrentWeaponMaxClipAmmo(pBot->Player) < 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
bShouldReload = bShouldReload && BotGetCurrentWeaponClipAmmo(pBot) == 0;
|
||||
bShouldReload = bShouldReload && GetPlayerCurrentWeaponClipAmmo(pBot->Player) == 0;
|
||||
}
|
||||
|
||||
if (bShouldReload)
|
||||
|
@ -790,7 +791,7 @@ void BotShootLocation(AvHAIPlayer* pBot, AvHAIWeapon AttackWeapon, const Vector
|
|||
{
|
||||
if (vIsZero(TargetLocation)) { return; }
|
||||
|
||||
AvHAIWeapon CurrentWeapon = GetBotCurrentWeapon(pBot);
|
||||
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
|
||||
pBot->DesiredCombatWeapon = AttackWeapon;
|
||||
|
||||
|
@ -881,15 +882,15 @@ void BotShootLocation(AvHAIPlayer* pBot, AvHAIWeapon AttackWeapon, const Vector
|
|||
|
||||
if (WeaponCanBeReloaded(CurrentWeapon))
|
||||
{
|
||||
bool bShouldReload = (BotGetCurrentWeaponReserveAmmo(pBot) > 0);
|
||||
bool bShouldReload = (GetPlayerCurrentWeaponReserveAmmo(pBot->Player) > 0);
|
||||
|
||||
if (CurrentWeapon == WEAPON_MARINE_SHOTGUN)
|
||||
{
|
||||
bShouldReload = bShouldReload && ((float)BotGetCurrentWeaponClipAmmo(pBot) / (float)BotGetCurrentWeaponMaxClipAmmo(pBot) < 0.5f);
|
||||
bShouldReload = bShouldReload && ((float)GetPlayerCurrentWeaponClipAmmo(pBot->Player) / (float)GetPlayerCurrentWeaponMaxClipAmmo(pBot->Player) < 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
bShouldReload = bShouldReload && BotGetCurrentWeaponClipAmmo(pBot) == 0;
|
||||
bShouldReload = bShouldReload && GetPlayerCurrentWeaponClipAmmo(pBot->Player) == 0;
|
||||
}
|
||||
|
||||
if (bShouldReload)
|
||||
|
@ -1486,6 +1487,11 @@ void StartNewBotFrame(AvHAIPlayer* pBot)
|
|||
|
||||
}
|
||||
|
||||
void CustomThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
AICOMM_CommanderThink(pBot);
|
||||
}
|
||||
|
||||
void DroneThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
AITASK_BotUpdateAndClearTasks(pBot);
|
||||
|
@ -1548,7 +1554,7 @@ void BotSwitchToWeapon(AvHAIPlayer* pBot, AvHAIWeapon NewWeaponSlot)
|
|||
|
||||
bool ShouldBotThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
return IsPlayerActiveInGame(pBot->Edict) && !IsPlayerGestating(pBot->Edict);
|
||||
return (IsPlayerActiveInGame(pBot->Edict) || IsPlayerCommander(pBot->Edict)) && !IsPlayerGestating(pBot->Edict);
|
||||
}
|
||||
|
||||
void BotResumePlay(AvHAIPlayer* pBot)
|
||||
|
@ -1583,4 +1589,14 @@ void UpdateCommanderOrders(AvHAIPlayer* pBot)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BotStopCommanderMode(AvHAIPlayer* pBot)
|
||||
{
|
||||
// Thanks EterniumDev (Alien) for logic to allow commander AI to leave the chair and build structures when needed
|
||||
|
||||
if (IsPlayerCommander(pBot->Edict))
|
||||
{
|
||||
CLIENT_COMMAND(pBot->Edict, "stopcommandermode");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ void StartNewBotFrame(AvHAIPlayer* pBot);
|
|||
|
||||
void TestNavThink(AvHAIPlayer* pBot);
|
||||
void DroneThink(AvHAIPlayer* pBot);
|
||||
void CustomThink(AvHAIPlayer* pBot);
|
||||
|
||||
void BotSwitchToWeapon(AvHAIPlayer* pBot, AvHAIWeapon NewWeaponSlot);
|
||||
|
||||
|
@ -64,4 +65,6 @@ void BotResumePlay(AvHAIPlayer* pBot);
|
|||
|
||||
void UpdateCommanderOrders(AvHAIPlayer* pBot);
|
||||
|
||||
void BotStopCommanderMode(AvHAIPlayer* pBot);
|
||||
|
||||
#endif
|
|
@ -547,13 +547,13 @@ void AIMGR_UpdateAIPlayers()
|
|||
|
||||
UpdateBotChat(bot);
|
||||
|
||||
DroneThink(bot);
|
||||
CustomThink(bot);
|
||||
|
||||
AIDEBUG_DrawPath(DebugPath, 0.0f);
|
||||
|
||||
AvHAIWeapon DesiredWeapon = (bot->DesiredMoveWeapon != WEAPON_NONE) ? bot->DesiredMoveWeapon : bot->DesiredCombatWeapon;
|
||||
|
||||
if (DesiredWeapon != WEAPON_NONE && GetBotCurrentWeapon(bot) != DesiredWeapon)
|
||||
if (DesiredWeapon != WEAPON_NONE && GetPlayerCurrentWeapon(bot->Player) != DesiredWeapon)
|
||||
{
|
||||
BotSwitchToWeapon(bot, DesiredWeapon);
|
||||
}
|
||||
|
|
|
@ -223,6 +223,7 @@ AvHAIBuildableStructure* AITAC_FindClosestDeployableToLocation(const Vector& Loc
|
|||
{
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -233,15 +234,12 @@ AvHAIBuildableStructure* AITAC_FindClosestDeployableToLocation(const Vector& Loc
|
|||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE && !(StructureReachabilityFlags & Filter->ReachabilityFlags)) { continue; }
|
||||
|
||||
if (it.second.StructureType & Filter->DeployableTypes)
|
||||
{
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && (!Result || DistSq < CurrMinDist))
|
||||
{
|
||||
Result = &it.second;
|
||||
CurrMinDist = DistSq;
|
||||
}
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && (!Result || DistSq < CurrMinDist))
|
||||
{
|
||||
Result = &it.second;
|
||||
CurrMinDist = DistSq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -252,6 +250,7 @@ AvHAIBuildableStructure* AITAC_FindClosestDeployableToLocation(const Vector& Loc
|
|||
{
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
|
@ -262,15 +261,83 @@ AvHAIBuildableStructure* AITAC_FindClosestDeployableToLocation(const Vector& Loc
|
|||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE && !(StructureReachabilityFlags & Filter->ReachabilityFlags)) { continue; }
|
||||
|
||||
if (it.second.StructureType & Filter->DeployableTypes)
|
||||
{
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && (!Result || DistSq < CurrMinDist))
|
||||
{
|
||||
Result = &it.second;
|
||||
CurrMinDist = DistSq;
|
||||
}
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && (!Result || DistSq < CurrMinDist))
|
||||
{
|
||||
Result = &it.second;
|
||||
CurrMinDist = DistSq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
AvHAIBuildableStructure* AITAC_FindFurthestDeployableFromLocation(const Vector& Location, const DeployableSearchFilter* Filter)
|
||||
{
|
||||
AvHTeamNumber TeamA = GetGameRules()->GetTeamANumber();
|
||||
AvHTeamNumber TeamB = GetGameRules()->GetTeamBNumber();
|
||||
|
||||
AvHAIBuildableStructure* Result = NULL;
|
||||
float CurrMinDist = 0.0f;
|
||||
|
||||
float MinDistSq = sqrf(Filter->MinSearchRadius);
|
||||
float MaxDistSq = sqrf(Filter->MaxSearchRadius);
|
||||
|
||||
bool bUseMinDist = MinDistSq > 0.1f;
|
||||
bool bUseMaxDist = MaxDistSq > 0.1f;
|
||||
|
||||
if (Filter->DeployableTeam == TeamA || Filter->DeployableTeam == TEAM_IND)
|
||||
{
|
||||
for (auto& it : TeamAStructureMap)
|
||||
{
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
if (Filter->ReachabilityTeam != TEAM_IND)
|
||||
{
|
||||
StructureReachabilityFlags = (Filter->ReachabilityTeam == TeamA) ? it.second.TeamAReachabilityFlags : it.second.TeamBReachabilityFlags;
|
||||
}
|
||||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE && !(StructureReachabilityFlags & Filter->ReachabilityFlags)) { continue; }
|
||||
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && DistSq > CurrMinDist)
|
||||
{
|
||||
Result = &it.second;
|
||||
CurrMinDist = DistSq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Filter->DeployableTeam == TeamB || Filter->DeployableTeam == TEAM_IND)
|
||||
{
|
||||
for (auto& it : TeamBStructureMap)
|
||||
{
|
||||
if (it.second.StructureStatusFlags & Filter->ExcludeStatusFlags) { continue; }
|
||||
if ((it.second.StructureStatusFlags & Filter->IncludeStatusFlags) != Filter->IncludeStatusFlags) { continue; }
|
||||
if (!(it.second.StructureType & Filter->DeployableTypes)) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
if (Filter->ReachabilityTeam != TEAM_IND)
|
||||
{
|
||||
StructureReachabilityFlags = (Filter->ReachabilityTeam == TeamA) ? it.second.TeamAReachabilityFlags : it.second.TeamBReachabilityFlags;
|
||||
}
|
||||
|
||||
if (Filter->ReachabilityFlags != AI_REACHABILITY_NONE && !(StructureReachabilityFlags & Filter->ReachabilityFlags)) { continue; }
|
||||
|
||||
float DistSq = (Filter->bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && DistSq > CurrMinDist)
|
||||
{
|
||||
Result = &it.second;
|
||||
CurrMinDist = DistSq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -326,6 +393,75 @@ AvHAIDroppedItem* AITAC_FindClosestItemToLocation(const Vector& Location, const
|
|||
return Result;
|
||||
}
|
||||
|
||||
int AITAC_GetNumItemsInLocation(const Vector& Location, const AvHAIDeployableItemType ItemType, AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags, float MinRadius, float MaxRadius, bool bConsiderPhaseDistance)
|
||||
{
|
||||
int Result = 0;
|
||||
|
||||
float MinDistSq = sqrf(MinRadius);
|
||||
float MaxDistSq = sqrf(MaxRadius);
|
||||
|
||||
bool bUseMinDist = MinDistSq > 0.1f;
|
||||
bool bUseMaxDist = MaxDistSq > 0.1f;
|
||||
|
||||
for (auto& it : MarineDroppedItemMap)
|
||||
{
|
||||
if (it.second.ItemType != ItemType) { continue; }
|
||||
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
if (SearchingTeam != TEAM_IND)
|
||||
{
|
||||
StructureReachabilityFlags = (SearchingTeam == GetGameRules()->GetTeamANumber()) ? it.second.TeamAReachabilityFlags : it.second.TeamBReachabilityFlags;
|
||||
}
|
||||
|
||||
if (ReachabilityFlags != AI_REACHABILITY_NONE && !(StructureReachabilityFlags & ReachabilityFlags)) { continue; }
|
||||
|
||||
float DistSq = (bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq))
|
||||
{
|
||||
Result++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool AITAC_ItemExistsInLocation(const Vector& Location, const AvHAIDeployableItemType ItemType, AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags, float MinRadius, float MaxRadius, bool bConsiderPhaseDistance)
|
||||
{
|
||||
|
||||
float MinDistSq = sqrf(MinRadius);
|
||||
float MaxDistSq = sqrf(MaxRadius);
|
||||
|
||||
bool bUseMinDist = MinDistSq > 0.1f;
|
||||
bool bUseMaxDist = MaxDistSq > 0.1f;
|
||||
|
||||
for (auto& it : MarineDroppedItemMap)
|
||||
{
|
||||
unsigned int StructureReachabilityFlags = (it.second.TeamAReachabilityFlags | it.second.TeamBReachabilityFlags);
|
||||
|
||||
if (SearchingTeam != TEAM_IND)
|
||||
{
|
||||
StructureReachabilityFlags = (SearchingTeam == GetGameRules()->GetTeamANumber()) ? it.second.TeamAReachabilityFlags : it.second.TeamBReachabilityFlags;
|
||||
}
|
||||
|
||||
if (ReachabilityFlags != AI_REACHABILITY_NONE && !(StructureReachabilityFlags & ReachabilityFlags)) { continue; }
|
||||
|
||||
if (it.second.ItemType != ItemType) { continue; }
|
||||
|
||||
float DistSq = (bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
|
||||
|
||||
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AvHAIBuildableStructure* AITAC_GetDeployableRefFromEdict(const edict_t* Structure)
|
||||
{
|
||||
if (FNullEnt(Structure)) { return nullptr; }
|
||||
|
@ -1470,7 +1606,6 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
{
|
||||
BuildingMap[EntIndex].EntityRef = BaseBuildable;
|
||||
BuildingMap[EntIndex].edict = BuildingEdict;
|
||||
BuildingMap[EntIndex].StructureType = StructureType;
|
||||
|
||||
BuildingMap[EntIndex].OffMeshConnections.clear();
|
||||
|
||||
|
@ -1494,6 +1629,8 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
AITAC_OnStructureCreated(&BuildingMap[EntIndex]);
|
||||
}
|
||||
|
||||
BuildingMap[EntIndex].StructureType = StructureType;
|
||||
|
||||
if (vIsZero(BuildingMap[EntIndex].Location) || !vEquals(BaseBuildable->pev->origin, BuildingMap[EntIndex].Location, 5.0f))
|
||||
{
|
||||
AITAC_RefreshReachabilityForStructure(&BuildingMap[EntIndex]);
|
||||
|
@ -1530,6 +1667,11 @@ void AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
NewFlags |= STRUCTURE_STATUS_RECYCLING;
|
||||
}
|
||||
|
||||
if (BaseBuildable->GetIsResearching())
|
||||
{
|
||||
NewFlags |= STRUCTURE_STATUS_RESEARCHING;
|
||||
}
|
||||
|
||||
float NewHealthPercent = (BuildingEdict->v.health / BuildingEdict->v.max_health);
|
||||
|
||||
if (NewHealthPercent < BuildingMap[EntIndex].healthPercent)
|
||||
|
@ -2030,6 +2172,40 @@ bool UTIL_StructureIsResearching(edict_t* Structure, const AvHMessageID Research
|
|||
return (StructureRef && StructureRef->GetIsResearching() && Structure->v.iuser2 == (int)Research);
|
||||
}
|
||||
|
||||
bool AITAC_MarineResearchIsAvailable(const AvHTeamNumber Team, const AvHMessageID Research)
|
||||
{
|
||||
AvHTeam* PlayerTeam = GetGameRules()->GetTeam(Team);
|
||||
|
||||
if (!PlayerTeam) { return false; }
|
||||
|
||||
AvHMessageID Message = Research;
|
||||
|
||||
return PlayerTeam->GetResearchManager().GetIsMessageAvailable(Message);
|
||||
|
||||
}
|
||||
|
||||
bool AITAC_ElectricalResearchIsAvailable(edict_t* Structure)
|
||||
{
|
||||
if (FNullEnt(Structure)) { return false; }
|
||||
|
||||
if (UTIL_IsStructureElectrified(Structure)) { return false; }
|
||||
|
||||
AvHAIDeployableStructureType StructureTypeToElectrify = GetStructureTypeFromEdict(Structure);
|
||||
AvHAIDeployableStructureType ElectrifyableStructureTypes = (AvHAIDeployableStructureType)(STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY | STRUCTURE_MARINE_RESTOWER);
|
||||
|
||||
if (!(ElectrifyableStructureTypes & StructureTypeToElectrify)) { return false; }
|
||||
|
||||
DeployableSearchFilter TFFilter;
|
||||
TFFilter.DeployableTypes = STRUCTURE_MARINE_TURRETFACTORY | STRUCTURE_MARINE_ADVTURRETFACTORY;
|
||||
TFFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
TFFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
TFFilter.DeployableTeam = (AvHTeamNumber)Structure->v.team;
|
||||
|
||||
if (!AITAC_DeployableExistsAtLocation(AITAC_GetCommChairLocation((AvHTeamNumber)Structure->v.team), &TFFilter)) { return false; }
|
||||
|
||||
return (Structure->v.iuser4 & MASK_UPGRADE_1);
|
||||
}
|
||||
|
||||
AvHAIHiveDefinition* AITAC_GetHiveFromEdict(const edict_t* Edict)
|
||||
{
|
||||
for (auto it = Hives.begin(); it != Hives.end(); it++)
|
||||
|
@ -2497,6 +2673,41 @@ AvHMessageID UTIL_StructureTypeToImpulseCommand(const AvHAIDeployableStructureTy
|
|||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
AvHMessageID UTIL_ItemTypeToImpulseCommand(const AvHAIDeployableItemType ItemType)
|
||||
{
|
||||
switch (ItemType)
|
||||
{
|
||||
|
||||
case DEPLOYABLE_ITEM_HEAVYARMOUR:
|
||||
return BUILD_HEAVY;
|
||||
case DEPLOYABLE_ITEM_JETPACK:
|
||||
return BUILD_JETPACK;
|
||||
case DEPLOYABLE_ITEM_CATALYSTS:
|
||||
return BUILD_CAT;
|
||||
case DEPLOYABLE_ITEM_SCAN:
|
||||
return BUILD_SCAN;
|
||||
case DEPLOYABLE_ITEM_HEALTHPACK:
|
||||
return BUILD_HEALTH;
|
||||
case DEPLOYABLE_ITEM_AMMO:
|
||||
return BUILD_AMMO;
|
||||
case DEPLOYABLE_ITEM_MINES:
|
||||
return BUILD_MINES;
|
||||
case DEPLOYABLE_ITEM_WELDER:
|
||||
return BUILD_WELDER;
|
||||
case DEPLOYABLE_ITEM_SHOTGUN:
|
||||
return BUILD_SHOTGUN;
|
||||
case DEPLOYABLE_ITEM_HMG:
|
||||
return BUILD_HMG;
|
||||
case DEPLOYABLE_ITEM_GRENADELAUNCHER:
|
||||
return BUILD_GRENADE_GUN;
|
||||
default:
|
||||
return MESSAGE_NULL;
|
||||
|
||||
}
|
||||
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
edict_t* AITAC_GetClosestPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, float SearchRadius, edict_t* IgnorePlayer)
|
||||
{
|
||||
float distSq = sqrf(SearchRadius);
|
||||
|
@ -2663,7 +2874,7 @@ AvHAIDeployableStructureType UTIL_GetChamberTypeForHiveTech(AvHMessageID HiveTec
|
|||
return STRUCTURE_NONE;
|
||||
}
|
||||
|
||||
bool UTIL_ResearchIsComplete(const AvHTeamNumber Team, const AvHTechID Research)
|
||||
bool AITAC_ResearchIsComplete(const AvHTeamNumber Team, const AvHTechID Research)
|
||||
{
|
||||
AvHTeam* TeamRef = GetGameRules()->GetTeam(Team);
|
||||
|
||||
|
@ -2672,4 +2883,200 @@ bool UTIL_ResearchIsComplete(const AvHTeamNumber Team, const AvHTechID Research)
|
|||
AvHResearchManager ResearchManager = TeamRef->GetResearchManager();
|
||||
|
||||
return ResearchManager.GetTechNodes().GetIsTechResearched(Research);
|
||||
}
|
||||
|
||||
bool AITAC_PhaseGatesAvailable(const AvHTeamNumber Team)
|
||||
{
|
||||
DeployableSearchFilter ObsFilter;
|
||||
ObsFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
ObsFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
ObsFilter.DeployableTypes = STRUCTURE_MARINE_OBSERVATORY;
|
||||
ObsFilter.DeployableTeam = Team;
|
||||
|
||||
bool bObsExists = AITAC_DeployableExistsAtLocation(AITAC_GetTeamStartingLocation(Team), &ObsFilter);
|
||||
|
||||
return bObsExists && AITAC_ResearchIsComplete(Team, TECH_RESEARCH_PHASETECH);
|
||||
}
|
||||
|
||||
int AITAC_GetNumDeadPlayersOnTeam(const AvHTeamNumber Team)
|
||||
{
|
||||
AvHTeam* TeamRef = GetGameRules()->GetTeam(Team);
|
||||
|
||||
if (!TeamRef) { return 0; }
|
||||
|
||||
return TeamRef->GetPlayerCount(true);
|
||||
}
|
||||
|
||||
bool AITAC_StructureCanBeUpgraded(edict_t* Structure)
|
||||
{
|
||||
// We can't upgrade a structure if it's not built, destroyed, or already doing something
|
||||
if (FNullEnt(Structure)
|
||||
|| Structure->v.deadflag != DEAD_NO
|
||||
|| !UTIL_StructureIsFullyBuilt(Structure)
|
||||
|| UTIL_StructureIsRecycling(Structure)
|
||||
|| UTIL_StructureIsResearching(Structure)
|
||||
|| UTIL_StructureIsUpgrading(Structure))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (GetStructureTypeFromEdict(Structure) == STRUCTURE_MARINE_ARMOURY || GetStructureTypeFromEdict(Structure) == STRUCTURE_MARINE_TURRETFACTORY);
|
||||
}
|
||||
|
||||
const AvHAIHiveDefinition* AITAC_GetNearestHiveUnderActiveSiege(AvHTeamNumber SiegingTeam, const Vector SearchLocation)
|
||||
{
|
||||
AvHAIHiveDefinition* Result = nullptr;
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = Hives.begin(); it != Hives.end(); it++)
|
||||
{
|
||||
if (it->Status == HIVE_STATUS_UNBUILT) { continue; }
|
||||
|
||||
DeployableSearchFilter SiegeFilter;
|
||||
SiegeFilter.DeployableTypes = STRUCTURE_MARINE_ADVTURRETFACTORY;
|
||||
SiegeFilter.DeployableTeam = SiegingTeam;
|
||||
SiegeFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
SiegeFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
|
||||
SiegeFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
|
||||
AvHAIBuildableStructure* AdvTF = AITAC_FindClosestDeployableToLocation(it->Location, &SiegeFilter);
|
||||
|
||||
if (!AdvTF) { continue; }
|
||||
|
||||
SiegeFilter.DeployableTypes = STRUCTURE_MARINE_SIEGETURRET;
|
||||
SiegeFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(5.0f);
|
||||
|
||||
bool bSTExists = AITAC_DeployableExistsAtLocation(AdvTF->Location, &SiegeFilter);
|
||||
|
||||
if (bSTExists)
|
||||
{
|
||||
float ThisDist = vDist2DSq(SearchLocation, it->Location);
|
||||
|
||||
if (!Result || ThisDist < MinDist)
|
||||
{
|
||||
Result = &(*it);
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
edict_t* AITAC_GetMarineEligibleToBuildSiege(AvHTeamNumber Team, const AvHAIHiveDefinition* Hive)
|
||||
{
|
||||
if (!Hive) { return nullptr; }
|
||||
|
||||
edict_t* Result = nullptr;
|
||||
|
||||
vector<AvHPlayer*> TeamPlayers = AITAC_GetAllPlayersOnTeam(Team);
|
||||
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = TeamPlayers.begin(); it != TeamPlayers.end(); it++)
|
||||
{
|
||||
edict_t* PlayerEdict = (*it)->edict();
|
||||
|
||||
// Find a player who is alive and not currently sighted by the enemy
|
||||
if (!IsPlayerActiveInGame(PlayerEdict) || (PlayerEdict->v.iuser4 & MASK_VIS_SIGHTED)) { continue; }
|
||||
|
||||
float ThisDist = vDist2DSq(PlayerEdict->v.origin, Hive->Location);
|
||||
|
||||
if (ThisDist < sqrf(UTIL_MetresToGoldSrcUnits(25.0f)) && !UTIL_QuickTrace(PlayerEdict, GetPlayerEyePosition(PlayerEdict), Hive->Location))
|
||||
{
|
||||
if (FNullEnt(Result) || ThisDist < MinDist)
|
||||
{
|
||||
Result = PlayerEdict;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
edict_t* AITAC_GetNearestHiddenPlayerInLocation(AvHTeamNumber Team, const Vector Location, const float MaxRadius)
|
||||
{
|
||||
edict_t* Result = nullptr;
|
||||
float MaxRadiusSq = sqrf(MaxRadius);
|
||||
|
||||
vector<AvHPlayer*> TeamPlayers = AITAC_GetAllPlayersOnTeam(Team);
|
||||
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = TeamPlayers.begin(); it != TeamPlayers.end(); it++)
|
||||
{
|
||||
edict_t* PlayerEdict = (*it)->edict();
|
||||
|
||||
// Find a player who is alive and not currently sighted by the enemy
|
||||
if (!IsPlayerActiveInGame(PlayerEdict) || (PlayerEdict->v.iuser4 & MASK_VIS_SIGHTED)) { continue; }
|
||||
|
||||
float ThisDist = vDist2DSq(PlayerEdict->v.origin, Location);
|
||||
|
||||
if (ThisDist < MaxRadiusSq)
|
||||
{
|
||||
if (FNullEnt(Result) || ThisDist < MinDist)
|
||||
{
|
||||
Result = PlayerEdict;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
vector<AvHPlayer*> AITAC_GetAllPlayersOnTeam(AvHTeamNumber Team)
|
||||
{
|
||||
vector<AvHPlayer*> Result;
|
||||
|
||||
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
edict_t* PlayerEdict = INDEXENT(i);
|
||||
|
||||
if (!FNullEnt(PlayerEdict) && PlayerEdict->v.team == Team)
|
||||
{
|
||||
AvHPlayer* PlayerRef = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(PlayerEdict));
|
||||
|
||||
if (PlayerRef)
|
||||
{
|
||||
Result.push_back(PlayerRef);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
const vector<AvHAIResourceNode>& AITAC_GetAllResourceNodes()
|
||||
{
|
||||
return ResourceNodes;
|
||||
}
|
||||
|
||||
const vector<AvHAIHiveDefinition>& AITAC_GetAllHives()
|
||||
{
|
||||
return Hives;
|
||||
}
|
||||
|
||||
bool AITAC_AnyPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, float SearchRadius)
|
||||
{
|
||||
float distSq = sqrf(SearchRadius);
|
||||
|
||||
vector<AvHPlayer*> Players = AITAC_GetAllPlayersOnTeam(Team);
|
||||
|
||||
for (auto it = Players.begin(); it != Players.end(); it++)
|
||||
{
|
||||
edict_t* PlayerRef = (*it)->edict();
|
||||
|
||||
if (!IsPlayerActiveInGame(PlayerRef)) { continue; }
|
||||
|
||||
if (vDist2DSq(PlayerRef->v.origin, Location) <= distSq && UTIL_QuickTrace(PlayerRef, GetPlayerEyePosition(PlayerRef), Location))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -23,6 +23,7 @@ static const float item_inventory_refresh_rate = 0.1f;
|
|||
bool AITAC_DeployableExistsAtLocation(const Vector& Location, const DeployableSearchFilter* Filter);
|
||||
std::vector<AvHAIBuildableStructure*> AITAC_FindAllDeployables(const Vector& Location, const DeployableSearchFilter* Filter);
|
||||
AvHAIBuildableStructure* AITAC_FindClosestDeployableToLocation(const Vector& Location, const DeployableSearchFilter* Filter);
|
||||
AvHAIBuildableStructure* AITAC_FindFurthestDeployableFromLocation(const Vector& Location, const DeployableSearchFilter* Filter);
|
||||
AvHAIBuildableStructure* AITAC_GetDeployableRefFromEdict(const edict_t* Structure);
|
||||
AvHAIBuildableStructure* AITAC_GetNearestDeployableDirectlyReachable(AvHAIPlayer* pBot, const Vector Location, const DeployableSearchFilter* Filter);
|
||||
int AITAC_GetNumDeployablesNearLocation(const Vector& Location, const DeployableSearchFilter* Filter);
|
||||
|
@ -57,6 +58,8 @@ Vector AITAC_GetTeamStartingLocation(AvHTeamNumber Team);
|
|||
AvHAIResourceNode* AITAC_GetRandomResourceNode(AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags);
|
||||
|
||||
AvHAIDroppedItem* AITAC_FindClosestItemToLocation(const Vector& Location, const AvHAIDeployableItemType ItemType, AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags, float MinRadius, float MaxRadius, bool bConsiderPhaseDistance);
|
||||
bool AITAC_ItemExistsInLocation(const Vector& Location, const AvHAIDeployableItemType ItemType, AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags, float MinRadius, float MaxRadius, bool bConsiderPhaseDistance);
|
||||
int AITAC_GetNumItemsInLocation(const Vector& Location, const AvHAIDeployableItemType ItemType, AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags, float MinRadius, float MaxRadius, bool bConsiderPhaseDistance);
|
||||
|
||||
AvHAIDroppedItem* AITAC_GetDroppedItemRefFromEdict(edict_t* ItemEdict);
|
||||
|
||||
|
@ -67,6 +70,7 @@ int AITAC_GetNumHives();
|
|||
void AITAC_OnNavMeshModified();
|
||||
|
||||
AvHMessageID UTIL_StructureTypeToImpulseCommand(const AvHAIDeployableStructureType StructureType);
|
||||
AvHMessageID UTIL_ItemTypeToImpulseCommand(const AvHAIDeployableItemType ItemType);
|
||||
|
||||
edict_t* AITAC_GetClosestPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, float SearchRadius, edict_t* IgnorePlayer);
|
||||
bool AITAC_AnyPlayerOnTeamHasLOSToLocation(AvHTeamNumber Team, const Vector& Location, float SearchRadius, edict_t* IgnorePlayer);
|
||||
|
@ -94,6 +98,7 @@ unsigned char UTIL_GetAreaForObstruction(AvHAIDeployableStructureType StructureT
|
|||
bool UTIL_IsStructureElectrified(edict_t* Structure);
|
||||
bool UTIL_StructureIsFullyBuilt(edict_t* Structure);
|
||||
bool UTIL_StructureIsRecycling(edict_t* Structure);
|
||||
bool AITAC_StructureCanBeUpgraded(edict_t* Structure);
|
||||
|
||||
AvHAIHiveDefinition* AITAC_GetHiveFromEdict(const edict_t* Edict);
|
||||
|
||||
|
@ -118,6 +123,9 @@ bool UTIL_StructureIsResearching(edict_t* Structure);
|
|||
bool UTIL_StructureIsResearching(edict_t* Structure, const AvHMessageID Research);
|
||||
bool UTIL_StructureIsUpgrading(edict_t* Structure);
|
||||
|
||||
bool AITAC_MarineResearchIsAvailable(const AvHTeamNumber Team, const AvHMessageID Research);
|
||||
bool AITAC_ElectricalResearchIsAvailable(edict_t* Structure);
|
||||
|
||||
Vector UTIL_GetNextMinePosition(edict_t* StructureToMine);
|
||||
int UTIL_GetCostOfStructureType(AvHAIDeployableStructureType StructureType);
|
||||
|
||||
|
@ -125,6 +133,21 @@ edict_t* AITAC_GetNearestHumanAtLocation(const AvHTeamNumber Team, const Vector
|
|||
|
||||
AvHAIDeployableStructureType UTIL_GetChamberTypeForHiveTech(AvHMessageID HiveTech);
|
||||
|
||||
bool UTIL_ResearchIsComplete(const AvHTeamNumber Team, const AvHTechID Research);
|
||||
bool AITAC_ResearchIsComplete(const AvHTeamNumber Team, const AvHTechID Research);
|
||||
|
||||
bool AITAC_PhaseGatesAvailable(const AvHTeamNumber Team);
|
||||
|
||||
int AITAC_GetNumDeadPlayersOnTeam(const AvHTeamNumber Team);
|
||||
|
||||
const AvHAIHiveDefinition* AITAC_GetNearestHiveUnderActiveSiege(AvHTeamNumber SiegingTeam, const Vector SearchLocation);
|
||||
edict_t* AITAC_GetMarineEligibleToBuildSiege(AvHTeamNumber Team, const AvHAIHiveDefinition* Hive);
|
||||
|
||||
vector<AvHPlayer*> AITAC_GetAllPlayersOnTeam(AvHTeamNumber Team);
|
||||
edict_t* AITAC_GetNearestHiddenPlayerInLocation(AvHTeamNumber Team, const Vector Location, const float MaxRadius);
|
||||
|
||||
const vector<AvHAIResourceNode>& AITAC_GetAllResourceNodes();
|
||||
const vector<AvHAIHiveDefinition>& AITAC_GetAllHives();
|
||||
|
||||
bool AITAC_AnyPlayerOnTeamWithLOS(AvHTeamNumber Team, const Vector& Location, float SearchRadius);
|
||||
|
||||
#endif
|
|
@ -148,7 +148,7 @@ bool AITASK_IsTaskUrgent(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
switch (Task->TaskType)
|
||||
{
|
||||
case TASK_GET_AMMO:
|
||||
return (BotGetPrimaryWeaponAmmoReserve(pBot) == 0);
|
||||
return (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) == 0);
|
||||
case TASK_GET_HEALTH:
|
||||
return (IsPlayerMarine(pBot->Edict)) ? (pBot->Edict->v.health < 50.0f) : (GetPlayerOverallHealthPercent(pBot->Edict) < 50.0f);
|
||||
case TASK_ATTACK:
|
||||
|
@ -157,7 +157,7 @@ bool AITASK_IsTaskUrgent(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
case TASK_WELD:
|
||||
return false;
|
||||
case TASK_RESUPPLY:
|
||||
return (pBot->Edict->v.health < 50.0f) || (BotGetPrimaryWeaponAmmoReserve(pBot) == 0);
|
||||
return (pBot->Edict->v.health < 50.0f) || (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) == 0);
|
||||
case TASK_MOVE:
|
||||
return AITASK_IsMoveTaskUrgent(pBot, Task);
|
||||
case TASK_BUILD:
|
||||
|
@ -420,7 +420,7 @@ bool AITASK_IsAmmoPickupTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (!UTIL_IsDroppedItemStillReachable(pBot, Task->TaskTarget)) { return false; }
|
||||
|
||||
return (vDist2DSq(pBot->Edict->v.origin, Task->TaskTarget->v.origin) < sqrf(UTIL_MetresToGoldSrcUnits(20.0f))) && (BotGetPrimaryWeaponAmmoReserve(pBot) < BotGetPrimaryWeaponMaxAmmoReserve(pBot));
|
||||
return (vDist2DSq(pBot->Edict->v.origin, Task->TaskTarget->v.origin) < sqrf(UTIL_MetresToGoldSrcUnits(20.0f))) && (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) < UTIL_GetPlayerPrimaryMaxAmmoReserve(pBot->Player));
|
||||
}
|
||||
|
||||
bool AITASK_IsHealthPickupTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
|
@ -475,7 +475,7 @@ bool AITASK_IsAttackTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
if (StructureType == STRUCTURE_ALIEN_HIVE || StructureType == STRUCTURE_ALIEN_OFFENCECHAMBER)
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) <= 0 && BotGetPrimaryWeaponAmmoReserve(pBot) <= 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) <= 0 && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ bool AITASK_IsResupplyTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
if (!UTIL_StructureIsFullyBuilt(Task->TaskTarget) || UTIL_StructureIsRecycling(Task->TaskTarget)) { return false; }
|
||||
|
||||
return ((pBot->Edict->v.health < pBot->Edict->v.max_health)
|
||||
|| (BotGetPrimaryWeaponAmmoReserve(pBot) < BotGetPrimaryWeaponMaxAmmoReserve(pBot))
|
||||
|| (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) < UTIL_GetPlayerPrimaryMaxAmmoReserve(pBot->Player))
|
||||
|| (BotGetSecondaryWeaponAmmoReserve(pBot) < BotGetSecondaryWeaponMaxAmmoReserve(pBot))
|
||||
);
|
||||
}
|
||||
|
@ -1020,7 +1020,7 @@ void BotProgressPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
if (Task->TaskType == TASK_GET_AMMO)
|
||||
{
|
||||
pBot->DesiredCombatWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
pBot->DesiredCombatWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
|
||||
MoveTo(pBot, Task->TaskTarget->v.origin, MOVESTYLE_NORMAL);
|
||||
|
@ -1040,11 +1040,11 @@ void BotProgressPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
// Allows bots to drop their current primary weapon to pick up a new weapon
|
||||
if (UTIL_DroppedItemIsPrimaryWeapon(ItemType))
|
||||
{
|
||||
AvHAIWeapon CurrentPrimaryWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
AvHAIWeapon CurrentPrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
|
||||
if (CurrentPrimaryWeapon != WEAPON_NONE && CurrentPrimaryWeapon != UTIL_GetWeaponTypeFromEdict(Task->TaskTarget))
|
||||
{
|
||||
if (GetBotCurrentWeapon(pBot) != CurrentPrimaryWeapon)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != CurrentPrimaryWeapon)
|
||||
{
|
||||
pBot->DesiredCombatWeapon = CurrentPrimaryWeapon;
|
||||
}
|
||||
|
@ -1121,7 +1121,7 @@ void BotProgressMineStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
BotLookAt(pBot, Task->TaskLocation);
|
||||
|
||||
if (GetBotCurrentWeapon(pBot) == WEAPON_MARINE_MINES)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == WEAPON_MARINE_MINES)
|
||||
{
|
||||
float LookDot = UTIL_GetDotProduct(UTIL_GetForwardVector(pBot->Edict->v.v_angle), UTIL_GetVectorNormal(Task->TaskLocation - pBot->CurrentEyePosition));
|
||||
|
||||
|
@ -1410,9 +1410,9 @@ void BotProgressReinforceStructureTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
void BotProgressResupplyTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
if (BotGetPrimaryWeaponAmmoReserve(pBot) < BotGetPrimaryWeaponMaxAmmoReserve(pBot))
|
||||
if (UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) < UTIL_GetPlayerPrimaryMaxAmmoReserve(pBot->Player))
|
||||
{
|
||||
pBot->DesiredCombatWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
pBot->DesiredCombatWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1442,9 +1442,9 @@ void MarineProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
edict_t* pEdict = pBot->Edict;
|
||||
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
pBot->DesiredCombatWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
pBot->DesiredCombatWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1454,7 +1454,7 @@ void MarineProgressBuildTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
}
|
||||
else
|
||||
{
|
||||
pBot->DesiredCombatWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
pBot->DesiredCombatWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1656,6 +1656,9 @@ void BotProgressDefendTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
void BotProgressTakeCommandTask(AvHAIPlayer* pBot)
|
||||
{
|
||||
// Don't take command if we already have a commander
|
||||
if (pBot->Player->GetCommander()) { return; }
|
||||
|
||||
edict_t* CommChair = AITAC_GetCommChair(pBot->Player->GetTeam());
|
||||
|
||||
if (!CommChair) { return; }
|
||||
|
@ -1775,7 +1778,7 @@ void AlienProgressGetHealthTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
if (PlayerHasWeapon(pBot->Player, WEAPON_FADE_METABOLIZE))
|
||||
{
|
||||
pBot->DesiredCombatWeapon = WEAPON_FADE_METABOLIZE;
|
||||
if (GetBotCurrentWeapon(pBot) == WEAPON_FADE_METABOLIZE)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == WEAPON_FADE_METABOLIZE)
|
||||
{
|
||||
pBot->Button |= IN_ATTACK;
|
||||
}
|
||||
|
@ -1812,7 +1815,7 @@ void AlienProgressHealTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
pBot->DesiredCombatWeapon = WEAPON_GORGE_HEALINGSPRAY;
|
||||
BotLookAt(pBot, UTIL_GetCentreOfEntity(Task->TaskTarget));
|
||||
if (GetBotCurrentWeapon(pBot) == WEAPON_GORGE_HEALINGSPRAY)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == WEAPON_GORGE_HEALINGSPRAY)
|
||||
{
|
||||
pBot->Button |= IN_ATTACK;
|
||||
}
|
||||
|
@ -2086,7 +2089,7 @@ void AlienProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
pBot->DesiredCombatWeapon = AttackWeapon;
|
||||
|
||||
if (GetBotCurrentWeapon(pBot) == AttackWeapon)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == AttackWeapon)
|
||||
{
|
||||
BotShootTarget(pBot, pBot->DesiredCombatWeapon, Task->TaskTarget);
|
||||
return;
|
||||
|
@ -2281,7 +2284,7 @@ void BotProgressWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
BotLookAt(pBot, vClosestPointOnBB(pBot->CurrentEyePosition, BBMin, BBMax));
|
||||
pBot->DesiredCombatWeapon = WEAPON_MARINE_WELDER;
|
||||
|
||||
if (GetBotCurrentWeapon(pBot) != WEAPON_MARINE_WELDER)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != WEAPON_MARINE_WELDER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2322,7 +2325,7 @@ void MarineProgressSecureHiveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (!TF || !(TF->StructureStatusFlags & STRUCTURE_STATUS_COMPLETED)) { bWaitForBuildingPlacement = true; }
|
||||
|
||||
bool bPhaseGatesAvailable = UTIL_ResearchIsComplete(pBot->Player->GetTeam(), TECH_PHASE_GATE);
|
||||
bool bPhaseGatesAvailable = AITAC_ResearchIsComplete(pBot->Player->GetTeam(), TECH_PHASE_GATE);
|
||||
|
||||
if (bPhaseGatesAvailable && !bWaitForBuildingPlacement)
|
||||
{
|
||||
|
@ -2443,7 +2446,7 @@ void MarineProgressCapResNodeTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
pBot->DesiredCombatWeapon = AttackWeapon;
|
||||
|
||||
if (GetBotCurrentWeapon(pBot) == AttackWeapon)
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) == AttackWeapon)
|
||||
{
|
||||
//BotShootTarget(pBot, pBot->DesiredCombatWeapon, Task->TaskTarget);
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
extern nav_mesh NavMeshes[MAX_NAV_MESHES]; // Array of nav meshes. Currently only 3 are used (building, onos, and regular)
|
||||
extern nav_profile BaseNavProfiles[MAX_NAV_PROFILES]; // Array of nav profiles
|
||||
|
||||
int BotGetCurrentWeaponClipAmmo(const AvHAIPlayer* pBot)
|
||||
int GetPlayerCurrentWeaponClipAmmo(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_pActiveItem);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_pActiveItem);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -28,9 +28,9 @@ int BotGetCurrentWeaponClipAmmo(const AvHAIPlayer* pBot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int BotGetCurrentWeaponMaxClipAmmo(const AvHAIPlayer* pBot)
|
||||
int GetPlayerCurrentWeaponMaxClipAmmo(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_pActiveItem);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_pActiveItem);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -40,13 +40,13 @@ int BotGetCurrentWeaponMaxClipAmmo(const AvHAIPlayer* pBot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int BotGetCurrentWeaponReserveAmmo(const AvHAIPlayer* pBot)
|
||||
int GetPlayerCurrentWeaponReserveAmmo(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_pActiveItem);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_pActiveItem);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
return pBot->Player->m_rgAmmo[theBasePlayerWeapon->m_iPrimaryAmmoType];
|
||||
return Player->m_rgAmmo[theBasePlayerWeapon->m_iPrimaryAmmoType];
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -165,9 +165,21 @@ void InterruptReload(AvHAIPlayer* pBot)
|
|||
pBot->Button |= IN_ATTACK;
|
||||
}
|
||||
|
||||
AvHAIWeapon UTIL_GetBotPrimaryWeapon(const AvHAIPlayer* pBot)
|
||||
AvHAIWeapon UTIL_GetPlayerPrimaryWeapon(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* Weapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* Weapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (Weapon)
|
||||
{
|
||||
return (AvHAIWeapon)Weapon->m_iId;
|
||||
}
|
||||
|
||||
return WEAPON_INVALID;
|
||||
}
|
||||
|
||||
AvHAIWeapon UTIL_GetPlayerSecondaryWeapon(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* Weapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (Weapon)
|
||||
{
|
||||
|
@ -206,9 +218,9 @@ AvHAIWeapon GetBotMarineSecondaryWeapon(const AvHAIPlayer* pBot)
|
|||
return WEAPON_INVALID;
|
||||
}
|
||||
|
||||
int BotGetPrimaryWeaponMaxAmmoReserve(AvHAIPlayer* pBot)
|
||||
int UTIL_GetPlayerPrimaryMaxAmmoReserve(AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -218,13 +230,37 @@ int BotGetPrimaryWeaponMaxAmmoReserve(AvHAIPlayer* pBot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int BotGetPrimaryWeaponAmmoReserve(AvHAIPlayer* pBot)
|
||||
int UTIL_GetPlayerPrimaryAmmoReserve(AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
return pBot->Player->m_rgAmmo[theBasePlayerWeapon->m_iPrimaryAmmoType];
|
||||
return Player->m_rgAmmo[theBasePlayerWeapon->m_iPrimaryAmmoType];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UTIL_GetPlayerSecondaryMaxAmmoReserve(AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
return theBasePlayerWeapon->iMaxAmmo1();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UTIL_GetPlayerSecondaryAmmoReserve(AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
return Player->m_rgAmmo[theBasePlayerWeapon->m_iPrimaryAmmoType];
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -242,9 +278,9 @@ int BotGetSecondaryWeaponAmmoReserve(AvHAIPlayer* pBot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int BotGetPrimaryWeaponClipAmmo(const AvHAIPlayer* pBot)
|
||||
int UTIL_GetPlayerPrimaryWeaponClipAmmo(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -266,9 +302,33 @@ int BotGetSecondaryWeaponClipAmmo(const AvHAIPlayer* pBot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int BotGetPrimaryWeaponMaxClipSize(const AvHAIPlayer* pBot)
|
||||
int UTIL_GetPlayerPrimaryWeaponMaxClipSize(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(pBot->Player->m_rgpPlayerItems[1]);
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[1]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
return theBasePlayerWeapon->iMaxClip();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UTIL_GetPlayerSecondaryWeaponClipAmmo(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
return theBasePlayerWeapon->m_iClip;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UTIL_GetPlayerSecondaryWeaponMaxClipSize(const AvHPlayer* Player)
|
||||
{
|
||||
AvHBasePlayerWeapon* theBasePlayerWeapon = dynamic_cast<AvHBasePlayerWeapon*>(Player->m_rgpPlayerItems[2]);
|
||||
|
||||
if (theBasePlayerWeapon)
|
||||
{
|
||||
|
@ -471,9 +531,9 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
|
||||
if (FNullEnt(target))
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
else if (BotGetSecondaryWeaponClipAmmo(pBot) > 0 || BotGetSecondaryWeaponAmmoReserve(pBot) > 0)
|
||||
{
|
||||
|
@ -481,7 +541,7 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
}
|
||||
else
|
||||
{
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,9 +549,9 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
{
|
||||
float DistFromEnemy = vDist2DSq(pBot->Edict->v.origin, target->v.origin);
|
||||
|
||||
if (UTIL_GetBotPrimaryWeapon(pBot) == WEAPON_MARINE_GL)
|
||||
if (UTIL_GetPlayerPrimaryWeapon(pBot->Player) == WEAPON_MARINE_GL)
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 && DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 && DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
return WEAPON_MARINE_GL;
|
||||
}
|
||||
|
@ -506,7 +566,7 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
|
||||
if (DistFromEnemy <= sqrf(UTIL_MetresToGoldSrcUnits(2.0f)))
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) == 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) == 0)
|
||||
{
|
||||
if (BotGetSecondaryWeaponClipAmmo(pBot) > 0)
|
||||
{
|
||||
|
@ -519,12 +579,12 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
}
|
||||
else
|
||||
{
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
|
||||
if (PrimaryWeapon == WEAPON_MARINE_SHOTGUN)
|
||||
{
|
||||
|
@ -536,7 +596,7 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
|
@ -548,7 +608,7 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
|
@ -569,7 +629,7 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
{
|
||||
if (DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
|
@ -583,7 +643,7 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || (DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)) && BotGetPrimaryWeaponAmmoReserve(pBot) > 0))
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || (DistFromEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)) && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0))
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
|
@ -614,7 +674,7 @@ AvHAIWeapon BotAlienChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* tar
|
|||
|
||||
if (StructureType == STRUCTURE_NONE)
|
||||
{
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
|
||||
if (PlayerHasWeapon(pBot->Player, WEAPON_GORGE_BILEBOMB))
|
||||
|
@ -651,7 +711,7 @@ AvHAIWeapon BotAlienChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* tar
|
|||
}
|
||||
}
|
||||
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
|
||||
AvHAIWeapon BotMarineChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* target)
|
||||
|
@ -660,9 +720,9 @@ AvHAIWeapon BotMarineChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* ta
|
|||
|
||||
if (StructureType == STRUCTURE_NONE)
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
else if (BotGetSecondaryWeaponClipAmmo(pBot) > 0 || BotGetSecondaryWeaponAmmoReserve(pBot) > 0)
|
||||
{
|
||||
|
@ -676,9 +736,9 @@ AvHAIWeapon BotMarineChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* ta
|
|||
|
||||
if (StructureType == STRUCTURE_ALIEN_HIVE || StructureType == STRUCTURE_ALIEN_OFFENCECHAMBER)
|
||||
{
|
||||
if (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0)
|
||||
if (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0)
|
||||
{
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
else if (BotGetSecondaryWeaponClipAmmo(pBot) > 0 || BotGetSecondaryWeaponAmmoReserve(pBot) > 0)
|
||||
{
|
||||
|
@ -691,9 +751,9 @@ AvHAIWeapon BotMarineChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* ta
|
|||
}
|
||||
else
|
||||
{
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetBotPrimaryWeapon(pBot);
|
||||
AvHAIWeapon PrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
|
||||
if ((PrimaryWeapon == WEAPON_MARINE_GL || PrimaryWeapon == WEAPON_MARINE_SHOTGUN) && (BotGetPrimaryWeaponClipAmmo(pBot) > 0 || BotGetPrimaryWeaponAmmoReserve(pBot) > 0))
|
||||
if ((PrimaryWeapon == WEAPON_MARINE_GL || PrimaryWeapon == WEAPON_MARINE_SHOTGUN) && (UTIL_GetPlayerPrimaryWeaponClipAmmo(pBot->Player) > 0 || UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) > 0))
|
||||
{
|
||||
return PrimaryWeapon;
|
||||
}
|
||||
|
@ -701,7 +761,7 @@ AvHAIWeapon BotMarineChooseBestWeaponForStructure(AvHAIPlayer* pBot, edict_t* ta
|
|||
return WEAPON_MARINE_KNIFE;
|
||||
}
|
||||
|
||||
return UTIL_GetBotPrimaryWeapon(pBot);
|
||||
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
}
|
||||
|
||||
AvHAIWeapon GorgeGetBestWeaponForCombatTarget(AvHAIPlayer* pBot, edict_t* Target)
|
||||
|
@ -875,7 +935,7 @@ AvHAIWeapon FadeGetBestWeaponForCombatTarget(AvHAIPlayer* pBot, edict_t* Target)
|
|||
|
||||
void BotReloadCurrentWeapon(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHAIWeapon CurrentWeapon = GetBotCurrentWeapon(pBot);
|
||||
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
|
||||
|
||||
if (!WeaponCanBeReloaded(CurrentWeapon)) { return; }
|
||||
|
||||
|
|
|
@ -5,19 +5,25 @@
|
|||
|
||||
#include "AvHAIPlayer.h"
|
||||
|
||||
int BotGetCurrentWeaponClipAmmo(const AvHAIPlayer* pBot);
|
||||
int BotGetCurrentWeaponMaxClipAmmo(const AvHAIPlayer* pBot);
|
||||
int BotGetCurrentWeaponReserveAmmo(const AvHAIPlayer* pBot);
|
||||
AvHAIWeapon GetBotCurrentWeapon(const AvHAIPlayer* pBot);
|
||||
int GetPlayerCurrentWeaponClipAmmo(const AvHPlayer* Player);
|
||||
int GetPlayerCurrentWeaponMaxClipAmmo(const AvHPlayer* Player);
|
||||
int GetPlayerCurrentWeaponReserveAmmo(const AvHPlayer* Player);
|
||||
AvHAIWeapon GetPlayerCurrentWeapon(const AvHPlayer* Player);
|
||||
AvHBasePlayerWeapon* GetPlayerCurrentWeaponReference(const AvHPlayer* Player);
|
||||
|
||||
|
||||
AvHAIWeapon UTIL_GetBotPrimaryWeapon(const AvHAIPlayer* pBot);
|
||||
AvHAIWeapon UTIL_GetPlayerPrimaryWeapon(const AvHPlayer* Player);
|
||||
AvHAIWeapon UTIL_GetPlayerSecondaryWeapon(const AvHPlayer* Player);
|
||||
|
||||
int BotGetPrimaryWeaponClipAmmo(const AvHAIPlayer* pBot);
|
||||
int BotGetPrimaryWeaponMaxClipSize(const AvHAIPlayer* pBot);
|
||||
int BotGetPrimaryWeaponAmmoReserve(AvHAIPlayer* pBot);
|
||||
int BotGetPrimaryWeaponMaxAmmoReserve(AvHAIPlayer* pBot);
|
||||
int UTIL_GetPlayerPrimaryWeaponClipAmmo(const AvHPlayer* Player);
|
||||
int UTIL_GetPlayerPrimaryWeaponMaxClipSize(const AvHPlayer* Player);
|
||||
int UTIL_GetPlayerPrimaryAmmoReserve(AvHPlayer* Player);
|
||||
int UTIL_GetPlayerPrimaryMaxAmmoReserve(AvHPlayer* Player);
|
||||
|
||||
int UTIL_GetPlayerSecondaryWeaponClipAmmo(const AvHPlayer* Player);
|
||||
int UTIL_GetPlayerSecondaryWeaponMaxClipSize(const AvHPlayer* Player);
|
||||
int UTIL_GetPlayerSecondaryAmmoReserve(AvHPlayer* Player);
|
||||
int UTIL_GetPlayerSecondaryMaxAmmoReserve(AvHPlayer* Player);
|
||||
|
||||
AvHAIWeapon GetBotMarineSecondaryWeapon(const AvHAIPlayer* pBot);
|
||||
int BotGetSecondaryWeaponClipAmmo(const AvHAIPlayer* pBot);
|
||||
|
|
|
@ -113,6 +113,7 @@
|
|||
#include "AIPlayers/AvHAIPlayerManager.h"
|
||||
#include "AIPlayers/AvHAITask.h"
|
||||
#include "AIPlayers/AvHAITactical.h"
|
||||
#include "AIPlayers/AvHAICommander.h"
|
||||
|
||||
extern AvHParticleTemplateListServer gParticleTemplateList;
|
||||
extern CVoiceGameMgr g_VoiceGameMgr;
|
||||
|
@ -1497,9 +1498,58 @@ BOOL AvHGamerules::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
|
|||
|
||||
theSuccess = true;
|
||||
}
|
||||
else if (FStrEq(pcmd, "testpathfind"))
|
||||
else if (FStrEq(pcmd, "testcommanderbuild"))
|
||||
{
|
||||
AIDEBUG_TestPathFind();
|
||||
AvHAIPlayer* AIComm = AIMGR_GetAICommander(theAvHPlayer->GetTeam());
|
||||
|
||||
if (AIComm)
|
||||
{
|
||||
|
||||
Vector TraceStart = GetPlayerEyePosition(theAvHPlayer->edict()); // origin + pev->view_ofs
|
||||
Vector LookDir = UTIL_GetForwardVector(theAvHPlayer->edict()->v.v_angle); // Converts view angles to normalized unit vector
|
||||
|
||||
Vector TraceEnd = TraceStart + (LookDir * 1000.0f);
|
||||
|
||||
TraceResult Hit;
|
||||
|
||||
UTIL_TraceLine(TraceStart, TraceEnd, ignore_monsters, theAvHPlayer->edict(), &Hit);
|
||||
|
||||
if (Hit.flFraction < 1.0f)
|
||||
{
|
||||
AICOMM_DeployStructure(AIComm, STRUCTURE_MARINE_ARMOURY, Hit.vecEndPos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
theSuccess = true;
|
||||
}
|
||||
else if (FStrEq(pcmd, "testresearchavailable"))
|
||||
{
|
||||
AvHTeam* PlayerTeam = GetGameRules()->GetTeam(theAvHPlayer->GetTeam());
|
||||
|
||||
if (PlayerTeam)
|
||||
{
|
||||
AvHMessageID Message = RESEARCH_ARMOR_ONE;
|
||||
AvHMessageID Message2 = RESEARCH_ARMOR_TWO;
|
||||
|
||||
if (PlayerTeam->GetResearchManager().GetIsMessageAvailable(Message))
|
||||
{
|
||||
UTIL_SayText("Armour 1: TRUE\n", theAvHPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_SayText("Armour 1: FALSE\n", theAvHPlayer);
|
||||
}
|
||||
|
||||
if (PlayerTeam->GetResearchManager().GetIsMessageAvailable(Message2))
|
||||
{
|
||||
UTIL_SayText("Armour 2: TRUE\n", theAvHPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_SayText("Armour 2: FALSE\n", theAvHPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
theSuccess = true;
|
||||
}
|
||||
|
|
|
@ -1941,7 +1941,7 @@ void AvHCommandStation::CommandUse( CBaseEntity* pActivator, CBaseEntity* pCalle
|
|||
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(pActivator);
|
||||
|
||||
// Mapper-placed CCs can be killed but they don't go away
|
||||
if(thePlayer && !(thePlayer->pev->flags & FL_FAKECLIENT) && !this->GetHasBeenKilled() && thePlayer->GetIsAbleToAct())
|
||||
if(thePlayer && !this->GetHasBeenKilled() && thePlayer->GetIsAbleToAct())
|
||||
{
|
||||
AvHTeam* theTeam = thePlayer->GetTeamPointer();
|
||||
if(theTeam && (theTeam->GetTeamType() == AVH_CLASS_TYPE_MARINE))
|
||||
|
|
|
@ -486,6 +486,8 @@ public:
|
|||
//
|
||||
|
||||
bool GetHasSeenATeam();
|
||||
|
||||
void GiveOrderToSelection(AvHOrder& inOrder);
|
||||
private:
|
||||
void AcquireOverwatchTarget();
|
||||
bool AttemptToBuildAlienStructure(AvHMessageID inMessageID);
|
||||
|
@ -509,7 +511,7 @@ private:
|
|||
void GetSpeeds(int& outBaseSpeed, int& outUnemcumberedSpeed) const;
|
||||
void GiveCombatUpgradesOnSpawn();
|
||||
bool GiveOrderToSelection(AvHOrderType inOrder, Vector inNormRay);
|
||||
void GiveOrderToSelection(AvHOrder& inOrder);
|
||||
|
||||
void GiveUpgrade(AvHMessageID inUpgrade);
|
||||
void HandleOverwatch(void);
|
||||
void HandleResearch();
|
||||
|
|
|
@ -196,6 +196,11 @@ void AvHResearchManager::SetTeamNumber(AvHTeamNumber inTeamNumber)
|
|||
this->mTeamNumber = inTeamNumber;
|
||||
}
|
||||
|
||||
bool AvHResearchManager::GetResearchDone(AvHTechID inTech)
|
||||
{
|
||||
return this->mTechNodes.GetIsTechResearched(inTech);
|
||||
}
|
||||
|
||||
bool AvHResearchManager::SetResearchDone(AvHMessageID inTech, int inEntityIndex)
|
||||
{
|
||||
bool theFoundIt = false;
|
||||
|
|
|
@ -79,6 +79,8 @@ public:
|
|||
void SetTeamNumber(AvHTeamNumber inTeamNumber);
|
||||
|
||||
void UpdateResearch();
|
||||
|
||||
bool GetResearchDone(AvHTechID inTech);
|
||||
|
||||
private:
|
||||
bool SetResearchDone(AvHMessageID inTech, int inEntityIndex);
|
||||
|
|
|
@ -96,6 +96,7 @@ vec3_t AvHSHUGetRealLocation(const vec3_t& inLocation, const vec3_t& inMinBox, c
|
|||
void AvHSHUGetFirstNonSolidPoint(float* inStartPos, float* inEndPos, float* outNonSolidPoint);
|
||||
void AvHSHUGetFirstNonSolidPoint(const vec3_t& inStartPos, const vec3_t& inEndPos, vec3_t& outNonSolidPoint);
|
||||
bool AvHSHUGetIsBuilding(AvHMessageID inMessageID);
|
||||
bool AvHSHUGetIsMarineStructure(AvHUser3 inUser3);
|
||||
bool AvHSHUGetIsBuildTech(AvHMessageID inMessageID);
|
||||
bool AvHSHUGetIsWeaponFocusable(AvHWeaponID inWeaponID);
|
||||
bool AvHSHUGetDoesTechCostEnergy(AvHMessageID inMessageID);
|
||||
|
|
Loading…
Reference in a new issue