From ce01e28be3e31b02b8ad3eeb9638cbe9b6f39c51 Mon Sep 17 00:00:00 2001 From: dmitry Date: Tue, 22 Feb 2022 13:51:59 +0300 Subject: [PATCH] fix: prevent bots from staying forever trying to destroy breakable (fixes #288) --- inc/yapb.h | 3 +++ src/botlib.cpp | 34 +++++++++++++++++++++++++++++++++- src/manager.cpp | 4 ++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/inc/yapb.h b/inc/yapb.h index 9d1c896..074e883 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -682,6 +682,7 @@ private: float m_joinServerTime; // time when bot joined the game float m_playServerTime; // time bot spent in the game float m_changeViewTime {}; // timestamp to change look at while at freezetime + float m_breakableTime {}; // breakeble acquired time bool m_moveToGoal {}; // bot currently moving to goal?? bool m_isStuck {}; // bot is stuck @@ -714,6 +715,7 @@ private: edict_t *m_itemIgnore {}; // pointer to entity to ignore for pickup edict_t *m_liftEntity {}; // pointer to lift entity edict_t *m_breakableEntity {}; // pointer to breakable entity + edict_t *m_lastBreakable {}; // last acquired breakable edict_t *m_targetEntity {}; // the entity that the bot is trying to reach edict_t *m_avoidGrenade {}; // pointer to grenade entity to avoid @@ -734,6 +736,7 @@ private: Vector m_desiredVelocity; // desired velocity for jump nodes Vector m_breakableOrigin; // origin of breakable + Array m_ignoredBreakable; // list of ignored breakables Array m_hostages; // pointer to used hostage entities Array m_routes; // pointer Array m_goalHistory; // history of selected goals diff --git a/src/botlib.cpp b/src/botlib.cpp index 0fd86a3..aeb2e1e 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -399,15 +399,31 @@ void Bot::checkBreakable (edict_t *touch) { } void Bot::checkBreakablesAround () { - if (!cv_destroy_breakables_around.bool_ () || usesKnife () || rg.chance (25) || !game.hasBreakables () || m_seeEnemyTime + 4.0f > game.time () || !game.isNullEntity (m_enemy) || !hasPrimaryWeapon ()) { + if (!m_buyingFinished || !cv_destroy_breakables_around.bool_ () || usesKnife () || rg.chance (25) || !game.hasBreakables () || m_seeEnemyTime + 4.0f > game.time () || !game.isNullEntity (m_enemy) || !hasPrimaryWeapon ()) { return; } // check if we're have some breakbles in 400 units range for (const auto &breakable : game.getBreakables ()) { + bool ignoreBreakable = false; + + // check if it's blacklisted + for (const auto &ignored : m_ignoredBreakable) { + if (ignored == breakable) { + ignoreBreakable = true; + break; + } + } + + // keep searching + if (ignoreBreakable) { + continue; + } + if (!game.isShootableBreakable (breakable)) { continue; } + const auto &origin = game.getEntityOrigin (breakable); const auto lengthToObstacle = origin.distanceSq (pev->origin); @@ -421,7 +437,23 @@ void Bot::checkBreakablesAround () { continue; } + // maybe time to give up? + if (m_lastBreakable == breakable && m_breakableTime + 1.0f < game.time ()) { + m_ignoredBreakable.emplace (breakable); + + m_breakableOrigin = nullptr; + m_lastBreakable = nullptr; + m_breakableEntity = nullptr; + + continue; + } + if (isInFOV (origin - getEyesPos ()) < pev->fov && seesEntity (origin)) { + if (m_breakableEntity != breakable) { + m_breakableTime = game.time (); + m_lastBreakable = breakable; + } + m_breakableOrigin = origin; m_breakableEntity = breakable; m_campButtons = pev->button & IN_DUCK; diff --git a/src/manager.cpp b/src/manager.cpp index a3b40b4..15b40e1 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -1263,6 +1263,8 @@ void Bot::newRound () { m_breakableEntity = nullptr; m_breakableOrigin = nullptr; + m_lastBreakable = nullptr; + m_timeDoorOpen = 0.0f; resetCollision (); @@ -1283,6 +1285,7 @@ void Bot::newRound () { m_shootAtDeadTime = 0.0f; m_oldCombatDesire = 0.0f; m_liftUsageTime = 0.0f; + m_breakableTime = 0.0f; m_avoidGrenade = nullptr; m_needAvoidGrenade = 0; @@ -1392,6 +1395,7 @@ void Bot::newRound () { } m_msgQueue.clear (); m_goalHistory.clear (); + m_ignoredBreakable.clear (); // clear last trace for (auto i = 0; i < TraceChannel::Num; ++i) {