mirror of
https://github.com/ENSL/NS.git
synced 2025-01-21 08:50:55 +00:00
Improved guard behaviour and randomisation
* Improved the bot guard behaviour * Improved randomisation of bot names and chamber sequences * Fixed bug where bots would drop hives within range of siege bases * Fixed bug where requesting turret factories and sentry turrets from the AI commander would place a phase gate instead
This commit is contained in:
parent
7d659fb8c2
commit
9484517a15
6 changed files with 171 additions and 114 deletions
|
@ -2978,12 +2978,15 @@ bool AICOMM_CheckForNextSupportAction(AvHAIPlayer* pBot)
|
|||
case BUILD_TURRET_FACTORY:
|
||||
RequiredRes = BALANCE_VAR(kTurretFactoryCost);
|
||||
StructureToDeploy = STRUCTURE_MARINE_TURRETFACTORY;
|
||||
break;
|
||||
case BUILD_TURRET:
|
||||
RequiredRes = BALANCE_VAR(kSentryCost);
|
||||
StructureToDeploy = STRUCTURE_MARINE_TURRET;
|
||||
break;
|
||||
case BUILD_PHASEGATE:
|
||||
RequiredRes = BALANCE_VAR(kPhaseGateCost);
|
||||
StructureToDeploy = STRUCTURE_MARINE_PHASEGATE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ std::unordered_map<std::string, TeamSizeDefinitions> TeamSizeMap;
|
|||
|
||||
bot_skill BotSkillLevels[4];
|
||||
|
||||
AvHMessageID ChamberSequence[3] = { ALIEN_BUILD_DEFENSE_CHAMBER, ALIEN_BUILD_MOVEMENT_CHAMBER, ALIEN_BUILD_SENSORY_CHAMBER };
|
||||
std::vector<AvHMessageID> ChamberSequence;
|
||||
|
||||
string DefaultBotNames[MAX_PLAYERS] = { "MrRobot",
|
||||
"Wall-E",
|
||||
|
@ -173,6 +173,7 @@ void CONFIG_PopulateBotNames()
|
|||
if (BotNames.size() > 2)
|
||||
{
|
||||
auto rng = std::default_random_engine{};
|
||||
rng.seed(time(0));
|
||||
std::shuffle(begin(BotNames), end(BotNames), rng);
|
||||
}
|
||||
|
||||
|
@ -187,6 +188,7 @@ void CONFIG_PopulateBotNames()
|
|||
if (DefaultNames.size() > 2)
|
||||
{
|
||||
auto rng = std::default_random_engine{};
|
||||
rng.seed(time(0));
|
||||
std::shuffle(begin(DefaultNames), end(DefaultNames), rng);
|
||||
}
|
||||
|
||||
|
@ -255,6 +257,15 @@ void CONFIG_ParseConfigFile()
|
|||
BotSkillLevels[3].alien_bot_motion_tracking_skill = 1.0f;
|
||||
BotSkillLevels[3].alien_bot_view_speed = 2.0f;
|
||||
|
||||
ChamberSequence.clear();
|
||||
ChamberSequence.push_back(ALIEN_BUILD_DEFENSE_CHAMBER);
|
||||
ChamberSequence.push_back(ALIEN_BUILD_MOVEMENT_CHAMBER);
|
||||
ChamberSequence.push_back(ALIEN_BUILD_SENSORY_CHAMBER);
|
||||
|
||||
std::srand(time(0));
|
||||
auto rng = std::default_random_engine{};
|
||||
rng.seed(time(0));
|
||||
std::shuffle(std::begin(ChamberSequence), std::end(ChamberSequence), rng);
|
||||
|
||||
string BotConfigFile = string(getModDirectory()) + "/nsbots.ini";
|
||||
|
||||
|
@ -503,12 +514,6 @@ void CONFIG_ParseConfigFile()
|
|||
|
||||
if (!stricmp(keyChar, "ChamberSequence"))
|
||||
{
|
||||
AvHMessageID HiveOneTech = MESSAGE_NULL;
|
||||
AvHMessageID HiveTwoTech = MESSAGE_NULL;
|
||||
AvHMessageID HiveThreeTech = MESSAGE_NULL;
|
||||
|
||||
std::vector<AvHMessageID> AvailableTechs = { ALIEN_BUILD_DEFENSE_CHAMBER, ALIEN_BUILD_MOVEMENT_CHAMBER, ALIEN_BUILD_SENSORY_CHAMBER };
|
||||
|
||||
auto firstTechDelimiter = value.find("/");
|
||||
|
||||
if (firstTechDelimiter == std::string::npos)
|
||||
|
@ -533,104 +538,64 @@ void CONFIG_ParseConfigFile()
|
|||
const char* SecondTechChar = SecondTech.c_str();
|
||||
const char* ThirdTechChar = ThirdTech.c_str();
|
||||
|
||||
if (!stricmp(FirstTechChar, "movement"))
|
||||
if (!stricmp(FirstTechChar, "defense"))
|
||||
{
|
||||
HiveOneTech = ALIEN_BUILD_MOVEMENT_CHAMBER;
|
||||
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER), AvailableTechs.end());
|
||||
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_DEFENSE_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[0], ChamberSequence[Index]);
|
||||
}
|
||||
else if (!stricmp(FirstTechChar, "defense"))
|
||||
else if (!stricmp(FirstTechChar, "movement"))
|
||||
{
|
||||
HiveOneTech = ALIEN_BUILD_DEFENSE_CHAMBER;
|
||||
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER), AvailableTechs.end());
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_MOVEMENT_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[0], ChamberSequence[Index]);
|
||||
}
|
||||
else if (!stricmp(FirstTechChar, "sensory"))
|
||||
{
|
||||
HiveOneTech = ALIEN_BUILD_SENSORY_CHAMBER;
|
||||
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER), AvailableTechs.end());
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_SENSORY_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[0], ChamberSequence[Index]);
|
||||
}
|
||||
|
||||
if (!stricmp(SecondTechChar, "movement"))
|
||||
|
||||
if (!stricmp(SecondTechChar, "defense"))
|
||||
{
|
||||
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER) != AvailableTechs.end())
|
||||
{
|
||||
HiveTwoTech = ALIEN_BUILD_MOVEMENT_CHAMBER;
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER), AvailableTechs.end());
|
||||
}
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_DEFENSE_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[1], ChamberSequence[Index]);
|
||||
}
|
||||
else if (!stricmp(SecondTechChar, "defense"))
|
||||
else if (!stricmp(SecondTechChar, "movement"))
|
||||
{
|
||||
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER) != AvailableTechs.end())
|
||||
{
|
||||
HiveTwoTech = ALIEN_BUILD_DEFENSE_CHAMBER;
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER), AvailableTechs.end());
|
||||
}
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_MOVEMENT_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[1], ChamberSequence[Index]);
|
||||
}
|
||||
else if (!stricmp(SecondTechChar, "sensory"))
|
||||
{
|
||||
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER) != AvailableTechs.end())
|
||||
{
|
||||
HiveTwoTech = ALIEN_BUILD_SENSORY_CHAMBER;
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER), AvailableTechs.end());
|
||||
}
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_SENSORY_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[1], ChamberSequence[Index]);
|
||||
}
|
||||
|
||||
if (!stricmp(ThirdTechChar, "movement"))
|
||||
if (!stricmp(ThirdTechChar, "defense"))
|
||||
{
|
||||
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER) != AvailableTechs.end())
|
||||
{
|
||||
HiveThreeTech = ALIEN_BUILD_MOVEMENT_CHAMBER;
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_MOVEMENT_CHAMBER), AvailableTechs.end());
|
||||
}
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_DEFENSE_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[2], ChamberSequence[Index]);
|
||||
}
|
||||
else if (!stricmp(ThirdTechChar, "defense"))
|
||||
else if (!stricmp(ThirdTechChar, "movement"))
|
||||
{
|
||||
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER) != AvailableTechs.end())
|
||||
{
|
||||
HiveThreeTech = ALIEN_BUILD_DEFENSE_CHAMBER;
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_DEFENSE_CHAMBER), AvailableTechs.end());
|
||||
}
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_MOVEMENT_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[2], ChamberSequence[Index]);
|
||||
}
|
||||
else if (!stricmp(ThirdTechChar, "sensory"))
|
||||
{
|
||||
if (std::find(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER) != AvailableTechs.end())
|
||||
{
|
||||
HiveThreeTech = ALIEN_BUILD_SENSORY_CHAMBER;
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), ALIEN_BUILD_SENSORY_CHAMBER), AvailableTechs.end());
|
||||
}
|
||||
auto Element = std::find(ChamberSequence.begin(), ChamberSequence.end(), ALIEN_BUILD_SENSORY_CHAMBER);
|
||||
int Index = Element - ChamberSequence.begin();
|
||||
std::swap(ChamberSequence[2], ChamberSequence[Index]);
|
||||
}
|
||||
|
||||
if (HiveOneTech == MESSAGE_NULL)
|
||||
{
|
||||
int random = rand() % AvailableTechs.size();
|
||||
HiveOneTech = AvailableTechs[random];
|
||||
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), HiveOneTech), AvailableTechs.end());
|
||||
}
|
||||
|
||||
if (HiveTwoTech == MESSAGE_NULL)
|
||||
{
|
||||
int random = rand() % AvailableTechs.size();
|
||||
HiveTwoTech = AvailableTechs[random];
|
||||
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), HiveTwoTech), AvailableTechs.end());
|
||||
}
|
||||
|
||||
if (HiveThreeTech == MESSAGE_NULL)
|
||||
{
|
||||
int random = rand() % AvailableTechs.size();
|
||||
HiveThreeTech = AvailableTechs[random];
|
||||
|
||||
AvailableTechs.erase(std::remove(AvailableTechs.begin(), AvailableTechs.end(), HiveTwoTech), AvailableTechs.end());
|
||||
}
|
||||
|
||||
ChamberSequence[0] = HiveOneTech;
|
||||
ChamberSequence[1] = HiveTwoTech;
|
||||
ChamberSequence[2] = HiveThreeTech;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -322,7 +322,7 @@ typedef struct _BOT_GUARD_INFO
|
|||
{
|
||||
Vector GuardLocation = g_vecZero; // What position are we guarding?
|
||||
Vector GuardStandPosition = g_vecZero; // Where the bot should stand to guard position (moves around a bit)
|
||||
Vector GuardPoints[8]; // All potential areas to watch that an enemy could approach from
|
||||
std::vector<Vector> GuardPoints; // All potential areas to watch that an enemy could approach from
|
||||
int NumGuardPoints = 0; // How many watch areas there are for the current location
|
||||
Vector GuardLookLocation = g_vecZero; // Which area are we currently watching?
|
||||
float GuardStartLookTime = 0.0f; // When did we start watching the current area?
|
||||
|
|
|
@ -4711,23 +4711,25 @@ bool AITAC_ShouldBotBuildHive(AvHAIPlayer* pBot, AvHAIHiveDefinition** EligibleH
|
|||
|
||||
// Must be an empty hive
|
||||
DeployableSearchFilter EnemyFortificationsFilter;
|
||||
EnemyFortificationsFilter.DeployableTeam = EnemyTeam;
|
||||
EnemyFortificationsFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
|
||||
EnemyFortificationsFilter.DeployableTeam = EnemyTeam;
|
||||
|
||||
if (AIMGR_GetTeamType(EnemyTeam) == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
EnemyFortificationsFilter.DeployableTypes = (STRUCTURE_MARINE_PHASEGATE | STRUCTURE_MARINE_TURRETFACTORY | STRUCTURE_MARINE_ADVTURRETFACTORY);
|
||||
EnemyFortificationsFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(20.0f);
|
||||
EnemyFortificationsFilter.DeployableTypes = (STRUCTURE_MARINE_PHASEGATE | STRUCTURE_MARINE_TURRETFACTORY | STRUCTURE_MARINE_ADVTURRETFACTORY | STRUCTURE_MARINE_SIEGETURRET);
|
||||
EnemyFortificationsFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
|
||||
EnemyFortificationsFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED; // This is important to prevent exploiting the AI. Those structures have to be built first!
|
||||
}
|
||||
else
|
||||
{
|
||||
EnemyFortificationsFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
|
||||
EnemyFortificationsFilter.DeployableTypes = (STRUCTURE_ALIEN_OFFENCECHAMBER);
|
||||
}
|
||||
|
||||
// Enemy have built some stuff, wait until it's clear before building
|
||||
if (AITAC_DeployableExistsAtLocation(ThisHive->FloorLocation, &EnemyFortificationsFilter)) { continue; }
|
||||
|
||||
|
||||
// Should be clear to drop dat hive!
|
||||
|
||||
float ThisDist = vDist2DSq(pBot->Edict->v.origin, ThisHive->FloorLocation);
|
||||
|
|
|
@ -1192,7 +1192,7 @@ void BotProgressPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
|
|||
{
|
||||
AvHAIWeapon CurrentPrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
|
||||
|
||||
if (CurrentPrimaryWeapon != WEAPON_NONE && CurrentPrimaryWeapon != UTIL_GetWeaponTypeFromEdict(Task->TaskTarget))
|
||||
if (CurrentPrimaryWeapon != WEAPON_INVALID && CurrentPrimaryWeapon != UTIL_GetWeaponTypeFromEdict(Task->TaskTarget))
|
||||
{
|
||||
if (GetPlayerCurrentWeapon(pBot->Player) != CurrentPrimaryWeapon)
|
||||
{
|
||||
|
@ -2821,9 +2821,9 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
{
|
||||
float DistFromGuardLocation = vDist2DSq(pBot->Edict->v.origin, GuardLocation);
|
||||
|
||||
if (DistFromGuardLocation > sqrf(UTIL_MetresToGoldSrcUnits(10.0f)))
|
||||
if (DistFromGuardLocation > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
|
||||
{
|
||||
memset(&pBot->GuardInfo, 0, sizeof(AvHAIGuardInfo));
|
||||
UTIL_ClearGuardInfo(pBot);
|
||||
MoveTo(pBot, GuardLocation, MOVESTYLE_NORMAL, UTIL_MetresToGoldSrcUnits(10.0f));
|
||||
return;
|
||||
}
|
||||
|
@ -2836,15 +2836,38 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
|
||||
if (gpGlobals->time > pBot->GuardInfo.ThisGuardLookTime)
|
||||
{
|
||||
if (pBot->GuardInfo.NumGuardPoints > 0)
|
||||
if (pBot->GuardInfo.GuardPoints.size() > 0)
|
||||
{
|
||||
int NewGuardLookIndex = irandrange(0, (pBot->GuardInfo.NumGuardPoints - 1));
|
||||
if (pBot->GuardInfo.GuardPoints.size() == 1)
|
||||
{
|
||||
pBot->GuardInfo.GuardLookLocation = (*pBot->GuardInfo.GuardPoints.begin());
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector NewLookPoint = pBot->GuardInfo.GuardLookLocation;
|
||||
|
||||
int HighestScore = 0.0f;
|
||||
|
||||
for (auto it = pBot->GuardInfo.GuardPoints.begin(); it != pBot->GuardInfo.GuardPoints.end(); it++)
|
||||
{
|
||||
if (vEquals((*it), pBot->GuardInfo.GuardLookLocation)) { continue; }
|
||||
|
||||
float thisScore = frandrange(0.01f, 1.0f);
|
||||
|
||||
if (thisScore > HighestScore)
|
||||
{
|
||||
NewLookPoint = (*it);
|
||||
HighestScore = thisScore;
|
||||
}
|
||||
}
|
||||
|
||||
pBot->GuardInfo.GuardLookLocation = NewLookPoint;
|
||||
}
|
||||
|
||||
pBot->GuardInfo.GuardLookLocation = pBot->GuardInfo.GuardPoints[NewGuardLookIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
pBot->GuardInfo.GuardLookLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[SKULK_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
|
||||
pBot->GuardInfo.GuardLookLocation = UTIL_GetRandomPointOnNavmeshInRadius(BaseNavProfiles[SKULK_BASE_NAV_PROFILE], pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
|
||||
pBot->GuardInfo.GuardLookLocation.z = pBot->CurrentEyePosition.z;
|
||||
}
|
||||
|
@ -2854,7 +2877,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(5.0f));
|
||||
pBot->GuardInfo.GuardStandPosition = UTIL_GetRandomPointOnNavmeshInRadius(pBot->BotNavInfo.NavProfile, GuardLocation, UTIL_MetresToGoldSrcUnits(3.0f));
|
||||
|
||||
pBot->GuardInfo.ThisGuardStandTime = gpGlobals->time + frandrange(5.0f, 10.0f);
|
||||
}
|
||||
|
@ -2878,7 +2901,14 @@ void BotGuardLocation(AvHAIPlayer* pBot, const Vector GuardLocation)
|
|||
|
||||
void UTIL_ClearGuardInfo(AvHAIPlayer* pBot)
|
||||
{
|
||||
memset(&pBot->GuardInfo, 0, sizeof(AvHAIGuardInfo));
|
||||
pBot->GuardInfo.GuardLocation = ZERO_VECTOR;
|
||||
pBot->GuardInfo.GuardLookLocation = ZERO_VECTOR;
|
||||
pBot->GuardInfo.GuardPoints.clear();
|
||||
pBot->GuardInfo.GuardStandPosition = ZERO_VECTOR;
|
||||
pBot->GuardInfo.GuardStartLookTime = 0.0f;
|
||||
pBot->GuardInfo.GuardStartStandTime = 0.0f;
|
||||
pBot->GuardInfo.ThisGuardLookTime = 0.0f;
|
||||
pBot->GuardInfo.ThisGuardStandTime = 0.0f;
|
||||
}
|
||||
|
||||
void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocation)
|
||||
|
@ -2903,51 +2933,107 @@ void AITASK_GenerateGuardWatchPoints(AvHAIPlayer* pBot, const Vector& GuardLocat
|
|||
{
|
||||
const AvHAIHiveDefinition* ThisHive = (*it);
|
||||
|
||||
if (UTIL_QuickTrace(pEdict, GuardLocation, ThisHive->Location)) { continue; }
|
||||
|
||||
if (UTIL_QuickTrace(pEdict, GuardLocation + Vector(0.0f, 0.0f, 10.0f), ThisHive->Location) || vDist2DSq(GuardLocation, ThisHive->Location) < sqrf(UTIL_MetresToGoldSrcUnits(10.0f))) { continue; }
|
||||
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, ThisHive->FloorLocation, GuardLocation, path, 500.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, GuardLocation, ThisHive->FloorLocation, path, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult) && path.size() > 0)
|
||||
{
|
||||
Vector FinalApproachDir = UTIL_GetVectorNormal2D(path.back().Location - prev(prev(path.end()))->Location);
|
||||
Vector ProspectiveNewGuardLoc = GuardLocation - (FinalApproachDir * 300.0f);
|
||||
Vector FurthestPoint = UTIL_GetFurthestVisiblePointOnPath(GuardLocation + Vector(0.0f, 0.0f, 64.0f), path, true);
|
||||
FurthestPoint.z += 64.0f;
|
||||
|
||||
ProspectiveNewGuardLoc.z = prev(prev(path.end()))->Location.z;
|
||||
Vector LookDir = UTIL_GetVectorNormal(FurthestPoint - GuardLocation);
|
||||
|
||||
pBot->GuardInfo.GuardPoints[pBot->GuardInfo.NumGuardPoints++] = ProspectiveNewGuardLoc;
|
||||
bool bShouldAdd = true;
|
||||
|
||||
for (auto it = pBot->GuardInfo.GuardPoints.begin(); it != pBot->GuardInfo.GuardPoints.end(); it++)
|
||||
{
|
||||
Vector ThisLookDir = UTIL_GetVectorNormal((*it) - GuardLocation);
|
||||
|
||||
if (UTIL_GetDotProduct(ThisLookDir, LookDir) > 0.8f)
|
||||
{
|
||||
bShouldAdd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bShouldAdd)
|
||||
{
|
||||
pBot->GuardInfo.GuardPoints.push_back(FurthestPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AIMGR_GetEnemyTeamType(pBot->Player->GetTeam()) == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(EnemyTeam), GuardLocation, path, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult) && path.size() > 0)
|
||||
if (!UTIL_QuickTrace(nullptr, GuardLocation, AITAC_GetTeamStartingLocation(EnemyTeam)))
|
||||
{
|
||||
Vector FinalApproachDir = UTIL_GetVectorNormal2D(path.back().Location - prev(prev(path.end()))->Location);
|
||||
Vector ProspectiveNewGuardLoc = GuardLocation - (FinalApproachDir * 300.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, GuardLocation, AITAC_GetTeamStartingLocation(EnemyTeam), path, 500.0f);
|
||||
|
||||
ProspectiveNewGuardLoc.z = prev(prev(path.end()))->Location.z;
|
||||
if (dtStatusSucceed(SearchResult) && path.size() > 0)
|
||||
{
|
||||
Vector FurthestPoint = UTIL_GetFurthestVisiblePointOnPath(GuardLocation + Vector(0.0f, 0.0f, 64.0f), path, true);
|
||||
FurthestPoint.z += 64.0f;
|
||||
|
||||
pBot->GuardInfo.GuardPoints[pBot->GuardInfo.NumGuardPoints++] = ProspectiveNewGuardLoc;
|
||||
Vector LookDir = UTIL_GetVectorNormal(FurthestPoint - GuardLocation);
|
||||
|
||||
bool bShouldAdd = true;
|
||||
|
||||
for (auto it = pBot->GuardInfo.GuardPoints.begin(); it != pBot->GuardInfo.GuardPoints.end(); it++)
|
||||
{
|
||||
Vector ThisLookDir = UTIL_GetVectorNormal((*it) - GuardLocation);
|
||||
|
||||
if (UTIL_GetDotProduct(ThisLookDir, LookDir) > 0.8f)
|
||||
{
|
||||
bShouldAdd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bShouldAdd)
|
||||
{
|
||||
pBot->GuardInfo.GuardPoints.push_back(FurthestPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AIMGR_GetTeamType(pBot->Player->GetTeam()) == AVH_CLASS_TYPE_MARINE)
|
||||
{
|
||||
if (vDist2DSq(GuardLocation, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam())) > sqrf(UTIL_MetresToGoldSrcUnits(15.0f)))
|
||||
if (!UTIL_QuickTrace(pEdict, GuardLocation, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam())))
|
||||
{
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), GuardLocation, path, 500.0f);
|
||||
|
||||
if (dtStatusSucceed(SearchResult) && path.size() > 0)
|
||||
if (vDist2DSq(GuardLocation, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam())) > sqrf(UTIL_MetresToGoldSrcUnits(15.0f)))
|
||||
{
|
||||
Vector FinalApproachDir = UTIL_GetVectorNormal2D(path.back().Location - prev(prev(path.end()))->Location);
|
||||
Vector ProspectiveNewGuardLoc = GuardLocation - (FinalApproachDir * 300.0f);
|
||||
dtStatus SearchResult = FindPathClosestToPoint(NavProfile, GuardLocation, AITAC_GetTeamStartingLocation(pBot->Player->GetTeam()), path, 500.0f);
|
||||
|
||||
ProspectiveNewGuardLoc.z = prev(prev(path.end()))->Location.z;
|
||||
if (dtStatusSucceed(SearchResult) && path.size() > 0)
|
||||
{
|
||||
Vector FurthestPoint = UTIL_GetFurthestVisiblePointOnPath(GuardLocation + Vector(0.0f, 0.0f, 64.0f), path, true);
|
||||
FurthestPoint.z += 64.0f;
|
||||
|
||||
pBot->GuardInfo.GuardPoints[pBot->GuardInfo.NumGuardPoints++] = ProspectiveNewGuardLoc;
|
||||
Vector LookDir = UTIL_GetVectorNormal(FurthestPoint - GuardLocation);
|
||||
|
||||
bool bShouldAdd = true;
|
||||
|
||||
for (auto it = pBot->GuardInfo.GuardPoints.begin(); it != pBot->GuardInfo.GuardPoints.end(); it++)
|
||||
{
|
||||
Vector ThisLookDir = UTIL_GetVectorNormal((*it) - GuardLocation);
|
||||
|
||||
if (UTIL_GetDotProduct(ThisLookDir, LookDir) > 0.8f)
|
||||
{
|
||||
bShouldAdd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bShouldAdd)
|
||||
{
|
||||
pBot->GuardInfo.GuardPoints.push_back(FurthestPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,4 +118,5 @@ void BotAlienHealTarget(AvHAIPlayer* pBot, edict_t* HealTarget);
|
|||
|
||||
void RegisterBotAlienBuildAttempt(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, Vector PlacementLocation, AvHAIDeployableStructureType DesiredStructure);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue