~ubuntu-branches/ubuntu/hardy/openarena/hardy-backports

« back to all changes in this revision

Viewing changes to code/q3_ui/ui_sppostgame.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
/*
 
24
=============================================================================
 
25
 
 
26
SINGLE PLAYER POSTGAME MENU
 
27
 
 
28
=============================================================================
 
29
*/
 
30
 
 
31
#include "ui_local.h"
 
32
 
 
33
#define MAX_SCOREBOARD_CLIENTS          8
 
34
 
 
35
#define AWARD_PRESENTATION_TIME         2000
 
36
 
 
37
#define ART_MENU0               "menu/art/menu_0"
 
38
#define ART_MENU1               "menu/art/menu_1"
 
39
#define ART_REPLAY0             "menu/art/replay_0"
 
40
#define ART_REPLAY1             "menu/art/replay_1"
 
41
#define ART_NEXT0               "menu/art/next_0"
 
42
#define ART_NEXT1               "menu/art/next_1"
 
43
 
 
44
#define ID_AGAIN                10
 
45
#define ID_NEXT                 11
 
46
#define ID_MENU                 12
 
47
 
 
48
typedef struct {
 
49
        menuframework_s menu;
 
50
        menubitmap_s    item_again;
 
51
        menubitmap_s    item_next;
 
52
        menubitmap_s    item_menu;
 
53
 
 
54
        int                             phase;
 
55
        int                             ignoreKeysTime;
 
56
        int                             starttime;
 
57
        int                             scoreboardtime;
 
58
        int                             serverId;
 
59
 
 
60
        int                             clientNums[MAX_SCOREBOARD_CLIENTS];
 
61
        int                             ranks[MAX_SCOREBOARD_CLIENTS];
 
62
        int                             scores[MAX_SCOREBOARD_CLIENTS];
 
63
 
 
64
        char                    placeNames[3][64];
 
65
 
 
66
        int                             level;
 
67
        int                             numClients;
 
68
        int                             won;
 
69
        int                             numAwards;
 
70
        int                             awardsEarned[6];
 
71
        int                             awardsLevels[6];
 
72
        qboolean                playedSound[6];
 
73
        int                             lastTier;
 
74
        sfxHandle_t             winnerSound;
 
75
} postgameMenuInfo_t;
 
76
 
 
77
static postgameMenuInfo_t       postgameMenuInfo;
 
78
static char                                     arenainfo[MAX_INFO_VALUE];
 
79
 
 
80
char    *ui_medalNames[] = {"Accuracy", "Impressive", "Excellent", "Gauntlet", "Frags", "Perfect"};
 
81
char    *ui_medalPicNames[] = {
 
82
        "menu/medals/medal_accuracy",
 
83
        "menu/medals/medal_impressive",
 
84
        "menu/medals/medal_excellent",
 
85
        "menu/medals/medal_gauntlet",
 
86
        "menu/medals/medal_frags",
 
87
        "menu/medals/medal_victory"
 
88
};
 
89
char    *ui_medalSounds[] = {
 
90
        "sound/feedback/accuracy.wav",
 
91
        "sound/feedback/impressive_a.wav",
 
92
        "sound/feedback/excellent_a.wav",
 
93
        "sound/feedback/gauntlet.wav",
 
94
        "sound/feedback/frags.wav",
 
95
        "sound/feedback/perfect.wav"
 
96
};
 
97
 
 
98
 
 
99
/*
 
100
=================
 
101
UI_SPPostgameMenu_AgainEvent
 
102
=================
 
103
*/
 
104
static void UI_SPPostgameMenu_AgainEvent( void* ptr, int event )
 
105
{
 
106
        if (event != QM_ACTIVATED) {
 
107
                return;
 
108
        }
 
109
        UI_PopMenu();
 
110
        trap_Cmd_ExecuteText( EXEC_APPEND, "map_restart 0\n" );
 
111
}
 
112
 
 
113
 
 
114
/*
 
115
=================
 
116
UI_SPPostgameMenu_NextEvent
 
117
=================
 
118
*/
 
