//-----------------------------------------------------------------------------
// Purpose: Detach the player from the "Buff Station."
//-----------------------------------------------------------------------------
void CObjectBuffStation::DetachPlayerByIndex( int nIndex )
{
	// Valid index?
	Assert( nIndex < BUFF_STATION_MAX_PLAYERS );

	// Get the player.
	CBaseTFPlayer *pPlayer = m_hPlayers[nIndex].Get();
	if ( !pPlayer )
	{
		m_hPlayers.Set( nIndex, NULL );
		return;
	}

	// Remove the damage modifier.
	m_aPlayerAttachInfo[nIndex].m_DamageModifier.RemoveModifier();

	// Remove the rope (cable).
	if ( m_aPlayerAttachInfo[nIndex].m_hRope.Get() )
	{
		m_aPlayerAttachInfo[nIndex].m_hRope->DetachPoint( 1 );
		m_aPlayerAttachInfo[nIndex].m_hRope->DieAtNextRest();
	}

	// Unconstrain the player movement.
	pPlayer->DeactivateMovementConstraint();

	// Keep track of player events.
	g_pNotify->RemoveEntity( this, pPlayer );

	// Reduce player count.
	m_nPlayerCount--;
	m_hPlayers.Set( nIndex, NULL );
}
예제 #2
0
static bool IsValidFn_PlayersWantingAssist( void *pUserData, int a )
{
	CSortBase *pSortBase = (CSortBase*)pUserData;
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)pSortBase->m_pPlayer->GetTeam()->GetPlayer( a );

	if ( !pPlayer->IsAlive() )
	{
		// This guy sure could have used an assist but YOU'RE TOO SLOW!!!
		return false;
	}

	// Don't try to assist yourself...
	if ( pPlayer == pSortBase->m_pPlayer )
		return false;

	// Make sure this guy was shot recently.
	if ( (gpGlobals->curtime - pPlayer->LastTimeDamagedByEnemy()) > COMMANDO_ASSIST_SHOT_DELAY )
		return false;

	// Is the guy close enough?
	if ( pSortBase->m_pPlayer->GetAbsOrigin().DistToSqr( pPlayer->GetAbsOrigin() ) > COMMAND_ASSIST_DISTANCE_SQR )
		return false;

	return true;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CWeaponCombatBurstRifle::GetFireRate( void )
{	
	if ( !inv_demo.GetFloat() )
	{
		float flFireRate = ( SequenceDuration() * 0.6f ) + SHARED_RANDOMFLOAT( 0.0, 0.035f );

		CBaseTFPlayer *pPlayer = static_cast<CBaseTFPlayer*>( GetOwner() );
		if ( pPlayer )
		{
			// Ducking players should fire more rapidly.
			if ( pPlayer->GetFlags() & FL_DUCKING )
			{
				flFireRate *= weapon_combat_burstrifle_ducking_mod.GetFloat();
			}
		}
		
		return flFireRate;
	}

	// Get the player and check to see if we are powered up.
	CBaseTFPlayer *pPlayer = ( CBaseTFPlayer* )GetOwner();
	if ( pPlayer && pPlayer->HasPowerup( POWERUP_BOOST ) )
	{
		return BURSTRIFLE_BOOSTED_FIRERATE;
	}

	return SHARED_RANDOMFLOAT( 0.075f, 0.15f );
}
//-----------------------------------------------------------------------------
// New technologies: 
//-----------------------------------------------------------------------------
void CWeaponCombat_ChargeablePlasma::GainedNewTechnology( CBaseTechnology *pTechnology )
{
	BaseClass::GainedNewTechnology( pTechnology );

	CBaseTFPlayer *pPlayer = ToBaseTFPlayer( (CBaseEntity*)GetOwner() );
	if ( pPlayer )
	{
		// Charge-up mode?
		if ( pPlayer->HasNamedTechnology( "com_comboshield_charge" ) )
		{
			m_bHasCharge = true;
		}
		else
		{
			m_bHasCharge = false;
		}

		// Burst shot mode?
		if ( pPlayer->HasNamedTechnology( "com_comboshield_tripleshot" ) )
		{
			m_bHasBurstShot = true;
		}
		else
		{
			m_bHasBurstShot = false;
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CGrenadeRocket::MissileTouch( CBaseEntity *pOther )
{
	Assert( pOther );
	if ( !pOther->IsSolid() )
		return;

	Vector vecAbsOrigin = GetAbsOrigin();
	CPASFilter filter( vecAbsOrigin );
	te->Explosion( filter, 0.0,	&vecAbsOrigin, g_sModelIndexFireball, 2.0, 15, TE_EXPLFLAG_NONE, 100, m_flDamage );

	StopSound( "GrenadeRocket.FlyLoop" );

	// Don't apply explosive damage if it hit a shield of any kind...
	bool bHittingShield = false;
	if (pOther->GetCollisionGroup() == TFCOLLISION_GROUP_SHIELD)
	{
		bHittingShield = true;
	}
	else if ( pOther->IsPlayer() )
	{
		CBaseTFPlayer *pPlayer = static_cast<CBaseTFPlayer*>(pOther);

		trace_t tr;
		float flDamage = m_flDamage;
		bHittingShield = pPlayer->IsHittingShield( GetAbsVelocity(), &flDamage );
	}

	if (!bHittingShield)
	{
		RadiusDamage( CTakeDamageInfo( this, m_pRealOwner, m_flDamage, DMG_BLAST ), vecAbsOrigin, 100, CLASS_NONE );
	}

	UTIL_Remove( this );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponCombatLaserRifle::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if (!pPlayer)
		return;
	
	WeaponSound(SINGLE);

	// Fire the bullets
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	Vector vecAiming;
	pPlayer->EyeVectors( &vecAiming );

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	// Reduce the spread if the player's ducking
	Vector vecSpread = GetBulletSpread();
	vecSpread *= m_flInaccuracy;

	TFGameRules()->FireBullets( CTakeDamageInfo( this, pPlayer, weapon_combat_laserrifle_damage.GetFloat(), DMG_PLASMA), 1, 
		vecSrc, vecAiming, vecSpread, weapon_combat_laserrifle_range.GetFloat(), m_iPrimaryAmmoType, 0, entindex(), 0 );

	m_flInaccuracy += 0.3;
	m_flInaccuracy = clamp(m_flInaccuracy, 0, 1);

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	m_iClip1 = m_iClip1 - 1;
}
//-----------------------------------------------------------------------------
// Purpose: Try and find an entity to lock onto
//-----------------------------------------------------------------------------
CBaseEntity *CWeaponCombat_ChargeablePlasma::GetLockTarget( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if ( !pPlayer )
		return NULL;

	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	Vector vecAiming;
	pPlayer->EyeVectors( &vecAiming );
	Vector vecEnd = vecSrc + vecAiming * MAX_TRACE_LENGTH;

	trace_t tr;
	TFGameRules()->WeaponTraceLine( vecSrc, vecEnd, MASK_SHOT, pPlayer, GetDamageType(), &tr );

	if ( (tr.fraction < 1.0f) && tr.m_pEnt )
	{
		CBaseEntity *pTargetEntity = tr.m_pEnt;

		// Don't guide on same team or on anything other than players, objects, and NPCs
		if ( pTargetEntity->InSameTeam(pPlayer) || (!pTargetEntity->IsPlayer() 
			&& (pTargetEntity->MyNPCPointer() == NULL)) )
			return NULL;

		// Compute the target offset relative to the target
		Vector vecWorldOffset;
		VectorSubtract( tr.endpos, pTargetEntity->GetAbsOrigin(), vecWorldOffset );
		VectorIRotate( vecWorldOffset, pTargetEntity->EntityToWorldTransform(), m_vecTargetOffset ); 
		m_flLockedAt = gpGlobals->curtime + 0.2;
		return pTargetEntity;
	}

	return NULL;
}
예제 #8
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponBuilder::ItemPostFrame( void )
{
	CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() );
	if ( !pOwner )
		return;

	// Ignore input while the player's building anything
	if ( pOwner->IsBuilding() )
		return;

	// Switch away if I'm not in placement mode
	if ( m_iBuildState != BS_PLACING && m_iBuildState != BS_PLACING_INVALID )
	{
		pOwner->SwitchToNextBestWeapon( NULL );
		return;
	}

	if (( pOwner->m_nButtons & IN_ATTACK ) && (m_flNextPrimaryAttack <= gpGlobals->curtime) )
	{
		PrimaryAttack();
	}

	// Allow shield post frame 
	AllowShieldPostFrame( true );

	WeaponIdle();
}
//-----------------------------------------------------------------------------
// Purpose: Place the combat object
//-----------------------------------------------------------------------------
void CWeaponBaseCombatObject::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = dynamic_cast<CBaseTFPlayer*>((CBaseEntity*)GetOwner());
	if ( !pPlayer )
		return;
	if ( pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
		return;

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();

	Vector vecPlaceOrigin;
	QAngle angPlaceAngles;
	if ( GetPlacePosition( pPlayer, &vecPlaceOrigin, &angPlaceAngles ) == false )
	{
		WeaponSound( DOUBLE );
		return;
	}

	// Place the combat object
	PlaceCombatObject( pPlayer, vecPlaceOrigin, angPlaceAngles );

	WeaponSound( SINGLE );
	pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType );

	// If I'm now out of ammo, switch away
	if ( !HasPrimaryAmmo() )
	{
		pPlayer->SelectLastItem();
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponCombatPlasmaGrenadeLauncher::PrimaryAttack( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if (!pPlayer)
		return;
	
	WeaponSound(SINGLE);

	// Fire the bullets
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );

	PlayAttackAnimation( GetPrimaryAttackActivity() );

	// Launch the grenade
	Vector vecForward;
	pPlayer->EyeVectors( &vecForward );
	Vector vecOrigin = pPlayer->EyePosition();
	vecOrigin += (vecForward);

#if !defined( CLIENT_DLL )
	float flSpeed = 1200;

	CGrenadeAntiPersonnel* pGrenade = CGrenadeAntiPersonnel::Create(vecOrigin, vecForward * flSpeed, pPlayer );
	pGrenade->SetModel( "models/weapons/w_grenade.mdl" );
	pGrenade->SetBounceSound( "PlasmaGrenade.Bounce" );
	pGrenade->SetDamage( weapon_combat_plasmagrenadelauncher_damage.GetFloat() );
	pGrenade->SetDamageRadius( weapon_combat_plasmagrenadelauncher_radius.GetFloat() );
	pGrenade->SetExplodeOnContact( true );
#endif

	m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
	m_iClip1 = m_iClip1 - 1;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerClassCommando::BullRushTouch( CBaseEntity *pTouched )
{
	if ( pTouched->IsPlayer() && !pTouched->InSameTeam( m_pPlayer ) )
	{
		// Get the player.
		CBaseTFPlayer *pTFPlayer = ( CBaseTFPlayer* )pTouched;

		// Check to see if we have "touched" this player already this bullrush cycle.
		if ( m_aHitPlayers.Find( pTFPlayer ) != -1 )
			return;

		// Hitting the player now.
		m_aHitPlayers.AddToTail( pTFPlayer );

		// ROBIN: Bullrush now instantly kills again
		float flDamage = 200;
		// Calculate the damage a player takes based on distance(time).
		//float flDamage = 1.0f - ( ( COMMANDO_BULLRUSH_TIME - m_ClassData.m_flBullRushTime ) * ( 1.0f / COMMANDO_BULLRUSH_TIME ) );
		//flDamage *= 115.0f; // max bullrush damage

		trace_t tr = m_pPlayer->GetTouchTrace();
		CTakeDamageInfo info( m_pPlayer, m_pPlayer, flDamage, DMG_CLUB, DMG_KILL_BULLRUSH );
		CalculateMeleeDamageForce( &info, (tr.endpos - tr.startpos), tr.endpos );
		pTFPlayer->TakeDamage( info );

		CPASAttenuationFilter filter( m_pPlayer, "Commando.BullRushFlesh" );
		CBaseEntity::EmitSound( filter, m_pPlayer->entindex(), "Commando.BullRushFlesh" );

		pTFPlayer->Touch( m_pPlayer ); 
	}
}
예제 #12
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseTFVehicle::FinishedBuilding( void )
{
	BaseClass::FinishedBuilding();

	// See if we've finished building on a vehicle that has a passenger slot assigned to my buildpoint.
	CBaseObject	*pParent = GetParentObject();
	if ( pParent && pParent->IsAVehicle() )
	{
		CBaseTFVehicle *pVehicle = static_cast<CBaseTFVehicle*>(pParent);
		int iRole = pVehicle->GetChildVehicleRole( this );
		if ( iRole != -1 )
		{
			// Is there a player in the role assigned to this buildpoint?
			CBaseTFPlayer *pExistingPlayer = static_cast<CBaseTFPlayer*>( pVehicle->GetPassenger( iRole ) );
			if ( pExistingPlayer )
			{
				// Remove the player from my parent vehicle and put them in me
				pExistingPlayer->LeaveVehicle();

				// Get in the vehicle.
				pExistingPlayer->GetInVehicle( this, VEHICLE_DRIVER );
			}
		}
	}
}
예제 #13
0
//-----------------------------------------------------------------------------
// Purpose: Check to see if our target has moved beyond our length
//-----------------------------------------------------------------------------
void CHarpoon::ConstrainThink( void )
{
	if ( !GetImpaledTarget() || !m_hLinkedHarpoon.Get() )
		return;

	// Moved too far away?
	float flDistSq = m_hLinkedHarpoon->GetAbsOrigin().DistToSqr( GetImpaledTarget()->GetAbsOrigin() ); 
	if ( flDistSq > m_flConstrainLength )
	{
		// Break the rope
		if ( m_hRope )
		{
			m_hRope->DetachPoint(1);
			m_hRope->DieAtNextRest();
			m_hRope = NULL;
		}

		// If we're impaling a player, remove his movement constraint
		if ( GetImpaledTarget()->IsPlayer() )
		{
			CBaseTFPlayer *pPlayer = (CBaseTFPlayer *)GetImpaledTarget();
			pPlayer->DeactivateMovementConstraint();
		}

		SetThink( NULL );
	}
	else
	{
		SetNextThink( gpGlobals->curtime + 0.1f );
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponCombatLaserRifle::RecalculateAccuracy( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if (!pPlayer)
		return;

	m_flAccuracyTime += gpGlobals->frametime;

	while ( m_flAccuracyTime > 0.05 )
	{
		if ( !(pPlayer->GetFlags() & FL_ONGROUND) )
		{
			m_flInaccuracy += 0.05;
		}
		else if ( pPlayer->GetFlags() & FL_DUCKING )
		{
			m_flInaccuracy -= 0.08;
		}
/*
		else if ( pPlayer->GetLocalVelocity().LengthSqr() > (100*100) )
		{
			// Never get worse than 1/2 accuracy from running
			if ( m_flInaccuracy < 0.25 )
			{
				m_flInaccuracy += 0.01;
				if ( m_flInaccuracy > 0.5 )
				{
					m_flInaccuracy = 0.5;
				}
			}
			else if ( m_flInaccuracy > 0.25 )
			{
				m_flInaccuracy -= 0.01;
			}
		}
*/
		else
		{
			m_flInaccuracy -= 0.04;
		}

		// Crouching prevents accuracy ever going beyond a point
		if ( pPlayer->GetFlags() & FL_DUCKING )
		{
			m_flInaccuracy = clamp(m_flInaccuracy, 0, 0.8);
		}
		else
		{
			m_flInaccuracy = clamp(m_flInaccuracy, 0, 1);
		}

		m_flAccuracyTime -= 0.05;

#ifndef CLIENT_DLL
		//if ( m_flInaccuracy )
			//Msg("Inaccuracy %.2f (%.2f)\n", m_flInaccuracy, gpGlobals->curtime );
#endif
	}
}
예제 #15
0
/*
===========
ClientPutInServer

called each time a player is spawned into the game
============
*/
void ClientPutInServer( edict_t *pEdict, const char *playername )
{
	// Allocate a CBaseTFPlayer for pev, and call spawn
	CBaseTFPlayer *pPlayer = CBaseTFPlayer::CreatePlayer( "player", pEdict );
	pPlayer->InitialSpawn();
	pPlayer->SetPlayerName( playername );
	pPlayer->Spawn();
}
예제 #16
0
//-----------------------------------------------------------------------------
// Purpose: This is called pre player movement and copies all the data necessary
//          from the player for movement. (Server-side, the client-side version
//          of this code can be found in prediction.cpp.)
//-----------------------------------------------------------------------------
void CTFPlayerMove::SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move )
{
	// Call the default SetupMove code.
	BaseClass::SetupMove( player, ucmd, pHelper, move );

	//
	// Convert to TF2 data.
	//
	CBaseTFPlayer *pTFPlayer = static_cast<CBaseTFPlayer*>( player );
	Assert( pTFPlayer );

	CTFMoveData *pTFMove = static_cast<CTFMoveData*>( move );
	Assert( pTFMove );

	//
	// Player movement data.
	//

	// Copy the position delta.
	pTFMove->m_vecPosDelta = pTFPlayer->m_vecPosDelta;

	// Copy the momentum data.
	pTFMove->m_iMomentumHead = pTFPlayer->m_iMomentumHead;
	for ( int iMomentum = 0; iMomentum < CTFMoveData::MOMENTUM_MAXSIZE; iMomentum++ )
	{
		pTFMove->m_aMomentum[iMomentum] = pTFPlayer->m_aMomentum[iMomentum];
	}

	pTFMove->m_nClassID = pTFPlayer->PlayerClass();

	IVehicle *pVehicle = player->GetVehicle();
	if (!pVehicle)
	{
		// Handle player class specific setup.
		switch( pTFPlayer->PlayerClass() )
		{
		case TFCLASS_RECON: 
			{ 
				SetupMoveRecon( pTFPlayer, ucmd, pHelper, pTFMove ); 
				break; 
			}
		case TFCLASS_COMMANDO: 
			{ 
				SetupMoveCommando( pTFPlayer, ucmd, pHelper, pTFMove ); 
				break;
			}
		default:
			{
	//			pTFMove->m_nClassID = TFCLASS_UNDECIDED;
				break;
			}
		}
	}
	else
	{
		pVehicle->SetupMove( player, ucmd, pHelper, move ); 
	}
}
예제 #17
0
//-----------------------------------------------------------------------------
// Purpose: Check to see if we've got a linked harpoon, and see if we should constrain something
//-----------------------------------------------------------------------------
void CHarpoon::CheckLinkedHarpoon( void )
{
	if ( m_hLinkedHarpoon )
	{
		CHarpoon *pPlayerHarpoon = NULL;
		CHarpoon *pNonMovingHarpoon = NULL;

		// Find out if either of us has impaled something
		if ( GetImpaledTarget() && m_hLinkedHarpoon->GetImpaledTarget() )
		{
			// Only care about players for now. One of the targets must be a player.
			CBaseTFPlayer *pPlayer = NULL;
			CBaseEntity *pOtherTarget = NULL;
			if ( GetImpaledTarget()->IsPlayer() )
			{
				pPlayer = (CBaseTFPlayer*)GetImpaledTarget();
				pPlayerHarpoon = this;
				pNonMovingHarpoon = m_hLinkedHarpoon;
			}
			else if ( m_hLinkedHarpoon->GetImpaledTarget()->IsPlayer() )
			{
				pPlayer = (CBaseTFPlayer*)m_hLinkedHarpoon->GetImpaledTarget();
				pNonMovingHarpoon = this;
				pPlayerHarpoon = m_hLinkedHarpoon;
			}

			// Found a player?
			if ( pPlayer )
			{
				pOtherTarget = pNonMovingHarpoon->GetImpaledTarget();

				// For now, we have to be linked to a non-moving target. Eventually we could support linked moving targets.
				// pOtherTarget == NULL means the harpoon's buried in the world.
				if ( pOtherTarget->IsBSPModel() || pOtherTarget->GetMoveType() == MOVETYPE_NONE )
				{
					// Add a little slack
					m_flConstrainLength = ( m_hLinkedHarpoon->GetAbsOrigin() - GetAbsOrigin() ).Length() + 150;
					pPlayer->ActivateMovementConstraint( NULL, pNonMovingHarpoon->GetAbsOrigin(), m_flConstrainLength, 150.0f, 0.1f );
					// Square it for later checking
					m_flConstrainLength *= m_flConstrainLength;

					// Start checking the length
					pPlayerHarpoon->m_flConstrainLength = m_flConstrainLength;
					pPlayerHarpoon->SetThink( ConstrainThink );
					pPlayerHarpoon->SetNextThink( gpGlobals->curtime + 0.1f );

					// Make the rope taught, and prevent it resizing
					if ( m_hRope )
					{
						m_hRope->m_RopeFlags &= ~ROPE_RESIZE;
						m_hRope->RecalculateLength();
					}
				}
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: Handle deploying, undeploying, firing, etc.
// TODO: Add a deploy to the firing!  Currently no reloading!
//-----------------------------------------------------------------------------
void CWeaponRocketLauncher::ItemPostFrame( void )
{
	// Get the player.
	CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() );
	if ( !pPlayer )
		return;

	if ( UsesClipsForAmmo1() )
	{
		CheckReload();
	}

#if !defined( CLIENT_DLL )
	if ( !HasPrimaryAmmo() && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) )
	{
		pPlayer->SwitchToNextBestWeapon( NULL );
	}
#endif

	// Handle Firing
	if ( GetShieldState() == SS_DOWN && !m_bInReload )
	{
		// Attempting to fire.
		if ( ( pPlayer->m_nButtons & IN_ATTACK ) && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) )
		{
			if ( m_iClip1 > 0 )
			{
				PrimaryAttack();
			}
			else
			{
				Reload();
			}
		}

		// Reload button (or fire button when we're out of ammo)
		if ( m_flNextPrimaryAttack <= gpGlobals->curtime ) 
		{
			if ( pPlayer->m_nButtons & IN_RELOAD ) 
			{
				Reload();
			}
			else if ( !((pPlayer->m_nButtons & IN_ATTACK) || (pPlayer->m_nButtons & IN_ATTACK2) || (pPlayer->m_nButtons & IN_RELOAD)) )
			{
				if ( !m_iClip1 && HasPrimaryAmmo() )
				{
					Reload();
				}
			}
		}
	}

	// Prevent shield post frame if we're not ready to attack, or we're charging
	AllowShieldPostFrame( m_flNextPrimaryAttack <= gpGlobals->curtime || m_bInReload );
}
예제 #19
0
//-----------------------------------------------------------------------------
// Purpose: Figure out if I should be using an attached item rather than this vehicle itself.
//-----------------------------------------------------------------------------
bool CBaseTFVehicle::UseAttachedItem( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	CBaseTFPlayer* pPlayer = dynamic_cast<CBaseTFPlayer*>(pActivator);
	if ( !pPlayer || !InSameTeam(pPlayer) )
		return false;

	Vector vecPlayerOrigin = pPlayer->GetAbsOrigin();
	int nBestBuildPoint = -1;
	float fBestDistance = FLT_MAX;

	// Get the closest regular entry point:
	int nRole = LocateEntryPoint( pPlayer, &fBestDistance );

	// Iterate through each of the build points, if any, and see which we are closest to.
	int nBuildPoints = GetNumBuildPoints();
	for( int i = 0; i < nBuildPoints; i++ )
	{	
		CBaseObject* pObject = GetBuildPointObject(i);

		// If there's something in the build point that isn't in the process of being built or placed:
		if( pObject && !pObject->IsPlacing() && !pObject->IsBuilding() ) 
		{
			Vector vecOrigin;
			QAngle vecAngles;

			// If the build point is the default point for this role, just take it 
			if (GetBuildPointPassenger(i) == nRole)
			{
				nBestBuildPoint = i;
				break;
			}

			// And I can get the build point.
			if( GetBuildPoint( i, vecOrigin, vecAngles )  )
			{
				float fLength2dSqr = (vecOrigin - vecPlayerOrigin).AsVector2D().LengthSqr();
				if( fLength2dSqr < fBestDistance )
				{
					nBestBuildPoint = i;
					fBestDistance = fLength2dSqr; 
				}
			}
		}
	}

	if( nBestBuildPoint >= 0 )
	{
		// They're using an item on me, so push out the deterioration time
		ResetDeteriorationTime();
		GetBuildPointObject(nBestBuildPoint)->Use( pActivator, pCaller, useType, value );
		return true;
	}

	return false;
}
예제 #20
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponBuilder::UpdateOnRemove( void )
{
	// Tell the player he's lost his build weapon
	CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() );
	if ( pOwner && pOwner->GetWeaponBuilder() == this )
	{
		pOwner->SetWeaponBuilder( NULL );
	}

	// Chain at end to mimic destructor unwind order
	BaseClass::UpdateOnRemove();
}
예제 #21
0
//-----------------------------------------------------------------------------
// Purpose: Run through all the Bots in the game and let them think.
//-----------------------------------------------------------------------------
void Bot_RunAll( void )
{
	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		CBaseTFPlayer *pPlayer = ToBaseTFPlayer( UTIL_PlayerByIndex( i ) );

		if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
		{
			Bot_Think( pPlayer );
		}
	}
}
//-----------------------------------------------------------------------------
// Boost those attached to me as long as I'm not EMPed
//-----------------------------------------------------------------------------
void CObjectBuffStation::BoostPlayerThink( void )
{
	// Are we emped?
	bool bIsEmped = HasPowerup( POWERUP_EMP );

	// Get range (squared = faster test).
	float flMaxRangeSq = obj_buff_station_range.GetFloat();
	flMaxRangeSq *= flMaxRangeSq;

	// Boost all attached players and objects.
	for ( int iPlayer = 0; iPlayer < BUFF_STATION_MAX_PLAYERS; iPlayer++ )
	{
		// Clean up dangling pointers + dead players, subversion, disconnection
		CBaseTFPlayer *pPlayer = m_hPlayers[iPlayer].Get();
		if ( !pPlayer || !pPlayer->IsAlive() || !InSameTeam( pPlayer ) || !pPlayer->PlayerClass() )
		{
			DetachPlayerByIndex( iPlayer );
			continue;
		}

		// Check for out of range.
		float flDistSq = GetAbsOrigin().DistToSqr( pPlayer->GetAbsOrigin() ); 
		if ( flDistSq > flMaxRangeSq )
		{
			DetachPlayerByIndex( iPlayer );
			continue;
		}

		bool bBoosted = false;
		if ( !bIsEmped )
		{
			float flHealAmount = obj_buff_station_heal_rate.GetFloat() * BUFF_STATION_BOOST_PLAYER_THINK_INTERVAL;
			bBoosted = pPlayer->AttemptToPowerup( POWERUP_BOOST, 0, flHealAmount, this, &m_aPlayerAttachInfo[iPlayer].m_DamageModifier );
		}

		if ( !bBoosted )
		{
			m_aPlayerAttachInfo[iPlayer].m_DamageModifier.RemoveModifier();
		}
	}

	// Set next think time.
	if ( m_nPlayerCount > 0 )
	{
		SetNextThink( gpGlobals->curtime + BUFF_STATION_BOOST_PLAYER_THINK_INTERVAL, 
			          BUFF_STATION_BOOST_PLAYER_THINK_CONTEXT );
	}
	else
	{
		SetNextThink( gpGlobals->curtime + 1.0f, BUFF_STATION_BOOST_PLAYER_THINK_CONTEXT );
	}
}
예제 #23
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponMortar::MortarDestroyed( void )
{
	CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() );
	if ( pPlayer )
	{
		ClientPrint( pPlayer, HUD_PRINTCENTER, "\n\n\n\n\n\n\n\n\n\nMortar Destroyed!" );
	}

	if ( pPlayer && pPlayer->GetActiveWeapon() == this )
	{
		SendWeaponAnim( ACT_SLAM_TRIPMINE_DRAW );
	}

	MortarObjectRemoved();
}
예제 #24
0
//-----------------------------------------------------------------------------
// Purpose: My player has just died
//-----------------------------------------------------------------------------
void CPlayerClass::PlayerDied( CBaseEntity *pAttacker )
{
	if ( pAttacker )
	{
		CBaseTFPlayer *pAttackerPlayer = dynamic_cast< CBaseTFPlayer* >( pAttacker );
		if ( pAttackerPlayer )
		{
			CPlayerClass *pAttackerClass = pAttackerPlayer->GetPlayerClass();
			if ( pAttackerClass )
			{
				int iStatGroup = GetStatGroupFor( pAttackerPlayer );
				g_PlayerClassStats[ iStatGroup ].m_InterClassStats[GetTFClass()].m_nKills++;
			}
		}
	}
}
예제 #25
0
//-----------------------------------------------------------------------------
// Purpose: Records that a player has left the zone, and updates it's state
//			according, maybe starting to change team.
// Input  : *pOther - the entity that left the zone
//-----------------------------------------------------------------------------
void CControlZone::EndTouch( CBaseEntity *pOther )
{
	CBaseTFPlayer *pl = ToBaseTFPlayer( pOther );
	if ( !pl )
		return;

	CHandle< CBaseTFPlayer > hHandle;
	hHandle = pl;
	m_ZonePlayerList.FindAndRemove( hHandle );

	ReevaluateControllingTeam();

	// Unset this player's current zone if it's this one
	if ( pl->GetCurrentZone() == this )
		pl->SetCurrentZone( NULL );
}
예제 #26
0
//-----------------------------------------------------------------------------
// Purpose: Records that a player has entered the zone, and updates it's state
//			according, maybe starting to change team.
// Input  : *pOther - the entity that left the zone
//-----------------------------------------------------------------------------
void CControlZone::StartTouch( CBaseEntity *pOther )
{
	CBaseTFPlayer *pl = ToBaseTFPlayer( pOther );
	if ( !pl )
		return;

	CHandle< CBaseTFPlayer > hHandle;
	hHandle = pl;

	m_ZonePlayerList.AddToTail( hHandle );

	ReevaluateControllingTeam();

	// Set this player's current zone to this zone
	pl->SetCurrentZone( this );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
float CWeaponCombatLaserRifle::GetFireRate( void )
{	
	float flFireRate = ( SequenceDuration() * 0.4 ) + SHARED_RANDOMFLOAT( 0.0, 0.035f );

	CBaseTFPlayer *pPlayer = static_cast<CBaseTFPlayer*>( GetOwner() );
	if ( pPlayer )
	{
		// Ducking players should fire more rapidly.
		if ( pPlayer->GetFlags() & FL_DUCKING )
		{
			flFireRate *= weapon_combat_laserrifle_ducking_mod.GetFloat();
		}
	}
	
	return flFireRate;
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame by postthink
//-----------------------------------------------------------------------------
void CPlayerClassCommando::ClassThink( void )
{
	// Check bullrush
	m_ClassData.m_bCanBullRush = true;

	// Do the init thing here!
	if ( m_bOldBullRush != m_ClassData.m_bBullRush )
	{
		if ( m_ClassData.m_bBullRush )
		{
			PreBullRush();
		}
		else
		{
			PostBullRush();
		}

		m_bOldBullRush = (bool)m_ClassData.m_bBullRush;
	} 

	// Check for melee attack
	if ( m_bCanBoot && m_pPlayer->IsAlive() && m_flNextBootCheck < gpGlobals->curtime )
	{
		m_flNextBootCheck = gpGlobals->curtime + 0.2;

		CBaseEntity *pEntity = NULL;
		Vector vecSrc	 = m_pPlayer->Weapon_ShootPosition( );
		Vector vecDir	 = m_pPlayer->BodyDirection2D( );
		Vector vecTarget = vecSrc + (vecDir * 48);
		for ( CEntitySphereQuery sphere( vecTarget, 16 ); pEntity = sphere.GetCurrentEntity(); sphere.NextEntity() )
		{
			if ( pEntity->IsPlayer() && (pEntity != m_pPlayer) )
			{
				CBaseTFPlayer *pPlayer = (CBaseTFPlayer *)pEntity;
				// Target needs to be on the enemy team
				if ( !pPlayer->IsClass( TFCLASS_UNDECIDED ) && pPlayer->IsAlive() && pPlayer->InSameTeam( m_pPlayer ) == false )
				{
					Boot( pPlayer );
					m_flNextBootCheck = gpGlobals->curtime + 1.5;
				}
			}
		}
	}

	BaseClass::ClassThink();
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CWeaponCombatShield::Holster( CBaseCombatWeapon *pSwitchingTo )
{
	CBaseTFPlayer *player = ToBaseTFPlayer( GetOwner() );
	if ( player )
	{
		player->SetBlocking( false );
		player->SetParrying( false );

		if ( m_iShieldState != SS_DOWN && 
			 m_iShieldState != SS_UNAVAILABLE )
		{
			SetShieldState( SS_LOWERING );
		}
	}

	return true;
}
예제 #30
0
//-----------------------------------------------------------------------------
// Purpose: The player holding this weapon has just gained new technology.
//			Check to see if it affects the mortar
//-----------------------------------------------------------------------------
void CWeaponMortar::GainedNewTechnology( CBaseTechnology *pTechnology )
{
	CBaseTFPlayer *pPlayer = ToBaseTFPlayer( GetOwner() );
	if ( pPlayer )
	{
		// Range upgraded?
		if ( pPlayer->HasNamedTechnology("mortar_range") )
			m_bRangeUpgraded = true;
		else
			m_bRangeUpgraded = false;

		// Accuracy upgraded?
		if ( pPlayer->HasNamedTechnology("mortar_accuracy") )
			m_bAccuracyUpgraded = true;
		else
			m_bAccuracyUpgraded = false;
	}
}