⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commanderoverlaypanel.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			(int)tr.endpos.x,
			(int)tr.endpos.y,
			(int)tr.endpos.z );

		engine->ServerCmd( cmd );
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : x - 
//			y - 
//			mouse - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::UpdateMousePos( int x, int y, MouseDown_t& mouse )
{
	// store previous
	mouse.m_nXPrev = mouse.m_nXCurrent;
	mouse.m_nYPrev = mouse.m_nYCurrent;
	// update current
	mouse.m_nXCurrent = x;
	mouse.m_nYCurrent = y;
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : x - 
//			y - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::OnCursorMoved(int x, int y)
{
	UpdateMousePos( x, y, m_left );
	UpdateMousePos( x, y, m_right );

	RightMouseMapMove();
//	RequestFocus();
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : x - 
//			y - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::GetMousePos( int& x, int& y )
{
	vgui::input()->GetCursorPos( x, y );
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : mouse - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::StartMovingMouse( MouseDown_t& mouse )
{
	mouse.m_bMouseDown = true;
	GetMousePos( mouse.m_nXStart, mouse.m_nYStart );

	mouse.m_nXCurrent = mouse.m_nXPrev = mouse.m_nXStart;
	mouse.m_nYCurrent = mouse.m_nYPrev = mouse.m_nYStart;

	vgui::input()->SetMouseCapture( GetVPanel() );
}

//-----------------------------------------------------------------------------
// Purpose: Left mouse button down
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::LeftMousePressed( void )
{
	if ( m_left.m_bMouseDown || m_right.m_bMouseDown )
		return;

	StartMovingMouse( m_left );
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : code - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::OnMousePressed(vgui::MouseCode code)
{
	switch ( code )
	{
	case vgui::MOUSE_LEFT:
		LeftMousePressed();
		break;
	case vgui::MOUSE_RIGHT:
		RightMousePressed();
		break;
	default:
		BaseClass::OnMousePressed( code );
		return;
	}

//	RequestFocus();
}

//-----------------------------------------------------------------------------
// Purpose: 
// Input  : x0 - 
//			y0 - 
//			x1 - 
//			y1 - 
//			true - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::SelectPlayersInRectangle( int x0, int y0, int x1, int y1, bool clearOldSelections /*= true*/ )
{
	int num_selected = 0;

	// Assume zero players in selection
	if ( clearOldSelections )
	{
		m_bHaveActiveSelection = false;
	}
	else
	{
		// Count # selected
		num_selected = CountSelectedPlayers();
	}

	CMapPlayers *pPlayer;
	C_BaseTFPlayer	*tf2player;

	// See which players on my team are within the rectangle in screen space
	//
	for ( int playerNum = 1; playerNum <= MAX_PLAYERS; playerNum++ )
	{
		pPlayer = &MapData().m_Players[ playerNum - 1 ];

		if ( clearOldSelections )
		{
			pPlayer->m_bSelected = false;
		}

		if ( playerNum > engine->GetMaxClients() )
		{
			continue;
		}

		tf2player = dynamic_cast<C_BaseTFPlayer *>( cl_entitylist->GetEnt( playerNum ) );
		if ( !tf2player )
		{
			continue;
		}

		// Check pvs on this guy
		// If the entity was in the commander's PVS then show it on the minimap, too
		//
		if ( ArePlayersOnSameTeam( engine->GetPlayer(), playerNum ) == false )
		{
			continue;
		}

		// Check their actual draw position
		int drawX, drawY;
		Vector pos, screen;

		pos = tf2player->GetAbsOrigin();

		// Transform
		debugoverlay->ScreenPosition( pos, screen );

		// FIXME: Get the player icon size from where?!?					
		drawX = screen.x - 32;
		drawY = screen.y - 40;
		int intersectX = 64;
		int intersectY = 64;

		// Check for intersection ( with slop )
		if ( drawX + intersectX < x0 )
			continue;
		if ( drawX > x1 )
			continue;
		if ( drawY + intersectY < y0 )
			continue;
		if ( drawY > y1 )
			continue;

		// Already selected?
		if ( !pPlayer->m_bSelected )
		{
			// Add to selected list
			pPlayer->m_bSelected = true;
			num_selected++;
		}
	}

	if ( num_selected != 0 )
	{
		m_bHaveActiveSelection = true;
	}
}

//-----------------------------------------------------------------------------
// Returns the visible area (not including the tech tree)
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::GetVisibleSize( int& w, int& h )
{
	GetSize( w, h );

	// FIXME: Hack to make the map appear above the tech tree
	h -= 200;
}

//-----------------------------------------------------------------------------
// Returns the visible area (not including the tech tree)
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::GetVisibleArea( Vector& mins, Vector& maxs )
{
	float w, h;
	GetVisibleOrthoSize( w, h );

	ActualToVisibleOffset( mins );
	mins += m_vecTacticalOrigin;
	maxs = mins;
	mins.x -= w; maxs.x +=w;
	mins.y -= h; maxs.y +=h;
}

//-----------------------------------------------------------------------------
// Purpose: User let go of left mouse button
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::LeftMouseReleased( void )
{
	if ( !m_left.m_bMouseDown )
		return;

	m_left.m_bMouseDown = false;

	int mx, my;
	GetMousePos( mx, my );
	UpdateMousePos( mx, my, m_left );

	vgui::input()->SetMouseCapture( NULL );

	// Normalize the rectangle
	int x0, y0, x1, y1;
	x0 = min( m_left.m_nXStart, m_left.m_nXCurrent );
	x1 = max( m_left.m_nXStart, m_left.m_nXCurrent );
	y0 = min( m_left.m_nYStart, m_left.m_nYCurrent );
	y1 = max( m_left.m_nYStart, m_left.m_nYCurrent );

	bool clearOldStates = true;
	if ( vgui::input()->IsKeyDown( vgui::KEY_LCONTROL ) )
	{
		clearOldStates = false;
	}

	SelectPlayersInRectangle( x0, y0, x1, y1, clearOldStates );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::GetOrthoRenderBox(Vector &vCenter, float &xSize, float &ySize)
{
	vCenter = m_vecTacticalOrigin;

	// min and max depends on the current zoom level
	int w, h;
	GetParent()->GetSize( w, h );

	xSize = m_fZoom;
	ySize = xSize * ( (float)h / (float)w );

	xSize *= 0.5f;
	ySize *= 0.5f;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::GetVisibleOrthoSize(float &xSize, float &ySize)
{
	// min and max depends on the current zoom level
	int w, h;
	GetVisibleSize( w, h );
	xSize = m_fZoom;
	ySize = xSize * ( (float)h / (float)w );

	xSize *= 0.5f;
	ySize *= 0.5f;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CCommanderOverlayPanel::WorldUnitsPerPixel()
{
	int w, h;
	GetParent()->GetSize( w, h );
	return m_fZoom / w;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::ActualToVisibleOffset( Vector& offset )
{
	// FIXME: This doesn't work arbitrarily; we assume the visible
	// part is on the top of the screen..
	int w, h, wact, hact;
	GetVisibleSize( w, h );
	GetParent()->GetSize( wact, hact );
	
	float worldUnitsPerPixel = m_fZoom / wact;
	float dWorldY = (hact - h) * 0.5f * worldUnitsPerPixel;
	offset.Init( 0, dWorldY, 0 );
}

//-----------------------------------------------------------------------------
// Purpose: Make sure origin is inside map x, y bounds ( not z )
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::BoundOrigin( Vector& camera )
{
	// We're going to do this entire computation assuming the camera
	// is in the center of the viewable area, which it isn't. At the
	// end, we'll need to apply a fixup to deal with that

	Vector mins, maxs, halfsize;
	MapData().GetMapBounds( mins, maxs );
	VectorSubtract( maxs, mins, halfsize );
	halfsize *= 0.5f;

	// avoid black edges...
	float dim[2];
	GetVisibleOrthoSize( dim[0], dim[1] );

	// Compute the position of the center of the visible area based on
	// the new suggested camera position 
	Vector actualToVisible, newVisCenter;
	ActualToVisibleOffset( actualToVisible );
	VectorAdd( camera, actualToVisible, newVisCenter );

	// Only bound x & y
	for ( int i = 0; i < 2; i++ )
	{
		if (dim[i] > halfsize[i])
		{
			newVisCenter[i] = mins[i] + halfsize[i];
		}
		else
		{
			newVisCenter[ i ] = max( newVisCenter[i], mins[i] + dim[i] );
			newVisCenter[ i ] = min( newVisCenter[i], maxs[i] - dim[i] );
		}
	}

	// Remember: The viewport takes up the entire screen; but the visible
	// area only takes up the top half of the screen. Therefore, we need to
	// set the origin so that the center of what we want lies at the
	// center of the visible region
	VectorSubtract( newVisCenter, actualToVisible, camera ); 
}

//-----------------------------------------------------------------------------
// Purpose: 
// Given mouse/screen positions as well as the current
//  render origin and angles, returns a unit vector through the mouse position
//  that can be used to trace into the world under the mouse click pixel.
// Input  : fov - 
//			mousex - 
//			mousey - 
//			screenwidth - 
//			screenheight - 
//			vecRenderAngles - 
//			c_x - 
//			vpn - 
//			vup - 
//			360.0 - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::CreatePickingRay( int mousex, int mousey, 
	int screenwidth, int screenheight,
	const Vector& vecRenderOrigin, 
	const QAngle& vecRenderAngles, 
	Vector &rayOrigin,
	Vector &rayDirection
	)
{
	Vector vCenter;
	float xSize, ySize;
	GetOrthoRenderBox(vCenter, xSize, ySize);
	
	float xPos = RemapVal(mousex, 0, screenwidth,  vCenter.x-xSize, vCenter.x+xSize);
	float yPos = RemapVal(mousey, 0, screenheight, vCenter.y+ySize, vCenter.y-ySize); // (flip screen y)
	rayOrigin.Init(xPos, yPos, vCenter.z);
	rayDirection.Init(0, 0, -1);
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::OnMouseReleased(vgui::MouseCode code)
{
	switch ( code )
	{
	case vgui::MOUSE_LEFT:
		LeftMouseReleased();
		break;
	case vgui::MOUSE_RIGHT:
		RightMouseReleased();
		break;
	default:
		BaseClass::OnMouseReleased( code );
		return;
	}

//	RequestFocus();
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::CenterOnMouse( Vector& mouseWorldPos )
{
	// Figure out worldspace movement based on picking ray
	Vector rayForward;
	Vector centerOrigin;

	int mx, my;
	GetMousePos( mx, my );

	// Need to convert from screen space back to a worldspace ray
	CreatePickingRay( 
		mx, my, 
		ScreenWidth(), ScreenHeight(),
		CurrentViewOrigin(), 
		CurrentViewAngles(),
		mouseWorldPos,
		rayForward );

	CreatePickingRay( 
		ScreenWidth()/2, ScreenHeight()/2, 
		ScreenWidth(), ScreenHeight(),
		CurrentViewOrigin(), 
		CurrentViewAngles(),
		centerOrigin,
		rayForward );

	Vector offset;
	VectorSubtract( mouseWorldPos, centerOrigin, offset );
	offset.z = 0.0f;
	VectorAdd( m_vecTacticalOrigin, offset, m_vecTacticalOrigin );
}


//-----------------------------------------------------------------------------
// Purpose: 
// Input  : delta - 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::OnMouseWheeled(int delta)
{
	// Figure out worldspace movement based on picking ray
	Vector rayOrigin;

	CenterOnMouse( rayOrigin );

	// Gotta do the zoom after picking the ray, or it'll use the wrong zoom factor
	// for computing the picking ray
	if ( delta < 0 )
	{
		m_fZoom *= 1.25f;
	}
	else if ( delta > 0 )
	{
		m_fZoom /= 1.25f;
	}

	m_fZoom = min( m_fZoom, m_MaxWorldWidth );
	m_fZoom = max( m_fZoom, m_MinWorldWidth );

	BoundOrigin( m_vecTacticalOrigin );

	// move mouse to center and zero out any delta
	m_pCommanderView->MoveMouse( rayOrigin );

//	RequestFocus();
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CCommanderOverlayPanel::Paint()
{
	if ( !m_left.m_bMouseDown )
		return;

	// Update mouse position, so we don't get the 1 frame lag
	int mx, my;
	GetMousePos( mx, my );
	UpdateMousePos( mx, my, m_left );

	int x0, x1, y0, y1;
	// Make sure it's normalized
	x0 = min( m_left.m_nXStart, m_left.m_nXCurrent );
	x1 = max( m_left.m_nXStart, m_left.m_nXCurrent );
	y0 = min( m_left.m_nYStart, m_left.m_nYCurrent );
	y1 = max( m_left.m_nYStart, m_left.m_nYCurrent );

	// Draw selection rectangle
	vgui::surface()->DrawSetColor( 200, 220, 250, 192 );
	vgui::surface()->DrawOutlinedRect( x0, y0, x1, y1 );
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CCommanderOverlayPanel::GetZoom( void )
{
	return (m_fZoom - m_MinWorldWidth) / (m_MaxWorldWidth - m_MinWorldWidth);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -