Exemple #1
0
/*
=================
CG_ParseVoice

voice clientNum vChan cmdNum trackNum [sayText]
=================
*/
static void CG_ParseVoice( void )
{
	int            clientNum;
	voiceChannel_t vChan;
	char           sayText[ MAX_SAY_TEXT ] = { "" };
	voiceTrack_t   *track;
	clientInfo_t   *ci;

	if ( trap_Argc() < 5 || trap_Argc() > 6 )
	{
		return;
	}

	if ( trap_Argc() == 6 )
	{
		Q_strncpyz( sayText, CG_Argv( 5 ), sizeof( sayText ) );
	}

	clientNum = atoi( CG_Argv( 1 ) );

	if ( clientNum < 0 || clientNum >= MAX_CLIENTS )
	{
		return;
	}

	vChan = atoi( CG_Argv( 2 ) );

	if ( ( unsigned ) vChan >= VOICE_CHAN_NUM_CHANS )
	{
		return;
	}

	if ( cg_teamChatsOnly.integer && vChan != VOICE_CHAN_TEAM )
	{
		return;
	}

	ci = &cgs.clientinfo[ clientNum ];

	// this joker is still talking
	if ( ci->voiceTime > cg.time )
	{
		return;
	}

	track = CG_VoiceTrack( ci->voice, atoi( CG_Argv( 3 ) ), atoi( CG_Argv( 4 ) ) );

	// keep track of how long the player will be speaking
	// assume it takes 3s to say "*unintelligible gibberish*"
	if ( track )
	{
		ci->voiceTime = cg.time + track->duration;
	}
	else
	{
		ci->voiceTime = cg.time + 3000;
	}

	if ( !sayText[ 0 ] )
	{
		if ( track )
		{
			Q_strncpyz( sayText, track->text, sizeof( sayText ) );
		}
		else
		{
			Q_strncpyz( sayText, "*unintelligible gibberish*", sizeof( sayText ) );
		}
	}

	if ( !cg_noVoiceText.integer )
	{
		switch ( vChan )
		{
			case VOICE_CHAN_ALL:
				CG_Say( NULL, clientNum, SAY_ALL, sayText );
				break;

			case VOICE_CHAN_TEAM:
				CG_Say( NULL, clientNum, SAY_TEAM, sayText );
				break;

			case VOICE_CHAN_LOCAL:
				CG_Say( NULL, clientNum, SAY_AREA_TEAM, sayText );
				break;

			default:
				break;
		}
	}

	// playing voice audio tracks disabled
	if ( cg_noVoiceChats.integer )
	{
		return;
	}

	// no audio track to play
	if ( !track )
	{
		return;
	}

	// don't play audio track for lamers
	if ( Com_ClientListContains( &cgs.ignoreList, clientNum ) )
	{
		return;
	}

	switch ( vChan )
	{
		case VOICE_CHAN_ALL:
			trap_S_StartLocalSound( track->track, CHAN_VOICE );
			break;

		case VOICE_CHAN_TEAM:
			trap_S_StartLocalSound( track->track, CHAN_VOICE );
			break;

		case VOICE_CHAN_LOCAL:
			trap_S_StartSound( NULL, clientNum, CHAN_VOICE, track->track );
			break;

		default:
			break;
	}
}
Exemple #2
0
/*
==============
CG_DrawPlayerWeaponIcon
==============
*/
void CG_DrawPlayerWeaponIcon(rectDef_t *rect, int align, vec4_t *refcolor) {
	int       size;
	int       realweap;             // DHM - Nerve
	qhandle_t icon;
	float     scale, halfScale;
	vec4_t    hcolor;

	VectorCopy(*refcolor, hcolor);
	hcolor[3] = 1.f;

	if (cg.predictedPlayerEntity.currentState.eFlags & EF_MG42_ACTIVE ||
	    cg.predictedPlayerEntity.currentState.eFlags & EF_MOUNTEDTANK) {
		realweap = WP_MOBILE_MG42;
	} else {
		realweap = cg.predictedPlayerState.weapon;
	}

	size = weapIconDrawSize(realweap);

	if (!size) {
		return;
	}

	if (cg.predictedPlayerEntity.currentState.eFlags & EF_MOUNTEDTANK && cg_entities[cg_entities[cg_entities[cg.snap->ps.clientNum].tagParent].tankparent].currentState.density & 8) {
		icon = cgs.media.browningIcon;
	} else {
		icon = cg_weapons[realweap].weaponIcon[1];
	}

	// pulsing grenade icon to help the player 'count' in their head
	if (cg.predictedPlayerState.grenadeTimeLeft) {     // grenades and dynamite set this
		// these time differently
		if (realweap == WP_DYNAMITE) {
			if (((cg.grenLastTime) % 1000) > ((cg.predictedPlayerState.grenadeTimeLeft) % 1000)) {
				trap_S_StartLocalSound(cgs.media.grenadePulseSound4, CHAN_LOCAL_SOUND);
			}
		} else {
			if (((cg.grenLastTime) % 1000) < ((cg.predictedPlayerState.grenadeTimeLeft) % 1000)) {
				switch (cg.predictedPlayerState.grenadeTimeLeft / 1000) {
				case 3:
					trap_S_StartLocalSound(cgs.media.grenadePulseSound4, CHAN_LOCAL_SOUND);
					break;
				case 2:
					trap_S_StartLocalSound(cgs.media.grenadePulseSound3, CHAN_LOCAL_SOUND);
					break;
				case 1:
					trap_S_StartLocalSound(cgs.media.grenadePulseSound2, CHAN_LOCAL_SOUND);
					break;
				case 0:
					trap_S_StartLocalSound(cgs.media.grenadePulseSound1, CHAN_LOCAL_SOUND);
					break;
				}
			}
		}

		scale     = (float)((cg.predictedPlayerState.grenadeTimeLeft) % 1000) / 100.0f;
		halfScale = scale * 0.5f;

		cg.grenLastTime = cg.predictedPlayerState.grenadeTimeLeft;
	} else {
		scale = halfScale = 0;
	}

	if (icon) {
		float x, y, w, h;

		if (size == 1) {   // draw half width to match the icon asset
			// start at left
			x = rect->x - halfScale;
			y = rect->y - halfScale;
			w = rect->w / 2 + scale;
			h = rect->h + scale;

			switch (align) {
			case ITEM_ALIGN_CENTER:
				x += rect->w / 4;
				break;
			case ITEM_ALIGN_RIGHT:
				x += rect->w / 2;
				break;
			case ITEM_ALIGN_LEFT:
			default:
				break;
			}

		} else {
			x = rect->x - halfScale;
			y = rect->y - halfScale;
			w = rect->w + scale;
			h = rect->h + scale;
		}


		trap_R_SetColor(hcolor);   // JPW NERVE
		CG_DrawPic(x, y, w, h, icon);
	}
}
Exemple #3
0
/*
===============
UI_DrawPlayer
===============
*/
void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) {
    refdef_t		refdef;
    refEntity_t		legs;
    refEntity_t		torso;
    refEntity_t		head;
    refEntity_t		gun;
    refEntity_t		flash;
    vec3_t			origin;
    int				renderfx;
    vec3_t			mins = {-16, -16, -24};
    vec3_t			maxs = {16, 16, 32};
    float			len;
    float			xx;

    if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) {
        return;
    }

    // this allows the ui to cache the player model on the main menu
    if (w == 0 || h == 0) {
        return;
    }

    dp_realtime = time;

    if ( pi->pendingWeapon != -1 && dp_realtime > pi->weaponTimer ) {
        pi->weapon = pi->pendingWeapon;
        pi->lastWeapon = pi->pendingWeapon;
        pi->pendingWeapon = -1;
        pi->weaponTimer = 0;
        if( pi->currentWeapon != pi->weapon ) {
            trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL );
        }
    }

    UI_AdjustFrom640( &x, &y, &w, &h );

    y -= jumpHeight;

    memset( &refdef, 0, sizeof( refdef ) );
    memset( &legs, 0, sizeof(legs) );
    memset( &torso, 0, sizeof(torso) );
    memset( &head, 0, sizeof(head) );

    refdef.rdflags = RDF_NOWORLDMODEL;

    AxisClear( refdef.viewaxis );

    refdef.x = x;
    refdef.y = y;
    refdef.width = w;
    refdef.height = h;

    refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f);
    xx = refdef.width / tan( refdef.fov_x / 360 * M_PI );
    refdef.fov_y = atan2( refdef.height, xx );
    refdef.fov_y *= ( 360 / (float)M_PI );

    // calculate distance so the player nearly fills the box
    len = 0.72 * ( maxs[2] - mins[2] );
    origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 );
    origin[1] = 0.5 * ( mins[1] + maxs[1] );
    origin[2] = -0.5 * ( mins[2] + maxs[2] );

    refdef.time = dp_realtime;

    trap_R_ClearScene();

    // get the rotation information
    UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis );

    // get the animation state (after rotation, to allow feet shuffle)
    UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp,
                        &torso.oldframe, &torso.frame, &torso.backlerp );

    renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;

    //
    // add the legs
    //
    legs.hModel = pi->legsModel;
    legs.customSkin = pi->legsSkin;

    VectorCopy( origin, legs.origin );

    VectorCopy( origin, legs.lightingOrigin );
    legs.renderfx = renderfx;
    VectorCopy (legs.origin, legs.oldorigin);

    trap_R_AddRefEntityToScene( &legs );

    if (!legs.hModel) {
        return;
    }

    //
    // add the torso
    //
    torso.hModel = pi->torsoModel;
    if (!torso.hModel) {
        return;
    }

    torso.customSkin = pi->torsoSkin;

    VectorCopy( origin, torso.lightingOrigin );

    UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso");

    torso.renderfx = renderfx;

    trap_R_AddRefEntityToScene( &torso );

    //
    // add the head
    //
    head.hModel = pi->headModel;
    if (!head.hModel) {
        return;
    }
    head.customSkin = pi->headSkin;

    VectorCopy( origin, head.lightingOrigin );

    UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head");

    head.renderfx = renderfx;

    trap_R_AddRefEntityToScene( &head );

    //
    // add the gun
    //
    if ( pi->currentWeapon != WP_NONE ) {
        memset( &gun, 0, sizeof(gun) );
        gun.hModel = pi->weaponModel;
        VectorCopy( origin, gun.lightingOrigin );
        UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon");
        gun.renderfx = renderfx;
        trap_R_AddRefEntityToScene( &gun );
    }

    //
    // add the spinning barrel
    //

    //
    // add muzzle flash
    //
    if ( dp_realtime <= pi->muzzleFlashTime ) {
        if ( pi->flashModel ) {
            memset( &flash, 0, sizeof(flash) );
            flash.hModel = pi->flashModel;
            VectorCopy( origin, flash.lightingOrigin );
            UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash");
            flash.renderfx = renderfx;
            trap_R_AddRefEntityToScene( &flash );
        }

        // make a dlight for the flash
        if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) {
            trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0],
                                    pi->flashDlightColor[1], pi->flashDlightColor[2] );
        }
    }

    //
    // add the chat icon
    //
    if ( pi->chat ) {
        UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) );
    }

    //
    // add an accent light
    //
    origin[0] -= 100;	// + = behind, - = in front
    origin[1] += 100;	// + = left, - = right
    origin[2] += 100;	// + = above, - = below
    trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0 );

    origin[0] -= 100;
    origin[1] -= 100;
    origin[2] -= 100;
    trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0 );

    trap_R_RenderScene( &refdef );
}
Exemple #4
0
void CG_SiegeRoundOver(centity_t *ent, int won)
{
	int				myTeam;
	char			teamstr[64];
	char			appstring[1024];
	char			soundstr[1024];
	int				success = 0;
	playerState_t	*ps = NULL;

	if (!siege_valid)
	{
		CG_Error("ERROR: Siege data does not exist on client!\n");
		return;
	}

	if (cg.snap)
	{ //this should always be true, if it isn't though use the predicted ps as a fallback
		ps = &cg.snap->ps;
	}
	else
	{
		ps = &cg.predictedPlayerState;
	}

	if (!ps)
	{
		assert(0);
		return;
	}

	myTeam = ps->persistant[PERS_TEAM];

	if (myTeam == TEAM_SPECTATOR)
	{
		return;
	}

	if (myTeam == SIEGETEAM_TEAM1)
	{
		Com_sprintf(teamstr, sizeof(teamstr), team1);
	}
	else
	{
		Com_sprintf(teamstr, sizeof(teamstr), team2);
	}

	if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
	{
		if (won == myTeam)
		{
			success = BG_SiegeGetPairedValue(cgParseObjectives, "wonround", appstring);
		}
		else
		{
			success = BG_SiegeGetPairedValue(cgParseObjectives, "lostround", appstring);
		}

		if (success)
		{
			CG_DrawSiegeMessage(appstring, 0);
		}

		appstring[0] = 0;
		soundstr[0] = 0;

		if (myTeam == won)
		{
			Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_wewon");
		}
		else
		{
			Com_sprintf(teamstr, sizeof(teamstr), "roundover_sound_welost");
		}

		if (BG_SiegeGetPairedValue(cgParseObjectives, teamstr, appstring))
		{
			Com_sprintf(soundstr, sizeof(soundstr), appstring);
		}
		/*
		else
		{
			if (myTeam != won)
			{
				Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_LOSE_ROUND);
			}
			else
			{
				Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_WIN_ROUND);
			}
		}
		*/

		if (soundstr[0])
		{
			trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
		}
	}
}
Exemple #5
0
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops )
{
    int reward, delta;

    // don't play the sounds if the player just spawned
    if( ps->persistant[ PERS_SPECSTATE ] != ops->persistant[ PERS_SPECSTATE ] )
        return;

    //hitsound
    delta = ps->persistant[PERS_HITS] - ops->persistant[PERS_HITS];

    if (cg_hitsound.integer == 3)
    {   if (delta > 165) //125
            trap_S_StartLocalSound( cgs.media.hitSound[8], CHAN_LOCAL_SOUND );
        else if (delta > 120) //100
            trap_S_StartLocalSound( cgs.media.hitSound[7], CHAN_LOCAL_SOUND );
        else if (delta > 85) //75
            trap_S_StartLocalSound( cgs.media.hitSound[6], CHAN_LOCAL_SOUND );
        else if (delta > 50)
            trap_S_StartLocalSound( cgs.media.hitSound[5], CHAN_LOCAL_SOUND );
        else if (delta > 25)
            trap_S_StartLocalSound( cgs.media.hitSound[4], CHAN_LOCAL_SOUND );
        else if (delta > 12)
            trap_S_StartLocalSound( cgs.media.hitSound[3], CHAN_LOCAL_SOUND );
        else if (delta > 8)
            trap_S_StartLocalSound( cgs.media.hitSound[2], CHAN_LOCAL_SOUND );
        else if (delta > 4)
            trap_S_StartLocalSound( cgs.media.hitSound[1], CHAN_LOCAL_SOUND );
        else if (delta > 0) //0 = no events
            trap_S_StartLocalSound( cgs.media.hitSound[0], CHAN_LOCAL_SOUND );
    }
    else if (cg_hitsound.integer == 2)
    {   if (delta > 8)
            trap_S_StartLocalSound( cgs.media.hitSound[8], CHAN_LOCAL_SOUND );
        else if (delta > 7)
            trap_S_StartLocalSound( cgs.media.hitSound[7], CHAN_LOCAL_SOUND );
        else if (delta > 6)
            trap_S_StartLocalSound( cgs.media.hitSound[6], CHAN_LOCAL_SOUND );
        else if (delta > 5)
            trap_S_StartLocalSound( cgs.media.hitSound[5], CHAN_LOCAL_SOUND );
        else if (delta > 4)
            trap_S_StartLocalSound( cgs.media.hitSound[4], CHAN_LOCAL_SOUND );
        else if (delta > 3)
            trap_S_StartLocalSound( cgs.media.hitSound[3], CHAN_LOCAL_SOUND );
        else if (delta > 2)
            trap_S_StartLocalSound( cgs.media.hitSound[2], CHAN_LOCAL_SOUND );
        else if (delta > 1)
            trap_S_StartLocalSound( cgs.media.hitSound[1], CHAN_LOCAL_SOUND );
        else if (delta > 0) //0 = no events
            trap_S_StartLocalSound( cgs.media.hitSound[0], CHAN_LOCAL_SOUND );
    }
    else if (cg_hitsound.integer && (delta > 0)) //no tonal change
        trap_S_StartLocalSound( cgs.media.hitSound[4], CHAN_LOCAL_SOUND );

    //health changes of more than -1 should make pain sounds
    //and don't play hurt sound if evolving
    if( ps->stats[ STAT_HEALTH ] < ops->stats[ STAT_HEALTH ] - 1
            && ps->stats[ STAT_CLASS ] == ops->stats[ STAT_CLASS ] )
    {
        float healthlost = ((ops->stats[ STAT_HEALTH ] - ps->stats[ STAT_HEALTH ])/ps->stats[ STAT_MAX_HEALTH ]);
        if( ps->stats[ STAT_HEALTH ] > 0 ) {
            CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[ STAT_HEALTH ] );
            //play critical hit! sound if lost > 30% hp
            if (healthlost > 0.3)
                trap_S_StartLocalSound( cgs.media.hitSound[9], CHAN_LOCAL_SOUND );
        }
    }
    //Don't spam it if the user is spamming spacebar up a stair (Urasai! Annoying!)
    if(cg_doublejumpsound.integer &&
            ps->persistant[PERS_DOUBLEJUMPED] > ops->persistant[PERS_DOUBLEJUMPED])
    {
        trap_S_StartLocalSound( cgs.media.doublejumpsound, CHAN_LOCAL_SOUND );
    }

    // health changes of more than -1 should make pain sounds
    if( ps->stats[ STAT_HEALTH ] < ops->stats[ STAT_HEALTH ] - 1 )
    {
        if( ps->stats[ STAT_HEALTH ] > 0 )
            CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[ STAT_HEALTH ] );
    }

    if( ( BG_UpgradeIsActive( UP_JETPACK, ps->stats ) ||
            ( cg.predictedPlayerEntity.jetPackJumpTime + 1000 > cg.time &&
              cg.predictedPlayerEntity.jetPackJumpTime + 250 < cg.time ) ) &&
            ps->stats[ STAT_FUEL ] <= JETPACK_FUEL_LOW )
    {
        static int last = 0;

        if( last + 740 < cg.time )
        {
            trap_S_StartSound( NULL, cg.predictedPlayerState.clientNum, CHAN_AUTO, cgs.media.jetpackLowFuelSound );
            last = cg.time;
        }
    }

    // if we are going into the intermission, don't start any voices
    if( cg.intermissionStarted )
        return;

    // reward sounds
    reward = qfalse;
}
Exemple #6
0
/**
The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
*/
static void CG_ServerCommand(void)
{
	const char	*cmd;
	char		text[MAX_SAY_TEXT];

	cmd = BG_Argv(0);

	if (!cmd[0]) {
		// server claimed the command
		return;
	}

	if (!strcmp(cmd, "cp")) {
		CG_CenterPrint(BG_Argv(1));
		return;
	}

	if (!strcmp(cmd, "cs")) {
		CG_ConfigStringModified();
		return;
	}

	if (!strcmp(cmd, "pings")) {
		CG_ParsePings();
		return;
	}

	if (!strcmp(cmd, "tinfo")) {
		CG_ParseTeamInfo();
	}

	if (!strcmp(cmd, "print")) {
		CG_Printf("%s", BG_Argv(1));
		return;
	}

	if (!strcmp(cmd, "screenprint")) {
		Q_strncpyz(text, BG_Argv(1), sizeof text);
		CG_AddScreenMessage(text, qfalse);
		CG_Printf("%s\n", text);
		return;
	}

	if (!strcmp(cmd, "s")) {
		CG_ParseScores();
		return;
	}

	if (!strcmp(cmd, "stats")) {
		CG_ParseStats();
		return;
	}

	if (!strcmp(cmd, "chat")) {
		if (cg_teamChatsOnly.integer) {
			return;
		}
		if (cg_teamChatBeep.integer) {
			trap_S_StartLocalSound(cgs.media.talkSound, CHAN_LOCAL_SOUND);
		}
		Q_strncpyz(text, BG_Argv(1), sizeof text);
		CG_RemoveChatEscapeChar(text);
		CG_AddScreenMessage(text, qfalse);
		CG_Printf("%s\n", text);
		return;
	}

	if (!strcmp(cmd, "tchat")) {
		if (cg_chatBeep.integer) {
			trap_S_StartLocalSound(cgs.media.talkSound, CHAN_LOCAL_SOUND);
		}
		Q_strncpyz(text, BG_Argv(1), sizeof text);
		CG_RemoveChatEscapeChar(text);
		CG_AddScreenMessage(text, qtrue);
		CG_Printf("%s\n", text);
		return;
	}

	if (!strcmp(cmd, "map_restart")) {
		CG_MapRestart();
		return;
	}

	if (!strcmp(cmd, "remapShader") == 0) {
		if (trap_Argc() == 4) {
			char shader1[MAX_QPATH];
			char shader2[MAX_QPATH];
			char shader3[MAX_QPATH];

			Q_strncpyz(shader1, BG_Argv(1), sizeof(shader1));
			Q_strncpyz(shader2, BG_Argv(2), sizeof(shader2));
			Q_strncpyz(shader3, BG_Argv(3), sizeof(shader3));

			trap_R_RemapShader(shader1, shader2, shader3);
		}

		return;
	}

	// clientLevelShot is sent before taking a special screenshot for
	// the menu system during development
	if (!strcmp(cmd, "clientLevelShot")) {
		cg.levelShot = qtrue;
		return;
	}

	CG_Printf("Unknown client game command: %s\n", cmd);
}
Exemple #7
0
/*
==============
CG_EntityEvent

An entity has an event value
also called by CG_CheckPlayerstateEvents
==============
*/
void CG_EntityEvent( centity_t *cent, vec3_t position )
{
    entityState_t *es;
    int           event;
    vec3_t        dir;
    const char    *s;
    int           clientNum;
    clientInfo_t  *ci;
    int           steptime;

    if ( cg.snap->ps.persistant[ PERS_SPECSTATE ] != SPECTATOR_NOT )
    {
        steptime = 200;
    }
    else
    {
        steptime = BG_Class( cg.snap->ps.stats[ STAT_CLASS ] )->steptime;
    }

    es = &cent->currentState;
    event = es->event & ~EV_EVENT_BITS;

    if ( cg_debugEvents.integer )
    {
        CG_Printf( "ent:%3i  event:%3i %s\n", es->number, event,
                   BG_EventName( event ) );
    }

    if ( !event )
    {
        return;
    }

    clientNum = es->clientNum;

    if ( clientNum < 0 || clientNum >= MAX_CLIENTS )
    {
        clientNum = 0;
    }

    ci = &cgs.clientinfo[ clientNum ];

    switch ( event )
    {
    case EV_FOOTSTEP:
        if ( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
        {
            if ( ci->footsteps == FOOTSTEP_CUSTOM )
            {
                trap_S_StartSound( NULL, es->number, CHAN_BODY,
                                   ci->customFootsteps[ rand() & 3 ] );
            }
            else
            {
                trap_S_StartSound( NULL, es->number, CHAN_BODY,
                                   cgs.media.footsteps[ ci->footsteps ][ rand() & 3 ] );
            }
        }

        break;

    case EV_FOOTSTEP_METAL:
        if ( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
        {
            if ( ci->footsteps == FOOTSTEP_CUSTOM )
            {
                trap_S_StartSound( NULL, es->number, CHAN_BODY,
                                   ci->customMetalFootsteps[ rand() & 3 ] );
            }
            else
            {
                trap_S_StartSound( NULL, es->number, CHAN_BODY,
                                   cgs.media.footsteps[ FOOTSTEP_METAL ][ rand() & 3 ] );
            }
        }

        break;

    case EV_FOOTSTEP_SQUELCH:
        if ( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
        {
            trap_S_StartSound( NULL, es->number, CHAN_BODY,
                               cgs.media.footsteps[ FOOTSTEP_FLESH ][ rand() & 3 ] );
        }

        break;

    case EV_FOOTSPLASH:
        if ( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
        {
            trap_S_StartSound( NULL, es->number, CHAN_BODY,
                               cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand() & 3 ] );
        }

        break;

    case EV_FOOTWADE:
        if ( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
        {
            trap_S_StartSound( NULL, es->number, CHAN_BODY,
                               cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand() & 3 ] );
        }

        break;

    case EV_SWIM:
        if ( cg_footsteps.integer && ci->footsteps != FOOTSTEP_NONE )
        {
            trap_S_StartSound( NULL, es->number, CHAN_BODY,
                               cgs.media.footsteps[ FOOTSTEP_SPLASH ][ rand() & 3 ] );
        }

        break;

    case EV_FALL_SHORT:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.landSound );

        if ( clientNum == cg.predictedPlayerState.clientNum )
        {
            // smooth landing z changes
            cg.landChange = -8;
            cg.landTime = cg.time;
        }

        break;

    case EV_FALL_MEDIUM:
        // use a general pain sound
        trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) );

        if ( clientNum == cg.predictedPlayerState.clientNum )
        {
            // smooth landing z changes
            cg.landChange = -16;
            cg.landTime = cg.time;
        }

        break;

    case EV_FALL_FAR:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) );
        cent->pe.painTime = cg.time; // don't play a pain sound right after this

        if ( clientNum == cg.predictedPlayerState.clientNum )
        {
            // smooth landing z changes
            cg.landChange = -24;
            cg.landTime = cg.time;
        }

        break;

    case EV_FALLING:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*falling1.wav" ) );
        break;

    case EV_STEP_4:
    case EV_STEP_8:
    case EV_STEP_12:
    case EV_STEP_16: // smooth out step up transitions
    case EV_STEPDN_4:
    case EV_STEPDN_8:
    case EV_STEPDN_12:
    case EV_STEPDN_16: // smooth out step down transitions
    {
        float oldStep;
        int   delta;
        int   step;

        if ( clientNum != cg.predictedPlayerState.clientNum )
        {
            break;
        }

        // if we are interpolating, we don't need to smooth steps
        if ( cg.demoPlayback || ( cg.snap->ps.pm_flags & PMF_FOLLOW ) ||
                cg_nopredict.integer || cg_synchronousClients.integer )
        {
            break;
        }

        // check for stepping up before a previous step is completed
        delta = cg.time - cg.stepTime;

        if ( delta < steptime )
        {
            oldStep = cg.stepChange * ( steptime - delta ) / steptime;
        }
        else
        {
            oldStep = 0;
        }

        // add this amount
        if ( event >= EV_STEPDN_4 )
        {
            step = 4 * ( event - EV_STEPDN_4 + 1 );
            cg.stepChange = oldStep - step;
        }
        else
        {
            step = 4 * ( event - EV_STEP_4 + 1 );
            cg.stepChange = oldStep + step;
        }

        if ( cg.stepChange > MAX_STEP_CHANGE )
        {
            cg.stepChange = MAX_STEP_CHANGE;
        }
        else if ( cg.stepChange < -MAX_STEP_CHANGE )
        {
            cg.stepChange = -MAX_STEP_CHANGE;
        }

        cg.stepTime = cg.time;
        break;
    }

    case EV_JUMP:
        trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );

        if ( BG_ClassHasAbility( cg.predictedPlayerState.stats[ STAT_CLASS ], SCA_WALLJUMPER ) )
        {
            vec3_t surfNormal, refNormal = { 0.0f, 0.0f, 1.0f };
            vec3_t rotAxis;

            if ( clientNum != cg.predictedPlayerState.clientNum )
            {
                break;
            }

            //set surfNormal
            VectorCopy( cg.predictedPlayerState.grapplePoint, surfNormal );

            //if we are moving from one surface to another smooth the transition
            if ( !VectorCompare( surfNormal, cg.lastNormal ) && surfNormal[ 2 ] != 1.0f )
            {
                CrossProduct( refNormal, surfNormal, rotAxis );
                VectorNormalize( rotAxis );

                //add the op
                CG_addSmoothOp( rotAxis, 15.0f, 1.0f );
            }

            //copy the current normal to the lastNormal
            VectorCopy( surfNormal, cg.lastNormal );
        }

        break;

    case EV_LEV1_GRAB:
        trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL1Grab );
        break;

    case EV_LEV4_TRAMPLE_PREPARE:
        trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargePrepare );
        break;

    case EV_LEV4_TRAMPLE_START:
        //FIXME: stop cgs.media.alienL4ChargePrepare playing here
        trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.media.alienL4ChargeStart );
        break;

    case EV_TAUNT:
        if ( !cg_noTaunt.integer )
        {
            trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) );
        }

        break;

    case EV_WATER_TOUCH:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrInSound );
        break;

    case EV_WATER_LEAVE:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound );
        break;

    case EV_WATER_UNDER:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound );
        break;

    case EV_WATER_CLEAR:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) );
        break;

    case EV_JETPACK_ENABLE:
        // TODO: Trigger jetpack enable animation
        break;

    case EV_JETPACK_DISABLE:
        // TODO: Trigger jetpack disable animation
        break;

    case EV_JETPACK_START:
        // TODO: Start jetpack gfx/sfx
        break;

    case EV_JETPACK_STOP:
        // TODO: Stop jetpack gfx/sfx
        break;

    case EV_NOAMMO:
        trap_S_StartSound( NULL, es->number, CHAN_WEAPON, cgs.media.weaponEmptyClick );
        break;

    case EV_CHANGE_WEAPON:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.selectSound );
        break;

    case EV_FIRE_WEAPON:
        CG_HandleFireWeapon( cent, WPM_PRIMARY );
        break;

    case EV_FIRE_WEAPON2:
        CG_HandleFireWeapon( cent, WPM_SECONDARY );
        break;

    case EV_FIRE_WEAPON3:
        CG_HandleFireWeapon( cent, WPM_TERTIARY );
        break;

    case EV_WEAPON_RELOAD:
        if ( cg_weapons[ es->eventParm ].wim[ WPM_PRIMARY ].reloadSound )
        {
            trap_S_StartSound( NULL, es->number, CHAN_WEAPON, cg_weapons[ es->eventParm ].wim[ WPM_PRIMARY ].reloadSound );
        }
        break;

    case EV_PLAYER_TELEPORT_IN:
        //deprecated
        break;

    case EV_PLAYER_TELEPORT_OUT:
        CG_PlayerDisconnect( position );
        break;

    case EV_BUILD_CONSTRUCT:
        break;

    case EV_BUILD_DESTROY:
        break;

    case EV_AMMO_REFILL:
    case EV_CLIPS_REFILL:
    case EV_FUEL_REFILL:
        // TODO: Add different sounds for EV_AMMO_REFILL, EV_CLIPS_REFILL, EV_FUEL_REFILL
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.repeaterUseSound );
        break;

    case EV_GRENADE_BOUNCE:
        if ( rand() & 1 )
        {
            trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hardBounceSound1 );
        }
        else
        {
            trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.hardBounceSound2 );
        }
        break;

    case EV_WEAPON_HIT_ENTITY:
        CG_HandleWeaponHitEntity( es, position );
        break;

    case EV_WEAPON_HIT_ENVIRONMENT:
        CG_HandleWeaponHitWall( es, position );
        break;

    case EV_MISSILE_HIT_ENTITY:
        CG_HandleMissileHitEntity( es, position );
        break;

    // currently there is no support for metal sounds
    case EV_MISSILE_HIT_ENVIRONMENT:
    case EV_MISSILE_HIT_METAL:
        CG_HandleMissileHitWall( es, position );
        break;

    case EV_SHOTGUN:
        CG_HandleFireShotgun( es );
        break;

    case EV_HUMAN_BUILDABLE_DYING:
        CG_HumanBuildableDying( (buildable_t) es->modelindex, position );
        break;

    case EV_HUMAN_BUILDABLE_EXPLOSION:
        ByteToDir( es->eventParm, dir );
        CG_HumanBuildableExplosion( (buildable_t) es->modelindex, position, dir );
        break;

    case EV_ALIEN_BUILDABLE_EXPLOSION:
        ByteToDir( es->eventParm, dir );
        CG_AlienBuildableExplosion( position, dir );
        break;

    case EV_TESLATRAIL:
        cent->currentState.weapon = WP_TESLAGEN;
        {
            centity_t *source = &cg_entities[ es->generic1 ];
            centity_t *target = &cg_entities[ es->clientNum ];
            vec3_t    sourceOffset = { 0.0f, 0.0f, 28.0f };

            if ( !CG_IsTrailSystemValid( &source->muzzleTS ) )
            {
                source->muzzleTS = CG_SpawnNewTrailSystem( cgs.media.teslaZapTS );

                if ( CG_IsTrailSystemValid( &source->muzzleTS ) )
                {
                    CG_SetAttachmentCent( &source->muzzleTS->frontAttachment, source );
                    CG_SetAttachmentCent( &source->muzzleTS->backAttachment, target );
                    CG_AttachToCent( &source->muzzleTS->frontAttachment );
                    CG_AttachToCent( &source->muzzleTS->backAttachment );
                    CG_SetAttachmentOffset( &source->muzzleTS->frontAttachment, sourceOffset );

                    source->muzzleTSDeathTime = cg.time + cg_teslaTrailTime.integer;
                }
            }
        }
        break;

    case EV_GENERAL_SOUND:
        if ( cgs.gameSounds[ es->eventParm ] )
        {
            trap_S_StartSound( NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] );
        }
        else
        {
            s = CG_ConfigString( CS_SOUNDS + es->eventParm );
            trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) );
        }

        break;

    case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes
        if ( cgs.gameSounds[ es->eventParm ] )
        {
            trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] );
        }
        else
        {
            s = CG_ConfigString( CS_SOUNDS + es->eventParm );
            trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) );
        }

        break;

    case EV_PAIN:
        // local player sounds are triggered in CG_CheckLocalSounds,
        // so ignore events on the player
        if ( cent->currentState.number != cg.snap->ps.clientNum )
        {
            CG_PainEvent( cent, es->eventParm );
        }

        break;

    case EV_DEATH1:
    case EV_DEATH2:
    case EV_DEATH3:
        trap_S_StartSound( NULL, es->number, CHAN_VOICE,
                           CG_CustomSound( es->number, va( "*death%i.wav", event - EV_DEATH1 + 1 ) ) );
        break;

    case EV_OBITUARY:
        CG_Obituary( es );
        break;

    case EV_GIB_PLAYER:
        // no gibbing
        break;

    case EV_STOPLOOPINGSOUND:
        trap_S_StopLoopingSound( es->number );
        es->loopSound = 0;
        break;

    case EV_DEBUG_LINE:
        CG_Beam( cent );
        break;

    case EV_BUILD_DELAY:
        if ( clientNum == cg.predictedPlayerState.clientNum )
        {
            trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND );
            cg.lastBuildAttempt = cg.time;
        }

        break;

    case EV_BUILD_REPAIR:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairSound );
        break;

    case EV_BUILD_REPAIRED:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.buildableRepairedSound );
        break;

    case EV_OVERMIND_ATTACK_1:
    case EV_OVERMIND_ATTACK_2:
        if ( cg.predictedPlayerState.persistant[ PERS_TEAM ] == TEAM_ALIENS )
        {
            trap_S_StartLocalSound( cgs.media.alienOvermindAttack, CHAN_ANNOUNCER );
            CG_CenterPrint( va( "^%c%s", "31"[ event - EV_OVERMIND_ATTACK_1 ], _( "The Overmind is under attack!" ) ), 200, GIANTCHAR_WIDTH * 4 );
        }

        break;

    case EV_OVERMIND_DYING:
        if ( cg.predictedPlayerState.persistant[ PERS_TEAM ] == TEAM_ALIENS )
        {
            trap_S_StartLocalSound( cgs.media.alienOvermindDying, CHAN_ANNOUNCER );
            CG_CenterPrint( _( "^1The Overmind is dying!" ), 200, GIANTCHAR_WIDTH * 4 );
        }

        break;

    case EV_REACTOR_ATTACK_1:
    case EV_REACTOR_ATTACK_2:
        if ( cg.predictedPlayerState.persistant[ PERS_TEAM ] == TEAM_HUMANS )
        {
            CG_CenterPrint( va( "^%c%s", "31"[ event - EV_REACTOR_ATTACK_1 ], _( "The reactor is under attack!" ) ), 200, GIANTCHAR_WIDTH * 4 );
        }

        break;

    case EV_REACTOR_DYING:
        if ( cg.predictedPlayerState.persistant[ PERS_TEAM ] == TEAM_HUMANS )
        {
            CG_CenterPrint( _( "^1The reactor is about to explode!" ), 200, GIANTCHAR_WIDTH * 4 );
        }

        break;

    case EV_WARN_ATTACK:
        // if eventParm is non-zero, this is for humans and there's a nearby reactor or repeater, otherwise it's for aliens
        if ( es->eventParm >= MAX_CLIENTS && es->eventParm < MAX_GENTITIES )
        {
            const char *location;
            qboolean    base = cg_entities[ es->eventParm ].currentState.modelindex == BA_H_REACTOR;
            centity_t  *locent = CG_GetLocation( cg_entities[ es->eventParm ].currentState.origin );

            CG_CenterPrint( base ? _( "Our base is under attack!" ) : _( "A forward base is under attack!" ), 200, GIANTCHAR_WIDTH * 4 );

            if ( locent )
            {
                location = CG_ConfigString( CS_LOCATIONS + locent->currentState.generic1 );
            }
            else
            {
                location = CG_ConfigString( CS_LOCATIONS );
            }

            if ( location && *location )
            {
                Com_Printf( _( "%s Under attack – %s\n" ), base ? "[reactor]" : "[repeater]", location );
            }
            else
            {
                Com_Printf( _( "%s Under attack\n" ), base ? "[reactor]" : "[repeater]" );
            }
        }
        else // this is for aliens, and the overmind is in range
        {
            CG_CenterPrint( _( "Our base is under attack!" ), 200, GIANTCHAR_WIDTH * 4 );
        }

        break;

    case EV_MGTURRET_SPINUP:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.turretSpinupSound );
        break;

    case EV_OVERMIND_SPAWNS:
        if ( cg.predictedPlayerState.persistant[ PERS_TEAM ] == TEAM_ALIENS )
        {
            trap_S_StartLocalSound( cgs.media.alienOvermindSpawns, CHAN_ANNOUNCER );
            CG_CenterPrint( "The Overmind needs spawns!", 200, GIANTCHAR_WIDTH * 4 );
        }

        break;

    case EV_ALIEN_EVOLVE:
        trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.alienEvolveSound );
        {
            particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienEvolvePS );

            if ( CG_IsParticleSystemValid( &ps ) )
            {
                CG_SetAttachmentCent( &ps->attachment, cent );
                CG_AttachToCent( &ps->attachment );
            }
        }

        if ( es->number == cg.clientNum )
        {
            CG_ResetPainBlend();
            cg.spawnTime = cg.time;
        }

        break;

    case EV_ALIEN_EVOLVE_FAILED:
        if ( clientNum == cg.predictedPlayerState.clientNum )
        {
            //FIXME: change to "negative" sound
            trap_S_StartLocalSound( cgs.media.buildableRepairedSound, CHAN_LOCAL_SOUND );
            cg.lastEvolveAttempt = cg.time;
        }

        break;

    case EV_ALIEN_ACIDTUBE:
    {
        particleSystem_t *ps = CG_SpawnNewParticleSystem( cgs.media.alienAcidTubePS );

        if ( CG_IsParticleSystemValid( &ps ) )
        {
            CG_SetAttachmentCent( &ps->attachment, cent );
            ByteToDir( es->eventParm, dir );
            CG_SetParticleSystemNormal( ps, dir );
            CG_AttachToCent( &ps->attachment );
        }
    }
    break;

    case EV_MEDKIT_USED:
        trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.medkitUseSound );
        break;

    case EV_PLAYER_RESPAWN:
        if ( es->number == cg.clientNum )
        {
            cg.spawnTime = cg.time;
        }

        break;

    case EV_LEV2_ZAP:
        CG_Level2Zap( es );
        break;

    case EV_HIT:
        cg.hitTime = cg.time;
        break;

    case EV_MOMENTUM:
        CG_Momentum( es );
        break;

    default:
        CG_Error( "Unknown event: %i", event );
    }
}
Exemple #8
0
/*
================
CG_ConfigStringModified

================
*/
static void CG_ConfigStringModified( void ) {
	const char	*str;
	int		num;

	num = atoi( CG_Argv( 1 ) );

	// get the gamestate from the client system, which will have the
	// new configstring already integrated
	trap_GetGameState( &cgs.gameState );

	// look up the individual string that was modified
	str = CG_ConfigString( num );

	// do something with it if necessary
	if ( num == CS_MUSIC ) {
		CG_StartMusic();
	} else if ( num == CS_SERVERINFO ) {
		CG_ParseServerinfo();
	} else if ( num == CS_WARMUP ) {
		CG_ParseWarmup();
	} else if ( num == CS_SCORES1 ) {
		cgs.scores1 = atoi( str );
	} else if ( num == CS_SCORES2 ) {
		cgs.scores2 = atoi( str );
	} else if ( num == CS_LEVEL_START_TIME ) {
		cgs.levelStartTime = atoi( str );
	} else if ( num == CS_VOTE_TIME ) {
		cgs.voteTime = atoi( str );
		cgs.voteModified = qtrue;
	} else if ( num == CS_VOTE_YES ) {
		cgs.voteYes = atoi( str );
		cgs.voteModified = qtrue;
	} else if ( num == CS_VOTE_NO ) {
		cgs.voteNo = atoi( str );
		cgs.voteModified = qtrue;
	} else if ( num == CS_VOTE_STRING ) {
		Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
#ifdef MISSIONPACK
		trap_S_StartLocalSound( cgs.media.voteNow, CHAN_ANNOUNCER );
#endif //MISSIONPACK
	} else if ( num >= CS_TEAMVOTE_TIME && num <= CS_TEAMVOTE_TIME + 1) {
		cgs.teamVoteTime[num-CS_TEAMVOTE_TIME] = atoi( str );
		cgs.teamVoteModified[num-CS_TEAMVOTE_TIME] = qtrue;
	} else if ( num >= CS_TEAMVOTE_YES && num <= CS_TEAMVOTE_YES + 1) {
		cgs.teamVoteYes[num-CS_TEAMVOTE_YES] = atoi( str );
		cgs.teamVoteModified[num-CS_TEAMVOTE_YES] = qtrue;
	} else if ( num >= CS_TEAMVOTE_NO && num <= CS_TEAMVOTE_NO + 1) {
		cgs.teamVoteNo[num-CS_TEAMVOTE_NO] = atoi( str );
		cgs.teamVoteModified[num-CS_TEAMVOTE_NO] = qtrue;
	} else if ( num >= CS_TEAMVOTE_STRING && num <= CS_TEAMVOTE_STRING + 1) {
		Q_strncpyz( cgs.teamVoteString[num-CS_TEAMVOTE_STRING], str, sizeof( cgs.teamVoteString ) );
#ifdef MISSIONPACK
		trap_S_StartLocalSound( cgs.media.voteNow, CHAN_ANNOUNCER );
#endif
	} else if ( num == CS_INTERMISSION ) {
		cg.intermissionStarted = atoi( str );
	} else if ( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS ) {
		cgs.gameModels[ num-CS_MODELS ] = trap_R_RegisterModel( str );
	} else if ( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_MODELS ) {
		if ( str[0] != '*' ) {	// player specific sounds don't register here
			cgs.gameSounds[ num-CS_SOUNDS] = trap_S_RegisterSound( str, qfalse );
		}
	} else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) {
		CG_NewClientInfo( num - CS_PLAYERS );
		CG_BuildSpectatorString();
	} else if ( num == CS_FLAGSTATUS ) {
		if( cgs.gametype == GT_CTF ) {
			// format is rb where its red/blue, 0 is at base, 1 is taken, 2 is dropped
			cgs.redflag = str[0] - '0';
			cgs.blueflag = str[1] - '0';
		}
#ifdef MISSIONPACK
		else if( cgs.gametype == GT_1FCTF ) {
			cgs.flagStatus = str[0] - '0';
		}
#endif
	}
	else if ( num == CS_SHADERSTATE ) {
		CG_ShaderStateChanged();
	}

}
Exemple #9
0
/*
=================
CG_ServerCommand

The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
static void CG_ServerCommand( void ) {
	const char	*cmd;
	char		text[MAX_SAY_TEXT];

	cmd = CG_Argv(0);

	if ( !cmd[0] ) {
		// server claimed the command
		return;
	}

	if ( !strcmp( cmd, "cp" ) ) {
		CG_CenterPrint( CG_Argv(1), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cs" ) ) {
		CG_ConfigStringModified();
		return;
	}

	if ( !strcmp( cmd, "print" ) ) {
		CG_Printf( "%s", CG_Argv(1) );
#ifdef MISSIONPACK
		cmd = CG_Argv(1);			// yes, this is obviously a hack, but so is the way we hear about
									// votes passing or failing
		if ( !Q_stricmpn( cmd, "vote failed", 11 ) || !Q_stricmpn( cmd, "team vote failed", 16 )) {
			trap_S_StartLocalSound( cgs.media.voteFailed, CHAN_ANNOUNCER );
		} else if ( !Q_stricmpn( cmd, "vote passed", 11 ) || !Q_stricmpn( cmd, "team vote passed", 16 ) ) {
			trap_S_StartLocalSound( cgs.media.votePassed, CHAN_ANNOUNCER );
		}
#endif
		return;
	}

	if ( !strcmp( cmd, "chat" ) ) {
		if ( !cg_teamChatsOnly.integer ) {
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
			Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
			CG_RemoveChatEscapeChar( text );
			CG_Printf( "%s\n", text );
		}
		return;
	}

	if ( !strcmp( cmd, "tchat" ) ) {
		trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
		CG_AddToTeamChat( text );
		CG_Printf( "%s\n", text );
		return;
	}
	if ( !strcmp( cmd, "vchat" ) ) {
		CG_VoiceChat( SAY_ALL );
		return;
	}

	if ( !strcmp( cmd, "vtchat" ) ) {
		CG_VoiceChat( SAY_TEAM );
		return;
	}

	if ( !strcmp( cmd, "vtell" ) ) {
		CG_VoiceChat( SAY_TELL );
		return;
	}

	if ( !strcmp( cmd, "scores" ) ) {
		CG_ParseScores();
		return;
	}

	if ( !strcmp( cmd, "tinfo" ) ) {
		CG_ParseTeamInfo();
		return;
	}

	if ( !strcmp( cmd, "map_restart" ) ) {
		CG_MapRestart();
		return;
	}

  if ( Q_stricmp (cmd, "remapShader") == 0 ) {
		if (trap_Argc() == 4) {
			trap_R_RemapShader(CG_Argv(1), CG_Argv(2), CG_Argv(3));
		}
	}

	// loaddeferred can be both a servercmd and a consolecmd
	if ( !strcmp( cmd, "loaddefered" ) ) {	// FIXME: spelled wrong, but not changing for demo
		CG_LoadDeferredPlayers();
		return;
	}

	// clientLevelShot is sent before taking a special screenshot for
	// the menu system during development
	if ( !strcmp( cmd, "clientLevelShot" ) ) {
		cg.levelShot = qtrue;
		return;
	}

	// CORKSCREW accuracy challenge

	if ( !strcmp( cmd, "drawchallengeinfo" ) ) {
		cg.encryptChallengeInfo = ( rand() % 9000 ) + 1000;
		cg.drawChallengeInfoScreenshotTime = 0;
		cg.drawChallengeInfo = qtrue;
		cg.drawChallengeInfoScreenshot = qtrue;
		cg.showScores = qtrue;
		return;
	}

	CG_Printf( "Unknown client game command: %s\n", cmd );
}
/*
=================
CG_ServerCommand

The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
static void CG_ServerCommand( void ) {
	const char	*cmd;
	char		text[MAX_SAY_TEXT];

	cmd = CG_Argv(0);

	if ( !cmd[0] ) {
		// server claimed the command
		return;
	}

	if ( !strcmp( cmd, "cp" ) ) {
		CG_CenterPrint( CG_Argv(1), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cs" ) ) {
		CG_ConfigStringModified();
		return;
	}

	if ( !strcmp( cmd, "print" ) ) {
		CG_Printf( "%s", CG_Argv(1) );
#ifdef MISSIONPACK
		cmd = CG_Argv(1);			// yes, this is obviously a hack, but so is the way we hear about
									// votes passing or failing
		if ( !Q_stricmpn( cmd, "vote failed", 11 ) || !Q_stricmpn( cmd, "team vote failed", 16 )) {
			trap_S_StartLocalSound( cgs.media.voteFailed, CHAN_ANNOUNCER );
		} else if ( !Q_stricmpn( cmd, "vote passed", 11 ) || !Q_stricmpn( cmd, "team vote passed", 16 ) ) {
			trap_S_StartLocalSound( cgs.media.votePassed, CHAN_ANNOUNCER );
		}
#endif
		return;
	}

	if ( !strcmp( cmd, "chat" ) ) {
		if ( !cg_teamChatsOnly.integer ) {
                        if( cg_chatBeep.integer )
                                trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
			Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
			CG_RemoveChatEscapeChar( text );
			CG_Printf( "%s\n", text );
		}
		return;
	}

	if ( !strcmp( cmd, "tchat" ) ) {
                if( cg_teamChatBeep.integer )
                        trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
		CG_AddToTeamChat( text );
		CG_Printf( "%s\n", text );
		return;
	}
	if ( !strcmp( cmd, "vchat" ) ) {
		CG_VoiceChat( SAY_ALL );
		return;
	}

	if ( !strcmp( cmd, "vtchat" ) ) {
		CG_VoiceChat( SAY_TEAM );
		return;
	}

	if ( !strcmp( cmd, "vtell" ) ) {
		CG_VoiceChat( SAY_TELL );
		return;
	}

	if ( !strcmp( cmd, "scores" ) ) {
		CG_ParseScores();
		return;
	}


        if ( !strcmp( cmd, "accs" ) ) {
                CG_ParseAccuracy();
                return;
        }


	if ( !strcmp( cmd, "ddtaken" ) ) {
		CG_ParseDDtimetaken();
		return;
	}

	if ( !strcmp( cmd, "dompointnames" ) ) {
		CG_ParseDomPointNames();
		return;
	}

	if ( !strcmp( cmd, "domStatus" ) ) {
		CG_ParseDomStatus();
		return;
	}

	if ( !strcmp( cmd, "elimination" ) ) {
		CG_ParseElimination();
		return;
	}

	if ( !strcmp( cmd, "mappage" ) ) {
		CG_ParseMappage();
		return;
	}

	if ( !strcmp( cmd, "attackingteam" ) ) {
		CG_ParseAttackingTeam();
		return;
	}

	if ( !strcmp( cmd, "tinfo" ) ) {
		CG_ParseTeamInfo();
		return;
	}

	if ( !strcmp( cmd, "map_restart" ) ) {
		CG_MapRestart();
		return;
	}

	if ( Q_stricmp (cmd, "remapShader") == 0 )
	{
		if (trap_Argc() == 4)
		{
			char shader1[MAX_QPATH];
			char shader2[MAX_QPATH];
			char shader3[MAX_QPATH];

			Q_strncpyz(shader1, CG_Argv(1), sizeof(shader1));
			Q_strncpyz(shader2, CG_Argv(2), sizeof(shader2));
			Q_strncpyz(shader3, CG_Argv(3), sizeof(shader3));

			trap_R_RemapShader(shader1, shader2, shader3);
		}
		
		return;
	}

	// loaddeferred can be both a servercmd and a consolecmd
	if ( !strcmp( cmd, "loaddefered" ) ) {	// FIXME: spelled wrong, but not changing for demo
		CG_LoadDeferredPlayers();
		return;
	}

	// clientLevelShot is sent before taking a special screenshot for
	// the menu system during development
	if ( !strcmp( cmd, "clientLevelShot" ) ) {
		cg.levelShot = qtrue;
		return;
	}

	// challenge completed is determened by the server. A client should consider this message valid:
	if ( !strcmp( cmd, "ch" ) ) {
		CG_ParseChallenge();
		return;
	}
        
        if ( !strcmp (cmd, "oh") ) {
            CG_ParseObeliskHealth();
            return;
        }

        if ( !strcmp( cmd, "respawn" ) ) {
		CG_ParseRespawnTime();
		return;
	}

        if ( !strcmp( cmd, "team" ) ) {
		CG_ParseTeam();
		return;
	}

        if ( !strcmp( cmd, "customvotes" ) ) {
            char infoString[1024];
            int i;
            //TODO: Create a ParseCustomvotes function
            memset(&infoString,0,sizeof(infoString));
            for(i=1;i<=12;i++) {
                Q_strcat(infoString,sizeof(infoString),CG_Argv( i ));
                Q_strcat(infoString,sizeof(infoString)," ");
            }
            trap_Cvar_Set("cg_vote_custom_commands",infoString);
		return;
	}

	CG_Printf( "Unknown client game command: %s\n", cmd );
}
Exemple #11
0
/*
==================
CG_CheckLocalSounds
==================
*/
void
CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops )
{
    if ( cg_hitsounds.integer &&
         ps->clientNum == ops->clientNum &&
         ps->persistant[PERS_SPAWN_COUNT] == ops->persistant[PERS_SPAWN_COUNT] )
    {
        int* const h  = ps->holdable;
        int* const oh = ops->holdable;

        ///////////////////////////////////////////////////////////////////

        if ((h[HOLDABLE_HIT] & 0x000f) > (oh[HOLDABLE_HIT] & 0x000f))
            trap_S_StartLocalSound( cgs.media.hitsound_head, CHAN_LOCAL_SOUND );

        if (cg_hitsounds.integer != 2) {
            if ((h[HOLDABLE_HIT] & 0x00f0) != (oh[HOLDABLE_HIT] & 0x00f0))
                trap_S_StartLocalSound( cgs.media.hitsound_hand, CHAN_LOCAL_SOUND );

            if ((h[HOLDABLE_HIT] & 0x0f00) != (oh[HOLDABLE_HIT] & 0x0f00))
                trap_S_StartLocalSound( cgs.media.hitsound_torso, CHAN_LOCAL_SOUND );

            if ((h[HOLDABLE_HIT] & 0xf000) != (oh[HOLDABLE_HIT] & 0xf000))
                trap_S_StartLocalSound( cgs.media.hitsound_foot, CHAN_LOCAL_SOUND );
        }

        ///////////////////////////////////////////////////////////////////

        if ((h[HOLDABLE_HITF] & 0x000f) != (oh[HOLDABLE_HITF] & 0x000f))
            trap_S_StartLocalSound( cgs.media.hitsound_fhead, CHAN_LOCAL_SOUND );

        if (cg_hitsounds.integer != 2) {
            if ((h[HOLDABLE_HITF] & 0x00f0) != (oh[HOLDABLE_HITF] & 0x00f0))
                trap_S_StartLocalSound( cgs.media.hitsound_fhand, CHAN_LOCAL_SOUND );

            if ((h[HOLDABLE_HITF] & 0x0f00) != (oh[HOLDABLE_HITF] & 0x0f00))
                trap_S_StartLocalSound( cgs.media.hitsound_ftorso, CHAN_LOCAL_SOUND );

            if ((h[HOLDABLE_HITF] & 0xf000) != (oh[HOLDABLE_HITF] & 0xf000))
                trap_S_StartLocalSound( cgs.media.hitsound_ffoot, CHAN_LOCAL_SOUND );
        }
    }

	// health changes of more than -1 should make pain sounds
	if ( ps->stats[STAT_HEALTH] < ops->stats[STAT_HEALTH] - 1 ) {
		if ( ps->stats[STAT_HEALTH] > 0 ) {
			CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH], qfalse );

			cg.painTime = cg.time;
		}
	}

	// timelimit warnings
	if ( cgs.timelimit > 0 && cgs.gamestate == GS_PLAYING) {
		int		msec;

		msec = cg.time - cgs.levelStartTime;

		if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && (msec > (cgs.timelimit - 5) * 60 * 1000) &&
			( msec < (cgs.timelimit-5)*60*1000+1000 ) ) {
			cg.timelimitWarnings |= 1;
			if( ps->persistant[PERS_TEAM] == TEAM_AXIS ) {
				if( cgs.media.fiveMinuteSound_g == -1 ) {
					CG_SoundPlaySoundScript( cg.fiveMinuteSound_g, NULL, -1, qtrue );
				} else if( cgs.media.fiveMinuteSound_g ) {
					trap_S_StartLocalSound( cgs.media.fiveMinuteSound_g, CHAN_ANNOUNCER );
				}
			} else if( ps->persistant[PERS_TEAM] == TEAM_ALLIES ) {
				if( cgs.media.fiveMinuteSound_a == -1 ) {
					CG_SoundPlaySoundScript( cg.fiveMinuteSound_a, NULL, -1, qtrue );
				} else if( cgs.media.fiveMinuteSound_a ) {
					trap_S_StartLocalSound( cgs.media.fiveMinuteSound_a, CHAN_ANNOUNCER );
				}
			}
		}
		if ( cgs.timelimit > 2 && !( cg.timelimitWarnings & 2 ) && (msec > (cgs.timelimit - 2) * 60 * 1000) &&
			( msec < (cgs.timelimit-2)*60*1000+1000 ) ) {
			cg.timelimitWarnings |= 2;
			if( ps->persistant[PERS_TEAM] == TEAM_AXIS ) {
				if( cgs.media.twoMinuteSound_g == -1 ) {
					CG_SoundPlaySoundScript( cg.twoMinuteSound_g, NULL, -1, qtrue );
				} else if( cgs.media.twoMinuteSound_g ) {
					trap_S_StartLocalSound( cgs.media.twoMinuteSound_g, CHAN_ANNOUNCER );
				}
			} else if( ps->persistant[PERS_TEAM] == TEAM_ALLIES ) {
				if( cgs.media.twoMinuteSound_a == -1 ) {
					CG_SoundPlaySoundScript( cg.twoMinuteSound_a, NULL, -1, qtrue );
				} else if( cgs.media.twoMinuteSound_a ) {
					trap_S_StartLocalSound( cgs.media.twoMinuteSound_a, CHAN_ANNOUNCER );
				}
			}
		}
		if ( !( cg.timelimitWarnings & 4 ) && (msec > (cgs.timelimit) * 60 * 1000 - 30000) && 
			(msec < (cgs.timelimit) * 60 * 1000 - 29000 ) ) {
			cg.timelimitWarnings |= 4;
			if( ps->persistant[PERS_TEAM] == TEAM_AXIS ) {
				if( cgs.media.thirtySecondSound_g == -1 ) {
					CG_SoundPlaySoundScript( cg.thirtySecondSound_g, NULL, -1, qtrue );
				} else if( cgs.media.thirtySecondSound_g ) {
					trap_S_StartLocalSound( cgs.media.thirtySecondSound_g, CHAN_ANNOUNCER );
				}
			} else if( ps->persistant[PERS_TEAM] == TEAM_ALLIES ) {
				if( cgs.media.thirtySecondSound_a == -1 ) {
					CG_SoundPlaySoundScript( cg.thirtySecondSound_a, NULL, -1, qtrue );
				} else if( cgs.media.thirtySecondSound_a ) {
					trap_S_StartLocalSound( cgs.media.thirtySecondSound_a, CHAN_ANNOUNCER );
				}
			}
		}
	}
}
static void InformUnlockableStatusChanges( int *statusChanges, int count )
{
	char         text[ MAX_STRING_CHARS ];
	char         *textptr = text;
	int          unlockableNum;
	bool     firstPass = true, unlocked = true;
	unlockable_t *unlockable;

	for ( unlockableNum = 0; unlockableNum < NUM_UNLOCKABLES; unlockableNum++ )
	{
		unlockable = &unlockables[ unlockableNum ];

		if ( !statusChanges[ unlockableNum ] || Disabled( unlockable ) )
		{
			continue;
		}

		if ( firstPass )
		{
			if ( statusChanges[ unlockableNum ] > 0 )
			{
				Com_sprintf( text, sizeof( text ),
				             S_COLOR_GREEN "ITEM%s UNLOCKED: " S_COLOR_WHITE, ( count > 1 ) ? "S" : "" );
			}
			else
			{
				unlocked = false;
				Com_sprintf( text, sizeof( text ),
				             S_COLOR_RED   "ITEM%s LOCKED: "   S_COLOR_WHITE, ( count > 1 ) ? "S" : "" );
			}

			textptr = text + strlen( text );
			firstPass = false;
		}
		else
		{
			Com_sprintf( textptr, sizeof( text ) - ( textptr - text ), ", " );
			textptr += 2;
		}

		Com_sprintf( textptr, sizeof( text ) - ( textptr - text ), "%s", UnlockableHumanName( unlockable ) );
		textptr += strlen( textptr );
	}

	// TODO: Add sound for items being locked for each team
	switch ( cg.snap->ps.persistant[ PERS_TEAM ] )
	{
		case TEAM_ALIENS:
			if ( unlocked )
			{
				trap_S_StartLocalSound( cgs.media.weHaveEvolved, CHAN_ANNOUNCER );
			}
			break;

		case TEAM_HUMANS:
		default:
			if ( unlocked )
			{
				trap_S_StartLocalSound( cgs.media.reinforcement, CHAN_ANNOUNCER );
			}
			break;
	}

	CG_CenterPrint( text, SCREEN_HEIGHT * 0.3, GIANTCHAR_WIDTH * 2 );
}
/*
=================
UI_SPPostgameMenu_MenuDraw
=================
*/
static void UI_SPPostgameMenu_MenuDraw( void ) {
    int		timer;
    int		serverId;
    int		n;
    char	info[MAX_INFO_STRING];

    trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) );
    serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) );
    if( serverId != postgameMenuInfo.serverId ) {
        UI_PopMenu();
        return;
    }

    // phase 1
    if ( postgameMenuInfo.numClients > 2 ) {
        UI_DrawProportionalString( 510, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[2], UI_CENTER, color_white );
    }
    UI_DrawProportionalString( 130, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[1], UI_CENTER, color_white );
    UI_DrawProportionalString( 320, 480 - 64 - 2 * PROP_HEIGHT, postgameMenuInfo.placeNames[0], UI_CENTER, color_white );

    if( postgameMenuInfo.phase == 1 ) {
        timer = uis.realtime - postgameMenuInfo.starttime;

        if( timer >= 1000 && postgameMenuInfo.winnerSound ) {
            trap_S_StartLocalSound( postgameMenuInfo.winnerSound, CHAN_ANNOUNCER );
            postgameMenuInfo.winnerSound = 0;
        }

        if( timer < 5000 ) {
            return;
        }
        postgameMenuInfo.phase = 2;
        postgameMenuInfo.starttime = uis.realtime;
    }

    // phase 2
    if( postgameMenuInfo.phase == 2 ) {
        timer = uis.realtime - postgameMenuInfo.starttime;
        if( timer >= ( postgameMenuInfo.numAwards * AWARD_PRESENTATION_TIME ) ) {

            if( timer < 5000 ) {
                return;
            }

            postgameMenuInfo.phase = 3;
            postgameMenuInfo.starttime = uis.realtime;
        }
        else {
            UI_SPPostgameMenu_DrawAwardsPresentation( timer );
        }
    }

    // phase 3
    if( postgameMenuInfo.phase == 3 ) {
        if( uis.demoversion ) {
            if( postgameMenuInfo.won == 1 && UI_ShowTierVideo( 8 )) {
                trap_Cvar_Set( "nextmap", "" );
                trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic demoEnd.RoQ\n" );
                return;
            }
        }
        else if( postgameMenuInfo.won > -1 && UI_ShowTierVideo( postgameMenuInfo.won + 1 )) {
            if( postgameMenuInfo.won == postgameMenuInfo.lastTier ) {
                trap_Cvar_Set( "nextmap", "" );
                trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic end.RoQ\n" );
                return;
            }

            trap_Cvar_SetValue( "ui_spSelection", postgameMenuInfo.won * ARENAS_PER_TIER );
            trap_Cvar_Set( "nextmap", "levelselect" );
            trap_Cmd_ExecuteText( EXEC_APPEND, va( "disconnect; cinematic tier%i.RoQ\n", postgameMenuInfo.won + 1 ) );
            return;
        }

        postgameMenuInfo.item_again.generic.flags &= ~QMF_INACTIVE;
        postgameMenuInfo.item_next.generic.flags &= ~QMF_INACTIVE;
        postgameMenuInfo.item_menu.generic.flags &= ~QMF_INACTIVE;

        UI_SPPostgameMenu_DrawAwardsMedals( postgameMenuInfo.numAwards );

        Menu_Draw( &postgameMenuInfo.menu );
    }

    // draw the scoreboard
    if( !trap_Cvar_VariableValue( "ui_spScoreboard" ) ) {
        return;
    }

    timer = uis.realtime - postgameMenuInfo.scoreboardtime;
    if( postgameMenuInfo.numClients <= 3 ) {
        n = 0;
    }
    else {
        n = timer / 1500 % (postgameMenuInfo.numClients + 2);
    }
    UI_SPPostgameMenu_MenuDrawScoreLine( n, 0 );
    UI_SPPostgameMenu_MenuDrawScoreLine( n + 1, 0 + SMALLCHAR_HEIGHT );
    UI_SPPostgameMenu_MenuDrawScoreLine( n + 2, 0 + 2 * SMALLCHAR_HEIGHT );
}
Exemple #14
0
/*
=================
CG_Say
=================
*/
static void CG_Say( const char *name, int clientNum, saymode_t mode, const char *text )
{
	char prefix[ 21 ] = "";
	char *ignore = "";
	char *location = "";
	char color;
	char *maybeColon;

	if ( clientNum >= 0 && clientNum < MAX_CLIENTS )
	{
		clientInfo_t *ci = &cgs.clientinfo[ clientNum ];
		char         *tcolor = S_COLOR_WHITE;

		name = ci->name;

		if ( ci->team == TEAM_ALIENS )
		{
			tcolor = S_COLOR_RED;
		}
		else if ( ci->team == TEAM_HUMANS )
		{
			tcolor = S_COLOR_CYAN;
		}

		if ( cg_chatTeamPrefix.integer )
		{
			Com_sprintf( prefix, sizeof( prefix ), "[%s%c" S_COLOR_WHITE "] ",
			             tcolor, toupper( * ( BG_TeamName( ci->team ) ) ) );
		}

		if ( Com_ClientListContains( &cgs.ignoreList, clientNum ) )
		{
			ignore = "[skipnotify]";
		}

		if ( ( mode == SAY_TEAM || mode == SAY_AREA ) &&
		     cg.snap->ps.pm_type != PM_INTERMISSION )
		{
			int locationNum;

			if ( clientNum == cg.snap->ps.clientNum )
			{
				centity_t *locent;

				locent = CG_GetPlayerLocation();

				if ( locent )
				{
					locationNum = locent->currentState.generic1;
				}
				else
				{
					locationNum = 0;
				}
			}
			else
			{
				locationNum = ci->location;
			}

			if ( locationNum > 0 && locationNum < MAX_LOCATIONS )
			{
				const char *s = CG_ConfigString( CS_LOCATIONS + locationNum );

				if ( *s )
				{
					location = va( " (%s" S_COLOR_WHITE ")", s );
				}
			}
		}
	}
	else if ( name )
	{
		Q_strcat( prefix, sizeof( prefix ), "[ADMIN]" );
	}
	else
	{
		name = "console";
	}

	// IRC-like /me parsing
	if ( mode != SAY_RAW && Q_stricmpn( text, "/me ", 4 ) == 0 )
	{
		text += 4;
		Q_strcat( prefix, sizeof( prefix ), "* " );
		maybeColon = "";
	}
	else
	{
		maybeColon = ":";
	}

	color = '0' + UI_GetChatColour( mode, cgs.clientinfo[ clientNum ].team );

	switch ( mode )
	{
		case SAY_ALL:
			// might already be ignored but in that case no harm is done
			if ( cg_teamChatsOnly.integer )
			{
				ignore = "[skipnotify]";
			}

		case SAY_ALL_ADMIN:
			CG_Printf(  "%s%s%s^7%s ^%c%s\n",
			           ignore, prefix, name, maybeColon, color, text );
			break;

		case SAY_TEAM:
			CG_Printf( "%s%s(%s^7)%s%s ^%c%s\n",
			           ignore, prefix, name, location, maybeColon, color, text );
			break;

		case SAY_ADMINS:
		case SAY_ADMINS_PUBLIC:
			CG_Printf( "%s%s%s%s^7%s ^%c%s\n",
			           ignore, prefix,
			           ( mode == SAY_ADMINS ) ? "[ADMIN]" : "[PLAYER]",
			           name, maybeColon, color, text );
			break;

		case SAY_AREA:
		case SAY_AREA_TEAM:
			CG_Printf( "%s%s<%s^7>%s%s ^%c%s\n",
			           ignore, prefix, name, location, maybeColon, color, text );
			break;

		case SAY_PRIVMSG:
		case SAY_TPRIVMSG:
			CG_Printf( "%s%s[%s^7 -> %s^7]%s ^%c%s\n",
			           ignore, prefix, name, cgs.clientinfo[ cg.clientNum ].name,
			           maybeColon, color, text );

			if ( !ignore[ 0 ] )
			{
				CG_CenterPrint( va( "^%cPrivate message from: " S_COLOR_WHITE "%s",
				                    color, name ), 200, GIANTCHAR_WIDTH * 4 );

				if ( clientNum < 0 || clientNum >= MAX_CLIENTS )
				{
					clientNum = cg.clientNum;
				}

				CG_Printf(_( ">> to reply, say: /m %d [your message] <<\n"), clientNum );
			}

			break;

		case SAY_RAW:
			CG_Printf( "%s\n", text );
			break;

		case SAY_DEFAULT:
		default:
			break;
	}

	switch ( mode )
	{
		case SAY_TEAM:
		case SAY_AREA:
		case SAY_TPRIVMSG:
			if ( cg.snap->ps.stats[ STAT_TEAM ] == TEAM_ALIENS )
			{
				trap_S_StartLocalSound( cgs.media.alienTalkSound, CHAN_LOCAL_SOUND );
				break;
			}
			else if ( cg.snap->ps.stats[ STAT_TEAM ] == TEAM_HUMANS )
			{
				trap_S_StartLocalSound( cgs.media.humanTalkSound, CHAN_LOCAL_SOUND );
				break;
			}

		default:
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
	}
}
/*
==============
CG_CheckAmmo

If the ammo has gone low enough to generate the warning, play a sound
==============
*/
void CG_CheckAmmo( void ) {
	int i;
	int total;
	int weapons[MAX_WEAPONS / ( sizeof( int ) * 8 )];

	// see about how many seconds of ammo we have remaining
	memcpy( weapons, cg.snap->ps.weapons, sizeof( weapons ) );

	if ( !weapons[0] && !weapons[1] ) { // (SA) we start out with no weapons, so don't make a click on startup
		return;
	}

	total = 0;

	// first weap now WP_LUGER
	for ( i = WP_FIRST ; i < WP_NUM_WEAPONS ; i++ )
	{
		if ( !( weapons[0] & ( 1 << i ) ) ) {
			continue;
		}
		switch ( i )
		{
		case WP_PANZERFAUST:
		case WP_GRENADE_LAUNCHER:
		case WP_GRENADE_PINEAPPLE:
		case WP_LUGER:
		case WP_COLT:
		case WP_AKIMBO:
		case WP_SILENCER:
		case WP_FG42:
		case WP_FG42SCOPE:
		case WP_MP40:
		case WP_THOMPSON:
		case WP_STEN:
		case WP_VENOM:
		case WP_TESLA:
		case WP_MAUSER:
		case WP_GARAND:
		default:
			total += cg.snap->ps.ammo[BG_FindAmmoForWeapon( i )] * 1000;
//				break;
//			default:
//				total += cg.snap->ps.ammo[BG_FindAmmoForWeapon(i)] * 200;
//				break;
		}

		if ( total >= 5000 ) {
			cg.lowAmmoWarning = 0;
			return;
		}
	}

	if ( !cg.lowAmmoWarning ) {
		// play a sound on this transition
		trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
	}

	if ( total == 0 ) {
		cg.lowAmmoWarning = 2;
	} else {
		cg.lowAmmoWarning = 1;
	}
}
Exemple #16
0
/*
===============
UI_DrawPlayer
===============
*/
void UI_DrawPlayer( float x, float y, float w, float h, uiPlayerInfo_t *pi, int time ) {
	refdef_t		refdef;
	refEntity_t		legs = {0};
	refEntity_t		torso = {0};
	refEntity_t		head = {0};
#ifdef TA_WEAPSYS
	refEntity_t		gun[MAX_HANDS] = {0};
#else
	refEntity_t		gun = {0};
#endif
	refEntity_t		barrel = {0};
	refEntity_t		flash = {0};
	vec3_t			origin;
	int				renderfx;
	vec3_t			mins = {-16, -16, -24};
	vec3_t			maxs = {16, 16, 32};
	float			len;
	float			xx;
	float			xscale;
	float			yscale;
#ifdef TA_WEAPSYS
	int				i;
	vec3_t			angles;
#ifdef TURTLEARENA // PLAYERS
	char *newTagNames[3] = { "tag_hand_primary", "tag_hand_secondary", NULL };
#endif
	char *originalTagNames[3] = { "tag_weapon", "tag_flag", NULL };
#endif

	if ( !pi->legsModel || !pi->torsoModel || !pi->headModel
#ifdef TA_PLAYERSYS
	|| !pi->playercfg.animations[0].numFrames ) {
#else
	|| !pi->animations[0].numFrames ) {
#endif
		return;
	}

	// this allows the ui to cache the player model on the main menu
	if (w == 0 || h == 0) {
		return;
	}

	dp_realtime = time;

	if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) {
		pi->weapon = pi->pendingWeapon;
		pi->lastWeapon = pi->pendingWeapon;
		pi->pendingWeapon = WP_NUM_WEAPONS;
		pi->weaponTimer = 0;
#ifndef TA_WEAPSYS_EX
		if( pi->currentWeapon != pi->weapon ) {
			trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL );
		}
