Stability and randomness improvements

* Fixed potential crashing when obtaining references to dropped items
* Fixed issues with random number generation
This commit is contained in:
RGreenlees 2024-05-30 13:44:46 +01:00 committed by pierow
parent ef7e7a9178
commit f427a9c052
9 changed files with 107 additions and 171 deletions

View file

@ -1453,10 +1453,10 @@ bool AICOMM_CheckForNextSupplyAction(AvHAIPlayer* pBot)
if (bBaseIsDamaged) if (bBaseIsDamaged)
{ {
AvHAIDroppedItem* NearestWelder = AITAC_FindClosestItemToLocation(AITAC_GetCommChairLocation(CommanderTeam), DEPLOYABLE_ITEM_WELDER, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(15.0f), false); AvHAIDroppedItem NearestWelder = AITAC_FindClosestItemToLocation(AITAC_GetCommChairLocation(CommanderTeam), DEPLOYABLE_ITEM_WELDER, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(15.0f), false);
bool bPlayerHasWelder = false; bool bPlayerHasWelder = false;
if (!NearestWelder) if (!NearestWelder.IsValid())
{ {
vector<AvHPlayer*> PlayersAtBase = AITAC_GetAllPlayersOfTeamInArea(CommanderTeam, AITAC_GetCommChairLocation(CommanderTeam), UTIL_MetresToGoldSrcUnits(15.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER); vector<AvHPlayer*> PlayersAtBase = AITAC_GetAllPlayersOfTeamInArea(CommanderTeam, AITAC_GetCommChairLocation(CommanderTeam), UTIL_MetresToGoldSrcUnits(15.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
@ -1471,7 +1471,7 @@ bool AICOMM_CheckForNextSupplyAction(AvHAIPlayer* pBot)
} }
} }
if (!NearestWelder && !bPlayerHasWelder) if (!NearestWelder.IsValid() && !bPlayerHasWelder)
{ {
DeployableSearchFilter ArmouryFilter; DeployableSearchFilter ArmouryFilter;
ArmouryFilter.DeployableTypes = (STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY); ArmouryFilter.DeployableTypes = (STRUCTURE_MARINE_ARMOURY | STRUCTURE_MARINE_ADVARMOURY);
@ -1659,11 +1659,11 @@ bool AICOMM_CheckForNextSupplyAction(AvHAIPlayer* pBot)
if (!NearestAdvArmoury.IsValid() || !NearestPrototypeLab.IsValid()) { return false; } if (!NearestAdvArmoury.IsValid() || !NearestPrototypeLab.IsValid()) { return false; }
AvHAIDroppedItem* ExistingHA = AITAC_FindClosestItemToLocation(NearestPrototypeLab.Location, DEPLOYABLE_ITEM_HEAVYARMOUR, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false); AvHAIDroppedItem ExistingHA = AITAC_FindClosestItemToLocation(NearestPrototypeLab.Location, DEPLOYABLE_ITEM_HEAVYARMOUR, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false);
AvHAIDroppedItem* ExistingHMG = AITAC_FindClosestItemToLocation(NearestAdvArmoury.Location, DEPLOYABLE_ITEM_HMG, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false); AvHAIDroppedItem ExistingHMG = AITAC_FindClosestItemToLocation(NearestAdvArmoury.Location, DEPLOYABLE_ITEM_HMG, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false);
AvHAIDroppedItem* ExistingWelder = AITAC_FindClosestItemToLocation(NearestAdvArmoury.Location, DEPLOYABLE_ITEM_WELDER, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false); AvHAIDroppedItem ExistingWelder = AITAC_FindClosestItemToLocation(NearestAdvArmoury.Location, DEPLOYABLE_ITEM_WELDER, CommanderTeam, AI_REACHABILITY_MARINE, 0.0f, UTIL_MetresToGoldSrcUnits(5.0f), false);
if (ExistingHA && ExistingHMG && ExistingWelder) { return false; } if (ExistingHA.IsValid() && ExistingHMG.IsValid() && ExistingWelder.IsValid()) { return false; }
vector<edict_t*> NearbyPlayers = AITAC_GetAllPlayersOfClassInArea(CommanderTeam, NearestAdvArmoury.Location, UTIL_MetresToGoldSrcUnits(10.0f), false, pBot->Edict, AVH_USER3_MARINE_PLAYER); vector<edict_t*> NearbyPlayers = AITAC_GetAllPlayersOfClassInArea(CommanderTeam, NearestAdvArmoury.Location, UTIL_MetresToGoldSrcUnits(10.0f), false, pBot->Edict, AVH_USER3_MARINE_PLAYER);
@ -1692,7 +1692,7 @@ bool AICOMM_CheckForNextSupplyAction(AvHAIPlayer* pBot)
} }
} }
if (!ExistingHA && !bDropWelder && !bDropWeapon) if (!ExistingHA.IsValid() && !bDropWelder && !bDropWeapon)
{ {
Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestPrototypeLab.Location, UTIL_MetresToGoldSrcUnits(3.0f)); Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestPrototypeLab.Location, UTIL_MetresToGoldSrcUnits(3.0f));
@ -1706,7 +1706,7 @@ bool AICOMM_CheckForNextSupplyAction(AvHAIPlayer* pBot)
return bSuccess; return bSuccess;
} }
if (bDropWeapon && !ExistingHMG) if (bDropWeapon && !ExistingHMG.IsValid())
{ {
Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestAdvArmoury.Location, UTIL_MetresToGoldSrcUnits(3.0f)); Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestAdvArmoury.Location, UTIL_MetresToGoldSrcUnits(3.0f));
@ -1720,7 +1720,7 @@ bool AICOMM_CheckForNextSupplyAction(AvHAIPlayer* pBot)
return bSuccess; return bSuccess;
} }
if (bDropWelder && !ExistingWelder) if (bDropWelder && !ExistingWelder.IsValid())
{ {
Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestAdvArmoury.Location, UTIL_MetresToGoldSrcUnits(3.0f)); Vector DeployLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), NearestAdvArmoury.Location, UTIL_MetresToGoldSrcUnits(3.0f));
@ -2402,6 +2402,8 @@ bool AICOMM_BuildInfantryPortal(AvHAIPlayer* pBot, edict_t* CommChair)
if (vIsZero(BuildLocation)) { return false; } if (vIsZero(BuildLocation)) { return false; }
UTIL_DrawLine(INDEXENT(1), BuildLocation, BuildLocation + Vector(0.0f, 0.0f, 100.0f), 2.0f);
return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE); return AICOMM_DeployStructure(pBot, STRUCTURE_MARINE_INFANTRYPORTAL, BuildLocation, STRUCTURE_PURPOSE_BASE);
} }

