2018-04-22 15:55:55 +00:00
//======== (C) Copyright 2002 Charles G. Cleveland All rights reserved. =========
//
// The copyright to the contents herein is the property of Charles G. Cleveland.
// The contents may be used and/or copied only with the written permission of
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: AvHGrenadeGun.cpp $
// $Date: 2002/11/22 21:28:16 $
//
//-------------------------------------------------------------------------------
// $Log: AvHGrenadeGun.cpp,v $
// Revision 1.17 2002/11/22 21:28:16 Flayra
// - mp_consistency changes
//
// Revision 1.16 2002/10/16 20:53:09 Flayra
// - Removed weapon upgrade sounds
//
// Revision 1.15 2002/10/03 18:46:26 Flayra
// - Added heavy view model
//
// Revision 1.14 2002/07/24 19:09:16 Flayra
// - Linux issues
//
// Revision 1.13 2002/07/24 18:45:41 Flayra
// - Linux and scripting changes
//
// Revision 1.12 2002/06/25 17:50:59 Flayra
// - Reworking for correct player animations and new enable/disable state, new view model artwork, alien weapon refactoring
//
// Revision 1.11 2002/06/03 16:37:56 Flayra
// - Added different deploy times (this should be refactored a bit more), refactored grenades
//
// Revision 1.10 2002/05/28 17:44:58 Flayra
// - Tweak weapon deploy volume, as Valve's sounds weren't normalized
//
// Revision 1.9 2002/05/23 02:33:42 Flayra
// - Post-crash checkin. Restored @Backup from around 4/16. Contains changes for last four weeks of development.
//
//===============================================================================
# include "AvHPlayer.h"
# ifdef AVH_CLIENT
# include "cl_dll/eventscripts.h"
# include "cl_dll/in_defs.h"
# include "cl_dll/wrect.h"
# include "cl_dll/cl_dll.h"
# endif
# include "../common/hldm.h"
# include "../common/event_api.h"
# include "../common/event_args.h"
# include "../common/vector_util.h"
# include "AvHMarineWeapons.h"
# include "AvHMarineWeaponConstants.h"
# include "AvHServerUtil.h"
LINK_ENTITY_TO_CLASS ( kwGrenadeGun , AvHGrenadeGun ) ;
void V_PunchAxis ( int axis , float punch ) ;
2021-10-29 16:17:22 +00:00
const int kSpecialReloadNone = 0 ;
const int kSpecialReloadGotoReload = 1 ;
const int kSpecialReloadAddGren = 2 ;
const int kSpecialReloadCloseGG = 3 ;
const float kEndReloadAnimationTime = 2.43f ;
2018-04-22 15:55:55 +00:00
void AvHGrenadeGun : : Init ( )
{
this - > mRange = kGGRange ;
this - > mDamage = BALANCE_VAR ( kGrenadeDamage ) ;
2021-10-29 16:17:22 +00:00
this - > m_fInSpecialReload = kSpecialReloadNone ;
2018-04-22 15:55:55 +00:00
}
int AvHGrenadeGun : : GetBarrelLength ( ) const
{
return kGGBarrelLength ;
}
float AvHGrenadeGun : : GetRateOfFire ( ) const
{
return BALANCE_VAR ( kGGROF ) ;
}
int AvHGrenadeGun : : GetDeployAnimation ( ) const
{
int theAnimation = - 1 ;
int theShotsInClip = this - > GetShotsInClip ( ) ;
switch ( theShotsInClip )
{
case 4 :
case 0 :
theAnimation = 13 ;
break ;
case 3 :
theAnimation = 14 ;
break ;
case 2 :
theAnimation = 15 ;
break ;
case 1 :
theAnimation = 16 ;
break ;
}
return theAnimation ;
}
char * AvHGrenadeGun : : GetDeploySound ( ) const
{
return kGGDeploySound ;
}
float AvHGrenadeGun : : GetReloadTime ( void ) const
{
int theShotsToLoad = BALANCE_VAR ( kGGMaxClip ) - this - > GetShotsInClip ( ) ;
float theBaseReloadTime = BALANCE_VAR ( kGrenadeLauncherBaseReloadTime ) ;
float theGrenadeReloadTime = BALANCE_VAR ( kGrenadeLauncherGrenadeReloadTime ) ;
float theEndReloadTime = BALANCE_VAR ( kGrenadeLauncherEndReloadTime ) ;
return theBaseReloadTime + theShotsToLoad * theGrenadeReloadTime + theEndReloadTime ;
}
bool AvHGrenadeGun : : GetHasMuzzleFlash ( ) const
{
return true ;
}
void AvHGrenadeGun : : GetEventOrigin ( Vector & outOrigin ) const
{
Vector theGunPosition = this - > m_pPlayer - > GetGunPosition ( ) ;
VectorCopy ( theGunPosition , outOrigin ) ;
}
void AvHGrenadeGun : : GetEventAngles ( Vector & outAngles ) const
{
float theGrenadeForce = BALANCE_VAR ( kGrenadeForce ) ;
Vector theAiming = this - > m_pPlayer - > GetAutoaimVector ( AUTOAIM_5DEGREES ) ;
Vector theVelocity = theAiming * theGrenadeForce + this - > m_pPlayer - > pev - > velocity ;
VectorCopy ( theVelocity , outAngles ) ;
}
char * AvHGrenadeGun : : GetHeavyViewModel ( ) const
{
return kGGHVVModel ;
}
int AvHGrenadeGun : : GetIdleAnimation ( ) const
{
int theAnimation = - 1 ;
int theShotsInClip = this - > GetShotsInClip ( ) ;
switch ( theShotsInClip )
{
case 0 :
case 4 :
theAnimation = 0 ;
break ;
case 1 :
theAnimation = 3 ;
break ;
case 2 :
theAnimation = 2 ;
break ;
case 3 :
theAnimation = 1 ;
break ;
}
return theAnimation ;
}
char * AvHGrenadeGun : : GetPlayerModel ( ) const
{
return kGGPModel ;
}
int AvHGrenadeGun : : GetReloadAnimation ( ) const
{
int theAnimation = - 1 ;
2021-10-29 16:17:22 +00:00
int ShotsEmpty = this - > GetClipSize ( ) - this - > GetShotsInClip ( ) ;
int Shotsleft = this - > m_pPlayer - > m_rgAmmo [ this - > m_iPrimaryAmmoType ] ;
int ShotsToReload = min ( ShotsEmpty , Shotsleft ) ;
2018-04-22 15:55:55 +00:00
2021-10-29 16:17:22 +00:00
switch ( ShotsToReload )
2018-04-22 15:55:55 +00:00
{
2021-10-29 16:17:22 +00:00
case 4 :
2018-04-22 15:55:55 +00:00
theAnimation = 7 ;
break ;
2021-10-29 16:17:22 +00:00
case 3 :
2018-04-22 15:55:55 +00:00
theAnimation = 6 ;
break ;
2021-10-29 16:17:22 +00:00
2018-04-22 15:55:55 +00:00
case 2 :
theAnimation = 5 ;
break ;
2021-10-29 16:17:22 +00:00
case 1 :
2018-04-22 15:55:55 +00:00
theAnimation = 4 ;
break ;
}
2021-10-29 16:17:22 +00:00
2018-04-22 15:55:55 +00:00
return theAnimation ;
}
int AvHGrenadeGun : : GetEmptyShootAnimation ( ) const
{
return 12 ;
}
int AvHGrenadeGun : : GetShootAnimation ( ) const
{
int theAnimation = - 1 ;
int theShotsInClip = this - > GetShotsInClip ( ) ;
switch ( theShotsInClip )
{
case 4 :
theAnimation = 8 ;
break ;
case 3 :
theAnimation = 9 ;
break ;
case 2 :
theAnimation = 10 ;
break ;
case 1 :
theAnimation = 11 ;
break ;
case 0 :
theAnimation = 12 ;
break ;
}
return theAnimation ;
}
2021-10-29 16:17:22 +00:00
int AvHGrenadeGun : : GetEndAnimation ( ) const
{
int theAnimation = - 1 ;
int theShotsInClip = this - > GetShotsInClip ( ) ;
switch ( theShotsInClip )
{
case 1 :
theAnimation = 17 ;
break ;
case 2 :
case 3 :
theAnimation = 18 ;
break ;
}
return theAnimation ;
}
2018-04-22 15:55:55 +00:00
char * AvHGrenadeGun : : GetViewModel ( ) const
{
return kGGVModel ;
}
char * AvHGrenadeGun : : GetWorldModel ( ) const
{
return kGGWModel ;
}
void AvHGrenadeGun : : FireProjectiles ( void )
{
# ifdef AVH_SERVER
Vector theOrigin ;
this - > GetEventOrigin ( theOrigin ) ;
// Grenade gun uses velocity here instead of angles, assumes angles are the player angles (for both the server grenade and the client temp entity)
Vector theVelocity ;
this - > GetEventAngles ( theVelocity ) ;
// How to handle this? Only generate entity on server, but we should do SOMETHING on the client, no?
CGrenade * theGrenade = AvHSUShootServerGrenade ( this - > m_pPlayer - > pev , theOrigin , theVelocity , BALANCE_VAR ( kGrenDetonateTime ) , false ) ;
ASSERT ( theGrenade ) ;
theGrenade - > pev - > dmg = this - > mDamage ;
# endif
}
void AvHGrenadeGun : : Precache ( )
{
AvHMarineWeapon : : Precache ( ) ;
PRECACHE_UNMODIFIED_MODEL ( kGGEjectModel ) ;
PRECACHE_UNMODIFIED_MODEL ( kGGAmmoModel ) ;
PRECACHE_UNMODIFIED_SOUND ( kGrenadeBounceSound1 ) ;
PRECACHE_UNMODIFIED_SOUND ( kGrenadeBounceSound2 ) ;
PRECACHE_UNMODIFIED_SOUND ( kGrenadeBounceSound3 ) ;
PRECACHE_UNMODIFIED_SOUND ( kGGFireSound1 ) ;
PRECACHE_UNMODIFIED_SOUND ( kGGReloadSound ) ;
this - > mEvent = PRECACHE_EVENT ( 1 , kGGEventName ) ;
}
2021-10-29 16:17:22 +00:00
void AvHGrenadeGun : : DeductCostForShot ( void )
{
AvHMarineWeapon : : DeductCostForShot ( ) ;
// Stop reload if we were in the middle of one
if ( this - > m_fInSpecialReload ! = kSpecialReloadNone )
{
this - > m_fInSpecialReload = kSpecialReloadNone ;
}
}
int AvHGrenadeGun : : DefaultReload ( int iClipSize , int iAnim , float fDelay )
{
// Needed to prevet super fast default reload
return FALSE ;
}
void AvHGrenadeGun : : Holster ( int skiplocal )
{
AvHMarineWeapon : : Holster ( skiplocal ) ;
// Cancel any reload in progress.
this - > m_fInSpecialReload = kSpecialReloadNone ;
}
void AvHGrenadeGun : : Reload ( void )
{
int theClipSize = this - > GetClipSize ( ) ;
if ( ( this - > m_pPlayer - > m_rgAmmo [ this - > m_iPrimaryAmmoType ] > 0 ) & & ( m_iClip < theClipSize ) )
{
if ( this - > m_fInSpecialReload = = kSpecialReloadCloseGG )
{
this - > SendWeaponAnim ( this - > GetEndAnimation ( ) ) ;
//Timings here made to match animations as well as reload length of the previous reload version. Numbers are seconds*2 because they get decremented twice in NS.
this - > m_flTimeWeaponIdle = UTIL_WeaponTimeBase ( ) + kEndReloadAnimationTime ;
this - > m_flNextPrimaryAttack = UTIL_WeaponTimeBase ( ) + kEndReloadAnimationTime ;
this - > m_flNextSecondaryAttack = UTIL_WeaponTimeBase ( ) + kEndReloadAnimationTime ;
//this->m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + kEndReloadAnimationTime;
this - > m_pPlayer - > SetAnimation ( PLAYER_RELOAD_END ) ;
this - > m_fInSpecialReload = kSpecialReloadNone ;
}
else if ( this - > m_fInSpecialReload = = kSpecialReloadAddGren )
{
// Add to grenade count at specified time in the middle of reload to sync with animation and sound.
if ( m_flTimeWeaponIdle < = UTIL_WeaponTimeBase ( ) )
{
// Add them to the clip
this - > m_iClip + = 1 ;
this - > m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] - = 1 ;
if ( this - > m_iClip < theClipSize & & ( this - > m_pPlayer - > m_rgAmmo [ this - > m_iPrimaryAmmoType ] ! = 0 ) )
{
this - > m_fInSpecialReload = kSpecialReloadGotoReload ;
}
else
{
this - > m_fInSpecialReload = kSpecialReloadNone ;
this - > m_flTimeWeaponIdle = UTIL_WeaponTimeBase ( ) + kEndReloadAnimationTime ;
this - > m_flNextPrimaryAttack = UTIL_WeaponTimeBase ( ) + kEndReloadAnimationTime ;
this - > m_flNextSecondaryAttack = UTIL_WeaponTimeBase ( ) + kEndReloadAnimationTime ;
this - > m_pPlayer - > SetAnimation ( PLAYER_RELOAD_END ) ;
}
}
}
// don't reload until recoil is done
else if ( this - > m_flNextPrimaryAttack < = UTIL_WeaponTimeBase ( ) )
{
if ( this - > m_fInSpecialReload = = kSpecialReloadNone )
{
// Start reload
this - > m_fInSpecialReload = kSpecialReloadGotoReload ;
this - > SendWeaponAnim ( this - > GetReloadAnimation ( ) ) ;
const float theGotoReloadAnimationTime = 1.1f ;
this - > m_flTimeWeaponIdle = UTIL_WeaponTimeBase ( ) + theGotoReloadAnimationTime ;
this - > m_flNextPrimaryAttack = UTIL_WeaponTimeBase ( ) + theGotoReloadAnimationTime ;
this - > m_flNextSecondaryAttack = UTIL_WeaponTimeBase ( ) + theGotoReloadAnimationTime ;
//this->m_pPlayer->SetAnimation(PLAYER_RELOAD);
this - > m_pPlayer - > SetAnimation ( PLAYER_RELOAD_START ) ;
}
else if ( this - > m_fInSpecialReload = = kSpecialReloadGotoReload )
{
if ( m_flTimeWeaponIdle < = UTIL_WeaponTimeBase ( ) )
{
this - > m_fInSpecialReload = kSpecialReloadAddGren ;
const float theGrenReloadTime = 2.4f ;
this - > m_flTimeWeaponIdle = UTIL_WeaponTimeBase ( ) + theGrenReloadTime ;
this - > m_flNextPrimaryAttack = UTIL_WeaponTimeBase ( ) + theGrenReloadTime ;
this - > m_flNextSecondaryAttack = UTIL_WeaponTimeBase ( ) + theGrenReloadTime ;
this - > m_pPlayer - > SetAnimation ( PLAYER_RELOAD_INSERT ) ;
}
}
}
}
2023-08-20 21:32:34 +00:00
else
{
this - > m_fInSpecialReload = kSpecialReloadNone ;
}
2021-10-29 16:17:22 +00:00
}
void AvHGrenadeGun : : WeaponIdle ( void )
{
// : 0000484 - ensures that all idle weapons can fire the empty sound
ResetEmptySound ( ) ;
if ( this - > m_flTimeWeaponIdle < UTIL_WeaponTimeBase ( ) )
{
if ( ( this - > m_iClip = = 0 ) & & ( this - > m_fInSpecialReload = = kSpecialReloadNone ) & & m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] )
{
this - > Reload ( ) ;
}
else if ( this - > m_fInSpecialReload ! = kSpecialReloadNone )
{
if ( ( m_iClip ! = this - > GetClipSize ( ) ) & & m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] )
{
this - > Reload ( ) ;
}
else
{
// reload debounce has timed out
this - > m_fInSpecialReload = kSpecialReloadNone ;
//ALERT(at_console, "specreset time:%g idle:%g primary:%g specrel:%d\n", gpGlobals->time, this->m_flTimeWeaponIdle, this->m_flNextPrimaryAttack, m_fInSpecialReload);
this - > SendWeaponAnim ( this - > GetEndAnimation ( ) ) ;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase ( ) + kEndReloadAnimationTime ;
this - > m_pPlayer - > SetAnimation ( PLAYER_RELOAD_END ) ;
}
}
//else
//{
// Hack to prevent idle animation from playing mid-reload. Not sure how to fix this right, but all this special reloading is happening server-side, client doesn't know about it
//if (m_iClip == this->GetClipSize())
//{
// AvHMarineWeapon::WeaponIdle();
//}
//}
}
}
2018-04-22 15:55:55 +00:00
void AvHGrenadeGun : : Spawn ( )
{
AvHMarineWeapon : : Spawn ( ) ;
Precache ( ) ;
this - > m_iId = AVH_WEAPON_GRENADE_GUN ;
m_iDefaultAmmo = BALANCE_VAR ( kGGMaxClip ) ;
// Set our class name
this - > pev - > classname = MAKE_STRING ( kwsGrenadeGun ) ;
SET_MODEL ( ENT ( this - > pev ) , kGGWModel ) ;
FallInit ( ) ; // get ready to fall down.
}