source-engine/game/shared/hl1/hl1mp_weapon_hornetgun.cpp
2022-04-16 12:05:19 +03:00

340 lines
7.6 KiB
C++

//========= 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();
}