#endif
	}

	CG_AdjustFrom640( &x, &y, &w, &h );

	y -= jumpHeight;

	memset( &refdef, 0, sizeof( refdef ) );
	memset( &legs, 0, sizeof(legs) );
	memset( &torso, 0, sizeof(torso) );
	memset( &head, 0, sizeof(head) );

	refdef.rdflags = RDF_NOWORLDMODEL;

	AxisClear( refdef.viewaxis );

	refdef.x = x;
	refdef.y = y;
	refdef.width = w;
	refdef.height = h;

	if ( ui_stretch.integer ) {
		xscale = cgs.screenXScaleStretch;
		yscale = cgs.screenYScaleStretch;
	} else {
		xscale = cgs.screenXScale;
		yscale = cgs.screenYScale;
	}

	refdef.fov_x = (int)((float)refdef.width / xscale / 640.0f * 90.0f);
	xx = refdef.width / xscale / tan( refdef.fov_x / 360 * M_PI );
	refdef.fov_y = atan2( refdef.height / yscale, xx );
	refdef.fov_y *= ( 360 / (float)M_PI );

	// calculate distance so the player nearly fills the box
	len = 0.7 * ( maxs[2] - mins[2] );
	origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 );
	origin[1] = 0.5 * ( mins[1] + maxs[1] );
	origin[2] = -0.5 * ( mins[2] + maxs[2] );

	refdef.time = dp_realtime;

	trap_R_ClearScene();

	// get the rotation information
	UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis );
	
	// get the animation state (after rotation, to allow feet shuffle)
	UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp,
		 &torso.oldframe, &torso.frame, &torso.backlerp );

	renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;

	//
	// add the legs
	//
	legs.hModel = pi->legsModel;
	legs.customSkin = CG_AddSkinToFrame( &pi->modelSkin );

	VectorCopy( origin, legs.origin );

	VectorCopy( origin, legs.lightingOrigin );
	legs.renderfx = renderfx;
	VectorCopy (legs.origin, legs.oldorigin);

	Byte4Copy( pi->c1RGBA, legs.shaderRGBA );

	CG_AddRefEntityWithMinLight( &legs );

	if (!legs.hModel) {
		return;
	}

	//
	// add the torso
	//
	torso.hModel = pi->torsoModel;
	if (!torso.hModel) {
		return;
	}

	torso.customSkin = legs.customSkin;

	VectorCopy( origin, torso.lightingOrigin );

	UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso");

	torso.renderfx = renderfx;

	Byte4Copy( pi->c1RGBA, torso.shaderRGBA );

	CG_AddRefEntityWithMinLight( &torso );

	//
	// add the head
	//
	head.hModel = pi->headModel;
	if (!head.hModel) {
		return;
	}
	head.customSkin = legs.customSkin;

	VectorCopy( origin, head.lightingOrigin );

	UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head");

	head.renderfx = renderfx;

	Byte4Copy( pi->c1RGBA, head.shaderRGBA );

	CG_AddRefEntityWithMinLight( &head );

	//
	// add the gun
	//
	if ( pi->currentWeapon != WP_NONE ) {

#ifdef TA_WEAPSYS
		// get hands from cent
		for (i = 0; i < MAX_HANDS; i++)
		{
			memset( &gun[i], 0, sizeof(gun[i]) );
			gun[i].hModel = pi->weaponModel[i];
			VectorCopy( origin, gun[i].lightingOrigin );
			gun[i].renderfx = renderfx;
			Byte4Copy( pi->c1RGBA, gun[i].shaderRGBA );

			if (!originalTagNames[i]
#ifdef TURTLEARENA // PLAYERS
				|| !newTagNames[i]
#endif
				)
			{
				break;
			}

			if (!gun[i].hModel) {
				continue;
			}

			if (
#ifdef TURTLEARENA // PLAYERS
				!UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, newTagNames[i]) &&
#endif
				!UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, originalTagNames[i]))
			{
				// Failed to find tag
				continue;
			}


			CG_AddRefEntityWithMinLight( &gun[i] );
		}
