diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /sp/src/game/server/hl2/weapon_annabelle.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/game/server/hl2/weapon_annabelle.cpp')
| -rw-r--r-- | sp/src/game/server/hl2/weapon_annabelle.cpp | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/sp/src/game/server/hl2/weapon_annabelle.cpp b/sp/src/game/server/hl2/weapon_annabelle.cpp new file mode 100644 index 00000000..047e32a9 --- /dev/null +++ b/sp/src/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;
+}
|