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/server/hl2/weapon_annabelle.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/server/hl2/weapon_annabelle.cpp')
| -rw-r--r-- | game/server/hl2/weapon_annabelle.cpp | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/game/server/hl2/weapon_annabelle.cpp b/game/server/hl2/weapon_annabelle.cpp new file mode 100644 index 0000000..94a8a1a --- /dev/null +++ b/game/server/hl2/weapon_annabelle.cpp @@ -0,0 +1,350 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Grigori's personal shotgun (npc_monk) +// +//=============================================================================// + +#include "cbase.h" +#include "npcevent.h" +#include "basehlcombatweapon_shared.h" +#include "basecombatcharacter.h" +#include "ai_basenpc.h" +#include "player.h" +#include "gamerules.h" // For g_pGameRules +#include "in_buttons.h" +#include "soundent.h" +#include "vstdlib/random.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern ConVar sk_auto_reload_time; + +class CWeaponAnnabelle : public CBaseHLCombatWeapon +{ + DECLARE_DATADESC(); +public: + DECLARE_CLASS( CWeaponAnnabelle, CBaseHLCombatWeapon ); + + DECLARE_SERVERCLASS(); + +private: + bool m_bNeedPump; // When emptied completely + bool m_bDelayedFire1; // Fire primary when finished reloading + bool m_bDelayedFire2; // Fire secondary when finished reloading + +public: + void Precache( void ); + + int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; } + + virtual const Vector& GetBulletSpread( void ) + { + static Vector cone = vec3_origin; + return cone; + } + + virtual int GetMinBurst() { return 1; } + virtual int GetMaxBurst() { return 3; } + + void ItemHolsterFrame( void ); + bool StartReload( void ); + bool Reload( void ); + void FillClip( void ); + void FinishReload( void ); + void CheckHolsterReload( void ); + void Pump( void ); + void DryFire( void ); + virtual float GetFireRate( void ) { return 1.5; }; + virtual float GetMinRestTime() { return 1.0; } + virtual float GetMaxRestTime() { return 1.5; } + + void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); + + DECLARE_ACTTABLE(); + + CWeaponAnnabelle(void); +}; + +IMPLEMENT_SERVERCLASS_ST(CWeaponAnnabelle, DT_WeaponAnnabelle) +END_SEND_TABLE() + +LINK_ENTITY_TO_CLASS( weapon_annabelle, CWeaponAnnabelle ); +#ifndef HL2MP +PRECACHE_WEAPON_REGISTER(weapon_annabelle); +#endif + +BEGIN_DATADESC( CWeaponAnnabelle ) + DEFINE_FIELD( m_bNeedPump, FIELD_BOOLEAN ), + DEFINE_FIELD( m_bDelayedFire1, FIELD_BOOLEAN ), + DEFINE_FIELD( m_bDelayedFire2, FIELD_BOOLEAN ), +END_DATADESC() + +acttable_t CWeaponAnnabelle::m_acttable[] = +{ + { ACT_IDLE_ANGRY, ACT_IDLE_ANGRY_SMG1, true }, + { ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, true }, + { ACT_RELOAD, ACT_RELOAD_SMG1, true }, + { ACT_WALK, ACT_WALK_RIFLE, true }, + { ACT_WALK_AIM, ACT_WALK_AIM_RIFLE, true }, + { ACT_WALK_CROUCH, ACT_WALK_CROUCH_RIFLE, false }, + { ACT_WALK_CROUCH_AIM, ACT_WALK_CROUCH_AIM_RIFLE, false }, + { ACT_RUN, ACT_RUN_RIFLE, true }, + { ACT_RUN_AIM, ACT_RUN_AIM_RIFLE, true }, + { ACT_RUN_CROUCH, ACT_RUN_CROUCH_RIFLE, false }, + { ACT_RUN_CROUCH_AIM, ACT_RUN_CROUCH_AIM_RIFLE, false }, + { ACT_GESTURE_RANGE_ATTACK1, ACT_GESTURE_RANGE_ATTACK_SHOTGUN, true }, + { ACT_RELOAD_LOW, ACT_RELOAD_SMG1_LOW, false }, + { ACT_GESTURE_RELOAD, ACT_GESTURE_RELOAD_SMG1, false }, +}; + +IMPLEMENT_ACTTABLE(CWeaponAnnabelle); + +void CWeaponAnnabelle::Precache( void ) +{ + CBaseCombatWeapon::Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +void CWeaponAnnabelle::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) +{ + switch( pEvent->event ) + { + case EVENT_WEAPON_SHOTGUN_FIRE: + { + Vector vecShootOrigin, vecShootDir; + vecShootOrigin = pOperator->Weapon_ShootPosition(); + CAI_BaseNPC *npc = pOperator->MyNPCPointer(); + ASSERT( npc != NULL ); + WeaponSound( SINGLE_NPC ); + pOperator->DoMuzzleFlash(); + m_iClip1 = m_iClip1 - 1; + + vecShootDir = npc->GetActualShootTrajectory( vecShootOrigin ); + pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 ); + } + break; + + default: + CBaseCombatWeapon::Operator_HandleAnimEvent( pEvent, pOperator ); + break; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Override so only reload one shell at a time +// Input : +// Output : +//----------------------------------------------------------------------------- +bool CWeaponAnnabelle::StartReload( void ) +{ + CBaseCombatCharacter *pOwner = GetOwner(); + + if ( pOwner == NULL ) + return false; + + if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0) + return false; + + if (m_iClip1 >= GetMaxClip1()) + return false; + + // If shotgun totally emptied then a pump animation is needed + if (m_iClip1 <= 0) + { + m_bNeedPump = true; + } + + int j = MIN(1, pOwner->GetAmmoCount(m_iPrimaryAmmoType)); + + if (j <= 0) + return false; + + SendWeaponAnim( ACT_SHOTGUN_RELOAD_START ); + + // Make shotgun shell visible + SetBodygroup(1,0); + + pOwner->m_flNextAttack = gpGlobals->curtime; + m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); + + m_bInReload = true; + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Override so only reload one shell at a time +// Input : +// Output : +//----------------------------------------------------------------------------- +bool CWeaponAnnabelle::Reload( void ) +{ + // Check that StartReload was called first + if (!m_bInReload) + { + Warning("ERROR: Shotgun Reload called incorrectly!\n"); + } + + CBaseCombatCharacter *pOwner = GetOwner(); + + if ( pOwner == NULL ) + return false; + + if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0) + return false; + + if (m_iClip1 >= GetMaxClip1()) + return false; + + int j = MIN(1, pOwner->GetAmmoCount(m_iPrimaryAmmoType)); + + if (j <= 0) + return false; + + FillClip(); + // Play reload on different channel as otherwise steals channel away from fire sound + WeaponSound(RELOAD); + SendWeaponAnim( ACT_VM_RELOAD ); + + pOwner->m_flNextAttack = gpGlobals->curtime; + m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Play finish reload anim and fill clip +// Input : +// Output : +//----------------------------------------------------------------------------- +void CWeaponAnnabelle::FinishReload( void ) +{ + // Make shotgun shell invisible + SetBodygroup(1,1); + + CBaseCombatCharacter *pOwner = GetOwner(); + + if ( pOwner == NULL ) + return; + + m_bInReload = false; + + // Finish reload animation + SendWeaponAnim( ACT_SHOTGUN_RELOAD_FINISH ); + + pOwner->m_flNextAttack = gpGlobals->curtime; + m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +} + +//----------------------------------------------------------------------------- +// Purpose: Play finish reload anim and fill clip +// Input : +// Output : +//----------------------------------------------------------------------------- +void CWeaponAnnabelle::FillClip( void ) +{ + CBaseCombatCharacter *pOwner = GetOwner(); + + if ( pOwner == NULL ) + return; + + // Add them to the clip + if ( pOwner->GetAmmoCount( m_iPrimaryAmmoType ) > 0 ) + { + if ( Clip1() < GetMaxClip1() ) + { + m_iClip1++; + pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Play weapon pump anim +// Input : +// Output : +//----------------------------------------------------------------------------- +void CWeaponAnnabelle::Pump( void ) +{ + CBaseCombatCharacter *pOwner = GetOwner(); + + if ( pOwner == NULL ) + return; + + m_bNeedPump = false; + + WeaponSound( SPECIAL1 ); + + // Finish reload animation + SendWeaponAnim( ACT_SHOTGUN_PUMP ); + + pOwner->m_flNextAttack = gpGlobals->curtime + SequenceDuration(); + m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// +// +//----------------------------------------------------------------------------- +void CWeaponAnnabelle::DryFire( void ) +{ + WeaponSound(EMPTY); + SendWeaponAnim( ACT_VM_DRYFIRE ); + + m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponAnnabelle::ItemHolsterFrame( void ) +{ + // Must be player held + if ( GetOwner() && GetOwner()->IsPlayer() == false ) + return; + + // We can't be active + if ( GetOwner()->GetActiveWeapon() == this ) + return; + + // If it's been longer than three seconds, reload + if ( ( gpGlobals->curtime - m_flHolsterTime ) > sk_auto_reload_time.GetFloat() ) + { + // Reset the timer + m_flHolsterTime = gpGlobals->curtime; + + if ( GetOwner() == NULL ) + return; + + if ( m_iClip1 == GetMaxClip1() ) + return; + + // Just load the clip with no animations + int ammoFill = MIN( (GetMaxClip1() - m_iClip1), GetOwner()->GetAmmoCount( GetPrimaryAmmoType() ) ); + + GetOwner()->RemoveAmmo( ammoFill, GetPrimaryAmmoType() ); + m_iClip1 += ammoFill; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CWeaponAnnabelle::CWeaponAnnabelle( void ) +{ + m_bReloadsSingly = true; + + m_bNeedPump = false; + m_bDelayedFire1 = false; + m_bDelayedFire2 = false; + + m_fMinRange1 = 0.0; + m_fMaxRange1 = 500; + m_fMinRange2 = 0.0; + m_fMaxRange2 = 200; +} |