#else
		memset( &gun, 0, sizeof(gun) );
		gun.hModel = pi->weaponModel;
		Byte4Copy( pi->c1RGBA, gun.shaderRGBA );
		VectorCopy( origin, gun.lightingOrigin );
		UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon");
		gun.renderfx = renderfx;
		CG_AddRefEntityWithMinLight( &gun );
#endif
	}

	//
	// add the spinning barrel
	//
#ifdef TA_WEAPSYS
	for (i = 0; i < MAX_HANDS; i++)
#else
	if ( pi->barrelModel )
#endif
	{
#ifdef TA_WEAPSYS
		if (!pi->barrelModel[i])
			continue;
#else
		vec3_t	angles;
#endif

		memset( &barrel, 0, sizeof(barrel) );
		VectorCopy( origin, barrel.lightingOrigin );
		barrel.renderfx = renderfx;

#ifdef TA_WEAPSYS
		barrel.hModel = pi->barrelModel[i];
		VectorClear(angles);
		if (bg_weapongroupinfo[pi->realWeapon].weapon[0]->barrelSpin != BS_NONE)
		{
			angles[bg_weapongroupinfo[pi->realWeapon].weapon[0]->barrelSpin]
						= UI_MachinegunSpinAngle( pi );
		}
#else
		barrel.hModel = pi->barrelModel;
		angles[YAW] = 0;
		angles[PITCH] = 0;
		angles[ROLL] = UI_MachinegunSpinAngle( pi );
#endif
		AnglesToAxis( angles, barrel.axis );

#ifdef TA_WEAPSYS
		UI_PositionRotatedEntityOnTag( &barrel, &gun[i], pi->weaponModel[i], "tag_barrel");
#else
		UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel");
#endif

		CG_AddRefEntityWithMinLight( &barrel );
	}

	//
	// add muzzle flash
	//
	if ( dp_realtime <= pi->muzzleFlashTime ) {
#ifdef TA_WEAPSYS
		vec3_t *flashDlightColor;

		for (i = 0; i < MAX_HANDS; i++)
		{
			memset( &flash, 0, sizeof(flash) );
			flash.hModel = pi->flashModel[i];
			flashDlightColor = &pi->flashDlightColor[i];
			Byte4Copy( pi->c1RGBA, flash.shaderRGBA );

			if (!flash.hModel)
				continue;

			VectorCopy( origin, flash.lightingOrigin );
			UI_PositionEntityOnTag( &flash, &gun[i], pi->weaponModel[i], "tag_flash");
			flash.renderfx = renderfx;
			trap_R_AddRefEntityToScene( &flash );

			// make a dlight for the flash
			if ( *flashDlightColor[0] || *flashDlightColor[1] || *flashDlightColor[2] ) {
				trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), 1.0f, *flashDlightColor[0],
					*flashDlightColor[1], *flashDlightColor[2] );
			}
		}
