nav: improved ladder handling

fix: bots can stuck when destroying breakables
This commit is contained in:
jeefo 2024-03-29 16:46:32 +03:00
commit c5ed52eb09
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
5 changed files with 27 additions and 17 deletions

View file

@ -156,9 +156,16 @@ void Bot::avoidGrenades () {
} }
void Bot::checkBreakable (edict_t *touch) { void Bot::checkBreakable (edict_t *touch) {
m_breakableEntity = touch != nullptr ? touch : lookupBreakable (); if (game.isNullEntity (touch)) {
m_breakableEntity = lookupBreakable ();
}
else {
m_breakableEntity = touch;
m_breakableOrigin = game.getEntityOrigin (touch);
}
if (game.isNullEntity (m_breakableEntity)) { // re-check from previous steps
if (game.isNullEntity (m_breakableEntity) || m_breakableOrigin.empty ()) {
return; return;
} }
m_campButtons = pev->button & IN_DUCK; m_campButtons = pev->button & IN_DUCK;
@ -3182,11 +3189,11 @@ void Bot::logic () {
// are we allowed to check blocking terrain (and react to it)? // are we allowed to check blocking terrain (and react to it)?
if (m_checkTerrain) { if (m_checkTerrain) {
doPlayerAvoidance (dirNormal);
checkTerrain (movedDistance, dirNormal);
// check for breakables around bots movement direction // check for breakables around bots movement direction
checkBreakable (nullptr); checkBreakable (nullptr);
doPlayerAvoidance (dirNormal);
checkTerrain (movedDistance, dirNormal);
} }
// check the darkness // check the darkness

View file

@ -1113,7 +1113,7 @@ bool Bot::updateNavigation () {
} }
} }
float desiredDistanceSq = cr::sqrf (8.0f); float desiredDistanceSq = cr::sqrf (4.0f);
const float nodeDistanceSq = pev->origin.distanceSq (m_pathOrigin); const float nodeDistanceSq = pev->origin.distanceSq (m_pathOrigin);
// initialize the radius for a special node type, where the node is considered to be reached // initialize the radius for a special node type, where the node is considered to be reached
@ -1128,8 +1128,8 @@ bool Bot::updateNavigation () {
desiredDistanceSq = cr::sqrf (128.0f); desiredDistanceSq = cr::sqrf (128.0f);
} }
} }
else if (isOnLadder () || (m_pathFlags & NodeFlag::Ladder)) { else if (m_pathFlags & NodeFlag::Ladder) {
desiredDistanceSq = cr::sqrf (14.0f); desiredDistanceSq = cr::sqrf (8.0f);
} }
else if (m_currentTravelFlags & PathFlag::Jump) { else if (m_currentTravelFlags & PathFlag::Jump) {
desiredDistanceSq = 0.0f; desiredDistanceSq = 0.0f;
@ -1709,7 +1709,12 @@ bool Bot::findNextBestNode () {
} }
float Bot::getEstimatedNodeReachTime () { float Bot::getEstimatedNodeReachTime () {
float estimatedTime = 3.5f; const bool longTermReachability = (m_pathFlags & NodeFlag::Crouch)
|| (m_pathFlags & NodeFlag::Ladder)
|| (pev->button & IN_DUCK)
|| (m_oldButtons & IN_DUCK);
float estimatedTime = longTermReachability ? 8.5f : 3.5f;
// if just fired at enemy, increase reachability // if just fired at enemy, increase reachability
if (m_shootTime + 0.15f < game.time ()) { if (m_shootTime + 0.15f < game.time ()) {
@ -1720,14 +1725,9 @@ float Bot::getEstimatedNodeReachTime () {
if (graph.exists (m_currentNodeIndex) && graph.exists (m_previousNodes[0])) { if (graph.exists (m_currentNodeIndex) && graph.exists (m_previousNodes[0])) {
const float distanceSq = graph[m_previousNodes[0]].origin.distanceSq (graph[m_currentNodeIndex].origin); const float distanceSq = graph[m_previousNodes[0]].origin.distanceSq (graph[m_currentNodeIndex].origin);
// caclulate estimated time // calculate estimated time
estimatedTime = 5.0f * (distanceSq / cr::sqrf (m_moveSpeed + 1.0f)); estimatedTime = 5.0f * (distanceSq / cr::sqrf (m_moveSpeed + 1.0f));
const bool longTermReachability = (m_pathFlags & NodeFlag::Crouch)
|| (m_pathFlags & NodeFlag::Ladder)
|| (pev->button & IN_DUCK)
|| (m_oldButtons & IN_DUCK);
// check for special nodes, that can slowdown our movement // check for special nodes, that can slowdown our movement
if (longTermReachability) { if (longTermReachability) {
estimatedTime *= 2.0f; estimatedTime *= 2.0f;

View file

@ -230,7 +230,7 @@ bool BotSupport::isHostageEntity (edict_t *ent) {
} }
bool BotSupport::isShootableBreakable (edict_t *ent) { bool BotSupport::isShootableBreakable (edict_t *ent) {
if (game.isNullEntity (ent)) { if (game.isNullEntity (ent) || ent == game.getStartEntity ()) {
return false; return false;
} }
const auto limit = cv_breakable_health_limit.float_ (); const auto limit = cv_breakable_health_limit.float_ ();

View file

@ -1459,6 +1459,9 @@ void Bot::shootBreakable_ () {
m_checkTerrain = true; m_checkTerrain = true;
m_moveToGoal = true; m_moveToGoal = true;
m_breakableOrigin = nullptr;
m_breakableEntity = nullptr;
completeTask (); completeTask ();
} }
} }

View file

@ -226,7 +226,7 @@ void Bot::setAimDirection () {
if (onLadder && m_pathWalk.hasNext ()) { if (onLadder && m_pathWalk.hasNext ()) {
const auto &nextPath = graph[m_pathWalk.next ()]; const auto &nextPath = graph[m_pathWalk.next ()];
if ((nextPath.flags & NodeFlag::Ladder) && m_destOrigin.distanceSq (pev->origin) < cr::sqrf (128.0f) && nextPath.origin.z > m_pathOrigin.z + 30.0f) { if ((nextPath.flags & NodeFlag::Ladder) && m_destOrigin.distanceSq (pev->origin) < cr::sqrf (64.0f) && nextPath.origin.z > m_pathOrigin.z + 30.0f) {
m_lookAt = nextPath.origin; m_lookAt = nextPath.origin;
} }
} }