All pastes #1876324 Raw Edit

Stuff

public cpp v1 · immutable
#1876324 ·published 2010-06-03 00:05 UTC
rendered paste body
//========= Copyright  1996-2005, Valve Corporation, All rights reserved. ============////// Purpose:		Player for HL2.////=============================================================================//#include "cbase.h"#include "hl2_player.h"#include "globalstate.h"#include "game.h"#include "gamerules.h"#include "trains.h"#include "basehlcombatweapon_shared.h"#include "vcollide_parse.h"#include "in_buttons.h"#include "ai_interactions.h"#include "ai_squad.h"#include "igamemovement.h"#include "ai_hull.h"#include "hl2_shareddefs.h"#include "info_camera_link.h"#include "point_camera.h"#include "engine/IEngineSound.h"#include "ndebugoverlay.h"#include "iservervehicle.h"#include "IVehicle.h"#include "globals.h"#include "collisionutils.h"#include "coordsize.h"#include "effect_color_tables.h"#include "vphysics/player_controller.h"#include "player_pickup.h"#include "weapon_physcannon.h"#include "script_intro.h"#include "effect_dispatch_data.h"#include "te_effect_dispatch.h" #include "ai_basenpc.h"#include "AI_Criteria.h"#include "npc_barnacle.h"#include "entitylist.h"#include "env_zoom.h"#include "hl2_gamerules.h"#include "prop_combine_ball.h"#include "datacache/imdlcache.h"#include "eventqueue.h"#include "GameStats.h"#include "filters.h"#include "tier0/icommandline.h"#ifdef HL2_EPISODIC#include "npc_alyx_episodic.h"#endif// memdbgon must be the last include file in a .cpp file!!!#include "tier0/memdbgon.h"extern ConVar weapon_showproficiency;extern ConVar autoaim_max_dist;// Do not touch with without seeing me, please! (sjb)// For consistency's sake, enemy gunfire is traced against a scaled down// version of the player's hull, not the hitboxes for the player's model// because the player isn't aware of his model, and can't do anything about// preventing headshots and other such things. Also, game difficulty will// not change if the model changes. This is the value by which to scale// the X/Y of the player's hull to get the volume to trace bullets against.#define PLAYER_HULL_REDUCTION	0.70// This switches between the single primary weapon, and multiple weapons with buckets approach (jdw)#define	HL2_SINGLE_PRIMARY_WEAPON_MODE	0#define TIME_IGNORE_FALL_DAMAGE 10.0extern int gEvilImpulse101;ConVar sv_autojump( "sv_autojump", "0" );ConVar hl2_walkspeed( "hl2_walkspeed", "150" );ConVar hl2_normspeed( "hl2_normspeed", "190" );ConVar hl2_sprintspeed( "hl2_sprintspeed", "320" );ConVar hl2_ig_walkspeed( "hl2_ig_walkspeed", "150" );ConVar hl2_ig_normspeed( "hl2_ig_normspeed", "190" );ConVar hl2_ig_sprintspeed( "hl2_ig_sprintspeed", "270" );ConVar hl2_ork_walkspeed( "hl2_ork_walkspeed", "200" );ConVar hl2_ork_normspeed( "hl2_ork_normspeed", "250" );ConVar hl2_ork_sprintspeed( "hl2_ork_sprintspeed", "250" );ConVar hl2_darkness_flashlight_factor ( "hl2_darkness_flashlight_factor", "1" );ConVar w40k_restrict_v1_weapons( "w40k_restrict_v1_weapons", "1" );// MERLYN HAX: why this cruel and unusual modification limitation, valve? ://*#ifdef HL2MP	#define	HL2_WALK_SPEED 150	#define	HL2_NORM_SPEED 190	#define	HL2_SPRINT_SPEED 320#else*//*	#define	HL2_WALK_SPEED hl2_walkspeed.GetFloat()	#define	HL2_NORM_SPEED hl2_normspeed.GetFloat()	#define	HL2_SPRINT_SPEED hl2_sprintspeed.GetFloat()*///#endif#define HL2_WALK_SPEED GetWalkSpeed()#define HL2_NORM_SPEED GetNormSpeed()#define HL2_SPRINT_SPEED GetRunSpeed()ConVar player_showpredictedposition( "player_showpredictedposition", "0" );ConVar player_showpredictedposition_timestep( "player_showpredictedposition_timestep", "1.0" );ConVar player_squad_transient_commands( "player_squad_transient_commands", "1", FCVAR_REPLICATED );ConVar player_squad_double_tap_time( "player_squad_double_tap_time", "0.25" );ConVar sv_infinite_aux_power( "sv_infinite_aux_power", "0", FCVAR_CHEAT );ConVar autoaim_unlock_target( "autoaim_unlock_target", "0.8666" );ConVar sv_stickysprint("sv_stickysprint", "0", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX);#define	FLASH_DRAIN_TIME	 1.1111	// 100 units / 90 secs#define	FLASH_CHARGE_TIME	 50.0f	// 100 units / 2 secs//==============================================================================================// CAPPED PLAYER PHYSICS DAMAGE TABLE//==============================================================================================static impactentry_t cappedPlayerLinearTable[] ={	{ 150*150, 5 },	{ 250*250, 10 },	{ 450*450, 20 },	{ 550*550, 30 },	//{ 700*700, 100 },	//{ 1000*1000, 500 },};static impactentry_t cappedPlayerAngularTable[] ={	{ 100*100, 10 },	{ 150*150, 20 },	{ 200*200, 30 },	//{ 300*300, 500 },};static impactdamagetable_t gCappedPlayerImpactDamageTable ={	cappedPlayerLinearTable,	cappedPlayerAngularTable,	ARRAYSIZE(cappedPlayerLinearTable),	ARRAYSIZE(cappedPlayerAngularTable),	24*24.0f,	// minimum linear speed	360*360.0f,	// minimum angular speed	2.0f,		// can't take damage from anything under 2kg	5.0f,		// anything less than 5kg is "small"	5.0f,		// never take more than 5 pts of damage from anything under 5kg	36*36.0f,	// <5kg objects must go faster than 36 in/s to do damage	0.0f,		// large mass in kg (no large mass effects)	1.0f,		// large mass scale	2.0f,		// large mass falling scale	320.0f,		// min velocity for player speed to cause damage};// Flashlight utilitybool g_bCacheLegacyFlashlightStatus = true;bool g_bUseLegacyFlashlight;bool Flashlight_UseLegacyVersion( void ){	// If this is the first run through, cache off what the answer should be (cannot change during a session)	if ( g_bCacheLegacyFlashlightStatus )	{		char modDir[MAX_PATH];		if ( UTIL_GetModDir( modDir, sizeof(modDir) ) == false )			return false;		g_bUseLegacyFlashlight = ( !Q_strcmp( modDir, "hl2" ) || !Q_strcmp( modDir, "episodic" ) );		g_bCacheLegacyFlashlightStatus = false;	}	// Return the results	return g_bUseLegacyFlashlight;}//-----------------------------------------------------------------------------// Purpose: Used to relay outputs/inputs from the player to the world and viceversa//-----------------------------------------------------------------------------class CLogicPlayerProxy : public CLogicalEntity{	DECLARE_CLASS( CLogicPlayerProxy, CLogicalEntity );private:	DECLARE_DATADESC();public:	COutputEvent m_OnFlashlightOn;	COutputEvent m_OnFlashlightOff;	COutputEvent m_PlayerHasAmmo;	COutputEvent m_PlayerHasNoAmmo;	COutputEvent m_PlayerDied;	COutputEvent m_PlayerMissedAR2AltFire; // Player fired a combine ball which did not dissolve any enemies. 	COutputInt m_RequestedPlayerHealth;	void InputRequestPlayerHealth( inputdata_t &inputdata );	void InputSetFlashlightSlowDrain( inputdata_t &inputdata );	void InputSetFlashlightNormalDrain( inputdata_t &inputdata );	void InputSetPlayerHealth( inputdata_t &inputdata );	void InputRequestAmmoState( inputdata_t &inputdata );	void InputLowerWeapon( inputdata_t &inputdata );	void InputEnableCappedPhysicsDamage( inputdata_t &inputdata );	void InputDisableCappedPhysicsDamage( inputdata_t &inputdata );	void InputSetLocatorTargetEntity( inputdata_t &inputdata );	void Activate ( void );	bool PassesDamageFilter( const CTakeDamageInfo &info );	EHANDLE m_hPlayer;};//------------------------------------------------------------------------------//------------------------------------------------------------------------------void CC_ToggleZoom( void ){	CBasePlayer* pPlayer = UTIL_GetCommandClient();	if( pPlayer )	{		CHL2_Player *pHL2Player = dynamic_cast<CHL2_Player*>(pPlayer);		if( pHL2Player && pHL2Player->IsSuitEquipped() )		{			pHL2Player->ToggleZoom();		}	}}static ConCommand toggle_zoom("toggle_zoom", CC_ToggleZoom, "Toggles zoom display" );// ConVar cl_forwardspeed( "cl_forwardspeed", "400", FCVAR_CHEAT ); // Links us to the client's versionConVar xc_crouch_range( "xc_crouch_range", "0.85", FCVAR_ARCHIVE, "Percentarge [1..0] of joystick range to allow ducking within" );	// Only 1/2 of the range is usedConVar xc_use_crouch_limiter( "xc_use_crouch_limiter", "0", FCVAR_ARCHIVE, "Use the crouch limiting logic on the controller" );//------------------------------------------------------------------------------//------------------------------------------------------------------------------void CC_ToggleDuck( void ){	CBasePlayer* pPlayer = UTIL_GetCommandClient();	if ( pPlayer == NULL )		return;	// Cannot be frozen	if ( pPlayer->GetFlags() & FL_FROZEN )		return;	static bool		bChecked = false;	static ConVar *pCVcl_forwardspeed = NULL;	if ( !bChecked )	{		bChecked = true;		pCVcl_forwardspeed = ( ConVar * )cvar->FindVar( "cl_forwardspeed" );	}	// If we're not ducked, do extra checking	if ( xc_use_crouch_limiter.GetBool() )	{		if ( pPlayer->GetToggledDuckState() == false )		{			float flForwardSpeed = 400.0f;			if ( pCVcl_forwardspeed )			{				flForwardSpeed = pCVcl_forwardspeed->GetFloat();			}			flForwardSpeed = max( 1.0f, flForwardSpeed );			// Make sure we're not in the blindspot on the crouch detection			float flStickDistPerc = ( pPlayer->GetStickDist() / flForwardSpeed ); // Speed is the magnitude			if ( flStickDistPerc > xc_crouch_range.GetFloat() )				return;		}	}	// Toggle the duck	pPlayer->ToggleDuck();}static ConCommand toggle_duck("toggle_duck", CC_ToggleDuck, "Toggles duck" );#ifndef HL2MP#ifndef PORTALLINK_ENTITY_TO_CLASS( player, CHL2_Player );#endif#endifPRECACHE_REGISTER(player);CBaseEntity *FindEntityForward( CBasePlayer *pMe, bool fHull );BEGIN_SIMPLE_DATADESC( LadderMove_t )	DEFINE_FIELD( m_bForceLadderMove, FIELD_BOOLEAN ),	DEFINE_FIELD( m_bForceMount, FIELD_BOOLEAN ),	DEFINE_FIELD( m_flStartTime, FIELD_TIME ),	DEFINE_FIELD( m_flArrivalTime, FIELD_TIME ),	DEFINE_FIELD( m_vecGoalPosition, FIELD_POSITION_VECTOR ),	DEFINE_FIELD( m_vecStartPosition, FIELD_POSITION_VECTOR ),	DEFINE_FIELD( m_hForceLadder, FIELD_EHANDLE ),	DEFINE_FIELD( m_hReservedSpot, FIELD_EHANDLE ),END_DATADESC()// Global Savedata for HL2 playerBEGIN_DATADESC( CHL2_Player )	DEFINE_FIELD( m_nControlClass, FIELD_INTEGER ),	DEFINE_EMBEDDED( m_HL2Local ),	DEFINE_FIELD( m_bSprintEnabled, FIELD_BOOLEAN ),	DEFINE_FIELD( m_flTimeAllSuitDevicesOff, FIELD_TIME ),	DEFINE_FIELD( m_fIsSprinting, FIELD_BOOLEAN ),	DEFINE_FIELD( m_fIsWalking, FIELD_BOOLEAN ),	/*	// These are initialized every time the player calls Activate()	DEFINE_FIELD( m_bIsAutoSprinting, FIELD_BOOLEAN ),	DEFINE_FIELD( m_fAutoSprintMinTime, FIELD_TIME ),	*/	// 	Field is used within a single tick, no need to save restore	// DEFINE_FIELD( m_bPlayUseDenySound, FIELD_BOOLEAN ),  	//							m_pPlayerAISquad reacquired on load	DEFINE_AUTO_ARRAY( m_vecMissPositions, FIELD_POSITION_VECTOR ),	DEFINE_FIELD( m_nNumMissPositions, FIELD_INTEGER ),	//					m_pPlayerAISquad	DEFINE_EMBEDDED( m_CommanderUpdateTimer ),	//					m_RealTimeLastSquadCommand	DEFINE_FIELD( m_QueuedCommand, FIELD_INTEGER ),	DEFINE_FIELD( m_flTimeIgnoreFallDamage, FIELD_TIME ),	DEFINE_FIELD( m_bIgnoreFallDamageResetAfterImpact, FIELD_BOOLEAN ),	// Suit power fields	DEFINE_FIELD( m_flSuitPowerLoad, FIELD_FLOAT ),	DEFINE_FIELD( m_flIdleTime, FIELD_TIME ),	DEFINE_FIELD( m_flMoveTime, FIELD_TIME ),	DEFINE_FIELD( m_flLastDamageTime, FIELD_TIME ),	DEFINE_FIELD( m_flTargetFindTime, FIELD_TIME ),	DEFINE_FIELD( m_flAdmireGlovesAnimTime, FIELD_TIME ),	DEFINE_FIELD( m_flNextFlashlightCheckTime, FIELD_TIME ),	DEFINE_FIELD( m_flFlashlightPowerDrainScale, FIELD_FLOAT ),	DEFINE_FIELD( m_bFlashlightDisabled, FIELD_BOOLEAN ),	DEFINE_FIELD( m_bUseCappedPhysicsDamageTable, FIELD_BOOLEAN ),	DEFINE_FIELD( m_hLockedAutoAimEntity, FIELD_EHANDLE ),	DEFINE_EMBEDDED( m_LowerWeaponTimer ),	DEFINE_EMBEDDED( m_AutoaimTimer ),	DEFINE_INPUTFUNC( FIELD_FLOAT, "IgnoreFallDamage", InputIgnoreFallDamage ),	DEFINE_INPUTFUNC( FIELD_FLOAT, "IgnoreFallDamageWithoutReset", InputIgnoreFallDamageWithoutReset ),	DEFINE_INPUTFUNC( FIELD_VOID, "OnSquadMemberKilled", OnSquadMemberKilled ),	DEFINE_INPUTFUNC( FIELD_VOID, "DisableFlashlight", InputDisableFlashlight ),	DEFINE_INPUTFUNC( FIELD_VOID, "EnableFlashlight", InputEnableFlashlight ),	DEFINE_INPUTFUNC( FIELD_VOID, "ForceDropPhysObjects", InputForceDropPhysObjects ),	DEFINE_SOUNDPATCH( m_sndLeeches ),	DEFINE_SOUNDPATCH( m_sndWaterSplashes ),	DEFINE_FIELD( m_flArmorReductionTime, FIELD_TIME ),	DEFINE_FIELD( m_iArmorReductionFrom, FIELD_INTEGER ),	DEFINE_FIELD( m_flTimeUseSuspended, FIELD_TIME ),	DEFINE_FIELD( m_hLocatorTargetEntity, FIELD_EHANDLE ),	DEFINE_FIELD( m_flTimeNextLadderHint, FIELD_TIME ),	//DEFINE_FIELD( m_hPlayerProxy, FIELD_EHANDLE ), //Shut up class check!END_DATADESC()CHL2_Player::CHL2_Player(){	m_nNumMissPositions	= 0;	m_pPlayerAISquad = 0;	m_bSprintEnabled = true;	m_flArmorReductionTime = 0.0f;	m_iArmorReductionFrom = 0;}//// SUIT POWER DEVICES//#define SUITPOWER_CHARGE_RATE	7.5											// (merlyn hax) 100 units in 16 seconds#ifdef HL2MP	CSuitPowerDevice SuitDeviceSprint( bits_SUIT_DEVICE_SPRINT, 20.0f );				// (merlyn hax) 100 units in 5 seconds#else	CSuitPowerDevice SuitDeviceSprint( bits_SUIT_DEVICE_SPRINT, 12.5f );				// 100 units in 8 seconds#endif#ifdef HL2_EPISODIC	CSuitPowerDevice SuitDeviceFlashlight( bits_SUIT_DEVICE_FLASHLIGHT, 1.111 );	// 100 units in 90 second#else	CSuitPowerDevice SuitDeviceFlashlight( bits_SUIT_DEVICE_FLASHLIGHT, 2.222 );	// 100 units in 45 second#endifCSuitPowerDevice SuitDeviceBreather( bits_SUIT_DEVICE_BREATHER, 6.7f );		// 100 units in 15 seconds (plus three padded seconds)IMPLEMENT_SERVERCLASS_ST(CHL2_Player, DT_HL2_Player)	SendPropDataTable(SENDINFO_DT(m_HL2Local), &REFERENCE_SEND_TABLE(DT_HL2Local), SendProxy_SendLocalDataTable),	SendPropBool( SENDINFO(m_fIsSprinting) ),END_SEND_TABLE()float CHL2_Player::GetWalkSpeed( void ){	// 2 == ig, 3 == orks	DevMsg("teamnum is %d", this->GetTeamNumber());	if (this->GetTeamNumber() == 2)		return hl2_ig_walkspeed.GetFloat();	else if (this->GetTeamNumber() == 3)		return hl2_ork_walkspeed.GetFloat();	else		return hl2_walkspeed.GetFloat();	}float CHL2_Player::GetNormSpeed( void ){	if (this->GetTeamNumber() == 2)		return hl2_ig_normspeed.GetFloat();	else if (this->GetTeamNumber() == 3)		return hl2_ork_normspeed.GetFloat();	else		return hl2_normspeed.GetFloat();}float CHL2_Player::GetRunSpeed( void ){	if (this->GetTeamNumber() == 2)		return hl2_ig_sprintspeed.GetFloat();	else if (this->GetTeamNumber() == 3)		return hl2_ork_sprintspeed.GetFloat();	else		return hl2_sprintspeed.GetFloat();}void CHL2_Player::Precache( void ){	BaseClass::Precache();	PrecacheScriptSound( "HL2Player.SprintNoPower" );	PrecacheScriptSound( "HL2Player.SprintStart" );	PrecacheScriptSound( "HL2Player.UseDeny" );	PrecacheScriptSound( "HL2Player.FlashLightOn" );	PrecacheScriptSound( "HL2Player.FlashLightOff" );	PrecacheScriptSound( "HL2Player.PickupWeapon" );	PrecacheScriptSound( "HL2Player.TrainUse" );	PrecacheScriptSound( "HL2Player.Use" );	PrecacheScriptSound( "HL2Player.BurnPain" );}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void CHL2_Player::CheckSuitZoom( void ){//#ifndef _XBOX 	//Adrian - No zooming without a suit!	if ( IsSuitEquipped() )	{		if ( m_afButtonReleased & IN_ZOOM )		{			StopZooming();		}			else if ( m_afButtonPressed & IN_ZOOM )		{			StartZooming();		}	}//#endif//_XBOX}void CHL2_Player::EquipSuit( bool bPlayEffects ){	MDLCACHE_CRITICAL_SECTION();	BaseClass::EquipSuit();		m_HL2Local.m_bDisplayReticle = true;	if ( bPlayEffects == true )	{		StartAdmireGlovesAnimation();	}}void CHL2_Player::RemoveSuit( void ){	BaseClass::RemoveSuit();	m_HL2Local.m_bDisplayReticle = false;}void CHL2_Player::HandleSpeedChanges( void ){	int buttonsChanged = m_afButtonPressed | m_afButtonReleased;	bool bCanSprint = CanSprint();	bool bIsSprinting = IsSprinting();	bool bWantSprint = ( bCanSprint && IsSuitEquipped() && (m_nButtons & IN_SPEED) );	if ( bIsSprinting != bWantSprint && (buttonsChanged & IN_SPEED) )	{		// If someone wants to sprint, make sure they've pressed the button to do so. We want to prevent the		// case where a player can hold down the sprint key and burn tiny bursts of sprint as the suit recharges		// We want a full debounce of the key to resume sprinting after the suit is completely drained		if ( bWantSprint )		{			if ( sv_stickysprint.GetBool() )			{				StartAutoSprint();			}			else			{				StartSprinting();			}		}		else		{			if ( !sv_stickysprint.GetBool() )			{				StopSprinting();			}			// Reset key, so it will be activated post whatever is suppressing it.			m_nButtons &= ~IN_SPEED;		}	}	bool bIsWalking = IsWalking();	// have suit, pressing button, not sprinting or ducking	bool bWantWalking;		if( IsSuitEquipped() )	{		bWantWalking = (m_nButtons & IN_WALK) && !IsSprinting() && !(m_nButtons & IN_DUCK);	}	else	{		bWantWalking = true;	}		if( bIsWalking != bWantWalking )	{		if ( bWantWalking )		{			StartWalking();		}		else		{			StopWalking();		}	}}//-----------------------------------------------------------------------------// This happens when we powerdown from the mega physcannon to the regular one//-----------------------------------------------------------------------------void CHL2_Player::HandleArmorReduction( void ){	if ( m_flArmorReductionTime < gpGlobals->curtime )		return;	if ( ArmorValue() <= 0 )		return;	float flPercent = 1.0f - (( m_flArmorReductionTime - gpGlobals->curtime ) / ARMOR_DECAY_TIME );	int iArmor = Lerp( flPercent, m_iArmorReductionFrom, 0 );	SetArmorValue( iArmor );}//-----------------------------------------------------------------------------// Purpose: Allow pre-frame adjustments on the player//-----------------------------------------------------------------------------void CHL2_Player::PreThink(void){	if ( player_showpredictedposition.GetBool() )	{		Vector	predPos;		UTIL_PredictedPosition( this, player_showpredictedposition_timestep.GetFloat(), &predPos );		NDebugOverlay::Box( predPos, NAI_Hull::Mins( GetHullType() ), NAI_Hull::Maxs( GetHullType() ), 0, 255, 0, 0, 0.01f );		NDebugOverlay::Line( GetAbsOrigin(), predPos, 0, 255, 0, 0, 0.01f );	}#ifdef HL2_EPISODIC	if( m_hLocatorTargetEntity != NULL )	{		// Keep track of the entity here, the client will pick up the rest of the work		m_HL2Local.m_vecLocatorOrigin = m_hLocatorTargetEntity->WorldSpaceCenter();	}	else	{		m_HL2Local.m_vecLocatorOrigin = vec3_invalid; // This tells the client we have no locator target.	}#endif//HL2_EPISODIC	// Riding a vehicle?	if ( IsInAVehicle() )		{		VPROF( "CHL2_Player::PreThink-Vehicle" );		// make sure we update the client, check for timed damage and update suit even if we are in a vehicle		UpdateClientData();				CheckTimeBasedDamage();		// Allow the suit to recharge when in the vehicle.		SuitPower_Update();		CheckSuitUpdate();		CheckSuitZoom();		WaterMove();			return;	}	// This is an experiment of mine- autojumping! 	// only affects you if sv_autojump is nonzero.	if( (GetFlags() & FL_ONGROUND) && sv_autojump.GetFloat() != 0 )	{		VPROF( "CHL2_Player::PreThink-Autojump" );		// check autojump		Vector vecCheckDir;		vecCheckDir = GetAbsVelocity();		float flVelocity = VectorNormalize( vecCheckDir );		if( flVelocity > 200 )		{			// Going fast enough to autojump			vecCheckDir = WorldSpaceCenter() + vecCheckDir * 34 - Vector( 0, 0, 16 );			trace_t tr;			UTIL_TraceHull( WorldSpaceCenter() - Vector( 0, 0, 16 ), vecCheckDir, NAI_Hull::Mins(HULL_TINY_CENTERED),NAI_Hull::Maxs(HULL_TINY_CENTERED), MASK_PLAYERSOLID, this, COLLISION_GROUP_PLAYER, &tr );						//NDebugOverlay::Line( tr.startpos, tr.endpos, 0,255,0, true, 10 );			if( tr.fraction == 1.0 && !tr.startsolid )			{				// Now trace down!				UTIL_TraceLine( vecCheckDir, vecCheckDir - Vector( 0, 0, 64 ), MASK_PLAYERSOLID, this, COLLISION_GROUP_NONE, &tr );				//NDebugOverlay::Line( tr.startpos, tr.endpos, 0,255,0, true, 10 );				if( tr.fraction == 1.0 && !tr.startsolid )				{					// !!!HACKHACK					// I KNOW, I KNOW, this is definitely not the right way to do this,					// but I'm prototyping! (sjb)					Vector vecNewVelocity = GetAbsVelocity();					vecNewVelocity.z += 250;					SetAbsVelocity( vecNewVelocity );				}			}		}	}	VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-Speed" );	HandleSpeedChanges();#ifdef HL2_EPISODIC	HandleArmorReduction();#endif	if( sv_stickysprint.GetBool() && m_bIsAutoSprinting )	{		// If we're ducked and not in the air		if( IsDucked() && GetGroundEntity() != NULL )		{			StopSprinting();		}		// Stop sprinting if the player lets off the stick for a moment.		else if( GetStickDist() == 0.0f )		{			if( gpGlobals->curtime > m_fAutoSprintMinTime )			{				StopSprinting();			}		}		else		{			// Stop sprinting one half second after the player stops inputting with the move stick.			m_fAutoSprintMinTime = gpGlobals->curtime + 0.5f;		}	}	else if ( IsSprinting() )	{		// Disable sprint while ducked unless we're in the air (jumping)		if ( IsDucked() && ( GetGroundEntity() != NULL ) )		{			StopSprinting();		}	}	VPROF_SCOPE_END();	if ( g_fGameOver || IsPlayerLockedInPlace() )		return;         // finale	VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-ItemPreFrame" );	ItemPreFrame( );	VPROF_SCOPE_END();	VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-WaterMove" );	WaterMove();	VPROF_SCOPE_END();	if ( g_pGameRules && g_pGameRules->FAllowFlashlight() )		m_Local.m_iHideHUD &= ~HIDEHUD_FLASHLIGHT;	else		m_Local.m_iHideHUD |= HIDEHUD_FLASHLIGHT;		VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-CommanderUpdate" );	CommanderUpdate();	VPROF_SCOPE_END();	// Operate suit accessories and manage power consumption/charge	VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-SuitPower_Update" );	SuitPower_Update();	VPROF_SCOPE_END();	// checks if new client data (for HUD and view control) needs to be sent to the client	VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-UpdateClientData" );	UpdateClientData();	VPROF_SCOPE_END();		VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-CheckTimeBasedDamage" );	CheckTimeBasedDamage();	VPROF_SCOPE_END();	VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-CheckSuitUpdate" );	CheckSuitUpdate();	VPROF_SCOPE_END();	VPROF_SCOPE_BEGIN( "CHL2_Player::PreThink-CheckSuitZoom" );	CheckSuitZoom();	VPROF_SCOPE_END();	if (m_lifeState >= LIFE_DYING)	{		PlayerDeathThink();		return;	}#ifdef HL2_EPISODIC	CheckFlashlight();#endif	// HL2_EPISODIC	// So the correct flags get sent to client asap.	//	if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE )		AddFlag( FL_ONTRAIN );	else 		RemoveFlag( FL_ONTRAIN );	// Train speed control	if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE )	{		CBaseEntity *pTrain = GetGroundEntity();		float vel;		if ( pTrain )		{			if ( !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) )				pTrain = NULL;		}				if ( !pTrain )		{			if ( GetActiveWeapon() && (GetActiveWeapon()->ObjectCaps() & FCAP_DIRECTIONAL_USE) )			{				m_iTrain = TRAIN_ACTIVE | TRAIN_NEW;				if ( m_nButtons & IN_FORWARD )				{					m_iTrain |= TRAIN_FAST;				}				else if ( m_nButtons & IN_BACK )				{					m_iTrain |= TRAIN_BACK;				}				else				{					m_iTrain |= TRAIN_NEUTRAL;				}				return;			}			else			{				trace_t trainTrace;				// Maybe this is on the other side of a level transition				UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector(0,0,-38), 					MASK_PLAYERSOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trainTrace );				if ( trainTrace.fraction != 1.0 && trainTrace.m_pEnt )					pTrain = trainTrace.m_pEnt;				if ( !pTrain || !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) || !pTrain->OnControls(this) )				{//					Warning( "In train mode with no train!\n" );					m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE;					m_iTrain = TRAIN_NEW|TRAIN_OFF;					return;				}			}		}		else if ( !( GetFlags() & FL_ONGROUND ) || pTrain->HasSpawnFlags( SF_TRACKTRAIN_NOCONTROL ) || (m_nButtons & (IN_MOVELEFT|IN_MOVERIGHT) ) )		{			// Turn off the train if you jump, strafe, or the train controls go dead			m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE;			m_iTrain = TRAIN_NEW|TRAIN_OFF;			return;		}		SetAbsVelocity( vec3_origin );		vel = 0;		if ( m_afButtonPressed & IN_FORWARD )		{			vel = 1;			pTrain->Use( this, this, USE_SET, (float)vel );		}		else if ( m_afButtonPressed & IN_BACK )		{			vel = -1;			pTrain->Use( this, this, USE_SET, (float)vel );		}		if (vel)		{			m_iTrain = TrainSpeed(pTrain->m_flSpeed, ((CFuncTrackTrain*)pTrain)->GetMaxSpeed());			m_iTrain |= TRAIN_ACTIVE|TRAIN_NEW;		}	} 	else if (m_iTrain & TRAIN_ACTIVE)	{		m_iTrain = TRAIN_NEW; // turn off train	}	//	// If we're not on the ground, we're falling. Update our falling velocity.	//	if ( !( GetFlags() & FL_ONGROUND ) )	{		m_Local.m_flFallVelocity = -GetAbsVelocity().z;	}	if ( m_afPhysicsFlags & PFLAG_ONBARNACLE )	{		bool bOnBarnacle = false;		CNPC_Barnacle *pBarnacle = NULL;		do		{			// FIXME: Not a good or fast solution, but maybe it will catch the bug!			pBarnacle = (CNPC_Barnacle*)gEntList.FindEntityByClassname( pBarnacle, "npc_barnacle" );			if ( pBarnacle )			{				if ( pBarnacle->GetEnemy() == this )				{					bOnBarnacle = true;				}			}		} while ( pBarnacle );				if ( !bOnBarnacle )		{			Warning( "Attached to barnacle?\n" );			Assert( 0 );			m_afPhysicsFlags &= ~PFLAG_ONBARNACLE;		}		else		{			SetAbsVelocity( vec3_origin );		}	}	// StudioFrameAdvance( );//!!!HACKHACK!!! Can't be hit by traceline when not animating?	// Update weapon's ready status	UpdateWeaponPosture();	// Disallow shooting while zooming	if ( IsX360() )	{		if ( IsZooming() )		{			if( GetActiveWeapon() && !GetActiveWeapon()->IsWeaponZoomed() )			{				// If not zoomed because of the weapon itself, do not attack.				m_nButtons &= ~(IN_ATTACK|IN_ATTACK2);			}		}	}	else	{		if ( m_nButtons & IN_ZOOM )		{			//FIXME: Held weapons like the grenade get sad when this happens	#ifdef HL2_EPISODIC			// Episodic allows players to zoom while using a func_tank			CBaseCombatWeapon* pWep = GetActiveWeapon();			if ( !m_hUseEntity || ( pWep && pWep->IsWeaponVisible() ) )	#endif			m_nButtons &= ~(IN_ATTACK|IN_ATTACK2);		}	}}void CHL2_Player::PostThink( void ){	BaseClass::PostThink();	if ( !g_fGameOver && !IsPlayerLockedInPlace() && IsAlive() )	{		 HandleAdmireGlovesAnimation();	}}void CHL2_Player::StartAdmireGlovesAnimation( void ){	MDLCACHE_CRITICAL_SECTION();	CBaseViewModel *vm = GetViewModel( 0 );	if ( vm && !GetActiveWeapon() )	{		vm->SetWeaponModel( "models/weapons/v_hands.mdl", NULL );		ShowViewModel( true );								int	idealSequence = vm->SelectWeightedSequence( ACT_VM_IDLE );				if ( idealSequence >= 0 )		{			vm->SendViewModelMatchingSequence( idealSequence );			m_flAdmireGlovesAnimTime = gpGlobals->curtime + vm->SequenceDuration( idealSequence ); 		}	}}void CHL2_Player::HandleAdmireGlovesAnimation( void ){	CBaseViewModel *pVM = GetViewModel();	if ( pVM && pVM->GetOwningWeapon() == NULL )	{		if ( m_flAdmireGlovesAnimTime != 0.0 )		{			if ( m_flAdmireGlovesAnimTime > gpGlobals->curtime )			{				pVM->m_flPlaybackRate = 1.0f;				pVM->StudioFrameAdvance( );			}			else if ( m_flAdmireGlovesAnimTime < gpGlobals->curtime )			{				m_flAdmireGlovesAnimTime = 0.0f;				pVM->SetWeaponModel( NULL, NULL );			}		}	}	else		m_flAdmireGlovesAnimTime = 0.0f;}#define HL2PLAYER_RELOADGAME_ATTACK_DELAY 1.0fvoid CHL2_Player::Activate( void ){	BaseClass::Activate();	InitSprinting();#ifdef HL2_EPISODIC	// Delay attacks by 1 second after loading a game.	if ( GetActiveWeapon() )	{		float flRemaining = GetActiveWeapon()->m_flNextPrimaryAttack - gpGlobals->curtime;		if ( flRemaining < HL2PLAYER_RELOADGAME_ATTACK_DELAY )		{			GetActiveWeapon()->m_flNextPrimaryAttack = gpGlobals->curtime + HL2PLAYER_RELOADGAME_ATTACK_DELAY;		}		flRemaining = GetActiveWeapon()->m_flNextSecondaryAttack - gpGlobals->curtime;		if ( flRemaining < HL2PLAYER_RELOADGAME_ATTACK_DELAY )		{			GetActiveWeapon()->m_flNextSecondaryAttack = gpGlobals->curtime + HL2PLAYER_RELOADGAME_ATTACK_DELAY;		}	}#endif	GetPlayerProxy();}//------------------------------------------------------------------------------// Purpose :// Input   :// Output  ://------------------------------------------------------------------------------Class_T  CHL2_Player::Classify ( void ){	// If player controlling another entity?  If so, return this class	if (m_nControlClass != CLASS_NONE)	{		return m_nControlClass;	}	else	{		if(IsInAVehicle())		{			IServerVehicle *pVehicle = GetVehicle();			return pVehicle->ClassifyPassenger( this, CLASS_PLAYER );		}		else		{			return CLASS_PLAYER;		}	}}//-----------------------------------------------------------------------------// Purpose:  This is a generic function (to be implemented by sub-classes) to//			 handle specific interactions between different types of characters//			 (For example the barnacle grabbing an NPC)// Input  :  Constant for the type of interaction// Output :	 true  - if sub-class has a response for the interaction//			 false - if sub-class has no response//-----------------------------------------------------------------------------bool CHL2_Player::HandleInteraction(int interactionType, void *data, CBaseCombatCharacter* sourceEnt){	if ( interactionType == g_interactionBarnacleVictimDangle )		return false;		if (interactionType ==	g_interactionBarnacleVictimReleased)	{		m_afPhysicsFlags &= ~PFLAG_ONBARNACLE;		SetMoveType( MOVETYPE_WALK );		return true;	}	else if (interactionType ==	g_interactionBarnacleVictimGrab)	{#ifdef HL2_EPISODIC		CNPC_Alyx *pAlyx = CNPC_Alyx::GetAlyx();		if ( pAlyx )		{			// Make Alyx totally hate this barnacle so that she saves the player.			int priority;			priority = pAlyx->IRelationPriority(sourceEnt);			pAlyx->AddEntityRelationship( sourceEnt, D_HT, priority + 5 );		}#endif//HL2_EPISODIC		m_afPhysicsFlags |= PFLAG_ONBARNACLE;		ClearUseEntity();		return true;	}	return false;}void CHL2_Player::PlayerRunCommand(CUserCmd *ucmd, IMoveHelper *moveHelper){	// Handle FL_FROZEN.	if ( m_afPhysicsFlags & PFLAG_ONBARNACLE )	{		ucmd->forwardmove = 0;		ucmd->sidemove = 0;		ucmd->upmove = 0;		ucmd->buttons &= ~IN_USE;	}	// Can't use stuff while dead	if ( IsDead() )	{		ucmd->buttons &= ~IN_USE;	}	//Update our movement information	if ( ( ucmd->forwardmove != 0 ) || ( ucmd->sidemove != 0 ) || ( ucmd->upmove != 0 ) )	{		m_flIdleTime -= TICK_INTERVAL * 2.0f;				if ( m_flIdleTime < 0.0f )		{			m_flIdleTime = 0.0f;		}		m_flMoveTime += TICK_INTERVAL;		if ( m_flMoveTime > 4.0f )		{			m_flMoveTime = 4.0f;		}	}	else	{		m_flIdleTime += TICK_INTERVAL;				if ( m_flIdleTime > 4.0f )		{			m_flIdleTime = 4.0f;		}		m_flMoveTime -= TICK_INTERVAL * 2.0f;				if ( m_flMoveTime < 0.0f )		{			m_flMoveTime = 0.0f;		}	}	//Msg("Player time: [ACTIVE: %f]\t[IDLE: %f]\n", m_flMoveTime, m_flIdleTime );	BaseClass::PlayerRunCommand( ucmd, moveHelper );}//-----------------------------------------------------------------------------// Purpose: Sets HL2 specific defaults.//-----------------------------------------------------------------------------void CHL2_Player::Spawn(void){#ifndef HL2MP#ifndef PORTAL	SetModel( "models/player.mdl" );#endif#endif	BaseClass::Spawn();	//	// Our player movement speed is set once here. This will override the cl_xxxx	// cvars unless they are set to be lower than this.	//	//m_flMaxspeed = 320;	if ( !IsSuitEquipped() )		 StartWalking();	SuitPower_SetCharge( 100 );	m_Local.m_iHideHUD |= HIDEHUD_CHAT;	m_pPlayerAISquad = g_AI_SquadManager.FindCreateSquad(AllocPooledString(PLAYER_SQUADNAME));	InitSprinting();	// Setup our flashlight values#ifdef HL2_EPISODIC	m_HL2Local.m_flFlashBattery = 100.0f;#endif 	GetPlayerProxy();	SetFlashlightPowerDrainScale( 1.0f );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::UpdateLocatorPosition( const Vector &vecPosition ){#ifdef HL2_EPISODIC	m_HL2Local.m_vecLocatorOrigin = vecPosition;#endif//HL2_EPISODIC }//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::InitSprinting( void ){	StopSprinting();}//-----------------------------------------------------------------------------// Purpose: Returns whether or not we are allowed to sprint now.//-----------------------------------------------------------------------------bool CHL2_Player::CanSprint(){	return ( m_bSprintEnabled &&										// Only if sprint is enabled 			!IsWalking() &&												// Not if we're walking			!( m_Local.m_bDucked && !m_Local.m_bDucking ) &&			// Nor if we're ducking			(GetWaterLevel() != 3) &&									// Certainly not underwater			(GlobalEntity_GetState("suit_no_sprint") != GLOBAL_ON) );	// Out of the question without the sprint module}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::StartAutoSprint() {	if( IsSprinting() )	{		StopSprinting();	}	else	{		StartSprinting();		m_bIsAutoSprinting = true;		m_fAutoSprintMinTime = gpGlobals->curtime + 1.5f;	}}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::StartSprinting( void ){	if( m_HL2Local.m_flSuitPower < 10 )	{		// Don't sprint unless there's a reasonable		// amount of suit power.				// debounce the button for sound playing		if ( m_afButtonPressed & IN_SPEED )		{			CPASAttenuationFilter filter( this );			filter.UsePredictionRules();			EmitSound( filter, entindex(), "HL2Player.SprintNoPower" );		}		return;	}	if( !SuitPower_AddDevice( SuitDeviceSprint ) )		return;	CPASAttenuationFilter filter( this );	filter.UsePredictionRules();	EmitSound( filter, entindex(), "HL2Player.SprintStart" );	SetMaxSpeed( HL2_SPRINT_SPEED );	m_fIsSprinting = true;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::StopSprinting( void ){	if ( m_HL2Local.m_bitsActiveDevices & SuitDeviceSprint.GetDeviceID() )	{		SuitPower_RemoveDevice( SuitDeviceSprint );	}	if( IsSuitEquipped() )	{		SetMaxSpeed( HL2_NORM_SPEED );	}	else	{		SetMaxSpeed( HL2_WALK_SPEED );	}	m_fIsSprinting = false;	if ( sv_stickysprint.GetBool() )	{		m_bIsAutoSprinting = false;		m_fAutoSprintMinTime = 0.0f;	}}//-----------------------------------------------------------------------------// Purpose: Called to disable and enable sprint due to temporary circumstances://			- Carrying a heavy object with the physcannon//-----------------------------------------------------------------------------void CHL2_Player::EnableSprint( bool bEnable ){	if ( !bEnable && IsSprinting() )	{		StopSprinting();	}	m_bSprintEnabled = bEnable;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::StartWalking( void ){	SetMaxSpeed( HL2_WALK_SPEED );	m_fIsWalking = true;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::StopWalking( void ){	SetMaxSpeed( HL2_NORM_SPEED );	m_fIsWalking = false;}//-----------------------------------------------------------------------------// Purpose: // Output : Returns true on success, false on failure.//-----------------------------------------------------------------------------bool CHL2_Player::CanZoom( CBaseEntity *pRequester ){	if ( IsZooming() )		return false;	//Check our weapon	return true;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::ToggleZoom(void){	if( IsZooming() )	{		StopZooming();	}	else	{		StartZooming();	}}//-----------------------------------------------------------------------------// Purpose: +zoom suit zoom//-----------------------------------------------------------------------------void CHL2_Player::StartZooming( void ){	int iFOV = 25;	if ( SetFOV( this, iFOV, 0.4f ) )	{		m_HL2Local.m_bZooming = true;	}}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void CHL2_Player::StopZooming( void ){	int iFOV = GetZoomOwnerDesiredFOV( m_hZoomOwner );	if ( SetFOV( this, iFOV, 0.2f ) )	{		m_HL2Local.m_bZooming = false;	}}//-----------------------------------------------------------------------------// Purpose: // Output : Returns true on success, false on failure.//-----------------------------------------------------------------------------bool CHL2_Player::IsZooming( void ){	if ( m_hZoomOwner != NULL )		return true;	return false;}class CPhysicsPlayerCallback : public IPhysicsPlayerControllerEvent{public:	int ShouldMoveTo( IPhysicsObject *pObject, const Vector &position )	{		CHL2_Player *pPlayer = (CHL2_Player *)pObject->GetGameData();		if ( pPlayer )		{			if ( pPlayer->TouchedPhysics() )			{				return 0;			}		}		return 1;	}};static CPhysicsPlayerCallback playerCallback;//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void CHL2_Player::InitVCollision( const Vector &vecAbsOrigin, const Vector &vecAbsVelocity ){	BaseClass::InitVCollision( vecAbsOrigin, vecAbsVelocity );	// Setup the HL2 specific callback.	IPhysicsPlayerController *pPlayerController = GetPhysicsController();	if ( pPlayerController )	{		pPlayerController->SetEventHandler( &playerCallback );	}}CHL2_Player::~CHL2_Player( void ){}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------bool CHL2_Player::CommanderFindGoal( commandgoal_t *pGoal ){	CAI_BaseNPC *pAllyNpc;	trace_t	tr;	Vector	vecTarget;	Vector	forward;	EyeVectors( &forward );		//---------------------------------	// MASK_SHOT on purpose! So that you don't hit the invisible hulls of the NPCs.	CTraceFilterSkipTwoEntities filter( this, PhysCannonGetHeldEntity( GetActiveWeapon() ), COLLISION_GROUP_INTERACTIVE_DEBRIS );	UTIL_TraceLine( EyePosition(), EyePosition() + forward * MAX_COORD_RANGE, MASK_SHOT, &filter, &tr );	if( !tr.DidHitWorld() )	{		CUtlVector<CAI_BaseNPC *> Allies;		AISquadIter_t iter;		for ( pAllyNpc = m_pPlayerAISquad->GetFirstMember(&iter); pAllyNpc; pAllyNpc = m_pPlayerAISquad->GetNextMember(&iter) )		{			if ( pAllyNpc->IsCommandable() )				Allies.AddToTail( pAllyNpc );		}		for( int i = 0 ; i < Allies.Count() ; i++ )		{			if( Allies[ i ]->IsValidCommandTarget( tr.m_pEnt ) )			{				pGoal->m_pGoalEntity = tr.m_pEnt;				return true;			}		}	}	if( tr.fraction == 1.0 || (tr.surface.flags & SURF_SKY) )	{		// Move commands invalid against skybox.		pGoal->m_vecGoalLocation = tr.endpos;		return false;	}	if ( tr.m_pEnt->IsNPC() && ((CAI_BaseNPC *)(tr.m_pEnt))->IsCommandable() )	{		pGoal->m_vecGoalLocation = tr.m_pEnt->GetAbsOrigin();	}	else	{		vecTarget = tr.endpos;		Vector mins( -16, -16, 0 );		Vector maxs( 16, 16, 0 );		// Back up from whatever we hit so that there's enough space at the 		// target location for a bounding box.		// Now trace down. 		//UTIL_TraceLine( vecTarget, vecTarget - Vector( 0, 0, 8192 ), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );		UTIL_TraceHull( vecTarget + tr.plane.normal * 24,						vecTarget - Vector( 0, 0, 8192 ),						mins,						maxs,						MASK_SOLID_BRUSHONLY,						this,						COLLISION_GROUP_NONE,						&tr );		if ( !tr.startsolid )			pGoal->m_vecGoalLocation = tr.endpos;		else			pGoal->m_vecGoalLocation = vecTarget;	}	pAllyNpc = GetSquadCommandRepresentative();	if ( !pAllyNpc )		return false;	vecTarget = pGoal->m_vecGoalLocation;	if ( !pAllyNpc->FindNearestValidGoalPos( vecTarget, &pGoal->m_vecGoalLocation ) )		return false;	return ( ( vecTarget - pGoal->m_vecGoalLocation ).LengthSqr() < Square( 15*12 ) );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------CAI_BaseNPC *CHL2_Player::GetSquadCommandRepresentative(){	if ( m_pPlayerAISquad != NULL )	{		CAI_BaseNPC *pAllyNpc = m_pPlayerAISquad->GetFirstMember();				if ( pAllyNpc )		{			return pAllyNpc->GetSquadCommandRepresentative();		}	}	return NULL;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------int CHL2_Player::GetNumSquadCommandables(){	AISquadIter_t iter;	int c = 0;	for ( CAI_BaseNPC *pAllyNpc = m_pPlayerAISquad->GetFirstMember(&iter); pAllyNpc; pAllyNpc = m_pPlayerAISquad->GetNextMember(&iter) )	{		if ( pAllyNpc->IsCommandable() )			c++;	}	return c;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------int CHL2_Player::GetNumSquadCommandableMedics(){	AISquadIter_t iter;	int c = 0;	for ( CAI_BaseNPC *pAllyNpc = m_pPlayerAISquad->GetFirstMember(&iter); pAllyNpc; pAllyNpc = m_pPlayerAISquad->GetNextMember(&iter) )	{		if ( pAllyNpc->IsCommandable() && pAllyNpc->IsMedic() )			c++;	}	return c;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::CommanderUpdate(){	CAI_BaseNPC *pCommandRepresentative = GetSquadCommandRepresentative();	bool bFollowMode = false;	if ( pCommandRepresentative )	{		bFollowMode = ( pCommandRepresentative->GetCommandGoal() == vec3_invalid );		// set the variables for network transmission (to show on the hud)		m_HL2Local.m_iSquadMemberCount = GetNumSquadCommandables();		m_HL2Local.m_iSquadMedicCount = GetNumSquadCommandableMedics();		m_HL2Local.m_fSquadInFollowMode = bFollowMode;		// debugging code for displaying extra squad indicators		/*		char *pszMoving = "";		AISquadIter_t iter;		for ( CAI_BaseNPC *pAllyNpc = m_pPlayerAISquad->GetFirstMember(&iter); pAllyNpc; pAllyNpc = m_pPlayerAISquad->GetNextMember(&iter) )		{			if ( pAllyNpc->IsCommandMoving() )			{				pszMoving = "<-";				break;			}		}		NDebugOverlay::ScreenText(			0.932, 0.919, 			CFmtStr( "%d|%c%s", GetNumSquadCommandables(), ( bFollowMode ) ? 'F' : 'S', pszMoving ),			255, 128, 0, 128,			0 );		*/	}	else	{		m_HL2Local.m_iSquadMemberCount = 0;		m_HL2Local.m_iSquadMedicCount = 0;		m_HL2Local.m_fSquadInFollowMode = true;	}	if ( m_QueuedCommand != CC_NONE && ( m_QueuedCommand == CC_FOLLOW || gpGlobals->realtime - m_RealTimeLastSquadCommand >= player_squad_double_tap_time.GetFloat() ) )	{		CommanderExecute( m_QueuedCommand );		m_QueuedCommand = CC_NONE;	}	else if ( !bFollowMode && pCommandRepresentative && m_CommanderUpdateTimer.Expired() && player_squad_transient_commands.GetBool() )	{		m_CommanderUpdateTimer.Set(2.5);		if ( pCommandRepresentative->ShouldAutoSummon() )			CommanderExecute( CC_FOLLOW );	}}//-----------------------------------------------------------------------------// Purpose: //// bHandled - indicates whether to continue delivering this order to// all allies. Allows us to stop delivering certain types of orders once we find// a suitable candidate. (like picking up a single weapon. We don't wish for// all allies to respond and try to pick up one weapon).//----------------------------------------------------------------------------- bool CHL2_Player::CommanderExecuteOne( CAI_BaseNPC *pNpc, const commandgoal_t &goal, CAI_BaseNPC **Allies, int numAllies ){	if ( goal.m_pGoalEntity )	{		return pNpc->TargetOrder( goal.m_pGoalEntity, Allies, numAllies );	}	else if ( pNpc->IsInPlayerSquad() )	{		pNpc->MoveOrder( goal.m_vecGoalLocation, Allies, numAllies );	}		return true;}//---------------------------------------------------------//---------------------------------------------------------void CHL2_Player::CommanderExecute( CommanderCommand_t command ){	CAI_BaseNPC *pPlayerSquadLeader = GetSquadCommandRepresentative();	if ( !pPlayerSquadLeader )	{		EmitSound( "HL2Player.UseDeny" );		return;	}	int i;	CUtlVector<CAI_BaseNPC *> Allies;	commandgoal_t goal;	if ( command == CC_TOGGLE )	{		if ( pPlayerSquadLeader->GetCommandGoal() != vec3_invalid )			command = CC_FOLLOW;		else			command = CC_SEND;	}	else	{		if ( command == CC_FOLLOW && pPlayerSquadLeader->GetCommandGoal() == vec3_invalid )			return;	}	if ( command == CC_FOLLOW )	{		goal.m_pGoalEntity = this;		goal.m_vecGoalLocation = vec3_invalid;	}	else	{		goal.m_pGoalEntity = NULL;		goal.m_vecGoalLocation = vec3_invalid;		// Find a goal for ourselves.		if( !CommanderFindGoal( &goal ) )		{			EmitSound( "HL2Player.UseDeny" );			return; // just keep following		}	}#ifdef _DEBUG	if( goal.m_pGoalEntity == NULL && goal.m_vecGoalLocation == vec3_invalid )	{		DevMsg( 1, "**ERROR: Someone sent an invalid goal to CommanderExecute!\n" );	}#endif // _DEBUG	AISquadIter_t iter;	for ( CAI_BaseNPC *pAllyNpc = m_pPlayerAISquad->GetFirstMember(&iter); pAllyNpc; pAllyNpc = m_pPlayerAISquad->GetNextMember(&iter) )	{		if ( pAllyNpc->IsCommandable() )			Allies.AddToTail( pAllyNpc );	}	//---------------------------------	// If the trace hits an NPC, send all ally NPCs a "target" order. Always	// goes to targeted one first#ifdef DEBUG	int nAIs = g_AI_Manager.NumAIs();#endif	CAI_BaseNPC * pTargetNpc = (goal.m_pGoalEntity) ? goal.m_pGoalEntity->MyNPCPointer() : NULL;		bool bHandled = false;	if( pTargetNpc )	{		bHandled = !CommanderExecuteOne( pTargetNpc, goal, Allies.Base(), Allies.Count() );	}		for ( i = 0; !bHandled && i < Allies.Count(); i++ )	{		if ( Allies[i] != pTargetNpc && Allies[i]->IsPlayerAlly() )		{			bHandled = !CommanderExecuteOne( Allies[i], goal, Allies.Base(), Allies.Count() );		}		Assert( nAIs == g_AI_Manager.NumAIs() ); // not coded to support mutating set of NPCs	}}//-----------------------------------------------------------------------------// Enter/exit commander mode, manage ally selection.//-----------------------------------------------------------------------------void CHL2_Player::CommanderMode(){	float commandInterval = gpGlobals->realtime - m_RealTimeLastSquadCommand;	m_RealTimeLastSquadCommand = gpGlobals->realtime;	if ( commandInterval < player_squad_double_tap_time.GetFloat() )	{		m_QueuedCommand = CC_FOLLOW;	}	else	{		m_QueuedCommand = (player_squad_transient_commands.GetBool()) ? CC_SEND : CC_TOGGLE;	}}//-----------------------------------------------------------------------------// Purpose: // Input  : iImpulse - //-----------------------------------------------------------------------------void CHL2_Player::CheatImpulseCommands( int iImpulse ){	switch( iImpulse )	{	case 50:	{		CommanderMode();		break;	}	case 51:	{		// Cheat to create a dynamic resupply item		Vector vecForward;		AngleVectors( EyeAngles(), &vecForward );		CBaseEntity *pItem = (CBaseEntity *)CreateEntityByName( "item_dynamic_resupply" );		if ( pItem )		{			Vector vecOrigin = GetAbsOrigin() + vecForward * 256 + Vector(0,0,64);			QAngle vecAngles( 0, GetAbsAngles().y - 90, 0 );			pItem->SetAbsOrigin( vecOrigin );			pItem->SetAbsAngles( vecAngles );			pItem->KeyValue( "targetname", "resupply" );			pItem->Spawn();			pItem->Activate();		}		break;	}	case 52:	{		// Rangefinder		trace_t tr;		UTIL_TraceLine( EyePosition(), EyePosition() + EyeDirection3D() * MAX_COORD_RANGE, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );		if( tr.fraction != 1.0 )		{			float flDist = (tr.startpos - tr.endpos).Length();			float flDist2D = (tr.startpos - tr.endpos).Length2D();			DevMsg( 1,"\nStartPos: %.4f %.4f %.4f --- EndPos: %.4f %.4f %.4f\n", tr.startpos.x,tr.startpos.y,tr.startpos.z,tr.endpos.x,tr.endpos.y,tr.endpos.z );			DevMsg( 1,"3D Distance: %.4f units  (%.2f feet) --- 2D Distance: %.4f units  (%.2f feet)\n", flDist, flDist / 12.0, flDist2D, flDist2D / 12.0 );		}		break;	}	default:		BaseClass::CheatImpulseCommands( iImpulse );	}}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void CHL2_Player::SetupVisibility( CBaseEntity *pViewEntity, unsigned char *pvs, int pvssize ){	BaseClass::SetupVisibility( pViewEntity, pvs, pvssize );	int area = pViewEntity ? pViewEntity->NetworkProp()->AreaNum() : NetworkProp()->AreaNum();	PointCameraSetupVisibility( this, area, pvs, pvssize );	// If the intro script is playing, we want to get it's visibility points	if ( g_hIntroScript )	{		Vector vecOrigin;		CBaseEntity *pCamera;		if ( g_hIntroScript->GetIncludedPVSOrigin( &vecOrigin, &pCamera ) )		{			// If it's a point camera, turn it on			CPointCamera *pPointCamera = dynamic_cast< CPointCamera* >(pCamera); 			if ( pPointCamera )			{				pPointCamera->SetActive( true );			}			engine->AddOriginToPVS( vecOrigin );		}	}}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::SuitPower_Update( void ){	if( SuitPower_ShouldRecharge() )	{		SuitPower_Charge( SUITPOWER_CHARGE_RATE * gpGlobals->frametime );	}	else if( m_HL2Local.m_bitsActiveDevices )	{		float flPowerLoad = m_flSuitPowerLoad;		//Since stickysprint quickly shuts off sprint if it isn't being used, this isn't an issue.		if ( !sv_stickysprint.GetBool() )		{			if( SuitPower_IsDeviceActive(SuitDeviceSprint) )			{				if( !fabs(GetAbsVelocity().x) && !fabs(GetAbsVelocity().y) )				{					// If player's not moving, don't drain sprint juice.					flPowerLoad -= SuitDeviceSprint.GetDeviceDrainRate();				}			}		}		if( SuitPower_IsDeviceActive(SuitDeviceFlashlight) )		{			float factor;			factor = 1.0f / m_flFlashlightPowerDrainScale;			flPowerLoad -= ( SuitDeviceFlashlight.GetDeviceDrainRate() * (1.0f - factor) );		}		if( !SuitPower_Drain( flPowerLoad * gpGlobals->frametime ) )		{			// TURN OFF ALL DEVICES!!			if( IsSprinting() )			{				StopSprinting();			}			if ( Flashlight_UseLegacyVersion() )			{				if( FlashlightIsOn() )				{#ifndef HL2MP					FlashlightTurnOff();#endif				}			}		}		if ( Flashlight_UseLegacyVersion() )		{			// turn off flashlight a little bit after it hits below one aux power notch (5%)			if( m_HL2Local.m_flSuitPower < 4.8f && FlashlightIsOn() )			{#ifndef HL2MP				FlashlightTurnOff();#endif			}		}	}}//-----------------------------------------------------------------------------// Charge battery fully, turn off all devices.//-----------------------------------------------------------------------------void CHL2_Player::SuitPower_Initialize( void ){	m_HL2Local.m_bitsActiveDevices = 0x00000000;	m_HL2Local.m_flSuitPower = 100.0;	m_flSuitPowerLoad = 0.0;}//-----------------------------------------------------------------------------// Purpose: Interface to drain power from the suit's power supply.// Input:	Amount of charge to remove (expressed as percentage of full charge)// Output:	Returns TRUE if successful, FALSE if not enough power available.//-----------------------------------------------------------------------------bool CHL2_Player::SuitPower_Drain( float flPower ){	// Suitpower cheat on?	if ( sv_infinite_aux_power.GetBool() )		return true;	m_HL2Local.m_flSuitPower -= flPower;	if( m_HL2Local.m_flSuitPower < 0.0 )	{		// Power is depleted!		// Clamp and fail		m_HL2Local.m_flSuitPower = 0.0;		return false;	}	return true;}//-----------------------------------------------------------------------------// Purpose: Interface to add power to the suit's power supply// Input:	Amount of charge to add//-----------------------------------------------------------------------------void CHL2_Player::SuitPower_Charge( float flPower ){	m_HL2Local.m_flSuitPower += flPower;	if( m_HL2Local.m_flSuitPower > 100.0 )	{		// Full charge, clamp.		m_HL2Local.m_flSuitPower = 100.0;	}}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------bool CHL2_Player::SuitPower_IsDeviceActive( const CSuitPowerDevice &device ){	return (m_HL2Local.m_bitsActiveDevices & device.GetDeviceID()) != 0;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------bool CHL2_Player::SuitPower_AddDevice( const CSuitPowerDevice &device ){	// Make sure this device is NOT active!!	if( m_HL2Local.m_bitsActiveDevices & device.GetDeviceID() )		return false;	if( !IsSuitEquipped() )		return false;	m_HL2Local.m_bitsActiveDevices |= device.GetDeviceID();	m_flSuitPowerLoad += device.GetDeviceDrainRate();	return true;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------bool CHL2_Player::SuitPower_RemoveDevice( const CSuitPowerDevice &device ){	// Make sure this device is active!!	if( ! (m_HL2Local.m_bitsActiveDevices & device.GetDeviceID()) )		return false;	if( !IsSuitEquipped() )		return false;	// Take a little bit of suit power when you disable a device. If the device is shutting off	// because the battery is drained, no harm done, the battery charge cannot go below 0. 	// This code in combination with the delay before the suit can start recharging are a defense	// against exploits where the player could rapidly tap sprint and never run out of power.	SuitPower_Drain( device.GetDeviceDrainRate() * 0.1f );	m_HL2Local.m_bitsActiveDevices &= ~device.GetDeviceID();	m_flSuitPowerLoad -= device.GetDeviceDrainRate();	if( m_HL2Local.m_bitsActiveDevices == 0x00000000 )	{		// With this device turned off, we can set this timer which tells us when the		// suit power system entered a no-load state.		m_flTimeAllSuitDevicesOff = gpGlobals->curtime;	}	return true;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------#define SUITPOWER_BEGIN_RECHARGE_DELAY	0.5fbool CHL2_Player::SuitPower_ShouldRecharge( void ){	// Make sure all devices are off.	if( m_HL2Local.m_bitsActiveDevices != 0x00000000 )		return false;	// Is the system fully charged?	if( m_HL2Local.m_flSuitPower >= 100.0f )		return false; 	// Has the system been in a no-load state for long enough	// to begin recharging?	if( gpGlobals->curtime < m_flTimeAllSuitDevicesOff + SUITPOWER_BEGIN_RECHARGE_DELAY )		return false;	return true;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------ConVar	sk_battery( "sk_battery","0" );			bool CHL2_Player::ApplyBattery( float powerMultiplier ){	const float MAX_NORMAL_BATTERY = 100;	if ((ArmorValue() < MAX_NORMAL_BATTERY) && IsSuitEquipped())	{		int pct;		char szcharge[64];		IncrementArmorValue( sk_battery.GetFloat() * powerMultiplier, MAX_NORMAL_BATTERY );		CPASAttenuationFilter filter( this, "ItemBattery.Touch" );		EmitSound( filter, entindex(), "ItemBattery.Touch" );		CSingleUserRecipientFilter user( this );		user.MakeReliable();		UserMessageBegin( user, "ItemPickup" );			WRITE_STRING( "item_battery" );		MessageEnd();				// Suit reports new power level		// For some reason this wasn't working in release build -- round it.		pct = (int)( (float)(ArmorValue() * 100.0) * (1.0/MAX_NORMAL_BATTERY) + 0.5);		pct = (pct / 5);		if (pct > 0)			pct--;			Q_snprintf( szcharge,sizeof(szcharge),"!HEV_%1dP", pct );				//UTIL_EmitSoundSuit(edict(), szcharge);		//SetSuitUpdate(szcharge, FALSE, SUIT_NEXT_IN_30SEC);		return true;			}	return false;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------int CHL2_Player::FlashlightIsOn( void ){	return IsEffectActive( EF_DIMLIGHT );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::FlashlightTurnOn( void ){	if( m_bFlashlightDisabled )		return;	if ( Flashlight_UseLegacyVersion() )	{		if( !SuitPower_AddDevice( SuitDeviceFlashlight ) )			return;	}#ifdef HL2_DLL	if( !IsSuitEquipped() )		return;#endif	AddEffects( EF_DIMLIGHT );	EmitSound( "HL2Player.FlashLightOn" );	variant_t flashlighton;	flashlighton.SetFloat( m_HL2Local.m_flSuitPower / 100.0f );	FirePlayerProxyOutput( "OnFlashlightOn", flashlighton, this, this );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::FlashlightTurnOff( void ){	if ( Flashlight_UseLegacyVersion() )	{		if( !SuitPower_RemoveDevice( SuitDeviceFlashlight ) )			return;	}	RemoveEffects( EF_DIMLIGHT );	EmitSound( "HL2Player.FlashLightOff" );	variant_t flashlightoff;	flashlightoff.SetFloat( m_HL2Local.m_flSuitPower / 100.0f );	FirePlayerProxyOutput( "OnFlashlightOff", flashlightoff, this, this );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------#define FLASHLIGHT_RANGE	Square(600)bool CHL2_Player::IsIlluminatedByFlashlight( CBaseEntity *pEntity, float *flReturnDot ){	if( !FlashlightIsOn() )		return false;	if( pEntity->Classify() == CLASS_BARNACLE && pEntity->GetEnemy() == this )	{		// As long as my flashlight is on, the barnacle that's pulling me in is considered illuminated.		// This is because players often shine their flashlights at Alyx when they are in a barnacle's 		// grasp, and wonder why Alyx isn't helping. Alyx isn't helping because the light isn't pointed		// at the barnacle. This will allow Alyx to see the barnacle no matter which way the light is pointed.		return true;	}	// Within 50 feet? 	float flDistSqr = GetAbsOrigin().DistToSqr(pEntity->GetAbsOrigin());	if( flDistSqr > FLASHLIGHT_RANGE )		return false;	// Within 45 degrees?	Vector vecSpot = pEntity->WorldSpaceCenter();	Vector los;	// If the eyeposition is too close, move it back. Solves problems	// caused by the player being too close the target.	if ( flDistSqr < (128 * 128) )	{		Vector vecForward;		EyeVectors( &vecForward );		Vector vecMovedEyePos = EyePosition() - (vecForward * 128);		los = ( vecSpot - vecMovedEyePos );	}	else	{		los = ( vecSpot - EyePosition() );	}	VectorNormalize( los );	Vector facingDir = EyeDirection3D( );	float flDot = DotProduct( los, facingDir );	if ( flReturnDot )	{		 *flReturnDot = flDot;	}	if ( flDot < 0.92387f )		return false;	if( !FVisible(pEntity) )		return false;	return true;}//-----------------------------------------------------------------------------// Purpose: Let NPCs know when the flashlight is trained on them//-----------------------------------------------------------------------------void CHL2_Player::CheckFlashlight( void ){	if ( !FlashlightIsOn() )		return;	if ( m_flNextFlashlightCheckTime > gpGlobals->curtime )		return;	m_flNextFlashlightCheckTime = gpGlobals->curtime + FLASHLIGHT_NPC_CHECK_INTERVAL;	// Loop through NPCs looking for illuminated ones	for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ )	{		CAI_BaseNPC *pNPC = g_AI_Manager.AccessAIs()[i];		float flDot;		if ( IsIlluminatedByFlashlight( pNPC, &flDot ) )		{			pNPC->PlayerHasIlluminatedNPC( this, flDot );		}	}}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::SetPlayerUnderwater( bool state ){	if ( state )	{		SuitPower_AddDevice( SuitDeviceBreather );	}	else	{  		SuitPower_RemoveDevice( SuitDeviceBreather );	}	BaseClass::SetPlayerUnderwater( state );}//-----------------------------------------------------------------------------bool CHL2_Player::PassesDamageFilter( const CTakeDamageInfo &info ){	CBaseEntity *pAttacker = info.GetAttacker();	if( pAttacker && pAttacker->MyNPCPointer() && pAttacker->MyNPCPointer()->IsPlayerAlly() )	{		return false;	}	if( m_hPlayerProxy && !m_hPlayerProxy->PassesDamageFilter( info ) )	{		return false;	}	return BaseClass::PassesDamageFilter( info );}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void CHL2_Player::SetFlashlightEnabled( bool bState ){	m_bFlashlightDisabled = !bState;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::InputDisableFlashlight( inputdata_t &inputdata ){	if( FlashlightIsOn() )		FlashlightTurnOff();	SetFlashlightEnabled( false );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::InputEnableFlashlight( inputdata_t &inputdata ){	SetFlashlightEnabled( true );}//-----------------------------------------------------------------------------// Purpose: Prevent the player from taking fall damage for [n] seconds, but// reset back to taking fall damage after the first impact (so players will be// hurt if they bounce off what they hit). This is the original behavior.//-----------------------------------------------------------------------------void CHL2_Player::InputIgnoreFallDamage( inputdata_t &inputdata ){	float timeToIgnore = inputdata.value.Float();	if ( timeToIgnore <= 0.0 )		timeToIgnore = TIME_IGNORE_FALL_DAMAGE;	m_flTimeIgnoreFallDamage = gpGlobals->curtime + timeToIgnore;	m_bIgnoreFallDamageResetAfterImpact = true;}//-----------------------------------------------------------------------------// Purpose: Absolutely prevent the player from taking fall damage for [n] seconds. //-----------------------------------------------------------------------------void CHL2_Player::InputIgnoreFallDamageWithoutReset( inputdata_t &inputdata ){	float timeToIgnore = inputdata.value.Float();	if ( timeToIgnore <= 0.0 )		timeToIgnore = TIME_IGNORE_FALL_DAMAGE;	m_flTimeIgnoreFallDamage = gpGlobals->curtime + timeToIgnore;	m_bIgnoreFallDamageResetAfterImpact = false;}//-----------------------------------------------------------------------------// Purpose: Notification of a player's npc ally in the players squad being killed//-----------------------------------------------------------------------------void CHL2_Player::OnSquadMemberKilled( inputdata_t &data ){	// send a message to the client, to notify the hud of the loss	CSingleUserRecipientFilter user( this );	user.MakeReliable();	UserMessageBegin( user, "SquadMemberDied" );	MessageEnd();}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void CHL2_Player::NotifyFriendsOfDamage( CBaseEntity *pAttackerEntity ){	CAI_BaseNPC *pAttacker = pAttackerEntity->MyNPCPointer();	if ( pAttacker )	{		const Vector &origin = GetAbsOrigin();		for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ )		{			const float NEAR_Z = 12*12;			const float NEAR_XY_SQ = Square( 50*12 );			CAI_BaseNPC *pNpc = g_AI_Manager.AccessAIs()[i];			if ( pNpc->IsPlayerAlly() )			{				const Vector &originNpc = pNpc->GetAbsOrigin();				if ( fabsf( originNpc.z - origin.z ) < NEAR_Z )				{					if ( (originNpc.AsVector2D() - origin.AsVector2D()).LengthSqr() < NEAR_XY_SQ )					{						pNpc->OnFriendDamaged( this, pAttacker );					}				}			}		}	}}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------ConVar test_massive_dmg("test_massive_dmg", "30" );ConVar test_massive_dmg_clip("test_massive_dmg_clip", "0.5" );int	CHL2_Player::OnTakeDamage( const CTakeDamageInfo &info ){	if ( GlobalEntity_GetState( "gordon_invulnerable" ) == GLOBAL_ON )		return 0;	// ignore fall damage if instructed to do so by input	if ( ( info.GetDamageType() & DMG_FALL ) && m_flTimeIgnoreFallDamage > gpGlobals->curtime )	{		// usually, we will reset the input flag after the first impact. However there is another input that		// prevents this behavior.		if ( m_bIgnoreFallDamageResetAfterImpact )		{			m_flTimeIgnoreFallDamage = 0;		}		return 0;	}	if( info.GetDamageType() & DMG_BLAST_SURFACE )	{		if( GetWaterLevel() > 2 )		{			// Don't take blast damage from anything above the surface.			if( info.GetInflictor()->GetWaterLevel() == 0 )			{				return 0;			}		}	}	if ( info.GetDamage() > 0.0f )	{		m_flLastDamageTime = gpGlobals->curtime;		if ( info.GetAttacker() )			NotifyFriendsOfDamage( info.GetAttacker() );	}		// Modify the amount of damage the player takes, based on skill.	CTakeDamageInfo playerDamage = info;	// Should we run this damage through the skill level adjustment?	bool bAdjustForSkillLevel = true;	if( info.GetDamageType() == DMG_GENERIC && info.GetAttacker() == this && info.GetInflictor() == this )	{		// Only do a skill level adjustment if the player isn't his own attacker AND inflictor.		// This prevents damage from SetHealth() inputs from being adjusted for skill level.		bAdjustForSkillLevel = false;	}	if ( GetVehicleEntity() != NULL && GlobalEntity_GetState("gordon_protect_driver") == GLOBAL_ON )	{		if( playerDamage.GetDamage() > test_massive_dmg.GetFloat() && playerDamage.GetInflictor() == GetVehicleEntity() && (playerDamage.GetDamageType() & DMG_CRUSH) )		{			playerDamage.ScaleDamage( test_massive_dmg_clip.GetFloat() / playerDamage.GetDamage() );		}	}	if( bAdjustForSkillLevel )	{		playerDamage.AdjustPlayerDamageTakenForSkillLevel();	}	gamestats->Event_PlayerDamage( this, info );	return BaseClass::OnTakeDamage( playerDamage );}//-----------------------------------------------------------------------------// Purpose: // Input  : &info - //-----------------------------------------------------------------------------int CHL2_Player::OnTakeDamage_Alive( const CTakeDamageInfo &info ){	// Drown	if( info.GetDamageType() & DMG_DROWN )	{		if( m_idrowndmg == m_idrownrestored )		{			EmitSound( "Player.DrownStart" );		}		else		{			EmitSound( "Player.DrownContinue" );		}	}	// Burnt	if ( info.GetDamageType() & DMG_BURN )	{		EmitSound( "HL2Player.BurnPain" );	}	if( (info.GetDamageType() & DMG_SLASH) && hl2_episodic.GetBool() )	{		if( m_afPhysicsFlags & PFLAG_USING )		{			// Stop the player using a rotating button for a short time if hit by a creature's melee attack.			// This is for the antlion burrow-corking training in EP1 (sjb).			SuspendUse( 0.5f );		}	}	// Call the base class implementation	return BaseClass::OnTakeDamage_Alive( info );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::OnDamagedByExplosion( const CTakeDamageInfo &info ){	if ( info.GetInflictor() && info.GetInflictor()->ClassMatches( "mortarshell" ) )	{		// No ear ringing for mortar		UTIL_ScreenShake( info.GetInflictor()->GetAbsOrigin(), 4.0, 1.0, 0.5, 1000, SHAKE_START, false );		return;	}	BaseClass::OnDamagedByExplosion( info );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------bool CHL2_Player::ShouldShootMissTarget( CBaseCombatCharacter *pAttacker ){	if( gpGlobals->curtime > m_flTargetFindTime )	{		// Put this off into the future again.		m_flTargetFindTime = gpGlobals->curtime + random->RandomFloat( 3, 5 );		return true;	}	return false;}//-----------------------------------------------------------------------------// Purpose: Notifies Alyx that player has put a combine ball into a socket so she can comment on it.// Input  : pCombineBall - ball the was socketed//-----------------------------------------------------------------------------void CHL2_Player::CombineBallSocketed( CPropCombineBall *pCombineBall ){#ifdef HL2_EPISODIC	CNPC_Alyx *pAlyx = CNPC_Alyx::GetAlyx();	if ( pAlyx )	{		pAlyx->CombineBallSocketed( pCombineBall->NumBounces() );	}#endif}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ){	BaseClass::Event_KilledOther( pVictim, info );#ifdef HL2_EPISODIC	CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();	for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ )	{		if ( ppAIs[i] && ppAIs[i]->IRelationType(this) == D_LI )		{			ppAIs[i]->OnPlayerKilledOther( pVictim, info );		}	}#endif}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::Event_Killed( const CTakeDamageInfo &info ){	BaseClass::Event_Killed( info );	FirePlayerProxyOutput( "PlayerDied", variant_t(), this, this );	NotifyScriptsOfDeath();}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::NotifyScriptsOfDeath( void ){	CBaseEntity *pEnt =	gEntList.FindEntityByClassname( NULL, "scripted_sequence" );	while( pEnt )	{		variant_t emptyVariant;		pEnt->AcceptInput( "ScriptPlayerDeath", NULL, NULL, emptyVariant, 0 );		pEnt = gEntList.FindEntityByClassname( pEnt, "scripted_sequence" );	}	pEnt =	gEntList.FindEntityByClassname( NULL, "logic_choreographed_scene" );	while( pEnt )	{		variant_t emptyVariant;		pEnt->AcceptInput( "ScriptPlayerDeath", NULL, NULL, emptyVariant, 0 );		pEnt = gEntList.FindEntityByClassname( pEnt, "logic_choreographed_scene" );	}}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------void CHL2_Player::GetAutoaimVector( autoaim_params_t &params ){	BaseClass::GetAutoaimVector( params );	if ( IsX360() )	{		if( IsInAVehicle() )		{			if( m_hLockedAutoAimEntity && m_hLockedAutoAimEntity->IsAlive() && ShouldKeepLockedAutoaimTarget(m_hLockedAutoAimEntity) )			{				if( params.m_hAutoAimEntity && params.m_hAutoAimEntity != m_hLockedAutoAimEntity )				{					// Autoaim has picked a new target. Switch.					m_hLockedAutoAimEntity = params.m_hAutoAimEntity;				}				// Ignore autoaim and just keep aiming at this target.				params.m_hAutoAimEntity = m_hLockedAutoAimEntity;				Vector vecTarget = m_hLockedAutoAimEntity->BodyTarget( EyePosition(), false );				Vector vecDir = vecTarget - EyePosition();				VectorNormalize( vecDir );				params.m_vecAutoAimDir = vecDir;				params.m_vecAutoAimPoint = vecTarget;				return;					}			else			{				m_hLockedAutoAimEntity = NULL;			}		}		// If the player manually gets his crosshair onto a target, make that target sticky		if( params.m_fScale != AUTOAIM_SCALE_DIRECT_ONLY )		{			// Only affect this for 'real' queries			//if( params.m_hAutoAimEntity && params.m_bOnTargetNatural )			if( params.m_hAutoAimEntity )			{				// Turn on sticky.				m_HL2Local.m_bStickyAutoAim = true;				if( IsInAVehicle() )				{					m_hLockedAutoAimEntity = params.m_hAutoAimEntity;				}			}			else if( !params.m_hAutoAimEntity )			{				// Turn off sticky only if there's no target at all.				m_HL2Local.m_bStickyAutoAim = false;				m_hLockedAutoAimEntity = NULL;			}		}	}}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------bool CHL2_Player::ShouldKeepLockedAutoaimTarget( EHANDLE hLockedTarget ){	Vector vecLooking;	Vector vecToTarget;	vecToTarget = hLockedTarget->WorldSpaceCenter()	- EyePosition();	float flDist = vecToTarget.Length2D();	VectorNormalize( vecToTarget );	if( flDist > autoaim_max_dist.GetFloat() )		return false;	float flDot;	vecLooking = EyeDirection3D();	flDot = DotProduct( vecLooking, vecToTarget );	if( flDot < autoaim_unlock_target.GetFloat() ) 		return false;	return true;}//-----------------------------------------------------------------------------// Purpose: // Input  : iCount - //			iAmmoIndex - //			bSuppressSound - // Output : int//-----------------------------------------------------------------------------int CHL2_Player::GiveAmmo( int nCount, int nAmmoIndex, bool bSuppressSound){	// Don't try to give the player invalid ammo indices.	if (nAmmoIndex < 0)		return 0;	bool bCheckAutoSwitch = false;	if (!HasAnyAmmoOfType(nAmmoIndex))	{		bCheckAutoSwitch = true;	}	int nAdd = BaseClass::GiveAmmo(nCount, nAmmoIndex, bSuppressSound);	if ( nCount > 0 && nAdd == 0 )	{		// we've been denied the pickup, display a hud icon to show that		CSingleUserRecipientFilter user( this );		user.MakeReliable();		UserMessageBegin( user, "AmmoDenied" );			WRITE_SHORT( nAmmoIndex );		MessageEnd();	}	//	// If I was dry on ammo for my best weapon and justed picked up ammo for it,	// autoswitch to my best weapon now.	//	if (bCheckAutoSwitch)	{		CBaseCombatWeapon *pWeapon = g_pGameRules->GetNextBestWeapon(this, GetActiveWeapon());		if ( pWeapon && pWeapon->GetPrimaryAmmoType() == nAmmoIndex )		{			SwitchToNextBestWeapon(GetActiveWeapon());		}	}	return nAdd;}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------bool CHL2_Player::Weapon_CanUse( CBaseCombatWeapon *pWeapon ){#ifndef HL2MP		if ( pWeapon->ClassMatches( "weapon_stunstick" ) )	{		if ( ApplyBattery( 0.5 ) )			UTIL_Remove( pWeapon );		return false;	}#endif	// merlyn hax, revert this later when we have our own maps...	if ( w40k_restrict_v1_weapons.GetInt() == 1 )	{		if ( GetTeamNumber() == 2 ) // ig		{			return ( strncmp(pWeapon->GetClassname(), "weapon_smg1", 11) == 0				|| strncmp(pWeapon->GetClassname(),   "weapon_pistol", 13) == 0				|| strncmp(pWeapon->GetClassname(),   "weapon_crossbow", 15) == 0);		}		else if ( GetTeamNumber() == 3 ) // orks		{			return ( strncmp(pWeapon->GetClassname(), "weapon_357", 10) == 0				|| strncmp(pWeapon->GetClassname(),   "weapon_ar2", 10) == 0				|| strncmp(pWeapon->GetClassname(),   "weapon_crowbar", 14) == 0				|| strncmp(pWeapon->GetClassname(),   "weapon_frag", 11) == 0				|| strncmp(pWeapon->GetClassname(),   "weapon_crossbow", 15) == 0);		}		else		{			Warning("Fuck! I don't know what team has number '%d'", GetTeamNumber());			return BaseClass::Weapon_CanUse( pWeapon );		}	}	else	{		return BaseClass::Weapon_CanUse( pWeapon );	}}//-----------------------------------------------------------------------------// Purpose: // Input  : *pWeapon - //-----------------------------------------------------------------------------void CHL2_Player::Weapon_Equip( CBaseCombatWeapon *pWeapon ){#if	HL2_SINGLE_PRIMARY_WEAPON_MODE	if ( pWeapon->GetSlot() == WEAPON_PRIMARY_SLOT )	{		Weapon_DropSlot( WEAPON_PRIMARY_SLOT );	}#endif	if( GetActiveWeapon() == NULL )	{		m_HL2Local.m_bWeaponLowered = false;	}	BaseClass::Weapon_Equip( pWeapon );}//-----------------------------------------------------------------------------// Purpose: Player reacts to bumping a weapon. // Input  : pWeapon - the weapon that the player bumped into.// Output : Returns true if player picked up the weapon//-----------------------------------------------------------------------------bool CHL2_Player::BumpWeapon( CBaseCombatWeapon *pWeapon ){#if	HL2_SINGLE_PRIMARY_WEAPON_MODE	CBaseCombatCharacter *pOwner = pWeapon->GetOwner();	// Can I have this weapon type?	if ( pOwner || !Weapon_CanUse( pWeapon ) || !g_pGameRules->CanHavePlayerItem( this, pWeapon ) )	{		if ( gEvilImpulse101 )		{			UTIL_Remove( pWeapon );		}		return false;	}	// ----------------------------------------	// If I already have it just take the ammo	// ----------------------------------------	if (Weapon_OwnsThisType( pWeapon->GetClassname(), pWeapon->GetSubType())) 	{		//Only remove the weapon if we attained ammo from it		if ( Weapon_EquipAmmoOnly( pWeapon ) == false )			return false;		// Only remove me if I have no ammo left		// Can't just check HasAnyAmmo because if I don't use clips, I want to be removed, 		if ( pWeapon->UsesClipsForAmmo1() && pWeapon->HasPrimaryAmmo() )			return false;		UTIL_Remove( pWeapon );		return false;	}	// -------------------------	// Otherwise take the weapon	// -------------------------	else 	{		//Make sure we're not trying to take a new weapon type we already have		if ( Weapon_SlotOccupied( pWeapon ) )		{			CBaseCombatWeapon *pActiveWeapon = Weapon_GetSlot( WEAPON_PRIMARY_SLOT );			if ( pActiveWeapon != NULL && pActiveWeapon->HasAnyAmmo() == false && Weapon_CanSwitchTo( pWeapon ) )			{				Weapon_Equip( pWeapon );				return true;			}			//Attempt to take ammo if this is the gun we're holding already			if ( Weapon_OwnsThisType( pWeapon->GetClassname(), pWeapon->GetSubType() ) )			{				Weapon_EquipAmmoOnly( pWeapon );			}			return false;		}		pWeapon->CheckRespawn();		pWeapon->AddSolidFlags( FSOLID_NOT_SOLID );		pWeapon->AddEffects( EF_NODRAW );		Weapon_Equip( pWeapon );		EmitSound( "HL2Player.PickupWeapon" );				return true;	}#else	return BaseClass::BumpWeapon( pWeapon );#endif}//-----------------------------------------------------------------------------// Purpose: // Input  : *cmd - // Output : Returns true on success, false on failure.//-----------------------------------------------------------------------------bool CHL2_Player::ClientCommand( const CCommand &args ){#if	HL2_SINGLE_PRIMARY_WEAPON_MODE	//Drop primary weapon	if ( !Q_stricmp( args[0], "DropPrimary" ) )	{		Weapon_DropSlot( WEAPON_PRIMARY_SLOT );		return true;	}#endif	if ( !Q_stricmp( args[0], "emit" ) )	{		CSingleUserRecipientFilter filter( this );		if ( args.ArgC() > 1 )		{			EmitSound( filter, entindex(), args[ 1 ] );		}		else		{			EmitSound( filter, entindex(), "Test.Sound" );		}		return true;	}	return BaseClass::ClientCommand( args );}//-----------------------------------------------------------------------------// Purpose: // Output : void CBasePlayer::PlayerUse//-----------------------------------------------------------------------------void CHL2_Player::PlayerUse ( void ){	// Was use pressed or released?	if ( ! ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) )		return;	if ( m_afButtonPressed & IN_USE )	{		// Currently using a latched entity?		if ( ClearUseEntity() )		{			return;		}		else		{			if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE )			{				m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE;				m_iTrain = TRAIN_NEW|TRAIN_OFF;				return;			}			else			{	// Start controlling the train!				CBaseEntity *pTrain = GetGroundEntity();				if ( pTrain && !(m_nButtons & IN_JUMP) && (GetFlags() & FL_ONGROUND) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) && pTrain->OnControls(this) )				{					m_afPhysicsFlags |= PFLAG_DIROVERRIDE;					m_iTrain = TrainSpeed(pTrain->m_flSpeed, ((CFuncTrackTrain*)pTrain)->GetMaxSpeed());					m_iTrain |= TRAIN_NEW;					EmitSound( "HL2Player.TrainUse" );					return;				}			}		}		// Tracker 3926:  We can't +USE something if we're climbing a ladder		if ( GetMoveType() == MOVETYPE_LADDER )		{			return;		}	}	if( m_flTimeUseSuspended > gpGlobals->curtime )	{		// Something has temporarily stopped us being able to USE things.		// Obviously, this should be used very carefully.(sjb)		return;	}	CBaseEntity *pUseEntity = FindUseEntity();	bool usedSomething = false;	// Found an object	if ( pUseEntity )	{		//!!!UNDONE: traceline here to prevent +USEing buttons through walls					int caps = pUseEntity->ObjectCaps();		variant_t emptyVariant;		if ( m_afButtonPressed & IN_USE )		{			// Robin: Don't play sounds for NPCs, because NPCs will allow respond with speech.			if ( !pUseEntity->MyNPCPointer() )			{				EmitSound( "HL2Player.Use" );			}		}		if ( ( (m_nButtons & IN_USE) && (caps & FCAP_CONTINUOUS_USE) ) ||			 ( (m_afButtonPressed & IN_USE) && (caps & (FCAP_IMPULSE_USE|FCAP_ONOFF_USE)) ) )		{			if ( caps & FCAP_CONTINUOUS_USE )				m_afPhysicsFlags |= PFLAG_USING;			pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE );			usedSomething = true;		}		// UNDONE: Send different USE codes for ON/OFF.  Cache last ONOFF_USE object to send 'off' if you turn away		else if ( (m_afButtonReleased & IN_USE) && (pUseEntity->ObjectCaps() & FCAP_ONOFF_USE) )	// BUGBUG This is an "off" use		{			pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE );			usedSomething = true;		}#if	HL2_SINGLE_PRIMARY_WEAPON_MODE		//Check for weapon pick-up		if ( m_afButtonPressed & IN_USE )		{			CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>(pUseEntity);			if ( ( pWeapon != NULL ) && ( Weapon_CanSwitchTo( pWeapon ) ) )			{				//Try to take ammo or swap the weapon				if ( Weapon_OwnsThisType( pWeapon->GetClassname(), pWeapon->GetSubType() ) )				{					Weapon_EquipAmmoOnly( pWeapon );				}				else				{					Weapon_DropSlot( pWeapon->GetSlot() );					Weapon_Equip( pWeapon );				}				usedSomething = true;			}		}#endif	}	else if ( m_afButtonPressed & IN_USE )	{		// Signal that we want to play the deny sound, unless the user is +USEing on a ladder!		// The sound is emitted in ItemPostFrame, since that occurs after GameMovement::ProcessMove which		// lets the ladder code unset this flag.		m_bPlayUseDenySound = true;	}	// Debounce the use key	if ( usedSomething && pUseEntity )	{		m_Local.m_nOldButtons |= IN_USE;		m_afButtonPressed &= ~IN_USE;	}}ConVar	sv_show_crosshair_target( "sv_show_crosshair_target", "0" );//-----------------------------------------------------------------------------// Purpose: Updates the posture of the weapon from lowered to ready//-----------------------------------------------------------------------------void CHL2_Player::UpdateWeaponPosture( void ){	CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>(GetActiveWeapon());	if ( pWeapon && m_LowerWeaponTimer.Expired() && pWeapon->CanLower() )	{		m_LowerWeaponTimer.Set( .3 );		VPROF( "CHL2_Player::UpdateWeaponPosture-CheckLower" );		Vector vecAim = BaseClass::GetAutoaimVector( AUTOAIM_SCALE_DIRECT_ONLY );		const float CHECK_FRIENDLY_RANGE = 50 * 12;		trace_t	tr;		UTIL_TraceLine( EyePosition(), EyePosition() + vecAim * CHECK_FRIENDLY_RANGE, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );		CBaseEntity *aimTarget = tr.m_pEnt;		//If we're over something		if (  aimTarget && !tr.DidHitWorld() )		{			if ( !aimTarget->IsNPC() || aimTarget->MyNPCPointer()->GetState() != NPC_STATE_COMBAT )			{				Disposition_t dis = IRelationType( aimTarget );				//Debug info for seeing what an object "cons" as				if ( sv_show_crosshair_target.GetBool() )				{					int text_offset = BaseClass::DrawDebugTextOverlays();					char tempstr[255];						switch ( dis )					{					case D_LI:						Q_snprintf( tempstr, sizeof(tempstr), "Disposition: Like" );						break;					case D_HT:						Q_snprintf( tempstr, sizeof(tempstr), "Disposition: Hate" );						break;					case D_FR:						Q_snprintf( tempstr, sizeof(tempstr), "Disposition: Fear" );						break;					case D_NU:						Q_snprintf( tempstr, sizeof(tempstr), "Disposition: Neutral" );						break;					default:					case D_ER:						Q_snprintf( tempstr, sizeof(tempstr), "Disposition: !!!ERROR!!!" );						break;					}					//Draw the text					NDebugOverlay::EntityText( aimTarget->entindex(), text_offset, tempstr, 0 );				}				//See if we hates it				if ( dis == D_LI  )				{					//We're over a friendly, drop our weapon					if ( Weapon_Lower() == false )					{						//FIXME: We couldn't lower our weapon!					}					return;				}			}		}		if ( Weapon_Ready() == false )		{			//FIXME: We couldn't raise our weapon!		}	}	if( g_pGameRules->GetAutoAimMode() != AUTOAIM_NONE )	{		if( !pWeapon )		{			// This tells the client to draw no crosshair			m_HL2Local.m_bWeaponLowered = true;			return;		}		else		{			if( !pWeapon->CanLower() && m_HL2Local.m_bWeaponLowered )				m_HL2Local.m_bWeaponLowered = false;		}		if( !m_AutoaimTimer.Expired() )			return;		m_AutoaimTimer.Set( .1 );		VPROF( "hl2_x360_aiming" );		// Call the autoaim code to update the local player data, which allows the client to update.		autoaim_params_t params;		params.m_vecAutoAimPoint.Init();		params.m_vecAutoAimDir.Init();		params.m_fScale = AUTOAIM_SCALE_DEFAULT;		params.m_fMaxDist = autoaim_max_dist.GetFloat();		GetAutoaimVector( params );		m_HL2Local.m_hAutoAimTarget.Set( params.m_hAutoAimEntity );		m_HL2Local.m_vecAutoAimPoint.Set( params.m_vecAutoAimPoint );		m_HL2Local.m_bAutoAimTarget = ( params.m_bAutoAimAssisting || params.m_bOnTargetNatural );		return;	}	else	{		// Make sure there's no residual autoaim target if the user changes the xbox_aiming convar on the fly.		m_HL2Local.m_hAutoAimTarget.Set(NULL);	}}//-----------------------------------------------------------------------------// Purpose: Lowers the weapon posture (for hovering over friendlies)// Output : Returns true on success, false on failure.//-----------------------------------------------------------------------------bool CHL2_Player::Weapon_Lower( void ){	VPROF( "CHL2_Player::Weapon_Lower" );	// Already lowered?	if ( m_HL2Local.m_bWeaponLowered )		return true;	m_HL2Local.m_bWeaponLowered = true;	CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>(GetActiveWeapon());	if ( pWeapon == NULL )		return false;	return pWeapon->Lower();}//-----------------------------------------------------------------------------// Purpose: Returns the weapon posture to normal// Output : Returns true on success, false on failure.//-----------------------------------------------------------------------------bool CHL2_Player::Weapon_Ready( void ){	VPROF( "CHL2_Player::Weapon_Ready" );	// Already ready?	if ( m_HL2Local.m_bWeaponLowered == false )		return true;	m_HL2Local.m_bWeaponLowered = false;	CBaseCombatWeapon *pWeapon = dynamic_cast<CBaseCombatWeapon *>(GetActiveWeapon());	if ( pWeapon == NULL )		return false;	return pWeapon->Ready();}//-----------------------------------------------------------------------------// Purpose: Returns whether or not we can switch to the given weapon.// Input  : pWeapon - //-----------------------------------------------------------------------------bool CHL2_Player::Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon ){	CBasePlayer *pPlayer = (CBasePlayer *)this;#if !defined( CLIENT_DLL )	IServerVehicle *pVehicle = pPlayer->GetVehicle();#else	IClientVehicle *pVehicle = pPlayer->GetVehicle();#endif	if (pVehicle && !pPlayer->UsingStandardWeaponsInVehicle())		return false;	if ( !pWeapon->HasAnyAmmo() && !GetAmmoCount( pWeapon->m_iPrimaryAmmoType ) )		return false;	if ( !pWeapon->CanDeploy() )		return false;	if ( GetActiveWeapon() )	{		if ( PhysCannonGetHeldEntity( GetActiveWeapon() ) == pWeapon && 			Weapon_OwnsThisType( pWeapon->GetClassname(), pWeapon->GetSubType()) )		{			return true;		}		if ( !GetActiveWeapon()->CanHolster() )			return false;	}	return true;}void CHL2_Player::PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize ){	// can't pick up what you're standing on	if ( GetGroundEntity() == pObject )		return;		if ( bLimitMassAndSize == true )	{		if ( CBasePlayer::CanPickupObject( pObject, 35, 128 ) == false )			 return;	}	// Can't be picked up if NPCs are on me	if ( pObject->HasNPCsOnIt() )		return;	PlayerPickupObject( this, pObject );}//-----------------------------------------------------------------------------// Purpose: // Output : CBaseEntity//-----------------------------------------------------------------------------bool CHL2_Player::IsHoldingEntity( CBaseEntity *pEnt ){	return PlayerPickupControllerIsHoldingEntity( m_hUseEntity, pEnt );}float CHL2_Player::GetHeldObjectMass( IPhysicsObject *pHeldObject ){	float mass = PlayerPickupGetHeldObjectMass( m_hUseEntity, pHeldObject );	if ( mass == 0.0f )	{		mass = PhysCannonGetHeldObjectMass( GetActiveWeapon(), pHeldObject );	}	return mass;}CBaseEntity	*CHL2_Player::GetHeldObject( void ){	return PhysCannonGetHeldEntity( GetActiveWeapon() );}//-----------------------------------------------------------------------------// Purpose: Force the player to drop any physics objects he's carrying//-----------------------------------------------------------------------------void CHL2_Player::ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldingThis ){	if ( PhysIsInCallback() )	{		variant_t value;		g_EventQueue.AddEvent( this, "ForceDropPhysObjects", value, 0.01f, pOnlyIfHoldingThis, this );		return;	}#ifdef HL2_EPISODIC	if ( hl2_episodic.GetBool() )	{		CBaseEntity *pHeldEntity = PhysCannonGetHeldEntity( GetActiveWeapon() );		if( pHeldEntity && pHeldEntity->ClassMatches( "grenade_helicopter" ) )		{			return;		}	}#endif	// Drop any objects being handheld.	ClearUseEntity();	// Then force the physcannon to drop anything it's holding, if it's our active weapon	PhysCannonForceDrop( GetActiveWeapon(), NULL );}void CHL2_Player::InputForceDropPhysObjects( inputdata_t &data ){	ForceDropOfCarriedPhysObjects( data.pActivator );}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void CHL2_Player::UpdateClientData( void ){	if (m_DmgTake || m_DmgSave || m_bitsHUDDamage != m_bitsDamageType)	{		// Comes from inside me if not set		Vector damageOrigin = GetLocalOrigin();		// send "damage" message		// causes screen to flash, and pain compass to show direction of damage		damageOrigin = m_DmgOrigin;		// only send down damage type that have hud art		int iShowHudDamage = g_pGameRules->Damage_GetShowOnHud();		int visibleDamageBits = m_bitsDamageType & iShowHudDamage;		m_DmgTake = clamp( m_DmgTake, 0, 255 );		m_DmgSave = clamp( m_DmgSave, 0, 255 );		// If we're poisoned, but it wasn't this frame, don't send the indicator		// Without this check, any damage that occured to the player while they were		// recovering from a poison bite would register as poisonous as well and flash		// the whole screen! -- jdw		if ( visibleDamageBits & DMG_POISON )		{			float flLastPoisonedDelta = gpGlobals->curtime - m_tbdPrev;			if ( flLastPoisonedDelta > 0.1f )			{				visibleDamageBits &= ~DMG_POISON;			}		}		CSingleUserRecipientFilter user( this );		user.MakeReliable();		UserMessageBegin( user, "Damage" );			WRITE_BYTE( m_DmgSave );			WRITE_BYTE( m_DmgTake );			WRITE_LONG( visibleDamageBits );			WRITE_FLOAT( damageOrigin.x );	//BUG: Should be fixed point (to hud) not floats			WRITE_FLOAT( damageOrigin.y );	//BUG: However, the HUD does _not_ implement bitfield messages (yet)			WRITE_FLOAT( damageOrigin.z );	//BUG: We use WRITE_VEC3COORD for everything else		MessageEnd();			m_DmgTake = 0;		m_DmgSave = 0;		m_bitsHUDDamage = m_bitsDamageType;				// Clear off non-time-based damage indicators		int iTimeBasedDamage = g_pGameRules->Damage_GetTimeBased();		m_bitsDamageType &= iTimeBasedDamage;	}	// Update Flashlight#ifdef HL2_EPISODIC	if ( Flashlight_UseLegacyVersion() == false )	{		if ( FlashlightIsOn() && sv_infinite_aux_power.GetBool() == false )		{			m_HL2Local.m_flFlashBattery -= FLASH_DRAIN_TIME * gpGlobals->frametime;			if ( m_HL2Local.m_flFlashBattery < 0.0f )			{				FlashlightTurnOff();				m_HL2Local.m_flFlashBattery = 0.0f;			}		}		else		{			m_HL2Local.m_flFlashBattery += FLASH_CHARGE_TIME * gpGlobals->frametime;			if ( m_HL2Local.m_flFlashBattery > 100.0f )			{				m_HL2Local.m_flFlashBattery = 100.0f;			}		}	}	else	{		m_HL2Local.m_flFlashBattery = -1.0f;	}#endif // HL2_EPISODIC	BaseClass::UpdateClientData();}//---------------------------------------------------------//---------------------------------------------------------void CHL2_Player::OnRestore(){	BaseClass::OnRestore();	m_pPlayerAISquad = g_AI_SquadManager.FindCreateSquad(AllocPooledString(PLAYER_SQUADNAME));}//---------------------------------------------------------//---------------------------------------------------------Vector CHL2_Player::EyeDirection2D( void ){	Vector vecReturn = EyeDirection3D();	vecReturn.z = 0;	vecReturn.AsVector2D().NormalizeInPlace();	return vecReturn;}//---------------------------------------------------------//---------------------------------------------------------Vector CHL2_Player::EyeDirection3D( void ){	Vector vecForward;	// Return the vehicle angles if we request them	if ( GetVehicle() != NULL )	{		CacheVehicleView();		EyeVectors( &vecForward );		return vecForward;	}		AngleVectors( EyeAngles(), &vecForward );	return vecForward;}//---------------------------------------------------------//---------------------------------------------------------bool CHL2_Player::Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex ){	MDLCACHE_CRITICAL_SECTION();	// Recalculate proficiency!	SetCurrentWeaponProficiency( CalcWeaponProficiency( pWeapon ) );	// Come out of suit zoom mode	if ( IsZooming() )	{		StopZooming();	}	return BaseClass::Weapon_Switch( pWeapon, viewmodelindex );}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------WeaponProficiency_t CHL2_Player::CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ){	WeaponProficiency_t proficiency;	proficiency = WEAPON_PROFICIENCY_PERFECT;	if( weapon_showproficiency.GetBool() != 0 )	{		Msg("Player switched to %s, proficiency is %s\n", pWeapon->GetClassname(), GetWeaponProficiencyName( proficiency ) );	}	return proficiency;}//-----------------------------------------------------------------------------// Purpose: override how single player rays hit the player//-----------------------------------------------------------------------------bool LineCircleIntersection(	const Vector2D &center,	const float radius,	const Vector2D &vLinePt,	const Vector2D &vLineDir,	float *fIntersection1,	float *fIntersection2){	// Line = P + Vt	// Sphere = r (assume we've translated to origin)	// (P + Vt)^2 = r^2	// VVt^2 + 2PVt + (PP - r^2)	// Solve as quadratic:  (-b  +/-  sqrt(b^2 - 4ac)) / 2a	// If (b^2 - 4ac) is < 0 there is no solution.	// If (b^2 - 4ac) is = 0 there is one solution (a case this function doesn't support).	// If (b^2 - 4ac) is > 0 there are two solutions.	Vector2D P;	float a, b, c, sqr, insideSqr;	// Translate circle to origin.	P[0] = vLinePt[0] - center[0];	P[1] = vLinePt[1] - center[1];		a = vLineDir.Dot(vLineDir);	b = 2.0f * P.Dot(vLineDir);	c = P.Dot(P) - (radius * radius);	insideSqr = b*b - 4*a*c;	if(insideSqr <= 0.000001f)		return false;	// Ok, two solutions.	sqr = (float)FastSqrt(insideSqr);	float denom = 1.0 / (2.0f * a);		*fIntersection1 = (-b - sqr) * denom;	*fIntersection2 = (-b + sqr) * denom;	return true;}static void Collision_ClearTrace( const Vector &vecRayStart, const Vector &vecRayDelta, CBaseTrace *pTrace ){	pTrace->startpos = vecRayStart;	pTrace->endpos = vecRayStart;	pTrace->endpos += vecRayDelta;	pTrace->startsolid = false;	pTrace->allsolid = false;	pTrace->fraction = 1.0f;	pTrace->contents = 0;}bool IntersectRayWithAACylinder( const Ray_t &ray, 	const Vector &center, float radius, float height, CBaseTrace *pTrace ){	Assert( ray.m_IsRay );	Collision_ClearTrace( ray.m_Start, ray.m_Delta, pTrace );	// First intersect the ray with the top + bottom planes	float halfHeight = height * 0.5;	// Handle parallel case	Vector vStart = ray.m_Start - center;	Vector vEnd = vStart + ray.m_Delta;	float flEnterFrac, flLeaveFrac;	if (FloatMakePositive(ray.m_Delta.z) < 1e-8)	{		if ( (vStart.z < -halfHeight) || (vStart.z > halfHeight) )		{			return false; // no hit		}		flEnterFrac = 0.0f; flLeaveFrac = 1.0f;	}	else	{		// Clip the ray to the top and bottom of box		flEnterFrac = IntersectRayWithAAPlane( vStart, vEnd, 2, 1, halfHeight);		flLeaveFrac = IntersectRayWithAAPlane( vStart, vEnd, 2, 1, -halfHeight);		if ( flLeaveFrac < flEnterFrac )		{			float temp = flLeaveFrac;			flLeaveFrac = flEnterFrac;			flEnterFrac = temp;		}		if ( flLeaveFrac < 0 || flEnterFrac > 1)		{			return false;		}	}	// Intersect with circle	float flCircleEnterFrac, flCircleLeaveFrac;	if ( !LineCircleIntersection( vec3_origin.AsVector2D(), radius,		vStart.AsVector2D(), ray.m_Delta.AsVector2D(), &flCircleEnterFrac, &flCircleLeaveFrac ) )	{		return false; // no hit	}	Assert( flCircleEnterFrac <= flCircleLeaveFrac );	if ( flCircleLeaveFrac < 0 || flCircleEnterFrac > 1)	{		return false;	}	if ( flEnterFrac < flCircleEnterFrac )		flEnterFrac = flCircleEnterFrac;	if ( flLeaveFrac > flCircleLeaveFrac )		flLeaveFrac = flCircleLeaveFrac;	if ( flLeaveFrac < flEnterFrac )		return false;	VectorMA( ray.m_Start, flEnterFrac , ray.m_Delta, pTrace->endpos );	pTrace->fraction = flEnterFrac;	pTrace->contents = CONTENTS_SOLID;	// Calculate the point on our center line where we're nearest the intersection point	Vector collisionCenter;	CalcClosestPointOnLineSegment( pTrace->endpos, center + Vector( 0, 0, halfHeight ), center - Vector( 0, 0, halfHeight ), collisionCenter );		// Our normal is the direction from that center point to the intersection point	pTrace->plane.normal = pTrace->endpos - collisionCenter;	VectorNormalize( pTrace->plane.normal );	return true;}bool CHL2_Player::TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr ){	if( g_pGameRules->IsMultiplayer() )	{		return BaseClass::TestHitboxes( ray, fContentsMask, tr );	}	else	{		Assert( ray.m_IsRay );		Vector mins, maxs;		mins = WorldAlignMins();		maxs = WorldAlignMaxs();		if ( IntersectRayWithAACylinder( ray, WorldSpaceCenter(), maxs.x * PLAYER_HULL_REDUCTION, maxs.z - mins.z, &tr ) )		{			tr.hitbox = 0;			CStudioHdr *pStudioHdr = GetModelPtr( );			if (!pStudioHdr)				return false;			mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( m_nHitboxSet );			if ( !set || !set->numhitboxes )				return false;			mstudiobbox_t *pbox = set->pHitbox( tr.hitbox );			mstudiobone_t *pBone = pStudioHdr->pBone(pbox->bone);			tr.surface.name = "**studio**";			tr.surface.flags = SURF_HITBOX;			tr.surface.surfaceProps = physprops->GetSurfaceIndex( pBone->pszSurfaceProp() );		}				return true;	}}//---------------------------------------------------------// Show the player's scaled down bbox that we use for// bullet impacts.//---------------------------------------------------------void CHL2_Player::DrawDebugGeometryOverlays(void) {	BaseClass::DrawDebugGeometryOverlays();	if (m_debugOverlays & OVERLAY_BBOX_BIT) 	{			Vector mins, maxs;		mins = WorldAlignMins();		maxs = WorldAlignMaxs();		mins.x *= PLAYER_HULL_REDUCTION;		mins.y *= PLAYER_HULL_REDUCTION;		maxs.x *= PLAYER_HULL_REDUCTION;		maxs.y *= PLAYER_HULL_REDUCTION;		NDebugOverlay::Box( GetAbsOrigin(), mins, maxs, 255, 0, 0, 100, 0 );	}}//-----------------------------------------------------------------------------// Purpose: Helper to remove from ladder//-----------------------------------------------------------------------------void CHL2_Player::ExitLadder(){	if ( MOVETYPE_LADDER != GetMoveType() )		return;		SetMoveType( MOVETYPE_WALK );	SetMoveCollide( MOVECOLLIDE_DEFAULT );	// Remove from ladder	m_HL2Local.m_hLadder.Set( NULL );}surfacedata_t *CHL2_Player::GetLadderSurface( const Vector &origin ){	extern const char *FuncLadder_GetSurfaceprops(CBaseEntity *pLadderEntity);	CBaseEntity *pLadder = m_HL2Local.m_hLadder.Get();	if ( pLadder )	{		const char *pSurfaceprops = FuncLadder_GetSurfaceprops(pLadder);		// get ladder material from func_ladder		return physprops->GetSurfaceData( physprops->GetSurfaceIndex( pSurfaceprops ) );	}	return BaseClass::GetLadderSurface(origin);}//-----------------------------------------------------------------------------// Purpose: Queues up a use deny sound, played in ItemPostFrame.//-----------------------------------------------------------------------------void CHL2_Player::PlayUseDenySound(){	m_bPlayUseDenySound = true;}void CHL2_Player::ItemPostFrame(){	BaseClass::ItemPostFrame();	if ( m_bPlayUseDenySound )	{		m_bPlayUseDenySound = false;		EmitSound( "HL2Player.UseDeny" );	}}void CHL2_Player::StartWaterDeathSounds( void ){	CPASAttenuationFilter filter( this );	if ( m_sndLeeches == NULL )	{		m_sndLeeches = (CSoundEnvelopeController::GetController()).SoundCreate( filter, entindex(), CHAN_STATIC, "coast.leech_bites_loop" , ATTN_NORM );	}	if ( m_sndLeeches )	{		(CSoundEnvelopeController::GetController()).Play( m_sndLeeches, 1.0f, 100 );	}	if ( m_sndWaterSplashes == NULL )	{		m_sndWaterSplashes = (CSoundEnvelopeController::GetController()).SoundCreate( filter, entindex(), CHAN_STATIC, "coast.leech_water_churn_loop" , ATTN_NORM );	}	if ( m_sndWaterSplashes )	{		(CSoundEnvelopeController::GetController()).Play( m_sndWaterSplashes, 1.0f, 100 );	}}void CHL2_Player::StopWaterDeathSounds( void ){	if ( m_sndLeeches )	{		(CSoundEnvelopeController::GetController()).SoundFadeOut( m_sndLeeches, 0.5f, true );		m_sndLeeches = NULL;	}	if ( m_sndWaterSplashes )	{		(CSoundEnvelopeController::GetController()).SoundFadeOut( m_sndWaterSplashes, 0.5f, true );		m_sndWaterSplashes = NULL;	}}//-----------------------------------------------------------------------------// //-----------------------------------------------------------------------------void CHL2_Player::MissedAR2AltFire(){	if( GetPlayerProxy() != NULL )	{		GetPlayerProxy()->m_PlayerMissedAR2AltFire.FireOutput( this, this );	}}//-----------------------------------------------------------------------------////-----------------------------------------------------------------------------void CHL2_Player::DisplayLadderHudHint(){#if !defined( CLIENT_DLL )	if( gpGlobals->curtime > m_flTimeNextLadderHint )	{		m_flTimeNextLadderHint = gpGlobals->curtime + 60.0f;		CFmtStr hint;		hint.sprintf( "#Valve_Hint_Ladder" );		UTIL_HudHintText( this, hint.Access() );	}#endif//CLIENT_DLL}//-----------------------------------------------------------------------------// Shuts down sounds//-----------------------------------------------------------------------------void CHL2_Player::StopLoopingSounds( void ){	if ( m_sndLeeches != NULL )	{		 (CSoundEnvelopeController::GetController()).SoundDestroy( m_sndLeeches );		 m_sndLeeches = NULL;	}	if ( m_sndWaterSplashes != NULL )	{		 (CSoundEnvelopeController::GetController()).SoundDestroy( m_sndWaterSplashes );		 m_sndWaterSplashes = NULL;	}	BaseClass::StopLoopingSounds();}//-----------------------------------------------------------------------------void CHL2_Player::ModifyOrAppendPlayerCriteria( AI_CriteriaSet& set ){	BaseClass::ModifyOrAppendPlayerCriteria( set );	if ( GlobalEntity_GetIndex( "gordon_precriminal" ) == -1 )	{		set.AppendCriteria( "gordon_precriminal", "0" );	}}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------const impactdamagetable_t &CHL2_Player::GetPhysicsImpactDamageTable(){	if ( m_bUseCappedPhysicsDamageTable )		return gCappedPlayerImpactDamageTable;		return BaseClass::GetPhysicsImpactDamageTable();}//-----------------------------------------------------------------------------// Purpose: Makes a splash when the player transitions between water states//-----------------------------------------------------------------------------void CHL2_Player::Splash( void ){	CEffectData data;	data.m_fFlags = 0;	data.m_vOrigin = GetAbsOrigin();	data.m_vNormal = Vector(0,0,1);	data.m_vAngles = QAngle( 0, 0, 0 );		if ( GetWaterType() & CONTENTS_SLIME )	{		data.m_fFlags |= FX_WATER_IN_SLIME;	}	float flSpeed = GetAbsVelocity().Length();	if ( flSpeed < 300 )	{		data.m_flScale = random->RandomFloat( 10, 12 );		DispatchEffect( "waterripple", data );	}	else	{		data.m_flScale = random->RandomFloat( 6, 8 );		DispatchEffect( "watersplash", data );	}}CLogicPlayerProxy *CHL2_Player::GetPlayerProxy( void ){	CLogicPlayerProxy *pProxy = dynamic_cast< CLogicPlayerProxy* > ( m_hPlayerProxy.Get() );	if ( pProxy == NULL )	{		pProxy = (CLogicPlayerProxy*)gEntList.FindEntityByClassname(NULL, "logic_playerproxy" );		if ( pProxy == NULL )			return NULL;		pProxy->m_hPlayer = this;		m_hPlayerProxy = pProxy;	}	return pProxy;}void CHL2_Player::FirePlayerProxyOutput( const char *pszOutputName, variant_t variant, CBaseEntity *pActivator, CBaseEntity *pCaller ){	if ( GetPlayerProxy() == NULL )		return;	GetPlayerProxy()->FireNamedOutput( pszOutputName, variant, pActivator, pCaller );}LINK_ENTITY_TO_CLASS( logic_playerproxy, CLogicPlayerProxy);BEGIN_DATADESC( CLogicPlayerProxy )	DEFINE_OUTPUT( m_OnFlashlightOn, "OnFlashlightOn" ),	DEFINE_OUTPUT( m_OnFlashlightOff, "OnFlashlightOff" ),	DEFINE_OUTPUT( m_RequestedPlayerHealth, "PlayerHealth" ),	DEFINE_OUTPUT( m_PlayerHasAmmo, "PlayerHasAmmo" ),	DEFINE_OUTPUT( m_PlayerHasNoAmmo, "PlayerHasNoAmmo" ),	DEFINE_OUTPUT( m_PlayerDied,	"PlayerDied" ),	DEFINE_OUTPUT( m_PlayerMissedAR2AltFire, "PlayerMissedAR2AltFire" ),	DEFINE_INPUTFUNC( FIELD_VOID,	"RequestPlayerHealth",	InputRequestPlayerHealth ),	DEFINE_INPUTFUNC( FIELD_VOID,	"SetFlashlightSlowDrain",	InputSetFlashlightSlowDrain ),	DEFINE_INPUTFUNC( FIELD_VOID,	"SetFlashlightNormalDrain",	InputSetFlashlightNormalDrain ),	DEFINE_INPUTFUNC( FIELD_INTEGER, "SetPlayerHealth",	InputSetPlayerHealth ),	DEFINE_INPUTFUNC( FIELD_VOID,	"RequestAmmoState", InputRequestAmmoState ),	DEFINE_INPUTFUNC( FIELD_VOID,	"LowerWeapon", InputLowerWeapon ),	DEFINE_INPUTFUNC( FIELD_VOID,	"EnableCappedPhysicsDamage", InputEnableCappedPhysicsDamage ),	DEFINE_INPUTFUNC( FIELD_VOID,	"DisableCappedPhysicsDamage", InputDisableCappedPhysicsDamage ),	DEFINE_INPUTFUNC( FIELD_STRING,	"SetLocatorTargetEntity", InputSetLocatorTargetEntity ),	DEFINE_FIELD( m_hPlayer, FIELD_EHANDLE ),END_DATADESC()void CLogicPlayerProxy::Activate( void ){	BaseClass::Activate();	if ( m_hPlayer == NULL )	{		m_hPlayer = UTIL_GetLocalPlayer();	}}bool CLogicPlayerProxy::PassesDamageFilter( const CTakeDamageInfo &info ){	if (m_hDamageFilter)	{		CBaseFilter *pFilter = (CBaseFilter *)(m_hDamageFilter.Get());		return pFilter->PassesDamageFilter(info);	}	return true;}void CLogicPlayerProxy::InputSetPlayerHealth( inputdata_t &inputdata ){	if ( m_hPlayer == NULL )		return;	m_hPlayer->SetHealth( inputdata.value.Int() );}void CLogicPlayerProxy::InputRequestPlayerHealth( inputdata_t &inputdata ){	if ( m_hPlayer == NULL )		return;	m_RequestedPlayerHealth.Set( m_hPlayer->GetHealth(), inputdata.pActivator, inputdata.pCaller );}void CLogicPlayerProxy::InputSetFlashlightSlowDrain( inputdata_t &inputdata ){	if( m_hPlayer == NULL )		return;	CHL2_Player *pPlayer = dynamic_cast<CHL2_Player*>(m_hPlayer.Get());	if( pPlayer )		pPlayer->SetFlashlightPowerDrainScale( hl2_darkness_flashlight_factor.GetFloat() );}void CLogicPlayerProxy::InputSetFlashlightNormalDrain( inputdata_t &inputdata ){	if( m_hPlayer == NULL )		return;	CHL2_Player *pPlayer = dynamic_cast<CHL2_Player*>(m_hPlayer.Get());	if( pPlayer )		pPlayer->SetFlashlightPowerDrainScale( 1.0f );}void CLogicPlayerProxy::InputRequestAmmoState( inputdata_t &inputdata ){	if( m_hPlayer == NULL )		return;	CHL2_Player *pPlayer = dynamic_cast<CHL2_Player*>(m_hPlayer.Get());	for ( int i = 0 ; i < pPlayer->WeaponCount(); ++i )	{		CBaseCombatWeapon* pCheck = pPlayer->GetWeapon( i );		if ( pCheck )		{			if ( pCheck->HasAnyAmmo() && (pCheck->UsesPrimaryAmmo() || pCheck->UsesSecondaryAmmo()))			{				m_PlayerHasAmmo.FireOutput( this, this, 0 );				return;			}		}	}	m_PlayerHasNoAmmo.FireOutput( this, this, 0 );}void CLogicPlayerProxy::InputLowerWeapon( inputdata_t &inputdata ){	if( m_hPlayer == NULL )		return;	CHL2_Player *pPlayer = dynamic_cast<CHL2_Player*>(m_hPlayer.Get());	pPlayer->Weapon_Lower();}void CLogicPlayerProxy::InputEnableCappedPhysicsDamage( inputdata_t &inputdata ){	if( m_hPlayer == NULL )		return;	CHL2_Player *pPlayer = dynamic_cast<CHL2_Player*>(m_hPlayer.Get());	pPlayer->EnableCappedPhysicsDamage();}void CLogicPlayerProxy::InputDisableCappedPhysicsDamage( inputdata_t &inputdata ){	if( m_hPlayer == NULL )		return;	CHL2_Player *pPlayer = dynamic_cast<CHL2_Player*>(m_hPlayer.Get());	pPlayer->DisableCappedPhysicsDamage();}void CLogicPlayerProxy::InputSetLocatorTargetEntity( inputdata_t &inputdata ){	if( m_hPlayer == NULL )		return;	CBaseEntity *pTarget = NULL; // assume no target	string_t iszTarget = MAKE_STRING( inputdata.value.String() );	if( iszTarget != NULL_STRING )	{		pTarget = gEntList.FindEntityByName( NULL, iszTarget );	}	CHL2_Player *pPlayer = dynamic_cast<CHL2_Player*>(m_hPlayer.Get());	pPlayer->SetLocatorTargetEntity(pTarget);}