2018-04-22 15:55:55 +00:00
/***
*
* Copyright ( c ) 1999 , Valve LLC . All rights reserved .
*
* This product contains software technology licensed from Id
* Software , Inc . ( " Id Technology " ) . Id Technology ( c ) 1996 Id Software , Inc .
* All Rights Reserved .
*
* Use , distribution , and modification of this source code and / or resulting
* object code is restricted to non - commercial enhancements to products from
* Valve LLC . All other use , distribution , or modification is prohibited
* without written permission from Valve LLC .
*
* Modified by Charlie Cleveland :
*
* $ Workfile : hl_weapons . cpp $
* $ Date : 2002 / 10 / 24 21 : 11 : 52 $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* $ Log : hl_weapons . cpp , v $
* Revision 1.31 2002 / 10 / 24 21 : 11 : 52 Flayra
* - Updated jetpack effect because it was really buggy this old way
*
* Revision 1.30 2002 / 10 / 16 02 : 12 : 10 Flayra
* - Valve anti - cheat integrated !
*
* Revision 1.29 2002 / 10 / 16 00 : 36 : 40 Flayra
* - Removed blink fail
*
* Revision 1.28 2002 / 08 / 31 18 : 01 : 59 Flayra
* - Work at VALVe
*
* Revision 1.27 2002 / 07 / 08 16 : 09 : 03 Flayra
* - Removed unneeded code here , so random numbers were generated properly on both client and server
*
* Revision 1.26 2002 / 07 / 01 20 : 56 : 31 Flayra
* - Added babbler gun
*
* Revision 1.25 2002 / 06 / 25 17 : 03 : 01 Flayra
* - Removed old weapons , added new weapons , fixed mines , iuser3 enables and disables weapons
*
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* * * */
# include "../hud.h"
# include "../cl_util.h"
# include "common/const.h"
# include "common/entity_state.h"
# include "common/cl_entity.h"
# include "../demo.h"
# include "common/usercmd.h"
# include "common/event_flags.h"
# include "common/event_api.h"
# include "cl_dll/com_weapons.h"
# include "cl_dll/ammo.h"
# include "cl_dll/ammohistory.h"
# include "dlls/extdll.h"
# include "dlls/util.h"
# include "dlls/cbase.h"
# include "dlls/monsters.h"
# include "dlls/weapons.h"
# include "dlls/nodes.h"
# include "dlls/player.h"
# include "mod/AvHEvents.h"
# include "common/usercmd.h"
# include "common/entity_state.h"
# include "common/demo_api.h"
# include "pm_shared/pm_defs.h"
# include "common/event_api.h"
# include "common/r_efx.h"
# include "../hud_iface.h"
# include "../com_weapons.h"
# include "mod/AvHMarineWeapons.h"
# include "mod/AvHSpecials.h"
# include "mod/AvHAlienWeapons.h"
# include "mod/AvHAlienAbilities.h"
# include "mod/AvHAlienWeaponConstants.h"
# include "mod/AvHAlienAbilityConstants.h"
# include "mod/AvHMovementUtil.h"
# include "engine/APIProxy.h"
# include "../Exports.h"
extern globalvars_t * gpGlobals ;
extern bool gIsJetpacking ;
// Pool of client side entities/entvars_t
static entvars_t ev [ 32 ] ;
static int num_ents = 0 ;
// The entity we'll use to represent the local client
static CBasePlayer player ;
// Local version of game .dll global variables ( time, etc. )
static globalvars_t Globals ;
static CBasePlayerWeapon * g_pWpns [ 32 ] ;
bool CheckInAttack2 ( void ) ;
vec3_t previousorigin ;
// HLDM Weapon placeholder entities.
//CGlock g_Glock;
// NS weapons
AvHKnife gKnife ;
AvHMachineGun gMachineGun ;
AvHPistol gPistol ;
AvHSonicGun gSonicGun ;
AvHHeavyMachineGun gHeavyMachineGun ;
AvHGrenadeGun gGrenadeGun ;
AvHGrenade gGrenade ;
AvHWelder gWelder ;
AvHMine gMine ;
AvHSpitGun gSpitGun ;
AvHClaws gClaws ;
AvHSpore gSpores ;
AvHBite gBite ;
AvHBite2 gBite2 ;
AvHSpikeGun gSpikeGun ;
AvHSwipe gSwipe ;
AvHWebSpinner gWebSpinner ;
AvHPrimalScream gPrimalScream ;
AvHParasiteGun gParasite ;
AvHUmbraGun gUmbra ;
AvHBlinkGun gBlink ;
AvHDivineWind gDivineWind ;
//AvHParalysisGun gParalysisGun;
AvHBileBombGun gBileBomb ;
AvHAcidRocketGun gAcidRocket ;
AvHHealingSpray gHealingSpray ;
AvHMetabolize gMetabolize ;
AvHDevour gDevour ;
AvHStomp gStomp ;
// Alien abilities
AvHLeap gLeap ;
AvHCharge gCharge ;
// Jetpack events
int gJetpackEventID ;
//int gWallJumpEventID;
//int gFlightEventID;
int gTeleportEventID ;
int gPhaseInEventID ;
int gSiegeHitEventID ;
int gSiegeViewHitEventID ;
int gCommanderPointsAwardedEventID ;
int gBlinkEffectSuccessEventID ;
2024-04-01 09:55:15 +00:00
static float prevUseTime = 0 ;
2018-04-22 15:55:55 +00:00
//bool gPlayingJetpack = false;
//CGlock g_Glock;
//CCrowbar g_Crowbar;
//CPython g_Python;
//CMP5 g_Mp5;
//CCrossbow g_Crossbow;
//CShotgun g_Shotgun;
//CRpg g_Rpg;
//CGauss g_Gauss;
//CEgon g_Egon;
//CHgun g_HGun;
//CHandGrenade g_HandGren;
//CSatchel g_Satchel;
//CTripmine g_Tripmine;
//CSqueak g_Snark;
/*
= = = = = = = = = = = = = = = = = = = = = =
AlertMessage
Print debug messages to console
= = = = = = = = = = = = = = = = = = = = = =
*/
void AlertMessage ( ALERT_TYPE atype , char * szFmt , . . . )
{
va_list argptr ;
static char string [ 1024 ] ;
va_start ( argptr , szFmt ) ;
# ifdef WIN32
//overflow protection in MS version of function...
_vsnprintf ( string , 1023 , szFmt , argptr ) ;
# else
vsprintf ( string , szFmt , argptr ) ;
# endif
va_end ( argptr ) ;
gEngfuncs . Con_Printf ( " cl: " ) ;
gEngfuncs . Con_Printf ( string ) ;
}
// Client-side effects for jetpack
void CheckJetpack ( )
{
// if local player is jetpacking, play effects immediately
// if(gIsJetpacking && !gPlayingJetpack)
// {
// cl_entity_t* thePlayer;
// thePlayer = gEngfuncs.GetLocalPlayer();
// ASSERT(thePlayer);
//
// // Play event locally, server will tell everyone else to play event
// gEngfuncs.pEventAPI->EV_PlaybackEvent(0, NULL, gJetpackEventID, 0, thePlayer->origin, (float *)&g_vecZero, 0.0, 0.0, /*theWeaponIndex*/ 0, 0, 0, 0 );
//
// //gPlayingJetpack = true;
// }
// Check to turn it off too (in case there's a network anomaly or the game resets or something, just trying to be safe)
//else if(!gIsJetpacking && (gPlayingJetpack))
//{
// gEngfuncs.pEventAPI->EV_PlaybackEvent(0, NULL, gEndJetpackEventID, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, /*theWeaponIndex*/ 0, 0, 0, 0 );
//
// gPlayingJetpack = false;
//}
}
//Returns if it's multiplayer.
//Mostly used by the client side weapons.
bool bIsMultiplayer ( void )
{
return gEngfuncs . GetMaxClients ( ) = = 1 ? 0 : 1 ;
}
//Just loads a v_ model.
void LoadVModel ( char * szViewModel , CBasePlayer * m_pPlayer )
{
gEngfuncs . CL_LoadModel ( szViewModel , & m_pPlayer - > pev - > viewmodel ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
HUD_PrepEntity
Links the raw entity to an entvars_s holder . If a player is passed in as the owner , then
we set up the m_pPlayer field .
= = = = = = = = = = = = = = = = = = = = =
*/
void HUD_PrepEntity ( CBaseEntity * pEntity , CBasePlayer * pWeaponOwner )
{
typedef vector < int > IDListType ;
static IDListType sIDList ;
memset ( & ev [ num_ents ] , 0 , sizeof ( entvars_t ) ) ;
pEntity - > pev = & ev [ num_ents + + ] ;
pEntity - > Precache ( ) ;
pEntity - > Spawn ( ) ;
if ( pWeaponOwner )
{
ItemInfo info ;
( ( CBasePlayerWeapon * ) pEntity ) - > m_pPlayer = pWeaponOwner ;
( ( CBasePlayerWeapon * ) pEntity ) - > GetItemInfo ( & info ) ;
// ASSERT that a weapon with this id isn't in the list
int theNewID = info . iId ;
IDListType : : iterator theIter = std : : find ( sIDList . begin ( ) , sIDList . end ( ) , theNewID ) ;
ASSERT ( theIter = = sIDList . end ( ) ) ;
// Insert id into our list
sIDList . push_back ( theNewID ) ;
g_pWpns [ theNewID ] = ( CBasePlayerWeapon * ) pEntity ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBaseEntity : : Killed
If weapons code " kills " an entity , just set its effects to EF_NODRAW
= = = = = = = = = = = = = = = = = = = = =
*/
void CBaseEntity : : Killed ( entvars_t * pevAttacker , int iGib )
{
pev - > effects | = EF_NODRAW ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : DefaultReload
= = = = = = = = = = = = = = = = = = = = =
*/
BOOL CBasePlayerWeapon : : DefaultReload ( int iClipSize , int iAnim , float fDelay , int body )
{
if ( m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] < = 0 )
return FALSE ;
int j = min ( iClipSize - m_iClip , m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] ) ;
if ( j = = 0 )
return FALSE ;
m_pPlayer - > m_flNextAttack = UTIL_WeaponTimeBase ( ) + fDelay ;
//!!UNDONE -- reload sound goes here !!!
//SendWeaponAnim( iAnim, UseDecrement(), body );
m_fInReload = TRUE ;
m_flTimeWeaponIdle = UTIL_WeaponTimeBase ( ) + kDeployIdleInterval ;
return TRUE ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : CanDeploy
= = = = = = = = = = = = = = = = = = = = =
*/
BOOL CBasePlayerWeapon : : CanDeploy ( void )
{
BOOL bHasAmmo = 0 ;
if ( ! pszAmmo1 ( ) )
{
// this weapon doesn't use ammo, can always deploy.
return TRUE ;
}
if ( pszAmmo1 ( ) )
{
bHasAmmo | = ( m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] ! = 0 ) ;
}
if ( pszAmmo2 ( ) )
{
bHasAmmo | = ( m_pPlayer - > m_rgAmmo [ m_iSecondaryAmmoType ] ! = 0 ) ;
}
if ( m_iClip > 0 )
{
bHasAmmo | = 1 ;
}
if ( ! bHasAmmo )
{
return FALSE ;
}
return TRUE ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : DefaultDeploy
= = = = = = = = = = = = = = = = = = = = =
*/
BOOL CBasePlayerWeapon : : DefaultDeploy ( char * szViewModel , char * szWeaponModel , int iAnim , char * szAnimExt , int skiplocal , int body )
{
if ( ! CanDeploy ( ) )
return FALSE ;
gEngfuncs . CL_LoadModel ( szViewModel , & m_pPlayer - > pev - > viewmodel ) ;
SendWeaponAnim ( iAnim , skiplocal , body ) ;
m_pPlayer - > m_flNextAttack = this - > GetDeployTime ( ) ;
m_flTimeWeaponIdle = this - > GetDeployTime ( ) + kDeployIdleInterval ;
return TRUE ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : PlayEmptySound
= = = = = = = = = = = = = = = = = = = = =
*/
BOOL CBasePlayerWeapon : : PlayEmptySound ( void )
{
if ( m_iPlayEmptySound )
{
HUD_PlaySound ( " weapons/357_cock1.wav " , 0.8 ) ;
m_iPlayEmptySound = 0 ;
return 0 ;
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : ResetEmptySound
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayerWeapon : : ResetEmptySound ( void )
{
m_iPlayEmptySound = 1 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : Holster
Put away weapon
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayerWeapon : : Holster ( int skiplocal /* = 0 */ )
{
m_fInReload = FALSE ; // cancel any reload in progress.
m_pPlayer - > pev - > viewmodel = 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : SendWeaponAnim
Animate weapon model
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayerWeapon : : SendWeaponAnim ( int iAnim , int skiplocal , int body )
{
m_pPlayer - > pev - > weaponanim = iAnim ;
HUD_SendWeaponAnim ( iAnim , body , 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBaseEntity : : FireBulletsPlayer
Only produces random numbers to match the server ones .
= = = = = = = = = = = = = = = = = = = = =
*/
Vector CBaseEntity : : FireBulletsPlayer ( ULONG cShots , Vector vecSrc , Vector vecDirShooting , Vector vecSpread , float flDistance , int iBulletType , int iTracerFreq , int iDamage , entvars_t * pevAttacker , int shared_rand )
{
//float x, y, z;
Vector theShotDirection ;
theShotDirection . x = theShotDirection . y = theShotDirection . z = 0 ;
// for ( ULONG iShot = 1; iShot <= cShots; iShot++ )
// {
// if ( pevAttacker == NULL )
// {
// // get circular gaussian spread
// do {
// x = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
// y = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
// z = x*x+y*y;
// } while (z > 1);
// }
// else
// {
// //Use player's random seed.
// // get circular gaussian spread
// x = UTIL_SharedRandomFloat( shared_rand + iShot, -0.5, 0.5 ) + UTIL_SharedRandomFloat( shared_rand + ( 1 + iShot ) , -0.5, 0.5 );
// y = UTIL_SharedRandomFloat( shared_rand + ( 2 + iShot ), -0.5, 0.5 ) + UTIL_SharedRandomFloat( shared_rand + ( 3 + iShot ), -0.5, 0.5 );
// z = x * x + y * y;
// }
//
// UTIL_GetRandomSpreadDir(shared_rand, iShot, vecDirShooting)
// }
// return Vector ( (float)(x * vecSpread.x), (float)(y * vecSpread.y), 0.0f );
return theShotDirection ;
}
bool GetCanUseWeapon ( )
{
// This mirrors the functionality of AvHPlayer::GetCanUseWeapon.
return ! gHUD . GetIsInTopDownMode ( ) & & ! gHUD . GetIsBeingDigested ( ) & & ! gHUD . GetIsEnsnared ( ) & & ! gHUD . GetIsStunned ( ) & & gEngfuncs . GetViewModel ( ) ! = NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : ItemPostFrame
Handles weapon firing , reloading , etc .
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayerWeapon : : ItemPostFrame ( void )
{
2021-02-24 20:14:31 +00:00
// Get item info necessary for various checks here. Adapted from Solokiller's halflife-updated. HL SDK has broken checks that always return false.
ItemInfo ii ;
memset ( & ii , 0 , sizeof ( ii ) ) ;
GetItemInfo ( & ii ) ;
2018-04-22 15:55:55 +00:00
// Hack initialization
if ( this - > m_flLastAnimationPlayed > = 3.0f * BALANCE_VAR ( kLeapROF ) + gpGlobals - > time )
this - > m_flLastAnimationPlayed = 0.0f ;
2021-02-24 20:14:31 +00:00
if ( ( m_fInReload ) & & ( m_pPlayer - > m_flNextAttack < = 0.0 ) )
{
2021-01-20 20:36:37 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Put code in here to predict reloads (ie, have the ammo on screen update before we get a response) //
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-02-24 20:14:31 +00:00
# if 1
// complete the reload.
int j = min ( ii . iMaxClip - m_iClip , m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] ) ;
// Add them to the clip
m_iClip + = j ;
m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] - = j ;
//ALERT(at_console, "hlweap predict reload\n");
# else
m_iClip + = 10 ;
# endif
m_fInReload = FALSE ;
}
2018-04-22 15:55:55 +00:00
2024-04-01 09:55:15 +00:00
if ( m_pPlayer - > pev - > button & IN_USE )
{
prevUseTime = gpGlobals - > time ;
}
else if ( gHUD . GetHUDUser3 ( ) = = AVH_USER3_ALIEN_PLAYER2 & & m_pPlayer - > m_afButtonReleased & IN_USE & & m_pPlayer - > pev - > weaponanim = = 4 )
{
switch ( gHUD . GetCurrentWeaponID ( ) )
{
case AVH_WEAPON_SPIT :
case AVH_WEAPON_BILEBOMB :
this - > SendWeaponAnim ( 7 ) ;
break ;
}
}
2018-04-22 15:55:55 +00:00
// Properly propagate the end animation
if ( this - > PrevAttack2Status = = true & & ! ( m_pPlayer - > pev - > button & IN_ATTACK2 ) )
{
switch ( gHUD . GetCurrentWeaponID ( ) )
{
case AVH_WEAPON_SWIPE :
this - > SendWeaponAnim ( 12 ) ;
break ;
case AVH_WEAPON_ACIDROCKET :
2024-04-01 09:55:15 +00:00
this - > SendWeaponAnim ( 13 ) ;
2018-04-22 15:55:55 +00:00
break ;
case AVH_WEAPON_CLAWS :
this - > SendWeaponAnim ( 9 ) ;
break ;
case AVH_WEAPON_STOMP :
2024-04-01 09:55:15 +00:00
this - > SendWeaponAnim ( 11 ) ;
2018-04-22 15:55:55 +00:00
break ;
case AVH_WEAPON_DEVOUR :
2024-04-01 09:55:15 +00:00
this - > SendWeaponAnim ( 12 ) ;
2018-04-22 15:55:55 +00:00
break ;
}
}
2024-04-01 09:55:15 +00:00
if ( ( m_pPlayer - > pev - > button & IN_ATTACK | | ( this - > m_bAttackQueued & & m_flNextPrimaryAttack < = 0.0 ) ) & & ( ! ( m_pPlayer - > pev - > button & IN_ATTACK2 ) | | gHUD . GetHUDUser3 ( ) = = AVH_USER3_ALIEN_PLAYER3 ) )
2018-04-22 15:55:55 +00:00
{
2024-02-04 09:05:28 +00:00
if ( GetCanUseWeapon ( ) )
2018-04-22 15:55:55 +00:00
{
2024-02-04 09:05:28 +00:00
if ( ( m_fInSpecialReload = = 1 | | m_fInSpecialReload = = 2 ) & & m_iClip ! = 0 )
{
m_fInSpecialReload = 3 ;
Reload ( ) ;
}
else if ( m_flNextPrimaryAttack < = 0.0 )
{
if ( ( m_iClip = = 0 & & ii . pszAmmo1 ) | |
( ii . iMaxClip = = - 1 & & ! m_pPlayer - > m_rgAmmo [ PrimaryAmmoIndex ( ) ] ) )
{
m_fFireOnEmpty = TRUE ;
}
2018-04-22 15:55:55 +00:00
2024-02-04 09:05:28 +00:00
if ( ( gHUD . GetHUDUser3 ( ) = = AVH_USER3_ALIEN_PLAYER1 )
& & ( gHUD . GetCurrentWeaponID ( ) = = AVH_ABILITY_LEAP )
& & ( this - > m_flLastAnimationPlayed + ( float ) BALANCE_VAR ( kLeapROF ) < = gpGlobals - > time ) )
{
// : 0001151 predict energy too
AvHAlienWeapon * theWeapon = dynamic_cast < AvHAlienWeapon * > ( g_pWpns [ AVH_ABILITY_LEAP ] ) ;
if ( theWeapon & & theWeapon - > IsUseable ( ) ) {
float theVolumeScalar = 1.0f ;
cl_entity_t * player = gEngfuncs . GetLocalPlayer ( ) ;
int theSilenceLevel = AvHGetAlienUpgradeLevel ( player - > curstate . iuser4 , MASK_UPGRADE_6 ) ;
switch ( theSilenceLevel )
{
case 1 :
theVolumeScalar = ( float ) BALANCE_VAR ( kSilenceLevel1Volume ) ;
break ;
case 2 :
theVolumeScalar = ( float ) BALANCE_VAR ( kSilenceLevel2Volume ) ;
break ;
case 3 :
theVolumeScalar = ( float ) BALANCE_VAR ( kSilenceLevel3Volume ) ;
break ;
}
HUD_PlaySound ( kLeapSound , theVolumeScalar ) ;
AvHMUDeductAlienEnergy ( m_pPlayer - > pev - > fuser3 , theWeapon - > GetEnergyForAttack ( ) ) ;
gEngfuncs . pEventAPI - > EV_WeaponAnimation ( 3 , 2 ) ;
this - > m_flLastAnimationPlayed = gpGlobals - > time ;
2018-04-22 15:55:55 +00:00
}
}
2024-04-01 09:55:15 +00:00
PrimaryAttack ( ) ;
2024-02-04 09:05:28 +00:00
//return;
}
else
{
2024-04-01 09:55:15 +00:00
if ( m_pPlayer - > m_afButtonPressed & IN_ATTACK )
{
QueueAttack ( ) ;
}
2018-04-22 15:55:55 +00:00
}
}
}
// +movement: Rewritten to allow us to use +attack2 for movement abilities
else if ( ( m_pPlayer - > pev - > button & IN_ATTACK2 ) & & ( gHUD . GetIsAlien ( ) ) )
{
2024-02-04 09:05:28 +00:00
AvHUser3 theUser3 = gHUD . GetHUDUser3 ( ) ;
2018-04-22 15:55:55 +00:00
//m_flNextSecondaryAttack
// Find out what kind of special movement we are using, and execute the animation for it
2024-02-04 09:05:28 +00:00
if ( theUser3 = = AVH_USER3_ALIEN_PLAYER2 )
{
if ( GetCanUseWeapon ( ) & & m_flNextPrimaryAttack < = 0.0 )
{
SecondaryAttack ( ) ;
}
}
else if ( this - > PrevAttack2Status = = false )
2018-04-22 15:55:55 +00:00
{
bool enabled = false ;
// : 0001151 predict energy too
AvHAlienWeapon * theWeapon = dynamic_cast < AvHAlienWeapon * > ( g_pWpns [ AVH_ABILITY_LEAP ] ) ;
if ( theWeapon )
enabled = theWeapon - > IsUseable ( ) ;
2024-02-04 09:05:28 +00:00
switch ( theUser3 )
2018-04-22 15:55:55 +00:00
{
case AVH_USER3_ALIEN_PLAYER1 :
if ( enabled & & ( this - > m_flLastAnimationPlayed + ( float ) BALANCE_VAR ( kLeapROF ) < = gpGlobals - > time ) )
{
float theVolumeScalar = 1.0f ;
cl_entity_t * player = gEngfuncs . GetLocalPlayer ( ) ;
int theSilenceLevel = AvHGetAlienUpgradeLevel ( player - > curstate . iuser4 , MASK_UPGRADE_6 ) ;
switch ( theSilenceLevel )
{
case 1 :
theVolumeScalar = ( float ) BALANCE_VAR ( kSilenceLevel1Volume ) ;
break ;
case 2 :
theVolumeScalar = ( float ) BALANCE_VAR ( kSilenceLevel2Volume ) ;
break ;
case 3 :
theVolumeScalar = ( float ) BALANCE_VAR ( kSilenceLevel3Volume ) ;
break ;
}
HUD_PlaySound ( kLeapSound , theVolumeScalar ) ;
AvHMUDeductAlienEnergy ( m_pPlayer - > pev - > fuser3 , theWeapon - > GetEnergyForAttack ( ) ) ;
this - > SendWeaponAnim ( 3 ) ;
this - > m_flLastAnimationPlayed = gpGlobals - > time ;
}
break ;
case AVH_USER3_ALIEN_PLAYER4 :
switch ( gHUD . GetCurrentWeaponID ( ) )
{
case AVH_WEAPON_SWIPE :
this - > SendWeaponAnim ( 9 ) ;
break ;
case AVH_WEAPON_ACIDROCKET :
this - > SendWeaponAnim ( 11 ) ;
break ;
}
break ;
case AVH_USER3_ALIEN_PLAYER5 :
switch ( gHUD . GetCurrentWeaponID ( ) )
{
case AVH_WEAPON_CLAWS :
this - > SendWeaponAnim ( 5 ) ;
break ;
case AVH_WEAPON_DEVOUR :
2024-04-01 09:55:15 +00:00
this - > SendWeaponAnim ( 19 ) ;
2018-04-22 15:55:55 +00:00
break ;
case AVH_WEAPON_STOMP :
2024-04-01 09:55:15 +00:00
this - > SendWeaponAnim ( 16 ) ;
2018-04-22 15:55:55 +00:00
break ;
}
break ;
}
}
2024-02-04 09:05:28 +00:00
if ( ( theUser3 = = AVH_USER3_ALIEN_PLAYER1 ) & & ( this - > m_flLastAnimationPlayed + BALANCE_VAR ( kLeapROF ) < gpGlobals - > time ) )
2018-04-22 15:55:55 +00:00
this - > PrevAttack2Status = false ;
else
this - > PrevAttack2Status = true ;
2024-04-01 09:55:15 +00:00
this - > PrevAttack2Time = gpGlobals - > time ;
2018-04-22 15:55:55 +00:00
return ;
// if (GetCanUseWeapon())
// {
// PrimaryAttack();
// }
}
2021-02-24 20:14:31 +00:00
else if ( m_pPlayer - > pev - > button & IN_RELOAD & & ii . iMaxClip ! = WEAPON_NOCLIP & & ! m_fInReload )
2018-04-22 15:55:55 +00:00
{
if ( GetCanUseWeapon ( ) )
{
// reload when reload is pressed, or if no buttons are down and weapon is empty.
Reload ( ) ;
2023-08-20 21:31:01 +00:00
return ;
2018-04-22 15:55:55 +00:00
}
}
// +movement: Removed case for +attack2
else if ( ! ( m_pPlayer - > pev - > button & ( IN_ATTACK /*|IN_ATTACK2 */ ) ) )
{
if ( GetCanUseWeapon ( ) )
{
// no fire buttons down
m_fFireOnEmpty = FALSE ;
2024-04-01 09:55:15 +00:00
2018-04-22 15:55:55 +00:00
// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
2021-02-24 20:14:31 +00:00
if ( m_iClip = = 0 & & ! ( ii . iFlags & ITEM_FLAG_NOAUTORELOAD ) & & m_flNextPrimaryAttack < 0.0 )
2018-04-22 15:55:55 +00:00
{
// << CGC >> Only reload if we have more ammo to reload with
2021-02-24 20:14:31 +00:00
if ( m_pPlayer - > m_rgAmmo [ m_iPrimaryAmmoType ] > 0 )
2018-04-22 15:55:55 +00:00
{
2021-01-20 20:36:37 +00:00
Reload ( ) ;
return ;
2018-04-22 15:55:55 +00:00
}
}
WeaponIdle ( ) ;
}
this - > PrevAttack2Status = false ;
return ;
}
2021-02-24 20:14:31 +00:00
2018-04-22 15:55:55 +00:00
this - > PrevAttack2Status = false ;
// catch all
if ( ShouldWeaponIdle ( ) )
{
WeaponIdle ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayer : : SelectItem
Switch weapons
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayer : : SelectItem ( const char * pstr )
{
if ( ! pstr )
return ;
CBasePlayerItem * pItem = NULL ;
if ( ! pItem )
return ;
if ( pItem = = m_pActiveItem )
return ;
if ( m_pActiveItem )
m_pActiveItem - > Holster ( ) ;
m_pLastItem = m_pActiveItem ;
m_pActiveItem = pItem ;
if ( m_pActiveItem )
{
m_pActiveItem - > Deploy ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayer : : SelectLastItem
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayer : : SelectLastItem ( void )
{
if ( ! m_pLastItem )
{
return ;
}
if ( m_pActiveItem & & ! m_pActiveItem - > CanHolster ( ) )
{
return ;
}
if ( m_pActiveItem )
m_pActiveItem - > Holster ( ) ;
CBasePlayerItem * pTemp = m_pActiveItem ;
m_pActiveItem = m_pLastItem ;
m_pLastItem = pTemp ;
m_pActiveItem - > Deploy ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayer : : Killed
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayer : : Killed ( entvars_t * pevAttacker , int iGib )
{
// Holster weapon immediately, to allow it to cleanup
if ( m_pActiveItem )
m_pActiveItem - > Holster ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayer : : Spawn
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayer : : Spawn ( void )
{
if ( m_pActiveItem )
m_pActiveItem - > Deploy ( ) ;
// this->m_flLastAnimationPlayed = gpGlobals->time;
}
/*
= = = = = = = = = = = = = = = = = = = = =
UTIL_TraceLine
Don ' t actually trace , but act like the trace didn ' t hit anything .
= = = = = = = = = = = = = = = = = = = = =
*/
void UTIL_TraceLine ( const Vector & vecStart , const Vector & vecEnd , IGNORE_MONSTERS igmon , edict_t * pentIgnore , TraceResult * ptr )
{
memset ( ptr , 0 , sizeof ( * ptr ) ) ;
ptr - > flFraction = 1.0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
UTIL_ParticleBox
For debugging , draw a box around a player made out of particles
= = = = = = = = = = = = = = = = = = = = =
*/
void UTIL_ParticleBox ( CBasePlayer * player , float * mins , float * maxs , float life , unsigned char r , unsigned char g , unsigned char b )
{
int i ;
vec3_t mmin , mmax ;
for ( i = 0 ; i < 3 ; i + + )
{
mmin [ i ] = player - > pev - > origin [ i ] + mins [ i ] ;
mmax [ i ] = player - > pev - > origin [ i ] + maxs [ i ] ;
}
gEngfuncs . pEfxAPI - > R_ParticleBox ( ( float * ) & mmin , ( float * ) & mmax , 5.0 , 0 , 255 , 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
UTIL_ParticleBoxes
For debugging , draw boxes for other collidable players
= = = = = = = = = = = = = = = = = = = = =
*/
void UTIL_ParticleBoxes ( void )
{
int idx ;
physent_t * pe ;
cl_entity_t * player ;
vec3_t mins , maxs ;
gEngfuncs . pEventAPI - > EV_SetUpPlayerPrediction ( false , true ) ;
// Store off the old count
gEngfuncs . pEventAPI - > EV_PushPMStates ( ) ;
player = gEngfuncs . GetLocalPlayer ( ) ;
// Now add in all of the players.
gEngfuncs . pEventAPI - > EV_SetSolidPlayers ( player - > index - 1 ) ;
for ( idx = 1 ; idx < 100 ; idx + + )
{
pe = gEngfuncs . pEventAPI - > EV_GetPhysent ( idx ) ;
if ( ! pe )
break ;
if ( pe - > info > = 1 & & pe - > info < = gEngfuncs . GetMaxClients ( ) )
{
mins = pe - > origin + pe - > mins ;
maxs = pe - > origin + pe - > maxs ;
gEngfuncs . pEfxAPI - > R_ParticleBox ( ( float * ) & mins , ( float * ) & maxs , 0 , 0 , 255 , 2.0 ) ;
}
}
gEngfuncs . pEventAPI - > EV_PopPMStates ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
UTIL_ParticleLine
For debugging , draw a line made out of particles
= = = = = = = = = = = = = = = = = = = = =
*/
void UTIL_ParticleLine ( CBasePlayer * player , float * start , float * end , float life , unsigned char r , unsigned char g , unsigned char b )
{
gEngfuncs . pEfxAPI - > R_ParticleLine ( start , end , r , g , b , life ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
CBasePlayerWeapon : : PrintState
For debugging , print out state variables to log file
= = = = = = = = = = = = = = = = = = = = =
*/
void CBasePlayerWeapon : : PrintState ( void )
{
COM_Log ( " c: \\ hl.log " , " %.4f " , gpGlobals - > time ) ;
COM_Log ( " c: \\ hl.log " , " %.4f " , m_pPlayer - > m_flNextAttack ) ;
COM_Log ( " c: \\ hl.log " , " %.4f " , m_flNextPrimaryAttack ) ;
COM_Log ( " c: \\ hl.log " , " %.4f " , m_flTimeWeaponIdle - gpGlobals - > time ) ;
COM_Log ( " c: \\ hl.log " , " %i " , m_iClip ) ;
COM_Log ( " c: \\ hl.log " , " \r \n " ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
HUD_InitClientWeapons
Set up weapons , player and functions needed to run weapons code client - side .
= = = = = = = = = = = = = = = = = = = = =
*/
void HUD_InitClientWeapons ( void )
{
static int initialized = 0 ;
if ( initialized )
return ;
initialized = 1 ;
// Set up pointer ( dummy object )
gpGlobals = & Globals ;
// Fill in current time ( probably not needed )
gpGlobals - > time = gEngfuncs . GetClientTime ( ) ;
// Fake functions
g_engfuncs . pfnPrecacheModel = stub_PrecacheModel ;
g_engfuncs . pfnPrecacheSound = stub_PrecacheSound ;
g_engfuncs . pfnPrecacheEvent = stub_PrecacheEvent ;
g_engfuncs . pfnNameForFunction = stub_NameForFunction ;
g_engfuncs . pfnSetModel = stub_SetModel ;
g_engfuncs . pfnSetClientMaxspeed = HUD_SetMaxSpeed ;
// Handled locally
g_engfuncs . pfnPlaybackEvent = HUD_PlaybackEvent ;
g_engfuncs . pfnAlertMessage = AlertMessage ;
// Pass through to engine
g_engfuncs . pfnPrecacheEvent = gEngfuncs . pfnPrecacheEvent ;
g_engfuncs . pfnRandomFloat = gEngfuncs . pfnRandomFloat ;
g_engfuncs . pfnRandomLong = gEngfuncs . pfnRandomLong ;
// Allocate a slot for the local player
HUD_PrepEntity ( & player , NULL ) ;
// Allocate slot(s) for each weapon that we are going to be predicting
//HUD_PrepEntity( &g_Glock, &player );
HUD_PrepEntity ( & gKnife , & player ) ;
HUD_PrepEntity ( & gMachineGun , & player ) ;
HUD_PrepEntity ( & gPistol , & player ) ;
HUD_PrepEntity ( & gSonicGun , & player ) ;
HUD_PrepEntity ( & gHeavyMachineGun , & player ) ;
HUD_PrepEntity ( & gGrenadeGun , & player ) ;
HUD_PrepEntity ( & gGrenade , & player ) ;
HUD_PrepEntity ( & gWelder , & player ) ;
HUD_PrepEntity ( & gMine , & player ) ;
HUD_PrepEntity ( & gSpitGun , & player ) ;
HUD_PrepEntity ( & gClaws , & player ) ;
HUD_PrepEntity ( & gSpores , & player ) ;
HUD_PrepEntity ( & gSpikeGun , & player ) ;
HUD_PrepEntity ( & gBite , & player ) ;
HUD_PrepEntity ( & gBite2 , & player ) ;
HUD_PrepEntity ( & gSwipe , & player ) ;
HUD_PrepEntity ( & gWebSpinner , & player ) ;
HUD_PrepEntity ( & gPrimalScream , & player ) ;
//HUD_PrepEntity( &gParalysisGun, &player);
HUD_PrepEntity ( & gBlink , & player ) ;
HUD_PrepEntity ( & gParasite , & player ) ;
HUD_PrepEntity ( & gUmbra , & player ) ;
HUD_PrepEntity ( & gDivineWind , & player ) ;
HUD_PrepEntity ( & gBileBomb , & player ) ;
HUD_PrepEntity ( & gAcidRocket , & player ) ;
HUD_PrepEntity ( & gHealingSpray , & player ) ;
HUD_PrepEntity ( & gMetabolize , & player ) ;
HUD_PrepEntity ( & gStomp , & player ) ;
HUD_PrepEntity ( & gDevour , & player ) ;
HUD_PrepEntity ( & gLeap , & player ) ;
HUD_PrepEntity ( & gCharge , & player ) ;
gJetpackEventID = PRECACHE_EVENT ( 1 , kJetpackEvent ) ;
//gWallJumpEventID = PRECACHE_EVENT(1, kWallJumpEvent);
//gFlightEventID = PRECACHE_EVENT(1, kFlightEvent);
gTeleportEventID = PRECACHE_EVENT ( 1 , kTeleportEvent ) ;
gPhaseInEventID = PRECACHE_EVENT ( 1 , kPhaseInEvent ) ;
gSiegeHitEventID = PRECACHE_EVENT ( 1 , kSiegeHitEvent ) ;
gSiegeViewHitEventID = PRECACHE_EVENT ( 1 , kSiegeViewHitEvent ) ;
gCommanderPointsAwardedEventID = PRECACHE_EVENT ( 1 , kCommanderPointsAwardedEvent ) ;
gBlinkEffectSuccessEventID = PRECACHE_EVENT ( 1 , kBlinkEffectSuccessEventName ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
HUD_GetLastOrg
Retruns the last position that we stored for egon beam endpoint .
= = = = = = = = = = = = = = = = = = = = =
*/
void HUD_GetLastOrg ( float * org )
{
int i ;
// Return last origin
for ( i = 0 ; i < 3 ; i + + )
{
org [ i ] = previousorigin [ i ] ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = =
HUD_SetLastOrg
Remember our exact predicted origin so we can draw the egon to the right position .
= = = = = = = = = = = = = = = = = = = = =
*/
void HUD_SetLastOrg ( void )
{
int i ;
// Offset final origin by view_offset
for ( i = 0 ; i < 3 ; i + + )
{
previousorigin [ i ] = g_finalstate - > playerstate . origin [ i ] + g_finalstate - > client . view_ofs [ i ] ;
}
}
CBasePlayerWeapon * HUD_GetWeaponForID ( int inID )
{
CBasePlayerWeapon * pWeapon = NULL ;
switch ( inID )
{
// case WEAPON_GLOCK:
// pWeapon = &g_Glock;
// break;
case AVH_WEAPON_KNIFE :
pWeapon = & gKnife ;
break ;
case AVH_WEAPON_MG :
pWeapon = & gMachineGun ;
break ;
case AVH_WEAPON_PISTOL :
pWeapon = & gPistol ;
break ;
case AVH_WEAPON_SONIC :
pWeapon = & gSonicGun ;
break ;
case AVH_WEAPON_HMG :
pWeapon = & gHeavyMachineGun ;
break ;
case AVH_WEAPON_GRENADE_GUN :
pWeapon = & gGrenadeGun ;
break ;
case AVH_WEAPON_GRENADE :
pWeapon = & gGrenade ;
break ;
case AVH_WEAPON_WELDER :
pWeapon = & gWelder ;
break ;
case AVH_WEAPON_MINE :
pWeapon = & gMine ;
break ;
case AVH_WEAPON_SPIT :
pWeapon = & gSpitGun ;
break ;
case AVH_WEAPON_CLAWS :
pWeapon = & gClaws ;
break ;
case AVH_WEAPON_SPORES :
pWeapon = & gSpores ;
break ;
case AVH_WEAPON_SPIKE :
pWeapon = & gSpikeGun ;
break ;
case AVH_WEAPON_BITE :
pWeapon = & gBite ;
break ;
case AVH_WEAPON_BITE2 :
pWeapon = & gBite2 ;
break ;
case AVH_WEAPON_SWIPE :
pWeapon = & gSwipe ;
break ;
case AVH_WEAPON_WEBSPINNER :
pWeapon = & gWebSpinner ;
break ;
case AVH_WEAPON_PRIMALSCREAM :
pWeapon = & gPrimalScream ;
break ;
case AVH_WEAPON_PARASITE :
pWeapon = & gParasite ;
break ;
case AVH_WEAPON_UMBRA :
pWeapon = & gUmbra ;
break ;
case AVH_WEAPON_BLINK :
pWeapon = & gBlink ;
break ;
case AVH_WEAPON_DIVINEWIND :
pWeapon = & gDivineWind ;
break ;
// case AVH_WEAPON_PARALYSIS:
// pWeapon = &gParalysisGun;
// break;
case AVH_WEAPON_BILEBOMB :
pWeapon = & gBileBomb ;
break ;
case AVH_WEAPON_ACIDROCKET :
pWeapon = & gAcidRocket ;
break ;
case AVH_WEAPON_HEALINGSPRAY :
pWeapon = & gHealingSpray ;
break ;
case AVH_WEAPON_METABOLIZE :
pWeapon = & gMetabolize ;
break ;
case AVH_WEAPON_STOMP :
pWeapon = & gStomp ;
break ;
case AVH_WEAPON_DEVOUR :
pWeapon = & gDevour ;
break ;
// Abilities
case AVH_ABILITY_LEAP :
pWeapon = & gLeap ;
break ;
case AVH_ABILITY_CHARGE :
pWeapon = & gCharge ;
break ;
}
return pWeapon ;
}
bool HUD_GetWeaponEnabled ( int inID )
{
ASSERT ( inID > = 0 ) ;
ASSERT ( inID < 32 ) ;
// : 497 - use the enabled state in the associated WEAPON instead of the CBasePlayerWeapon's iuser3
bool theWeaponEnabled = false ;
CBasePlayerWeapon * theWeapon = g_pWpns [ inID ] ;
if ( theWeapon )
{
ItemInfo theItemInfo ;
theWeapon - > GetItemInfo ( & theItemInfo ) ;
WEAPON * pWeapon = gWR . GetWeapon ( theItemInfo . iId ) ;
if ( pWeapon ! = 0 ) {
theWeaponEnabled = ( pWeapon - > iEnabled = = 1 ) ;
}
}
return theWeaponEnabled ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
HUD_WeaponsPostThink
Run Weapon firing code on client
= = = = = = = = = = = = = = = = = = = = =
*/
void HUD_WeaponsPostThink ( local_state_s * from , local_state_s * to , usercmd_t * cmd , double time , unsigned int random_seed )
{
int i ;
int buttonsChanged ;
CBasePlayerWeapon * pCurrent = NULL ;
weapon_data_t nulldata , * pfrom , * pto ;
static int lasthealth ;
memset ( & nulldata , 0 , sizeof ( nulldata ) ) ;
HUD_InitClientWeapons ( ) ;
// Get current clock
gpGlobals - > time = time ;
// Fill in data based on selected weapon
// FIXME, make this a method in each weapon? where you pass in an entity_state_t *?
// Store pointer to our destination entity_state_t so we can get our origin, etc. from it
CBasePlayerWeapon * pWeapon = HUD_GetWeaponForID ( from - > client . m_iId ) ;
// for setting up events on the client
g_finalstate = to ;
// If we are running events/etc. go ahead and see if we
// managed to die between last frame and this one
// If so, run the appropriate player killed or spawn function
if ( g_runfuncs )
{
if ( to - > client . health < = 0 & & lasthealth > 0 )
{
player . Killed ( NULL , 0 ) ;
}
else if ( to - > client . health > 0 & & lasthealth < = 0 )
{
player . Spawn ( ) ;
}
lasthealth = to - > client . health ;
}
// We are not predicting the current weapon, just bow out here.
if ( ! pWeapon )
return ;
for ( i = 0 ; i < 32 ; i + + )
{
pCurrent = g_pWpns [ i ] ;
if ( ! pCurrent )
{
continue ;
}
pfrom = & from - > weapondata [ i ] ;
2024-04-01 09:55:15 +00:00
2018-04-22 15:55:55 +00:00
pCurrent - > m_fInReload = pfrom - > m_fInReload ;
pCurrent - > m_fInSpecialReload = pfrom - > m_fInSpecialReload ;
// pCurrent->m_flPumpTime = pfrom->m_flPumpTime;
pCurrent - > m_iClip = pfrom - > m_iClip ;
pCurrent - > m_flNextPrimaryAttack = pfrom - > m_flNextPrimaryAttack ;
pCurrent - > m_flNextSecondaryAttack = pfrom - > m_flNextSecondaryAttack ;
pCurrent - > m_flTimeWeaponIdle = pfrom - > m_flTimeWeaponIdle ;
2024-04-01 09:55:15 +00:00
2018-04-22 15:55:55 +00:00
if ( pWeapon & & ( pWeapon - > m_iId = = pfrom - > m_iId ) )
{
// Predict clip
gHUD . m_Ammo . SetCurrentClip ( pfrom - > m_iClip ) ;
AvHBasePlayerWeapon * theWeapon = dynamic_cast < AvHBasePlayerWeapon * > ( pWeapon ) ;
if ( theWeapon )
{
gHUD . SetCurrentWeaponData ( pWeapon - > m_iId , theWeapon - > GetEnabledState ( ) ) ;
}
//gHUD.SetClientDebugCSP(pfrom, from->client.m_flNextAttack);
}
// Tell HUD what energy level is needed to use weapon, so alien HUD can indicate this
float theEnergyLevel = 0.0f ;
AvHMUGetEnergyCost ( ( AvHWeaponID ) ( pWeapon - > m_iId ) , theEnergyLevel ) ;
gHUD . SetCurrentUseableEnergyLevel ( theEnergyLevel ) ;
// New SDK stuff...needed?
// pCurrent->pev->fuser1 = pfrom->fuser1;
pCurrent - > m_flStartThrow = pfrom - > fuser2 ;
pCurrent - > m_flReleaseThrow = pfrom - > fuser3 ;
// pCurrent->m_chargeReady = pfrom->iuser1;
2024-04-01 09:55:15 +00:00
pCurrent - > m_fInAttack = pfrom - > iuser2 ;
2018-04-22 15:55:55 +00:00
pCurrent - > pev - > iuser3 = pfrom - > iuser3 ;
2024-04-01 09:55:15 +00:00
pCurrent - > m_bAttackQueued = pfrom - > iuser4 ;
2018-04-22 15:55:55 +00:00
// pCurrent->m_iSecondaryAmmoType = (int)from->client.vuser3[2];
2021-01-20 20:36:37 +00:00
// pCurrent->m_iPrimaryAmmoType = (int)from->client.vuser4[0];
2018-04-22 15:55:55 +00:00
// player.m_rgAmmo[ pCurrent->m_iPrimaryAmmoType ] = (int)from->client.vuser4[1];
// player.m_rgAmmo[ pCurrent->m_iSecondaryAmmoType ] = (int)from->client.vuser4[2];
2021-01-20 20:36:37 +00:00
// Ammo networking 2021
pCurrent - > m_iPrimaryAmmoType = from - > client . ammo_nails ;
pCurrent - > m_iSecondaryAmmoType = from - > client . ammo_shells ;
player . m_rgAmmo [ pCurrent - > m_iPrimaryAmmoType ] = from - > client . ammo_cells ;
player . m_rgAmmo [ pCurrent - > m_iSecondaryAmmoType ] = from - > client . ammo_rockets ;
2018-04-22 15:55:55 +00:00
}
// For random weapon events, use this seed to seed random # generator
player . random_seed = random_seed ;
// Get old buttons from previous state.
player . m_afButtonLast = from - > playerstate . oldbuttons ;
// Which buttsons chave changed
buttonsChanged = ( player . m_afButtonLast ^ cmd - > buttons ) ; // These buttons have changed this frame
// Debounced button codes for pressed/released
// The changed ones still down are "pressed"
player . m_afButtonPressed = buttonsChanged & cmd - > buttons ;
// The ones not down are "released"
player . m_afButtonReleased = buttonsChanged & ( ~ cmd - > buttons ) ;
// Set player variables that weapons code might check/alter
player . pev - > button = cmd - > buttons ;
player . pev - > velocity = from - > client . velocity ;
player . pev - > flags = from - > client . flags ;
player . pev - > deadflag = from - > client . deadflag ;
player . pev - > waterlevel = from - > client . waterlevel ;
player . pev - > maxspeed = from - > client . maxspeed ;
player . pev - > fov = from - > client . fov ;
player . pev - > weaponanim = from - > client . weaponanim ;
player . pev - > viewmodel = from - > client . viewmodel ;
player . m_flNextAttack = from - > client . m_flNextAttack ;
//player.m_flNextAmmoBurn = from->client.fuser2;
//player.m_flAmmoStartCharge = from->client.fuser3;
// Removed this because NS uses vuser1 and vuser2 (and the HL weapons aren't used)
////Stores all our ammo info, so the client side weapons can use them.
//player.ammo_9mm = (int)from->client.vuser1[0];
//player.ammo_357 = (int)from->client.vuser1[1];
//player.ammo_argrens = (int)from->client.vuser1[2];
//player.ammo_bolts = (int)from->client.ammo_nails; //is an int anyways...
//player.ammo_buckshot = (int)from->client.ammo_shells;
//player.ammo_uranium = (int)from->client.ammo_cells;
//player.ammo_hornets = (int)from->client.vuser2[0];
//player.ammo_rockets = (int)from->client.ammo_rockets;
// Point to current weapon object
if ( from - > client . m_iId )
{
player . m_pActiveItem = g_pWpns [ from - > client . m_iId ] ;
}
2021-01-20 20:36:37 +00:00
//if ( player.m_pActiveItem->m_iId == WEAPON_RPG )
//{
// ( ( CRpg * )player.m_pActiveItem)->m_fSpotActive = (int)from->client.vuser2[ 1 ];
// ( ( CRpg * )player.m_pActiveItem)->m_cActiveRockets = (int)from->client.vuser2[ 2 ];
//}
2018-04-22 15:55:55 +00:00
// Don't go firing anything if we have died.
// Or if we don't have a weapon model deployed
if ( ( player . pev - > deadflag ! = ( DEAD_DISCARDBODY + 1 ) ) & & ! CL_IsDead ( ) & & player . pev - > viewmodel & & ! g_iUser1 )
{
if ( player . m_flNextAttack < = 0 )
{
pWeapon - > ItemPostFrame ( ) ;
}
// if ( g_runfuncs )
// {
// pWeapon->PrintState();
// }
}
// Assume that we are not going to switch weapons
to - > client . m_iId = from - > client . m_iId ;
// Now see if we issued a changeweapon command ( and we're not dead )
if ( cmd - > weaponselect & & ( player . pev - > deadflag ! = ( DEAD_DISCARDBODY + 1 ) ) )
{
// Switched to a different weapon?
if ( from - > weapondata [ cmd - > weaponselect ] . m_iId = = cmd - > weaponselect )
{
ASSERT ( cmd - > weaponselect > = 0 ) ;
ASSERT ( cmd - > weaponselect < 32 ) ;
CBasePlayerWeapon * pNew = g_pWpns [ cmd - > weaponselect ] ;
if ( pNew & & ( pNew ! = pWeapon ) & & player . m_pActiveItem & & player . m_pActiveItem - > CanHolster ( ) )
{
// Put away old weapon
if ( player . m_pActiveItem )
player . m_pActiveItem - > Holster ( ) ;
player . m_pLastItem = player . m_pActiveItem ;
player . m_pActiveItem = pNew ;
// Deploy new weapon
if ( player . m_pActiveItem )
{
player . m_pActiveItem - > Deploy ( ) ;
}
// Update weapon id so we can predict things correctly.
to - > client . m_iId = cmd - > weaponselect ;
}
}
}
// Copy in results of prediction code
to - > client . viewmodel = player . pev - > viewmodel ;
to - > client . fov = player . pev - > fov ;
to - > client . weaponanim = player . pev - > weaponanim ;
to - > client . m_flNextAttack = player . m_flNextAttack ;
//to->client.fuser2 = player.m_flNextAmmoBurn;
//to->client.fuser3 = player.m_flAmmoStartCharge;
to - > client . maxspeed = player . pev - > maxspeed ;
// Removed this because NS uses vuser1 and vuser2 (and the HL weapons aren't used)
// //HL Weapons
// to->client.vuser1[0] = player.ammo_9mm;
// to->client.vuser1[1] = player.ammo_357;
// to->client.vuser1[2] = player.ammo_argrens;
//
// to->client.ammo_nails = player.ammo_bolts;
// to->client.ammo_shells = player.ammo_buckshot;
// to->client.ammo_cells = player.ammo_uranium;
// to->client.vuser2[0] = player.ammo_hornets;
// to->client.ammo_rockets = player.ammo_rockets;
2021-01-20 20:36:37 +00:00
//if ( player.m_pActiveItem->m_iId == WEAPON_RPG )
//{
// from->client.vuser2[ 1 ] = ( ( CRpg * )player.m_pActiveItem)->m_fSpotActive;
// from->client.vuser2[ 2 ] = ( ( CRpg * )player.m_pActiveItem)->m_cActiveRockets;
//}
2018-04-22 15:55:55 +00:00
// Make sure that weapon animation matches what the game .dll is telling us
// over the wire ( fixes some animation glitches )
2024-04-01 09:55:15 +00:00
if ( g_runfuncs & & HUD_GetWeaponAnim ( ) ! = to - > client . weaponanim )
2018-04-22 15:55:55 +00:00
{
int body = 2 ;
2024-04-01 09:55:15 +00:00
bool processTheAnim = true ;
//gEngfuncs.Con_Printf("trying to force animation on client currentanim:%d serveranim:%d nextattack:%f time:%f\n", HUD_GetWeaponAnim(), to->client.weaponanim, to->client.m_flNextAttack, gpGlobals->time);
//// 2024 - Don't correct with +movement transitional animations since +movement animations are hacked in on the client and it bugs out. Remove most of this if alien weapons get refactored to shared code.
if ( to - > client . iuser3 = = AVH_USER3_ALIEN_PLAYER5 )
{
if ( ( gpGlobals - > time - pWeapon - > PrevAttack2Time < 1.0f ) | | ( to - > client . weaponanim > 4 & & to - > client . weaponanim < 21 ) )
//(to->client.weaponanim == 27 && gpGlobals->time - pWeapon->PrevAttack2Time < 10.0f) ||
{
processTheAnim = false ;
}
}
else if ( to - > client . iuser3 = = AVH_USER3_ALIEN_PLAYER4 )
{
if ( ( gpGlobals - > time - pWeapon - > PrevAttack2Time < 1.0f ) | | ( to - > client . weaponanim > 7 & & to - > client . weaponanim < 14 ) )
//(to->client.weaponanim == 5 && gpGlobals->time - pWeapon->PrevAttack2Time < 10.0f) ||
{
processTheAnim = false ;
}
}
//else if (to->client.iuser3 == AVH_USER3_ALIEN_PLAYER3 && to->client.weaponanim > 6 && to->client.weaponanim < 13)
else if ( to - > client . iuser3 = = AVH_USER3_ALIEN_PLAYER1 )
{
if ( gpGlobals - > time - pWeapon - > PrevAttack2Time < 1.0f )
processTheAnim = false ;
}
// Gorge building animation fixes since it's server side and the new transition out of it is client side.
else if ( to - > client . iuser3 = = AVH_USER3_ALIEN_PLAYER2 )
{
if ( player . pev - > button & IN_USE | |
( to - > client . weaponanim = = 4 & & gpGlobals - > time - prevUseTime < 10.0f ) | |
( to - > client . weaponanim < 2 & & gpGlobals - > time - prevUseTime < 1.0f ) | |
( HUD_GetWeaponAnim ( ) = = 4 & & to - > client . weaponanim = = 5 ) )
{
processTheAnim = false ;
}
}
2018-04-22 15:55:55 +00:00
// Force a fixed anim down to viewmodel
2024-04-01 09:55:15 +00:00
if ( processTheAnim )
HUD_SendWeaponAnim ( to - > client . weaponanim , body , 1 ) ;
2018-04-22 15:55:55 +00:00
}
for ( i = 0 ; i < 32 ; i + + )
{
pCurrent = g_pWpns [ i ] ;
pto = & to - > weapondata [ i ] ;
if ( ! pCurrent )
{
memset ( pto , 0 , sizeof ( weapon_data_t ) ) ;
continue ;
}
pto - > m_fInReload = pCurrent - > m_fInReload ;
pto - > m_fInSpecialReload = pCurrent - > m_fInSpecialReload ;
// pto->m_flPumpTime = pCurrent->m_flPumpTime;
pto - > m_iClip = pCurrent - > m_iClip ;
pto - > m_flNextPrimaryAttack = pCurrent - > m_flNextPrimaryAttack ;
pto - > m_flNextSecondaryAttack = pCurrent - > m_flNextSecondaryAttack ;
pto - > m_flTimeWeaponIdle = pCurrent - > m_flTimeWeaponIdle ;
// pto->fuser1 = pCurrent->pev->fuser1;
// pto->fuser2 = pCurrent->m_flStartThrow;
// pto->fuser3 = pCurrent->m_flReleaseThrow;
// pto->iuser1 = pCurrent->m_chargeReady;
2024-04-01 09:55:15 +00:00
pto - > iuser2 = pCurrent - > m_fInAttack ;
2018-04-22 15:55:55 +00:00
pto - > iuser3 = pCurrent - > pev - > iuser3 ;
2024-04-01 09:55:15 +00:00
pto - > iuser4 = pCurrent - > m_bAttackQueued ;
2018-04-22 15:55:55 +00:00
// Decrement weapon counters, server does this at same time ( during post think, after doing everything else )
pto - > m_flNextReload - = cmd - > msec / 1000.0 ;
pto - > m_fNextAimBonus - = cmd - > msec / 1000.0 ;
pto - > m_flNextPrimaryAttack - = cmd - > msec / 1000.0 ;
pto - > m_flNextSecondaryAttack - = cmd - > msec / 1000.0 ;
pto - > m_flTimeWeaponIdle - = cmd - > msec / 1000.0 ;
pto - > fuser1 - = cmd - > msec / 1000.0 ;
2021-01-20 20:36:37 +00:00
//to->client.vuser3[2] = pCurrent->m_iSecondaryAmmoType;
2018-04-22 15:55:55 +00:00
to - > client . vuser4 = pCurrent - > pev - > vuser4 ;
// to->client.vuser4[0] = pCurrent->m_iPrimaryAmmoType;
// to->client.vuser4[1] = player.m_rgAmmo[ pCurrent->m_iPrimaryAmmoType ];
// to->client.vuser4[2] = player.m_rgAmmo[ pCurrent->m_iSecondaryAmmoType ];
2021-01-20 20:36:37 +00:00
// Ammo networking 2021
to - > client . ammo_nails = pCurrent - > m_iPrimaryAmmoType ;
to - > client . ammo_shells = pCurrent - > m_iSecondaryAmmoType ;
to - > client . ammo_cells = player . m_rgAmmo [ pCurrent - > m_iPrimaryAmmoType ] ;
to - > client . ammo_rockets = player . m_rgAmmo [ pCurrent - > m_iSecondaryAmmoType ] ;
2018-04-22 15:55:55 +00:00
/* if ( pto->m_flPumpTime != -9999 )
{
pto - > m_flPumpTime - = cmd - > msec / 1000.0 ;
if ( pto - > m_flPumpTime < - 0.001 )
pto - > m_flPumpTime = - 0.001 ;
} */
if ( pto - > m_fNextAimBonus < - 1.0 )
{
pto - > m_fNextAimBonus = - 1.0 ;
}
if ( pto - > m_flNextPrimaryAttack < - 1.0 )
{
pto - > m_flNextPrimaryAttack = - 1.0 ;
}
if ( pto - > m_flNextSecondaryAttack < - 0.001 )
{
pto - > m_flNextSecondaryAttack = - 0.001 ;
}
if ( pto - > m_flTimeWeaponIdle < - 0.001 )
{
pto - > m_flTimeWeaponIdle = - 0.001 ;
}
if ( pto - > m_flNextReload < - 0.001 )
{
pto - > m_flNextReload = - 0.001 ;
}
if ( pto - > fuser1 < - 0.001 )
{
pto - > fuser1 = - 0.001 ;
}
}
// m_flNextAttack is now part of the weapons, but is part of the player instead
to - > client . m_flNextAttack - = cmd - > msec / 1000.0 ;
if ( to - > client . m_flNextAttack < - 0.001 )
{
to - > client . m_flNextAttack = - 0.001 ;
}
to - > client . fuser2 - = cmd - > msec / 1000.0 ;
if ( to - > client . fuser2 < - 0.001 )
{
to - > client . fuser2 = - 0.001 ;
}
to - > client . fuser3 - = cmd - > msec / 1000.0 ;
if ( to - > client . fuser3 < - 0.001 )
{
to - > client . fuser3 = - 0.001 ;
}
// Store off the last position from the predicted state.
HUD_SetLastOrg ( ) ;
// Wipe it so we can't use it after this frame
g_finalstate = NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = =
HUD_PostRunCmd
Client calls this during prediction , after it has moved the player and updated any info changed into to - >
time is the current client clock based on prediction
cmd is the command that caused the movement , etc
runfuncs is 1 if this is the first time we ' ve predicted this command . If so , sounds and effects should play , otherwise , they should
be ignored
= = = = = = = = = = = = = = = = = = = = =
*/
void CL_DLLEXPORT HUD_PostRunCmd ( struct local_state_s * from , struct local_state_s * to , struct usercmd_s * cmd , int runfuncs , double time , unsigned int random_seed )
{
// RecClPostRunCmd(from, to, cmd, runfuncs, time, random_seed);
g_runfuncs = runfuncs ;
if ( cl_lw & & cl_lw - > value )
{
HUD_WeaponsPostThink ( from , to , cmd , time , random_seed ) ;
}
else
{
to - > client . fov = g_lastFOV ;
}
// Check to see whether too play local jetpack effects
if ( runfuncs )
{
static int sLastTime = 0 ;
float theTimePassed = time - sLastTime ;
//CheckJetpack();
//UpdateJetpackLights();
sLastTime = time ;
}
// All games can use FOV state
g_lastFOV = to - > client . fov ;
}