mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 22:56:50 +00:00
472 lines
12 KiB
C++
472 lines
12 KiB
C++
|
//========= 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 );
|
||
|
}
|
||
|
}
|