diff --git a/sp/src/game/server/ai_hint.cpp b/sp/src/game/server/ai_hint.cpp index 2e8e90af..e9844a01 100644 --- a/sp/src/game/server/ai_hint.cpp +++ b/sp/src/game/server/ai_hint.cpp @@ -1325,7 +1325,7 @@ bool CAI_Hint::HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hint if ( distance > nRadius * nRadius ) { - REPORTFAILURE( "NPC is not within the node's radius." ); + REPORTFAILURE( "Not within the node's radius." ); return false; } } @@ -1794,6 +1794,11 @@ hinttypedescs_t g_pszHintDescriptions[] = { HINT_HL1_WORLD_ALIEN_BLOOD, "HL1: World: Alien Blood" }, { HINT_CSTRIKE_HOSTAGE_ESCAPE, "CS Port: Hostage Escape" }, + +#ifdef MAPBASE + { HINT_TACTICAL_COVER_CUSTOM, "Mapbase: Custom Cover" }, + { HINT_TACTICAL_GRENADE_THROW, "Mapbase: Grenade Throw Hint" }, +#endif }; //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/ai_hint.h b/sp/src/game/server/ai_hint.h index 570f85ef..fc23f9c3 100644 --- a/sp/src/game/server/ai_hint.h +++ b/sp/src/game/server/ai_hint.h @@ -118,6 +118,7 @@ enum Hint_e // (these start at a high number to avoid potential conflicts with mod hints) HINT_TACTICAL_COVER_CUSTOM = 10000, // Cover node with a custom hint activity (NPCs can take cover and reload here while playing said activity) + HINT_TACTICAL_GRENADE_THROW, // Pre-determined position for NPCs to throw grenades at when their target in combat is near it #endif }; const char *GetHintTypeDescription( Hint_e iHintType ); diff --git a/sp/src/game/server/mapbase/ai_grenade.h b/sp/src/game/server/mapbase/ai_grenade.h index 543969c2..d2e02839 100644 --- a/sp/src/game/server/mapbase/ai_grenade.h +++ b/sp/src/game/server/mapbase/ai_grenade.h @@ -138,6 +138,8 @@ public: void ClearAttackConditions( void ); + bool FValidateHintType( CAI_Hint *pHint ); + Vector GetAltFireTarget() { return m_vecAltFireTarget; } virtual bool CanAltFireEnemy( bool bUseFreeKnowledge ); void DelayAltFireAttack( float flDelay ); @@ -558,6 +560,29 @@ bool CAI_GrenadeUser::CanThrowGrenade( const Vector &vecTarget ) } } + CHintCriteria hintCriteria; + hintCriteria.SetHintType( HINT_TACTICAL_GRENADE_THROW ); + hintCriteria.SetFlag( bits_HINT_NPC_IN_NODE_FOV ); + hintCriteria.SetGroup( this->GetHintGroup() ); + hintCriteria.AddIncludePosition( this->GetAbsOrigin(), 1024 ); + + if (this->m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) + hintCriteria.SetFlag( bits_HINT_NODE_REPORT_FAILURES ); + + // If there's a grenade throw hint nearby, try using it + CAI_Hint *pHint = CAI_HintManager::FindHint( this, vecTarget, hintCriteria ); + if ( pHint ) + { + if ( CheckCanThrowGrenade( pHint->GetAbsOrigin() ) ) + { + return true; + } + else + { + DevMsg( this, "Unable to throw grenade at hint %s\n", pHint->GetDebugName() ); + } + } + return CheckCanThrowGrenade( vecTarget ); } @@ -636,6 +661,18 @@ void CAI_GrenadeUser::ClearAttackConditions() } } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +template +bool CAI_GrenadeUser::FValidateHintType( CAI_Hint *pHint ) +{ + if ( pHint->HintType() == HINT_TACTICAL_GRENADE_THROW ) + return true; + + return BaseClass::FValidateHintType( pHint ); +} + //----------------------------------------------------------------------------- // Purpose: Drops grenades and alt-fire items on death. Based on code from npc_combines.cpp and npc_combine.cpp //-----------------------------------------------------------------------------