119
static void UI_SPPostgameMenu_NextEvent( void* ptr, int event ) {
 
120
        int                     currentSet;
 
121
        int                     levelSet;
 
122
        int                     level;
 
123
        int                     currentLevel;
 
124
        const char      *arenaInfo;
 
125
 
 
126
        if (event != QM_ACTIVATED) {
 
127
                return;
 
128
        }
 
129
        UI_PopMenu();
 
130
 
 
131
        // handle specially if we just won the training map
 
132
        if( postgameMenuInfo.won == 0 ) {
 
133
                level = 0;
 
134
        }
 
135
        else {
 
136
                level = postgameMenuInfo.level + 1;
 
137
        }
 
138
        levelSet = level / ARENAS_PER_TIER;
 
139
 
 
140
        currentLevel = UI_GetCurrentGame();
 
141
        if( currentLevel == -1 ) {
 
142
                currentLevel = postgameMenuInfo.level;
 
143
        }
 
144
        currentSet = currentLevel / ARENAS_PER_TIER;
 
145
 
 
146
        if( levelSet > currentSet || levelSet == UI_GetNumSPTiers() ) {
 
147
                level = currentLevel;
 
148
        }
 
149
 
 
150
        arenaInfo = UI_GetArenaInfoByNumber( level );
 
151
        if ( !arenaInfo ) {
 
152
                return;
 
153
        }
 
154
 
 
155
        UI_SPArena_Start( arenaInfo );
 
156
}
 
157
 
 
158
 
 
159
/*
 
160
=================
 
161
UI_SPPostgameMenu_MenuEvent
 
162
=================
 
163
*/
 
164
static void UI_SPPostgameMenu_MenuEvent( void* ptr, int event )
 
165
{
 
166
        if (event != QM_ACTIVATED) {
 
167
                return;
 
168
        }
 
169
        UI_PopMenu();
 
170
        trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; levelselect\n" );
 
171
}
 
172
 
 
173
 
 
174
/*
 
175
=================
 
176
UI_SPPostgameMenu_MenuKey
 
177
=================
 
178
*/
 
179
static sfxHandle_t UI_SPPostgameMenu_MenuKey( int key ) {
 
180
        if ( uis.realtime < postgameMenuInfo.ignoreKeysTime ) {
 
181
                return 0;
 
182
        }
 
183
 
 
184
        if( postgameMenuInfo.phase == 1 ) {
 
185
                trap_Cmd_ExecuteText( EXEC_APPEND, "abort_podium\n" );
 
186
                postgameMenuInfo.phase = 2;
 
187
                postgameMenuInfo.starttime = uis.realtime;
 
188
                postgameMenuInfo.ignoreKeysTime = uis.realtime + 250;
 
189
                return 0;
 
190
        }
 
191
 
 
192
        if( postgameMenuInfo.phase == 2 ) {
 
193
                postgameMenuInfo.phase = 3;
 
194
                postgameMenuInfo.starttime = uis.realtime;
 
195
                postgameMenuInfo.ignoreKeysTime = uis.realtime + 250;
 
196
                return 0;
 
197
        }
 
198
 
 
199
        if( key == K_ESCAPE || key == K_MOUSE2 ) {
 
200
                return 0;
 
201
        }
 
202
 
 
203
        return Menu_DefaultKey( &postgameMenuInfo.menu, key );
 
204
}
 
205
 
 
206
 
 
207
static int medalLocations[6] = {144, 448, 88, 504, 32, 560};
 
208
 
 
209
static void UI_SPPostgameMenu_DrawAwardsMedals( int max ) {
 
210
        int             n;
 
211
        int             medal;
 
212
        int             amount;
 
213
        int             x, y;
 
214
        char    buf[16];
 
215
 
 
216
        for( n = 0; n < max; n++ ) {
 
217
                x = medalLocations[n];
 
218
                y = 64;
 
219
                medal = postgameMenuInfo.awardsEarned[n];
 
220
                amount = postgameMenuInfo.awardsLevels[n];
 
221
 
 
222
                UI_DrawNamedPic( x, y, 48, 48, ui_medalPicNames[medal] );
 
223
 
 
224
                if( medal == AWARD_ACCURACY ) {
 
225
                        Com_sprintf( buf, sizeof(buf), "%i%%", amount );
 
226
                }
 
227
                else {
 
228
                        if( amount == 1 ) {
 
229
                                continue;
 
230
                        }
 
231
                        Com_sprintf( buf, sizeof(buf), "%i", amount );
 
232
                }
 
233
 
 
234
                UI_DrawString( x + 24, y + 52, buf, UI_CENTER, color_yellow );
 
235
        }
 
236
}
 
237
 
 
238
 
 
239
static void UI_SPPostgameMenu_DrawAwardsPresentation( int timer ) {
 
240
        int             awardNum;
 
241
        int             atimer;
 
242
        vec4_t  color;
 
243
 
 
244
        awardNum = timer / AWARD_PRESENTATION_TIME;
 
245
        atimer = timer % AWARD_PRESENTATION_TIME;
 
246
 
 
247
        color[0] = color[1] = color[2] = 1.0f;
 
248
        color[3] = (float)( AWARD_PRESENTATION_TIME - atimer ) / (float)AWARD_PRESENTATION_TIME;
 
249
        UI_DrawProportionalString( 320, 64, ui_medalNames[postgameMenuInfo.awardsEarned[awardNum]], UI_CENTER, color );
 
250
 
 
251
        UI_SPPostgameMenu_DrawAwardsMedals( awardNum + 1 );
 
252
 
 
253
        if( !postgameMenuInfo.playedSound[awardNum] ) {
 
254
                postgameMenuInfo.playedSound[awardNum] = qtrue;
 
255
                trap_S_StartLocalSound( trap_S_RegisterSound( ui_medalSounds[postgameMenuInfo.awardsEarned[awardNum]], qfalse ), CHAN_ANNOUNCER );
 
256
        }
 
257
}
 
258
 
 
259
 
 
260
/*
 
261
=================
 
262
UI_SPPostgameMenu_MenuDrawScoreLine
 
263
=================
 
264
*/
 
265
static void UI_SPPostgameMenu_MenuDrawScoreLine( int n, int y ) {
 
266
        int             rank;
 
267
        char    name[64];
 
268
        char    info[MAX_INFO_STRING];
 
269
 
 
270
        if( n > (postgameMenuInfo.numClients + 1) ) {
 
271
                n -= (postgameMenuInfo.numClients + 2);
 
272
        }
 
273
 
 
274
        if( n >= postgameMenuInfo.numClients ) {
 
275
                return;
 
276
        }
 
277
 
 
278
        rank = postgameMenuInfo.ranks[n];
 
279
        if( rank & RANK_TIED_FLAG ) {
 
280
                UI_DrawString( 640 - 31 * SMALLCHAR_WIDTH, y, "(tie)", UI_LEFT|UI_SMALLFONT, color_white );
 
281
                rank &= ~RANK_TIED_FLAG;
 
282
        }
 
283
        trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[n], info, MAX_INFO_STRING );
 
284
        Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) );
 
285
        Q_CleanStr( name );
 
286
 
 
287
        UI_DrawString( 640 - 25 * SMALLCHAR_WIDTH, y, va( "#%i: %-16s %2i", rank + 1, name, postgameMenuInfo.scores[n] ), UI_LEFT|UI_SMALLFONT, color_white );
 
288
}
 
289
 
 
290
 
 
291
/*
 
292
=================
 
293
UI_SPPostgameMenu_MenuDraw
 
294
=================
 
295
*/
 
296
static void UI_SPPostgameMenu_MenuDraw( void ) {
 
297
        int             timer;
 
298
        int             serverId;
 
299
        int             n;
 
300
        char    info[MAX_INFO_STRING];
 
301
 
 
302
        trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) );
 
303
        serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) );
 
304
        if( serverId != postgameMenuInfo.serverId ) {
 
305
                UI_PopMenu();
 
306
                return;
 
307
        }
 
308
 
 
309
        // phase 1
 
310
        if ( postgameMenuInfo.numClients > 2 ) {
 
311
                UI_DrawProportionalString( 510, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[2], UI_CENTER, color_white );
 
312
        }
 
313
        UI_DrawProportionalString( 130, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[1], UI_CENTER, color_white );
 
314
        UI_DrawProportionalString( 320, 480 - 64 - 2 * PROP_HEIGHT, postgameMenuInfo.placeNames[0], UI_CENTER, color_white );
 
