~ubuntu-branches/ubuntu/precise/openarena/precise

« back to all changes in this revision

Viewing changes to code/cgame/cg_event.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno "Fuddl" Kleinert
  • Date: 2007-01-20 12:28:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070120122809-2yza5ojt7nqiyiam
Tags: upstream-0.6.0
ImportĀ upstreamĀ versionĀ 0.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
===========================================================================
 
3
Copyright (C) 1999-2005 Id Software, Inc.
 
4
 
 
5
This file is part of Quake III Arena source code.
 
6
 
 
7
Quake III Arena source code is free software; you can redistribute it
 
8
and/or modify it under the terms of the GNU General Public License as
 
9
published by the Free Software Foundation; either version 2 of the License,
 
10
or (at your option) any later version.
 
11
 
 
12
Quake III Arena source code is distributed in the hope that it will be
 
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with Quake III Arena source code; if not, write to the Free Software
 
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
20
===========================================================================
 
21
*/
 
22
//
 
23
// cg_event.c -- handle entity events at snapshot or playerstate transitions
 
24
 
 
25
#include "cg_local.h"
 
26
 
 
27
// for the voice chats
 
28
#ifdef MISSIONPACK // bk001205
 
29
#include "../../ui/menudef.h"
 
30
#endif
 
31
//==========================================================================
 
32
 
 
33
/*
 
34
===================
 
35
CG_PlaceString
 
36
 
 
37
Also called by scoreboard drawing
 
38
===================
 
39
*/
 
40
const char      *CG_PlaceString( int rank ) {
 
41
        static char     str[64];
 
42
        char    *s, *t;
 
43
 
 
44
        if ( rank & RANK_TIED_FLAG ) {
 
45
                rank &= ~RANK_TIED_FLAG;
 
46
                t = "Tied for ";
 
47
        } else {
 
48
                t = "";
 
49
        }
 
50
 
 
51
        if ( rank == 1 ) {
 
52
                s = S_COLOR_BLUE "1st" S_COLOR_WHITE;           // draw in blue
 
53
        } else if ( rank == 2 ) {
 
54
                s = S_COLOR_RED "2nd" S_COLOR_WHITE;            // draw in red
 
55
        } else if ( rank == 3 ) {
 
56
                s = S_COLOR_YELLOW "3rd" S_COLOR_WHITE;         // draw in yellow
 
57
        } else if ( rank == 11 ) {
 
58
                s = "11th";
 
59
        } else if ( rank == 12 ) {
 
60
                s = "12th";
 
61
        } else if ( rank == 13 ) {
 
62
                s = "13th";
 
63
        } else if ( rank % 10 == 1 ) {
 
64
                s = va("%ist", rank);
 
65
        } else if ( rank % 10 == 2 ) {
 
66
                s = va("%ind", rank);
 
67
        } else if ( rank % 10 == 3 ) {
 
68
                s = va("%ird", rank);
 
69
        } else {
 
70
                s = va("%ith", rank);
 
71
        }
 
72
 
 
73
        Com_sprintf( str, sizeof( str ), "%s%s", t, s );
 
74
        return str;
 
75
}
 
76
 
 
77
/*
 
78
=============
 
79
CG_Obituary
 
80
=============
 
81
*/
 
