I tried something like this a while ago but lost the source and forgot how until I remembered 20 minutes ago...
Code:
// Causes pain to someone by using a trigger_hurt to apply damage
// Params:
// pVictim - Who takes the damage
// pInflictor - Who does the damage
// flAmount - How much damage to do ( TRIGGER_HURT TAKES ARMOR INTO ACCOUNT! )
// iDmgmask - See DMG_xxx macros, in cbase.h I think
// pszPainname - What should this pain be called? NULL leaves it at trigger_hurt
void Ouch( edict_t* pVictim, edict_t* pInflictor, float flAmount, int iDmgmask, const char* pszPainname ) {
char szKeyValue[ 32 ]; // Will contain iDmgmask as a string
edict_t* pEnt = NULL; // Trigger_hurt entity pointer
KeyValueData keyData; // Used to setup the damage type on the trigger_hurt entity
// Create a trigger_hurt entity
pEnt = CREATE_NAMED_ENTITY( MAKE_STRING( "trigger_hurt" ) );
// Make sure it's valid
if ( ! FNullEnt( pEnt ) ) {
if ( pszPainname ) pEnt->v.classname = MAKE_STRING( pszPainname ); // Custom name! ( if set )
pEnt->v.dmg_inflictor = INDEXENT( 0 ); // Who's attacking me?
pEnt->v.dmg = flAmount; // Take this much damage ( note: goes by trigger_hurt rules! )
pEnt->v.dmg_take = 1.0f; // TODO: Figure out what this does... later
pEnt->v.dmgtime = 2.0f; // ^^^^^
// Somewhere out of the way
SET_ORIGIN( pEnt, Vector( -4000, -4000, -4000 ) );
SET_SIZE( pEnt, Vector( -32, -32, -32 ), Vector( 32, 32, 32 ) );
// Setup the damage type
_snprintf( szKeyValue, sizeof( szKeyValue ), "%d", iDmgmask ); // Setup value string
keyData.szClassName = ( char* ) pszPainname; // TODO: ???
keyData.szKeyName = "damagetype"; // damagetype key
keyData.szValue = szKeyValue; // What kind of damage to do
keyData.fHandled = FALSE; // Not handled yet
// Set the key/value pair on the entity
MDLL_KeyValue( pEnt, &keyData );
// Spawn it and force it to touch us...
MDLL_Spawn( pEnt );
MDLL_Touch( pEnt, pVictim );
// So noone accidentally walks into it later on
REMOVE_ENTITY( pEnt );
}
}
void ClientCommand( edict_t* pEdict ) {
if ( FStrEq( CMD_ARGV( 0 ), "hurtme" ) ) {
Ouch( pEdict, INDEXENT( 0 ), 35.0f, ( 1<< 4 ) /* DMG_FROZEN */, "canadian_winter" );
RETURN_META( MRES_SUPERCEDE );
}
RETURN_META( MRES_IGNORED );
}
I just tested that locally by myself and it seems to work great, you can even have your custom death message set.
This should work with any mod that has trigger_hurt entities compiled in.