315
 
 
316
        if( postgameMenuInfo.phase == 1 ) {
 
317
                timer = uis.realtime - postgameMenuInfo.starttime;
 
318
 
 
319
                if( timer >= 1000 && postgameMenuInfo.winnerSound ) {
 
320
                        trap_S_StartLocalSound( postgameMenuInfo.winnerSound, CHAN_ANNOUNCER );
 
321
                        postgameMenuInfo.winnerSound = 0;
 
322
                }
 
323
 
 
324
                if( timer < 5000 ) {
 
325
                        return;
 
326
                }
 
327
                postgameMenuInfo.phase = 2;
 
328
                postgameMenuInfo.starttime = uis.realtime;
 
329
        }
 
330
 
 
331
        // phase 2
 
332
        if( postgameMenuInfo.phase == 2 ) {
 
333
                timer = uis.realtime - postgameMenuInfo.starttime;
 
334
                if( timer >= ( postgameMenuInfo.numAwards * AWARD_PRESENTATION_TIME ) ) {
 
335
 
 
336
                        if( timer < 5000 ) {
 
337
                                return;
 
338
                        }
 
339
 
 
340
                        postgameMenuInfo.phase = 3;
 
341
                        postgameMenuInfo.starttime = uis.realtime;
 
342
                }
 
343
                else {
 
344
                        UI_SPPostgameMenu_DrawAwardsPresentation( timer );
 
345
                }
 
346
        }
 
347
 
 
348
        // phase 3
 
349
        if( postgameMenuInfo.phase == 3 ) {
 
350
                if( uis.demoversion ) {
 
351
                        if( postgameMenuInfo.won == 1 && UI_ShowTierVideo( 8 )) {
 
352
                                trap_Cvar_Set( "nextmap", "" );
 
353
                                trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic demoEnd.RoQ\n" );
 
354
                                return;
 
355
                        }
 
356
                }
 
357
                else if( postgameMenuInfo.won > -1 && UI_ShowTierVideo( postgameMenuInfo.won + 1 )) {
 
358
                        if( postgameMenuInfo.won == postgameMenuInfo.lastTier ) {
 
359
                                trap_Cvar_Set( "nextmap", "" );
 
360
                                trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic end.RoQ\n" );
 
361
                                return;
 
362
                        }
 
363
 
 
364
                        trap_Cvar_SetValue( "ui_spSelection", postgameMenuInfo.won * ARENAS_PER_TIER );
 
365
                        trap_Cvar_Set( "nextmap", "levelselect" );
 
366
                        trap_Cmd_ExecuteText( EXEC_APPEND, va( "disconnect; cinematic tier%i.RoQ\n", postgameMenuInfo.won + 1 ) );
 
367
                        return;
 
368
                }
 
369
 
 
370
                postgameMenuInfo.item_again.generic.flags &= ~QMF_INACTIVE;
 
371
                postgameMenuInfo.item_next.generic.flags &= ~QMF_INACTIVE;
 
372
                postgameMenuInfo.item_menu.generic.flags &= ~QMF_INACTIVE;
 
373
 
 
374
                UI_SPPostgameMenu_DrawAwardsMedals( postgameMenuInfo.numAwards );
 
375
 
 
376
                Menu_Draw( &postgameMenuInfo.menu );
 
377
        }
 
378
 
 
379
        // draw the scoreboard
 
380
        if( !trap_Cvar_VariableValue( "ui_spScoreboard" ) ) {
 
381
                return;
 
382
        }
 
383
 
 
384
        timer = uis.realtime - postgameMenuInfo.scoreboardtime;
 
385
        if( postgameMenuInfo.numClients <= 3 ) {
 
386
                n = 0;
 
387
        }
 
388
        else {
 
389
                n = timer / 1500 % (postgameMenuInfo.numClients + 2);
 
390
        }
 
391
        UI_SPPostgameMenu_MenuDrawScoreLine( n, 0 );
 
392
        UI_SPPostgameMenu_MenuDrawScoreLine( n + 1, 0 + SMALLCHAR_HEIGHT );
 
393
        UI_SPPostgameMenu_MenuDrawScoreLine( n + 2, 0 + 2 * SMALLCHAR_HEIGHT );
 
394
}
 
395
 
 
396
 
 
397
/*
 
398
=================
 
399
UI_SPPostgameMenu_Cache
 
400
=================
 
401
*/
 