#else
		if ( pi->flashModel ) {
			memset( &flash, 0, sizeof(flash) );
			flash.hModel = pi->flashModel;
			Byte4Copy( pi->c1RGBA, flash.shaderRGBA );
			VectorCopy( origin, flash.lightingOrigin );
			UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash");
			flash.renderfx = renderfx;
			CG_AddRefEntityWithMinLight( &flash );
		}

		// make a dlight for the flash
		if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) {
			trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, pi->flashDlightColor[0],
				pi->flashDlightColor[1], pi->flashDlightColor[2] );
		}
#endif
	}

	//
	// add the chat icon
	//
	if ( pi->chat ) {
#ifdef TA_DATA // shaders
		UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/talkBalloon" ) );
#else
		UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) );
#endif
	}

	//
	// add an accent light
	//
	origin[0] -= 100;	// + = behind, - = in front
	origin[1] += 100;	// + = left, - = right
	origin[2] += 100;	// + = above, - = below
	trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 1.0, 1.0 );

	origin[0] -= 100;
	origin[1] -= 100;
	origin[2] -= 100;
	trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 0.0, 0.0 );

	trap_R_RenderScene( &refdef );
}

/*
==========================
UI_FileExists
==========================
*/
static qboolean	UI_FileExists(const char *filename) {
	int len;

	len = trap_FS_FOpenFile( filename, NULL, FS_READ );
	if (len>0) {
		return qtrue;
	}
	return qfalse;
}
Exemple #17
0
static void CG_ConfigStringModified(void)
{
	const char	*str;
	int		num;

	num = atoi(BG_Argv(1));

	// get the gamestate from the client system, which will have the
	// new configstring already integrated
	trap_GetGameState(&cgs.gameState);

	// look up the individual string that was modified
	str = CG_ConfigString(num);

	// do something with it if necessary
	if (num == CS_SERVERINFO) {
		CG_ParseServerinfo();
	} else if (num == CS_WARMUP) {
		CG_SetWarmup(atoi(str));
	} else if (num == CS_SCORES1) {
		cgs.scores1 = atoi(str);
	} else if (num == CS_SCORES2) {
		cgs.scores2 = atoi(str);
	} else if (num == CS_LEVEL_START_TIME) {
		cgs.levelStartTime = atoi(str);
	} else if (num == CS_VOTE_TIME) {
		if (!strcmp(str, "failed")) {
			cgs.voteTime = 0;
			CG_Printf("Vote failed.\n");
			CG_AddBufferedSound(cgs.media.voteFailed);
		} else if (!strcmp(str, "passed")) {
			cgs.voteTime = 0;
			CG_Printf("Vote passed.\n");
			CG_AddBufferedSound(cgs.media.votePassed);
		} else if (*str) {
			cgs.voteTime = atoi(str);
			CG_Printf("Vote cast.\n");
			CG_AddBufferedSound(cgs.media.voteNow);
		}
	} else if (num == CS_VOTE_YES) {
		cgs.voteYes = atoi(str);
		trap_S_StartLocalSound(cgs.media.talkSound, CHAN_LOCAL_SOUND);
	} else if (num == CS_VOTE_NO) {
		cgs.voteNo = atoi(str);
		trap_S_StartLocalSound(cgs.media.talkSound, CHAN_LOCAL_SOUND);
	} else if (num == CS_VOTE_STRING) {
		Q_strncpyz(cgs.voteString, str, sizeof(cgs.voteString));
	} else if (num == CS_INTERMISSION) {
		cg.intermissionStarted = atoi(str);
	} else if (num >= CS_MODELS && num < CS_MODELS+MAX_MODELS) {
		cgs.gameModels[num-CS_MODELS] = trap_R_RegisterModel(str);
	} else if (num >= CS_SOUNDS && num < CS_SOUNDS+MAX_SOUNDS) {
		if (str[0] != '*') {	// player specific sounds don't register here
			cgs.gameSounds[num-CS_SOUNDS] = trap_S_RegisterSound(str, qfalse);
		}
	} else if (num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS) {
		CG_NewClientInfo(num - CS_PLAYERS);
	} else if (num == CS_FLAGSTATUS) {
		// format is rb where its red/blue, 0 is at base, 1 is taken, 2 is dropped
		if (cgs.gametype == GT_CTF) {
			team_t	team;
			team = cgs.clientinfo[cg.clientNum].team;
			if ((cgs.redflag == 1 && str[0] - '0' == 2 && team == TEAM_RED)
				|| (cgs.blueflag == 1 && str[1] - '0' == 2 && team == TEAM_BLUE))
			{
				CG_CenterPrint("^2The enemy dropped your flag");
			} else if ((cgs.redflag == 1 && str[0] - '0' == 2 && team == TEAM_BLUE)
				|| (cgs.blueflag == 1 && str[1] - '0' == 2 && team == TEAM_RED))
			{
				CG_CenterPrint("^1You team dropped the flag");
			}

			cgs.redflag = str[0] - '0';
			cgs.blueflag = str[1] - '0';
		}
	} else if (num == CS_SHADERSTATE) {
		CG_ShaderStateChanged();
	} else if (num == CS_ROUND_START) {
		cg.countdownCount = -1;
		cgs.roundStartTime = atoi(str);
	} else if (num == CS_LIVING_COUNT) {
		int		newRed, newBlue;

		newRed = atoi(COM_Parse((char **) &str));
		newBlue = atoi(COM_Parse((char **) &str));

		if (!cgs.warmup && cg.time >= cgs.roundStartTime) {
			team_t	team;
			team = cg.snap->ps.persistant[PERS_TEAM];
			if ((newRed == 1 && cgs.redLivingCount != 1 && team == TEAM_RED)
				|| (newBlue == 1 && cgs.blueLivingCount != 1 && team == TEAM_BLUE))
			{
				CG_CenterPrint("You are the last in your team");
			}
		}

		cgs.redLivingCount = newRed;
		cgs.blueLivingCount = newBlue;
	} else if (num == CS_OVERTIME) {
		cgs.overtimeStart = atoi(str);
		trap_S_StartLocalSound(cgs.media.protectSound, CHAN_ANNOUNCER);
		CG_CenterPrint(va("^3OVERTIME^7 - %d seconds added", cgs.overtimeLimit));
	} else if (num >= CS_RESPAWN_TIMERS && num < CS_RESPAWN_TIMERS + MAX_RESPAWN_TIMERS) {
		CG_ParseRespawnTimer(num - CS_RESPAWN_TIMERS, str);
	} else if (num == CS_PAUSE_START) {
		cgs.pauseStart = atoi(str);
		if (cgs.pauseStart > 0) {
			trap_S_StartLocalSound(cgs.media.pauseSound, CHAN_LOCAL_SOUND);
		}
	} else if (num == CS_PAUSE_END) {
		cg.countdownCount = -1;
		cgs.pauseEnd = atoi(str);
	} else if (num == CS_PAUSE_TIME) {
		cgs.pauseTime = atoi(str);
	}
}
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
	// health changes of more than -1 should make pain sounds
	if ( ps->stats[STAT_HEALTH] < ops->stats[STAT_HEALTH] - 1 ) {
		if ( ps->stats[STAT_HEALTH] > 0 ) {
			CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH], qfalse );

			cg.painTime = cg.time;
		}
	}

	// timelimit warnings
	if ( cgs.timelimit > 0 && cgs.gamestate == GS_PLAYING) {
		int		msec;

		msec = cg.time - cgs.levelStartTime;

		if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && (msec > (cgs.timelimit - 5) * 60 * 1000) &&
			( msec < (cgs.timelimit-5)*60*1000+1000 ) ) {
			cg.timelimitWarnings |= 1;
			if( ps->persistant[PERS_TEAM] == TEAM_AXIS ) {
				if( cgs.media.fiveMinuteSound_g == -1 ) {
					CG_SoundPlaySoundScript( cg.fiveMinuteSound_g, NULL, -1, qtrue );
				} else if( cgs.media.fiveMinuteSound_g ) {
					trap_S_StartLocalSound( cgs.media.fiveMinuteSound_g, CHAN_ANNOUNCER );
				}
			} else if( ps->persistant[PERS_TEAM] == TEAM_ALLIES ) {
				if( cgs.media.fiveMinuteSound_a == -1 ) {
					CG_SoundPlaySoundScript( cg.fiveMinuteSound_a, NULL, -1, qtrue );
				} else if( cgs.media.fiveMinuteSound_a ) {
					trap_S_StartLocalSound( cgs.media.fiveMinuteSound_a, CHAN_ANNOUNCER );
				}
			}
		}
		if ( cgs.timelimit > 2 && !( cg.timelimitWarnings & 2 ) && (msec > (cgs.timelimit - 2) * 60 * 1000) &&
			( msec < (cgs.timelimit-2)*60*1000+1000 ) ) {
			cg.timelimitWarnings |= 2;
			if( ps->persistant[PERS_TEAM] == TEAM_AXIS ) {
				if( cgs.media.twoMinuteSound_g == -1 ) {
					CG_SoundPlaySoundScript( cg.twoMinuteSound_g, NULL, -1, qtrue );
				} else if( cgs.media.twoMinuteSound_g ) {
					trap_S_StartLocalSound( cgs.media.twoMinuteSound_g, CHAN_ANNOUNCER );
				}
			} else if( ps->persistant[PERS_TEAM] == TEAM_ALLIES ) {
				if( cgs.media.twoMinuteSound_a == -1 ) {
					CG_SoundPlaySoundScript( cg.twoMinuteSound_a, NULL, -1, qtrue );
				} else if( cgs.media.twoMinuteSound_a ) {
					trap_S_StartLocalSound( cgs.media.twoMinuteSound_a, CHAN_ANNOUNCER );
				}
			}
		}
		if ( !( cg.timelimitWarnings & 4 ) && (msec > (cgs.timelimit) * 60 * 1000 - 30000) && 
			(msec < (cgs.timelimit) * 60 * 1000 - 29000 ) ) {
			cg.timelimitWarnings |= 4;
			if( ps->persistant[PERS_TEAM] == TEAM_AXIS ) {
				if( cgs.media.thirtySecondSound_g == -1 ) {
					CG_SoundPlaySoundScript( cg.thirtySecondSound_g, NULL, -1, qtrue );
				} else if( cgs.media.thirtySecondSound_g ) {
					trap_S_StartLocalSound( cgs.media.thirtySecondSound_g, CHAN_ANNOUNCER );
				}
			} else if( ps->persistant[PERS_TEAM] == TEAM_ALLIES ) {
				if( cgs.media.thirtySecondSound_a == -1 ) {
					CG_SoundPlaySoundScript( cg.thirtySecondSound_a, NULL, -1, qtrue );
				} else if( cgs.media.thirtySecondSound_a ) {
					trap_S_StartLocalSound( cgs.media.thirtySecondSound_a, CHAN_ANNOUNCER );
				}
			}
		}
	}
}
Exemple #19
0
/*
====================
CG_AddKamikaze
====================
*/
void CG_AddKamikaze( localEntity_t *le ) {
	refEntity_t	*re;
	refEntity_t shockwave;
	float		c;
	vec3_t		test, axis[3];
	int			t;

	re = &le->refEntity;

	t = cg.time - le->startTime;
	VectorClear( test );
	AnglesToAxis( test, axis );

	if (t > KAMI_SHOCKWAVE_STARTTIME && t < KAMI_SHOCKWAVE_ENDTIME) {

		if (!(le->leFlags & LEF_SOUND1)) {
//			trap_S_StartSound (re->origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.kamikazeExplodeSound );
			trap_S_StartLocalSound(cgs.media.kamikazeExplodeSound, CHAN_AUTO);
			le->leFlags |= LEF_SOUND1;
		}
		// 1st kamikaze shockwave
		memset(&shockwave, 0, sizeof(shockwave));
		shockwave.hModel = cgs.media.kamikazeShockWave;
		shockwave.reType = RT_MODEL;
		shockwave.shaderTime = re->shaderTime;
		VectorCopy(re->origin, shockwave.origin);

		c = (float)(t - KAMI_SHOCKWAVE_STARTTIME) / (float)(KAMI_SHOCKWAVE_ENDTIME - KAMI_SHOCKWAVE_STARTTIME);
		VectorScale( axis[0], c * KAMI_SHOCKWAVE_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[0] );
		VectorScale( axis[1], c * KAMI_SHOCKWAVE_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[1] );
		VectorScale( axis[2], c * KAMI_SHOCKWAVE_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[2] );
		shockwave.nonNormalizedAxes = qtrue;

		if (t > KAMI_SHOCKWAVEFADE_STARTTIME) {
			c = (float)(t - KAMI_SHOCKWAVEFADE_STARTTIME) / (float)(KAMI_SHOCKWAVE_ENDTIME - KAMI_SHOCKWAVEFADE_STARTTIME);
		}
		else {
			c = 0;
		}
		c *= 0xff;
		shockwave.shaderRGBA[0] = 0xff - c;
		shockwave.shaderRGBA[1] = 0xff - c;
		shockwave.shaderRGBA[2] = 0xff - c;
		shockwave.shaderRGBA[3] = 0xff - c;

		CG_AddRefEntityWithMinLight( &shockwave );
	}

	if (t > KAMI_EXPLODE_STARTTIME && t < KAMI_IMPLODE_ENDTIME) {
		// explosion and implosion
		c = ( le->endTime - cg.time ) * le->lifeRate;
		c *= 0xff;
		re->shaderRGBA[0] = le->color[0] * c;
		re->shaderRGBA[1] = le->color[1] * c;
		re->shaderRGBA[2] = le->color[2] * c;
		re->shaderRGBA[3] = le->color[3] * c;

		if( t < KAMI_IMPLODE_STARTTIME ) {
			c = (float)(t - KAMI_EXPLODE_STARTTIME) / (float)(KAMI_IMPLODE_STARTTIME - KAMI_EXPLODE_STARTTIME);
		}
		else {
			if (!(le->leFlags & LEF_SOUND2)) {
//				trap_S_StartSound (re->origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.kamikazeImplodeSound );
				trap_S_StartLocalSound(cgs.media.kamikazeImplodeSound, CHAN_AUTO);
				le->leFlags |= LEF_SOUND2;
			}
			c = (float)(KAMI_IMPLODE_ENDTIME - t) / (float) (KAMI_IMPLODE_ENDTIME - KAMI_IMPLODE_STARTTIME);
		}
		VectorScale( axis[0], c * KAMI_BOOMSPHERE_MAXRADIUS / KAMI_BOOMSPHEREMODEL_RADIUS, re->axis[0] );
		VectorScale( axis[1], c * KAMI_BOOMSPHERE_MAXRADIUS / KAMI_BOOMSPHEREMODEL_RADIUS, re->axis[1] );
		VectorScale( axis[2], c * KAMI_BOOMSPHERE_MAXRADIUS / KAMI_BOOMSPHEREMODEL_RADIUS, re->axis[2] );
		re->nonNormalizedAxes = qtrue;

		CG_AddRefEntityWithMinLight( re );
		// add the dlight
		trap_R_AddLightToScene( re->origin, c * 1000.0, 1.0, 1.0, 1.0, c );
	}

	if (t > KAMI_SHOCKWAVE2_STARTTIME && t < KAMI_SHOCKWAVE2_ENDTIME) {
		// 2nd kamikaze shockwave
		if (le->angles.trBase[0] == 0 &&
			le->angles.trBase[1] == 0 &&
			le->angles.trBase[2] == 0) {
			le->angles.trBase[0] = random() * 360;
			le->angles.trBase[1] = random() * 360;
			le->angles.trBase[2] = random() * 360;
		}
		memset(&shockwave, 0, sizeof(shockwave));
		shockwave.hModel = cgs.media.kamikazeShockWave;
		shockwave.reType = RT_MODEL;
		shockwave.shaderTime = re->shaderTime;
		VectorCopy(re->origin, shockwave.origin);

		test[0] = le->angles.trBase[0];
		test[1] = le->angles.trBase[1];
		test[2] = le->angles.trBase[2];
		AnglesToAxis( test, axis );

		c = (float)(t - KAMI_SHOCKWAVE2_STARTTIME) / (float)(KAMI_SHOCKWAVE2_ENDTIME - KAMI_SHOCKWAVE2_STARTTIME);
		VectorScale( axis[0], c * KAMI_SHOCKWAVE2_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[0] );
		VectorScale( axis[1], c * KAMI_SHOCKWAVE2_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[1] );
		VectorScale( axis[2], c * KAMI_SHOCKWAVE2_MAXRADIUS / KAMI_SHOCKWAVEMODEL_RADIUS, shockwave.axis[2] );
		shockwave.nonNormalizedAxes = qtrue;

		if (t > KAMI_SHOCKWAVE2FADE_STARTTIME) {
			c = (float)(t - KAMI_SHOCKWAVE2FADE_STARTTIME) / (float)(KAMI_SHOCKWAVE2_ENDTIME - KAMI_SHOCKWAVE2FADE_STARTTIME);
		}
		else {
			c = 0;
		}
		c *= 0xff;
		shockwave.shaderRGBA[0] = 0xff - c;
		shockwave.shaderRGBA[1] = 0xff - c;
		shockwave.shaderRGBA[2] = 0xff - c;
		shockwave.shaderRGBA[3] = 0xff - c;

		CG_AddRefEntityWithMinLight( &shockwave );
	}
}
Exemple #20
0
void UI_StartSound( qhandle_t sound ) {
	if ( soundTime > uis.realtime ) return;

	trap_S_StartLocalSound( sound, CHAN_LOCAL_SOUND );
}
Exemple #21
0
void CG_SiegeObjectiveCompleted(centity_t *ent, int won, int objectivenum)
{
	int				myTeam;
	char			teamstr[64];
	char			objstr[256];
	char			foundobjective[MAX_SIEGE_INFO_SIZE];
	char			appstring[1024];
	char			soundstr[1024];
	int				success = 0;
	playerState_t	*ps = NULL;

	if (!siege_valid)
	{
		CG_Error("Siege data does not exist on client!\n");
		return;
	}

	if (cg.snap)
	{ //this should always be true, if it isn't though use the predicted ps as a fallback
		ps = &cg.snap->ps;
	}
	else
	{
		ps = &cg.predictedPlayerState;
	}

	if (!ps)
	{
		assert(0);
		return;
	}

	myTeam = ps->persistant[PERS_TEAM];

	if (myTeam == TEAM_SPECTATOR)
	{
		return;
	}

	if (won == SIEGETEAM_TEAM1)
	{
		Com_sprintf(teamstr, sizeof(teamstr), team1);
	}
	else
	{
		Com_sprintf(teamstr, sizeof(teamstr), team2);
	}

	if (BG_SiegeGetValueGroup(siege_info, teamstr, cgParseObjectives))
	{
		Com_sprintf(objstr, sizeof(objstr), "Objective%i", objectivenum);

		if (BG_SiegeGetValueGroup(cgParseObjectives, objstr, foundobjective))
		{
			if (myTeam == SIEGETEAM_TEAM1)
			{
				success = BG_SiegeGetPairedValue(foundobjective, "message_team1", appstring);
			}
			else
			{
				success = BG_SiegeGetPairedValue(foundobjective, "message_team2", appstring);
			}

			if (success)
			{
				CG_DrawSiegeMessageNonMenu(appstring);
			}

			appstring[0] = 0;
			soundstr[0] = 0;

			if (myTeam == SIEGETEAM_TEAM1)
			{
				Com_sprintf(teamstr, sizeof(teamstr), "sound_team1");
			}
			else
			{
				Com_sprintf(teamstr, sizeof(teamstr), "sound_team2");
			}

			if (BG_SiegeGetPairedValue(foundobjective, teamstr, appstring))
			{
				Com_sprintf(soundstr, sizeof(soundstr), appstring);
			}
			/*
			else
			{
				if (myTeam != won)
				{
					Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_LOSE_OBJECTIVE);
				}
				else
				{
					Com_sprintf(soundstr, sizeof(soundstr), DEFAULT_WIN_OBJECTIVE);
				}
			}
			*/

			if (soundstr[0])
			{
				trap_S_StartLocalSound(trap_S_RegisterSound(soundstr), CHAN_ANNOUNCER);
			}
		}
	}
}
Exemple #22
0
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds(playerState_t *ps, playerState_t *ops)
{
	// health changes of more than -1 should make pain sounds
	if (ps->stats[STAT_HEALTH] < ops->stats[STAT_HEALTH] - 1)
	{
		if (ps->stats[STAT_HEALTH] > 0)
		{
			CG_PainEvent(&cg.predictedPlayerEntity, ps->stats[STAT_HEALTH], qfalse);

			cg.painTime = cg.time;
		}
	}

	// hitsounds
	// add server control cvars?! - no, admins just have to force cg_hitSounds
	if (ops->persistant[PERS_HITS] != ps->persistant[PERS_HITS] && (cg_hitSounds.integer & HITSOUNDS_ON))
	{
		if (ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS])
		{
			if (!(cg_hitSounds.integer & HITSOUNDS_NOTEAMSHOT))
			{
				trap_S_StartSound(NULL, ps->clientNum, CHAN_AUTO, cgs.media.teamShot);
			}
		}
		else if (ps->persistant[PERS_HEADSHOTS] > ops->persistant[PERS_HEADSHOTS])
		{
			if (!(cg_hitSounds.integer & HITSOUNDS_NOHEADSHOT))
			{
				trap_S_StartSound(NULL, ps->clientNum, CHAN_AUTO, cgs.media.headShot);
			}
			else if (!(cg_hitSounds.integer & HITSOUNDS_NOBODYSHOT))
			{
				trap_S_StartSound(NULL, ps->clientNum, CHAN_AUTO, cgs.media.bodyShot);
			}
		}
		else
		{
			if (!(cg_hitSounds.integer & HITSOUNDS_NOBODYSHOT))
			{
				trap_S_StartSound(NULL, ps->clientNum, CHAN_AUTO, cgs.media.bodyShot);
			}
		}
	}

	// timelimit warnings
	if (cgs.timelimit > 0 && cgs.gamestate == GS_PLAYING)
	{
		int msec = cg.time - cgs.levelStartTime;

		if (cgs.timelimit > 5 && !(cg.timelimitWarnings & 1) && (msec > (cgs.timelimit - 5) * 60 * 1000) &&
		    (msec < (cgs.timelimit - 5) * 60 * 1000 + 1000))
		{
			cg.timelimitWarnings |= 1;
			if (ps->persistant[PERS_TEAM] == TEAM_AXIS)
			{
				if (cgs.media.fiveMinuteSound_g == -1)
				{
					CG_SoundPlaySoundScript(cg.fiveMinuteSound_g, NULL, -1, qtrue);
				}
				else if (cgs.media.fiveMinuteSound_g)
				{
					trap_S_StartLocalSound(cgs.media.fiveMinuteSound_g, CHAN_ANNOUNCER);
				}
			}
			else if (ps->persistant[PERS_TEAM] == TEAM_ALLIES)
			{
				if (cgs.media.fiveMinuteSound_a == -1)
				{
					CG_SoundPlaySoundScript(cg.fiveMinuteSound_a, NULL, -1, qtrue);
				}
				else if (cgs.media.fiveMinuteSound_a)
				{
					trap_S_StartLocalSound(cgs.media.fiveMinuteSound_a, CHAN_ANNOUNCER);
				}
			}
		}
		if (cgs.timelimit > 2 && !(cg.timelimitWarnings & 2) && (msec > (cgs.timelimit - 2) * 60 * 1000) &&
		    (msec < (cgs.timelimit - 2) * 60 * 1000 + 1000))
		{
			cg.timelimitWarnings |= 2;
			if (ps->persistant[PERS_TEAM] == TEAM_AXIS)
			{
				if (cgs.media.twoMinuteSound_g == -1)
				{
					CG_SoundPlaySoundScript(cg.twoMinuteSound_g, NULL, -1, qtrue);
				}
				else if (cgs.media.twoMinuteSound_g)
				{
					trap_S_StartLocalSound(cgs.media.twoMinuteSound_g, CHAN_ANNOUNCER);
				}
			}
			else if (ps->persistant[PERS_TEAM] == TEAM_ALLIES)
			{
				if (cgs.media.twoMinuteSound_a == -1)
				{
					CG_SoundPlaySoundScript(cg.twoMinuteSound_a, NULL, -1, qtrue);
				}
				else if (cgs.media.twoMinuteSound_a)
				{
					trap_S_StartLocalSound(cgs.media.twoMinuteSound_a, CHAN_ANNOUNCER);
				}
			}
		}
		if (!(cg.timelimitWarnings & 4) && (msec > (cgs.timelimit) * 60 * 1000 - 30000) &&
		    (msec < (cgs.timelimit) * 60 * 1000 - 29000))
		{
			cg.timelimitWarnings |= 4;
			if (ps->persistant[PERS_TEAM] == TEAM_AXIS)
			{
				if (cgs.media.thirtySecondSound_g == -1)
				{
					CG_SoundPlaySoundScript(cg.thirtySecondSound_g, NULL, -1, qtrue);
				}
				else if (cgs.media.thirtySecondSound_g)
				{
					trap_S_StartLocalSound(cgs.media.thirtySecondSound_g, CHAN_ANNOUNCER);
				}
			}
			else if (ps->persistant[PERS_TEAM] == TEAM_ALLIES)
			{
				if (cgs.media.thirtySecondSound_a == -1)
				{
					CG_SoundPlaySoundScript(cg.thirtySecondSound_a, NULL, -1, qtrue);
				}
				else if (cgs.media.thirtySecondSound_a)
				{
					trap_S_StartLocalSound(cgs.media.thirtySecondSound_a, CHAN_ANNOUNCER);
				}
			}
		}
	}
}
Exemple #23
0
/*
==============
CG_CheckAmmo

If the ammo has gone low enough to generate the warning, play a sound
==============
*/
void CG_CheckAmmo( void ) {
#if 0
	int		i;
	int		total;
	int		previous;
	int		weapons;

	// see about how many seconds of ammo we have remaining
	weapons = cg.snap->ps.stats[ STAT_WEAPONS ];
	total = 0;
	for ( i = WP_BRYAR_PISTOL; i < WP_NUM_WEAPONS ; i++ ) {
		if ( ! ( weapons & ( 1 << i ) ) ) {
			continue;
		}
		switch ( i ) 
		{
		case WP_BRYAR_PISTOL:
		case WP_CONCUSSION:
		case WP_BRYAR_OLD:
		case WP_BLASTER:
		case WP_DISRUPTOR:
		case WP_BOWCASTER:
		case WP_REPEATER:
		case WP_DEMP2:
		case WP_FLECHETTE:
		case WP_ROCKET_LAUNCHER:
		case WP_THERMAL:
		case WP_TRIP_MINE:
		case WP_DET_PACK:
		case WP_EMPLACED_GUN:
			total += cg.snap->ps.ammo[weaponData[i].ammoIndex] * 1000;
			break;
		default:
			total += cg.snap->ps.ammo[weaponData[i].ammoIndex] * 200;
			break;
		}
		if ( total >= 5000 ) {
			cg.lowAmmoWarning = 0;
			return;
		}
	}

	previous = cg.lowAmmoWarning;

	if ( total == 0 ) {
		cg.lowAmmoWarning = 2;
	} else {
		cg.lowAmmoWarning = 1;
	}

	if (cg.snap->ps.weapon == WP_SABER)
	{
		cg.lowAmmoWarning = 0;
	}

	// play a sound on transitions
	if ( cg.lowAmmoWarning != previous ) {
		trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND );
	}
