diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/SharedFunctorUtils.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/shared/SharedFunctorUtils.h')
| -rw-r--r-- | game/shared/SharedFunctorUtils.h | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/game/shared/SharedFunctorUtils.h b/game/shared/SharedFunctorUtils.h new file mode 100644 index 0000000..a4e4c67 --- /dev/null +++ b/game/shared/SharedFunctorUtils.h @@ -0,0 +1,156 @@ +// SharedFunctorUtils.h +// Useful functors for client and server +//========= Copyright Valve Corporation, All rights reserved. ============// + +//-------------------------------------------------------------------------------------------------------- +/** +* NOTE: The functors in this file should ideally be game-independant, +* and work for any Source based game +*/ +//-------------------------------------------------------------------------------------------------------- +#ifndef _SHARED_FUNCTOR_UTILS_H_ +#define _SHARED_FUNCTOR_UTILS_H_ + +#include "debugoverlay_shared.h" +#include "vprof.h" + +//-------------------------------------------------------------------------------------------------------- +/** + * Finds visible player on given team that we are pointing at. + * "team" can be TEAM_ANY + * Use with ForEachPlayer() + */ +template < class PlayerType > +class TargetScan +{ +public: + TargetScan( PlayerType *me, int team, float aimTolerance = 0.01f, float maxRange = 2000.0f, float closestPointTestDistance = 50.0f, bool debug = false ) + { + m_me = me; + AngleVectors( m_me->EyeAngles(), &m_viewForward ); + m_team = team; + m_closeDot = 1.0f - aimTolerance; + m_bestDot = m_closeDot; + m_maxRange = maxRange; + m_target = NULL; + m_closestPointTestDistance = closestPointTestDistance; + m_debug = debug; + } + + + virtual bool operator() ( PlayerType *them ) + { + VPROF( "TargetScan()" ); + if ( them != m_me && + them->IsAlive() && + (m_team == TEAM_ANY || them->GetTeamNumber() == m_team) && + IsPotentialTarget( them ) ) + { + // move the start point out for determining closestPos, to help with close-in checks (healing, etc) + Vector closestPos; + Vector start = m_me->EyePosition(); + Vector end = start + m_viewForward * m_closestPointTestDistance; + Vector testPos; + CalcClosestPointOnLineSegment( them->WorldSpaceCenter(), start, end, testPos ); + + start = them->GetAbsOrigin(); + end = start; + end.z += them->CollisionProp()->OBBMaxs().z; + CalcClosestPointOnLineSegment( testPos, start, end, closestPos ); + if ( m_debug ) + { + NDebugOverlay::Cross3D( closestPos, 1, 255, 255, 255, true, -1.0f ); + NDebugOverlay::Line( end, start, 255, 0, 0, true, -1.0f ); + } + + Vector to = closestPos - m_me->EyePosition(); + to.NormalizeInPlace(); + + Vector meRangePoint, themRangePoint; + m_me->CollisionProp()->CalcNearestPoint( closestPos, &meRangePoint ); + them->CollisionProp()->CalcNearestPoint( meRangePoint, &themRangePoint ); + float range = meRangePoint.DistTo( themRangePoint ); + + if ( range > m_maxRange ) + { + // too far away + return true; + } + + float dot = ViewDot( to ); + if ( dot > m_closeDot ) + { + // target is within angle cone, check visibility + if ( IsTargetVisible( them ) ) + { + if ( dot >= m_bestDot ) + { + m_target = them; + m_bestDot = dot; + } + + m_allTargets.AddToTail( them ); + } + } + } + + return true; + } + + PlayerType *GetTarget( void ) const + { + return m_target; + } + + const CUtlVector< PlayerType * > &GetAllTargets( void ) const + { + return m_allTargets; + } + + float GetTargetDot( void ) const + { + return m_bestDot; + } + +protected: + /** + * Is the point in our FOV? + */ + virtual float ViewDot( const Vector &dir ) const + { + return DotProduct( m_viewForward, dir ); + } + + /** + * Is the given actor a visible target? + */ + virtual bool IsTargetVisible( PlayerType *them ) const + { + // The default check is a straight-up IsAbleToSee + return m_me->IsAbleToSee( them, CBaseCombatCharacter::DISREGARD_FOV ); // already have a dot product checking FOV + } + + /** + * Is the given player a possible target at all? + */ + virtual bool IsPotentialTarget( PlayerType *them ) const + { + return true; + } + + PlayerType *m_me; + Vector m_viewForward; + int m_team; + + float m_closeDot; + float m_bestDot; + float m_maxRange; + float m_closestPointTestDistance; + bool m_debug; + + PlayerType *m_target; + CUtlVector< PlayerType * > m_allTargets; +}; + + +#endif |