diff options
Diffstat (limited to 'game/shared/tf/tf_wearable_item_demoshield.cpp')
| -rw-r--r-- | game/shared/tf/tf_wearable_item_demoshield.cpp | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/game/shared/tf/tf_wearable_item_demoshield.cpp b/game/shared/tf/tf_wearable_item_demoshield.cpp new file mode 100644 index 0000000..7378921 --- /dev/null +++ b/game/shared/tf/tf_wearable_item_demoshield.cpp @@ -0,0 +1,278 @@ +//========= 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 ); + } +}
\ No newline at end of file |