#endif
	//disabled silly ammo warning stuff for now
}
Exemple #24
0
/*
=================
UI_SPSkillMenu_Key
=================
*/
static sfxHandle_t UI_SPSkillMenu_Key( int key ) {
	if( key == K_MOUSE2 || key == K_ESCAPE ) {
		trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER );
	}
	return Menu_DefaultKey( &skillMenuInfo.menu, key );
}
Exemple #25
0
void CG_EntityEvent( centity_t *cent, vec3_t position ) {
	entityState_t	*es;
	int				event;
	vec3_t			dir;
	const char		*s;
	int				clientNum;
	clientInfo_t	*ci;

	es = &cent->currentState;
	event = es->event & ~EV_EVENT_BITS;

	if ( cg_debugEvents.integer ) {
		CG_Printf( "ent:%3i  event:%3i ", es->number, event );
	}

	if ( !event ) {
		DEBUGNAME("ZEROEVENT");
		return;
	}

	clientNum = es->clientNum;
	if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) {
		clientNum = 0;
	}
	ci = &cgs.clientinfo[ clientNum ];

	switch ( event ) {
	//
	// movement generated events
	//
	case EV_FOOTSTEP:
		DEBUGNAME("EV_FOOTSTEP");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ ci->footsteps ][rand()&3] );
		}
		break;
	case EV_FOOTSTEP_METAL:
		DEBUGNAME("EV_FOOTSTEP_METAL");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3] );
		}
		break;
	case EV_FOOTSPLASH:
		DEBUGNAME("EV_FOOTSPLASH");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
		}
		break;
	case EV_FOOTWADE:
		DEBUGNAME("EV_FOOTWADE");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
		}
		break;
	case EV_SWIM:
		DEBUGNAME("EV_SWIM");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
		}
		break;


	case EV_FALL_SHORT:
		DEBUGNAME("EV_FALL_SHORT");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound );
		if ( clientNum == cg.predictedPlayerState.clientNum ) {
			// smooth landing z changes
			cg.landChange = -8;
			cg.landTime = cg.time;
		}
		break;
	case EV_FALL_MEDIUM:
		DEBUGNAME("EV_FALL_MEDIUM");
		// use normal pain sound
		trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) );
		if ( clientNum == cg.predictedPlayerState.clientNum ) {
			// smooth landing z changes
			cg.landChange = -16;
			cg.landTime = cg.time;
		}
		break;
	case EV_FALL_FAR:
		DEBUGNAME("EV_FALL_FAR");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) );
		cent->pe.painTime = cg.time;	// don't play a pain sound right after this
		if ( clientNum == cg.predictedPlayerState.clientNum ) {
			// smooth landing z changes
			cg.landChange = -24;
			cg.landTime = cg.time;
		}
		break;

	case EV_STEP_4:
	case EV_STEP_8:
	case EV_STEP_12:
	case EV_STEP_16:		// smooth out step up transitions
		DEBUGNAME("EV_STEP");
	{
		float	oldStep;
		int		delta;
		int		step;

		if ( clientNum != cg.predictedPlayerState.clientNum ) {
			break;
		}
		// if we are interpolating, we don't need to smooth steps
		if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ||
			cg_nopredict.integer || cg_synchronousClients.integer ) {
			break;
		}
		// check for stepping up before a previous step is completed
		delta = cg.time - cg.stepTime;
		if (delta < STEP_TIME) {
			oldStep = cg.stepChange * (STEP_TIME - delta) / STEP_TIME;
		} else {
			oldStep = 0;
		}

		// add this amount
		step = 4 * (event - EV_STEP_4 + 1 );
		cg.stepChange = oldStep + step;
		if ( cg.stepChange > MAX_STEP_CHANGE ) {
			cg.stepChange = MAX_STEP_CHANGE;
		}
		cg.stepTime = cg.time;
		break;
	}

	case EV_JUMP_PAD:
		DEBUGNAME("EV_JUMP_PAD");
//		CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm );
		{
			localEntity_t	*smoke;
			vec3_t			up = {0, 0, 1};


			smoke = CG_SmokePuff( cent->lerpOrigin, up, 
						  32, 
						  1, 1, 1, 0.33f,
						  1000, 
						  cg.time, 0,
						  LEF_PUFF_DONT_SCALE, 
						  cgs.media.smokePuffShader );
		}

		// boing sound at origin, jump sound on player
		trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound );
		trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
		break;

	case EV_JUMP:
		DEBUGNAME("EV_JUMP");
		trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
		break;
	case EV_TAUNT:
		DEBUGNAME("EV_TAUNT");
		trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) );
		break;
#ifdef MISSIONPACK
	case EV_TAUNT_YES:
		DEBUGNAME("EV_TAUNT_YES");
		CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_YES);
		break;
	case EV_TAUNT_NO:
		DEBUGNAME("EV_TAUNT_NO");
		CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_NO);
		break;
	case EV_TAUNT_FOLLOWME:
		DEBUGNAME("EV_TAUNT_FOLLOWME");
		CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_FOLLOWME);
		break;
	case EV_TAUNT_GETFLAG:
		DEBUGNAME("EV_TAUNT_GETFLAG");
		CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONGETFLAG);
		break;
	case EV_TAUNT_GUARDBASE:
		DEBUGNAME("EV_TAUNT_GUARDBASE");
		CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONDEFENSE);
		break;
	case EV_TAUNT_PATROL:
		DEBUGNAME("EV_TAUNT_PATROL");
		CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONPATROL);
		break;
#endif
	case EV_WATER_TOUCH:
		DEBUGNAME("EV_WATER_TOUCH");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound );
		break;
	case EV_WATER_LEAVE:
		DEBUGNAME("EV_WATER_LEAVE");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound );
		break;
	case EV_WATER_UNDER:
		DEBUGNAME("EV_WATER_UNDER");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound );
		break;
	case EV_WATER_CLEAR:
		DEBUGNAME("EV_WATER_CLEAR");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) );
		break;

	case EV_ITEM_PICKUP:
		DEBUGNAME("EV_ITEM_PICKUP");
		{
			gitem_t	*item;
			int		index;

			index = es->eventParm;		// player predicted

			if ( index < 1 || index >= bg_numItems ) {
				break;
			}
			item = &bg_itemlist[ index ];

			// powerups and team items will have a separate global sound, this one
			// will be played at prediction time
			if ( item->giType == IT_POWERUP || item->giType == IT_TEAM) {
				trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.n_healthSound );
			} else if (item->giType == IT_PERSISTANT_POWERUP) {
#ifdef MISSIONPACK
				switch (item->giTag ) {
					case PW_SCOUT:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.scoutSound );
					break;
					case PW_GUARD:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.guardSound );
					break;
					case PW_DOUBLER:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.doublerSound );
					break;
					case PW_AMMOREGEN:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.ammoregenSound );
					break;
				}
#endif
			} else {
				trap_S_StartSound (NULL, es->number, CHAN_AUTO,	trap_S_RegisterSound( item->pickup_sound, qfalse ) );
			}

			// show icon and name on status bar
			if ( es->number == cg.snap->ps.clientNum ) {
				CG_ItemPickup( index );
			}
		}
		break;

	case EV_GLOBAL_ITEM_PICKUP:
		DEBUGNAME("EV_GLOBAL_ITEM_PICKUP");
		{
			gitem_t	*item;
			int		index;

			index = es->eventParm;		// player predicted

			if ( index < 1 || index >= bg_numItems ) {
				break;
			}
			item = &bg_itemlist[ index ];
			// powerup pickups are global
			if( item->pickup_sound ) {
				trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) );
			}

			// show icon and name on status bar
			if ( es->number == cg.snap->ps.clientNum ) {
				CG_ItemPickup( index );
			}
		}
		break;

	//
	// weapon events
	//
	case EV_NOAMMO:
		DEBUGNAME("EV_NOAMMO");
//		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound );
		if ( es->number == cg.snap->ps.clientNum ) {
			CG_OutOfAmmoChange();
		}
		break;
	case EV_CHANGE_WEAPON:
		DEBUGNAME("EV_CHANGE_WEAPON");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound );
		break;
	case EV_FIRE_WEAPON:
		DEBUGNAME("EV_FIRE_WEAPON");
		CG_FireWeapon( cent );
		break;

	case EV_USE_ITEM0:
		DEBUGNAME("EV_USE_ITEM0");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM1:
		DEBUGNAME("EV_USE_ITEM1");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM2:
		DEBUGNAME("EV_USE_ITEM2");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM3:
		DEBUGNAME("EV_USE_ITEM3");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM4:
		DEBUGNAME("EV_USE_ITEM4");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM5:
		DEBUGNAME("EV_USE_ITEM5");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM6:
		DEBUGNAME("EV_USE_ITEM6");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM7:
		DEBUGNAME("EV_USE_ITEM7");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM8:
		DEBUGNAME("EV_USE_ITEM8");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM9:
		DEBUGNAME("EV_USE_ITEM9");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM10:
		DEBUGNAME("EV_USE_ITEM10");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM11:
		DEBUGNAME("EV_USE_ITEM11");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM12:
		DEBUGNAME("EV_USE_ITEM12");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM13:
		DEBUGNAME("EV_USE_ITEM13");
		CG_UseItem( cent );
		break;
	case EV_USE_ITEM14:
		DEBUGNAME("EV_USE_ITEM14");
		CG_UseItem( cent );
		break;

	//=================================================================

	//
	// other events
	//
	case EV_PLAYER_TELEPORT_IN:
		DEBUGNAME("EV_PLAYER_TELEPORT_IN");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound );
		CG_SpawnEffect( position);
		break;

	case EV_PLAYER_TELEPORT_OUT:
		DEBUGNAME("EV_PLAYER_TELEPORT_OUT");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound );
		CG_SpawnEffect(  position);
		break;

	case EV_ITEM_POP:
		DEBUGNAME("EV_ITEM_POP");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
		break;
	case EV_ITEM_RESPAWN:
		DEBUGNAME("EV_ITEM_RESPAWN");
		cent->miscTime = cg.time;	// scale up from this
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
		break;

	case EV_GRENADE_BOUNCE:
		DEBUGNAME("EV_GRENADE_BOUNCE");
		if ( rand() & 1 ) {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound );
		} else {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound );
		}
		break;


	case EV_PROXIMITY_MINE_STICK:
		DEBUGNAME("EV_PROXIMITY_MINE_STICK");
		if( es->eventParm & SURF_FLESH ) {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound );
		} else 	if( es->eventParm & SURF_METALSTEPS ) {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound );
		} else {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound );
		}
		break;

	case EV_PROXIMITY_MINE_TRIGGER:
		DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound );
		break;
	case EV_KAMIKAZE:
		DEBUGNAME("EV_KAMIKAZE");
		CG_KamikazeEffect( cent->lerpOrigin );
		break;
	case EV_OBELISKEXPLODE:
		DEBUGNAME("EV_OBELISKEXPLODE");
		CG_ObeliskExplode( cent->lerpOrigin, es->eventParm );
		break;
	case EV_OBELISKPAIN:
		DEBUGNAME("EV_OBELISKPAIN");
		CG_ObeliskPain( cent->lerpOrigin );
		break;
	case EV_INVUL_IMPACT:
		DEBUGNAME("EV_INVUL_IMPACT");
		CG_InvulnerabilityImpact( cent->lerpOrigin, cent->currentState.angles );
		break;
        case EV_JUICED:
		DEBUGNAME("EV_JUICED");
		CG_InvulnerabilityJuiced( cent->lerpOrigin );
		break;
	case EV_LIGHTNINGBOLT:
		DEBUGNAME("EV_LIGHTNINGBOLT");
		CG_LightningBoltBeam(es->origin2, es->pos.trBase);
		break;
	case EV_SCOREPLUM:
		DEBUGNAME("EV_SCOREPLUM");
		CG_ScorePlum( cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time );
		break;

	//
	// missile impacts
	//
	case EV_MISSILE_HIT:
		DEBUGNAME("EV_MISSILE_HIT");
		ByteToDir( es->eventParm, dir );
		CG_MissileHitPlayer( es->weapon, position, dir, es->otherEntityNum );
		break;

	case EV_MISSILE_MISS:
		DEBUGNAME("EV_MISSILE_MISS");
		ByteToDir( es->eventParm, dir );
		CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT );
		break;

	case EV_MISSILE_MISS_METAL:
		DEBUGNAME("EV_MISSILE_MISS_METAL");
		ByteToDir( es->eventParm, dir );
		CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL );
		break;

	case EV_RAILTRAIL:
		DEBUGNAME("EV_RAILTRAIL");
		cent->currentState.weapon = WP_RAILGUN;
//unlagged - attack prediction #2
		// if the client is us, unlagged is on server-side, and we've got it client-side
		if ( es->clientNum == cg.predictedPlayerState.clientNum && 
				cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 16) ) {
			// do nothing, because it was already predicted
			//Com_Printf("Ignoring rail trail event\n");
		}
		else {
                        if(es->clientNum == cg.snap->ps.clientNum && !cg.renderingThirdPerson)
                        {
                           if(cg_drawGun.integer == 2)
				VectorMA(es->origin2, 8, cg.refdef.viewaxis[1], es->origin2);
                           else if(cg_drawGun.integer == 3)
				VectorMA(es->origin2, 4, cg.refdef.viewaxis[1], es->origin2);
                        }


			// draw a rail trail, because it wasn't predicted
			CG_RailTrail( ci, es->origin2, es->pos.trBase );

			// if the end was on a nomark surface, don't make an explosion
			if ( es->eventParm != 255 ) {
				ByteToDir( es->eventParm, dir );
				CG_MissileHitWall( es->weapon, es->clientNum, position, dir, IMPACTSOUND_DEFAULT );
			}
			//Com_Printf("Non-predicted rail trail\n");
		}
//unlagged - attack prediction #2
		break;

	case EV_BULLET_HIT_WALL:
		DEBUGNAME("EV_BULLET_HIT_WALL");
//unlagged - attack prediction #2
		// if the client is us, unlagged is on server-side, and we've got it client-side
		if ( es->clientNum == cg.predictedPlayerState.clientNum && 
				cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2) ) {
			// do nothing, because it was already predicted
			//Com_Printf("Ignoring bullet event\n");
		}
		else {
			// do the bullet, because it wasn't predicted
			ByteToDir( es->eventParm, dir );
			CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD );
			//Com_Printf("Non-predicted bullet\n");
		}
//unlagged - attack prediction #2
		break;

	case EV_BULLET_HIT_FLESH:
		DEBUGNAME("EV_BULLET_HIT_FLESH");
//unlagged - attack prediction #2
		// if the client is us, unlagged is on server-side, and we've got it client-side
		if ( es->clientNum == cg.predictedPlayerState.clientNum && 
				cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 2) ) {
			// do nothing, because it was already predicted
			//Com_Printf("Ignoring bullet event\n");
		}
		else {
			// do the bullet, because it wasn't predicted
			CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm );
			//Com_Printf("Non-predicted bullet\n");
		}
//unlagged - attack prediction #2
		break;

	case EV_SHOTGUN:
		DEBUGNAME("EV_SHOTGUN");
//unlagged - attack prediction #2
		// if the client is us, unlagged is on server-side, and we've got it client-side
		if ( es->otherEntityNum == cg.predictedPlayerState.clientNum && 
				cgs.delagHitscan && (cg_delag.integer & 1 || cg_delag.integer & 4) ) {
			// do nothing, because it was already predicted
			//Com_Printf("Ignoring shotgun event\n");
		}
		else {
			// do the shotgun pattern, because it wasn't predicted
			CG_ShotgunFire( es );
			//Com_Printf("Non-predicted shotgun pattern\n");
		}
//unlagged - attack prediction #2
		break;

	case EV_GENERAL_SOUND:
		DEBUGNAME("EV_GENERAL_SOUND");
		if ( cgs.gameSounds[ es->eventParm ] ) {
			trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] );
		} else {
			s = CG_ConfigString( CS_SOUNDS + es->eventParm );
			trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) );
		}
		break;

	case EV_GLOBAL_SOUND:	// play from the player's head so it never diminishes
		DEBUGNAME("EV_GLOBAL_SOUND");
		if ( cgs.gameSounds[ es->eventParm ] ) {
			trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] );
		} else {
			s = CG_ConfigString( CS_SOUNDS + es->eventParm );
			trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) );
		}
		break;

	case EV_GLOBAL_TEAM_SOUND:	// play from the player's head so it never diminishes
		{
			DEBUGNAME("EV_GLOBAL_TEAM_SOUND");
			switch( es->eventParm ) {
				case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag
					if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED )
						CG_AddBufferedSound( cgs.media.captureYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.captureOpponentSound );
					break;
				case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag
					if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE )
						CG_AddBufferedSound( cgs.media.captureYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.captureOpponentSound );
					break;
				case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used
					if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED )
						CG_AddBufferedSound( cgs.media.returnYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.returnOpponentSound );
					//
					CG_AddBufferedSound( cgs.media.blueFlagReturnedSound );
					break;
				case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned
					if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE )
						CG_AddBufferedSound( cgs.media.returnYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.returnOpponentSound );
					//
					CG_AddBufferedSound( cgs.media.redFlagReturnedSound );
					break;

				case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag
					// if this player picked up the flag then a sound is played in CG_CheckLocalSounds
					if (cg.snap->ps.powerups[PW_BLUEFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) {
					}
					else {
					if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
//#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF) 
								CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound );
							else
//#endif
						 	CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound );
						}
						else if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
//#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF)
								CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound );
							else
//#endif
 							CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound );
						}
					}
					break;
				case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag
					// if this player picked up the flag then a sound is played in CG_CheckLocalSounds
					if (cg.snap->ps.powerups[PW_REDFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) {
					}
					else {
						if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
//#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF)
								CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound );
							else
//#endif
							CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound );
						}
						else if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
//#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF)
								CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound );
							else
//#endif
							CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound );
						}
					}
					break;
				case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked
					if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
						CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound );
					}
					break;
				case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked
					if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
						CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound );
					}
					break;

				case GTS_REDTEAM_SCORED:
					CG_AddBufferedSound(cgs.media.redScoredSound);
					break;
				case GTS_BLUETEAM_SCORED:
					CG_AddBufferedSound(cgs.media.blueScoredSound);
					break;
				case GTS_REDTEAM_TOOK_LEAD:
					CG_AddBufferedSound(cgs.media.redLeadsSound);
					break;
				case GTS_BLUETEAM_TOOK_LEAD:
					CG_AddBufferedSound(cgs.media.blueLeadsSound);
					break;
				case GTS_TEAMS_ARE_TIED:
					CG_AddBufferedSound( cgs.media.teamsTiedSound );
					break;
				case GTS_KAMIKAZE:
					trap_S_StartLocalSound(cgs.media.kamikazeFarSound, CHAN_ANNOUNCER);
					break;
				default:
					break;
			}
			break;
		}

	case EV_PAIN:
		// local player sounds are triggered in CG_CheckLocalSounds,
		// so ignore events on the player
		DEBUGNAME("EV_PAIN");
		if ( cent->currentState.number != cg.snap->ps.clientNum ) {
			CG_PainEvent( cent, es->eventParm );
		}
		break;

	case EV_DEATH1:
	case EV_DEATH2:
	case EV_DEATH3:
		DEBUGNAME("EV_DEATHx");

		if (CG_WaterLevel(cent) >= 1) {
			trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*drown.wav"));
		} else {
			trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1)));
		}

		break;


	case EV_OBITUARY:
		DEBUGNAME("EV_OBITUARY");
		CG_Obituary( es );
		break;

	//
	// powerup events
	//
	case EV_POWERUP_QUAD:
		DEBUGNAME("EV_POWERUP_QUAD");
		if ( es->number == cg.snap->ps.clientNum ) {
			cg.powerupActive = PW_QUAD;
			cg.powerupTime = cg.time;
		}
		trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.quadSound );
		break;
	case EV_POWERUP_BATTLESUIT:
		DEBUGNAME("EV_POWERUP_BATTLESUIT");
		if ( es->number == cg.snap->ps.clientNum ) {
			cg.powerupActive = PW_BATTLESUIT;
			cg.powerupTime = cg.time;
		}
		trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.protectSound );
		break;
	case EV_POWERUP_REGEN:
		DEBUGNAME("EV_POWERUP_REGEN");
		if ( es->number == cg.snap->ps.clientNum ) {
			cg.powerupActive = PW_REGEN;
			cg.powerupTime = cg.time;
		}
		trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.regenSound );
		break;

	case EV_GIB_PLAYER:
		DEBUGNAME("EV_GIB_PLAYER");
		// don't play gib sound when using the kamikaze because it interferes
		// with the kamikaze sound, downside is that the gib sound will also
		// not be played when someone is gibbed while just carrying the kamikaze
		if ( !(es->eFlags & EF_KAMIKAZE) ) {
			trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound );
		}
		CG_GibPlayer( cent->lerpOrigin );
		break;

	case EV_STOPLOOPINGSOUND:
		DEBUGNAME("EV_STOPLOOPINGSOUND");
		trap_S_StopLoopingSound( es->number );
		es->loopSound = 0;
		break;

	case EV_DEBUG_LINE:
		DEBUGNAME("EV_DEBUG_LINE");
		CG_Beam( cent );
		break;

	default:
		DEBUGNAME("UNKNOWN");
		CG_Error( "Unknown event: %i", event );
		break;
	}

}
Exemple #26
0
/*
=================
UI_SPSkillMenu_Init
=================
*/
static void UI_SPSkillMenu_Init( void ) {
	int		skill;

	memset( &skillMenuInfo, 0, sizeof(skillMenuInfo) );
	skillMenuInfo.menu.fullscreen = qtrue;
	skillMenuInfo.menu.key = UI_SPSkillMenu_Key;

	UI_SPSkillMenu_Cache();

	skillMenuInfo.art_frame.generic_mc.type		= MTYPE_BITMAP;
	skillMenuInfo.art_frame.generic_mc.name		= ART_FRAME;
	skillMenuInfo.art_frame.generic_mc.flags		= QMF_LEFT_JUSTIFY|QMF_INACTIVE;
	skillMenuInfo.art_frame.generic_mc.x			= 142;
	skillMenuInfo.art_frame.generic_mc.y			= 118;
	skillMenuInfo.art_frame.width				= 359;
	skillMenuInfo.art_frame.height				= 256;

	skillMenuInfo.art_banner.generic_mc.type		= MTYPE_BTEXT;
	skillMenuInfo.art_banner.generic_mc.flags		= QMF_CENTER_JUSTIFY;
	skillMenuInfo.art_banner.generic_mc.x			= 320;
	skillMenuInfo.art_banner.generic_mc.y			= 16;
	skillMenuInfo.art_banner.string				= "DIFFICULTY";
	skillMenuInfo.art_banner.color				= color_white;
	skillMenuInfo.art_banner.style				= UI_CENTER;

	skillMenuInfo.item_baby.generic_mc.type		= MTYPE_PTEXT;
	skillMenuInfo.item_baby.generic_mc.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
	skillMenuInfo.item_baby.generic_mc.x			= 320;
	skillMenuInfo.item_baby.generic_mc.y			= 170;
	skillMenuInfo.item_baby.generic_mc.callback	= UI_SPSkillMenu_SkillEvent;
	skillMenuInfo.item_baby.generic_mc.id			= ID_BABY;
	skillMenuInfo.item_baby.string				= "I Can Win";
	skillMenuInfo.item_baby.color				= color_red;
	skillMenuInfo.item_baby.style				= UI_CENTER;

	skillMenuInfo.item_easy.generic_mc.type		= MTYPE_PTEXT;
	skillMenuInfo.item_easy.generic_mc.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
	skillMenuInfo.item_easy.generic_mc.x			= 320;
	skillMenuInfo.item_easy.generic_mc.y			= 198;
	skillMenuInfo.item_easy.generic_mc.callback	= UI_SPSkillMenu_SkillEvent;
	skillMenuInfo.item_easy.generic_mc.id			= ID_EASY;
	skillMenuInfo.item_easy.string				= "Bring It On";
	skillMenuInfo.item_easy.color				= color_red;
	skillMenuInfo.item_easy.style				= UI_CENTER;

	skillMenuInfo.item_medium.generic_mc.type		= MTYPE_PTEXT;
	skillMenuInfo.item_medium.generic_mc.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
	skillMenuInfo.item_medium.generic_mc.x			= 320;
	skillMenuInfo.item_medium.generic_mc.y			= 227;
	skillMenuInfo.item_medium.generic_mc.callback	= UI_SPSkillMenu_SkillEvent;
	skillMenuInfo.item_medium.generic_mc.id		= ID_MEDIUM;
	skillMenuInfo.item_medium.string			= "Hurt Me Plenty";
	skillMenuInfo.item_medium.color				= color_red;
	skillMenuInfo.item_medium.style				= UI_CENTER;

	skillMenuInfo.item_hard.generic_mc.type		= MTYPE_PTEXT;
	skillMenuInfo.item_hard.generic_mc.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
	skillMenuInfo.item_hard.generic_mc.x			= 320;
	skillMenuInfo.item_hard.generic_mc.y			= 255;
	skillMenuInfo.item_hard.generic_mc.callback	= UI_SPSkillMenu_SkillEvent;
	skillMenuInfo.item_hard.generic_mc.id			= ID_HARD;
	skillMenuInfo.item_hard.string				= "Hardcore";
	skillMenuInfo.item_hard.color				= color_red;
	skillMenuInfo.item_hard.style				= UI_CENTER;

	skillMenuInfo.item_nightmare.generic_mc.type		= MTYPE_PTEXT;
	skillMenuInfo.item_nightmare.generic_mc.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
	skillMenuInfo.item_nightmare.generic_mc.x			= 320;
	skillMenuInfo.item_nightmare.generic_mc.y			= 283;
	skillMenuInfo.item_nightmare.generic_mc.callback	= UI_SPSkillMenu_SkillEvent;
	skillMenuInfo.item_nightmare.generic_mc.id			= ID_NIGHTMARE;
	skillMenuInfo.item_nightmare.string				= "NIGHTMARE!";
	skillMenuInfo.item_nightmare.color				= color_red;
	skillMenuInfo.item_nightmare.style				= UI_CENTER;

	skillMenuInfo.item_back.generic_mc.type		= MTYPE_BITMAP;
	skillMenuInfo.item_back.generic_mc.name		= ART_BACK;
	skillMenuInfo.item_back.generic_mc.flags		= QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
	skillMenuInfo.item_back.generic_mc.x			= 0;
	skillMenuInfo.item_back.generic_mc.y			= 480-64;
	skillMenuInfo.item_back.generic_mc.callback	= UI_SPSkillMenu_BackEvent;
	skillMenuInfo.item_back.generic_mc.id			= ID_BACK;
	skillMenuInfo.item_back.width				= 128;
	skillMenuInfo.item_back.height				= 64;
	skillMenuInfo.item_back.focuspic			= ART_BACK_FOCUS;

	skillMenuInfo.art_skillPic.generic_mc.type		= MTYPE_BITMAP;
	skillMenuInfo.art_skillPic.generic_mc.flags	= QMF_LEFT_JUSTIFY|QMF_INACTIVE;
	skillMenuInfo.art_skillPic.generic_mc.x		= 320-64;
	skillMenuInfo.art_skillPic.generic_mc.y		= 368;
	skillMenuInfo.art_skillPic.width			= 128;
	skillMenuInfo.art_skillPic.height			= 96;

	skillMenuInfo.item_fight.generic_mc.type		= MTYPE_BITMAP;
	skillMenuInfo.item_fight.generic_mc.name		= ART_FIGHT;
	skillMenuInfo.item_fight.generic_mc.flags		= QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
	skillMenuInfo.item_fight.generic_mc.callback	= UI_SPSkillMenu_FightEvent;
	skillMenuInfo.item_fight.generic_mc.id			= ID_FIGHT;
	skillMenuInfo.item_fight.generic_mc.x			= 640;
	skillMenuInfo.item_fight.generic_mc.y			= 480-64;
	skillMenuInfo.item_fight.width				= 128;
	skillMenuInfo.item_fight.height				= 64;
	skillMenuInfo.item_fight.focuspic			= ART_FIGHT_FOCUS;

	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_frame );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_banner );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_baby );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_easy );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_medium );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_hard );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_nightmare );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_skillPic );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_back );
	Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_fight );

	skill = (int)Com_Clamp( 1, 5, trap_Cvar_VariableValue( "g_spSkill" ) );
	SetSkillColor( skill, color_white );
	skillMenuInfo.art_skillPic.shader = skillMenuInfo.skillpics[skill - 1];
	if( skill == 5 ) {
		trap_S_StartLocalSound( skillMenuInfo.nightmareSound, CHAN_ANNOUNCER );
	}
}
void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) {
	refdef_t refdef;
	refEntity_t legs = {0};
	refEntity_t torso = {0};
	refEntity_t head = {0};
	refEntity_t gun = {0};
	refEntity_t backpack = {0};
	refEntity_t helmet = {0};
//	refEntity_t		barrel = {0};
	refEntity_t flash = {0};
	vec3_t origin;
	int renderfx;
	vec3_t mins = {-16, -16, -24};
	vec3_t maxs = {16, 16, 32};
	float len;
	float xx;
	vec4_t hcolor = { 1, 0, 0, 0.5 };
	const char      *torso_anim = NULL, *legs_anim = NULL;

	if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) {
		return;
	}

	dp_realtime = time;

	if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) {
		pi->weapon = pi->pendingWeapon;
		pi->lastWeapon = pi->pendingWeapon;
		pi->pendingWeapon = WP_NUM_WEAPONS;
		pi->weaponTimer = 0;
		if ( pi->currentWeapon != pi->weapon ) {
			trap_S_StartLocalSound( trap_S_RegisterSound( "sound/weapons/change.wav" ), CHAN_LOCAL );
		}
	}

	UI_AdjustFrom640( &x, &y, &w, &h );

	y -= jumpHeight;

	memset( &refdef, 0, sizeof( refdef ) );
	memset( &legs, 0, sizeof( legs ) );
	memset( &torso, 0, sizeof( torso ) );
	memset( &head, 0, sizeof( head ) );

	refdef.rdflags = RDF_NOWORLDMODEL;

	AxisClear( refdef.viewaxis );

	refdef.x = x;
	refdef.y = y;
	refdef.width = w;
	refdef.height = h;

	refdef.fov_x = (int)((float)refdef.width / uiInfo.uiDC.xscale / 640.0f * 90.0f);
	xx = refdef.width / uiInfo.uiDC.xscale / tan( refdef.fov_x / 360 * M_PI );
	refdef.fov_y = atan2( refdef.height / uiInfo.uiDC.yscale, xx );
	refdef.fov_y *= ( 360 / M_PI );

	// calculate distance so the player nearly fills the box
	len = 1.01 * ( maxs[2] - mins[2] );                         // NERVE - SMF - changed from 0.7
	origin[0] = len / tan( DEG2RAD( refdef.fov_x ) * 0.5 );
	origin[1] = 0.5 * ( mins[1] + maxs[1] );
	origin[2] = -0.5 * ( mins[2] + maxs[2] );

	refdef.time = dp_realtime;

	trap_R_SetColor( hcolor );
	trap_R_ClearScene();
	trap_R_SetColor( NULL );

	// get the rotation information
	UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis );

	// get the animation state (after rotation, to allow feet shuffle)
//	UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp,
//		 &torso.oldframe, &torso.frame, &torso.backlerp );

	renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;

	//
	// add the body
	//
	legs.hModel = pi->legsModel;
	legs.customSkin = pi->legsSkin;
	legs.renderfx = renderfx;

	VectorCopy( origin, legs.origin );
	VectorCopy( origin, legs.lightingOrigin );
	VectorCopy( legs.origin, legs.oldorigin );

	WM_getWeaponAnim( &torso_anim, &legs_anim );

	if ( torso_anim ) {
		legs.torsoFrame = UI_GetAnimation( pi, torso_anim );
		legs.oldTorsoFrame = UI_GetAnimation( pi, torso_anim );
	}
	legs.torsoBacklerp = 0; //torso.backlerp;

	if ( legs_anim ) {
		legs.frame = UI_GetAnimation( pi, legs_anim );
		legs.oldframe = UI_GetAnimation( pi, legs_anim );
	}
	legs.backlerp = 0;

	memcpy( legs.torsoAxis, torso.axis, sizeof( torso.axis ) );
	torso = legs;

	trap_R_AddRefEntityToScene( &torso );

	//
	// add the head
	//
	head.hModel = pi->headModel;
	if ( !head.hModel ) {
		return;
	}
	head.customSkin = pi->headSkin;

	VectorCopy( origin, head.lightingOrigin );

	UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head" );

	head.renderfx = renderfx;

	trap_R_AddRefEntityToScene( &head );

	//
	// add the gun
	//
	if ( pi->currentWeapon != WP_NONE ) {
		memset( &gun, 0, sizeof( gun ) );
		gun.hModel = pi->weaponModel;
		VectorCopy( origin, gun.lightingOrigin );
		UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon" );
		gun.renderfx = renderfx;
		trap_R_AddRefEntityToScene( &gun );
	}

	//
	// add muzzle flash
	//
	if ( dp_realtime <= pi->muzzleFlashTime ) {
		if ( pi->flashModel ) {
			memset( &flash, 0, sizeof( flash ) );
			flash.hModel = pi->flashModel;
			VectorCopy( origin, flash.lightingOrigin );
			UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash" );
			flash.renderfx = renderfx;
			trap_R_AddRefEntityToScene( &flash );
		}

		// make a dlight for the flash
		if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) {
			trap_R_AddLightToScene( flash.origin, 200 + ( rand() & 31 ), pi->flashDlightColor[0],
									pi->flashDlightColor[1], pi->flashDlightColor[2], 0 );
		}
	}

	//
	// add the backpack
	//
	if ( pi->backpackModel ) {
		memset( &backpack, 0, sizeof( backpack ) );
		backpack.hModel = pi->backpackModel;
		VectorCopy( origin, backpack.lightingOrigin );
		UI_PositionEntityOnTag( &backpack, &torso, pi->torsoModel, "tag_back" );
		backpack.renderfx = renderfx;
		trap_R_AddRefEntityToScene( &backpack );
	}

	//
	// add the helmet
	//
	if ( pi->helmetModel ) {
		memset( &helmet, 0, sizeof( helmet ) );
		helmet.hModel = pi->helmetModel;
		VectorCopy( origin, helmet.lightingOrigin );
		UI_PositionEntityOnTag( &helmet, &head, pi->headModel, "tag_mouth" );
		helmet.renderfx = renderfx;
		trap_R_AddRefEntityToScene( &helmet );
	}

	//
	// add the chat icon
	//
	if ( pi->chat ) {
		UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) );
	}

	//
	// add an accent light
	//
