From 0e539f9b260c3bee76b410baa570b8ac4c91fbce Mon Sep 17 00:00:00 2001 From: a1batross Date: Sat, 31 Oct 2015 01:36:15 +0300 Subject: [PATCH] Add client-side weapon prediction --- cl_dll/hl/hl_baseentity.cpp | 46 ++- cl_dll/hl/hl_events.cpp | 83 ++--- cl_dll/hl/hl_weapons.cpp | 674 ++++++++++++++++++++++++++++++------ 3 files changed, 653 insertions(+), 150 deletions(-) diff --git a/cl_dll/hl/hl_baseentity.cpp b/cl_dll/hl/hl_baseentity.cpp index e07b5ad..be34c65 100644 --- a/cl_dll/hl/hl_baseentity.cpp +++ b/cl_dll/hl/hl_baseentity.cpp @@ -81,22 +81,13 @@ BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeap void UTIL_LogPrintf(char *,...) { } void UTIL_ClientPrintAll( int,char const *,char const *,char const *,char const *,char const *) { } void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) { } +CBaseEntity *UTIL_FindEntityByClassname(CBaseEntity *pStartEntity, const char *szName) { return 0; } // CBaseToggle Stubs int CBaseToggle::Restore( class CRestore & ) { return 1; } int CBaseToggle::Save( class CSave & ) { return 1; } void CBaseToggle :: KeyValue( struct KeyValueData_s * ) { } -// CGrenade Stubs -void CGrenade::BounceSound( void ) { } -void CGrenade::Explode( Vector, Vector ) { } -void CGrenade::Explode( TraceResult *, int ) { } -void CGrenade::Killed( entvars_t *, int ) { } -void CGrenade::Spawn( void ) { } -CGrenade * CGrenade:: ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time ){ return 0; } -CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ){ return 0; } -void CGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ){ } - void UTIL_Remove( CBaseEntity *pEntity ){ } struct skilldata_t gSkillData; void UTIL_SetSize( entvars_t *pev, const Vector &vecMin, const Vector &vecMax ){ } @@ -213,7 +204,7 @@ Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flD void CBasePlayer :: ResetAutoaim( ) { } void CBasePlayer :: SetCustomDecalFrames( int nFrames ) { } int CBasePlayer :: GetCustomDecalFrames( void ) { return -1; } -void CBasePlayer::DropPlayerItem ( char *pszItemName ) { } +void CBasePlayer::DropPlayerItem ( const char *pszItemName ) { } BOOL CBasePlayer::HasPlayerItem( CBasePlayerItem *pCheckItem ) { return FALSE; } BOOL CBasePlayer :: SwitchWeapon( CBasePlayerItem *pWeapon ) { return FALSE; } Vector CBasePlayer :: GetGunPosition( void ) { return g_vecZero; } @@ -222,12 +213,45 @@ int CBasePlayer :: GiveAmmo( int iCount, char *szName, int iMax ) { return 0; } void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) { } void CBasePlayer::AddPointsToTeam( int score, BOOL bAllowNegativeScore ) { } +// CS16 START +void CBasePlayer::Restart( ) { } +void CBasePlayer::ResetMaxSpeed() { } +void CBasePlayer::RoundRespawn() { } +void CBasePlayer::Blind(float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha) { } +bool CBasePlayer::HasShield() { return FALSE; } +void CBasePlayerWeapon::KickBack(float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change) { } +void CBasePlayer::SetProgressBarTime( int iTime ) { } +void CBasePlayer::SetBombIcon( int ) { } +bool CBasePlayerWeapon::ShieldSecondaryFire(int up_anim, int down_anim) { return 0; } +void CBasePlayerWeapon::SetPlayerShieldAnim() { } +void CBasePlayerWeapon::ResetPlayerShieldAnim() { } +void CBasePlayer::UpdateShieldCrosshair(bool bShieldDrawn) { } +void CBasePlayer::Radio(const char *msg_id, const char *msg_verbose, int pitch, bool showIcon) { } + +void RadiusFlash(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage) { } +void UTIL_TraceHull(const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr) { } +float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType) { } +void UTIL_ScreenShake(const Vector ¢er, float amplitude, float frequency, float duration, float radius) { } +void UTIL_Bubbles(Vector mins, Vector maxs, int count) { } +void RemoveEntityHashValue(entvars_s *pev, const char *value, hash_types_e fieldType) { } +void AddEntityHashValue(entvars_s *pev, const char *value, hash_types_e fieldType) { } +int UTIL_PointContents(const Vector &vec) { } +void UTIL_EmitAmbientSound(edict_t *entity, const Vector &vecOrigin, const char *samp, float vol, float attenuation, int fFlags, int pitch) { } + +CGrenade *CGrenade::ShootSatchelCharge(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity) { } +CGrenade *CGrenade::ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time) { } +CGrenade *CGrenade::ShootTimed2(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time, int iTeam, unsigned short usEvent) { } +CGrenade *CGrenade::ShootSmokeGrenade(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time, unsigned short usEvent) { } + +// CS16 END + void ClearMultiDamage(void) { } void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker ) { } void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) { } void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage) { } int DamageDecal( CBaseEntity *pEntity, int bitsDamageType ) { return 0; } void DecalGunshot( TraceResult *pTrace, int iBulletType ) { } +void DecalGunshot( TraceResult *pTrace, int iBulletType, bool ClientOnly, entvars_t *pShooter, bool bHitMetal ) { } void EjectBrass ( const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ) { } void AddAmmoNameToAmmoRegistry( const char *szAmmoname ) { } int CBasePlayerItem::Restore( class CRestore & ) { return 1; } diff --git a/cl_dll/hl/hl_events.cpp b/cl_dll/hl/hl_events.cpp index 5ad4459..d497f46 100644 --- a/cl_dll/hl/hl_events.cpp +++ b/cl_dll/hl/hl_events.cpp @@ -19,26 +19,20 @@ extern "C" { // HLDM -void EV_FireGlock1( struct event_args_s *args ); -void EV_FireGlock2( struct event_args_s *args ); -void EV_FireShotGunSingle( struct event_args_s *args ); -void EV_FireShotGunDouble( struct event_args_s *args ); -void EV_FireMP5( struct event_args_s *args ); -void EV_FireMP52( struct event_args_s *args ); -void EV_FirePython( struct event_args_s *args ); -void EV_FireGauss( struct event_args_s *args ); -void EV_SpinGauss( struct event_args_s *args ); -void EV_Crowbar( struct event_args_s *args ); -void EV_FireCrossbow( struct event_args_s *args ); -void EV_FireCrossbow2( struct event_args_s *args ); -void EV_FireRpg( struct event_args_s *args ); -void EV_EgonFire( struct event_args_s *args ); -void EV_EgonStop( struct event_args_s *args ); -void EV_HornetGunFire( struct event_args_s *args ); -void EV_TripmineFire( struct event_args_s *args ); -void EV_SnarkFire( struct event_args_s *args ); - - + void EV_Knife( event_args_t *args ); + void EV_FireUSP( struct event_args_s *args ); + void EV_Fireglock18( struct event_args_s *args ); + void EV_FireM4A1( struct event_args_s *args ); + void EV_FireAK47( struct event_args_s *args ); + void EV_FireAWP( struct event_args_s *args ); + void EV_FireGALIL( struct event_args_s *args ); + void EV_FireFAMAS( struct event_args_s *args ); + void EV_FireDEAGLE( struct event_args_s *args ); + void EV_FireAUG( struct event_args_s *args ); + void EV_FireSG552( struct event_args_s *args ); + void EV_FireMP5( struct event_args_s *args ); + void EV_FireM3( struct event_args_s *args ); + void EV_Dummy( struct event_args_s *args ); void EV_TrainPitchAdjust( struct event_args_s *args ); } @@ -58,23 +52,34 @@ That was what we were going to do, but we ran out of time...oh well. */ void Game_HookEvents( void ) { - gEngfuncs.pfnHookEvent( "events/glock1.sc", EV_FireGlock1 ); - gEngfuncs.pfnHookEvent( "events/glock2.sc", EV_FireGlock2 ); - gEngfuncs.pfnHookEvent( "events/shotgun1.sc", EV_FireShotGunSingle ); - gEngfuncs.pfnHookEvent( "events/shotgun2.sc", EV_FireShotGunDouble ); - gEngfuncs.pfnHookEvent( "events/mp5.sc", EV_FireMP5 ); - gEngfuncs.pfnHookEvent( "events/mp52.sc", EV_FireMP52 ); - gEngfuncs.pfnHookEvent( "events/python.sc", EV_FirePython ); - gEngfuncs.pfnHookEvent( "events/gauss.sc", EV_FireGauss ); - gEngfuncs.pfnHookEvent( "events/gaussspin.sc", EV_SpinGauss ); - gEngfuncs.pfnHookEvent( "events/train.sc", EV_TrainPitchAdjust ); - gEngfuncs.pfnHookEvent( "events/crowbar.sc", EV_Crowbar ); - gEngfuncs.pfnHookEvent( "events/crossbow1.sc", EV_FireCrossbow ); - gEngfuncs.pfnHookEvent( "events/crossbow2.sc", EV_FireCrossbow2 ); - gEngfuncs.pfnHookEvent( "events/rpg.sc", EV_FireRpg ); - gEngfuncs.pfnHookEvent( "events/egon_fire.sc", EV_EgonFire ); - gEngfuncs.pfnHookEvent( "events/egon_stop.sc", EV_EgonStop ); - gEngfuncs.pfnHookEvent( "events/firehornet.sc", EV_HornetGunFire ); - gEngfuncs.pfnHookEvent( "events/tripfire.sc", EV_TripmineFire ); - gEngfuncs.pfnHookEvent( "events/snarkfire.sc", EV_SnarkFire ); + gEngfuncs.pfnHookEvent("events/ak47.sc", EV_FireAK47); + gEngfuncs.pfnHookEvent("events/aug.sc", EV_FireAUG); + gEngfuncs.pfnHookEvent("events/awp.sc", EV_FireAWP); + gEngfuncs.pfnHookEvent("events/createexplo.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/createsmoke.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/deagle.sc", EV_FireDEAGLE); + gEngfuncs.pfnHookEvent("events/decal_reset.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/elite_left.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/elite_right.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/famas.sc", EV_FireFAMAS); + gEngfuncs.pfnHookEvent("events/fiveseven.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/g3sg1.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/galil.sc", EV_FireGALIL); + gEngfuncs.pfnHookEvent("events/glock18.sc", EV_Fireglock18); + gEngfuncs.pfnHookEvent("events/knife.sc", EV_Knife); + gEngfuncs.pfnHookEvent("events/m249.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/m3.sc", EV_FireM3); + gEngfuncs.pfnHookEvent("events/m4a1.sc", EV_FireM4A1); + gEngfuncs.pfnHookEvent("events/mac10.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/mp5n.sc", EV_FireMP5); + gEngfuncs.pfnHookEvent("events/p228.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/p90.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/scout.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/sg550.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/sg552.sc", EV_FireSG552); + gEngfuncs.pfnHookEvent("events/tmp.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/ump45.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/usp.sc", EV_FireUSP); + gEngfuncs.pfnHookEvent("events/vehicle.sc", EV_Dummy); + gEngfuncs.pfnHookEvent("events/xm1014.sc", EV_Dummy); } diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 820e49f..9b4a8f6 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -31,6 +31,14 @@ #include "../com_weapons.h" #include "../demo.h" +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + extern globalvars_t *gpGlobals; extern int g_iUser1; @@ -52,7 +60,7 @@ int g_irunninggausspred = 0; vec3_t previousorigin; // HLDM Weapon placeholder entities. -CGlock g_Glock; +/*CGlock g_Glock; CCrowbar g_Crowbar; CPython g_Python; CMP5 g_Mp5; @@ -65,8 +73,37 @@ CHgun g_HGun; CHandGrenade g_HandGren; CSatchel g_Satchel; CTripmine g_Tripmine; -CSqueak g_Snark; +CSqueak g_Snark;*/ +CAK47 g_AK47; +CAUG g_AUG; +CAWP g_AWP; +CC4 g_C4; +CDEAGLE g_DEAGLE; +CELITE g_ELITE; +CFamas g_Famas; +CFiveSeven g_FiveSeven; +CFlashbang g_Flashbang; +CG3SG1 g_G3SG1; +CGalil g_Galil; +CGLOCK18 g_GLOCK18; +CHEGrenade g_HEGrenade; +CKnife g_Knife; +CM249 g_M249; +CM3 g_M3; +CM4A1 g_M4A1; +CMAC10 g_MAC10; +CMP5N g_MP5N; +CP228 g_P228; +CP90 g_P90; +CSCOUT g_SCOUT; +CSG550 g_SG550; +CSG552 g_SG552; +CSmokeGrenade g_SmokeGrenade; +CTMP g_TMP; +CUMP45 g_UMP45; +CUSP g_USP; +CXM1014 g_XM1014; /* ====================== @@ -108,6 +145,61 @@ Links the raw entity to an entvars_s holder. If a player is passed in as the ow we set up the m_pPlayer field. ===================== */ +edict_t *EHANDLE::Get(void) +{ + if (!m_pent) + return NULL; + + if (m_pent->serialnumber != m_serialnumber) + return NULL; + + return m_pent; +} + +edict_t *EHANDLE::Set(edict_t *pent) +{ + m_pent = pent; + + if (pent) + m_serialnumber = m_pent->serialnumber; + + return pent; +} + +EHANDLE::operator CBaseEntity *(void) +{ + return (CBaseEntity *)GET_PRIVATE(Get()); +} + +CBaseEntity *EHANDLE::operator = (CBaseEntity *pEntity) +{ + if (pEntity) + { + m_pent = ENT(pEntity->pev); + + if (m_pent) + m_serialnumber = m_pent->serialnumber; + } + else + { + m_pent = NULL; + m_serialnumber = 0; + } + + return pEntity; +} + +EHANDLE::operator int(void) +{ + return Get() != NULL; +} + +CBaseEntity *EHANDLE::operator ->(void) +{ + return (CBaseEntity *)GET_PRIVATE(Get()); +} + + void HUD_PrepEntity( CBaseEntity *pEntity, CBasePlayer *pWeaponOwner ) { memset( &ev[ num_ents ], 0, sizeof( entvars_t ) ); @@ -159,7 +251,7 @@ BOOL CBasePlayerWeapon :: DefaultReload( int iClipSize, int iAnim, float fDelay, m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fDelay; //!!UNDONE -- reload sound goes here !!! - SendWeaponAnim( iAnim, UseDecrement(), body ); + SendWeaponAnim( iAnim, UseDecrement() ); m_fInReload = TRUE; @@ -208,14 +300,14 @@ CBasePlayerWeapon :: DefaultDeploy ===================== */ -BOOL CBasePlayerWeapon :: DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal, int body ) +BOOL CBasePlayerWeapon :: DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal ) { if ( !CanDeploy() ) return FALSE; gEngfuncs.CL_LoadModel( szViewModel, &m_pPlayer->pev->viewmodel ); - SendWeaponAnim( iAnim, skiplocal, body ); + SendWeaponAnim( iAnim, skiplocal ); g_irunninggausspred = false; m_pPlayer->m_flNextAttack = 0.5; @@ -272,49 +364,289 @@ CBasePlayerWeapon::SendWeaponAnim Animate weapon model ===================== */ -void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal, int body ) +void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal ) { m_pPlayer->pev->weaponanim = iAnim; - HUD_SendWeaponAnim( iAnim, body, 0 ); + HUD_SendWeaponAnim( iAnim, m_pPlayer->pev->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 ) +Vector CBaseEntity::FireBullets3 ( Vector vecSrc, Vector vecDirShooting, float flSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand ) { - float x, y, z; + /*int iOriginalPenetration = iPenetration; + int iPenetrationPower; + float flPenetrationDistance; + int iCurrentDamage = iDamage; + float flCurrentDistance; + TraceResult tr, tr2; + Vector vecRight = gpGlobals->v_right; + Vector vecUp = gpGlobals->v_up; + CBaseEntity *pEntity; + bool bHitMetal = false; + int iSparksAmount; - for ( ULONG iShot = 1; iShot <= cShots; iShot++ ) + switch (iBulletType) { - 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; - } - + case BULLET_PLAYER_9MM: + { + iPenetrationPower = 21; + flPenetrationDistance = 800; + iSparksAmount = 15; + iCurrentDamage += (-4 + RANDOM_LONG(0, 10)); + break; } - return Vector ( x * vecSpread.x, y * vecSpread.y, 0.0 ); -} + case BULLET_PLAYER_45ACP: + { + iPenetrationPower = 15; + flPenetrationDistance = 500; + iSparksAmount = 20; + iCurrentDamage += (-2 + RANDOM_LONG(0, 4)); + break; + } + case BULLET_PLAYER_50AE: + { + iPenetrationPower = 30; + flPenetrationDistance = 1000; + iSparksAmount = 20; + iCurrentDamage += (-4 + RANDOM_LONG(0, 10)); + break; + } + + case BULLET_PLAYER_762MM: + { + iPenetrationPower = 39; + flPenetrationDistance = 5000; + iSparksAmount = 30; + iCurrentDamage += (-2 + RANDOM_LONG(0, 4)); + break; + } + + case BULLET_PLAYER_556MM: + { + iPenetrationPower = 35; + flPenetrationDistance = 4000; + iSparksAmount = 30; + iCurrentDamage += (-3 + RANDOM_LONG(0, 6)); + break; + } + + case BULLET_PLAYER_338MAG: + { + iPenetrationPower = 45; + flPenetrationDistance = 8000; + iSparksAmount = 30; + iCurrentDamage += (-4 + RANDOM_LONG(0, 8)); + break; + } + + case BULLET_PLAYER_57MM: + { + iPenetrationPower = 30; + flPenetrationDistance = 2000; + iSparksAmount = 20; + iCurrentDamage += (-4 + RANDOM_LONG(0, 10)); + break; + } + + case BULLET_PLAYER_357SIG: + { + iPenetrationPower = 25; + flPenetrationDistance = 800; + iSparksAmount = 20; + iCurrentDamage += (-4 + RANDOM_LONG(0, 10)); + break; + } + + default: + { + iPenetrationPower = 0; + flPenetrationDistance = 0; + break; + } + } + + if (!pevAttacker) + pevAttacker = pev; + + //gMultiDamage.type = DMG_BULLET | DMG_NEVERGIB; + + float x, y, z; + + if (IsPlayer()) + { + x = UTIL_SharedRandomFloat(shared_rand, -0.5, 0.5) + UTIL_SharedRandomFloat(shared_rand + 1, -0.5, 0.5); + y = UTIL_SharedRandomFloat(shared_rand + 2, -0.5, 0.5) + UTIL_SharedRandomFloat(shared_rand + 3, -0.5, 0.5); + } + else + { + 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); + } + + Vector vecDir = vecDirShooting + x * flSpread * vecRight + y * flSpread * vecUp; + Vector vecEnd = vecSrc + vecDir * flDistance; + Vector vecOldSrc; + Vector vecNewSrc; + float flDamageModifier = 0.5; + + while (iPenetration != 0) + { + ClearMultiDamage(); + UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr); + + char cTextureType = UTIL_TextureHit(&tr, vecSrc, vecEnd); + bool bSparks = false; + + switch (cTextureType) + { + case CHAR_TEX_METAL: + { + bSparks = true; + bHitMetal = true; + iPenetrationPower *= 0.15; + flDamageModifier = 0.2; + break; + } + + case CHAR_TEX_CONCRETE: + { + iPenetrationPower *= 0.25; + flDamageModifier = 0.25; + break; + } + + case CHAR_TEX_GRATE: + { + bSparks = true; + bHitMetal = true; + iPenetrationPower *= 0.5; + flDamageModifier = 0.4; + break; + } + + case CHAR_TEX_VENT: + { + bSparks = true; + bHitMetal = true; + iPenetrationPower *= 0.5; + flDamageModifier = 0.45; + break; + } + + case CHAR_TEX_TILE: + { + iPenetrationPower *= 0.65; + flDamageModifier = 0.3; + break; + } + + case CHAR_TEX_COMPUTER: + { + bSparks = true; + bHitMetal = true; + iPenetrationPower *= 0.4; + flDamageModifier = 0.45; + break; + } + + case CHAR_TEX_WOOD: + { + iPenetrationPower *= 1; + flDamageModifier = 0.6; + break; + } + + default: + { + bSparks = false; + break; + } + } + + if (tr.flFraction != 1.0) + { + pEntity = CBaseEntity::Instance(tr.pHit); + iPenetration--; + flCurrentDistance = tr.flFraction * flDistance; + iCurrentDamage *= pow(flRangeModifier, flCurrentDistance / 500); + + if (flCurrentDistance > flPenetrationDistance) + iPenetration = 0; + + if (tr.iHitgroup == HITGROUP_SHIELD) + { + iPenetration = 0; + + if (tr.flFraction != 1.0) + { + if (RANDOM_LONG(0, 1)) + EMIT_SOUND(pEntity->edict(), CHAN_VOICE, "weapons/ric_metal-1.wav", 1, ATTN_NORM); + else + EMIT_SOUND(pEntity->edict(), CHAN_VOICE, "weapons/ric_metal-2.wav", 1, ATTN_NORM); + + UTIL_Sparks(tr.vecEndPos); + + pEntity->pev->punchangle.x = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15); + pEntity->pev->punchangle.z = iCurrentDamage * RANDOM_FLOAT(-0.15, 0.15); + + if (pEntity->pev->punchangle.x < 4) + pEntity->pev->punchangle.x = 4; + + if (pEntity->pev->punchangle.z < -5) + pEntity->pev->punchangle.z = -5; + else if (pEntity->pev->punchangle.z > 5) + pEntity->pev->punchangle.z = 5; + } + + break; + } + + if ((VARS(tr.pHit)->solid == SOLID_BSP) && (iPenetration != 0)) + { + if (bPistol) + DecalGunshot(&tr, iBulletType, false, pev, bHitMetal); + else if (RANDOM_LONG(0, 3)) + DecalGunshot(&tr, iBulletType, true, pev, bHitMetal); + + vecSrc = tr.vecEndPos + (vecDir * iPenetrationPower); + flDistance = (flDistance - flCurrentDistance) * 0.5; + vecEnd = vecSrc + (vecDir * flDistance); + + pEntity->TraceAttack(pevAttacker, iCurrentDamage, vecDir, &tr, DMG_BULLET | DMG_NEVERGIB); + + iCurrentDamage *= flDamageModifier; + } + else + { + if (bPistol) + DecalGunshot(&tr, iBulletType, false, pev, bHitMetal); + else if (RANDOM_LONG(0, 3)) + DecalGunshot(&tr, iBulletType, true, pev, bHitMetal); + + vecSrc = tr.vecEndPos + (vecDir * 42); + flDistance = (flDistance - flCurrentDistance) * 0.75; + vecEnd = vecSrc + (vecDir * flDistance); + + pEntity->TraceAttack(pevAttacker, iCurrentDamage, vecDir, &tr, DMG_BULLET | DMG_NEVERGIB); + + iCurrentDamage *= 0.75; + } + } + else + iPenetration = 0; + + ApplyMultiDamage(pev, pevAttacker); + } + + return Vector(x * flSpread, y * flSpread, 0);*/ +} /* ===================== CBasePlayerWeapon::ItemPostFrame @@ -563,6 +895,59 @@ void UTIL_ParticleLine( CBasePlayer *player, float *start, float *end, float lif gEngfuncs.pEfxAPI->R_ParticleLine( start, end, r, g, b, life ); } +/*char UTIL_TextureHit(TraceResult *ptr, Vector vecSrc, Vector vecEnd) +{ + char chTextureType; + float rgfl1[3], rgfl2[3]; + const char *pTextureName; + char szbuffer[64]; + CBaseEntity *pEntity = CBaseEntity::Instance(ptr->pHit); + + if (pEntity && pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE) + return CHAR_TEX_FLESH; + + vecSrc.CopyToArray(rgfl1); + vecEnd.CopyToArray(rgfl2); + + if (pEntity) + pTextureName = TRACE_TEXTURE(ENT(pEntity->pev), rgfl1, rgfl2); + else + pTextureName = TRACE_TEXTURE(ENT(0), rgfl1, rgfl2); + + if (pTextureName) + { + if (*pTextureName == '-' || *pTextureName == '+') + pTextureName += 2; + + if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') + pTextureName++; + + strcpy(szbuffer, pTextureName); + szbuffer[CBTEXTURENAMEMAX - 1] = 0; + chTextureType = TEXTURETYPE_Find(szbuffer); + } + else + chTextureType = 0; + + return chTextureType; +}*/ + +CBaseEntity *UTIL_PlayerByIndex(int playerIndex) +{ + CBaseEntity *pPlayer = NULL; + + if (playerIndex > 0 && playerIndex <= gpGlobals->maxClients) + { + edict_t *pPlayerEdict = INDEXENT(playerIndex); + + if (pPlayerEdict && !pPlayerEdict->free) + pPlayer = CBaseEntity::Instance(pPlayerEdict); + } + + return pPlayer; +} + + /* ===================== CBasePlayerWeapon::PrintState @@ -570,14 +955,14 @@ CBasePlayerWeapon::PrintState For debugging, print out state variables to log file ===================== */ -void CBasePlayerWeapon::PrintState( void ) +/*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 ); -} +}*/ /* ===================== @@ -621,7 +1006,7 @@ void HUD_InitClientWeapons( void ) HUD_PrepEntity( &player , NULL ); // Allocate slot(s) for each weapon that we are going to be predicting - HUD_PrepEntity( &g_Glock , &player ); + /*HUD_PrepEntity( &g_Glock , &player ); HUD_PrepEntity( &g_Crowbar , &player ); HUD_PrepEntity( &g_Python , &player ); HUD_PrepEntity( &g_Mp5 , &player ); @@ -634,7 +1019,36 @@ void HUD_InitClientWeapons( void ) HUD_PrepEntity( &g_HandGren , &player ); HUD_PrepEntity( &g_Satchel , &player ); HUD_PrepEntity( &g_Tripmine , &player ); - HUD_PrepEntity( &g_Snark , &player ); + HUD_PrepEntity( &g_Snark , &player );*/ + HUD_PrepEntity( &g_P228, &player); + //HUD_PrepEntity( &g_GLOCK18, &player); + HUD_PrepEntity( &g_SCOUT, &player); + HUD_PrepEntity( &g_HEGrenade, &player); + HUD_PrepEntity( &g_XM1014, &player); + HUD_PrepEntity( &g_C4, &player); + HUD_PrepEntity( &g_MAC10, &player); + HUD_PrepEntity( &g_AUG, &player); + HUD_PrepEntity( &g_SmokeGrenade, &player); + HUD_PrepEntity( &g_ELITE, &player); + HUD_PrepEntity( &g_FiveSeven, &player); + HUD_PrepEntity( &g_UMP45, &player); + HUD_PrepEntity( &g_SG550, &player); + HUD_PrepEntity( &g_Galil, &player); + HUD_PrepEntity( &g_Famas, &player); + HUD_PrepEntity( &g_USP, &player); + HUD_PrepEntity( &g_GLOCK18, &player); + HUD_PrepEntity( &g_AWP, &player); + HUD_PrepEntity( &g_MP5N, &player); + HUD_PrepEntity( &g_M249, &player); + HUD_PrepEntity( &g_M4A1, &player); + HUD_PrepEntity( &g_TMP, &player); + HUD_PrepEntity( &g_G3SG1, &player); + HUD_PrepEntity( &g_Flashbang, &player); + HUD_PrepEntity( &g_DEAGLE, &player); + HUD_PrepEntity( &g_SG552, &player); + HUD_PrepEntity( &g_AK47, &player); + HUD_PrepEntity( &g_Knife, &player); + HUD_PrepEntity( &g_P90, &player ); } /* @@ -700,60 +1114,120 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm // FIXME, make this a method in each weapon? where you pass in an entity_state_t *? switch ( from->client.m_iId ) { - case WEAPON_CROWBAR: - pWeapon = &g_Crowbar; + case WEAPON_P228: + pWeapon = &g_P228; break; - case WEAPON_GLOCK: - pWeapon = &g_Glock; - break; - - case WEAPON_PYTHON: - pWeapon = &g_Python; + case WEAPON_SCOUT: + pWeapon = &g_SCOUT; break; - case WEAPON_MP5: - pWeapon = &g_Mp5; + case WEAPON_HEGRENADE: + pWeapon = &g_HEGrenade; break; - case WEAPON_CROSSBOW: - pWeapon = &g_Crossbow; + case WEAPON_XM1014: + pWeapon = &g_XM1014; break; - case WEAPON_SHOTGUN: - pWeapon = &g_Shotgun; + case WEAPON_C4: + pWeapon = &g_C4; break; - case WEAPON_RPG: - pWeapon = &g_Rpg; + case WEAPON_MAC10: + pWeapon = &g_MAC10; break; - case WEAPON_GAUSS: - pWeapon = &g_Gauss; + case WEAPON_AUG: + pWeapon = &g_AUG; break; - case WEAPON_EGON: - pWeapon = &g_Egon; + case WEAPON_SMOKEGRENADE: + pWeapon = &g_SmokeGrenade; break; - case WEAPON_HORNETGUN: - pWeapon = &g_HGun; + case WEAPON_ELITE: + pWeapon = &g_ELITE; break; - case WEAPON_HANDGRENADE: - pWeapon = &g_HandGren; + case WEAPON_FIVESEVEN: + pWeapon = &g_FiveSeven; break; - case WEAPON_SATCHEL: - pWeapon = &g_Satchel; + case WEAPON_UMP45: + pWeapon = &g_UMP45; break; - case WEAPON_TRIPMINE: - pWeapon = &g_Tripmine; + case WEAPON_SG550: + pWeapon = &g_SG550; break; - case WEAPON_SNARK: - pWeapon = &g_Snark; + case WEAPON_GALIL: + pWeapon = &g_Galil; + break; + + case WEAPON_FAMAS: + pWeapon = &g_Famas; + break; + + case WEAPON_USP: + pWeapon = &g_USP; + break; + + case WEAPON_GLOCK18: + pWeapon = &g_GLOCK18; + break; + + case WEAPON_AWP: + pWeapon = &g_AWP; + break; + + case WEAPON_MP5N: + pWeapon = &g_MP5N; + break; + + case WEAPON_M249: + pWeapon = &g_M249; + break; + + case WEAPON_M3: + pWeapon = &g_M3; + break; + + case WEAPON_M4A1: + pWeapon = &g_M4A1; + break; + + case WEAPON_TMP: + pWeapon = &g_TMP; + break; + + case WEAPON_G3SG1: + pWeapon = &g_G3SG1; + break; + + case WEAPON_FLASHBANG: + pWeapon = &g_Flashbang; + break; + + case WEAPON_DEAGLE: + pWeapon = &g_DEAGLE; + break; + + case WEAPON_SG552: + pWeapon = &g_SG552; + break; + + case WEAPON_AK47: + pWeapon = &g_AK47; + break; + + case WEAPON_KNIFE: + pWeapon = &g_Knife; + break; + + case WEAPON_P90: + pWeapon = &g_P90; break; } @@ -803,9 +1277,9 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm pCurrent->pev->fuser1 = pfrom->fuser1; pCurrent->m_flStartThrow = pfrom->fuser2; pCurrent->m_flReleaseThrow = pfrom->fuser3; - pCurrent->m_chargeReady = pfrom->iuser1; + /*pCurrent->m_chargeReady = pfrom->iuser1; pCurrent->m_fInAttack = pfrom->iuser2; - pCurrent->m_fireState = pfrom->iuser3; + pCurrent->m_fireState = pfrom->iuser3;*/ pCurrent->m_iSecondaryAmmoType = (int)from->client.vuser3[ 2 ]; pCurrent->m_iPrimaryAmmoType = (int)from->client.vuser4[ 0 ]; @@ -841,18 +1315,18 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm 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; + //player.m_flNextAmmoBurn = from->client.fuser2; + //player.m_flAmmoStartCharge = from->client.fuser3; //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_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; + //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 @@ -861,11 +1335,11 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm player.m_pActiveItem = g_pWpns[ from->client.m_iId ]; } - if ( player.m_pActiveItem->m_iId == WEAPON_RPG ) + /*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 ]; - } + }*/ // Don't go firing anything if we have died. // Or if we don't have a weapon model deployed @@ -914,26 +1388,26 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm 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.fuser2 = player.m_flNextAmmoBurn; + //to->client.fuser3 = player.m_flAmmoStartCharge; to->client.maxspeed = player.pev->maxspeed; //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.vuser1[1] = player.ammo_357; + //to->client.vuser1[2] = player.ammo_argrens; - to->client.ammo_nails = player.ammo_bolts; + //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; + //to->client.ammo_cells = player.ammo_uranium; + //to->client.vuser2[0] = player.ammo_hornets; + //to->client.ammo_rockets = player.ammo_rockets; - if ( player.m_pActiveItem->m_iId == WEAPON_RPG ) + /*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; - } + }*/ // Make sure that weapon animation matches what the game .dll is telling us // over the wire ( fixes some animation glitches ) @@ -942,12 +1416,12 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm int body = 2; //Pop the model to body 0. - if ( pWeapon == &g_Tripmine ) - body = 0; + /*if ( pWeapon == &g_Tripmine ) + body = 0;*/ //Show laser sight/scope combo - if ( pWeapon == &g_Python && bIsMultiplayer() ) - body = 1; + /*if ( pWeapon == &g_Python && bIsMultiplayer() ) + body = 1;*/ // Force a fixed anim down to viewmodel HUD_SendWeaponAnim( to->client.weaponanim, body, 1 ); @@ -975,9 +1449,9 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm pto->fuser1 = pCurrent->pev->fuser1; pto->fuser2 = pCurrent->m_flStartThrow; pto->fuser3 = pCurrent->m_flReleaseThrow; - pto->iuser1 = pCurrent->m_chargeReady; - pto->iuser2 = pCurrent->m_fInAttack; - pto->iuser3 = pCurrent->m_fireState; + //pto->iuser1 = pCurrent->m_chargeReady; + //pto->iuser2 = pCurrent->m_fInAttack; + //pto->iuser3 = pCurrent->m_fireState; // Decrement weapon counters, server does this at same time ( during post think, after doing everything else ) pto->m_flNextReload -= cmd->msec / 1000.0;