bot: allow bots to ignore more than one item on the ground per-round

This commit is contained in:
jeefo 2024-07-03 11:48:56 +03:00
commit 8c0e603e55
No known key found for this signature in database
GPG key ID: D696786B81B667C8
4 changed files with 22 additions and 10 deletions

View file

@ -323,7 +323,6 @@ private:
UniquePtr <class AStarAlgo> m_planner {}; UniquePtr <class AStarAlgo> m_planner {};
edict_t *m_pickupItem {}; // pointer to entity of item to use/pickup 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_liftEntity {}; // pointer to lift entity
edict_t *m_breakableEntity {}; // pointer to breakable entity edict_t *m_breakableEntity {}; // pointer to breakable entity
edict_t *m_lastBreakable {}; // last acquired breakable edict_t *m_lastBreakable {}; // last acquired breakable
@ -353,6 +352,7 @@ private:
Vector m_checkFallPoint[2] {}; // check fall point Vector m_checkFallPoint[2] {}; // check fall point
Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables Array <edict_t *> m_ignoredBreakable {}; // list of ignored breakables
Array <edict_t *> m_ignoredItems {}; // list of pointers to entity to ignore for pickup
Array <edict_t *> m_hostages {}; // pointer to used hostage entities Array <edict_t *> m_hostages {}; // pointer to used hostage entities
UniquePtr <class PlayerHitboxEnumerator> m_hitboxEnumerator {}; UniquePtr <class PlayerHitboxEnumerator> m_hitboxEnumerator {};
@ -452,6 +452,7 @@ private:
bool isEnemyNoticeable (float range); bool isEnemyNoticeable (float range);
bool isCreature (); bool isCreature ();
bool isOnLadderPath (); bool isOnLadderPath ();
bool isIgnoredItem (edict_t *ent);
void doPlayerAvoidance (const Vector &normal); void doPlayerAvoidance (const Vector &normal);
void selectCampButtons (int index); void selectCampButtons (int index);

View file

@ -392,7 +392,7 @@ void Bot::updatePickups () {
// get the entity origin // get the entity origin
const auto &origin = game.getEntityOrigin (ent); 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 continue; // someone owns this weapon or it hasn't re-spawned yet
} }
@ -566,7 +566,7 @@ void Bot::updatePickups () {
clearSearchNodes (); clearSearchNodes ();
} }
else if (pickupType == Pickup::Hostage) { else if (pickupType == Pickup::Hostage) {
m_itemIgnore = ent; m_ignoredItems.push (ent);
allowPickup = false; allowPickup = false;
if (!m_defendHostage && m_personality if (!m_defendHostage && m_personality
@ -694,7 +694,7 @@ void Bot::updatePickups () {
} }
} }
else if (pickupType == Pickup::DroppedC4) { else if (pickupType == Pickup::DroppedC4) {
m_itemIgnore = ent; m_ignoredItems.push (ent);
allowPickup = false; allowPickup = false;
if (!m_defendedBomb && m_difficulty >= Difficulty::Normal && rg.chance (75) && m_healthValue < 60) { 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 // check if item is too high to reach, check if getting the item would hurt bot
if (pickupPos.z > getEyesPos ().z + highOffset || isDeadlyMove (pickupPos)) { if (pickupPos.z > getEyesPos ().z + highOffset || isDeadlyMove (pickupPos)) {
m_itemIgnore = m_pickupItem; m_ignoredItems.push (m_pickupItem);
m_pickupItem = nullptr; m_pickupItem = nullptr;
m_pickupType = Pickup::None; m_pickupType = Pickup::None;
@ -755,7 +756,7 @@ void Bot::ensureEntitiesClear () {
if (tid == Task::PickupItem || (m_states & Sense::PickupItem)) { if (tid == Task::PickupItem || (m_states & Sense::PickupItem)) {
if (!game.isNullEntity (m_pickupItem) && !m_hasProgressBar) { 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; m_itemCheckTime = game.time () + 5.0f;
@ -781,6 +782,15 @@ void Bot::ensureEntitiesClear () {
findValidNode (); 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) { Vector Bot::getCampDirection (const Vector &dest) {
// this function check if view on last enemy position is blocked - replace with better vector then // 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 // 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) && pev->origin.distanceSq (bombPosition) < cr::sqrf (1540.0f)
&& !isBombDefusing (bombPosition)) { && !isBombDefusing (bombPosition)) {
m_itemIgnore = nullptr; m_ignoredItems.clear ();
m_itemCheckTime = game.time (); m_itemCheckTime = game.time ();
clearTask (getCurrentTaskId ()); clearTask (getCurrentTaskId ());
@ -3320,7 +3330,7 @@ void Bot::logic () {
} }
// ensure we're not stuck destroying/picking something // 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)) { && !(m_states & Sense::SeeingEnemy)) {
ensureEntitiesClear (); ensureEntitiesClear ();
} }

View file

@ -1493,8 +1493,8 @@ void Bot::newRound () {
m_liftEntity = nullptr; m_liftEntity = nullptr;
m_pickupItem = nullptr; m_pickupItem = nullptr;
m_itemIgnore = nullptr;
m_itemCheckTime = 0.0f; m_itemCheckTime = 0.0f;
m_ignoredItems.clear ();
m_breakableEntity = nullptr; m_breakableEntity = nullptr;
m_breakableOrigin = nullptr; m_breakableOrigin = nullptr;

View file

@ -1541,7 +1541,8 @@ void Bot::pickupItem_ () {
} }
if (!weaponIndex || !niceWeapon) { if (!weaponIndex || !niceWeapon) {
m_itemIgnore = m_pickupItem; m_ignoredItems.push (m_pickupItem);
m_pickupItem = nullptr; m_pickupItem = nullptr;
m_pickupType = Pickup::None; m_pickupType = Pickup::None;