diff --git a/src/game/server/neo/bot/behavior/neo_bot_attack.cpp b/src/game/server/neo/bot/behavior/neo_bot_attack.cpp index 7a1f4005a..b9a3f463e 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_attack.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_attack.cpp @@ -71,8 +71,7 @@ ActionResult< CNEOBot > CNEOBotAttack::Update( CNEOBot *me, float interval ) // SUPA7 reload can be interrupted so proactively reload if (myWeapon && (myWeapon->GetNeoWepBits() & NEO_WEP_SUPA7) && (myWeapon->Clip1() < myWeapon->GetMaxClip1())) { - me->ReleaseFireButton(); - me->PressReloadButton(); + me->ReloadIfLowClip(true); } if ( threat->IsVisibleRecently() ) diff --git a/src/game/server/neo/bot/behavior/neo_bot_behavior.cpp b/src/game/server/neo/bot/behavior/neo_bot_behavior.cpp index 244ac6835..3a9ea7e19 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_behavior.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_behavior.cpp @@ -622,10 +622,9 @@ void CNEOBotMainAction::FireWeaponAtEnemy( CNEOBot *me ) { if ( myWeapon->Clip1() <= 0 ) { - me->ReleaseFireButton(); me->EnableCloak(3.0f); m_isWaitingForFullReload = true; - me->PressReloadButton(); + me->ReloadIfLowClip(true); } if ( m_isWaitingForFullReload ) @@ -670,8 +669,7 @@ void CNEOBotMainAction::FireWeaponAtEnemy( CNEOBot *me ) if (myWeapon->Clip1() <= 0) { - me->ReleaseFireButton(); - me->PressReloadButton(); + me->ReloadIfLowClip(true); m_isWaitingForFullReload = true; } @@ -849,8 +847,7 @@ void CNEOBotMainAction::FireWeaponAtEnemy( CNEOBot *me ) } else { - me->ReleaseFireButton(); - me->PressReloadButton(); + me->ReloadIfLowClip(true); m_isWaitingForFullReload = true; } return; diff --git a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp index c561f5032..cca00ee16 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp @@ -47,13 +47,10 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolf::Update( CNEOBot *me, float interval const CKnownEntity *threat = me->GetVisionInterface()->GetPrimaryKnownThreat( true ); CBaseCombatWeapon *pWeapon = me->GetActiveWeapon(); - if ( !threat && pWeapon && pWeapon->UsesClipsForAmmo1() ) + if ( !threat && pWeapon ) { - if ( pWeapon->Clip1() < pWeapon->GetMaxClip1() && me->GetAmmoCount( pWeapon->GetPrimaryAmmoType() ) > 0 ) - { - // Aggressively reload due to lack of backup - me->PressReloadButton(); - } + // Aggressively reload due to lack of backup + me->ReloadIfLowClip(true); // force reload true } // We dropped the ghost to hunt a threat. diff --git a/src/game/server/neo/bot/behavior/neo_bot_jgr_capture.cpp b/src/game/server/neo/bot/behavior/neo_bot_jgr_capture.cpp index a582fc298..b9847b82a 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_jgr_capture.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_jgr_capture.cpp @@ -35,6 +35,7 @@ ActionResult CNEOBotJgrCapture::OnStart( CNEOBot *me, Action * // Ignore enemies while capturing juggernaut me->StopLookingAroundForEnemies(); + me->ReloadIfLowClip(); // might as well as we're preoccupied return Continue(); } diff --git a/src/game/server/neo/bot/behavior/neo_bot_retreat_to_cover.cpp b/src/game/server/neo/bot/behavior/neo_bot_retreat_to_cover.cpp index ae1ea157d..cf95cb193 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_retreat_to_cover.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_retreat_to_cover.cpp @@ -204,7 +204,11 @@ ActionResult< CNEOBot > CNEOBotRetreatToCover::Update( CNEOBot *me, float interv { const CKnownEntity *threat = me->GetVisionInterface()->GetPrimaryKnownThreat( true ); - if ( threat && threat->GetEntity() && threat->GetEntity()->IsPlayer() ) + if (!threat) + { + me->ReloadIfLowClip(); + } + else if ( threat->GetEntity() && threat->GetEntity()->IsPlayer() ) { CNEO_Player *pThreatPlayer = ToNEOPlayer( threat->GetEntity() ); if ( pThreatPlayer && pThreatPlayer->IsCarryingGhost() ) diff --git a/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp b/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp index 7f9d1a5fa..a1229e7f1 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp @@ -435,6 +435,12 @@ ActionResult< CNEOBot > CNEOBotTacticalMonitor::Update( CNEOBot *me, float inter AvoidBumpingFriends( me ); } + const CKnownEntity *threat = me->GetVisionInterface()->GetPrimaryKnownThreat(); + if ( !threat ) + { + me->ReloadIfLowClip(); + } + me->UpdateDelayedThreatNotices(); return Continue(); diff --git a/src/game/server/neo/bot/neo_bot.cpp b/src/game/server/neo/bot/neo_bot.cpp index 58714c882..f3f336e57 100644 --- a/src/game/server/neo/bot/neo_bot.cpp +++ b/src/game/server/neo/bot/neo_bot.cpp @@ -1597,40 +1597,76 @@ void CNEOBot::EquipBestWeaponForThreat(const CKnownEntity* threat, const bool bN //----------------------------------------------------------------------------------------------------- // Reload the active weapon if it makes sense for the situation -void CNEOBot::ReloadIfLowClip(void) +void CNEOBot::ReloadIfLowClip(bool bForceReload) { CNEOBaseCombatWeapon* myWeapon = static_cast(GetActiveWeapon()); - if (myWeapon && myWeapon->GetPrimaryAmmoCount() > 0) + + if (!myWeapon) + { + return; + } + + if (myWeapon->GetPrimaryAmmoCount() <= 0) + { + return; + } + + if (myWeapon->Clip1() >= myWeapon->GetMaxClip1()) { - bool shouldReload = false; - // SUPA7 reload doesn't discard ammo - if ((myWeapon->GetNeoWepBits() & NEO_WEP_SUPA7) && (myWeapon->Clip1() < myWeapon->GetMaxClip1())) + return; + } + + if (!(myWeapon->GetNeoWepBits() & NEO_WEP_FIREARM)) + { + return; + } + + if (myWeapon->GetNeoWepBits() & NEO_WEP_BALC) + { + return; + } + + if (myWeapon->GetNeoWepBits() & NEO_WEP_SMAC) + { + return; + } + + if (myWeapon->GetNeoWepBits() & NEO_WEP_SUPA7) + { + // Consider loading slug + if ( (myWeapon->m_iSecondaryAmmoCount > 0) && (myWeapon->Clip1() == myWeapon->GetMaxClip1() - 1)) { - shouldReload = true; + ReleaseFireButton(); + PressAltFireButton(); + return; // attempt to load slug } - else + // SUPA7 reload doesn't discard ammo, continue + } + else if (myWeapon->Clip1() > 0) + { + auto* pPlayer = ToNEOPlayer(this); + if ( pPlayer->GetTimeSinceWeaponFired() < 3.0f) { - int maxClip = myWeapon->GetMaxClip1(); - bool isBarrage = IsBarrageAndReloadWeapon(myWeapon); + return; // still in the middle of a fight + } - int baseThreshold = isBarrage ? (maxClip / 3) : (maxClip / 2); + int maxClip = myWeapon->GetMaxClip1(); + bool isBarrage = IsBarrageAndReloadWeapon(myWeapon); - float aggressionFactor = 1.0f - HealthFraction(); + int baseThreshold = isBarrage ? (maxClip / 3) : (maxClip / 2); - float dynamicThreshold = baseThreshold + aggressionFactor * (maxClip - baseThreshold); + float aggressionFactor = 1.0f - HealthFraction(); - if (myWeapon->Clip1() < static_cast(dynamicThreshold)) - { - shouldReload = true; - } - } + float dynamicThreshold = baseThreshold + aggressionFactor * (maxClip - baseThreshold); - if (shouldReload) + if (!bForceReload && myWeapon->Clip1() > static_cast(dynamicThreshold)) { - ReleaseFireButton(); - PressReloadButton(); + return; // reloads drop ammo, still have enough in clip } } + + ReleaseFireButton(); + PressReloadButton(); } @@ -1781,7 +1817,7 @@ bool CNEOBot::IsLineOfFirePenetrationClear(const trace_t &tr, const Vector &from // Only bother with fire penetration in short distance auto *neoWeapon = static_cast(GetActiveWeapon()); - if (!neoWeapon) + if (!neoWeapon || !(neoWeapon->GetNeoWepBits() & NEO_WEP_FIREARM)) { return false; } diff --git a/src/game/server/neo/bot/neo_bot.h b/src/game/server/neo/bot/neo_bot.h index 190ecdcb9..01f83b0e3 100644 --- a/src/game/server/neo/bot/neo_bot.h +++ b/src/game/server/neo/bot/neo_bot.h @@ -156,7 +156,7 @@ class CNEOBot : public NextBotPlayer< CNEO_Player >, public CGameEventListener bool EquipRequiredWeapon(void); // if we're required to equip a specific weapon, do it. void EquipBestWeaponForThreat(const CKnownEntity* threat, const bool bNotPrimary = false); // equip the best weapon we have to attack the given threat - void ReloadIfLowClip(void); + void ReloadIfLowClip(bool bForceReload = false); void PushRequiredWeapon(CNEOBaseCombatWeapon* weapon); // force us to equip and use this weapon until popped off the required stack void PopRequiredWeapon(void); // pop top required weapon off of stack and discard