Skip to content

Commit eb8f4e6

Browse files
authored
Bots consider nav pathing penalties based on weapon limits (#1805)
- Bots with shotguns significantly penalize NavAreas that have many visibility connections - Bots with pistol caliber weapons slightly avoid areas but to a lesser degree - Bots with scoped/semi-auto weapons favor exposed NavAreas with long sightlines - Generally, a minor penalty is applied for NavArea exposure for bots to avoid wide open exposed NavAreas - Further discourage bots from taking reserved paths and jumping with higher compensating NavArea pathing penalties - Opposing enemies take direct path when chasing ghoster in CTG mode (since careful paths are now significantly longer to traverse)
1 parent f063fcf commit eb8f4e6

6 files changed

Lines changed: 120 additions & 11 deletions

File tree

src/game/server/nav_area.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,37 @@ CNavArea::CNavArea( void )
258258
m_funcNavCostVector.RemoveAll();
259259

260260
m_nVisTestCounter = (uint32)-1;
261+
262+
#ifdef NEO
263+
m_visibleAreaCount = 0;
264+
#endif
261265
}
262266

267+
268+
#ifdef NEO
269+
//--------------------------------------------------------------------------------------------------------------
270+
struct CountPotentiallyVisibleAreas
271+
{
272+
int count;
273+
CountPotentiallyVisibleAreas() : count(0) {}
274+
bool operator()( CNavArea* area )
275+
{
276+
count++;
277+
return true;
278+
}
279+
};
280+
281+
282+
//--------------------------------------------------------------------------------------------------------------
283+
void CNavArea::ComputePotentiallyVisibleAreaCount()
284+
{
285+
CountPotentiallyVisibleAreas counter;
286+
const_cast<CNavArea*>(this)->ForAllPotentiallyVisibleAreas( counter );
287+
m_visibleAreaCount = counter.count;
288+
}
289+
#endif
290+
291+
263292
//--------------------------------------------------------------------------------------------------------------
264293
/**
265294
* Assumes Z is flat

src/game/server/nav_area.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ class CNavArea : protected CNavAreaCriticalData
520520
virtual bool IsPartiallyVisible( const Vector &eye, const CBaseEntity *ignore = NULL ) const; // return true if any portion of the area is visible from given eyepoint (CPU intensive)
521521

522522
virtual bool IsPotentiallyVisible( const CNavArea *area ) const; // return true if given area is potentially visible from somewhere in this area (very fast)
523+
#ifdef NEO
524+
int GetPotentiallyVisibleAreaCount() const { return m_visibleAreaCount; }
525+
void ComputePotentiallyVisibleAreaCount();
526+
#endif
523527
virtual bool IsPotentiallyVisibleToTeam( int team ) const; // return true if any portion of this area is visible to anyone on the given team (very fast)
524528

525529
virtual bool IsCompletelyVisible( const CNavArea *area ) const; // return true if given area is completely visible from somewhere in this area (very fast)
@@ -662,6 +666,9 @@ class CNavArea : protected CNavAreaCriticalData
662666
*/
663667

664668
static unsigned int m_nextID; // used to allocate unique IDs
669+
#ifdef NEO
670+
int m_visibleAreaCount;
671+
#endif
665672
unsigned int m_id; // unique area ID
666673
unsigned int m_debugid;
667674

src/game/server/nav_file.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,14 @@ NavErrorType CNavMesh::PostLoad( unsigned int version )
16471647
area->PostLoad();
16481648
}
16491649

1650+
#ifdef NEO
1651+
FOR_EACH_VEC( TheNavAreas, vit )
1652+
{
1653+
CNavArea *area = TheNavAreas[ vit ];
1654+
area->ComputePotentiallyVisibleAreaCount();
1655+
}
1656+
#endif
1657+
16501658
// allow hiding spots to compute information
16511659
FOR_EACH_VEC( TheHidingSpots, hit )
16521660
{

src/game/server/neo/bot/behavior/neo_bot_ctg_enemy.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ ActionResult< CNEOBot > CNEOBotCtgEnemy::Update( CNEOBot *me, float interval )
4949
// Investigate the ghost carrier's position
5050
if ( m_repathTimer.IsElapsed() )
5151
{
52-
CNEOBotPathCompute( me, m_path, pGhostCarrier->GetAbsOrigin(), DEFAULT_ROUTE );
52+
// FASTEST_ROUTE: don't waste chase time looking for cover
53+
CNEOBotPathCompute( me, m_path, pGhostCarrier->GetAbsOrigin(), FASTEST_ROUTE );
5354
m_repathTimer.Start( RandomFloat( 0.2f, 1.0f ) );
5455
}
5556
m_path.Update( me );

src/game/server/neo/bot/neo_bot_path_cost.cpp

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,28 @@
99
extern ConVar neo_bot_path_reservation_enable;
1010

1111
ConVar neo_bot_path_around_friendly_cooldown("neo_bot_path_around_friendly_cooldown", "2.0", FCVAR_CHEAT,
12-
"How often to check for friendly path dispersion", false, 0, false, 60);
12+
"How often to check for friendly path dispersion", true, 0, true, 60);
1313

