diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/tf2/weapon_combat_chargeableplasma.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/shared/tf2/weapon_combat_chargeableplasma.cpp')
| -rw-r--r-- | game/shared/tf2/weapon_combat_chargeableplasma.cpp | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/game/shared/tf2/weapon_combat_chargeableplasma.cpp b/game/shared/tf2/weapon_combat_chargeableplasma.cpp new file mode 100644 index 0000000..3507030 --- /dev/null +++ b/game/shared/tf2/weapon_combat_chargeableplasma.cpp @@ -0,0 +1,322 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Chargeable Plasma & Shield combo +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "tf_player.h" +#include "weapon_combat_usedwithshieldbase.h" +#include "weapon_combatshield.h" +#include "tf_guidedplasma.h" +#include "in_buttons.h" +#include "tf_gamerules.h" + +#define BURST_FIRE_RATE 0.15 + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CWeaponCombat_ChargeablePlasma : public CWeaponCombatUsedWithShieldBase +{ + DECLARE_CLASS( CWeaponCombat_ChargeablePlasma, CWeaponCombatUsedWithShieldBase ); +public: + DECLARE_SERVERCLASS(); + + virtual void ItemPostFrame( void ); + virtual void PrimaryAttack( void ); + virtual float GetFireRate( void ); + virtual void Spawn(); + virtual bool Deploy( void ); + virtual bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); + virtual void Precache( void ); + virtual void GainedNewTechnology( CBaseTechnology *pTechnology ); + virtual CBaseEntity *GetLockTarget( void ); + +private: + CNetworkVar( bool, m_bCharging ); + float m_flChargeStartTime; + float m_flPower; + float m_flNextBurstShotTime; + int m_iBurstShotsRemaining; + bool m_bHasBurstShot; + bool m_bHasCharge; + + // Guidance + EHANDLE m_hLockTarget; + Vector m_vecTargetOffset; + float m_flLockedAt; +}; + +IMPLEMENT_SERVERCLASS_ST(CWeaponCombat_ChargeablePlasma, DT_WeaponCombat_ChargeablePlasma ) + SendPropInt( SENDINFO( m_bCharging ), 1, SPROP_UNSIGNED ), +END_SEND_TABLE() + +LINK_ENTITY_TO_CLASS( weapon_combat_chargeableplasma, CWeaponCombat_ChargeablePlasma ); +PRECACHE_WEAPON_REGISTER(weapon_combat_chargeableplasma); + + +//----------------------------------------------------------------------------- +// Spawn weapon +//----------------------------------------------------------------------------- +void CWeaponCombat_ChargeablePlasma::Spawn() +{ + BaseClass::Spawn(); + m_bHasBurstShot = false; + m_bHasCharge = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCombat_ChargeablePlasma::Precache( void ) +{ + BaseClass::Precache(); +} + +//----------------------------------------------------------------------------- +// 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 CWeaponCombat_ChargeablePlasma::ItemPostFrame( void ) +{ + CBaseTFPlayer *pOwner = ToBaseTFPlayer( GetOwner() ); + if (!pOwner) + return; + + if ( UsesClipsForAmmo1() ) + { + CheckReload(); + } + + // If burst shots are firing, ignore input + if ( m_iBurstShotsRemaining > 0 ) + { + if ( gpGlobals->curtime < m_flNextBurstShotTime ) + return; + + if ( m_iClip1 > 0 ) + { + PrimaryAttack(); + } + + m_iBurstShotsRemaining--; + m_flNextBurstShotTime = gpGlobals->curtime + BURST_FIRE_RATE; + m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); + return; + } + + // Handle charge firing + if ( m_iClip1 > 0 && GetShieldState() == SS_DOWN && !m_bInReload ) + { + if ( (pOwner->m_nButtons & IN_ATTACK ) ) + { + if (m_bHasCharge) + { + if ( !m_bCharging && (m_flNextPrimaryAttack <= gpGlobals->curtime) ) + { + m_bCharging = true; + m_flChargeStartTime = gpGlobals->curtime; + + // Get a lock target right now + m_hLockTarget = GetLockTarget(); + } + } + else + { + // Fire the plasma shot + if (m_flNextPrimaryAttack <= gpGlobals->curtime) + PrimaryAttack(); + } + } + else if ( m_bCharging ) + { + m_bCharging = false; + + // Fire the plasma shot + PrimaryAttack(); + + // We might be firing a burst shot + if (m_bHasBurstShot) + { + if ( m_flPower >= (MAX_CHARGED_TIME * 0.5) ) + { + if ( m_flPower >= MAX_CHARGED_TIME ) + { + m_iBurstShotsRemaining = 2; + } + else + { + m_iBurstShotsRemaining = 1; + } + + m_flNextBurstShotTime = gpGlobals->curtime + BURST_FIRE_RATE; + } + } + } + } + + // Reload button + if ( m_iBurstShotsRemaining == 0 && !m_bCharging ) + { + if ( pOwner->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload ) + { + Reload(); + } + } + + // Prevent shield post frame if we're not ready to attack, or we're charging + AllowShieldPostFrame( !m_bCharging && ((m_flNextPrimaryAttack <= gpGlobals->curtime) || m_bInReload) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponCombat_ChargeablePlasma::PrimaryAttack( void ) +{ + CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner(); + if (!pPlayer) + return; + + WeaponSound(SINGLE); + + // Fire the bullets + Vector vecSrc = pPlayer->Weapon_ShootPosition( ); + Vector vecAiming; + pPlayer->EyeVectors( &vecAiming ); + + // If we already have a lock target from button down, see if we shouldn't try and get a new one + // Only do this is the button was released immediately + if ( !m_hLockTarget || ( m_flLockedAt < gpGlobals->curtime ) ) + { + m_hLockTarget = GetLockTarget(); + } + + PlayAttackAnimation( GetPrimaryAttackActivity() ); + + // Shift it down a bit so the firer can see it + Vector right; + AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &right, NULL ); + Vector vecStartSpot = vecSrc + Vector(0,0,-8) + right * 12; + + CGuidedPlasma *pShot = CGuidedPlasma::Create(vecStartSpot, vecAiming, m_hLockTarget, m_vecTargetOffset, pPlayer); + + // Set it's charged power level + if (m_bHasCharge) + m_flPower = MIN( MAX_CHARGED_TIME, gpGlobals->curtime - m_flChargeStartTime ); + else + m_flPower = 0.0f; + + float flDamageMult = RemapVal( m_flPower, 0, MAX_CHARGED_TIME, 1.0, MAX_CHARGED_POWER ); + pShot->SetPowerLevel( flDamageMult ); + + m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); + m_iClip1 = m_iClip1 - 1; + m_hLockTarget = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +float CWeaponCombat_ChargeablePlasma::GetFireRate( void ) +{ + return SequenceDuration(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CWeaponCombat_ChargeablePlasma::Deploy( void ) +{ + if ( BaseClass::Deploy() ) + { + GainedNewTechnology(NULL); + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Our player just died +//----------------------------------------------------------------------------- +bool CWeaponCombat_ChargeablePlasma::Holster( CBaseCombatWeapon *pSwitchingTo ) +{ + bool bReturn = BaseClass::Holster(pSwitchingTo); + + // Stop the charging sound + if ( m_bCharging ) + { + m_bCharging = false; + } + + return bReturn; +} + +//----------------------------------------------------------------------------- +// 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; +} |