402
void UI_SPPostgameMenu_Cache( void ) {
 
403
        int                     n;
 
404
        qboolean        buildscript;
 
405
 
 
406
        buildscript = trap_Cvar_VariableValue("com_buildscript");
 
407
 
 
408
        trap_R_RegisterShaderNoMip( ART_MENU0 );
 
409
        trap_R_RegisterShaderNoMip( ART_MENU1 );
 
410
        trap_R_RegisterShaderNoMip( ART_REPLAY0 );
 
411
        trap_R_RegisterShaderNoMip( ART_REPLAY1 );
 
412
        trap_R_RegisterShaderNoMip( ART_NEXT0 );
 
413
        trap_R_RegisterShaderNoMip( ART_NEXT1 );
 
414
        for( n = 0; n < 6; n++ ) {
 
415
                trap_R_RegisterShaderNoMip( ui_medalPicNames[n] );
 
416
                trap_S_RegisterSound( ui_medalSounds[n], qfalse );
 
417
        }
 
418
 
 
419
        if( buildscript ) {
 
420
                trap_S_RegisterSound( "music/loss.wav", qfalse );
 
421
                trap_S_RegisterSound( "music/win.wav", qfalse );
 
422
                trap_S_RegisterSound( "sound/player/announce/youwin.wav", qfalse );
 
423
        }
 
424
}
 
425
 
 
426
 
 
427
/*
 
428
=================
 
429
UI_SPPostgameMenu_Init
 
430
=================
 
431
*/
 
432
static void UI_SPPostgameMenu_Init( void ) {
 
433
        postgameMenuInfo.menu.wrapAround        = qtrue;
 
434
        postgameMenuInfo.menu.key                       = UI_SPPostgameMenu_MenuKey;
 
435
        postgameMenuInfo.menu.draw                      = UI_SPPostgameMenu_MenuDraw;
 
436
        postgameMenuInfo.ignoreKeysTime         = uis.realtime + 1500;
 
437
 
 
438
        UI_SPPostgameMenu_Cache();
 
439
 
 
440
        postgameMenuInfo.item_menu.generic.type                 = MTYPE_BITMAP;
 
441
        postgameMenuInfo.item_menu.generic.name                 = ART_MENU0;
 
442
        postgameMenuInfo.item_menu.generic.flags                = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE;
 
443
        postgameMenuInfo.item_menu.generic.x                    = 0;
 
444
        postgameMenuInfo.item_menu.generic.y                    = 480-64;
 
445
        postgameMenuInfo.item_menu.generic.callback             = UI_SPPostgameMenu_MenuEvent;
 
446
        postgameMenuInfo.item_menu.generic.id                   = ID_MENU;
 
447
        postgameMenuInfo.item_menu.width                                = 128;
 
448
        postgameMenuInfo.item_menu.height                               = 64;
 
449
        postgameMenuInfo.item_menu.focuspic                             = ART_MENU1;
 
450
 
 
451
        postgameMenuInfo.item_again.generic.type                = MTYPE_BITMAP;
 
452
        postgameMenuInfo.item_again.generic.name                = ART_REPLAY0;
 
453
        postgameMenuInfo.item_again.generic.flags               = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE;
 
454
        postgameMenuInfo.item_again.generic.x                   = 320;
 
455
        postgameMenuInfo.item_again.generic.y                   = 480-64;
 
456
        postgameMenuInfo.item_again.generic.callback    = UI_SPPostgameMenu_AgainEvent;
 
457
        postgameMenuInfo.item_again.generic.id                  = ID_AGAIN;
 
458
        postgameMenuInfo.item_again.width                               = 128;
 
459
        postgameMenuInfo.item_again.height                              = 64;
 
460
        postgameMenuInfo.item_again.focuspic                    = ART_REPLAY1;
 
461
 
 
462
        postgameMenuInfo.item_next.generic.type                 = MTYPE_BITMAP;
 
463
        postgameMenuInfo.item_next.generic.name                 = ART_NEXT0;
 
464
        postgameMenuInfo.item_next.generic.flags                = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE;
 
465
        postgameMenuInfo.item_next.generic.x                    = 640;
 
466
        postgameMenuInfo.item_next.generic.y                    = 480-64;
 
467
        postgameMenuInfo.item_next.generic.callback             = UI_SPPostgameMenu_NextEvent;
 
468
        postgameMenuInfo.item_next.generic.id                   = ID_NEXT;
 
469
        postgameMenuInfo.item_next.width                                = 128;
 
470
        postgameMenuInfo.item_next.height                               = 64;
 
471
        postgameMenuInfo.item_next.focuspic                             = ART_NEXT1;
 
472
 
 
473
        Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_menu );
 
