diff --git a/inc/manager.h b/inc/manager.h index cc8d373..0c368e7 100644 --- a/inc/manager.h +++ b/inc/manager.h @@ -38,7 +38,6 @@ private: float m_lastChatTime {}; // global chat time timestamp float m_timeBombPlanted {}; // time the bomb were planted float m_lastRadioTime[kGameTeamNum] {}; // global radio time - float m_predictUpdateTime {}; // time to update prediction entity int m_lastWinner {}; // the team who won previous round int m_lastDifficulty {}; // last bots difficulty @@ -122,8 +121,6 @@ public: void handleDeath (edict_t *killer, edict_t *victim); void setLastWinner (int winner); void checkBotModel (edict_t *ent, char *infobuffer); - void syncUpdateBotsPredict (); - void updateBotsPredict (); bool isTeamStacked (int team); bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned); diff --git a/inc/yapb.h b/inc/yapb.h index f722aff..b0a42b9 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -218,6 +218,7 @@ public: private: mutable Mutex m_pathFindLock {}; + mutable Mutex m_predictLock {}; private: uint32_t m_states {}; // sensing bitstates @@ -500,6 +501,7 @@ private: void selectSecondary (); void selectWeaponById (int id); void selectWeaponByIndex (int index); + void syncUpdatePredictedIndex (); void updatePredictedIndex (); void refreshModelName (char *infobuffer); diff --git a/src/botlib.cpp b/src/botlib.cpp index ec4feb4..4afe732 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -1623,12 +1623,17 @@ void Bot::overrideConditions () { } } -void Bot::updatePredictedIndex () { +void Bot::syncUpdatePredictedIndex () { auto wipePredict = [this] () { m_lastPredictIndex = kInvalidNodeIndex; m_lastPredictLength = kInfiniteDistanceLong; }; + if (!m_predictLock.tryLock ()) { + return; // allow only single instance of search per-bot + } + ScopedUnlock unlock (m_predictLock); + const auto lastEnemyOrigin = m_lastEnemyOrigin; const auto currentNodeIndex = m_currentNodeIndex; const auto &botOrigin = pev->origin; @@ -1666,6 +1671,16 @@ void Bot::updatePredictedIndex () { wipePredict (); } +void Bot::updatePredictedIndex () { + if (m_lastEnemyOrigin.empty ()) { + return; // do not run task if no last enemy + } + + worker.enqueue ([this] () { + syncUpdatePredictedIndex (); + }); +} + void Bot::refreshEnemyPredict () { if (game.isNullEntity (m_enemy) && !game.isNullEntity (m_lastEnemy) && !m_lastEnemyOrigin.empty ()) { const auto distanceToLastEnemySq = m_lastEnemyOrigin.distanceSq (pev->origin); @@ -1679,6 +1694,10 @@ void Bot::refreshEnemyPredict () { m_aimFlags |= AimFlags::LastEnemy; } } + + if (m_aimFlags & AimFlags::PredictPath) { + updatePredictedIndex (); + } } void Bot::setConditions () { @@ -3222,7 +3241,10 @@ void Bot::takeDamage (edict_t *inflictor, int damage, int armor, int bits) { // other player. m_lastDamageType = bits; - updatePracticeValue (damage); + + if (!game.is (GameFlags::CSDM)) { + updatePracticeValue (damage); + } if (util.isPlayer (inflictor) || (cv_attack_monsters.bool_ () && util.isMonster (inflictor))) { if (!util.isMonster (inflictor) && cv_tkpunish.bool_ () && game.getTeam (inflictor) == m_team && !util.isFakeClient (inflictor)) { diff --git a/src/manager.cpp b/src/manager.cpp index 7013f68..7919b37 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -295,9 +295,6 @@ void BotManager::frame () { for (const auto &bot : m_bots) { bot->frame (); } - - // run prediction for bots - updateBotsPredict (); } void BotManager::addbot (StringRef name, int difficulty, int personality, int team, int skin, bool manual) { @@ -765,30 +762,6 @@ void BotManager::checkBotModel (edict_t *ent, char *infobuffer) { } } -void BotManager::syncUpdateBotsPredict () { - if (m_predictUpdateTime > game.time ()) { - return; - } - - // update predicted index for all the bots - for (const auto &bot : m_bots) { - if (!bot.get ()) { - continue; - } - if (bot->m_notKilled && (bot->m_aimFlags & AimFlags::PredictPath)) { - bot->updatePredictedIndex (); - } - } - m_predictUpdateTime = game.time () + 0.1f; -} - -void BotManager::updateBotsPredict () { - // push update predict task for all bots to queue - worker.enqueue ([this] { - syncUpdateBotsPredict (); - }); -} - void BotManager::setWeaponMode (int selection) { // this function sets bots weapon mode @@ -1999,7 +1972,6 @@ void BotManager::initRound () { m_timeBombPlanted = 0.0f; m_plantSearchUpdateTime = 0.0f; m_autoKillCheckTime = 0.0f; - m_predictUpdateTime = 0.0f; m_botsCanPause = false; resetFilters (); diff --git a/src/navigate.cpp b/src/navigate.cpp index 93cec76..4f869c4 100644 --- a/src/navigate.cpp +++ b/src/navigate.cpp @@ -901,7 +901,7 @@ bool Bot::updateNavigation () { // pressing the jump button gives the illusion of the bot actual jumping. if (isOnFloor () || isOnLadder ()) { if (m_desiredVelocity.length2d () > 0.0f) { - pev->velocity = m_desiredVelocity; + pev->velocity = m_desiredVelocity + m_desiredVelocity * m_frameInterval; } else { auto feet = pev->origin + pev->mins; @@ -943,7 +943,7 @@ bool Bot::updateNavigation () { } } } - else if (!cv_jasonmode.bool_ () && usesKnife () && isOnFloor ()) { + else if (!cv_jasonmode.bool_ () && usesKnife () && isOnFloor () && getCurrentTaskId () != Task::EscapeFromBomb) { selectBestWeapon (); } } diff --git a/src/vision.cpp b/src/vision.cpp index 5468d6b..bcbf6ac 100644 --- a/src/vision.cpp +++ b/src/vision.cpp @@ -7,7 +7,7 @@ #include -ConVar cv_max_nodes_for_predict ("yb_max_nodes_for_predict", "20", "Maximum number for path length, to predict the enemy.", true, 15.0f, 256.0f); +ConVar cv_max_nodes_for_predict ("yb_max_nodes_for_predict", "25", "Maximum number for path length, to predict the enemy.", true, 15.0f, 256.0f); // game console variables ConVar mp_flashlight ("mp_flashlight", nullptr, Var::GameRef); @@ -19,12 +19,12 @@ float Bot::isInFOV (const Vector &destination) { // return the absolute value of angle to destination entity // zero degrees means straight ahead, 45 degrees to the left or // 45 degrees to the right is the limit of the normal view angle - float absoluteAngle = cr::abs (viewAngle - entityAngle); + const float absAngle = cr::abs (viewAngle - entityAngle); - if (absoluteAngle > 180.0f) { - absoluteAngle = 360.0f - absoluteAngle; + if (absAngle > 180.0f) { + return 360.0f - absAngle; } - return absoluteAngle; + return absAngle; } bool Bot::isInViewCone (const Vector &origin) { @@ -142,18 +142,15 @@ void Bot::updateAimDir () { int predictNode = m_lastPredictIndex; auto isPredictedIndexApplicable = [&] () -> bool { - if (predictNode != kInvalidNodeIndex) { - if (!vistab.visible (m_currentNodeIndex, predictNode) || !vistab.visible (m_previousNodes[0], predictNode)) { - predictNode = kInvalidNodeIndex; - pathLength = kInfiniteDistanceLong; - } + if (!vistab.visible (m_currentNodeIndex, predictNode) || !vistab.visible (m_previousNodes[0], predictNode)) { + predictNode = kInvalidNodeIndex; } return predictNode != kInvalidNodeIndex && pathLength < cv_max_nodes_for_predict.int_ (); }; if (changePredictedEnemy) { if (isPredictedIndexApplicable ()) { - m_lookAtPredict = graph[predictNode].origin; + m_lookAtPredict = graph[m_lastPredictIndex].origin; m_timeNextTracking = game.time () + rg.get (0.5f, 1.0f); m_trackingEdict = m_lastEnemy;