View file

@ -20,6 +20,8 @@ bot_skill BotSkillLevels[4];
std::vector<AvHMessageID> ChamberSequence; std::vector<AvHMessageID> ChamberSequence;
bool bRNGSeeded = false;
string DefaultBotNames[MAX_PLAYERS] = { "MrRobot", string DefaultBotNames[MAX_PLAYERS] = { "MrRobot",
"Wall-E", "Wall-E",
"BeepBoop", "BeepBoop",
@ -185,7 +187,6 @@ void CONFIG_PopulateBotNames()
if (BotNames.size() > 2) if (BotNames.size() > 2)
{ {
auto rng = std::default_random_engine{}; auto rng = std::default_random_engine{};
rng.seed(time(0));
std::shuffle(begin(BotNames), end(BotNames), rng); std::shuffle(begin(BotNames), end(BotNames), rng);
} }
@ -200,7 +201,6 @@ void CONFIG_PopulateBotNames()
if (DefaultNames.size() > 2) if (DefaultNames.size() > 2)
{ {
auto rng = std::default_random_engine{}; auto rng = std::default_random_engine{};
rng.seed(time(0));
std::shuffle(begin(DefaultNames), end(DefaultNames), rng); std::shuffle(begin(DefaultNames), end(DefaultNames), rng);
} }
@ -274,9 +274,15 @@ void CONFIG_ParseConfigFile()
ChamberSequence.push_back(ALIEN_BUILD_MOVEMENT_CHAMBER); ChamberSequence.push_back(ALIEN_BUILD_MOVEMENT_CHAMBER);
ChamberSequence.push_back(ALIEN_BUILD_SENSORY_CHAMBER); ChamberSequence.push_back(ALIEN_BUILD_SENSORY_CHAMBER);
std::srand(time(0));
auto rng = std::default_random_engine{}; auto rng = std::default_random_engine{};
rng.seed(time(0));
if (!bRNGSeeded)
{
srand(time(NULL));
rng.seed(time(NULL));
bRNGSeeded = true;
}
std::shuffle(std::begin(ChamberSequence), std::end(ChamberSequence), rng); std::shuffle(std::begin(ChamberSequence), std::end(ChamberSequence), rng);
string BotConfigFile = string(getModDirectory()) + "/nsbots.ini"; string BotConfigFile = string(getModDirectory()) + "/nsbots.ini";

View file

@ -372,6 +372,8 @@ typedef struct _DROPPED_MARINE_ITEM
unsigned int TeamBReachabilityFlags = AI_REACHABILITY_NONE; unsigned int TeamBReachabilityFlags = AI_REACHABILITY_NONE;
bool bReachabilityMarkedDirty = false; // Reachability needs to be recalculated bool bReachabilityMarkedDirty = false; // Reachability needs to be recalculated
int LastSeen = 0; // Which refresh cycle was this last seen on? Used to determine if the item has been removed from play int LastSeen = 0; // Which refresh cycle was this last seen on? Used to determine if the item has been removed from play
bool IsValid() { return !FNullEnt(edict) && !edict->free && !(edict->v.flags & EF_NODRAW) && edict->v.deadflag == DEAD_NO; }
} AvHAIDroppedItem; } AvHAIDroppedItem;
// How far a bot can be from a useable object when trying to interact with it. Used also for melee attacks. We make it slightly less than actual to avoid edge cases // How far a bot can be from a useable object when trying to interact with it. Used also for melee attacks. We make it slightly less than actual to avoid edge cases

