summaryrefslogtreecommitdiff
path: root/game/client/hl2/hud_radar.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/hl2/hud_radar.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/hl2/hud_radar.cpp')
-rw-r--r--game/client/hl2/hud_radar.cpp587
1 files changed, 587 insertions, 0 deletions
diff --git a/game/client/hl2/hud_radar.cpp b/game/client/hl2/hud_radar.cpp
new file mode 100644
index 0000000..2f0fd7e
--- /dev/null
+++ b/game/client/hl2/hud_radar.cpp
@@ -0,0 +1,587 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include <vgui/ISurface.h>
+#include "hud_numericdisplay.h"
+#include "iclientmode.h"
+#include <coordsize.h>
+#include "hud_macros.h"
+#include "vgui/IVGui.h"
+#include "vgui/ILocalize.h"
+#include "mapoverview.h"
+#include "hud_radar.h"
+#include "iclientvehicle.h"
+
+#define RADAR_DOT_NORMAL 0
+#define RADAR_IGNORE_Z (1<<6) //always draw this item as if it was at the same Z as the player
+#define RADAR_MAX_GHOST_ALPHA 25
+
+DECLARE_VGUI_SCREEN_FACTORY( CHudRadar, "jalopy_radar_panel" );
+
+#define RADAR_PANEL_MATERIAL "vgui/screens/radar"
+#define RADAR_CONTACT_LAMBDA_MATERIAL "vgui/icons/icon_lambda" // Lambda cache
+#define RADAR_CONTACT_BUSTER_MATERIAL "vgui/icons/icon_buster" // Striderbuster
+#define RADAR_CONTACT_STRIDER_MATERIAL "vgui/icons/icon_strider" // Strider
+#define RADAR_CONTACT_DOG_MATERIAL "vgui/icons/icon_dog" // Dog
+#define RADAR_CONTACT_BASE_MATERIAL "vgui/icons/icon_base" // Ally base
+
+static CHudRadar *s_Radar = NULL;
+
+CHudRadar *GetHudRadar()
+{
+ return s_Radar;
+}
+
+DECLARE_HUDELEMENT( CMapOverview );
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+CHudRadar::CHudRadar( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
+{
+ m_pVehicle = NULL;
+ m_iImageID = -1;
+ m_textureID_IconLambda = -1;
+ m_textureID_IconBuster = -1;
+ m_textureID_IconStrider = -1;
+ m_textureID_IconDog = -1;
+ m_textureID_IconBase = -1;
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+CHudRadar::~CHudRadar()
+{
+ s_Radar = NULL;
+
+#if defined(_X360)
+ if( m_iImageID != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_iImageID );
+ m_iImageID = -1;
+ }
+
+ if( m_textureID_IconLambda != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconLambda );
+ m_textureID_IconLambda = -1;
+ }
+
+ if( m_textureID_IconBuster != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconBuster );
+ m_textureID_IconBuster = -1;
+ }
+
+ if( m_textureID_IconStrider != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconStrider );
+ m_textureID_IconStrider = -1;
+ }
+
+ if( m_textureID_IconDog != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconDog );
+ m_textureID_IconDog = -1;
+ }
+
+ if( m_textureID_IconBase != -1 )
+ {
+ vgui::surface()->DestroyTextureID( m_textureID_IconBase );
+ m_textureID_IconBase = -1;
+ }
+#endif//_X360
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+bool CHudRadar::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
+{
+ bool result = BaseClass::Init( pKeyValues, pInitData );
+ ClearAllRadarContacts();
+ s_Radar = this;
+
+ m_ghostAlpha = 0;
+ m_flTimeStartGhosting = gpGlobals->curtime + 1.0f;
+
+ return result;
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+void CHudRadar::VidInit(void)
+{
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+void CHudRadar::MsgFunc_UpdateRadar(bf_read &msg )
+{
+}
+
+//---------------------------------------------------------
+// Purpose: Register a radar contact in the list of contacts
+//---------------------------------------------------------
+void CHudRadar::AddRadarContact( const Vector &vecOrigin, int iType, float flTimeToLive )
+{
+ if( m_iNumRadarContacts == RADAR_MAX_CONTACTS )
+ return;
+
+ Vector v = vecOrigin;
+ int iExistingContact = FindRadarContact( vecOrigin );
+
+ if( iExistingContact > -1 )
+ {
+ // Just update this contact.
+ m_radarContacts[iExistingContact].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
+ return;
+ }
+
+ m_radarContacts[m_iNumRadarContacts].m_vecOrigin = vecOrigin;
+ m_radarContacts[m_iNumRadarContacts].m_iType = iType;
+ m_radarContacts[m_iNumRadarContacts].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
+ m_iNumRadarContacts++;
+}
+
+//---------------------------------------------------------
+// Purpose: Search the contact list for a specific contact
+//---------------------------------------------------------
+int CHudRadar::FindRadarContact( const Vector &vecOrigin )
+{
+ for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
+ {
+ if( m_radarContacts[ i ].m_vecOrigin == vecOrigin )
+ return i;
+ }
+
+ return -1;
+}
+
+//---------------------------------------------------------
+// Purpose: Go through all radar targets and see if any
+// have expired. If yes, remove them from the
+// list.
+//---------------------------------------------------------
+void CHudRadar::MaintainRadarContacts()
+{
+ bool bKeepWorking = true;
+ while( bKeepWorking )
+ {
+ bKeepWorking = false;
+ for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
+ {
+ CRadarContact *pContact = &m_radarContacts[ i ];
+ if( gpGlobals->curtime >= pContact->m_flTimeToRemove )
+ {
+ // Time for this guy to go. Easiest thing is just to copy the last element
+ // into this element's spot and then decrement the count of entities.
+ bKeepWorking = true;
+
+ m_radarContacts[ i ] = m_radarContacts[ m_iNumRadarContacts - 1 ];
+ m_iNumRadarContacts--;
+ break;
+ }
+ }
+ }
+}
+
+//---------------------------------------------------------
+//---------------------------------------------------------
+void CHudRadar::SetVisible(bool state)
+{
+ BaseClass::SetVisible(state);
+
+ if( g_pMapOverview && g_pMapOverview->GetMode() == CMapOverview::MAP_MODE_RADAR )
+ {
+ // We are the hud element still, but he is in charge of the new style now.
+ g_pMapOverview->SetVisible( state );
+ }
+}
+
+#define RADAR_BLIP_FADE_TIME 1.0f
+#define RADAR_USE_ICONS 1
+//---------------------------------------------------------
+// Purpose: Draw the radar panel.
+// We're probably doing too much other work in here
+//---------------------------------------------------------
+void CHudRadar::Paint()
+{
+ if (m_iImageID == -1 )
+ {
+ // Set up the image ID's if they've somehow gone bad.
+ m_textureID_IconLambda = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconLambda, RADAR_CONTACT_LAMBDA_MATERIAL, true, false );
+
+ m_textureID_IconBuster = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconBuster, RADAR_CONTACT_BUSTER_MATERIAL, true, false );
+
+ m_textureID_IconStrider = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconStrider, RADAR_CONTACT_STRIDER_MATERIAL, true, false );
+
+ m_textureID_IconDog = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconDog, RADAR_CONTACT_DOG_MATERIAL, true, false );
+
+ m_textureID_IconBase = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_textureID_IconBase, RADAR_CONTACT_BASE_MATERIAL, true, false );
+
+ m_iImageID = vgui::surface()->CreateNewTextureID();
+ vgui::surface()->DrawSetTextureFile( m_iImageID, RADAR_PANEL_MATERIAL, true, false );
+ }
+
+ // Draw the radar background.
+ int wide, tall;
+ GetSize(wide, tall);
+ int alpha = 255;
+ vgui::surface()->DrawSetColor(255, 255, 255, alpha);
+ vgui::surface()->DrawSetTexture(m_iImageID);
+ vgui::surface()->DrawTexturedRect(0, 0, wide, tall);
+
+ // Manage the CRT 'ghosting' effect
+ if( gpGlobals->curtime > m_flTimeStartGhosting )
+ {
+ if( m_ghostAlpha < RADAR_MAX_GHOST_ALPHA )
+ {
+ m_ghostAlpha++;
+ }
+ else
+ {
+ m_flTimeStartGhosting = FLT_MAX;
+ m_flTimeStopGhosting = gpGlobals->curtime + RandomFloat( 1.0f, 2.0f );// How long to ghost for
+ }
+ }
+ else if( gpGlobals->curtime > m_flTimeStopGhosting )
+ {
+ // We're supposed to stop ghosting now.
+ if( m_ghostAlpha > 0 )
+ {
+ // Still fading the effects.
+ m_ghostAlpha--;
+ }
+ else
+ {
+ // DONE fading the effects. Now stop ghosting for a short while
+ m_flTimeStartGhosting = gpGlobals->curtime + RandomFloat( 2.0f, 3.0f );// how long between ghosts
+ m_flTimeStopGhosting = FLT_MAX;
+ }
+ }
+
+ // Now go through the list of radar targets and represent them on the radar screen
+ // by drawing their icons on top of the background.
+ C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
+
+ for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
+ {
+ int alpha = 90;
+ CRadarContact *pContact = &m_radarContacts[ i ];
+ float deltaT = pContact->m_flTimeToRemove - gpGlobals->curtime;
+ if ( deltaT < RADAR_BLIP_FADE_TIME )
+ {
+ float factor = deltaT / RADAR_BLIP_FADE_TIME;
+
+ alpha = (int) ( ((float)alpha) * factor );
+
+ if( alpha < 10 )
+ alpha = 10;
+ }
+
+ if( RADAR_USE_ICONS )
+ {
+ int flicker = RandomInt( 0, 30 );
+ DrawIconOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha + flicker );
+ }
+ else
+ {
+ DrawPositionOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha );
+ }
+ }
+
+ MaintainRadarContacts();
+}
+
+ConVar radar_range("radar_range", "3000" ); // 180 feet
+//---------------------------------------------------------
+// Scale maps the distance of the target from the radar
+// source.
+//
+// 1.0 = target at or beyond radar range.
+// 0.5 = target at (radar_range * 0.5) units distance
+// 0.25 = target at (radar_range * 0.25) units distance
+// -etc-
+//---------------------------------------------------------
+bool CHudRadar::WorldToRadar( const Vector location, const Vector origin, const QAngle angles, float &x, float &y, float &z_delta, float &scale )
+{
+ bool bInRange = true;
+
+ float x_diff = location.x - origin.x;
+ float y_diff = location.y - origin.y;
+
+ // Supply epsilon values to avoid divide-by-zero
+ if(x_diff == 0)
+ x_diff = 0.00001f;
+
+ if(y_diff == 0)
+ y_diff = 0.00001f;
+
+ int iRadarRadius = GetWide(); //width of the panel
+ float fRange = radar_range.GetFloat();
+
+ // This magic /2.15 makes the radar scale seem smaller than the VGUI panel so the icons clamp
+ // to the outer ring in the radar graphic, not the very edge of the panel itself.
+ float fScale = (iRadarRadius/2.15f) / fRange;
+
+ float flOffset = atan(y_diff/x_diff);
+ flOffset *= 180;
+ flOffset /= M_PI;
+
+ if ((x_diff < 0) && (y_diff >= 0))
+ flOffset = 180 + flOffset;
+ else if ((x_diff < 0) && (y_diff < 0))
+ flOffset = 180 + flOffset;
+ else if ((x_diff >= 0) && (y_diff < 0))
+ flOffset = 360 + flOffset;
+
+ y_diff = -1*(sqrt((x_diff)*(x_diff) + (y_diff)*(y_diff)));
+ x_diff = 0;
+
+ flOffset = angles.y - flOffset;
+
+ flOffset *= M_PI;
+ flOffset /= 180; // now theta is in radians
+
+ // Transform relative to radar source
+ float xnew_diff = x_diff * cos(flOffset) - y_diff * sin(flOffset);
+ float ynew_diff = x_diff * sin(flOffset) + y_diff * cos(flOffset);
+
+ if ( (-1 * y_diff) > fRange )
+ {
+ float flScale;
+
+ flScale = ( -1 * y_diff) / fRange;
+
+ xnew_diff /= (flScale);
+ ynew_diff /= (flScale);
+
+ bInRange = false;
+
+ scale = 1.0f;
+ }
+ else
+ {
+ // scale
+ float flDist = sqrt( ((xnew_diff)*(xnew_diff) + (ynew_diff)*(ynew_diff)) );
+ scale = flDist / fRange;
+ }
+
+
+ // Scale the dot's position to match radar scale
+ xnew_diff *= fScale;
+ ynew_diff *= fScale;
+
+ // Translate to screen coordinates
+ x = (iRadarRadius/2) + (int)xnew_diff;
+ y = (iRadarRadius/2) + (int)ynew_diff;
+ z_delta = 0.0f;
+
+ return bInRange;
+}
+
+void CHudRadar::DrawPositionOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
+{
+ float x, y, z_delta;
+ int iBaseDotSize = 3;
+
+ QAngle viewAngle = pLocalPlayer->EyeAngles();
+
+ if( m_pVehicle != NULL )
+ {
+ viewAngle = m_pVehicle->GetAbsAngles();
+ viewAngle.y += 90.0f;
+ }
+
+ float flScale;
+
+ WorldToRadar( vecPos, pLocalPlayer->GetAbsOrigin(), viewAngle, x, y, z_delta, flScale );
+
+ if( flags & RADAR_IGNORE_Z )
+ z_delta = 0;
+
+ switch( type )
+ {
+ case RADAR_CONTACT_GENERIC:
+ r = 255; g = 170; b = 0;
+ iBaseDotSize *= 2;
+ break;
+ case RADAR_CONTACT_MAGNUSSEN_RDU:
+ r = 0; g = 200; b = 255;
+ iBaseDotSize *= 2;
+ break;
+ case RADAR_CONTACT_ENEMY:
+ r = 255; g = 0; b = 0;
+ iBaseDotSize *= 2;
+ break;
+ case RADAR_CONTACT_LARGE_ENEMY:
+ r = 255; g = 0; b = 0;
+ iBaseDotSize *= 3;
+ break;
+ }
+
+ DrawRadarDot( x, y, z_delta, iBaseDotSize, flags, r, g, b, a );
+}
+
+//---------------------------------------------------------
+// Purpose: Compute the proper position on the radar screen
+// for this object's position relative to the player.
+// Then draw the icon in the proper location on the
+// radar screen.
+//---------------------------------------------------------
+#define RADAR_ICON_MIN_SCALE 0.75f
+#define RADAR_ICON_MAX_SCALE 1.0f
+void CHudRadar::DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
+{
+ float x, y, z_delta;
+ int wide, tall;
+
+ // for 'ghosting' CRT effects:
+ int xmod;
+ int ymod;
+ int xoffset;
+ int yoffset;
+
+ // Assume we're going to use the player's location and orientation
+ QAngle viewAngle = pLocalPlayer->EyeAngles();
+ Vector viewOrigin = pLocalPlayer->GetAbsOrigin();
+
+ // However, happily use those of the vehicle if available!
+ if( m_pVehicle != NULL )
+ {
+ viewAngle = m_pVehicle->GetAbsAngles();
+ viewAngle.y += 90.0f;
+ viewOrigin = m_pVehicle->WorldSpaceCenter();
+ }
+
+ float flScale;
+
+ WorldToRadar( vecPos, viewOrigin, viewAngle, x, y, z_delta, flScale );
+
+ flScale = RemapVal( flScale, 1.0f, 0.0f, RADAR_ICON_MIN_SCALE, RADAR_ICON_MAX_SCALE );
+
+ // Get the correct icon for this type of contact
+ int iTextureID_Icon = -1;
+
+ switch( type )
+ {
+ case RADAR_CONTACT_GENERIC:
+ iTextureID_Icon = m_textureID_IconLambda;
+ break;
+ case RADAR_CONTACT_MAGNUSSEN_RDU:
+ iTextureID_Icon = m_textureID_IconBuster;
+ break;
+ case RADAR_CONTACT_LARGE_ENEMY:
+ case RADAR_CONTACT_ENEMY:
+ iTextureID_Icon = m_textureID_IconStrider;
+ break;
+ case RADAR_CONTACT_DOG:
+ iTextureID_Icon = m_textureID_IconDog;
+ break;
+ case RADAR_CONTACT_ALLY_INSTALLATION:
+ iTextureID_Icon = m_textureID_IconBase;
+ break;
+ default:
+ return;
+ break;
+ }
+
+ vgui::surface()->DrawSetColor( r, g, b, a );
+ vgui::surface()->DrawSetTexture( iTextureID_Icon );
+ vgui::surface()->DrawGetTextureSize( iTextureID_Icon, wide, tall );
+
+ wide = ( int((float)wide * flScale) );
+ tall = ( int((float)tall * flScale) );
+
+ if( type == RADAR_CONTACT_LARGE_ENEMY )
+ {
+ wide *= 2;
+ tall *= 2;
+ }
+
+ // Center the icon around its position.
+ x -= (wide >> 1);
+ y -= (tall >> 1);
+
+ vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
+
+ // Draw the crt 'ghost' if the icon is not pegged to the outer rim
+ if( flScale > RADAR_ICON_MIN_SCALE && m_ghostAlpha > 0 )
+ {
+ vgui::surface()->DrawSetColor( r, g, b, m_ghostAlpha );
+ xmod = RandomInt( 1, 4 );
+ ymod = RandomInt( 1, 4 );
+ xoffset = RandomInt( -1, 1 );
+ yoffset = RandomInt( -1, 1 );
+ x -= (xmod - xoffset);
+ y -= (ymod - yoffset);
+ wide += (xmod + xoffset);
+ tall += (ymod + yoffset);
+ vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
+ }
+}
+
+void CHudRadar::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 );
+}
+
+void CHudRadar::DrawRadarDot( int x, int y, float z_diff, int iBaseDotSize, int flags, int r, int g, int b, int a )
+{
+ vgui::surface()->DrawSetColor( r, g, b, a );
+
+ if ( z_diff < -128 ) // below the player
+ {
+ z_diff *= -1;
+
+ if ( z_diff > 3096 )
+ {
+ z_diff = 3096;
+ }
+
+ int iBar = (int)( z_diff / 400 ) + 2;
+
+ // Draw an upside-down T shape to symbolize the dot is below the player.
+
+ iBaseDotSize /= 2;
+
+ //horiz
+ FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
+
+ //vert
+ FillRect( x, y - iBar*iBaseDotSize, iBaseDotSize, iBar*iBaseDotSize );
+ }
+ else if ( z_diff > 128 ) // above the player
+ {
+ if ( z_diff > 3096 )
+ {
+ z_diff = 3096;
+ }
+
+ int iBar = (int)( z_diff / 400 ) + 2;
+
+ iBaseDotSize /= 2;
+
+ // Draw a T shape to symbolize the dot is above the player.
+
+ //horiz
+ FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
+
+ //vert
+ FillRect( x, y, iBaseDotSize, iBar*iBaseDotSize );
+ }
+ else
+ {
+ FillRect( x, y, iBaseDotSize, iBaseDotSize );
+ }
+}