Exemplo n.º 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 );
		}
	}
}
Exemplo n.º 2
0
/*
* CG_Event_Pain
*/
void CG_Event_Pain( entity_state_t *state, int parm )
{
	if( parm == PAIN_WARSHELL )
	{
		if( ISVIEWERENTITY( state->number ) )
			trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxShellHit ), CHAN_PAIN, cg_volume_players->value );
		else
			trap_S_StartRelativeSound( CG_MediaSfx( cgs.media.sfxShellHit ), state->number, CHAN_PAIN, cg_volume_players->value, ATTN_NORM );
	}
	else
	{
		CG_SexedSound( state->number, CHAN_PAIN, va( S_PLAYER_PAINS, 25*( parm+1 ) ), cg_volume_players->value );
	}

	switch( (int)brandom( 0, 3 ) )
	{
	case 0:
		CG_PModel_AddAnimation( state->number, 0, TORSO_PAIN1, 0, EVENT_CHANNEL );
		break;
	case 1:
		CG_PModel_AddAnimation( state->number, 0, TORSO_PAIN2, 0, EVENT_CHANNEL );
		break;
	case 2:
	default:
		CG_PModel_AddAnimation( state->number, 0, TORSO_PAIN3, 0, EVENT_CHANNEL );
		break;
	}
}
Exemplo n.º 3
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 ) );
	}
}
Exemplo n.º 4
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 );
}
Exemplo n.º 5
0
/*
* CG_Event_WallJump
*/
void CG_Event_WallJump( entity_state_t *state, int parm, int ev )
{
	vec3_t normal, forward, right;

	ByteToDir( parm, normal );

	AngleVectors( tv( state->angles[0], state->angles[1], 0 ), forward, right, NULL );

	if( DotProduct( normal, right ) > 0.3 )
		CG_PModel_AddAnimation( state->number, LEGS_WALLJUMP_RIGHT, 0, 0, EVENT_CHANNEL );
	else if( -DotProduct( normal, right ) > 0.3 )
		CG_PModel_AddAnimation( state->number, LEGS_WALLJUMP_LEFT, 0, 0, EVENT_CHANNEL );
	else if( -DotProduct( normal, forward ) > 0.3 )
		CG_PModel_AddAnimation( state->number, LEGS_WALLJUMP_BACK, 0, 0, EVENT_CHANNEL );
	else
		CG_PModel_AddAnimation( state->number, LEGS_WALLJUMP, 0, 0, EVENT_CHANNEL );

	if( ev == EV_WALLJUMP_FAILED )
	{
		if( ISVIEWERENTITY( state->number ) )
			trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxWalljumpFailed ), CHAN_BODY, cg_volume_effects->value );
		else
			trap_S_StartRelativeSound( CG_MediaSfx( cgs.media.sfxWalljumpFailed ), state->number, CHAN_BODY, cg_volume_effects->value, ATTN_NORM );
	}
	else
	{
		CG_SexedSound( state->number, CHAN_BODY, va( S_PLAYER_WALLJUMP_1_to_2, ( rand()&1 )+1 ), cg_volume_players->value );
	
		// smoke effect
		if( cg_cartoonEffects->integer & 1 )
		{
			vec3_t pos;
			VectorCopy( state->origin, pos );
			pos[2] += 15;
			CG_DustCircle( pos, normal, 65, 12 );
		}
	}

  //racesow - lm: filter out other players
  if( ISVIEWERENTITY( state->number ))
    CG_AddJumpspeed();
  //!racesow
}
Exemplo n.º 6
0
/*
* CG_SC_TVChatPrint
*/
static void CG_SC_TVChatPrint( void )
{
	const char *name = trap_Cmd_Argv( 1 );
	const char *text = trap_Cmd_Argv( 2 );
	const cvar_t *filter = (cgs.tv ? cg_chatFilterTV : cg_chatFilter);

	if( filter->integer & 4 )
		return;

	CG_LocalPrint( qfalse, S_COLOR_RED "[TV]" S_COLOR_WHITE "%s" S_COLOR_GREEN ": %s", name, text );
	if( cg_chatBeep->integer )
		trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxChat ), CHAN_AUTO, 1.0f );
}
Exemplo n.º 7
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 );
}
Exemplo n.º 8
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 );
}
Exemplo n.º 9
0
/*
* CG_StartVoiceTokenEffect
*/
static void CG_StartVoiceTokenEffect( int entNum, int type, int vsay )
{
	centity_t *cent;
	cgs_media_handle_t *sound = NULL;

	if( !cg_voiceChats->integer || cg_volume_voicechats->value <= 0.0f )
		return;

	cent = &cg_entities[entNum];

	// set the icon effect
	cent->localEffects[LOCALEFFECT_VSAY_HEADICON] = vsay;
	cent->localEffects[LOCALEFFECT_VSAY_HEADICON_TIMEOUT] = cg.time + HEADICON_TIMEOUT;

	// play the sound
	sound = cgs.media.sfxVSaySounds[vsay];

	// played as it was made by the 1st person player
	trap_S_StartGlobalSound( CG_MediaSfx( sound ), CHAN_AUTO, cg_volume_voicechats->value );
}
Exemplo n.º 10
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 );
}
Exemplo n.º 11
0
/*
* CG_SC_ChatPrint
*/
static void CG_SC_ChatPrint( void )
{
	const qboolean teamonly = (!Q_stricmp( trap_Cmd_Argv( 0 ), "tch" ) ? qtrue : qfalse);
	const int who = atoi( trap_Cmd_Argv( 1 ) );
	const char *name = (who && who == bound(1, who, MAX_CLIENTS) ? cgs.clientInfo[who-1].name : NULL);
	const char *text = trap_Cmd_Argv( 2 );
	const cvar_t *filter = (cgs.tv ? cg_chatFilterTV : cg_chatFilter);

	if( filter->integer & (teamonly ? 2 : 1) )
		return;

	if( !name )
		CG_LocalPrint( qfalse, S_COLOR_GREEN "console: %s\n", text );
	else if( teamonly )
		CG_LocalPrint( qtrue, S_COLOR_YELLOW "[%s]" S_COLOR_WHITE "%s" S_COLOR_YELLOW ": %s\n",
			cg.frame.playerState.stats[STAT_REALTEAM] == TEAM_SPECTATOR ? "SPEC" : "TEAM", name, text );
	else
		CG_LocalPrint( qfalse, "%s" S_COLOR_GREEN ": %s\n", name, text );

	if( cg_chatBeep->integer )
		trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxChat ), CHAN_AUTO, 1.0f );
}
Exemplo n.º 12
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 );
}
Exemplo n.º 13
0
/*
* CG_FirePlayerStateEvents
* This events are only received by this client, and only affect it.
*/
static void CG_FirePlayerStateEvents( void )
{
	unsigned int event, parm, i, count;
	vec3_t dir;

	if( !cg.frame.playerState.event )
		return;

	if( cg.view.POVent != (int)cg.frame.playerState.POVnum )
		return;

	for( count = 0; count < 2; count++ )
	{
		// first byte is event number, second is parm
		event = cg.frame.playerState.event[count] & 127;
		parm = cg.frame.playerState.eventParm[count] & 0xFF;

		switch( event )
		{
		case PSEV_HIT:
			if( parm > 6 )
				break;
			if( parm < 4 )
			{        // hit of some caliber
				trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxWeaponHit[parm] ), CHAN_AUTO, cg_volume_hitsound->value );
				CG_ScreenCrosshairDamageUpdate();
			}
			else if( parm == 4 ) // killed an enemy
			{
				trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxWeaponKill ), CHAN_AUTO, cg_volume_hitsound->value );
				CG_ScreenCrosshairDamageUpdate();
			}
			else
			{ // hit a teammate
				trap_S_StartGlobalSound( CG_MediaSfx( cgs.media.sfxWeaponHitTeam ), CHAN_AUTO, cg_volume_hitsound->value );
				if( cg_showhelp->integer )
				{
					if( random() <= 0.5f )
						CG_CenterPrint( "Don't shoot at members of your team!" );
					else
						CG_CenterPrint( "You are shooting at your teammates!" );
				}
			}
			break;

		case PSEV_PICKUP:
			if( cg_pickup_flash->integer && !cg.view.thirdperson )
				CG_StartColorBlendEffect( 1.0f, 1.0f, 1.0f, 0.25f, 150 );

			// auto-switch
			if( cg_weaponAutoSwitch->integer && ( parm > WEAP_NONE && parm < WEAP_TOTAL ) )
			{
				if( !cgs.demoPlaying && cg.predictedPlayerState.pmove.pm_type == PM_NORMAL 
					&& cg.predictedPlayerState.POVnum == cgs.playerNum + 1 )
				{
					// auto-switch only works when the user didn't have the just-picked weapon
					if( !cg.oldFrame.playerState.inventory[parm] )
					{
						// switch when player's only weapon is gunblade
						if( cg_weaponAutoSwitch->integer == 2 )
						{
							for( i = WEAP_GUNBLADE + 1; i < WEAP_TOTAL; i++ )
							{
								if( i == parm )
									continue;
								if( cg.predictedPlayerState.inventory[i] )
									break;
							}

							if( i == WEAP_TOTAL ) // didn't have any weapon
								CG_UseItem( va( "%i", parm ) );

						}
						// switch when the new weapon improves player's selected weapon
						else if( cg_weaponAutoSwitch->integer == 1 )
						{
							unsigned int best = WEAP_GUNBLADE;
							for( i = WEAP_GUNBLADE + 1; i < WEAP_TOTAL; i++ )
							{
								if( i == parm )
									continue;
								if( cg.predictedPlayerState.inventory[i] )
									best = i;
							}

							if( best < parm )
								CG_UseItem( va( "%i", parm ) );
						}
					}
				}
			}
			break;

		case PSEV_DAMAGE_20:
			ByteToDir( parm, dir );
			CG_DamageIndicatorAdd( 20, dir );
			break;

		case PSEV_DAMAGE_40:
			ByteToDir( parm, dir );
			CG_DamageIndicatorAdd( 40, dir );
			break;

		case PSEV_DAMAGE_60:
			ByteToDir( parm, dir );
			CG_DamageIndicatorAdd( 60, dir );
			break;

		case PSEV_DAMAGE_80:
			ByteToDir( parm, dir );
			CG_DamageIndicatorAdd( 80, dir );
			break;

		case PSEV_INDEXEDSOUND:
			if( cgs.soundPrecache[parm] )
				trap_S_StartGlobalSound( cgs.soundPrecache[parm], CHAN_AUTO, cg_volume_effects->value );
			break;

		case PSEV_ANNOUNCER:
			CG_AddAnnouncerEvent( cgs.soundPrecache[parm], qfalse );
			break;

		case PSEV_ANNOUNCER_QUEUED:
			CG_AddAnnouncerEvent( cgs.soundPrecache[parm], qtrue );
			break;

		default:
			break;
		}
	}
}
Exemplo n.º 14
0
void CG_LaserBeamEffect( centity_t *cent )
{
	struct sfx_s *sound = NULL;
	float range;
	trace_t trace;
	orientation_t projectsource;
	vec4_t color;
	vec3_t laserOrigin, laserAngles, laserPoint;
	int i, j;

	if( cent->localEffects[LOCALEFFECT_LASERBEAM] <= cg.time )
		return;

	laserOwner = cent;

	if( cg_teamColoredBeams->integer && ( cent->current.team == TEAM_ALPHA || cent->current.team == TEAM_BETA ) )
		CG_TeamColor( cent->current.team, color );
	else
		Vector4Set( color, 1, 1, 1, 1 );

	// interpolate the positions

	if( ISVIEWERENTITY( cent->current.number ) && !cg.view.thirdperson )
	{
		VectorCopy( cg.predictedPlayerState.pmove.origin, laserOrigin );
		laserOrigin[2] += cg.predictedPlayerState.viewheight;
		VectorCopy( cg.predictedPlayerState.viewangles, laserAngles );

		VectorLerp( cent->laserPointOld, cg.lerpfrac, cent->laserPoint, laserPoint );
	}
	else
	{
		VectorLerp( cent->laserOriginOld, cg.lerpfrac, cent->laserOrigin, laserOrigin );
		VectorLerp( cent->laserPointOld, cg.lerpfrac, cent->laserPoint, laserPoint );
		if( !cent->laserCurved )
		{
			vec3_t dir;

			// make up the angles from the start and end points (s->angles is not so precise)
			VectorSubtract( laserPoint, laserOrigin, dir );
			VecToAngles( dir, laserAngles );
		}
		else // use player entity angles
		{
			for( i = 0; i < 3; i++ )
				laserAngles[i] = LerpAngle( cent->prev.angles[i], cent->current.angles[i], cg.lerpfrac );
		}
	}

	if( !cent->laserCurved )
	{
		range = GS_GetWeaponDef( WEAP_LASERGUN )->firedef.timeout;

		if( cent->current.effects & EF_QUAD )
			sound = CG_MediaSfx( cgs.media.sfxLasergunStrongQuadHum );
		else
			sound = CG_MediaSfx( cgs.media.sfxLasergunStrongHum );

		// trace the beam: for tracing we use the real beam origin
		GS_TraceLaserBeam( &trace, laserOrigin, laserAngles, range, cent->current.number, 0, _LaserImpact );
		
		// draw the beam: for drawing we use the weapon projection source (already handles the case of viewer entity)
		if( !CG_PModel_GetProjectionSource( cent->current.number, &projectsource ) )
			VectorCopy( laserOrigin, projectsource.origin );

		CG_KillPolyBeamsByTag( cent->current.number );
		CG_LaserGunPolyBeam( projectsource.origin, trace.endpos, color, cent->current.number );
	}
	else
	{
		float frac, subdivisions = cg_laserBeamSubdivisions->integer;
		vec3_t from, dir, end, blendPoint;
		int passthrough = cent->current.number;
		vec3_t tmpangles, blendAngles;

		range = GS_GetWeaponDef( WEAP_LASERGUN )->firedef_weak.timeout;

		if( cent->current.effects & EF_QUAD )
			sound = CG_MediaSfx( cgs.media.sfxLasergunWeakQuadHum );
		else
			sound = CG_MediaSfx( cgs.media.sfxLasergunWeakHum );

		// trace the beam: for tracing we use the real beam origin
		GS_TraceCurveLaserBeam( &trace, laserOrigin, laserAngles, laserPoint, cent->current.number, 0, _LaserImpact );

		// draw the beam: for drawing we use the weapon projection source (already handles the case of viewer entity)
		if( !CG_PModel_GetProjectionSource( cent->current.number, &projectsource ) )
			VectorCopy( laserOrigin, projectsource.origin );

		if( subdivisions < CURVELASERBEAM_SUBDIVISIONS )
			subdivisions = CURVELASERBEAM_SUBDIVISIONS;

		CG_KillPolyBeamsByTag( cent->current.number );

		// we redraw the full beam again, and trace each segment for stop dead impact
		VectorCopy( laserPoint, blendPoint );
		VectorCopy( projectsource.origin, from );
		VectorSubtract( blendPoint, projectsource.origin, dir );
		VecToAngles( dir, blendAngles );

		for( i = 1; i <= (int)subdivisions; i++ )
		{
			frac = ( ( range/subdivisions )*(float)i ) / (float)range;

			for( j = 0; j < 3; j++ )
				tmpangles[j] = LerpAngle( laserAngles[j], blendAngles[j], frac );

			AngleVectors( tmpangles, dir, NULL, NULL );
			VectorMA( projectsource.origin, range * frac, dir, end );

			GS_TraceLaserBeam( &trace, from, tmpangles, DistanceFast( from, end ), passthrough, 0, NULL );
			CG_LaserGunPolyBeam( from, trace.endpos, color, cent->current.number );
			if( trace.fraction != 1.0f )
				break;

			passthrough = trace.ent;
			VectorCopy( trace.endpos, from );
		}
	}

	// enable continuous flash on the weapon owner
	if( cg_weaponFlashes->integer )
		cg_entPModels[cent->current.number].flash_time = cg.time + CG_GetWeaponInfo( WEAP_LASERGUN )->flashTime;

	if( sound )
	{
		if( ISVIEWERENTITY( cent->current.number ) )
			trap_S_AddLoopSound( sound, cent->current.number, 1.0, ATTN_NONE );
		else
			trap_S_AddLoopSound( sound, cent->current.number, 1.0, ATTN_STATIC );
	}

	laserOwner = NULL;
}
Exemplo n.º 15
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;
	}
}
Exemplo n.º 16
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?
}
Exemplo n.º 17
0
/*
* CG_FireWeaponEvent
*/
static void CG_FireWeaponEvent( int entNum, int weapon, int fireMode )
{
	float attenuation;
	struct sfx_s *sound = NULL;
	weaponinfo_t *weaponInfo;

	if( !weapon )
		return;

	// hack idle attenuation on the plasmagun to reduce sound flood on the scene
	if( weapon == WEAP_PLASMAGUN )
		attenuation = ATTN_IDLE;
	else
		attenuation = ATTN_NORM;

	weaponInfo = CG_GetWeaponInfo( weapon );

	// sound
	if( fireMode == FIRE_MODE_STRONG )
	{
		if( weaponInfo->num_strongfire_sounds )
			sound = weaponInfo->sound_strongfire[(int)brandom( 0, weaponInfo->num_strongfire_sounds )];
	}
	else
	{
		if( weaponInfo->num_fire_sounds )
			sound = weaponInfo->sound_fire[(int)brandom( 0, weaponInfo->num_fire_sounds )];
	}

	if( sound )
	{
		if( ISVIEWERENTITY( entNum ) )
			trap_S_StartGlobalSound( sound, CHAN_MUZZLEFLASH, cg_volume_effects->value );
		else
			// fixed position is better for location, but the channels are used from worldspawn
			// and openal runs out of channels quick on cheap cards. Relative sound uses per-entity channels.
			trap_S_StartRelativeSound( sound, entNum, CHAN_MUZZLEFLASH, cg_volume_effects->value, attenuation );

		if( ( cg_entities[entNum].current.effects & EF_QUAD ) && ( weapon != WEAP_LASERGUN ) )
		{
			struct sfx_s *quadSfx = CG_MediaSfx( cgs.media.sfxQuadFireSound );
			if( ISVIEWERENTITY( entNum ) )
				trap_S_StartGlobalSound( quadSfx, CHAN_AUTO, cg_volume_effects->value );
			else
				trap_S_StartRelativeSound( quadSfx, entNum, CHAN_AUTO, cg_volume_effects->value, attenuation );
		}
	}

	// flash and barrel effects
	
	if( weapon == WEAP_GUNBLADE ) // gunblade is special
	{
		if( fireMode == FIRE_MODE_STRONG )
		{
			// light flash
			if( cg_weaponFlashes->integer && weaponInfo->flashTime )
				cg_entPModels[entNum].flash_time = cg.time + weaponInfo->flashTime;
		}
		else
		{
			// start barrel rotation or offsetting
			if( weaponInfo->barrelTime )
				cg_entPModels[entNum].barrel_time = cg.time + weaponInfo->barrelTime;
		}
	}
	else
	{
		// light flash
		if( cg_weaponFlashes->integer && weaponInfo->flashTime )
			cg_entPModels[entNum].flash_time = cg.time + weaponInfo->flashTime;

		// start barrel rotation or offsetting
		if( weaponInfo->barrelTime )
			cg_entPModels[entNum].barrel_time = cg.time + weaponInfo->barrelTime;
	}

	// add animation to the player model
	switch( weapon )
	{
	case WEAP_NONE:
		break;

	case WEAP_GUNBLADE:
		if( fireMode == FIRE_MODE_WEAK )
			CG_PModel_AddAnimation( entNum, 0, TORSO_SHOOT_BLADE, 0, EVENT_CHANNEL );
		else
			CG_PModel_AddAnimation( entNum, 0, TORSO_SHOOT_PISTOL, 0, EVENT_CHANNEL );
		break;

	case WEAP_LASERGUN:
		CG_PModel_AddAnimation( entNum, 0, TORSO_SHOOT_PISTOL, 0, EVENT_CHANNEL );
		break;

	default:
	case WEAP_RIOTGUN:
	case WEAP_PLASMAGUN:
		CG_PModel_AddAnimation( entNum, 0, TORSO_SHOOT_LIGHTWEAPON, 0, EVENT_CHANNEL );
		break;

	case WEAP_ROCKETLAUNCHER:
	case WEAP_GRENADELAUNCHER:
		CG_PModel_AddAnimation( entNum, 0, TORSO_SHOOT_HEAVYWEAPON, 0, EVENT_CHANNEL );
		break;

	case WEAP_ELECTROBOLT:
		CG_PModel_AddAnimation( entNum, 0, TORSO_SHOOT_AIMWEAPON, 0, EVENT_CHANNEL );
		break;
	}

	// add animation to the view weapon model
	if( ISVIEWERENTITY( entNum ) && !cg.view.thirdperson )
		CG_ViewWeapon_StartAnimationEvent( fireMode == FIRE_MODE_STRONG ? WEAPMODEL_ATTACK_STRONG : WEAPMODEL_ATTACK_WEAK );
}