82
static void CG_Obituary( entityState_t *ent ) {
 
83
        int                     mod;
 
84
        int                     target, attacker;
 
85
        char            *message;
 
86
        char            *message2;
 
87
        const char      *targetInfo;
 
88
        const char      *attackerInfo;
 
89
        char            targetName[32];
 
90
        char            attackerName[32];
 
91
        gender_t        gender;
 
92
        clientInfo_t    *ci;
 
93
 
 
94
        target = ent->otherEntityNum;
 
95
        attacker = ent->otherEntityNum2;
 
96
        mod = ent->eventParm;
 
97
 
 
98
        if ( target < 0 || target >= MAX_CLIENTS ) {
 
99
                CG_Error( "CG_Obituary: target out of range" );
 
100
        }
 
101
        ci = &cgs.clientinfo[target];
 
102
 
 
103
        if ( attacker < 0 || attacker >= MAX_CLIENTS ) {
 
104
                attacker = ENTITYNUM_WORLD;
 
105
                attackerInfo = NULL;
 
106
        } else {
 
107
                attackerInfo = CG_ConfigString( CS_PLAYERS + attacker );
 
108
        }
 
109
 
 
110
        targetInfo = CG_ConfigString( CS_PLAYERS + target );
 
111
        if ( !targetInfo ) {
 
112
                return;
 
113
        }
 
114
        Q_strncpyz( targetName, Info_ValueForKey( targetInfo, "n" ), sizeof(targetName) - 2);
 
115
        strcat( targetName, S_COLOR_WHITE );
 
116
 
 
117
        message2 = "";
 
118
 
 
119
        // check for single client messages
 
120
 
 
121
        switch( mod ) {
 
122
        case MOD_SUICIDE:
 
123
                message = "suicides";
 
124
                break;
 
125
        case MOD_FALLING:
 
126
                message = "cratered";
 
127
                break;
 
128
        case MOD_CRUSH:
 
129
                message = "was squished";
 
130
                break;
 
131
        case MOD_WATER:
 
132
                message = "sank like a rock";
 
133
                break;
 
134
        case MOD_SLIME:
 
135
                message = "melted";
 
136
                break;
 
137
        case MOD_LAVA:
 
138
                message = "does a back flip into the lava";
 
139
                break;
 
140
        case MOD_TARGET_LASER:
 
141
                message = "saw the light";
 
142
                break;
 
143
        case MOD_TRIGGER_HURT:
 
144
                message = "was in the wrong place";
 
145
                break;
 
146
        default:
 
147
                message = NULL;
 
148
                break;
 
149
        }
 
150
 
 
151
        if (attacker == target) {
 
152
                gender = ci->gender;
 
153
                switch (mod) {
 
154
#ifdef MISSIONPACK
 
155
                case MOD_KAMIKAZE:
 
156
                        message = "goes out with a bang";
 
157
                        break;
 
158
#endif
 
159
                case MOD_GRENADE_SPLASH:
 
160
                        if ( gender == GENDER_FEMALE )
 
161
                                message = "tripped on her own grenade";
 
162
                        else if ( gender == GENDER_NEUTER )
 
163
                                message = "tripped on its own grenade";
 
164
                        else
 
165
                                message = "tripped on his own grenade";
 
166
                        break;
 
167
                case MOD_ROCKET_SPLASH:
 
168
                        if ( gender == GENDER_FEMALE )
 
169
                                message = "blew herself up";
 
170
                        else if ( gender == GENDER_NEUTER )
 
171
                                message = "blew itself up";
 
172
                        else
 
173
                                message = "blew himself up";
 
174
                        break;
 
175
                case MOD_PLASMA_SPLASH:
 
176
                        if ( gender == GENDER_FEMALE )
 
177
                                message = "melted herself";
 
178
                        else if ( gender == GENDER_NEUTER )
 
179
                                message = "melted itself";
 
180
                        else
 
181
                                message = "melted himself";
 
182
                        break;
 
183
                case MOD_BFG_SPLASH:
 
184
                        message = "should have used a smaller gun";
 
185
                        break;
 
186
#ifdef MISSIONPACK
 
187
                case MOD_PROXIMITY_MINE:
 
188
                        if( gender == GENDER_FEMALE ) {
 
189
                                message = "found her prox mine";
 
190
                        } else if ( gender == GENDER_NEUTER ) {
 
191
                                message = "found it's prox mine";
 
192
                        } else {
 
193
                                message = "found his prox mine";
 
194
                        }
 
195
                        break;
 
196
#endif
 
197
                default:
 
198
                        if ( gender == GENDER_FEMALE )
 
199
                                message = "killed herself";
 
200
                        else if ( gender == GENDER_NEUTER )
 
201
                                message = "killed itself";
 
202
                        else
 
203
                                message = "killed himself";
 
204
                        break;
 
205
                }
 
206
        }
 
207
 
 
208
        if (message) {
 
209
                CG_Printf( "%s %s.\n", targetName, message);
 
210
                return;
 
211
        }
 
212
 
 
213
        // check for kill messages from the current clientNum
 
214
        if ( attacker == cg.snap->ps.clientNum ) {
 
215
                char    *s;
 
216
 
 
217
                if ( cgs.gametype < GT_TEAM ) {
 
218
                        s = va("You fragged %s\n%s place with %i", targetName, 
 
219
                                CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ),
 
220
                                cg.snap->ps.persistant[PERS_SCORE] );
 
221
                } else {
 
222
                        s = va("You fragged %s", targetName );
 
223
                }
 
224
#ifdef MISSIONPACK
 
225
                if (!(cg_singlePlayerActive.integer && cg_cameraOrbit.integer)) {
 
226
                        CG_CenterPrint( s, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
 
227
                } 
 
228
#else
 
229
                CG_CenterPrint( s, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
 
230
#endif
 
231
 
 
232
                // print the text message as well
 
233
        }
 
234
 
 
235
        // check for double client messages
 
236
        if ( !attackerInfo ) {
 
237
                attacker = ENTITYNUM_WORLD;
 
238
                strcpy( attackerName, "noname" );
 
239
        } else {
 
240
                Q_strncpyz( attackerName, Info_ValueForKey( attackerInfo, "n" ), sizeof(attackerName) - 2);
 
241
                strcat( attackerName, S_COLOR_WHITE );
 
242
                // check for kill messages about the current clientNum
 
243
                if ( target == cg.snap->ps.clientNum ) {
 
244
                        Q_strncpyz( cg.killerName, attackerName, sizeof( cg.killerName ) );
 
245
                }
 
246
        }
 
247
 
 
248
        if ( attacker != ENTITYNUM_WORLD ) {
 
249
                switch (mod) {
 
250
                case MOD_GRAPPLE:
 
251
                        message = "was caught by";
 
252
                        break;
 
253
                case MOD_GAUNTLET:
 
254
                        message = "was pummeled by";
 
255
                        break;
 
256
                case MOD_MACHINEGUN:
 
257
                        message = "was machinegunned by";
 
258
                        break;
 
259
                case MOD_SHOTGUN:
 
260
                        message = "was gunned down by";
 
261
                        break;
 
262
                case MOD_GRENADE:
 
263
                        message = "ate";
 
264
                        message2 = "'s grenade";
 
265
                        break;
 
266
                case MOD_GRENADE_SPLASH:
 
267
                        message = "was shredded by";
 
268
                        message2 = "'s shrapnel";
 
269
                        break;
 
270
                case MOD_ROCKET:
 
271
                        message = "ate";
 
272
                        message2 = "'s rocket";
 
273
                        break;
 
274
                case MOD_ROCKET_SPLASH:
 
275
                        message = "almost dodged";
 
276
                        message2 = "'s rocket";
 
277
                        break;
 
278
                case MOD_PLASMA:
 
279
                        message = "was melted by";
 
280
                        message2 = "'s plasmagun";
 
281
                        break;
 
282
                case MOD_PLASMA_SPLASH:
 
283
                        message = "was melted by";
 
284
                        message2 = "'s plasmagun";
 
285
                        break;
 
286
                case MOD_RAILGUN:
 
287
                        message = "was railed by";
 
288
                        break;
 
289
                case MOD_LIGHTNING:
 
290
                        message = "was electrocuted by";
 
291
                        break;
 
292
                case MOD_BFG:
 
293
                case MOD_BFG_SPLASH:
 
294
                        message = "was blasted by";
 
295
                        message2 = "'s BFG";
 
296
                        break;
 
297
#ifdef MISSIONPACK
 
298
                case MOD_NAIL:
 
299
                        message = "was nailed by";
 
300
                        break;
 
301
                case MOD_CHAINGUN:
 
302
                        message = "got lead poisoning from";
 
303
                        message2 = "'s Chaingun";
 
304
                        break;
 
305
                case MOD_PROXIMITY_MINE:
 
306
                        message = "was too close to";
 
307
                        message2 = "'s Prox Mine";
 
308
                        break;
 
309
                case MOD_KAMIKAZE:
 
310
                        message = "falls to";
 
311
                        message2 = "'s Kamikaze blast";
 
312
                        break;
 
313
                case MOD_JUICED:
 
314
                        message = "was juiced by";
 
315
                        break;
 
316
#endif
 
317
                case MOD_TELEFRAG:
 
318
                        message = "tried to invade";
 
319
                        message2 = "'s personal space";
 
320
                        break;
 
321
                default:
 
322
                        message = "was killed by";
 
323
                        break;
 
324
                }
 
325
 
 
326
                if (message) {
 
327
                        CG_Printf( "%s %s %s%s\n", 
 
328
                                targetName, message, attackerName, message2);
 
329
                        return;
 
330
                }
 
331
        }
 
332
 
 
333
        // we don't know what it was
 
334
        CG_Printf( "%s died.\n", targetName );
 
335
}
 
336
 
 
337
//==========================================================================
 
338
 
 
339
/*
 
340
===============
 
341
CG_UseItem
 
342
===============
 
343
*/
 
344
static void CG_UseItem( centity_t *cent ) {
 
345
        clientInfo_t *ci;
 
346
        int                     itemNum, clientNum;
 
347
        gitem_t         *item;
 
348
        entityState_t *es;
 
349
 
 
350
        es = &cent->currentState;
 
351
        
 
352
        itemNum = (es->event & ~EV_EVENT_BITS) - EV_USE_ITEM0;
 
353
        if ( itemNum < 0 || itemNum > HI_NUM_HOLDABLE ) {
 
354
                itemNum = 0;
 
355
        }
 
356
 
 
357
        // print a message if the local player
 
358
        if ( es->number == cg.snap->ps.clientNum ) {
 
359
                if ( !itemNum ) {
 
360
                        CG_CenterPrint( "No item to use", SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
 
361
                } else {
 
362
                        item = BG_FindItemForHoldable( itemNum );
 
363
                        CG_CenterPrint( va("Use %s", item->pickup_name), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
 
364
                }
 
365
        }
 
366
 
 
367
        switch ( itemNum ) {
 
368
        default:
 
369
        case HI_NONE:
 
370
                trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.useNothingSound );
 
371
                break;
 
372
 
 
373
        case HI_TELEPORTER:
 
374
                break;
 
375
 
 
376
        case HI_MEDKIT:
 
377
                clientNum = cent->currentState.clientNum;
 
378
                if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) {
 
379
                        ci = &cgs.clientinfo[ clientNum ];
 
380
                        ci->medkitUsageTime = cg.time;
 
381
                }
 
382
                trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.medkitSound );
 
383
                break;
 
384
 
 
385
#ifdef MISSIONPACK
 
386
        case HI_KAMIKAZE:
 
387
                break;
 
388
 
 
389
        case HI_PORTAL:
 
390
                break;
 
391
        case HI_INVULNERABILITY:
 
392
                trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.useInvulnerabilitySound );
 
393
                break;
 
394
#endif
 
395
        }
 
