//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Hornetgun // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "npcevent.h" #include "hl1mp_basecombatweapon_shared.h" //#include "basecombatcharacter.h" //#include "AI_BaseNPC.h" #include "gamerules.h" #include "in_buttons.h" #ifdef CLIENT_DLL #include "hl1/c_hl1mp_player.h" #else #include "hl1mp_player.h" #include "soundent.h" #include "game.h" #endif #include "vstdlib/random.h" #include "engine/IEngineSound.h" #if !defined(CLIENT_DLL) #include "hl1_npc_hornet.h" #endif //----------------------------------------------------------------------------- // CWeaponHgun //----------------------------------------------------------------------------- #ifdef CLIENT_DLL #define CWeaponHgun C_WeaponHgun #endif class CWeaponHgun : public CBaseHL1MPCombatWeapon { DECLARE_CLASS( CWeaponHgun, CBaseHL1MPCombatWeapon ); public: DECLARE_NETWORKCLASS(); DECLARE_PREDICTABLE(); CWeaponHgun( void ); void Precache( void ); void PrimaryAttack( void ); void SecondaryAttack( void ); void WeaponIdle( void ); bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); bool Reload( void ); virtual void ItemPostFrame( void ); // DECLARE_SERVERCLASS(); DECLARE_DATADESC(); private: // float m_flRechargeTime; // int m_iFirePhase; CNetworkVar( float, m_flRechargeTime ); CNetworkVar( int, m_iFirePhase ); }; IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHgun, DT_WeaponHgun ); BEGIN_NETWORK_TABLE( CWeaponHgun, DT_WeaponHgun ) #ifdef CLIENT_DLL RecvPropFloat( RECVINFO( m_flRechargeTime ) ), RecvPropInt( RECVINFO( m_iFirePhase ) ), #else SendPropFloat( SENDINFO( m_flRechargeTime ) ), SendPropInt( SENDINFO( m_iFirePhase ) ), #endif END_NETWORK_TABLE() BEGIN_PREDICTION_DATA( CWeaponHgun ) #ifdef CLIENT_DLL DEFINE_PRED_FIELD( m_flRechargeTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), DEFINE_PRED_FIELD( m_iFirePhase, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), #endif END_PREDICTION_DATA() LINK_ENTITY_TO_CLASS( weapon_hornetgun, CWeaponHgun ); PRECACHE_WEAPON_REGISTER( weapon_hornetgun ); //IMPLEMENT_SERVERCLASS_ST( CWeaponHgun, DT_WeaponHgun ) //END_SEND_TABLE() BEGIN_DATADESC( CWeaponHgun ) DEFINE_FIELD( m_flRechargeTime, FIELD_TIME ), DEFINE_FIELD( m_iFirePhase, FIELD_INTEGER ), END_DATADESC() //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- CWeaponHgun::CWeaponHgun( void ) { m_bReloadsSingly = false; m_bFiresUnderwater = true; m_flRechargeTime = 0.0; m_iFirePhase = 0; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponHgun::Precache( void ) { #ifndef CLIENT_DLL UTIL_PrecacheOther( "hornet" ); #endif BaseClass::Precache(); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponHgun::PrimaryAttack( void ) { CHL1_Player *pPlayer = ToHL1Player( GetOwner() ); if ( !pPlayer ) { return; } if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) { return; } WeaponSound( SINGLE ); #if !defined(CLIENT_DLL) CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 ); #endif pPlayer->DoMuzzleFlash(); SendWeaponAnim( ACT_VM_PRIMARYATTACK ); pPlayer->SetAnimation( PLAYER_ATTACK1 ); Vector vForward, vRight, vUp; QAngle vecAngles; pPlayer->EyeVectors( &vForward, &vRight, &vUp ); VectorAngles( vForward, vecAngles ); #if !defined(CLIENT_DLL) CBaseEntity *pHornet = CBaseEntity::Create( "hornet", pPlayer->Weapon_ShootPosition() + vForward * 16 + vRight * 8 + vUp * -12, vecAngles, pPlayer ); pHornet->SetAbsVelocity( vForward * 300 ); #endif m_flRechargeTime = gpGlobals->curtime + 0.5; pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType ); pPlayer->ViewPunch( QAngle( -2, 0, 0 ) ); m_flNextPrimaryAttack = m_flNextPrimaryAttack + 0.25; if (m_flNextPrimaryAttack < gpGlobals->curtime ) { m_flNextPrimaryAttack = gpGlobals->curtime + 0.25; } SetWeaponIdleTime( random->RandomFloat( 10, 15 ) ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponHgun::SecondaryAttack( void ) { CHL1_Player *pPlayer = ToHL1Player( GetOwner() ); if ( !pPlayer ) { return; } if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) { return; } WeaponSound( SINGLE ); #if !defined(CLIENT_DLL) CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 200, 0.2 ); #endif pPlayer->DoMuzzleFlash(); SendWeaponAnim( ACT_VM_PRIMARYATTACK ); pPlayer->SetAnimation( PLAYER_ATTACK1 ); CBaseEntity *pHornet; Vector vecSrc; Vector vForward, vRight, vUp; QAngle vecAngles; pPlayer->EyeVectors( &vForward, &vRight, &vUp ); VectorAngles( vForward, vecAngles ); vecSrc = pPlayer->Weapon_ShootPosition() + vForward * 16 + vRight * 8 + vUp * -12; m_iFirePhase++; switch ( m_iFirePhase ) { case 1: vecSrc = vecSrc + vUp * 8; break; case 2: vecSrc = vecSrc + vUp * 8; vecSrc = vecSrc + vRight * 8; break; case 3: vecSrc = vecSrc + vRight * 8; break; case 4: vecSrc = vecSrc + vUp * -8; vecSrc = vecSrc + vRight * 8; break; case 5: vecSrc = vecSrc + vUp * -8; break; case 6: vecSrc = vecSrc + vUp * -8; vecSrc = vecSrc + vRight * -8; break; case 7: vecSrc = vecSrc + vRight * -8; break; case 8: vecSrc = vecSrc + vUp * 8; vecSrc = vecSrc + vRight * -8; m_iFirePhase = 0; break; } #ifdef CLIENT_DLL pHornet = NULL; #else pHornet = CBaseEntity::Create( "hornet", vecSrc, vecAngles, pPlayer ); pHornet->SetAbsVelocity( vForward * 1200 ); pHornet->SetThink( &CNPC_Hornet::StartDart ); #endif m_flRechargeTime = gpGlobals->curtime + 0.5; pPlayer->ViewPunch( QAngle( -2, 0, 0 ) ); pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType ); m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + 0.1; SetWeaponIdleTime( random->RandomFloat( 10, 15 ) ); } void CWeaponHgun::WeaponIdle( void ) { if ( !HasWeaponIdleTimeElapsed() ) return; int iAnim; float flRand = random->RandomFloat( 0, 1 ); if ( flRand <= 0.75 ) { iAnim = ACT_VM_IDLE; } else { iAnim = ACT_VM_FIDGET; } SendWeaponAnim( iAnim ); } bool CWeaponHgun::Holster( CBaseCombatWeapon *pSwitchingTo ) { bool bRet; bRet = BaseClass::Holster( pSwitchingTo ); if ( bRet ) { CHL1_Player *pPlayer = ToHL1Player( GetOwner() ); if ( pPlayer ) { #if !defined(CLIENT_DLL) //!!!HACKHACK - can't select hornetgun if it's empty! no way to get ammo for it, either. int iCount = pPlayer->GetAmmoCount( m_iPrimaryAmmoType ); if ( iCount <= 0 ) { pPlayer->GiveAmmo( iCount+1, m_iPrimaryAmmoType, true ); } #endif } } return bRet; } bool CWeaponHgun::Reload( void ) { if ( m_flRechargeTime >= gpGlobals->curtime ) { return true; } CHL1_Player *pPlayer = ToHL1Player( GetOwner() ); if ( !pPlayer ) { return true; } #ifdef CLIENT_DLL #else if ( !g_pGameRules->CanHaveAmmo( pPlayer, m_iPrimaryAmmoType ) ) return true; while ( ( m_flRechargeTime < gpGlobals->curtime ) && g_pGameRules->CanHaveAmmo( pPlayer, m_iPrimaryAmmoType ) ) { pPlayer->GiveAmmo( 1, m_iPrimaryAmmoType, true ); m_flRechargeTime += 0.5; } #endif return true; } void CWeaponHgun::ItemPostFrame( void ) { Reload(); BaseClass::ItemPostFrame(); }