You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
7.9 KiB
278 lines
7.9 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: TF Base Rockets. |
|
// |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "tf_wearable_item_demoshield.h" |
|
#include "tf_gamerules.h" |
|
#include "engine/ivdebugoverlay.h" |
|
#include "tf_weapon_medigun.h" |
|
|
|
#ifdef CLIENT_DLL |
|
#include "tf_weapon_sword.h" |
|
#include "renamed_recvtable_compat.h" |
|
|
|
NOTE_RENAMED_RECVTABLE( DT_TFWearableItemDemoShield, DT_TFWearableDemoShield ) |
|
#endif |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
LINK_ENTITY_TO_CLASS( tf_wearable_demoshield, CTFWearableDemoShield ); |
|
IMPLEMENT_NETWORKCLASS_ALIASED( TFWearableDemoShield, DT_TFWearableDemoShield ) |
|
|
|
// Network Table -- |
|
BEGIN_NETWORK_TABLE( CTFWearableDemoShield, DT_TFWearableDemoShield ) |
|
#if defined( GAME_DLL ) |
|
#else |
|
#endif // GAME_DLL |
|
END_NETWORK_TABLE() |
|
// -- Network Table |
|
|
|
// Data Desc -- |
|
BEGIN_DATADESC( CTFWearableDemoShield ) |
|
END_DATADESC() |
|
// -- Data Desc |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFWearableDemoShield::CTFWearableDemoShield() : CTFWearable() |
|
{ |
|
#ifdef GAME_DLL |
|
m_bImpactedSomething = false; |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFWearableDemoShield::Precache() |
|
{ |
|
BaseClass::Precache(); |
|
|
|
PrecacheScriptSound( "DemoCharge.HitWorld" ); |
|
PrecacheScriptSound( "DemoCharge.HitFlesh" ); |
|
PrecacheScriptSound( "DemoCharge.HitFleshRange" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFWearableDemoShield::DoSpecialAction( CTFPlayer *pPlayer ) |
|
{ |
|
if ( CanCharge( pPlayer ) ) |
|
{ |
|
DoCharge( pPlayer ); |
|
return; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFWearableDemoShield::EndSpecialAction( CTFPlayer *pPlayer ) |
|
{ |
|
int nAttackNotCancelCharge = 0; |
|
CALL_ATTRIB_HOOK_INT( nAttackNotCancelCharge, attack_not_cancel_charge ); |
|
if ( nAttackNotCancelCharge > 0 ) |
|
{ |
|
return; |
|
} |
|
|
|
if ( pPlayer->m_Shared.InCond( TF_COND_SHIELD_CHARGE ) ) |
|
{ |
|
pPlayer->m_Shared.CalcChargeCrit(); |
|
pPlayer->m_Shared.SetDemomanChargeMeter( 0 ); |
|
pPlayer->m_Shared.RemoveCond( TF_COND_SHIELD_CHARGE ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CTFWearableDemoShield::CanCharge( CTFPlayer *pPlayer ) |
|
{ |
|
// 6/14/2011 - Demos can now charge while in the air to counter pyro control. |
|
// if ( !(pPlayer->GetFlags() & FL_ONGROUND) ) |
|
// return false; |
|
|
|
if ( TFGameRules() && (TFGameRules()->State_Get() == GR_STATE_PREROUND) ) |
|
return false; |
|
|
|
if ( pPlayer->m_Shared.IsLoser() ) |
|
return false; |
|
|
|
if ( pPlayer->m_Shared.InCond( TF_COND_STUNNED ) ) |
|
return false; |
|
|
|
if ( pPlayer->IsTaunting() ) |
|
return false; |
|
|
|
if ( pPlayer->GetGrapplingHookTarget() ) |
|
return false; |
|
|
|
if ( pPlayer->m_Shared.GetDemomanChargeMeter() == 100.f ) |
|
return true; |
|
|
|
if ( TFGameRules() && TFGameRules()->IsPasstimeMode() && pPlayer->m_Shared.HasPasstimeBall() ) |
|
return false; |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFWearableDemoShield::DoCharge( CTFPlayer *pPlayer ) |
|
{ |
|
#ifdef GAME_DLL |
|
float flChargeTime = 1.5f; |
|
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pPlayer, flChargeTime, mod_charge_time ); |
|
pPlayer->m_Shared.AddCond( TF_COND_SHIELD_CHARGE, flChargeTime ); |
|
|
|
m_bImpactedSomething = false; |
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFWearableDemoShield::ShieldBash( CTFPlayer *pPlayer, float flCurrentChargeMeter ) |
|
{ |
|
CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() ); |
|
if ( !pOwner ) |
|
return; |
|
|
|
#ifdef GAME_DLL |
|
|
|
if ( m_bImpactedSomething ) |
|
return; |
|
|
|
m_bImpactedSomething = true; |
|
|
|
// Setup the swing range. |
|
Vector vecForward; |
|
AngleVectors( pOwner->EyeAngles(), &vecForward ); |
|
Vector vecStart = pOwner->Weapon_ShootPosition(); |
|
Vector vecEnd = vecStart + vecForward * 48; |
|
|
|
// See if we hit anything. |
|
trace_t trace; |
|
UTIL_TraceHull( vecStart, vecEnd, -Vector(24,24,24), Vector(24,24,24), |
|
MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &trace ); |
|
|
|
// Play an impact sound. |
|
bool bImpactDamage = false; |
|
if ( trace.m_pEnt ) |
|
{ |
|
const char* pszSoundName = ""; |
|
if ( trace.m_pEnt->IsPlayer() ) |
|
{ |
|
bImpactDamage = true; |
|
pszSoundName = "DemoCharge.HitFleshRange"; |
|
} |
|
else |
|
{ |
|
pszSoundName = "DemoCharge.HitWorld"; |
|
} |
|
pOwner->EmitSound( pszSoundName ); |
|
} |
|
|
|
// Apply impact damage, if any. |
|
if ( bImpactDamage ) |
|
{ |
|
float flBashDamage = CalculateChargeDamage( flCurrentChargeMeter ); |
|
CTakeDamageInfo info; |
|
info.SetAttacker( pOwner ); |
|
info.SetInflictor( this ); |
|
info.SetWeapon( this ); |
|
info.SetDamage( flBashDamage ); |
|
info.SetDamageCustom( TF_DMG_CUSTOM_CHARGE_IMPACT ); |
|
info.SetDamageForce( GetShieldDamageForce( flCurrentChargeMeter ) ); |
|
info.SetDamagePosition( trace.endpos ); |
|
info.SetDamageType( DMG_CLUB ); |
|
|
|
Vector dir; |
|
AngleVectors( pOwner->GetAbsAngles(), &dir ); |
|
trace.m_pEnt->DispatchTraceAttack( info, dir, &trace ); |
|
ApplyMultiDamage(); |
|
|
|
// Calculate charge crit if we did any bash damage |
|
pOwner->m_Shared.CalcChargeCrit(); |
|
} |
|
|
|
UTIL_ScreenShake( pOwner->WorldSpaceCenter(), 25.0, 150.0, 1.0, 750, SHAKE_START ); |
|
|
|
#endif |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
float CTFWearableDemoShield::CalculateChargeDamage( float flCurrentChargeMeter ) |
|
{ |
|
float flImpactDamage = RemapValClamped( flCurrentChargeMeter, 90.0f, 40.0f, 15.0f, 50.0f ); |
|
|
|
CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() ); |
|
if ( !pOwner ) |
|
return flImpactDamage; |
|
|
|
// Cap at 5 decapitations for dmg bonus |
|
int iDecaps = Min( pOwner->m_Shared.GetDecapitations(), 5 ); |
|
if ( iDecaps > 0 ) |
|
{ |
|
flImpactDamage *= (1.0f + iDecaps * 0.1f ); |
|
} |
|
|
|
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pOwner, flImpactDamage, charge_impact_damage ); |
|
|
|
return flImpactDamage; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
Vector CTFWearableDemoShield::GetShieldDamageForce( float flCurrentChargeMeter ) |
|
{ |
|
Vector vecVelocity = GetAbsVelocity(); |
|
IPhysicsObject *pPhysicsObject = VPhysicsGetObject(); |
|
if ( pPhysicsObject ) |
|
{ |
|
pPhysicsObject->GetVelocity( &vecVelocity, NULL ); |
|
VectorNormalize( vecVelocity ); |
|
} |
|
|
|
return (vecVelocity * CalculateChargeDamage( flCurrentChargeMeter ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Attaches the item to the player. |
|
//----------------------------------------------------------------------------- |
|
void CTFWearableDemoShield::Equip( CBasePlayer* pOwner ) |
|
{ |
|
BaseClass::Equip( pOwner ); |
|
if ( !CanEquip( pOwner ) ) |
|
return; |
|
|
|
CTFPlayer *pTFPlayer = ToTFPlayer( pOwner ); |
|
if ( pTFPlayer ) |
|
{ |
|
pTFPlayer->m_Shared.SetShieldEquipped( true ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Remove item from the player. |
|
//----------------------------------------------------------------------------- |
|
void CTFWearableDemoShield::UnEquip( CBasePlayer* pOwner ) |
|
{ |
|
BaseClass::UnEquip( pOwner ); |
|
|
|
CTFPlayer *pTFPlayer = ToTFPlayer( pOwner ); |
|
if ( pTFPlayer ) |
|
{ |
|
pTFPlayer->m_Shared.SetShieldEquipped( false ); |
|
} |
|
} |