View file

@ -403,7 +403,6 @@ Vector UTIL_RandomPointOnCircle(const Vector origin, const float radius)
{ {
Vector result; Vector result;
srand(time(NULL));
float random = ((float)rand()) / (float)RAND_MAX; float random = ((float)rand()) / (float)RAND_MAX;
float a = random * (MATH_PI * 2); float a = random * (MATH_PI * 2);
@ -643,7 +642,6 @@ float fInterpConstantTo(float start, float end, float DeltaTime, float InterpSpe
float frandrange(float MinValue, float MaxValue) float frandrange(float MinValue, float MaxValue)
{ {
srand(time(NULL));
return ((float(rand()) / float(RAND_MAX)) * (MaxValue - MinValue)) + MinValue; return ((float(rand()) / float(RAND_MAX)) * (MaxValue - MinValue)) + MinValue;
} }
@ -651,14 +649,11 @@ int irandrange(int MinValue, int MaxValue)
{ {
if (MinValue == MaxValue) { return MinValue; } if (MinValue == MaxValue) { return MinValue; }
srand(time(NULL));
return MinValue + rand() / (RAND_MAX / (MaxValue - MinValue + 1) + 1); return MinValue + rand() / (RAND_MAX / (MaxValue - MinValue + 1) + 1);
} }
bool randbool() bool randbool()
{ {
srand(time(NULL));
return (rand() & 1); return (rand() & 1);
} }
@ -666,8 +661,6 @@ Vector random_unit_vector_within_cone(const Vector Direction, double cone_half_a
{ {
Vector Result = ZERO_VECTOR; Vector Result = ZERO_VECTOR;
srand(time(NULL));
double u = ((double)rand() / RAND_MAX) * 2 - 1; // random number in [-1, 1] double u = ((double)rand() / RAND_MAX) * 2 - 1; // random number in [-1, 1]
double phi = ((double)rand() / RAND_MAX) * 2 * M_PI; // random number in [0, 2*pi] double phi = ((double)rand() / RAND_MAX) * 2 * M_PI; // random number in [0, 2*pi]
double r = sqrt(1 - u * u); double r = sqrt(1 - u * u);

View file

@ -6448,9 +6448,9 @@ void MarineUpdateBotMoveProfile(AvHAIPlayer* pBot, BotMoveStyle MoveStyle)
if (!bHasWelder) if (!bHasWelder)
{ {
AvHAIDroppedItem* NearbyWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearbyWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
bHasWelder = (NearbyWelder != nullptr); bHasWelder = (NearbyWelder.IsValid());
} }
// Did our nav profile previously indicate we could go through weldable doors? // Did our nav profile previously indicate we could go through weldable doors?
@ -6914,11 +6914,11 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
{ {
nav_profile BaseProfile = GetBaseNavProfile(MARINE_BASE_NAV_PROFILE); nav_profile BaseProfile = GetBaseNavProfile(MARINE_BASE_NAV_PROFILE);
AvHAIDroppedItem* NearestWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), BaseProfile.ReachabilityFlag, 0.0f, 0.0f, true); AvHAIDroppedItem NearestWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), BaseProfile.ReachabilityFlag, 0.0f, 0.0f, true);
if (NearestWelder) if (NearestWelder.IsValid())
{ {
NAV_SetPickupMovementTask(pBot, NearestWelder->edict, nullptr); NAV_SetPickupMovementTask(pBot, NearestWelder.edict, nullptr);
return true; return true;
} }
} }

View file

@ -1896,107 +1896,36 @@ void CustomThink(AvHAIPlayer* pBot)
AITASK_BotUpdateAndClearTasks(pBot); AITASK_BotUpdateAndClearTasks(pBot);
if (pBot->CurrentTask->TaskType == TASK_REINFORCE_STRUCTURE) if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_MINES))
{ {
BotProgressTask(pBot, pBot->CurrentTask); if (pBot->CurrentTask->TaskType != TASK_GET_WEAPON)
return;
}
// No missing upgrade chambers to drop, let's look for empty hives we can start staking a claim to, to deny to the enemy
vector<AvHAIHiveDefinition*> AllHives = AITAC_GetAllHives();
AvHAIHiveDefinition* HiveToSecure = nullptr;
AvHTeamNumber BotTeam = pBot->Player->GetTeam();
AvHTeamNumber EnemyTeam = AIMGR_GetEnemyTeam(BotTeam);
float MinDist = 0.0f;
for (auto it = AllHives.begin(); it != AllHives.end(); it++)
{
AvHAIHiveDefinition* ThisHive = (*it);
if (ThisHive->Status == HIVE_STATUS_UNBUILT)
{ {
unsigned int StructureTypes = (STRUCTURE_MARINE_PHASEGATE | STRUCTURE_MARINE_TURRETFACTORY | STRUCTURE_MARINE_ADVTURRETFACTORY); AvHAIDroppedItem Mines = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_MINES, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, false);
if (AIMGR_GetTeamType(EnemyTeam) == AVH_CLASS_TYPE_ALIEN) if (Mines.IsValid())
{ {
StructureTypes = STRUCTURE_ALIEN_OFFENCECHAMBER; AITASK_SetPickupTask(pBot, pBot->CurrentTask, Mines.edict, true);
} }
}
}
else
{
if (pBot->CurrentTask->TaskType != TASK_PLACE_MINE)
{
DeployableSearchFilter EnemyStructureFilter; DeployableSearchFilter TFFilter;
EnemyStructureFilter.DeployableTeam = EnemyTeam; TFFilter.DeployableTypes = STRUCTURE_MARINE_TURRETFACTORY;
EnemyStructureFilter.IncludeStatusFlags = STRUCTURE_STATUS_COMPLETED;
EnemyStructureFilter.ExcludeStatusFlags = STRUCTURE_STATUS_RECYCLING;
EnemyStructureFilter.DeployableTypes = StructureTypes;
EnemyStructureFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
bool bEnemyHaveFoothold = AITAC_DeployableExistsAtLocation(ThisHive->FloorLocation, &EnemyStructureFilter); AvHAIBuildableStructure NearestTF = AITAC_FindClosestDeployableToLocation(pBot->Edict->v.origin, &TFFilter);
if (bEnemyHaveFoothold) { continue; } if (NearestTF.IsValid())
if (AITAC_GetNumPlayersOfTeamInArea(EnemyTeam, ThisHive->FloorLocation, UTIL_MetresToGoldSrcUnits(10.0f), false, nullptr, AVH_USER3_COMMANDER_PLAYER) > 1) { continue; }
int OtherBuilders = AITAC_GetNumPlayersOfTeamAndClassInArea(EnemyTeam, ThisHive->FloorLocation, UTIL_MetresToGoldSrcUnits(10.0f), false, nullptr, AVH_USER3_ALIEN_PLAYER2);
if (OtherBuilders >= 2) { continue; }
DeployableSearchFilter ExistingReinforcementFilter;
ExistingReinforcementFilter.DeployableTeam = BotTeam;
ExistingReinforcementFilter.MaxSearchRadius = UTIL_MetresToGoldSrcUnits(10.0f);
ExistingReinforcementFilter.DeployableTypes = SEARCH_ALL_STRUCTURES;
vector<AvHAIBuildableStructure> AllReinforcingStructures = AITAC_FindAllDeployables(ThisHive->FloorLocation, &ExistingReinforcementFilter);
int NumOCs = 0;
int NumDCs = 0;
int NumMCs = 0;
int NumSCs = 0;
for (auto it = AllReinforcingStructures.begin(); it != AllReinforcingStructures.end(); it++)
{ {
switch ((*it).StructureType) AITASK_SetMineStructureTask(pBot, pBot->CurrentTask, NearestTF.edict, true);
{
case STRUCTURE_ALIEN_OFFENCECHAMBER:
NumOCs++;
break;
case STRUCTURE_ALIEN_DEFENCECHAMBER:
NumDCs++;
break;
case STRUCTURE_ALIEN_MOVEMENTCHAMBER:
NumMCs++;
break;
case STRUCTURE_ALIEN_SENSORYCHAMBER:
NumSCs++;
break;
default:
break;
}
} }
if (NumOCs < 3
|| (AITAC_TeamHiveWithTechExists(BotTeam, ALIEN_BUILD_DEFENSE_CHAMBER) && NumDCs < 2)
|| (AITAC_TeamHiveWithTechExists(BotTeam, ALIEN_BUILD_MOVEMENT_CHAMBER) && NumMCs < 1)
|| (AITAC_TeamHiveWithTechExists(BotTeam, ALIEN_BUILD_SENSORY_CHAMBER) && NumSCs < 1))
{
float ThisDist = vDist2DSq(pBot->Edict->v.origin, ThisHive->FloorLocation);
if (!HiveToSecure || ThisDist < MinDist)
{
HiveToSecure = ThisHive;
MinDist = ThisDist;
}
}
} }
} }
if (HiveToSecure) BotProgressTask(pBot, pBot->CurrentTask);
{
AITASK_SetReinforceStructureTask(pBot, &pBot->PrimaryBotTask, HiveToSecure->HiveEdict, false);
return;
}
} }
void DroneThink(AvHAIPlayer* pBot) void DroneThink(AvHAIPlayer* pBot)
@ -3273,8 +3202,8 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
edict_t* CurrentEnemy = pBot->TrackedEnemies[pBot->CurrentEnemy].PlayerEdict; edict_t* CurrentEnemy = pBot->TrackedEnemies[pBot->CurrentEnemy].PlayerEdict;
enemy_status* TrackedEnemyRef = &pBot->TrackedEnemies[pBot->CurrentEnemy]; enemy_status* TrackedEnemyRef = &pBot->TrackedEnemies[pBot->CurrentEnemy];
AvHAIDroppedItem* NearestHealthPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HEALTHPACK, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearestHealthPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HEALTHPACK, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
AvHAIDroppedItem* NearestAmmoPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_AMMO, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearestAmmoPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_AMMO, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
AvHAIWeapon DesiredCombatWeapon = BotMarineChooseBestWeapon(pBot, CurrentEnemy); AvHAIWeapon DesiredCombatWeapon = BotMarineChooseBestWeapon(pBot, CurrentEnemy);
@ -3294,17 +3223,17 @@ bool RegularMarineCombatThink(AvHAIPlayer* pBot)
{ {
pBot->DesiredCombatWeapon = DesiredCombatWeapon; pBot->DesiredCombatWeapon = DesiredCombatWeapon;
if (NearestHealthPack && (pBot->Edict->v.health < pBot->Edict->v.max_health * 0.7f)) if (NearestHealthPack.IsValid() && (pBot->Edict->v.health < pBot->Edict->v.max_health * 0.7f))
{ {
MoveTo(pBot, NearestHealthPack->Location, MOVESTYLE_NORMAL); MoveTo(pBot, NearestHealthPack.Location, MOVESTYLE_NORMAL);
} }
else if (NearestAmmoPack && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) < UTIL_GetPlayerPrimaryMaxAmmoReserve(pBot->Player)) else if (NearestAmmoPack.IsValid() && UTIL_GetPlayerPrimaryAmmoReserve(pBot->Player) < UTIL_GetPlayerPrimaryMaxAmmoReserve(pBot->Player))
{ {
if (vDist2DSq(pBot->Edict->v.origin, NearestAmmoPack->Location) < sqrf(150.0f)) if (vDist2DSq(pBot->Edict->v.origin, NearestAmmoPack.Location) < sqrf(150.0f))
{ {
pBot->DesiredCombatWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player); pBot->DesiredCombatWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
} }
MoveTo(pBot, NearestAmmoPack->Location, MOVESTYLE_NORMAL); MoveTo(pBot, NearestAmmoPack.Location, MOVESTYLE_NORMAL);
} }
else else
{ {
@ -4119,18 +4048,18 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
float SearchRadius = (bTaskIsUrgent) ? UTIL_MetresToGoldSrcUnits(5.0f) : UTIL_MetresToGoldSrcUnits(10.0f); float SearchRadius = (bTaskIsUrgent) ? UTIL_MetresToGoldSrcUnits(5.0f) : UTIL_MetresToGoldSrcUnits(10.0f);
AvHAIDroppedItem* NearestHealthPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HEALTHPACK, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, SearchRadius, false); AvHAIDroppedItem NearestHealthPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HEALTHPACK, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, SearchRadius, false);
AvHAIDroppedItem* NearestAmmoPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_AMMO, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, SearchRadius, false); AvHAIDroppedItem NearestAmmoPack = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_AMMO, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, SearchRadius, false);
if (bNeedsHealth && NearestHealthPack) if (bNeedsHealth && NearestHealthPack.IsValid())
{ {
AITASK_SetPickupTask(pBot, Task, NearestHealthPack->edict, bTaskIsUrgent); AITASK_SetPickupTask(pBot, Task, NearestHealthPack.edict, bTaskIsUrgent);
return; return;
} }
if (bNeedsAmmo && NearestAmmoPack) if (bNeedsAmmo && NearestAmmoPack.IsValid())
{ {
AITASK_SetPickupTask(pBot, Task, NearestAmmoPack->edict, bTaskIsUrgent); AITASK_SetPickupTask(pBot, Task, NearestAmmoPack.edict, bTaskIsUrgent);
return; return;
} }
@ -4176,11 +4105,11 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!PlayerHasEquipment(pBot->Edict)) if (!PlayerHasEquipment(pBot->Edict))
{ {
AvHAIDroppedItem* NearbyHA = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HEAVYARMOUR, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearbyHA = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HEAVYARMOUR, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
if (NearbyHA) if (NearbyHA.IsValid())
{ {
vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyHA->Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER); vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyHA.Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
bool bHumanNearby = false; bool bHumanNearby = false;
bool bHumanWaitingRespawn = false; bool bHumanWaitingRespawn = false;
@ -4198,7 +4127,7 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!bHumanNearby) if (!bHumanNearby)
{ {
AITASK_SetPickupTask(pBot, Task, NearbyHA->edict, vDist2DSq(pBot->Edict->v.origin, NearbyHA->Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f))); AITASK_SetPickupTask(pBot, Task, NearbyHA.edict, vDist2DSq(pBot->Edict->v.origin, NearbyHA.Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)));
return; return;
} }
} }
@ -4208,14 +4137,14 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
{ {
if (!PlayerHasSpecialWeapon(pBot->Player)) if (!PlayerHasSpecialWeapon(pBot->Player))
{ {
AvHAIDroppedItem* NearbyHMG = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HMG, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearbyHMG = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_HMG, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
AvHAIDroppedItem* NearbyGL = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_GRENADELAUNCHER, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearbyGL = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_GRENADELAUNCHER, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
AvHAIDroppedItem* NearbyWeapon = (NearbyHMG != nullptr) ? NearbyHMG : NearbyGL; AvHAIDroppedItem NearbyWeapon = (NearbyHMG.IsValid()) ? NearbyHMG : NearbyGL;
if (NearbyWeapon) if (NearbyWeapon.IsValid())
{ {
vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon->Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER); vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon.Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
bool bHumanNearby = false; bool bHumanNearby = false;
for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++) for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++)
@ -4232,7 +4161,7 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!bHumanNearby) if (!bHumanNearby)
{ {
AITASK_SetPickupTask(pBot, Task, NearbyWeapon->edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon->Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f))); AITASK_SetPickupTask(pBot, Task, NearbyWeapon.edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon.Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)));
return; return;
} }
} }
@ -4241,11 +4170,11 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_WELDER)) if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_WELDER))
{ {
AvHAIDroppedItem* NearbyWeapon = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearbyWeapon = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
if (NearbyWeapon) if (NearbyWeapon.IsValid())
{ {
vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon->Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER); vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon.Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
bool bHumanNearby = false; bool bHumanNearby = false;
for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++) for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++)
@ -4262,7 +4191,7 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!bHumanNearby) if (!bHumanNearby)
{ {
AITASK_SetPickupTask(pBot, Task, NearbyWeapon->edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon->Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f))); AITASK_SetPickupTask(pBot, Task, NearbyWeapon.edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon.Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)));
return; return;
} }
} }
@ -4270,11 +4199,11 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!PlayerHasSpecialWeapon(pBot->Player)) if (!PlayerHasSpecialWeapon(pBot->Player))
{ {
AvHAIDroppedItem* NearbyWeapon = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_SHOTGUN, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearbyWeapon = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_SHOTGUN, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
if (NearbyWeapon) if (NearbyWeapon.IsValid())
{ {
vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon->Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER); vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon.Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
bool bHumanNearby = false; bool bHumanNearby = false;
for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++) for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++)
@ -4291,7 +4220,7 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!bHumanNearby) if (!bHumanNearby)
{ {
AITASK_SetPickupTask(pBot, Task, NearbyWeapon->edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon->Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f))); AITASK_SetPickupTask(pBot, Task, NearbyWeapon.edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon.Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)));
return; return;
} }
} }
@ -4299,11 +4228,11 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_MINES)) if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_MINES))
{ {
AvHAIDroppedItem* NearbyWeapon = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_MINES, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true); AvHAIDroppedItem NearbyWeapon = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_MINES, BotTeam, pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, UTIL_MetresToGoldSrcUnits(10.0f), true);
if (NearbyWeapon) if (NearbyWeapon.IsValid())
{ {
vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon->Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER); vector<AvHPlayer*> NearbyPlayers = AITAC_GetAllPlayersOfTeamInArea(BotTeam, NearbyWeapon.Location, UTIL_MetresToGoldSrcUnits(5.0f), false, pBot->Edict, AVH_USER3_COMMANDER_PLAYER);
bool bHumanNearby = false; bool bHumanNearby = false;
for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++) for (auto it = NearbyPlayers.begin(); it != NearbyPlayers.end(); it++)
@ -4320,7 +4249,7 @@ void AIPlayerSetWantsAndNeedsMarineTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task
if (!bHumanNearby) if (!bHumanNearby)
{ {
AITASK_SetPickupTask(pBot, Task, NearbyWeapon->edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon->Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f))); AITASK_SetPickupTask(pBot, Task, NearbyWeapon.edict, vDist2DSq(pBot->Edict->v.origin, NearbyWeapon.Location) < sqrf(UTIL_MetresToGoldSrcUnits(5.0f)));
return; return;
} }
} }

