From 88f2cd32ade44b574fd4d28ce8c18f7dbc2ac0c4 Mon Sep 17 00:00:00 2001 From: wootguy Date: Tue, 3 Dec 2024 15:01:17 -0800 Subject: [PATCH] fix broken explosion hit detection (fixes #33) mp_explosionbug 1 reverts this change, for players that like grenades turning into mini nukes inside vents. --- dlls/env/CEnvExplosion.cpp | 41 +++++++++++++++++++++----------------- dlls/game/game.cpp | 2 ++ dlls/game/game.h | 3 +++ dlls/weapon/CGrenade.cpp | 31 +++++++++++++++++----------- dlls/weapon/CGrenade.h | 1 + dlls/weapon/combat.cpp | 7 ++++++- 6 files changed, 54 insertions(+), 31 deletions(-) diff --git a/dlls/env/CEnvExplosion.cpp b/dlls/env/CEnvExplosion.cpp index 72f88c79..fd9da7b2 100644 --- a/dlls/env/CEnvExplosion.cpp +++ b/dlls/env/CEnvExplosion.cpp @@ -19,6 +19,7 @@ class CEnvExplosion : public CPointEntity int m_iMagnitude;// how large is the fireball? how much damage? int m_spriteScale; // what's the exact fireball sprite scale? + Vector m_effectOrigin; // where to play the explosion effects (offset from real origin so sprites look nice) }; TYPEDESCRIPTION CEnvExplosion::m_SaveData[] = @@ -84,14 +85,12 @@ void CEnvExplosion::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE UTIL_TraceLine(vecSpot, vecSpot + Vector(0, 0, -40), ignore_monsters, ENT(pev), &tr); + m_effectOrigin = pev->origin; + // Pull out of the wall a bit if (tr.flFraction != 1.0) { - pev->origin = tr.vecEndPos + (tr.vecPlaneNormal * (m_iMagnitude - 24) * 0.6); - } - else - { - pev->origin = pev->origin; + m_effectOrigin = tr.vecEndPos + (tr.vecPlaneNormal * (m_iMagnitude - 24) * 0.6); } // draw decal @@ -110,11 +109,11 @@ void CEnvExplosion::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE // draw fireball if (!(pev->spawnflags & SF_ENVEXPLOSION_NOFIREBALL)) { - MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, pev->origin); + MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, m_effectOrigin); WRITE_BYTE(TE_EXPLOSION); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z); + WRITE_COORD(m_effectOrigin.x); + WRITE_COORD(m_effectOrigin.y); + WRITE_COORD(m_effectOrigin.z); WRITE_SHORT(g_sModelIndexFireball); WRITE_BYTE((BYTE)m_spriteScale); // scale * 10 WRITE_BYTE(15); // framerate @@ -125,9 +124,9 @@ void CEnvExplosion::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE { MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, pev->origin); WRITE_BYTE(TE_EXPLOSION); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z); + WRITE_COORD(m_effectOrigin.x); + WRITE_COORD(m_effectOrigin.y); + WRITE_COORD(m_effectOrigin.z); WRITE_SHORT(g_sModelIndexFireball); WRITE_BYTE(0); // no sprite WRITE_BYTE(15); // framerate @@ -141,7 +140,13 @@ void CEnvExplosion::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE if (!(pev->spawnflags & SF_ENVEXPLOSION_NODAMAGE)) { entvars_t* ownerpev = pev->owner ? &pev->owner->v : pev; - ::RadiusDamage(pev->origin, pev, ownerpev, m_iMagnitude, m_iMagnitude * 2.5, CLASS_NONE, DMG_BLAST); + + if (mp_explosionbug.value) { + ::RadiusDamage(m_effectOrigin, pev, ownerpev, m_iMagnitude, m_iMagnitude * 2.5, CLASS_NONE, DMG_BLAST); + } + else { + ::RadiusDamage(pev->origin, pev, ownerpev, m_iMagnitude, m_iMagnitude * 2.5, CLASS_NONE, DMG_BLAST); + } } SetThink(&CEnvExplosion::Smoke); @@ -154,7 +159,7 @@ void CEnvExplosion::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE for (int i = 0; i < sparkCount; i++) { - Create("spark_shower", pev->origin, tr.vecPlaneNormal, NULL); + Create("spark_shower", m_effectOrigin, tr.vecPlaneNormal, NULL); } } } @@ -163,11 +168,11 @@ void CEnvExplosion::Smoke(void) { if (!(pev->spawnflags & SF_ENVEXPLOSION_NOSMOKE)) { - MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, pev->origin); + MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, m_effectOrigin); WRITE_BYTE(TE_SMOKE); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z); + WRITE_COORD(m_effectOrigin.x); + WRITE_COORD(m_effectOrigin.y); + WRITE_COORD(m_effectOrigin.z); WRITE_SHORT(g_sModelIndexSmoke); WRITE_BYTE((BYTE)m_spriteScale); // scale * 10 WRITE_BYTE(12); // framerate diff --git a/dlls/game/game.cpp b/dlls/game/game.cpp index 94b77866..86c8f26f 100644 --- a/dlls/game/game.cpp +++ b/dlls/game/game.cpp @@ -49,6 +49,7 @@ cvar_t allowmonsters={"mp_allowmonsters","1", FCVAR_SERVER, 0, 0 }; cvar_t mp_nextmap={"mp_nextmap","", FCVAR_SERVER, 0, 0 }; cvar_t mp_prefer_server_maxspeed={"mp_prefer_server_maxspeed","1", FCVAR_SERVER, 0, 0 }; cvar_t mp_objectboost ={"mp_objectboost","0", FCVAR_SERVER, 0, 0 }; +cvar_t mp_explosionbug ={"mp_explosionbug","0", FCVAR_SERVER, 0, 0 }; cvar_t mp_respawndelay ={"mp_respawndelay","3", FCVAR_SERVER, 0, 0 }; cvar_t mp_debugmsg ={"mp_debugmsg","0", FCVAR_SERVER, 0, 0 }; cvar_t mp_starthealth ={"starthealth","0", FCVAR_SERVER, 0, 0 }; @@ -359,6 +360,7 @@ void GameDLLInit( void ) CVAR_REGISTER (&mp_nextmap); CVAR_REGISTER (&mp_prefer_server_maxspeed); CVAR_REGISTER (&mp_objectboost); + CVAR_REGISTER (&mp_explosionbug); CVAR_REGISTER (&mp_respawndelay); CVAR_REGISTER (&mp_debugmsg); CVAR_REGISTER (&mp_starthealth); diff --git a/dlls/game/game.h b/dlls/game/game.h index 1d2d100b..de967e6f 100644 --- a/dlls/game/game.h +++ b/dlls/game/game.h @@ -80,6 +80,9 @@ EXPORT extern cvar_t mp_default_medkit; // provide a medkit by default unless no // The higher your FPS, the faster you can boost pushables. You also get boosted. EXPORT extern cvar_t mp_objectboost; +// Enables classic hit detection for explosives (grenade in vent hits everything nearby) +EXPORT extern cvar_t mp_explosionbug; + // write network messages to log file for debugging EXPORT extern cvar_t mp_debugmsg; diff --git a/dlls/weapon/CGrenade.cpp b/dlls/weapon/CGrenade.cpp index 400a8ca7..037d94c4 100644 --- a/dlls/weapon/CGrenade.cpp +++ b/dlls/weapon/CGrenade.cpp @@ -54,19 +54,21 @@ void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) pev->takedamage = DAMAGE_NO; + m_effectOrigin = pev->origin; + // Pull out of the wall a bit - if ( pTrace->flFraction != 1.0 ) + if (pTrace->flFraction != 1.0) { - pev->origin = pTrace->vecEndPos + (pTrace->vecPlaneNormal * (pev->dmg - 24) * 0.6); + m_effectOrigin = pTrace->vecEndPos + (pTrace->vecPlaneNormal * (pev->dmg - 24) * 0.6); } int iContents = UTIL_PointContents ( pev->origin ); - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); + MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, m_effectOrigin ); WRITE_BYTE( TE_EXPLOSION ); // This makes a dynamic light and the explosion sprites/sound - WRITE_COORD( pev->origin.x ); // Send to PAS because of the sound - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); + WRITE_COORD(m_effectOrigin.x); // Send to PAS because of the sound + WRITE_COORD(m_effectOrigin.y); + WRITE_COORD(m_effectOrigin.z); if (iContents != CONTENTS_WATER) { WRITE_SHORT( g_sModelIndexFireball ); @@ -89,7 +91,12 @@ void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) pev->owner = NULL; // can't traceline attack owner if this is set - RadiusDamage ( pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType ); + if (mp_explosionbug.value) { + RadiusDamage(m_effectOrigin, pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType); + } + else { + RadiusDamage(pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType); + } if ( RANDOM_FLOAT( 0 , 1 ) < 0.5 ) { @@ -118,7 +125,7 @@ void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) { int sparkCount = RANDOM_LONG(0,3); for ( int i = 0; i < sparkCount; i++ ) - Create( "spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL ); + Create( "spark_shower", m_effectOrigin, pTrace->vecPlaneNormal, NULL ); } } @@ -131,11 +138,11 @@ void CGrenade::Smoke( void ) } else { - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin ); + MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, m_effectOrigin); WRITE_BYTE( TE_SMOKE ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); + WRITE_COORD(m_effectOrigin.x ); + WRITE_COORD(m_effectOrigin.y ); + WRITE_COORD(m_effectOrigin.z ); WRITE_SHORT( g_sModelIndexSmoke ); WRITE_BYTE( (pev->dmg - 50) * 0.80 ); // scale * 10 WRITE_BYTE( 12 ); // framerate diff --git a/dlls/weapon/CGrenade.h b/dlls/weapon/CGrenade.h index 85414808..832c5932 100644 --- a/dlls/weapon/CGrenade.h +++ b/dlls/weapon/CGrenade.h @@ -40,4 +40,5 @@ class CGrenade : public CBaseMonster virtual BOOL IsNormalMonster(void) { return FALSE; } BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet. + Vector m_effectOrigin; // where to play the explosion effects (offset from real origin so sprites look nice) }; diff --git a/dlls/weapon/combat.cpp b/dlls/weapon/combat.cpp index e6b285c7..3ca2088a 100644 --- a/dlls/weapon/combat.cpp +++ b/dlls/weapon/combat.cpp @@ -45,10 +45,15 @@ void RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacke else falloff = 1.0; - int bInWater = (UTIL_PointContents ( vecSrc ) == CONTENTS_WATER); + int pointContents = UTIL_PointContents(vecSrc); + int bInWater = (pointContents == CONTENTS_WATER); vecSrc.z += 1;// in case grenade is lying on the ground + if (mp_explosionbug.value == 0 && UTIL_PointContents(vecSrc) != pointContents) { + vecSrc.z -= 1; // must have hit a ceiling + } + if ( !pevAttacker ) pevAttacker = pevInflictor;