Skip to content
Merged
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
29 changes: 29 additions & 0 deletions src/game/server/nav_area.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,37 @@ CNavArea::CNavArea( void )
m_funcNavCostVector.RemoveAll();

m_nVisTestCounter = (uint32)-1;

#ifdef NEO
m_visibleAreaCount = 0;
#endif
}


#ifdef NEO
//--------------------------------------------------------------------------------------------------------------
struct CountPotentiallyVisibleAreas
{
int count;
CountPotentiallyVisibleAreas() : count(0) {}
bool operator()( CNavArea* area )
{
count++;
return true;
}
};


//--------------------------------------------------------------------------------------------------------------
void CNavArea::ComputePotentiallyVisibleAreaCount()
{
CountPotentiallyVisibleAreas counter;
const_cast<CNavArea*>(this)->ForAllPotentiallyVisibleAreas( counter );
m_visibleAreaCount = counter.count;
}
#endif


//--------------------------------------------------------------------------------------------------------------
/**
* Assumes Z is flat
Expand Down
7 changes: 7 additions & 0 deletions src/game/server/nav_area.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,10 @@ class CNavArea : protected CNavAreaCriticalData
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)

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

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

static unsigned int m_nextID; // used to allocate unique IDs
#ifdef NEO
int m_visibleAreaCount;
#endif
unsigned int m_id; // unique area ID
unsigned int m_debugid;

Expand Down
8 changes: 8 additions & 0 deletions src/game/server/nav_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1647,6 +1647,14 @@ NavErrorType CNavMesh::PostLoad( unsigned int version )
area->PostLoad();
}

#ifdef NEO
FOR_EACH_VEC( TheNavAreas, vit )
{
CNavArea *area = TheNavAreas[ vit ];
area->ComputePotentiallyVisibleAreaCount();
}
#endif

// allow hiding spots to compute information
FOR_EACH_VEC( TheHidingSpots, hit )
{
Expand Down
3 changes: 2 additions & 1 deletion src/game/server/neo/bot/behavior/neo_bot_ctg_enemy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ ActionResult< CNEOBot > CNEOBotCtgEnemy::Update( CNEOBot *me, float interval )
// Investigate the ghost carrier's position
if ( m_repathTimer.IsElapsed() )
{
CNEOBotPathCompute( me, m_path, pGhostCarrier->GetAbsOrigin(), DEFAULT_ROUTE );
// FASTEST_ROUTE: don't waste chase time looking for cover
CNEOBotPathCompute( me, m_path, pGhostCarrier->GetAbsOrigin(), FASTEST_ROUTE );
Comment thread
sunzenshen marked this conversation as resolved.
m_repathTimer.Start( RandomFloat( 0.2f, 1.0f ) );
}
m_path.Update( me );
Expand Down
72 changes: 68 additions & 4 deletions src/game/server/neo/bot/neo_bot_path_cost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,28 @@
extern ConVar neo_bot_path_reservation_enable;

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

ConVar neo_bot_path_penalty_jump_multiplier("neo_bot_path_penalty_jump_multiplier", "100.0", FCVAR_CHEAT,
"Maximum penalty multiplier for jump height changes in pathfinding", false, 0.01f, false, 1000.0f);
ConVar neo_bot_path_penalty_jump_multiplier("neo_bot_path_penalty_jump_multiplier", "100000.0", FCVAR_CHEAT,
"Maximum penalty multiplier for jump height changes in pathfinding", true, 0.01f, false, 0.0f);
Comment thread
sunzenshen marked this conversation as resolved.

ConVar neo_bot_path_penalty_ladder_multiplier("neo_bot_path_penalty_ladder_multiplier", "3.0", FCVAR_CHEAT,
"Penalty multiplier for ladder traversal in pathfinding", true, 0.1f, true, 100.0f);
"Penalty multiplier for ladder traversal in pathfinding", true, 0.1f, false, 0.0f);

ConVar neo_bot_path_penalty_exposure_base("neo_bot_path_penalty_exposure_base", "5.0", FCVAR_CHEAT,
"General additional penalty per visible area for bots to avoid exposed areas", true, 0.0f, false, 0.0f);

ConVar neo_bot_path_penalty_exposure_pistol("neo_bot_path_penalty_exposure_pistol", "10.0", FCVAR_CHEAT,
"Additional penalty per visible area for bots wielding pistol caliber weapons", true, 0.0f, false, 0.0f);

ConVar neo_bot_path_penalty_exposure_shotgun("neo_bot_path_penalty_exposure_shotgun", "20.0", FCVAR_CHEAT,
"Additional penalty per visible area for shotgun-wielding bots", true, 0.0f, false, 0.0f);

ConVar neo_bot_path_penalty_exposure_inverse_base_battle_rifle("neo_bot_path_penalty_exposure_inverse_base_battle_rifle", "500.0", FCVAR_CHEAT,
"Base penalty for calculating inverse traversal penalty for semi-auto battle rifles", true, 1.0f, false, 0.0f);

ConVar neo_bot_path_penalty_exposure_inverse_base_scoped("neo_bot_path_penalty_exposure_inverse_base_scoped", "1000.0", FCVAR_CHEAT,
"Base penalty for calculating inverse traversal penalty for scoped weapons", true, 1.0f, false, 0.0f);

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

// Weapon range penalties
auto* myWeapon = assert_cast<CNEOBaseCombatWeapon*>(m_me->GetActiveWeapon());
if (myWeapon)
{
const int nWeaponBits = myWeapon->GetNeoWepBits();
if (nWeaponBits & NEO_WEP_FIREARM)
{
const int visibleAreaCount = area->GetPotentiallyVisibleAreaCount();
if (visibleAreaCount > 0)
{
constexpr int nShotgunBits = NEO_WEP_AA13 | NEO_WEP_SUPA7;
constexpr int nBattleRifleBits = NEO_WEP_M41 | NEO_WEP_M41_S;
constexpr int nPistolCaliberBits = NEO_WEP_MILSO | NEO_WEP_TACHI | NEO_WEP_KYLA
| NEO_WEP_MPN | NEO_WEP_MPN_S | NEO_WEP_JITTE | NEO_WEP_JITTE_S | NEO_WEP_SRM | NEO_WEP_SRM_S;
Comment thread
sunzenshen marked this conversation as resolved.

if (nWeaponBits & nPistolCaliberBits)
{
// Weapons that don't have max first shot accuracy
const float exposurePenalty = neo_bot_path_penalty_exposure_pistol.GetFloat();
cost += visibleAreaCount * exposurePenalty;
Comment thread
sunzenshen marked this conversation as resolved.
}
else if (nWeaponBits & nShotgunBits)
{
// Weapons that have spread that can't hit long range targets
const float exposurePenalty = neo_bot_path_penalty_exposure_shotgun.GetFloat();
cost += visibleAreaCount * exposurePenalty;
}
else if (nWeaponBits & nBattleRifleBits)
{
// Weapons that benefit from medium sightlines that can see many NavAreas
const float baseline_penalty = neo_bot_path_penalty_exposure_inverse_base_battle_rifle.GetFloat();
cost += baseline_penalty / visibleAreaCount;
}
else if (nWeaponBits & NEO_WEP_SCOPEDWEAPON)
{
// Weapons that benefit from long sightlines that can see many NavAreas
const float baseline_penalty = neo_bot_path_penalty_exposure_inverse_base_scoped.GetFloat();
cost += baseline_penalty / visibleAreaCount;
}
else
{
// Generally avoiding exposed areas when traversing a wide open area
const float exposurePenalty = neo_bot_path_penalty_exposure_base.GetFloat();
cost += visibleAreaCount * exposurePenalty;
}
}
}
}

if (m_routeType == SAFEST_ROUTE)
{
// NEO Jank Cheat: Incorporate enemy bot paths so that we don't run directly into their line of fire
Expand Down
12 changes: 6 additions & 6 deletions src/game/server/neo/bot/neo_bot_path_reservation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ ConVar neo_bot_path_reservation_enable("neo_bot_path_reservation_enable", "1", F
"Enable the bot path reservation system.", true, 0, true, 1);

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

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

ConVar neo_bot_path_reservation_penalty("neo_bot_path_reservation_penalty", "100", FCVAR_NONE,
"Pathing cost penalty for a reserved area.", true, 0, true, 1000000);
ConVar neo_bot_path_reservation_penalty("neo_bot_path_reservation_penalty", "10000", FCVAR_NONE,
"Pathing cost penalty for a reserved area.", true, 0, false, 0);
Comment thread
sunzenshen marked this conversation as resolved.

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

ConVar neo_bot_path_reservation_onstuck_penalty("neo_bot_path_reservation_onstuck_penalty", "10000", FCVAR_NONE,
ConVar neo_bot_path_reservation_onstuck_penalty("neo_bot_path_reservation_onstuck_penalty", "1000", FCVAR_NONE,
Comment thread
sunzenshen marked this conversation as resolved.
"Path selection penalty added to a nav area each time a bot gets stuck moving through that area.", true, 0, false, 0);


Expand Down
Loading