//	origin[0] -= 100;	// + = behind, - = in front
//	origin[1] += 100;	// + = left, - = right
//	origin[2] += 100;	// + = above, - = below
	trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0, 0 );

	origin[0] -= 100;
	origin[1] -= 100;
	origin[2] -= 100;
	trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0, 0 );

	trap_R_RenderScene( &refdef );
}
/*
==================
CG_CheckLocalSounds
==================
*/
void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
	const char  *s;
	int highScore;

	// hit changes
	if ( ps->persistant[PERS_HITS] > ops->persistant[PERS_HITS] ) {
		trap_S_StartLocalSound( cgs.media.hitSound, CHAN_LOCAL_SOUND );
	} else if ( ps->persistant[PERS_HITS] < ops->persistant[PERS_HITS] ) {
		trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND );
	}

	// health changes of more than -1 should make pain sounds
	if ( ps->stats[STAT_HEALTH] < ops->stats[STAT_HEALTH] - 1 ) {
		if ( ps->stats[STAT_HEALTH] > 0 ) {
			CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH], qfalse );
		}
	}


	// if we are going into the intermission, don't start any voices
	if ( cg.intermissionStarted ) {
		return;
	}

	// reward sounds
	if ( ps->persistant[PERS_REWARD_COUNT] > ops->persistant[PERS_REWARD_COUNT] ) {
		switch ( ps->persistant[PERS_REWARD] ) {
		case REWARD_IMPRESSIVE:
			trap_S_StartLocalSound( cgs.media.impressiveSound, CHAN_ANNOUNCER );
			cg.rewardTime = cg.time;
			cg.rewardShader = cgs.media.medalImpressive;
			cg.rewardCount = ps->persistant[PERS_IMPRESSIVE_COUNT];
			break;
		case REWARD_EXCELLENT:
			trap_S_StartLocalSound( cgs.media.excellentSound, CHAN_ANNOUNCER );
			cg.rewardTime = cg.time;
			cg.rewardShader = cgs.media.medalExcellent;
			cg.rewardCount = ps->persistant[PERS_EXCELLENT_COUNT];
			break;
		case REWARD_DENIED:
			trap_S_StartLocalSound( cgs.media.deniedSound, CHAN_ANNOUNCER );
			break;
		case REWARD_GAUNTLET:
			trap_S_StartLocalSound( cgs.media.humiliationSound, CHAN_ANNOUNCER );
			// if we are the killer and not the killee, show the award
			if ( ps->stats[STAT_HEALTH] ) {
				cg.rewardTime = cg.time;
				cg.rewardShader = cgs.media.medalGauntlet;
				cg.rewardCount = ps->persistant[PERS_GAUNTLET_FRAG_COUNT];
			}
			break;
		default:
			CG_Error( "Bad reward_t" );
		}
	} else {
		// lead changes (only if no reward)
		s = CG_ConfigString( CS_WARMUP );
		if ( !s[0] ) {
			// never play lead changes during warmup
			if ( ps->persistant[PERS_RANK] != ops->persistant[PERS_RANK] ) {
				if ( cgs.gametype >= GT_TEAM ) {
					if ( ps->persistant[PERS_RANK] == 2 ) {
						trap_S_StartLocalSound( cgs.media.teamsTiedSound, CHAN_ANNOUNCER );
					} else if (  ps->persistant[PERS_RANK] == 0 ) {
						trap_S_StartLocalSound( cgs.media.redLeadsSound, CHAN_ANNOUNCER );
					} else if ( ps->persistant[PERS_RANK] == 1 ) {
						trap_S_StartLocalSound( cgs.media.blueLeadsSound, CHAN_ANNOUNCER );
					}
				} else {
					if (  ps->persistant[PERS_RANK] == 0 ) {
						trap_S_StartLocalSound( cgs.media.takenLeadSound, CHAN_ANNOUNCER );
					} else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) {
						trap_S_StartLocalSound( cgs.media.tiedLeadSound, CHAN_ANNOUNCER );
					} else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) {
						trap_S_StartLocalSound( cgs.media.lostLeadSound, CHAN_ANNOUNCER );
					}
				}
			}
		}
	}

	// timelimit warnings
	if ( cgs.timelimit > 0 ) {
		int msec;

		msec = cg.time - cgs.levelStartTime;

		if ( cgs.timelimit > 5 && !( cg.timelimitWarnings & 1 ) && msec > ( cgs.timelimit - 5 ) * 60 * 1000 ) {
			cg.timelimitWarnings |= 1;
			trap_S_StartLocalSound( cgs.media.fiveMinuteSound, CHAN_ANNOUNCER );
		}
		if ( !( cg.timelimitWarnings & 2 ) && msec > ( cgs.timelimit - 1 ) * 60 * 1000 ) {
			cg.timelimitWarnings |= 2;
			trap_S_StartLocalSound( cgs.media.oneMinuteSound, CHAN_ANNOUNCER );
		}
		if ( !( cg.timelimitWarnings & 4 ) && msec > ( cgs.timelimit * 60 + 2 ) * 1000 ) {
			cg.timelimitWarnings |= 4;
			trap_S_StartLocalSound( cgs.media.suddenDeathSound, CHAN_ANNOUNCER );
		}
	}

	// fraglimit warnings
	if ( cgs.fraglimit > 0 && cgs.gametype != GT_CTF ) {
		highScore = cgs.scores1;
		if ( cgs.fraglimit > 3 && !( cg.fraglimitWarnings & 1 ) && highScore == ( cgs.fraglimit - 3 ) ) {
			cg.fraglimitWarnings |= 1;
			trap_S_StartLocalSound( cgs.media.threeFragSound, CHAN_ANNOUNCER );
		}
		if ( cgs.fraglimit > 2 && !( cg.fraglimitWarnings & 2 ) && highScore == ( cgs.fraglimit - 2 ) ) {
			cg.fraglimitWarnings |= 2;
			trap_S_StartLocalSound( cgs.media.twoFragSound, CHAN_ANNOUNCER );
		}
		if ( !( cg.fraglimitWarnings & 4 ) && highScore == ( cgs.fraglimit - 1 ) ) {
			cg.fraglimitWarnings |= 4;
			trap_S_StartLocalSound( cgs.media.oneFragSound, CHAN_ANNOUNCER );
		}
	}
}
Exemple #29
0
void CG_EntityEvent( centity_t *cent, vec3_t position ) {
	entityState_t	*es;
	int				event;
	vec3_t			dir;
	const char		*s;
	int				playerNum;
	playerInfo_t	*pi;
	int				i;

	es = &cent->currentState;
	event = es->event & ~EV_EVENT_BITS;

	if ( cg_debugEvents.integer ) {
		CG_Printf( "ent:%3i  event:%3i ", es->number, event );
	}

	if ( !event ) {
		DEBUGNAME("ZEROEVENT");
		return;
	}

	playerNum = es->playerNum;
	if ( playerNum < 0 || playerNum >= MAX_CLIENTS ) {
		playerNum = 0;
	}
	pi = &cgs.playerinfo[ playerNum ];

	switch ( event ) {
	//
	// movement generated events
	//
	case EV_FOOTSTEP:
		DEBUGNAME("EV_FOOTSTEP");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ pi->footsteps ][rand()&3] );
		}
		break;
	case EV_FOOTSTEP_METAL:
		DEBUGNAME("EV_FOOTSTEP_METAL");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3] );
		}
		break;
	case EV_FOOTSPLASH:
		DEBUGNAME("EV_FOOTSPLASH");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
		}
		break;
	case EV_FOOTWADE:
		DEBUGNAME("EV_FOOTWADE");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
		}
		break;
	case EV_SWIM:
		DEBUGNAME("EV_SWIM");
		if (cg_footsteps.integer) {
			trap_S_StartSound (NULL, es->number, CHAN_BODY, 
				cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
		}
		break;


	case EV_FALL_SHORT:
		DEBUGNAME("EV_FALL_SHORT");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound );
		for (i = 0; i < CG_MaxSplitView(); i++) {
			if ( playerNum == cg.snap->pss[i].playerNum ) {
				// smooth landing z changes
				cg.localPlayers[i].landChange = -8;
				cg.localPlayers[i].landTime = cg.time;
			}
		}
		break;
	case EV_FALL_MEDIUM:
		DEBUGNAME("EV_FALL_MEDIUM");
		// use normal pain sound
		if (cgs.fallDamage) {
			trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) );
		} else {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound );	
		}
		for (i = 0; i < CG_MaxSplitView(); i++) {
			if ( playerNum == cg.snap->pss[i].playerNum ) {
				// smooth landing z changes
				cg.localPlayers[i].landChange = -16;
				cg.localPlayers[i].landTime = cg.time;
			}
		}
		break;
	case EV_FALL_FAR:
		DEBUGNAME("EV_FALL_FAR");
		if (cgs.fallDamage) {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) );
		} else {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound );
		}
		cent->pe.painTime = cg.time;	// don't play a pain sound right after this
		for (i = 0; i < CG_MaxSplitView(); i++) {
			if ( playerNum == cg.snap->pss[i].playerNum ) {
				// smooth landing z changes
				cg.localPlayers[i].landChange = -24;
				cg.localPlayers[i].landTime = cg.time;
			}
		}
		break;

	case EV_STEP_4:
	case EV_STEP_8:
	case EV_STEP_12:
	case EV_STEP_16:		// smooth out step up transitions
		DEBUGNAME("EV_STEP");
	{
		float	oldStep;
		int		delta;
		int		step;
		localPlayer_t *player;
		playerState_t *ps;

		for (i = 0; i < CG_MaxSplitView(); i++) {
			player = &cg.localPlayers[i];
			ps = &cg.snap->pss[i];

			if ( playerNum != ps->playerNum ) {
				continue;
			}

			// if we are interpolating, we don't need to smooth steps
			if ( cg.demoPlayback || (ps->pm_flags & PMF_FOLLOW) ||
				cg_nopredict.integer || cg_synchronousClients.integer ) {
				continue;
			}
			// check for stepping up before a previous step is completed
			delta = cg.time - player->stepTime;
			if (delta < STEP_TIME) {
				oldStep = player->stepChange * (STEP_TIME - delta) / STEP_TIME;
			} else {
				oldStep = 0;
			}

			// add this amount
			step = 4 * (event - EV_STEP_4 + 1 );
			player->stepChange = oldStep + step;
			if ( player->stepChange > MAX_STEP_CHANGE ) {
				player->stepChange = MAX_STEP_CHANGE;
			}
			player->stepTime = cg.time;
		}
		break;
	}

	case EV_JUMP_PAD:
		DEBUGNAME("EV_JUMP_PAD");
//		CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm );
		{
			vec3_t			up = {0, 0, 1};


			CG_SmokePuff( cent->lerpOrigin, up, 
						  32, 
						  1, 1, 1, 0.33f,
						  1000, 
						  cg.time, 0,
						  LEF_PUFF_DONT_SCALE, 
						  cgs.media.smokePuffShader );
		}

		// boing sound at origin, jump sound on player
		trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound );
		trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
		break;

	case EV_JUMP:
		DEBUGNAME("EV_JUMP");
		trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
		break;
	case EV_TAUNT:
		DEBUGNAME("EV_TAUNT");
		trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) );
		break;
#ifdef MISSIONPACK
	case EV_TAUNT_YES:
		DEBUGNAME("EV_TAUNT_YES");
		CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_YES);
		break;
	case EV_TAUNT_NO:
		DEBUGNAME("EV_TAUNT_NO");
		CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_NO);
		break;
	case EV_TAUNT_FOLLOWME:
		DEBUGNAME("EV_TAUNT_FOLLOWME");
		CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_FOLLOWME);
		break;
	case EV_TAUNT_GETFLAG:
		DEBUGNAME("EV_TAUNT_GETFLAG");
		CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONGETFLAG);
		break;
	case EV_TAUNT_GUARDBASE:
		DEBUGNAME("EV_TAUNT_GUARDBASE");
		CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONDEFENSE);
		break;
	case EV_TAUNT_PATROL:
		DEBUGNAME("EV_TAUNT_PATROL");
		CG_VoiceChatLocal(~0, SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONPATROL);
		break;
#endif
	case EV_WATER_TOUCH:
		DEBUGNAME("EV_WATER_TOUCH");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound );
		break;
	case EV_WATER_LEAVE:
		DEBUGNAME("EV_WATER_LEAVE");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound );
		break;
	case EV_WATER_UNDER:
		DEBUGNAME("EV_WATER_UNDER");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound );
		break;
	case EV_WATER_CLEAR:
		DEBUGNAME("EV_WATER_CLEAR");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) );
		break;

	case EV_ITEM_PICKUP:
		DEBUGNAME("EV_ITEM_PICKUP");
		{
			gitem_t	*item;
			int		index;

			index = es->eventParm;		// player predicted

			if ( index < 1 || index >= BG_NumItems() ) {
				break;
			}
			item = BG_ItemForItemNum( index );

			// powerups and team items will have a separate global sound, this one
			// will be played at prediction time
			if ( item->giType == IT_POWERUP || item->giType == IT_TEAM) {
				trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.n_healthSound );
			} else if (item->giType == IT_PERSISTANT_POWERUP) {
#ifdef MISSIONPACK
				switch (item->giTag ) {
					case PW_SCOUT:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.scoutSound );
					break;
					case PW_GUARD:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.guardSound );
					break;
					case PW_DOUBLER:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.doublerSound );
					break;
					case PW_AMMOREGEN:
						trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.ammoregenSound );
					break;
				}
#endif
			} else {
				trap_S_StartSound (NULL, es->number, CHAN_AUTO,	cgs.media.itemPickupSounds[ index ] );
			}

			// show icon and name on status bar
			for (i = 0; i < CG_MaxSplitView(); i++) {
				if ( es->number == cg.snap->pss[i].playerNum ) {
					CG_ItemPickup( i, index );
				}
			}
		}
		break;

	case EV_GLOBAL_ITEM_PICKUP:
		DEBUGNAME("EV_GLOBAL_ITEM_PICKUP");
		{
			int		index;

			index = es->eventParm;		// player predicted

			if ( index < 1 || index >= BG_NumItems() ) {
				break;
			}
			// powerup pickups are global
			trap_S_StartLocalSound( cgs.media.itemPickupSounds[ index ], CHAN_AUTO );

			// show icon and name on status bar
			for (i = 0; i < CG_MaxSplitView(); i++) {
				if ( es->number == cg.snap->pss[i].playerNum ) {
					CG_ItemPickup( i, index );
				}
			}
		}
		break;

	//
	// weapon events
	//
	case EV_NOAMMO:
		DEBUGNAME("EV_NOAMMO");
//		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound );
		for (i = 0; i < CG_MaxSplitView(); i++) {
			if ( es->number == cg.snap->pss[i].playerNum ) {
				CG_OutOfAmmoChange(i);
			}
		}
		break;
	case EV_CHANGE_WEAPON:
		DEBUGNAME("EV_CHANGE_WEAPON");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound );
		break;
	case EV_FIRE_WEAPON:
		DEBUGNAME("EV_FIRE_WEAPON");
		CG_FireWeapon( cent );
		break;

	case EV_USE_ITEM0:
	case EV_USE_ITEM1:
	case EV_USE_ITEM2:
	case EV_USE_ITEM3:
	case EV_USE_ITEM4:
	case EV_USE_ITEM5:
	case EV_USE_ITEM6:
	case EV_USE_ITEM7:
	case EV_USE_ITEM8:
	case EV_USE_ITEM9:
	case EV_USE_ITEM10:
	case EV_USE_ITEM11:
	case EV_USE_ITEM12:
	case EV_USE_ITEM13:
	case EV_USE_ITEM14:
	case EV_USE_ITEM15:
		DEBUGNAME2("EV_USE_ITEM%d", event - EV_USE_ITEM0);
		CG_UseItem( cent );
		break;

	//=================================================================

	//
	// other events
	//
	case EV_PLAYER_TELEPORT_IN:
		DEBUGNAME("EV_PLAYER_TELEPORT_IN");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound );
		CG_SpawnEffect( position);
		break;

	case EV_PLAYER_TELEPORT_OUT:
		DEBUGNAME("EV_PLAYER_TELEPORT_OUT");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound );
		CG_SpawnEffect(  position);
		break;

	case EV_ITEM_POP:
		DEBUGNAME("EV_ITEM_POP");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
		break;
	case EV_ITEM_RESPAWN:
		DEBUGNAME("EV_ITEM_RESPAWN");
		cent->miscTime = cg.time;	// scale up from this
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
		break;

	case EV_GRENADE_BOUNCE:
		DEBUGNAME("EV_GRENADE_BOUNCE");
		if ( rand() & 1 ) {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound );
		} else {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound );
		}
		break;

#ifdef MISSIONPACK
	case EV_PROXIMITY_MINE_STICK:
		DEBUGNAME("EV_PROXIMITY_MINE_STICK");
		if( es->eventParm & SURF_FLESH ) {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound );
		} else 	if( es->eventParm & SURF_METALSTEPS ) {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound );
		} else {
			trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound );
		}
		break;

	case EV_PROXIMITY_MINE_TRIGGER:
		DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER");
		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound );
		break;
	case EV_KAMIKAZE:
		DEBUGNAME("EV_KAMIKAZE");
		CG_KamikazeEffect( cent->lerpOrigin );
		break;
	case EV_OBELISKEXPLODE:
		DEBUGNAME("EV_OBELISKEXPLODE");
		CG_ObeliskExplode( cent->lerpOrigin, es->eventParm );
		break;
	case EV_OBELISKPAIN:
		DEBUGNAME("EV_OBELISKPAIN");
		CG_ObeliskPain( cent->lerpOrigin );
		break;
	case EV_INVUL_IMPACT:
		DEBUGNAME("EV_INVUL_IMPACT");
		CG_InvulnerabilityImpact( cent->lerpOrigin, cent->currentState.angles );
		break;
	case EV_JUICED:
		DEBUGNAME("EV_JUICED");
		CG_InvulnerabilityJuiced( cent->lerpOrigin );
		break;
	case EV_LIGHTNINGBOLT:
		DEBUGNAME("EV_LIGHTNINGBOLT");
		CG_LightningBoltBeam(es->origin2, es->pos.trBase);
		break;
#endif
	case EV_SCOREPLUM:
		DEBUGNAME("EV_SCOREPLUM");
		CG_ScorePlum( cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time );
		break;

	//
	// missile impacts
	//
	case EV_MISSILE_HIT:
		DEBUGNAME("EV_MISSILE_HIT");
		ByteToDir( es->eventParm, dir );
		CG_MissileHitPlayer( es->weapon, position, dir, es->otherEntityNum );
		break;

	case EV_MISSILE_MISS:
		DEBUGNAME("EV_MISSILE_MISS");
		ByteToDir( es->eventParm, dir );
		CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT );
		break;

	case EV_MISSILE_MISS_METAL:
		DEBUGNAME("EV_MISSILE_MISS_METAL");
		ByteToDir( es->eventParm, dir );
		CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL );
		break;

	case EV_RAILTRAIL:
		DEBUGNAME("EV_RAILTRAIL");
		cent->currentState.weapon = WP_RAILGUN;

		if ( es->playerNum >= 0 && es->playerNum < MAX_CLIENTS ) {
			for (i = 0; i < CG_MaxSplitView(); i++) {
				if ( es->playerNum == cg.snap->pss[i].playerNum
					&& !cg.localPlayers[i].renderingThirdPerson)
				{
					if(cg_drawGun[i].integer == 2)
						VectorMA(es->origin2, 8, cg.refdef.viewaxis[1], es->origin2);
					else if(cg_drawGun[i].integer == 3)
						VectorMA(es->origin2, 4, cg.refdef.viewaxis[1], es->origin2);
					break;
				}
			}
		}

		CG_RailTrail(pi, es->origin2, es->pos.trBase);

		// if the end was on a nomark surface, don't make an explosion
		if ( es->eventParm != 255 ) {
			ByteToDir( es->eventParm, dir );
			CG_MissileHitWall( es->weapon, es->playerNum, position, dir, IMPACTSOUND_DEFAULT );
		}
		break;

	case EV_BULLET_HIT_WALL:
		DEBUGNAME("EV_BULLET_HIT_WALL");
		ByteToDir( es->eventParm, dir );
		CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD );
		break;

	case EV_BULLET_HIT_FLESH:
		DEBUGNAME("EV_BULLET_HIT_FLESH");
		CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm );
		break;

	case EV_SHOTGUN:
		DEBUGNAME("EV_SHOTGUN");
		CG_ShotgunFire( es );
		break;

	case EV_GENERAL_SOUND:
		DEBUGNAME("EV_GENERAL_SOUND");
		if ( cgs.gameSounds[ es->eventParm ] ) {
			trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] );
		} else {
			s = CG_ConfigString( CS_SOUNDS + es->eventParm );
			trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) );
		}
		break;

	case EV_GLOBAL_SOUND:	// play as a local sound so it never diminishes
		DEBUGNAME("EV_GLOBAL_SOUND");
		if ( cgs.gameSounds[ es->eventParm ] ) {
			trap_S_StartLocalSound( cgs.gameSounds[ es->eventParm ], CHAN_AUTO );
		} else {
			s = CG_ConfigString( CS_SOUNDS + es->eventParm );
			trap_S_StartLocalSound( CG_CustomSound( es->number, s ), CHAN_AUTO );
		}
		break;

	case EV_GLOBAL_TEAM_SOUND:	// play as a local sound so it never diminishes
		DEBUGNAME("EV_GLOBAL_TEAM_SOUND");
		{
			qboolean blueTeam			= qfalse;
			qboolean redTeam			= qfalse;
			qboolean localHasBlue		= qfalse;
			qboolean localHasRed		= qfalse;
			qboolean localHasNeutral	= qfalse;

			// Check if any local player is on blue/red team or has flags.
			for (i = 0; i < CG_MaxSplitView(); i++) {
				if (cg.snap->playerNums[i] == -1) {
					continue;
				}
				if (cg.snap->pss[i].persistant[PERS_TEAM] == TEAM_BLUE) {
					blueTeam = qtrue;
				}
				if (cg.snap->pss[i].persistant[PERS_TEAM] == TEAM_RED) {
					redTeam = qtrue;
				}

				if (cg.snap->pss[i].powerups[PW_BLUEFLAG]) {
					localHasBlue = qtrue;
				}
				if (cg.snap->pss[i].powerups[PW_REDFLAG]) {
					localHasRed = qtrue;
				}
				if (cg.snap->pss[i].powerups[PW_NEUTRALFLAG]) {
					localHasNeutral = qtrue;
				}
			}

			// ZTM: NOTE: Some of these sounds don't really work with local player on different teams.
			//     New games might want to replace you/enemy sounds with red/blue.
			//     See http://github.com/zturtleman/spearmint/wiki/New-Sounds

			switch( es->eventParm ) {
				case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag
					if ( redTeam )
						CG_AddBufferedSound( cgs.media.captureYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.captureOpponentSound );
					break;
				case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag
					if ( blueTeam )
						CG_AddBufferedSound( cgs.media.captureYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.captureOpponentSound );
					break;
				case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used
					if ( redTeam )
						CG_AddBufferedSound( cgs.media.returnYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.returnOpponentSound );
					//
					CG_AddBufferedSound( cgs.media.blueFlagReturnedSound );
					break;
				case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned
					if ( blueTeam )
						CG_AddBufferedSound( cgs.media.returnYourTeamSound );
					else
						CG_AddBufferedSound( cgs.media.returnOpponentSound );
					//
					CG_AddBufferedSound( cgs.media.redFlagReturnedSound );
					break;

				case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag
					// if this player picked up the flag then a sound is played in CG_CheckLocalSounds
					if (localHasBlue || localHasNeutral) {
					}
					else if (!(redTeam && blueTeam)) {
						if (blueTeam) {
#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF) 
								CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound );
							else
#endif
							CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound );
						}
						else if (redTeam) {
#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF)
								CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound );
							else
#endif
 							CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound );
						}
					} else {
						// ZTM: NOTE: There are local players on both teams, so have no correct sound to play. New games should fix this.
					}
					break;
				case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag
					// if this player picked up the flag then a sound is played in CG_CheckLocalSounds
					if (localHasRed || localHasNeutral) {
					}
					else if (!(redTeam && blueTeam)) {
						if (redTeam) {
#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF)
								CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound );
							else
#endif
							CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound );
						}
						else if (blueTeam) {
#ifdef MISSIONPACK
							if (cgs.gametype == GT_1FCTF)
								CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound );
							else
#endif
							CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound );
						}
					} else {
						// ZTM: NOTE: There are local players on both teams, so have no correct sound to play. New games should fix this.
					}
					break;
#ifdef MISSIONPACK
				// ZTM: NOTE: These are confusing when there are players on both teams (players don't know which base is attacked). New games should fix this.
				case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked
					if (redTeam) {
						CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound );
					}
					break;
				case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked
					if (blueTeam) {
						CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound );
					}
					break;
#endif

				case GTS_REDTEAM_SCORED:
					CG_AddBufferedSound(cgs.media.redScoredSound);
					break;
				case GTS_BLUETEAM_SCORED:
					CG_AddBufferedSound(cgs.media.blueScoredSound);
					break;
				case GTS_REDTEAM_TOOK_LEAD:
					if ( cgs.gametype != GT_TEAM || cg_teamDmLeadAnnouncements.integer ) {
						CG_AddBufferedSound(cgs.media.redLeadsSound);
					}
					break;
				case GTS_BLUETEAM_TOOK_LEAD:
					if ( cgs.gametype != GT_TEAM || cg_teamDmLeadAnnouncements.integer ) {
						CG_AddBufferedSound(cgs.media.blueLeadsSound);
					}
					break;
				case GTS_TEAMS_ARE_TIED:
					if ( cgs.gametype != GT_TEAM || cg_teamDmLeadAnnouncements.integer ) {
						CG_AddBufferedSound( cgs.media.teamsTiedSound );
					}
					break;
#ifdef MISSIONPACK
				case GTS_KAMIKAZE:
					trap_S_StartLocalSound(cgs.media.kamikazeFarSound, CHAN_ANNOUNCER);
					break;
