//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose: A stationary gun that players can man
//
// $NoKeywords: $
//=============================================================================

#include "cbase.h"
#include "tf_obj_base_manned_gun.h"
#include "tf_obj_manned_plasmagun_shared.h"
#include "in_buttons.h"
#include "tf_movedata.h"
#include "tf_gamerules.h"

#if defined( CLIENT_DLL )
#include "hudelement.h"
#include "bone_setup.h"
#include "hud_ammo.h"
#include "hud_crosshair.h"
#else
#endif

IMPLEMENT_NETWORKCLASS_ALIASED( ObjectBaseMannedGun, DT_ObjectBaseMannedGun )

BEGIN_NETWORK_TABLE( CObjectBaseMannedGun, DT_ObjectBaseMannedGun )
#if !defined( CLIENT_DLL )
	SendPropInt	(SENDINFO(m_nMoveStyle),	2, SPROP_UNSIGNED ),
	SendPropInt	(SENDINFO(m_nAmmoType),		8 ),
	SendPropInt	(SENDINFO(m_nAmmoCount),	6, SPROP_UNSIGNED ),
	SendPropAngle(SENDINFO(m_flGunYaw),		12 ),
	SendPropAngle(SENDINFO(m_flGunPitch),	12 ),
	SendPropAngle(SENDINFO(m_flBarrelPitch), 12 ),

	SendPropEHandle( SENDINFO( m_hLaserDesignation ) ),
	SendPropEHandle( SENDINFO( m_hBeam ) ),

#else
	RecvPropInt( RECVINFO(m_nMoveStyle) ),
	RecvPropInt( RECVINFO(m_nAmmoType) ),
	RecvPropInt( RECVINFO(m_nAmmoCount) ),
	RecvPropFloat( RECVINFO(m_flGunYaw) ),
	RecvPropFloat( RECVINFO(m_flGunPitch) ),
	RecvPropFloat( RECVINFO(m_flBarrelPitch) ),

	RecvPropEHandle( RECVINFO( m_hLaserDesignation ) ),
	RecvPropEHandle( RECVINFO( m_hBeam ) ),

#endif
END_NETWORK_TABLE()

LINK_ENTITY_TO_CLASS( tf_obj_base_manned_gun, CObjectBaseMannedGun );