View file

@ -630,20 +630,24 @@ AvHAIBuildableStructure* AITAC_FindFurthestDeployableFromLocationByRef(const Vec
return Result; return Result;
} }
AvHAIDroppedItem* AITAC_GetDroppedItemRefFromEdict(edict_t* ItemEdict) AvHAIDroppedItem AITAC_GetDroppedItemRefFromEdict(edict_t* ItemEdict)
{ {
if (FNullEnt(ItemEdict)) { return nullptr; } AvHAIDroppedItem Result;
if (FNullEnt(ItemEdict)) { return Result; }
int EntIndex = ENTINDEX(ItemEdict); int EntIndex = ENTINDEX(ItemEdict);
if (EntIndex < 0) { return nullptr; } if (EntIndex < 0) { return Result; }
return &MarineDroppedItemMap[EntIndex]; Result = MarineDroppedItemMap[EntIndex];
return Result;
} }
AvHAIDroppedItem* AITAC_FindClosestItemToLocation(const Vector& Location, const AvHAIDeployableItemType ItemType, AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags, float MinRadius, float MaxRadius, bool bConsiderPhaseDistance) AvHAIDroppedItem AITAC_FindClosestItemToLocation(const Vector& Location, const AvHAIDeployableItemType ItemType, AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags, float MinRadius, float MaxRadius, bool bConsiderPhaseDistance)
{ {
AvHAIDroppedItem* Result = NULL; AvHAIDroppedItem Result;
float CurrMinDist = 0.0f; float CurrMinDist = 0.0f;
float MinDistSq = sqrf(MinRadius); float MinDistSq = sqrf(MinRadius);
@ -669,9 +673,9 @@ AvHAIDroppedItem* AITAC_FindClosestItemToLocation(const Vector& Location, const
float DistSq = (bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location); float DistSq = (bConsiderPhaseDistance) ? sqrf(AITAC_GetPhaseDistanceBetweenPoints(it.second.Location, Location)) : vDist2DSq(it.second.Location, Location);
if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && (!Result || DistSq < CurrMinDist)) if ((!bUseMinDist || DistSq >= MinDistSq) && (!bUseMaxDist || DistSq <= MaxDistSq) && (!Result.IsValid() || DistSq < CurrMinDist))
{ {
Result = &it.second; Result = it.second;
CurrMinDist = DistSq; CurrMinDist = DistSq;
} }

View file

@ -67,11 +67,11 @@ Vector AITAC_GetTeamRelocationPoint(AvHTeamNumber Team);
AvHAIResourceNode* AITAC_GetRandomResourceNode(AvHTeamNumber SearchingTeam, const unsigned int ReachabilityFlags); 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); 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); 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); 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); AvHAIDroppedItem AITAC_GetDroppedItemRefFromEdict(edict_t* ItemEdict);
Vector AITAC_GetRandomBuildHintInLocation(const unsigned int StructureType, const Vector SearchLocation, const float SearchRadius); Vector AITAC_GetRandomBuildHintInLocation(const unsigned int StructureType, const Vector SearchLocation, const float SearchRadius);

