cl_dll/hud_crosshair.cpp
13141516171819202122232425
#include "vgui_controls/controls.h"
#include "vgui/ISurface.h"
#include "IVRenderView.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar crosshair( "crosshair", "1", FCVAR_ARCHIVE );
ConVar cl_observercrosshair( "cl_observercrosshair", "1", FCVAR_ARCHIVE );
using namespace vgui;
int ScreenTransform( const Vector& point, Vector& screen );
1314151617181920212223242526272829303132333435363738
#include "vgui_controls/controls.h"
#include "vgui/ISurface.h"
#include "IVRenderView.h"
#include "ff_weapon_base.h"
#include "c_ff_player.h"
#include "ff_utils.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar crosshair( "crosshair", "1", FCVAR_ARCHIVE | FCVAR_CLIENTDLL);
ConVar cl_observercrosshair( "cl_observercrosshair", "1", FCVAR_ARCHIVE | FCVAR_CLIENTDLL);
ConVar cl_acchargebar("cl_acchargebar", "0", FCVAR_ARCHIVE | FCVAR_CLIENTDLL);
//Tie crosshair values to cheats -GreenMushy
ConVar cl_concaim("cl_concaim", "1", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "0 = always show crosshair in center. 1 = flash trueaim after shooting. 2 = hide crosshair when conced.");
ConVar cl_concaim_fadetime("cl_concaim_fadetime", "0.25", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_CHEAT, "When cl_concaim is 1, controls the time the crosshair stays visible after shooting. Requires sv_cheats 1");
ConVar cl_concaim_showtrueaim("cl_concaim_showtrueaim", "0", FCVAR_CLIENTDLL | FCVAR_CHEAT, "Good way to learn how to concaim. If set to 1, when conced, the crosshair will show exactly where you will shoot. Requires sv_cheats 1");
#define FFDEV_CONCAIM cl_concaim.GetInt()
#define FFDEV_CONCAIM_FADETIME cl_concaim_fadetime.GetFloat()
#define FFDEV_CONCAIM_SHOWTRUEAIM cl_concaim_showtrueaim.GetBool()
using namespace vgui;
int ScreenTransform( const Vector& point, Vector& screen );
38394041424344
m_vecCrossHairOffsetAngle.Init();
SetHiddenBits( HIDEHUD_PLAYERDEAD | HIDEHUD_CROSSHAIR );
}
void CHudCrosshair::ApplySchemeSettings( IScheme *scheme )
51525354555657
m_vecCrossHairOffsetAngle.Init();
SetHiddenBits( HIDEHUD_CROSSHAIR );
}
void CHudCrosshair::ApplySchemeSettings( IScheme *scheme )
484950515253
m_pDefaultCrosshair = gHUD.GetIcon("crosshair_default");
SetPaintBackgroundEnabled( false );
SetSize( ScreenWidth(), ScreenHeight() );
}
6162636465666768697071727374757677
m_pDefaultCrosshair = gHUD.GetIcon("crosshair_default");
SetPaintBackgroundEnabled( false );
// --> Mirv
vgui::HScheme CrossHairScheme = vgui::scheme()->LoadSchemeFromFile("resource/CrosshairScheme.res", "CrosshairScheme");
for (int i = 0; i < CROSSHAIR_SIZES; i++)
{
m_hPrimaryCrosshairs[i] = vgui::scheme()->GetIScheme(CrossHairScheme)->GetFont(VarArgs("PrimaryCrosshairs%d", (i + 1)));
m_hSecondaryCrosshairs[i] = vgui::scheme()->GetIScheme(CrossHairScheme)->GetFont(VarArgs("SecondaryCrosshairs%d", (i + 1)));
}
// <-- Mirv
SetSize( ScreenWidth(), ScreenHeight() );
}
646566676869
if ( !pPlayer )
return false;
// draw a crosshair only if alive or spectating in eye
if ( IsXbox() )
{
888990919293949596979899
if ( !pPlayer )
return false;
C_FFPlayer *pFFPlayer = ToFFPlayer( pPlayer );
// Dunno about this... specs might want a crosshair drawn?
/*if( FF_IsPlayerSpec( pFFPlayer ) || !FF_HasPlayerPickedClass( pFFPlayer ) )
return false;*/
// draw a crosshair only if alive or spectating in eye
if ( IsXbox() )
{
919293949596
return ( bNeedsDraw && CHudElement::ShouldDraw() );
}
void CHudCrosshair::Paint( void )
{
if ( !m_pCrosshair )
121122123124125126127128
return ( bNeedsDraw && CHudElement::ShouldDraw() );
}
extern void GetCrosshair(FFWeaponID iWeapon, char &innerChar, Color &innerCol, int &innerSize, char &outerChar, Color &outerCol, int &outerSize); // |-- Mirv
void CHudCrosshair::Paint( void )
{
if ( !m_pCrosshair )
99100101102103104
if ( !IsCurrentViewAccessAllowed() )
return;
m_curViewAngles = CurrentViewAngles();
m_curViewOrigin = CurrentViewOrigin();
131132133134135136137138139140141
if ( !IsCurrentViewAccessAllowed() )
return;
C_FFPlayer *pActivePlayer = C_FFPlayer::GetLocalFFPlayerOrObserverTarget();
if (!pActivePlayer)
return;
m_curViewAngles = CurrentViewAngles();
m_curViewOrigin = CurrentViewOrigin();
106107108109110111112113114115116
x = ScreenWidth()/2;
y = ScreenHeight()/2;
// 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 forward;
Vector point, screen;
143144145146147148149150151152153154155156157158
x = ScreenWidth()/2;
y = ScreenHeight()/2;
float x_chargebar, y_chargebar;
x_chargebar = ScreenWidth()/2;
y_chargebar = ScreenHeight()/2;
// 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 )
{
Assert(0); // |-- Mirv
QAngle angles;
Vector forward;
Vector point, screen;
123124125126127128129130131132133134
x += 0.5f * screen[0] * ScreenWidth() + 0.5f;
y += 0.5f * screen[1] * ScreenHeight() + 0.5f;
}
m_pCrosshair->DrawSelf(
x - 0.5f * m_pCrosshair->Width(),
y - 0.5f * m_pCrosshair->Height(),
m_clrCrosshair );
}
//-----------------------------------------------------------------------------
165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
x += 0.5f * screen[0] * ScreenWidth() + 0.5f;
y += 0.5f * screen[1] * ScreenHeight() + 0.5f;
x_chargebar += 0.5f * screen[0] * ScreenWidth() + 0.5f;
y_chargebar += 0.5f * screen[1] * ScreenHeight() + 0.5f;
}
// AfterShock: Conc aim -> plot crosshair properly
if ( ( FFDEV_CONCAIM_SHOWTRUEAIM ) && ( (pActivePlayer->m_flConcTime > gpGlobals->curtime) || (pActivePlayer->m_flConcTime < 0) ) )
{
QAngle angles;
Vector forward;
Vector point, screen;
// this code is wrong
// AfterShock: No, the code is now right!
angles = pActivePlayer->EyeAngles();
AngleVectors( angles, &forward );
forward *= 10000.0f;
VectorAdd( m_curViewOrigin, forward, point );
ScreenTransform( point, screen );
x = (screen[0]*0.5 + 0.5f) * ScreenWidth();
y = (1 - ( screen[1]*0.5 + 0.5f ) ) * ScreenHeight();
x_chargebar = x;
y_chargebar = y;
}
// hide crosshair
else if ( ( FFDEV_CONCAIM == 2) && ( (pActivePlayer->m_flConcTime > gpGlobals->curtime) || (pActivePlayer->m_flConcTime < 0) ) )
{
x = -1;
y = -1;
}
// flash crosshair
else if ( ( FFDEV_CONCAIM == 1) && ( (pActivePlayer->m_flConcTime > gpGlobals->curtime) || (pActivePlayer->m_flConcTime < 0) ) )
{
// if should be flashing
if (gpGlobals->curtime < pActivePlayer->m_flTrueAimTime + FFDEV_CONCAIM_FADETIME)
{
QAngle angles;
Vector forward;
Vector point, screen;
// this code is wrong
// AfterShock: No, the code is now right!
angles = pActivePlayer->EyeAngles();
AngleVectors( angles, &forward );
forward *= 10000.0f;
VectorAdd( m_curViewOrigin, forward, point );
ScreenTransform( point, screen );
x = (screen[0]*0.5 + 0.5f) * ScreenWidth();
y = (1 - ( screen[1]*0.5 + 0.5f ) ) * ScreenHeight();
}
// else don't draw xhair at all
else
{
x = -1;
y = -1;
}
}
// --> Mirv: Crosshair stuff
//m_pCrosshair->DrawSelf(
// x - 0.5f * m_pCrosshair->Width(),
// y - 0.5f * m_pCrosshair->Height(),
// m_clrCrosshair );
C_FFWeaponBase *pWeapon = pActivePlayer->GetActiveFFWeapon();
// No crosshair for no weapon
if (!pWeapon)
return;
FFWeaponID weaponID = pWeapon->GetWeaponID();
// Weapons other than these don't get crosshairs
if (weaponID <= FF_WEAPON_NONE || weaponID > FF_WEAPON_TOMMYGUN)
return;
Color innerCol, outerCol;
char innerChar, outerChar;
int innerSize, outerSize;
wchar_t unicode[2];
//
// TODO: Clean this up!!!!
//
HFont currentFont;
GetCrosshair(weaponID, innerChar, innerCol, innerSize, outerChar, outerCol, outerSize);
// concaim 1 = flash xhair when shooting
if ( ( FFDEV_CONCAIM == 1) && ( (pActivePlayer->m_flConcTime > gpGlobals->curtime) || (pActivePlayer->m_flConcTime < 0) ) )
{
//Get the weapon and see if you should draw the crosshair while conced
if( weaponID == FF_WEAPON_ASSAULTCANNON ||
weaponID == FF_WEAPON_SUPERNAILGUN ||
weaponID == FF_WEAPON_FLAMETHROWER ||
weaponID == FF_WEAPON_NAILGUN ||
weaponID == FF_WEAPON_AUTORIFLE)
{
//If it was one of these weapons, just return before it tries to draw anything
return;
}
// calculate alphas
float flFlashAlpha = clamp(1.0f - (gpGlobals->curtime - pActivePlayer->m_flTrueAimTime)/FFDEV_CONCAIM_FADETIME, 0.0f, 1.0f);
// set alphas
outerCol[3] *= flFlashAlpha;
innerCol[3] *= flFlashAlpha;
}
currentFont = m_hSecondaryCrosshairs[clamp(outerSize, 1, CROSSHAIR_SIZES) - 1];
surface()->DrawSetTextColor(outerCol.r(), outerCol.g(), outerCol.b(), outerCol.a());
surface()->DrawSetTextFont(currentFont);
int charOffsetX = surface()->GetCharacterWidth(currentFont, outerChar) / 2;
int charOffsetY = surface()->GetFontTall(currentFont) / 2;
swprintf(unicode, L"%c", outerChar);
surface()->DrawSetTextPos(x - charOffsetX, y - charOffsetY);
surface()->DrawUnicodeChar(unicode[0]);
currentFont = m_hPrimaryCrosshairs[clamp(innerSize, 1, CROSSHAIR_SIZES) - 1];
surface()->DrawSetTextColor(innerCol.r(), innerCol.g(), innerCol.b(), innerCol.a());
surface()->DrawSetTextFont(currentFont);
charOffsetX = surface()->GetCharacterWidth(currentFont, innerChar) / 2;
charOffsetY = surface()->GetFontTall(currentFont) / 2;
swprintf(unicode, L"%c", innerChar);
surface()->DrawSetTextPos(x - charOffsetX, y - charOffsetY);
surface()->DrawUnicodeChar(unicode[0]);
// <-- Mirv
// Mulch: Draw charge bar!
if( (weaponID == FF_WEAPON_ASSAULTCANNON) && (cl_acchargebar.GetBool()) )
{
extern float GetAssaultCannonCharge();
float flCharge = GetAssaultCannonCharge();
if( flCharge <= 0.0f )
return;
int iLeft = x_chargebar - charOffsetX;
int iTop = y_chargebar + charOffsetY;
int iRight = iLeft + (charOffsetX * 2);
int iBottom = iTop + 10;
surface()->DrawSetColor( innerCol.r(), innerCol.g(), innerCol.b(), 150 );
surface()->DrawFilledRect( iLeft, iTop, iLeft + ((float)(iRight - iLeft) * (flCharge / 100.0f)), iBottom );
surface()->DrawSetColor( outerCol.r(), outerCol.g(), outerCol.b(), 200 );
surface()->DrawOutlinedRect( iLeft, iTop, iRight, iBottom );
}
else if( weaponID == FF_WEAPON_SNIPERRIFLE )
{
extern float GetSniperRifleCharge();
float flCharge = GetSniperRifleCharge();
if( flCharge <= 1.0f )
return;
int iLeft = x_chargebar - charOffsetX;
int iTop = y_chargebar + charOffsetY;
int iRight = iLeft + (charOffsetX * 2);
int iBottom = iTop + 10;
surface()->DrawSetColor( innerCol.r(), innerCol.g(), innerCol.b(), 150 );
surface()->DrawFilledRect( iLeft, iTop, iLeft + ((float)(iRight - iLeft) * (flCharge / 100.0f)), iBottom );
surface()->DrawSetColor( outerCol.r(), outerCol.g(), outerCol.b(), 200 );
surface()->DrawOutlinedRect( iLeft, iTop, iRight, iBottom );
}
}
//-----------------------------------------------------------------------------