mirror of
https://github.com/ENSL/NS.git
synced 2024-11-10 07:11:38 +00:00
First pass at combat mode
This commit is contained in:
parent
4fe93a7fd6
commit
2789e7a57c
9 changed files with 909 additions and 99 deletions
|
@ -20,7 +20,10 @@ bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureTyp
|
|||
WelderProfile.Filters.addIncludeFlags(SAMPLE_POLYFLAGS_WELD);
|
||||
|
||||
// Don't allow the commander to place a structure somewhere unreachable to marines
|
||||
if (!UTIL_PointIsReachable(WelderProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), Location, max_player_use_reach)) { return false; }
|
||||
if (!UTIL_PointIsReachable(WelderProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), Location, max_player_use_reach))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AvHMessageID StructureID = UTIL_StructureTypeToImpulseCommand(StructureToDeploy);
|
||||
|
||||
|
@ -28,7 +31,10 @@ bool AICOMM_DeployStructure(AvHAIPlayer* pBot, const AvHAIDeployableStructureTyp
|
|||
BuildLocation.z += 4.0f;
|
||||
|
||||
// This would be rejected if a human was trying to build here, so don't let the bot do it
|
||||
if (!AvHSHUGetIsSiteValidForBuild(StructureID, &BuildLocation)) { return false; }
|
||||
if (!AvHSHUGetIsSiteValidForBuild(StructureID, &BuildLocation))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string theErrorMessage;
|
||||
int theCost = 0;
|
||||
|
@ -477,7 +483,7 @@ void AICOMM_UpdatePlayerOrders(AvHAIPlayer* pBot)
|
|||
|
||||
if (SiegedHive)
|
||||
{
|
||||
int NumAssignedPlayers = AICOMM_GetNumPlayersAssignedToOrder(pBot, SiegedHive->HiveEntity->edict(), ORDERPURPOSE_SIEGE_HIVE);
|
||||
int NumAssignedPlayers = AICOMM_GetNumPlayersAssignedToOrder(pBot, SiegedHive->HiveEdict, ORDERPURPOSE_SIEGE_HIVE);
|
||||
|
||||
if (NumAssignedPlayers < DesiredPlayers)
|
||||
{
|
||||
|
@ -487,7 +493,7 @@ void AICOMM_UpdatePlayerOrders(AvHAIPlayer* pBot)
|
|||
|
||||
if (!FNullEnt(NewAssignee))
|
||||
{
|
||||
AICOMM_AssignNewPlayerOrder(pBot, NewAssignee, SiegedHive->HiveEntity->edict(), ORDERPURPOSE_SIEGE_HIVE);
|
||||
AICOMM_AssignNewPlayerOrder(pBot, NewAssignee, SiegedHive->HiveEdict, ORDERPURPOSE_SIEGE_HIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -560,7 +566,7 @@ void AICOMM_UpdatePlayerOrders(AvHAIPlayer* pBot)
|
|||
if (ThisHive->Status != HIVE_STATUS_UNBUILT) { continue; }
|
||||
if (AICOMM_IsHiveFullySecured(pBot, ThisHive, false)) { continue; }
|
||||
|
||||
int NumAssignedPlayers = AICOMM_GetNumPlayersAssignedToOrder(pBot, ThisHive->HiveEntity->edict(), ORDERPURPOSE_SECURE_HIVE);
|
||||
int NumAssignedPlayers = AICOMM_GetNumPlayersAssignedToOrder(pBot, ThisHive->HiveEdict, ORDERPURPOSE_SECURE_HIVE);
|
||||
|
||||
if (NumAssignedPlayers < DesiredPlayers)
|
||||
{
|
||||
|
@ -583,7 +589,7 @@ void AICOMM_UpdatePlayerOrders(AvHAIPlayer* pBot)
|
|||
|
||||
if (!FNullEnt(NewAssignee))
|
||||
{
|
||||
AICOMM_AssignNewPlayerOrder(pBot, NewAssignee, EmptyHive->HiveEntity->edict(), ORDERPURPOSE_SECURE_HIVE);
|
||||
AICOMM_AssignNewPlayerOrder(pBot, NewAssignee, EmptyHive->HiveEdict, ORDERPURPOSE_SECURE_HIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -913,19 +919,33 @@ bool AICOMM_CheckForNextBuildAction(AvHAIPlayer* pBot)
|
|||
|
||||
Vector BuildLocation = ZERO_VECTOR;
|
||||
|
||||
bool bSuccess = false;
|
||||
bool bFoundLocation = false;
|
||||
|
||||
if (NearestInfantryPortal)
|
||||
{
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestInfantryPortal->Location, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
}
|
||||
|
||||
if (vIsZero(BuildLocation))
|
||||
{
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
}
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation);
|
||||
bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation);
|
||||
bFoundLocation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bSuccess)
|
||||
{
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_ARMOURY, BuildLocation);
|
||||
bFoundLocation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bFoundLocation)
|
||||
{
|
||||
return (bSuccess || pBot->Player->GetResources() <= BALANCE_VAR(kArmoryCost) + 5);
|
||||
}
|
||||
}
|
||||
|
@ -1977,10 +1997,15 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
if (ExistingInfantryPortal)
|
||||
{
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInDonutIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), ExistingInfantryPortal->edict->v.origin, UTIL_MetresToGoldSrcUnits(2.0f), UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
if (vIsZero(BuildLocation))
|
||||
{
|
||||
Vector SearchPoint = ZERO_VECTOR;
|
||||
|
||||
DeployableSearchFilter ResNodeFilter;
|
||||
|
@ -2000,19 +2025,23 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
|
|||
|
||||
Vector NearestPointToChair = FindClosestNavigablePointToDestination(GetBaseNavProfile(MARINE_BASE_NAV_PROFILE), SearchPoint, CommChair->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
if (NearestPointToChair != ZERO_VECTOR)
|
||||
if (!vIsZero(NearestPointToChair))
|
||||
{
|
||||
float Distance = vDist2D(NearestPointToChair, CommChair->v.origin);
|
||||
float RandomDist = UTIL_MetresToGoldSrcUnits(5.0f) - Distance;
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestPointToChair, RandomDist);
|
||||
|
||||
}
|
||||
else
|
||||
if (!vIsZero(BuildLocation))
|
||||
{
|
||||
bool bSuccess = AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation);
|
||||
|
||||
if (bSuccess) { return true; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BuildLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), CommChair->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (vIsZero(BuildLocation)) { return false; }
|
||||
|
||||
|
|
|
@ -189,12 +189,12 @@ typedef enum _AVHAIBOTROLE
|
|||
|
||||
BOT_ROLE_FIND_RESOURCES, // Will hunt for uncapped resource nodes and cap them. Will attack enemy resource towers
|
||||
BOT_ROLE_SWEEPER, // Defensive role to protect infrastructure and build at base. Will patrol to keep outposts secure
|
||||
BOT_ROLE_ASSAULT, // Will go to attack the hive and other alien structures
|
||||
BOT_ROLE_ASSAULT, // Will go to attack the enemy base. In combat mode, used for Fade-focus aliens
|
||||
|
||||
// Marine-only Roles
|
||||
|
||||
BOT_ROLE_COMMAND, // Will attempt to take command
|
||||
BOT_ROLE_BOMBARDIER, // Bot is armed with a GL and wants to wreck your shit
|
||||
BOT_ROLE_BOMBARDIER, // Bot is armed with a GL and wants to wreck your shit. In combat mode, used for Onos-focus aliens
|
||||
|
||||
// Alien-only roles
|
||||
|
||||
|
@ -248,11 +248,13 @@ typedef struct _RESOURCE_NODE
|
|||
typedef struct _HIVE_DEFINITION_T
|
||||
{
|
||||
AvHHive* HiveEntity = nullptr; // Hive entity reference
|
||||
edict_t* HiveEdict = nullptr; // Hive edict reference
|
||||
Vector Location = g_vecZero; // Origin of the hive
|
||||
Vector FloorLocation = g_vecZero; // Some hives are suspended in the air, this is the floor location directly beneath it
|
||||
HiveStatusType Status = HIVE_STATUS_UNBUILT; // Can be unbuilt, in progress, or fully built
|
||||
AvHMessageID TechStatus = MESSAGE_NULL; // What tech (if any) is assigned to this hive right now
|
||||
bool bIsUnderAttack = false; // Is the hive currently under attack? Becomes false if not taken damage for more than 10 seconds
|
||||
float HealthPercent = 0.0f; // If the hive is built and active, what its health currently is
|
||||
AvHAIResourceNode* HiveResNodeRef = nullptr; // Which resource node (indexes into ResourceNodes array) belongs to this hive?
|
||||
unsigned int ObstacleRefs[MAX_NAV_MESHES]; // When in progress or built, will place an obstacle so bots don't try to walk through it
|
||||
float NextFloorLocationCheck = 0.0f; // When should the closest navigable point to the hive be calculated? Used to delay the check after a hive is built
|
||||
|
@ -759,6 +761,7 @@ typedef struct AVH_AI_PLAYER
|
|||
AvHAIBotRole BotRole = BOT_ROLE_NONE;
|
||||
|
||||
int ExperiencePointsAvailable = 0; // How much experience the bot has to spend
|
||||
AvHMessageID NextCombatModeUpgrade = MESSAGE_NULL;
|
||||
|
||||
} AvHAIPlayer;
|
||||
|
||||
|
|
|
@ -6,8 +6,12 @@
|
|||
|
||||
#include "../AvHGamerules.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
int m_spriteTexture;
|
||||
|
||||
std::unordered_map<const char*, std::string> LocalizedLocationsMap;
|
||||
|
||||
bool UTIL_CommanderTrace(const edict_t* pEdict, const Vector& start, const Vector& end)
|
||||
{
|
||||
TraceResult hit;
|
||||
|
@ -493,3 +497,90 @@ void UTIL_DrawHUDText(edict_t* pEntity, char channel, float x, float y, unsigned
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
void UTIL_ClearLocalizations()
|
||||
{
|
||||
LocalizedLocationsMap.clear();
|
||||
}
|
||||
|
||||
void UTIL_LocalizeText(const char* InputText, string& OutputText)
|
||||
{
|
||||
// Don't localize empty strings
|
||||
if (!strcmp(InputText, ""))
|
||||
{
|
||||
OutputText = "";
|
||||
}
|
||||
|
||||
char theInputString[1024];
|
||||
|
||||
sprintf(theInputString, "%s", InputText);
|
||||
|
||||
std::unordered_map<const char*, std::string>::const_iterator FoundLocalization = LocalizedLocationsMap.find(theInputString);
|
||||
|
||||
if (FoundLocalization != LocalizedLocationsMap.end())
|
||||
{
|
||||
OutputText = FoundLocalization->second;
|
||||
return;
|
||||
}
|
||||
|
||||
char filename[256];
|
||||
|
||||
std::string localizedString(theInputString);
|
||||
|
||||
string titlesPath = string(getModDirectory()) + "/titles.txt";
|
||||
strcpy(filename, titlesPath.c_str());
|
||||
|
||||
std::ifstream cFile(filename);
|
||||
if (cFile.is_open())
|
||||
{
|
||||
std::string line;
|
||||
while (getline(cFile, line))
|
||||
{
|
||||
line.erase(std::remove_if(line.begin(), line.end(), isspace),
|
||||
line.end());
|
||||
if (line[0] == '/' || line.empty())
|
||||
continue;
|
||||
|
||||
if (line.compare(theInputString) == 0)
|
||||
{
|
||||
getline(cFile, line);
|
||||
getline(cFile, localizedString);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char theOutputString[1024];
|
||||
|
||||
sprintf(theOutputString, "%s", localizedString.c_str());
|
||||
|
||||
string Delimiter = "Hive -";
|
||||
auto delimiterPos = localizedString.find(Delimiter);
|
||||
|
||||
if (delimiterPos == std::string::npos)
|
||||
{
|
||||
Delimiter = "Hive Location -";
|
||||
delimiterPos = localizedString.find(Delimiter);
|
||||
}
|
||||
|
||||
if (delimiterPos == std::string::npos)
|
||||
{
|
||||
Delimiter = "Hive Location -";
|
||||
delimiterPos = localizedString.find("Hive Location -");
|
||||
}
|
||||
|
||||
if (delimiterPos != std::string::npos)
|
||||
{
|
||||
auto AreaName = localizedString.substr(delimiterPos + Delimiter.length());
|
||||
|
||||
AreaName.erase(0, AreaName.find_first_not_of(" \r\n\t\v\f"));
|
||||
|
||||
sprintf(theOutputString, "%s", AreaName.c_str());
|
||||
}
|
||||
|
||||
OutputText = theOutputString;
|
||||
|
||||
LocalizedLocationsMap[InputText] = OutputText;
|
||||
|
||||
}
|
|
@ -52,4 +52,7 @@ void UTIL_DrawLine(edict_t* pEntity, Vector start, Vector end, float drawTimeSec
|
|||
|
||||
void UTIL_DrawHUDText(edict_t* pEntity, char channel, float x, float y, unsigned char r, unsigned char g, unsigned char b, const char* string);
|
||||
|
||||
void UTIL_ClearLocalizations();
|
||||
void UTIL_LocalizeText(const char* InputText, string& OutputText);
|
||||
|
||||
#endif
|
|
@ -5161,11 +5161,19 @@ void UpdateBotStuck(AvHAIPlayer* pBot)
|
|||
}
|
||||
|
||||
ClearBotPath(pBot);
|
||||
|
||||
}
|
||||
|
||||
if (!vIsZero(pBot->desiredMovementDir))
|
||||
{
|
||||
edict_t* BlockingEntity = UTIL_TraceEntity(pBot->Edict, pBot->Edict->v.origin, (pBot->Edict->v.origin + pBot->desiredMovementDir * 50.0f));
|
||||
|
||||
if (IsEdictStructure(BlockingEntity))
|
||||
{
|
||||
pBot->desiredMovementDir = UTIL_GetVectorNormal2D(pBot->desiredMovementDir + UTIL_GetCrossProduct(pBot->desiredMovementDir, UP_VECTOR));
|
||||
|
||||
BotMovementInputs(pBot);
|
||||
}
|
||||
|
||||
BotJump(pBot);
|
||||
|
||||
if (!IsPlayerSkulk(pBot->Edict))
|
||||
|
@ -5235,11 +5243,15 @@ void UpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle)
|
|||
{
|
||||
pBot->BotNavInfo.NavProfile.Filters.removeExcludeFlags(SAMPLE_POLYFLAGS_TEAM2STRUCTURE);
|
||||
pBot->BotNavInfo.NavProfile.Filters.addExcludeFlags(SAMPLE_POLYFLAGS_TEAM1STRUCTURE);
|
||||
pBot->BotNavInfo.NavProfile.Filters.removeIncludeFlags(SAMPLE_POLYFLAGS_TEAM1STRUCTURE);
|
||||
pBot->BotNavInfo.NavProfile.Filters.addIncludeFlags(SAMPLE_POLYFLAGS_TEAM2STRUCTURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->BotNavInfo.NavProfile.Filters.removeExcludeFlags(SAMPLE_POLYFLAGS_TEAM1STRUCTURE);
|
||||
pBot->BotNavInfo.NavProfile.Filters.addExcludeFlags(SAMPLE_POLYFLAGS_TEAM2STRUCTURE);
|
||||
pBot->BotNavInfo.NavProfile.Filters.removeIncludeFlags(SAMPLE_POLYFLAGS_TEAM2STRUCTURE);
|
||||
pBot->BotNavInfo.NavProfile.Filters.addIncludeFlags(SAMPLE_POLYFLAGS_TEAM1STRUCTURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8245,12 +8257,12 @@ void NAV_ProgressMovementTask(AvHAIPlayer* pBot)
|
|||
{
|
||||
if (IsPlayerInUseRange(pBot->Edict, MoveTask->TaskTarget))
|
||||
{
|
||||
Vector BBMin = MoveTask->TaskTarget->v.absmin;
|
||||
Vector BBMax = MoveTask->TaskTarget->v.absmax;
|
||||
Vector BBMin = MoveTask->TaskTarget->v.absmin + Vector(5.0f, 5.0f, 5.0f);
|
||||
Vector BBMax = MoveTask->TaskTarget->v.absmax - Vector(5.0f, 5.0f, 5.0f);
|
||||
|
||||
vScaleBB(BBMin, BBMax, 0.75f);
|
||||
|
||||
BotLookAt(pBot, vClosestPointOnBB(pBot->CurrentEyePosition, BBMin, BBMax));
|
||||
BotLookAt(pBot, vClosestPointOnBB(pBot->Edict->v.origin, BBMin, BBMax));
|
||||
pBot->DesiredCombatWeapon = WEAPON_MARINE_WELDER;
|
||||
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != WEAPON_MARINE_WELDER)
|
||||
|
|
|
@ -1814,9 +1814,9 @@ void SetNewAIPlayerRole(AvHAIPlayer* pBot, AvHAIBotRole NewRole)
|
|||
|
||||
void UpdateAIPlayerCORole(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
|
||||
|
||||
if (AIMGR_GetNumAIPlayersWithRoleOnTeam(pBot->Player->GetTeam(), BOT_ROLE_SWEEPER, pBot) == 0)
|
||||
if (AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_SWEEPER, pBot) == 0)
|
||||
{
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_SWEEPER);
|
||||
return;
|
||||
|
@ -1826,21 +1826,30 @@ void UpdateAIPlayerCORole(AvHAIPlayer* pBot)
|
|||
{
|
||||
if (IsPlayerLerk(pBot->Edict))
|
||||
{
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_SWEEPER);
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_HARASS);
|
||||
return;
|
||||
}
|
||||
|
||||
int NumLerks = AITAC_GetNumPlayersOnTeamOfClass(pBot->Player->GetTeam(), AVH_USER3_ALIEN_PLAYER3, pBot->Edict);
|
||||
int NumHarassers = AIMGR_GetNumAIPlayersWithRoleOnTeam(pBot->Player->GetTeam(), BOT_ROLE_HARASS, pBot);
|
||||
int NumLerks = AITAC_GetNumPlayersOnTeamOfClass(BotTeam, AVH_USER3_ALIEN_PLAYER3, pBot->Edict);
|
||||
int NumHarassers = AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_HARASS, pBot);
|
||||
|
||||
if (NumLerks + NumHarassers == 0)
|
||||
{
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_SWEEPER);
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_HARASS);
|
||||
return;
|
||||
}
|
||||
|
||||
int MaxOnos = (int)(ceilf((float)(AIMGR_GetNumPlayersOnTeam(BotTeam) - 2)) * 0.3f);
|
||||
|
||||
if (AIMGR_GetNumAIPlayersWithRoleOnTeam(BotTeam, BOT_ROLE_BOMBARDIER, pBot) < MaxOnos)
|
||||
{
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_BOMBARDIER);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetNewAIPlayerRole(pBot, BOT_ROLE_ASSAULT);
|
||||
|
||||
}
|
||||
|
||||
void UpdateAIPlayerDMRole(AvHAIPlayer* pBot)
|
||||
|
@ -3268,7 +3277,7 @@ void AIPlayerSetMarineAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
|
||||
if (ActiveSiegeHive)
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, ActiveSiegeHive->HiveEntity->edict(), false);
|
||||
AITASK_SetAttackTask(pBot, Task, ActiveSiegeHive->HiveEdict, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3304,7 +3313,7 @@ void AIPlayerSetMarineAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
|
||||
if (!vIsZero(ActualMoveLocation))
|
||||
{
|
||||
AITASK_SetSecureHiveTask(pBot, Task, NearestEmptyHive->HiveEntity->edict(), NearestEmptyHive->FloorLocation, false);
|
||||
AITASK_SetSecureHiveTask(pBot, Task, NearestEmptyHive->HiveEdict, NearestEmptyHive->FloorLocation, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -3834,7 +3843,7 @@ void AIPlayerNSAlienThink(AvHAIPlayer* pBot)
|
|||
{
|
||||
pBot->PrimaryBotTask.TaskType = TASK_BUILD;
|
||||
pBot->PrimaryBotTask.StructureType = STRUCTURE_ALIEN_HIVE;
|
||||
char msg[64];
|
||||
char msg[128];
|
||||
sprintf(msg, "I'm going to drop the hive at %s", HiveToBuild->HiveName);
|
||||
BotSay(pBot, true, 1.0f, msg);
|
||||
}
|
||||
|
@ -3946,48 +3955,233 @@ AvHMessageID GetNextAIPlayerCOMarineUpgrade(AvHAIPlayer* pBot)
|
|||
return RESEARCH_WEAPONS_ONE;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(BUILD_SHOTGUN))
|
||||
{
|
||||
return BUILD_SHOTGUN;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(BUILD_SHOTGUN))
|
||||
{
|
||||
return BUILD_SHOTGUN;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(BUILD_HMG))
|
||||
{
|
||||
return BUILD_HMG;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(RESEARCH_ARMOR_TWO))
|
||||
{
|
||||
return RESEARCH_ARMOR_TWO;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(RESEARCH_WEAPONS_TWO))
|
||||
{
|
||||
return RESEARCH_WEAPONS_TWO;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(BUILD_HEAVY))
|
||||
{
|
||||
return BUILD_HEAVY;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(RESEARCH_ARMOR_THREE))
|
||||
{
|
||||
return RESEARCH_ARMOR_TWO;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(RESEARCH_WEAPONS_THREE))
|
||||
{
|
||||
return RESEARCH_WEAPONS_TWO;
|
||||
}
|
||||
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
AvHMessageID GetNextAIPlayerCOAlienUpgrade(AvHAIPlayer* pBot)
|
||||
{
|
||||
int NumPointsAvailable = pBot->ExperiencePointsAvailable;
|
||||
|
||||
if (IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
NumPointsAvailable += GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_TWO);
|
||||
}
|
||||
|
||||
if (IsPlayerLerk(pBot->Edict))
|
||||
{
|
||||
NumPointsAvailable += GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_THREE);
|
||||
}
|
||||
|
||||
if (IsPlayerFade(pBot->Edict))
|
||||
{
|
||||
NumPointsAvailable += GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FOUR);
|
||||
}
|
||||
|
||||
if (IsPlayerOnos(pBot->Edict))
|
||||
{
|
||||
NumPointsAvailable += GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FIVE);
|
||||
}
|
||||
|
||||
// Always start off getting carapace, to improve viability early game
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_ONE))
|
||||
{
|
||||
return ALIEN_EVOLUTION_ONE;
|
||||
}
|
||||
|
||||
// Unlock leap for further viability early game
|
||||
// If we are a harasser, always ensure we have enough resources to go lerk
|
||||
if (pBot->BotRole == BOT_ROLE_HARASS)
|
||||
{
|
||||
if (NumPointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_THREE))
|
||||
{
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
// Lerks need adrenaline
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_EIGHT))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// Unlock umbra
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_HIVE_TWO_UNLOCK))
|
||||
{
|
||||
return ALIEN_HIVE_TWO_UNLOCK;
|
||||
}
|
||||
|
||||
// If we are a sweeper, always ensure we have enough resources to go gorge in case we want to heal the hive
|
||||
// Get that sweet primal scream
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_HIVE_THREE_UNLOCK))
|
||||
{
|
||||
return ALIEN_HIVE_THREE_UNLOCK;
|
||||
}
|
||||
|
||||
// Unlock focus
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_ELEVEN))
|
||||
{
|
||||
return ALIEN_EVOLUTION_ELEVEN;
|
||||
}
|
||||
|
||||
// Unlock regeneration
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_TWO))
|
||||
{
|
||||
return ALIEN_EVOLUTION_TWO;
|
||||
}
|
||||
|
||||
// Unlock celerity
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_SEVEN))
|
||||
{
|
||||
return ALIEN_EVOLUTION_SEVEN;
|
||||
}
|
||||
|
||||
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
|
||||
if (pBot->BotRole == BOT_ROLE_SWEEPER)
|
||||
{
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
if (pBot->ExperiencePointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_TWO))
|
||||
// If we are a sweeper, always ensure we have enough resources to go gorge in case we want to heal the hive
|
||||
if (NumPointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_TWO))
|
||||
{
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Gorges need adrenaline
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_EIGHT))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// If we are a harasser, always ensure we have enough resources to go lerk
|
||||
if (pBot->BotRole == BOT_ROLE_HARASS)
|
||||
// Regen
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_TWO))
|
||||
{
|
||||
if (!IsPlayerLerk(pBot->Edict))
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// Celerity
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_SEVEN))
|
||||
{
|
||||
if (pBot->ExperiencePointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_THREE))
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// Redemption
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_THREE))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// Focus
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_ELEVEN))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// Silence
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_NINE))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// Cloak
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_TEN))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
// ASSAULT and BOMBARDIER STUFF BELOW
|
||||
// ASSAULT = jacked-up fade
|
||||
// BOMBARDIER = Onos
|
||||
|
||||
// Unlock leap
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_HIVE_TWO_UNLOCK))
|
||||
{
|
||||
return ALIEN_HIVE_TWO_UNLOCK;
|
||||
}
|
||||
|
||||
// If we're going assault then make sure we've saved up enough for fade
|
||||
if (pBot->BotRole == BOT_ROLE_ASSAULT)
|
||||
{
|
||||
if (NumPointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FOUR))
|
||||
{
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
// Unlock adrenaline
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_EIGHT))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_HIVE_THREE_UNLOCK))
|
||||
{
|
||||
return ALIEN_HIVE_THREE_UNLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
// As a bombardier, we can still go fade if we can't afford Onos yet, so calculate our points savings accordingly
|
||||
if (pBot->BotRole == BOT_ROLE_BOMBARDIER)
|
||||
{
|
||||
if (NumPointsAvailable <= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FIVE))
|
||||
{
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
// Unlock adrenaline
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_EIGHT))
|
||||
{
|
||||
return ALIEN_EVOLUTION_EIGHT;
|
||||
}
|
||||
|
||||
// Unlock regeneration
|
||||
if (!pBot->Player->GetHasCombatModeUpgrade(ALIEN_EVOLUTION_TWO))
|
||||
{
|
||||
return ALIEN_EVOLUTION_TWO;
|
||||
}
|
||||
}
|
||||
|
||||
return MESSAGE_NULL;
|
||||
}
|
||||
|
||||
void AIPlayerCOThink(AvHAIPlayer* pBot)
|
||||
|
@ -4012,9 +4206,462 @@ void AIPlayerCOThink(AvHAIPlayer* pBot)
|
|||
|
||||
UpdateAIPlayerCORole(pBot);
|
||||
|
||||
AvHMessageID NextCombatUpgrade = GetNextAIPlayerCOUpgrade(pBot);
|
||||
if (IsPlayerMarine(pBot->Edict))
|
||||
{
|
||||
AIPlayerCOMarineThink(pBot);
|
||||
}
|
||||
else
|
||||
{
|
||||
AIPlayerCOAlienThink(pBot);
|
||||
}
|
||||
}
|
||||
|
||||
void AIPlayerCOMarineThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
AvHMessageID NextCombatUpgrade = GetNextAIPlayerCOMarineUpgrade(pBot);
|
||||
|
||||
if (NextCombatUpgrade != MESSAGE_NULL)
|
||||
{
|
||||
int Cost = GetGameRules()->GetCostForMessageID(NextCombatUpgrade);
|
||||
|
||||
if (pBot->ExperiencePointsAvailable >= Cost)
|
||||
{
|
||||
if (gpGlobals->time - pBot->LastRequestTime > 1.0f)
|
||||
{
|
||||
pBot->Impulse = (int)NextCombatUpgrade;
|
||||
pBot->LastRequestTime = gpGlobals->time;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gpGlobals->time >= pBot->BotNextTaskEvaluationTime)
|
||||
{
|
||||
pBot->BotNextTaskEvaluationTime = gpGlobals->time + frandrange(0.2f, 0.5f);
|
||||
|
||||
AITASK_BotUpdateAndClearTasks(pBot);
|
||||
|
||||
AIPlayerSetPrimaryCOMarineTask(pBot, &pBot->PrimaryBotTask);
|
||||
AIPlayerSetSecondaryCOMarineTask(pBot, &pBot->SecondaryBotTask);
|
||||
}
|
||||
|
||||
pBot->CurrentTask = AIPlayerGetNextTask(pBot);
|
||||
|
||||
if (pBot->CurrentTask && pBot->CurrentTask->TaskType != TASK_NONE)
|
||||
{
|
||||
BotProgressTask(pBot, pBot->CurrentTask);
|
||||
}
|
||||
}
|
||||
|
||||
void AIPlayerCOAlienThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
if (!pBot->CurrentTask) { pBot->CurrentTask = &pBot->PrimaryBotTask; }
|
||||
|
||||
AvHMessageID NextCombatUpgrade = GetNextAIPlayerCOAlienUpgrade(pBot);
|
||||
|
||||
if (NextCombatUpgrade != MESSAGE_NULL)
|
||||
{
|
||||
int Cost = GetGameRules()->GetCostForMessageID(NextCombatUpgrade);
|
||||
|
||||
if (pBot->ExperiencePointsAvailable >= Cost)
|
||||
{
|
||||
if (gpGlobals->time - pBot->LastCombatTime > 5.0f)
|
||||
{
|
||||
if (gpGlobals->time - pBot->LastRequestTime > 1.0f)
|
||||
{
|
||||
pBot->Impulse = (int)NextCombatUpgrade;
|
||||
pBot->LastRequestTime = gpGlobals->time;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gpGlobals->time >= pBot->BotNextTaskEvaluationTime)
|
||||
{
|
||||
pBot->BotNextTaskEvaluationTime = gpGlobals->time + frandrange(0.2f, 0.5f);
|
||||
|
||||
AITASK_BotUpdateAndClearTasks(pBot);
|
||||
|
||||
AIPlayerSetPrimaryCOAlienTask(pBot, &pBot->PrimaryBotTask);
|
||||
AIPlayerSetSecondaryCOAlienTask(pBot, &pBot->SecondaryBotTask);
|
||||
}
|
||||
|
||||
pBot->CurrentTask = AIPlayerGetNextTask(pBot);
|
||||
|
||||
if (pBot->CurrentTask && pBot->CurrentTask->TaskType != TASK_NONE)
|
||||
{
|
||||
BotProgressTask(pBot, pBot->CurrentTask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AIPlayerSetPrimaryCOMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||
|
||||
DeployableSearchFilter EnemyStuffFilter;
|
||||
EnemyStuffFilter.DeployableTeam = EnemyTeam;
|
||||
EnemyStuffFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
EnemyStuffFilter.ReachabilityTeam = BotTeam;
|
||||
EnemyStuffFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
|
||||
AvHAIBuildableStructure* EnemyStructure = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &EnemyStuffFilter);
|
||||
|
||||
if (EnemyStructure)
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyStructure->edict, false);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AIMGR_GetTeamType(EnemyTeam) == AVH_CLASS_TYPE_ALIEN)
|
||||
{
|
||||
const AvHAIHiveDefinition* EnemyHive = AITAC_GetActiveHiveNearestLocation(EnemyTeam, pBot->Edict->v.origin);
|
||||
|
||||
if (EnemyHive)
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyHive->HiveEdict, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<AvHPlayer*> AllEnemyPlayers = AIMGR_GetAllPlayersOnTeam(EnemyTeam);
|
||||
edict_t* TargetPlayer = nullptr;
|
||||
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = AllEnemyPlayers.begin(); it != AllEnemyPlayers.end(); it++)
|
||||
{
|
||||
AvHPlayer* ThisPlayer = (*it);
|
||||
|
||||
if (!ThisPlayer) { continue; }
|
||||
|
||||
edict_t* PlayerEdict = ThisPlayer->edict();
|
||||
|
||||
if (!IsPlayerActiveInGame(PlayerEdict)) { continue; }
|
||||
|
||||
float ThisDist = vDist2DSq(PlayerEdict->v.origin, pBot->Edict->v.origin);
|
||||
|
||||
if (FNullEnt(TargetPlayer) || ThisDist < MinDist)
|
||||
{
|
||||
TargetPlayer = PlayerEdict;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FNullEnt(TargetPlayer))
|
||||
{
|
||||
MoveTo(pBot, UTIL_GetEntityGroundLocation(TargetPlayer), MOVESTYLE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void AIPlayerSetSecondaryCOMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||
|
||||
edict_t* CommChair = AITAC_GetCommChair(BotTeam);
|
||||
|
||||
DeployableSearchFilter AttackedStructuresFilter;
|
||||
AttackedStructuresFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
AttackedStructuresFilter.DeployableTeam = BotTeam;
|
||||
AttackedStructuresFilter.ReachabilityTeam = BotTeam;
|
||||
AttackedStructuresFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
AttackedStructuresFilter.IncludeStatusFlags = STRUCTURE_STATUS_UNDERATTACK;
|
||||
AttackedStructuresFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(30.0f);
|
||||
|
||||
vector<AvHAIBuildableStructure*> AllAttackedStructures = AITAC_FindAllDeployables(pBot->Edict->v.origin, &AttackedStructuresFilter);
|
||||
|
||||
AvHAIBuildableStructure* StructureToDefend = nullptr;
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = AllAttackedStructures.begin(); it != AllAttackedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure* ThisStructure = (*it);
|
||||
|
||||
float ThisDist = vDist2D(pBot->Edict->v.origin, ThisStructure->edict->v.origin);
|
||||
|
||||
int NumAttackers = AITAC_GetNumPlayersOnTeamWithLOS(EnemyTeam, ThisStructure->Location, UTIL_MetresToGoldSrcUnits(15.0f), nullptr);
|
||||
|
||||
if (NumAttackers == 0) { continue; }
|
||||
|
||||
int NumExistingDefenders = AITAC_GetNumPlayersOfTeamInArea(BotTeam, ThisStructure->Location, ThisDist - 10.0f, false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
|
||||
|
||||
if (NumExistingDefenders < 2)
|
||||
{
|
||||
if (!StructureToDefend || ThisDist < MinDist)
|
||||
{
|
||||
StructureToDefend = ThisStructure;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (StructureToDefend)
|
||||
{
|
||||
AITASK_SetDefendTask(pBot, Task, StructureToDefend->edict, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerHasWeapon(pBot->Player, WEAPON_MARINE_WELDER))
|
||||
{
|
||||
DeployableSearchFilter DamagedStructuresFilter;
|
||||
DamagedStructuresFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
DamagedStructuresFilter.DeployableTeam = BotTeam;
|
||||
DamagedStructuresFilter.ReachabilityTeam = BotTeam;
|
||||
DamagedStructuresFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
DamagedStructuresFilter.IncludeStatusFlags = STRUCTURE_STATUS_DAMAGED;
|
||||
DamagedStructuresFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
|
||||
AvHAIBuildableStructure* StructureToRepair = nullptr;
|
||||
vector<AvHAIBuildableStructure*> AllDamagedStructures = AITAC_FindAllDeployables(pBot->Edict->v.origin, &DamagedStructuresFilter);
|
||||
|
||||
MinDist = 0.0f;
|
||||
|
||||
for (auto it = AllDamagedStructures.begin(); it != AllDamagedStructures.end(); it++)
|
||||
{
|
||||
AvHAIBuildableStructure* ThisStructure = (*it);
|
||||
|
||||
if (ThisStructure->StructureType == STRUCTURE_MARINE_COMMCHAIR && ThisStructure->healthPercent < 0.7f)
|
||||
{
|
||||
StructureToRepair = ThisStructure;
|
||||
break;
|
||||
}
|
||||
|
||||
float ThisDist = vDist2DSq(ThisStructure->Location, pBot->Edict->v.origin);
|
||||
|
||||
if (!StructureToRepair || ThisDist < MinDist)
|
||||
{
|
||||
StructureToRepair = ThisStructure;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
||||
if (StructureToRepair)
|
||||
{
|
||||
AITASK_SetWeldTask(pBot, Task, StructureToRepair->edict, true);
|
||||
return;
|
||||
}
|
||||
|
||||
DeployableSearchFilter NearbyArmouryFilter;
|
||||
NearbyArmouryFilter.DeployableTypes = (STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY);
|
||||
NearbyArmouryFilter.DeployableTeam = BotTeam;
|
||||
NearbyArmouryFilter.ReachabilityTeam = BotTeam;
|
||||
NearbyArmouryFilter.ReachabilityFlags = AI_REACHABILITY_MARINE;
|
||||
|
||||
AvHAIBuildableStructure* NearestEasyAccessArmoury = AITAC_FindClosestDeployableToLocation(ZERO_VECTOR, &NearbyArmouryFilter);
|
||||
|
||||
if (!NearestEasyAccessArmoury)
|
||||
{
|
||||
NearbyArmouryFilter.ReachabilityFlags = AI_REACHABILITY_WELDER;
|
||||
|
||||
AvHAIBuildableStructure* NearestWeldableAccessArmoury = AITAC_FindClosestDeployableToLocation(ZERO_VECTOR, &NearbyArmouryFilter);
|
||||
|
||||
if (NearestWeldableAccessArmoury)
|
||||
{
|
||||
AITASK_SetMoveTask(pBot, Task, NearestWeldableAccessArmoury->Location, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AITASK_ClearBotTask(pBot, Task);
|
||||
}
|
||||
|
||||
void AIPlayerSetPrimaryCOAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
|
||||
if (IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
const AvHAIHiveDefinition* TheHive = AITAC_GetNearestTeamHive(pBot->Player->GetTeam(), pBot->Edict->v.origin, true);
|
||||
|
||||
if (TheHive)
|
||||
{
|
||||
AITASK_ClearBotTask(pBot, Task);
|
||||
BotGuardLocation(pBot, TheHive->FloorLocation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Task->TaskType == TASK_ATTACK && vDist2DSq(Task->TaskTarget->v.origin, pBot->Edict->v.origin) < sqrf(UTIL_MetresToGoldSrcUnits(10.0f)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||
|
||||
if (pBot->BotRole == BOT_ROLE_HARASS)
|
||||
{
|
||||
if (!IsPlayerLerk(pBot->Edict) && pBot->ExperiencePointsAvailable >= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_THREE))
|
||||
{
|
||||
if (Task->TaskType != TASK_EVOLVE)
|
||||
{
|
||||
const AvHAIHiveDefinition* NearestHive = AITAC_GetActiveHiveNearestLocation(BotTeam, pBot->Edict->v.origin);
|
||||
|
||||
if (NearestHive)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEdict, ALIEN_LIFEFORM_THREE, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBot->BotRole == BOT_ROLE_ASSAULT)
|
||||
{
|
||||
if (!IsPlayerFade(pBot->Edict) && pBot->ExperiencePointsAvailable >= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FOUR))
|
||||
{
|
||||
if (Task->TaskType != TASK_EVOLVE)
|
||||
{
|
||||
const AvHAIHiveDefinition* NearestHive = AITAC_GetActiveHiveNearestLocation(BotTeam, pBot->Edict->v.origin);
|
||||
|
||||
if (NearestHive)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEdict, ALIEN_LIFEFORM_FOUR, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBot->BotRole == BOT_ROLE_BOMBARDIER)
|
||||
{
|
||||
if (!IsPlayerOnos(pBot->Edict) && !IsPlayerFade(pBot->Edict))
|
||||
{
|
||||
AvHMessageID DesiredEvolution = MESSAGE_NULL;
|
||||
|
||||
if (pBot->ExperiencePointsAvailable >= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FIVE))
|
||||
{
|
||||
DesiredEvolution = ALIEN_LIFEFORM_FIVE;
|
||||
}
|
||||
else if (pBot->ExperiencePointsAvailable >= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_FOUR))
|
||||
{
|
||||
DesiredEvolution = ALIEN_LIFEFORM_FOUR;
|
||||
}
|
||||
|
||||
if (DesiredEvolution != MESSAGE_NULL)
|
||||
{
|
||||
if (Task->TaskType != TASK_EVOLVE)
|
||||
{
|
||||
const AvHAIHiveDefinition* NearestHive = AITAC_GetActiveHiveNearestLocation(BotTeam, pBot->Edict->v.origin);
|
||||
|
||||
if (NearestHive)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEdict, DesiredEvolution, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeployableSearchFilter EnemyStuffFilter;
|
||||
EnemyStuffFilter.DeployableTeam = EnemyTeam;
|
||||
EnemyStuffFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
|
||||
EnemyStuffFilter.ReachabilityTeam = BotTeam;
|
||||
EnemyStuffFilter.ReachabilityFlags = pBot->BotNavInfo.NavProfile.ReachabilityFlag;
|
||||
|
||||
AvHAIBuildableStructure* EnemyStructure = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &EnemyStuffFilter);
|
||||
|
||||
if (EnemyStructure)
|
||||
{
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyStructure->edict, false);
|
||||
return;
|
||||
}
|
||||
|
||||
vector<AvHPlayer*> AllEnemyPlayers = AIMGR_GetAllPlayersOnTeam(EnemyTeam);
|
||||
edict_t* TargetPlayer = nullptr;
|
||||
|
||||
float MinDist = 0.0f;
|
||||
|
||||
for (auto it = AllEnemyPlayers.begin(); it != AllEnemyPlayers.end(); it++)
|
||||
{
|
||||
AvHPlayer* ThisPlayer = (*it);
|
||||
|
||||
if (!ThisPlayer) { continue; }
|
||||
|
||||
edict_t* PlayerEdict = ThisPlayer->edict();
|
||||
|
||||
if (!IsPlayerActiveInGame(PlayerEdict)) { continue; }
|
||||
|
||||
float ThisDist = vDist2DSq(PlayerEdict->v.origin, pBot->Edict->v.origin);
|
||||
|
||||
if (FNullEnt(TargetPlayer) || ThisDist < MinDist)
|
||||
{
|
||||
TargetPlayer = PlayerEdict;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FNullEnt(TargetPlayer))
|
||||
{
|
||||
MoveTo(pBot, UTIL_GetEntityGroundLocation(TargetPlayer), MOVESTYLE_NORMAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AIPlayerSetSecondaryCOAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
||||
{
|
||||
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
|
||||
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
|
||||
|
||||
const AvHAIHiveDefinition* TheHive = AITAC_GetNearestTeamHive(BotTeam, pBot->Edict->v.origin, true);
|
||||
|
||||
if (TheHive->bIsUnderAttack)
|
||||
{
|
||||
int NumAttackers = AITAC_GetNumPlayersOfTeamInArea(EnemyTeam, TheHive->FloorLocation, UTIL_MetresToGoldSrcUnits(15.0f), false, nullptr, AVH_USER3_NONE);
|
||||
|
||||
int MaxDefenders = imini(NumAttackers + 1, (int)floorf((float)AIMGR_GetNumPlayersOnTeam(BotTeam) * 0.5f));
|
||||
|
||||
float ThisDist = vDist2D(pBot->Edict->v.origin, TheHive->FloorLocation);
|
||||
|
||||
int NumExistingDefenders = AITAC_GetNumPlayersOfTeamInArea(BotTeam, TheHive->FloorLocation, ThisDist - 10.0f, false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
|
||||
|
||||
if (NumExistingDefenders < MaxDefenders)
|
||||
{
|
||||
AITASK_SetDefendTask(pBot, Task, TheHive->HiveEdict, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (TheHive->HealthPercent < 1.0f && IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
Task->TaskType = TASK_HEAL;
|
||||
Task->TaskTarget = TheHive->HiveEdict;
|
||||
Task->bTaskIsUrgent = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (TheHive->HealthPercent < 0.8f)
|
||||
{
|
||||
if (IsPlayerGorge(pBot->Edict) || (pBot->BotRole == BOT_ROLE_SWEEPER && pBot->ExperiencePointsAvailable >= GetGameRules()->GetCostForMessageID(ALIEN_LIFEFORM_TWO)))
|
||||
{
|
||||
if (!IsPlayerGorge(pBot->Edict))
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, TheHive->HiveEdict, ALIEN_LIFEFORM_TWO, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task->TaskType = TASK_HEAL;
|
||||
Task->TaskTarget = TheHive->HiveEdict;
|
||||
Task->bTaskIsUrgent = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AITASK_ClearBotTask(pBot, Task);
|
||||
}
|
||||
|
||||
|
||||
void AIPlayerDMThink(AvHAIPlayer* pBot)
|
||||
{
|
||||
pBot->CurrentEnemy = BotGetNextEnemyTarget(pBot);
|
||||
|
@ -4259,7 +4906,7 @@ void AIPlayerReceiveMoveOrder(AvHAIPlayer* pBot, Vector Destination)
|
|||
{
|
||||
if (!AICOMM_IsHiveFullySecured(pBot, HiveRef, false))
|
||||
{
|
||||
AITASK_SetSecureHiveTask(pBot, &pBot->CommanderTask, HiveRef->HiveEntity->edict(), ActualMoveLocation, false);
|
||||
AITASK_SetSecureHiveTask(pBot, &pBot->CommanderTask, HiveRef->HiveEdict, ActualMoveLocation, false);
|
||||
pBot->CommanderTask.bIssuedByCommander = true;
|
||||
return;
|
||||
}
|
||||
|
@ -4480,7 +5127,7 @@ void AIPlayerSetAlienBuilderPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
|
||||
if (HiveToSecure)
|
||||
{
|
||||
AITASK_SetReinforceStructureTask(pBot, Task, HiveToSecure->HiveEntity->edict(), false);
|
||||
AITASK_SetReinforceStructureTask(pBot, Task, HiveToSecure->HiveEdict, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4771,7 +5418,7 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
|
||||
if (NearestHive)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEntity->edict(), ALIEN_LIFEFORM_FIVE, true);
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEdict, ALIEN_LIFEFORM_FIVE, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4788,7 +5435,7 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
|
||||
if (NearestHive)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEntity->edict(), ALIEN_LIFEFORM_FOUR, true);
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEdict, ALIEN_LIFEFORM_FOUR, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5022,7 +5669,7 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
{
|
||||
if ((*AIIt) == pBot) { continue; }
|
||||
|
||||
if ((*AIIt)->PrimaryBotTask.TaskType == TASK_GUARD && (*AIIt)->PrimaryBotTask.TaskTarget == ThisHive->HiveEntity->edict())
|
||||
if ((*AIIt)->PrimaryBotTask.TaskType == TASK_GUARD && (*AIIt)->PrimaryBotTask.TaskTarget == ThisHive->HiveEdict)
|
||||
{
|
||||
if ((*AIIt)->Player->GetUser3() >= AVH_USER3_ALIEN_PLAYER3) { bNeedsExtraGuards = false; }
|
||||
NumGuards++;
|
||||
|
@ -5065,7 +5712,7 @@ void AIPlayerSetAlienAssaultPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
|
|||
{
|
||||
Task->TaskType = TASK_GUARD;
|
||||
Task->TaskLocation = HiveToGuard->FloorLocation;
|
||||
Task->TaskTarget = HiveToGuard->HiveEntity->edict();
|
||||
Task->TaskTarget = HiveToGuard->HiveEdict;
|
||||
return;
|
||||
}
|
||||
else if (HiveToSecure)
|
||||
|
@ -5215,7 +5862,7 @@ void AIPlayerSetAlienHarasserPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
|
||||
if (NearestHive)
|
||||
{
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEntity->edict(), ALIEN_LIFEFORM_THREE, true);
|
||||
AITASK_SetEvolveTask(pBot, Task, NearestHive->HiveEdict, ALIEN_LIFEFORM_THREE, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -5282,7 +5929,7 @@ void AIPlayerSetAlienHarasserPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
{
|
||||
const AvHAIHiveDefinition* EnemyHive = AITAC_GetActiveHiveNearestLocation(EnemyTeam, pBot->Edict->v.origin);
|
||||
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyHive->HiveEntity->edict(), false);
|
||||
AITASK_SetAttackTask(pBot, Task, EnemyHive->HiveEdict, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5466,7 +6113,7 @@ void AIPlayerSetSecondaryAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (ThisBot != pBot && IsPlayerActiveInGame(ThisBot->Edict) && !IsPlayerGorge(ThisBot->Edict) && vDist2DSq(ThisBot->Edict->v.origin, ThisHive->FloorLocation) > sqrf(UTIL_MetresToGoldSrcUnits(15.0f)))
|
||||
{
|
||||
if (ThisBot->SecondaryBotTask.TaskType == TASK_DEFEND && ThisBot->SecondaryBotTask.TaskTarget == ThisHive->HiveEntity->edict())
|
||||
if (ThisBot->SecondaryBotTask.TaskType == TASK_DEFEND && ThisBot->SecondaryBotTask.TaskTarget == ThisHive->HiveEdict)
|
||||
{
|
||||
int ThisDefenderStrength = 1;
|
||||
|
||||
|
@ -5500,7 +6147,7 @@ void AIPlayerSetSecondaryAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
|
||||
if (HiveToDefend)
|
||||
{
|
||||
AITASK_SetDefendTask(pBot, Task, HiveToDefend->HiveEntity->edict(), true);
|
||||
AITASK_SetDefendTask(pBot, Task, HiveToDefend->HiveEdict, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,11 @@ void AIPlayerNSMarineThink(AvHAIPlayer* pBot);
|
|||
void AIPlayerNSAlienThink(AvHAIPlayer* pBot);
|
||||
// Think routine for the combat game mode
|
||||
void AIPlayerCOThink(AvHAIPlayer* pBot);
|
||||
void AIPlayerCOMarineThink(AvHAIPlayer* pBot);
|
||||
void AIPlayerCOAlienThink(AvHAIPlayer* pBot);
|
||||
|
||||
|
||||
|
||||
// Think routine for the deathmatch game mode (e.g. when playing CS maps)
|
||||
void AIPlayerDMThink(AvHAIPlayer* pBot);
|
||||
|
||||
|
@ -94,6 +99,11 @@ void AIPlayerSetAlienHarasserPrimaryTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Tas
|
|||
void AIPlayerSetSecondaryAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
|
||||
void AIPlayerSetWantsAndNeedsAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
|
||||
|
||||
void AIPlayerSetPrimaryCOMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
|
||||
void AIPlayerSetSecondaryCOMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
|
||||
void AIPlayerSetPrimaryCOAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
|
||||
void AIPlayerSetSecondaryCOAlienTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task);
|
||||
|
||||
void BotSwitchToWeapon(AvHAIPlayer* pBot, AvHAIWeapon NewWeaponSlot);
|
||||
|
||||
bool ShouldBotThink(AvHAIPlayer* pBot);
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
// Contains gorge-related functions. Needs refactoring into helper function file
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
#include "AvHAITactical.h"
|
||||
#include "AvHAINavigation.h"
|
||||
#include "AvHAITask.h"
|
||||
|
@ -28,7 +31,6 @@
|
|||
#include <unordered_map>
|
||||
|
||||
|
||||
|
||||
vector<AvHAIResourceNode> ResourceNodes;
|
||||
vector<AvHAIHiveDefinition> Hives;
|
||||
|
||||
|
@ -636,7 +638,7 @@ Vector AITAC_GetFloorLocationForHive(const AvHAIHiveDefinition* Hive)
|
|||
{
|
||||
if (!Hive) { return ZERO_VECTOR; }
|
||||
|
||||
Vector HiveFloorLoc = UTIL_GetFloorUnderEntity(Hive->HiveEntity->edict());
|
||||
Vector HiveFloorLoc = UTIL_GetFloorUnderEntity(Hive->HiveEdict);
|
||||
|
||||
Vector NearestNavigableLoc = ZERO_VECTOR;
|
||||
|
||||
|
@ -672,23 +674,26 @@ void AITAC_PopulateHiveData()
|
|||
|
||||
AvHAIHiveDefinition NewHive;
|
||||
NewHive.HiveEntity = theEntity;
|
||||
NewHive.HiveEdict = theEntity->edict();
|
||||
NewHive.Location = theEntity->pev->origin;
|
||||
memset(&NewHive.ObstacleRefs, 0, sizeof(NewHive.ObstacleRefs));
|
||||
|
||||
AvHAIResourceNode* NearestNode = AITAC_GetNearestResourceNodeToLocation(theEntity->pev->origin);
|
||||
|
||||
if (NearestNode)
|
||||
{
|
||||
NewHive.HiveResNodeRef = NearestNode;
|
||||
NearestNode->ParentHive = NewHive.HiveEntity->edict();
|
||||
NearestNode->ParentHive = NewHive.HiveEdict;
|
||||
}
|
||||
|
||||
NewHive.FloorLocation = UTIL_GetFloorUnderEntity(theEntity->edict()); // Some hives are suspended in the air, this is the floor location directly beneath it
|
||||
NewHive.FloorLocation = UTIL_GetFloorUnderEntity(NewHive.HiveEdict); // Some hives are suspended in the air, this is the floor location directly beneath it
|
||||
|
||||
string HiveName;
|
||||
|
||||
string theLocationName;
|
||||
if (AvHSHUGetNameOfLocation(GetGameRules()->GetInfoLocations(), NewHive.Location, theLocationName))
|
||||
{
|
||||
UTIL_LocalizeText(theLocationName.c_str(), theLocationName);
|
||||
HiveName = theLocationName;
|
||||
}
|
||||
|
||||
|
@ -719,6 +724,15 @@ void AITAC_RefreshHiveData()
|
|||
AvHTeamNumber CurrentOwningTeam = theEntity->GetTeamNumber();
|
||||
HiveStatusType CurrentStatus = (theEntity->GetIsActive() ? HIVE_STATUS_BUILT : (theEntity->GetIsSpawning() ? HIVE_STATUS_BUILDING : HIVE_STATUS_UNBUILT));
|
||||
|
||||
if (CurrentStatus == HIVE_STATUS_BUILT)
|
||||
{
|
||||
it->HealthPercent = (it->HiveEdict->v.health / it->HiveEdict->v.max_health);
|
||||
}
|
||||
else
|
||||
{
|
||||
it->HealthPercent = 1.0f;
|
||||
}
|
||||
|
||||
bool bHiveDestroyed = (CurrentOwningTeam != it->OwningTeam) || (it->Status == HIVE_STATUS_BUILT && CurrentStatus != it->Status);
|
||||
|
||||
if (bHiveDestroyed)
|
||||
|
@ -745,7 +759,7 @@ void AITAC_RefreshHiveData()
|
|||
|
||||
if (it->Status != HIVE_STATUS_UNBUILT && it->ObstacleRefs[REGULAR_NAV_MESH] == 0)
|
||||
{
|
||||
UTIL_AddTemporaryObstacles(UTIL_GetCentreOfEntity(it->HiveEntity->edict()) - Vector(0.0f, 0.0f, 25.0f), 125.0f, 300.0f, DT_AREA_NULL, it->ObstacleRefs);
|
||||
UTIL_AddTemporaryObstacles(UTIL_GetCentreOfEntity(it->HiveEdict) - Vector(0.0f, 0.0f, 25.0f), 125.0f, 300.0f, DT_AREA_NULL, it->ObstacleRefs);
|
||||
it->NextFloorLocationCheck = gpGlobals->time + 1.0f;
|
||||
}
|
||||
else if (it->Status == HIVE_STATUS_UNBUILT && it->ObstacleRefs[REGULAR_NAV_MESH] != 0)
|
||||
|
@ -2061,8 +2075,6 @@ AvHAIBuildableStructure* AITAC_UpdateBuildableStructure(CBaseEntity* Structure)
|
|||
|
||||
void AITAC_OnStructureCreated(AvHAIBuildableStructure* NewStructure)
|
||||
{
|
||||
if (!GetGameRules()->GetGameStarted()) { return; }
|
||||
|
||||
UTIL_AddStructureTemporaryObstacles(NewStructure);
|
||||
|
||||
AvHTeamNumber StructureTeam = (AvHTeamNumber)NewStructure->edict->v.team;
|
||||
|
@ -2250,6 +2262,8 @@ void AITAC_LinkDeployedItemToAction(AvHAIPlayer* CommanderBot, const AvHAIDroppe
|
|||
|
||||
void AITAC_ClearMapAIData()
|
||||
{
|
||||
UTIL_ClearLocalizations();
|
||||
|
||||
ResourceNodes.clear();
|
||||
|
||||
AITAC_ClearHiveInfo();
|
||||
|
@ -2632,7 +2646,7 @@ AvHAIHiveDefinition* AITAC_GetHiveFromEdict(const edict_t* Edict)
|
|||
|
||||
for (auto it = Hives.begin(); it != Hives.end(); it++)
|
||||
{
|
||||
if (it->HiveEntity->edict() == Edict)
|
||||
if (it->HiveEdict == Edict)
|
||||
{
|
||||
return &(*it);
|
||||
}
|
||||
|
@ -4503,11 +4517,11 @@ edict_t* AITAC_AlienFindNearestHealingSource(AvHTeamNumber Team, Vector SearchLo
|
|||
ThisDist -= BALANCE_VAR(kHiveHealRadius) * 0.75f;
|
||||
|
||||
// We're already in healing distance of a hive, that's our healing source
|
||||
if (ThisDist <= 0.0f) { return (*it)->HiveEntity->edict(); }
|
||||
if (ThisDist <= 0.0f) { return (*it)->HiveEdict; }
|
||||
|
||||
if (FNullEnt(Result) || ThisDist < MinDist)
|
||||
{
|
||||
Result = (*it)->HiveEntity->edict();
|
||||
Result = (*it)->HiveEdict;
|
||||
MinDist = ThisDist;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2384,12 +2384,13 @@ void BotProgressWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
// so instead aim at the closest point on the func_weldable to us.
|
||||
if (!IsEdictPlayer(Task->TaskTarget) && !IsEdictStructure(Task->TaskTarget))
|
||||
{
|
||||
Vector BBMin = Task->TaskTarget->v.absmin;
|
||||
Vector BBMax = Task->TaskTarget->v.absmax;
|
||||
Vector BBMin = Task->TaskTarget->v.absmin + Vector(5.0f, 5.0f, 5.0f);
|
||||
Vector BBMax = Task->TaskTarget->v.absmax - Vector(5.0f, 5.0f, 5.0f);
|
||||
|
||||
vScaleBB(BBMin, BBMax, 0.75f);
|
||||
|
||||
AimLocation = vClosestPointOnBB(pBot->CurrentEyePosition, BBMin, BBMax);
|
||||
AimLocation = vClosestPointOnBB(pBot->Edict->v.origin, BBMin, BBMax);
|
||||
|
||||
}
|
||||
|
||||
BotLookAt(pBot, AimLocation);
|
||||
|
@ -2625,7 +2626,7 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
{
|
||||
float DistFromGuardLocation = vDist2DSq(pBot->Edict->v.origin, GuardLocation);
|
||||
|
||||
if (DistFromGuardLocation > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
if (DistFromGuardLocation > sqrf(UTIL_MetresToGoldSrcUnits(10.0f)))
|
||||
{
|
||||
pBot->GuardInfo.GuardLocation = g_vecZero;
|
||||
pBot->GuardInfo.GuardStartLookTime = 0.0f;
|
||||
|
@ -2662,7 +2663,7 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
|
||||
if (gpGlobals->time > pBot->GuardInfo.ThisGuardStandTime)
|
||||
{
|
||||
pBot->GuardInfo.GuardStandPosition = UTIL_GetRandomPointOnNavmeshInRadius(pBot->BotNavInfo.NavProfile, GuardLocation, UTIL_MetresToGoldSrcUnits(4.0f));
|
||||
pBot->GuardInfo.GuardStandPosition = UTIL_GetRandomPointOnNavmeshInRadius(pBot->BotNavInfo.NavProfile, GuardLocation, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
|
||||
pBot->GuardInfo.ThisGuardStandTime = gpGlobals->time + frandrange(5.0f, 10.0f);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue