diff --git a/src/game/server/neo/bot/behavior/neo_bot_ctg_capture.cpp b/src/game/server/neo/bot/behavior/neo_bot_ctg_capture.cpp index d6ee9d542..054b9421e 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_ctg_capture.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_ctg_capture.cpp @@ -56,7 +56,9 @@ ActionResult CNEOBotCtgCapture::Update( CNEOBot *me, float interval ) { if ( !CNEOBotPathCompute( me, m_path, m_hObjective->GetAbsOrigin(), FASTEST_ROUTE ) ) { - return Done( "Unable to find a path to the ghost capture target" ); + // Something has gone wrong if we can't path to a ghost that we by convention started close to + // Transition to search around the ghost behavior to avoid cycle of ghost search failure and retry attempts + return ChangeTo( new CNEOBotCtgLoneWolf(), "Unable to find a path to the ghost capture target, searching around nearest areas" ); } m_repathTimer.Start( RandomFloat( 0.3f, 0.6f ) ); } @@ -84,7 +86,9 @@ ActionResult CNEOBotCtgCapture::Update( CNEOBot *me, float interval ) if ( m_captureAttemptTimer.IsElapsed() ) { - return ChangeTo( new CNEOBotSeekWeapon, "Failed to capture ghost in time" ); + // If the bot fails to capture the ghost, it's sometimes because the ghost is lodged into an awkward position + // Have the bot search around the location instead, to avoid cycle of failing to pick up ghost and retrying + return ChangeTo( new CNEOBotCtgLoneWolf(), "Failed to pick up ghost in time, searching around nearest areas" ); } return Continue(); diff --git a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp index 060824007..0313121be 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.cpp @@ -2,6 +2,8 @@ #include "neo_player.h" #include "bot/neo_bot.h" #include "bot/behavior/neo_bot_attack.h" +#include "bot/behavior/neo_bot_ctg_enemy.h" +#include "bot/behavior/neo_bot_ctg_escort.h" #include "bot/behavior/neo_bot_ctg_lone_wolf.h" #include "bot/behavior/neo_bot_ctg_lone_wolf_ambush.h" #include "bot/behavior/neo_bot_ctg_lone_wolf_seek.h" @@ -23,6 +25,12 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolf::OnStart( CNEOBot *me, Action< CNEOBo //--------------------------------------------------------------------------------------------- ActionResult< CNEOBot > CNEOBotCtgLoneWolf::Update( CNEOBot *me, float interval ) { + ActionResult< CNEOBot > result = ConsiderGhostCaptureTransition( me ); + if ( result.IsRequestingChange() ) + { + return result; + } + if ( me->DropGhost() ) { return Continue(); // ghost drop in progress @@ -142,6 +150,39 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolf::ConsiderGhostVisualCheck( CNEOBot *m } +//--------------------------------------------------------------------------------------------- +ActionResult< CNEOBot > CNEOBotCtgLoneWolf::ConsiderGhostCaptureTransition( CNEOBot *me ) +{ + if (NEORules()->GhostExists()) + { + int iGhosterPlayer = NEORules()->GetGhosterPlayer(); + if (iGhosterPlayer > 0 && iGhosterPlayer <= gpGlobals->maxClients) + { + CNEO_Player* pGhostCarrier = ToNEOPlayer(UTIL_PlayerByIndex(iGhosterPlayer)); + if (pGhostCarrier && pGhostCarrier != me) + { + // We sometimes flow into CNEOBotCtgLoneWolf if this bot failed to get the ghost + // Use ChangeTo to reset scenario evaluation after reacting to ghost pickup + if (pGhostCarrier->GetTeamNumber() == me->GetTeamNumber()) + { + return ChangeTo(new CNEOBotCtgEscort, "Protect teammate that had better luck capturing ghost"); + } + else + { + return ChangeTo(new CNEOBotCtgEnemy, "Intercepting the ghost carrier!"); + } + } + } + } + else + { + return Done("No ghost exists, exiting behavior to reevaluate situation."); + } + + return Continue(); +} + + //--------------------------------------------------------------------------------------------- ActionResult< CNEOBot > CNEOBotCtgLoneWolf::OnSuspend( CNEOBot *me, Action< CNEOBot > *interruptingAction ) { diff --git a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.h b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.h index a38f6e337..9070f34dd 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.h +++ b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf.h @@ -20,6 +20,7 @@ class CNEOBotCtgLoneWolf : public Action< CNEOBot > protected: virtual ActionResult< CNEOBot > ConsiderGhostInterception( CNEOBot *me, const CBaseCombatCharacter *pGhostOwner = nullptr ); virtual ActionResult< CNEOBot > ConsiderGhostVisualCheck( CNEOBot *me ); + virtual ActionResult< CNEOBot > ConsiderGhostCaptureTransition( CNEOBot *me ); Vector GetNearestEnemyCapPoint( CNEOBot *me ) const; diff --git a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_ambush.cpp b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_ambush.cpp index 2264071ea..639d0730e 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_ambush.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_ambush.cpp @@ -29,6 +29,12 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolfAmbush::OnStart( CNEOBot *me, Action< //--------------------------------------------------------------------------------------------- ActionResult< CNEOBot > CNEOBotCtgLoneWolfAmbush::Update( CNEOBot *me, float interval ) { + ActionResult< CNEOBot > result = ConsiderGhostCaptureTransition( me ); + if ( result.IsRequestingChange() ) + { + return result; + } + CWeaponGhost *pGhost = NEORules()->m_pGhost; if ( !pGhost ) { diff --git a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_seek.cpp b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_seek.cpp index b5f40b25e..1a8e7429e 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_seek.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_ctg_lone_wolf_seek.cpp @@ -106,6 +106,12 @@ ActionResult< CNEOBot > CNEOBotCtgLoneWolfSeek::OnStart( CNEOBot *me, Action< CN //--------------------------------------------------------------------------------------------- ActionResult< CNEOBot > CNEOBotCtgLoneWolfSeek::Update( CNEOBot *me, float interval ) { + ActionResult< CNEOBot > result = ConsiderGhostCaptureTransition( me ); + if ( result.IsRequestingChange() ) + { + return result; + } + me->PressCrouchButton( 0.2f ); // Keep a lower profile if ( !NEORules()->GhostExists() || !NEORules()->m_pGhost ) diff --git a/src/game/server/neo/bot/behavior/neo_bot_ctg_seek.cpp b/src/game/server/neo/bot/behavior/neo_bot_ctg_seek.cpp index e7134f5fb..8f321c502 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_ctg_seek.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_ctg_seek.cpp @@ -89,7 +89,7 @@ ActionResult< CNEOBot > CNEOBotCtgSeek::Update( CNEOBot *me, float interval ) } else { - return Done("Capture target was not a ghost"); + return SuspendFor(new CNEOBotCtgLoneWolf, "Capture target is blocked by some other entity, searching around the nearest areas"); } } }