📄 hud_minimap.cpp
字号:
//-----------------------------------------------------------------------------
// 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 ( vgui::filesystem()->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 ( vgui::filesystem()->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 ( vgui::filesystem()->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 ( vgui::filesystem()->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." );
//-----------------------------------------------------------------------------
// Purpose: Play a pulse on the minimap
//-----------------------------------------------------------------------------
void __MsgFunc_MinimapPulse(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
Vector vecPosition;
READ_VEC3COORD( vecPosition );
C_TFTeam *pTeam = (C_TFTeam *)GetLocalTeam();
if ( pTeam )
{
pTeam->NotifyBaseUnderAttack( vecPosition, false );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -