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
135 changes: 135 additions & 0 deletions src/game/server/neo/bot/behavior/neo_bot_behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ ConVar neo_bot_fire_weapon_allowed( "neo_bot_fire_weapon_allowed", "1", FCVAR_CH

ConVar neo_bot_allow_retreat( "neo_bot_allow_retreat", "1", FCVAR_CHEAT, "If zero, bots will not attempt to retreat if they are are in a bad situation." );

ConVar neo_bot_recon_superjump_min_dist( "neo_bot_recon_superjump_min_dist", "1000", FCVAR_NONE,
"Minimum straight-line path distance required for a Recon bot to super jump while moving", true, 0, false, 0 );

ConVar neo_bot_recon_superjump_min_accuracy( "neo_bot_recon_superjump_min_accuracy", "0.95", FCVAR_NONE,
"Minimum directional alignment with path required for a Recon bot to super jump while moving", true, 0.1f, false, 1.0f );

//---------------------------------------------------------------------------------------------
Action< CNEOBot > *CNEOBotMainAction::InitialContainedAction( CNEOBot *me )
{
Expand Down Expand Up @@ -176,6 +182,8 @@ ActionResult< CNEOBot > CNEOBotMainAction::Update( CNEOBot *me, float interval )

me->RepathIfFriendlyBlockingLineOfFire();

ReconConsiderSuperJump( me );

return Continue();
}

Expand Down Expand Up @@ -359,6 +367,133 @@ Vector CNEOBotMainAction::SelectTargetPoint( const INextBot *meBot, const CBaseC
}


//-----------------------------------------------------------------------------------------
void CNEOBotMainAction::ReconConsiderSuperJump( CNEOBot *me )
{
CNEO_Player *pNeoMe = ToNEOPlayer(me);
if ( !pNeoMe || pNeoMe->GetClass() != NEO_CLASS_RECON )
{
return;
}

// Check that bot isn't only moving sideways which wastes aux power
// Also determines a direction to jump towards
// NEO Jank: We don't check sprint here because bots don't anticipate using sprint in a smart manner
if ( ( pNeoMe->m_nButtons & ( IN_FORWARD | IN_BACK ) ) == 0 )
{
// Remove this check if we add sideways super jump in the future
return;
}

if (!pNeoMe->IsAllowedToSuperJump())
{
return;
}

bool bImmediateDanger = gpGlobals->curtime - pNeoMe->GetLastDamageTime() <= 2.0f;

if (!bImmediateDanger
&& (pNeoMe->m_nButtons & IN_FORWARD)
&& (neo_bot_recon_superjump_min_dist.GetFloat() > 1))
{
if (!m_reconSuperJumpPathCheckTimer.IsElapsed())
{
return;
}
m_reconSuperJumpPathCheckTimer.Start(1.0f);

const PathFollower *path = me->GetCurrentPath();
if (!path || !path->IsValid())
{
return;
}

const Path::Segment *seg = path->GetCurrentGoal();
if (!seg)
{
return;
}

// Get the bot motion to know which direction the jump will be boosted
Vector vecMovement = me->GetLocomotionInterface()->GetGroundMotionVector();
vecMovement.z = 0.0f;
vecMovement.NormalizeInPlace();

// Get the bot's facing direction
Vector vecFacing;
pNeoMe->EyeVectors( &vecFacing );
vecFacing.z = 0.0f;
vecFacing.NormalizeInPlace();

if (vecMovement.Dot(vecFacing) < neo_bot_recon_superjump_min_accuracy.GetFloat())
{
return;
}

// Check that upcoming path is in line of a jump
bool bCanJump = false;
while (seg)
{
constexpr int maskAttributesToStopPathEval = (
NAV_MESH_AVOID |
NAV_MESH_CLIFF |
NAV_MESH_CROUCH |
NAV_MESH_HAS_ELEVATOR |
NAV_MESH_JUMP | // likely to interrupt superjump trajectory
NAV_MESH_NAV_BLOCKER |
NAV_MESH_NO_JUMP |
NAV_MESH_OBSTACLE_TOP |
NAV_MESH_PRECISE |
NAV_MESH_STAIRS |
NAV_MESH_STOP |
NAV_MESH_TRANSIENT
);

if (seg->area && seg->area->HasAttributes( maskAttributesToStopPathEval ))
{
return; // Don't superjump toward areas with potentially problematic attributes
}

// Sanity check that each waypoint is relatively aligned with our jump direction
Vector vecToWaypoint = seg->pos - pNeoMe->GetAbsOrigin();
vecToWaypoint.z = 0.0f;

float flDist = vecToWaypoint.NormalizeInPlace();

if (vecMovement.Dot(vecToWaypoint) < neo_bot_recon_superjump_min_accuracy.GetFloat())
{
return; // Diverges too much from trajectory
}

if (flDist >= neo_bot_recon_superjump_min_dist.GetFloat())
{
bCanJump = true;
break;
}
else if (flDist < 0)
{
return; // Just in case of a bad value
}

seg = path->NextSegment(seg);
}

if (!bCanJump)
{
return;
}
}

// NEO Jank: We allow bots to super jump even if they didn't perform the prerequisite inputs
// For example, they don't consistently hold sprint when it's appropriate so we just boost their speed
me->GetLocomotionInterface()->Run();
me->PressRunButton();
me->GetLocomotionInterface()->Jump();
me->PressJumpButton();
me->SuperJump();
}


//---------------------------------------------------------------------------------------------
/**
* Allow bot to approve of positions game movement tries to put him into.
Expand Down
2 changes: 2 additions & 0 deletions src/game/server/neo/bot/behavior/neo_bot_behavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class CNEOBotMainAction : public Action< CNEOBot >, public CNEOBotContextualQuer

private:
CountdownTimer m_reloadTimer;
CountdownTimer m_reconSuperJumpPathCheckTimer;
mutable CountdownTimer m_aimAdjustTimer;
mutable float m_aimErrorRadius;
mutable float m_aimErrorAngle;
Expand Down Expand Up @@ -67,6 +68,7 @@ class CNEOBotMainAction : public Action< CNEOBot >, public CNEOBotContextualQuer


void Dodge( CNEOBot *me );
void ReconConsiderSuperJump(CNEOBot *me);

IntervalTimer m_undergroundTimer;

Expand Down
134 changes: 0 additions & 134 deletions src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,138 +177,6 @@ void CNEOBotTacticalMonitor::AvoidBumpingFriends( CNEOBot *me )
}


ConVar neo_bot_recon_superjump_min_dist( "neo_bot_recon_superjump_min_dist", "1000", FCVAR_NONE,
"Minimum straight-line path distance required for a Recon bot to super jump while moving", true, 0, false, 0 );

ConVar neo_bot_recon_superjump_min_accuracy( "neo_bot_recon_superjump_min_accuracy", "0.95", FCVAR_NONE,
"Minimum directional alignment with path required for a Recon bot to super jump while moving", true, 0.1f, false, 1.0f );

//-----------------------------------------------------------------------------------------
void CNEOBotTacticalMonitor::ReconConsiderSuperJump( CNEOBot *me )
{
CNEO_Player *pNeoMe = ToNEOPlayer(me);
if ( !pNeoMe || pNeoMe->GetClass() != NEO_CLASS_RECON )
{
return;
}

// Check that bot isn't only moving sideways which wastes aux power
// Also determines a direction to jump towards
// NEO Jank: We don't check sprint here because bots don't anticipate using sprint in a smart manner
if ( ( pNeoMe->m_nButtons & ( IN_FORWARD | IN_BACK ) ) == 0 )
{
// Remove this check if we add sideways super jump in the future
return;
}

if (!pNeoMe->IsAllowedToSuperJump())
{
return;
}

bool bImmediateDanger = gpGlobals->curtime - pNeoMe->GetLastDamageTime() <= 2.0f;

if (!bImmediateDanger
&& (pNeoMe->m_nButtons & IN_FORWARD)
&& (neo_bot_recon_superjump_min_dist.GetFloat() > 1))
{
if (!m_reconSuperJumpPathCheckTimer.IsElapsed())
{
return;
}
m_reconSuperJumpPathCheckTimer.Start(1.0f);

const PathFollower *path = me->GetCurrentPath();
if (!path || !path->IsValid())
{
return;
}

const Path::Segment *seg = path->GetCurrentGoal();
if (!seg)
{
return;
}

// Get the bot motion to know which direction the jump will be boosted
Vector vecMovement = me->GetLocomotionInterface()->GetGroundMotionVector();
vecMovement.z = 0.0f;
vecMovement.NormalizeInPlace();

// Get the bot's facing direction
Vector vecFacing;
pNeoMe->EyeVectors( &vecFacing );
vecFacing.z = 0.0f;
vecFacing.NormalizeInPlace();

if (vecMovement.Dot(vecFacing) < neo_bot_recon_superjump_min_accuracy.GetFloat())
{
return;
}

// Check that upcoming path is in line of a jump
bool bCanJump = false;
while (seg)
{
constexpr int maskAttributesToStopPathEval = (
NAV_MESH_AVOID |
NAV_MESH_CLIFF |
NAV_MESH_CROUCH |
NAV_MESH_HAS_ELEVATOR |
NAV_MESH_JUMP | // likely to interrupt superjump trajectory
NAV_MESH_NAV_BLOCKER |
NAV_MESH_NO_JUMP |
NAV_MESH_OBSTACLE_TOP |
NAV_MESH_PRECISE |
NAV_MESH_STAIRS |
NAV_MESH_STOP |
NAV_MESH_TRANSIENT
);

if (seg->area && seg->area->HasAttributes( maskAttributesToStopPathEval ))
{
return; // Don't superjump toward areas with potentially problematic attributes
}

// Sanity check that each waypoint is relatively aligned with our jump direction
Vector vecToWaypoint = seg->pos - pNeoMe->GetAbsOrigin();
vecToWaypoint.z = 0.0f;

float flDist = vecToWaypoint.NormalizeInPlace();

if (vecMovement.Dot(vecToWaypoint) < neo_bot_recon_superjump_min_accuracy.GetFloat())
{
return; // Diverges too much from trajectory
}

if (flDist >= neo_bot_recon_superjump_min_dist.GetFloat())
{
bCanJump = true;
break;
}
else if (flDist < 0)
{
return; // Just in case of a bad value
}

seg = path->NextSegment(seg);
}

if (!bCanJump)
{
return;
}
}

// NEO Jank: We allow bots to super jump even if they didn't perform the prerequisite inputs
// For example, they don't consistently hold sprint when it's appropriate so we just boost their speed
me->GetLocomotionInterface()->Run();
me->PressRunButton();
me->GetLocomotionInterface()->Jump();
me->PressJumpButton();
me->SuperJump();
}


//-----------------------------------------------------------------------------------------
ActionResult< CNEOBot > CNEOBotTacticalMonitor::WatchForLadders( CNEOBot *me )
Expand Down Expand Up @@ -363,8 +231,6 @@ ActionResult< CNEOBot > CNEOBotTacticalMonitor::Update( CNEOBot *me, float inter
}
}

ReconConsiderSuperJump( me );

CBaseEntity *dangerousGrenade = CNEOBotRetreatFromGrenade::FindDangerousGrenade( me );
if ( dangerousGrenade )
{
Expand Down
2 changes: 0 additions & 2 deletions src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class CNEOBotTacticalMonitor : public Action< CNEOBot >

private:
CountdownTimer m_maintainTimer;
CountdownTimer m_reconSuperJumpPathCheckTimer;

CountdownTimer m_acknowledgeAttentionTimer;
CountdownTimer m_acknowledgeRetryTimer;
Expand All @@ -35,6 +34,5 @@ class CNEOBotTacticalMonitor : public Action< CNEOBot >
ActionResult< CNEOBot > ScavengeForPrimaryWeapon(CNEOBot* me);

void AvoidBumpingFriends(CNEOBot* me);
void ReconConsiderSuperJump(CNEOBot *me);
ActionResult< CNEOBot > WatchForLadders(CNEOBot* me);
};
Loading