|
|
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hud.h"
#include "hud_crosshair.h"
#include "iclientmode.h"
#include "view.h"
#include "vgui_controls/Controls.h"
#include "vgui/ISurface.h"
#include "ivrenderview.h"
#ifdef PORTAL2
#include "ivieweffects.h"
#include "c_basehlplayer.h"
#endif // PORTAL2
#ifdef SIXENSE
#include "sixense/in_sixense.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#if !defined( CSTRIKE15 )
ConVar crosshair( "crosshair", "1", FCVAR_ARCHIVE ); ConVar cl_observercrosshair( "cl_observercrosshair", "1", FCVAR_ARCHIVE );
#endif
using namespace vgui;
int ScreenTransform( const Vector& point, Vector& screen );
DECLARE_HUDELEMENT( CHudCrosshair );
CHudCrosshair::CHudCrosshair( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudCrosshair" ) { vgui::Panel *pParent = GetClientMode()->GetViewport(); SetParent( pParent );
m_pCrosshair = 0;
m_clrCrosshair = Color( 0, 0, 0, 0 );
m_vecCrossHairOffsetAngle.Init();
SetHiddenBits( HIDEHUD_PLAYERDEAD | HIDEHUD_CROSSHAIR ); }
void CHudCrosshair::ApplySchemeSettings( IScheme *scheme ) { BaseClass::ApplySchemeSettings( scheme );
m_pDefaultCrosshair = HudIcons().GetIcon( "crosshair_default" ); SetPaintBackgroundEnabled( false );
SetSize( ScreenWidth(), ScreenHeight() ); }
//-----------------------------------------------------------------------------
// Purpose: Save CPU cycles by letting the HUD system early cull
// costly traversal. Called per frame, return true if thinking and
// painting need to occur.
//-----------------------------------------------------------------------------
bool CHudCrosshair::ShouldDraw( void ) { #if defined ( CSTRIKE15 )
return false; #else
bool bNeedsDraw;
if ( m_bHideCrosshair ) return false;
C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return false;
C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); if ( pWeapon && !pWeapon->ShouldDrawCrosshair() ) return false;
/* disabled to avoid assuming it's an HL2 player.
// suppress crosshair in zoom.
if ( pPlayer->m_HL2Local.m_bZooming ) return false; */
// draw a crosshair only if alive or spectating in eye
if ( IsGameConsole() ) { bNeedsDraw = m_pCrosshair && !engine->IsDrawingLoadingImage() && !engine->IsPaused() && ( !pPlayer->IsSuitEquipped() || g_pGameRules->IsMultiplayer() ) && GetClientMode()->ShouldDrawCrosshair() && !( pPlayer->GetFlags() & FL_FROZEN ) && ( pPlayer->IsViewEntity() ) && ( pPlayer->IsAlive() || ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) || ( cl_observercrosshair.GetBool() && pPlayer->GetObserverMode() == OBS_MODE_ROAMING ) ); } else { bNeedsDraw = m_pCrosshair && crosshair.GetInt() && !engine->IsDrawingLoadingImage() && !engine->IsPaused() && GetClientMode()->ShouldDrawCrosshair() && !( pPlayer->GetFlags() & FL_FROZEN ) && ( pPlayer->IsViewEntity() ) && !pPlayer->IsInVGuiInputMode() && ( pPlayer->IsAlive() || ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) || ( cl_observercrosshair.GetBool() && pPlayer->GetObserverMode() == OBS_MODE_ROAMING ) ); }
return ( bNeedsDraw && CHudElement::ShouldDraw() ); #endif
}
void CHudCrosshair::Paint( void ) { if ( !m_pCrosshair ) return;
if ( !IsCurrentViewAccessAllowed() ) return;
#ifdef SIXENSE
float x=0, y=0;
if( g_pSixenseInput->IsEnabled() && C_BasePlayer::GetLocalPlayer() && (C_BasePlayer::GetLocalPlayer()->GetObserverMode()==OBS_MODE_NONE) ) { C_BasePlayer *player = C_BasePlayer::GetLocalPlayer(); if ( player != NULL ) {
// Never autoaim a predicted weapon (for now)
Vector aimVector; AngleVectors( CurrentViewAngles() - g_pSixenseInput->GetViewAngleOffset(), &aimVector );
// calculate where the bullet would go so we can draw the cross appropriately
Vector vecStart = player->Weapon_ShootPosition(); Vector vecEnd = player->Weapon_ShootPosition() + aimVector * MAX_TRACE_LENGTH;
trace_t tr; UTIL_TraceLine( vecStart, vecEnd, MASK_SHOT, player, COLLISION_GROUP_NONE, &tr );
Vector screen; screen.Init(); ScreenTransform(tr.endpos, screen);
x = ScreenWidth() / 2; y = ScreenHeight() / 2;
x += 0.5 * screen[0] * ScreenWidth() + 0.5; y += 0.5 * screen[1] * ScreenHeight() + 0.5; y = ScreenHeight() - y; }
} else { x = ScreenWidth() / 2; y = ScreenHeight() / 2; }
#else
float x, y; x = ScreenWidth()/2; y = ScreenHeight()/2; #endif
float flApparentZ = vgui::STEREO_NOOP; bool bStereoActive = materials->IsStereoActiveThisFrame();
m_curViewAngles = CurrentViewAngles(); m_curViewOrigin = CurrentViewOrigin();
Vector screen; screen.Init();
// TrackIR
if ( IsHeadTrackingEnabled() ) { C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return;
// TrackIR
// get the direction the player is aiming
Vector aimVector = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
// calculate where the bullet would go so we can draw the cross appropriately
Vector vecEnd = pPlayer->Weapon_ShootPosition() + aimVector * MAX_TRACE_LENGTH;
trace_t tr; UTIL_TraceLine( pPlayer->Weapon_ShootPosition(), vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr );
QAngle angles; Vector forward; Vector point;
// this code is wrong
angles = m_curViewAngles + m_vecCrossHairOffsetAngle; AngleVectors( angles, &forward );
// need to project forward into an object to see how far this
// vector should be!!
//forward *= 1000;
//VectorAdd( m_curViewOrigin, forward, point );
//ScreenTransform( point, screen );
if ( bStereoActive && ( !tr.allsolid || !tr.startsolid ) ) { // NOTE: This isn't exactly right, because the trace above starts with the gun and
// not with the camera origin, so this will be slightly off. It shouldn't really matter.
flApparentZ = ( tr.endpos - tr.startpos ).Length(); }
ScreenTransform( tr.endpos, screen ); } // TrackIR
else { Vector forward;
// MattB - m_vecCrossHairOffsetAngle is the autoaim angle.
// if we're not using autoaim, just draw in the middle of the
// screen
if ( m_vecCrossHairOffsetAngle != vec3_angle ) { QAngle angles; Vector point;
// this code is wrong
angles = m_curViewAngles + m_vecCrossHairOffsetAngle; AngleVectors( angles, &forward ); VectorAdd( m_curViewOrigin, forward, point ); ScreenTransform( point, screen ); } else { AngleVectors( m_curViewAngles, &forward ); }
if ( bStereoActive ) { C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( pPlayer && m_clrCrosshair.a() != 0.0f ) // if we have a player and we're not going to ignore the results...
{ Vector vecEnd = m_curViewOrigin + ( forward * MAX_TRACE_LENGTH );
trace_t tr; UTIL_TraceLine( m_curViewOrigin, vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr );
if ( !tr.allsolid || !tr.startsolid ) { // NOTE: This isn't exactly right, because the trace above starts with the gun and
// not with the camera origin, so this will be slightly off. It shouldn't really matter.
flApparentZ = ( tr.endpos - tr.startpos ).Length(); } } } }
x += 0.5f * screen[0] * ScreenWidth() + 0.5f; y += 0.5f * screen[1] * ScreenHeight() + 0.5f;
#ifdef PORTAL2
// Find any full-screen fades
byte color[4]; bool blend; GetViewEffects()->GetFadeParams( &color[0], &color[1], &color[2], &color[3], &blend ); m_clrCrosshair[3] = SimpleSplineRemapValClamped( color[3], 0, 64, 255, 0 ); #endif // PORTAL2
C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return;
float flWeaponScale = 1.f; float flW = m_pCrosshair->Width(); float flH = m_pCrosshair->Height(); C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); if ( pWeapon ) { pWeapon->GetWeaponCrosshairScale( flWeaponScale ); }
m_pCrosshair->DrawSelfCropped( x - 0.5f * m_pCrosshair->Width() * flWeaponScale + 0.5, y - 0.5f * m_pCrosshair->Height() * flWeaponScale + 0.5, 0, 0, flW, flH, flW*flWeaponScale, flH*flWeaponScale, m_clrCrosshair ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudCrosshair::SetCrosshairAngle( const QAngle& angle ) { VectorCopy( angle, m_vecCrossHairOffsetAngle ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudCrosshair::SetCrosshair( CHudTexture *texture, const Color& clr ) { m_pCrosshair = texture; m_clrCrosshair = clr; }
//-----------------------------------------------------------------------------
// Purpose: Resets the crosshair back to the default
//-----------------------------------------------------------------------------
void CHudCrosshair::ResetCrosshair() { SetCrosshair( m_pDefaultCrosshair, Color( 255, 255, 255, 255 ) ); }
|