Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
9.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Hud locator element, helps direct the player to objects in the world
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hudelement.h"
  8. #include "hud_numericdisplay.h"
  9. #include <vgui_controls/Panel.h>
  10. #include "hud.h"
  11. #include "hud_suitpower.h"
  12. #include "hud_macros.h"
  13. #include "iclientmode.h"
  14. #include <vgui_controls/AnimationController.h>
  15. #include <vgui/ISurface.h>
  16. #include "c_basehlplayer.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. #define LOCATOR_MATERIAL_JALOPY "vgui/icons/icon_jalopy"
  20. #define LOCATOR_MATERIAL_BIG_TICK "vgui/icons/tick_long"
  21. #define LOCATOR_MATERIAL_SMALL_TICK "vgui/icons/tick_short"
  22. ConVar hud_locator_alpha( "hud_locator_alpha", "230" );
  23. ConVar hud_locator_fov("hud_locator_fov", "350" );
  24. //-----------------------------------------------------------------------------
  25. // Purpose: Shows positions of objects relative to the player.
  26. //-----------------------------------------------------------------------------
  27. class CHudLocator : public CHudElement, public vgui::Panel
  28. {
  29. DECLARE_CLASS_SIMPLE( CHudLocator, vgui::Panel );
  30. public:
  31. CHudLocator( const char *pElementName );
  32. virtual ~CHudLocator( void );
  33. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  34. void VidInit( void );
  35. bool ShouldDraw();
  36. protected:
  37. void FillRect( int x, int y, int w, int h );
  38. float LocatorXPositionForYawDiff( float yawDiff );
  39. void DrawGraduations( float flYawPlayerFacing );
  40. virtual void Paint();
  41. private:
  42. void Reset( void );
  43. int m_textureID_IconJalopy;
  44. int m_textureID_IconBigTick;
  45. int m_textureID_IconSmallTick;
  46. Vector m_vecLocation;
  47. };
  48. using namespace vgui;
  49. #ifdef HL2_EPISODIC
  50. DECLARE_HUDELEMENT( CHudLocator );
  51. #endif
  52. //-----------------------------------------------------------------------------
  53. // Purpose: Constructor
  54. //-----------------------------------------------------------------------------
  55. CHudLocator::CHudLocator( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudLocator" )
  56. {
  57. vgui::Panel *pParent = g_pClientMode->GetViewport();
  58. SetParent( pParent );
  59. SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
  60. m_textureID_IconJalopy = -1;
  61. m_textureID_IconSmallTick = -1;
  62. m_textureID_IconBigTick = -1;
  63. }
  64. CHudLocator::~CHudLocator( void )
  65. {
  66. if ( vgui::surface() )
  67. {
  68. if ( m_textureID_IconJalopy != -1 )
  69. {
  70. vgui::surface()->DestroyTextureID( m_textureID_IconJalopy );
  71. m_textureID_IconJalopy = -1;
  72. }
  73. if ( m_textureID_IconSmallTick != -1 )
  74. {
  75. vgui::surface()->DestroyTextureID( m_textureID_IconSmallTick );
  76. m_textureID_IconSmallTick = -1;
  77. }
  78. if ( m_textureID_IconBigTick != -1 )
  79. {
  80. vgui::surface()->DestroyTextureID( m_textureID_IconBigTick );
  81. m_textureID_IconBigTick = -1;
  82. }
  83. }
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Purpose:
  87. // Input : *pScheme -
  88. //-----------------------------------------------------------------------------
  89. void CHudLocator::ApplySchemeSettings( vgui::IScheme *pScheme )
  90. {
  91. BaseClass::ApplySchemeSettings(pScheme);
  92. }
  93. //-----------------------------------------------------------------------------
  94. //-----------------------------------------------------------------------------
  95. void CHudLocator::VidInit( void )
  96. {
  97. }
  98. //-----------------------------------------------------------------------------
  99. //-----------------------------------------------------------------------------
  100. bool CHudLocator::ShouldDraw( void )
  101. {
  102. C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
  103. if ( !pPlayer )
  104. return false;
  105. if( pPlayer->GetVehicle() )
  106. return false;
  107. if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_invalid )
  108. return false;
  109. return true;
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Purpose: Start with our background off
  113. //-----------------------------------------------------------------------------
  114. void CHudLocator::Reset( void )
  115. {
  116. m_vecLocation = Vector( 0, 0, 0 );
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Purpose: Make it a bit more convenient to do a filled rect.
  120. //-----------------------------------------------------------------------------
  121. void CHudLocator::FillRect( int x, int y, int w, int h )
  122. {
  123. int panel_x, panel_y, panel_w, panel_h;
  124. GetBounds( panel_x, panel_y, panel_w, panel_h );
  125. vgui::surface()->DrawFilledRect( x, y, x+w, y+h );
  126. }
  127. //-----------------------------------------------------------------------------
  128. //-----------------------------------------------------------------------------
  129. float CHudLocator::LocatorXPositionForYawDiff( float yawDiff )
  130. {
  131. float fov = hud_locator_fov.GetFloat() / 2;
  132. float remappedAngle = RemapVal( yawDiff, -fov, fov, -90, 90 );
  133. float cosine = sin(DEG2RAD(remappedAngle));
  134. int element_wide = GetWide();
  135. float position = (element_wide>>1) + ((element_wide>>1) * cosine);
  136. return position;
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Draw the tickmarks on the locator
  140. //-----------------------------------------------------------------------------
  141. #define NUM_GRADUATIONS 16.0f
  142. void CHudLocator::DrawGraduations( float flYawPlayerFacing )
  143. {
  144. int icon_wide, icon_tall;
  145. int xPos, yPos;
  146. float fov = hud_locator_fov.GetFloat() / 2;
  147. if( m_textureID_IconBigTick == -1 )
  148. {
  149. m_textureID_IconBigTick = vgui::surface()->CreateNewTextureID();
  150. vgui::surface()->DrawSetTextureFile( m_textureID_IconBigTick, LOCATOR_MATERIAL_BIG_TICK, true, false );
  151. }
  152. if( m_textureID_IconSmallTick == -1 )
  153. {
  154. m_textureID_IconSmallTick = vgui::surface()->CreateNewTextureID();
  155. vgui::surface()->DrawSetTextureFile( m_textureID_IconSmallTick, LOCATOR_MATERIAL_SMALL_TICK, true, false );
  156. }
  157. int element_tall = GetTall(); // Height of the VGUI element
  158. surface()->DrawSetColor( 255, 255, 255, 255 );
  159. // Tick Icons
  160. float angleStep = 360.0f / NUM_GRADUATIONS;
  161. bool tallLine = true;
  162. for( float angle = -180 ; angle <= 180 ; angle += angleStep )
  163. {
  164. yPos = (element_tall>>1);
  165. if( tallLine )
  166. {
  167. vgui::surface()->DrawSetTexture( m_textureID_IconBigTick );
  168. vgui::surface()->DrawGetTextureSize( m_textureID_IconBigTick, icon_wide, icon_tall );
  169. tallLine = false;
  170. }
  171. else
  172. {
  173. vgui::surface()->DrawSetTexture( m_textureID_IconSmallTick );
  174. vgui::surface()->DrawGetTextureSize( m_textureID_IconSmallTick, icon_wide, icon_tall );
  175. tallLine = true;
  176. }
  177. float flDiff = UTIL_AngleDiff( flYawPlayerFacing, angle );
  178. if( fabs(flDiff) > fov )
  179. continue;
  180. float xPosition = LocatorXPositionForYawDiff( flDiff );
  181. xPos = (int)xPosition;
  182. xPos -= (icon_wide>>1);
  183. vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
  184. }
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Purpose: draws the locator icons on the VGUI element.
  188. //-----------------------------------------------------------------------------
  189. void CHudLocator::Paint()
  190. {
  191. #ifdef HL2_EPISODIC
  192. if( m_textureID_IconJalopy == -1 )
  193. {
  194. m_textureID_IconJalopy = vgui::surface()->CreateNewTextureID();
  195. vgui::surface()->DrawSetTextureFile( m_textureID_IconJalopy, LOCATOR_MATERIAL_JALOPY, true, false );
  196. }
  197. int alpha = hud_locator_alpha.GetInt();
  198. SetAlpha( alpha );
  199. C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
  200. if ( !pPlayer )
  201. return;
  202. if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_origin )
  203. return;
  204. int element_tall = GetTall(); // Height of the VGUI element
  205. float fov = (hud_locator_fov.GetFloat()) / 2.0f;
  206. // Compute the relative position of objects we're tracking
  207. // We'll need the player's yaw for comparison.
  208. float flYawPlayerForward = pPlayer->EyeAngles().y;
  209. // Copy this value out of the member variable in case we decide to expand this
  210. // feature later and want to iterate some kind of list.
  211. Vector vecLocation = pPlayer->m_HL2Local.m_vecLocatorOrigin;
  212. Vector vecToLocation = vecLocation - pPlayer->GetAbsOrigin();
  213. QAngle locationAngles;
  214. VectorAngles( vecToLocation, locationAngles );
  215. float yawDiff = UTIL_AngleDiff( flYawPlayerForward, locationAngles.y );
  216. bool bObjectInFOV = (yawDiff > -fov && yawDiff < fov);
  217. // Draw the icons!
  218. int icon_wide, icon_tall;
  219. int xPos, yPos;
  220. surface()->DrawSetColor( 255, 255, 255, 255 );
  221. DrawGraduations( flYawPlayerForward );
  222. if( bObjectInFOV )
  223. {
  224. // The object's location maps to a valid position along the tape, so draw an icon.
  225. float tapePosition = LocatorXPositionForYawDiff(yawDiff);
  226. // derive a scale for the locator icon
  227. yawDiff = fabs(yawDiff);
  228. float scale = 1.0f;
  229. scale = RemapValClamped( yawDiff, (fov/4), fov, 1.0f, 0.25f );
  230. vgui::surface()->DrawSetTexture( m_textureID_IconJalopy );
  231. vgui::surface()->DrawGetTextureSize( m_textureID_IconJalopy, icon_wide, icon_tall );
  232. float flIconWide = ((float)element_tall * 1.25f);
  233. float flIconTall = ((float)element_tall * 1.25f);
  234. // Scale the icon as desired...
  235. // Put back into ints
  236. icon_wide = (int)flIconWide;
  237. icon_tall = (int)flIconTall;
  238. icon_wide *= scale;
  239. //Msg("yawDiff:%f xPos:%d scale:%f\n", yawDiff, xPos, scale );
  240. // Center the icon around its position.
  241. xPos = (int)tapePosition;
  242. xPos -= (icon_wide >> 1);
  243. yPos = (element_tall>>1) - (icon_tall >> 1);
  244. //Msg("Drawing at %f %f\n", x, y );
  245. vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
  246. }
  247. #endif // HL2_EPISODIC
  248. }