14-
ConVar neo_bot_path_penalty_jump_multiplier("neo_bot_path_penalty_jump_multiplier", "100.0", FCVAR_CHEAT,
15-
"Maximum penalty multiplier for jump height changes in pathfinding", false, 0.01f, false, 1000.0f);
14+
ConVar neo_bot_path_penalty_jump_multiplier("neo_bot_path_penalty_jump_multiplier", "100000.0", FCVAR_CHEAT,
15+
"Maximum penalty multiplier for jump height changes in pathfinding", true, 0.01f, false, 0.0f);
1616

1717
ConVar neo_bot_path_penalty_ladder_multiplier("neo_bot_path_penalty_ladder_multiplier", "3.0", FCVAR_CHEAT,
18-
"Penalty multiplier for ladder traversal in pathfinding", true, 0.1f, true, 100.0f);
18+
"Penalty multiplier for ladder traversal in pathfinding", true, 0.1f, false, 0.0f);
19+
20+
ConVar neo_bot_path_penalty_exposure_base("neo_bot_path_penalty_exposure_base", "5.0", FCVAR_CHEAT,
21+
"General additional penalty per visible area for bots to avoid exposed areas", true, 0.0f, false, 0.0f);
22+
23+
ConVar neo_bot_path_penalty_exposure_pistol("neo_bot_path_penalty_exposure_pistol", "10.0", FCVAR_CHEAT,
24+
"Additional penalty per visible area for bots wielding pistol caliber weapons", true, 0.0f, false, 0.0f);
25+
26+
ConVar neo_bot_path_penalty_exposure_shotgun("neo_bot_path_penalty_exposure_shotgun", "20.0", FCVAR_CHEAT,
27+
"Additional penalty per visible area for shotgun-wielding bots", true, 0.0f, false, 0.0f);
28+
29+
ConVar neo_bot_path_penalty_exposure_inverse_base_battle_rifle("neo_bot_path_penalty_exposure_inverse_base_battle_rifle", "500.0", FCVAR_CHEAT,
30+
"Base penalty for calculating inverse traversal penalty for semi-auto battle rifles", true, 1.0f, false, 0.0f);
31+
32+
ConVar neo_bot_path_penalty_exposure_inverse_base_scoped("neo_bot_path_penalty_exposure_inverse_base_scoped", "1000.0", FCVAR_CHEAT,
33+
"Base penalty for calculating inverse traversal penalty for scoped weapons", true, 1.0f, false, 0.0f);
1934

