📄 commanderoverlaypanel.cpp
字号:
//-----------------------------------------------------------------------------
// The panel responsible for rendering the 3D view in orthographic mode
//-----------------------------------------------------------------------------
#include "cbase.h"
#include <vgui/VGUI.h>
#include <vgui_controls/Controls.h>
#include <vgui/IVGui.h>
#include <vgui/IInput.h>
#include <vgui/ISurface.h>
#include "clientmode_commander.h"
#include "vgui_int.h"
#include "iinput.h"
#include "kbutton.h"
#include "hud_minimap.h"
#include "usercmd.h"
#include "mapdata.h"
#include "c_basetfplayer.h"
#include "view.h"
#include "view_shared.h"
#include "CommanderOverlay.h"
#include "C_TfTeam.h"
#include <vgui/mousecode.h>
#include <vgui/KeyCode.h>
#include <vgui/IPanel.h>
#include "commanderoverlaypanel.h"
#include "PixelWriter.h"
#include "materialsystem/IMaterialVar.h"
#include "materialsystem/ITexture.h"
#include "vtf/vtf.h"
#include "engine/IVDebugOverlay.h"
static inline int AlphaMapIndex(int x, int y)
{
return y * FOG_ALPHAMAP_SIZE + x;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *commander -
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::SetCommanderView( CClientModeCommander *commander )
{
m_pCommanderView = commander;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CCommanderOverlayPanel::CCommanderOverlayPanel( void ) :
vgui::Panel( NULL, "CommanderOverlayPanel" ),
m_CursorCommander(vgui::dc_arrow),
m_CursorRightMouseMove(vgui::dc_hand)
{
MakePopup();
SetPaintBackgroundEnabled( false );
m_left.m_bMouseDown = false;
m_left.m_nXStart = 0;
m_left.m_nYStart = 0;
m_right.m_bMouseDown = false;
m_right.m_nXStart = 0;
m_right.m_nYStart = 0;
m_fZoom = 0;
m_flPreviousMaxWorldWidth = 0.0f;
SetVisible( false );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CCommanderOverlayPanel::~CCommanderOverlayPanel( void )
{
}
//-----------------------------------------------------------------------------
// Initialize rendering origin
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::InitializeRenderOrigin()
{
// Initializes the rendering origin
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
if ( player )
{
m_vecTacticalOrigin = player->GetAbsOrigin();
}
else
{
MapData().GetMapOrigin( m_vecTacticalOrigin );
}
Vector mins, maxs;
MapData().GetMapBounds( mins, maxs );
m_vecTacticalOrigin.z = maxs.z + TACTICAL_ZOFFSET;
m_vecTacticalAngles.Init( 90, 90, 0 );
BoundOrigin( m_vecTacticalOrigin );
}
//-----------------------------------------------------------------------------
// Computes the view range:
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::ComputeZoomRange()
{
// This is
m_MinWorldWidth = TACTICAL_MIN_VIEWABLE_SIZE;
// Get the world size
Vector mins, maxs, size;
MapData().GetMapBounds( mins, maxs );
VectorSubtract( maxs, mins, size );
float worldAspect = size[0] / size[1];
// size[ 0 ] *= 1.05f;
// size[ 1 ] *= 1.05f;
// Find out the panel aspect ratio
int w, h;
GetVisibleSize( w, h );
float panelAspect = (float)w / (float)h;
// Store off old zoom
m_flPreviousMaxWorldWidth = m_MaxWorldWidth;
if (panelAspect > worldAspect)
{
// In this case, to see the whole map,
// we'll have black areas on the left + right sides
// Make sure we choose a width big enough to display the entire height
m_MaxWorldWidth = size[1] * panelAspect;
}
else
{
// In this case, to see the whole map,
// we'll have black areas on the top + bottom
// Make sure we choose a width big enough to display the entire height
m_MaxWorldWidth = size[0];
}
// if flipping open/close the tech tree, preserver relative zoom amount
if ( m_flPreviousMaxWorldWidth )
{
float ratio = m_MaxWorldWidth / m_flPreviousMaxWorldWidth;
m_fZoom *= ratio;
}
}
//-----------------------------------------------------------------------------
// Call when the map changes
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::LevelInit( char const* pMapName )
{
// Always look at the entire map to start with
m_fZoom = 0;
m_flPreviousMaxWorldWidth = 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::LevelShutdown( void )
{
}
//-----------------------------------------------------------------------------
// call these when commander view is enabled/disabled
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::Enable()
{
vgui::VPANEL pRoot = VGui_GetClientDLLRootPanel();
SetCursor(m_CursorCommander);
SetVisible( true );
// Make the viewport fill the root panel.
if( pRoot)
{
int wide, tall;
vgui::ipanel()->GetSize(pRoot, wide, tall);
// subtract out the technology UI size
tall -= 0;// xxx200
SetBounds(0, 0, wide, tall);
}
// Cache the orthographic view size range
ComputeZoomRange();
// Start out looking at the whole world
if (m_fZoom == 0)
m_fZoom = m_MaxWorldWidth;
// clamp
if (m_fZoom < m_MinWorldWidth)
m_fZoom = m_MinWorldWidth;
else if (m_fZoom > m_MaxWorldWidth)
m_fZoom = m_MaxWorldWidth;
// Figure out where the camera is
InitializeRenderOrigin();
vgui::ivgui()->AddTickSignal( GetVPanel() );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::Disable()
{
SetVisible( false );
// FIXME: Need a removeTickSignal!
// vgui::ivgui()->removeTickSignal( GetVPanel() );
}
//-----------------------------------------------------------------------------
// called when we're ticked...
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::OnTick()
{
if (!IsLocalPlayerInTactical() || !engine->IsInGame())
return;
}
//-----------------------------------------------------------------------------
// Purpose: Returns up to 32 players encoded as a bit per player in a 32 bit unsigned
// Output : unsigned int
//-----------------------------------------------------------------------------
unsigned int CCommanderOverlayPanel::GetSelectedPlayerBitField( void )
{
CMapPlayers *pPlayer;
// bitfield variable
unsigned int bf = 0;
// maxplayers that can be encoded
int maxplayers;
// FIXME, do we need 64 player support?
maxplayers = min( 32, MAX_PLAYERS );
// draw all the visible players
for ( int playerNum = 0; playerNum < maxplayers; playerNum++ )
{
pPlayer = &MapData().m_Players[ playerNum ];
if ( pPlayer->m_bSelected )
{
bf |= (1<<playerNum);
}
}
return bf;
}
//-----------------------------------------------------------------------------
// Purpose: Counts how many players are selected
// Output : int
//-----------------------------------------------------------------------------
int CCommanderOverlayPanel::CountSelectedPlayers( void )
{
CMapPlayers *pPlayer;
// bitfield variable
int count = 0;
// maxplayers that can be encoded
int maxplayers;
// FIXME, do we need 64 player support?
maxplayers = min( 32, MAX_PLAYERS );
// draw all the visible players
for ( int playerNum = 0; playerNum < maxplayers; playerNum++ )
{
pPlayer = &MapData().m_Players[ playerNum ];
if ( pPlayer->m_bSelected )
{
count++;
}
}
return count;
}
//-----------------------------------------------------------------------------
// Purpose: Called when a key is pressed
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::OnKeyPressed(vgui::KeyCode code)
{
switch(code)
{
case vgui::KEY_SPACE:
if (m_fZoom != m_MaxWorldWidth)
{
ChangeZoomLevel(m_MaxWorldWidth);
}
else
{
Vector mouseWorldPos;
CenterOnMouse( mouseWorldPos );
ChangeZoomLevel(TACTICAL_SPACEBAR_VIEWABLE_SIZE);
// Place mouse over me
m_pCommanderView->MoveMouse( mouseWorldPos );
}
break;
default:
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: when space is hit, show the entire view
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::ChangeZoomLevel( float newZoom )
{
// Make sure the mouse remains over the thing it started over
// Figure out worldspace movement based on picking ray
Vector rayOrigin, rayForward;
int mx, my;
GetMousePos( mx, my );
// Need to convert from screen space back to a worldspace ray
CreatePickingRay(
mx, my,
ScreenWidth(), ScreenHeight(),
CurrentViewOrigin(),
CurrentViewAngles(),
rayOrigin,
rayForward );
m_fZoom = newZoom;
BoundOrigin( m_vecTacticalOrigin );
// move mouse to center and zero out any delta
m_pCommanderView->MoveMouse( rayOrigin );
// RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CCommanderOverlayPanel::IsRightMouseMapMoving( void )
{
return m_right.m_bMouseDown;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::RightMouseMapMove( void )
{
/*
// Figure out worldspace movement based on picking ray
Vector rayForward;
Vector vecEndPosCurrent, vecEndPosPrevious;
// Need to convert from screen space back to a worldspace ray
CreatePickingRay(
m_right.m_nXCurrent, m_right.m_nYCurrent,
ScreenWidth(), ScreenHeight(),
g_vecRenderOrigin,
g_vecRenderAngles,
vecEndPosCurrent,
rayForward );
engine->Con_NPrintf( 8, "x %i y %i hit %.3f %.3f",
m_right.m_nXCurrent, m_right.m_nYCurrent, vecEndPosCurrent.x, vecEndPosCurrent.y );
*/
if ( !m_right.m_bMouseDown )
return;
/*
// See if there is a delta in the current and previous mouse positions
//
int dx, dy;
dx = m_right.m_nXCurrent - m_right.m_nXPrev;
dy = m_right.m_nYCurrent - m_right.m_nYPrev;
// No relative move
if ( !dx && !dy )
return;
// Figure out worldspace movement based on picking ray
Vector rayForward;
Vector vecEndPosCurrent, vecEndPosPrevious;
// Need to convert from screen space back to a worldspace ray
CreatePickingRay(
m_right.m_nXCurrent, m_right.m_nYCurrent,
ScreenWidth(), ScreenHeight(),
g_vecRenderOrigin,
g_vecRenderAngles,
vecEndPosCurrent,
rayForward );
// Now create ray from old position
// Need to convert from screen space back to a worldspace ray
CreatePickingRay(
m_right.m_nXPrev, m_right.m_nYPrev,
ScreenWidth(), ScreenHeight(),
g_vecRenderOrigin,
g_vecRenderAngles,
vecEndPosPrevious,
rayForward );
// Remove z component
vecEndPosPrevious.z = 0.0;
vecEndPosCurrent.z = 0.0;
// Compute offset
Vector viewDelta;
VectorSubtract( vecEndPosCurrent, vecEndPosPrevious, viewDelta );
viewDelta.z = 0.0f;
VectorAdd( m_vecTacticalOrigin, viewDelta, m_vecTacticalOrigin );
m_pCommanderView->BoundOrigin( m_vecTacticalOrigin );
*/
}
//-----------------------------------------------------------------------------
// Purpose: Right mouse button down
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::RightMousePressed( void )
{
if ( m_left.m_bMouseDown || m_right.m_bMouseDown )
return;
SetCursor(m_CursorRightMouseMove);
StartMovingMouse( m_right );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::RightMouseReleased( void )
{
if ( !m_right.m_bMouseDown )
return;
m_right.m_bMouseDown = false;
int mx, my;
GetMousePos( mx, my );
UpdateMousePos( mx, my, m_right );
// Final move
RightMouseMapMove();
vgui::input()->SetMouseCapture( NULL );
SetCursor(m_CursorCommander);
// If the player's dead, and doesn't have the special sniper upgrade
// then check for respawn stations....
C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
if (!pPlayer)
return;
// If the player's dead, abort
if ( pPlayer->PlayerClass() == TFCLASS_SNIPER )
{
// Sniper's can request a respawn point when dead
//
Vector rayOrigin, rayForward;
Vector vecEndPos;
// Need to convert from screen space back to a worldspace ray
CreatePickingRay(
m_right.m_nXCurrent, m_right.m_nYCurrent,
ScreenWidth(), ScreenHeight(),
CurrentViewOrigin(),
CurrentViewAngles(),
rayOrigin,
rayForward );
// Now do the trace
trace_t tr;
vecEndPos = rayOrigin + rayForward * MAX_TRACE_LENGTH;
UTIL_TraceLine( rayOrigin, vecEndPos, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
// Didn't hit anything
if ( tr.fraction == 1.0 )
return;
char cmd[ 1024 ];
sprintf( cmd, "respawnpoint %i %i %i\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -