diff options
Diffstat (limited to 'game/server/hl1/hl1_weapon_snark.cpp')
| -rw-r--r-- | game/server/hl1/hl1_weapon_snark.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/game/server/hl1/hl1_weapon_snark.cpp b/game/server/hl1/hl1_weapon_snark.cpp new file mode 100644 index 0000000..9339297 --- /dev/null +++ b/game/server/hl1/hl1_weapon_snark.cpp @@ -0,0 +1,208 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Snark +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "npcevent.h" +#include "hl1_basecombatweapon_shared.h" +#include "basecombatcharacter.h" +#include "ai_basenpc.h" +#include "player.h" +#include "gamerules.h" +#include "in_buttons.h" +#include "soundent.h" +#include "game.h" +#include "vstdlib/random.h" +#include "engine/IEngineSound.h" +#include "hl1_npc_snark.h" +#include "beam_shared.h" + + +//----------------------------------------------------------------------------- +// CWeaponSnark +//----------------------------------------------------------------------------- + + +#define SNARK_NEST_MODEL "models/w_sqknest.mdl" + + +class CWeaponSnark : public CBaseHL1CombatWeapon +{ + DECLARE_CLASS( CWeaponSnark, CBaseHL1CombatWeapon ); +public: + + CWeaponSnark( void ); + + void Precache( void ); + void PrimaryAttack( void ); + void WeaponIdle( void ); + bool Deploy( void ); + bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); + + DECLARE_SERVERCLASS(); + DECLARE_DATADESC(); + +private: + bool m_bJustThrown; +}; + +LINK_ENTITY_TO_CLASS( weapon_snark, CWeaponSnark ); + +PRECACHE_WEAPON_REGISTER( weapon_snark ); + +IMPLEMENT_SERVERCLASS_ST( CWeaponSnark, DT_WeaponSnark ) +END_SEND_TABLE() + +BEGIN_DATADESC( CWeaponSnark ) + DEFINE_FIELD( m_bJustThrown, FIELD_BOOLEAN ), +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CWeaponSnark::CWeaponSnark( void ) +{ + m_bReloadsSingly = false; + m_bFiresUnderwater = true; + m_bJustThrown = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponSnark::Precache( void ) +{ + BaseClass::Precache(); + + PrecacheScriptSound( "WpnSnark.PrimaryAttack" ); + PrecacheScriptSound( "WpnSnark.Deploy" ); + + UTIL_PrecacheOther("monster_snark"); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeaponSnark::PrimaryAttack( void ) +{ + // Only the player fires this way so we can cast + CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + + if ( !pPlayer ) + { + return; + } + + if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) + return; + + Vector vecForward; + pPlayer->EyeVectors( &vecForward ); + + // find place to toss monster + // Does this need to consider a crouched player? + Vector vecStart = pPlayer->WorldSpaceCenter() + (vecForward * 20); + Vector vecEnd = vecStart + (vecForward * 44); + trace_t tr; + UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); + if ( tr.allsolid || tr.startsolid || tr.fraction <= 0.25 ) + return; + + // player "shoot" animation + SendWeaponAnim( ACT_VM_PRIMARYATTACK ); + pPlayer->SetAnimation( PLAYER_ATTACK1 ); + + CSnark *pSnark = (CSnark*)Create( "monster_snark", tr.endpos, pPlayer->EyeAngles(), GetOwner() ); + if ( pSnark ) + { + pSnark->SetAbsVelocity( vecForward * 200 + pPlayer->GetAbsVelocity() ); + } + + // play hunt sound + CPASAttenuationFilter filter( this ); + EmitSound( filter, entindex(), "WpnSnark.PrimaryAttack" ); + + CSoundEnt::InsertSound( SOUND_DANGER, GetAbsOrigin(), 200, 0.2 ); + + pPlayer->RemoveAmmo( 1, m_iPrimaryAmmoType ); + + m_bJustThrown = true; + + m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; + SetWeaponIdleTime( gpGlobals->curtime + 1.0 ); +} + +void CWeaponSnark::WeaponIdle( void ) +{ + CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + + if ( !pPlayer ) + { + return; + } + + if ( !HasWeaponIdleTimeElapsed() ) + return; + + if ( m_bJustThrown ) + { + m_bJustThrown = false; + + if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) + { + if ( !pPlayer->SwitchToNextBestWeapon( pPlayer->GetActiveWeapon() ) ) + Holster(); + } + else + { + SendWeaponAnim( ACT_VM_DRAW ); + SetWeaponIdleTime( gpGlobals->curtime + random->RandomFloat( 10, 15 ) ); + } + } + else + { + if ( random->RandomFloat( 0, 1 ) <= 0.75 ) + { + SendWeaponAnim( ACT_VM_IDLE ); + } + else + { + SendWeaponAnim( ACT_VM_FIDGET ); + } + } +} + +bool CWeaponSnark::Deploy( void ) +{ + CPASAttenuationFilter filter( this ); + EmitSound( filter, entindex(), "WpnSnark.Deploy" ); + + return BaseClass::Deploy(); +} + +bool CWeaponSnark::Holster( CBaseCombatWeapon *pSwitchingTo ) +{ + CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); + if ( !pPlayer ) + { + return false; + } + + if ( !BaseClass::Holster( pSwitchingTo ) ) + { + return false; + } + + if ( pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 ) + { + SetThink( &CWeaponSnark::DestroyItem ); + SetNextThink( gpGlobals->curtime + 0.1 ); + } + + pPlayer->SetNextAttack( gpGlobals->curtime + 0.5 ); + + return true; +} |