66#include " nav_mesh.h"
77
88// ---------------------------------------------------------------------------------------------
9- // Mask of non-identity "tag" bits that GetNeoWepBits() may include
10- static constexpr NEO_WEP_BITS_UNDERLYING_TYPE WEP_TAG_BITS_MASK =
11- NEO_WEP_SCOPEDWEAPON | NEO_WEP_THROWABLE | NEO_WEP_SUPPRESSED | NEO_WEP_FIREARM | NEO_WEP_EXPLOSIVE ;
12-
139static constexpr int BOT_WEP_PREF_RANK_UNPREFERRED = -1 ;
1410static constexpr int BOT_WEP_PREF_RANK_EMPTY = -2 ;
1511
@@ -22,16 +18,12 @@ bool IsUndroppablePrimary( CBaseCombatWeapon *pPrimary )
2218 }
2319
2420 auto *pNeoWep = assert_cast<CNEOBaseCombatWeapon *>( pPrimary );
25- const NEO_WEP_BITS_UNDERLYING_TYPE wepBits = pNeoWep->GetNeoWepBits ();
26- return ( wepBits & NEO_WEP_BALC ) != 0 ;
21+ return !pNeoWep->CanDrop ();
2722}
2823
2924// ---------------------------------------------------------------------------------------------
30- int GetBotWeaponPreferenceRank ( CNEOBot *me, NEO_WEP_BITS_UNDERLYING_TYPE wepBit )
25+ int GetBotWeaponPreferenceRank ( const CNEOBot *me, NEO_WEP_BITS_UNDERLYING_TYPE wepBit )
3126{
32- // Strip tag bits to get the primary identity bit
33- const NEO_WEP_BITS_UNDERLYING_TYPE identityBit = wepBit & ~WEP_TAG_BITS_MASK ;
34-
3527 const int playerClass = me->GetClass ();
3628 if ( playerClass < 0 || playerClass >= NEO_CLASS__LOADOUTABLE_COUNT )
3729 {
@@ -40,7 +32,7 @@ int GetBotWeaponPreferenceRank( CNEOBot *me, NEO_WEP_BITS_UNDERLYING_TYPE wepBit
4032
4133 for ( int idxRank = NEO_RANK__TOTAL - 1 ; idxRank >= 0 ; --idxRank )
4234 {
43- if ( me->m_profile .flagsWepPrefs [playerClass][idxRank] & identityBit )
35+ if ( me->m_profile .flagsWepPrefs [playerClass][idxRank] & wepBit )
4436 {
4537 return idxRank;
4638 }
@@ -50,13 +42,18 @@ int GetBotWeaponPreferenceRank( CNEOBot *me, NEO_WEP_BITS_UNDERLYING_TYPE wepBit
5042}
5143
5244// ---------------------------------------------------------------------------------------------
53- bool IsWeaponPreferenceUpgrade ( CNEOBot *me, CNEOBaseCombatWeapon *pTargetWep, int myPrefRank, bool bHasReserveAmmo )
45+ bool IsWeaponPreferenceUpgrade ( const CNEOBot *me, CNEOBaseCombatWeapon *pTargetWep, int myPrefRank, bool bHasReserveAmmo )
5446{
5547 if ( !pTargetWep )
5648 {
5749 return false ;
5850 }
5951
52+ if ( pTargetWep->GetPrimaryAmmoCount () <= 0 )
53+ {
54+ return false ;
55+ }
56+
6057 if ( myPrefRank == BOT_WEP_PREF_RANK_EMPTY )
6158 {
6259 // We have no primary weapon at all, anything is an upgrade
@@ -65,13 +62,10 @@ bool IsWeaponPreferenceUpgrade( CNEOBot *me, CNEOBaseCombatWeapon *pTargetWep, i
6562
6663 if ( !bHasReserveAmmo )
6764 {
68- if ( pTargetWep->GetPrimaryAmmoCount () > 0 )
69- {
70- return true ;
71- }
65+ return true ;
7266 }
7367
74- const NEO_WEP_BITS_UNDERLYING_TYPE targetWepBits = pTargetWep->GetNeoWepBits ();
68+ const auto targetWepBits = pTargetWep->GetNeoWepBits ();
7569 const int targetPrefRank = GetBotWeaponPreferenceRank ( me, targetWepBits );
7670
7771 if ( targetPrefRank <= BOT_WEP_PREF_RANK_UNPREFERRED && bHasReserveAmmo )
@@ -88,18 +82,21 @@ bool IsWeaponPreferenceUpgrade( CNEOBot *me, CNEOBaseCombatWeapon *pTargetWep, i
8882}
8983
9084// ---------------------------------------------------------------------------------------------
91- CBaseEntity *FindNearestPrimaryWeapon ( CNEOBot *me, bool bAllowDropGhost, CNEOIgnoredWeaponsCache *pIgnoredWeapons )
85+ CBaseEntity *FindNearestPrimaryWeapon ( const CNEOBot *me, bool bAllowDropGhost, const CNEOIgnoredWeaponsCache *pIgnoredWeapons )
9286{
9387 constexpr float flSearchRadius = 1000 .0f ;
9488 CBaseEntity *pClosestWeapon = nullptr ;
9589 float flClosestDistSq = FLT_MAX ;
9690 int iBestWeaponRank = -999 ;
9791
92+ int myPrefRank = BOT_WEP_PREF_RANK_EMPTY ;
93+ bool bHasReserveAmmo = false ;
94+
9895 CBaseCombatWeapon *pPrimary = me->Weapon_GetSlot ( 0 );
9996 if ( pPrimary )
10097 {
10198 auto *pNeoPrimary = assert_cast<CNEOBaseCombatWeapon *>( pPrimary );
102- if ( pNeoPrimary->GetNeoWepBits () & NEO_WEP_BALC )
99+ if ( ! pNeoPrimary->CanDrop () )
103100 {
104101 // can't switch these weapons
105102 return nullptr ;
@@ -119,16 +116,9 @@ CBaseEntity *FindNearestPrimaryWeapon( CNEOBot *me, bool bAllowDropGhost, CNEOIg
119116 return nullptr ;
120117 }
121118 }
122- }
123119
124- int myPrefRank = BOT_WEP_PREF_RANK_EMPTY ;
125- bool bHasReserveAmmo = false ;
126- if ( pPrimary )
127- {
128- myPrefRank = BOT_WEP_PREF_RANK_UNPREFERRED ;
129120 bHasReserveAmmo = pPrimary->GetPrimaryAmmoCount () > 0 ;
130- auto *pMyNeoWep = assert_cast<CNEOBaseCombatWeapon *>( pPrimary );
131- myPrefRank = GetBotWeaponPreferenceRank ( me, pMyNeoWep->GetNeoWepBits () );
121+ myPrefRank = GetBotWeaponPreferenceRank ( me, pNeoPrimary->GetNeoWepBits () );
132122 }
133123
134124 // For checking if weapon candidate is in PVS of me
@@ -156,13 +146,19 @@ CBaseEntity *FindNearestPrimaryWeapon( CNEOBot *me, bool bAllowDropGhost, CNEOIg
156146 continue ;
157147 }
158148
149+ if ( !pNeoWeapon->CanBePickedUpByClass ( me->GetClass () ) )
150+ {
151+ continue ;
152+ }
153+
159154 // only consider weapons in the bot's wishlist that are an upgrade
160155 if ( !IsWeaponPreferenceUpgrade ( me, pNeoWeapon, myPrefRank, bHasReserveAmmo ) )
161156 {
162157 continue ;
163158 }
164159
165- const int targetPrefRank = GetBotWeaponPreferenceRank ( me, pNeoWeapon->GetNeoWepBits () );
160+ const auto targetWepBits = pNeoWeapon->GetNeoWepBits ();
161+ const int targetPrefRank = GetBotWeaponPreferenceRank ( me, targetWepBits );
166162
167163 float flDistSq = me->GetAbsOrigin ().DistToSqr ( pEntity->GetAbsOrigin () );
168164
@@ -254,7 +250,7 @@ ActionResult< CNEOBot > CNEOBotSeekWeapon::OnStart( CNEOBot *me, Action< CNEOBot
254250 return Done (" No valid replacement primary found" );
255251 }
256252
257- auto *pNeoPrimary = pPrimary ? assert_cast<CNEOBaseCombatWeapon *>( pPrimary ) : nullptr ;
253+ auto *pNeoPrimary = assert_cast<CNEOBaseCombatWeapon *>( pPrimary );
258254 if ( pNeoPrimary && ( pNeoPrimary->GetNeoWepBits () & NEO_WEP_GHOST ) )
259255 {
260256 // Try to drop once, but sometimes the environment causes a bounce back
0 commit comments