Page 1 of 1

[STOCK] Creating explosions by the engine

Posted: Fri Sep 25, 2026 4:36 am
by Archive-Poster
Here is a stock I usually use for my plugins. With this one you can create an explosion effect (dmg included only if enabled) without caching sprites, and these sh*ts.

Code: Select all

/**
 * Creates an explosion which the engine will do.
 * Note: Requieres Engine Module. Tested only on CS Steam.
 *
 * @param vecCenter                Position where the explosion should be created.
 * @param iMagnitude            Explosion size. This defines the explosion's max damage and sprite's size
 * @param iFlags                Explosion flags which you can find on hlsdk_const.inc
 * @param bDoDamage                Should do a radius damage?
 * @param bNoActivate        If this param is on true, the entity won't explode, and you must do it manually
 * @return                    Entity index on sucess, 0 on failure.
 */

stock ExplosionCreate(const Float:vecCenter[3], iMagnitude, iFlags = 0, bool:bDoDamage = true, bool:bNoActivate = false)
{
    // env_explosion entities are the ones
    // who creates explosions. So we are available
    // for using this one for creating explosions
    new iEnt = create_entity("env_explosion")
    
    if(!iEnt) // Invalid?
    return 0
    
    // The center of the explosion
    entity_set_origin(iEnt, vecCenter)
    
    // Key values must be only string, so we must
    // convert it from Int to String.
    new szMagnitude[8] // In explode.cpp the char size is 128 lol.
    formatex(szMagnitude, charsmax(szMagnitude), "%3d", iMagnitude) // Exactly as how the engine does it.
    DispatchKeyValue(iEnt, "iMagnitude", szMagnitude) // This will modify m_iMagnitude value.
    
    // In hlsdk_const.inc you can find env_explosion's spawn flags
    if(!bDoDamage) // If you don't want to create a damage sphere, so we must only add this flag.
        entity_set_int(iEnt, EV_INT_spawnflags, iFlags | SF_ENVEXPLOSION_NODAMAGE)
    else
        entity_set_int(iEnt, EV_INT_spawnflags, iFlags) // 3rd parameter flags.
    
    // Applying some pev values, and offset modifications
    DispatchSpawn(iEnt)
    
    if(!bNoActivate)
        force_use(iEnt, iEnt) // The engine doesn't care who used it. Btw, this actives the explosion.
    
    return iEnt
} 
Code from explode.cpp (HLSDK, line 257):

Code: Select all

// HACKHACK -- create one of these and fake a keyvalue to get the right explosion setup
void ExplosionCreate( const Vector &center, const Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage )
{
    KeyValueData    kvd;
    char            buf[128];

    CBaseEntity *pExplosion = CBaseEntity::Create( "env_explosion", center, angles, pOwner );
    sprintf( buf, "%3d", magnitude );
    kvd.szKeyName = "iMagnitude";
    kvd.szValue = buf;
    pExplosion->KeyValue( &kvd );
    if ( !doDamage )
        pExplosion->pev->spawnflags |= SF_ENVEXPLOSION_NODAMAGE;

    pExplosion->Spawn();
    pExplosion->Use( NULL, NULL, USE_TOGGLE, 0 );
} 
You can easily use it like in this example:

Code: Select all

// HamSandwich forward "Ham_Killed" on "player"
// Called when someone killed.
public fw_Player_Killed(iVictim) 
{
    new Float:vecOrigin[3]
    entity_get_vector(iVictim, EV_VEC_origin, vecOrigin)
    
    ExplosionCreate(vecOrigin, 100.0)
} 
If you want to modify engine default values, check this example of how to it:

Code: Select all

// HamSandwich forward "Ham_Killed" on "player"
// Called when someone killed.
public fw_Player_Killed(iVictim) 
{
    new Float:vecOrigin[3]
    entity_get_vector(iVictim, EV_VEC_origin, vecOrigin)
    
    // Registering Ham_TakeDamage fwd
    new HamHook:hTakeDamageFwd = RegisterHam(Ham_TakeDamage, "player", "fw_Player_TakeDamage")
    
    // Creating explosion entity
    new iEntId = ExplosionCreate(vecOrigin, 100.0, _ /* no flags */, true, true /* we must activate it manually */)
    
    // His owner would be the victim, here is where we should
    entity_set_edict(iEntId, EV_ENT_owner, iVictim)
    
    // Manually activation
    force_use(iEntId, iEntId) 
    
    // We don't need the Ham forward, so we must disable it
    DisableHamForward(hTakeDamageFwd)
}

// HamSandwich forward "Ham_TakeDamage" on "player"
// Called when "in this case" someone takes damage by an explosion entity.
public fw_Player_TakeDamage(iVictim, iInflictor, iAttacker, Float:flDamage, iDamageType)
{
    // iVictim -> Any player on the radius
    // iInflictor -> Explosion entity
    // iAttacker -> iInflictor
    // flDamage -> Damage done
    // iDamageType -> DMG_BLAST
    
    // The attacker will be the player who got killed
    // If mp_friendlyfire cvar is off, won't do team kill
    SetHamParamEntity(3, entity_get_edict(iInflictor, EV_ENT_owner))
    
    // Fix DMG_BLAST value which does not able to send DeathMsg HUD
    SetHamParamInteger(5, DMG_GENERIC) // DMG_GENERIC works fine without probles
    
    // Any code that you want to put, do it here.
    // Like restrictions for special players, etc.
    // ...
} 
For usage, you must Copy-Paste this code to your plugin, and including "engine".