View file

@ -441,11 +441,11 @@ bool AITASK_IsWeldTaskStillValid(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
{ {
if (FNullEnt(Task->TaskSecondaryTarget)) if (FNullEnt(Task->TaskSecondaryTarget))
{ {
AvHAIDroppedItem* NearestWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, true); AvHAIDroppedItem NearestWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, true);
if (NearestWelder) if (NearestWelder.IsValid())
{ {
Task->TaskSecondaryTarget = NearestWelder->edict; Task->TaskSecondaryTarget = NearestWelder.edict;
} }
else else
{ {
@ -2651,11 +2651,11 @@ void BotProgressWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
} }
else else
{ {
AvHAIDroppedItem* Welder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, true); AvHAIDroppedItem Welder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, true);
if (Welder) if (Welder.IsValid())
{ {
Task->TaskSecondaryTarget = Welder->edict; Task->TaskSecondaryTarget = Welder.edict;
} }
} }
@ -3537,9 +3537,9 @@ void AITASK_SetPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Tar
return; return;
} }
AvHAIDroppedItem* ItemToPickup = AITAC_GetDroppedItemRefFromEdict(Target); AvHAIDroppedItem ItemToPickup = AITAC_GetDroppedItemRefFromEdict(Target);
if (!ItemToPickup) if (!ItemToPickup.IsValid())
{ {
AITASK_ClearBotTask(pBot, Task); AITASK_ClearBotTask(pBot, Task);
return; return;
@ -3553,7 +3553,7 @@ void AITASK_SetPickupTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Tar
return; return;
} }
switch (ItemToPickup->ItemType) switch (ItemToPickup.ItemType)
{ {
case DEPLOYABLE_ITEM_AMMO: case DEPLOYABLE_ITEM_AMMO:
Task->TaskType = TASK_GET_AMMO; Task->TaskType = TASK_GET_AMMO;
@ -3633,16 +3633,16 @@ void AITASK_SetWeldTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task, edict_t* Targe
if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_WELDER)) if (!PlayerHasWeapon(pBot->Player, WEAPON_MARINE_WELDER))
{ {
AvHAIDroppedItem* NearestWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, true); AvHAIDroppedItem NearestWelder = AITAC_FindClosestItemToLocation(pBot->Edict->v.origin, DEPLOYABLE_ITEM_WELDER, pBot->Player->GetTeam(), pBot->BotNavInfo.NavProfile.ReachabilityFlag, 0.0f, 0.0f, true);
if (!NearestWelder) if (!NearestWelder.IsValid())
{ {
AITASK_ClearBotTask(pBot, Task); AITASK_ClearBotTask(pBot, Task);
return; return;
} }
else else
{ {
Task->TaskSecondaryTarget = NearestWelder->edict; Task->TaskSecondaryTarget = NearestWelder.edict;
} }
} }