00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "ui_local.h"
00033
00034
00035 #define GAMESERVER_BACK0 "menu/art/back_0"
00036 #define GAMESERVER_BACK1 "menu/art/back_1"
00037 #define GAMESERVER_NEXT0 "menu/art/next_0"
00038 #define GAMESERVER_NEXT1 "menu/art/next_1"
00039 #define GAMESERVER_FRAMEL "menu/art/frame2_l"
00040 #define GAMESERVER_FRAMER "menu/art/frame1_r"
00041 #define GAMESERVER_SELECT "menu/art/maps_select"
00042 #define GAMESERVER_SELECTED "menu/art/maps_selected"
00043 #define GAMESERVER_FIGHT0 "menu/art/fight_0"
00044 #define GAMESERVER_FIGHT1 "menu/art/fight_1"
00045 #define GAMESERVER_UNKNOWNMAP "menu/art/unknownmap"
00046 #define GAMESERVER_ARROWS "menu/art/gs_arrows_0"
00047 #define GAMESERVER_ARROWSL "menu/art/gs_arrows_l"
00048 #define GAMESERVER_ARROWSR "menu/art/gs_arrows_r"
00049
00050 #define MAX_MAPROWS 2
00051 #define MAX_MAPCOLS 2
00052 #define MAX_MAPSPERPAGE 4
00053
00054 #define MAX_SERVERSTEXT 8192
00055
00056 #define MAX_SERVERMAPS 64
00057 #define MAX_NAMELENGTH 16
00058
00059 #define ID_GAMETYPE 10
00060 #define ID_PICTURES 11 // 12, 13, 14
00061 #define ID_PREVPAGE 15
00062 #define ID_NEXTPAGE 16
00063 #define ID_STARTSERVERBACK 17
00064 #define ID_STARTSERVERNEXT 18
00065
00066 typedef struct {
00067 menuframework_s menu;
00068
00069 menutext_s banner;
00070 menubitmap_s framel;
00071 menubitmap_s framer;
00072
00073 menulist_s gametype;
00074 menubitmap_s mappics[MAX_MAPSPERPAGE];
00075 menubitmap_s mapbuttons[MAX_MAPSPERPAGE];
00076 menubitmap_s arrows;
00077 menubitmap_s prevpage;
00078 menubitmap_s nextpage;
00079 menubitmap_s back;
00080 menubitmap_s next;
00081
00082 menutext_s mapname;
00083 menubitmap_s item_null;
00084
00085 qboolean multiplayer;
00086 int currentmap;
00087 int nummaps;
00088 int page;
00089 int maxpages;
00090 char maplist[MAX_SERVERMAPS][MAX_NAMELENGTH];
00091 int mapGamebits[MAX_SERVERMAPS];
00092 } startserver_t;
00093
00094 static startserver_t s_startserver;
00095
00096 static const char *gametype_items[] = {
00097 "Free For All",
00098 "Team Deathmatch",
00099 "Tournament",
00100 "Capture the Flag",
00101 0
00102 };
00103
00104 static int gametype_remap[] = {GT_FFA, GT_TEAM, GT_TOURNAMENT, GT_CTF};
00105 static int gametype_remap2[] = {0, 2, 0, 1, 3};
00106
00107
00108 extern const char* punkbuster_items[];
00109
00110 static void UI_ServerOptionsMenu( qboolean multiplayer );
00111
00112
00113
00114
00115
00116
00117
00118 static int GametypeBits( char *string ) {
00119 int bits;
00120 char *p;
00121 char *token;
00122
00123 bits = 0;
00124 p = string;
00125 while( 1 ) {
00126 token = COM_ParseExt( &p, qfalse );
00127 if( token[0] == 0 ) {
00128 break;
00129 }
00130
00131 if( Q_stricmp( token, "ffa" ) == 0 ) {
00132 bits |= 1 << GT_FFA;
00133 continue;
00134 }
00135
00136 if( Q_stricmp( token, "tourney" ) == 0 ) {
00137 bits |= 1 << GT_TOURNAMENT;
00138 continue;
00139 }
00140
00141 if( Q_stricmp( token, "single" ) == 0 ) {
00142 bits |= 1 << GT_SINGLE_PLAYER;
00143 continue;
00144 }
00145
00146 if( Q_stricmp( token, "team" ) == 0 ) {
00147 bits |= 1 << GT_TEAM;
00148 continue;
00149 }
00150
00151 if( Q_stricmp( token, "ctf" ) == 0 ) {
00152 bits |= 1 << GT_CTF;
00153 continue;
00154 }
00155 }
00156
00157 return bits;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 static void StartServer_Update( void ) {
00167 int i;
00168 int top;
00169 static char picname[MAX_MAPSPERPAGE][64];
00170
00171 top = s_startserver.page*MAX_MAPSPERPAGE;
00172
00173 for (i=0; i<MAX_MAPSPERPAGE; i++)
00174 {
00175 if (top+i >= s_startserver.nummaps)
00176 break;
00177
00178 Com_sprintf( picname[i], sizeof(picname[i]), "levelshots/%s", s_startserver.maplist[top+i] );
00179
00180 s_startserver.mappics[i].generic.flags &= ~QMF_HIGHLIGHT;
00181 s_startserver.mappics[i].generic.name = picname[i];
00182 s_startserver.mappics[i].shader = 0;
00183
00184
00185 s_startserver.mapbuttons[i].generic.flags |= QMF_PULSEIFFOCUS;
00186 s_startserver.mapbuttons[i].generic.flags &= ~QMF_INACTIVE;
00187 }
00188
00189 for (; i<MAX_MAPSPERPAGE; i++)
00190 {
00191 s_startserver.mappics[i].generic.flags &= ~QMF_HIGHLIGHT;
00192 s_startserver.mappics[i].generic.name = NULL;
00193 s_startserver.mappics[i].shader = 0;
00194
00195
00196 s_startserver.mapbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS;
00197 s_startserver.mapbuttons[i].generic.flags |= QMF_INACTIVE;
00198 }
00199
00200
00201
00202 if( !s_startserver.nummaps ) {
00203 s_startserver.next.generic.flags |= QMF_INACTIVE;
00204
00205
00206 strcpy( s_startserver.mapname.string, "NO MAPS FOUND" );
00207 }
00208 else {
00209
00210 s_startserver.next.generic.flags &= ~QMF_INACTIVE;
00211 i = s_startserver.currentmap - top;
00212 if ( i >=0 && i < MAX_MAPSPERPAGE )
00213 {
00214 s_startserver.mappics[i].generic.flags |= QMF_HIGHLIGHT;
00215 s_startserver.mapbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS;
00216 }
00217
00218
00219 strcpy( s_startserver.mapname.string, s_startserver.maplist[s_startserver.currentmap] );
00220 }
00221
00222 Q_strupr( s_startserver.mapname.string );
00223 }
00224
00225
00226
00227
00228
00229
00230
00231 static void StartServer_MapEvent( void* ptr, int event ) {
00232 if( event != QM_ACTIVATED) {
00233 return;
00234 }
00235
00236 s_startserver.currentmap = (s_startserver.page*MAX_MAPSPERPAGE) + (((menucommon_s*)ptr)->id - ID_PICTURES);
00237 StartServer_Update();
00238 }
00239
00240
00241
00242
00243
00244
00245
00246 static void StartServer_GametypeEvent( void* ptr, int event ) {
00247 int i;
00248 int count;
00249 int gamebits;
00250 int matchbits;
00251 const char *info;
00252
00253 if( event != QM_ACTIVATED) {
00254 return;
00255 }
00256
00257 count = UI_GetNumArenas();
00258 s_startserver.nummaps = 0;
00259 matchbits = 1 << gametype_remap[s_startserver.gametype.curvalue];
00260 if( gametype_remap[s_startserver.gametype.curvalue] == GT_FFA ) {
00261 matchbits |= ( 1 << GT_SINGLE_PLAYER );
00262 }
00263 for( i = 0; i < count; i++ ) {
00264 info = UI_GetArenaInfoByNumber( i );
00265
00266 gamebits = GametypeBits( Info_ValueForKey( info, "type") );
00267 if( !( gamebits & matchbits ) ) {
00268 continue;
00269 }
00270
00271 Q_strncpyz( s_startserver.maplist[s_startserver.nummaps], Info_ValueForKey( info, "map"), MAX_NAMELENGTH );
00272 Q_strupr( s_startserver.maplist[s_startserver.nummaps] );
00273 s_startserver.mapGamebits[s_startserver.nummaps] = gamebits;
00274 s_startserver.nummaps++;
00275 }
00276 s_startserver.maxpages = (s_startserver.nummaps + MAX_MAPSPERPAGE-1)/MAX_MAPSPERPAGE;
00277 s_startserver.page = 0;
00278 s_startserver.currentmap = 0;
00279
00280 StartServer_Update();
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 static void StartServer_MenuEvent( void* ptr, int event ) {
00290 if( event != QM_ACTIVATED ) {
00291 return;
00292 }
00293
00294 switch( ((menucommon_s*)ptr)->id ) {
00295 case ID_PREVPAGE:
00296 if( s_startserver.page > 0 ) {
00297 s_startserver.page--;
00298 StartServer_Update();
00299 }
00300 break;
00301
00302 case ID_NEXTPAGE:
00303 if( s_startserver.page < s_startserver.maxpages - 1 ) {
00304 s_startserver.page++;
00305 StartServer_Update();
00306 }
00307 break;
00308
00309 case ID_STARTSERVERNEXT:
00310 trap_Cvar_SetValue( "g_gameType", gametype_remap[s_startserver.gametype.curvalue] );
00311 UI_ServerOptionsMenu( s_startserver.multiplayer );
00312 break;
00313
00314 case ID_STARTSERVERBACK:
00315 UI_PopMenu();
00316 break;
00317 }
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 static void StartServer_LevelshotDraw( void *self ) {
00327 menubitmap_s *b;
00328 int x;
00329 int y;
00330 int w;
00331 int h;
00332 int n;
00333
00334 b = (menubitmap_s *)self;
00335
00336 if( !b->generic.name ) {
00337 return;
00338 }
00339
00340 if( b->generic.name && !b->shader ) {
00341 b->shader = trap_R_RegisterShaderNoMip( b->generic.name );
00342 if( !b->shader && b->errorpic ) {
00343 b->shader = trap_R_RegisterShaderNoMip( b->errorpic );
00344 }
00345 }
00346
00347 if( b->focuspic && !b->focusshader ) {
00348 b->focusshader = trap_R_RegisterShaderNoMip( b->focuspic );
00349 }
00350
00351 x = b->generic.x;
00352 y = b->generic.y;
00353 w = b->width;
00354 h = b->height;
00355 if( b->shader ) {
00356 UI_DrawHandlePic( x, y, w, h, b->shader );
00357 }
00358
00359 x = b->generic.x;
00360 y = b->generic.y + b->height;
00361 UI_FillRect( x, y, b->width, 28, colorBlack );
00362
00363 x += b->width / 2;
00364 y += 4;
00365 n = s_startserver.page * MAX_MAPSPERPAGE + b->generic.id - ID_PICTURES;
00366 UI_DrawString( x, y, s_startserver.maplist[n], UI_CENTER|UI_SMALLFONT, color_orange );
00367
00368 x = b->generic.x;
00369 y = b->generic.y;
00370 w = b->width;
00371 h = b->height + 28;
00372 if( b->generic.flags & QMF_HIGHLIGHT ) {
00373 UI_DrawHandlePic( x, y, w, h, b->focusshader );
00374 }
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 static void StartServer_MenuInit( void ) {
00384 int i;
00385 int x;
00386 int y;
00387 static char mapnamebuffer[64];
00388
00389
00390 memset( &s_startserver, 0 ,sizeof(startserver_t) );
00391
00392 StartServer_Cache();
00393
00394 s_startserver.menu.wrapAround = qtrue;
00395 s_startserver.menu.fullscreen = qtrue;
00396
00397 s_startserver.banner.generic.type = MTYPE_BTEXT;
00398 s_startserver.banner.generic.x = 320;
00399 s_startserver.banner.generic.y = 16;
00400 s_startserver.banner.string = "GAME SERVER";
00401 s_startserver.banner.color = color_white;
00402 s_startserver.banner.style = UI_CENTER;
00403
00404 s_startserver.framel.generic.type = MTYPE_BITMAP;
00405 s_startserver.framel.generic.name = GAMESERVER_FRAMEL;
00406 s_startserver.framel.generic.flags = QMF_INACTIVE;
00407 s_startserver.framel.generic.x = 0;
00408 s_startserver.framel.generic.y = 78;
00409 s_startserver.framel.width = 256;
00410 s_startserver.framel.height = 329;
00411
00412 s_startserver.framer.generic.type = MTYPE_BITMAP;
00413 s_startserver.framer.generic.name = GAMESERVER_FRAMER;
00414 s_startserver.framer.generic.flags = QMF_INACTIVE;
00415 s_startserver.framer.generic.x = 376;
00416 s_startserver.framer.generic.y = 76;
00417 s_startserver.framer.width = 256;
00418 s_startserver.framer.height = 334;
00419
00420 s_startserver.gametype.generic.type = MTYPE_SPINCONTROL;
00421 s_startserver.gametype.generic.name = "Game Type:";
00422 s_startserver.gametype.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
00423 s_startserver.gametype.generic.callback = StartServer_GametypeEvent;
00424 s_startserver.gametype.generic.id = ID_GAMETYPE;
00425 s_startserver.gametype.generic.x = 320 - 24;
00426 s_startserver.gametype.generic.y = 368;
00427 s_startserver.gametype.itemnames = gametype_items;
00428
00429 for (i=0; i<MAX_MAPSPERPAGE; i++)
00430 {
00431 x = (i % MAX_MAPCOLS) * (128+8) + 188;
00432 y = (i / MAX_MAPROWS) * (128+8) + 96;
00433
00434 s_startserver.mappics[i].generic.type = MTYPE_BITMAP;
00435 s_startserver.mappics[i].generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
00436 s_startserver.mappics[i].generic.x = x;
00437 s_startserver.mappics[i].generic.y = y;
00438 s_startserver.mappics[i].generic.id = ID_PICTURES+i;
00439 s_startserver.mappics[i].width = 128;
00440 s_startserver.mappics[i].height = 96;
00441 s_startserver.mappics[i].focuspic = GAMESERVER_SELECTED;
00442 s_startserver.mappics[i].errorpic = GAMESERVER_UNKNOWNMAP;
00443 s_startserver.mappics[i].generic.ownerdraw = StartServer_LevelshotDraw;
00444
00445 s_startserver.mapbuttons[i].generic.type = MTYPE_BITMAP;
00446 s_startserver.mapbuttons[i].generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_NODEFAULTINIT;
00447 s_startserver.mapbuttons[i].generic.id = ID_PICTURES+i;
00448 s_startserver.mapbuttons[i].generic.callback = StartServer_MapEvent;
00449 s_startserver.mapbuttons[i].generic.x = x - 30;
00450 s_startserver.mapbuttons[i].generic.y = y - 32;
00451 s_startserver.mapbuttons[i].width = 256;
00452 s_startserver.mapbuttons[i].height = 248;
00453 s_startserver.mapbuttons[i].generic.left = x;
00454 s_startserver.mapbuttons[i].generic.top = y;
00455 s_startserver.mapbuttons[i].generic.right = x + 128;
00456 s_startserver.mapbuttons[i].generic.bottom = y + 128;
00457 s_startserver.mapbuttons[i].focuspic = GAMESERVER_SELECT;
00458 }
00459
00460 s_startserver.arrows.generic.type = MTYPE_BITMAP;
00461 s_startserver.arrows.generic.name = GAMESERVER_ARROWS;
00462 s_startserver.arrows.generic.flags = QMF_INACTIVE;
00463 s_startserver.arrows.generic.x = 260;
00464 s_startserver.arrows.generic.y = 400;
00465 s_startserver.arrows.width = 128;
00466 s_startserver.arrows.height = 32;
00467
00468 s_startserver.prevpage.generic.type = MTYPE_BITMAP;
00469 s_startserver.prevpage.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
00470 s_startserver.prevpage.generic.callback = StartServer_MenuEvent;
00471 s_startserver.prevpage.generic.id = ID_PREVPAGE;
00472 s_startserver.prevpage.generic.x = 260;
00473 s_startserver.prevpage.generic.y = 400;
00474 s_startserver.prevpage.width = 64;
00475 s_startserver.prevpage.height = 32;
00476 s_startserver.prevpage.focuspic = GAMESERVER_ARROWSL;
00477
00478 s_startserver.nextpage.generic.type = MTYPE_BITMAP;
00479 s_startserver.nextpage.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
00480 s_startserver.nextpage.generic.callback = StartServer_MenuEvent;
00481 s_startserver.nextpage.generic.id = ID_NEXTPAGE;
00482 s_startserver.nextpage.generic.x = 321;
00483 s_startserver.nextpage.generic.y = 400;
00484 s_startserver.nextpage.width = 64;
00485 s_startserver.nextpage.height = 32;
00486 s_startserver.nextpage.focuspic = GAMESERVER_ARROWSR;
00487
00488 s_startserver.mapname.generic.type = MTYPE_PTEXT;
00489 s_startserver.mapname.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE;
00490 s_startserver.mapname.generic.x = 320;
00491 s_startserver.mapname.generic.y = 440;
00492 s_startserver.mapname.string = mapnamebuffer;
00493 s_startserver.mapname.style = UI_CENTER|UI_BIGFONT;
00494 s_startserver.mapname.color = text_color_normal;
00495
00496 s_startserver.back.generic.type = MTYPE_BITMAP;
00497 s_startserver.back.generic.name = GAMESERVER_BACK0;
00498 s_startserver.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
00499 s_startserver.back.generic.callback = StartServer_MenuEvent;
00500 s_startserver.back.generic.id = ID_STARTSERVERBACK;
00501 s_startserver.back.generic.x = 0;
00502 s_startserver.back.generic.y = 480-64;
00503 s_startserver.back.width = 128;
00504 s_startserver.back.height = 64;
00505 s_startserver.back.focuspic = GAMESERVER_BACK1;
00506
00507 s_startserver.next.generic.type = MTYPE_BITMAP;
00508 s_startserver.next.generic.name = GAMESERVER_NEXT0;
00509 s_startserver.next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
00510 s_startserver.next.generic.callback = StartServer_MenuEvent;
00511 s_startserver.next.generic.id = ID_STARTSERVERNEXT;
00512 s_startserver.next.generic.x = 640;
00513 s_startserver.next.generic.y = 480-64;
00514 s_startserver.next.width = 128;
00515 s_startserver.next.height = 64;
00516 s_startserver.next.focuspic = GAMESERVER_NEXT1;
00517
00518 s_startserver.item_null.generic.type = MTYPE_BITMAP;
00519 s_startserver.item_null.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY|QMF_SILENT;
00520 s_startserver.item_null.generic.x = 0;
00521 s_startserver.item_null.generic.y = 0;
00522 s_startserver.item_null.width = 640;
00523 s_startserver.item_null.height = 480;
00524
00525 Menu_AddItem( &s_startserver.menu, &s_startserver.banner );
00526 Menu_AddItem( &s_startserver.menu, &s_startserver.framel );
00527 Menu_AddItem( &s_startserver.menu, &s_startserver.framer );
00528
00529 Menu_AddItem( &s_startserver.menu, &s_startserver.gametype );
00530 for (i=0; i<MAX_MAPSPERPAGE; i++)
00531 {
00532 Menu_AddItem( &s_startserver.menu, &s_startserver.mappics[i] );
00533 Menu_AddItem( &s_startserver.menu, &s_startserver.mapbuttons[i] );
00534 }
00535
00536 Menu_AddItem( &s_startserver.menu, &s_startserver.arrows );
00537 Menu_AddItem( &s_startserver.menu, &s_startserver.prevpage );
00538 Menu_AddItem( &s_startserver.menu, &s_startserver.nextpage );
00539 Menu_AddItem( &s_startserver.menu, &s_startserver.back );
00540 Menu_AddItem( &s_startserver.menu, &s_startserver.next );
00541 Menu_AddItem( &s_startserver.menu, &s_startserver.mapname );
00542 Menu_AddItem( &s_startserver.menu, &s_startserver.item_null );
00543
00544 StartServer_GametypeEvent( NULL, QM_ACTIVATED );
00545 }
00546
00547
00548
00549
00550
00551
00552
00553 void StartServer_Cache( void )
00554 {
00555 int i;
00556 const char *info;
00557 qboolean precache;
00558 char picname[64];
00559
00560 trap_R_RegisterShaderNoMip( GAMESERVER_BACK0 );
00561 trap_R_RegisterShaderNoMip( GAMESERVER_BACK1 );
00562 trap_R_RegisterShaderNoMip( GAMESERVER_NEXT0 );
00563 trap_R_RegisterShaderNoMip( GAMESERVER_NEXT1 );
00564 trap_R_RegisterShaderNoMip( GAMESERVER_FRAMEL );
00565 trap_R_RegisterShaderNoMip( GAMESERVER_FRAMER );
00566 trap_R_RegisterShaderNoMip( GAMESERVER_SELECT );
00567 trap_R_RegisterShaderNoMip( GAMESERVER_SELECTED );
00568 trap_R_RegisterShaderNoMip( GAMESERVER_UNKNOWNMAP );
00569 trap_R_RegisterShaderNoMip( GAMESERVER_ARROWS );
00570 trap_R_RegisterShaderNoMip( GAMESERVER_ARROWSL );
00571 trap_R_RegisterShaderNoMip( GAMESERVER_ARROWSR );
00572
00573 precache = trap_Cvar_VariableValue("com_buildscript");
00574
00575 s_startserver.nummaps = UI_GetNumArenas();
00576
00577 for( i = 0; i < s_startserver.nummaps; i++ ) {
00578 info = UI_GetArenaInfoByNumber( i );
00579
00580 Q_strncpyz( s_startserver.maplist[i], Info_ValueForKey( info, "map"), MAX_NAMELENGTH );
00581 Q_strupr( s_startserver.maplist[i] );
00582 s_startserver.mapGamebits[i] = GametypeBits( Info_ValueForKey( info, "type") );
00583
00584 if( precache ) {
00585 Com_sprintf( picname, sizeof(picname), "levelshots/%s", s_startserver.maplist[i] );
00586 trap_R_RegisterShaderNoMip(picname);
00587 }
00588 }
00589
00590 s_startserver.maxpages = (s_startserver.nummaps + MAX_MAPSPERPAGE-1)/MAX_MAPSPERPAGE;
00591 }
00592
00593
00594
00595
00596
00597
00598
00599 void UI_StartServerMenu( qboolean multiplayer ) {
00600 StartServer_MenuInit();
00601 s_startserver.multiplayer = multiplayer;
00602 UI_PushMenu( &s_startserver.menu );
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 #define ID_PLAYER_TYPE 20
00616 #define ID_MAXCLIENTS 21
00617 #define ID_DEDICATED 22
00618 #define ID_GO 23
00619 #define ID_BACK 24
00620
00621 #define PLAYER_SLOTS 12
00622
00623
00624 typedef struct {
00625 menuframework_s menu;
00626
00627 menutext_s banner;
00628
00629 menubitmap_s mappic;
00630 menubitmap_s picframe;
00631
00632 menulist_s dedicated;
00633 menufield_s timelimit;
00634 menufield_s fraglimit;
00635 menufield_s flaglimit;
00636 menuradiobutton_s friendlyfire;
00637 menufield_s hostname;
00638 menuradiobutton_s pure;
00639 menulist_s botSkill;
00640
00641 menutext_s player0;
00642 menulist_s playerType[PLAYER_SLOTS];
00643 menutext_s playerName[PLAYER_SLOTS];
00644 menulist_s playerTeam[PLAYER_SLOTS];
00645
00646 menubitmap_s go;
00647 menubitmap_s next;
00648 menubitmap_s back;
00649
00650 qboolean multiplayer;
00651 int gametype;
00652 char mapnamebuffer[32];
00653 char playerNameBuffers[PLAYER_SLOTS][16];
00654
00655 qboolean newBot;
00656 int newBotIndex;
00657 char newBotName[16];
00658
00659 menulist_s punkbuster;
00660 } serveroptions_t;
00661
00662 static serveroptions_t s_serveroptions;
00663
00664 static const char *dedicated_list[] = {
00665 "No",
00666 "LAN",
00667 "Internet",
00668 0
00669 };
00670
00671 static const char *playerType_list[] = {
00672 "Open",
00673 "Bot",
00674 "----",
00675 0
00676 };
00677
00678 static const char *playerTeam_list[] = {
00679 "Blue",
00680 "Red",
00681 0
00682 };
00683
00684 static const char *botSkill_list[] = {
00685 "I Can Win",
00686 "Bring It On",
00687 "Hurt Me Plenty",
00688 "Hardcore",
00689 "Nightmare!",
00690 0
00691 };
00692
00693
00694
00695
00696
00697
00698
00699 static qboolean BotAlreadySelected( const char *checkName ) {
00700 int n;
00701
00702 for( n = 1; n < PLAYER_SLOTS; n++ ) {
00703 if( s_serveroptions.playerType[n].curvalue != 1 ) {
00704 continue;
00705 }
00706 if( (s_serveroptions.gametype >= GT_TEAM) &&
00707 (s_serveroptions.playerTeam[n].curvalue != s_serveroptions.playerTeam[s_serveroptions.newBotIndex].curvalue ) ) {
00708 continue;
00709 }
00710 if( Q_stricmp( checkName, s_serveroptions.playerNameBuffers[n] ) == 0 ) {
00711 return qtrue;
00712 }
00713 }
00714
00715 return qfalse;
00716 }
00717
00718
00719
00720
00721
00722
00723
00724 static void ServerOptions_Start( void ) {
00725 int timelimit;
00726 int fraglimit;
00727 int maxclients;
00728 int dedicated;
00729 int friendlyfire;
00730 int flaglimit;
00731 int pure;
00732 int skill;
00733 int n;
00734 char buf[64];
00735
00736
00737 timelimit = atoi( s_serveroptions.timelimit.field.buffer );
00738 fraglimit = atoi( s_serveroptions.fraglimit.field.buffer );
00739 flaglimit = atoi( s_serveroptions.flaglimit.field.buffer );
00740 dedicated = s_serveroptions.dedicated.curvalue;
00741 friendlyfire = s_serveroptions.friendlyfire.curvalue;
00742 pure = s_serveroptions.pure.curvalue;
00743 skill = s_serveroptions.botSkill.curvalue + 1;
00744
00745
00746 for( n = 0, maxclients = 0; n < PLAYER_SLOTS; n++ ) {
00747 if( s_serveroptions.playerType[n].curvalue == 2 ) {
00748 continue;
00749 }
00750 if( (s_serveroptions.playerType[n].curvalue == 1) && (s_serveroptions.playerNameBuffers[n][0] == 0) ) {
00751 continue;
00752 }
00753 maxclients++;
00754 }
00755
00756 switch( s_serveroptions.gametype ) {
00757 case GT_FFA:
00758 default:
00759 trap_Cvar_SetValue( "ui_ffa_fraglimit", fraglimit );
00760 trap_Cvar_SetValue( "ui_ffa_timelimit", timelimit );
00761 break;
00762
00763 case GT_TOURNAMENT:
00764 trap_Cvar_SetValue( "ui_tourney_fraglimit", fraglimit );
00765 trap_Cvar_SetValue( "ui_tourney_timelimit", timelimit );
00766 break;
00767
00768 case GT_TEAM:
00769 trap_Cvar_SetValue( "ui_team_fraglimit", fraglimit );
00770 trap_Cvar_SetValue( "ui_team_timelimit", timelimit );
00771 trap_Cvar_SetValue( "ui_team_friendlt", friendlyfire );
00772 break;
00773
00774 case GT_CTF:
00775 trap_Cvar_SetValue( "ui_ctf_fraglimit", fraglimit );
00776 trap_Cvar_SetValue( "ui_ctf_timelimit", timelimit );
00777 trap_Cvar_SetValue( "ui_ctf_friendlt", friendlyfire );
00778 break;
00779 }
00780
00781 trap_Cvar_SetValue( "sv_maxclients", Com_Clamp( 0, 12, maxclients ) );
00782 trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, dedicated ) );
00783 trap_Cvar_SetValue ("timelimit", Com_Clamp( 0, timelimit, timelimit ) );
00784 trap_Cvar_SetValue ("fraglimit", Com_Clamp( 0, fraglimit, fraglimit ) );
00785 trap_Cvar_SetValue ("capturelimit", Com_Clamp( 0, flaglimit, flaglimit ) );
00786 trap_Cvar_SetValue( "g_friendlyfire", friendlyfire );
00787 trap_Cvar_SetValue( "sv_pure", pure );
00788 trap_Cvar_Set("sv_hostname", s_serveroptions.hostname.field.buffer );
00789
00790 trap_Cvar_SetValue( "sv_punkbuster", s_serveroptions.punkbuster.curvalue );
00791
00792
00793 trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", s_startserver.maplist[s_startserver.currentmap] ) );
00794
00795
00796 trap_Cmd_ExecuteText( EXEC_APPEND, "wait 3\n" );
00797 for( n = 1; n < PLAYER_SLOTS; n++ ) {
00798 if( s_serveroptions.playerType[n].curvalue != 1 ) {
00799 continue;
00800 }
00801 if( s_serveroptions.playerNameBuffers[n][0] == 0 ) {
00802 continue;
00803 }
00804 if( s_serveroptions.playerNameBuffers[n][0] == '-' ) {
00805 continue;
00806 }
00807 if( s_serveroptions.gametype >= GT_TEAM ) {
00808 Com_sprintf( buf, sizeof(buf), "addbot %s %i %s\n", s_serveroptions.playerNameBuffers[n], skill,
00809 playerTeam_list[s_serveroptions.playerTeam[n].curvalue] );
00810 }
00811 else {
00812 Com_sprintf( buf, sizeof(buf), "addbot %s %i\n", s_serveroptions.playerNameBuffers[n], skill );
00813 }
00814 trap_Cmd_ExecuteText( EXEC_APPEND, buf );
00815 }
00816
00817
00818 if( dedicated == 0 && s_serveroptions.gametype >= GT_TEAM ) {
00819 trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait 5; team %s\n", playerTeam_list[s_serveroptions.playerTeam[0].curvalue] ) );
00820 }
00821 }
00822
00823
00824
00825
00826
00827
00828
00829 static void ServerOptions_InitPlayerItems( void ) {
00830 int n;
00831 int v;
00832
00833
00834 if( s_serveroptions.multiplayer ) {
00835 v = 0;
00836 }
00837 else {
00838 v = 1;
00839 }
00840
00841 for( n = 0; n < PLAYER_SLOTS; n++ ) {
00842 s_serveroptions.playerType[n].curvalue = v;
00843 }
00844
00845 if( s_serveroptions.multiplayer && (s_serveroptions.gametype < GT_TEAM) ) {
00846 for( n = 8; n < PLAYER_SLOTS; n++ ) {
00847 s_serveroptions.playerType[n].curvalue = 2;
00848 }
00849 }
00850
00851
00852 if( s_serveroptions.dedicated.curvalue == 0 ) {
00853
00854 s_serveroptions.playerType[0].generic.flags |= QMF_INACTIVE;
00855 s_serveroptions.playerType[0].curvalue = 0;
00856 trap_Cvar_VariableStringBuffer( "name", s_serveroptions.playerNameBuffers[0], sizeof(s_serveroptions.playerNameBuffers[0]) );
00857 Q_CleanStr( s_serveroptions.playerNameBuffers[0] );
00858 }
00859
00860
00861 if( s_serveroptions.gametype >= GT_TEAM ) {
00862 for( n = 0; n < (PLAYER_SLOTS / 2); n++ ) {
00863 s_serveroptions.playerTeam[n].curvalue = 0;
00864 }
00865 for( ; n < PLAYER_SLOTS; n++ ) {
00866 s_serveroptions.playerTeam[n].curvalue = 1;
00867 }
00868 }
00869 else {
00870 for( n = 0; n < PLAYER_SLOTS; n++ ) {
00871 s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN);
00872 }
00873 }
00874 }
00875
00876
00877
00878
00879
00880
00881
00882 static void ServerOptions_SetPlayerItems( void ) {
00883 int start;
00884 int n;
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 if( s_serveroptions.dedicated.curvalue == 0 ) {
00895 s_serveroptions.player0.string = "Human";
00896 s_serveroptions.playerName[0].generic.flags &= ~QMF_HIDDEN;
00897
00898 start = 1;
00899 }
00900 else {
00901 s_serveroptions.player0.string = "Open";
00902 start = 0;
00903 }
00904 for( n = start; n < PLAYER_SLOTS; n++ ) {
00905 if( s_serveroptions.