nuclide/Source/shared/effects.c

296 lines
8.4 KiB
C
Raw Normal View History

2019-01-16 16:43:50 +00:00
/***
*
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
*
* See the file LICENSE attached with the sources for usage details.
*
****/
void Effect_CreateExplosion( vector vPos ) {
#ifdef SSQC
vPos_z += 48;
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_EXPLOSION );
WriteCoord( MSG_MULTICAST, vPos_x );
WriteCoord( MSG_MULTICAST, vPos_y );
WriteCoord( MSG_MULTICAST, vPos_z );
msg_entity = self;
multicast( vPos, MULTICAST_PVS );
#else
sprite eExplosion = spawn(sprite);
setorigin( eExplosion, vPos );
setmodel( eExplosion, "sprites/fexplo.spr" );
sound( eExplosion, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 3 ) + 3 ), 1, ATTN_NORM );
//eExplosion.think = Effect_CreateExplosion_Animate;
eExplosion.nextthink = time + 0.05f;
eExplosion.effects = EF_ADDITIVE;
eExplosion.drawmask = MASK_ENGINE;
eExplosion.maxframe = modelframecount( eExplosion.modelindex );
te_explosion( vPos );
#endif
}
void Effect_CreateSpark( vector vPos, vector vAngle ) {
#ifdef SSQC
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_SPARK );
WriteCoord( MSG_MULTICAST, vPos_x );
WriteCoord( MSG_MULTICAST, vPos_y );
WriteCoord( MSG_MULTICAST, vPos_z );
WriteCoord( MSG_MULTICAST, vAngle_x );
WriteCoord( MSG_MULTICAST, vAngle_y );
WriteCoord( MSG_MULTICAST, vAngle_z );
msg_entity = self;
multicast( vPos, MULTICAST_PVS );
#else
pointparticles( PARTICLE_SPARK, vPos, vAngle, 1 );
pointsound( vPos, sprintf( "buttons/spark%d.wav", floor( random() * 6 ) + 1 ), 1, ATTN_STATIC );
#endif
}
#ifdef CSTRIKE
#ifdef SSQC
void Effect_CreateFlash( entity eTarget ) {
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_FLASH );
msg_entity = eTarget;
multicast( '0 0 0', MULTICAST_ONE );
}
#endif
#endif
#ifdef CSTRIKE
void Effect_CreateSmoke( vector vPos ) {
#ifdef SSQC
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_SMOKE );
WriteCoord( MSG_MULTICAST, vPos_x );
WriteCoord( MSG_MULTICAST, vPos_y );
WriteCoord( MSG_MULTICAST, vPos_z );
msg_entity = self;
multicast( '0 0 0', MULTICAST_ALL );
#else
static void Effect_CreateSmoke_Think( void ) {
// HACK: This should only ever happen when rounds restart!
// Any way this can go wrong?
if ( self.skin < getstatf( STAT_GAMETIME ) ) {
remove( self );
}
if ( self.frame <= 0 ) {
remove( self );
return;
}
pointparticles( PARTICLE_SMOKEGRENADE, self.origin, '0 0 0', 1 );
self.frame--;
self.nextthink = time + 0.2f;
self.skin = getstatf( STAT_GAMETIME );
}
entity eSmoke = spawn();
setorigin( eSmoke, vPos );
eSmoke.think = Effect_CreateSmoke_Think;
eSmoke.nextthink = time;
eSmoke.frame = 200;
eSmoke.skin = getstatf( STAT_GAMETIME );
#endif
}
#endif
void Effect_Impact( int iType, vector vPos, vector vNormal ) {
#ifdef SSQC
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_IMPACT );
WriteByte( MSG_MULTICAST, (float)iType );
WriteCoord( MSG_MULTICAST, vPos_x );
WriteCoord( MSG_MULTICAST, vPos_y );
WriteCoord( MSG_MULTICAST, vPos_z );
WriteCoord( MSG_MULTICAST, vNormal_x );
WriteCoord( MSG_MULTICAST, vNormal_y );
WriteCoord( MSG_MULTICAST, vNormal_z );
msg_entity = self;
multicast( vPos, MULTICAST_PVS );
#else
switch ( iType ) {
case IMPACT_MELEE:
/*pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );*/
pointsound( vPos, "weapons/knife_hitwall1.wav", 1, ATTN_STATIC );
break;
case IMPACT_EXPLOSION:
break;
case IMPACT_GLASS:
pointparticles( DECAL_GLASS, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
break;
case IMPACT_WOOD:
pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
pointparticles( PARTICLE_SMOKE_BROWN, vPos, vNormal, 1 );
break;
case IMPACT_METAL:
pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
break;
case IMPACT_FLESH:
pointparticles( PARTICLE_BLOOD, vPos, vNormal, 1 );
break;
case IMPACT_DEFAULT:
pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
pointparticles( PARTICLE_SMOKE_GREY, vPos, vNormal, 1 );
break;
default:
}
switch ( iType ) {
case IMPACT_METAL:
pointsound( vPos, sprintf( "weapons/ric_metal-%d.wav", floor( ( random() * 2 ) + 1 ) ), 1, ATTN_STATIC );
break;
case IMPACT_FLESH:
break;
default:
pointsound( vPos, sprintf( "weapons/ric%d.wav", floor( ( random() * 5 ) + 1 ) ), 1, ATTN_STATIC );
break;
}
#endif
}
void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle ) {
#ifdef SSQC
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
WriteByte( MSG_MULTICAST, EV_MODELGIB );
WriteCoord( MSG_MULTICAST, vMins_x);
WriteCoord( MSG_MULTICAST, vMins_y);
WriteCoord( MSG_MULTICAST, vMins_z);
WriteCoord( MSG_MULTICAST, vMaxs_x);
WriteCoord( MSG_MULTICAST, vMaxs_y);
WriteCoord( MSG_MULTICAST, vMaxs_z);
WriteByte( MSG_MULTICAST, fStyle );
msg_entity = self;
vector vWorldPos;
vWorldPos_x = vMins_x + ( 0.5 * ( vMaxs_x - vMins_x ) );
vWorldPos_y = vMins_y + ( 0.5 * ( vMaxs_y - vMins_y ) );
vWorldPos_z = vMins_z + ( 0.5 * ( vMaxs_z - vMins_z ) );
multicast( vWorldPos, MULTICAST_PVS );
#else
static void Effect_BreakModel_Remove( void ) { remove( self ) ; }
float fModelCount;
vector vPos;
string sModel = "";
float fCount = 20;
switch ( fStyle ) {
case MATERIAL_GLASS:
case MATERIAL_GLASS_UNBREAKABLE:
sModel = "models/glassgibs.mdl";
fModelCount = 8;
break;
case MATERIAL_WOOD:
sModel = "models/woodgibs.mdl";
fModelCount = 3;
break;
case MATERIAL_METAL:
sModel = "models/metalplategibs.mdl";
fModelCount = 13;
break;
case MATERIAL_FLESH:
sModel = "models/fleshgibs.mdl";
fModelCount = 4;
break;
case MATERIAL_TILE:
sModel = "models/ceilinggibs.mdl";
fModelCount = 4;
break;
case MATERIAL_COMPUTER:
sModel = "models/computergibs.mdl";
fModelCount = 15;
break;
case MATERIAL_ROCK:
sModel = "models/rockgibs.mdl";
fModelCount = 3;
break;
default:
case MATERIAL_CINDER:
sModel = "models/cindergibs.mdl";
fModelCount = 9;
break;
}
vector vWorldPos;
vWorldPos_x = vMins_x + ( 0.5 * ( vMaxs_x - vMins_x ) );
vWorldPos_y = vMins_y + ( 0.5 * ( vMaxs_y - vMins_y ) );
vWorldPos_z = vMins_z + ( 0.5 * ( vMaxs_z - vMins_z ) );
switch ( fStyle ) {
case MATERIAL_GLASS:
pointsound( vWorldPos, sprintf( "debris/bustglass%d.wav", random( 1, 4 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_WOOD:
pointsound( vWorldPos, sprintf( "debris/bustcrate%d.wav", random( 1, 4 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_METAL:
case MATERIAL_COMPUTER:
pointsound( vWorldPos, sprintf( "debris/bustmetal%d.wav", random( 1, 3 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_FLESH:
pointsound( vWorldPos, sprintf( "debris/bustflesh%d.wav", random( 1, 3 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_CINDER:
case MATERIAL_ROCK:
pointsound( vWorldPos, sprintf( "debris/bustconcrete%d.wav", random( 1, 4 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_TILE:
pointsound( vWorldPos, "debris/bustceiling.wav", 1.0f, ATTN_NORM );
break;
}
while ( fCount > 0 ) {
entity eGib = spawn();
eGib.classname = "gib";
vPos_x = vMins_x + ( random() * ( vMaxs_x - vMins_x ) );
vPos_y = vMins_y + ( random() * ( vMaxs_y - vMins_y ) );
vPos_z = vMins_z + ( random() * ( vMaxs_z - vMins_z ) );
setorigin( eGib, vPos );
setmodel( eGib, sModel );
setcustomskin( eGib, "", sprintf( "geomset 0 %f\n", random( 1, fModelCount + 1 ) ) );
eGib.movetype = MOVETYPE_BOUNCE;
eGib.solid = SOLID_NOT;
eGib.avelocity_x = random()*600;
eGib.avelocity_y = random()*600;
eGib.avelocity_z = random()*600;
eGib.think = Effect_BreakModel_Remove;
eGib.nextthink = time + 10;
if ( ( fStyle == MATERIAL_GLASS ) || ( fStyle == MATERIAL_GLASS_UNBREAKABLE ) ) {
eGib.effects = EF_ADDITIVE;
eGib.alpha = 0.3;
}
fCount--;
eGib.drawmask = MASK_ENGINE;
}
#endif
}
#ifdef CSQC
float Effect_Decal( void ) {
adddecal( self.classname, self.origin, self.mins, self.maxs, self.color, 1.0f );
addentity( self );
return PREDRAW_NEXT;
}
#endif