474
        Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_again );
 
475
        Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_next );
 
476
}
 
477
 
 
478
 
 
479
static void Prepname( int index ) {
 
480
        int             len;
 
481
        char    name[64];
 
482
        char    info[MAX_INFO_STRING];
 
483
 
 
484
        trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[index], info, MAX_INFO_STRING );
 
485
        Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) );
 
486
        Q_CleanStr( name );
 
487
        len = strlen( name );
 
488
 
 
489
        while( len && UI_ProportionalStringWidth( name ) > 256 ) {
 
490
                len--;
 
491
                name[len] = 0;
 
492
        }
 
493
 
 
494
        Q_strncpyz( postgameMenuInfo.placeNames[index], name, sizeof(postgameMenuInfo.placeNames[index]) );
 
495
}
 
496
 
 
497
 
 
498
/*
 
499
=================
 
500
UI_SPPostgameMenu_f
 
501
=================
 
502
*/
 
503
void UI_SPPostgameMenu_f( void ) {
 
504
        int                     playerGameRank;
 
505
        int                     playerClientNum;
 
506
        int                     n;
 
507
        int                     oldFrags, newFrags;
 
508
        const char      *arena;
 
509
        int                     awardValues[6];
 
510
        char            map[MAX_QPATH];
 
511
        char            info[MAX_INFO_STRING];
 
512
 
 
513
        memset( &postgameMenuInfo, 0, sizeof(postgameMenuInfo) );
 
514
 
 
515
        trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) );
 
516
        postgameMenuInfo.serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) );
 
517
 
 
518
        trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
 
519
        Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) );
 
520
        arena = UI_GetArenaInfoByMap( map );
 
521
        if ( !arena ) {
 
522
                return;
 
523
        }
 
524
        Q_strncpyz( arenainfo, arena, sizeof(arenainfo) );
 
525
 
 
526
        postgameMenuInfo.level = atoi( Info_ValueForKey( arenainfo, "num" ) );
 
527
 
 
528
        postgameMenuInfo.numClients = atoi( UI_Argv( 1 ) );
 
529
        playerClientNum = atoi( UI_Argv( 2 ) );
 
530
        playerGameRank = 8;             // in case they ended game as a spectator
 
531
 
 
532
        if( postgameMenuInfo.numClients > MAX_SCOREBOARD_CLIENTS ) {
 
533
                postgameMenuInfo.numClients = MAX_SCOREBOARD_CLIENTS;
 
534
        }
 
535
 
 
536
        for( n = 0; n < postgameMenuInfo.numClients; n++ ) {
 
537
                postgameMenuInfo.clientNums[n] = atoi( UI_Argv( 8 + n * 3 + 1 ) );
 
538
                postgameMenuInfo.ranks[n] = atoi( UI_Argv( 8 + n * 3 + 2 ) );
 
539
                postgameMenuInfo.scores[n] = atoi( UI_Argv( 8 + n * 3 + 3 ) );
 
540
 
 
541
                if( postgameMenuInfo.clientNums[n] == playerClientNum ) {
 
542
                        playerGameRank = (postgameMenuInfo.ranks[n] & ~RANK_TIED_FLAG) + 1;
 
543
                }
 
544
        }
 
545
 
 
546
        UI_SetBestScore( postgameMenuInfo.level, playerGameRank );
 
547
 
 
548
        // process award stats and prepare presentation data
 
549
        awardValues[AWARD_ACCURACY] = atoi( UI_Argv( 3 ) );
 
550
        awardValues[AWARD_IMPRESSIVE] = atoi( UI_Argv( 4 ) );
 
551
        awardValues[AWARD_EXCELLENT] = atoi( UI_Argv( 5 ) );
 
552
        awardValues[AWARD_GAUNTLET] = atoi( UI_Argv( 6 ) );
 
553
        awardValues[AWARD_FRAGS] = atoi( UI_Argv( 7 ) );
 
