From 0c8a7ab23de92321d1ab457bb873b59a1de0c52e Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sun, 28 Mar 2021 12:26:44 +0500 Subject: [PATCH] Fix https://github.com/FWGS/hlsdk-xash3d/issues/127. --- cl_dll/ev_hldm.cpp | 42 +++++++++++++++++++++++++++++++++----- dlls/combat.cpp | 4 ++++ dlls/sound.cpp | 21 +++++++++++++++++++ dlls/util.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/util.h | 3 +++ dlls/weapons.cpp | 8 +++++++- dlls/weapons.h | 3 +++ 7 files changed, 125 insertions(+), 6 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index a2f84dfa..cf853c58 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -91,7 +91,7 @@ void EV_FireSniper( struct event_args_s *args ); // play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the // original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture. // returns volume of strike instrument (crowbar) to play -float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *vecEnd, int iBulletType ) +float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *vecEnd, float *forward, int iBulletType ) { // hit the world, try to play sound based on texture material type char chTextureType = CHAR_TEX_CONCRETE; @@ -104,6 +104,8 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v char *pTextureName; char texname[64]; char szbuffer[64]; + int flags = 0; + int iGibs = -1; entity = gEngfuncs.pEventAPI->EV_IndexFromTrace( ptr ); @@ -146,16 +148,19 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v chTextureType = PM_FindTextureType( szbuffer ); } } - + switch (chTextureType) { default: case CHAR_TEX_CONCRETE: + case CHAR_TEX_CONCRETE2: fvol = 0.9; fvolbar = 0.6; rgsz[0] = "player/pl_step1.wav"; rgsz[1] = "player/pl_step2.wav"; cnt = 2; + if( iBulletType != BULLET_PLAYER_CROWBAR && chTextureType == CHAR_TEX_CONCRETE2 ) + iGibs = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/concretegibs.mdl" ); break; case CHAR_TEX_METAL: fvol = 0.9; @@ -165,12 +170,23 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v cnt = 2; break; case CHAR_TEX_DIRT: + case CHAR_TEX_ROCK: + case CHAR_TEX_SMOKE: fvol = 0.9; fvolbar = 0.1; rgsz[0] = "player/pl_dirt1.wav"; rgsz[1] = "player/pl_dirt2.wav"; rgsz[2] = "player/pl_dirt3.wav"; cnt = 3; + if( iBulletType == BULLET_PLAYER_CROWBAR ) + break; + if( chTextureType == CHAR_TEX_SMOKE && iBulletType != BULLET_PLAYER_CROWBAR ) + gEngfuncs.pEfxAPI->R_Sprite_Smoke( gEngfuncs.pEfxAPI->R_DefaultSprite( ptr->endpos, gEngfuncs.pEventAPI->EV_FindModelIndex( "sprites/steam1.spr" ), 25 ), 12 * 0.1f ); + else if( chTextureType == CHAR_TEX_ROCK ) + { + iGibs = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/rockgibs.mdl" ); + flags = BREAK_CONCRETE; + } break; case CHAR_TEX_VENT: fvol = 0.5; @@ -195,6 +211,7 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v rgsz[3] = "player/pl_tile4.wav"; cnt = 4; break; + case CHAR_TEX_FLUID: case CHAR_TEX_SLOSH: fvol = 0.9; fvolbar = 0.0; @@ -205,12 +222,15 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v cnt = 4; break; case CHAR_TEX_WOOD: + case CHAR_TEX_WOOD2: fvol = 0.9; fvolbar = 0.2; rgsz[0] = "debris/wood1.wav"; rgsz[1] = "debris/wood2.wav"; rgsz[2] = "debris/wood3.wav"; cnt = 3; + if( iBulletType != BULLET_PLAYER_CROWBAR && chTextureType == CHAR_TEX_WOOD2 ) + iGibs = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/woodgibs.mdl" ); break; case CHAR_TEX_GLASS: case CHAR_TEX_COMPUTER: @@ -233,6 +253,17 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v break; } + if( iGibs != -1 ) + { + vec3_t size = {25, 25, 8}; + vec3_t dir; + + VectorCopy( forward, dir ); + VectorScale( dir, -100.0f, dir ); + + gEngfuncs.pEfxAPI->R_BreakModel( ptr->endpos, size, dir, 10, 50, 1, iGibs, flags ); + } + // play material hit sound gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, rgsz[gEngfuncs.pfnRandomLong( 0, cnt - 1 )], fvol, fattn, 0, 96 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); return fvolbar; @@ -435,22 +466,23 @@ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int { default: case BULLET_PLAYER_9MM: - EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); + EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, forward, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); break; case BULLET_PLAYER_MP5: if( !tracer ) { - EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); + EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, forward, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); } break; case BULLET_PLAYER_BUCKSHOT: + EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, forward, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); break; case BULLET_PLAYER_357: case BULLET_PLAYER_SNIPER: - EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); + EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, forward, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); break; } diff --git a/dlls/combat.cpp b/dlls/combat.cpp index a732fec0..af1a7bc6 100644 --- a/dlls/combat.cpp +++ b/dlls/combat.cpp @@ -1466,6 +1466,8 @@ void CBaseEntity::FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShootin UTIL_BubbleTrail( vecSrc, tr.vecEndPos, (int)( ( flDistance * tr.flFraction ) / 64.0f ) ); } ApplyMultiDamage( pev, pevAttacker ); + + UTIL_MuzzleLight( vecSrc, 15, Vector( 255, 255, 128 ), 1, 0 ); } /* @@ -1556,6 +1558,8 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi } ApplyMultiDamage( pev, pevAttacker ); + UTIL_MuzzleLight( vecSrc, 15, Vector( 255, 255, 128 ), 1, 0 ); + return Vector( x * vecSpread.x, y * vecSpread.y, 0.0 ); } diff --git a/dlls/sound.cpp b/dlls/sound.cpp index 688b4016..851e9b5c 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -1521,6 +1521,8 @@ float TEXTURETYPE_PlaySound( TraceResult *ptr, Vector vecSrc, Vector vecEnd, in const char *rgsz[4]; int cnt; float fattn = ATTN_NORM; + short sModelIndex = -1; + byte flags = 0; if( !g_pGameRules->PlayTextureSounds() ) return 0.0f; @@ -1572,11 +1574,14 @@ float TEXTURETYPE_PlaySound( TraceResult *ptr, Vector vecSrc, Vector vecEnd, in { default: case CHAR_TEX_CONCRETE: + case CHAR_TEX_CONCRETE2: fvol = 0.9f; fvolbar = 0.6f; rgsz[0] = "player/pl_step1.wav"; rgsz[1] = "player/pl_step2.wav"; cnt = 2; + if( chTextureType == CHAR_TEX_CONCRETE2 ) + sModelIndex = g_sModelIndexConcreteGibs; break; case CHAR_TEX_METAL: fvol = 0.9f; @@ -1586,12 +1591,21 @@ float TEXTURETYPE_PlaySound( TraceResult *ptr, Vector vecSrc, Vector vecEnd, in cnt = 2; break; case CHAR_TEX_DIRT: + case CHAR_TEX_ROCK: + case CHAR_TEX_SMOKE: fvol = 0.9f; fvolbar = 0.1f; rgsz[0] = "player/pl_dirt1.wav"; rgsz[1] = "player/pl_dirt2.wav"; rgsz[2] = "player/pl_dirt3.wav"; cnt = 3; + if( chTextureType == CHAR_TEX_SMOKE && iBulletType != BULLET_PLAYER_CROWBAR ) + UTIL_Smoke( ptr->vecEndPos, 25, 12, sModelIndex ); + else if( chTextureType == CHAR_TEX_ROCK ) + { + sModelIndex = g_sModelIndexRockGibs; + flags = BREAK_CONCRETE; + } break; case CHAR_TEX_VENT: fvol = 0.5f; @@ -1616,6 +1630,7 @@ float TEXTURETYPE_PlaySound( TraceResult *ptr, Vector vecSrc, Vector vecEnd, in rgsz[3] = "player/pl_tile4.wav"; cnt = 4; break; + case CHAR_TEX_FLUID: case CHAR_TEX_SLOSH: fvol = 0.9f; fvolbar = 0.0f; @@ -1626,12 +1641,15 @@ float TEXTURETYPE_PlaySound( TraceResult *ptr, Vector vecSrc, Vector vecEnd, in cnt = 4; break; case CHAR_TEX_WOOD: + case CHAR_TEX_WOOD2: fvol = 0.9f; fvolbar = 0.2f; rgsz[0] = "debris/wood1.wav"; rgsz[1] = "debris/wood2.wav"; rgsz[2] = "debris/wood3.wav"; cnt = 3; + if( chTextureType == CHAR_TEX_WOOD2 ) + sModelIndex = g_sModelIndexWoodGibs; break; case CHAR_TEX_GLASS: case CHAR_TEX_COMPUTER: @@ -1687,6 +1705,9 @@ float TEXTURETYPE_PlaySound( TraceResult *ptr, Vector vecSrc, Vector vecEnd, in } } + if( iBulletType != BULLET_PLAYER_CROWBAR && sModelIndex != -1 ) + UTIL_BreakModel( ptr->vecEndPos, Vector( 25, 25, 8 ), gpGlobals->v_forward * -100.0f, 10, sModelIndex, 1, 50, flags ); + // play material hit sound UTIL_EmitAmbientSound( ENT( 0 ), ptr->vecEndPos, rgsz[RANDOM_LONG( 0, cnt - 1 )], fvol, fattn, 0, 96 + RANDOM_LONG( 0, 0xf ) ); //EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_WEAPON, rgsz[RANDOM_LONG( 0, cnt - 1 )], fvol, ATTN_NORM, 0, 96 + RANDOM_LONG( 0, 0xf ) ); diff --git a/dlls/util.cpp b/dlls/util.cpp index e2e4292d..cbe98a24 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -31,6 +31,56 @@ #include "weapons.h" #include "gamerules.h" +void UTIL_MuzzleLight( const Vector &vecSrc, float flRadius, const Vector &color, float flTime, float flDecay ) +{ + MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); + WRITE_BYTE( TE_DLIGHT ); + WRITE_COORD( vecSrc.x ); // X + WRITE_COORD( vecSrc.y ); // Y + WRITE_COORD( vecSrc.z ); // Z + WRITE_BYTE( flRadius ); // radius * 0.1 + WRITE_BYTE( color.x ); // r + WRITE_BYTE( color.y ); // g + WRITE_BYTE( color.z ); // b + WRITE_BYTE( flTime ); // time * 10 + WRITE_BYTE( flDecay); // decay * 0.1 + MESSAGE_END(); +} + +void UTIL_Smoke( const Vector &origin, byte framerate, byte scale, short modelIndex ) +{ + MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, origin ); + WRITE_BYTE( TE_SMOKE ); + WRITE_COORD( origin.x ); + WRITE_COORD( origin.y ); + WRITE_COORD( origin.z ); + WRITE_SHORT( modelIndex == -1 ? g_sModelIndexSmoke : modelIndex ); + WRITE_BYTE( scale ); // scale * 10 + WRITE_BYTE( framerate ); // framerate + MESSAGE_END(); +} + +void UTIL_BreakModel( const Vector &origin, const Vector &size, const Vector &velocity, byte random, short modelIndex, byte shardNum, byte duration, byte flags ) +{ + MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, origin ); + WRITE_BYTE( TE_BREAKMODEL ); + WRITE_COORD( origin.x ); + WRITE_COORD( origin.y ); + WRITE_COORD( origin.z ); + WRITE_COORD( size.x ); + WRITE_COORD( size.y ); + WRITE_COORD( size.z ); + WRITE_COORD( velocity.x ); + WRITE_COORD( velocity.y ); + WRITE_COORD( velocity.z ); + WRITE_BYTE( random ); + WRITE_SHORT( modelIndex ); + WRITE_BYTE( shardNum ); + WRITE_BYTE( duration ); + WRITE_BYTE( flags ); + MESSAGE_END(); +} + float UTIL_WeaponTimeBase( void ) { #if defined( CLIENT_WEAPONS ) diff --git a/dlls/util.h b/dlls/util.h index 08c5af05..b27eedb1 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -578,4 +578,7 @@ int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); float UTIL_WeaponTimeBase( void ); +void UTIL_MuzzleLight( const Vector &vecSrc, float flRadius, const Vector &color, float flTime, float flDecay ); +void UTIL_Smoke( const Vector &origin, byte framerate, byte scale, short modelIndex ); +void UTIL_BreakModel( const Vector &origin, const Vector &size, const Vector &velocity, byte random, short modelIndex, byte shardNum, byte duration, byte flags ); #endif // UTIL_H diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index fdfdf70c..3a3e408e 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -45,6 +45,9 @@ DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the underwater e DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for the initial blood DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for splattered blood +DLL_GLOBAL short g_sModelIndexConcreteGibs; +DLL_GLOBAL short g_sModelIndexRockGibs; +DLL_GLOBAL short g_sModelIndexWoodGibs; ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS]; AmmoInfo CBasePlayerItem::AmmoInfoArray[MAX_AMMO_SLOTS]; @@ -378,7 +381,10 @@ void W_Precache( void ) g_sModelIndexSmoke = PRECACHE_MODEL( "sprites/steam1.spr" );// smoke g_sModelIndexBubbles = PRECACHE_MODEL( "sprites/bubble.spr" );//bubbles g_sModelIndexBloodSpray = PRECACHE_MODEL( "sprites/bloodspray.spr" ); // initial blood - g_sModelIndexBloodDrop = PRECACHE_MODEL( "sprites/blood.spr" ); // splattered blood + g_sModelIndexBloodDrop = PRECACHE_MODEL( "sprites/blood.spr" ); // splattered blood + g_sModelIndexConcreteGibs = PRECACHE_MODEL( "models/concretegibs.mdl" ); + g_sModelIndexRockGibs = PRECACHE_MODEL( "models/rockgibs.mdl" ); + g_sModelIndexWoodGibs = PRECACHE_MODEL( "models/woodgibs.mdl" ); g_sModelIndexLaser = PRECACHE_MODEL( g_pModelNameLaser ); g_sModelIndexLaserDot = PRECACHE_MODEL( "sprites/laserdot.spr" ); diff --git a/dlls/weapons.h b/dlls/weapons.h index 4fa7963e..817ac722 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -382,6 +382,9 @@ extern DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the under extern DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model extern DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for blood drops extern DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for blood spray (bigger) +extern DLL_GLOBAL short g_sModelIndexConcreteGibs; +extern DLL_GLOBAL short g_sModelIndexRockGibs; +extern DLL_GLOBAL short g_sModelIndexWoodGibs; extern void ClearMultiDamage(void); extern void ApplyMultiDamage(entvars_t* pevInflictor, entvars_t* pevAttacker );