Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/game/server/neo/bot/behavior/neo_bot_attack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() )
Expand Down
9 changes: 3 additions & 6 deletions src/game/server/neo/bot/behavior/neo_bot_behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down Expand Up @@ -670,8 +669,7 @@ void CNEOBotMainAction::FireWeaponAtEnemy( CNEOBot *me )

if (myWeapon->Clip1() <= 0)
{
me->ReleaseFireButton();
me->PressReloadButton();
me->ReloadIfLowClip(true);
m_isWaitingForFullReload = true;
}

Expand Down Expand Up @@ -849,8 +847,7 @@ void CNEOBotMainAction::FireWeaponAtEnemy( CNEOBot *me )
}
else
{
me->ReleaseFireButton();
me->PressReloadButton();
me->ReloadIfLowClip(true);
m_isWaitingForFullReload = true;
}
return;
Expand Down
9 changes: 3 additions & 6 deletions src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/game/server/neo/bot/behavior/neo_bot_jgr_capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ ActionResult<CNEOBot> CNEOBotJgrCapture::OnStart( CNEOBot *me, Action<CNEOBot> *

// Ignore enemies while capturing juggernaut
me->StopLookingAroundForEnemies();
me->ReloadIfLowClip(); // might as well as we're preoccupied
return Continue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() )
Expand Down
6 changes: 6 additions & 0 deletions src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
78 changes: 57 additions & 21 deletions src/game/server/neo/bot/neo_bot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CNEOBaseCombatWeapon*>(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<int>(dynamicThreshold))
{
shouldReload = true;
}
}
float dynamicThreshold = baseThreshold + aggressionFactor * (maxClip - baseThreshold);

if (shouldReload)
if (!bForceReload && myWeapon->Clip1() > static_cast<int>(dynamicThreshold))
{
ReleaseFireButton();
PressReloadButton();
return; // reloads drop ammo, still have enough in clip
}
}

ReleaseFireButton();
PressReloadButton();
}


Expand Down Expand Up @@ -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<CNEOBaseCombatWeapon *>(GetActiveWeapon());
if (!neoWeapon)
if (!neoWeapon || !(neoWeapon->GetNeoWepBits() & NEO_WEP_FIREARM))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see if the attached stack trace scenario happens again after checking the NEO_WEP_FIREARM bit. This should filter out the smoke grenade case mentioned.

{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/server/neo/bot/neo_bot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down