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.
1367 lines
37 KiB
1367 lines
37 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $Workfile: $ |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "hud_minimap.h" |
|
#include <vgui_controls/Controls.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/IVGui.h> |
|
#include <vgui/IInput.h> |
|
#include <vgui_controls/AnimationController.h> |
|
#include "vgui_bitmapimage.h" |
|
#include "clientmode_tfbase.h" |
|
#include "clientmode_tfnormal.h" |
|
#include "hud.h" |
|
#include "hud_commander_statuspanel.h" |
|
#include "view.h" |
|
#include "filesystem.h" |
|
#include "imessagechars.h" |
|
#include "hud_macros.h" |
|
#include "c_tfteam.h" |
|
#include "c_info_act.h" |
|
#include "engine/IEngineSound.h" |
|
#include "iinput.h" |
|
#include "in_buttons.h" |
|
#include "c_basetfplayer.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
static ConVar minimap_visible( "minimap_visible", "1", 0, "Draw minimap?" ); |
|
ConVar minimap_zoomtime( "minimap_zoomtime", "0.4", 0, "How long it takes to resize the minimap." ); |
|
|
|
|
|
static ConVar current_team( "current_team", "-1", 0 ); |
|
|
|
// Start out new maps at this zoom level |
|
#define DEFAULT_ZOOM_LEVEL 0 |
|
|
|
using namespace vgui; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Instantiate a temporary trace (position based, or entity based) |
|
//----------------------------------------------------------------------------- |
|
void MinimapCreateTempTrace( const char* pMetaClassName, int sortOrder, const Vector &vecPosition ) |
|
{ |
|
MinimapInitData_t initData; |
|
initData.m_vecPosition = vecPosition; |
|
|
|
PanelMetaClassMgr()->CreatePanelMetaClass( |
|
pMetaClassName, sortOrder, &initData, CMinimapPanel::MinimapRootPanel() ); |
|
} |
|
|
|
void MinimapCreateTempTrace( const char* pMetaClassName, int sortOrder, C_BaseEntity *pEntity, const Vector &vecOffset ) |
|
{ |
|
MinimapInitData_t initData; |
|
initData.m_pEntity = pEntity; |
|
initData.m_vecPosition = vecOffset; |
|
|
|
PanelMetaClassMgr()->CreatePanelMetaClass( |
|
pMetaClassName, sortOrder, &initData, CMinimapPanel::MinimapRootPanel() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// dummy root panel for all minimap traces |
|
//----------------------------------------------------------------------------- |
|
class CMinimapRootPanel : public Panel |
|
{ |
|
typedef Panel BaseClass; |
|
|
|
public: |
|
CMinimapRootPanel( Panel *pParent = NULL ) |
|
: BaseClass( pParent,"CMinimapRootPanel" ) |
|
{ |
|
SetPaintBackgroundEnabled( false ); |
|
SetPaintEnabled( false ); |
|
SetAutoDelete( false ); |
|
} |
|
}; |
|
|
|
class CTextHelpPanel : public vgui::Panel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CTextHelpPanel, vgui::Panel ) |
|
|
|
public: |
|
|
|
CTextHelpPanel(); |
|
|
|
virtual void Paint(); |
|
virtual void PaintBackground(); |
|
|
|
void SetImage( BitmapImage *image ); |
|
|
|
virtual void ApplySettings( KeyValues *inResourceData ) |
|
{ |
|
BaseClass::ApplySettings( inResourceData ); |
|
} |
|
|
|
private: |
|
|
|
BitmapImage *m_pImage; |
|
|
|
CPanelAnimationVar( Color, m_OverlayColor, "OverlayColor", "White" ); |
|
CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "BrightFg" ); |
|
CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "Black" ); |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTextHelpPanel::CTextHelpPanel() |
|
: BaseClass( NULL, "HudMinimapTextHelpPanel" ) |
|
{ |
|
Panel *pParent = g_pClientMode->GetViewport(); |
|
SetParent( pParent ); |
|
|
|
SetVisible( false ); |
|
SetZPos( 1 ); |
|
|
|
m_pImage = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTextHelpPanel::PaintBackground() |
|
{ |
|
// Get alpha from image |
|
if ( m_pImage ) |
|
{ |
|
Color bg = m_BackgroundColor; |
|
int r, g, b, a; |
|
m_pImage->GetColor( r, g, b, a ); |
|
bg[3] = a; |
|
SetBgColor( bg ); |
|
|
|
BaseClass::PaintBackground(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTextHelpPanel::Paint() |
|
{ |
|
BaseClass::Paint(); |
|
|
|
if ( !m_pImage ) |
|
return; |
|
|
|
m_pImage->SetColor( m_OverlayColor ); |
|
m_pImage->DoPaint( GetVPanel() ); |
|
|
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
surface()->DrawSetColor( m_BorderColor ); |
|
surface()->DrawOutlinedRect( 0, 0, w, h ); |
|
surface()->DrawOutlinedRect( 1, 1, w-1, h-1 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *image - |
|
// x - |
|
// y - |
|
// w - |
|
// h - |
|
//----------------------------------------------------------------------------- |
|
void CTextHelpPanel::SetImage( BitmapImage *image ) |
|
{ |
|
m_pImage = image; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// globals |
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// All traces are children of this panel |
|
//----------------------------------------------------------------------------- |
|
Panel *CMinimapPanel::MinimapRootPanel() |
|
{ |
|
static CMinimapRootPanel s_MinimapRootPanel; |
|
return &s_MinimapRootPanel; |
|
} |
|
|
|
CMinimapPanel *CMinimapPanel::MinimapPanel() |
|
{ |
|
ClientModeTFBase *pBasemode = ( ClientModeTFBase * )g_pClientMode; |
|
if ( !pBasemode ) |
|
return NULL; |
|
|
|
return pBasemode->GetMinimap(); |
|
} |
|
|
|
DECLARE_HUDELEMENT( CMinimapPanel ); |
|
DECLARE_HUD_MESSAGE( CMinimapPanel, MinimapPulse ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Placeholder for small overview map with viewport rectangle/selector |
|
//----------------------------------------------------------------------------- |
|
CMinimapPanel::CMinimapPanel( const char *pElementName ) |
|
: CHudElement( pElementName ), BaseClass( NULL, "HudMinimap" ) |
|
{ |
|
Panel *pParent = g_pClientMode->GetViewport(); |
|
SetParent( pParent ); |
|
|
|
SetAutoDelete( false ); |
|
for ( int i = 0; i < MAX_ACT_TEAMS; i++ ) |
|
{ |
|
m_pBackground[ i ] = 0; |
|
} |
|
memset( m_rgOverlays, 0, sizeof( m_rgOverlays ) ); |
|
|
|
m_flExpansionFrac = 0.0f; |
|
|
|
// Minimap zoom |
|
m_bMinimapZoomed = false; |
|
m_nZoomLevel = DEFAULT_ZOOM_LEVEL; |
|
|
|
m_vecCurrentOrigin.Init(); |
|
m_vecMapCenter.Init(); |
|
m_flMapAspectRatio = 1.0f; |
|
m_flViewportAspectRatio = 1.0f; |
|
m_flAspectAdjustment = 1.0f; |
|
m_flNormalizedXScale = 1.0f; |
|
m_flNormalizedYScale = 1.0f; |
|
m_flNormalizedXOffset = 0.0f; |
|
m_flNormalizedYOffset = 0.0f; |
|
|
|
m_nCurrentAct = ACT_NONE_SPECIFIED; |
|
|
|
m_pTextPanel = new CTextHelpPanel(); |
|
m_pBackgroundPanel = new Panel( NULL, "BackgroundPanel" ); |
|
|
|
// We're gonna manage the lifetime of the text panel |
|
// since we change it's hierarchical connections from time to time |
|
m_pTextPanel->SetAutoDelete( false ); |
|
m_pBackgroundPanel->SetAutoDelete( false ); |
|
SetAutoDelete( false ); |
|
|
|
m_pClient = NULL; |
|
|
|
m_flZoomAdjust = 1.0f; |
|
m_flPrevZoomAmount = 0.01f; |
|
|
|
SetZPos( 10 ); |
|
|
|
ivgui()->AddTickSignal( GetVPanel() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CMinimapPanel::~CMinimapPanel( void ) |
|
{ |
|
delete m_pTextPanel; |
|
delete m_pBackgroundPanel; |
|
|
|
for ( int i = 0; i < MAX_ACT_TEAMS; i++ ) |
|
{ |
|
delete m_pBackground[ i ]; |
|
} |
|
|
|
ShutdownOverlays(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *scheme - |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::ApplySchemeSettings( IScheme *scheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( scheme ); |
|
SetPaintBackgroundEnabled( false ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// initialization |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::Init( IMinimapClient* pClient ) |
|
{ |
|
m_pClient = pClient; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Call this when the minimap panel is going to be drawn... |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::Activate() |
|
{ |
|
// The panel is a view into the minimap root panel |
|
MinimapRootPanel()->SetParent( this ); |
|
|
|
Panel *pParent = g_pClientMode->GetViewport(); |
|
|
|
if ( pParent && m_pBackgroundPanel ) |
|
{ |
|
m_pBackgroundPanel->SetParent( pParent ); |
|
m_pBackgroundPanel->SetBounds( XRES( 0 ), YRES( 0 ), XRES( 640 ), YRES( 480 ) ); |
|
m_pBackgroundPanel->SetVisible( false ); |
|
m_pBackgroundPanel->SetZPos( 0 ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : w - |
|
// h - |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::OnSizeChanged( int w, int h ) |
|
{ |
|
BaseClass::OnSizeChanged( w, h ); |
|
|
|
MinimapRootPanel()->SetSize( w, h ); |
|
|
|
// Make sure icons are snapped to current window size |
|
InvokeOnTickOnChildren( this ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : float |
|
//----------------------------------------------------------------------------- |
|
float CMinimapPanel::GetAdjustedZoom( void ) |
|
{ |
|
return m_flZoomAmount * m_flZoomAdjust; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : float |
|
//----------------------------------------------------------------------------- |
|
float CMinimapPanel::GetTrueZoom() |
|
{ |
|
return m_flZoomAmount; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : center - |
|
// scale - |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::GetMapOriginAndScale( Vector& origin, float& scale ) |
|
{ |
|
origin = m_vecCurrentOrigin; |
|
scale = GetAdjustedZoom(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : clip - |
|
// pos - |
|
// outx - |
|
// outy - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool CMinimapPanel::WorldToMinimap( MinimapPosType_t posType, const Vector& pos, float& outx, float& outy ) |
|
{ |
|
Vector origin; |
|
float zoomscale; |
|
|
|
GetMapOriginAndScale( origin, zoomscale ); |
|
|
|
return InternalWorldToMinimap( posType, pos, origin, zoomscale, outx, outy ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : x - |
|
// y - |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::AdjustNormalizedPositionForAspectRatio( float& x, float& y ) |
|
{ |
|
x = m_flNormalizedXOffset + x * m_flNormalizedXScale; |
|
y = m_flNormalizedYOffset + y * m_flNormalizedYScale; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Converts a world-space position to a coordinate in minimap panel space |
|
//----------------------------------------------------------------------------- |
|
bool CMinimapPanel::InternalWorldToMinimap( MinimapPosType_t posType, const Vector &pos, const Vector& origin, float zoomscale, float& outx, float& outy ) |
|
{ |
|
int wide, tall; |
|
MinimapRootPanel()->GetSize( wide, tall ); |
|
|
|
Vector worldmins, worldmaxs; |
|
MapData().GetMapBounds( worldmins, worldmaxs ); |
|
Vector worldsize = worldmaxs - worldmins; |
|
|
|
Vector test = ( pos - origin ); |
|
|
|
float xfraction = 0.0f; |
|
|
|
if ( worldsize.x > 0 ) |
|
{ |
|
xfraction = (test.x - worldmins.x) / (worldmaxs.x - worldmins.x); |
|
} |
|
|
|
float yfraction = 0.0f; |
|
|
|
if ( worldsize.y > 0 ) |
|
{ |
|
yfraction = (test.y - worldmins.y) / (worldmaxs.y - worldmins.y); |
|
} |
|
|
|
xfraction = ( xfraction - 0.5f ) * zoomscale + 0.5f; |
|
yfraction = ( yfraction - 0.5f ) * zoomscale + 0.5f; |
|
|
|
yfraction = 1.0f - yfraction; |
|
|
|
// Adjust in case not all of map can be shown |
|
AdjustNormalizedPositionForAspectRatio( xfraction, yfraction ); |
|
|
|
// Normalize? |
|
bool inside = true; |
|
switch ( posType ) |
|
{ |
|
case MINIMAP_CLIP: |
|
{ |
|
// Clip the vector from minimap center to object |
|
// to the minimap bounds and put the object on the edge |
|
Vector2D delta( xfraction - 0.5f, yfraction - 0.5f ); |
|
Vector2D fdelta( fabs(delta.x), fabs(delta.y) ); |
|
if (fdelta.x > fdelta.y) |
|
{ |
|
// It's more horizontal than vertical.. |
|
if (fdelta.x >= 0.5f) |
|
{ |
|
float flRatio = delta.y / delta.x; |
|
xfraction = clamp(xfraction, 0, 1); |
|
yfraction = (xfraction - 0.5f) * flRatio + 0.5f; |
|
} |
|
} |
|
else |
|
{ |
|
if (fdelta.y >= 0.5f) |
|
{ |
|
// It's more vertical than horizontal |
|
float flRatio = delta.x / delta.y; |
|
yfraction = clamp(yfraction, 0, 1); |
|
xfraction = (yfraction - 0.5f) * flRatio + 0.5f; |
|
} |
|
} |
|
} |
|
break; |
|
|
|
case MINIMAP_CLAMP: |
|
{ |
|
// Clamp the position to lie within the minimap |
|
xfraction = clamp(xfraction, 0, 1); |
|
yfraction = clamp(yfraction, 0, 1); |
|
} |
|
break; |
|
|
|
case MINIMAP_NOCLIP: |
|
{ |
|
// See if it's off screen |
|
if ( xfraction < 0.0 || xfraction > 1.0 || |
|
yfraction < 0.0 || yfraction > 1.0 ) |
|
{ |
|
inside = false; |
|
} |
|
} |
|
break; |
|
} |
|
|
|
outx = xfraction * wide; |
|
outy = yfraction * tall; |
|
|
|
return inside; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *mapname - |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::LevelInit( const char *mapname ) |
|
{ |
|
SetBackgroundMaterials( MapData().m_Minimap.m_szBackgroundMaterial ); |
|
|
|
m_nZoomLevel = DEFAULT_ZOOM_LEVEL; |
|
|
|
HOOK_HUD_MESSAGE( CMinimapPanel, MinimapPulse ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Play a pulse on the minimap |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::MsgFunc_MinimapPulse( bf_read &msg ) |
|
{ |
|
Vector vecPosition; |
|
msg.ReadBitVec3Coord( vecPosition ); |
|
C_TFTeam *pTeam = (C_TFTeam *)GetLocalTeam(); |
|
if ( pTeam ) |
|
{ |
|
pTeam->NotifyBaseUnderAttack( vecPosition, false ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::LevelShutdown( void ) |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the background material |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::SetBackgroundMaterials( const char *pMaterialName ) |
|
{ |
|
int i; |
|
for ( i = 0; i < MAX_ACT_TEAMS; i++ ) |
|
{ |
|
delete m_pBackground[ i ]; |
|
m_pBackground[ i ] = NULL; |
|
} |
|
|
|
if ( pMaterialName[ 0 ] ) |
|
{ |
|
for ( i = 0; i < MAX_ACT_TEAMS; i++ ) |
|
{ |
|
char teammaterial[ 512 ]; |
|
|
|
Q_snprintf( teammaterial, sizeof( teammaterial ), "%s_team%i", |
|
pMaterialName, i + 1 ); |
|
|
|
// If a _team# version exists, use that, otherwise, use the default |
|
if ( g_pFullFileSystem->FileExists( VarArgs( "materials/%s.vmt", teammaterial ) ) ) |
|
{ |
|
m_pBackground[ i ] = new BitmapImage( GetVPanel(), teammaterial ); |
|
} |
|
else |
|
{ |
|
m_pBackground[ i ] = new BitmapImage( GetVPanel(), pMaterialName ); |
|
} |
|
} |
|
} |
|
|
|
if ( m_pTextPanel ) |
|
{ |
|
m_pTextPanel->SetImage( NULL ); |
|
} |
|
|
|
ShutdownOverlays(); |
|
InitOverlays( pMaterialName ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Called when the mouse is hit |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::OnMousePressed(MouseCode code) |
|
{ |
|
if ((code == MOUSE_LEFT) && m_pClient) |
|
{ |
|
// Convert mouse position to world position |
|
int x, y; |
|
vgui::input()->GetCursorPos( x, y ); |
|
|
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
Vector worldPos; |
|
worldPos.x = (float) x / (float) w; |
|
worldPos.y = 1.0f - (float) y / (float) h; |
|
worldPos.z = 0; // z isn't used |
|
|
|
Vector worldMins, worldMaxs; |
|
MapData().GetMapBounds( worldMins, worldMaxs ); |
|
worldPos *= (worldMaxs - worldMins); |
|
worldPos += worldMins; |
|
|
|
m_pClient->MinimapClicked( worldPos ); |
|
} |
|
} |
|
|
|
void CMinimapPanel::SetBackgroundViewport( float minx, float miny, float maxx, float maxy, bool includedetails ) |
|
{ |
|
int i; |
|
int x, y, w, h; |
|
|
|
x = 0; |
|
y = 0; |
|
w = GetWide(); |
|
h = GetTall(); |
|
|
|
if ( minx < 0.0f || maxx > 1.0f || |
|
miny < 0.0f || maxy > 1.0f ) |
|
{ |
|
float x0 = 0.0f; |
|
float y0 = 0.0f; |
|
float x1 = 1.0f; |
|
float y1 = 1.0f; |
|
|
|
float xrange = maxx - minx; |
|
float yrange = maxy - miny; |
|
|
|
if ( minx < 0.0f ) |
|
{ |
|
x0 = -minx / xrange; |
|
//xrange += minx; |
|
maxx -= minx; |
|
minx = 0.0f; |
|
} |
|
if ( maxx > 1.0f ) |
|
{ |
|
x1 = 1.0f - ( maxx - 1.0f ) / xrange; |
|
maxx = 1.0f; |
|
} |
|
if ( miny < 0.0f ) |
|
{ |
|
y0 = -miny / yrange; |
|
//yrange += miny; |
|
maxy -= miny; |
|
miny = 0.0f; |
|
} |
|
if ( maxy > 1.0f ) |
|
{ |
|
y1 = 1.0f - ( maxy - 1.0f ) / yrange; |
|
maxy = 1.0f; |
|
} |
|
|
|
x = x0 * w; |
|
y = y0 * h; |
|
w = x1 * w; |
|
h = y1 * h; |
|
} |
|
|
|
for ( i = 0; i < MAX_ACT_TEAMS; i++ ) |
|
{ |
|
if ( m_pBackground[ i ] ) |
|
{ |
|
m_pBackground[ i ]->SetPos( x, y ); |
|
m_pBackground[ i ]->SetRenderSize( w, h ); |
|
m_pBackground[ i ]->SetViewport( true, minx, miny, maxx, maxy ); |
|
} |
|
} |
|
|
|
if ( includedetails ) |
|
{ |
|
int t; |
|
for ( t = 0; t < MAX_ACT_TEAMS; t++ ) |
|
{ |
|
for ( i = 0; i < MAX_ACTS; i++ ) |
|
{ |
|
Overlays *p = &m_rgOverlays[ t ][ i ]; |
|
if ( !p->m_bInUse ) |
|
continue; |
|
|
|
if ( !p->m_pOverlay ) |
|
continue; |
|
|
|
p->m_pOverlay->SetPos( x, y ); |
|
p->m_pOverlay->SetRenderSize( w, h ); |
|
p->m_pOverlay->SetViewport( true, minx, miny, maxx, maxy ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::PaintActOverlays( int teamIndex, int alpha ) |
|
{ |
|
Assert( teamIndex >= 0 && teamIndex < MAX_ACT_TEAMS ); |
|
|
|
bool textshowing = false; |
|
|
|
int i = GetCurrentActNumber(); |
|
if ( i != ACT_NONE_SPECIFIED ) |
|
{ |
|
i = clamp( i, 0, MAX_ACTS - 1 ); |
|
Overlays *p = &m_rgOverlays[ teamIndex ][ i ]; |
|
if ( p->m_bInUse ) |
|
{ |
|
int r, g, b, a; |
|
|
|
if ( p->m_pOverlay ) |
|
{ |
|
p->m_pOverlay->GetColor( r, g, b, a ); |
|
Color clr( r, g, b, alpha ); |
|
p->m_pOverlay->SetColor( clr ); |
|
p->m_pOverlay->DoPaint( NULL, 0, (float)alpha/255.0f ); |
|
} |
|
|
|
if ( p->m_pText && m_pTextPanel ) |
|
{ |
|
p->m_pText->GetColor( r, g, b, a ); |
|
Color clr( r, g, b, alpha ); |
|
p->m_pText->SetColor( clr ); |
|
|
|
m_pTextPanel->SetImage( p->m_pText ); |
|
|
|
clr = m_BackgroundColor; |
|
clr[3] = alpha; |
|
m_pBackgroundPanel->SetBgColor( clr ); |
|
|
|
textshowing = true; |
|
} |
|
} |
|
} |
|
|
|
if ( !textshowing ) |
|
{ |
|
m_pTextPanel->SetVisible( false ); |
|
m_pTextPanel->SetImage( NULL ); |
|
m_pBackgroundPanel->SetVisible( false ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::OnThink() |
|
{ |
|
BaseClass::OnThink(); |
|
|
|
C_BaseTFPlayer *local = C_BaseTFPlayer::GetLocalPlayer(); |
|
if ( local ) |
|
{ |
|
if ( local->m_TFLocal.m_bForceMapOverview && m_bMinimapZoomed != local->m_TFLocal.m_bForceMapOverview ) |
|
{ |
|
SetMinimapZoom( local->m_TFLocal.m_bForceMapOverview ); |
|
} |
|
} |
|
|
|
if ( !IsVisible() ) |
|
return; |
|
|
|
if ( m_flZoomAmount != m_flPrevZoomAmount ) |
|
{ |
|
m_flPrevZoomAmount = m_flZoomAmount; |
|
ComputeMapOrigin( m_vecCurrentOrigin ); |
|
InvokeOnTickOnChildren( this ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::Paint() |
|
{ |
|
if ( gHUD.IsHidden( HIDEHUD_MISCSTATUS ) ) |
|
{ |
|
// Remove the minimap zoom if the hud's hidden |
|
SetMinimapZoom( false ); |
|
return; |
|
} |
|
|
|
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer(); |
|
int team = 0; |
|
if ( local ) |
|
{ |
|
team = local->GetTeamNumber(); |
|
} |
|
|
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
int alpha; |
|
bool shouldDrawDetails = ShouldDrawZoomDetails( alpha ); |
|
|
|
if ( m_pTextPanel && m_pBackgroundPanel ) |
|
{ |
|
m_pTextPanel->SetVisible( shouldDrawDetails ); |
|
m_pBackgroundPanel->SetVisible( shouldDrawDetails ); |
|
} |
|
|
|
// DEBUGGING: Allow cvar override |
|
if ( current_team.GetInt() >= 0 ) |
|
{ |
|
team = current_team.GetInt(); |
|
} |
|
|
|
// Can can be 0 through MAX_ACT_TEAMS |
|
team = clamp( team, 0, MAX_ACT_TEAMS ); |
|
|
|
// Array index is 0 to MAX_ACT_TEAMS - 1 where a team of zero means no team and won't be indexed |
|
// due to logic that checks team > 0 |
|
int teamIndex = clamp( team - 1, 0, MAX_ACT_TEAMS - 1 ); |
|
|
|
if ( m_pBackground[ teamIndex ] ) |
|
{ |
|
if ( shouldDrawDetails ) |
|
{ |
|
Color clr = m_BackgroundColor; |
|
clr[3] *= alpha / 255.0f; |
|
surface()->DrawSetColor( clr ); |
|
surface()->DrawFilledRect( 0, 0, w, h ); |
|
} |
|
|
|
float offsetx, offsety; |
|
|
|
// Need to translate m_vecCurrentOrigin into minimap space |
|
InternalWorldToMinimap( |
|
MINIMAP_NOCLIP, |
|
m_vecCurrentOrigin, |
|
-m_vecMapCenter, |
|
1, |
|
offsetx, offsety ); |
|
|
|
// Scale to 0.0f to 1.0f |
|
offsetx /= (float)w; |
|
offsety /= (float)h; |
|
|
|
float minx, maxx, miny, maxy; |
|
|
|
float xscale = 1.0f; |
|
float yscale = 1.0f; |
|
float startx = 0.0f; |
|
float starty = 0.0f; |
|
|
|
Assert( m_flAspectAdjustment > 0.0f ); |
|
|
|
// Note, the scale sense is inverted here |
|
float invaspect = 1.0f / m_flAspectAdjustment; |
|
|
|
if ( m_flAspectAdjustment < 1.0f ) |
|
{ |
|
xscale = invaspect; |
|
startx = ( 1.0f - xscale ) * 0.5f; |
|
} |
|
else |
|
{ |
|
yscale = m_flAspectAdjustment; |
|
starty = ( 1.0f - yscale ) * 0.5f; |
|
} |
|
|
|
float halfzoom = ( 1.0f / GetAdjustedZoom() ) * 0.5f; |
|
|
|
// zoom scale is already normalized, so just take half in one direction, half the other |
|
minx = startx + xscale * ( offsetx - halfzoom ); |
|
miny = starty + yscale * ( offsety - halfzoom ); |
|
maxx = startx + xscale * ( offsetx + halfzoom ); |
|
maxy = starty + yscale * ( offsety + halfzoom ); |
|
|
|
SetBackgroundViewport( minx, miny, maxx, maxy, shouldDrawDetails ); |
|
|
|
m_pBackground[ teamIndex ]->DoPaint( NULL ); |
|
|
|
if ( shouldDrawDetails && ( team > 0 ) ) |
|
{ |
|
PaintActOverlays( teamIndex, alpha ); |
|
} |
|
} |
|
else |
|
{ |
|
Color clr = m_BackgroundColor; |
|
clr[3] *= alpha * 0.9f / 255.0f; |
|
|
|
surface()->DrawSetColor( clr ); |
|
surface()->DrawFilledRect( 0, 0, w, h ); |
|
} |
|
|
|
// Dumb place to do this |
|
if ( !shouldDrawDetails && CurrentActIsAWaitingAct() ) |
|
{ |
|
char *cmsg = "Wait for game start..."; |
|
int width, height; |
|
messagechars->GetStringLength( g_hFontTrebuchet24, &width, &height, cmsg ); |
|
messagechars->DrawString( g_hFontTrebuchet24, XRES(16), ScreenHeight() - (height * 6), 255, 255, 245, 255, cmsg, IMessageChars::MESSAGESTRINGID_NONE ); |
|
} |
|
|
|
Color border = m_BorderColor; |
|
border[3] = border[3] * ( alpha * 0.9f ) / 255.0f; |
|
|
|
//border = vgui::Color( 255, 0, 120, 255 ); |
|
|
|
surface()->DrawSetColor( border ); |
|
surface()->DrawOutlinedRect( 0, 0, w, h ); |
|
surface()->DrawOutlinedRect( 1, 1, w-1, h-1 ); |
|
} |
|
|
|
void CMinimapPanel::InvokeOnTickOnChildren( vgui::Panel *parent ) |
|
{ |
|
if ( !parent ) |
|
return; |
|
|
|
int c = parent->GetChildCount(); |
|
int i; |
|
for ( i = 0; i < c; i++ ) |
|
{ |
|
vgui::Panel *child = parent->GetChild( i ); |
|
child->OnTick(); |
|
InvokeOnTickOnChildren( child ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::OnTick() |
|
{ |
|
// See if the act's changed. If it has, bring up the act overlays. |
|
if ( m_nCurrentAct != GetCurrentActNumber() ) |
|
{ |
|
// g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MinimapActChanged" ); |
|
// SetMinimapZoom( true ); |
|
m_nCurrentAct = GetCurrentActNumber(); |
|
} |
|
|
|
// Cache these only once per frame if in a valid game |
|
if ( C_BasePlayer::GetLocalPlayer() && minimap_visible.GetBool() ) |
|
{ |
|
SetVisible( true ); |
|
ComputeMapOrigin( m_vecCurrentOrigin ); |
|
} |
|
else |
|
{ |
|
SetVisible( false ); |
|
} |
|
|
|
InvokeOnTickOnChildren( this ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : alpha - |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool CMinimapPanel::ShouldDrawZoomDetails( int& alpha ) |
|
{ |
|
alpha = (int)m_flDetailsAlpha; |
|
alpha = clamp( alpha, 0, 255 ); |
|
|
|
if ( !alpha ) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : center - |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::ComputeMapOrigin( Vector& origin ) |
|
{ |
|
Vector worldmins, worldmaxs, worldsize; |
|
MapData().GetMapBounds( worldmins, worldmaxs ); |
|
VectorSubtract( worldmaxs, worldmins, worldsize ); |
|
|
|
// Cache true map center |
|
m_vecMapCenter = ( worldmins + worldmaxs ) * 0.5f; |
|
|
|
C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); |
|
|
|
Vector playerOrigin; |
|
|
|
if( !pPlayer ) |
|
{ |
|
playerOrigin = m_vecMapCenter; |
|
} |
|
else |
|
{ |
|
playerOrigin = pPlayer->GetAbsOrigin(); |
|
} |
|
|
|
origin.Init(); |
|
|
|
playerOrigin.z = m_vecMapCenter.z = 0.0f; |
|
|
|
Vector delta = playerOrigin - m_vecMapCenter; |
|
|
|
// Map center pointer is biased toward player origin as we become zoomed in to 1.0x to 2.5x and toward true world center as we zoom all the way out |
|
VectorScale( delta, m_flCenterOnPlayer, origin ); |
|
|
|
int vw, vh; |
|
GetSize( vw, vh ); |
|
|
|
m_flMapAspectRatio = 1.0f; |
|
m_flViewportAspectRatio = 1.0f; |
|
m_flAspectAdjustment = 1.0f; |
|
|
|
if ( vh > 0 ) |
|
{ |
|
m_flViewportAspectRatio = ( float )vw / ( float )vh; |
|
} |
|
|
|
if ( worldsize.y > 0 ) |
|
{ |
|
m_flMapAspectRatio = worldsize.x / worldsize.y; |
|
} |
|
|
|
if ( m_flViewportAspectRatio > 0 ) |
|
{ |
|
m_flAspectAdjustment = m_flMapAspectRatio / m_flViewportAspectRatio; |
|
} |
|
|
|
float fittedworldunitsperpixel; |
|
float zoomedworldunitsperpixel; |
|
float zooomedoutworldunitsperpixel; |
|
float actualworldunitsperpixel; |
|
|
|
if ( m_flAspectAdjustment > 1.0f ) |
|
{ |
|
// World height fits exactly in minimap height at zoom 1x |
|
fittedworldunitsperpixel = worldsize.y / (float)( vh ); |
|
|
|
// At higher zoom we get less world units per pixel |
|
zoomedworldunitsperpixel = fittedworldunitsperpixel / m_flZoomAmount; |
|
|
|
// at fully zoomed back view, world width fits window width instead |
|
zooomedoutworldunitsperpixel = worldsize.x / (float)( vw ); |
|
|
|
// As we center more on player, we move away from zoomed out units and toward zoomed units per pixel |
|
actualworldunitsperpixel = zooomedoutworldunitsperpixel + m_flCenterOnPlayer * ( zoomedworldunitsperpixel - zooomedoutworldunitsperpixel ); |
|
|
|
m_flZoomAdjust = (1-m_flCenterOnPlayer) + m_flCenterOnPlayer * ( 1/m_flViewportAspectRatio ); |
|
} |
|
else |
|
{ |
|
// World width fits exactly in minimap width at zoom 1x |
|
fittedworldunitsperpixel = worldsize.x / (float)( vw ); |
|
|
|
// At higher zoom we get less world units per pixel |
|
zoomedworldunitsperpixel = fittedworldunitsperpixel / m_flZoomAmount; |
|
|
|
// at fully zoomed back view, world height fits window height instead |
|
zooomedoutworldunitsperpixel = worldsize.y / (float)( vh ); |
|
|
|
// As we center more on player, we move away from zoomed out units and toward zoomed units per pixel |
|
actualworldunitsperpixel = zooomedoutworldunitsperpixel + m_flCenterOnPlayer * ( zoomedworldunitsperpixel - zooomedoutworldunitsperpixel ); |
|
|
|
m_flZoomAdjust = (1-m_flCenterOnPlayer) + m_flCenterOnPlayer * ( 1/m_flAspectAdjustment ); |
|
} |
|
|
|
Vector preOrigin = origin; |
|
|
|
float inset_pixels = m_flInsetPixels; |
|
|
|
float viewport_width_world_units = ( float )( vw - 2 * inset_pixels ) * actualworldunitsperpixel; |
|
float viewport_height_world_units = ( float )( vh - 2 * inset_pixels ) * actualworldunitsperpixel; |
|
|
|
// Insets apply when centering on player |
|
m_flWorldSpaceInsets[ 0 ] = MIN( m_vecMapCenter.x, worldmins.x + m_flCenterOnPlayer * ( viewport_width_world_units ) * 0.5f ); |
|
m_flWorldSpaceInsets[ 1 ] = MIN( m_vecMapCenter.y, worldmins.y + m_flCenterOnPlayer * ( viewport_height_world_units ) * 0.5f ); |
|
m_flWorldSpaceInsets[ 2 ] = MAX( m_vecMapCenter.x, worldmaxs.x - m_flCenterOnPlayer * ( viewport_width_world_units ) * 0.5f ); |
|
m_flWorldSpaceInsets[ 3 ] = MAX( m_vecMapCenter.y, worldmaxs.y - m_flCenterOnPlayer * ( viewport_height_world_units ) * 0.5f ); |
|
|
|
// Assuming origin is at center of view, compute world space left, top, right, bottom |
|
m_flWorldSpaceBounds[ 0 ] = m_vecMapCenter.x + origin.x - viewport_width_world_units * 0.5f; |
|
m_flWorldSpaceBounds[ 1 ] = m_vecMapCenter.y + origin.y - viewport_height_world_units * 0.5f; |
|
m_flWorldSpaceBounds[ 2 ] = m_vecMapCenter.x + origin.x + viewport_width_world_units * 0.5f; |
|
m_flWorldSpaceBounds[ 3 ] = m_vecMapCenter.y + origin.y + viewport_height_world_units * 0.5f; |
|
|
|
// Clip these bounds |
|
m_flClippedWorldSpaceBounds[ 0 ] = MAX( worldmins.x, m_flWorldSpaceBounds[ 0 ] ); |
|
m_flClippedWorldSpaceBounds[ 1 ] = MAX( worldmins.y, m_flWorldSpaceBounds[ 1 ] ); |
|
m_flClippedWorldSpaceBounds[ 2 ] = MIN( worldmaxs.x, m_flWorldSpaceBounds[ 2 ] ); |
|
m_flClippedWorldSpaceBounds[ 3 ] = MIN( worldmaxs.y, m_flWorldSpaceBounds[ 3 ] ); |
|
|
|
// Clip origin to inserts |
|
origin.x = clamp( origin.x, m_flWorldSpaceInsets[ 0 ] - m_vecMapCenter.x, m_flWorldSpaceInsets[ 2 ] - m_vecMapCenter.x ); |
|
origin.y = clamp( origin.y, m_flWorldSpaceInsets[ 1 ] - m_vecMapCenter.y, m_flWorldSpaceInsets[ 3 ] - m_vecMapCenter.y ); |
|
|
|
/* |
|
engine->Con_NPrintf( 1, "map bounds left %i top %i right %i bottom %i", |
|
(int)worldmins.x, |
|
(int)worldmins.y, |
|
(int)worldmaxs.x, |
|
(int)worldmaxs.y ); |
|
|
|
engine->Con_NPrintf( 2, "world space bounds left %i top %i right %i bottom %i", |
|
(int)m_flWorldSpaceBounds[ 0 ], |
|
(int)m_flWorldSpaceBounds[ 1 ], |
|
(int)m_flWorldSpaceBounds[ 2 ], |
|
(int)m_flWorldSpaceBounds[ 3 ] ); |
|
|
|
engine->Con_NPrintf( 3, "world space insets left %i top %i right %i bottom %i", |
|
(int)m_flWorldSpaceInsets[ 0 ], |
|
(int)m_flWorldSpaceInsets[ 1 ], |
|
(int)m_flWorldSpaceInsets[ 2 ], |
|
(int)m_flWorldSpaceInsets[ 3 ] ); |
|
|
|
engine->Con_NPrintf( 4, "world space clipping left %i top %i right %i bottom %i", |
|
(int)m_flClippedWorldSpaceBounds[ 0 ], |
|
(int)m_flClippedWorldSpaceBounds[ 1 ], |
|
(int)m_flClippedWorldSpaceBounds[ 2 ], |
|
(int)m_flClippedWorldSpaceBounds[ 3 ] ); |
|
|
|
|
|
engine->Con_NPrintf( 5, "world center %i %i", |
|
(int)m_vecMapCenter.x, (int)m_vecMapCenter.y ); |
|
|
|
engine->Con_NPrintf( 6, "player origin %i %i", |
|
(int)playerOrigin.x, (int)playerOrigin.y ); |
|
|
|
engine->Con_NPrintf( 7, "desired map center %i %i", |
|
(int)( m_vecMapCenter.x + preOrigin.x ), (int)( preOrigin.y + m_vecMapCenter.x ) ); |
|
|
|
engine->Con_NPrintf( 8, "actual map center %i %i", |
|
(int)( m_vecMapCenter.x + origin.x ), (int)( origin.y + m_vecMapCenter.y ) ); |
|
|
|
engine->Con_NPrintf( 9, "viewport (%ix%i) aspect %.2f world (%ix%i) aspect %f", |
|
vw, vh, m_flViewportAspectRatio, (int)worldsize.x, (int)worldsize.y, m_flMapAspectRatio ); |
|
|
|
engine->Con_NPrintf( 10, "zoom %.3f zoom adjust %.3f", |
|
m_flZoomAmount, m_flZoomAdjust ); |
|
|
|
engine->Con_NPrintf( 11, "viewport %i x %i", |
|
(int)viewport_width_world_units, (int)viewport_height_world_units ); |
|
*/ |
|
|
|
// Assume 100% scale and no x or y offset to make up for aspect ration diff |
|
m_flNormalizedXScale = 1.0f; |
|
m_flNormalizedYScale = 1.0f; |
|
m_flNormalizedXOffset = 0.0f; |
|
m_flNormalizedYOffset = 0.0f; |
|
|
|
if ( m_flAspectAdjustment < 1.0f ) |
|
{ |
|
m_flNormalizedXScale = m_flAspectAdjustment; |
|
// Offset 0->1 version of x value |
|
m_flNormalizedXOffset = ( 1.0f - m_flNormalizedXScale ) * 0.5f; |
|
} |
|
else |
|
{ |
|
m_flNormalizedYScale = 1.0f / m_flAspectAdjustment; |
|
// Offset 0->1 version of y value |
|
m_flNormalizedYOffset = ( 1.0f - m_flNormalizedYScale ) * 0.5f; |
|
} |
|
} |
|
|
|
void CMinimapPanel::InitOverlays( const char *materialrootname ) |
|
{ |
|
if ( !materialrootname || !materialrootname[0] ) |
|
return; |
|
|
|
int t; |
|
for ( t = 0; t < MAX_ACT_TEAMS; t++ ) |
|
{ |
|
char teamnum[ 2 ]; |
|
Q_snprintf( teamnum, sizeof( teamnum ), "%01i", t + 1 ); |
|
|
|
int i; |
|
for ( i = 0; i < MAX_ACTS; i++ ) |
|
{ |
|
char actnum[ 3 ]; |
|
|
|
char filename[ 512 ]; |
|
|
|
Q_snprintf( actnum, sizeof( actnum ), "%02i", i ); |
|
|
|
Overlays *p = &m_rgOverlays[ t ][ i ]; |
|
Assert( p && !p->m_bInUse ); |
|
|
|
Q_snprintf( filename, sizeof( filename ), "%s_act%s_overlay_team%s", |
|
materialrootname, actnum, teamnum ); |
|
|
|
// Check if file exists |
|
if ( g_pFullFileSystem->FileExists( VarArgs( "materials/%s.vmt", filename ) ) ) |
|
{ |
|
p->m_pOverlay = new BitmapImage( GetVPanel(), filename ); |
|
p->m_bInUse = true; |
|
} |
|
else |
|
{ |
|
// Try it without the team number |
|
Q_snprintf( filename, sizeof( filename ), "%s_act%s_overlay", |
|
materialrootname, actnum ); |
|
|
|
if ( g_pFullFileSystem->FileExists( VarArgs( "materials/%s.vmt", filename ) ) ) |
|
{ |
|
p->m_pOverlay = new BitmapImage( GetVPanel(), filename ); |
|
p->m_bInUse = true; |
|
} |
|
} |
|
|
|
Q_snprintf( filename, sizeof( filename ), "%s_act%s_text_team%s", |
|
materialrootname, actnum, teamnum ); |
|
|
|
// Check if file exists |
|
if ( g_pFullFileSystem->FileExists( VarArgs( "materials/%s.vmt", filename ) ) ) |
|
{ |
|
p->m_pText = new BitmapImage( GetTextPaintPanel()->GetVPanel(), filename ); |
|
p->m_bInUse = true; |
|
} |
|
else |
|
{ |
|
// Try it without the team number |
|
Q_snprintf( filename, sizeof( filename ), "%s_act%s_text", |
|
materialrootname, actnum ); |
|
|
|
// Check if file exists |
|
if ( g_pFullFileSystem->FileExists( VarArgs( "materials/%s.vmt", filename ) ) ) |
|
{ |
|
p->m_pText = new BitmapImage( GetTextPaintPanel()->GetVPanel(), filename ); |
|
p->m_bInUse = true; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
void CMinimapPanel::ShutdownOverlays( void ) |
|
{ |
|
int t; |
|
for ( t = 0; t < MAX_ACT_TEAMS; t++ ) |
|
{ |
|
|
|
int i; |
|
for ( i = 0; i < MAX_ACTS; i++ ) |
|
{ |
|
Overlays *p = &m_rgOverlays[ t ][ i ]; |
|
Assert( p ); |
|
if ( !p->m_bInUse ) |
|
continue; |
|
|
|
delete p->m_pOverlay; |
|
delete p->m_pText; |
|
p->m_bInUse = false; |
|
p->m_pOverlay = NULL; |
|
p->m_pText = NULL; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : Panel |
|
//----------------------------------------------------------------------------- |
|
Panel *CMinimapPanel::GetTextPaintPanel( void ) |
|
{ |
|
ClientModeTFBase *basemode = ( ClientModeTFBase * )g_pClientMode; |
|
if ( !basemode ) |
|
{ |
|
Assert( 0 ); |
|
return NULL; |
|
} |
|
|
|
return basemode->GetMinimapParent(); |
|
} |
|
|
|
void CMinimapPanel::ZoomIn( void ) |
|
{ |
|
if ( m_flDetailsAlpha > 0 ) |
|
{ |
|
if ( m_nZoomLevel != 0 ) |
|
{ |
|
// g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( |
|
// "MinimapZoomLevel0" ); |
|
} |
|
|
|
// Full window |
|
m_nZoomLevel = 0; |
|
} |
|
else |
|
{ |
|
m_nZoomLevel = ( m_nZoomLevel + 1 ) % ( NUM_WIDTHS ); |
|
m_nZoomLevel = clamp( m_nZoomLevel, 0, NUM_WIDTHS - 1 ); |
|
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( |
|
m_nZoomLevel == 0 ? |
|
"MinimapZoomLevel0" : |
|
"MinimapZoomLevel1" ); |
|
} |
|
} |
|
|
|
void CMinimapPanel::Zoom_Minimap_f( void ) |
|
{ |
|
ClientModeTFBase *basemode = ( ClientModeTFBase * )g_pClientMode; |
|
if ( !basemode ) |
|
return; |
|
|
|
CMinimapPanel *minimap = basemode->GetMinimap(); |
|
if ( !minimap ) |
|
return; |
|
|
|
minimap->ZoomIn(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::ToggleMinimap( void ) |
|
{ |
|
int iKeybits = ::input->GetButtonBits( 0 ); |
|
bool hitting_button = ( iKeybits & (IN_ATTACK | IN_ATTACK2 | IN_JUMP) ) ? true : false; |
|
if ( hitting_button && !m_bMinimapZoomed ) |
|
{ |
|
CLocalPlayerFilter filter; |
|
C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "ClientModeTFNormal.ToggleMinimap" ); |
|
} |
|
|
|
SetMinimapZoom( !m_bMinimapZoomed ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void Toggle_Minimap_f( void ) |
|
{ |
|
ClientModeTFBase *basemode = ( ClientModeTFBase * )g_pClientMode; |
|
if ( !basemode ) |
|
return; |
|
|
|
CMinimapPanel *minimap = basemode->GetMinimap(); |
|
if ( !minimap ) |
|
return; |
|
minimap->ToggleMinimap(); |
|
} |
|
|
|
static ConCommand minimap( "minimap", Toggle_Minimap_f, "Toggle size of the tf2 minimap." ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the state of the minimap's zoom |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::SetMinimapZoom( bool bZoom ) |
|
{ |
|
C_BaseTFPlayer *local = C_BaseTFPlayer::GetLocalPlayer(); |
|
if ( local && local->m_TFLocal.m_bForceMapOverview ) |
|
{ |
|
bZoom = true; |
|
} |
|
|
|
bool changed = bZoom != m_bMinimapZoomed; |
|
m_bMinimapZoomed = bZoom; |
|
if ( bZoom ) |
|
{ |
|
m_nZoomLevel = 0; |
|
} |
|
|
|
if ( changed ) |
|
{ |
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( |
|
m_bMinimapZoomed ? |
|
"MinimapZoomToFullScreen" : |
|
"MinimapZoomToCorner"); |
|
|
|
CLocalPlayerFilter filter; |
|
C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, m_bMinimapZoomed ? "Minimap.ZoomIn" : "Minimap.ZoomOut" ); |
|
|
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get at input data before it's used |
|
//----------------------------------------------------------------------------- |
|
void CMinimapPanel::ProcessInput() |
|
{ |
|
int iKeybits = ::input->GetButtonBits( 0 ); |
|
|
|
bool hitting_button = ( iKeybits & (IN_ATTACK | IN_ATTACK2 | IN_JUMP) ) ? true : false; |
|
|
|
// While the minimap's zoomed, |
|
if ( m_bMinimapZoomed && hitting_button ) |
|
{ |
|
SetMinimapZoom( false ); |
|
::input->ClearInputButton( (IN_ATTACK | IN_ATTACK2 | IN_JUMP) ); |
|
} |
|
|
|
CHudElement::ProcessInput(); |
|
} |
|
|
|
static ConCommand zoom_minimap( "zoom_minimap", CMinimapPanel::Zoom_Minimap_f, "Zoom in on minimap." ); |
|
|
|
|
|
|
|
|
|
|