#endif
				default:
					break;
			}
			break;
		}

	case EV_PAIN:
		// local player sounds are triggered in CG_CheckLocalSounds,
		// so ignore events on the player
		DEBUGNAME("EV_PAIN");
		if ( !CG_LocalPlayerState( es->number ) ) {
			CG_PainEvent( cent, es->eventParm );
		}
		break;

	case EV_DEATH1:
	case EV_DEATH2:
	case EV_DEATH3:
		DEBUGNAME2("EV_DEATH%d", event - EV_DEATH1 + 1);

		// check if gibbed
		// eventParm 1 = living player gibbed
		// eventParm 2 = corpse gibbed
		// eventParm 3 = living person gib headshot
		if ( es->eventParm >= 1 ) {
			CG_GibPlayer( cent->lerpOrigin, (es->eventParm == 3) ? qtrue : qfalse );

			if ( cg_blood.integer && cg_gibs.integer ) {
				// don't play gib sound when using the kamikaze because it interferes
				// with the kamikaze sound, downside is that the gib sound will also
				// not be played when someone is gibbed while just carrying the kamikaze
				if ( !(es->eFlags & EF_KAMIKAZE) ) {
					trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound );
				}

				// don't play death sound
				break;
			}

			// don't play death sound if already dead
			if ( es->eventParm == 2 ) {
				break;
			}
		}

		if (CG_WaterLevel(cent) >= 1) {
			trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*drown.wav"));
		} else {
			trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1)));
		}

		break;


	case EV_OBITUARY:
		DEBUGNAME("EV_OBITUARY");
		CG_ParseObituary( es );
		break;

	//
	// powerup events
	//
	case EV_POWERUP_QUAD:
		DEBUGNAME("EV_POWERUP_QUAD");
		for (i = 0; i < CG_MaxSplitView(); i++) {
			if ( es->number == cg.snap->pss[i].playerNum ) {
				cg.localPlayers[i].powerupActive = PW_QUAD;
				cg.localPlayers[i].powerupTime = cg.time;
			}
		}
		trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.quadSound );
		break;
	case EV_POWERUP_BATTLESUIT:
		DEBUGNAME("EV_POWERUP_BATTLESUIT");
		for (i = 0; i < CG_MaxSplitView(); i++) {
			if ( es->number == cg.snap->pss[i].playerNum ) {
				cg.localPlayers[i].powerupActive = PW_BATTLESUIT;
				cg.localPlayers[i].powerupTime = cg.time;
			}
		}
		trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.protectSound );
		break;
	case EV_POWERUP_REGEN:
		DEBUGNAME("EV_POWERUP_REGEN");
		for (i = 0; i < CG_MaxSplitView(); i++) {
			if ( es->number == cg.snap->pss[i].playerNum ) {
				cg.localPlayers[i].powerupActive = PW_REGEN;
				cg.localPlayers[i].powerupTime = cg.time;
			}
		}
		trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.regenSound );
		break;

	case EV_STOPLOOPINGSOUND:
		DEBUGNAME("EV_STOPLOOPINGSOUND");
		trap_S_StopLoopingSound( es->number );
		es->loopSound = 0;
		break;

	case EV_DEBUG_LINE:
		DEBUGNAME("EV_DEBUG_LINE");
		CG_Beam( cent );
		break;

	default:
		DEBUGNAME("UNKNOWN");
		CG_Error( "Unknown event: %i", event );
		break;
	}

}
Exemple #30
0
void CG_EntityEvent(centity_t *cent, vec3_t position) {
    entityState_t *es;
    int event;
    vec3_t dir;
    const char *s;
    int clientNum;
    clientInfo_t *ci;
    es = &cent->currentState;
    event = es->event & ~EV_EVENT_BITS;

    if (cg_debugEvents.integer) {
        CG_Printf("ent:%3i  event:%3i ", es->number, event);
    }

    if (!event) {
        DEBUGNAME("ZEROEVENT");
        return;
    }

    clientNum = es->clientNum;
    if (clientNum < 0 || clientNum >= MAX_CLIENTS) {
        clientNum = 0;
    }
    ci = &cgs.clientinfo[ clientNum ];

    switch (event) {
    //
    // movement generated events
    //


    case EV_BANDAGE:
        DEBUGNAME("EV_BANDAGE");
        if (clientNum == cg.predictedPlayerState.clientNum) {
            CG_ZoomReset_f();
        }
        trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.bandageSound);
        break;

    case EV_FOOTSTEP:
        DEBUGNAME("EV_FOOTSTEP");
        if (cg_footsteps.integer) {
            trap_S_StartSound(NULL, es->number, CHAN_BODY,
                              cgs.media.footsteps[ ci->footsteps ][rand()&3]);
        }
        break;
    case EV_FOOTSTEP_METAL:
        DEBUGNAME("EV_FOOTSTEP_METAL");
        if (cg_footsteps.integer) {
            trap_S_StartSound(NULL, es->number, CHAN_BODY,
                              cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3]);
        }
        break;
    case EV_FOOTSPLASH:
        DEBUGNAME("EV_FOOTSPLASH");
        if (cg_footsteps.integer) {
            trap_S_StartSound(NULL, es->number, CHAN_BODY,
                              cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3]);
        }
        break;
    case EV_FOOTWADE:
        DEBUGNAME("EV_FOOTWADE");
        if (cg_footsteps.integer) {
            trap_S_StartSound(NULL, es->number, CHAN_BODY,
                              cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3]);
        }
        break;
    case EV_SWIM:
        DEBUGNAME("EV_SWIM");
        if (cg_footsteps.integer) {
            trap_S_StartSound(NULL, es->number, CHAN_BODY,
                              cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3]);
        }
        break;
    case EV_FOOTSTEP_LADDER: //Xamis
        DEBUGNAME("EV_FOOTSTEP_LADDER");
        {
            trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.ladderSound[rand()&3]);
        }
        break;

    case EV_LEDGEGRAB: //Xamis
        DEBUGNAME("EV_LEDGEGRAB");
        {
            trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.ledgeSound);
        }
        break;

    case EV_FALL_SHORT:
        DEBUGNAME("EV_FALL_SHORT");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.landSound);
        if (clientNum == cg.predictedPlayerState.clientNum) {
            // smooth landing z changes
            cg.landChange = -8;
            cg.landTime = cg.time;
        }
        break;
    case EV_FALL_MEDIUM:
        DEBUGNAME("EV_FALL_MEDIUM");
        // use normal pain sound
        trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*pain100_1.wav"));
        if (clientNum == cg.predictedPlayerState.clientNum) {
            // smooth landing z changes
            cg.landChange = -16;
            cg.landTime = cg.time;
        }
        break;
    case EV_FALL_FAR:
        DEBUGNAME("EV_FALL_FAR");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, CG_CustomSound(es->number, "*fall1.wav"));
        cent->pe.painTime = cg.time; // don't play a pain sound right after this
        if (clientNum == cg.predictedPlayerState.clientNum) {
            // smooth landing z changes
            cg.landChange = -32;
            cg.landTime = cg.time;
        }
        break;
    case EV_CURBSTOMP:
        DEBUGNAME("EV_CURBSTOMP");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.stompSound);
        break;
    case EV_STEP_4:
    case EV_STEP_8:
    case EV_STEP_12:
    case EV_STEP_16: // smooth out step up transitions
        DEBUGNAME("EV_STEP");
        {
            float oldStep;
            int delta;
            int step;

            if (clientNum != cg.predictedPlayerState.clientNum) {
                break;
            }
            // if we are interpolating, we don't need to smooth steps
            if (cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ||
                    cg_nopredict.integer || cg_synchronousClients.integer) {
                break;
            }
            // check for stepping up before a previous step is completed
            delta = cg.time - cg.stepTime;
            if (delta < STEP_TIME) {
                oldStep = cg.stepChange * (STEP_TIME - delta) / STEP_TIME;
            } else {
                oldStep = 0;
            }

            // add this amount
            step = 4 * (event - EV_STEP_4 + 1);
            cg.stepChange = oldStep + step;
            if (cg.stepChange > MAX_STEP_CHANGE) {
                cg.stepChange = MAX_STEP_CHANGE;
            }
            cg.stepTime = cg.time;
            break;
        }

    case EV_JUMP_PAD:
        DEBUGNAME("EV_JUMP_PAD");
        //		CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm );
        {
            localEntity_t *smoke;
            vec3_t up = {0, 0, 1};


            smoke = CG_SmokePuff(cent->lerpOrigin, up,
                                 32,
                                 1, 1, 1, 0.33f,
                                 1000,
                                 cg.time, 0,
                                 LEF_PUFF_DONT_SCALE,
                                 cgs.media.smokePuffShader);
        }

        // boing sound at origin, jump sound on player
        trap_S_StartSound(cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound);
        trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*jump1.wav"));
        break;

    case EV_JUMP:
        DEBUGNAME("EV_JUMP");
        //trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); //Xamis
        {
            vec3_t surfNormal, refNormal = {0.0f, 0.0f, 1.0f};
            vec3_t rotAxis;

            if (clientNum != cg.predictedPlayerState.clientNum)
                break;

            //set surfNormal
            VectorCopy(cg.predictedPlayerState.grapplePoint, surfNormal);

            //if we are moving from one surface to another smooth the transition
            if (!VectorCompare(surfNormal, cg.lastNormal) && surfNormal[ 2 ] != 1.0f) {
                CrossProduct(refNormal, surfNormal, rotAxis);
                VectorNormalize(rotAxis);

                //add the op
                CG_addSmoothOp(rotAxis, 15.0f, 1.0f);
            }

            //copy the current normal to the lastNormal
            VectorCopy(surfNormal, cg.lastNormal);
        }
        break;
    case EV_BLEED:
        DEBUGNAME("EV_BLEED");
        CG_CreateBleeder(es->pos.trBase, 10, cent->currentState.clientNum);
        //     CG_PlayerBleed(cent->currentState.clientNum, 10, es->pos.trBase, dir );
        break;
    case EV_WALLJUMP:
        DEBUGNAME("EV_WALLJUMP")
        break;
    case EV_TAUNT:
        DEBUGNAME("EV_TAUNT");
        trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*taunt.wav"));
        break;
#ifdef MISSIONPACK
    case EV_TAUNT_YES:
        DEBUGNAME("EV_TAUNT_YES");
        CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_YES);
        break;
    case EV_TAUNT_NO:
        DEBUGNAME("EV_TAUNT_NO");
        CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_NO);
        break;
    case EV_TAUNT_FOLLOWME:
        DEBUGNAME("EV_TAUNT_FOLLOWME");
        CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_FOLLOWME);
        break;
    case EV_TAUNT_GETFLAG:
        DEBUGNAME("EV_TAUNT_GETFLAG");
        CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONGETFLAG);
        break;
    case EV_TAUNT_GUARDBASE:
        DEBUGNAME("EV_TAUNT_GUARDBASE");
        CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONDEFENSE);
        break;
    case EV_TAUNT_PATROL:
        DEBUGNAME("EV_TAUNT_PATROL");
        CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONPATROL);
        break;
#endif
    case EV_WATER_TOUCH:
        DEBUGNAME("EV_WATER_TOUCH");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrInSound);
        break;
    case EV_WATER_LEAVE:
        DEBUGNAME("EV_WATER_LEAVE");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound);
        break;
    case EV_WATER_UNDER:
        DEBUGNAME("EV_WATER_UNDER");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound);
        break;
    case EV_WATER_CLEAR:
        DEBUGNAME("EV_WATER_CLEAR");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, CG_CustomSound(es->number, "*gasp.wav"));
        break;

    case EV_ITEM_PICKUP:
        DEBUGNAME("EV_ITEM_PICKUP");
        {
            gitem_t *item;
            int index;

            index = es->eventParm; // player predicted

            if (index < 1 || index >= bg_numItems) {
                break;
            }
            item = &bg_itemlist[ index ];
            //  trap_S_StartSound (NULL, es->number, CHAN_AUTO,	trap_S_RegisterSound( item->pickup_sound, qfalse ) );
            //Disable sounds for powerup -- Xamis
            // powerups and team items will have a separate global sound, this one
            // will be played at prediction time
            if (item->giType == IT_POWERUP || item->giType == IT_TEAM) {

                //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound );
            } else {
                trap_S_StartSound(NULL, es->number, CHAN_AUTO, trap_S_RegisterSound(item->pickup_sound, qfalse));
            }

            // show icon and name on status bar
            if (es->number == cg.snap->ps.clientNum) {
                CG_ItemPickup(index);
            }
        }
        break;

    case EV_GLOBAL_ITEM_PICKUP:
        DEBUGNAME("EV_GLOBAL_ITEM_PICKUP");
        {
            gitem_t *item;
            int index;

            index = es->eventParm; // player predicted

            if (index < 1 || index >= bg_numItems) {
                break;
            }
            item = &bg_itemlist[ index ];

            // powerup pickups are global
            if (item->pickup_sound) {
                trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, trap_S_RegisterSound(item->pickup_sound, qfalse));
            }

            // show icon and name on status bar
            if (es->number == cg.snap->ps.clientNum) {
                CG_ItemPickup(index);
            }
        }
        break;

    //
    // weapon events
    //
    case EV_NOAMMO:
        DEBUGNAME("EV_NOAMMO");
        //		trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound );
        if (es->number == cg.snap->ps.clientNum) {
            trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.noammoSound);
        }
        break;

    case EV_NONADES:
        DEBUGNAME("EV_NONADES");
        if (clientNum == cg.predictedPlayerState.clientNum) {
            CG_WeaponSort();
        }
        break;
    case EV_POWERSLIDE:
        CG_HasteTrail(cent);

        break;
    case EV_CHANGE_WEAPON:
        DEBUGNAME("EV_CHANGE_WEAPON");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.selectSound);
        break;

    case EV_WEAPON_DROPPED:
        DEBUGNAME("EV_WEAPON_DROPPED");
        if (clientNum == cg.predictedPlayerState.clientNum) {
            //CG_Printf("EV_WEAPON_DROPPED\n");
            CG_WeaponSort();
        }
        break;
    case EV_FIRE_WEAPON:
        DEBUGNAME("EV_FIRE_WEAPON");
        CG_FireWeapon(cent);
        break;
    case EV_ZOOM_RESET:
        if (clientNum == cg.predictedPlayerState.clientNum) {
            CG_ZoomReset_f();
        }
        break;

    case EV_EJECT_CASING:
    {
        entityState_t *ent;
        weaponInfo_t *weap;
        ent = &cent->currentState;
        weap = &cg_weapons[ ent->weapon ];
        weap->ejectBrassFunc(cent);
        break;
    }
    case EV_USE_ITEM0:
        DEBUGNAME("EV_USE_ITEM0");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM1:
        DEBUGNAME("EV_USE_ITEM1");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM2:
        DEBUGNAME("EV_USE_ITEM2");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM3:
        DEBUGNAME("EV_USE_ITEM3");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM4:
        DEBUGNAME("EV_USE_ITEM4");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM5:
        DEBUGNAME("EV_USE_ITEM5");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM6:
        DEBUGNAME("EV_USE_ITEM6");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM7:
        DEBUGNAME("EV_USE_ITEM7");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM8:
        DEBUGNAME("EV_USE_ITEM8");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM9:
        DEBUGNAME("EV_USE_ITEM9");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM10:
        DEBUGNAME("EV_USE_ITEM10");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM11:
        DEBUGNAME("EV_USE_ITEM11");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM12:
        DEBUGNAME("EV_USE_ITEM12");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM13:
        DEBUGNAME("EV_USE_ITEM13");
        CG_UseItem(cent);
        break;
    case EV_USE_ITEM14:
        DEBUGNAME("EV_USE_ITEM14");
        CG_UseItem(cent);
        break;

    //=================================================================

    //
    // other events
    //
    case EV_PLAYER_TELEPORT_IN:
        DEBUGNAME("EV_PLAYER_TELEPORT_IN");
        //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound ); //disable sound --Xamis
        CG_SpawnEffect(position);
        break;

    case EV_PLAYER_TELEPORT_OUT:
        DEBUGNAME("EV_PLAYER_TELEPORT_OUT");
        //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound );//disable sound --Xamis
        CG_SpawnEffect(position);
        break;

    case EV_ITEM_POP:
        DEBUGNAME("EV_ITEM_POP");
        //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
        break;
    case EV_ITEM_RESPAWN:
        DEBUGNAME("EV_ITEM_RESPAWN");
        cent->miscTime = cg.time; // scale up from this
        //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
        break;

    case EV_GRENADE_BOUNCE:
        DEBUGNAME("EV_GRENADE_BOUNCE");
        if (rand() & 1) {
            trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound);
        } else {
            trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound);
        }
        break;

#ifdef MISSIONPACK
    case EV_PROXIMITY_MINE_STICK:
        DEBUGNAME("EV_PROXIMITY_MINE_STICK");
        if (es->eventParm & SURF_FLESH) {
            trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound);
        } else if (es->eventParm & SURF_METALSTEPS) {
            trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound);
        } else {
            trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound);
        }
        break;

    case EV_PROXIMITY_MINE_TRIGGER:
        DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER");
        trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound);
        break;
    case EV_KAMIKAZE:
        DEBUGNAME("EV_KAMIKAZE");
        CG_KamikazeEffect(cent->lerpOrigin);
        break;
    case EV_OBELISKEXPLODE:
        DEBUGNAME("EV_OBELISKEXPLODE");
        CG_ObeliskExplode(cent->lerpOrigin, es->eventParm);
        break;
    case EV_OBELISKPAIN:
        DEBUGNAME("EV_OBELISKPAIN");
        CG_ObeliskPain(cent->lerpOrigin);
        break;
    case EV_INVUL_IMPACT:
        DEBUGNAME("EV_INVUL_IMPACT");
        CG_InvulnerabilityImpact(cent->lerpOrigin, cent->currentState.angles);
        break;
    case EV_JUICED:
        DEBUGNAME("EV_JUICED");
        CG_InvulnerabilityJuiced(cent->lerpOrigin);
        break;
    case EV_LIGHTNINGBOLT:
        DEBUGNAME("EV_LIGHTNINGBOLT");
        CG_LightningBoltBeam(es->origin2, es->pos.trBase);
        break;
#endif
    case EV_SCOREPLUM:
        DEBUGNAME("EV_SCOREPLUM");
        CG_ScorePlum(cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time);
        break;

    //
    // missile impacts
    //
    case EV_MISSILE_HIT:
        DEBUGNAME("EV_MISSILE_HIT");
        ByteToDir(es->eventParm, dir);
        CG_MissileHitPlayer(es->weapon, position, dir, es->otherEntityNum);
        break;

    case EV_MISSILE_MISS:
        DEBUGNAME("EV_MISSILE_MISS");
        ByteToDir(es->eventParm, dir);
        CG_MissileHitWall(es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT);
        break;

    case EV_MISSILE_MISS_METAL:
        DEBUGNAME("EV_MISSILE_MISS_METAL");
        ByteToDir(es->eventParm, dir);
        CG_MissileHitWall(es->weapon, 0, position, dir, IMPACTSOUND_METAL);
        break;

    case EV_BULLET_HIT_WALL:
        DEBUGNAME("EV_BULLET_HIT_WALL");
        ByteToDir(es->eventParm, dir);
        CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD);
        break;

    case EV_BULLET_HIT_FLESH:
        DEBUGNAME("EV_BULLET_HIT_FLESH");
        CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm);
        break;

    case EV_SHOTGUN:
        DEBUGNAME("EV_SHOTGUN");
        CG_ShotgunFire(es);
        break;

    case EV_GAMESTATE:
        trap_Cvar_Set("ui_gamestate", va("%i", es->eventParm));
        break;

    case EV_GENERAL_SOUND:
        DEBUGNAME("EV_GENERAL_SOUND");
        if (cgs.gameSounds[ es->eventParm ]) {
            trap_S_StartSound(NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ]);
        } else {
            s = CG_ConfigString(CS_SOUNDS + es->eventParm);
            trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, s));
        }
        break;

    case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes
        DEBUGNAME("EV_GLOBAL_SOUND");
        if (cgs.gameSounds[ es->eventParm ]) {
            trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ]);
        } else {
            s = CG_ConfigString(CS_SOUNDS + es->eventParm);
            trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound(es->number, s));
        }
        break;

    case EV_GLOBAL_TEAM_SOUND: // play from the player's head so it never diminishes
    {
        DEBUGNAME("EV_GLOBAL_TEAM_SOUND");
        switch (es->eventParm) {
        case GTS_DRAW_ROUND:
            CG_AddBufferedSound(cgs.media.roundDrawSound);
            break;

        case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag
            if (cgs.clientinfo[cg.clientNum].team == TEAM_RED)
                CG_AddBufferedSound(cgs.media.captureYourTeamSound);
            else
                CG_AddBufferedSound(cgs.media.captureOpponentSound);
            break;
        case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag
            if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE)
                CG_AddBufferedSound(cgs.media.captureYourTeamSound);
            else
                CG_AddBufferedSound(cgs.media.captureOpponentSound);
            break;
        case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used
            if (cgs.clientinfo[cg.clientNum].team == TEAM_RED)
                CG_AddBufferedSound(cgs.media.returnYourTeamSound);
            else
                CG_AddBufferedSound(cgs.media.returnOpponentSound);
            //
            CG_AddBufferedSound(cgs.media.blueFlagReturnedSound);
            break;
        case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned
            if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE)
                CG_AddBufferedSound(cgs.media.returnYourTeamSound);
            else
                CG_AddBufferedSound(cgs.media.returnOpponentSound);
            //
            CG_AddBufferedSound(cgs.media.redFlagReturnedSound);
            break;

        case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag
            // if this player picked up the flag then a sound is played in CG_CheckLocalSounds
            if (cg.snap->ps.powerups[PW_BLUEFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) {
            } else {
                if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
#ifdef MISSIONPACK
                    if (cgs.gametype == GT_BOMB)
                        CG_AddBufferedSound(cgs.media.yourTeamTookTheFlagSound);
                    else
#endif
                        CG_AddBufferedSound(cgs.media.enemyTookYourFlagSound);
                } else if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
#ifdef MISSIONPACK
                    if (cgs.gametype == GT_BOMB)
                        CG_AddBufferedSound(cgs.media.enemyTookTheFlagSound);
                    else
#endif
                        CG_AddBufferedSound(cgs.media.yourTeamTookEnemyFlagSound);
                }
            }
            break;
        case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag
            // if this player picked up the flag then a sound is played in CG_CheckLocalSounds
            if (cg.snap->ps.powerups[PW_REDFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) {
            } else {
                if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
#ifdef MISSIONPACK
                    if (cgs.gametype == GT_BOMB)
                        CG_AddBufferedSound(cgs.media.yourTeamTookTheFlagSound);
                    else
#endif
                        CG_AddBufferedSound(cgs.media.enemyTookYourFlagSound);
                } else if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
#ifdef MISSIONPACK
                    if (cgs.gametype == GT_BOMB)
                        CG_AddBufferedSound(cgs.media.enemyTookTheFlagSound);
                    else
#endif
                        CG_AddBufferedSound(cgs.media.yourTeamTookEnemyFlagSound);
                }
            }
            break;
        case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked
            if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
                CG_AddBufferedSound(cgs.media.yourBaseIsUnderAttackSound);
            }
            break;
        case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked
            if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
                CG_AddBufferedSound(cgs.media.yourBaseIsUnderAttackSound);
            }
            break;

        case GTS_REDTEAM_SCORED:
            CG_AddBufferedSound(cgs.media.redScoredSound);
            break;
        case GTS_BLUETEAM_SCORED:
            CG_AddBufferedSound(cgs.media.blueScoredSound);
            break;
        case GTS_REDTEAM_TOOK_LEAD:
            CG_AddBufferedSound(cgs.media.redLeadsSound);
            break;
        case GTS_BLUETEAM_TOOK_LEAD:
            CG_AddBufferedSound(cgs.media.blueLeadsSound);
            break;
        case GTS_TEAMS_ARE_TIED:
            CG_AddBufferedSound(cgs.media.teamsTiedSound);
            break;
#ifdef MISSIONPACK
        case GTS_KAMIKAZE:
            trap_S_StartLocalSound(cgs.media.kamikazeFarSound, CHAN_ANNOUNCER);
            break;
#endif
        default:
            break;
        }
        break;
    }

    case EV_PAIN:
        // local player sounds are triggered in CG_CheckLocalSounds,
        // so ignore events on the player
        DEBUGNAME("EV_PAIN");
        if (cent->currentState.number != cg.snap->ps.clientNum) {
            CG_PainEvent(cent, es->eventParm);
        }
        break;

    case EV_DEATH1:
    case EV_DEATH2:
    case EV_DEATH3:
        DEBUGNAME("EV_DEATHx");
        if (clientNum == cg.predictedPlayerState.clientNum) {
            CG_ZoomReset_f();
        }
        trap_S_StartSound(NULL, es->number, CHAN_VOICE,
                          CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1)));
        break;


    case EV_OBITUARY:
        DEBUGNAME("EV_OBITUARY");
        CG_Obituary(es);
        break;

    //
    // powerup events
    //
    case EV_GIB_PLAYER:
        DEBUGNAME("EV_GIB_PLAYER");
        // don't play gib sound when using the kamikaze because it interferes
        // with the kamikaze sound, downside is that the gib sound will also
        // not be played when someone is gibbed while just carrying the kamikaze
        if (!(es->eFlags & EF_KAMIKAZE)) {
            trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.gibSound);
        }
        CG_GibPlayer(cent->lerpOrigin);
        break;
    //Xamis
    case EV_BREAK_GLASS:
        DEBUGNAME("EV_BREAK_GLASS");
        trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.glassSound);
        CG_BreakGlass(cent->lerpOrigin);
        break;

    case EV_STOPLOOPINGSOUND:
        DEBUGNAME("EV_STOPLOOPINGSOUND");
        trap_S_StopLoopingSound(es->number);
        es->loopSound = 0;
        break;

    case EV_DEBUG_LINE:
        DEBUGNAME("EV_DEBUG_LINE");
        CG_Beam(cent);
        break;

    default:
        DEBUGNAME("UNKNOWN");
        CG_Error("Unknown event: %i", event);
        break;
    }

}