396
 
 
397
}
 
398
 
 
399
/*
 
400
================
 
401
CG_ItemPickup
 
402
 
 
403
A new item was picked up this frame
 
404
================
 
405
*/
 
406
static void CG_ItemPickup( int itemNum ) {
 
407
        cg.itemPickup = itemNum;
 
408
        cg.itemPickupTime = cg.time;
 
409
        cg.itemPickupBlendTime = cg.time;
 
410
        // see if it should be the grabbed weapon
 
411
        if ( bg_itemlist[itemNum].giType == IT_WEAPON ) {
 
412
                // select it immediately
 
413
                if ( cg_autoswitch.integer && bg_itemlist[itemNum].giTag != WP_MACHINEGUN ) {
 
414
                        cg.weaponSelectTime = cg.time;
 
415
                        cg.weaponSelect = bg_itemlist[itemNum].giTag;
 
416
                }
 
417
        }
 
418
 
 
419
}
 
420
 
 
421
 
 
422
/*
 
423
================
 
424
CG_PainEvent
 
425
 
 
426
Also called by playerstate transition
 
427
================
 
428
*/
 
429
void CG_PainEvent( centity_t *cent, int health ) {
 
430
        char    *snd;
 
431
 
 
432
        // don't do more than two pain sounds a second
 
433
        if ( cg.time - cent->pe.painTime < 500 ) {
 
434
                return;
 
435
        }
 
436
 
 
437
        if ( health < 25 ) {
 
438
                snd = "*pain25_1.wav";
 
439
        } else if ( health < 50 ) {
 
440
                snd = "*pain50_1.wav";
 
441
        } else if ( health < 75 ) {
 
442
                snd = "*pain75_1.wav";
 
443
        } else {
 
444
                snd = "*pain100_1.wav";
 
445
        }
 
446
        trap_S_StartSound( NULL, cent->currentState.number, CHAN_VOICE, 
 
447
                CG_CustomSound( cent->currentState.number, snd ) );
 
448
 
 
449
        // save pain time for programitic twitch animation
 
450
        cent->pe.painTime = cg.time;
 
451
        cent->pe.painDirection ^= 1;
 
452
}
 
453
 
 
454
 
 
455
 
 
456
/*
 
457
==============
 
458
CG_EntityEvent
 
459
 
 
460
An entity has an event value
 
461
also called by CG_CheckPlayerstateEvents
 
462
==============
 
463
*/
 
464
#define DEBUGNAME(x) if(cg_debugEvents.integer){CG_Printf(x"\n");}
 
465
void CG_EntityEvent( centity_t *cent, vec3_t position ) {
 
466
        entityState_t   *es;
 
467
        int                             event;
 
468
        vec3_t                  dir;
 
469
        const char              *s;
 
470
        int                             clientNum;
 
471
        clientInfo_t    *ci;
 
472
 
 
473
        es = &cent->currentState;
 
474
        event = es->event & ~EV_EVENT_BITS;
 
475
 
 
476
        if ( cg_debugEvents.integer ) {
 
477
                CG_Printf( "ent:%3i  event:%3i ", es->number, event );
 
478
        }
 
479
 
 
480
        if ( !event ) {
 
481
                DEBUGNAME("ZEROEVENT");
 
482
                return;
 
483
        }
 
484
 
 
485
        clientNum = es->clientNum;
 
486
        if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) {
 
487
                clientNum = 0;
 
488
        }
 
489
        ci = &cgs.clientinfo[ clientNum ];
 
