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.
1368 lines
37 KiB
1368 lines
37 KiB
5 years ago
|
//========= 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." );
|
||
|
|
||
|
|
||
|
|
||
|
|