//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Hud locator element, helps direct the player to objects in the world // //=============================================================================// #include "cbase.h" #include "hudelement.h" #include "hud_numericdisplay.h" #include #include "hud.h" #include "hud_suitpower.h" #include "hud_macros.h" #include "iclientmode.h" #include #include #include "c_basehlplayer.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" #define LOCATOR_MATERIAL_JALOPY "vgui/icons/icon_jalopy" #define LOCATOR_MATERIAL_BIG_TICK "vgui/icons/tick_long" #define LOCATOR_MATERIAL_SMALL_TICK "vgui/icons/tick_short" ConVar hud_locator_alpha( "hud_locator_alpha", "230" ); ConVar hud_locator_fov("hud_locator_fov", "350" ); //----------------------------------------------------------------------------- // Purpose: Shows positions of objects relative to the player. //----------------------------------------------------------------------------- class CHudLocator : public CHudElement, public vgui::Panel { DECLARE_CLASS_SIMPLE( CHudLocator, vgui::Panel ); public: CHudLocator( const char *pElementName ); virtual ~CHudLocator( void ); virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); void VidInit( void ); bool ShouldDraw(); protected: void FillRect( int x, int y, int w, int h ); float LocatorXPositionForYawDiff( float yawDiff ); void DrawGraduations( float flYawPlayerFacing ); virtual void Paint(); private: void Reset( void ); int m_textureID_IconJalopy; int m_textureID_IconBigTick; int m_textureID_IconSmallTick; Vector m_vecLocation; }; using namespace vgui; #ifdef HL2_EPISODIC DECLARE_HUDELEMENT( CHudLocator ); #endif //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- CHudLocator::CHudLocator( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudLocator" ) { vgui::Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT ); m_textureID_IconJalopy = -1; m_textureID_IconSmallTick = -1; m_textureID_IconBigTick = -1; } CHudLocator::~CHudLocator( void ) { if ( vgui::surface() ) { if ( m_textureID_IconJalopy != -1 ) { vgui::surface()->DestroyTextureID( m_textureID_IconJalopy ); m_textureID_IconJalopy = -1; } if ( m_textureID_IconSmallTick != -1 ) { vgui::surface()->DestroyTextureID( m_textureID_IconSmallTick ); m_textureID_IconSmallTick = -1; } if ( m_textureID_IconBigTick != -1 ) { vgui::surface()->DestroyTextureID( m_textureID_IconBigTick ); m_textureID_IconBigTick = -1; } } } //----------------------------------------------------------------------------- // Purpose: // Input : *pScheme - //----------------------------------------------------------------------------- void CHudLocator::ApplySchemeSettings( vgui::IScheme *pScheme ) { BaseClass::ApplySchemeSettings(pScheme); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CHudLocator::VidInit( void ) { } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- bool CHudLocator::ShouldDraw( void ) { C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return false; if( pPlayer->GetVehicle() ) return false; if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_invalid ) return false; return true; } //----------------------------------------------------------------------------- // Purpose: Start with our background off //----------------------------------------------------------------------------- void CHudLocator::Reset( void ) { m_vecLocation = Vector( 0, 0, 0 ); } //----------------------------------------------------------------------------- // Purpose: Make it a bit more convenient to do a filled rect. //----------------------------------------------------------------------------- void CHudLocator::FillRect( int x, int y, int w, int h ) { int panel_x, panel_y, panel_w, panel_h; GetBounds( panel_x, panel_y, panel_w, panel_h ); vgui::surface()->DrawFilledRect( x, y, x+w, y+h ); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- float CHudLocator::LocatorXPositionForYawDiff( float yawDiff ) { float fov = hud_locator_fov.GetFloat() / 2; float remappedAngle = RemapVal( yawDiff, -fov, fov, -90, 90 ); float cosine = sin(DEG2RAD(remappedAngle)); int element_wide = GetWide(); float position = (element_wide>>1) + ((element_wide>>1) * cosine); return position; } //----------------------------------------------------------------------------- // Draw the tickmarks on the locator //----------------------------------------------------------------------------- #define NUM_GRADUATIONS 16.0f void CHudLocator::DrawGraduations( float flYawPlayerFacing ) { int icon_wide, icon_tall; int xPos, yPos; float fov = hud_locator_fov.GetFloat() / 2; if( m_textureID_IconBigTick == -1 ) { m_textureID_IconBigTick = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_IconBigTick, LOCATOR_MATERIAL_BIG_TICK, true, false ); } if( m_textureID_IconSmallTick == -1 ) { m_textureID_IconSmallTick = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_IconSmallTick, LOCATOR_MATERIAL_SMALL_TICK, true, false ); } int element_tall = GetTall(); // Height of the VGUI element surface()->DrawSetColor( 255, 255, 255, 255 ); // Tick Icons float angleStep = 360.0f / NUM_GRADUATIONS; bool tallLine = true; for( float angle = -180 ; angle <= 180 ; angle += angleStep ) { yPos = (element_tall>>1); if( tallLine ) { vgui::surface()->DrawSetTexture( m_textureID_IconBigTick ); vgui::surface()->DrawGetTextureSize( m_textureID_IconBigTick, icon_wide, icon_tall ); tallLine = false; } else { vgui::surface()->DrawSetTexture( m_textureID_IconSmallTick ); vgui::surface()->DrawGetTextureSize( m_textureID_IconSmallTick, icon_wide, icon_tall ); tallLine = true; } float flDiff = UTIL_AngleDiff( flYawPlayerFacing, angle ); if( fabs(flDiff) > fov ) continue; float xPosition = LocatorXPositionForYawDiff( flDiff ); xPos = (int)xPosition; xPos -= (icon_wide>>1); vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall); } } //----------------------------------------------------------------------------- // Purpose: draws the locator icons on the VGUI element. //----------------------------------------------------------------------------- void CHudLocator::Paint() { #ifdef HL2_EPISODIC if( m_textureID_IconJalopy == -1 ) { m_textureID_IconJalopy = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_IconJalopy, LOCATOR_MATERIAL_JALOPY, true, false ); } int alpha = hud_locator_alpha.GetInt(); SetAlpha( alpha ); C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return; if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_origin ) return; int element_tall = GetTall(); // Height of the VGUI element float fov = (hud_locator_fov.GetFloat()) / 2.0f; // Compute the relative position of objects we're tracking // We'll need the player's yaw for comparison. float flYawPlayerForward = pPlayer->EyeAngles().y; // Copy this value out of the member variable in case we decide to expand this // feature later and want to iterate some kind of list. Vector vecLocation = pPlayer->m_HL2Local.m_vecLocatorOrigin; Vector vecToLocation = vecLocation - pPlayer->GetAbsOrigin(); QAngle locationAngles; VectorAngles( vecToLocation, locationAngles ); float yawDiff = UTIL_AngleDiff( flYawPlayerForward, locationAngles.y ); bool bObjectInFOV = (yawDiff > -fov && yawDiff < fov); // Draw the icons! int icon_wide, icon_tall; int xPos, yPos; surface()->DrawSetColor( 255, 255, 255, 255 ); DrawGraduations( flYawPlayerForward ); if( bObjectInFOV ) { // The object's location maps to a valid position along the tape, so draw an icon. float tapePosition = LocatorXPositionForYawDiff(yawDiff); // derive a scale for the locator icon yawDiff = fabs(yawDiff); float scale = 1.0f; scale = RemapValClamped( yawDiff, (fov/4), fov, 1.0f, 0.25f ); vgui::surface()->DrawSetTexture( m_textureID_IconJalopy ); vgui::surface()->DrawGetTextureSize( m_textureID_IconJalopy, icon_wide, icon_tall ); float flIconWide = ((float)element_tall * 1.25f); float flIconTall = ((float)element_tall * 1.25f); // Scale the icon as desired... // Put back into ints icon_wide = (int)flIconWide; icon_tall = (int)flIconTall; icon_wide *= scale; //Msg("yawDiff:%f xPos:%d scale:%f\n", yawDiff, xPos, scale ); // Center the icon around its position. xPos = (int)tapePosition; xPos -= (icon_wide >> 1); yPos = (element_tall>>1) - (icon_tall >> 1); //Msg("Drawing at %f %f\n", x, y ); vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall); } #endif // HL2_EPISODIC }