554
        awardValues[AWARD_PERFECT] = atoi( UI_Argv( 8 ) );
 
555
 
 
556
        postgameMenuInfo.numAwards = 0;
 
557
 
 
558
        if( awardValues[AWARD_ACCURACY] >= 50 ) {
 
559
                UI_LogAwardData( AWARD_ACCURACY, 1 );
 
560
                postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_ACCURACY;
 
561
                postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_ACCURACY];
 
562
                postgameMenuInfo.numAwards++;
 
563
        }
 
564
 
 
565
        if( awardValues[AWARD_IMPRESSIVE] ) {
 
566
                UI_LogAwardData( AWARD_IMPRESSIVE, awardValues[AWARD_IMPRESSIVE] );
 
567
                postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_IMPRESSIVE;
 
568
                postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_IMPRESSIVE];
 
569
                postgameMenuInfo.numAwards++;
 
570
        }
 
571
 
 
572
        if( awardValues[AWARD_EXCELLENT] ) {
 
573
                UI_LogAwardData( AWARD_EXCELLENT, awardValues[AWARD_EXCELLENT] );
 
574
                postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_EXCELLENT;
 
575
                postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_EXCELLENT];
 
576
                postgameMenuInfo.numAwards++;
 
577
        }
 
578
 
 
579
        if( awardValues[AWARD_GAUNTLET] ) {
 
580
                UI_LogAwardData( AWARD_GAUNTLET, awardValues[AWARD_GAUNTLET] );
 
581
                postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_GAUNTLET;
 
582
                postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_GAUNTLET];
 
583
                postgameMenuInfo.numAwards++;
 
584
        }
 
585
 
 
586
        oldFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100;
 
587
        UI_LogAwardData( AWARD_FRAGS, awardValues[AWARD_FRAGS] );
 
588
        newFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100;
 
589
        if( newFrags > oldFrags ) {
 
590
                postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_FRAGS;
 
591
                postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = newFrags * 100;
 
592
                postgameMenuInfo.numAwards++;
 
593
        }
 
594
 
 
595
        if( awardValues[AWARD_PERFECT] ) {
 
596
                UI_LogAwardData( AWARD_PERFECT, 1 );
 
597
                postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_PERFECT;
 
598
                postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = 1;
 
599
                postgameMenuInfo.numAwards++;
 
600
        }
 
601
 
 
602
        if ( playerGameRank == 1 ) {
 
603
                postgameMenuInfo.won = UI_TierCompleted( postgameMenuInfo.level );
 
604
        }
 
605
        else {
 
606
                postgameMenuInfo.won = -1;
 
607
        }
 
608
 
 
609
        postgameMenuInfo.starttime = uis.realtime;
 
610
        postgameMenuInfo.scoreboardtime = uis.realtime;
 
611
 
 
612
        trap_Key_SetCatcher( KEYCATCH_UI );
 
613
        uis.menusp = 0;
 
614
 
 
615
        UI_SPPostgameMenu_Init();
 
616
        UI_PushMenu( &postgameMenuInfo.menu );
 
617
 
 
618
        if ( playerGameRank == 1 ) {
 
619
                Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_next );
 
620
        }
 
621
        else {
 
622
                Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_again );
 
623
        }
 
624
 
 
625
        Prepname( 0 );
 
626
        Prepname( 1 );
 
627
        Prepname( 2 );
 
628
 
 
629
        if ( playerGameRank != 1 ) {
 
630
                postgameMenuInfo.winnerSound = trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", postgameMenuInfo.placeNames[0] ), qfalse );
 
631
                trap_Cmd_ExecuteText( EXEC_APPEND, "music music/loss\n" );
 
632
        }
 
633
        else {
 
634
                postgameMenuInfo.winnerSound = trap_S_RegisterSound( "sound/player/announce/youwin.wav", qfalse );
 
635
                trap_Cmd_ExecuteText( EXEC_APPEND, "music music/win\n" );
 
636
        }
 
637
 
 
638
        postgameMenuInfo.phase = 1;
 
639
 
 
640
        postgameMenuInfo.lastTier = UI_GetNumSPTiers();
 
641
        if ( UI_GetSpecialArenaInfo( "final" ) ) {
 
642
                postgameMenuInfo.lastTier++;
 
643
        }
 
644
}