490
 
 
491
        switch ( event ) {
 
492
        //
 
493
        // movement generated events
 
494
        //
 
495
        case EV_FOOTSTEP:
 
496
                DEBUGNAME("EV_FOOTSTEP");
 
497
                if (cg_footsteps.integer) {
 
498
                        trap_S_StartSound (NULL, es->number, CHAN_BODY, 
 
499
                                cgs.media.footsteps[ ci->footsteps ][rand()&3] );
 
500
                }
 
501
                break;
 
502
        case EV_FOOTSTEP_METAL:
 
503
                DEBUGNAME("EV_FOOTSTEP_METAL");
 
504
                if (cg_footsteps.integer) {
 
505
                        trap_S_StartSound (NULL, es->number, CHAN_BODY, 
 
506
                                cgs.media.footsteps[ FOOTSTEP_METAL ][rand()&3] );
 
507
                }
 
508
                break;
 
509
        case EV_FOOTSPLASH:
 
510
                DEBUGNAME("EV_FOOTSPLASH");
 
511
                if (cg_footsteps.integer) {
 
512
                        trap_S_StartSound (NULL, es->number, CHAN_BODY, 
 
513
                                cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
 
514
                }
 
515
                break;
 
516
        case EV_FOOTWADE:
 
517
                DEBUGNAME("EV_FOOTWADE");
 
518
                if (cg_footsteps.integer) {
 
519
                        trap_S_StartSound (NULL, es->number, CHAN_BODY, 
 
520
                                cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
 
521
                }
 
522
                break;
 
523
        case EV_SWIM:
 
524
                DEBUGNAME("EV_SWIM");
 
525
                if (cg_footsteps.integer) {
 
526
                        trap_S_StartSound (NULL, es->number, CHAN_BODY, 
 
527
                                cgs.media.footsteps[ FOOTSTEP_SPLASH ][rand()&3] );
 
528
                }
 
529
                break;
 
530
 
 
531
 
 
532
        case EV_FALL_SHORT:
 
533
                DEBUGNAME("EV_FALL_SHORT");
 
534
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.landSound );
 
535
                if ( clientNum == cg.predictedPlayerState.clientNum ) {
 
536
                        // smooth landing z changes
 
537
                        cg.landChange = -8;
 
538
                        cg.landTime = cg.time;
 
539
                }
 
540
                break;
 
541
        case EV_FALL_MEDIUM:
 
542
                DEBUGNAME("EV_FALL_MEDIUM");
 
543
                // use normal pain sound
 
544
                trap_S_StartSound( NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*pain100_1.wav" ) );
 
545
                if ( clientNum == cg.predictedPlayerState.clientNum ) {
 
546
                        // smooth landing z changes
 
547
                        cg.landChange = -16;
 
548
                        cg.landTime = cg.time;
 
549
                }
 
550
                break;
 
551
        case EV_FALL_FAR:
 
552
                DEBUGNAME("EV_FALL_FAR");
 
553
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*fall1.wav" ) );
 
554
                cent->pe.painTime = cg.time;    // don't play a pain sound right after this
 
555
                if ( clientNum == cg.predictedPlayerState.clientNum ) {
 
556
                        // smooth landing z changes
 
557
                        cg.landChange = -24;
 
558
                        cg.landTime = cg.time;
 
559
                }
 
560
                break;
 
561
 
 
562
        case EV_STEP_4:
 
563
        case EV_STEP_8:
 
564
        case EV_STEP_12:
 
565
        case EV_STEP_16:                // smooth out step up transitions
 
566
                DEBUGNAME("EV_STEP");
 
567
        {
 
568
                float   oldStep;
 
569
                int             delta;
 
570
                int             step;
 
571
 
 
572
                if ( clientNum != cg.predictedPlayerState.clientNum ) {
 
573
                        break;
 
574
                }
 
575
                // if we are interpolating, we don't need to smooth steps
 
576
                if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ||
 
577
                        cg_nopredict.integer || cg_synchronousClients.integer ) {
 
578
                        break;
 
579
                }
 
580
                // check for stepping up before a previous step is completed
 
581
                delta = cg.time - cg.stepTime;
 
582
                if (delta < STEP_TIME) {
 
583
                        oldStep = cg.stepChange * (STEP_TIME - delta) / STEP_TIME;
 
584
                } else {
 
585
                        oldStep = 0;
 
586
                }
 
587
 
 
588
                // add this amount
 
589
                step = 4 * (event - EV_STEP_4 + 1 );
 
590
                cg.stepChange = oldStep + step;
 
591
                if ( cg.stepChange > MAX_STEP_CHANGE ) {
 
592
                        cg.stepChange = MAX_STEP_CHANGE;
 
593
                }
 
594
                cg.stepTime = cg.time;
 
595
                break;
 
596
        }
 
597
 
 
598
        case EV_JUMP_PAD:
 
599
                DEBUGNAME("EV_JUMP_PAD");
 
600
//              CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm );
 
601
                {
 
602
                        localEntity_t   *smoke;
 
603
                        vec3_t                  up = {0, 0, 1};
 
604
 
 
605
 
 
606
                        smoke = CG_SmokePuff( cent->lerpOrigin, up, 
 
607
                                                  32, 
 
608
                                                  1, 1, 1, 0.33f,
 
609
                                                  1000, 
 
610
                                                  cg.time, 0,
 
611
                                                  LEF_PUFF_DONT_SCALE, 
 
612
                                                  cgs.media.smokePuffShader );
 
613
                }
 
614
 
 
615
                // boing sound at origin, jump sound on player
 
616
                trap_S_StartSound ( cent->lerpOrigin, -1, CHAN_VOICE, cgs.media.jumpPadSound );
 
617
                trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
 
618
                break;
 
619
 
 
620
        case EV_JUMP:
 
621
                DEBUGNAME("EV_JUMP");
 
622
                trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
 
623
                break;
 
624
        case EV_TAUNT:
 
625
                DEBUGNAME("EV_TAUNT");
 
626
                trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*taunt.wav" ) );
 
627
                break;
 
628
#ifdef MISSIONPACK
 
629
        case EV_TAUNT_YES:
 
630
                DEBUGNAME("EV_TAUNT_YES");
 
631
                CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_YES);
 
632
                break;
 
633
        case EV_TAUNT_NO:
 
634
                DEBUGNAME("EV_TAUNT_NO");
 
635
                CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_NO);
 
636
                break;
 
637
        case EV_TAUNT_FOLLOWME:
 
638
                DEBUGNAME("EV_TAUNT_FOLLOWME");
 
639
                CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_FOLLOWME);
 
640
                break;
 
641
        case EV_TAUNT_GETFLAG:
 
642
                DEBUGNAME("EV_TAUNT_GETFLAG");
 
643
                CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONGETFLAG);
 
644
                break;
 
645
        case EV_TAUNT_GUARDBASE:
 
646
                DEBUGNAME("EV_TAUNT_GUARDBASE");
 
647
                CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONDEFENSE);
 
648
                break;
 
649
        case EV_TAUNT_PATROL:
 
650
                DEBUGNAME("EV_TAUNT_PATROL");
 
651
                CG_VoiceChatLocal(SAY_TEAM, qfalse, es->number, COLOR_CYAN, VOICECHAT_ONPATROL);
 
652
                break;
 
653
#endif
 
654
        case EV_WATER_TOUCH:
 
655
                DEBUGNAME("EV_WATER_TOUCH");
 
656
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrInSound );
 
657
                break;
 
658
        case EV_WATER_LEAVE:
 
659
                DEBUGNAME("EV_WATER_LEAVE");
 
660
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound );
 
661
                break;
 
662
        case EV_WATER_UNDER:
 
663
                DEBUGNAME("EV_WATER_UNDER");
 
664
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound );
 
665
                break;
 
666
        case EV_WATER_CLEAR:
 
667
                DEBUGNAME("EV_WATER_CLEAR");
 
668
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, CG_CustomSound( es->number, "*gasp.wav" ) );
 
669
                break;
 
670
 
 
671
        case EV_ITEM_PICKUP:
 
672
                DEBUGNAME("EV_ITEM_PICKUP");
 
673
                {
 
674
                        gitem_t *item;
 
675
                        int             index;
 
676
 
 
677
                        index = es->eventParm;          // player predicted
 
678
 
 
679
                        if ( index < 1 || index >= bg_numItems ) {
 
680
                                break;
 
681
                        }
 
682
                        item = &bg_itemlist[ index ];
 
683
 
 
684
                        // powerups and team items will have a separate global sound, this one
 
685
                        // will be played at prediction time
 
686
                        if ( item->giType == IT_POWERUP || item->giType == IT_TEAM) {
 
687
                                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound );
 
688
                        } else if (item->giType == IT_PERSISTANT_POWERUP) {
 
689
#ifdef MISSIONPACK
 
690
                                switch (item->giTag ) {
 
691
                                        case PW_SCOUT:
 
692
                                                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.scoutSound );
 
693
                                        break;
 
694
                                        case PW_GUARD:
 
695
                                                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.guardSound );
 
696
                                        break;
 
697
                                        case PW_DOUBLER:
 
698
                                                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.doublerSound );
 
699
                                        break;
 
700
                                        case PW_AMMOREGEN:
 
701
                                                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.ammoregenSound );
 
702
                                        break;
 
703
                                }
 
704
#endif
 
705
                        } else {
 
706
                                trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) );
 
707
                        }
 
708
 
 
709
                        // show icon and name on status bar
 
710
                        if ( es->number == cg.snap->ps.clientNum ) {
 
711
                                CG_ItemPickup( index );
 
712
                        }
 
713
                }
 
714
                break;
 
715
 
 
716
        case EV_GLOBAL_ITEM_PICKUP:
 
717
                DEBUGNAME("EV_GLOBAL_ITEM_PICKUP");
 
718
                {
 
719
                        gitem_t *item;
 
720
                        int             index;
 
721
 
 
722
                        index = es->eventParm;          // player predicted
 
723
 
 
724
                        if ( index < 1 || index >= bg_numItems ) {
 
725
                                break;
 
726
                        }
 
727
                        item = &bg_itemlist[ index ];
 
728
                        // powerup pickups are global
 
729
                        if( item->pickup_sound ) {
 
730
                                trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) );
 
731
                        }
 
732
 
 
733
                        // show icon and name on status bar
 
734
                        if ( es->number == cg.snap->ps.clientNum ) {
 
735
                                CG_ItemPickup( index );
 
736
                        }
 
737
                }
 
738
                break;
 
739
 
 
740
        //
 
741
        // weapon events
 
742
        //
 
743
        case EV_NOAMMO:
 
744
                DEBUGNAME("EV_NOAMMO");
 
745
//              trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound );
 
746
                if ( es->number == cg.snap->ps.clientNum ) {
 
747
                        CG_OutOfAmmoChange();
 
748
                }
 
749
                break;
 
750
        case EV_CHANGE_WEAPON:
 
751
                DEBUGNAME("EV_CHANGE_WEAPON");
 
752
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound );
 
753
                break;
 
754
        case EV_FIRE_WEAPON:
 
755
                DEBUGNAME("EV_FIRE_WEAPON");
 
756
                CG_FireWeapon( cent );
 
757
                break;
 
758
 
 
759
        case EV_USE_ITEM0:
 
760
                DEBUGNAME("EV_USE_ITEM0");
 
761
                CG_UseItem( cent );
 
762
                break;
 
763
        case EV_USE_ITEM1:
 
764
                DEBUGNAME("EV_USE_ITEM1");
 
765
                CG_UseItem( cent );
 
766
                break;
 
767
        case EV_USE_ITEM2:
 
768
                DEBUGNAME("EV_USE_ITEM2");
 
769
                CG_UseItem( cent );
 
770
                break;
 
771
        case EV_USE_ITEM3:
 
772
                DEBUGNAME("EV_USE_ITEM3");
 
773
                CG_UseItem( cent );
 
774
                break;
 
775
        case EV_USE_ITEM4:
 
776
                DEBUGNAME("EV_USE_ITEM4");
 
777
                CG_UseItem( cent );
 
778
                break;
 
779
        case EV_USE_ITEM5:
 
780
                DEBUGNAME("EV_USE_ITEM5");
 
781
                CG_UseItem( cent );
 
782
                break;
 
783
        case EV_USE_ITEM6:
 
784
                DEBUGNAME("EV_USE_ITEM6");
 
785
                CG_UseItem( cent );
 
786
                break;
 
787
        case EV_USE_ITEM7:
 
788
                DEBUGNAME("EV_USE_ITEM7");
 
789
                CG_UseItem( cent );
 
790
                break;
 
791
        case EV_USE_ITEM8:
 
792
                DEBUGNAME("EV_USE_ITEM8");
 
793
                CG_UseItem( cent );
 
794
                break;
 
795
        case EV_USE_ITEM9:
 
796
                DEBUGNAME("EV_USE_ITEM9");
 
797
                CG_UseItem( cent );
 
798
                break;
 
799
        case EV_USE_ITEM10:
 
800
                DEBUGNAME("EV_USE_ITEM10");
 
801
                CG_UseItem( cent );
 
802
                break;
 
803
        case EV_USE_ITEM11:
 
804
                DEBUGNAME("EV_USE_ITEM11");
 
805
                CG_UseItem( cent );
 
806
                break;
 
807
        case EV_USE_ITEM12:
 
808
                DEBUGNAME("EV_USE_ITEM12");
 
809
                CG_UseItem( cent );
 
810
                break;
 
811
        case EV_USE_ITEM13:
 
812
                DEBUGNAME("EV_USE_ITEM13");
 
813
                CG_UseItem( cent );
 
814
                break;
 
815
        case EV_USE_ITEM14:
 
816
                DEBUGNAME("EV_USE_ITEM14");
 
817
                CG_UseItem( cent );
 
818
                break;
 
819
 
 
820
        //=================================================================
 
821
 
 
822
        //
 
823
        // other events
 
824
        //
 
825
        case EV_PLAYER_TELEPORT_IN:
 
826
                DEBUGNAME("EV_PLAYER_TELEPORT_IN");
 
827
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleInSound );
 
828
                CG_SpawnEffect( position);
 
829
                break;
 
830
 
 
831
        case EV_PLAYER_TELEPORT_OUT:
 
832
                DEBUGNAME("EV_PLAYER_TELEPORT_OUT");
 
833
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound );
 
834
                CG_SpawnEffect(  position);
 
835
                break;
 
836
 
 
837
        case EV_ITEM_POP:
 
838
                DEBUGNAME("EV_ITEM_POP");
 
839
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
 
840
                break;
 
841
        case EV_ITEM_RESPAWN:
 
842
                DEBUGNAME("EV_ITEM_RESPAWN");
 
843
                cent->miscTime = cg.time;       // scale up from this
 
844
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.respawnSound );
 
845
                break;
 
846
 
 
847
        case EV_GRENADE_BOUNCE:
 
848
                DEBUGNAME("EV_GRENADE_BOUNCE");
 
849
                if ( rand() & 1 ) {
 
850
                        trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound );
 
851
                } else {
 
852
                        trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound );
 
853
                }
 
854
                break;
 
855
 
 
856
#ifdef MISSIONPACK
 
857
        case EV_PROXIMITY_MINE_STICK:
 
858
                DEBUGNAME("EV_PROXIMITY_MINE_STICK");
 
859
                if( es->eventParm & SURF_FLESH ) {
 
860
                        trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimplSound );
 
861
                } else  if( es->eventParm & SURF_METALSTEPS ) {
 
862
                        trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpmSound );
 
863
                } else {
 
864
                        trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbimpdSound );
 
865
                }
 
866
                break;
 
867
 
 
868
        case EV_PROXIMITY_MINE_TRIGGER:
 
869
                DEBUGNAME("EV_PROXIMITY_MINE_TRIGGER");
 
870
                trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.wstbactvSound );
 
871
                break;
 
872
        case EV_KAMIKAZE:
 
873
                DEBUGNAME("EV_KAMIKAZE");
 
874
                CG_KamikazeEffect( cent->lerpOrigin );
 
875
                break;
 
876
        case EV_OBELISKEXPLODE:
 
877
                DEBUGNAME("EV_OBELISKEXPLODE");
 
878
                CG_ObeliskExplode( cent->lerpOrigin, es->eventParm );
 
879
                break;
 
880
        case EV_OBELISKPAIN:
 
881
                DEBUGNAME("EV_OBELISKPAIN");
 
882
                CG_ObeliskPain( cent->lerpOrigin );
 
883
                break;
 
884
        case EV_INVUL_IMPACT:
 
885
                DEBUGNAME("EV_INVUL_IMPACT");
 
886
                CG_InvulnerabilityImpact( cent->lerpOrigin, cent->currentState.angles );
 
887
                break;
 
888
        case EV_JUICED:
 
889
                DEBUGNAME("EV_JUICED");
 
890
                CG_InvulnerabilityJuiced( cent->lerpOrigin );
 
891
                break;
 
892
        case EV_LIGHTNINGBOLT:
 
893
                DEBUGNAME("EV_LIGHTNINGBOLT");
 
894
                CG_LightningBoltBeam(es->origin2, es->pos.trBase);
 
895
                break;
 
896
#endif
 
897
        case EV_SCOREPLUM:
 
898
                DEBUGNAME("EV_SCOREPLUM");
 
899
                CG_ScorePlum( cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time );
 
900
                break;
 
901
 
 
902
        //
 
903
        // missile impacts
 
904
        //
 
905
        case EV_MISSILE_HIT:
 
906
                DEBUGNAME("EV_MISSILE_HIT");
 
907
                ByteToDir( es->eventParm, dir );
 
908
                CG_MissileHitPlayer( es->weapon, position, dir, es->otherEntityNum );
 
909
                break;
 
910
 
 
911
        case EV_MISSILE_MISS:
 
912
                DEBUGNAME("EV_MISSILE_MISS");
 
913
                ByteToDir( es->eventParm, dir );
 
914
                CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT );
 
915
                break;
 
916
 
 
917
        case EV_MISSILE_MISS_METAL:
 
918
                DEBUGNAME("EV_MISSILE_MISS_METAL");
 
919
                ByteToDir( es->eventParm, dir );
 
920
                CG_MissileHitWall( es->weapon, 0, position, dir, IMPACTSOUND_METAL );
 
921
                break;
 
922
 
 
923
        case EV_RAILTRAIL:
 
924
                DEBUGNAME("EV_RAILTRAIL");
 
925
                cent->currentState.weapon = WP_RAILGUN;
 
926
                // if the end was on a nomark surface, don't make an explosion
 
927
                CG_RailTrail( ci, es->origin2, es->pos.trBase );
 
928
                if ( es->eventParm != 255 ) {
 
929
                        ByteToDir( es->eventParm, dir );
 
930
                        CG_MissileHitWall( es->weapon, es->clientNum, position, dir, IMPACTSOUND_DEFAULT );
 
931
                }
 
932
                break;
 
933
 
 
934
        case EV_BULLET_HIT_WALL:
 
935
                DEBUGNAME("EV_BULLET_HIT_WALL");
 
936
                ByteToDir( es->eventParm, dir );
 
937
                CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD );
 
938
                break;
 
939
 
 
940
        case EV_BULLET_HIT_FLESH:
 
941
                DEBUGNAME("EV_BULLET_HIT_FLESH");
 
942
                CG_Bullet( es->pos.trBase, es->otherEntityNum, dir, qtrue, es->eventParm );
 
943
                break;
 
944
 
 
945
        case EV_SHOTGUN:
 
946
                DEBUGNAME("EV_SHOTGUN");
 
947
                CG_ShotgunFire( es );
 
948
                break;
 
949
 
 
950
        case EV_GENERAL_SOUND:
 
951
                DEBUGNAME("EV_GENERAL_SOUND");
 
952
                if ( cgs.gameSounds[ es->eventParm ] ) {
 
953
                        trap_S_StartSound (NULL, es->number, CHAN_VOICE, cgs.gameSounds[ es->eventParm ] );
 
954
                } else {
 
955
                        s = CG_ConfigString( CS_SOUNDS + es->eventParm );
 
956
                        trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, s ) );
 
957
                }
 
958
                break;
 
959
 
 
960
        case EV_GLOBAL_SOUND:   // play from the player's head so it never diminishes
 
961
                DEBUGNAME("EV_GLOBAL_SOUND");
 
962
                if ( cgs.gameSounds[ es->eventParm ] ) {
 
963
                        trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[ es->eventParm ] );
 
964
                } else {
 
965
                        s = CG_ConfigString( CS_SOUNDS + es->eventParm );
 
966
                        trap_S_StartSound (NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound( es->number, s ) );
 
967
                }
 
968
                break;
 
969
 
 
970
        case EV_GLOBAL_TEAM_SOUND:      // play from the player's head so it never diminishes
 
971
                {
 
972
                        DEBUGNAME("EV_GLOBAL_TEAM_SOUND");
 
973
                        switch( es->eventParm ) {
 
974
                                case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag
 
975
                                        if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED )
 
976
                                                CG_AddBufferedSound( cgs.media.captureYourTeamSound );
 
977
                                        else
 
978
                                                CG_AddBufferedSound( cgs.media.captureOpponentSound );
 
979
                                        break;
 
980
                                case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag
 
981
                                        if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE )
 
982
                                                CG_AddBufferedSound( cgs.media.captureYourTeamSound );
 
983
                                        else
 
984
                                                CG_AddBufferedSound( cgs.media.captureOpponentSound );
 
985
                                        break;
 
986
                                case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used
 
987
                                        if ( cgs.clientinfo[cg.clientNum].team == TEAM_RED )
 
988
                                                CG_AddBufferedSound( cgs.media.returnYourTeamSound );
 
989
                                        else
 
990
                                                CG_AddBufferedSound( cgs.media.returnOpponentSound );
 
991
                                        //
 
992
                                        CG_AddBufferedSound( cgs.media.blueFlagReturnedSound );
 
993
                                        break;
 
994
                                case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned
 
995
                                        if ( cgs.clientinfo[cg.clientNum].team == TEAM_BLUE )
 
996
                                                CG_AddBufferedSound( cgs.media.returnYourTeamSound );
 
997
                                        else
 
998
                                                CG_AddBufferedSound( cgs.media.returnOpponentSound );
 
999
                                        //
 
1000
                                        CG_AddBufferedSound( cgs.media.redFlagReturnedSound );
 
1001
                                        break;
 
1002
 
 
1003
                                case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag
 
1004
                                        // if this player picked up the flag then a sound is played in CG_CheckLocalSounds
 
1005
                                        if (cg.snap->ps.powerups[PW_BLUEFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) {
 
1006
                                        }
 
1007
                                        else {
 
1008
                                        if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
 
1009
#ifdef MISSIONPACK
 
1010
                                                        if (cgs.gametype == GT_1FCTF) 
 
1011
                                                                CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound );
 
1012
                                                        else
 
1013
#endif
 
1014
                                                        CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound );
 
1015
                                                }
 
1016
                                                else if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
 
1017
#ifdef MISSIONPACK
 
1018
                                                        if (cgs.gametype == GT_1FCTF)
 
1019
                                                                CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound );
 
1020
                                                        else
 
1021
#endif
 
1022
                                                        CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound );
 
1023
                                                }
 
1024
                                        }
 
1025
                                        break;
 
1026
                                case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag
 
1027
                                        // if this player picked up the flag then a sound is played in CG_CheckLocalSounds
 
1028
                                        if (cg.snap->ps.powerups[PW_REDFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) {
 
1029
                                        }
 
1030
                                        else {
 
1031
                                                if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
 
1032
#ifdef MISSIONPACK
 
1033
                                                        if (cgs.gametype == GT_1FCTF)
 
1034
                                                                CG_AddBufferedSound( cgs.media.yourTeamTookTheFlagSound );
 
1035
                                                        else
 
1036
#endif
 
1037
                                                        CG_AddBufferedSound( cgs.media.enemyTookYourFlagSound );
 
1038
                                                }
 
1039
                                                else if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
 
1040
#ifdef MISSIONPACK
 
1041
                                                        if (cgs.gametype == GT_1FCTF)
 
1042
                                                                CG_AddBufferedSound( cgs.media.enemyTookTheFlagSound );
 
1043
                                                        else
 
1044
#endif
 
1045
                                                        CG_AddBufferedSound( cgs.media.yourTeamTookEnemyFlagSound );
 
1046
                                                }
 
1047
                                        }
 
1048
                                        break;
 
1049
                                case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked
 
1050
                                        if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) {
 
1051
                                                CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound );
 
1052
                                        }
 
1053
                                        break;
 
1054
                                case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked
 
1055
                                        if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) {
 
1056
                                                CG_AddBufferedSound( cgs.media.yourBaseIsUnderAttackSound );
 
1057
                                        }
 
1058
                                        break;
 
1059
 
 
1060
                                case GTS_REDTEAM_SCORED:
 
1061
                                        CG_AddBufferedSound(cgs.media.redScoredSound);
 
1062
                                        break;
 
1063
                                case GTS_BLUETEAM_SCORED:
 
1064
                                        CG_AddBufferedSound(cgs.media.blueScoredSound);
 
1065
                                        break;
 
1066
                                case GTS_REDTEAM_TOOK_LEAD:
 
1067
                                        CG_AddBufferedSound(cgs.media.redLeadsSound);
 
1068
                                        break;
 
1069
                                case GTS_BLUETEAM_TOOK_LEAD:
 
1070
                                        CG_AddBufferedSound(cgs.media.blueLeadsSound);
 
1071
                                        break;
 
1072
                                case GTS_TEAMS_ARE_TIED:
 
1073
                                        CG_AddBufferedSound( cgs.media.teamsTiedSound );
 
1074
                                        break;
 
1075
#ifdef MISSIONPACK
 
1076
                                case GTS_KAMIKAZE:
 
1077
                                        trap_S_StartLocalSound(cgs.media.kamikazeFarSound, CHAN_ANNOUNCER);
 
1078
                                        break;
 
1079
#endif
 
1080
                                default:
 
1081
                                        break;
 
1082
                        }
 
1083
                        break;
 
1084
                }
 
1085
 
 
1086
        case EV_PAIN:
 
1087
                // local player sounds are triggered in CG_CheckLocalSounds,
 
1088
                // so ignore events on the player
 
1089
                DEBUGNAME("EV_PAIN");
 
1090
                if ( cent->currentState.number != cg.snap->ps.clientNum ) {
 
1091
                        CG_PainEvent( cent, es->eventParm );
 
1092
                }
 
1093
                break;
 
1094
 
 
1095
        case EV_DEATH1:
 
1096
        case EV_DEATH2:
 
1097
        case EV_DEATH3:
 
1098
                DEBUGNAME("EV_DEATHx");
 
1099
                trap_S_StartSound( NULL, es->number, CHAN_VOICE, 
 
1100
                                CG_CustomSound( es->number, va("*death%i.wav", event - EV_DEATH1 + 1) ) );
 
1101
                break;
 
1102
 
 
1103
 
 
1104
        case EV_OBITUARY:
 
1105
                DEBUGNAME("EV_OBITUARY");
 
1106
                CG_Obituary( es );
 
1107
                break;
 
1108
 
 
1109
        //
 
1110
        // powerup events
 
1111
        //
 
1112
        case EV_POWERUP_QUAD:
 
1113
                DEBUGNAME("EV_POWERUP_QUAD");
 
1114
                if ( es->number == cg.snap->ps.clientNum ) {
 
1115
                        cg.powerupActive = PW_QUAD;
 
1116
                        cg.powerupTime = cg.time;
 
1117
                }
 
1118
                trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.quadSound );
 
1119
                break;
 
1120
        case EV_POWERUP_BATTLESUIT:
 
1121
                DEBUGNAME("EV_POWERUP_BATTLESUIT");
 
1122
                if ( es->number == cg.snap->ps.clientNum ) {
 
1123
                        cg.powerupActive = PW_BATTLESUIT;
 
1124
                        cg.powerupTime = cg.time;
 
1125
                }
 
1126
                trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.protectSound );
 
1127
                break;
 
1128
        case EV_POWERUP_REGEN:
 
1129
                DEBUGNAME("EV_POWERUP_REGEN");
 
1130
                if ( es->number == cg.snap->ps.clientNum ) {
 
1131
                        cg.powerupActive = PW_REGEN;
 
1132
                        cg.powerupTime = cg.time;
 
1133
                }
 
1134
                trap_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.regenSound );
 
1135
                break;
 
1136
 
 
1137
        case EV_GIB_PLAYER:
 
1138
                DEBUGNAME("EV_GIB_PLAYER");
 
1139
                // don't play gib sound when using the kamikaze because it interferes
 
1140
                // with the kamikaze sound, downside is that the gib sound will also
 
1141
                // not be played when someone is gibbed while just carrying the kamikaze
 
1142
                if ( !(es->eFlags & EF_KAMIKAZE) ) {
 
1143
                        trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound );
 
1144
                }
 
1145
                CG_GibPlayer( cent->lerpOrigin );
 
1146
                break;
 
1147
 
 
1148
        case EV_STOPLOOPINGSOUND:
 
1149
                DEBUGNAME("EV_STOPLOOPINGSOUND");
 
1150
                trap_S_StopLoopingSound( es->number );
 
1151
                es->loopSound = 0;
 
1152
                break;
 
1153
 
 
1154
        case EV_DEBUG_LINE:
 
1155
                DEBUGNAME("EV_DEBUG_LINE");
 
1156
                CG_Beam( cent );
 
1157
                break;
 
1158
 
 
1159
        default:
 
1160
                DEBUGNAME("UNKNOWN");
 
1161
                CG_Error( "Unknown event: %i", event );
 
1162
                break;
 
1163
        }
 
1164
 
 
1165
}
 
1166
 
 
1167
 
 
1168
/*
 
1169
==============
 
1170
CG_CheckEvents
 
1171
 
 
1172
==============
 
1173
*/
 
1174
void CG_CheckEvents( centity_t *cent ) {
 
1175
        // check for event-only entities
 
1176
        if ( cent->currentState.eType > ET_EVENTS ) {
 
1177
                if ( cent->previousEvent ) {
 
1178
                        return; // already fired
 
1179
                }
 
1180
                // if this is a player event set the entity number of the client entity number
 
1181
                if ( cent->currentState.eFlags & EF_PLAYER_EVENT ) {
 
1182
                        cent->currentState.number = cent->currentState.otherEntityNum;
 
1183
                }
 
1184
 
 
1185
                cent->previousEvent = 1;
 
1186
 
 
1187
                cent->currentState.event = cent->currentState.eType - ET_EVENTS;
 
1188
        } else {
 
1189
                // check for events riding with another entity
 
1190
                if ( cent->currentState.event == cent->previousEvent ) {
 
1191
                        return;
 
1192
                }
 
1193
                cent->previousEvent = cent->currentState.event;
 
1194
                if ( ( cent->currentState.event & ~EV_EVENT_BITS ) == 0 ) {
 
1195
                        return;
 
1196
                }
 
1197
        }
 
1198
 
 
1199
        // calculate the position at exactly the frame time
 
1200
        BG_EvaluateTrajectory( &cent->currentState.pos, cg.snap->serverTime, cent->lerpOrigin );
 
1201
        CG_SetEntitySoundPosition( cent );
 
1202
 
 
1203
        CG_EntityEvent( cent, cent->lerpOrigin );
 
1204
}
 
1205