Skip to content

Commit 13819e4

Browse files
committed
Lone bots deploy detpack ambush at ghost
1 parent 8177887 commit 13819e4

File tree

8 files changed

+488
-72
lines changed

8 files changed

+488
-72
lines changed

src/game/server/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,8 @@ target_sources_grouped(
14511451
neo/bot/behavior/neo_bot_ctg_escort.h
14521452
neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp
14531453
neo/bot/behavior/neo_bot_ctg_lone_wolf.h
1454+
neo/bot/behavior/neo_bot_ctg_lone_wolf_ambush.cpp
1455+
neo/bot/behavior/neo_bot_ctg_lone_wolf_ambush.h
14541456
neo/bot/behavior/neo_bot_ctg_seek.cpp
14551457
neo/bot/behavior/neo_bot_ctg_seek.h
14561458
neo/bot/behavior/neo_bot_dead.cpp

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

Lines changed: 84 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
#include "bot/behavior/neo_bot_attack.h"
55
#include "bot/behavior/neo_bot_ctg_capture.h"
66
#include "bot/behavior/neo_bot_ctg_lone_wolf.h"
7+
#include "bot/behavior/neo_bot_ctg_lone_wolf_ambush.h"
78
#include "bot/behavior/neo_bot_seek_weapon.h"
89
#include "bot/behavior/neo_bot_retreat_to_cover.h"
910
#include "bot/neo_bot_path_compute.h"
1011
#include "neo_gamerules.h"
1112
#include "neo_ghost_cap_point.h"
13+
#include "weapon_detpack.h"
1214
#include "weapon_ghost.h"
1315

1416

@@ -17,7 +19,6 @@ CNEOBotCtgLoneWolf::CNEOBotCtgLoneWolf( void )
1719
{
1820
m_hGhost = nullptr;
1921
m_bPursuingDropThreat = false;
20-
m_bHasRetreatedFromGhost = false;
2122
m_vecDropThreatPos = CNEO_Player::VECTOR_INVALID_WAYPOINT;
2223
m_closestCapturePoint = CNEO_Player::VECTOR_INVALID_WAYPOINT;
2324
}
@@ -26,7 +27,7 @@ CNEOBotCtgLoneWolf::CNEOBotCtgLoneWolf( void )
2627
ActionResult< CNEOBot > CNEOBotCtgLoneWolf::OnStart( CNEOBot *me, Action< CNEOBot > *priorAction )
2728
{
2829
m_hGhost = nullptr;
29-
m_bHasRetreatedFromGhost = false;
30+
m_hPursueTarget = nullptr;
3031
m_bPursuingDropThreat = false;
3132
m_useAttemptTimer.Invalidate();
3233
m_lookAroundTimer.Invalidate();
@@ -35,7 +36,6 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolf::OnStart( CNEOBot *me, Action< CNEOBo
3536
m_capPointUpdateTimer.Invalidate();
3637
m_vecDropThreatPos = CNEO_Player::VECTOR_INVALID_WAYPOINT;
3738
m_closestCapturePoint = CNEO_Player::VECTOR_INVALID_WAYPOINT;
38-
m_hPursueTarget = nullptr;
3939

4040
return Continue();
4141
}
@@ -87,42 +87,15 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolf::Update( CNEOBot *me, float interval
8787
}
8888

8989
// Always need to find the ghost to act on it
90-
if (!m_hGhost)
91-
{
92-
m_hGhost = dynamic_cast<CWeaponGhost*>( gEntList.FindEntityByClassname(nullptr, "weapon_ghost") );
93-
}
94-
95-
if (!m_hGhost)
90+
if ( !UpdateGhostHandle( me ) )
9691
{
9792
return Done( "Ghost not found" );
9893
}
9994

10095
// Occasionally reconsider which cap zone is our goal
10196
if ( !m_capPointUpdateTimer.HasStarted() || m_capPointUpdateTimer.IsElapsed() )
10297
{
103-
m_closestCapturePoint = CNEO_Player::VECTOR_INVALID_WAYPOINT;
104-
float flNearestCapDistSq = FLT_MAX;
105-
106-
if ( NEORules()->m_pGhostCaps.Count() > 0 )
107-
{
108-
const Vector& vecStart = me->IsCarryingGhost() ? me->GetAbsOrigin() : m_hGhost->GetAbsOrigin();
109-
110-
for( int i=0; i<NEORules()->m_pGhostCaps.Count(); ++i )
111-
{
112-
CNEOGhostCapturePoint *pCapPoint = dynamic_cast<CNEOGhostCapturePoint*>( UTIL_EntityByIndex( NEORules()->m_pGhostCaps[i] ) );
113-
if ( !pCapPoint ) continue;
114-
115-
if ( pCapPoint->owningTeamAlternate() == me->GetTeamNumber() )
116-
{
117-
float distSq = vecStart.DistToSqr( pCapPoint->GetAbsOrigin() );
118-
if ( distSq < flNearestCapDistSq )
119-
{
120-
flNearestCapDistSq = distSq;
121-
m_closestCapturePoint = pCapPoint->GetAbsOrigin();
122-
}
123-
}
124-
}
125-
}
98+
m_closestCapturePoint = GetNearestCapturePoint( me, false );
12699
m_capPointUpdateTimer.Start( RandomFloat( 0.5f, 1.0f ) );
127100
}
128101

@@ -294,11 +267,20 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolf::Update( CNEOBot *me, float interval
294267
// Ghost is free for taking
295268
if ( bSafeToCap || (bIs1v1 && m_stalemateTimer.HasStarted() && m_stalemateTimer.IsElapsed()) )
296269
{
297-
// Try to cap before enemy can stop us.
298270
float flDistToGhostSq = me->GetAbsOrigin().DistToSqr(m_hGhost->GetAbsOrigin());
299-
if ( flDistToGhostSq < 100.0f * 100.0f )
271+
float flAmbushDistSq = CNEOBotCtgLoneWolf::GetDetpackDeployDistanceSq( me );
272+
273+
if ( flDistToGhostSq < flAmbushDistSq)
300274
{
301-
return SuspendFor(new CNEOBotCtgCapture(m_hGhost.Get()), "Picking up ghost to make a run for it!");
275+
if ( !bSafeToCap && me->Weapon_OwnsThisType("weapon_remotedet") )
276+
{
277+
return ChangeTo(new CNEOBotCtgLoneWolfAmbush(), "Setting up detpack ambush at ghost");
278+
}
279+
else
280+
{
281+
// Try to cap before enemy can stop us.
282+
return SuspendFor(new CNEOBotCtgCapture(m_hGhost.Get()), "Picking up ghost to make a run for it!");
283+
}
302284
}
303285

304286
if ( !m_repathTimer.HasStarted() || m_repathTimer.IsElapsed() )
@@ -323,40 +305,27 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolf::Update( CNEOBot *me, float interval
323305
m_stalemateTimer.Start( RandomFloat( 10.0f, 20.0f ) );
324306
}
325307

326-
if ( m_bHasRetreatedFromGhost )
308+
// Hide out of sight of ghost to ambush anyone that picks up the ghost
309+
float flDistToGhostSq = me->GetAbsOrigin().DistToSqr(m_hGhost->GetAbsOrigin());
310+
float flAmbushDistSq = CNEOBotCtgLoneWolf::GetDetpackDeployDistanceSq( me );
311+
if (flDistToGhostSq < flAmbushDistSq)
327312
{
328-
// Waiting in ambush/cover
329-
if (threat && me->IsLineOfFireClear( threat->GetEntity()->WorldSpaceCenter(), CNEOBot::LINE_OF_FIRE_FLAGS_DEFAULT ))
330-
{
331-
me->EnableCloak( 3.0f );
332-
return SuspendFor(new CNEOBotAttack, "Ambushing enemy near ghost!");
333-
}
334-
return UpdateLookAround( me, m_hGhost->GetAbsOrigin() );
313+
return ChangeTo(new CNEOBotCtgLoneWolfAmbush(), "Setting up ambush near the ghost");
335314
}
336315
else
337316
{
338-
// Hide out of sight of ghost to ambush anyone that picks up the ghost
339-
float flDistToGhostSq = me->GetAbsOrigin().DistToSqr(m_hGhost->GetAbsOrigin());
340-
if (flDistToGhostSq < 300.0f * 300.0f)
317+
// Get near the ghost first before surveying hiding spots
318+
if ( !m_repathTimer.HasStarted() || m_repathTimer.IsElapsed() )
341319
{
342-
m_bHasRetreatedFromGhost = true;
343-
return SuspendFor(new CNEOBotRetreatToCover(), "Finding a hiding spot near the ghost");
320+
CNEOBotPathCompute(me, m_path, m_hGhost->GetAbsOrigin(), FASTEST_ROUTE);
321+
m_path.Update(me);
322+
m_repathTimer.Start( RandomFloat( 0.5f, 1.0f ) );
344323
}
345324
else
346325
{
347-
// Get near the ghost first before surveying hiding spots
348-
if ( !m_repathTimer.HasStarted() || m_repathTimer.IsElapsed() )
349-
{
350-
CNEOBotPathCompute(me, m_path, m_hGhost->GetAbsOrigin(), FASTEST_ROUTE);
351-
m_path.Update(me);
352-
m_repathTimer.Start( RandomFloat( 0.5f, 1.0f ) );
353-
}
354-
else
355-
{
356-
m_path.Update(me);
357-
}
358-
return Continue();
326+
m_path.Update(me);
359327
}
328+
return Continue();
360329
}
361330
}
362331
}
@@ -417,7 +386,50 @@ EventDesiredResult< CNEOBot > CNEOBotCtgLoneWolf::OnMoveToFailure( CNEOBot *me,
417386
return TryContinue();
418387
}
419388

389+
//---------------------------------------------------------------------------------------------
390+
Vector CNEOBotCtgLoneWolf::GetNearestCapturePoint( CNEOBot *me, bool bEnemyCapPoint )
391+
{
392+
Vector vecBestCapPoint = CNEO_Player::VECTOR_INVALID_WAYPOINT;
393+
float flNearestCapDistSq = FLT_MAX;
394+
395+
if ( NEORules()->m_pGhostCaps.Count() > 0 )
396+
{
397+
const Vector& vecStart = me->IsCarryingGhost() ? me->GetAbsOrigin() : ( m_hGhost.Get() ? m_hGhost->GetAbsOrigin() : me->GetAbsOrigin() );
398+
399+
for( int i=0; i<NEORules()->m_pGhostCaps.Count(); ++i )
400+
{
401+
CNEOGhostCapturePoint *pCapPoint = dynamic_cast<CNEOGhostCapturePoint*>( UTIL_EntityByIndex( NEORules()->m_pGhostCaps[i] ) );
402+
if ( !pCapPoint ) continue;
403+
404+
bool bValidTeam = (pCapPoint->owningTeamAlternate() == me->GetTeamNumber());
405+
if ( bEnemyCapPoint )
406+
{
407+
bValidTeam = (pCapPoint->owningTeamAlternate() != me->GetTeamNumber());
408+
}
420409

410+
if ( bValidTeam )
411+
{
412+
float distSq = vecStart.DistToSqr( pCapPoint->GetAbsOrigin() );
413+
if ( distSq < flNearestCapDistSq )
414+
{
415+
flNearestCapDistSq = distSq;
416+
vecBestCapPoint = pCapPoint->GetAbsOrigin();
417+
}
418+
}
419+
}
420+
}
421+
422+
return vecBestCapPoint;
423+
}
424+
425+
//---------------------------------------------------------------------------------------------
426+
float CNEOBotCtgLoneWolf::GetDetpackDeployDistanceSq( CNEOBot *me )
427+
{
428+
float flArmingTime = CWeaponDetpack::GetArmingTime();
429+
return Square( MAX( 100.0f, flArmingTime * me->GetNormSpeed() ) );
430+
}
431+
432+
//---------------------------------------------------------------------------------------------
421433
// Helper for "UpdateLookAround" - inspired from how CNavArea CollectPotentiallyVisibleAreas works
422434
class CCollectPotentiallyVisibleAreas
423435
{
@@ -437,7 +449,18 @@ class CCollectPotentiallyVisibleAreas
437449
};
438450

439451
//---------------------------------------------------------------------------------------------
440-
ActionResult< CNEOBot > CNEOBotCtgLoneWolf::UpdateLookAround( CNEOBot *me, const Vector &anchorPos )
452+
bool CNEOBotCtgLoneWolf::UpdateGhostHandle( CNEOBot *me )
453+
{
454+
if ( !m_hGhost )
455+
{
456+
m_hGhost = dynamic_cast<CWeaponGhost*>( gEntList.FindEntityByClassname( nullptr, "weapon_ghost" ) );
457+
}
458+
459+
return ( m_hGhost != nullptr );
460+
}
461+
462+
//---------------------------------------------------------------------------------------------
463+
ActionResult< CNEOBot > CNEOBotCtgLoneWolf::UpdateLookAround( CNEOBot *me )
441464
{
442465
if ( !m_lookAroundTimer.HasStarted() || m_lookAroundTimer.IsElapsed() )
443466
{

src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,28 @@ class CNEOBotCtgLoneWolf : public Action< CNEOBot >
1919

2020
virtual const char *GetName( void ) const override { return "ctgLoneWolf"; }
2121

22-
private:
23-
PathFollower m_path;
22+
protected:
23+
static float GetDetpackDeployDistanceSq( CNEOBot *me );
24+
Vector GetNearestCapturePoint( CNEOBot *me, bool bEnemyCapPoint );
25+
bool UpdateGhostHandle( CNEOBot *me );
26+
ActionResult< CNEOBot > UpdateLookAround( CNEOBot *me );
27+
2428
CHandle<CWeaponGhost> m_hGhost;
2529
CountdownTimer m_repathTimer;
26-
CountdownTimer m_useAttemptTimer;
27-
bool m_bHasRetreatedFromGhost;
30+
PathFollower m_path;
2831

29-
Vector m_vecDropThreatPos;
30-
CHandle<CBaseEntity> m_hPursueTarget;
32+
private:
3133
bool m_bPursuingDropThreat;
3234

33-
ActionResult< CNEOBot > UpdateLookAround( CNEOBot *me, const Vector &anchorPos );
34-
CountdownTimer m_lookAroundTimer;
35-
CountdownTimer m_stalemateTimer;
35+
CHandle<CBaseEntity> m_hPursueTarget;
3636

3737
CountdownTimer m_capPointUpdateTimer;
38-
Vector m_closestCapturePoint;
38+
CountdownTimer m_lookAroundTimer;
39+
CountdownTimer m_stalemateTimer;
40+
CountdownTimer m_useAttemptTimer;
3941

4042
CUtlVector< CNavArea * > m_visibleAreas;
43+
44+
Vector m_closestCapturePoint;
45+
Vector m_vecDropThreatPos;
4146
};

0 commit comments

Comments
 (0)