📄 hud_minimap.cpp
字号:
//======== (C) Copyright 1999, 2000 Valve, L.L.C. All rights reserved. ========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// 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 "parsemsg.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
void __MsgFunc_MinimapPulse(const char *pszName, int iSize, void *pbuf);
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 );
//-----------------------------------------------------------------------------
// 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;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -