Fixed bug with lift detection

* Bots no longer get perma-stuck when standing on the drill in Ragnarok (or similar situations in other maps)
* Fixed fades getting glued to the ceiling when trying to blink into a vent
* Fixed bots getting stuck on top of railings sometimes
* Fixed bots sometimes deciding to evolve in the ready room on certain maps
* Updated nav mesh for eclipse
This commit is contained in:
RGreenlees 2024-04-19 15:25:24 +01:00
parent 33b5fcbe82
commit f24261e416
6 changed files with 85 additions and 21 deletions

Binary file not shown.

View file

@ -2059,7 +2059,7 @@ dtStatus FindPathClosestToPoint(AvHAIPlayer* pBot, const BotMoveStyle MoveStyle,
Vector FromFloorLocation = AdjustPointForPathfinding(FromLocation);
nav_door* LiftReference = UTIL_GetNavDoorByEdict(pBot->Edict->v.groundentity);
nav_door* LiftReference = UTIL_GetLiftReferenceByEdict(pBot->Edict->v.groundentity);
bool bMustDisembarkLiftFirst = false;
Vector LiftStart = ZERO_VECTOR;
Vector LiftEnd = ZERO_VECTOR;
@ -3718,6 +3718,10 @@ void BlockedMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoi
if (FaceDot < 0.95f)
{
float MoveSpeed = vSize2D(pBot->Edict->v.velocity);
if (MoveSpeed < 20.0f)
{
MoveSpeed = 100.0f;
}
Vector NewVelocity = vForward * MoveSpeed;
NewVelocity.z = pBot->Edict->v.velocity.z;
@ -3756,6 +3760,10 @@ void JumpMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector EndPoint)
if (FaceDot < 0.95f)
{
float MoveSpeed = vSize2D(pBot->Edict->v.velocity);
if (MoveSpeed < 20.0f)
{
MoveSpeed = 100.0f;
}
Vector NewVelocity = vForward * MoveSpeed;
NewVelocity.z = pBot->Edict->v.velocity.z;
@ -4739,7 +4747,7 @@ void BlinkClimbMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector End
if (GetPlayerCurrentWeapon(pBot->Player) != WEAPON_FADE_BLINK) { return; }
// Only blink if we're below the target climb height
if (pEdict->v.origin.z < RequiredClimbHeight + 32.0f)
if (pEdict->v.origin.z < RequiredClimbHeight + 4.0f)
{
float HeightToClimb = (fabsf(pEdict->v.origin.z - RequiredClimbHeight));
@ -4756,6 +4764,12 @@ void BlinkClimbMove(AvHAIPlayer* pBot, const Vector StartPoint, const Vector End
if (FaceDot < 0.95f)
{
float MoveSpeed = vSize2D(pBot->Edict->v.velocity);
if (MoveSpeed < 20.0f)
{
MoveSpeed = 100.0f;
}
Vector NewVelocity = MoveDir * MoveSpeed;
NewVelocity.z = pBot->Edict->v.velocity.z;
@ -6375,6 +6389,7 @@ bool MoveTo(AvHAIPlayer* pBot, const Vector Destination, const BotMoveStyle Move
{
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = false;
ClearBotMovement(pBot);
return true;
}
@ -6821,6 +6836,7 @@ void BotFollowSwimPath(AvHAIPlayer* pBot)
if (pBot->BotNavInfo.CurrentPath.size() == 0 || pBot->BotNavInfo.CurrentPathPoint >= pBot->BotNavInfo.CurrentPath.size())
{
ClearBotPath(pBot);
NAV_ClearMovementTask(pBot);
return;
}
@ -6974,6 +6990,7 @@ void BotFollowPath(AvHAIPlayer* pBot)
MoveToWithoutNav(pBot, CurrentNode.Location);
pBot->BotNavInfo.StuckInfo.bPathFollowFailed = true;
ClearBotPath(pBot);
NAV_ClearMovementTask(pBot);
return;
}
@ -7418,6 +7435,7 @@ void ClearBotStuck(AvHAIPlayer* pBot)
bool BotRecalcPath(AvHAIPlayer* pBot, const Vector Destination)
{
ClearBotPath(pBot);
NAV_ClearMovementTask(pBot);
Vector ValidNavmeshPoint = UTIL_ProjectPointToNavmesh(Destination, Vector(max_ai_use_reach, max_ai_use_reach, max_ai_use_reach), pBot->BotNavInfo.NavProfile);
@ -8782,6 +8800,18 @@ void UTIL_PopulateDoors()
NavDoors.push_back(NewDoor);
}
for (auto it = BaseMapConnections.begin(); it != BaseMapConnections.end(); it++)
{
if (!(it->ConnectionFlags & SAMPLE_POLYFLAGS_LIFT)) { continue; }
nav_door* CorrespondingLift = UTIL_GetClosestLiftToPoints(it->FromLocation, it->ToLocation);
if (CorrespondingLift)
{
it->TargetObject = CorrespondingLift->DoorEdict;
}
}
UTIL_UpdateDoors(true);
}
@ -8800,6 +8830,28 @@ nav_door* UTIL_GetNavDoorByEdict(const edict_t* DoorEdict)
return nullptr;
}
nav_door* UTIL_GetLiftReferenceByEdict(const edict_t* DoorEdict)
{
if (FNullEnt(DoorEdict)) { return nullptr; }
for (auto it = NavDoors.begin(); it != NavDoors.end(); it++)
{
if (it->DoorEdict == DoorEdict)
{
if (UTIL_GetOffMeshConnectionForLift(&(*it)) != nullptr)
{
return &(*it);
}
else
{
return nullptr;
}
}
}
return nullptr;
}
AvHAIOffMeshConnection* UTIL_GetOffMeshConnectionForLift(nav_door* LiftRef)
{
if (!LiftRef) { return nullptr; }
@ -8811,15 +8863,20 @@ AvHAIOffMeshConnection* UTIL_GetOffMeshConnectionForLift(nav_door* LiftRef)
{
if (!(it->ConnectionFlags & SAMPLE_POLYFLAGS_LIFT)) { continue; }
Vector LiftLocation = UTIL_GetCentreOfEntity(LiftRef->DoorEdict);
float ThisDist = fminf(vDist3DSq(it->FromLocation, LiftLocation), vDist3DSq(it->ToLocation, LiftLocation));
if (!NearestConnection || ThisDist < MinDist)
if (it->TargetObject == LiftRef->DoorEdict)
{
NearestConnection = &(*it);
MinDist = ThisDist;
return &(*it);
}
//Vector LiftLocation = UTIL_GetCentreOfEntity(LiftRef->DoorEdict);
//float ThisDist = fminf(vDist3DSq(it->FromLocation, LiftLocation), vDist3DSq(it->ToLocation, LiftLocation));
//if (!NearestConnection || ThisDist < MinDist)
//{
// NearestConnection = &(*it);
// MinDist = ThisDist;
//}
}
return NearestConnection;

View file

@ -482,6 +482,7 @@ void UTIL_PopulateWeldableObstacles();
void UTIL_ApplyTempObstaclesToDoor(nav_door* DoorRef, const int Area);
nav_door* UTIL_GetLiftReferenceByEdict(const edict_t* DoorEdict);
nav_door* UTIL_GetNavDoorByEdict(const edict_t* DoorEdict);
nav_door* UTIL_GetClosestLiftToPoints(const Vector StartPoint, const Vector EndPoint);
AvHAIOffMeshConnection* UTIL_GetOffMeshConnectionForLift(nav_door* LiftRef);

View file

@ -1385,10 +1385,6 @@ void BotUpdateView(AvHAIPlayer* pBot)
TrackingInfo->CertaintyOfLocation -= (ViewUpdateDelta * 0.15f);
TrackingInfo->CertaintyOfLocation = clampf(TrackingInfo->CertaintyOfLocation, 0.0f, 1.0f);
char msg[32];
sprintf(msg, "%.2f\n", TrackingInfo->CertaintyOfLocation);
UTIL_SayText(msg, CBaseEntity::Instance(INDEXENT(1)));
if (gpGlobals->time < TrackingInfo->NextUpdateTime)
{
continue;
@ -1915,6 +1911,12 @@ void CustomThink(AvHAIPlayer* pBot)
if (pBot->CurrentEnemy >= 0)
{
enemy_status* TrackingInfo = &pBot->TrackedEnemies[pBot->CurrentEnemy];
char msg[32];
sprintf(msg, "%.2f\n", TrackingInfo->CertaintyOfLocation);
UTIL_SayText(msg, CBaseEntity::Instance(INDEXENT(1)));
if (IsPlayerMarine(pBot->Edict))
{
MarineCombatThink(pBot);
@ -2616,7 +2618,7 @@ AvHAICombatStrategy GetFadeCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_stat
{
if (DistToEnemy > sqrf(UTIL_MetresToGoldSrcUnits(5.0f)))
{
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 2)
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 1)
{
return COMBAT_STRATEGY_SKIRMISH;
}
@ -2624,7 +2626,7 @@ AvHAICombatStrategy GetFadeCombatStrategyForTarget(AvHAIPlayer* pBot, enemy_stat
}
else
{
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 2)
if ((bEnemyHasDeadlyWeapon && (FacingDot > 0.5f || NumAllies > 0)) || NumAllies > 1)
{
Vector EnemyVelocity = UTIL_GetVectorNormal2D(CurrentEnemy->LastSeenVelocity);

View file

@ -1931,7 +1931,7 @@ void BotProgressEvolveTask(AvHAIPlayer* pBot, AvHAIPlayerTask* Task)
{
if ((gpGlobals->time - Task->TaskStartedTime) > 1.0f)
{
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadiusIgnoreReachability(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
Task->TaskLocation = UTIL_GetRandomPointOnNavmeshInRadius(GetBaseNavProfile(STRUCTURE_BASE_NAV_PROFILE), pBot->Edict->v.origin, UTIL_MetresToGoldSrcUnits(5.0f));
if (vIsZero(Task->TaskLocation))
{

View file

@ -562,15 +562,12 @@ AvHAIWeapon BotMarineChooseBestWeapon(AvHAIPlayer* pBot, edict_t* target)
{
return GetBotMarineSecondaryWeapon(pBot);
}
else
{
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
}
return UTIL_GetPlayerPrimaryWeapon(pBot->Player);
}
if (IsEdictPlayer(target))
{
return BotMarineChooseBestWeaponForStructure(pBot, target);
return MarineGetBestWeaponForPlayerTarget(pBot, dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(target)));
}
else
{
@ -671,6 +668,7 @@ AvHAIWeapon MarineGetBestWeaponForPlayerTarget(AvHAIPlayer* pBot, AvHPlayer* Tar
{
AvHAIWeapon PrimaryWeapon = UTIL_GetPlayerPrimaryWeapon(pBot->Player);
AvHAIWeapon SecondaryWeapon = UTIL_GetPlayerSecondaryWeapon(pBot->Player);
AvHAIWeapon CurrentWeapon = GetPlayerCurrentWeapon(pBot->Player);
float DistToEnemy = vDist2DSq(pBot->Edict->v.origin, Target->pev->origin);
@ -700,6 +698,12 @@ AvHAIWeapon MarineGetBestWeaponForPlayerTarget(AvHAIPlayer* pBot, AvHPlayer* Tar
else if (PrimaryWeapon == WEAPON_MARINE_SHOTGUN)
{
float MaxDist = (IsPlayerMarine(Target) || Target->GetUser3() > AVH_USER3_ALIEN_PLAYER3) ? UTIL_MetresToGoldSrcUnits(15.0f) : UTIL_MetresToGoldSrcUnits(8.0f);
// Give a little extra leeway if the bot is currently holding a shotgun. Helps prevent rapid switching if the enemy is right on the edge of the max distance
if (CurrentWeapon == PrimaryWeapon)
{
MaxDist *= 1.25f;
}
if (DistToEnemy < sqrf(MaxDist) || !bHasAmmoForSecondary)
{