BEGIN_PREDICTION_DATA( CObjectBaseMannedGun  )

	DEFINE_PRED_FIELD( CObjectBaseMannedGun, m_nMoveStyle, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
	DEFINE_PRED_FIELD( CObjectBaseMannedGun, m_nAmmoType, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
	DEFINE_PRED_FIELD( CObjectBaseMannedGun, m_nAmmoCount, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),

	DEFINE_PRED_FIELD_TOL( CObjectBaseMannedGun, m_flGunYaw, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, 0.5f),
	DEFINE_PRED_FIELD_TOL( CObjectBaseMannedGun, m_flGunPitch, FIELD_FLOAT, FTYPEDESC_INSENDTABLE | FTYPEDESC_NOERRORCHECK, 0.125f ),
	DEFINE_PRED_FIELD_TOL( CObjectBaseMannedGun, m_flBarrelPitch, FIELD_FLOAT, FTYPEDESC_INSENDTABLE | FTYPEDESC_NOERRORCHECK, 0.125f ),

	DEFINE_PRED_FIELD( CObjectBaseMannedGun, m_hLaserDesignation, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),

	DEFINE_PRED_FIELD( CObjectBaseMannedGun, m_hBeam, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),

	DEFINE_FIELD( CObjectBaseMannedGun, m_flBarrelHeight, FIELD_FLOAT ),

//	DEFINE_FIELD( CObjectBaseMannedGun, m_nBarrelAttachment, FIELD_INTEGER ),
//	DEFINE_FIELD( CObjectBaseMannedGun, m_nBarrelPivotAttachment, FIELD_INTEGER ),
//	DEFINE_FIELD( CObjectBaseMannedGun, m_nStandAttachment, FIELD_INTEGER ),
//	DEFINE_FIELD( CObjectBaseMannedGun, m_nEyesAttachment, FIELD_INTEGER ),

END_PREDICTION_DATA()

extern ConVar mannedgun_usethirdperson;
static ConVar obj_manned_gun_designator_range( "obj_manned_gun_designator_range","2048", FCVAR_REPLICATED, "Manned gun's laser designation range" );
ConVar obj_child_range_factor( "obj_child_range_factor","1.1", FCVAR_REPLICATED, "Factor applied to range of objects that are built on a buildpoint" );

// Restoring initial state handling
#define OBJ_BASE_MANNEDGUN_THINK_CONTEXT		"BaseMannedGunThink"
#define MANNEDGUN_RESTORE_TIME					5.0
#define MANNEDGUN_RESTORE_TURN_RATE				150

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CObjectBaseMannedGun::CObjectBaseMannedGun()
{
	m_nMoveStyle = MOVEMENT_STYLE_STANDARD;
}


//-----------------------------------------------------------------------------
// Sets the movement style
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::SetMovementStyle( MovementStyle_t style )
{
	m_nMoveStyle = style;
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::Precache()
{
	BaseClass::Precache();
#if !defined( CLIENT_DLL )
	PrecacheVGuiScreen( "screen_obj_manned_plasmagun" );
	PrecacheMaterial( "sprites/laserbeam" );
#endif
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::Spawn()
{
	m_takedamage = DAMAGE_YES;

	SetMaxPassengerCount( 1 );

	m_flGunYaw = 0;
	m_flGunPitch = 0;
	m_flBarrelPitch = 0;

	BaseClass::Spawn();

	// Manned guns don't need to be built like other vehicles
	int curFlags = GetObjectFlags();
	curFlags &= ~OF_MUST_BE_BUILT_IN_CONSTRUCTION_YARD;
	curFlags &= ~OF_MUST_BE_BUILT_ON_ATTACHMENT;
	curFlags &= ~OF_DOESNT_NEED_POWER;
	curFlags |= OF_DONT_PREVENT_BUILD_NEAR_OBJ;
	SetObjectFlags( curFlags );

	m_flMaxRange = 0;
}

//-----------------------------------------------------------------------------
// Purpose: Calculate the max range of this gun
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::CalculateMaxRange( float flDefensiveRange, float flOffensiveRange )
{
	if ( GetTeamNumber() == TEAM_HUMANS )
	{
		m_flMaxRange = flDefensiveRange;
		if ( GetParentObject() )
		{
			m_flMaxRange *= obj_child_range_factor.GetFloat();
		}
	}
	else
	{
		m_flMaxRange = flOffensiveRange;
	}
}

//-----------------------------------------------------------------------------
// Sets up various attachment points once the model is selected 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::OnModelSelected()
{
	m_nBarrelAttachment = LookupAttachment( "barrel" );
	m_nBarrelPivotAttachment = LookupAttachment( "barrelpivot" );
	m_nStandAttachment = LookupAttachment( "vehicle_feet_passenger0" );
	m_nEyesAttachment = LookupAttachment( "vehicle_eyes_passenger0" );

	// Find the barrel height in its quiescent state...
	Vector vBarrel;
	QAngle vBarrelAngles;
	GetAttachmentLocal( m_nBarrelAttachment, vBarrel, vBarrelAngles );
	m_flBarrelHeight = vBarrel.z;
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::UpdateOnRemove( void )
{
	if ( m_hLaserDesignation.Get() )
	{
		m_hLaserDesignation->Remove( );
		m_hLaserDesignation = NULL;
	}

	// Chain at end to mimic destructor unwind order
	BaseClass::UpdateOnRemove();
}


//-----------------------------------------------------------------------------
// Purpose: Gets info about the control panels
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::GetControlPanelInfo( int nPanelIndex, const char *&pPanelName )
{
	pPanelName = "screen_obj_manned_plasmagun";
}


//-----------------------------------------------------------------------------
// Purpose: Hide the base of the gun if it's on an attachment
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::SetupAttachedVersion( void )
{
	BaseClass::SetupAttachedVersion();

	SetBodygroup( 1, true );
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::SetupUnattachedVersion( void )
{
	BaseClass::SetupUnattachedVersion();

	SetBodygroup( 1, false );
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::OnGoInactive( void )
{
	BaseClass::OnGoInactive();

	// If we've got a player in the gun, tell him he's got to get out
	if ( GetDriverPlayer() )
	{
		ClientPrint( GetDriverPlayer(), HUD_PRINTCENTER, "Lost power to the manned gun!" );
		GetDriverPlayer()->LeaveVehicle();
	}

#if 0
	if ( GetBuffStation() )
	{
		GetBuffStation()->DeBuffObject( this );
	}
#endif
}

//-----------------------------------------------------------------------------
// Purpose: Can we get into the vehicle?
//-----------------------------------------------------------------------------
bool CObjectBaseMannedGun::CanGetInVehicle( CBaseTFPlayer *pPlayer )
{
	if ( !IsPowered() )
	{
		ClientPrint( pPlayer, HUD_PRINTCENTER, "No power source for the manned gun!" );
		return false;
	}

	return true;
}


//-----------------------------------------------------------------------------
// Returns the eye position 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles )
{
	BaseClass::GetVehicleViewPosition( nRole, pOrigin, pAngles );
	return;
	Assert( nRole == VEHICLE_DRIVER );
	QAngle vPlayerFeetAngles;
	GetAttachment(m_nEyesAttachment, *pOrigin, vPlayerFeetAngles);
}

//-----------------------------------------------------------------------------
// Purpose: Return to our original facing after a while
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::BaseMannedGunThink( void )
{
	// If someone's got in the gun, stop moving
	if ( GetDriverPlayer() )
		return;

	// Otherwise, move back towards the initial state
	if ( m_flGunPitch )
	{
		float flPitch = anglemod( m_flGunPitch );
		if (( flPitch <= 180 ) && ( flPitch >= 0 ))
		{
			m_flGunPitch = max( 0, flPitch - (gpGlobals->frametime * MANNEDGUN_RESTORE_TURN_RATE) );
		}
		else
		{
			m_flGunPitch = flPitch + (gpGlobals->frametime * MANNEDGUN_RESTORE_TURN_RATE);
			if ( m_flGunPitch >= 360 )
			{
				m_flGunPitch = 0;
			}
		}
	}
	else if ( m_flGunYaw )
	{
		if ( m_flGunYaw > 180 )
		{
			m_flGunYaw = m_flGunYaw + (gpGlobals->frametime * MANNEDGUN_RESTORE_TURN_RATE);
			if ( m_flGunYaw >= 360 )
			{
				m_flGunYaw = 0;
			}
		}
		else
		{
			m_flGunYaw = max( 0, m_flGunYaw - (gpGlobals->frametime * MANNEDGUN_RESTORE_TURN_RATE) );
		}

	}
	else
	{
		// We're done
		return;
	}

	// Keep thinking
	SetContextThink( BaseMannedGunThink, gpGlobals->curtime + 0.1, OBJ_BASE_MANNEDGUN_THINK_CONTEXT );
	NetworkStateChanged();
}

#ifndef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose: Get and set the current driver.
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::SetPassenger( int nRole, CBasePlayer *pEnt )
{
	BaseClass::SetPassenger( nRole, pEnt );

	// If we don't have a driver anymore, return to our original facing after a while
	if ( !GetDriverPlayer() && (m_flGunPitch || m_flGunYaw) )
	{
		StopDesignating();
		SetContextThink( BaseMannedGunThink, gpGlobals->curtime + MANNEDGUN_RESTORE_TIME, OBJ_BASE_MANNEDGUN_THINK_CONTEXT );
	}
}
#endif

//-----------------------------------------------------------------------------
// Here's where we deal with weapons
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::OnItemPostFrame( CBaseTFPlayer *pDriver )
{
	// I can't do anything if I'm not active
	if ( !ShouldBeActive() )
		return;

	if ( !IsReadyToDrive() )
		return;

	// If we don't have a laser designator yet, create one
	if ( !m_hLaserDesignation )
	{
		m_hLaserDesignation = CEnvLaserDesignation::CreatePredicted( pDriver ); 
	}

	// Designating?
	if (pDriver->m_nButtons & IN_ATTACK2)
	{
		UpdateDesignator();
		return;
	}

	StopDesignating();

	// Fire our base weapon?
	if ( pDriver->m_nButtons & IN_ATTACK )
	{
		Fire();
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::StopDesignating( void )
{
	// Remove our beam if we just stopped designating
	if ( m_hBeam.Get() )
	{
		m_hBeam->Remove(  );
	}

	if ( m_hLaserDesignation.Get() )
	{
		m_hLaserDesignation->SetActive( false );
	}
}

//-----------------------------------------------------------------------------
// Purpose: Update the designator position
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::UpdateDesignator( void )
{
	// Make the beam, if we don't have one yet
	if ( !m_hBeam && GetDriverPlayer() )
	{
		m_hBeam = BEAM_CREATE_PREDICTABLE_PERSIST( "sprites/laserbeam.vmt", 5, GetDriverPlayer() );
		if ( m_hBeam.Get() )
		{
			m_hBeam->PointEntInit( vec3_origin, this );
			m_hBeam->SetEndAttachment( m_nBarrelAttachment );
			m_hBeam->SetColor( 255, 32, 32 );
			m_hBeam->SetBrightness( 255 );
			m_hBeam->SetNoise( 0 );
			m_hBeam->SetWidth( 0.5 );
			m_hBeam->SetEndWidth( 0.5 );
		}
	}

	// We have to flush the bone cache because it's possible that only the bone controllers
	// have changed since the bonecache was generated, and bone controllers aren't checked.
	InvalidateBoneCache();

	QAngle vecAng;
	Vector vecSrc, vecAim;
	GetAttachment( m_nBarrelAttachment, vecSrc, vecAng );
	AngleVectors( vecAng, &vecAim, 0, 0 );

	// "Fire" the designator beam
	Vector vecEnd = vecSrc + vecAim * obj_manned_gun_designator_range.GetFloat();
	trace_t tr;
	TFGameRules()->WeaponTraceLine(vecSrc, vecEnd, MASK_SHOT, this, DMG_PROBE, &tr);

	if ( m_hLaserDesignation.Get() )
	{
		// Only update our designated target point if we hit something
		if ( tr.fraction != 1.0 )
		{
			m_hLaserDesignation->SetActive( true );
			m_hLaserDesignation->SetAbsOrigin( tr.endpos );
		}
		else
		{
			m_hLaserDesignation->SetActive( false );
		}
	}

	// Update beam visual
	if ( m_hBeam.Get() )
	{
		m_hBeam->SetStartPos( tr.endpos );
		m_hBeam->RelinkBeam();
	}
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::SetupMove( CBasePlayer *pPlayer, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
{
	BaseClass::SetupMove( pPlayer, ucmd, pHelper, move );

	CTFMoveData *pMoveData = (CTFMoveData*)move; 
	Assert( sizeof(MannedPlasmagunData_t) <= pMoveData->VehicleDataMaxSize() );

	MannedPlasmagunData_t *pVehicleData = (MannedPlasmagunData_t*)pMoveData->VehicleData();
	pVehicleData->m_pVehicle = this;
	pVehicleData->m_flGunYaw = m_flGunYaw;
	pVehicleData->m_flGunPitch = m_flGunPitch;
	pVehicleData->m_flBarrelPitch = m_flBarrelPitch;
	pVehicleData->m_nMoveStyle = m_nMoveStyle;
	pVehicleData->m_flBarrelHeight = m_flBarrelHeight;
	pVehicleData->m_nBarrelPivotAttachment = m_nBarrelPivotAttachment;
	pVehicleData->m_nBarrelAttachment = m_nBarrelAttachment;
	pVehicleData->m_nStandAttachment = m_nStandAttachment;
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move )
{
	BaseClass::FinishMove( player, ucmd, move );
	CTFMoveData *pMoveData = (CTFMoveData*)move; 
	Assert( sizeof(MannedPlasmagunData_t) <= pMoveData->VehicleDataMaxSize() );

	MannedPlasmagunData_t *pVehicleData = (MannedPlasmagunData_t*)pMoveData->VehicleData();
	m_flGunYaw = pVehicleData->m_flGunYaw;
	m_flGunPitch = pVehicleData->m_flGunPitch;
	m_flBarrelPitch = pVehicleData->m_flBarrelPitch;

	// Set the bone state..
	SetBoneController( 0, m_flGunYaw );
	SetBoneController( 1, m_flGunPitch );

	if ( m_nMoveStyle == MOVEMENT_STYLE_BARREL_PIVOT )
	{
		SetBoneController( 2, m_flBarrelPitch );
	}

	NetworkStateChanged();
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CObjectBaseMannedGun::ProcessMovement( CBasePlayer *pPlayer, CMoveData *pMove )
{
	m_Movement.ProcessMovement( pPlayer, pMove );

	m_flGunPitch = AngleNormalize( m_flGunPitch );
	m_flBarrelPitch = AngleNormalize( m_flBarrelPitch );
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CObjectBaseMannedGun::GetGunYaw() const
{
	return m_flGunYaw;
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CObjectBaseMannedGun::GetGunPitch() const
{
	return m_flGunPitch;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CObjectBaseMannedGun::ShouldUseThirdPersonVehicleView( void )
{
	if ( mannedgun_usethirdperson.GetInt() )
	{
		// We want to use third person if we're mounted on a vehicle.
		return dynamic_cast< CBaseTFVehicle* >( GetMoveParent() ) != NULL;
	}
	else
	{
		return false;
	}
}

#if defined( CLIENT_DLL )
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_ObjectBaseMannedGun::OnDataChanged( DataUpdateType_t updateType )
{
	BaseClass::OnDataChanged(updateType);

	if ( updateType == DATA_UPDATE_CREATED )
	{
		// FIXME: Will this work with build animations models?

		m_nBarrelAttachment = LookupAttachment( "barrel" );
		m_nBarrelPivotAttachment = LookupAttachment( "barrelpivot" );
		m_nStandAttachment = LookupAttachment( "vehicle_feet_passenger0" );

		// Find the barrel height in its quiescent state...
		Vector vBarrel;
		QAngle vBarrelAngles;
		GetAttachmentLocal(m_nBarrelAttachment, vBarrel, vBarrelAngles);
		m_flBarrelHeight = vBarrel.z;

		// HACK HACK:  This should be read from a .txt file at some point!!!!
		CHudTexture newTexture;
		Q_strcpy( newTexture.szTextureFile, "sprites/crosshairs" );

		newTexture.rc.left		= 0;
		newTexture.rc.top		= 48;
		newTexture.rc.right		= newTexture.rc.left + 24;
		newTexture.rc.bottom	= newTexture.rc.top + 24;
		iconCrosshair = gHUD.AddUnsearchableHudIconToList( newTexture );
	}
	else
	{
		// Set the bone state..
		SetBoneController( 0, m_flGunYaw );
		SetBoneController( 1, m_flGunPitch );

		if ( m_nMoveStyle == MOVEMENT_STYLE_BARREL_PIVOT )
		{
			SetBoneController( 2, m_flBarrelPitch );
		}
	}
}

//-----------------------------------------------------------------------------
// Clamps the view angles while manning the gun 
//-----------------------------------------------------------------------------
void C_ObjectBaseMannedGun::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
{
#if 0
	// Confine the view to the appropriate yaw range...
	float flAngleDiff = AngleDiff( pCmd->viewangles[YAW], flCenterYaw );

	// Here, we must clamp to the cone...
	if (flAngleDiff < m_Movement.GetMinYaw())
		pCmd->viewangles[YAW] = anglemod(flCenterYaw + m_Movement.GetMinYaw());
	else if (flAngleDiff > m_Movement.GetMaxYaw())
		pCmd->viewangles[YAW] = anglemod(flCenterYaw + m_Movement.GetMaxYaw());
#endif

	// Prevent too much downward looking
	if ( pCmd->viewangles[PITCH] > m_Movement.GetMaxPitch())
	{
		pCmd->viewangles[PITCH] = m_Movement.GetMaxPitch();
	}
}

//-----------------------------------------------------------------------------
// Orients the gun correctly 
//-----------------------------------------------------------------------------
void C_ObjectBaseMannedGun::GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS], float dadt)
{
	// turret angle values:
	// 0 = front, 90 = left, 180 = back, 270 = right
	studiohdr_t *pModel = modelinfo->GetStudiomodel( GetModel() );
	Studio_SetController(pModel, 0, m_flGunYaw,   controllers[0]);
	Studio_SetController(pModel, 1, m_flGunPitch, controllers[1]);

	if ( m_nMoveStyle == MOVEMENT_STYLE_BARREL_PIVOT )
	{
		Studio_SetController(pModel, 2, m_flBarrelPitch, controllers[2]);
	}
}

//-----------------------------------------------------------------------------
// Purpose: Get the angles that a player in the specified role should be using for visuals
//-----------------------------------------------------------------------------
QAngle C_ObjectBaseMannedGun::GetPassengerAngles( QAngle angCurrent, int nRole )
{
	// Stomp the current angle's pitch with our rotation
	QAngle vecNewAngles = angCurrent;
	angCurrent[PITCH] = m_flGunPitch;

	return angCurrent;
}

//-----------------------------------------------------------------------------
// Renders hud elements
//-----------------------------------------------------------------------------
void C_ObjectBaseMannedGun::DrawHudElements( void )
{
	GetHudAmmo()->SetPrimaryAmmo( m_nAmmoType, m_nAmmoCount );
	GetHudAmmo()->SetSecondaryAmmo( -1, -1 );

	// Let the plasma gun operator see a crosshair
	DrawCrosshair();
}


//-----------------------------------------------------------------------------
// Purpose: Draw the weapon's crosshair
//-----------------------------------------------------------------------------
void C_ObjectBaseMannedGun::DrawCrosshair()
{
	C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
	if ( !player )
		return;

	CHudCrosshair *crosshair = (CHudCrosshair *)GET_HUDELEMENT( CHudCrosshair );
	if ( !crosshair )
		return;
	
	if ( iconCrosshair )
	{
		crosshair->SetCrosshair( iconCrosshair, gHUD.m_clrNormal );
	}
	else
	{
		static wrect_t nullrc;
		crosshair->SetCrosshair( 0, Color( 255, 255, 255, 255 ) );
	}
}

#endif