2035
//-------------------------------------------------------------------------------------------------
2136
CNEOBotPathCost::CNEOBotPathCost(CNEOBot* me, RouteType routeType)
@@ -126,6 +141,55 @@ float CNEOBotPathCost::operator()(CNavArea* baseArea, CNavArea* fromArea, const
126141
cost += CNEOBotPathReservations()->GetPredictedFriendlyPathCount(area->GetID(), m_me->GetTeamNumber()) * neo_bot_path_reservation_penalty.GetFloat();
127142
cost += CNEOBotPathReservations()->GetAreaAvoidPenalty(area->GetID());
128143

144+
// Weapon range penalties
145+
auto* myWeapon = assert_cast<CNEOBaseCombatWeapon*>(m_me->GetActiveWeapon());
146+
if (myWeapon)
147+
{
148+
const int nWeaponBits = myWeapon->GetNeoWepBits();
149+
if (nWeaponBits & NEO_WEP_FIREARM)
150+
{
151+
const int visibleAreaCount = area->GetPotentiallyVisibleAreaCount();
152+
if (visibleAreaCount > 0)
153+
{
154+
constexpr int nShotgunBits = NEO_WEP_AA13 | NEO_WEP_SUPA7;
155+
constexpr int nBattleRifleBits = NEO_WEP_M41 | NEO_WEP_M41_S;
156+
constexpr int nPistolCaliberBits = NEO_WEP_MILSO | NEO_WEP_TACHI | NEO_WEP_KYLA
157+
| NEO_WEP_MPN | NEO_WEP_MPN_S | NEO_WEP_JITTE | NEO_WEP_JITTE_S | NEO_WEP_SRM | NEO_WEP_SRM_S;
158+
159+
if (nWeaponBits & nPistolCaliberBits)
160+
{
161+
// Weapons that don't have max first shot accuracy
162+
const float exposurePenalty = neo_bot_path_penalty_exposure_pistol.GetFloat();
163+
cost += visibleAreaCount * exposurePenalty;
164+
}
165+
else if (nWeaponBits & nShotgunBits)
166+
{
167+
// Weapons that have spread that can't hit long range targets
168+
const float exposurePenalty = neo_bot_path_penalty_exposure_shotgun.GetFloat();
169+
cost += visibleAreaCount * exposurePenalty;
170+
}
171+
else if (nWeaponBits & nBattleRifleBits)
172+
{
173+
// Weapons that benefit from medium sightlines that can see many NavAreas
174+
const float baseline_penalty = neo_bot_path_penalty_exposure_inverse_base_battle_rifle.GetFloat();
175+
cost += baseline_penalty / visibleAreaCount;
176+
}
177+
else if (nWeaponBits & NEO_WEP_SCOPEDWEAPON)
178+
{
179+
// Weapons that benefit from long sightlines that can see many NavAreas
180+
const float baseline_penalty = neo_bot_path_penalty_exposure_inverse_base_scoped.GetFloat();
181+
cost += baseline_penalty / visibleAreaCount;
182+
}
183+
else
184+
{
185+
// Generally avoiding exposed areas when traversing a wide open area
186+
const float exposurePenalty = neo_bot_path_penalty_exposure_base.GetFloat();
187+
cost += visibleAreaCount * exposurePenalty;
188+
}
189+
}
190+
}
191+
}
192+
129193
if (m_routeType == SAFEST_ROUTE)
130194
{
131195
// NEO Jank Cheat: Incorporate enemy bot paths so that we don't run directly into their line of fire

src/game/server/neo/bot/neo_bot_path_reservation.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ ConVar neo_bot_path_reservation_enable("neo_bot_path_reservation_enable", "1", F
1212
"Enable the bot path reservation system.", true, 0, true, 1);
1313

1414
ConVar neo_bot_path_reservation_duration("neo_bot_path_reservation_duration", "30.0", FCVAR_NONE,
15-
"How long a path reservation lasts, in seconds.", true, 1, true, 1000000);
15+
"How long a path reservation lasts, in seconds.", true, 1, false, 0);
1616

17-
ConVar neo_bot_path_reservation_distance("neo_bot_path_reservation_distance", "10000", FCVAR_NONE,
18-
"How far along the path to reserve, in Hammer units.", true, 0, true, 1000000);
17+
ConVar neo_bot_path_reservation_distance("neo_bot_path_reservation_distance", "100000", FCVAR_NONE,
18+
"How far along the path to reserve, in Hammer units.", true, 0, false, 0);
1919

20-
ConVar neo_bot_path_reservation_penalty("neo_bot_path_reservation_penalty", "100", FCVAR_NONE,
21-
"Pathing cost penalty for a reserved area.", true, 0, true, 1000000);
20+
ConVar neo_bot_path_reservation_penalty("neo_bot_path_reservation_penalty", "10000", FCVAR_NONE,
21+
"Pathing cost penalty for a reserved area.", true, 0, false, 0);
2222

2323
ConVar neo_bot_path_reservation_friendly_penalty_enable("neo_bot_path_reservation_friendly_penalty_enable", "1", FCVAR_NONE,
2424
"Whether to update or retrieve the area friendly reservation penalty.", true, 0, true, 1);
@@ -29,7 +29,7 @@ ConVar neo_bot_path_reservation_avoid_penalty_enable("neo_bot_path_reservation_a
2929
ConVar neo_bot_path_reservation_killed_penalty("neo_bot_path_reservation_killed_penalty", "10", FCVAR_NONE,
3030
"Path selection penalty added to a nav area each time a bot dies moving through that area.", true, 0, false, 0);
3131

32-
ConVar neo_bot_path_reservation_onstuck_penalty("neo_bot_path_reservation_onstuck_penalty", "10000", FCVAR_NONE,
32+
ConVar neo_bot_path_reservation_onstuck_penalty("neo_bot_path_reservation_onstuck_penalty", "1000", FCVAR_NONE,
3333
"Path selection penalty added to a nav area each time a bot gets stuck moving through that area.", true, 0, false, 0);
3434

3535

0 commit comments

Comments
 (0)