From 8c0e603e5560858716c798c36a8e975d5d45dcb2 Mon Sep 17 00:00:00 2001 From: jeefo Date: Wed, 3 Jul 2024 11:48:56 +0300 Subject: [PATCH] bot: allow bots to ignore more than one item on the ground per-round --- inc/yapb.h | 3 ++- src/botlib.cpp | 24 +++++++++++++++++------- src/manager.cpp | 2 +- src/tasks.cpp | 3 ++- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/inc/yapb.h b/inc/yapb.h index 1968172..0ccff41 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -323,7 +323,6 @@ private: UniquePtr m_planner {}; edict_t *m_pickupItem {}; // pointer to entity of item to use/pickup - 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 @@ -353,6 +352,7 @@ private: Vector m_checkFallPoint[2] {}; // check fall point Array m_ignoredBreakable {}; // list of ignored breakables + Array m_ignoredItems {}; // list of pointers to entity to ignore for pickup Array m_hostages {}; // pointer to used hostage entities UniquePtr m_hitboxEnumerator {}; @@ -452,6 +452,7 @@ private: bool isEnemyNoticeable (float range); bool isCreature (); bool isOnLadderPath (); + bool isIgnoredItem (edict_t *ent); void doPlayerAvoidance (const Vector &normal); void selectCampButtons (int index); diff --git a/src/botlib.cpp b/src/botlib.cpp index f659d8c..655bcf9 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -392,7 +392,7 @@ void Bot::updatePickups () { // get the entity origin const auto &origin = game.getEntityOrigin (ent); - if ((ent->v.effects & EF_NODRAW) || ent == m_itemIgnore || cr::abs (origin.z - pev->origin.z) > 96.0f) { + if ((ent->v.effects & EF_NODRAW) || isIgnoredItem (ent) || cr::abs (origin.z - pev->origin.z) > 96.0f) { continue; // someone owns this weapon or it hasn't re-spawned yet } @@ -566,7 +566,7 @@ void Bot::updatePickups () { clearSearchNodes (); } else if (pickupType == Pickup::Hostage) { - m_itemIgnore = ent; + m_ignoredItems.push (ent); allowPickup = false; if (!m_defendHostage && m_personality @@ -694,7 +694,7 @@ void Bot::updatePickups () { } } else if (pickupType == Pickup::DroppedC4) { - m_itemIgnore = ent; + m_ignoredItems.push (ent); allowPickup = false; if (!m_defendedBomb && m_difficulty >= Difficulty::Normal && rg.chance (75) && m_healthValue < 60) { @@ -740,7 +740,8 @@ void Bot::updatePickups () { // check if item is too high to reach, check if getting the item would hurt bot if (pickupPos.z > getEyesPos ().z + highOffset || isDeadlyMove (pickupPos)) { - m_itemIgnore = m_pickupItem; + m_ignoredItems.push (m_pickupItem); + m_pickupItem = nullptr; m_pickupType = Pickup::None; @@ -755,7 +756,7 @@ void Bot::ensureEntitiesClear () { if (tid == Task::PickupItem || (m_states & Sense::PickupItem)) { if (!game.isNullEntity (m_pickupItem) && !m_hasProgressBar) { - m_itemIgnore = m_pickupItem; // clear these pointers, bot might be stuck getting to them + m_ignoredItems.push (m_pickupItem); // clear these pointers, bot might be stuck getting to them } m_itemCheckTime = game.time () + 5.0f; @@ -781,6 +782,15 @@ void Bot::ensureEntitiesClear () { findValidNode (); } +bool Bot::isIgnoredItem (edict_t *ent) { + for (const auto &ignored : m_ignoredItems) { + if (ignored == ent) { + return true; + } + } + return false; +} + Vector Bot::getCampDirection (const Vector &dest) { // this function check if view on last enemy position is blocked - replace with better vector then // mostly used for getting a good camping direction vector if not camping on a camp node @@ -2914,7 +2924,7 @@ void Bot::frame () { && pev->origin.distanceSq (bombPosition) < cr::sqrf (1540.0f) && !isBombDefusing (bombPosition)) { - m_itemIgnore = nullptr; + m_ignoredItems.clear (); m_itemCheckTime = game.time (); clearTask (getCurrentTaskId ()); @@ -3320,7 +3330,7 @@ void Bot::logic () { } // ensure we're not stuck destroying/picking something - if (m_moveToGoal && rg (2.0f, 3.0f) + m_navTimeset + m_destOrigin.distanceSq2d (pev->origin) / m_moveSpeed < game.time () + if (m_moveToGoal && m_moveSpeed > 0.0f && rg (2.5f, 3.5f) + m_navTimeset + m_destOrigin.distanceSq2d (pev->origin) / cr::sqrf (m_moveSpeed) < game.time () && !(m_states & Sense::SeeingEnemy)) { ensureEntitiesClear (); } diff --git a/src/manager.cpp b/src/manager.cpp index 151c8fc..b376b47 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -1493,8 +1493,8 @@ void Bot::newRound () { m_liftEntity = nullptr; m_pickupItem = nullptr; - m_itemIgnore = nullptr; m_itemCheckTime = 0.0f; + m_ignoredItems.clear (); m_breakableEntity = nullptr; m_breakableOrigin = nullptr; diff --git a/src/tasks.cpp b/src/tasks.cpp index 413a755..f58b5e4 100644 --- a/src/tasks.cpp +++ b/src/tasks.cpp @@ -1541,7 +1541,8 @@ void Bot::pickupItem_ () { } if (!weaponIndex || !niceWeapon) { - m_itemIgnore = m_pickupItem; + m_ignoredItems.push (m_pickupItem); + m_pickupItem = nullptr; m_pickupType = Pickup::None;