Пример #1
0
/*
* CG_Event_FireRiotgun
*/
static void CG_Event_FireRiotgun( vec3_t origin, vec3_t dir, int weapon, int firemode, int seed, int owner ) 
{
	trace_t	trace;
	vec3_t end;
	gs_weapon_definition_t *weapondef = GS_GetWeaponDef( weapon );
	firedef_t *firedef = ( firemode ) ? &weapondef->firedef : &weapondef->firedef_weak;

	CG_Fire_SpiralPattern( origin, dir, &seed, owner, firedef->projectile_count, firedef->spread, firedef->timeout, CG_BulletImpact );

	// spawn a single sound at the impact
	VectorMA( origin, firedef->timeout, dir, end );
	CG_Trace( &trace, origin, vec3_origin, vec3_origin, end, owner, MASK_SHOT );

	if( trace.ent != -1 && !( trace.surfFlags & SURF_NOIMPACT ) )
	{
		if( firedef->fire_mode == FIRE_MODE_STRONG )
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRiotgunStrongHit ), trace.endpos, CHAN_AUTO,
				cg_volume_effects->value, ATTN_IDLE );
		}
		else
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRiotgunWeakHit ), trace.endpos, CHAN_AUTO,
				cg_volume_effects->value, ATTN_IDLE );
		}
	}
}
Пример #2
0
/*
* CG_BladeImpact
*/
void CG_BladeImpact( const vec3_t pos, const vec3_t dir )
{
	lentity_t *le;
	vec3_t angles;
	vec3_t end;
	vec3_t local_pos, local_dir;
	trace_t	trace;

	//find what are we hitting
	VectorCopy( pos, local_pos );
	VectorNormalize2( dir, local_dir );
	VectorMA( pos, -1.0, local_dir, end );
	CG_Trace( &trace, local_pos, vec3_origin, vec3_origin, end, cg.view.POVent, MASK_SHOT );
	if( trace.fraction == 1.0 )
		return;

	VecToAngles( local_dir, angles );

	if( trace.surfFlags & SURF_FLESH ||
		( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_PLAYER )
		|| ( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_CORPSE ) )
	{
		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak
			1, 1, 1, 1, //full white no inducted alpha
			0, 0, 0, 0, //dlight
			CG_MediaModel( cgs.media.modBladeWallHit ), NULL );
		le->ent.rotation = rand() % 360;
		le->ent.scale = 1.0f;

		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeFleshHit[(int)( random()*3 )] ), pos, CHAN_AUTO,
			cg_volume_effects->value, ATTN_NORM );
	}
	else if( trace.surfFlags & SURF_DUST )
	{
		// throw particles on dust
		CG_ParticleEffect( trace.endpos, trace.plane.normal, 0.30f, 0.30f, 0.25f, 30 );

		//fixme? would need a dust sound
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeWallHit[(int)( random()*2 )] ), pos, CHAN_AUTO,
			cg_volume_effects->value, ATTN_NORM );
	}
	else
	{
		le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 3, //3 frames for weak
			1, 1, 1, 1, //full white no inducted alpha
			0, 0, 0, 0, //dlight
			CG_MediaModel( cgs.media.modBladeWallHit ), NULL );
		le->ent.rotation = rand() % 360;
		le->ent.scale = 1.0f;

		CG_ParticleEffect( trace.endpos, trace.plane.normal, 0.30f, 0.30f, 0.25f, 15 );

		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxBladeWallHit[(int)( random()*2 )] ), pos, CHAN_AUTO,
			cg_volume_effects->value, ATTN_NORM );
		if( !( trace.surfFlags & SURF_NOMARKS ) )
			CG_SpawnDecal( pos, dir, random()*10, 8, 1, 1, 1, 1, 10, 1, false, CG_MediaShader( cgs.media.shaderBladeMark ) );
	}
}
Пример #3
0
/*
* CG_BoltExplosionMode
*/
void CG_BoltExplosionMode( const vec3_t pos, const vec3_t dir, int fire_mode, int surfFlags )
{
	lentity_t *le;
	vec3_t angles;

	if( !CG_SpawnDecal( pos, dir, random()*360, 12, 
		1, 1, 1, 1, 10, 1, true, CG_MediaShader( cgs.media.shaderElectroboltMark ) ) ) {
		if( surfFlags & (SURF_SKY|SURF_NOMARKS|SURF_NOIMPACT) ) {
			return;
		}
	}

	VecToAngles( dir, angles );

	le = CG_AllocModel( LE_INVERSESCALE_ALPHA_FADE, pos, angles, 6, // 6 is time
		1, 1, 1, 1, //full white no inducted alpha
		250, 0.75, 0.75, 0.75, //white dlight
		CG_MediaModel( cgs.media.modElectroBoltWallHit ), NULL );

	le->ent.rotation = rand() % 360;
	le->ent.scale = ( fire_mode == FIRE_MODE_STRONG ) ? 1.5f : 1.0f;
	
	// add white energy particles on the impact
	CG_ImpactPuffParticles( pos, dir, 15, 0.75f, 1, 1, 1, 1, NULL );
	
	trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxElectroboltHit ), pos, CHAN_AUTO, 
		cg_volume_effects->value, ATTN_STATIC );
}
Пример #4
0
/*
* CG_GenericExplosion
*/
void CG_GenericExplosion( vec3_t pos, vec3_t dir, int fire_mode, float radius )
{
	lentity_t *le;
	vec3_t angles;
	vec3_t decaldir;
	vec3_t origin, vec;
	float expvelocity = 8.0f;

	VectorCopy( dir, decaldir );
	VecToAngles( dir, angles );

	//if( CG_PointContents( pos ) & MASK_WATER )
	//jalfixme: (shouldn't we do the water sound variation?)

	if( fire_mode == FIRE_MODE_STRONG )
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.5, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	else
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.25, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );

	// animmap shader of the explosion
	VectorMA( pos, radius*0.15f, dir, origin );
	le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius * 0.5f, 8,
		1, 1, 1, 1,
		radius*4, 0.75f, 0.533f, 0, // yellow dlight
		CG_MediaShader( cgs.media.shaderRocketExplosion ) );

	VectorSet( vec, crandom()*expvelocity, crandom()*expvelocity, crandom()*expvelocity );
	VectorScale( dir, expvelocity, le->velocity );
	VectorAdd( le->velocity, vec, le->velocity );
	le->ent.rotation = rand() % 360;

	// use the rocket explosion sounds
	if( fire_mode == FIRE_MODE_STRONG )
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherStrongHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
	else
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherWeakHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
}
Пример #5
0
static void CG_Event_FireMachinegun( vec3_t origin, vec3_t dir, int weapon, int firemode, int seed, int owner )
{
	float r, u;
	double alpha, s;
	trace_t trace, *water_trace;
	gs_weapon_definition_t *weapondef = GS_GetWeaponDef( weapon );
	firedef_t *firedef = ( firemode ) ? &weapondef->firedef : &weapondef->firedef_weak;
	int range = firedef->timeout, spread = firedef->spread;

	// circle shape
	alpha = M_PI * Q_crandom( &seed ); // [-PI ..+PI]
	s = fabs( Q_crandom( &seed ) ); // [0..1]
	r = s * cos( alpha ) * spread;
	u = s * sin( alpha ) * spread;

	water_trace = GS_TraceBullet( &trace, origin, dir, r, u, range, owner, 0 );
	if( water_trace )
	{
		if( !VectorCompare( water_trace->endpos, origin ) )
			CG_LeadWaterSplash( water_trace );
	}

	if( trace.ent != -1 && !( trace.surfFlags & SURF_NOIMPACT ) )
	{
		CG_BulletImpact( &trace );

		if( !water_trace )
		{
			if( trace.surfFlags & SURF_FLESH ||
				( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_PLAYER ) ||
				( trace.ent > 0 && cg_entities[trace.ent].current.type == ET_CORPSE ) )
			{
				// flesh impact sound
			}
			else
				trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRic[ rand()&2 ] ), trace.endpos, CHAN_AUTO, cg_volume_effects->value, ATTN_STATIC );
		}
	}

	if( water_trace )
		CG_LeadBubbleTrail( &trace, water_trace->endpos );
}
Пример #6
0
/*
* CG_InstaExplosionMode
*/
void CG_InstaExplosionMode( const vec3_t pos, const vec3_t dir, int fire_mode, int surfFlags, int owner )
{
	int team = -1;
	vec4_t tcolor = { 0.65f, 0.0f, 0.26f, 1.0f };
	lentity_t *le;
	vec3_t angles;

	if( cg_teamColoredInstaBeams->integer && owner && ( owner < gs.maxclients + 1 ) )
		team = cg_entities[owner].current.team;
	if( ( team == TEAM_ALPHA ) || ( team == TEAM_BETA ) )
	{
		CG_TeamColor( team, tcolor );
		tcolor[0] *= 0.65f;
		tcolor[1] *= 0.65f;
		tcolor[2] *= 0.65f;
	}

	if( !CG_SpawnDecal( pos, dir, random()*360, 12, 
		tcolor[0], tcolor[1], tcolor[2], 1.0f,
		10, 1, true, CG_MediaShader( cgs.media.shaderInstagunMark ) ) ) {
		if( surfFlags & (SURF_SKY|SURF_NOMARKS|SURF_NOIMPACT) ) {
			return;
		}
	}

	VecToAngles( dir, angles );

	le = CG_AllocModel( LE_ALPHA_FADE, pos, angles, 6, // 6 is time
		tcolor[0], tcolor[1], tcolor[2], 1,
		250, 0.65, 0.65, 0.65, //white dlight
		CG_MediaModel( cgs.media.modInstagunWallHit ), NULL );

	le->ent.rotation = rand() % 360;
	le->ent.scale = ( fire_mode == FIRE_MODE_STRONG ) ? 1.5f : 1.0f;
	// add white energy particles on the impact
	CG_ImpactPuffParticles( pos, dir, 15, 0.75f, 1, 1, 1, 1, NULL );
	
	trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxElectroboltHit ), pos, CHAN_AUTO, 
		cg_volume_effects->value, ATTN_STATIC );
}
Пример #7
0
/*
* CG_RocketExplosionMode
*/
void CG_RocketExplosionMode( vec3_t pos, vec3_t dir, int fire_mode, float radius )
{
	lentity_t *le;
	vec3_t angles, vec;
	vec3_t origin;
	float expvelocity = 8.0f;

	VecToAngles( dir, angles );

	if( fire_mode == FIRE_MODE_STRONG )
	{
		//trap_S_StartSound ( pos, 0, 0, CG_MediaSfx (cgs.media.sfxRocketLauncherStrongHit), cg_volume_effects->value, ATTN_NORM, 0 );
		CG_SpawnDecal( pos, dir, random()*360, radius * 0.5, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );

	}
	else
	{
		//trap_S_StartSound ( pos, 0, 0, CG_MediaSfx (cgs.media.sfxRocketLauncherWeakHit), cg_volume_effects->value, ATTN_NORM, 0 );
		CG_SpawnDecal( pos, dir, random()*360, radius * 0.25, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	}

	// animmap shader of the explosion
	VectorMA( pos, radius*0.12f, dir, origin );
	le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius * 0.5f, 8,
		1, 1, 1, 1,
		radius*4, 0.75f, 0.533f, 0, // yellow dlight
		CG_MediaShader( cgs.media.shaderRocketExplosion ) );

	VectorSet( vec, crandom()*expvelocity, crandom()*expvelocity, crandom()*expvelocity );
	VectorScale( dir, expvelocity, le->velocity );
	VectorAdd( le->velocity, vec, le->velocity );
	le->ent.rotation = rand() % 360;

	if( cg_explosionsRing->integer )
	{
		// explosion ring sprite
		VectorMA( pos, radius*0.20f, dir, origin );
		le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius, 3,
			1, 1, 1, 1,
			0, 0, 0, 0, // no dlight
			CG_MediaShader( cgs.media.shaderRocketExplosionRing ) );

		le->ent.rotation = rand() % 360;
	}

	if( cg_explosionsDust->integer == 1 )
	{
		// dust ring parallel to the contact surface
		CG_ExplosionsDust(pos, dir, radius);
	}

	// Explosion particles
	CG_ParticleExplosionEffect( pos, dir, 1, 0.5, 0, 32 );

	if( fire_mode == FIRE_MODE_STRONG )
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherStrongHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
	else
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRocketLauncherWeakHit ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );

	//jalfixme: add sound at water?
}
Пример #8
0
/*
* CG_GrenadeExplosionMode
*/
void CG_GrenadeExplosionMode( vec3_t pos, vec3_t dir, int fire_mode, float radius )
{
	lentity_t *le;
	vec3_t angles;
	vec3_t decaldir;
	vec3_t origin, vec;
	float expvelocity = 8.0f;

	VectorCopy( dir, decaldir );
	VecToAngles( dir, angles );

	//if( CG_PointContents( pos ) & MASK_WATER )
	//jalfixme: (shouldn't we do the water sound variation?)

	if( fire_mode == FIRE_MODE_STRONG )
	{
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.5, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	}
	else
	{
		CG_SpawnDecal( pos, decaldir, random()*360, radius * 0.25, 1, 1, 1, 1, 10, 1, qfalse, CG_MediaShader( cgs.media.shaderExplosionMark ) );
	}

	// animmap shader of the explosion
	VectorMA( pos, radius*0.15f, dir, origin );
	le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius * 0.5f, 8,
		1, 1, 1, 1,
		radius*4, 0.75f, 0.533f, 0, // yellow dlight
		CG_MediaShader( cgs.media.shaderRocketExplosion ) );

	VectorSet( vec, crandom()*expvelocity, crandom()*expvelocity, crandom()*expvelocity );
	VectorScale( dir, expvelocity, le->velocity );
	VectorAdd( le->velocity, vec, le->velocity );
	le->ent.rotation = rand() % 360;

	// explosion ring sprite
	if( cg_explosionsRing->integer )
	{
		VectorMA( pos, radius*0.25f, dir, origin );
		le = CG_AllocSprite( LE_ALPHA_FADE, origin, radius, 3,
			1, 1, 1, 1,
			0, 0, 0, 0, // no dlight
			CG_MediaShader( cgs.media.shaderRocketExplosionRing ) );

		le->ent.rotation = rand() % 360;
	}

	if( cg_explosionsDust->integer == 1 )
	{
		// dust ring parallel to the contact surface
		CG_ExplosionsDust(pos, dir, radius);
	}

	// Explosion particles
	CG_ParticleExplosionEffect( pos, dir, 1, 0.5, 0, 32 );	

	if( fire_mode == FIRE_MODE_STRONG )
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxGrenadeStrongExplosion ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
	else
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxGrenadeWeakExplosion ), pos, CHAN_AUTO, cg_volume_effects->value, ATTN_DISTANT );
}
Пример #9
0
/*
* CG_EntityEvent
*/
void CG_EntityEvent( entity_state_t *ent, int ev, int parm, qboolean predicted )
{
	//static orientation_t projection;
	vec3_t dir;
	qboolean viewer = ISVIEWERENTITY( ent->number );
	vec4_t color;
	int weapon = 0, fireMode = 0, count = 0;

	if( viewer && ( ev < PREDICTABLE_EVENTS_MAX ) && ( predicted != cg.view.playerPrediction ) )
		return;

	switch( ev )
	{
	case EV_NONE:
	default:
		break;

	//  PREDICTABLE EVENTS

	case EV_WEAPONACTIVATE:
		CG_PModel_AddAnimation( ent->number, 0, TORSO_WEAPON_SWITCHIN, 0, EVENT_CHANNEL );
		weapon = ( parm & ~EV_INVERSE );
		fireMode = ( parm & EV_INVERSE ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;
		if( predicted )
		{
			cg_entities[ent->number].current.weapon = weapon;
			if( fireMode == FIRE_MODE_STRONG )
				cg_entities[ent->number].current.effects |= EF_STRONG_WEAPON;

			CG_ViewWeapon_RefreshAnimation( &cg.weapon );
		}

		if( viewer )
			cg.predictedWeaponSwitch = 0;

		if( viewer )
			trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxWeaponUp ), CHAN_AUTO, cg_volume_effects->value );
		else
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxWeaponUp ), ent->origin, CHAN_AUTO, cg_volume_effects->value, ATTN_NORM );
		break;

	case EV_SMOOTHREFIREWEAPON: // the server never sends this event
		if( predicted )
		{
			weapon = ( parm & ~EV_INVERSE );
			fireMode = ( parm & EV_INVERSE ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;

			cg_entities[ent->number].current.weapon = weapon;
			if( fireMode == FIRE_MODE_STRONG )
				cg_entities[ent->number].current.effects |= EF_STRONG_WEAPON;

			CG_ViewWeapon_RefreshAnimation( &cg.weapon );

			if( weapon == WEAP_LASERGUN )
				CG_Event_LaserBeam( ent->number, weapon, fireMode );
		}
		break;

	case EV_FIREWEAPON:
		weapon = ( parm & ~EV_INVERSE );
		fireMode = ( parm & EV_INVERSE ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;

		if( predicted )
		{
			cg_entities[ent->number].current.weapon = weapon;
			if( fireMode == FIRE_MODE_STRONG )
				cg_entities[ent->number].current.effects |= EF_STRONG_WEAPON;
		}

		CG_FireWeaponEvent( ent->number, weapon, fireMode );
		
		// riotgun bullets, electrobolt and instagun beams are predicted when the weapon is fired
		if( predicted )
		{
			vec3_t origin;

			if( ( weapon == WEAP_ELECTROBOLT 
#ifndef ELECTROBOLT_TEST
				&& fireMode == FIRE_MODE_STRONG
#endif
				) 
				|| weapon == WEAP_INSTAGUN )
			{
				VectorCopy( cg.predictedPlayerState.pmove.origin, origin );
				origin[2] += cg.predictedPlayerState.viewheight;
				AngleVectors( cg.predictedPlayerState.viewangles, dir, NULL, NULL );
				CG_Event_WeaponBeam( origin, dir, cg.predictedPlayerState.POVnum, weapon, fireMode );
			}
			else if( weapon == WEAP_RIOTGUN || weapon == WEAP_MACHINEGUN )
			{
				int seed = cg.predictedEventTimes[EV_FIREWEAPON] & 255;

				VectorCopy( cg.predictedPlayerState.pmove.origin, origin );
				origin[2] += cg.predictedPlayerState.viewheight;
				AngleVectors( cg.predictedPlayerState.viewangles, dir, NULL, NULL );

				if( weapon == WEAP_RIOTGUN )
					CG_Event_FireRiotgun( origin, dir, weapon, fireMode, seed, cg.predictedPlayerState.POVnum );
				else
					CG_Event_FireMachinegun( origin, dir, weapon, fireMode, seed, cg.predictedPlayerState.POVnum );
			}
			else if( weapon == WEAP_LASERGUN )
			{
				CG_Event_LaserBeam( ent->number, weapon, fireMode );
			}
		}
		break;

	case EV_ELECTROTRAIL:
		// check the owner for predicted case
		if( ISVIEWERENTITY( parm ) && ( ev < PREDICTABLE_EVENTS_MAX ) && ( predicted != cg.view.playerPrediction ) )
			return;
		CG_Event_WeaponBeam( ent->origin, ent->origin2, parm, WEAP_ELECTROBOLT, ent->firemode );
		break;

	case EV_INSTATRAIL:
		// check the owner for predicted case
		if( ISVIEWERENTITY( parm ) && ( ev < PREDICTABLE_EVENTS_MAX ) && ( predicted != cg.view.playerPrediction ) )
			return;
		CG_Event_WeaponBeam( ent->origin, ent->origin2, parm, WEAP_INSTAGUN, FIRE_MODE_STRONG );
		break;

	case EV_FIRE_RIOTGUN:
	case EV_FIRE_BULLET:
		{
			// check the owner for predicted case
			if( ISVIEWERENTITY( ent->ownerNum ) && ( ev < PREDICTABLE_EVENTS_MAX ) && ( predicted != cg.view.playerPrediction ) )
				return;

			if( ev == EV_FIRE_RIOTGUN )
				CG_Event_FireRiotgun( ent->origin, ent->origin2, ( ent->weapon & ~EV_INVERSE ),
					( ent->weapon & EV_INVERSE ), parm, ent->ownerNum );
			else
				CG_Event_FireMachinegun( ent->origin, ent->origin2, ( ent->weapon & ~EV_INVERSE ), 
					( ent->weapon & EV_INVERSE ), parm, ent->ownerNum );
		}
		break;

	case EV_NOAMMOCLICK:
		if( viewer )
			trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxWeaponUpNoAmmo ), CHAN_ITEM, cg_volume_effects->value );
		else
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxWeaponUpNoAmmo ), ent->origin, CHAN_ITEM, cg_volume_effects->value, ATTN_IDLE );
		break;

	case EV_DASH:
		CG_Event_Dash( ent, parm );
		break;

	case EV_WALLJUMP:
	case EV_WALLJUMP_FAILED:
		CG_Event_WallJump( ent, parm, ev );
		break;

	case EV_DOUBLEJUMP:
		CG_Event_DoubleJump( ent, parm );
		break;

	case EV_JUMP:
		CG_Event_Jump( ent, parm );
		break;

	case EV_JUMP_PAD:
		CG_TouchJumpPad( ent->number );
		break;

	case EV_FALL:
		CG_Event_Fall( ent, parm );
		break;


		//  NON PREDICTABLE EVENTS

	case EV_WEAPONDROP: // deactivate is not predictable
		CG_PModel_AddAnimation( ent->number, 0, TORSO_WEAPON_SWITCHOUT, 0, EVENT_CHANNEL );
		break;

	case EV_SEXEDSOUND:
		if( parm == 2 )
			CG_SexedSound( ent->number, CHAN_AUTO, S_PLAYER_GASP, cg_volume_players->value );
		else if( parm == 1 )
			CG_SexedSound( ent->number, CHAN_AUTO, S_PLAYER_DROWN, cg_volume_players->value );
		break;

	case EV_PAIN:
		CG_Event_Pain( ent, parm );
		break;

	case EV_DIE:
		CG_Event_Die( ent, parm );
		break;

	case EV_GIB:
		break;

	case EV_EXPLOSION1:
		CG_GenericExplosion( ent->origin, vec3_origin, FIRE_MODE_WEAK, parm * 8 );
		break;

	case EV_EXPLOSION2:
		CG_GenericExplosion( ent->origin, vec3_origin, FIRE_MODE_STRONG, parm * 16 );
		break;

	case EV_GREEN_LASER:
		CG_GreenLaser( ent->origin, ent->origin2 );
		break;

	case EV_PNODE:
		color[0] = COLOR_R( ent->colorRGBA ) * ( 1.0 / 255.0 );
		color[1] = COLOR_G( ent->colorRGBA ) * ( 1.0 / 255.0 );
		color[2] = COLOR_B( ent->colorRGBA ) * ( 1.0 / 255.0 );
		color[3] = COLOR_A( ent->colorRGBA ) * ( 1.0 / 255.0 );
		CG_PLink( ent->origin, ent->origin2, color, parm );
		break;

	case EV_SPARKS:
		ByteToDir( parm, dir );
		if( ent->damage > 0 )
		{
			count = (int)( ent->damage * 0.25f );
			clamp( count, 1, 10 );
		}
		else
			count = 6;

		CG_ParticleEffect( ent->origin, dir, 1.0f, 0.67f, 0.0f, count );
		break;

	case EV_BULLET_SPARKS:
		ByteToDir( parm, dir );
		CG_BulletExplosion( ent->origin, dir, NULL );
		CG_ParticleEffect( ent->origin, dir, 1.0f, 0.67f, 0.0f, 6 );
		trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxRic[rand()&2] ), ent->origin, CHAN_AUTO,
			cg_volume_effects->value, ATTN_STATIC );
		break;

	case EV_LASER_SPARKS:
		ByteToDir( parm, dir );
		CG_ParticleEffect2( ent->origin, dir,
			COLOR_R( ent->colorRGBA ) * ( 1.0 / 255.0 ),
			COLOR_G( ent->colorRGBA ) * ( 1.0 / 255.0 ),
			COLOR_B( ent->colorRGBA ) * ( 1.0 / 255.0 ),
			ent->eventCount );
		break;

	case EV_GESTURE:
		CG_SexedSound( ent->number, CHAN_BODY, "*taunt", cg_volume_players->value );
		break;

	case EV_DROP:
		CG_PModel_AddAnimation( ent->number, 0, TORSO_DROP, 0, EVENT_CHANNEL );
		break;

	case EV_SPOG:
		CG_SmallPileOfGibs( ent->origin, parm, ent->origin2 );
		break;

	case EV_ITEM_RESPAWN:
		cg_entities[ent->number].respawnTime = cg.time;
		trap_S_StartRelativeSound( CG_MediaSfx( cgs.media.sfxItemRespawn ), ent->number, CHAN_AUTO,
			cg_volume_effects->value, ATTN_IDLE );
		break;

	case EV_PLAYER_RESPAWN:
		if( (unsigned)ent->ownerNum == cgs.playerNum + 1 )
		{
			CG_ResetKickAngles();
			CG_ResetColorBlend();
			CG_ResetDamageIndicator();
		}
		// fallthrough
	case EV_PLAYER_TELEPORT_IN:
		if( ISVIEWERENTITY( ent->ownerNum ) )
		{
			trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxTeleportIn ), CHAN_AUTO,
				cg_volume_effects->value );
		}
		else
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxTeleportIn ), ent->origin, CHAN_AUTO,
				cg_volume_effects->value, ATTN_NORM );
		}

		if( ent->ownerNum && ent->ownerNum < gs.maxclients + 1 )
			cg_entities[ent->ownerNum].localEffects[LOCALEFFECT_EV_PLAYER_TELEPORT_IN] = cg.time;
		break;

	case EV_PLAYER_TELEPORT_OUT:
		if( ISVIEWERENTITY( ent->ownerNum ) )
		{
			trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxTeleportOut ), CHAN_AUTO,
				cg_volume_effects->value );
		}
		else
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxTeleportOut ), ent->origin, CHAN_AUTO,
				cg_volume_effects->value, ATTN_NORM );
		}
		if( ent->ownerNum && ent->ownerNum < gs.maxclients + 1 )
		{
			cg_entities[ent->ownerNum].localEffects[LOCALEFFECT_EV_PLAYER_TELEPORT_OUT] = cg.time;
			VectorCopy( ent->origin, cg_entities[ent->ownerNum].teleportedFrom );
		}
		break;

	case EV_PLASMA_EXPLOSION:
		ByteToDir( parm, dir );
		CG_PlasmaExplosion( ent->origin, dir, ent->firemode, (float)ent->weapon * 8.0f );
		if( ent->firemode == FIRE_MODE_STRONG )
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxPlasmaStrongHit ), ent->origin, CHAN_AUTO, cg_volume_effects->value, ATTN_IDLE );
			CG_StartKickAnglesEffect( ent->origin, 50, ent->weapon * 8, 100 );
		}
		else
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxPlasmaWeakHit ), ent->origin, CHAN_AUTO, cg_volume_effects->value, ATTN_IDLE );
			CG_StartKickAnglesEffect( ent->origin, 30, ent->weapon * 8, 75 );
		}
		break;

	case EV_BOLT_EXPLOSION:
		ByteToDir( parm, dir );
		CG_BoltExplosionMode( ent->origin, dir, ent->firemode );
		break;

	case EV_INSTA_EXPLOSION:
		ByteToDir( parm, dir );
		CG_InstaExplosionMode( ent->origin, dir, ent->firemode );
		break;

	case EV_GRENADE_EXPLOSION:
		if( parm )
		{    // we have a direction
			ByteToDir( parm, dir );
			CG_GrenadeExplosionMode( ent->origin, dir, ent->firemode, (float)ent->weapon*8.0f );
		}
		else
		{ // no direction
			CG_GrenadeExplosionMode( ent->origin, vec3_origin, ent->firemode, (float)ent->weapon*8.0f );
		}

		if( ent->firemode == FIRE_MODE_STRONG )
			CG_StartKickAnglesEffect( ent->origin, 135, ent->weapon*8, 325 );
		else
			CG_StartKickAnglesEffect( ent->origin, 125, ent->weapon*8, 300 );
		break;

	case EV_ROCKET_EXPLOSION:
		ByteToDir( parm, dir );
		CG_RocketExplosionMode( ent->origin, dir, ent->firemode, (float)ent->weapon * 8.0f );

		if( ent->firemode == FIRE_MODE_STRONG )
			CG_StartKickAnglesEffect( ent->origin, 135, ent->weapon * 8, 300 );
		else
			CG_StartKickAnglesEffect( ent->origin, 125, ent->weapon * 8, 275 );
		break;

	case EV_GRENADE_BOUNCE:
		if( parm == FIRE_MODE_STRONG )
			trap_S_StartRelativeSound( CG_MediaSfx( cgs.media.sfxGrenadeStrongBounce[rand()&1] ), ent->number, CHAN_AUTO, cg_volume_effects->value, ATTN_IDLE );
		else
			trap_S_StartRelativeSound( CG_MediaSfx( cgs.media.sfxGrenadeWeakBounce[rand()&1] ), ent->number, CHAN_AUTO, cg_volume_effects->value, ATTN_IDLE );
		break;

	case EV_BLADE_IMPACT:
		CG_BladeImpact( ent->origin, ent->origin2 );
		break;

	case EV_GUNBLADEBLAST_IMPACT:
		ByteToDir( parm, dir );
		CG_GunBladeBlastImpact( ent->origin, dir, (float)ent->weapon*8 );
		if( ent->skinnum > 64 )
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxGunbladeStrongHit[2] ), ent->origin, CHAN_AUTO,
				cg_volume_effects->value, ATTN_DISTANT );
		}
		else if( ent->skinnum > 34 )
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxGunbladeStrongHit[1] ), ent->origin, CHAN_AUTO,
				cg_volume_effects->value, ATTN_NORM );
		}
		else
		{
			trap_S_StartFixedSound( CG_MediaSfx( cgs.media.sfxGunbladeStrongHit[0] ), ent->origin, CHAN_AUTO,
				cg_volume_effects->value, ATTN_IDLE );
		}

		//ent->skinnum is knockback value
		CG_StartKickAnglesEffect( ent->origin, ent->skinnum*8, ent->weapon*8, 200 );
		break;

	case EV_BLOOD:
		if( cg_showBloodTrail->integer == 2 && ISVIEWERENTITY( ent->ownerNum ) )
			break;
		ByteToDir( parm, dir );
		CG_BloodDamageEffect( ent->origin, dir, ent->damage );
		CG_CartoonHitEffect( ent->origin, dir, ent->damage );
		break;

		// func movers
	case EV_PLAT_HIT_TOP:
	case EV_PLAT_HIT_BOTTOM:
	case EV_PLAT_START_MOVING:
	case EV_DOOR_HIT_TOP:
	case EV_DOOR_HIT_BOTTOM:
	case EV_DOOR_START_MOVING:
	case EV_BUTTON_FIRE:
	case EV_TRAIN_STOP:
	case EV_TRAIN_START:
		{
			vec3_t so;
			CG_GetEntitySpatilization( ent->number, so, NULL );
			trap_S_StartFixedSound( cgs.soundPrecache[parm], so, CHAN_AUTO, cg_volume_effects->value, ATTN_STATIC );
		}
		break;

	case EV_VSAY:
		CG_StartVoiceTokenEffect( ent->ownerNum, EV_VSAY, parm );
		break;
	}
}