//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFFlareGun::LaunchProjectile(void)
{
	// Get the player owning the weapon.
	CTFPlayer *pPlayer = ToTFPlayer(GetPlayerOwner());
	if (!pPlayer)
		return;

	CalcIsAttackCritical();

	SendWeaponAnim(ACT_VM_PRIMARYATTACK);

	pPlayer->SetAnimation(PLAYER_ATTACK1);
	pPlayer->DoAnimationEvent(PLAYERANIMEVENT_ATTACK_PRIMARY);

	FireProjectile(pPlayer);

#if !defined( CLIENT_DLL ) 
	pPlayer->SpeakWeaponFire();
	CTF_GameStats.Event_PlayerFiredWeapon(pPlayer, IsCurrentAttackACrit());
#endif

	// Set next attack times.
	m_flNextPrimaryAttack = gpGlobals->curtime + m_pWeaponInfo->GetWeaponData(m_iWeaponMode).m_flTimeFireDelay;

	SetWeaponIdleTime(gpGlobals->curtime + SequenceDuration());

	// Check the reload mode and behave appropriately.
	if (m_bReloadsSingly)
	{
		m_iReloadMode.Set(TF_RELOAD_START);
	}
}
void CTFBotVision::Update()
{
	if (TFGameRules()->IsMannVsMachineMode()) {
		if (!this->m_ctUpdate.IsElapsed()) {
			return;
		}
		
		this->m_ctUpdate.Start(RandomFloat(0.9f, 1.1f));
	}
	
	IVision::Update();
	
	CTFBot *actor = static_cast<CTFBot *>(this->GetBot()->GetEntity());
	if (actor == nullptr) {
		return;
	}
	
	CUtlVector<CTFPlayer *> enemies;
	CollectPlayers<CTFPlayer>(enemies, GetEnemyTeam(actor), true, false);
	
	FOR_EACH_VEC(enemies, i) {
		CTFPlayer *enemy = enemies[i];
		
		if (enemy->IsPlayerClass(TF_CLASS_SPY)) {
			const CKnownEntity *known = this->GetKnown(enemy);
			
			if (known != nullptr && (known->IsVisibleRecently() ||
				!player->m_Shared.InCond(TF_COND_DISGUISING))) {
				actor->ForgetSpy(enemy);
			}
		}
	}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int CTFViewModel::GetSkin()
{
    int nSkin = BaseClass::GetSkin();

    CTFWeaponBase *pWeapon = ( CTFWeaponBase * )GetOwningWeapon();

    if ( !pWeapon )
        return nSkin;

    CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
    if ( pPlayer )
    {
        if ( pWeapon->GetTFWpnData().m_bHasTeamSkins_Viewmodel )
        {
            switch( pPlayer->GetTeamNumber() )
            {
            case TF_TEAM_RED:
                nSkin = 0;
                break;
            case TF_TEAM_BLUE:
                nSkin = 1;
                break;
            case TF_TEAM_GREEN:
                nSkin = 2;
                break;
            case TF_TEAM_YELLOW:
                nSkin = 3;
                break;
            }
        }
    }

    return nSkin;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFPlayerResource::UpdatePlayerData( void )
{
	int i;

	BaseClass::UpdatePlayerData();

	for ( i = 1 ; i <= gpGlobals->maxClients; i++ )
	{
		CTFPlayer *pPlayer = (CTFPlayer*)UTIL_PlayerByIndex( i );
		
		if ( pPlayer && pPlayer->IsConnected() )
		{			
			PlayerStats_t *pPlayerStats = CTF_GameStats.FindPlayerStats( pPlayer );
			if ( pPlayerStats ) 
			{
			m_iMaxHealth.Set( i, pPlayer->GetPlayerClass()->GetMaxHealth() );
			m_iPlayerClass.Set( i, pPlayer->GetPlayerClass()->GetClassIndex() );
			int iTotalScore = CTFGameRules::CalcPlayerScore( &pPlayerStats->statsAccumulated );
			m_iTotalScore.Set( i, iTotalScore );

			Vector vecColor = pPlayer->m_vecPlayerColor;
			m_iColors.Set(i, Vector(vecColor.x, vecColor.y, vecColor.z));
			//Msg("Server %f %f %f\n", m_iColors.Get(i).x, m_iColors.Get(i).y, m_iColors.Get(i).z);

			m_iKillstreak.Set(i, pPlayer->m_Shared.GetKillstreak());
			}					
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: only called for local player
//-----------------------------------------------------------------------------
void C_TFWeaponBuilder::Redraw()
{
	if ( m_iValidBuildPoseParam >= 0 )
	{
		CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
		if ( !pOwner )
			return;

		// Assuming here that our model is the same as our viewmodel's model!
		CBaseViewModel *pViewModel = pOwner->GetViewModel(0);

		if ( pViewModel )
		{
			float flPoseParamValue = pViewModel->GetPoseParameter( m_iValidBuildPoseParam );

			C_BaseObject *pObj = m_hObjectBeingBuilt.Get();

			if ( pObj && pObj->WasLastPlacementPosValid() )
			{
				// pose param approach 1.0
				flPoseParamValue = Approach( 1.0, flPoseParamValue, 3.0 * gpGlobals->frametime );
			}
			else
			{
				// pose param approach 0.0
				flPoseParamValue = Approach( 0.0, flPoseParamValue, 1.5 * gpGlobals->frametime );
			}

			pViewModel->SetPoseParameter( m_iValidBuildPoseParam, flPoseParamValue );
		}
	}

	BaseClass::Redraw();
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHudMenuSpyDisguise::FireGameEvent( IGameEvent *event )
{
	const char * type = event->GetName();

	if ( Q_strcmp(type, "spy_pda_reset") == 0 )
	{
		CTFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
		if ( pPlayer )
		{
			bool bShowBlue = ( pPlayer->GetTeamNumber() == TF_TEAM_RED );

			for ( int i=0; i<9; i++ )
			{
				m_pClassItems_Red[i]->SetVisible( !bShowBlue );
				m_pClassItems_Blue[i]->SetVisible( bShowBlue );
			}

			m_iShowingTeam = ( bShowBlue ) ? TF_TEAM_BLUE : TF_TEAM_RED;
		}
	}
	else
	{
		CHudElement::FireGameEvent( event );
	}
}
Beispiel #7
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CChangeClassZone::Touch( CBaseEntity *pOther )
{
    if ( !IsDisabled() )
    {
        CTFPlayer *pPlayer = ToTFPlayer( pOther );
        if ( pPlayer )
        {
            if ( pPlayer->GetNextChangeClassTime() > gpGlobals->curtime )
                return;

            int iTeam = GetTeamNumber();
            if ( iTeam && ( pPlayer->GetTeamNumber() != iTeam ) )
                return;

            // bring up the player's changeclass menu
            CCommand args;
            args.Tokenize( "changeclass" );
            pPlayer->ClientCommand( args );
            pPlayer->SetNextChangeClassTime( gpGlobals->curtime + TF_CHANGECLASS_NEXT_USE_TIME );

            CPASAttenuationFilter filter( pOther, TF_CHANGECLASS_SOUND );
            EmitSound( filter, pOther->entindex(), TF_CHANGECLASS_SOUND );
        }
    }
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFSniperRifle::ZoomOut( void )
{
	BaseClass::ZoomOut();

	// Stop aiming
	CTFPlayer *pPlayer = GetTFPlayerOwner();

	if ( !pPlayer )
		return;

	pPlayer->m_Shared.RemoveCond( TF_COND_AIMING );
	pPlayer->TeamFortress_SetSpeed();

#ifdef GAME_DLL
	// Destroy the sniper dot.
	DestroySniperDot();
	pPlayer->ClearExpression();
#endif

	// if we are thinking about zooming, cancel it
	m_flUnzoomTime = -1;
	m_flRezoomTime = -1;
	m_bRezoomAfterShot = false;
	m_flChargedDamage = 0.0f;	
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFWeaponBaseGun::ItemPostFrame( void )
{
	int iOldBurstSize = m_iBurstSize;
	CTFPlayer *pOwner = GetTFPlayerOwner();
	if ( pOwner )
	{
		if ( m_iBurstSize > 0 )
		{
			// Fake the fire button.
			pOwner->m_nButtons |= IN_ATTACK;
		}
	}

	BaseClass::ItemPostFrame();

	// Stop burst if we run out of ammo.
	if ( ( UsesClipsForAmmo1() && m_iClip1 <= 0 ) ||
		( !UsesClipsForAmmo1() && pOwner->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) ) 
	{
		m_iBurstSize = 0;
	}

	if ( iOldBurstSize > 0 && m_iBurstSize == 0 )
	{
		// Delay the next burst.
		m_flNextPrimaryAttack = gpGlobals->curtime + m_pWeaponInfo->GetWeaponData( TF_WEAPON_PRIMARY_MODE ).m_flBurstDelay;
	}
}
//-----------------------------------------------------------------------------
// Purpose: Player holding this weapon has started building something
// Assumes we are in a valid build position
//-----------------------------------------------------------------------------
void CTFWeaponBuilder::StartBuilding( void )
{
	CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
	CBaseObject *pObj = m_hObjectBeingBuilt.Get();

	if ( pPlayer && pPlayer->m_Shared.IsCarryingObject() )
	{
		Assert( pObj );

		pObj->RedeployBuilding( ToTFPlayer( GetOwner() ) );
		m_hObjectBeingBuilt = NULL;

		pPlayer->m_Shared.SetCarriedObject( NULL );
		return;
	}

	Assert( pObj );

	pObj->StartBuilding( GetOwner() );
	pObj->AddSpawnFlags( SF_OBJ_UPGRADABLE );

	m_hObjectBeingBuilt = NULL;

	if ( pPlayer )
	{
		pPlayer->RemoveInvisibility();
	}
}
// ---------------------------------------------------------------------------- -
// Purpose: 
//-----------------------------------------------------------------------------
void CTFCompoundBow::PrimaryAttack( void )
{
	if ( !CanAttack() )
	{
		m_flChargeBeginTime = 0;
		return;
	}

	if ( m_flChargeBeginTime <= 0 )
	{
		// Set the weapon mode.
		m_iWeaponMode = TF_WEAPON_PRIMARY_MODE;

		// save that we had the attack button down
		m_flChargeBeginTime = gpGlobals->curtime;

		SendWeaponAnim( ACT_ITEM2_VM_CHARGE );
		
		CTFPlayer *pOwner = GetTFPlayerOwner();
		if ( pOwner )
		{
			WeaponSound( SPECIAL1 );

			pOwner->m_Shared.AddCond( TF_COND_AIMING );
			pOwner->TeamFortress_SetSpeed();
		}
	}
}
Beispiel #12
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFMinigun::WindDown( void )
{
	// Get the player owning the weapon.
	CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
	if ( !pPlayer )
		return;

	SendWeaponAnim( ACT_MP_ATTACK_STAND_POSTFIRE );

	// Set the appropriate firing state.
	m_iWeaponState = AC_STATE_IDLE;
	pPlayer->m_Shared.RemoveCond( TF_COND_AIMING );
#ifdef CLIENT_DLL
	WeaponSoundUpdate();
#else
	pPlayer->ClearWeaponFireScene();
#endif

	// Time to weapon idle.
	m_flTimeWeaponIdle = gpGlobals->curtime + 2.0;

	// Update player's speed
	pPlayer->TeamFortress_SetSpeed();

#ifdef CLIENT_DLL
	m_flBarrelTargetVelocity = 0;
#endif
}
Beispiel #13
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input :
//-----------------------------------------------------------------------------
void CViewModelInvisProxy::OnBind( C_BaseEntity *pEnt )
{
	if ( !m_pPercentInvisible )
		return;

	if ( !pEnt )
		return;

	CTFViewModel *pVM = dynamic_cast<CTFViewModel *>( pEnt );
	if ( !pVM )
	{
		m_pPercentInvisible->SetFloatValue( 0.0f );
		return;
	}

	CTFPlayer *pPlayer = ToTFPlayer( pVM->GetOwner() );

	if ( !pPlayer )
	{
		m_pPercentInvisible->SetFloatValue( 0.0f );
		return;
	}

	float flPercentInvisible = pPlayer->GetPercentInvisible();

	// remap from 0.22 to 0.5
	// but drop to 0.0 if we're not invis at all
	float flWeaponInvis = ( flPercentInvisible < 0.01 ) ?
		0.0 :
		RemapVal( flPercentInvisible, 0.0, 1.0, tf_vm_min_invis.GetFloat(), tf_vm_max_invis.GetFloat() );

	m_pPercentInvisible->SetFloatValue( flWeaponInvis );
}
void CTFWeaponBuilder::SecondaryAttack( void )
{
	if ( m_bInAttack2 )
		return;

	// require a re-press
	m_bInAttack2 = true;

	CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
	if ( !pOwner )
		return;

	if ( pOwner->DoClassSpecialSkill() )
	{
		// intentionally blank
	}
	else if ( m_iBuildState == BS_PLACING )
	{
		if ( m_hObjectBeingBuilt )
		{
			pOwner->StopHintTimer( HINT_ALTFIRE_ROTATE_BUILDING );
			m_hObjectBeingBuilt->RotateBuildAngles();
		}
	}

	m_flNextSecondaryAttack = gpGlobals->curtime + 0.2f;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CTFWeaponBuilder::Deploy( void )
{
	bool bDeploy = BaseClass::Deploy();

	if ( bDeploy )
	{
		SetCurrentState( BS_PLACING );
		StartPlacement(); 
		m_flNextPrimaryAttack = gpGlobals->curtime + 0.35f;
		m_flNextSecondaryAttack = gpGlobals->curtime;		// asap

		CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
		if (!pPlayer)
			return false;

		pPlayer->SetNextAttack( gpGlobals->curtime );

		m_iWorldModelIndex = modelinfo->GetModelIndex( GetWorldModel() );

		m_flNextDenySound = 0;

		// Set off the hint here, because we don't know until now if our building
		// is rotate-able or not.
		if ( m_hObjectBeingBuilt && !m_hObjectBeingBuilt->MustBeBuiltOnAttachmentPoint() )
		{
			// set the alt-fire hint so it gets removed when we holster
			m_iAltFireHint = HINT_ALTFIRE_ROTATE_BUILDING;
			pPlayer->StartHintTimer( m_iAltFireHint );
		}
	}

	return bDeploy;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CTFWeaponBaseMelee::CalcIsAttackCriticalHelper( void )
{
	CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
	if ( !pPlayer )
		return false;

	int nCvarValue = tf_weapon_criticals_melee.GetInt();

	if ( nCvarValue == 0 )
		return false;

	if ( nCvarValue == 1 && !tf_weapon_criticals.GetBool() )
		return false;

	float flPlayerCritMult = pPlayer->GetCritMult();

	float flCritChance = TF_DAMAGE_CRIT_CHANCE_MELEE * flPlayerCritMult;
	CALL_ATTRIB_HOOK_FLOAT( flCritChance, mult_crit_chance );

	// If the chance is 0, just bail.
	if ( flCritChance == 0.0f )
		return false;

	return ( RandomInt( 0, WEAPON_RANDOM_RANGE-1 ) <= flCritChance * WEAPON_RANDOM_RANGE );
}
Beispiel #17
0
//-----------------------------------------------------------------------------
// Purpose:
// NOTE: Should this be put into fire gun
//-----------------------------------------------------------------------------
void CTFWeaponBaseGun::DoFireEffects()
{
	CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
	if ( !pPlayer )
		return;

	// Muzzle flash on weapon.
	bool bMuzzleFlash = true;

	// We no longer need this
	/*
	if ( pPlayer->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
	{
		//CTFWeaponBase *pWeapon = pPlayer->GetActiveTFWeapon();
		//if ( pWeapon && pWeapon->GetWeaponID() == TF_WEAPON_MINIGUN )
		if (pPlayer->IsActiveTFWeapon(TF_WEAPON_MINIGUN))
		{
			bMuzzleFlash = false;
		}
	}*/

	if ( bMuzzleFlash )
	{
		pPlayer->DoMuzzleFlash();
	}
}
Beispiel #18
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CFuncRespawnFlagZone::Touch( CBaseEntity *pOther )
{
	if (!IsDisabled())
	{
		CTFPlayer *pPlayer = ToTFPlayer(pOther);
		if ( pPlayer && pPlayer->HasTheFlag() )
		{
			CTFItem *pItem = pPlayer->GetItem();
			if (pItem)
			{
				CCaptureFlag *pFlag = dynamic_cast<CCaptureFlag*>(pItem);
				pPlayer->DropFlag();
				if (pFlag)
				{
					pFlag->Reset();
					pFlag->ResetMessage();
				}
			}
			else
			{
				pPlayer->DropFlag();
			}
		}
	}
}
Beispiel #19
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponMedigun::AddCharge( void )
{
#ifdef GAME_DLL
	CTFPlayer *pPlayer = GetTFPlayerOwner();
	CTFPlayer *pHealingTarget = ToTFPlayer( m_hHealingTarget );
#endif

	float flNewLevel = min( m_flChargeLevel + 0.25, 1.0 );

	if ( flNewLevel >= 1.0 && m_flChargeLevel < 1.0 )
	{
#ifdef GAME_DLL
		if ( pPlayer )
		{
			pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_MEDIC_CHARGEREADY );
		}

		if ( pHealingTarget )
		{
			pHealingTarget->SpeakConceptIfAllowed( MP_CONCEPT_HEALTARGET_CHARGEREADY );
		}
#endif
	}

	m_flChargeLevel = flNewLevel;
}
// ---------------------------------------------------------------------------- -
// Purpose: 
//-----------------------------------------------------------------------------
void CTFCompoundBow::FireArrow( void )
{
	// Get the player owning the weapon.
	CTFPlayer *pPlayer = GetTFPlayerOwner();
	if ( !pPlayer )
		return;

	CalcIsAttackCritical();

	SendWeaponAnim( ACT_VM_PRIMARYATTACK );

	pPlayer->SetAnimation( PLAYER_ATTACK1 );
	pPlayer->DoAnimationEvent( PLAYERANIMEVENT_ATTACK_PRIMARY );

	pPlayer->m_Shared.RemoveCond( TF_COND_AIMING );
	pPlayer->TeamFortress_SetSpeed();

	FireProjectile( pPlayer );

#if !defined( CLIENT_DLL ) 
	pPlayer->SpeakWeaponFire();
	CTF_GameStats.Event_PlayerFiredWeapon( pPlayer, IsCurrentAttackACrit() );
#endif

	// Set next attack times.
	float flDelay = m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_flTimeFireDelay;
	CALL_ATTRIB_HOOK_FLOAT( flDelay, mult_postfiredelay );
	m_flNextPrimaryAttack = gpGlobals->curtime + flDelay;

	SetWeaponIdleTime( gpGlobals->curtime + SequenceDuration() );

	m_flChargeBeginTime = 0.0f;
}
CObjectTeleporter* CObjectTeleporter::FindMatch( void )
{
	int iObjType = GetType();
	int iOppositeType = ( iObjType == OBJ_TELEPORTER_ENTRANCE ) ? OBJ_TELEPORTER_EXIT : OBJ_TELEPORTER_ENTRANCE;

	CObjectTeleporter *pMatch = NULL;

	CTFPlayer *pBuilder = GetBuilder();

	Assert( pBuilder );

	if ( !pBuilder )
	{
		return NULL;
	}

	int i;
	int iNumObjects = pBuilder->GetObjectCount();
	for ( i=0;i<iNumObjects;i++ )
	{
		CBaseObject *pObj = pBuilder->GetObject(i);

		if ( pObj && pObj->GetType() == iOppositeType && !pObj->IsDisabled() )
		{
			pMatch = ( CObjectTeleporter * )pObj;
			break;
		}
	}

	return pMatch;
}
Beispiel #22
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFMinigun::WindUp( void )
{
	// Get the player owning the weapon.
	CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
	if ( !pPlayer )
		return;

	// Play wind-up animation and sound (SPECIAL1).
	SendWeaponAnim( ACT_MP_ATTACK_STAND_PREFIRE );

	// Set the appropriate firing state.
	m_iWeaponState = AC_STATE_STARTFIRING;
	pPlayer->m_Shared.AddCond( TF_COND_AIMING );

#ifndef CLIENT_DLL
	pPlayer->StopRandomExpressions();
#endif

#ifdef CLIENT_DLL 
	WeaponSoundUpdate();
#endif


	// Update player's speed
	pPlayer->TeamFortress_SetSpeed();
}
Beispiel #23
0
	QueryResponse CTFBotMarkGiants::ShouldAttack(const INextBot *nextbot, const CKnownEntity *threat) const
	{
		CTFPlayer *player = ToTFPlayer(threat->GetEntity());
		if (player != nullptr && player->IsMiniBoss()) {
			return QueryResponse::YES;
		}
		
		return QueryResponse::NO;
	}
Beispiel #24
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponMedigun::MaintainTargetInSlot()
{
	CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() );
	if ( !pOwner )
		return;

	CBaseEntity *pTarget = m_hHealingTarget;
	Assert( pTarget );

	// Make sure the guy didn't go out of range.
	bool bLostTarget = true;
	Vector vecSrc = pOwner->Weapon_ShootPosition( );
	Vector vecTargetPoint = pTarget->WorldSpaceCenter();
	Vector vecPoint;

	// If it's brush built, use absmins/absmaxs
	pTarget->CollisionProp()->CalcNearestPoint( vecSrc, &vecPoint );

	float flDistance = (vecPoint - vecSrc).Length();
	if ( flDistance < GetStickRange() )
	{
		if ( m_flNextTargetCheckTime > gpGlobals->curtime )
			return;

		m_flNextTargetCheckTime = gpGlobals->curtime + 1.0f;

		trace_t tr;
		CMedigunFilter drainFilter( pOwner );

		Vector vecAiming;
		pOwner->EyeVectors( &vecAiming );

		Vector vecEnd = vecSrc + vecAiming * GetTargetRange();
		UTIL_TraceLine( vecSrc, vecEnd, (MASK_SHOT & ~CONTENTS_HITBOX), pOwner, DMG_GENERIC, &tr );

		// Still visible?
		if ( tr.m_pEnt == pTarget )
			return;

		UTIL_TraceLine( vecSrc, vecTargetPoint, MASK_SHOT, &drainFilter, &tr );

		// Still visible?
		if (( tr.fraction == 1.0f) || (tr.m_pEnt == pTarget))
			return;

		// If we failed, try the target's eye point as well
		UTIL_TraceLine( vecSrc, pTarget->EyePosition(), MASK_SHOT, &drainFilter, &tr );
		if (( tr.fraction == 1.0f) || (tr.m_pEnt == pTarget))
			return;
	}

	// We've lost this guy
	if ( bLostTarget )
	{
		RemoveHealingTarget();
	}
}
//-----------------------------------------------------------------------------
// Purpose: Return true if this weapon has some ammo
//-----------------------------------------------------------------------------
bool CTFWeaponBuilder::HasAmmo( void )
{
	CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
	if ( !pOwner )
		return false;

	int iCost = CalculateObjectCost( m_iObjectType );
	return ( pOwner->GetBuildResources() >= iCost );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CObjectTeleporter::TeleporterTouch( CBaseEntity *pOther )
{
	if ( IsDisabled() )
	{
		return;
	}

	// if it's not a player, ignore
	if ( !pOther->IsPlayer() )
		return;

	CTFPlayer *pPlayer = ToTFPlayer( pOther );

	CTFPlayer *pBuilder = GetBuilder();

	Assert( pBuilder );

	if ( !pBuilder )
	{
		return;
	}

	// if its not a teammate of the builder, notify the builder
	if ( pBuilder->GetTeamNumber() != pOther->GetTeamNumber() )
	{
		// Don't teleport enemies
		return;
	}

	// is this an entrance and do we have an exit?
	if ( GetType() == OBJ_TELEPORTER_ENTRANCE )
	{		
		if ( ( m_iState == TELEPORTER_STATE_READY ) )
		{
			// are we able to teleport?
			if ( pPlayer->HasTheFlag() )
			{
				// If they have the flag, print a warning that you can't tele with the flag
				CSingleUserRecipientFilter filter( pPlayer );
				TFGameRules()->SendHudNotification( filter, HUD_NOTIFY_NO_TELE_WITH_FLAG );
				return;
			}

			// get the velocity of the player touching the teleporter
			if ( pPlayer->GetAbsVelocity().Length() < 5.0 )
			{
				CObjectTeleporter *pDest = GetMatchingTeleporter();

				if ( pDest )
				{
					TeleporterSend( pPlayer );
				}
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::ComputeAmmoRatios( CItem_DynamicResupply* pMaster, CBasePlayer *pPlayer, int iDebug, SpawnInfo_t *pSpawnInfo )
{
#ifdef TF_CLASSIC
	// TF2 players don't use HL2 ammo and TF2 ammo packs are based on ratios so we act differently here.
	// We get player's lowest ammo ratio and compare it to the desired ratio.
	CTFPlayer *pTFPlayer = ToTFPlayer( pPlayer );
	float flLowestRatio = 1.0f;

	for ( int i = 1; i < TF_AMMO_GRENADES1; i++ )
	{
		float flMaxAmmo = pTFPlayer->GetPlayerClass()->GetData()->m_aAmmoMax[i];
		float flCurrentAmmo = pTFPlayer->GetAmmoCount( i );
		flLowestRatio = min( flLowestRatio, ( flCurrentAmmo / flMaxAmmo ) );
	}
#endif

	for ( int i = 0; i < NUM_AMMO_ITEMS; i++ )
	{
#ifdef TF_CLASSIC
		flLowestRatio += (pSpawnInfo[i].m_iPotentialItems * g_DynamicResupplyAmmoItems[i].flAmmoRatio);
		pSpawnInfo[i].m_flCurrentRatio = clamp( flLowestRatio, 0, 1 );;
#else
		// Get the ammodef's
		int iAmmoType = GetAmmoDef()->Index( g_DynamicResupplyAmmoItems[i].sAmmoDef );
		Assert( iAmmoType != -1 );

		// Ignore ammo types if we don't have a weapon that uses it (except for the grenade)
		if ( (i != DS_GRENADE_INDEX) && !pPlayer->Weapon_GetWpnForAmmo( iAmmoType ) )
		{
			pSpawnInfo[i].m_flCurrentRatio = 1.0;
		}
		else
		{
			float flMax = GetAmmoDef()->MaxCarry( iAmmoType );
			float flCurrentAmmo = pPlayer->GetAmmoCount( iAmmoType );
			flCurrentAmmo += (pSpawnInfo[i].m_iPotentialItems * g_DynamicResupplyAmmoItems[i].iAmmoCount);
			pSpawnInfo[i].m_flCurrentRatio = (flCurrentAmmo / flMax);
		}
#endif

		// Use the master if we're supposed to
		pSpawnInfo[i].m_flDesiredRatio = pMaster->m_flDesiredAmmo[i] * sk_dynamic_resupply_modifier.GetFloat();
		pSpawnInfo[i].m_flDelta = pSpawnInfo[i].m_flDesiredRatio - pSpawnInfo[i].m_flCurrentRatio;
		pSpawnInfo[i].m_flDelta = clamp( pSpawnInfo[i].m_flDelta, 0, 1 );
	}

	if ( iDebug )
	{
		Msg("Calculating desired ammo ratios & deltas:\n");
		for ( int i = 0; i < NUM_AMMO_ITEMS; i++ )
		{
			Msg("   %s Desired Ratio: %.2f, Current Ratio: %.2f = Delta of %.2f\n", 
				g_DynamicResupplyAmmoItems[i].sEntityName, pSpawnInfo[i].m_flDesiredRatio, pSpawnInfo[i].m_flCurrentRatio, pSpawnInfo[i].m_flDelta );
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CTFWeaponBaseMelee::CalcIsAttackCriticalHelper( void )
{
	CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() );
	if ( !pPlayer )
		return false;

	float flPlayerCritMult = pPlayer->GetCritMult();

	return ( RandomInt( 0, WEAPON_RANDOM_RANGE-1 ) <= ( TF_DAMAGE_CRIT_CHANCE_MELEE * flPlayerCritMult ) * WEAPON_RANDOM_RANGE );
}
//-----------------------------------------------------------------------------
// Purpose: Return true if this weapon can be selected via the weapon selection
//-----------------------------------------------------------------------------
bool C_TFWeaponBuilder::CanBeSelected( void )
{
	CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
	if ( !pOwner )
		return false;

	if ( pOwner->CanBuild( m_iObjectType ) != CB_CAN_BUILD )
		return false;

	return HasAmmo();
}
//-----------------------------------------------------------------------------
// Purpose: Gets a value from an array member
//-----------------------------------------------------------------------------
int CTFPlayerResource::GetTotalScore( int iIndex )
{
	CTFPlayer *pPlayer = (CTFPlayer*)UTIL_PlayerByIndex( iIndex );

	if ( pPlayer && pPlayer->IsConnected() )
	{	
		return m_iTotalScore[iIndex];
	}

	return 0;
}