⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tf_playerclass.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPlayerClass::CreateClass( void )
{ 
	// Give them a full loadout on the initial spawn
	ResupplyAmmo( 100.0f, RESUPPLY_ALL_FROM_STATION );

	// Create the builder weapon & all objects in it (Helpers are automatically deleted when the weapon's deleted)
	// Make sure they can build at least 1 object
	if ( GetTFClassInfo( m_TFClass )->m_pClassObjects[0] != OBJ_LAST )
	{
		m_pPlayer->GiveNamedItem( "weapon_builder" );

		Assert( m_pPlayer->GetWeaponBuilder() );

		// Do we have a construction yard?
		bool bHaveYard = false;
		CBaseEntity *pEntity = NULL;
		while ((pEntity = gEntList.FindEntityByClassname( pEntity, "func_construction_yard" )) != NULL)
		{
			if ( m_pPlayer->InSameTeam( pEntity ) )
			{
				bHaveYard = true;
				break;
			}
		}

		for ( int i = 0; i < OBJ_LAST; i++ )
		{
			int iClassObject = GetTFClassInfo( m_TFClass )->m_pClassObjects[i];
			
			// Hit the end?
			if ( iClassObject == OBJ_LAST )
				break;

			// Only Humans can build the powerpacks & mortars
			if ( iClassObject == OBJ_POWERPACK || iClassObject == OBJ_MORTAR)
			{
				if ( m_pPlayer->GetTeamNumber() != TEAM_HUMANS )
					continue;
			}

			// Only Aliens can build shields
			if ( iClassObject == OBJ_SHIELDWALL )
			{
				if ( m_pPlayer->GetTeamNumber() != TEAM_ALIENS )
					continue;
			}

			// If my team doesn't have a construction yard, don't allow me to build vehicles
			if ( !tf_fastbuild.GetBool() && !bHaveYard )
			{
				if ( IsObjectAVehicle(iClassObject) ) 
					continue;

				// Don't allow them to build vehicle upgrades either
				if ( iClassObject == OBJ_DRIVER_MACHINEGUN )
					continue;
			}

			// If my team has a construction yard, don't allow me to build defensive buildings
			if ( !tf_fastbuild.GetBool() && bHaveYard && IsObjectADefensiveBuilding(iClassObject) )
				continue;

			m_pPlayer->GetWeaponBuilder()->AddBuildableObject( iClassObject );

			// Give the player a fake weapon to select this object with
			CWeaponObjectSelection *pSelection = (CWeaponObjectSelection *)m_pPlayer->GiveNamedItem( "weapon_objectselection", iClassObject  );
			if ( pSelection )
			{
				pSelection->SetType( iClassObject );
			}
		}
	}

	// Give the player all the weapons from tech associations
	CTechnologyTree *pTechTree = m_pPlayer->GetTechTree();
	if ( pTechTree )
	{
		// Give the player any weapons s/he might have just received the tech for
		for ( int i = 0; i < m_iNumWeaponTechAssociations; i++ )
		{
			if ( m_pPlayer->HasNamedTechnology( m_WeaponTechAssociations[i].pWeaponTech ) )
			{
				CBaseTechnology *tech = pTechTree->GetTechnology( m_WeaponTechAssociations[i].pWeaponTech );
				if ( tech )
				{	
					for ( int j = 0; j < tech->GetNumWeaponAssociations(); j++ )
					{
						const char *weaponname = tech->GetAssociatedWeapon( j );
						Assert( weaponname );
						
						m_pPlayer->GiveNamedItem( weaponname );
					}
				}
			}
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: Called on each respawn
//-----------------------------------------------------------------------------
void CPlayerClass::RespawnClass( void )
{
	ResupplyAmmo( 100.0f, RESUPPLY_ALL_FROM_STATION );
	GainedNewTechnology( NULL );
	SetMaxHealth( GetMaxHealthCVarValue() );
	SetMaxSpeed( GetMaxSpeed() );
	CheckDeterioratingObjects();

	SetupSizeData();

	// Refill the clips of all my weapons
	for (int i = 0; i < MAX_WEAPONS; i++)
	{
		CBaseCombatWeapon *pWeapon = m_pPlayer->GetWeapon(i);
		if ( pWeapon )
		{
			if ( pWeapon->UsesClipsForAmmo1() )
			{
				pWeapon->m_iClip1 = pWeapon->GetDefaultClip1();
			}
			if ( pWeapon->UsesClipsForAmmo2() )
			{
				pWeapon->m_iClip2 = pWeapon->GetDefaultClip2();
			}
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: Supply the player with Ammo. Return true if some ammo was given.
//-----------------------------------------------------------------------------
bool CPlayerClass::ResupplyAmmoType( float flAmount, const char *pAmmoType )
{
	if (flAmount <= 0)
		return false;

	// Make sure at least 1 if given...
	int nAmount;
	if (flAmount <= 1)
		nAmount = 1;
	else
		nAmount = (int)flAmount;

	bool bGiven = false;
	if ( g_pGameRules->CanHaveAmmo( m_pPlayer, pAmmoType ) )
	{
		if ( m_pPlayer->GiveAmmo( nAmount, pAmmoType, true ) > 0 )
			bGiven = true;
	}

	return bGiven;
}

//-----------------------------------------------------------------------------
// Purpose: Supply the player with Ammo. Return true if some ammo was given.
//-----------------------------------------------------------------------------
bool CPlayerClass::ResupplyAmmo( float flPercentage, ResupplyReason_t reason )
{
	bool bGiven = false;

	// Fully resupply shield energy everytime
	if ( m_pPlayer->GetCombatShield() )
	{
		m_pPlayer->GetCombatShield()->AddShieldHealth( 1.0 ); 
	}

	if ((reason == RESUPPLY_RESPAWN) || (reason == RESUPPLY_ALL_FROM_STATION) || (reason == RESUPPLY_AMMO_FROM_STATION))
	{
		if (ResupplyAmmoType( 1, "Sappers" ))
		{
			bGiven = true;
		}
	}

	return bGiven;
}

//-----------------------------------------------------------------------------
// Purpose: Calculate the player's Speed
//-----------------------------------------------------------------------------
float CPlayerClass::GetMaxSpeed( void )
{
	float flMaxSpeed = m_flMaxWalkingSpeed;

	// Is the player in adrenalin mode?
	if ( m_pPlayer->HasPowerup( POWERUP_RUSH ) )
	{
		flMaxSpeed *= ADRENALIN_SPEED_INCREASE;
	}

	// Is the player unable to move right now?
	if ( m_pPlayer->CantMove() )
	{
		flMaxSpeed = 1;
	}

	return flMaxSpeed;
}

//-----------------------------------------------------------------------------
// Purpose: Get the player's maximum walking speed
//-----------------------------------------------------------------------------
float CPlayerClass::GetMaxWalkSpeed( void )
{ 
	return m_flMaxWalkingSpeed; 
}

//-----------------------------------------------------------------------------
// Purpose: Set the player's speed
//-----------------------------------------------------------------------------
void CPlayerClass::SetMaxSpeed( float flMaxSpeed )
{
	if ( m_pPlayer )
	{
		m_pPlayer->SetMaxSpeed( flMaxSpeed );

		float curspeed = m_pPlayer->GetAbsVelocity().Length();

		if ( curspeed != 0.0f && curspeed > flMaxSpeed )
		{
			float crop = flMaxSpeed / curspeed;

			Vector vecNewVelocity;
			VectorScale( m_pPlayer->GetAbsVelocity(), crop, vecNewVelocity );
			m_pPlayer->SetAbsVelocity( vecNewVelocity );
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: Return the player's max health
//-----------------------------------------------------------------------------
int CPlayerClass::GetMaxHealthCVarValue()
{
	int val = GetTFClassInfo( GetTFClass() )->m_pMaxHealthCVar->GetInt();
	Assert( val > 0 );	// If you hit this assert, then you probably didn't add an entry to skill?.cfg
	return val;
}

//-----------------------------------------------------------------------------
// Purpose: Set the player's health
//-----------------------------------------------------------------------------
void CPlayerClass::SetMaxHealth( float flMaxHealth )
{
	if ( m_pPlayer )
	{
		m_pPlayer->m_iMaxHealth = m_pPlayer->m_iHealth = flMaxHealth;
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
string_t CPlayerClass::GetClassModel( int nTeam )
{
	return m_sClassModel[nTeam];
}


const char*	CPlayerClass::GetClassModelString( int nTeam )
{
	// Each derived class should implement this.
	Assert( false );
	return "INVALID";
}


//-----------------------------------------------------------------------------
// Purpose: Called to see if another player should be displayed on the players radar
//-----------------------------------------------------------------------------
bool CPlayerClass::CanSeePlayerOnRadar( CBaseTFPlayer *pl )
{
//	if ( pl->InSameTeam(m_pPlayer) )
//		return false;

	return true;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPlayerClass::ItemPostFrame()
{
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : TFClass
//-----------------------------------------------------------------------------
TFClass CPlayerClass::GetTFClass( void )
{
	return m_TFClass;
}

//-----------------------------------------------------------------------------
// Purpose: Handle custom commands for this playerclass
//-----------------------------------------------------------------------------
bool CPlayerClass::ClientCommand( const char *cmd )
{
	if ( FStrEq( cmd, "builder_select_obj" ) )
	{
		if ( engine->Cmd_Argc() < 2 )
			return true;

		// This is a total hack. Eventually this should come in via usercmds.

		// Get our builder weapon
		if ( !m_pPlayer->GetWeaponBuilder() )
			return true;

		// Select a state for the builder weapon
		m_pPlayer->GetWeaponBuilder()->SetCurrentObject( atoi( engine->Cmd_Argv(1) ) );
		m_pPlayer->GetWeaponBuilder()->SetCurrentState( BS_PLACING );
		m_pPlayer->GetWeaponBuilder()->StartPlacement(); 
		m_pPlayer->GetWeaponBuilder()->m_flNextPrimaryAttack = gpGlobals->curtime + 0.35f;
		return true;
	}
	else if ( FStrEq( cmd, "builder_select_mode" ) )
	{
		if ( engine->Cmd_Argc() < 2 )
			return true;

		// Get our builder weapon
		if ( !m_pPlayer->GetWeaponBuilder() )
			return true;

		// Select a state for the builder weapon
		m_pPlayer->GetWeaponBuilder()->SetCurrentState( atoi( engine->Cmd_Argv(1) ) );
		m_pPlayer->GetWeaponBuilder()->m_flNextPrimaryAttack = gpGlobals->curtime + 0.35f;
		return true;
	}

	return false;
}


//-----------------------------------------------------------------------------
// Should we take damage-based force?
//-----------------------------------------------------------------------------
bool CPlayerClass::ShouldApplyDamageForce( const CTakeDamageInfo &info )
{
	return true;
}


//-----------------------------------------------------------------------------
// Purpose: The player has taken damage. Return the damage done.
//-----------------------------------------------------------------------------
float CPlayerClass::OnTakeDamage( const CTakeDamageInfo &info )
{
	if ( info.GetAttacker() )
	{
		CBaseTFPlayer *pPlayer = dynamic_cast< CBaseTFPlayer* >( info.GetAttacker() );
		if ( pPlayer && pPlayer->GetPlayerClass() )
		{
			int iStatGroup = GetStatGroupFor( pPlayer );
			CInterClassStats *pInter = &g_PlayerClassStats[iStatGroup].m_InterClassStats[GetTFClass()];
			
			pInter->m_flTotalDamageInflicted += info.GetDamage();
			
			float flDistToAttacker = pPlayer->GetAbsOrigin().DistTo( GetPlayer()->GetAbsOrigin() );
			pInter->m_flTotalEngagementDist += flDistToAttacker;
			pInter->m_nEngagements++;

			if ( gpGlobals->curtime >= m_flNormalizedEngagementNextTime )
			{
				pInter->m_flTotalNormalizedEngagementDist += flDistToAttacker;
				pInter->m_nNormalizedEngagements++;

				m_flNormalizedEngagementNextTime = gpGlobals->curtime + 3;
			}

			// Store detailed stats for the shot?
			if ( tf_DetailedStats.GetInt() )
			{
				CShotInfo shotInfo;
				
				shotInfo.m_flDistance = flDistToAttacker;
				shotInfo.m_nDamage = (int)info.GetDamage();

				g_ClassShotInfos[iStatGroup].AddToTail( shotInfo );
			}
		}
	}
	
	return info.GetDamage();
}

//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -