|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "iclientmode.h"
#include "c_basehlplayer.h"
#include "view_scene.h"
#include "engine/IEngineSound.h"
#include "vgui_controls/AnimationController.h"
#include "vgui_controls/Controls.h"
#include "vgui_controls/Panel.h"
#include "vgui/ISurface.h"
#include "iviewrender.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar hud_draw_active_reticle("hud_draw_active_reticle", "0" ); ConVar hud_draw_fixed_reticle("hud_draw_fixed_reticle", "0", FCVAR_ARCHIVE ); ConVar hud_autoaim_scale_icon( "hud_autoaim_scale_icon", "0" ); ConVar hud_autoaim_method( "hud_autoaim_method", "1" );
ConVar hud_reticle_scale("hud_reticle_scale", "1.0" ); ConVar hud_reticle_minalpha( "hud_reticle_minalpha", "125" ); ConVar hud_reticle_maxalpha( "hud_reticle_maxalpha", "255" ); ConVar hud_alpha_speed("hud_reticle_alpha_speed", "700" ); ConVar hud_magnetism("hud_magnetism", "0.3" );
enum { AUTOAIM_METHOD_RETICLE = 1, AUTOAIM_METHOD_DRIFT, };
using namespace vgui;
class CHUDAutoAim : public CHudElement, public vgui::Panel { DECLARE_CLASS_SIMPLE( CHUDAutoAim, vgui::Panel ); public: CHUDAutoAim( const char *pElementName ); virtual ~CHUDAutoAim( void );
void ApplySchemeSettings( IScheme *scheme ); void Init( void ); void VidInit( void ); bool ShouldDraw( void ); virtual void OnThink(); virtual void Paint();
private: void ResetAlpha() { m_alpha = 0; } void ResetScale() { m_scale = 1.0f; } void ResetPosition() { m_vecPos.x = ScreenWidth() / 2; m_vecPos.y = ScreenHeight() / 2; m_vecPos.z = 0; }
Vector m_vecPos; float m_alpha; float m_scale;
float m_alphaFixed; // alpha value for the fixed element.
int m_textureID_ActiveReticle; int m_textureID_FixedReticle; };
DECLARE_HUDELEMENT( CHUDAutoAim );
CHUDAutoAim::CHUDAutoAim( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HUDAutoAim" ) { vgui::Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); SetHiddenBits( HIDEHUD_CROSSHAIR );
m_textureID_ActiveReticle = -1; m_textureID_FixedReticle = -1; }
CHUDAutoAim::~CHUDAutoAim( void ) { if ( vgui::surface() ) { if ( m_textureID_ActiveReticle != -1 ) { vgui::surface()->DestroyTextureID( m_textureID_ActiveReticle ); m_textureID_ActiveReticle = -1; }
if ( m_textureID_FixedReticle != -1 ) { vgui::surface()->DestroyTextureID( m_textureID_FixedReticle ); m_textureID_FixedReticle = -1; } } }
void CHUDAutoAim::ApplySchemeSettings( IScheme *scheme ) { BaseClass::ApplySchemeSettings( scheme );
SetPaintBackgroundEnabled( false ); }
void CHUDAutoAim::Init( void ) { ResetPosition(); ResetAlpha(); ResetScale(); }
void CHUDAutoAim::VidInit( void ) { SetAlpha( 255 ); Init();
if ( m_textureID_ActiveReticle == -1 ) { m_textureID_ActiveReticle = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_ActiveReticle, "vgui/hud/autoaim", true, false ); }
if ( m_textureID_FixedReticle == -1 ) { m_textureID_FixedReticle = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_FixedReticle, "vgui/hud/xbox_reticle", true, false ); } }
//-----------------------------------------------------------------------------
// 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 CHUDAutoAim::ShouldDraw( void ) { #ifndef HL1_CLIENT_DLL
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( pLocalPlayer ) { if( !pLocalPlayer->m_HL2Local.m_bDisplayReticle ) { return false; } } #endif
return ( (hud_draw_fixed_reticle.GetBool() || hud_draw_active_reticle.GetBool()) && CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() ); }
#define AUTOAIM_ALPHA_UP_SPEED 1000
#define AUTOAIM_ALPHA_DOWN_SPEED 300
#define AUTOAIM_MAX_ALPHA 120
#define AUTOAIM_MAX_SCALE 1.0f
#define AUTOAIM_MIN_SCALE 0.5f
#define AUTOAIM_SCALE_SPEED 10.0f
#define AUTOAIM_ONTARGET_CROSSHAIR_SPEED (ScreenWidth() / 3) // Can cross the whole screen in 3 seconds.
#define AUTOAIM_OFFTARGET_CROSSHAIR_SPEED (ScreenWidth() / 4)
void CHUDAutoAim::OnThink() { int wide, tall; GetSize( wide, tall );
BaseClass::OnThink();
// Get the HL2 player
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if ( pLocalPlayer == NULL ) { // Just turn the autoaim crosshair off.
ResetPosition(); ResetAlpha(); ResetScale();
m_alphaFixed = 0.0f; return; }
// Get the autoaim target.
CBaseEntity *pTarget = pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get();
// Fixed element stuff
float flFixedAlphaGoal;
if( pTarget ) { flFixedAlphaGoal = hud_reticle_maxalpha.GetFloat(); } else { flFixedAlphaGoal = hud_reticle_minalpha.GetFloat(); }
if( pLocalPlayer->m_HL2Local.m_bZooming || pLocalPlayer->m_HL2Local.m_bWeaponLowered ) { flFixedAlphaGoal = 0.0f; }
m_alphaFixed = Approach( flFixedAlphaGoal, m_alphaFixed, (hud_alpha_speed.GetFloat() * gpGlobals->frametime) );
switch( hud_autoaim_method.GetInt() ) { case AUTOAIM_METHOD_RETICLE: { if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() && pLocalPlayer->m_HL2Local.m_bStickyAutoAim ) { if( !pLocalPlayer->IsInAVehicle() ) { Vector vecLook; pLocalPlayer->EyeVectors( &vecLook, NULL, NULL );
Vector vecMove = pLocalPlayer->GetAbsVelocity(); float flSpeed = VectorNormalize( vecMove ); float flDot = DotProduct( vecLook, vecMove );
if( flSpeed >= 100 && fabs(flDot) <= 0.707f ) { QAngle viewangles; QAngle targetangles; QAngle delta;
engine->GetViewAngles( viewangles );
Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition(); VectorNormalize(vecDir); VectorAngles( vecDir, targetangles );
float magnetism = hud_magnetism.GetFloat();
delta[0] = ApproachAngle( targetangles[0], viewangles[0], magnetism ); delta[1] = ApproachAngle( targetangles[1], viewangles[1], magnetism ); delta[2] = targetangles[2];
//viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
engine->SetViewAngles( delta ); } } }
#if 0
bool doScaling = hud_autoaim_scale_icon.GetBool();
// These are the X & Y coords of where the crosshair should be. Default to
// returning to the center of the screen if there is no target.
int goalx = ScreenWidth() / 2; int goaly = ScreenHeight() / 2; int goalalpha = 0; float goalscale = AUTOAIM_MIN_SCALE; float speed = AUTOAIM_OFFTARGET_CROSSHAIR_SPEED;
if( pTarget ) { // Get the autoaim crosshair onto the target.
Vector screen;
// Center the crosshair on the entity.
if( doScaling ) { // Put the crosshair over the center of the target.
ScreenTransform( pTarget->WorldSpaceCenter(), screen ); } else { // Put the crosshair exactly where the player is aiming.
ScreenTransform( pLocalPlayer->m_HL2Local.m_vecAutoAimPoint, screen ); }
// Set Goal Position and speed.
goalx += 0.5f * screen[0] * ScreenWidth() + 0.5f; goaly -= 0.5f * screen[1] * ScreenHeight() + 0.5f; speed = AUTOAIM_ONTARGET_CROSSHAIR_SPEED;
goalalpha = AUTOAIM_MAX_ALPHA;
if( doScaling ) { // Scale the crosshair to envelope the entity's bounds on screen.
Vector vecMins, vecMaxs; Vector vecScreenMins, vecScreenMaxs;
// Get mins and maxs in world space
vecMins = pTarget->GetAbsOrigin() + pTarget->WorldAlignMins(); vecMaxs = pTarget->GetAbsOrigin() + pTarget->WorldAlignMaxs();
// Project them to screen
ScreenTransform( vecMins, vecScreenMins ); ScreenTransform( vecMaxs, vecScreenMaxs );
vecScreenMins.y = (ScreenWidth()/2) - 0.5f * vecScreenMins.y * ScreenWidth() + 0.5f; vecScreenMaxs.y = (ScreenWidth()/2) - 0.5f * vecScreenMaxs.y * ScreenWidth() + 0.5f;
float screenSize = vecScreenMins.y - vecScreenMaxs.y;
// Set goal scale
goalscale = screenSize / 64.0f; // 64 is the width of the crosshair art.
} else { goalscale = 1.0f; } }
// Now approach the goal, alpha, and scale
Vector vecGoal( goalx, goaly, 0 ); Vector vecDir = vecGoal - m_vecPos; float flDistRemaining = VectorNormalize( vecDir ); m_vecPos += vecDir * min(flDistRemaining, (speed * gpGlobals->frametime) );
// Lerp and Clamp scale
float scaleDelta = fabs( goalscale - m_scale ); float scaleMove = MIN( AUTOAIM_SCALE_SPEED * gpGlobals->frametime, scaleDelta ); if( m_scale < goalscale ) { m_scale += scaleMove; } else if( m_scale > goalscale ) { m_scale -= scaleMove; } if( m_scale > AUTOAIM_MAX_SCALE ) { m_scale = AUTOAIM_MAX_SCALE; } else if( m_scale < AUTOAIM_MIN_SCALE ) { m_scale = AUTOAIM_MIN_SCALE; }
if( goalalpha > m_alpha ) { m_alpha += AUTOAIM_ALPHA_UP_SPEED * gpGlobals->frametime; } else if( goalalpha < m_alpha ) { m_alpha -= AUTOAIM_ALPHA_DOWN_SPEED * gpGlobals->frametime; }
// Clamp alpha
if( m_alpha < 0 ) { m_alpha = 0; } else if( m_alpha > AUTOAIM_MAX_ALPHA ) { m_alpha = AUTOAIM_MAX_ALPHA; } #endif
} break;
case AUTOAIM_METHOD_DRIFT: { if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() ) { QAngle viewangles;
engine->GetViewAngles( viewangles ); Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition(); VectorNormalize(vecDir);
VectorAngles( vecDir, viewangles );
//viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
engine->SetViewAngles( viewangles ); } } break; } }
void CHUDAutoAim::Paint() { if( hud_draw_active_reticle.GetBool() ) { int xCenter = m_vecPos.x; int yCenter = m_vecPos.y;
int width, height; float xMod, yMod;
vgui::surface()->DrawSetTexture( m_textureID_ActiveReticle ); vgui::surface()->DrawSetColor( 255, 255, 255, m_alpha ); vgui::surface()->DrawGetTextureSize( m_textureID_ActiveReticle, width, height );
float uv1 = 0.5f / width, uv2 = 1.0f - uv1;
vgui::Vertex_t vert[4];
Vector2D uv11( uv1, uv1 ); Vector2D uv12( uv1, uv2 ); Vector2D uv21( uv2, uv1 ); Vector2D uv22( uv2, uv2 );
xMod = width; yMod = height;
xMod *= m_scale; yMod *= m_scale;
xMod /= 2; yMod /= 2;
vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 ); vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 ); vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 ); vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 ); vgui::surface()->DrawTexturedPolygon( 4, vert ); }
if( hud_draw_fixed_reticle.GetBool() ) { int width, height; float xMod, yMod;
vgui::surface()->DrawSetTexture( m_textureID_FixedReticle ); vgui::surface()->DrawGetTextureSize( m_textureID_FixedReticle, width, height );
int xCenter = ScreenWidth() / 2; int yCenter = ScreenHeight() / 2;
vgui::Vertex_t vert[4];
Vector2D uv11( 0, 0 ); Vector2D uv12( 0, 1 ); Vector2D uv21( 1, 0 ); Vector2D uv22( 1, 1 );
xMod = width; yMod = height;
xMod /= 2; yMod /= 2;
vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 ); vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 ); vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 ); vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 );
Color clr; clr = gHUD.m_clrNormal; int r,g,b,a; clr.GetColor( r,g,b,a );
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer(); if( pLocalPlayer && pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() ) { r = 250; g = 138; b = 4; }
clr.SetColor( r,g,b,m_alphaFixed);
vgui::surface()->DrawSetColor( clr ); vgui::surface()->DrawTexturedPolygon( 4, vert ); } }
|