codemp/ui/ui_main.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 /*
00004 =======================================================================
00005 
00006 USER INTERFACE MAIN
00007 
00008 =======================================================================
00009 */
00010 
00011 // use this to get a demo build without an explicit demo build, i.e. to get the demo ui files to build
00012 //#define PRE_RELEASE_TADEMO
00013 
00014 #include "../ghoul2/G2.h"
00015 #include "ui_local.h"
00016 #include "../qcommon/qfiles.h"
00017 #include "../qcommon/game_version.h"
00018 #include "ui_force.h"
00019 #include "../cgame/animtable.h" //we want this to be compiled into the module because we access it in the shared module.
00020 #include "../game/bg_saga.h"
00021 
00022 #include "..\cgame\holocronicons.h"
00023 
00024 extern void UI_SaberAttachToChar( itemDef_t *item );
00025 
00026 char *forcepowerDesc[NUM_FORCE_POWERS] = 
00027 {
00028 "@MENUS_OF_EFFECT_JEDI_ONLY_NEFFECT",
00029 "@MENUS_DURATION_IMMEDIATE_NAREA",
00030 "@MENUS_DURATION_5_SECONDS_NAREA",
00031 "@MENUS_DURATION_INSTANTANEOUS",
00032 "@MENUS_INSTANTANEOUS_EFFECT_NAREA",
00033 "@MENUS_DURATION_VARIABLE_20",
00034 "@MENUS_DURATION_INSTANTANEOUS_NAREA",
00035 "@MENUS_OF_EFFECT_LIVING_PERSONS",
00036 "@MENUS_DURATION_VARIABLE_10",
00037 "@MENUS_DURATION_VARIABLE_NAREA",
00038 "@MENUS_DURATION_CONTINUOUS_NAREA",
00039 "@MENUS_OF_EFFECT_JEDI_ALLIES_NEFFECT",
00040 "@MENUS_EFFECT_JEDI_ALLIES_NEFFECT",
00041 "@MENUS_VARIABLE_NAREA_OF_EFFECT",
00042 "@MENUS_EFFECT_NAREA_OF_EFFECT",
00043 "@SP_INGAME_FORCE_SABER_OFFENSE_DESC",
00044 "@SP_INGAME_FORCE_SABER_DEFENSE_DESC",
00045 "@SP_INGAME_FORCE_SABER_THROW_DESC"
00046 };
00047 
00048 // Movedata Sounds
00049 typedef enum
00050 {
00051         MDS_NONE = 0,
00052         MDS_FORCE_JUMP,
00053         MDS_ROLL,
00054         MDS_SABER,
00055         MDS_MOVE_SOUNDS_MAX
00056 };
00057 
00058 typedef enum
00059 {
00060         MD_ACROBATICS = 0,
00061         MD_SINGLE_FAST,
00062         MD_SINGLE_MEDIUM,
00063         MD_SINGLE_STRONG,
00064         MD_DUAL_SABERS,
00065         MD_SABER_STAFF,
00066         MD_MOVE_TITLE_MAX
00067 };
00068 
00069 // Some hard coded badness
00070 // At some point maybe this should be externalized to a .dat file
00071 char *datapadMoveTitleData[MD_MOVE_TITLE_MAX] =
00072 {
00073 "@MENUS_ACROBATICS",
00074 "@MENUS_SINGLE_FAST",
00075 "@MENUS_SINGLE_MEDIUM",
00076 "@MENUS_SINGLE_STRONG",
00077 "@MENUS_DUAL_SABERS",
00078 "@MENUS_SABER_STAFF",
00079 };
00080 
00081 char *datapadMoveTitleBaseAnims[MD_MOVE_TITLE_MAX] =
00082 {
00083 "BOTH_RUN1",
00084 "BOTH_SABERFAST_STANCE",
00085 "BOTH_STAND2",
00086 "BOTH_SABERSLOW_STANCE",
00087 "BOTH_SABERDUAL_STANCE",
00088 "BOTH_SABERSTAFF_STANCE",
00089 };
00090 
00091 #define MAX_MOVES 16
00092 
00093 typedef struct 
00094 {
00095         char    *title; 
00096         char    *desc;  
00097         char    *anim;
00098         short   sound;
00099 } datpadmovedata_t;
00100 
00101 static datpadmovedata_t datapadMoveData[MD_MOVE_TITLE_MAX][MAX_MOVES] = 
00102 {
00103 // Acrobatics
00104 "@MENUS_FORCE_JUMP1",                           "@MENUS_FORCE_JUMP1_DESC",                      "BOTH_FORCEJUMP1",                              MDS_FORCE_JUMP,
00105 "@MENUS_FORCE_FLIP",                            "@MENUS_FORCE_FLIP_DESC",                       "BOTH_FLIP_F",                                  MDS_FORCE_JUMP,
00106 "@MENUS_ROLL",                                          "@MENUS_ROLL_DESC",                                     "BOTH_ROLL_F",                                  MDS_ROLL,
00107 "@MENUS_BACKFLIP_OFF_WALL",                     "@MENUS_BACKFLIP_OFF_WALL_DESC",        "BOTH_WALL_FLIP_BACK1",                 MDS_FORCE_JUMP,
00108 "@MENUS_SIDEFLIP_OFF_WALL",                     "@MENUS_SIDEFLIP_OFF_WALL_DESC",        "BOTH_WALL_FLIP_RIGHT",                 MDS_FORCE_JUMP,
00109 "@MENUS_WALL_RUN",                                      "@MENUS_WALL_RUN_DESC",                         "BOTH_WALL_RUN_RIGHT",                  MDS_FORCE_JUMP,
00110 "@MENUS_WALL_GRAB_JUMP",                        "@MENUS_WALL_GRAB_JUMP_DESC",           "BOTH_FORCEWALLREBOUND_FORWARD",MDS_FORCE_JUMP,
00111 "@MENUS_RUN_UP_WALL_BACKFLIP",          "@MENUS_RUN_UP_WALL_BACKFLIP_DESC",     "BOTH_FORCEWALLRUNFLIP_START",  MDS_FORCE_JUMP,
00112 "@MENUS_JUMPUP_FROM_KNOCKDOWN",         "@MENUS_JUMPUP_FROM_KNOCKDOWN_DESC","BOTH_KNOCKDOWN3",                          MDS_NONE,
00113 "@MENUS_JUMPKICK_FROM_KNOCKDOWN",       "@MENUS_JUMPKICK_FROM_KNOCKDOWN_DESC","BOTH_KNOCKDOWN2",                        MDS_NONE,
00114 "@MENUS_ROLL_FROM_KNOCKDOWN",           "@MENUS_ROLL_FROM_KNOCKDOWN_DESC",      "BOTH_KNOCKDOWN1",                              MDS_NONE,
00115 NULL, NULL, 0,  MDS_NONE,
00116 NULL, NULL, 0,  MDS_NONE,
00117 NULL, NULL, 0,  MDS_NONE,
00118 NULL, NULL, 0,  MDS_NONE,
00119 NULL, NULL, 0,  MDS_NONE,
00120 
00121 //Single Saber, Fast Style
00122 "@MENUS_STAB_BACK",                                     "@MENUS_STAB_BACK_DESC",                        "BOTH_A2_STABBACK1",                    MDS_SABER,
00123 "@MENUS_LUNGE_ATTACK",                          "@MENUS_LUNGE_ATTACK_DESC",                     "BOTH_LUNGE2_B__T_",                    MDS_SABER,
00124 "@MENUS_FAST_ATTACK_KATA",                      "@MENUS_FAST_ATTACK_KATA_DESC",         "BOTH_A1_SPECIAL",                              MDS_SABER,
00125 "@MENUS_ATTACK_ENEMYONGROUND",          "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN",                            MDS_FORCE_JUMP,
00126 "@MENUS_CARTWHEEL",                                     "@MENUS_CARTWHEEL_DESC",                        "BOTH_ARIAL_RIGHT",                             MDS_FORCE_JUMP,
00127 "@MENUS_BOTH_ROLL_STAB",                        "@MENUS_BOTH_ROLL_STAB2_DESC",          "BOTH_ROLL_STAB",                               MDS_SABER,
00128 NULL, NULL, 0,  MDS_NONE,
00129 NULL, NULL, 0,  MDS_NONE,
00130 NULL, NULL, 0,  MDS_NONE,
00131 NULL, NULL, 0,  MDS_NONE,
00132 NULL, NULL, 0,  MDS_NONE,
00133 NULL, NULL, 0,  MDS_NONE,
00134 NULL, NULL, 0,  MDS_NONE,
00135 NULL, NULL, 0,  MDS_NONE,
00136 NULL, NULL, 0,  MDS_NONE,
00137 NULL, NULL, 0,  MDS_NONE,
00138 
00139 //Single Saber, Medium Style
00140 "@MENUS_SLASH_BACK",                            "@MENUS_SLASH_BACK_DESC",                       "BOTH_ATTACK_BACK",                             MDS_SABER,
00141 "@MENUS_FLIP_ATTACK",                           "@MENUS_FLIP_ATTACK_DESC",                      "BOTH_JUMPFLIPSLASHDOWN1",              MDS_FORCE_JUMP,
00142 "@MENUS_MEDIUM_ATTACK_KATA",            "@MENUS_MEDIUM_ATTACK_KATA_DESC",       "BOTH_A2_SPECIAL",                              MDS_SABER,
00143 "@MENUS_ATTACK_ENEMYONGROUND",          "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN",                            MDS_FORCE_JUMP,
00144 "@MENUS_CARTWHEEL",                                     "@MENUS_CARTWHEEL_DESC",                        "BOTH_ARIAL_RIGHT",                             MDS_FORCE_JUMP,
00145 "@MENUS_BOTH_ROLL_STAB",                        "@MENUS_BOTH_ROLL_STAB2_DESC",          "BOTH_ROLL_STAB",                               MDS_SABER,
00146 NULL, NULL, 0,  MDS_NONE,
00147 NULL, NULL, 0,  MDS_NONE,
00148 NULL, NULL, 0,  MDS_NONE,
00149 NULL, NULL, 0,  MDS_NONE,
00150 NULL, NULL, 0,  MDS_NONE,
00151 NULL, NULL, 0,  MDS_NONE,
00152 NULL, NULL, 0,  MDS_NONE,
00153 NULL, NULL, 0,  MDS_NONE,
00154 NULL, NULL, 0,  MDS_NONE,
00155 NULL, NULL, 0,  MDS_NONE,
00156 
00157 //Single Saber, Strong Style
00158 "@MENUS_SLASH_BACK",                            "@MENUS_SLASH_BACK_DESC",                       "BOTH_ATTACK_BACK",                             MDS_SABER,
00159 "@MENUS_JUMP_ATTACK",                           "@MENUS_JUMP_ATTACK_DESC",                      "BOTH_FORCELEAP2_T__B_",                MDS_FORCE_JUMP,
00160 "@MENUS_STRONG_ATTACK_KATA",            "@MENUS_STRONG_ATTACK_KATA_DESC",       "BOTH_A3_SPECIAL",                              MDS_SABER,
00161 "@MENUS_ATTACK_ENEMYONGROUND",          "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN",                            MDS_FORCE_JUMP,
00162 "@MENUS_CARTWHEEL",                                     "@MENUS_CARTWHEEL_DESC",                        "BOTH_ARIAL_RIGHT",                             MDS_FORCE_JUMP,
00163 "@MENUS_BOTH_ROLL_STAB",                        "@MENUS_BOTH_ROLL_STAB2_DESC",          "BOTH_ROLL_STAB",                               MDS_SABER,
00164 NULL, NULL, 0,  MDS_NONE,
00165 NULL, NULL, 0,  MDS_NONE,
00166 NULL, NULL, 0,  MDS_NONE,
00167 NULL, NULL, 0,  MDS_NONE,
00168 NULL, NULL, 0,  MDS_NONE,
00169 NULL, NULL, 0,  MDS_NONE,
00170 NULL, NULL, 0,  MDS_NONE,
00171 NULL, NULL, 0,  MDS_NONE,
00172 NULL, NULL, 0,  MDS_NONE,
00173 NULL, NULL, 0,  MDS_NONE,
00174 
00175 //Dual Sabers
00176 "@MENUS_SLASH_BACK",                            "@MENUS_SLASH_BACK_DESC",                       "BOTH_ATTACK_BACK",                             MDS_SABER,
00177 "@MENUS_FLIP_FORWARD_ATTACK",           "@MENUS_FLIP_FORWARD_ATTACK_DESC",      "BOTH_JUMPATTACK6",                             MDS_FORCE_JUMP,
00178 "@MENUS_DUAL_SABERS_TWIRL",                     "@MENUS_DUAL_SABERS_TWIRL_DESC",        "BOTH_SPINATTACK6",                             MDS_SABER,
00179 "@MENUS_ATTACK_ENEMYONGROUND",          "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN_DUAL",                               MDS_FORCE_JUMP,
00180 "@MENUS_DUAL_SABER_BARRIER",            "@MENUS_DUAL_SABER_BARRIER_DESC",       "BOTH_A6_SABERPROTECT",                 MDS_SABER,
00181 "@MENUS_DUAL_STAB_FRONT_BACK",          "@MENUS_DUAL_STAB_FRONT_BACK_DESC", "BOTH_A6_FB",                                       MDS_SABER,
00182 "@MENUS_DUAL_STAB_LEFT_RIGHT",          "@MENUS_DUAL_STAB_LEFT_RIGHT_DESC", "BOTH_A6_LR",                                       MDS_SABER,
00183 "@MENUS_CARTWHEEL",                                     "@MENUS_CARTWHEEL_DESC",                        "BOTH_ARIAL_RIGHT",                             MDS_FORCE_JUMP,
00184 "@MENUS_BOTH_ROLL_STAB",                        "@MENUS_BOTH_ROLL_STAB_DESC",           "BOTH_ROLL_STAB",                               MDS_SABER,
00185 NULL, NULL, 0,  MDS_NONE,
00186 NULL, NULL, 0,  MDS_NONE,
00187 NULL, NULL, 0,  MDS_NONE,
00188 NULL, NULL, 0,  MDS_NONE,
00189 NULL, NULL, 0,  MDS_NONE,
00190 NULL, NULL, 0,  MDS_NONE,
00191 NULL, NULL, 0,  MDS_NONE,
00192 
00193 // Saber Staff
00194 "@MENUS_STAB_BACK",                                     "@MENUS_STAB_BACK_DESC",                        "BOTH_A2_STABBACK1",                    MDS_SABER,
00195 "@MENUS_BACK_FLIP_ATTACK",                      "@MENUS_BACK_FLIP_ATTACK_DESC",         "BOTH_JUMPATTACK7",                             MDS_FORCE_JUMP,
00196 "@MENUS_SABER_STAFF_TWIRL",                     "@MENUS_SABER_STAFF_TWIRL_DESC",        "BOTH_SPINATTACK7",                             MDS_SABER,
00197 "@MENUS_ATTACK_ENEMYONGROUND",          "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN_STAFF",                      MDS_FORCE_JUMP,
00198 "@MENUS_SPINNING_KATA",                         "@MENUS_SPINNING_KATA_DESC",            "BOTH_A7_SOULCAL",                              MDS_SABER,
00199 "@MENUS_KICK1",                                         "@MENUS_KICK1_DESC",                            "BOTH_A7_KICK_F",                               MDS_FORCE_JUMP,
00200 "@MENUS_JUMP_KICK",                                     "@MENUS_JUMP_KICK_DESC",                        "BOTH_A7_KICK_F_AIR",                   MDS_FORCE_JUMP,
00201 "@MENUS_BUTTERFLY_ATTACK",                      "@MENUS_BUTTERFLY_ATTACK_DESC",         "BOTH_BUTTERFLY_FR1",                   MDS_SABER,
00202 "@MENUS_BOTH_ROLL_STAB",                        "@MENUS_BOTH_ROLL_STAB2_DESC",          "BOTH_ROLL_STAB",                               MDS_SABER,
00203 NULL, NULL, 0,  MDS_NONE,
00204 NULL, NULL, 0,  MDS_NONE,
00205 NULL, NULL, 0,  MDS_NONE,
00206 NULL, NULL, 0,  MDS_NONE,
00207 NULL, NULL, 0,  MDS_NONE,
00208 NULL, NULL, 0,  MDS_NONE,
00209 NULL, NULL, 0,  MDS_NONE,
00210 };
00211 
00212 
00213 /*
00214 ================
00215 vmMain
00216 
00217 This is the only way control passes into the module.
00218 !!! This MUST BE THE VERY FIRST FUNCTION compiled into the .qvm file !!!
00219 ================
00220 */
00221 vmCvar_t  ui_debug;
00222 vmCvar_t  ui_initialized;
00223 vmCvar_t        ui_char_color_red;
00224 vmCvar_t        ui_char_color_green;
00225 vmCvar_t        ui_char_color_blue;
00226 vmCvar_t        ui_PrecacheModels;
00227 vmCvar_t        ui_char_anim;
00228 
00229 void _UI_Init( qboolean );
00230 void _UI_Shutdown( void );
00231 void _UI_KeyEvent( int key, qboolean down );
00232 void _UI_MouseEvent( int dx, int dy );
00233 void _UI_Refresh( int realtime );
00234 qboolean _UI_IsFullscreen( void );
00235 void UI_SetSiegeTeams(void);
00236 extern qboolean UI_SaberModelForSaber( const char *saberName, char *saberModel );
00237 void UI_SiegeSetCvarsForClass(siegeClass_t *scl);
00238 int UI_SiegeClassNum(siegeClass_t *scl);
00239 void UI_UpdateCvarsForClass(const int team,const baseClass,const int index);
00240 void    UI_UpdateSiegeStatusIcons(void);
00241 void UI_ClampMaxPlayers(void);
00242 static void UI_CheckServerName( void );
00243 static qboolean UI_CheckPassword( void );
00244 static void UI_JoinServer( void );
00245 
00246 #include "../namespace_begin.h"
00247 // Functions in BG or ui_shared
00248 void Menu_ShowGroup (menuDef_t *menu, char *itemName, qboolean showFlag);
00249 void Menu_ItemDisable(menuDef_t *menu, char *name,int disableFlag);
00250 int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name);
00251 itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name);
00252 
00253 int BG_GetUIPortrait(const int team, const short classIndex, const short cntIndex);
00254 char *BG_GetUIPortraitFile(const int team, const short classIndex, const short cntIndex);
00255 
00256 siegeClass_t *BG_GetClassOnBaseClass(const int team, const short classIndex, const short cntIndex);
00257 
00258 int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11  ) {
00259   switch ( command ) {
00260           case UI_GETAPIVERSION:
00261                   return UI_API_VERSION;
00262 
00263           case UI_INIT:
00264                   _UI_Init(arg0);
00265                   return 0;
00266 
00267           case UI_SHUTDOWN:
00268                   _UI_Shutdown();
00269                   return 0;
00270 
00271           case UI_KEY_EVENT:
00272                   _UI_KeyEvent( arg0, arg1 );
00273                   return 0;
00274 
00275           case UI_MOUSE_EVENT:
00276                   _UI_MouseEvent( arg0, arg1 );
00277                   return 0;
00278 
00279           case UI_REFRESH:
00280                   _UI_Refresh( arg0 );
00281                   return 0;
00282 
00283           case UI_IS_FULLSCREEN:
00284                   return _UI_IsFullscreen();
00285 
00286           case UI_SET_ACTIVE_MENU:
00287                   _UI_SetActiveMenu( arg0 );
00288                   return 0;
00289 
00290           case UI_CONSOLE_COMMAND:
00291                   return UI_ConsoleCommand(arg0);
00292 
00293           case UI_DRAW_CONNECT_SCREEN:
00294                   UI_DrawConnectScreen( arg0 );
00295                   return 0;
00296           case UI_HASUNIQUECDKEY: // mod authors need to observe this
00297             return qtrue; // bk010117 - change this to qfalse for mods!
00298           case UI_MENU_RESET:
00299                   Menu_Reset();
00300                   return 0;
00301         }
00302 
00303         return -1;
00304 }
00305 #include "../namespace_end.h"
00306 
00307 siegeClassDesc_t g_UIClassDescriptions[MAX_SIEGE_CLASSES];
00308 siegeTeam_t *siegeTeam1 = NULL;
00309 siegeTeam_t *siegeTeam2 = NULL;
00310 int g_UIGloballySelectedSiegeClass = -1;
00311 
00312 //Cut down version of the stuff used in the game code
00313 //This is just the bare essentials of what we need to load animations properly for ui ghoul2 models.
00314 //This function doesn't need to be sync'd with the BG_ version in bg_panimate.c unless some sort of fundamental change
00315 //is made. Just make sure the variables/functions accessed in ui_shared.c exist in both modules.
00316 qboolean        UIPAFtextLoaded = qfalse;
00317 animation_t     uiHumanoidAnimations[MAX_TOTALANIMATIONS]; //humanoid animations are the only ones that are statically allocated.
00318 
00319 #include "../namespace_begin.h"
00320 bgLoadedAnim_t bgAllAnims[MAX_ANIM_FILES];
00321 int uiNumAllAnims = 1; //start off at 0, because 0 will always be assigned to humanoid.
00322 #include "../namespace_end.h"
00323 
00324 animation_t *UI_AnimsetAlloc(void)
00325 {
00326         assert (uiNumAllAnims < MAX_ANIM_FILES);
00327         bgAllAnims[uiNumAllAnims].anims = (animation_t *) BG_Alloc(sizeof(animation_t)*MAX_TOTALANIMATIONS);
00328 
00329         return bgAllAnims[uiNumAllAnims].anims;
00330 }
00331 
00332 /*
00333 ======================
00334 UI_ParseAnimationFile
00335 
00336 Read a configuration file containing animation coutns and rates
00337 models/players/visor/animation.cfg, etc
00338 
00339 ======================
00340 */
00341 #include "../namespace_begin.h"
00342 static char UIPAFtext[60000];
00343 int UI_ParseAnimationFile(const char *filename, animation_t *animset, qboolean isHumanoid) 
00344 {
00345         char            *text_p;
00346         int                     len;
00347         int                     i;
00348         char            *token;
00349         float           fps;
00350         int                     skip;
00351         int                     usedIndex = -1;
00352         int                     nextIndex = uiNumAllAnims;
00353 
00354         fileHandle_t    f;
00355         int                             animNum;
00356 
00357         if (!isHumanoid)
00358         {
00359                 i = 1;
00360                 while (i < uiNumAllAnims)
00361                 { //see if it's been loaded already
00362                         if (!Q_stricmp(bgAllAnims[i].filename, filename))
00363                         {
00364                                 animset = bgAllAnims[i].anims;
00365                                 return i; //alright, we already have it.
00366                         }
00367                         i++;
00368                 }
00369 
00370                 //Looks like it has not yet been loaded. Allocate space for the anim set if we need to, and continue along.
00371                 if (!animset)
00372                 {
00373                         if (strstr(filename, "players/_humanoid/"))
00374                         { //then use the static humanoid set.
00375                                 animset = uiHumanoidAnimations;
00376                                 isHumanoid = qtrue;
00377                                 nextIndex = 0;
00378                         }
00379                         else
00380                         {
00381                                 animset = UI_AnimsetAlloc();
00382 
00383                                 if (!animset)
00384                                 {
00385                                         assert(!"Anim set alloc failed!");
00386                                         return -1;
00387                                 }
00388                         }
00389                 }
00390         }
00391 #ifdef _DEBUG
00392         else
00393         {
00394                 assert(animset);
00395         }
00396 #endif
00397 
00398         // load the file
00399         if (!UIPAFtextLoaded || !isHumanoid)
00400         { //rww - We are always using the same animation config now. So only load it once.
00401                 len = trap_FS_FOpenFile( filename, &f, FS_READ );
00402                 if ( (len <= 0) || (len >= sizeof( UIPAFtext ) - 1) ) 
00403                 {
00404                         if (len > 0)
00405                         {
00406                                 Com_Error(ERR_DROP, "%s exceeds the allowed ui-side animation buffer!", filename);
00407                         }
00408                         return -1;
00409                 }
00410 
00411                 trap_FS_Read( UIPAFtext, len, f );
00412                 UIPAFtext[len] = 0;
00413                 trap_FS_FCloseFile( f );
00414         }
00415         else
00416         {
00417                 return 0; //humanoid index
00418         }
00419 
00420         // parse the text
00421         text_p = UIPAFtext;
00422         skip = 0;       // quiet the compiler warning
00423 
00424         //FIXME: have some way of playing anims backwards... negative numFrames?
00425 
00426         //initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100
00427         for(i = 0; i < MAX_ANIMATIONS; i++)
00428         {
00429                 animset[i].firstFrame = 0;
00430                 animset[i].numFrames = 0;
00431                 animset[i].loopFrames = -1;
00432                 animset[i].frameLerp = 100;
00433 //              animset[i].initialLerp = 100;
00434         }
00435 
00436         // read information for each frame
00437         while(1) 
00438         {
00439                 token = COM_Parse( (const char **)(&text_p) );
00440 
00441                 if ( !token || !token[0]) 
00442                 {
00443                         break;
00444                 }
00445 
00446                 animNum = GetIDForString(animTable, token);
00447                 if(animNum == -1)
00448                 {
00449 //#ifndef FINAL_BUILD
00450 #ifdef _DEBUG
00451                         //Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename);
00452 #endif
00453                         continue;
00454                 }
00455 
00456                 token = COM_Parse( (const char **)(&text_p) );
00457                 if ( !token ) 
00458                 {
00459                         break;
00460                 }
00461                 animset[animNum].firstFrame = atoi( token );
00462 
00463                 token = COM_Parse( (const char **)(&text_p) );
00464                 if ( !token ) 
00465                 {
00466                         break;
00467                 }
00468                 animset[animNum].numFrames = atoi( token );
00469 
00470                 token = COM_Parse( (const char **)(&text_p) );
00471                 if ( !token ) 
00472                 {
00473                         break;
00474                 }
00475                 animset[animNum].loopFrames = atoi( token );
00476 
00477                 token = COM_Parse( (const char **)(&text_p) );
00478                 if ( !token ) 
00479                 {
00480                         break;
00481                 }
00482                 fps = atof( token );
00483                 if ( fps == 0 ) 
00484                 {
00485                         fps = 1;//Don't allow divide by zero error
00486                 }
00487                 if ( fps < 0 )
00488                 {//backwards
00489                         animset[animNum].frameLerp = floor(1000.0f / fps);
00490                 }
00491                 else
00492                 {
00493                         animset[animNum].frameLerp = ceil(1000.0f / fps);
00494                 }
00495 
00496 //              animset[animNum].initialLerp = ceil(1000.0f / fabs(fps));
00497         }
00498 
00499 #ifdef _DEBUG
00500         //Check the array, and print the ones that have nothing in them.
00501         /*
00502         for(i = 0; i < MAX_ANIMATIONS; i++)
00503         {       
00504                 if (animTable[i].name != NULL)          // This animation reference exists.
00505                 {
00506                         if (animset[i].firstFrame <= 0 && animset[i].numFrames <=0)
00507                         {       // This is an empty animation reference.
00508                                 Com_Printf("***ANIMTABLE reference #%d (%s) is empty!\n", i, animTable[i].name);
00509                         }
00510                 }
00511         }
00512         */
00513 #endif // _DEBUG
00514 
00515         if (isHumanoid)
00516         {
00517                 bgAllAnims[0].anims = animset;
00518                 strcpy(bgAllAnims[0].filename, filename);
00519                 UIPAFtextLoaded = qtrue;
00520 
00521                 usedIndex = 0;
00522         }
00523         else
00524         {
00525                 bgAllAnims[nextIndex].anims = animset;
00526                 strcpy(bgAllAnims[nextIndex].filename, filename);
00527 
00528                 usedIndex = nextIndex;
00529 
00530                 if (nextIndex)
00531                 { //don't bother increasing the number if this ended up as a humanoid load.
00532                         uiNumAllAnims++;
00533                 }
00534                 else
00535                 {
00536                         UIPAFtextLoaded = qtrue;
00537                         usedIndex = 0;
00538                 }
00539         }
00540 
00541         return usedIndex;
00542 }
00543 
00544 //menuDef_t *Menus_FindByName(const char *p);
00545 void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow);
00546 
00547 #include "../namespace_end.h"
00548 
00549 void UpdateForceUsed();
00550 
00551 char holdSPString[MAX_STRING_CHARS]={0};
00552 char holdSPString2[MAX_STRING_CHARS]={0};
00553 
00554 uiInfo_t uiInfo;
00555 
00556 static void UI_StartServerRefresh(qboolean full);
00557 static void UI_StopServerRefresh( void );
00558 static void UI_DoServerRefresh( void );
00559 static void UI_BuildServerDisplayList(qboolean force);
00560 static void UI_BuildServerStatus(qboolean force);
00561 static void UI_BuildFindPlayerList(qboolean force);
00562 static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 );
00563 static int UI_MapCountByGameType(qboolean singlePlayer);
00564 static int UI_HeadCountByColor( void );
00565 static void UI_ParseGameInfo(const char *teamFile);
00566 static const char *UI_SelectedMap(int index, int *actual);
00567 static int UI_GetIndexFromSelection(int actual);
00568 static void UI_SiegeClassCnt( const int team );
00569 
00570 
00571 int ProcessNewUI( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 );
00572 int     uiSkinColor=TEAM_FREE;
00573 int     uiHoldSkinColor=TEAM_FREE;      // Stores the skin color so that in non-team games, the player screen remembers the team you chose, in case you're coming back from the force powers screen.
00574 
00575 static const serverFilter_t serverFilters[] = {
00576         {"MENUS_ALL", "" },
00577         {"MENUS_JEDI_ACADEMY", "" },
00578 };
00579 static const int numServerFilters = sizeof(serverFilters) / sizeof(serverFilter_t);
00580 
00581 static const char *skillLevels[] = {
00582   "SKILL1",//"I Can Win",
00583   "SKILL2",//"Bring It On",
00584   "SKILL3",//"Hurt Me Plenty",
00585   "SKILL4",//"Hardcore",
00586   "SKILL5"//"Nightmare"
00587 };
00588 static const int numSkillLevels = sizeof(skillLevels) / sizeof(const char*);
00589 
00590 
00591 
00592 static const char *teamArenaGameTypes[] = {
00593         "FFA",
00594         "Holocron",
00595         "JediMaster",
00596         "Duel",
00597         "PowerDuel",
00598         "SP",
00599         "Team FFA",
00600         "Siege",
00601         "CTF",
00602         "CTY",
00603         "TeamTournament"
00604 };
00605 static int const numTeamArenaGameTypes = sizeof(teamArenaGameTypes) / sizeof(const char*);
00606 
00607 
00608 
00609 static char* netnames[] = {
00610         "???",
00611         "UDP",
00612         "IPX",
00613         NULL
00614 };
00615 
00616 static int gamecodetoui[] = {4,2,3,0,5,1,6};
00617 static int uitogamecode[] = {4,6,2,3,1,5,7};
00618 
00619 const char *UI_GetStringEdString(const char *refSection, const char *refName);
00620 
00621 const char *UI_TeamName(int team)  {
00622         if (team==TEAM_RED)
00623                 return "RED";
00624         else if (team==TEAM_BLUE)
00625                 return "BLUE";
00626         else if (team==TEAM_SPECTATOR)
00627                 return "SPECTATOR";
00628         return "FREE";
00629 }
00630 
00631 // returns either string or NULL for OOR...
00632 //
00633 static const char *GetCRDelineatedString( const char *psStripFileRef, const char *psStripStringRef, int iIndex)
00634 {
00635         static char sTemp[256];
00636         const char *psList = UI_GetStringEdString(psStripFileRef, psStripStringRef);
00637         char *p;
00638 
00639         while (iIndex--)
00640         {
00641                 psList = strchr(psList,'\n');
00642                 if (!psList){
00643                         return NULL;    // OOR
00644                 }
00645                 psList++;
00646         }
00647 
00648         strcpy(sTemp,psList);
00649         p = strchr(sTemp,'\n');
00650         if (p) {
00651                 *p = '\0';
00652         }
00653 
00654         return sTemp;
00655 }
00656 
00657 
00658 static const char *GetMonthAbbrevString( int iMonth )
00659 {
00660         const char *p = GetCRDelineatedString("MP_INGAME","MONTHS", iMonth);
00661         
00662         return p ? p : "Jan";   // sanity
00663 }
00664 
00665 
00666 
00667 
00668 /*
00669 static const char *netSources[] = {
00670         "Local",
00671         "Internet",
00672         "Favorites"
00673 //      "Mplayer"
00674 };
00675 static const int numNetSources = sizeof(netSources) / sizeof(const char*);
00676 */
00677 static const int numNetSources = 3;     // now hard-entered in StringEd file
00678 static const char *GetNetSourceString(int iSource)
00679 {
00680         const char *p = GetCRDelineatedString("MP_INGAME","NET_SOURCES", iSource);
00681 
00682         return p ? p : "??";
00683 }
00684 
00685 
00686 
00687 
00688 void AssetCache() {
00689         int n;
00690         //if (Assets.textFont == NULL) {
00691         //}
00692         //Assets.background = trap_R_RegisterShaderNoMip( ASSET_BACKGROUND );
00693         //Com_Printf("Menu Size: %i bytes\n", sizeof(Menus));
00694         uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
00695         uiInfo.uiDC.Assets.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE );
00696         uiInfo.uiDC.Assets.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED );
00697         uiInfo.uiDC.Assets.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_ORANGE );//trap_R_RegisterShaderNoMip( ART_FX_YELLOW );
00698         uiInfo.uiDC.Assets.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW );//trap_R_RegisterShaderNoMip( ART_FX_GREEN );
00699         uiInfo.uiDC.Assets.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_GREEN );//trap_R_RegisterShaderNoMip( ART_FX_TEAL );
00700         uiInfo.uiDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE );
00701         uiInfo.uiDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_PURPLE );//trap_R_RegisterShaderNoMip( ART_FX_CYAN );
00702         uiInfo.uiDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE );
00703         uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
00704         uiInfo.uiDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
00705         uiInfo.uiDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
00706         uiInfo.uiDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
00707         uiInfo.uiDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
00708         uiInfo.uiDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
00709         uiInfo.uiDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
00710         uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
00711 
00712         // Icons for various server settings.
00713         uiInfo.uiDC.Assets.needPass = trap_R_RegisterShaderNoMip( "gfx/menus/needpass" );
00714         uiInfo.uiDC.Assets.noForce = trap_R_RegisterShaderNoMip( "gfx/menus/noforce" );
00715         uiInfo.uiDC.Assets.forceRestrict = trap_R_RegisterShaderNoMip( "gfx/menus/forcerestrict" );
00716         uiInfo.uiDC.Assets.saberOnly = trap_R_RegisterShaderNoMip( "gfx/menus/saberonly" );
00717         uiInfo.uiDC.Assets.trueJedi = trap_R_RegisterShaderNoMip( "gfx/menus/truejedi" );
00718                                                         
00719         for( n = 0; n < NUM_CROSSHAIRS; n++ ) {
00720                 uiInfo.uiDC.Assets.crosshairShader[n] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) );
00721         }
00722 
00723         uiInfo.newHighScoreSound = 0;//trap_S_RegisterSound("sound/feedback/voc_newhighscore.wav");
00724 }
00725 
00726 void _UI_DrawSides(float x, float y, float w, float h, float size) {
00727         size *= uiInfo.uiDC.xscale;
00728         trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00729         trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00730 }
00731 
00732 void _UI_DrawTopBottom(float x, float y, float w, float h, float size) {
00733         size *= uiInfo.uiDC.yscale;
00734         trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00735         trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00736 }
00737 /*
00738 ================
00739 UI_DrawRect
00740 
00741 Coordinates are 640*480 virtual values
00742 =================
00743 */
00744 void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
00745         trap_R_SetColor( color );
00746 
00747   _UI_DrawTopBottom(x, y, width, height, size);
00748   _UI_DrawSides(x, y, width, height, size);
00749 
00750         trap_R_SetColor( NULL );
00751 }
00752 
00753 #include "../namespace_begin.h"
00754 int MenuFontToHandle(int iMenuFont)
00755 {
00756         switch (iMenuFont)
00757         {
00758                 case 1: return uiInfo.uiDC.Assets.qhSmallFont;
00759                 case 2: return uiInfo.uiDC.Assets.qhMediumFont;
00760                 case 3: return uiInfo.uiDC.Assets.qhBigFont;
00761                 case 4: return uiInfo.uiDC.Assets.qhSmall2Font;
00762         }
00763 
00764         return uiInfo.uiDC.Assets.qhMediumFont; // 0;
00765 }
00766 #include "../namespace_end.h"
00767 
00768 int Text_Width(const char *text, float scale, int iMenuFont) 
00769 {       
00770         int iFontIndex = MenuFontToHandle(iMenuFont);
00771 
00772         return trap_R_Font_StrLenPixels(text, iFontIndex, scale);
00773 }
00774 
00775 int Text_Height(const char *text, float scale, int iMenuFont) 
00776 {
00777         int iFontIndex = MenuFontToHandle(iMenuFont);
00778 
00779         return trap_R_Font_HeightPixels(iFontIndex, scale);
00780 }
00781 
00782 void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style, int iMenuFont)
00783 {
00784         int iStyleOR = 0;
00785 
00786         int iFontIndex = MenuFontToHandle(iMenuFont);
00787         //
00788         // kludge.. convert JK2 menu styles to SOF2 printstring ctrl codes...
00789         //      
00790         switch (style)
00791         {
00792         case  ITEM_TEXTSTYLE_NORMAL:                    iStyleOR = 0;break;                                     // JK2 normal text
00793         case  ITEM_TEXTSTYLE_BLINK:                             iStyleOR = (int)STYLE_BLINK;break;              // JK2 fast blinking
00794         case  ITEM_TEXTSTYLE_PULSE:                             iStyleOR = (int)STYLE_BLINK;break;              // JK2 slow pulsing
00795         case  ITEM_TEXTSTYLE_SHADOWED:                  iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
00796         case  ITEM_TEXTSTYLE_OUTLINED:                  iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
00797         case  ITEM_TEXTSTYLE_OUTLINESHADOWED:   iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
00798         case  ITEM_TEXTSTYLE_SHADOWEDMORE:              iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
00799         }
00800 
00801         trap_R_Font_DrawString( x,              // int ox
00802                                                         y,              // int oy
00803                                                         text,   // const char *text
00804                                                         color,  // paletteRGBA_c c
00805                                                         iStyleOR | iFontIndex,  // const int iFontHandle
00806                                                         !limit?-1:limit,                // iCharLimit (-1 = none)
00807                                                         scale   // const float scale = 1.0f
00808                                                         );
00809 }
00810 
00811 
00812 void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style, int iMenuFont) 
00813 {
00814         Text_Paint(x, y, scale, color, text, 0, limit, style, iMenuFont);
00815 
00816         // now print the cursor as well...  (excuse the braces, it's for porting C++ to C)
00817         //
00818         {
00819                 char sTemp[1024];
00820                 int iCopyCount = limit ? min(strlen(text), limit) : strlen(text);
00821                         iCopyCount = min(iCopyCount,cursorPos);
00822                         iCopyCount = min(iCopyCount,sizeof(sTemp));
00823 
00824                         // copy text into temp buffer for pixel measure...
00825                         //                      
00826                         strncpy(sTemp,text,iCopyCount);
00827                                         sTemp[iCopyCount] = '\0';
00828 
00829                         {
00830                                 int iFontIndex = MenuFontToHandle( iMenuFont ); 
00831                                 int iNextXpos  = trap_R_Font_StrLenPixels(sTemp, iFontIndex, scale );
00832 
00833                                 Text_Paint(x+iNextXpos, y, scale, color, va("%c",cursor), 0, limit, style|ITEM_TEXTSTYLE_BLINK, iMenuFont);
00834                         }
00835         }
00836 }
00837 
00838 
00839 // maxX param is initially an X limit, but is also used as feedback. 0 = text was clipped to fit within, else maxX = next pos
00840 //
00841 static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char* text, float adjust, int limit, int iMenuFont) 
00842 {
00843         // this is kinda dirty, but...
00844         //
00845         int iFontIndex = MenuFontToHandle(iMenuFont);
00846         
00847         //float fMax = *maxX;
00848         int iPixelLen = trap_R_Font_StrLenPixels(text, iFontIndex, scale);
00849         if (x + iPixelLen > *maxX)
00850         {
00851                 // whole text won't fit, so we need to print just the amount that does...
00852                 //  Ok, this is slow and tacky, but only called occasionally, and it works...
00853                 //
00854                 char sTemp[4096]={0};   // lazy assumption
00855                 const char *psText = text;
00856                 char *psOut = &sTemp[0];
00857                 char *psOutLastGood = psOut;
00858                 unsigned int uiLetter;
00859 
00860                 while (*psText && (x + trap_R_Font_StrLenPixels(sTemp, iFontIndex, scale)<=*maxX) 
00861                            && psOut < &sTemp[sizeof(sTemp)-1]   // sanity
00862                                 )
00863                 {
00864                         int iAdvanceCount;
00865                         psOutLastGood = psOut;
00866                         
00867                         uiLetter = trap_AnyLanguage_ReadCharFromString(psText, &iAdvanceCount, NULL);
00868                         psText += iAdvanceCount;
00869 
00870                         if (uiLetter > 255)
00871                         {
00872                                 *psOut++ = uiLetter>>8;
00873                                 *psOut++ = uiLetter&0xFF;
00874                         }
00875                         else
00876                         {
00877                                 *psOut++ = uiLetter&0xFF;
00878                         }
00879                 }
00880                 *psOutLastGood = '\0';
00881 
00882                 *maxX = 0;      // feedback
00883                 Text_Paint(x, y, scale, color, sTemp, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
00884         }
00885         else
00886         {
00887                 // whole text fits fine, so print it all...
00888                 //
00889                 *maxX = x + iPixelLen;  // feedback the next position, as the caller expects            
00890                 Text_Paint(x, y, scale, color, text, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
00891         }
00892 }
00893 
00894 
00895 void UI_ShowPostGame(qboolean newHigh) {
00896         trap_Cvar_Set ("cg_cameraOrbit", "0");
00897         trap_Cvar_Set("cg_thirdPerson", "0");
00898         trap_Cvar_Set( "sv_killserver", "1" );
00899         uiInfo.soundHighScore = newHigh;
00900   _UI_SetActiveMenu(UIMENU_POSTGAME);
00901 }
00902 /*
00903 =================
00904 _UI_Refresh
00905 =================
00906 */
00907 
00908 void UI_DrawCenteredPic(qhandle_t image, int w, int h) {
00909   int x, y;
00910   x = (SCREEN_WIDTH - w) / 2;
00911   y = (SCREEN_HEIGHT - h) / 2;
00912   UI_DrawHandlePic(x, y, w, h, image);
00913 }
00914 
00915 int frameCount = 0;
00916 int startTime;
00917 
00918 vmCvar_t        ui_rankChange;
00919 static void UI_BuildPlayerList();
00920 char parsedFPMessage[1024];
00921 
00922 #include "../namespace_begin.h"
00923 extern int FPMessageTime;
00924 #include "../namespace_end.h"
00925 
00926 void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust, int iMenuFont);
00927 
00928 const char *UI_GetStringEdString(const char *refSection, const char *refName)
00929 {
00930         static char text[1024]={0};
00931 
00932         trap_SP_GetStringTextString(va("%s_%s", refSection, refName), text, sizeof(text));
00933         return text;
00934 }
00935 
00936 #define UI_FPS_FRAMES   4
00937 void _UI_Refresh( int realtime )
00938 {
00939         static int index;
00940         static int      previousTimes[UI_FPS_FRAMES];
00941 
00942         //if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
00943         //      return;
00944         //}
00945 
00946         trap_G2API_SetTime(realtime, 0);
00947         trap_G2API_SetTime(realtime, 1);
00948         //ghoul2 timer must be explicitly updated during ui rendering.
00949 
00950         uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime;
00951         uiInfo.uiDC.realTime = realtime;
00952 
00953         previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime;
00954         index++;
00955         if ( index > UI_FPS_FRAMES ) {
00956                 int i, total;
00957                 // average multiple frames together to smooth changes out a bit
00958                 total = 0;
00959                 for ( i = 0 ; i < UI_FPS_FRAMES ; i++ ) {
00960                         total += previousTimes[i];
00961                 }
00962                 if ( !total ) {
00963                         total = 1;
00964                 }
00965                 uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total;
00966         }
00967 
00968 
00969 
00970         UI_UpdateCvars();
00971 
00972         if (Menu_Count() > 0) {
00973                 // paint all the menus
00974                 Menu_PaintAll();
00975                 // refresh server browser list
00976                 UI_DoServerRefresh();
00977                 // refresh server status
00978                 UI_BuildServerStatus(qfalse);
00979                 // refresh find player list
00980                 UI_BuildFindPlayerList(qfalse);
00981         } 
00982 #ifndef _XBOX   
00983         // draw cursor
00984         UI_SetColor( NULL );
00985         if (Menu_Count() > 0) {
00986                 UI_DrawHandlePic( uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory, 48, 48, uiInfo.uiDC.Assets.cursor);
00987         }
00988 #endif
00989 
00990 #ifndef NDEBUG
00991         if (uiInfo.uiDC.debug)
00992         {
00993                 // cursor coordinates
00994                 //FIXME
00995                 //UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed );
00996         }
00997 #endif
00998 
00999         if (ui_rankChange.integer)
01000         {
01001                 FPMessageTime = realtime + 3000;
01002 
01003                 if (!parsedFPMessage[0] /*&& uiMaxRank > ui_rankChange.integer*/)
01004                 {
01005                         const char *printMessage = UI_GetStringEdString("MP_INGAME", "SET_NEW_RANK");
01006 
01007                         int i = 0;
01008                         int p = 0;
01009                         int linecount = 0;
01010 
01011                         while (printMessage[i] && p < 1024)
01012                         {
01013                                 parsedFPMessage[p] = printMessage[i];
01014                                 p++;
01015                                 i++;
01016                                 linecount++;
01017 
01018                                 if (linecount > 64 && printMessage[i] == ' ')
01019                                 {
01020                                         parsedFPMessage[p] = '\n';
01021                                         p++;
01022                                         linecount = 0;
01023                                 }
01024                         }
01025                         parsedFPMessage[p] = '\0';
01026                 }
01027 
01028                 //if (uiMaxRank > ui_rankChange.integer)
01029                 {
01030                         uiMaxRank = ui_rankChange.integer;
01031                         uiForceRank = uiMaxRank;
01032 
01033                         /*
01034                         while (x < NUM_FORCE_POWERS)
01035                         {
01036                                 //For now just go ahead and clear force powers upon rank change
01037                                 uiForcePowersRank[x] = 0;
01038                                 x++;
01039                         }
01040                         uiForcePowersRank[FP_LEVITATION] = 1;
01041                         uiForceUsed = 0;
01042                         */
01043 
01044                         //Use BG_LegalizedForcePowers and transfer the result into the UI force settings
01045                         UI_ReadLegalForce();
01046                 }
01047 
01048                 if (ui_freeSaber.integer && uiForcePowersRank[FP_SABER_OFFENSE] < 1)
01049                 {
01050                         uiForcePowersRank[FP_SABER_OFFENSE] = 1;
01051                 }
01052                 if (ui_freeSaber.integer && uiForcePowersRank[FP_SABER_DEFENSE] < 1)
01053                 {
01054                         uiForcePowersRank[FP_SABER_DEFENSE] = 1;
01055                 }
01056                 trap_Cvar_Set("ui_rankChange", "0");
01057 
01058                 //remember to update the force power count after changing the max rank
01059                 UpdateForceUsed();
01060         }
01061 
01062         if (ui_freeSaber.integer)
01063         {
01064                 bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 0;
01065                 bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 0;
01066         }
01067         else
01068         {
01069                 bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 1;
01070                 bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 1;
01071         }
01072 
01073         /*
01074         if (parsedFPMessage[0] && FPMessageTime > realtime)
01075         {
01076                 vec4_t txtCol;
01077                 int txtStyle = ITEM_TEXTSTYLE_SHADOWED;
01078 
01079                 if ((FPMessageTime - realtime) < 2000)
01080                 {
01081                         txtCol[0] = colorWhite[0];
01082                         txtCol[1] = colorWhite[1];
01083                         txtCol[2] = colorWhite[2];
01084                         txtCol[3] = (((float)FPMessageTime - (float)realtime)/2000);
01085 
01086                         txtStyle = 0;
01087                 }
01088                 else
01089                 {
01090                         txtCol[0] = colorWhite[0];
01091                         txtCol[1] = colorWhite[1];
01092                         txtCol[2] = colorWhite[2];
01093                         txtCol[3] = colorWhite[3];
01094                 }
01095 
01096                 Text_Paint(10, 0, 1, txtCol, parsedFPMessage, 0, 1024, txtStyle, FONT_MEDIUM);
01097         }
01098         */
01099         //For now, don't bother.
01100 }
01101 
01102 /*
01103 =================
01104 _UI_Shutdown
01105 =================
01106 */
01107 #include "../namespace_begin.h"
01108 void UI_CleanupGhoul2(void);
01109 #include "../namespace_end.h"
01110 
01111 void _UI_Shutdown( void ) {
01112         trap_LAN_SaveCachedServers();
01113         UI_CleanupGhoul2();
01114 }
01115 
01116 char *defaultMenu = NULL;
01117 
01118 char *GetMenuBuffer(const char *filename) {
01119         int     len;
01120         fileHandle_t    f;
01121         static char buf[MAX_MENUFILE];
01122 
01123         len = trap_FS_FOpenFile( filename, &f, FS_READ );
01124         if ( !f ) {
01125                 trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
01126                 return defaultMenu;
01127         }
01128         if ( len >= MAX_MENUFILE ) {
01129                 trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) );
01130                 trap_FS_FCloseFile( f );
01131                 return defaultMenu;
01132         }
01133 
01134         trap_FS_Read( buf, len, f );
01135         buf[len] = 0;
01136         trap_FS_FCloseFile( f );
01137         //COM_Compress(buf);
01138   return buf;
01139 
01140 }
01141 
01142 qboolean Asset_Parse(int handle) {
01143         pc_token_t token;
01144 
01145         if (!trap_PC_ReadToken(handle, &token))
01146                 return qfalse;
01147         if (Q_stricmp(token.string, "{") != 0) {
01148                 return qfalse;
01149         }
01150     
01151         while ( 1 ) {
01152 
01153                 memset(&token, 0, sizeof(pc_token_t));
01154 
01155                 if (!trap_PC_ReadToken(handle, &token))
01156                         return qfalse;
01157 
01158                 if (Q_stricmp(token.string, "}") == 0) {
01159                         return qtrue;
01160                 }
01161 
01162                 // font
01163                 if (Q_stricmp(token.string, "font") == 0) {
01164                         int pointSize;
01165                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
01166                                 return qfalse;
01167                         }                       
01168                         //trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont);
01169                         uiInfo.uiDC.Assets.qhMediumFont = trap_R_RegisterFont(token.string);
01170                         uiInfo.uiDC.Assets.fontRegistered = qtrue;
01171                         continue;
01172                 }
01173 
01174                 if (Q_stricmp(token.string, "smallFont") == 0) {
01175                         int pointSize;
01176                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
01177                                 return qfalse;
01178                         }
01179                         //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.smallFont);
01180                         uiInfo.uiDC.Assets.qhSmallFont = trap_R_RegisterFont(token.string);
01181                         continue;
01182                 }
01183 
01184                 if (Q_stricmp(token.string, "small2Font") == 0) {
01185                         int pointSize;
01186                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
01187                                 return qfalse;
01188                         }
01189                         //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.smallFont);
01190                         uiInfo.uiDC.Assets.qhSmall2Font = trap_R_RegisterFont(token.string);
01191                         continue;
01192                 }
01193 
01194                 if (Q_stricmp(token.string, "bigFont") == 0) {
01195                         int pointSize;
01196                         if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
01197                                 return qfalse;
01198                         }
01199                         //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.bigFont);
01200                         uiInfo.uiDC.Assets.qhBigFont = trap_R_RegisterFont(token.string);
01201                         continue;
01202                 }
01203 
01204                 if (Q_stricmp(token.string, "cursor") == 0) 
01205                 {
01206                         if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr))
01207                         {
01208                                 Com_Printf(S_COLOR_YELLOW,"Bad 1st parameter for keyword 'cursor'");
01209                                 return qfalse;
01210                         }
01211                         uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr);
01212                         continue;
01213                 }
01214 
01215                 // gradientbar
01216                 if (Q_stricmp(token.string, "gradientbar") == 0) {
01217                         if (!trap_PC_ReadToken(handle, &token)) {
01218                                 return qfalse;
01219                         }
01220                         uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(token.string);
01221                         continue;
01222                 }
01223 
01224                 // enterMenuSound
01225                 if (Q_stricmp(token.string, "menuEnterSound") == 0) {
01226                         if (!trap_PC_ReadToken(handle, &token)) {
01227                                 return qfalse;
01228                         }
01229                         uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( token.string );
01230                         continue;
01231                 }
01232 
01233                 // exitMenuSound
01234                 if (Q_stricmp(token.string, "menuExitSound") == 0) {
01235                         if (!trap_PC_ReadToken(handle, &token)) {
01236                                 return qfalse;
01237                         }
01238                         uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( token.string );
01239                         continue;
01240                 }
01241 
01242                 // itemFocusSound
01243                 if (Q_stricmp(token.string, "itemFocusSound") == 0) {
01244                         if (!trap_PC_ReadToken(handle, &token)) {
01245                                 return qfalse;
01246                         }
01247                         uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( token.string );
01248                         continue;
01249                 }
01250 
01251                 // menuBuzzSound
01252                 if (Q_stricmp(token.string, "menuBuzzSound") == 0) {
01253                         if (!trap_PC_ReadToken(handle, &token)) {
01254                                 return qfalse;
01255                         }
01256                         uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( token.string );
01257                         continue;
01258                 }
01259 
01260                 if (Q_stricmp(token.string, "fadeClamp") == 0) {
01261                         if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp)) {
01262                                 return qfalse;
01263                         }
01264                         continue;
01265                 }
01266 
01267                 if (Q_stricmp(token.string, "fadeCycle") == 0) {
01268                         if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle)) {
01269                                 return qfalse;
01270                         }
01271                         continue;
01272                 }
01273 
01274                 if (Q_stricmp(token.string, "fadeAmount") == 0) {
01275                         if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount)) {
01276                                 return qfalse;
01277                         }
01278                         continue;
01279                 }
01280 
01281                 if (Q_stricmp(token.string, "shadowX") == 0) {
01282                         if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX)) {
01283                                 return qfalse;
01284                         }
01285                         continue;
01286                 }
01287 
01288                 if (Q_stricmp(token.string, "shadowY") == 0) {
01289                         if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY)) {
01290                                 return qfalse;
01291                         }
01292                         continue;
01293                 }
01294 
01295                 if (Q_stricmp(token.string, "shadowColor") == 0) {
01296                         if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor)) {
01297                                 return qfalse;
01298                         }
01299                         uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3];
01300                         continue;
01301                 }
01302 
01303                 if (Q_stricmp(token.string, "moveRollSound") == 0) 
01304                 {
01305                         if (trap_PC_ReadToken(handle,&token))
01306                         {
01307                                 uiInfo.uiDC.Assets.moveRollSound = trap_S_RegisterSound( token.string );
01308                         }
01309                         continue;
01310                 }
01311 
01312                 if (Q_stricmp(token.string, "moveJumpSound") == 0) 
01313                 {
01314                         if (trap_PC_ReadToken(handle,&token))
01315                         {
01316                                 uiInfo.uiDC.Assets.moveJumpSound = trap_S_RegisterSound( token.string );
01317                         }
01318 
01319                         continue;
01320                 }
01321                 if (Q_stricmp(token.string, "datapadmoveSaberSound1") == 0) 
01322                 {
01323                         if (trap_PC_ReadToken(handle,&token))
01324                         {
01325                                 uiInfo.uiDC.Assets.datapadmoveSaberSound1 = trap_S_RegisterSound( token.string );
01326                         }
01327 
01328                         continue;
01329                 }
01330 
01331                 if (Q_stricmp(token.string, "datapadmoveSaberSound2") == 0) 
01332                 {
01333                         if (trap_PC_ReadToken(handle,&token))
01334                         {
01335                                 uiInfo.uiDC.Assets.datapadmoveSaberSound2 = trap_S_RegisterSound( token.string );
01336                         }
01337 
01338                         continue;
01339                 }
01340 
01341                 if (Q_stricmp(token.string, "datapadmoveSaberSound3") == 0) 
01342                 {
01343                         if (trap_PC_ReadToken(handle,&token))
01344                         {
01345                                 uiInfo.uiDC.Assets.datapadmoveSaberSound3 = trap_S_RegisterSound( token.string );
01346                         }
01347 
01348                         continue;
01349                 }
01350 
01351                 if (Q_stricmp(token.string, "datapadmoveSaberSound4") == 0) 
01352                 {
01353                         if (trap_PC_ReadToken(handle,&token))
01354                         {
01355                                 uiInfo.uiDC.Assets.datapadmoveSaberSound4 = trap_S_RegisterSound( token.string );
01356                         }
01357 
01358                         continue;
01359                 }
01360 
01361                 if (Q_stricmp(token.string, "datapadmoveSaberSound5") == 0) 
01362                 {
01363                         if (trap_PC_ReadToken(handle,&token))
01364                         {
01365                                 uiInfo.uiDC.Assets.datapadmoveSaberSound5 = trap_S_RegisterSound( token.string );
01366                         }
01367 
01368                         continue;
01369                 }
01370 
01371                 if (Q_stricmp(token.string, "datapadmoveSaberSound6") == 0) 
01372                 {
01373                         if (trap_PC_ReadToken(handle,&token))
01374                         {
01375                                 uiInfo.uiDC.Assets.datapadmoveSaberSound6 = trap_S_RegisterSound( token.string );
01376                         }
01377 
01378                         continue;
01379                 }
01380 
01381 
01382                 // precaching various sound files used in the menus
01383                 if (Q_stricmp(token.string, "precacheSound") == 0)
01384                 {
01385                         const char *tempStr;
01386                         if (PC_Script_Parse(handle, &tempStr)) 
01387                         {
01388                                 char *soundFile;
01389                                 do
01390                                 {
01391                                         soundFile = COM_ParseExt(&tempStr, qfalse);     
01392                                         if (soundFile[0] != 0 && soundFile[0] != ';') {
01393                                                 trap_S_RegisterSound( soundFile);
01394                                         }
01395                                 } while (soundFile[0]);
01396                         }
01397                         continue;
01398                 }
01399         }
01400         return qfalse;
01401 }
01402 
01403 
01404 void UI_Report() {
01405   String_Report();
01406   //Font_Report();
01407 
01408 }
01409 
01410 void UI_ParseMenu(const char *menuFile) {
01411         int handle;
01412         pc_token_t token;
01413 
01414         //Com_Printf("Parsing menu file: %s\n", menuFile);
01415 
01416         handle = trap_PC_LoadSource(menuFile);
01417         if (!handle) {
01418                 return;
01419         }
01420 
01421         while ( 1 ) {
01422                 memset(&token, 0, sizeof(pc_token_t));
01423                 if (!trap_PC_ReadToken( handle, &token )) {
01424                         break;
01425                 }
01426 
01427                 //if ( Q_stricmp( token, "{" ) ) {
01428                 //      Com_Printf( "Missing { in menu file\n" );
01429                 //      break;
01430                 //}
01431 
01432                 //if ( menuCount == MAX_MENUS ) {
01433                 //      Com_Printf( "Too many menus!\n" );
01434                 //      break;
01435                 //}
01436 
01437                 if ( token.string[0] == '}' ) {
01438                         break;
01439                 }
01440 
01441                 if (Q_stricmp(token.string, "assetGlobalDef") == 0) {
01442                         if (Asset_Parse(handle)) {
01443                                 continue;
01444                         } else {
01445                                 break;
01446                         }
01447                 }
01448 
01449                 if (Q_stricmp(token.string, "menudef") == 0) {
01450                         // start a new menu
01451                         Menu_New(handle);
01452                 }
01453         }
01454         trap_PC_FreeSource(handle);
01455 }
01456 
01457 qboolean Load_Menu(int handle) {
01458         pc_token_t token;
01459 
01460         if (!trap_PC_ReadToken(handle, &token))
01461                 return qfalse;
01462         if (token.string[0] != '{') {
01463                 return qfalse;
01464         }
01465 
01466         while ( 1 ) {
01467 
01468                 if (!trap_PC_ReadToken(handle, &token))
01469                         return qfalse;
01470     
01471                 if ( token.string[0] == 0 ) {
01472                         return qfalse;
01473                 }
01474 
01475                 if ( token.string[0] == '}' ) {
01476                         return qtrue;
01477                 }
01478 
01479                 UI_ParseMenu(token.string); 
01480         }
01481         return qfalse;
01482 }
01483 
01484 void UI_LoadMenus(const char *menuFile, qboolean reset) {
01485         pc_token_t token;
01486         int handle;
01487         int start;
01488 
01489         start = trap_Milliseconds();
01490 
01491         trap_PC_LoadGlobalDefines ( "ui/jamp/menudef.h" );
01492 
01493         handle = trap_PC_LoadSource( menuFile );
01494         if (!handle) {
01495                 Com_Printf( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile );
01496                 handle = trap_PC_LoadSource( "ui/jampmenus.txt" );
01497                 if (!handle) {
01498                         trap_Error( va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n", menuFile ) );
01499                 }
01500         }
01501 
01502         if (reset) {
01503                 Menu_Reset();
01504         }
01505 
01506         while ( 1 ) {
01507                 if (!trap_PC_ReadToken(handle, &token))
01508                         break;
01509                 if( token.string[0] == 0 || token.string[0] == '}') {
01510                         break;
01511                 }
01512 
01513                 if ( token.string[0] == '}' ) {
01514                         break;
01515                 }
01516 
01517                 if (Q_stricmp(token.string, "loadmenu") == 0) {
01518                         if (Load_Menu(handle)) {
01519                                 continue;
01520                         } else {
01521                                 break;
01522                         }
01523                 }
01524         }
01525 
01526 //      Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start);
01527 
01528         trap_PC_FreeSource( handle );
01529 
01530         trap_PC_RemoveAllGlobalDefines ( );
01531 }
01532 
01533 void UI_Load() {
01534         char *menuSet;
01535         char lastName[1024];
01536         menuDef_t *menu = Menu_GetFocused();
01537 
01538         if (menu && menu->window.name) {
01539                 strcpy(lastName, menu->window.name);
01540         }
01541         else
01542         {
01543                 lastName[0] = 0;
01544         }
01545 
01546         if (uiInfo.inGameLoad)
01547         {
01548                 menuSet= "ui/jampingame.txt";
01549         }
01550         else
01551         {
01552                 menuSet= UI_Cvar_VariableString("ui_menuFilesMP");
01553         }
01554         if (menuSet == NULL || menuSet[0] == '\0') {
01555                 menuSet = "ui/jampmenus.txt";
01556         }
01557 
01558         String_Init();
01559 
01560 #ifdef PRE_RELEASE_TADEMO
01561         UI_ParseGameInfo("demogameinfo.txt");
01562 #else
01563         UI_ParseGameInfo("ui/jamp/gameinfo.txt");
01564 #endif
01565         UI_LoadArenas();
01566         UI_LoadBots();
01567 
01568         UI_LoadMenus(menuSet, qtrue);
01569         Menus_CloseAll();
01570         Menus_ActivateByName(lastName);
01571 
01572 }
01573 
01574 static const char *handicapValues[] = {"None","95","90","85","80","75","70","65","60","55","50","45","40","35","30","25","20","15","10","5",NULL};
01575 
01576 static void UI_DrawHandicap(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
01577   int i, h;
01578 
01579   h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
01580   i = 20 - h / 5;
01581 
01582   Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle, iMenuFont);
01583 }
01584 
01585 static void UI_DrawClanName(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
01586   Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_teamName"), 0, 0, textStyle, iMenuFont);
01587 }
01588 
01589 
01590 static void UI_SetCapFragLimits(qboolean uiVars) {
01591         int cap = 5;
01592         int frag = 10;
01593 
01594         if (uiVars) {
01595                 trap_Cvar_Set("ui_captureLimit", va("%d", cap));
01596                 trap_Cvar_Set("ui_fragLimit", va("%d", frag));
01597         } else {
01598                 trap_Cvar_Set("capturelimit", va("%d", cap));
01599                 trap_Cvar_Set("fraglimit", va("%d", frag));
01600         }
01601 }
01602 
01603 static const char* UI_GetGameTypeName(int gtEnum)
01604 {
01605         switch ( gtEnum ) 
01606         {
01607         case GT_FFA:
01608                 return UI_GetStringEdString("MENUS", "FREE_FOR_ALL");//"Free For All";
01609         case GT_HOLOCRON:
01610                 return UI_GetStringEdString("MENUS", "HOLOCRON_FFA");//"Holocron FFA";
01611         case GT_JEDIMASTER:
01612                 return UI_GetStringEdString("MENUS", "SAGA");//"Jedi Master";??
01613         case GT_SINGLE_PLAYER:
01614                 return UI_GetStringEdString("MENUS", "SAGA");//"Team FFA";
01615         case GT_DUEL:
01616                 return UI_GetStringEdString("MENUS", "DUEL");//"Team FFA";
01617         case GT_POWERDUEL:
01618                 return UI_GetStringEdString("MENUS", "POWERDUEL");//"Team FFA";
01619         case GT_TEAM:
01620                 return UI_GetStringEdString("MENUS", "TEAM_FFA");//"Team FFA";
01621         case GT_SIEGE:
01622                 return UI_GetStringEdString("MENUS", "SIEGE");//"Siege";
01623         case GT_CTF:
01624                 return UI_GetStringEdString("MENUS", "CAPTURE_THE_FLAG");//"Capture the Flag";
01625         case GT_CTY:
01626                 return UI_GetStringEdString("MENUS", "CAPTURE_THE_YSALIMARI");//"Capture the Ysalamiri";
01627         }
01628         return UI_GetStringEdString("MENUS", "SAGA");//"Team FFA";
01629 }
01630 
01631 
01632 
01633 // ui_gameType assumes gametype 0 is -1 ALL and will not show
01634 static void UI_DrawGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) 
01635 {
01636   Text_Paint(rect->x, rect->y, scale, color, UI_GetGameTypeName(uiInfo.gameTypes[ui_gameType.integer].gtEnum), 0, 0, textStyle, iMenuFont);
01637 }
01638 
01639 static void UI_DrawNetGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) 
01640 {
01641         if (ui_netGameType.integer < 0 || ui_netGameType.integer >= uiInfo.numGameTypes) 
01642         {
01643                 trap_Cvar_Set("ui_netGameType", "0");
01644                 trap_Cvar_Set("ui_actualNetGameType", "0");
01645         }
01646         Text_Paint(rect->x, rect->y, scale, color, UI_GetGameTypeName(uiInfo.gameTypes[ui_netGameType.integer].gtEnum) , 0, 0, textStyle, iMenuFont);
01647 }
01648 
01649 static void UI_DrawAutoSwitch(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
01650         int switchVal = trap_Cvar_VariableValue("cg_autoswitch");
01651         const char *switchString = "AUTOSWITCH1";
01652         const char *stripString = NULL;
01653 
01654         switch(switchVal)
01655         {
01656         case 2:
01657                 switchString = "AUTOSWITCH2";
01658                 break;
01659         case 3:
01660                 switchString = "AUTOSWITCH3";
01661                 break;
01662         case 0:
01663                 switchString = "AUTOSWITCH0";
01664                 break;
01665         default:
01666                 break;
01667         }
01668 
01669         stripString = UI_GetStringEdString("MP_INGAME", (char *)switchString);
01670 
01671         if (stripString)
01672         {
01673                 Text_Paint(rect->x, rect->y, scale, color, stripString, 0, 0, textStyle, iMenuFont);
01674         }
01675 }
01676 
01677 static void UI_DrawJoinGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) 
01678 {
01679         if (ui_joinGameType.integer < 0 || ui_joinGameType.integer > uiInfo.numJoinGameTypes) 
01680         {
01681                 trap_Cvar_Set("ui_joinGameType", "0");
01682         }
01683 
01684         Text_Paint(rect->x, rect->y, scale, color, UI_GetGameTypeName(uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum) , 0, 0, textStyle, iMenuFont);
01685 }
01686 
01687 
01688 
01689 static int UI_TeamIndexFromName(const char *name) {
01690   int i;
01691 
01692   if (name && *name) {
01693     for (i = 0; i < uiInfo.teamCount; i++) {
01694       if (Q_stricmp(name, uiInfo.teamList[i].teamName) == 0) {
01695         return i;
01696       }
01697     }
01698   } 
01699 
01700   return 0;
01701 
01702 }
01703 
01704 static void UI_DrawClanLogo(rectDef_t *rect, float scale, vec4_t color) {
01705   int i;
01706   i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
01707   if (i >= 0 && i < uiInfo.teamCount) {
01708         trap_R_SetColor( color );
01709 
01710                 if (uiInfo.teamList[i].teamIcon == -1) {
01711       uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
01712       uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
01713       uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
01714                 }
01715 
01716         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon);
01717     trap_R_SetColor(NULL);
01718   }
01719 }
01720 
01721 static void UI_DrawClanCinematic(rectDef_t *rect, float scale, vec4_t color) {
01722   int i;
01723   i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
01724   if (i >= 0 && i < uiInfo.teamCount) {
01725 
01726                 if (uiInfo.teamList[i].cinematic >= -2) {
01727                         if (uiInfo.teamList[i].cinematic == -1) {
01728                                 uiInfo.teamList[i].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.teamList[i].imageName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
01729                         }
01730                         if (uiInfo.teamList[i].cinematic >= 0) {
01731                           trap_CIN_RunCinematic(uiInfo.teamList[i].cinematic);
01732                                 trap_CIN_SetExtents(uiInfo.teamList[i].cinematic, rect->x, rect->y, rect->w, rect->h);
01733                                 trap_CIN_DrawCinematic(uiInfo.teamList[i].cinematic);
01734                         } else {
01735                                 trap_R_SetColor( color );
01736                                 UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal);
01737                                 trap_R_SetColor(NULL);
01738                                 uiInfo.teamList[i].cinematic = -2;
01739                         }
01740                 } else {
01741                 trap_R_SetColor( color );
01742                         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon);
01743                         trap_R_SetColor(NULL);
01744                 }
01745         }
01746 
01747 }
01748 
01749 static void UI_DrawPreviewCinematic(rectDef_t *rect, float scale, vec4_t color) {
01750         if (uiInfo.previewMovie > -2) {
01751                 uiInfo.previewMovie = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.movieList[uiInfo.movieIndex]), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
01752                 if (uiInfo.previewMovie >= 0) {
01753                   trap_CIN_RunCinematic(uiInfo.previewMovie);
01754                         trap_CIN_SetExtents(uiInfo.previewMovie, rect->x, rect->y, rect->w, rect->h);
01755                         trap_CIN_DrawCinematic(uiInfo.previewMovie);
01756                 } else {
01757                         uiInfo.previewMovie = -2;
01758                 }
01759         } 
01760 
01761 }
01762 
01763 static void UI_DrawSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
01764   int i;
01765         i = trap_Cvar_VariableValue( "g_spSkill" );
01766   if (i < 1 || i > numSkillLevels) {
01767     i = 1;
01768   }
01769   Text_Paint(rect->x, rect->y, scale, color, (char *)UI_GetStringEdString("MP_INGAME", (char *)skillLevels[i-1]),0, 0, textStyle, iMenuFont);
01770 }
01771 
01772 
01773 static void UI_DrawGenericNum(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int type,int iMenuFont) 
01774 {
01775         int i;
01776         char s[256];
01777 
01778         i = val;
01779         if (i < min || i > max) 
01780         {
01781                 i = min;
01782         }
01783 
01784         Com_sprintf(s, sizeof(s), "%i\0", val);
01785         Text_Paint(rect->x, rect->y, scale, color, s,0, 0, textStyle, iMenuFont);
01786 }
01787 
01788 static void UI_DrawForceMastery(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
01789 {
01790         int i;
01791         char *s;
01792 
01793         i = val;
01794         if (i < min)
01795         {
01796                 i = min;
01797         }
01798         if (i > max)
01799         {
01800                 i = max;
01801         }
01802 
01803         s = (char *)UI_GetStringEdString("MP_INGAME", forceMasteryLevels[i]);
01804         Text_Paint(rect->x, rect->y, scale, color, s, 0, 0, textStyle, iMenuFont);
01805 }
01806 
01807 
01808 static void UI_DrawSkinColor(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
01809 {
01810         char s[256];
01811 
01812         switch(val)
01813         {
01814         case TEAM_RED:
01815                 trap_SP_GetStringTextString("MENUS_TEAM_RED", s, sizeof(s));
01816 //              Com_sprintf(s, sizeof(s), "Red\0");
01817                 break;
01818         case TEAM_BLUE:
01819                 trap_SP_GetStringTextString("MENUS_TEAM_BLUE", s, sizeof(s));
01820 //              Com_sprintf(s, sizeof(s), "Blue\0");
01821                 break;
01822         default:
01823                 trap_SP_GetStringTextString("MENUS_DEFAULT", s, sizeof(s));
01824 //              Com_sprintf(s, sizeof(s), "Default\0");
01825                 break;
01826         }
01827 
01828         Text_Paint(rect->x, rect->y, scale, color, s, 0, 0, textStyle, iMenuFont);
01829 }
01830 
01831 static void UI_DrawForceSide(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
01832 {
01833         char s[256];
01834         menuDef_t *menu;
01835         
01836         char info[MAX_INFO_VALUE];
01837 
01838         info[0] = '\0';
01839         trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
01840 
01841         if (atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ))
01842         {
01843                 switch((int)(trap_Cvar_VariableValue("ui_myteam")))
01844                 {
01845                 case TEAM_RED:
01846                         uiForceSide = FORCE_DARKSIDE;
01847                         color[0] = 0.2;
01848                         color[1] = 0.2;
01849                         color[2] = 0.2;
01850                         break;
01851                 case TEAM_BLUE:
01852                         uiForceSide = FORCE_LIGHTSIDE;
01853                         color[0] = 0.2;
01854                         color[1] = 0.2;
01855                         color[2] = 0.2;
01856                         break;
01857                 default:
01858                         break;
01859                 }
01860         }
01861 
01862         if (val == FORCE_LIGHTSIDE)
01863         {
01864                 trap_SP_GetStringTextString("MENUS_FORCEDESC_LIGHT",s, sizeof(s));
01865                 menu = Menus_FindByName("forcealloc");
01866                 if (menu)
01867                 {
01868                         Menu_ShowItemByName(menu, "lightpowers", qtrue);
01869                         Menu_ShowItemByName(menu, "darkpowers", qfalse);
01870                         Menu_ShowItemByName(menu, "darkpowers_team", qfalse);
01871 
01872                         Menu_ShowItemByName(menu, "lightpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
01873 
01874                 }
01875                 menu = Menus_FindByName("ingame_playerforce");
01876                 if (menu)
01877                 {
01878                         Menu_ShowItemByName(menu, "lightpowers", qtrue);
01879                         Menu_ShowItemByName(menu, "darkpowers", qfalse);
01880                         Menu_ShowItemByName(menu, "darkpowers_team", qfalse);
01881 
01882                         Menu_ShowItemByName(menu, "lightpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
01883                 }
01884         }
01885         else
01886         {
01887                 trap_SP_GetStringTextString("MENUS_FORCEDESC_DARK",s, sizeof(s));
01888                 menu = Menus_FindByName("forcealloc");
01889                 if (menu)
01890                 {
01891                         Menu_ShowItemByName(menu, "lightpowers", qfalse);
01892                         Menu_ShowItemByName(menu, "lightpowers_team", qfalse);
01893                         Menu_ShowItemByName(menu, "darkpowers", qtrue);
01894 
01895                         Menu_ShowItemByName(menu, "darkpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
01896                 }
01897                 menu = Menus_FindByName("ingame_playerforce");
01898                 if (menu)
01899                 {
01900                         Menu_ShowItemByName(menu, "lightpowers", qfalse);
01901                         Menu_ShowItemByName(menu, "lightpowers_team", qfalse);
01902                         Menu_ShowItemByName(menu, "darkpowers", qtrue);
01903 
01904                         Menu_ShowItemByName(menu, "darkpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
01905                 }
01906         }
01907 
01908         Text_Paint(rect->x, rect->y, scale, color, s,0, 0, textStyle, iMenuFont);
01909 }
01910 
01911 qboolean UI_HasSetSaberOnly( void )
01912 {
01913         char    info[MAX_INFO_STRING];
01914         int i = 0;
01915         int wDisable = 0;
01916         int     gametype = 0;
01917 
01918         gametype = atoi(Info_ValueForKey(info, "g_gametype"));
01919 
01920         if ( gametype == GT_JEDIMASTER )
01921         { //set to 0 
01922                 return qfalse;
01923         }
01924 
01925         trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
01926 
01927         if (gametype == GT_DUEL || gametype == GT_POWERDUEL)
01928         {
01929                 wDisable = atoi(Info_ValueForKey(info, "g_duelWeaponDisable"));
01930         }
01931         else
01932         {
01933                 wDisable = atoi(Info_ValueForKey(info, "g_weaponDisable"));
01934         }
01935 
01936         while (i < WP_NUM_WEAPONS)
01937         {
01938                 if (!(wDisable & (1 << i)) &&
01939                         i != WP_SABER && i != WP_NONE)
01940                 {
01941                         return qfalse;
01942                 }
01943 
01944                 i++;
01945         }
01946 
01947         return qtrue;
01948 }
01949 
01950 static qboolean UI_AllForceDisabled(int force)
01951 {
01952         int i;
01953 
01954         if (force)
01955         {
01956                 for (i=0;i<NUM_FORCE_POWERS;i++)
01957                 {
01958                         if (!(force & (1<<i)))
01959                         {
01960                                 return qfalse;
01961                         }
01962                 }
01963 
01964                 return qtrue;
01965         }
01966 
01967         return qfalse;
01968 }
01969 
01970 qboolean UI_TrueJediEnabled( void )
01971 {
01972         char    info[MAX_INFO_STRING];
01973         int             gametype = 0, disabledForce = 0, trueJedi = 0;
01974         qboolean saberOnly = qfalse, allForceDisabled = qfalse;
01975 
01976         trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
01977 
01978         //already have serverinfo at this point for stuff below. Don't bother trying to use ui_forcePowerDisable.
01979         //if (ui_forcePowerDisable.integer)
01980         //if (atoi(Info_ValueForKey(info, "g_forcePowerDisable")))
01981         disabledForce = atoi(Info_ValueForKey(info, "g_forcePowerDisable"));
01982         allForceDisabled = UI_AllForceDisabled(disabledForce);
01983         gametype = atoi(Info_ValueForKey(info, "g_gametype"));
01984         saberOnly = UI_HasSetSaberOnly();
01985 
01986         if ( gametype == GT_HOLOCRON 
01987                 || gametype == GT_JEDIMASTER 
01988                 || saberOnly 
01989                 || allForceDisabled )
01990         {
01991                 trueJedi = 0;
01992         }
01993         else
01994         {
01995                 trueJedi = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );
01996         }
01997         return (trueJedi != 0);
01998 }
01999 
02000 static void UI_DrawJediNonJedi(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
02001 {
02002         int i;
02003         char s[256];
02004         //menuDef_t *menu;
02005         
02006         char info[MAX_INFO_VALUE];
02007 
02008         i = val;
02009         if (i < min || i > max) 
02010         {
02011                 i = min;
02012         }
02013 
02014         info[0] = '\0';
02015         trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
02016 
02017         if ( !UI_TrueJediEnabled() )
02018         {//true jedi mode is not on, do not draw this button type
02019                 return;
02020         }
02021 
02022         if ( val == FORCE_NONJEDI )
02023         {
02024                 trap_SP_GetStringTextString("MENUS_NO",s, sizeof(s));
02025         }
02026         else
02027         {
02028                 trap_SP_GetStringTextString("MENUS_YES",s, sizeof(s));
02029         }
02030 
02031         Text_Paint(rect->x, rect->y, scale, color, s,0, 0, textStyle, iMenuFont);
02032 }
02033 
02034 static void UI_DrawTeamName(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int textStyle, int iMenuFont) {
02035   int i;
02036   i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
02037   if (i >= 0 && i < uiInfo.teamCount) {
02038     Text_Paint(rect->x, rect->y, scale, color, va("%s: %s", (blue) ? "Blue" : "Red", uiInfo.teamList[i].teamName),0, 0, textStyle, iMenuFont);
02039   }
02040 }
02041 
02042 static void UI_DrawTeamMember(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int num, int textStyle, int iMenuFont) 
02043 {
02044         // 0 - None
02045         // 1 - Human
02046         // 2..NumCharacters - Bot
02047         int value = trap_Cvar_VariableValue(va(blue ? "ui_blueteam%i" : "ui_redteam%i", num));
02048         const char *text;
02049         int maxcl = trap_Cvar_VariableValue( "sv_maxClients" );
02050         vec4_t finalColor;
02051         int numval = num;
02052 
02053         numval *= 2;
02054 
02055         if (blue)
02056         {
02057                 numval -= 1;
02058         }
02059 
02060         finalColor[0] = color[0];
02061         finalColor[1] = color[1];
02062         finalColor[2] = color[2];
02063         finalColor[3] = color[3];
02064 
02065         if (numval > maxcl)
02066         {
02067                 finalColor[0] *= 0.5;
02068                 finalColor[1] *= 0.5;
02069                 finalColor[2] *= 0.5;
02070 
02071                 value = -1;
02072         }
02073 
02074         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
02075         {
02076                 if (value > 1 )
02077                 {
02078                         value = 1;
02079                 }
02080         }
02081 
02082         if (value <= 1) {
02083                 if (value == -1)
02084                 {
02085                         //text = "Closed";
02086                         text = UI_GetStringEdString("MENUS", "CLOSED");
02087                 }
02088                 else
02089                 {
02090                         //text = "Human";
02091                         text = UI_GetStringEdString("MENUS", "HUMAN");
02092                 }
02093         } else {
02094                 value -= 2;
02095                 if (value >= UI_GetNumBots()) {
02096                         value = 1;
02097                 }
02098                 text = UI_GetBotNameByNumber(value);
02099         }
02100 
02101   Text_Paint(rect->x, rect->y, scale, finalColor, text, 0, 0, textStyle, iMenuFont);
02102 }
02103 
02104 static void UI_DrawEffects(rectDef_t *rect, float scale, vec4_t color) 
02105 {
02106         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiSaberColorShaders[uiInfo.effectsColor]);
02107 }
02108 
02109 static void UI_DrawMapPreview(rectDef_t *rect, float scale, vec4_t color, qboolean net) {
02110         int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
02111         if (map < 0 || map > uiInfo.mapCount) {
02112                 if (net) {
02113                         ui_currentNetMap.integer = 0;
02114                         trap_Cvar_Set("ui_currentNetMap", "0");
02115                 } else {
02116                         ui_currentMap.integer = 0;
02117                         trap_Cvar_Set("ui_currentMap", "0");
02118                 }
02119                 map = 0;
02120         }
02121 
02122         if (uiInfo.mapList[map].levelShot == -1) {
02123                 uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[map].imageName);
02124         }
02125 
02126         if (uiInfo.mapList[map].levelShot > 0) {
02127                 UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.mapList[map].levelShot);
02128         } else {
02129                 UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("menu/art/unknownmap_mp"));
02130         }
02131 }                                                
02132 
02133 
02134 static void UI_DrawMapTimeToBeat(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
02135         int minutes, seconds, time;
02136         if (ui_currentMap.integer < 0 || ui_currentMap.integer > uiInfo.mapCount) {
02137                 ui_currentMap.integer = 0;
02138                 trap_Cvar_Set("ui_currentMap", "0");
02139         }
02140 
02141         time = uiInfo.mapList[ui_currentMap.integer].timeToBeat[uiInfo.gameTypes[ui_gameType.integer].gtEnum];
02142 
02143         minutes = time / 60;
02144         seconds = time % 60;
02145 
02146   Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, textStyle, iMenuFont);
02147 }
02148 
02149 
02150 
02151 static void UI_DrawMapCinematic(rectDef_t *rect, float scale, vec4_t color, qboolean net) {
02152 
02153         int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; 
02154         if (map < 0 || map > uiInfo.mapCount) {
02155                 if (net) {
02156                         ui_currentNetMap.integer = 0;
02157                         trap_Cvar_Set("ui_currentNetMap", "0");
02158                 } else {
02159                         ui_currentMap.integer = 0;
02160                         trap_Cvar_Set("ui_currentMap", "0");
02161                 }
02162                 map = 0;
02163         }
02164 
02165         if (uiInfo.mapList[map].cinematic >= -1) {
02166                 if (uiInfo.mapList[map].cinematic == -1) {
02167                         uiInfo.mapList[map].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[map].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
02168                 }
02169                 if (uiInfo.mapList[map].cinematic >= 0) {
02170                   trap_CIN_RunCinematic(uiInfo.mapList[map].cinematic);
02171                   trap_CIN_SetExtents(uiInfo.mapList[map].cinematic, rect->x, rect->y, rect->w, rect->h);
02172                         trap_CIN_DrawCinematic(uiInfo.mapList[map].cinematic);
02173                 } else {
02174                         uiInfo.mapList[map].cinematic = -2;
02175                 }
02176         } else {
02177                 UI_DrawMapPreview(rect, scale, color, net);
02178         }
02179 }
02180 
02181 static void UI_SetForceDisabled(int force)
02182 {
02183         int i = 0;
02184 
02185         if (force)
02186         {
02187                 while (i < NUM_FORCE_POWERS)
02188                 {
02189                         if (force & (1 << i))
02190                         {
02191                                 uiForcePowersDisabled[i] = qtrue;
02192 
02193                                 if (i != FP_LEVITATION && i != FP_SABER_OFFENSE && i != FP_SABER_DEFENSE)
02194                                 {
02195                                         uiForcePowersRank[i] = 0;
02196                                 }
02197                                 else
02198                                 {
02199                                         if (i == FP_LEVITATION)
02200                                         {
02201                                                 uiForcePowersRank[i] = 1;
02202                                         }
02203                                         else
02204                                         {
02205                                                 uiForcePowersRank[i] = 3;
02206                                         }
02207                                 }
02208                         }
02209                         else
02210                         {
02211                                 uiForcePowersDisabled[i] = qfalse;
02212                         }
02213                         i++;
02214                 }
02215         }
02216         else
02217         {
02218                 i = 0;
02219 
02220                 while (i < NUM_FORCE_POWERS)
02221                 {
02222                         uiForcePowersDisabled[i] = qfalse;
02223                         i++;
02224                 }
02225         }
02226 }
02227 // The game type on create server has changed - make the HUMAN/BOTS fields active 
02228 void UpdateBotButtons(void)
02229 {
02230         menuDef_t *menu;
02231 
02232         menu = Menu_GetFocused();       
02233 
02234         if (!menu)
02235         {
02236                 return;
02237         }
02238 
02239         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
02240         {
02241                 Menu_ShowItemByName(menu, "humanbotfield", qfalse);
02242                 Menu_ShowItemByName(menu, "humanbotnonfield", qtrue);
02243         }
02244         else
02245         {
02246                 Menu_ShowItemByName(menu, "humanbotfield", qtrue);
02247                 Menu_ShowItemByName(menu, "humanbotnonfield", qfalse);
02248         }
02249 
02250 }
02251 
02252 void UpdateForceStatus()
02253 {
02254         menuDef_t *menu;
02255 
02256         // Currently we don't make a distinction between those that wish to play Jedi of lower than maximum skill.
02257 /*      if (ui_forcePowerDisable.integer)
02258         {
02259                 uiForceRank = 0;
02260                 uiForceAvailable = 0;
02261                 uiForceUsed = 0;
02262         }
02263         else
02264         {
02265                 uiForceRank = uiMaxRank;
02266                 uiForceUsed = 0;
02267                 uiForceAvailable = forceMasteryPoints[uiForceRank];
02268         }
02269 */
02270         menu = Menus_FindByName("ingame_player");
02271         if (menu)
02272         {
02273                 char    info[MAX_INFO_STRING];
02274                 int             disabledForce = 0;
02275                 qboolean trueJedi = qfalse, allForceDisabled = qfalse;
02276 
02277                 trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
02278 
02279                 //already have serverinfo at this point for stuff below. Don't bother trying to use ui_forcePowerDisable.
02280                 //if (ui_forcePowerDisable.integer)
02281                 //if (atoi(Info_ValueForKey(info, "g_forcePowerDisable")))
02282                 disabledForce = atoi(Info_ValueForKey(info, "g_forcePowerDisable"));
02283                 allForceDisabled = UI_AllForceDisabled(disabledForce);
02284                 trueJedi = UI_TrueJediEnabled();
02285 
02286                 if ( !trueJedi || allForceDisabled )
02287                 {
02288                         Menu_ShowItemByName(menu, "jedinonjedi", qfalse);
02289                 }
02290                 else
02291                 {
02292                         Menu_ShowItemByName(menu, "jedinonjedi", qtrue);
02293                 }
02294                 if ( allForceDisabled == qtrue || (trueJedi && uiJediNonJedi == FORCE_NONJEDI) )
02295                 {       // No force stuff
02296                         Menu_ShowItemByName(menu, "noforce", qtrue);
02297                         Menu_ShowItemByName(menu, "yesforce", qfalse);
02298                         // We don't want the saber explanation to say "configure saber attack 1" since we can't.
02299                         Menu_ShowItemByName(menu, "sabernoneconfigme", qfalse);
02300                 }
02301                 else
02302                 {
02303                         UI_SetForceDisabled(disabledForce);
02304                         Menu_ShowItemByName(menu, "noforce", qfalse);
02305                         Menu_ShowItemByName(menu, "yesforce", qtrue);
02306                 }
02307 
02308                 //Moved this to happen after it's done with force power disabling stuff
02309                 if (uiForcePowersRank[FP_SABER_OFFENSE] > 0 || ui_freeSaber.integer)
02310                 {       // Show lightsaber stuff.
02311                         Menu_ShowItemByName(menu, "nosaber", qfalse);
02312                         Menu_ShowItemByName(menu, "yessaber", qtrue);
02313                 }
02314                 else
02315                 {
02316                         Menu_ShowItemByName(menu, "nosaber", qtrue);
02317                         Menu_ShowItemByName(menu, "yessaber", qfalse);
02318                 }
02319 
02320                 // The leftmost button should be "apply" unless you are in spectator, where you can join any team.
02321                 if ((int)(trap_Cvar_VariableValue("ui_myteam")) != TEAM_SPECTATOR)
02322                 {
02323                         Menu_ShowItemByName(menu, "playerapply", qtrue);
02324                         Menu_ShowItemByName(menu, "playerforcejoin", qfalse);
02325                         Menu_ShowItemByName(menu, "playerforcered", qtrue);
02326                         Menu_ShowItemByName(menu, "playerforceblue", qtrue);
02327                         Menu_ShowItemByName(menu, "playerforcespectate", qtrue);
02328                 }
02329                 else
02330                 {
02331                         // Set or reset buttons based on choices
02332                         if (atoi(Info_ValueForKey(info, "g_gametype")) >= GT_TEAM)
02333                         {       // This is a team-based game.
02334                                 Menu_ShowItemByName(menu, "playerforcespectate", qtrue);
02335                                 
02336                                 // This is disabled, always show both sides from spectator.
02337                                 if ( 0 && atoi(Info_ValueForKey(info, "g_forceBasedTeams")))
02338                                 {       // Show red or blue based on what side is chosen.
02339                                         if (uiForceSide==FORCE_LIGHTSIDE)
02340                                         {
02341                                                 Menu_ShowItemByName(menu, "playerforcered", qfalse);
02342                                                 Menu_ShowItemByName(menu, "playerforceblue", qtrue);
02343                                         }
02344                                         else if (uiForceSide==FORCE_DARKSIDE)
02345                                         {
02346                                                 Menu_ShowItemByName(menu, "playerforcered", qtrue);
02347                                                 Menu_ShowItemByName(menu, "playerforceblue", qfalse);
02348                                         }
02349                                         else
02350                                         {
02351                                                 Menu_ShowItemByName(menu, "playerforcered", qtrue);
02352                                                 Menu_ShowItemByName(menu, "playerforceblue", qtrue);
02353                                         }
02354                                 }
02355                                 else
02356                                 {
02357                                         Menu_ShowItemByName(menu, "playerforcered", qtrue);
02358                                         Menu_ShowItemByName(menu, "playerforceblue", qtrue);
02359                                 }
02360                         }
02361                         else
02362                         {
02363                                 Menu_ShowItemByName(menu, "playerforcered", qfalse);
02364                                 Menu_ShowItemByName(menu, "playerforceblue", qfalse);
02365                         }
02366 
02367                         Menu_ShowItemByName(menu, "playerapply", qfalse);
02368                         Menu_ShowItemByName(menu, "playerforcejoin", qtrue);
02369                         Menu_ShowItemByName(menu, "playerforcespectate", qtrue);
02370                 }
02371         }
02372 
02373 
02374         if ( !UI_TrueJediEnabled() )
02375         {// Take the current team and force a skin color based on it.
02376                 char    info[MAX_INFO_STRING];
02377 
02378                 switch((int)(trap_Cvar_VariableValue("ui_myteam")))
02379                 {
02380                 case TEAM_RED:
02381                         uiSkinColor = TEAM_RED;
02382                         uiInfo.effectsColor = SABER_RED;
02383                         break;
02384                 case TEAM_BLUE:
02385                         uiSkinColor = TEAM_BLUE;
02386                         uiInfo.effectsColor = SABER_BLUE;
02387                         break;
02388                 default:
02389                         trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
02390 
02391                         if (atoi(Info_ValueForKey(info, "g_gametype")) >= GT_TEAM)
02392                         {
02393                                 uiSkinColor = TEAM_FREE;
02394                         }
02395                         else    // A bit of a hack so non-team games will remember which skin set you chose in the player menu
02396                         {
02397                                 uiSkinColor = uiHoldSkinColor;
02398                         }
02399                         break;
02400                 }
02401         }
02402 }
02403 
02404 
02405 
02406 static void UI_DrawNetSource(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) 
02407 {
02408         if (ui_netSource.integer < 0 || ui_netSource.integer > uiInfo.numGameTypes) 
02409         {
02410                 ui_netSource.integer = 0;
02411         }
02412 
02413         trap_SP_GetStringTextString("MENUS_SOURCE", holdSPString, sizeof(holdSPString) );
02414         Text_Paint(rect->x, rect->y, scale, color, va("%s %s",holdSPString,
02415                  GetNetSourceString(ui_netSource.integer)), 0, 0, textStyle, iMenuFont);
02416 }
02417 
02418 static void UI_DrawNetMapPreview(rectDef_t *rect, float scale, vec4_t color) {
02419 
02420         if (uiInfo.serverStatus.currentServerPreview > 0) {
02421                 UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.serverStatus.currentServerPreview);
02422         } else {
02423                 UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("menu/art/unknownmap_mp"));
02424         }
02425 }
02426 
02427 static void UI_DrawNetMapCinematic(rectDef_t *rect, float scale, vec4_t color) {
02428         if (ui_currentNetMap.integer < 0 || ui_currentNetMap.integer > uiInfo.mapCount) {
02429                 ui_currentNetMap.integer = 0;
02430                 trap_Cvar_Set("ui_currentNetMap", "0");
02431         }
02432 
02433         if (uiInfo.serverStatus.currentServerCinematic >= 0) {
02434           trap_CIN_RunCinematic(uiInfo.serverStatus.currentServerCinematic);
02435           trap_CIN_SetExtents(uiInfo.serverStatus.currentServerCinematic, rect->x, rect->y, rect->w, rect->h);
02436           trap_CIN_DrawCinematic(uiInfo.serverStatus.currentServerCinematic);
02437         } else {
02438                 UI_DrawNetMapPreview(rect, scale, color);
02439         }
02440 }
02441 
02442 
02443 
02444 static void UI_DrawNetFilter(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) 
02445 {
02446 
02447         if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) 
02448         {
02449                 ui_serverFilterType.integer = 0;
02450         }
02451 
02452         trap_SP_GetStringTextString("MENUS_GAME", holdSPString, sizeof(holdSPString));
02453 
02454         trap_SP_GetStringTextString(serverFilters[ui_serverFilterType.integer].description, holdSPString2, sizeof(holdSPString2));
02455 
02456         Text_Paint(rect->x, rect->y, scale, color, va("%s %s",holdSPString,
02457                  holdSPString2), 0, 0, textStyle, iMenuFont);
02458 }
02459 
02460 
02461 static void UI_DrawTier(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
02462   int i;
02463         i = trap_Cvar_VariableValue( "ui_currentTier" );
02464   if (i < 0 || i >= uiInfo.tierCount) {
02465     i = 0;
02466   }
02467   Text_Paint(rect->x, rect->y, scale, color, va("Tier: %s", uiInfo.tierList[i].tierName),0, 0, textStyle, iMenuFont);
02468 }
02469 
02470 static void UI_DrawTierMap(rectDef_t *rect, int index) {
02471   int i;
02472         i = trap_Cvar_VariableValue( "ui_currentTier" );
02473   if (i < 0 || i >= uiInfo.tierCount) {
02474     i = 0;
02475   }
02476 
02477         if (uiInfo.tierList[i].mapHandles[index] == -1) {
02478                 uiInfo.tierList[i].mapHandles[index] = trap_R_RegisterShaderNoMip(va("levelshots/%s", uiInfo.tierList[i].maps[index]));
02479         }
02480                                                                                                  
02481         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.tierList[i].mapHandles[index]);
02482 }
02483 
02484 static const char *UI_EnglishMapName(const char *map) {
02485         int i;
02486         for (i = 0; i < uiInfo.mapCount; i++) {
02487                 if (Q_stricmp(map, uiInfo.mapList[i].mapLoadName) == 0) {
02488                         return uiInfo.mapList[i].mapName;
02489                 }
02490         }
02491         return "";
02492 }
02493 
02494 static void UI_DrawTierMapName(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
02495   int i, j;
02496         i = trap_Cvar_VariableValue( "ui_currentTier" );
02497   if (i < 0 || i >= uiInfo.tierCount) {
02498     i = 0;
02499   }
02500         j = trap_Cvar_VariableValue("ui_currentMap");
02501         if (j < 0 || j > MAPS_PER_TIER) {
02502                 j = 0;
02503         }
02504 
02505   Text_Paint(rect->x, rect->y, scale, color, UI_EnglishMapName(uiInfo.tierList[i].maps[j]), 0, 0, textStyle, iMenuFont);
02506 }
02507 
02508 static void UI_DrawTierGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
02509   int i, j;
02510         i = trap_Cvar_VariableValue( "ui_currentTier" );
02511   if (i < 0 || i >= uiInfo.tierCount) {
02512     i = 0;
02513   }
02514         j = trap_Cvar_VariableValue("ui_currentMap");
02515         if (j < 0 || j > MAPS_PER_TIER) {
02516                 j = 0;
02517         }
02518 
02519   Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[uiInfo.tierList[i].gameTypes[j]].gameType , 0, 0, textStyle,iMenuFont);
02520 }
02521 
02522 
02523 static const char *UI_AIFromName(const char *name) {
02524         int j;
02525         for (j = 0; j < uiInfo.aliasCount; j++) {
02526                 if (Q_stricmp(uiInfo.aliasList[j].name, name) == 0) {
02527                         return uiInfo.aliasList[j].ai;
02528                 }
02529         }
02530         return "Kyle";
02531 }
02532 
02533 
02534 /*
02535 static qboolean updateOpponentModel = qtrue;
02536 static void UI_DrawOpponent(rectDef_t *rect) {
02537   static playerInfo_t info2;
02538   char model[MAX_QPATH];
02539   char headmodel[MAX_QPATH];
02540   char team[256];
02541         vec3_t  viewangles;
02542         vec3_t  moveangles;
02543   
02544         if (updateOpponentModel) {
02545                 
02546                 strcpy(model, UI_Cvar_VariableString("ui_opponentModel"));
02547           strcpy(headmodel, UI_Cvar_VariableString("ui_opponentModel"));
02548                 team[0] = '\0';
02549 
02550         memset( &info2, 0, sizeof(playerInfo_t) );
02551         viewangles[YAW]   = 180 - 10;
02552         viewangles[PITCH] = 0;
02553         viewangles[ROLL]  = 0;
02554         VectorClear( moveangles );
02555     UI_PlayerInfo_SetModel( &info2, model, headmodel, "");
02556     UI_PlayerInfo_SetInfo( &info2, TORSO_WEAPONREADY3, TORSO_WEAPONREADY3, viewangles, vec3_origin, WP_BRYAR_PISTOL, qfalse );
02557                 UI_RegisterClientModelname( &info2, model, headmodel, team);
02558     updateOpponentModel = qfalse;
02559   }
02560 
02561   UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info2, uiInfo.uiDC.realTime / 2);
02562 
02563 }
02564 */
02565 static void UI_NextOpponent() {
02566   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
02567   int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
02568         i++;
02569         if (i >= uiInfo.teamCount) {
02570                 i = 0;
02571         }
02572         if (i == j) {
02573                 i++;
02574                 if ( i >= uiInfo.teamCount) {
02575                         i = 0;
02576                 }
02577         }
02578         trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName );
02579 }
02580 
02581 static void UI_PriorOpponent() {
02582   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
02583   int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
02584         i--;
02585         if (i < 0) {
02586                 i = uiInfo.teamCount - 1;
02587         }
02588         if (i == j) {
02589                 i--;
02590                 if ( i < 0) {
02591                         i = uiInfo.teamCount - 1;
02592                 }
02593         }
02594         trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName );
02595 }
02596 
02597 static void     UI_DrawPlayerLogo(rectDef_t *rect, vec3_t color) {
02598   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
02599 
02600         if (uiInfo.teamList[i].teamIcon == -1) {
02601     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
02602     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
02603     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
02604         }
02605 
02606         trap_R_SetColor( color );
02607         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon );
02608         trap_R_SetColor( NULL );
02609 }
02610 
02611 static void     UI_DrawPlayerLogoMetal(rectDef_t *rect, vec3_t color) {
02612   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
02613         if (uiInfo.teamList[i].teamIcon == -1) {
02614     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
02615     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
02616     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
02617         }
02618 
02619         trap_R_SetColor( color );
02620         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal );
02621         trap_R_SetColor( NULL );
02622 }
02623 
02624 static void     UI_DrawPlayerLogoName(rectDef_t *rect, vec3_t color) {
02625   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
02626         if (uiInfo.teamList[i].teamIcon == -1) {
02627     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
02628     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
02629     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
02630         }
02631 
02632         trap_R_SetColor( color );
02633         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name );
02634         trap_R_SetColor( NULL );
02635 }
02636 
02637 static void     UI_DrawOpponentLogo(rectDef_t *rect, vec3_t color) {
02638   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
02639         if (uiInfo.teamList[i].teamIcon == -1) {
02640     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
02641     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
02642     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
02643         }
02644 
02645         trap_R_SetColor( color );
02646         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon );
02647         trap_R_SetColor( NULL );
02648 }
02649 
02650 static void     UI_DrawOpponentLogoMetal(rectDef_t *rect, vec3_t color) {
02651   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
02652         if (uiInfo.teamList[i].teamIcon == -1) {
02653     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
02654     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
02655     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
02656         }
02657 
02658         trap_R_SetColor( color );
02659         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal );
02660         trap_R_SetColor( NULL );
02661 }
02662 
02663 static void     UI_DrawOpponentLogoName(rectDef_t *rect, vec3_t color) {
02664   int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
02665         if (uiInfo.teamList[i].teamIcon == -1) {
02666     uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
02667     uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
02668     uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
02669         }
02670 
02671         trap_R_SetColor( color );
02672         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name );
02673         trap_R_SetColor( NULL );
02674 }
02675 
02676 static void UI_DrawAllMapsSelection(rectDef_t *rect, float scale, vec4_t color, int textStyle, qboolean net, int iMenuFont) {
02677         int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
02678         if (map >= 0 && map < uiInfo.mapCount) {
02679           Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle, iMenuFont);
02680         }
02681 }
02682 
02683 static void UI_DrawOpponentName(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
02684   Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, textStyle, iMenuFont);
02685 }
02686 
02687 static int UI_OwnerDrawWidth(int ownerDraw, float scale) {
02688         int i, h, value, findex, iUse = 0;
02689         const char *text;
02690         const char *s = NULL;
02691 
02692 
02693   switch (ownerDraw) {
02694     case UI_HANDICAP:
02695                           h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
02696                                 i = 20 - h / 5;
02697                                 s = handicapValues[i];
02698       break;
02699     case UI_SKIN_COLOR:
02700                 switch(uiSkinColor)
02701                 {
02702                 case TEAM_RED:
02703 //                      s = "Red";
02704                         s = (char *)UI_GetStringEdString("MENUS", "TEAM_RED");
02705                         break;
02706                 case TEAM_BLUE:
02707 //                      s = "Blue";
02708                         s = (char *)UI_GetStringEdString("MENUS", "TEAM_BLUE");
02709                         break;
02710                 default:
02711 //                      s = "Default";
02712                         s = (char *)UI_GetStringEdString("MENUS", "DEFAULT");
02713                         break;
02714                 }
02715                 break;
02716     case UI_FORCE_SIDE:
02717                 i = uiForceSide;
02718                 if (i < 1 || i > 2) {
02719                         i = 1;
02720                 }
02721 
02722                 if (i == FORCE_LIGHTSIDE)
02723                 {
02724 //                      s = "Light";
02725                         s = (char *)UI_GetStringEdString("MENUS", "FORCEDESC_LIGHT");
02726                 }
02727                 else
02728                 {
02729 //                      s = "Dark";
02730                         s = (char *)UI_GetStringEdString("MENUS", "FORCEDESC_DARK");
02731                 }
02732                 break;
02733     case UI_JEDI_NONJEDI:
02734                 i = uiJediNonJedi;
02735                 if (i < 0 || i > 1)
02736                 {
02737                         i = 0;
02738                 }
02739 
02740                 if (i == FORCE_NONJEDI)
02741                 {
02742 //                      s = "Non-Jedi";
02743                         s = (char *)UI_GetStringEdString("MENUS", "NO");
02744                 }
02745                 else
02746                 {
02747 //                      s = "Jedi";
02748                         s = (char *)UI_GetStringEdString("MENUS", "YES");
02749                 }
02750                 break;
02751     case UI_FORCE_RANK:
02752                 i = uiForceRank;
02753                 if (i < 1 || i > MAX_FORCE_RANK) {
02754                         i = 1;
02755                 }
02756 
02757                 s = (char *)UI_GetStringEdString("MP_INGAME", forceMasteryLevels[i]);
02758                 break;
02759         case UI_FORCE_RANK_HEAL:
02760         case UI_FORCE_RANK_LEVITATION:
02761         case UI_FORCE_RANK_SPEED:
02762         case UI_FORCE_RANK_PUSH:
02763         case UI_FORCE_RANK_PULL:
02764         case UI_FORCE_RANK_TELEPATHY:
02765         case UI_FORCE_RANK_GRIP:
02766         case UI_FORCE_RANK_LIGHTNING:
02767         case UI_FORCE_RANK_RAGE:
02768         case UI_FORCE_RANK_PROTECT:
02769         case UI_FORCE_RANK_ABSORB:
02770         case UI_FORCE_RANK_TEAM_HEAL:
02771         case UI_FORCE_RANK_TEAM_FORCE:
02772         case UI_FORCE_RANK_DRAIN:
02773         case UI_FORCE_RANK_SEE:
02774         case UI_FORCE_RANK_SABERATTACK:
02775         case UI_FORCE_RANK_SABERDEFEND:
02776         case UI_FORCE_RANK_SABERTHROW:
02777                 findex = (ownerDraw - UI_FORCE_RANK)-1;
02778                 //this will give us the index as long as UI_FORCE_RANK is always one below the first force rank index
02779                 i = uiForcePowersRank[findex];
02780 
02781                 if (i < 0 || i > NUM_FORCE_POWER_LEVELS-1)
02782                 {
02783                         i = 0;
02784                 }
02785 
02786                 s = va("%i", uiForcePowersRank[findex]);
02787                 break;
02788     case UI_CLANNAME:
02789                                 s = UI_Cvar_VariableString("ui_teamName");
02790       break;
02791     case UI_GAMETYPE:
02792                                 s = uiInfo.gameTypes[ui_gameType.integer].gameType;
02793       break;
02794     case UI_SKILL:
02795                                 i = trap_Cvar_VariableValue( "g_spSkill" );
02796                                 if (i < 1 || i > numSkillLevels) {
02797                                         i = 1;
02798                                 }
02799                           s = (char *)UI_GetStringEdString("MP_INGAME", (char *)skillLevels[i-1]);
02800       break;
02801     case UI_BLUETEAMNAME:
02802                           i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_blueTeam"));
02803                           if (i >= 0 && i < uiInfo.teamCount) {
02804                             s = va("%s: %s", (char *)UI_GetStringEdString("MENUS", "TEAM_BLUE"), uiInfo.teamList[i].teamName);
02805                           }
02806       break;
02807     case UI_REDTEAMNAME:
02808                           i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_redTeam"));
02809                           if (i >= 0 && i < uiInfo.teamCount) {
02810                             s = va("%s: %s",  (char *)UI_GetStringEdString("MENUS", "TEAM_RED"), uiInfo.teamList[i].teamName);
02811                           }
02812       break;
02813     case UI_BLUETEAM1:
02814                 case UI_BLUETEAM2:
02815                 case UI_BLUETEAM3:
02816                 case UI_BLUETEAM4:
02817                 case UI_BLUETEAM5:
02818                 case UI_BLUETEAM6:
02819                 case UI_BLUETEAM7:
02820                 case UI_BLUETEAM8:
02821                         if (ownerDraw <= UI_BLUETEAM5)
02822                         {
02823                           iUse = ownerDraw-UI_BLUETEAM1 + 1;
02824                         }
02825                         else
02826                         {
02827                           iUse = ownerDraw-274; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
02828                         }
02829 
02830                         value = trap_Cvar_VariableValue(va("ui_blueteam%i", iUse));
02831                         if (value <= 1) {
02832                                 text = "Human";
02833                         } else {
02834                                 value -= 2;
02835                                 if (value >= uiInfo.aliasCount) {
02836                                         value = 1;
02837                                 }
02838                                 text = uiInfo.aliasList[value].name;
02839                         }
02840                         s = va("%i. %s", iUse, text);
02841       break;
02842     case UI_REDTEAM1:
02843                 case UI_REDTEAM2:
02844                 case UI_REDTEAM3:
02845                 case UI_REDTEAM4:
02846                 case UI_REDTEAM5:
02847                 case UI_REDTEAM6:
02848                 case UI_REDTEAM7:
02849                 case UI_REDTEAM8:
02850                         if (ownerDraw <= UI_REDTEAM5)
02851                         {
02852                           iUse = ownerDraw-UI_REDTEAM1 + 1;
02853                         }
02854                         else
02855                         {
02856                           iUse = ownerDraw-277; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
02857                         }
02858 
02859                         value = trap_Cvar_VariableValue(va("ui_redteam%i", iUse));
02860                         if (value <= 1) {
02861                                 text = "Human";
02862                         } else {
02863                                 value -= 2;
02864                                 if (value >= uiInfo.aliasCount) {
02865                                         value = 1;
02866                                 }
02867                                 text = uiInfo.aliasList[value].name;
02868                         }
02869                         s = va("%i. %s", iUse, text);
02870       break;
02871                 case UI_NETSOURCE:
02872                         if (ui_netSource.integer < 0 || ui_netSource.integer > uiInfo.numJoinGameTypes) {
02873                                 ui_netSource.integer = 0;
02874                         }
02875                         trap_SP_GetStringTextString("MENUS_SOURCE", holdSPString, sizeof(holdSPString));
02876                         s = va("%s %s", holdSPString, GetNetSourceString(ui_netSource.integer));
02877                         break;
02878                 case UI_NETFILTER:
02879                         if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) {
02880                                 ui_serverFilterType.integer = 0;
02881                         }
02882                         trap_SP_GetStringTextString("MENUS_GAME", holdSPString, sizeof(holdSPString));
02883                         trap_SP_GetStringTextString(serverFilters[ui_serverFilterType.integer].description, holdSPString2, sizeof(holdSPString2));
02884 
02885                         s = va("%s %s", holdSPString, holdSPString2 );
02886                         break;
02887                 case UI_TIER:
02888                         break;
02889                 case UI_TIER_MAPNAME:
02890                         break;
02891                 case UI_TIER_GAMETYPE:
02892                         break;
02893                 case UI_ALLMAPS_SELECTION:
02894                         break;
02895                 case UI_OPPONENT_NAME:
02896                         break;
02897                 case UI_KEYBINDSTATUS:
02898                         if (Display_KeyBindPending()) {
02899                                 s = UI_GetStringEdString("MP_INGAME", "WAITING_FOR_NEW_KEY");
02900                         } else {
02901                         //      s = "Press ENTER or CLICK to change, Press BACKSPACE to clear";
02902                         }
02903                         break;
02904                 case UI_SERVERREFRESHDATE:
02905                         s = UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer));
02906                         break;
02907     default:
02908       break;
02909   }
02910 
02911         if (s) {
02912                 return Text_Width(s, scale, 0);
02913         }
02914         return 0;
02915 }
02916 
02917 static void UI_DrawBotName(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont) 
02918 {
02919         int value = uiInfo.botIndex;
02920         const char *text = "";
02921         if (value >= UI_GetNumBots()) {
02922                 value = 0;
02923         }
02924         text = UI_GetBotNameByNumber(value);
02925         Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle,iMenuFont);
02926 }
02927 
02928 static void UI_DrawBotSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont) 
02929 {
02930         if (uiInfo.skillIndex >= 0 && uiInfo.skillIndex < numSkillLevels) 
02931         {
02932                 Text_Paint(rect->x, rect->y, scale, color, (char *)UI_GetStringEdString("MP_INGAME", (char *)skillLevels[uiInfo.skillIndex]), 0, 0, textStyle,iMenuFont);
02933         }
02934 }
02935 
02936 static void UI_DrawRedBlue(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont) 
02937 {
02938         Text_Paint(rect->x, rect->y, scale, color, (uiInfo.redBlue == 0) ? UI_GetStringEdString("MP_INGAME","RED") : UI_GetStringEdString("MP_INGAME","BLUE"), 0, 0, textStyle,iMenuFont);
02939 }
02940 
02941 static void UI_DrawCrosshair(rectDef_t *rect, float scale, vec4_t color) {
02942         trap_R_SetColor( color );
02943         if (uiInfo.currentCrosshair < 0 || uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
02944                 uiInfo.currentCrosshair = 0;
02945         }
02946         UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.uiDC.Assets.crosshairShader[uiInfo.currentCrosshair]);
02947         trap_R_SetColor( NULL );
02948 }
02949 
02950 /*
02951 ===============
02952 UI_BuildPlayerList
02953 ===============
02954 */
02955 static void UI_BuildPlayerList() {
02956         uiClientState_t cs;
02957         int             n, count, team, team2, playerTeamNumber;
02958         char    info[MAX_INFO_STRING];
02959 
02960         trap_GetClientState( &cs );
02961         trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING );
02962         uiInfo.playerNumber = cs.clientNum;
02963         uiInfo.teamLeader = atoi(Info_ValueForKey(info, "tl"));
02964         team = atoi(Info_ValueForKey(info, "t"));
02965         trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
02966         count = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
02967         uiInfo.playerCount = 0;
02968         uiInfo.myTeamCount = 0;
02969         playerTeamNumber = 0;
02970         for( n = 0; n < count; n++ ) {
02971                 trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING );
02972 
02973                 if (info[0]) {
02974                         Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
02975                         Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] );
02976                         uiInfo.playerIndexes[uiInfo.playerCount] = n;
02977                         uiInfo.playerCount++;
02978                         team2 = atoi(Info_ValueForKey(info, "t"));
02979                         if (team2 == team && n != uiInfo.playerNumber) {
02980                                 Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
02981                                 Q_CleanStr( uiInfo.teamNames[uiInfo.myTeamCount] );
02982                                 uiInfo.teamClientNums[uiInfo.myTeamCount] = n;
02983                                 if (uiInfo.playerNumber == n) {
02984                                         playerTeamNumber = uiInfo.myTeamCount;
02985                                 }
02986                                 uiInfo.myTeamCount++;
02987                         }
02988                 }
02989         }
02990 
02991         if (!uiInfo.teamLeader) {
02992                 trap_Cvar_Set("cg_selectedPlayer", va("%d", playerTeamNumber));
02993         }
02994 
02995         n = trap_Cvar_VariableValue("cg_selectedPlayer");
02996         if (n < 0 || n > uiInfo.myTeamCount) {
02997                 n = 0;
02998         }
02999 
03000 
03001         if (n < uiInfo.myTeamCount) {
03002                 trap_Cvar_Set("cg_selectedPlayerName", uiInfo.teamNames[n]);
03003         }
03004         else
03005         {
03006                 trap_Cvar_Set("cg_selectedPlayerName", "Everyone");
03007         }
03008 
03009         if (!team || team == TEAM_SPECTATOR || !uiInfo.teamLeader)
03010         {
03011                 n = uiInfo.myTeamCount;
03012                 trap_Cvar_Set("cg_selectedPlayer", va("%d", n));
03013                 trap_Cvar_Set("cg_selectedPlayerName", "N/A");
03014         }
03015 }
03016 
03017 
03018 static void UI_DrawSelectedPlayer(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
03019         if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) {
03020                 uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
03021                 UI_BuildPlayerList();
03022         }
03023   Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("cg_selectedPlayerName"), 0, 0, textStyle, iMenuFont);
03024 }
03025 
03026 static void UI_DrawServerRefreshDate(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) 
03027 {
03028         if (uiInfo.serverStatus.refreshActive) 
03029         {
03030                 vec4_t lowLight, newColor;
03031                 lowLight[0] = 0.8 * color[0]; 
03032                 lowLight[1] = 0.8 * color[1]; 
03033                 lowLight[2] = 0.8 * color[2]; 
03034                 lowLight[3] = 0.8 * color[3]; 
03035                 LerpColor(color,lowLight,newColor,0.5+0.5*sin((float)(uiInfo.uiDC.realTime / PULSE_DIVISOR)));
03036 
03037                 trap_SP_GetStringTextString("MP_INGAME_GETTINGINFOFORSERVERS", holdSPString, sizeof(holdSPString));
03038                 Text_Paint(rect->x, rect->y, scale, newColor, va((char *) holdSPString, trap_LAN_GetServerCount(ui_netSource.integer)), 0, 0, textStyle, iMenuFont);
03039         } 
03040         else 
03041         {
03042                 char buff[64];
03043                 Q_strncpyz(buff, UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)), 64);
03044                 trap_SP_GetStringTextString("MP_INGAME_SERVER_REFRESHTIME", holdSPString, sizeof(holdSPString));
03045 
03046                 Text_Paint(rect->x, rect->y, scale, color, va("%s: %s", holdSPString, buff), 0, 0, textStyle, iMenuFont);
03047         }
03048 }
03049 
03050 static void UI_DrawServerMOTD(rectDef_t *rect, float scale, vec4_t color, int iMenuFont) {
03051         if (uiInfo.serverStatus.motdLen) {
03052                 float maxX;
03053          
03054                 if (uiInfo.serverStatus.motdWidth == -1) {
03055                         uiInfo.serverStatus.motdWidth = 0;
03056                         uiInfo.serverStatus.motdPaintX = rect->x + 1;
03057                         uiInfo.serverStatus.motdPaintX2 = -1;
03058                 }
03059 
03060                 if (uiInfo.serverStatus.motdOffset > uiInfo.serverStatus.motdLen) {
03061                         uiInfo.serverStatus.motdOffset = 0;
03062                         uiInfo.serverStatus.motdPaintX = rect->x + 1;
03063                         uiInfo.serverStatus.motdPaintX2 = -1;
03064                 }
03065 
03066                 if (uiInfo.uiDC.realTime > uiInfo.serverStatus.motdTime) {
03067                         uiInfo.serverStatus.motdTime = uiInfo.uiDC.realTime + 10;
03068                         if (uiInfo.serverStatus.motdPaintX <= rect->x + 2) {
03069                                 if (uiInfo.serverStatus.motdOffset < uiInfo.serverStatus.motdLen) {
03070                                         uiInfo.serverStatus.motdPaintX += Text_Width(&uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], scale, 1) - 1;
03071                                         uiInfo.serverStatus.motdOffset++;
03072                                 } else {
03073                                         uiInfo.serverStatus.motdOffset = 0;
03074                                         if (uiInfo.serverStatus.motdPaintX2 >= 0) {
03075                                                 uiInfo.serverStatus.motdPaintX = uiInfo.serverStatus.motdPaintX2;
03076                                         } else {
03077                                                 uiInfo.serverStatus.motdPaintX = rect->x + rect->w - 2;
03078                                         }
03079                                         uiInfo.serverStatus.motdPaintX2 = -1;
03080                                 }
03081                         } else {
03082                                 //serverStatus.motdPaintX--;
03083                                 uiInfo.serverStatus.motdPaintX -= 2;
03084                                 if (uiInfo.serverStatus.motdPaintX2 >= 0) {
03085                                         //serverStatus.motdPaintX2--;
03086                                         uiInfo.serverStatus.motdPaintX2 -= 2;
03087                                 }
03088                         }
03089                 }
03090 
03091                 maxX = rect->x + rect->w - 2;
03092                 Text_Paint_Limit(&maxX, uiInfo.serverStatus.motdPaintX, rect->y + rect->h - 3, scale, color, &uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], 0, 0, iMenuFont); 
03093                 if (uiInfo.serverStatus.motdPaintX2 >= 0) {
03094                         float maxX2 = rect->x + rect->w - 2;
03095                         Text_Paint_Limit(&maxX2, uiInfo.serverStatus.motdPaintX2, rect->y + rect->h - 3, scale, color, uiInfo.serverStatus.motd, 0, uiInfo.serverStatus.motdOffset, iMenuFont); 
03096                 }
03097                 if (uiInfo.serverStatus.motdOffset && maxX > 0) {
03098                         // if we have an offset ( we are skipping the first part of the string ) and we fit the string
03099                         if (uiInfo.serverStatus.motdPaintX2 == -1) {
03100                                                 uiInfo.serverStatus.motdPaintX2 = rect->x + rect->w - 2;
03101                         }
03102                 } else {
03103                         uiInfo.serverStatus.motdPaintX2 = -1;
03104                 }
03105 
03106         }
03107 }
03108 
03109 static void UI_DrawKeyBindStatus(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont) {
03110 //      int ofs = 0; TTimo: unused
03111         if (Display_KeyBindPending()) 
03112         {
03113                 Text_Paint(rect->x, rect->y, scale, color, UI_GetStringEdString("MP_INGAME", "WAITING_FOR_NEW_KEY"), 0, 0, textStyle,iMenuFont);
03114         } else {
03115 //              Text_Paint(rect->x, rect->y, scale, color, "Press ENTER or CLICK to change, Press BACKSPACE to clear", 0, 0, textStyle,iMenuFont);
03116         }
03117 }
03118 
03119 static void UI_DrawGLInfo(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont) 
03120 {
03121         char * eptr;
03122         char buff[4096];
03123         const char *lines[128];
03124         int y, numLines, i;
03125 
03126         Text_Paint(rect->x + 2, rect->y, scale, color, va("GL_VENDOR: %s", uiInfo.uiDC.glconfig.vendor_string), 0, rect->w, textStyle,iMenuFont);
03127         Text_Paint(rect->x + 2, rect->y + 15, scale, color, va("GL_VERSION: %s: %s", uiInfo.uiDC.glconfig.version_string,uiInfo.uiDC.glconfig.renderer_string), 0, rect->w, textStyle,iMenuFont);
03128         Text_Paint(rect->x + 2, rect->y + 30, scale, color, va ("GL_PIXELFORMAT: color(%d-bits) Z(%d-bits) stencil(%d-bits)", uiInfo.uiDC.glconfig.colorBits, uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits), 0, rect->w, textStyle,iMenuFont);
03129 
03130         // build null terminated extension strings
03131         Q_strncpyz(buff, uiInfo.uiDC.glconfig.extensions_string, 4096);
03132         eptr = buff;
03133         y = rect->y + 45;
03134         numLines = 0;
03135         while ( y < rect->y + rect->h && *eptr )
03136         {
03137                 while ( *eptr && *eptr == ' ' )
03138                         *eptr++ = '\0';
03139 
03140                 // track start of valid string
03141                 if (*eptr && *eptr != ' ') 
03142                 {
03143                         lines[numLines++] = eptr;
03144                 }
03145 
03146                 while ( *eptr && *eptr != ' ' )
03147                         eptr++;
03148         }
03149 
03150         i = 0;
03151         while (i < numLines) 
03152         {
03153                 Text_Paint(rect->x + 2, y, scale, color, lines[i++], 0, (rect->w/2), textStyle,iMenuFont);
03154                 if (i < numLines) 
03155                 {
03156                         Text_Paint(rect->x + rect->w / 2, y, scale, color, lines[i++], 0, (rect->w/2), textStyle,iMenuFont);
03157                 }
03158                 y += 10;
03159                 if (y > rect->y + rect->h - 11) 
03160                 {
03161                         break;
03162                 }
03163         }
03164 
03165 
03166 }
03167 
03168 /*
03169 =================
03170 UI_Version
03171 =================
03172 */
03173 static void UI_Version(rectDef_t *rect, float scale, vec4_t color, int iMenuFont) 
03174 {
03175         int width;
03176         
03177         width = uiInfo.uiDC.textWidth(Q3_VERSION, scale, iMenuFont);
03178 
03179         uiInfo.uiDC.drawText(rect->x - width, rect->y, scale, color, Q3_VERSION, 0, 0, 0, iMenuFont);
03180 }
03181 
03182 /*
03183 =================
03184 UI_OwnerDraw
03185 =================
03186 */
03187 // FIXME: table drive
03188 //
03189 static void UI_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, int align, float special, float scale, vec4_t color, qhandle_t shader, int textStyle,int iMenuFont) 
03190 {
03191         rectDef_t rect;
03192         int findex;
03193         int drawRank = 0, iUse = 0;
03194 
03195         rect.x = x + text_x;
03196         rect.y = y + text_y;
03197         rect.w = w;
03198         rect.h = h;
03199 
03200   switch (ownerDraw) 
03201   {
03202     case UI_HANDICAP:
03203       UI_DrawHandicap(&rect, scale, color, textStyle, iMenuFont);
03204       break;
03205     case UI_SKIN_COLOR:
03206       UI_DrawSkinColor(&rect, scale, color, textStyle, uiSkinColor, TEAM_FREE, TEAM_BLUE, iMenuFont);
03207       break;
03208         case UI_FORCE_SIDE:
03209       UI_DrawForceSide(&rect, scale, color, textStyle, uiForceSide, 1, 2, iMenuFont);
03210       break;
03211         case UI_JEDI_NONJEDI:
03212       UI_DrawJediNonJedi(&rect, scale, color, textStyle, uiJediNonJedi, 0, 1, iMenuFont);
03213       break;
03214     case UI_FORCE_POINTS:
03215       UI_DrawGenericNum(&rect, scale, color, textStyle, uiForceAvailable, 1, forceMasteryPoints[MAX_FORCE_RANK], ownerDraw,iMenuFont);
03216       break;
03217         case UI_FORCE_MASTERY_SET:
03218       UI_DrawForceMastery(&rect, scale, color, textStyle, uiForceRank, 0, MAX_FORCE_RANK, iMenuFont);
03219       break;
03220     case UI_FORCE_RANK:
03221       UI_DrawForceMastery(&rect, scale, color, textStyle, uiForceRank, 0, MAX_FORCE_RANK, iMenuFont);
03222       break;
03223         case UI_FORCE_RANK_HEAL:
03224         case UI_FORCE_RANK_LEVITATION:
03225         case UI_FORCE_RANK_SPEED:
03226         case UI_FORCE_RANK_PUSH:
03227         case UI_FORCE_RANK_PULL:
03228         case UI_FORCE_RANK_TELEPATHY:
03229         case UI_FORCE_RANK_GRIP:
03230         case UI_FORCE_RANK_LIGHTNING:
03231         case UI_FORCE_RANK_RAGE:
03232         case UI_FORCE_RANK_PROTECT:
03233         case UI_FORCE_RANK_ABSORB:
03234         case UI_FORCE_RANK_TEAM_HEAL:
03235         case UI_FORCE_RANK_TEAM_FORCE:
03236         case UI_FORCE_RANK_DRAIN:
03237         case UI_FORCE_RANK_SEE:
03238         case UI_FORCE_RANK_SABERATTACK:
03239         case UI_FORCE_RANK_SABERDEFEND:
03240         case UI_FORCE_RANK_SABERTHROW:
03241 
03242 //              uiForceRank
03243 /*
03244                 uiForceUsed
03245                 // Only fields for white stars
03246                 if (uiForceUsed<3)
03247                 {
03248                     Menu_ShowItemByName(menu, "lightpowers_team", qtrue);
03249                 }
03250                 else if (uiForceUsed<6)
03251                 {
03252                     Menu_ShowItemByName(menu, "lightpowers_team", qtrue);
03253                 }
03254 */
03255 
03256                 findex = (ownerDraw - UI_FORCE_RANK)-1;
03257                 //this will give us the index as long as UI_FORCE_RANK is always one below the first force rank index
03258                 if (uiForcePowerDarkLight[findex] && uiForceSide != uiForcePowerDarkLight[findex])
03259                 {
03260                         color[0] *= 0.5;
03261                         color[1] *= 0.5;
03262                         color[2] *= 0.5;
03263                 }
03264 /*              else if (uiForceRank < UI_ForceColorMinRank[bgForcePowerCost[findex][FORCE_LEVEL_1]])
03265                 {
03266                         color[0] *= 0.5;
03267                         color[1] *= 0.5;
03268                         color[2] *= 0.5;
03269                 }
03270 */              drawRank = uiForcePowersRank[findex];
03271 
03272                 UI_DrawForceStars(&rect, scale, color, textStyle, findex, drawRank, 0, NUM_FORCE_POWER_LEVELS-1);
03273                 break;
03274     case UI_EFFECTS:
03275       UI_DrawEffects(&rect, scale, color);
03276       break;
03277     case UI_PLAYERMODEL:
03278       //UI_DrawPlayerModel(&rect);
03279       break;
03280     case UI_CLANNAME:
03281       UI_DrawClanName(&rect, scale, color, textStyle, iMenuFont);
03282       break;
03283     case UI_CLANLOGO:
03284       UI_DrawClanLogo(&rect, scale, color);
03285       break;
03286     case UI_CLANCINEMATIC:
03287       UI_DrawClanCinematic(&rect, scale, color);
03288       break;
03289     case UI_PREVIEWCINEMATIC:
03290       UI_DrawPreviewCinematic(&rect, scale, color);
03291       break;
03292     case UI_GAMETYPE:
03293       UI_DrawGameType(&rect, scale, color, textStyle, iMenuFont);
03294       break;
03295     case UI_NETGAMETYPE:
03296       UI_DrawNetGameType(&rect, scale, color, textStyle, iMenuFont);
03297       break;
03298     case UI_AUTOSWITCHLIST:
03299       UI_DrawAutoSwitch(&rect, scale, color, textStyle, iMenuFont);
03300       break;
03301     case UI_JOINGAMETYPE:
03302           UI_DrawJoinGameType(&rect, scale, color, textStyle, iMenuFont);
03303           break;
03304     case UI_MAPPREVIEW:
03305       UI_DrawMapPreview(&rect, scale, color, qtrue);
03306       break;
03307     case UI_MAP_TIMETOBEAT:
03308       UI_DrawMapTimeToBeat(&rect, scale, color, textStyle, iMenuFont);
03309       break;
03310     case UI_MAPCINEMATIC:
03311       UI_DrawMapCinematic(&rect, scale, color, qfalse);
03312       break;
03313     case UI_STARTMAPCINEMATIC:
03314       UI_DrawMapCinematic(&rect, scale, color, qtrue);
03315       break;
03316     case UI_SKILL:
03317       UI_DrawSkill(&rect, scale, color, textStyle, iMenuFont);
03318       break;
03319     case UI_TOTALFORCESTARS:
03320 //      UI_DrawTotalForceStars(&rect, scale, color, textStyle);
03321       break;
03322     case UI_BLUETEAMNAME:
03323       UI_DrawTeamName(&rect, scale, color, qtrue, textStyle, iMenuFont);
03324       break;
03325     case UI_REDTEAMNAME:
03326       UI_DrawTeamName(&rect, scale, color, qfalse, textStyle, iMenuFont);
03327       break;
03328     case UI_BLUETEAM1:
03329                 case UI_BLUETEAM2:
03330                 case UI_BLUETEAM3:
03331                 case UI_BLUETEAM4:
03332                 case UI_BLUETEAM5:
03333                 case UI_BLUETEAM6:
03334                 case UI_BLUETEAM7:
03335                 case UI_BLUETEAM8:
03336         if (ownerDraw <= UI_BLUETEAM5)
03337         {
03338           iUse = ownerDraw-UI_BLUETEAM1 + 1;
03339         }
03340         else
03341         {
03342           iUse = ownerDraw-274; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
03343         }
03344       UI_DrawTeamMember(&rect, scale, color, qtrue, iUse, textStyle, iMenuFont);
03345       break;
03346     case UI_REDTEAM1:
03347                 case UI_REDTEAM2:
03348                 case UI_REDTEAM3:
03349                 case UI_REDTEAM4:
03350                 case UI_REDTEAM5:
03351                 case UI_REDTEAM6:
03352                 case UI_REDTEAM7:
03353                 case UI_REDTEAM8:
03354         if (ownerDraw <= UI_REDTEAM5)
03355         {
03356           iUse = ownerDraw-UI_REDTEAM1 + 1;
03357         }
03358         else
03359         {
03360           iUse = ownerDraw-277; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
03361         }
03362       UI_DrawTeamMember(&rect, scale, color, qfalse, iUse, textStyle, iMenuFont);
03363       break;
03364                 case UI_NETSOURCE:
03365       UI_DrawNetSource(&rect, scale, color, textStyle, iMenuFont);
03366                         break;
03367     case UI_NETMAPPREVIEW:
03368       UI_DrawNetMapPreview(&rect, scale, color);
03369       break;
03370     case UI_NETMAPCINEMATIC:
03371       UI_DrawNetMapCinematic(&rect, scale, color);
03372       break;
03373                 case UI_NETFILTER:
03374       UI_DrawNetFilter(&rect, scale, color, textStyle, iMenuFont);
03375                         break;
03376                 case UI_TIER:
03377                         UI_DrawTier(&rect, scale, color, textStyle, iMenuFont);
03378                         break;
03379                 case UI_OPPONENTMODEL:
03380                         //UI_DrawOpponent(&rect);
03381                         break;
03382                 case UI_TIERMAP1:
03383                         UI_DrawTierMap(&rect, 0);
03384                         break;
03385                 case UI_TIERMAP2:
03386                         UI_DrawTierMap(&rect, 1);
03387                         break;
03388                 case UI_TIERMAP3:
03389                         UI_DrawTierMap(&rect, 2);
03390                         break;
03391                 case UI_PLAYERLOGO:
03392                         UI_DrawPlayerLogo(&rect, color);
03393                         break;
03394                 case UI_PLAYERLOGO_METAL:
03395                         UI_DrawPlayerLogoMetal(&rect, color);
03396                         break;
03397                 case UI_PLAYERLOGO_NAME:
03398                         UI_DrawPlayerLogoName(&rect, color);
03399                         break;
03400                 case UI_OPPONENTLOGO:
03401                         UI_DrawOpponentLogo(&rect, color);
03402                         break;
03403                 case UI_OPPONENTLOGO_METAL:
03404                         UI_DrawOpponentLogoMetal(&rect, color);
03405                         break;
03406                 case UI_OPPONENTLOGO_NAME:
03407                         UI_DrawOpponentLogoName(&rect, color);
03408                         break;
03409                 case UI_TIER_MAPNAME:
03410                         UI_DrawTierMapName(&rect, scale, color, textStyle, iMenuFont);
03411                         break;
03412                 case UI_TIER_GAMETYPE:
03413                         UI_DrawTierGameType(&rect, scale, color, textStyle, iMenuFont);
03414                         break;
03415                 case UI_ALLMAPS_SELECTION:
03416                         UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qtrue, iMenuFont);
03417                         break;
03418                 case UI_MAPS_SELECTION:
03419                         UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qfalse, iMenuFont);
03420                         break;
03421                 case UI_OPPONENT_NAME:
03422                         UI_DrawOpponentName(&rect, scale, color, textStyle, iMenuFont);
03423                         break;
03424                 case UI_BOTNAME:
03425                         UI_DrawBotName(&rect, scale, color, textStyle,iMenuFont);
03426                         break;
03427                 case UI_BOTSKILL:
03428                         UI_DrawBotSkill(&rect, scale, color, textStyle,iMenuFont);
03429                         break;
03430                 case UI_REDBLUE:
03431                         UI_DrawRedBlue(&rect, scale, color, textStyle,iMenuFont);
03432                         break;
03433                 case UI_CROSSHAIR:
03434                         UI_DrawCrosshair(&rect, scale, color);
03435                         break;
03436                 case UI_SELECTEDPLAYER:
03437                         UI_DrawSelectedPlayer(&rect, scale, color, textStyle, iMenuFont);
03438                         break;
03439                 case UI_SERVERREFRESHDATE:
03440                         UI_DrawServerRefreshDate(&rect, scale, color, textStyle, iMenuFont);
03441                         break;
03442                 case UI_SERVERMOTD:
03443                         UI_DrawServerMOTD(&rect, scale, color, iMenuFont);
03444                         break;
03445                 case UI_GLINFO:
03446                         UI_DrawGLInfo(&rect,scale, color, textStyle, iMenuFont);
03447                         break;
03448                 case UI_KEYBINDSTATUS:
03449                         UI_DrawKeyBindStatus(&rect,scale, color, textStyle,iMenuFont);
03450                         break;
03451                 case UI_VERSION:
03452                         UI_Version(&rect, scale, color, iMenuFont);
03453                         break;
03454     default:
03455       break;
03456   }
03457 
03458 }
03459 
03460 static qboolean UI_OwnerDrawVisible(int flags) {
03461         qboolean vis = qtrue;
03462 
03463         while (flags) {
03464 
03465                 if (flags & UI_SHOW_FFA) {
03466                         if (trap_Cvar_VariableValue("g_gametype") != GT_FFA && trap_Cvar_VariableValue("g_gametype") != GT_HOLOCRON && trap_Cvar_VariableValue("g_gametype") != GT_JEDIMASTER) {
03467                                 vis = qfalse;
03468                         }
03469                         flags &= ~UI_SHOW_FFA;
03470                 }
03471 
03472                 if (flags & UI_SHOW_NOTFFA) {
03473                         if (trap_Cvar_VariableValue("g_gametype") == GT_FFA || trap_Cvar_VariableValue("g_gametype") == GT_HOLOCRON || trap_Cvar_VariableValue("g_gametype") != GT_JEDIMASTER) {
03474                                 vis = qfalse;
03475                         }
03476                         flags &= ~UI_SHOW_NOTFFA;
03477                 }
03478 
03479                 if (flags & UI_SHOW_LEADER) {
03480                         // these need to show when this client can give orders to a player or a group
03481                         if (!uiInfo.teamLeader) {
03482                                 vis = qfalse;
03483                         } else {
03484                                 // if showing yourself
03485                                 if (ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber) { 
03486                                         vis = qfalse;
03487                                 }
03488                         }
03489                         flags &= ~UI_SHOW_LEADER;
03490                 } 
03491                 if (flags & UI_SHOW_NOTLEADER) {
03492                         // these need to show when this client is assigning their own status or they are NOT the leader
03493                         if (uiInfo.teamLeader) {
03494                                 // if not showing yourself
03495                                 if (!(ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber)) { 
03496                                         vis = qfalse;
03497                                 }
03498                                 // these need to show when this client can give orders to a player or a group
03499                         }
03500                         flags &= ~UI_SHOW_NOTLEADER;
03501                 } 
03502                 if (flags & UI_SHOW_FAVORITESERVERS) {
03503                         // this assumes you only put this type of display flag on something showing in the proper context
03504                         if (ui_netSource.integer != AS_FAVORITES) {
03505                                 vis = qfalse;
03506                         }
03507                         flags &= ~UI_SHOW_FAVORITESERVERS;
03508                 } 
03509                 if (flags & UI_SHOW_NOTFAVORITESERVERS) {
03510                         // this assumes you only put this type of display flag on something showing in the proper context
03511                         if (ui_netSource.integer == AS_FAVORITES) {
03512                                 vis = qfalse;
03513                         }
03514                         flags &= ~UI_SHOW_NOTFAVORITESERVERS;
03515                 } 
03516                 if (flags & UI_SHOW_ANYTEAMGAME) {
03517                         if (uiInfo.gameTypes[ui_gameType.integer].gtEnum <= GT_TEAM ) {
03518                                 vis = qfalse;
03519                         }
03520                         flags &= ~UI_SHOW_ANYTEAMGAME;
03521                 } 
03522                 if (flags & UI_SHOW_ANYNONTEAMGAME) {
03523                         if (uiInfo.gameTypes[ui_gameType.integer].gtEnum > GT_TEAM ) {
03524                                 vis = qfalse;
03525                         }
03526                         flags &= ~UI_SHOW_ANYNONTEAMGAME;
03527                 } 
03528                 if (flags & UI_SHOW_NETANYTEAMGAME) {
03529                         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum <= GT_TEAM ) {
03530                                 vis = qfalse;
03531                         }
03532                         flags &= ~UI_SHOW_NETANYTEAMGAME;
03533                 } 
03534                 if (flags & UI_SHOW_NETANYNONTEAMGAME) {
03535                         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum > GT_TEAM ) {
03536                                 vis = qfalse;
03537                         }
03538                         flags &= ~UI_SHOW_NETANYNONTEAMGAME;
03539                 } 
03540                 if (flags & UI_SHOW_NEWHIGHSCORE) {
03541                         if (uiInfo.newHighScoreTime < uiInfo.uiDC.realTime) {
03542                                 vis = qfalse;
03543                         } else {
03544                                 if (uiInfo.soundHighScore) {
03545                                         if (trap_Cvar_VariableValue("sv_killserver") == 0) {
03546                                                 // wait on server to go down before playing sound
03547                                                 //trap_S_StartLocalSound(uiInfo.newHighScoreSound, CHAN_ANNOUNCER);
03548                                                 uiInfo.soundHighScore = qfalse;
03549                                         }
03550                                 }
03551                         }
03552                         flags &= ~UI_SHOW_NEWHIGHSCORE;
03553                 } 
03554                 if (flags & UI_SHOW_NEWBESTTIME) {
03555                         if (uiInfo.newBestTime < uiInfo.uiDC.realTime) {
03556                                 vis = qfalse;
03557                         }
03558                         flags &= ~UI_SHOW_NEWBESTTIME;
03559                 } 
03560                 if (flags & UI_SHOW_DEMOAVAILABLE) {
03561                         if (!uiInfo.demoAvailable) {
03562                                 vis = qfalse;
03563                         }
03564                         flags &= ~UI_SHOW_DEMOAVAILABLE;
03565                 } else {
03566                         flags = 0;
03567                 }
03568         }
03569   return vis;
03570 }
03571 
03572 static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) {
03573   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
03574     int h;
03575     h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
03576                 if (key == A_MOUSE2) {
03577             h -= 5;
03578                 } else {
03579             h += 5;
03580                 }
03581     if (h > 100) {
03582       h = 5;
03583     } else if (h < 0) {
03584                         h = 100;
03585                 }
03586         trap_Cvar_Set( "handicap", va( "%i", h) );
03587     return qtrue;
03588   }
03589   return qfalse;
03590 }
03591 
03592 static qboolean UI_Effects_HandleKey(int flags, float *special, int key) {
03593         if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
03594                 
03595                 if ( !UI_TrueJediEnabled() )
03596                 {
03597                         int team = (int)(trap_Cvar_VariableValue("ui_myteam"));
03598                                         
03599                         if (team == TEAM_RED || team==TEAM_BLUE)
03600                         {
03601                                 return qfalse;
03602                         }
03603                 }
03604                                 
03605                 if (key == A_MOUSE2) {
03606                         uiInfo.effectsColor--;
03607                 } else {
03608                         uiInfo.effectsColor++;
03609                 }
03610                 
03611                 if( uiInfo.effectsColor > 5 ) {
03612                         uiInfo.effectsColor = 0;
03613                 } else if (uiInfo.effectsColor < 0) {
03614                         uiInfo.effectsColor = 5;
03615                 }
03616                 
03617                 trap_Cvar_SetValue( "color1", /*uitogamecode[uiInfo.effectsColor]*/uiInfo.effectsColor );
03618                 return qtrue;
03619         }
03620         return qfalse;
03621 }
03622 
03623 #include "../namespace_begin.h"
03624 extern void     Item_RunScript(itemDef_t *item, const char *s);         //from ui_shared;
03625 #include "../namespace_end.h"
03626 
03627 // For hot keys on the chat main menu.
03628 static qboolean UI_Chat_Main_HandleKey(int key) 
03629 {
03630         menuDef_t *menu;
03631         itemDef_t *item;
03632 
03633         menu = Menu_GetFocused();       
03634 
03635         if (!menu)
03636         {
03637                 return (qfalse);
03638         }
03639 
03640         if ((key == A_1) || ( key == A_PLING))
03641         {
03642                 item = Menu_FindItemByName(menu, "attack");
03643         }
03644         else if ((key == A_2) || ( key == A_AT))
03645         {
03646                 item = Menu_FindItemByName(menu, "defend");
03647         }
03648         else if ((key == A_3) || ( key == A_HASH))
03649         {
03650                 item = Menu_FindItemByName(menu, "request");
03651         }
03652         else if ((key == A_4) || ( key == A_STRING))
03653         {
03654                 item = Menu_FindItemByName(menu, "reply");
03655         }
03656         else if ((key == A_5) || ( key == A_PERCENT))
03657         {
03658                 item = Menu_FindItemByName(menu, "spot");
03659         }
03660         else if ((key == A_6) || ( key == A_CARET))
03661         {
03662                 item = Menu_FindItemByName(menu, "tactics");
03663         }
03664         else
03665         {
03666                 return (qfalse);
03667         }
03668 
03669         if (item)
03670         {
03671             Item_RunScript(item, item->action);
03672         }
03673 
03674         return (qtrue);
03675 }
03676 
03677 // For hot keys on the chat main menu.
03678 static qboolean UI_Chat_Attack_HandleKey(int key) 
03679 {
03680         menuDef_t *menu;
03681         itemDef_t *item;
03682 
03683         menu = Menu_GetFocused();       
03684 
03685         if (!menu)
03686         {
03687                 return (qfalse);
03688         }
03689 
03690         if ((key == A_1) || ( key == A_PLING))
03691         {
03692                 item = Menu_FindItemByName(menu, "att_01");
03693         }
03694         else if ((key == A_2) || ( key == A_AT))
03695         {
03696                 item = Menu_FindItemByName(menu, "att_02");
03697         }
03698         else if ((key == A_3) || ( key == A_HASH))
03699         {
03700                 item = Menu_FindItemByName(menu, "att_03");
03701         }
03702         else
03703         {
03704                 return (qfalse);
03705         }
03706 
03707         if (item)
03708         {
03709             Item_RunScript(item, item->action);
03710         }
03711 
03712         return (qtrue);
03713 }
03714 
03715 // For hot keys on the chat main menu.
03716 static qboolean UI_Chat_Defend_HandleKey(int key) 
03717 {
03718         menuDef_t *menu;
03719         itemDef_t *item;
03720 
03721         menu = Menu_GetFocused();       
03722 
03723         if (!menu)
03724         {
03725                 return (qfalse);
03726         }
03727 
03728         if ((key == A_1) || ( key == A_PLING))
03729         {
03730                 item = Menu_FindItemByName(menu, "def_01");
03731         }
03732         else if ((key == A_2) || ( key == A_AT))
03733         {
03734                 item = Menu_FindItemByName(menu, "def_02");
03735         }
03736         else if ((key == A_3) || ( key == A_HASH))
03737         {
03738                 item = Menu_FindItemByName(menu, "def_03");
03739         }
03740         else if ((key == A_4) || ( key == A_STRING))
03741         {
03742                 item = Menu_FindItemByName(menu, "def_04");
03743         }
03744         else
03745         {
03746                 return (qfalse);
03747         }
03748 
03749         if (item)
03750         {
03751             Item_RunScript(item, item->action);
03752         }
03753 
03754         return (qtrue);
03755 }
03756 
03757 // For hot keys on the chat main menu.
03758 static qboolean UI_Chat_Request_HandleKey(int key) 
03759 {
03760         menuDef_t *menu;
03761         itemDef_t *item;
03762 
03763         menu = Menu_GetFocused();       
03764 
03765         if (!menu)
03766         {
03767                 return (qfalse);
03768         }
03769 
03770         if ((key == A_1) || ( key == A_PLING))
03771         {
03772                 item = Menu_FindItemByName(menu, "req_01");
03773         }
03774         else if ((key == A_2) || ( key == A_AT))
03775         {
03776                 item = Menu_FindItemByName(menu, "req_02");
03777         }
03778         else if ((key == A_3) || ( key == A_HASH))
03779         {
03780                 item = Menu_FindItemByName(menu, "req_03");
03781         }
03782         else if ((key == A_4) || ( key == A_STRING))
03783         {
03784                 item = Menu_FindItemByName(menu, "req_04");
03785         }
03786         else if ((key == A_5) || ( key == A_PERCENT))
03787         {
03788                 item = Menu_FindItemByName(menu, "req_05");
03789         }
03790         else if ((key == A_6) || ( key == A_CARET))
03791         {
03792                 item = Menu_FindItemByName(menu, "req_06");
03793         }
03794         else
03795         {
03796                 return (qfalse);
03797         }
03798 
03799         if (item)
03800         {
03801             Item_RunScript(item, item->action);
03802         }
03803 
03804         return (qtrue);
03805 }
03806 
03807 // For hot keys on the chat main menu.
03808 static qboolean UI_Chat_Reply_HandleKey(int key) 
03809 {
03810         menuDef_t *menu;
03811         itemDef_t *item;
03812 
03813         menu = Menu_GetFocused();       
03814 
03815         if (!menu)
03816         {
03817                 return (qfalse);
03818         }
03819 
03820         if ((key == A_1) || ( key == A_PLING))
03821         {
03822                 item = Menu_FindItemByName(menu, "rep_01");
03823         }
03824         else if ((key == A_2) || ( key == A_AT))
03825         {
03826                 item = Menu_FindItemByName(menu, "rep_02");
03827         }
03828         else if ((key == A_3) || ( key == A_HASH))
03829         {
03830                 item = Menu_FindItemByName(menu, "rep_03");
03831         }
03832         else if ((key == A_4) || ( key == A_STRING))
03833         {
03834                 item = Menu_FindItemByName(menu, "rep_04");
03835         }
03836         else if ((key == A_5) || ( key == A_PERCENT))
03837         {
03838                 item = Menu_FindItemByName(menu, "rep_05");
03839         }
03840         else
03841         {
03842                 return (qfalse);
03843         }
03844 
03845         if (item)
03846         {
03847             Item_RunScript(item, item->action);
03848         }
03849 
03850         return (qtrue);
03851 }
03852 
03853 // For hot keys on the chat main menu.
03854 static qboolean UI_Chat_Spot_HandleKey(int key) 
03855 {
03856         menuDef_t *menu;
03857         itemDef_t *item;
03858 
03859         menu = Menu_GetFocused();       
03860 
03861         if (!menu)
03862         {
03863                 return (qfalse);
03864         }
03865 
03866         if ((key == A_1) || ( key == A_PLING))
03867         {
03868                 item = Menu_FindItemByName(menu, "spot_01");
03869         }
03870         else if ((key == A_2) || ( key == A_AT))
03871         {
03872                 item = Menu_FindItemByName(menu, "spot_02");
03873         }
03874         else if ((key == A_3) || ( key == A_HASH))
03875         {
03876                 item = Menu_FindItemByName(menu, "spot_03");
03877         }
03878         else if ((key == A_4) || ( key == A_STRING))
03879         {
03880                 item = Menu_FindItemByName(menu, "spot_04");
03881         }
03882         else
03883         {
03884                 return (qfalse);
03885         }
03886 
03887         if (item)
03888         {
03889             Item_RunScript(item, item->action);
03890         }
03891 
03892         return (qtrue);
03893 }
03894 
03895 // For hot keys on the chat main menu.
03896 static qboolean UI_Chat_Tactical_HandleKey(int key) 
03897 {
03898         menuDef_t *menu;
03899         itemDef_t *item;
03900 
03901         menu = Menu_GetFocused();       
03902 
03903         if (!menu)
03904         {
03905                 return (qfalse);
03906         }
03907 
03908         if ((key == A_1) || ( key == A_PLING))
03909         {
03910                 item = Menu_FindItemByName(menu, "tac_01");
03911         }
03912         else if ((key == A_2) || ( key == A_AT))
03913         {
03914                 item = Menu_FindItemByName(menu, "tac_02");
03915         }
03916         else if ((key == A_3) || ( key == A_HASH))
03917         {
03918                 item = Menu_FindItemByName(menu, "tac_03");
03919         }
03920         else if ((key == A_4) || ( key == A_STRING))
03921         {
03922                 item = Menu_FindItemByName(menu, "tac_04");
03923         }
03924         else if ((key == A_5) || ( key == A_PERCENT))
03925         {
03926                 item = Menu_FindItemByName(menu, "tac_05");
03927         }
03928         else if ((key == A_6) || ( key == A_CARET))
03929         {
03930                 item = Menu_FindItemByName(menu, "tac_06");
03931         }
03932         else
03933         {
03934                 return (qfalse);
03935         }
03936 
03937         if (item)
03938         {
03939             Item_RunScript(item, item->action);
03940         }
03941 
03942         return (qtrue);
03943 }
03944 
03945 static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) {
03946   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
03947                 int oldCount = UI_MapCountByGameType(qtrue);
03948 
03949                 // hard coded mess here
03950                 if (key == A_MOUSE2) {
03951                         ui_gameType.integer--;
03952                         if (ui_gameType.integer == 2) {
03953                                 ui_gameType.integer = 1;
03954                         } else if (ui_gameType.integer < 2) {
03955                                 ui_gameType.integer = uiInfo.numGameTypes - 1;
03956                         }
03957                 } else {
03958                         ui_gameType.integer++;
03959                         if (ui_gameType.integer >= uiInfo.numGameTypes) {
03960                                 ui_gameType.integer = 1;
03961                         } else if (ui_gameType.integer == 2) {
03962                                 ui_gameType.integer = 3;
03963                         }
03964                 }
03965     
03966                 trap_Cvar_Set("ui_gameType", va("%d", ui_gameType.integer));
03967                 UI_SetCapFragLimits(qtrue);
03968                 UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
03969                 if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) {
03970                 trap_Cvar_Set( "ui_currentMap", "0");
03971                         Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL);
03972                 }
03973     return qtrue;
03974   }
03975   return qfalse;
03976 }
03977 
03978 // If we're in the solo menu, don't let them see siege maps.
03979 static qboolean UI_InSoloMenu( void )
03980 {
03981         menuDef_t *menu;
03982         itemDef_t *item;
03983         char *name = "solo_gametypefield";
03984 
03985         menu = Menu_GetFocused();       // Get current menu (either video or ingame video, I would assume)
03986 
03987         if (!menu)
03988         {
03989                 return (qfalse);
03990         }
03991 
03992         item = Menu_FindItemByName(menu, name);
03993         if (item)
03994         {
03995                 return qtrue;
03996         }
03997 
03998         return (qfalse);
03999 }
04000 
04001 static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) 
04002 {
04003 #ifdef _XBOX
04004   if (key == A_CURSOR_RIGHT || key == A_CURSOR_LEFT)
04005 #else
04006   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) 
04007 #endif
04008   {
04009 
04010 #ifdef _XBOX
04011         if (key == A_CURSOR_LEFT) 
04012 #else
04013         if (key == A_MOUSE2) 
04014 #endif
04015         {
04016                 ui_netGameType.integer--;
04017                 if (UI_InSoloMenu())
04018                 {
04019                         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
04020                         {
04021                                 ui_netGameType.integer--;
04022                         }
04023                 }
04024         } 
04025         else 
04026         {
04027                 ui_netGameType.integer++;
04028                 if (UI_InSoloMenu())
04029                 {
04030                         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
04031                         {
04032                                 ui_netGameType.integer++;
04033                         }
04034                 }
04035         }
04036 
04037     if (ui_netGameType.integer < 0) 
04038         {
04039                 ui_netGameType.integer = uiInfo.numGameTypes - 1;
04040         } 
04041         else if (ui_netGameType.integer >= uiInfo.numGameTypes) 
04042         {
04043                 ui_netGameType.integer = 0;
04044     } 
04045 
04046         trap_Cvar_Set( "ui_netGameType", va("%d", ui_netGameType.integer));
04047         trap_Cvar_Set( "ui_actualnetGameType", va("%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum));
04048         trap_Cvar_Set( "ui_currentNetMap", "0");
04049                 UI_MapCountByGameType(qfalse);
04050                 Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL);
04051     return qtrue;
04052   }
04053   return qfalse;
04054 }
04055 
04056 static qboolean UI_AutoSwitch_HandleKey(int flags, float *special, int key) {
04057   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04058          int switchVal = trap_Cvar_VariableValue("cg_autoswitch");
04059 
04060                 if (key == A_MOUSE2) {
04061                         switchVal--;
04062                 } else {
04063                         switchVal++;
04064                 }
04065 
04066     if (switchVal < 0)
04067         {
04068                 switchVal = 2;
04069         }
04070         else if (switchVal >= 3)
04071         {
04072       switchVal = 0;
04073     } 
04074 
04075         trap_Cvar_Set( "cg_autoswitch", va("%i", switchVal));
04076     return qtrue;
04077   }
04078   return qfalse;
04079 }
04080 
04081 static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
04082         if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04083 
04084                 if (key == A_MOUSE2) {
04085                         ui_joinGameType.integer--;
04086                 } else {
04087                         ui_joinGameType.integer++;
04088                 }
04089 
04090                 if (ui_joinGameType.integer < 0) {
04091                         ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1;
04092                 } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) {
04093                         ui_joinGameType.integer = 0;
04094                 }
04095 
04096                 trap_Cvar_Set( "ui_joinGameType", va("%d", ui_joinGameType.integer));
04097                 UI_BuildServerDisplayList(qtrue);
04098                 return qtrue;
04099         }
04100         return qfalse;
04101 }
04102 
04103 
04104 
04105 static qboolean UI_Skill_HandleKey(int flags, float *special, int key) {
04106   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04107         int i = trap_Cvar_VariableValue( "g_spSkill" );
04108 
04109                 if (key == A_MOUSE2) {
04110             i--;
04111                 } else {
04112             i++;
04113                 }
04114 
04115     if (i < 1) {
04116                         i = numSkillLevels;
04117                 } else if (i > numSkillLevels) {
04118       i = 1;
04119     }
04120 
04121     trap_Cvar_Set("g_spSkill", va("%i", i));
04122     return qtrue;
04123   }
04124   return qfalse;
04125 }
04126 
04127 
04128 static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) {
04129   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04130     int i;
04131     i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
04132 
04133                 if (key == A_MOUSE2) {
04134             i--;
04135                 } else {
04136             i++;
04137                 }
04138 
04139     if (i >= uiInfo.teamCount) {
04140       i = 0;
04141     } else if (i < 0) {
04142                         i = uiInfo.teamCount - 1;
04143                 }
04144 
04145     trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName);
04146 
04147     return qtrue;
04148   }
04149   return qfalse;
04150 }
04151 
04152 static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) {
04153   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04154                 // 0 - None
04155                 // 1 - Human
04156                 // 2..NumCharacters - Bot
04157                 char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num);
04158                 int value = trap_Cvar_VariableValue(cvar);
04159                 int maxcl = trap_Cvar_VariableValue( "sv_maxClients" );
04160                 int numval = num;
04161 
04162                 numval *= 2;
04163 
04164                 if (blue)
04165                 {
04166                         numval -= 1;
04167                 }
04168 
04169                 if (numval > maxcl)
04170                 {
04171                         return qfalse;
04172                 }
04173 
04174                 if (value < 1)
04175                 {
04176                         value = 1;
04177                 }
04178 
04179                 if (key == A_MOUSE2) {
04180                         value--;
04181                 } else {
04182                         value++;
04183                 }
04184 
04185                 /*if (ui_actualNetGameType.integer >= GT_TEAM) {
04186                         if (value >= uiInfo.characterCount + 2) {
04187                                 value = 0;
04188                         } else if (value < 0) {
04189                                 value = uiInfo.characterCount + 2 - 1;
04190                         }
04191                 } else {*/
04192                         if (value >= UI_GetNumBots() + 2) {
04193                                 value = 1;
04194                         } else if (value < 1) {
04195                                 value = UI_GetNumBots() + 2 - 1;
04196                         }
04197                 //}
04198 
04199                 trap_Cvar_Set(cvar, va("%i", value));
04200     return qtrue;
04201   }
04202   return qfalse;
04203 }
04204 
04205 static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
04206   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04207                 
04208                 if (key == A_MOUSE2) {
04209                         ui_netSource.integer--;
04210                 } else {
04211                         ui_netSource.integer++;
04212                 }
04213     
04214                 if (ui_netSource.integer >= numNetSources) {
04215       ui_netSource.integer = 0;
04216     } else if (ui_netSource.integer < 0) {
04217       ui_netSource.integer = numNetSources - 1;
04218                 }
04219 
04220                 UI_BuildServerDisplayList(qtrue);
04221                 if (ui_netSource.integer != AS_GLOBAL) {
04222                         UI_StartServerRefresh(qtrue);
04223                 }
04224         trap_Cvar_Set( "ui_netSource", va("%d", ui_netSource.integer));
04225     return qtrue;
04226   }
04227   return qfalse;
04228 }
04229 
04230 static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) {
04231   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04232 
04233                 if (key == A_MOUSE2) {
04234                         ui_serverFilterType.integer--;
04235                 } else {
04236                         ui_serverFilterType.integer++;
04237                 }
04238 
04239     if (ui_serverFilterType.integer >= numServerFilters) {
04240       ui_serverFilterType.integer = 0;
04241     } else if (ui_serverFilterType.integer < 0) {
04242       ui_serverFilterType.integer = numServerFilters - 1;
04243                 }
04244                 UI_BuildServerDisplayList(qtrue);
04245     return qtrue;
04246   }
04247   return qfalse;
04248 }
04249 
04250 static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) {
04251   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04252                 if (key == A_MOUSE2) {
04253                         UI_PriorOpponent();
04254                 } else {
04255                         UI_NextOpponent();
04256                 }
04257     return qtrue;
04258   }
04259   return qfalse;
04260 }
04261 
04262 static qboolean UI_BotName_HandleKey(int flags, float *special, int key) {
04263   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04264 //              int game = trap_Cvar_VariableValue("g_gametype");
04265                 int value = uiInfo.botIndex;
04266 
04267                 if (key == A_MOUSE2) {
04268                         value--;
04269                 } else {
04270                         value++;
04271                 }
04272 
04273                 /*
04274                 if (game >= GT_TEAM) {
04275                         if (value >= uiInfo.characterCount + 2) {
04276                                 value = 0;
04277                         } else if (value < 0) {
04278                                 value = uiInfo.characterCount + 2 - 1;
04279                         }
04280                 } else {
04281                 */
04282                         if (value >= UI_GetNumBots()/* + 2*/) {
04283                                 value = 0;
04284                         } else if (value < 0) {
04285                                 value = UI_GetNumBots()/* + 2*/ - 1;
04286                         }
04287                 //}
04288                 uiInfo.botIndex = value;
04289     return qtrue;
04290   }
04291   return qfalse;
04292 }
04293 
04294 static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) {
04295   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04296                 if (key == A_MOUSE2) {
04297                         uiInfo.skillIndex--;
04298                 } else {
04299                         uiInfo.skillIndex++;
04300                 }
04301                 if (uiInfo.skillIndex >= numSkillLevels) {
04302                         uiInfo.skillIndex = 0;
04303                 } else if (uiInfo.skillIndex < 0) {
04304                         uiInfo.skillIndex = numSkillLevels-1;
04305                 }
04306     return qtrue;
04307   }
04308         return qfalse;
04309 }
04310 
04311 static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) {
04312   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04313                 uiInfo.redBlue ^= 1;
04314                 return qtrue;
04315         }
04316         return qfalse;
04317 }
04318 
04319 static qboolean UI_Crosshair_HandleKey(int flags, float *special, int key) {
04320   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04321                 if (key == A_MOUSE2) {
04322                         uiInfo.currentCrosshair--;
04323                 } else {
04324                         uiInfo.currentCrosshair++;
04325                 }
04326 
04327                 if (uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
04328                         uiInfo.currentCrosshair = 0;
04329                 } else if (uiInfo.currentCrosshair < 0) {
04330                         uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
04331                 }
04332                 trap_Cvar_Set("cg_drawCrosshair", va("%d", uiInfo.currentCrosshair)); 
04333                 return qtrue;
04334         }
04335         return qfalse;
04336 }
04337 
04338 
04339 
04340 static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) {
04341   if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
04342                 int selected;
04343 
04344                 UI_BuildPlayerList();
04345                 if (!uiInfo.teamLeader) {
04346                         return qfalse;
04347                 }
04348                 selected = trap_Cvar_VariableValue("cg_selectedPlayer");
04349                 
04350                 if (key == A_MOUSE2) {
04351                         selected--;
04352                 } else {
04353                         selected++;
04354                 }
04355 
04356                 if (selected > uiInfo.myTeamCount) {
04357                         selected = 0;
04358                 } else if (selected < 0) {
04359                         selected = uiInfo.myTeamCount;
04360                 }
04361 
04362                 if (selected == uiInfo.myTeamCount) {
04363                         trap_Cvar_Set( "cg_selectedPlayerName", "Everyone");
04364                 } else {
04365                         trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]);
04366                 }
04367                 trap_Cvar_Set( "cg_selectedPlayer", va("%d", selected));
04368         }
04369         return qfalse;
04370 }
04371 
04372 /*
04373 static qboolean UI_VoiceChat_HandleKey(int flags, float *special, int key)
04374 {
04375 
04376         qboolean ret = qfalse;
04377 
04378         switch(key)
04379         {
04380                 case A_1:
04381                 case A_KP_1:
04382                         ret = qtrue;
04383                         break;
04384                 case A_2:
04385                 case A_KP_2:
04386                         ret = qtrue;
04387                         break;
04388 
04389         }
04390   
04391         return ret;
04392 }
04393 */
04394 
04395 
04396 static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) {
04397         int findex, iUse = 0;
04398 
04399   switch (ownerDraw) {
04400     case UI_HANDICAP:
04401       return UI_Handicap_HandleKey(flags, special, key);
04402       break;
04403     case UI_SKIN_COLOR:
04404       return UI_SkinColor_HandleKey(flags, special, key, uiSkinColor, TEAM_FREE, TEAM_BLUE, ownerDraw);
04405       break;
04406     case UI_FORCE_SIDE:
04407       return UI_ForceSide_HandleKey(flags, special, key, uiForceSide, 1, 2, ownerDraw);
04408       break;
04409     case UI_JEDI_NONJEDI:
04410       return UI_JediNonJedi_HandleKey(flags, special, key, uiJediNonJedi, 0, 1, ownerDraw);
04411       break;
04412         case UI_FORCE_MASTERY_SET:
04413       return UI_ForceMaxRank_HandleKey(flags, special, key, uiForceRank, 1, MAX_FORCE_RANK, ownerDraw);
04414       break;
04415     case UI_FORCE_RANK:
04416                 break;          
04417         case UI_CHAT_MAIN:
04418                 return UI_Chat_Main_HandleKey(key);
04419                 break;
04420         case UI_CHAT_ATTACK:
04421                 return UI_Chat_Attack_HandleKey(key);
04422                 break;
04423         case UI_CHAT_DEFEND:
04424                 return UI_Chat_Defend_HandleKey(key);
04425                 break;
04426         case UI_CHAT_REQUEST:
04427                 return UI_Chat_Request_HandleKey(key);
04428                 break;
04429         case UI_CHAT_REPLY:
04430                 return UI_Chat_Reply_HandleKey(key);
04431                 break;
04432         case UI_CHAT_SPOT:
04433                 return UI_Chat_Spot_HandleKey(key);
04434                 break;
04435         case UI_CHAT_TACTICAL:
04436                 return UI_Chat_Tactical_HandleKey(key);
04437                 break;
04438         case UI_FORCE_RANK_HEAL:
04439         case UI_FORCE_RANK_LEVITATION:
04440         case UI_FORCE_RANK_SPEED:
04441         case UI_FORCE_RANK_PUSH:
04442         case UI_FORCE_RANK_PULL:
04443         case UI_FORCE_RANK_TELEPATHY:
04444         case UI_FORCE_RANK_GRIP:
04445         case UI_FORCE_RANK_LIGHTNING:
04446         case UI_FORCE_RANK_RAGE:
04447         case UI_FORCE_RANK_PROTECT:
04448         case UI_FORCE_RANK_ABSORB:
04449         case UI_FORCE_RANK_TEAM_HEAL:
04450         case UI_FORCE_RANK_TEAM_FORCE:
04451         case UI_FORCE_RANK_DRAIN:
04452         case UI_FORCE_RANK_SEE:
04453         case UI_FORCE_RANK_SABERATTACK:
04454         case UI_FORCE_RANK_SABERDEFEND:
04455         case UI_FORCE_RANK_SABERTHROW:
04456                 findex = (ownerDraw - UI_FORCE_RANK)-1;
04457                 //this will give us the index as long as UI_FORCE_RANK is always one below the first force rank index
04458                 return UI_ForcePowerRank_HandleKey(flags, special, key, uiForcePowersRank[findex], 0, NUM_FORCE_POWER_LEVELS-1, ownerDraw);
04459                 break;
04460     case UI_EFFECTS:
04461       return UI_Effects_HandleKey(flags, special, key);
04462       break;
04463     case UI_GAMETYPE:
04464       return UI_GameType_HandleKey(flags, special, key, qtrue);
04465       break;
04466     case UI_NETGAMETYPE:
04467       return UI_NetGameType_HandleKey(flags, special, key);
04468       break;
04469     case UI_AUTOSWITCHLIST:
04470       return UI_AutoSwitch_HandleKey(flags, special, key);
04471       break;
04472     case UI_JOINGAMETYPE:
04473       return UI_JoinGameType_HandleKey(flags, special, key);
04474       break;
04475     case UI_SKILL:
04476       return UI_Skill_HandleKey(flags, special, key);
04477       break;
04478     case UI_BLUETEAMNAME:
04479       return UI_TeamName_HandleKey(flags, special, key, qtrue);
04480       break;
04481     case UI_REDTEAMNAME:
04482       return UI_TeamName_HandleKey(flags, special, key, qfalse);
04483       break;
04484     case UI_BLUETEAM1:
04485                 case UI_BLUETEAM2:
04486                 case UI_BLUETEAM3:
04487                 case UI_BLUETEAM4:
04488                 case UI_BLUETEAM5:
04489                 case UI_BLUETEAM6:
04490                 case UI_BLUETEAM7:
04491                 case UI_BLUETEAM8:
04492         if (ownerDraw <= UI_BLUETEAM5)
04493         {
04494           iUse = ownerDraw-UI_BLUETEAM1 + 1;
04495         }
04496         else
04497         {
04498           iUse = ownerDraw-274; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
04499         }
04500 
04501       UI_TeamMember_HandleKey(flags, special, key, qtrue, iUse);
04502       break;
04503     case UI_REDTEAM1:
04504                 case UI_REDTEAM2:
04505                 case UI_REDTEAM3:
04506                 case UI_REDTEAM4:
04507                 case UI_REDTEAM5:
04508                 case UI_REDTEAM6:
04509                 case UI_REDTEAM7:
04510                 case UI_REDTEAM8:
04511         if (ownerDraw <= UI_REDTEAM5)
04512         {
04513           iUse = ownerDraw-UI_REDTEAM1 + 1;
04514         }
04515         else
04516         {
04517           iUse = ownerDraw-277; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
04518         }
04519       UI_TeamMember_HandleKey(flags, special, key, qfalse, iUse);
04520       break;
04521                 case UI_NETSOURCE:
04522       UI_NetSource_HandleKey(flags, special, key);
04523                         break;
04524                 case UI_NETFILTER:
04525       UI_NetFilter_HandleKey(flags, special, key);
04526                         break;
04527                 case UI_OPPONENT_NAME:
04528                         UI_OpponentName_HandleKey(flags, special, key);
04529                         break;
04530                 case UI_BOTNAME:
04531                         return UI_BotName_HandleKey(flags, special, key);
04532                         break;
04533                 case UI_BOTSKILL:
04534                         return UI_BotSkill_HandleKey(flags, special, key);
04535                         break;
04536                 case UI_REDBLUE:
04537                         UI_RedBlue_HandleKey(flags, special, key);
04538                         break;
04539                 case UI_CROSSHAIR:
04540                         UI_Crosshair_HandleKey(flags, special, key);
04541                         break;
04542                 case UI_SELECTEDPLAYER:
04543                         UI_SelectedPlayer_HandleKey(flags, special, key);
04544                         break;
04545         //      case UI_VOICECHAT:
04546         //              UI_VoiceChat_HandleKey(flags, special, key);
04547         //              break;
04548     default:
04549       break;
04550   }
04551 
04552   return qfalse;
04553 }
04554 
04555 
04556 static float UI_GetValue(int ownerDraw) {
04557   return 0;
04558 }
04559 
04560 /*
04561 =================
04562 UI_ServersQsortCompare
04563 =================
04564 */
04565 static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ) {
04566         return trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, uiInfo.serverStatus.sortDir, *(int*)arg1, *(int*)arg2);
04567 }
04568 
04569 
04570 /*
04571 =================
04572 UI_ServersSort
04573 =================
04574 */
04575 void UI_ServersSort(int column, qboolean force) {
04576 
04577         if ( !force ) {
04578                 if ( uiInfo.serverStatus.sortKey == column ) {
04579                         return;
04580                 }
04581         }
04582 
04583         uiInfo.serverStatus.sortKey = column;
04584         qsort( &uiInfo.serverStatus.displayServers[0], uiInfo.serverStatus.numDisplayServers, sizeof(int), UI_ServersQsortCompare);
04585 }
04586 
04587 /*
04588 static void UI_StartSinglePlayer() {
04589         int i,j, k, skill;
04590         char buff[1024];
04591         i = trap_Cvar_VariableValue( "ui_currentTier" );
04592   if (i < 0 || i >= tierCount) {
04593     i = 0;
04594   }
04595         j = trap_Cvar_VariableValue("ui_currentMap");
04596         if (j < 0 || j > MAPS_PER_TIER) {
04597                 j = 0;
04598         }
04599 
04600         trap_Cvar_SetValue( "singleplayer", 1 );
04601         trap_Cvar_SetValue( "g_gametype", Com_Clamp( 0, 7, tierList[i].gameTypes[j] ) );
04602         trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", tierList[i].maps[j] ) );
04603         skill = trap_Cvar_VariableValue( "g_spSkill" );
04604 
04605         if (j == MAPS_PER_TIER-1) {
04606                 k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
04607                 Com_sprintf( buff, sizeof(buff), "wait ; addbot %s %i %s 250 %s\n", UI_AIFromName(teamList[k].teamMembers[0]), skill, "", teamList[k].teamMembers[0]);
04608         } else {
04609                 k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
04610                 for (i = 0; i < PLAYERS_PER_TEAM; i++) {
04611                         Com_sprintf( buff, sizeof(buff), "wait ; addbot %s %i %s 250 %s\n", UI_AIFromName(teamList[k].teamMembers[i]), skill, "Blue", teamList[k].teamMembers[i]);
04612                         trap_Cmd_ExecuteText( EXEC_APPEND, buff );
04613                 }
04614 
04615                 k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
04616                 for (i = 1; i < PLAYERS_PER_TEAM; i++) {
04617                         Com_sprintf( buff, sizeof(buff), "wait ; addbot %s %i %s 250 %s\n", UI_AIFromName(teamList[k].teamMembers[i]), skill, "Red", teamList[k].teamMembers[i]);
04618                         trap_Cmd_ExecuteText( EXEC_APPEND, buff );
04619                 }
04620                 trap_Cmd_ExecuteText( EXEC_APPEND, "wait 5; team Red\n" );
04621         }
04622         
04623 
04624 }
04625 */
04626 
04627 /*
04628 ===============
04629 UI_LoadMods
04630 ===============
04631 */
04632 static void UI_LoadMods() {
04633         int             numdirs;
04634         char    dirlist[2048];
04635         char    *dirptr;
04636   char  *descptr;
04637         int             i;
04638         int             dirlen;
04639 
04640         uiInfo.modCount = 0;
04641         numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) );
04642         dirptr  = dirlist;
04643         for( i = 0; i < numdirs; i++ ) {
04644                 dirlen = strlen( dirptr ) + 1;
04645     descptr = dirptr + dirlen;
04646                 uiInfo.modList[uiInfo.modCount].modName = String_Alloc(dirptr);
04647                 uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc(descptr);
04648     dirptr += dirlen + strlen(descptr) + 1;
04649                 uiInfo.modCount++;
04650                 if (uiInfo.modCount >= MAX_MODS) {
04651                         break;
04652                 }
04653         }
04654 
04655 }
04656 
04657 
04658 /*
04659 ===============
04660 UI_LoadMovies
04661 ===============
04662 */
04663 static void UI_LoadMovies() {
04664         char    movielist[4096];
04665         char    *moviename;
04666         int             i, len;
04667 
04668         uiInfo.movieCount = trap_FS_GetFileList( "video", "roq", movielist, 4096 );
04669 
04670         if (uiInfo.movieCount) {
04671                 if (uiInfo.movieCount > MAX_MOVIES) {
04672                         uiInfo.movieCount = MAX_MOVIES;
04673                 }
04674                 moviename = movielist;
04675                 for ( i = 0; i < uiInfo.movieCount; i++ ) {
04676                         len = strlen( moviename );
04677                         if (!Q_stricmp(moviename +  len - 4,".roq")) {
04678                                 moviename[len-4] = '\0';
04679                         }
04680                         Q_strupr(moviename);
04681                         uiInfo.movieList[i] = String_Alloc(moviename);
04682                         moviename += len + 1;
04683                 }
04684         }
04685 
04686 }
04687 
04688 
04689 
04690 /*
04691 ===============
04692 UI_LoadDemos
04693 ===============
04694 */
04695 static void UI_LoadDemos() {
04696         char    demolist[4096];
04697         char demoExt[32];
04698         char    *demoname;
04699         int             i, len;
04700 
04701         Com_sprintf(demoExt, sizeof(demoExt), "dm_%d", (int)trap_Cvar_VariableValue("protocol"));
04702 
04703         uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 );
04704 
04705         Com_sprintf(demoExt, sizeof(demoExt), ".dm_%d", (int)trap_Cvar_VariableValue("protocol"));
04706 
04707         if (uiInfo.demoCount) {
04708                 if (uiInfo.demoCount > MAX_DEMOS) {
04709                         uiInfo.demoCount = MAX_DEMOS;
04710                 }
04711                 demoname = demolist;
04712                 for ( i = 0; i < uiInfo.demoCount; i++ ) {
04713                         len = strlen( demoname );
04714                         if (!Q_stricmp(demoname +  len - strlen(demoExt), demoExt)) {
04715                                 demoname[len-strlen(demoExt)] = '\0';
04716                         }
04717                         Q_strupr(demoname);
04718                         uiInfo.demoList[i] = String_Alloc(demoname);
04719                         demoname += len + 1;
04720                 }
04721         }
04722 
04723 }
04724 
04725 
04726 static qboolean UI_SetNextMap(int actual, int index) {
04727         int i;
04728         for (i = actual + 1; i < uiInfo.mapCount; i++) {
04729                 if (uiInfo.mapList[i].active) {
04730                         Menu_SetFeederSelection(NULL, FEEDER_MAPS, index + 1, "skirmish");
04731                         return qtrue;
04732                 }
04733         }
04734         return qfalse;
04735 }
04736 
04737 
04738 static void UI_StartSkirmish(qboolean next) {
04739         int i, k, g, delay, temp;
04740         float skill;
04741         char buff[MAX_STRING_CHARS];
04742 
04743         temp = trap_Cvar_VariableValue( "g_gametype" );
04744         trap_Cvar_Set("ui_gameType", va("%i", temp));
04745 
04746         if (next) {
04747                 int actual;
04748                 int index = trap_Cvar_VariableValue("ui_mapIndex");
04749                 UI_MapCountByGameType(qtrue);
04750                 UI_SelectedMap(index, &actual);
04751                 if (UI_SetNextMap(actual, index)) {
04752                 } else {
04753                         UI_GameType_HandleKey(0, 0, A_MOUSE1, qfalse);
04754                         UI_MapCountByGameType(qtrue);
04755                         Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, "skirmish");
04756                 }
04757         }
04758 
04759         g = uiInfo.gameTypes[ui_gameType.integer].gtEnum;
04760         trap_Cvar_SetValue( "g_gametype", g );
04761         trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName) );
04762         skill = trap_Cvar_VariableValue( "g_spSkill" );
04763         trap_Cvar_Set("ui_scoreMap", uiInfo.mapList[ui_currentMap.integer].mapName);
04764 
04765         k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
04766 
04767         trap_Cvar_Set("ui_singlePlayerActive", "1");
04768 
04769         // set up sp overrides, will be replaced on postgame
04770         temp = trap_Cvar_VariableValue( "capturelimit" );
04771         trap_Cvar_Set("ui_saveCaptureLimit", va("%i", temp));
04772         temp = trap_Cvar_VariableValue( "fraglimit" );
04773         trap_Cvar_Set("ui_saveFragLimit", va("%i", temp));
04774         temp = trap_Cvar_VariableValue( "duel_fraglimit" );
04775         trap_Cvar_Set("ui_saveDuelLimit", va("%i", temp));
04776 
04777         UI_SetCapFragLimits(qfalse);
04778 
04779         temp = trap_Cvar_VariableValue( "cg_drawTimer" );
04780         trap_Cvar_Set("ui_drawTimer", va("%i", temp));
04781         temp = trap_Cvar_VariableValue( "g_doWarmup" );
04782         trap_Cvar_Set("ui_doWarmup", va("%i", temp));
04783         temp = trap_Cvar_VariableValue( "g_friendlyFire" );
04784         trap_Cvar_Set("ui_friendlyFire", va("%i", temp));
04785         temp = trap_Cvar_VariableValue( "sv_maxClients" );
04786         trap_Cvar_Set("ui_maxClients", va("%i", temp));
04787         temp = trap_Cvar_VariableValue( "g_warmup" );
04788         trap_Cvar_Set("ui_Warmup", va("%i", temp));
04789         temp = trap_Cvar_VariableValue( "sv_pure" );
04790         trap_Cvar_Set("ui_pure", va("%i", temp));
04791 
04792         trap_Cvar_Set("cg_cameraOrbit", "0");
04793         trap_Cvar_Set("cg_thirdPerson", "0");
04794         trap_Cvar_Set("cg_drawTimer", "1");
04795         trap_Cvar_Set("g_doWarmup", "1");
04796         trap_Cvar_Set("g_warmup", "15");
04797         trap_Cvar_Set("sv_pure", "0");
04798         trap_Cvar_Set("g_friendlyFire", "0");
04799 //      trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName"));
04800 //      trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName"));
04801 
04802         if (trap_Cvar_VariableValue("ui_recordSPDemo")) {
04803                 Com_sprintf(buff, MAX_STRING_CHARS, "%s_%i", uiInfo.mapList[ui_currentMap.integer].mapLoadName, g);
04804                 trap_Cvar_Set("ui_recordSPDemoName", buff);
04805         }
04806 
04807         delay = 500;
04808 
04809         if (g == GT_DUEL || g == GT_POWERDUEL) {
04810                 temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2;
04811                 trap_Cvar_Set("sv_maxClients", va("%d", temp));
04812                 Com_sprintf( buff, sizeof(buff), "wait ; addbot %s %f "", %i \n", uiInfo.mapList[ui_currentMap.integer].opponentName, skill, delay);
04813                 trap_Cmd_ExecuteText( EXEC_APPEND, buff );
04814         } else if (g == GT_HOLOCRON || g == GT_JEDIMASTER) {
04815                 temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2;
04816                 trap_Cvar_Set("sv_maxClients", va("%d", temp));
04817                 for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers; i++) {
04818                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, (g == GT_HOLOCRON) ? "" : "Blue", delay, uiInfo.teamList[k].teamMembers[i]);
04819                         trap_Cmd_ExecuteText( EXEC_APPEND, buff );
04820                         delay += 500;
04821                 }
04822                 k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
04823                 for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers-1; i++) {
04824                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, (g == GT_HOLOCRON) ? "" : "Red", delay, uiInfo.teamList[k].teamMembers[i]);
04825                         trap_Cmd_ExecuteText( EXEC_APPEND, buff );
04826                         delay += 500;
04827                 }
04828         } else {
04829                 temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2;
04830                 trap_Cvar_Set("sv_maxClients", va("%d", temp));
04831                 for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers; i++) {
04832                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, (g == GT_FFA) ? "" : "Blue", delay, uiInfo.teamList[k].teamMembers[i]);
04833                         trap_Cmd_ExecuteText( EXEC_APPEND, buff );
04834                         delay += 500;
04835                 }
04836                 k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
04837                 for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers-1; i++) {
04838                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, (g == GT_FFA) ? "" : "Red", delay, uiInfo.teamList[k].teamMembers[i]);
04839                         trap_Cmd_ExecuteText( EXEC_APPEND, buff );
04840                         delay += 500;
04841                 }
04842         }
04843         if (g >= GT_TEAM ) {
04844                 trap_Cmd_ExecuteText( EXEC_APPEND, "wait 5; team Red\n" );
04845         }
04846 }
04847 
04848 static void UI_Update(const char *name) {
04849         int     val = trap_Cvar_VariableValue(name);
04850 
04851         if (Q_stricmp(name, "s_khz") == 0) 
04852         {
04853                 trap_Cmd_ExecuteText( EXEC_APPEND, "snd_restart\n" );
04854                 return;
04855         }
04856 
04857         if (Q_stricmp(name, "ui_SetName") == 0) {
04858                 trap_Cvar_Set( "name", UI_Cvar_VariableString("ui_Name"));
04859         } else if (Q_stricmp(name, "ui_setRate") == 0) {
04860                 float rate = trap_Cvar_VariableValue("rate");
04861                 if (rate >= 5000) {
04862                         trap_Cvar_Set("cl_maxpackets", "30");
04863                         trap_Cvar_Set("cl_packetdup", "1");
04864                 } else if (rate >= 4000) {
04865                         trap_Cvar_Set("cl_maxpackets", "15");
04866                         trap_Cvar_Set("cl_packetdup", "2");             // favor less prediction errors when there's packet loss
04867                 } else {
04868                         trap_Cvar_Set("cl_maxpackets", "15");
04869                         trap_Cvar_Set("cl_packetdup", "1");             // favor lower bandwidth
04870                 }
04871         } 
04872         else if (Q_stricmp(name, "ui_GetName") == 0) 
04873         {
04874                 trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString("name"));
04875         }
04876         else if (Q_stricmp(name, "ui_r_colorbits") == 0) 
04877         {
04878                 switch (val) 
04879                 {
04880                         case 0:
04881                                 trap_Cvar_SetValue( "ui_r_depthbits", 0 );
04882                                 break;
04883 
04884                         case 16:
04885                                 trap_Cvar_SetValue( "ui_r_depthbits", 16 );
04886                                 break;
04887 
04888                         case 32:
04889                                 trap_Cvar_SetValue( "ui_r_depthbits", 24 );
04890                                 break;
04891                 }
04892         } 
04893         else if (Q_stricmp(name, "ui_r_lodbias") == 0) 
04894         {
04895                 switch (val) 
04896                 {
04897                         case 0:
04898                                 trap_Cvar_SetValue( "ui_r_subdivisions", 4 );
04899                                 break;
04900                         case 1:
04901                                 trap_Cvar_SetValue( "ui_r_subdivisions", 12 );
04902                                 break;
04903 
04904                         case 2:
04905                                 trap_Cvar_SetValue( "ui_r_subdivisions", 20 );
04906                                 break;
04907                 }
04908         } 
04909         else if (Q_stricmp(name, "ui_r_glCustom") == 0) 
04910         {
04911                 switch (val) 
04912                 {
04913                         case 0: // high quality
04914 
04915                                 trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
04916                                 trap_Cvar_SetValue( "ui_r_subdivisions", 4 );
04917                                 trap_Cvar_SetValue( "ui_r_lodbias", 0 );
04918                                 trap_Cvar_SetValue( "ui_r_colorbits", 32 );
04919                                 trap_Cvar_SetValue( "ui_r_depthbits", 24 );
04920                                 trap_Cvar_SetValue( "ui_r_picmip", 0 );
04921                                 trap_Cvar_SetValue( "ui_r_mode", 4 );
04922                                 trap_Cvar_SetValue( "ui_r_texturebits", 32 );
04923                                 trap_Cvar_SetValue( "ui_r_fastSky", 0 );
04924                                 trap_Cvar_SetValue( "ui_r_inGameVideo", 1 );
04925                                 //trap_Cvar_SetValue( "ui_cg_shadows", 2 );//stencil
04926                                 trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
04927                                 break;
04928 
04929                         case 1: // normal 
04930                                 trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
04931                                 trap_Cvar_SetValue( "ui_r_subdivisions", 4 );
04932                                 trap_Cvar_SetValue( "ui_r_lodbias", 0 );
04933                                 trap_Cvar_SetValue( "ui_r_colorbits", 0 );
04934                                 trap_Cvar_SetValue( "ui_r_depthbits", 24 );
04935                                 trap_Cvar_SetValue( "ui_r_picmip", 1 );
04936                                 trap_Cvar_SetValue( "ui_r_mode", 3 );
04937                                 trap_Cvar_SetValue( "ui_r_texturebits", 0 );
04938                                 trap_Cvar_SetValue( "ui_r_fastSky", 0 );
04939                                 trap_Cvar_SetValue( "ui_r_inGameVideo", 1 );
04940                                 //trap_Cvar_SetValue( "ui_cg_shadows", 2 );
04941                                 trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
04942                                 break;
04943 
04944                         case 2: // fast
04945 
04946                                 trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
04947                                 trap_Cvar_SetValue( "ui_r_subdivisions", 12 );
04948                                 trap_Cvar_SetValue( "ui_r_lodbias", 1 );
04949                                 trap_Cvar_SetValue( "ui_r_colorbits", 0 );
04950                                 trap_Cvar_SetValue( "ui_r_depthbits", 0 );
04951                                 trap_Cvar_SetValue( "ui_r_picmip", 2 );
04952                                 trap_Cvar_SetValue( "ui_r_mode", 3 );
04953                                 trap_Cvar_SetValue( "ui_r_texturebits", 0 );
04954                                 trap_Cvar_SetValue( "ui_r_fastSky", 1 );
04955                                 trap_Cvar_SetValue( "ui_r_inGameVideo", 0 );
04956                                 //trap_Cvar_SetValue( "ui_cg_shadows", 1 );
04957                                 trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
04958                                 break;
04959 
04960                         case 3: // fastest
04961 
04962                                 trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
04963                                 trap_Cvar_SetValue( "ui_r_subdivisions", 20 );
04964                                 trap_Cvar_SetValue( "ui_r_lodbias", 2 );
04965                                 trap_Cvar_SetValue( "ui_r_colorbits", 16 );
04966                                 trap_Cvar_SetValue( "ui_r_depthbits", 16 );
04967                                 trap_Cvar_SetValue( "ui_r_mode", 3 );
04968                                 trap_Cvar_SetValue( "ui_r_picmip", 3 );
04969                                 trap_Cvar_SetValue( "ui_r_texturebits", 16 );
04970                                 trap_Cvar_SetValue( "ui_r_fastSky", 1 );
04971                                 trap_Cvar_SetValue( "ui_r_inGameVideo", 0 );
04972                                 //trap_Cvar_SetValue( "ui_cg_shadows", 0 );
04973                                 trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
04974                         break;
04975                 }
04976         } 
04977         else if (Q_stricmp(name, "ui_mousePitch") == 0) 
04978         {
04979                 if (val == 0) 
04980                 {
04981                         trap_Cvar_SetValue( "m_pitch", 0.022f );
04982                 } 
04983                 else 
04984                 {
04985                         trap_Cvar_SetValue( "m_pitch", -0.022f );
04986                 }
04987         }
04988         else if (Q_stricmp(name, "ui_mousePitchVeh") == 0) 
04989         {
04990                 if (val == 0) 
04991                 {
04992                         trap_Cvar_SetValue( "m_pitchVeh", 0.022f );
04993                 } 
04994                 else 
04995                 {
04996                         trap_Cvar_SetValue( "m_pitchVeh", -0.022f );
04997                 }
04998         }
04999 }
05000 
05001 int gUISelectedMap = 0;
05002 
05003 /*
05004 ===============
05005 UI_DeferMenuScript
05006 
05007 Return true if the menu script should be deferred for later
05008 ===============
05009 */
05010 static qboolean UI_DeferMenuScript ( char **args )
05011 {
05012         const char* name;
05013 
05014         // Whats the reason for being deferred?
05015         if (!String_Parse( (char**)args, &name)) 
05016         {
05017                 return qfalse;
05018         }
05019 
05020         // Handle the custom cases
05021         if ( !Q_stricmp ( name, "VideoSetup" ) )
05022         {
05023                 const char* warningMenuName;
05024                 qboolean        deferred;
05025 
05026                 // No warning menu specified
05027                 if ( !String_Parse( (char**)args, &warningMenuName) )
05028                 {
05029                         return qfalse;
05030                 }
05031 
05032                 // Defer if the video options were modified
05033                 deferred = trap_Cvar_VariableValue ( "ui_r_modified" ) ? qtrue : qfalse;
05034 
05035                 if ( deferred )
05036                 {
05037                         // Open the warning menu
05038                         Menus_OpenByName(warningMenuName);
05039                 }
05040 
05041                 return deferred;
05042         }
05043         else if ( !Q_stricmp ( name, "RulesBackout" ) )
05044         {
05045                 qboolean deferred;
05046                 
05047                 deferred = trap_Cvar_VariableValue ( "ui_rules_backout" ) ? qtrue : qfalse ;
05048 
05049                 trap_Cvar_Set ( "ui_rules_backout", "0" );
05050 
05051                 return deferred;
05052         }
05053 
05054         return qfalse;
05055 }
05056 
05057 /*
05058 =================
05059 UI_UpdateVideoSetup
05060 
05061 Copies the temporary user interface version of the video cvars into
05062 their real counterparts.  This is to create a interface which allows 
05063 you to discard your changes if you did something you didnt want
05064 =================
05065 */
05066 void UI_UpdateVideoSetup ( void )
05067 {
05068         trap_Cvar_Set ( "r_mode", UI_Cvar_VariableString ( "ui_r_mode" ) );
05069         trap_Cvar_Set ( "r_fullscreen", UI_Cvar_VariableString ( "ui_r_fullscreen" ) );
05070         trap_Cvar_Set ( "r_colorbits", UI_Cvar_VariableString ( "ui_r_colorbits" ) );
05071         trap_Cvar_Set ( "r_lodbias", UI_Cvar_VariableString ( "ui_r_lodbias" ) );
05072         trap_Cvar_Set ( "r_picmip", UI_Cvar_VariableString ( "ui_r_picmip" ) );
05073         trap_Cvar_Set ( "r_texturebits", UI_Cvar_VariableString ( "ui_r_texturebits" ) );
05074         trap_Cvar_Set ( "r_texturemode", UI_Cvar_VariableString ( "ui_r_texturemode" ) );
05075         trap_Cvar_Set ( "r_detailtextures", UI_Cvar_VariableString ( "ui_r_detailtextures" ) );
05076         trap_Cvar_Set ( "r_ext_compress_textures", UI_Cvar_VariableString ( "ui_r_ext_compress_textures" ) );
05077         trap_Cvar_Set ( "r_depthbits", UI_Cvar_VariableString ( "ui_r_depthbits" ) );
05078         trap_Cvar_Set ( "r_subdivisions", UI_Cvar_VariableString ( "ui_r_subdivisions" ) );
05079         trap_Cvar_Set ( "r_fastSky", UI_Cvar_VariableString ( "ui_r_fastSky" ) );
05080         trap_Cvar_Set ( "r_inGameVideo", UI_Cvar_VariableString ( "ui_r_inGameVideo" ) );
05081         trap_Cvar_Set ( "r_allowExtensions", UI_Cvar_VariableString ( "ui_r_allowExtensions" ) );
05082         trap_Cvar_Set ( "cg_shadows", UI_Cvar_VariableString ( "ui_cg_shadows" ) );
05083         trap_Cvar_Set ( "ui_r_modified", "0" );
05084 
05085         trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
05086 }
05087 
05088 /*
05089 =================
05090 UI_GetVideoSetup
05091 
05092 Retrieves the current actual video settings into the temporary user
05093 interface versions of the cvars.
05094 =================
05095 */
05096 void UI_GetVideoSetup ( void )
05097 {
05098         // Make sure the cvars are registered as read only.
05099         trap_Cvar_Register ( NULL, "ui_r_glCustom",                             "4", CVAR_ROM|CVAR_INTERNAL|CVAR_ARCHIVE );
05100 
05101         trap_Cvar_Register ( NULL, "ui_r_mode",                                 "0", CVAR_ROM|CVAR_INTERNAL );
05102         trap_Cvar_Register ( NULL, "ui_r_fullscreen",                   "0", CVAR_ROM|CVAR_INTERNAL );
05103         trap_Cvar_Register ( NULL, "ui_r_colorbits",                    "0", CVAR_ROM|CVAR_INTERNAL );
05104         trap_Cvar_Register ( NULL, "ui_r_lodbias",                              "0", CVAR_ROM|CVAR_INTERNAL );
05105         trap_Cvar_Register ( NULL, "ui_r_picmip",                               "0", CVAR_ROM|CVAR_INTERNAL );
05106         trap_Cvar_Register ( NULL, "ui_r_texturebits",                  "0", CVAR_ROM|CVAR_INTERNAL );
05107         trap_Cvar_Register ( NULL, "ui_r_texturemode",                  "0", CVAR_ROM|CVAR_INTERNAL );
05108         trap_Cvar_Register ( NULL, "ui_r_detailtextures",               "0", CVAR_ROM|CVAR_INTERNAL );
05109         trap_Cvar_Register ( NULL, "ui_r_ext_compress_textures","0", CVAR_ROM|CVAR_INTERNAL );
05110         trap_Cvar_Register ( NULL, "ui_r_depthbits",                    "0", CVAR_ROM|CVAR_INTERNAL );
05111         trap_Cvar_Register ( NULL, "ui_r_subdivisions",                 "0", CVAR_ROM|CVAR_INTERNAL );
05112         trap_Cvar_Register ( NULL, "ui_r_fastSky",                              "0", CVAR_ROM|CVAR_INTERNAL );
05113         trap_Cvar_Register ( NULL, "ui_r_inGameVideo",                  "0", CVAR_ROM|CVAR_INTERNAL );
05114         trap_Cvar_Register ( NULL, "ui_r_allowExtensions",              "0", CVAR_ROM|CVAR_INTERNAL );
05115         trap_Cvar_Register ( NULL, "ui_cg_shadows",                             "0", CVAR_ROM|CVAR_INTERNAL );
05116         trap_Cvar_Register ( NULL, "ui_r_modified",                             "0", CVAR_ROM|CVAR_INTERNAL );
05117         
05118         // Copy over the real video cvars into their temporary counterparts
05119         trap_Cvar_Set ( "ui_r_mode",            UI_Cvar_VariableString ( "r_mode" ) );
05120         trap_Cvar_Set ( "ui_r_colorbits",       UI_Cvar_VariableString ( "r_colorbits" ) );
05121         trap_Cvar_Set ( "ui_r_fullscreen",      UI_Cvar_VariableString ( "r_fullscreen" ) );
05122         trap_Cvar_Set ( "ui_r_lodbias",         UI_Cvar_VariableString ( "r_lodbias" ) );
05123         trap_Cvar_Set ( "ui_r_picmip",          UI_Cvar_VariableString ( "r_picmip" ) );
05124         trap_Cvar_Set ( "ui_r_texturebits", UI_Cvar_VariableString ( "r_texturebits" ) );
05125         trap_Cvar_Set ( "ui_r_texturemode", UI_Cvar_VariableString ( "r_texturemode" ) );
05126         trap_Cvar_Set ( "ui_r_detailtextures", UI_Cvar_VariableString ( "r_detailtextures" ) );
05127         trap_Cvar_Set ( "ui_r_ext_compress_textures", UI_Cvar_VariableString ( "r_ext_compress_textures" ) );
05128         trap_Cvar_Set ( "ui_r_depthbits", UI_Cvar_VariableString ( "r_depthbits" ) );
05129         trap_Cvar_Set ( "ui_r_subdivisions", UI_Cvar_VariableString ( "r_subdivisions" ) );
05130         trap_Cvar_Set ( "ui_r_fastSky", UI_Cvar_VariableString ( "r_fastSky" ) );
05131         trap_Cvar_Set ( "ui_r_inGameVideo", UI_Cvar_VariableString ( "r_inGameVideo" ) );
05132         trap_Cvar_Set ( "ui_r_allowExtensions", UI_Cvar_VariableString ( "r_allowExtensions" ) );
05133         trap_Cvar_Set ( "ui_cg_shadows", UI_Cvar_VariableString ( "cg_shadows" ) );
05134         trap_Cvar_Set ( "ui_r_modified", "0" );
05135 }
05136 
05137 // If the game type is siege, hide the addbot button. I would have done a cvar text on that item,
05138 // but it already had one on it.
05139 static void UI_SetBotButton ( void )
05140 {
05141         int gameType = trap_Cvar_VariableValue( "g_gametype" );
05142         int server;
05143         menuDef_t *menu;
05144         itemDef_t *item;
05145         char *name = "addBot";
05146 
05147         server = trap_Cvar_VariableValue( "sv_running" );
05148 
05149         // If in siege or a client, don't show add bot button
05150         if ((gameType==GT_SIEGE) || (server==0))        // If it's not siege, don't worry about it
05151         {
05152                 menu = Menu_GetFocused();       // Get current menu (either video or ingame video, I would assume)
05153 
05154                 if (!menu)
05155                 {
05156                         return;
05157                 }
05158 
05159                 item = Menu_FindItemByName(menu, name);
05160                 if (item)
05161                 {
05162                         Menu_ShowItemByName(menu, name, qfalse);
05163                 }
05164         }
05165 }
05166 
05167 // Update the model cvar and everything is good.
05168 static void UI_UpdateCharacterCvars ( void )
05169 {
05170         char skin[MAX_QPATH];
05171         char model[MAX_QPATH];
05172         char head[MAX_QPATH];
05173         char torso[MAX_QPATH];
05174         char legs[MAX_QPATH];
05175 
05176         trap_Cvar_VariableStringBuffer("ui_char_model", model, sizeof(model));
05177         trap_Cvar_VariableStringBuffer("ui_char_skin_head", head, sizeof(head));
05178         trap_Cvar_VariableStringBuffer("ui_char_skin_torso", torso, sizeof(torso));
05179         trap_Cvar_VariableStringBuffer("ui_char_skin_legs", legs, sizeof(legs));
05180 
05181         Com_sprintf( skin, sizeof( skin ), "%s/%s|%s|%s", 
05182                                                                                 model, 
05183                                                                                 head, 
05184                                                                                 torso, 
05185                                                                                 legs 
05186                                 );
05187 
05188         trap_Cvar_Set ( "model", skin );
05189 
05190         trap_Cvar_Set ( "char_color_red", UI_Cvar_VariableString ( "ui_char_color_red" ) );
05191         trap_Cvar_Set ( "char_color_green", UI_Cvar_VariableString ( "ui_char_color_green" ) );
05192         trap_Cvar_Set ( "char_color_blue", UI_Cvar_VariableString ( "ui_char_color_blue" ) );
05193         trap_Cvar_Set ( "ui_selectedModelIndex", "-1");
05194 
05195 }
05196 
05197 static void UI_GetCharacterCvars ( void )
05198 {
05199         char *model;
05200         char *skin;
05201         int i;
05202 
05203         trap_Cvar_Set ( "ui_char_color_red", UI_Cvar_VariableString ( "char_color_red" ) );
05204         trap_Cvar_Set ( "ui_char_color_green", UI_Cvar_VariableString ( "char_color_green" ) );
05205         trap_Cvar_Set ( "ui_char_color_blue", UI_Cvar_VariableString ( "char_color_blue" ) );
05206 
05207         model = UI_Cvar_VariableString ( "model" );
05208         skin = strrchr(model,'/');
05209         if (skin && strchr(model,'|'))  //we have a multipart custom jedi
05210         {
05211                 char skinhead[MAX_QPATH];
05212                 char skintorso[MAX_QPATH];
05213                 char skinlower[MAX_QPATH];
05214                 char *p2;
05215 
05216                 *skin=0;
05217                 skin++;
05218                 //now get the the individual files
05219 
05220                 //advance to second
05221                 p2 = strchr(skin, '|'); 
05222                 assert(p2);
05223                 *p2=0;
05224                 p2++;
05225                 strcpy (skinhead, skin);
05226 
05227 
05228                 //advance to third
05229                 skin = strchr(p2, '|');
05230                 assert(skin);
05231                 *skin=0;
05232                 skin++;
05233                 strcpy (skintorso,p2);
05234 
05235                 strcpy (skinlower,skin);
05236 
05237 
05238 
05239                 trap_Cvar_Set("ui_char_model", model);
05240                 trap_Cvar_Set("ui_char_skin_head", skinhead);
05241                 trap_Cvar_Set("ui_char_skin_torso", skintorso);
05242                 trap_Cvar_Set("ui_char_skin_legs", skinlower);
05243 
05244                 for (i = 0; i < uiInfo.playerSpeciesCount; i++)
05245                 {
05246                         if ( !stricmp(model, uiInfo.playerSpecies[i].Name) )
05247                         {
05248                                 uiInfo.playerSpeciesIndex = i;
05249                                 break;
05250                         }
05251                 }
05252         }
05253         else
05254         {
05255                 model = UI_Cvar_VariableString ( "ui_char_model" );
05256                 for (i = 0; i < uiInfo.playerSpeciesCount; i++)
05257                 {
05258                         if ( !stricmp(model, uiInfo.playerSpecies[i].Name) )
05259                         {
05260                                 uiInfo.playerSpeciesIndex = i;
05261                                 return; //FOUND IT, don't fall through
05262                         }
05263                 }
05264                 //nope, didn't find it.
05265                 uiInfo.playerSpeciesIndex = 0;//jic
05266                 trap_Cvar_Set("ui_char_model", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name);
05267                 trap_Cvar_Set("ui_char_skin_head", "head_a1");
05268                 trap_Cvar_Set("ui_char_skin_torso","torso_a1");
05269                 trap_Cvar_Set("ui_char_skin_legs", "lower_a1");
05270         }
05271 }
05272 
05273 void UI_SetSiegeObjectiveGraphicPos(menuDef_t *menu,const char *itemName,const char *cvarName)
05274 {
05275         itemDef_t       *item;
05276         char            cvarBuf[1024];
05277         const char      *holdVal;
05278         char            *holdBuf;
05279 
05280         item = Menu_FindItemByName(menu, itemName);
05281 
05282         if (item)
05283         {
05284                 // get cvar data
05285                 trap_Cvar_VariableStringBuffer(cvarName, cvarBuf, sizeof(cvarBuf));
05286                 
05287                 holdBuf = cvarBuf;
05288                 if (String_Parse(&holdBuf,&holdVal))
05289                 {
05290                         item->window.rectClient.x = atof(holdVal);
05291                         if (String_Parse(&holdBuf,&holdVal))
05292                         {
05293                                 item->window.rectClient.y = atof(holdVal);
05294                                 if (String_Parse(&holdBuf,&holdVal))
05295                                 {
05296                                         item->window.rectClient.w = atof(holdVal);
05297                                         if (String_Parse(&holdBuf,&holdVal))
05298                                         {
05299                                                 item->window.rectClient.h = atof(holdVal);
05300 
05301                                                 item->window.rect.x = item->window.rectClient.x;
05302                                                 item->window.rect.y = item->window.rectClient.y;
05303 
05304                                                 item->window.rect.w = item->window.rectClient.w;
05305                                                 item->window.rect.h = item->window.rectClient.h;
05306                                         }
05307                                 }
05308                         }
05309                 }
05310         }
05311 }
05312 
05313 void UI_FindCurrentSiegeTeamClass( void )
05314 {
05315         menuDef_t *menu;
05316         int myTeam = (int)(trap_Cvar_VariableValue("ui_myteam"));
05317         char *itemname;
05318         itemDef_t *item;
05319         int     baseClass;
05320 
05321         menu = Menu_GetFocused();       // Get current menu
05322 
05323         if (!menu)
05324         {
05325                 return;
05326         }
05327 
05328         if (( myTeam != TEAM_RED ) && ( myTeam != TEAM_BLUE ))
05329         {
05330                 return;
05331         }
05332 
05333         // If the player is on a team, 
05334         if ( myTeam == TEAM_RED )
05335         {                       
05336                 itemDef_t *item;
05337                 item = (itemDef_t *) Menu_FindItemByName(menu, "onteam1" );
05338                 if (item)
05339                 {
05340                     Item_RunScript(item, item->action);
05341                 }
05342         }
05343         else if ( myTeam == TEAM_BLUE )
05344         {                       
05345                 itemDef_t *item;
05346                 item = (itemDef_t *) Menu_FindItemByName(menu, "onteam2" );
05347                 if (item)
05348                 {
05349                     Item_RunScript(item, item->action);
05350                 }
05351         }       
05352 
05353 
05354         baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
05355 
05356         // Find correct class button and activate it.
05357         if (baseClass == SPC_INFANTRY)
05358         {
05359                 itemname = "class1_button";
05360         }
05361         else if (baseClass == SPC_HEAVY_WEAPONS)
05362         {
05363                 itemname = "class2_button";
05364         }
05365         else if (baseClass == SPC_DEMOLITIONIST)
05366         {
05367                 itemname = "class3_button";
05368         }
05369         else if (baseClass == SPC_VANGUARD)
05370         {
05371                 itemname = "class4_button";
05372         }
05373         else if (baseClass == SPC_SUPPORT)
05374         {
05375                 itemname = "class5_button";
05376         }
05377         else if (baseClass == SPC_SUPPORT)
05378         {
05379                 itemname = "class5_button";
05380         }
05381         else if (baseClass == SPC_JEDI)
05382         {
05383                 itemname = "class6_button";
05384         }
05385         else 
05386         {
05387                 return;
05388         }
05389 
05390         item = (itemDef_t *) Menu_FindItemByName(menu, itemname );
05391         if (item)
05392         {
05393                 Item_RunScript(item, item->action);
05394         }
05395 
05396 }
05397 
05398 void UI_UpdateSiegeObjectiveGraphics( void )
05399 {
05400         menuDef_t *menu;
05401         int     teamI,objI;
05402 
05403         menu = Menu_GetFocused();       // Get current menu
05404 
05405         if (!menu)
05406         {
05407                 return;
05408         }
05409 
05410         // Hiding a bunch of fields because the opening section of the siege menu was getting too long
05411         Menu_ShowGroup(menu,"class_button",qfalse);
05412         Menu_ShowGroup(menu,"class_count",qfalse);
05413         Menu_ShowGroup(menu,"feeders",qfalse);
05414         Menu_ShowGroup(menu,"classdescription",qfalse);
05415         Menu_ShowGroup(menu,"minidesc",qfalse);
05416         Menu_ShowGroup(menu,"obj_longdesc",qfalse);
05417         Menu_ShowGroup(menu,"objective_pic",qfalse);
05418         Menu_ShowGroup(menu,"stats",qfalse);
05419         Menu_ShowGroup(menu,"forcepowerlevel",qfalse);
05420 
05421         // Get objective icons for each team
05422         for (teamI=1;teamI<3;teamI++)
05423         {
05424                 for (objI=1;objI<8;objI++)
05425                 {
05426                         Menu_SetItemBackground(menu,va("tm%i_icon%i",teamI,objI),va("*team%i_objective%i_mapicon",teamI,objI));
05427                         Menu_SetItemBackground(menu,va("tm%i_l_icon%i",teamI,objI),va("*team%i_objective%i_mapicon",teamI,objI));
05428                 }
05429         }
05430 
05431         // Now get their placement on the map
05432         for (teamI=1;teamI<3;teamI++)
05433         {
05434                 for (objI=1;objI<8;objI++)
05435                 {
05436                         UI_SetSiegeObjectiveGraphicPos(menu,va("tm%i_icon%i",teamI,objI),va("team%i_objective%i_mappos",teamI,objI));
05437                 }
05438         }
05439 
05440 }
05441 
05442 saber_colors_t TranslateSaberColor( const char *name );
05443 
05444 static void UI_UpdateSaberCvars ( void )
05445 {
05446         saber_colors_t colorI;
05447 
05448         trap_Cvar_Set ( "saber1", UI_Cvar_VariableString ( "ui_saber" ) );
05449         trap_Cvar_Set ( "saber2", UI_Cvar_VariableString ( "ui_saber2" ) );
05450 
05451         colorI = TranslateSaberColor( UI_Cvar_VariableString ( "ui_saber_color" ) );
05452         trap_Cvar_Set ( "color1", va("%d",colorI));
05453         trap_Cvar_Set ( "g_saber_color", UI_Cvar_VariableString ( "ui_saber_color" ));
05454 
05455         colorI = TranslateSaberColor( UI_Cvar_VariableString ( "ui_saber2_color" ) );
05456         trap_Cvar_Set ( "color2", va("%d",colorI) );
05457         trap_Cvar_Set ( "g_saber2_color", UI_Cvar_VariableString ( "ui_saber2_color" ));
05458 }
05459 
05460 // More hard coded goodness for the menus.
05461 static void UI_SetSaberBoxesandHilts (void)
05462 {
05463         menuDef_t *menu;
05464         itemDef_t *item;
05465         qboolean        getBig = qfalse;
05466         char sType[MAX_QPATH];
05467 
05468         menu = Menu_GetFocused();       // Get current menu (either video or ingame video, I would assume)
05469 
05470         if (!menu)
05471         {
05472                 return;
05473         }
05474 
05475         trap_Cvar_VariableStringBuffer( "ui_saber_type", sType, sizeof(sType) );
05476 
05477         if ( Q_stricmp( "dual", sType ) != 0 )
05478         {
05479 //              trap_Cvar_Set("ui_saber", "single_1");
05480 //              trap_Cvar_Set("ui_saber2", "single_1");
05481                 getBig = qtrue;
05482         }
05483 
05484         else if (Q_stricmp( "staff", sType ) != 0 )
05485         {
05486 //              trap_Cvar_Set("ui_saber", "dual_1");
05487 //              trap_Cvar_Set("ui_saber2", "none");
05488                 getBig = qtrue;
05489         }
05490 
05491         if (!getBig)
05492         {
05493                 return;
05494         }
05495 
05496         item = (itemDef_t *) Menu_FindItemByName(menu, "box2middle" );
05497 
05498         if(item)
05499         {
05500                 item->window.rect.x = 212;
05501                 item->window.rect.y = 126;
05502                 item->window.rect.w = 219;
05503                 item->window.rect.h = 44;
05504         }
05505 
05506         item = (itemDef_t *) Menu_FindItemByName(menu, "box2bottom" );
05507 
05508         if(item)
05509         {
05510                 item->window.rect.x = 212;
05511                 item->window.rect.y = 170;
05512                 item->window.rect.w = 219;
05513                 item->window.rect.h = 60;
05514         }
05515 
05516         item = (itemDef_t *) Menu_FindItemByName(menu, "box3middle" );
05517 
05518         if(item)
05519         {
05520                 item->window.rect.x = 418;
05521                 item->window.rect.y = 126;
05522                 item->window.rect.w = 219;
05523                 item->window.rect.h = 44;
05524         }
05525 
05526         item = (itemDef_t *) Menu_FindItemByName(menu, "box3bottom" );
05527 
05528         if(item)
05529         {
05530                 item->window.rect.x = 418;
05531                 item->window.rect.y = 170;
05532                 item->window.rect.w = 219;
05533                 item->window.rect.h = 60;
05534         }
05535 }
05536 
05537 //extern qboolean UI_SaberModelForSaber( const char *saberName, char *saberModel );
05538 extern qboolean UI_SaberSkinForSaber( const char *saberName, char *saberSkin );
05539 #include "../namespace_begin.h"
05540 extern qboolean ItemParse_asset_model_go( itemDef_t *item, const char *name,int *runTimeLength );
05541 extern qboolean ItemParse_model_g2skin_go( itemDef_t *item, const char *skinName );
05542 #include "../namespace_end.h"
05543 
05544 static void UI_UpdateSaberType( void )
05545 {
05546         char sType[MAX_QPATH];
05547         trap_Cvar_VariableStringBuffer( "ui_saber_type", sType, sizeof(sType) );
05548 
05549         if ( Q_stricmp( "single", sType ) == 0 ||
05550                 Q_stricmp( "staff", sType ) == 0 )
05551         {
05552                 trap_Cvar_Set( "ui_saber2", "" );
05553         }
05554 }
05555 
05556 static void UI_UpdateSaberHilt( qboolean secondSaber )
05557 {
05558         menuDef_t *menu;
05559         itemDef_t *item;
05560         char model[MAX_QPATH];
05561         char modelPath[MAX_QPATH];
05562         char skinPath[MAX_QPATH];
05563         char *itemName;
05564         char *saberCvarName;
05565         int     animRunLength;
05566 
05567         menu = Menu_GetFocused();       // Get current menu (either video or ingame video, I would assume)
05568 
05569         if (!menu)
05570         {
05571                 return;
05572         }
05573 
05574         if ( secondSaber )
05575         {
05576                 itemName = "saber2";
05577                 saberCvarName = "ui_saber2";
05578         }
05579         else
05580         {
05581                 itemName = "saber";
05582                 saberCvarName = "ui_saber";
05583         }
05584 
05585         item = (itemDef_t *) Menu_FindItemByName(menu, itemName );
05586 
05587         if(!item)
05588         {
05589                 Com_Error( ERR_FATAL, "UI_UpdateSaberHilt: Could not find item (%s) in menu (%s)", itemName, menu->window.name);
05590         }
05591 
05592         trap_Cvar_VariableStringBuffer( saberCvarName, model, sizeof(model) );
05593 
05594         item->text = model;
05595         //read this from the sabers.cfg
05596         if ( UI_SaberModelForSaber( model, modelPath ) )
05597         {//successfully found a model
05598                 ItemParse_asset_model_go( item, modelPath, &animRunLength );//set the model
05599                 //get the customSkin, if any
05600                 //COM_StripExtension( modelPath, skinPath );
05601                 //COM_DefaultExtension( skinPath, sizeof( skinPath ), ".skin" );
05602                 if ( UI_SaberSkinForSaber( model, skinPath ) )
05603                 {
05604                         ItemParse_model_g2skin_go( item, skinPath );//apply the skin
05605                 }
05606                 else
05607                 {
05608                         ItemParse_model_g2skin_go( item, NULL );//apply the skin
05609                 }
05610         }
05611 }
05612 
05613 static void UI_UpdateSaberColor( qboolean secondSaber )
05614 {
05615 }
05616 
05617 extern char * SaberColorToString(saber_colors_t color);
05618 
05619 static void UI_GetSaberCvars ( void )
05620 {
05621 //      trap_Cvar_Set ( "ui_saber_type", UI_Cvar_VariableString ( "g_saber_type" ) );
05622         trap_Cvar_Set ( "ui_saber", UI_Cvar_VariableString ( "saber1" ) );
05623         trap_Cvar_Set ( "ui_saber2", UI_Cvar_VariableString ( "saber2" ));
05624 
05625         trap_Cvar_Set("g_saber_color", SaberColorToString(trap_Cvar_VariableValue("color1")));
05626         trap_Cvar_Set("g_saber2_color", SaberColorToString(trap_Cvar_VariableValue("color2")));
05627 
05628         trap_Cvar_Set ( "ui_saber_color", UI_Cvar_VariableString ( "g_saber_color" ) );
05629         trap_Cvar_Set ( "ui_saber2_color", UI_Cvar_VariableString ( "g_saber2_color" ) );
05630 
05631 
05632 }
05633 
05634 
05635 //extern qboolean ItemParse_model_g2skin_go( itemDef_t *item, const char *skinName );
05636 #include "../namespace_begin.h"
05637 extern qboolean ItemParse_model_g2anim_go( itemDef_t *item, const char *animName );
05638 #include "../namespace_end.h"
05639 //extern qboolean ItemParse_asset_model_go( itemDef_t *item, const char *name );
05640 
05641 void UI_UpdateCharacterSkin( void )
05642 {
05643         menuDef_t *menu;
05644         itemDef_t *item;
05645         char skin[MAX_QPATH];
05646         char model[MAX_QPATH];
05647         char head[MAX_QPATH];
05648         char torso[MAX_QPATH];
05649         char legs[MAX_QPATH];
05650 
05651         menu = Menu_GetFocused();       // Get current menu
05652 
05653         if (!menu)
05654         {
05655                 return;
05656         }
05657 
05658         item = (itemDef_t *) Menu_FindItemByName(menu, "character");
05659 
05660         if (!item)
05661         {
05662                 Com_Error( ERR_FATAL, "UI_UpdateCharacterSkin: Could not find item (character) in menu (%s)", menu->window.name);
05663         }
05664 
05665         trap_Cvar_VariableStringBuffer("ui_char_model", model, sizeof(model));
05666         trap_Cvar_VariableStringBuffer("ui_char_skin_head", head, sizeof(head));
05667         trap_Cvar_VariableStringBuffer("ui_char_skin_torso", torso, sizeof(torso));
05668         trap_Cvar_VariableStringBuffer("ui_char_skin_legs", legs, sizeof(legs));
05669 
05670         Com_sprintf( skin, sizeof( skin ), "models/players/%s/|%s|%s|%s", 
05671                                                                                 model, 
05672                                                                                 head, 
05673                                                                                 torso, 
05674                                                                                 legs 
05675                                 );
05676 
05677         ItemParse_model_g2skin_go( item, skin );
05678 }
05679 
05680 static void UI_ResetCharacterListBoxes( void )
05681 {
05682 
05683         itemDef_t *item;
05684         menuDef_t *menu;
05685         listBoxDef_t *listPtr;
05686 
05687         menu = Menu_GetFocused();
05688 
05689         if (menu)
05690         {
05691                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "headlistbox");
05692                 if (item)
05693                 {
05694                         listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
05695                         if( listPtr )
05696                         {
05697                                 listPtr->cursorPos = 0;
05698                         }
05699                         item->cursorPos = 0;
05700                 }
05701 
05702                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "torsolistbox");
05703                 if (item)
05704                 {
05705                         listPtr = (listBoxDef_t*)item->typeData;
05706                         if( listPtr )
05707                         {
05708                                 listPtr->cursorPos = 0;
05709                         }
05710                         item->cursorPos = 0;
05711                 }
05712 
05713                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "lowerlistbox");
05714                 if (item)
05715                 {
05716                         listPtr = (listBoxDef_t*)item->typeData;
05717                         if( listPtr )
05718                         {
05719                                 listPtr->cursorPos = 0;
05720                         }
05721                         item->cursorPos = 0;
05722                 }
05723 
05724                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "colorbox");
05725                 if (item)
05726                 {
05727                         listPtr = (listBoxDef_t*)item->typeData;
05728                         if( listPtr )
05729                         {
05730                                 listPtr->cursorPos = 0;
05731                         }
05732                         item->cursorPos = 0;
05733                 }
05734         }
05735 }
05736 
05737 #define MAX_SABER_HILTS 64
05738 
05739 char *saberSingleHiltInfo [MAX_SABER_HILTS];
05740 char *saberStaffHiltInfo [MAX_SABER_HILTS];
05741 
05742 qboolean UI_SaberProperNameForSaber( const char *saberName, char *saberProperName );
05743 void UI_SaberGetHiltInfo( char *singleHilts[MAX_SABER_HILTS],char *staffHilts[MAX_SABER_HILTS] );
05744 
05745 
05746 static void UI_UpdateCharacter( qboolean changedModel )
05747 {
05748         menuDef_t *menu;
05749         itemDef_t *item;
05750         char modelPath[MAX_QPATH];
05751         int     animRunLength;
05752 
05753         menu = Menu_GetFocused();       // Get current menu
05754 
05755         if (!menu)
05756         {
05757                 return;
05758         }
05759 
05760         item = (itemDef_t *) Menu_FindItemByName(menu, "character");
05761 
05762         if (!item)
05763         {
05764                 Com_Error( ERR_FATAL, "UI_UpdateCharacter: Could not find item (character) in menu (%s)", menu->window.name);
05765         }
05766 
05767         ItemParse_model_g2anim_go( item, ui_char_anim.string );
05768 
05769         Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
05770         ItemParse_asset_model_go( item, modelPath, &animRunLength );
05771 
05772         if ( changedModel )
05773         {//set all skins to first skin since we don't know you always have all skins
05774                 //FIXME: could try to keep the same spot in each list as you swtich models
05775                 UI_FeederSelection(FEEDER_PLAYER_SKIN_HEAD, 0, item);   //fixme, this is not really the right item!!
05776                 UI_FeederSelection(FEEDER_PLAYER_SKIN_TORSO, 0, item);
05777                 UI_FeederSelection(FEEDER_PLAYER_SKIN_LEGS, 0, item);
05778                 UI_FeederSelection(FEEDER_COLORCHOICES, 0, item);
05779         }
05780         UI_UpdateCharacterSkin();
05781 }
05782 
05783 static void UI_RunMenuScript(char **args) 
05784 {
05785         const char *name, *name2;
05786         char buff[1024];
05787 
05788         if (String_Parse(args, &name)) 
05789         {
05790                 if (Q_stricmp(name, "StartServer") == 0) 
05791                 {
05792                         int i, added = 0;
05793                         float skill;
05794                         int warmupTime = 0;
05795                         int doWarmup = 0;
05796                         
05797                         trap_Cvar_Set("cg_thirdPerson", "0");
05798                         trap_Cvar_Set("cg_cameraOrbit", "0");
05799                         // for Solo games I set this to 1 in the menu and don't want it stomped here,
05800                         // this cvar seems to be reset to 0 in all the proper places so... -dmv
05801                 //      trap_Cvar_Set("ui_singlePlayerActive", "0");
05802 
05803                         // if a solo game is started, automatically turn dedicated off here (don't want to do it in the menu, might get annoying)
05804                         if( trap_Cvar_VariableValue( "ui_singlePlayerActive" ) )
05805                         {
05806                                 trap_Cvar_Set( "dedicated", "0" );
05807                         }
05808                         else
05809                         {
05810                                 trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, ui_dedicated.integer ) );
05811                         }
05812                         trap_Cvar_SetValue( "g_gametype", Com_Clamp( 0, 8, uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) );
05813                         //trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName"));
05814                         //trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName"));
05815                         trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) );
05816                         skill = trap_Cvar_VariableValue( "g_spSkill" );
05817 
05818                         //Cap the warmup values in case the user tries a dumb setting.
05819                         warmupTime = trap_Cvar_VariableValue( "g_warmup" );
05820                         doWarmup = trap_Cvar_VariableValue( "g_doWarmup" );
05821 
05822                         if (doWarmup && warmupTime < 1)
05823                         {
05824                                 trap_Cvar_Set("g_doWarmup", "0");
05825                         }
05826                         if (warmupTime < 5)
05827                         {
05828                                 trap_Cvar_Set("g_warmup", "5");
05829                         }
05830                         if (warmupTime > 120)
05831                         {
05832                                 trap_Cvar_Set("g_warmup", "120");
05833                         }
05834 
05835                         if (trap_Cvar_VariableValue( "g_gametype" ) == GT_DUEL ||
05836                                 trap_Cvar_VariableValue( "g_gametype" ) == GT_POWERDUEL)
05837                         { //always set fraglimit 1 when starting a duel game
05838                                 trap_Cvar_Set("fraglimit", "1");
05839                                 trap_Cvar_Set("timelimit", "0");
05840                         }
05841 
05842                         for (i = 0; i < PLAYERS_PER_TEAM; i++) 
05843                         {
05844                                 int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1));
05845                                 int maxcl = trap_Cvar_VariableValue( "sv_maxClients" );
05846 
05847                                 if (bot > 1) 
05848                                 {
05849                                         int numval = i+1;
05850 
05851                                         numval *= 2;
05852 
05853                                         numval -= 1;
05854 
05855                                         if (numval <= maxcl)
05856                                         {
05857                                                 if (ui_actualNetGameType.integer >= GT_TEAM) {
05858                                                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Blue");
05859                                                 } else {
05860                                                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f \n", UI_GetBotNameByNumber(bot-2), skill);
05861                                                 }
05862                                                 trap_Cmd_ExecuteText( EXEC_APPEND, buff );
05863                                                 added++;
05864                                         }
05865                                 }
05866                                 bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1));
05867                                 if (bot > 1) {
05868                                         int numval = i+1;
05869 
05870                                         numval *= 2;
05871 
05872                                         if (numval <= maxcl)
05873                                         {
05874                                                 if (ui_actualNetGameType.integer >= GT_TEAM) {
05875                                                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Red");
05876                                                 } else {
05877                                                         Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f \n", UI_GetBotNameByNumber(bot-2), skill);
05878                                                 }
05879                                                 trap_Cmd_ExecuteText( EXEC_APPEND, buff );
05880                                                 added++;
05881                                         }
05882                                 }
05883                                 if (added >= maxcl)
05884                                 { //this means the client filled up all their slots in the UI with bots. So stretch out an extra slot for them, and then stop adding bots.
05885                                         trap_Cvar_Set("sv_maxClients", va("%i", added+1));
05886                                         break;
05887                                 }
05888                         }
05889                 } else if (Q_stricmp(name, "updateSPMenu") == 0) {
05890                         UI_SetCapFragLimits(qtrue);
05891                         UI_MapCountByGameType(qtrue);
05892                         ui_mapIndex.integer = UI_GetIndexFromSelection(ui_currentMap.integer);
05893                         trap_Cvar_Set("ui_mapIndex", va("%d", ui_mapIndex.integer));
05894                         Menu_SetFeederSelection(NULL, FEEDER_MAPS, ui_mapIndex.integer, "skirmish");
05895                         UI_GameType_HandleKey(0, 0, A_MOUSE1, qfalse);
05896                         UI_GameType_HandleKey(0, 0, A_MOUSE2, qfalse);
05897                 } else if (Q_stricmp(name, "resetDefaults") == 0) {
05898                         trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n");
05899                         trap_Cmd_ExecuteText( EXEC_APPEND, "exec mpdefault.cfg\n");
05900                         trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
05901                         trap_Cvar_Set("com_introPlayed", "1" );
05902 #ifdef USE_CD_KEY
05903                 } else if (Q_stricmp(name, "getCDKey") == 0) {
05904                         char out[17];
05905                         trap_GetCDKey(buff, 17);
05906                         trap_Cvar_Set("cdkey1", "");
05907                         trap_Cvar_Set("cdkey2", "");
05908                         trap_Cvar_Set("cdkey3", "");
05909                         trap_Cvar_Set("cdkey4", "");
05910                         if (strlen(buff) == CDKEY_LEN) {
05911                                 Q_strncpyz(out, buff, 5);
05912                                 trap_Cvar_Set("cdkey1", out);
05913                                 Q_strncpyz(out, buff + 4, 5);
05914                                 trap_Cvar_Set("cdkey2", out);
05915                                 Q_strncpyz(out, buff + 8, 5);
05916                                 trap_Cvar_Set("cdkey3", out);
05917                                 Q_strncpyz(out, buff + 12, 5);
05918                                 trap_Cvar_Set("cdkey4", out);
05919                         }
05920 
05921                 } else if (Q_stricmp(name, "verifyCDKey") == 0) {
05922                         buff[0] = '\0';
05923                         Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey1")); 
05924                         Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey2")); 
05925                         Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey3")); 
05926                         Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey4")); 
05927                         trap_Cvar_Set("cdkey", buff);
05928                         if (trap_VerifyCDKey(buff, UI_Cvar_VariableString("cdkeychecksum"))) {
05929                                 trap_Cvar_Set("ui_cdkeyvalid", "CD Key Appears to be valid.");
05930                                 trap_SetCDKey(buff);
05931                         } else {
05932                                 trap_Cvar_Set("ui_cdkeyvalid", "CD Key does not appear to be valid.");
05933                         }
05934 #endif // USE_CD_KEY
05935                 } else if (Q_stricmp(name, "loadArenas") == 0) {
05936                         UI_LoadArenas();
05937                         UI_MapCountByGameType(qfalse);
05938                         Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, gUISelectedMap, "createserver");
05939                         uiForceRank = trap_Cvar_VariableValue("g_maxForceRank");
05940                 } else if (Q_stricmp(name, "saveControls") == 0) {
05941                         Controls_SetConfig(qtrue);
05942                 } else if (Q_stricmp(name, "loadControls") == 0) {
05943                         Controls_GetConfig();
05944                 } else if (Q_stricmp(name, "clearError") == 0) {
05945                         trap_Cvar_Set("com_errorMessage", "");
05946                 } else if (Q_stricmp(name, "loadGameInfo") == 0) {
05947                         UI_ParseGameInfo("ui/jamp/gameinfo.txt");
05948                         UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
05949                 } else if (Q_stricmp(name, "resetScores") == 0) {
05950                         UI_ClearScores();
05951                 } else if (Q_stricmp(name, "RefreshServers") == 0) {
05952                         UI_StartServerRefresh(qtrue);
05953                         UI_BuildServerDisplayList(qtrue);
05954                 } else if (Q_stricmp(name, "RefreshFilter") == 0) {
05955                         UI_StartServerRefresh(qfalse);
05956                         UI_BuildServerDisplayList(qtrue);
05957                 } else if (Q_stricmp(name, "RunSPDemo") == 0) {
05958                         if (uiInfo.demoAvailable) {
05959                           trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s_%i\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum));
05960                         }
05961                 } else if (Q_stricmp(name, "LoadDemos") == 0) {
05962                         UI_LoadDemos();
05963                 } else if (Q_stricmp(name, "LoadMovies") == 0) {
05964                         UI_LoadMovies();
05965                 } else if (Q_stricmp(name, "LoadMods") == 0) {
05966                         UI_LoadMods();
05967                 } else if (Q_stricmp(name, "playMovie") == 0) {
05968                         if (uiInfo.previewMovie >= 0) {
05969                           trap_CIN_StopCinematic(uiInfo.previewMovie);
05970                         }
05971                         trap_Cmd_ExecuteText( EXEC_APPEND, va("cinematic %s.roq 2\n", uiInfo.movieList[uiInfo.movieIndex]));
05972                 } else if (Q_stricmp(name, "RunMod") == 0) {
05973                         trap_Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName);
05974                         trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
05975                 } else if (Q_stricmp(name, "RunDemo") == 0) {
05976                         trap_Cmd_ExecuteText( EXEC_APPEND, va("demo \"%s\"\n", uiInfo.demoList[uiInfo.demoIndex]));
05977                 } else if (Q_stricmp(name, "Quake3") == 0) {
05978                         trap_Cvar_Set( "fs_game", "");
05979                         trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
05980                 } else if (Q_stricmp(name, "closeJoin") == 0) {
05981                         if (uiInfo.serverStatus.refreshActive) {
05982                                 UI_StopServerRefresh();
05983                                 uiInfo.serverStatus.nextDisplayRefresh = 0;
05984                                 uiInfo.nextServerStatusRefresh = 0;
05985                                 uiInfo.nextFindPlayerRefresh = 0;
05986                                 UI_BuildServerDisplayList(qtrue);
05987                         } else {
05988                                 Menus_CloseByName("joinserver");
05989                                 Menus_OpenByName("main");
05990                         }
05991                 } else if (Q_stricmp(name, "StopRefresh") == 0) {
05992                         UI_StopServerRefresh();
05993                         uiInfo.serverStatus.nextDisplayRefresh = 0;
05994                         uiInfo.nextServerStatusRefresh = 0;
05995                         uiInfo.nextFindPlayerRefresh = 0;
05996                 } else if (Q_stricmp(name, "UpdateFilter") == 0) {
05997                         if (ui_netSource.integer == AS_LOCAL) {
05998                                 UI_StartServerRefresh(qtrue);
05999                         }
06000                         UI_BuildServerDisplayList(qtrue);
06001                         UI_FeederSelection(FEEDER_SERVERS, 0, NULL );
06002 
06003                 } else if (Q_stricmp(name, "ServerStatus") == 0) {
06004                         trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], uiInfo.serverStatusAddress, sizeof(uiInfo.serverStatusAddress));
06005                         UI_BuildServerStatus(qtrue);
06006                 } else if (Q_stricmp(name, "FoundPlayerServerStatus") == 0) {
06007                         Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress));
06008                         UI_BuildServerStatus(qtrue);
06009                         Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
06010                 } else if (Q_stricmp(name, "FindPlayer") == 0) {
06011                         UI_BuildFindPlayerList(qtrue);
06012                         // clear the displayed server status info
06013                         uiInfo.serverStatusInfo.numLines = 0;
06014                         Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
06015                 }
06016                 else if (Q_stricmp(name, "checkservername") == 0)
06017                 {
06018                         UI_CheckServerName();
06019                         
06020                 }
06021                 else if (Q_stricmp(name, "checkpassword") == 0)
06022                 {
06023                         if( UI_CheckPassword() )
06024                         {
06025                                 UI_JoinServer();
06026                         }
06027                         
06028                 }
06029                 else if (Q_stricmp(name, "JoinServer") == 0)
06030                 {
06031                         UI_JoinServer();
06032                 }
06033                 else if (Q_stricmp(name, "FoundPlayerJoinServer") == 0) {
06034                         trap_Cvar_Set("ui_singlePlayerActive", "0");
06035                         if (uiInfo.currentFoundPlayerServer >= 0 && uiInfo.currentFoundPlayerServer < uiInfo.numFoundPlayerServers) {
06036                                 trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer] ) );
06037                         }
06038                 } else if (Q_stricmp(name, "Quit") == 0) {
06039                         trap_Cvar_Set("ui_singlePlayerActive", "0");
06040                         trap_Cmd_ExecuteText( EXEC_NOW, "quit");
06041                 } else if (Q_stricmp(name, "Controls") == 0) {
06042                   trap_Cvar_Set( "cl_paused", "1" );
06043                         trap_Key_SetCatcher( KEYCATCH_UI );
06044                         Menus_CloseAll();
06045                         Menus_ActivateByName("setup_menu2");
06046                 } 
06047                 else if (Q_stricmp(name, "Leave") == 0) 
06048                 {
06049                         trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" );
06050                         trap_Key_SetCatcher( KEYCATCH_UI );
06051                         Menus_CloseAll();
06052                         Menus_ActivateByName("main");
06053                 } 
06054                 else if (Q_stricmp(name, "getvideosetup") == 0) 
06055                 {
06056                         UI_GetVideoSetup ( );
06057                 }
06058                 else if (Q_stricmp(name, "getsaberhiltinfo") == 0) 
06059                 {
06060                         UI_SaberGetHiltInfo(saberSingleHiltInfo,saberStaffHiltInfo);
06061                 }
06062                 // On the solo game creation screen, we can't see siege maps
06063                 else if (Q_stricmp(name, "checkforsiege") == 0) 
06064                 {
06065                         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
06066                         {
06067                                 // fake out the handler to advance to the next game type
06068                                 UI_NetGameType_HandleKey(0, NULL, A_MOUSE1);
06069                         }
06070                 }
06071                 else if (Q_stricmp(name, "updatevideosetup") == 0)
06072                 {
06073                         UI_UpdateVideoSetup ( );
06074                 }
06075                 else if (Q_stricmp(name, "ServerSort") == 0) 
06076                 {
06077                         int sortColumn;
06078                         if (Int_Parse(args, &sortColumn)) {
06079                                 // if same column we're already sorting on then flip the direction
06080                                 if (sortColumn == uiInfo.serverStatus.sortKey) {
06081                                         uiInfo.serverStatus.sortDir = !uiInfo.serverStatus.sortDir;
06082                                 }
06083                                 // make sure we sort again
06084                                 UI_ServersSort(sortColumn, qtrue);
06085                         }
06086                 } else if (Q_stricmp(name, "nextSkirmish") == 0) {
06087                         UI_StartSkirmish(qtrue);
06088                 } else if (Q_stricmp(name, "SkirmishStart") == 0) {
06089                         UI_StartSkirmish(qfalse);
06090                 } else if (Q_stricmp(name, "closeingame") == 0) {
06091                         trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
06092                         trap_Key_ClearStates();
06093                         trap_Cvar_Set( "cl_paused", "0" );
06094                         Menus_CloseAll();
06095                 } else if (Q_stricmp(name, "voteMap") == 0) {
06096                         if (ui_currentNetMap.integer >=0 && ui_currentNetMap.integer < uiInfo.mapCount) {
06097                                 trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote map %s\n",uiInfo.mapList[ui_currentNetMap.integer].mapLoadName) );
06098                         }
06099                 } else if (Q_stricmp(name, "voteKick") == 0) {
06100                         if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount) {
06101                                 //trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote kick \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex]) );
06102                                 trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote clientkick \"%i\"\n",uiInfo.playerIndexes[uiInfo.playerIndex]) );
06103                         }
06104                 } else if (Q_stricmp(name, "voteGame") == 0) {
06105                         if (ui_netGameType.integer >= 0 && ui_netGameType.integer < uiInfo.numGameTypes) {
06106                                 trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote g_gametype %i\n",uiInfo.gameTypes[ui_netGameType.integer].gtEnum) );
06107                         }
06108                 } else if (Q_stricmp(name, "voteLeader") == 0) {
06109                         if (uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount) {
06110                                 trap_Cmd_ExecuteText( EXEC_APPEND, va("callteamvote leader \"%s\"\n",uiInfo.teamNames[uiInfo.teamIndex]) );
06111                         }
06112                 } else if (Q_stricmp(name, "addBot") == 0) {
06113                         if (trap_Cvar_VariableValue("g_gametype") >= GT_TEAM) {
06114                                 trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot \"%s\" %i %s\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue") );
06115                         } else {
06116                                 trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot \"%s\" %i %s\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue") );
06117                         }
06118                 } else if (Q_stricmp(name, "addFavorite") == 0) 
06119                 {
06120                         if (ui_netSource.integer != AS_FAVORITES) 
06121                         {
06122                                 char name[MAX_NAME_LENGTH];
06123                                 char addr[MAX_NAME_LENGTH];
06124                                 int res;
06125 
06126                                 trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
06127                                 name[0] = addr[0] = '\0';
06128                                 Q_strncpyz(name,        Info_ValueForKey(buff, "hostname"), MAX_NAME_LENGTH);
06129                                 Q_strncpyz(addr,        Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
06130                                 if (strlen(name) > 0 && strlen(addr) > 0) 
06131                                 {
06132                                         res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
06133                                         if (res == 0) 
06134                                         {
06135                                                 // server already in the list
06136                                                 Com_Printf("Favorite already in list\n");
06137                                         }
06138                                         else if (res == -1) 
06139                                         {
06140                                                 // list full
06141                                                 Com_Printf("Favorite list full\n");
06142                                         }
06143                                         else 
06144                                         {
06145                                                 // successfully added
06146                                                 Com_Printf("Added favorite server %s\n", addr);
06147 
06148 
06149 //                                              trap_SP_GetStringTextString((char *)va("%s_GETTINGINFOFORSERVERS",uiInfo.uiDC.Assets.stringedFile), holdSPString, sizeof(holdSPString));
06150 //                                              Text_Paint(rect->x, rect->y, scale, newColor, va((char *) holdSPString, trap_LAN_GetServerCount(ui_netSource.integer)), 0, 0, textStyle);
06151 
06152                                         }
06153                                 }
06154                         }
06155                 } 
06156                 else if (Q_stricmp(name, "deleteFavorite") == 0) 
06157                 {
06158                         if (ui_netSource.integer == AS_FAVORITES) 
06159                         {
06160                                 char addr[MAX_NAME_LENGTH];
06161                                 trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
06162                                 addr[0] = '\0';
06163                                 Q_strncpyz(addr,        Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
06164                                 if (strlen(addr) > 0) 
06165                                 {
06166                                         trap_LAN_RemoveServer(AS_FAVORITES, addr);
06167                                 }
06168                         }
06169                 } 
06170                 else if (Q_stricmp(name, "createFavorite") == 0) 
06171                 {
06172                 //      if (ui_netSource.integer == AS_FAVORITES) 
06173                 //rww - don't know why this check was here.. why would you want to only add new favorites when the filter was favorites?
06174                         {
06175                                 char name[MAX_NAME_LENGTH];
06176                                 char addr[MAX_NAME_LENGTH];
06177                                 int res;
06178 
06179                                 name[0] = addr[0] = '\0';
06180                                 Q_strncpyz(name,        UI_Cvar_VariableString("ui_favoriteName"), MAX_NAME_LENGTH);
06181                                 Q_strncpyz(addr,        UI_Cvar_VariableString("ui_favoriteAddress"), MAX_NAME_LENGTH);
06182                                 if (/*strlen(name) > 0 &&*/ strlen(addr) > 0) {
06183                                         res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
06184                                         if (res == 0) {
06185                                                 // server already in the list
06186                                                 Com_Printf("Favorite already in list\n");
06187                                         }
06188                                         else if (res == -1) {
06189                                                 // list full
06190                                                 Com_Printf("Favorite list full\n");
06191                                         }
06192                                         else {
06193                                                 // successfully added
06194                                                 Com_Printf("Added favorite server %s\n", addr);
06195                                         }
06196                                 }
06197                         }
06198                 } else if (Q_stricmp(name, "orders") == 0) {
06199                         const char *orders;
06200                         if (String_Parse(args, &orders)) {
06201                                 int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
06202                                 if (selectedPlayer < uiInfo.myTeamCount) {
06203                                         strcpy(buff, orders);
06204                                         trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) );
06205                                         trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
06206                                 } else {
06207                                         int i;
06208                                         for (i = 0; i < uiInfo.myTeamCount; i++) {
06209                                                 if (Q_stricmp(UI_Cvar_VariableString("name"), uiInfo.teamNames[i]) == 0) {
06210                                                         continue;
06211                                                 }
06212                                                 strcpy(buff, orders);
06213                                                 trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamNames[i]) );
06214                                                 trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
06215                                         }
06216                                 }
06217                                 trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
06218                                 trap_Key_ClearStates();
06219                                 trap_Cvar_Set( "cl_paused", "0" );
06220                                 Menus_CloseAll();
06221                         }
06222                 } else if (Q_stricmp(name, "voiceOrdersTeam") == 0) {
06223                         const char *orders;
06224                         if (String_Parse(args, &orders)) {
06225                                 int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
06226                                 if (selectedPlayer == uiInfo.myTeamCount) {
06227                                         trap_Cmd_ExecuteText( EXEC_APPEND, orders );
06228                                         trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
06229                                 }
06230                                 trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
06231                                 trap_Key_ClearStates();
06232                                 trap_Cvar_Set( "cl_paused", "0" );
06233                                 Menus_CloseAll();
06234                         }
06235                 } else if (Q_stricmp(name, "voiceOrders") == 0) {
06236                         const char *orders;
06237                         if (String_Parse(args, &orders)) {
06238                                 int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
06239 
06240                                 if (selectedPlayer == uiInfo.myTeamCount)
06241                                 {
06242                                         selectedPlayer = -1;
06243                                         strcpy(buff, orders);
06244                                         trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, selectedPlayer) );
06245                                 }
06246                                 else
06247                                 {
06248                                         strcpy(buff, orders);
06249                                         trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) );
06250                                 }
06251                                 trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
06252 
06253                                 trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
06254                                 trap_Key_ClearStates();
06255                                 trap_Cvar_Set( "cl_paused", "0" );
06256                                 Menus_CloseAll();
06257                         }
06258                 }
06259                 else if (Q_stricmp(name, "setForce") == 0)
06260                 {
06261                         const char *teamArg;
06262 
06263                         if (String_Parse(args, &teamArg))
06264                         {
06265                                 if ( Q_stricmp( "none", teamArg ) == 0 )
06266                                 {
06267                                         UI_UpdateClientForcePowers(NULL);
06268                                 }
06269                                 else if ( Q_stricmp( "same", teamArg ) == 0 )
06270                                 {//stay on current team
06271                                         int myTeam = (int)(trap_Cvar_VariableValue("ui_myteam"));
06272                                         if ( myTeam != TEAM_SPECTATOR )
06273                                         {
06274                                                 UI_UpdateClientForcePowers(UI_TeamName(myTeam));//will cause him to respawn, if it's been 5 seconds since last one
06275                                         }
06276                                         else
06277                                         {
06278                                                 UI_UpdateClientForcePowers(NULL);//just update powers
06279                                         }
06280                                 }
06281                                 else
06282                                 {
06283                                         UI_UpdateClientForcePowers(teamArg);
06284                                 }
06285                         }
06286                         else
06287                         {
06288                                 UI_UpdateClientForcePowers(NULL);
06289                         }
06290                 }
06291                 else if (Q_stricmp(name, "setsiegeclassandteam") == 0)
06292                 {
06293                         int team = (int)trap_Cvar_VariableValue("ui_holdteam");
06294                         int oldteam = (int)trap_Cvar_VariableValue("ui_startsiegeteam");
06295                         qboolean        goTeam = qtrue;
06296                         char    newclassString[512];
06297                         char    startclassString[512];
06298 
06299                         trap_Cvar_VariableStringBuffer( "ui_mySiegeClass", newclassString, sizeof(newclassString) );
06300                         trap_Cvar_VariableStringBuffer( "ui_startsiegeclass", startclassString, sizeof(startclassString) );
06301 
06302                         // Was just a spectator - is still just a spectator
06303                         if ((oldteam == team) && (oldteam == 3))
06304                         {
06305                                 goTeam = qfalse;
06306                         }
06307                         // If new team and class match old team and class, just return to the game.
06308                         else if ((oldteam == team))
06309                         {       // Classes match?
06310                                 if (g_UIGloballySelectedSiegeClass != -1)
06311                                 {       
06312                                         if (!strcmp(startclassString,bgSiegeClasses[g_UIGloballySelectedSiegeClass].name))
06313                                         {
06314                                                 goTeam = qfalse;
06315                                         }
06316                                 }
06317                         }
06318 
06319                         if (goTeam)
06320                         {
06321                                 if (team == 1)  // Team red
06322                                 {
06323                                         trap_Cvar_Set("ui_team", va("%d", team));
06324                                 }
06325                                 else if (team == 2)     // Team blue
06326                                 {
06327                                         trap_Cvar_Set("ui_team", va("%d", team));
06328                                 }
06329                                 else if (team == 3)     // Team spectator
06330                                 {
06331                                         trap_Cvar_Set("ui_team", va("%d", team));
06332                                 }
06333 
06334                                 if (g_UIGloballySelectedSiegeClass != -1)
06335                                 {
06336                                         trap_Cmd_ExecuteText( EXEC_APPEND, va("siegeclass \"%s\"\n", bgSiegeClasses[g_UIGloballySelectedSiegeClass].name) );
06337                                 }
06338                         }
06339                 }
06340                 else if (Q_stricmp(name, "setBotButton") == 0) 
06341                 {
06342                         UI_SetBotButton();
06343                 }
06344                 else if (Q_stricmp(name, "saveTemplate") == 0) {
06345                         UI_SaveForceTemplate();
06346                 } else if (Q_stricmp(name, "refreshForce") == 0) {
06347                         UI_UpdateForcePowers();
06348                 } else if (Q_stricmp(name, "glCustom") == 0) {
06349                         trap_Cvar_Set("ui_r_glCustom", "4");
06350                 } 
06351                 else if (Q_stricmp(name, "setMovesListDefault") == 0) 
06352                 {
06353                         uiInfo.movesTitleIndex = 2;
06354                 }
06355                 else if (Q_stricmp(name, "resetMovesList") == 0) 
06356                 {
06357                         menuDef_t *menu;
06358                         menu = Menus_FindByName("rulesMenu_moves");
06359                         //update saber models
06360                         if (menu)
06361                         {
06362                                 itemDef_t *item  = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
06363                                 if (item)
06364                                 {
06365                                         UI_SaberAttachToChar( item );
06366                                 }
06367                         }
06368 
06369                         trap_Cvar_Set( "ui_move_desc", " " );
06370                 }
06371                 else if (Q_stricmp(name, "resetcharacterlistboxes") == 0) 
06372                 {
06373                         UI_ResetCharacterListBoxes();
06374                 }
06375                 else if (Q_stricmp(name, "setMoveCharacter") == 0) 
06376                 {
06377                         itemDef_t *item;
06378                         menuDef_t *menu;
06379                         modelDef_t *modelPtr;
06380                         int     animRunLength;
06381 
06382                         UI_GetCharacterCvars();
06383 
06384                         uiInfo.movesTitleIndex = 0;
06385 
06386                         menu = Menus_FindByName("rulesMenu_moves");
06387 
06388                         if (menu)
06389                         {
06390                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
06391                                 if (item)
06392                                 {
06393                                         modelPtr = (modelDef_t*)item->typeData;
06394                                         if (modelPtr)
06395                                         {
06396                                                 char modelPath[MAX_QPATH];
06397 
06398                                                 uiInfo.movesBaseAnim = datapadMoveTitleBaseAnims[uiInfo.movesTitleIndex];
06399                                                 ItemParse_model_g2anim_go( item,  uiInfo.movesBaseAnim );
06400                                                 uiInfo.moveAnimTime = 0 ;
06401 
06402                                                 Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
06403                                                 ItemParse_asset_model_go( item, modelPath, &animRunLength);
06404 
06405                                                 UI_UpdateCharacterSkin();
06406                                                 UI_SaberAttachToChar( item );
06407                                         }
06408                                 }
06409                         } 
06410                 }
06411                 else if (Q_stricmp(name, "character") == 0) 
06412                 {
06413                         UI_UpdateCharacter( qfalse );
06414                 }
06415                 else if (Q_stricmp(name, "characterchanged") == 0) 
06416                 {
06417                         UI_UpdateCharacter( qtrue );
06418                 }
06419                 else if (Q_stricmp(name, "updatecharcvars") == 0
06420                         || (Q_stricmp(name, "updatecharmodel") == 0) )
06421                 {
06422                         UI_UpdateCharacterCvars();
06423                 }
06424                 else if (Q_stricmp(name, "getcharcvars") == 0) 
06425                 {
06426                         UI_GetCharacterCvars();
06427                 }
06428                 else if (Q_stricmp(name, "char_skin") == 0) 
06429                 {
06430                         UI_UpdateCharacterSkin();
06431                 }
06432                 else if (Q_stricmp(name, "setui_dualforcepower") == 0) 
06433                 {
06434                         int forcePowerDisable = trap_Cvar_VariableValue("g_forcePowerDisable");
06435                         int     i, forceBitFlag=0;
06436 
06437                         // Turn off all powers but a few
06438                         for (i=0;i<NUM_FORCE_POWERS;i++)
06439                         {
06440                                 if ((i != FP_LEVITATION) &&
06441                                         (i != FP_PUSH) &&
06442                                         (i != FP_PULL) &&
06443                                         (i != FP_SABERTHROW) &&
06444                                         (i != FP_SABER_DEFENSE) &&
06445                                         (i != FP_SABER_OFFENSE))
06446                                 {
06447                                         forceBitFlag |= (1<<i);
06448                                 }
06449                         }
06450 
06451 
06452                         if (forcePowerDisable==0)
06453                         {
06454                                 trap_Cvar_Set("ui_dualforcepower", "0");
06455                         }
06456                         else if (forcePowerDisable==forceBitFlag)
06457                         {
06458                                 trap_Cvar_Set("ui_dualforcepower", "2");
06459                         }
06460                         else 
06461                         {
06462                                 trap_Cvar_Set("ui_dualforcepower", "1");
06463                         }
06464 
06465                 }
06466                 else if (Q_stricmp(name, "dualForcePowers") == 0) 
06467                 {
06468                         int     dualforcePower,i, forcePowerDisable;
06469                         dualforcePower = trap_Cvar_VariableValue("ui_dualforcepower");
06470 
06471                         if (dualforcePower==0)  // All force powers
06472                         {
06473                                 forcePowerDisable = 0;
06474                         }
06475                         else if (dualforcePower==1)     // Remove All force powers
06476                         {
06477                                 // It was set to something, so might as well make sure it got all flags set.
06478                                 for (i=0;i<NUM_FORCE_POWERS;i++)
06479                                 {
06480                                         forcePowerDisable |= (1<<i);
06481                                 }
06482                         }
06483                         else if (dualforcePower==2)     // Limited force powers
06484                         {
06485                                 forcePowerDisable = 0;                                          
06486                                 
06487                                 // Turn off all powers but a few
06488                                 for (i=0;i<NUM_FORCE_POWERS;i++)
06489                                 {
06490                                         if ((i != FP_LEVITATION) &&
06491                                                 (i != FP_PUSH) &&
06492                                                 (i != FP_PULL) &&
06493                                                 (i != FP_SABERTHROW) &&
06494                                                 (i != FP_SABER_DEFENSE) &&
06495                                                 (i != FP_SABER_OFFENSE))
06496                                         {
06497                                                 forcePowerDisable |= (1<<i);
06498                                         }
06499                                 }
06500                         }
06501 
06502                         trap_Cvar_Set("g_forcePowerDisable", va("%i",forcePowerDisable));
06503                 }
06504                 else if (Q_stricmp(name, "forcePowersDisable") == 0) 
06505                 {
06506                         int     forcePowerDisable,i;
06507 
06508                         forcePowerDisable = trap_Cvar_VariableValue("g_forcePowerDisable");
06509 
06510                         // It was set to something, so might as well make sure it got all flags set.
06511                         if (forcePowerDisable)
06512                         {
06513                                 for (i=0;i<NUM_FORCE_POWERS;i++)
06514                                 {
06515                                         forcePowerDisable |= (1<<i);
06516                                 }
06517 
06518                                 trap_Cvar_Set("g_forcePowerDisable", va("%i",forcePowerDisable));
06519                         }
06520 
06521                 } 
06522                 else if (Q_stricmp(name, "weaponDisable") == 0) 
06523                 {
06524                         int     weaponDisable,i;
06525                         const char *cvarString;
06526 
06527                         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_DUEL ||
06528                                 uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_POWERDUEL)
06529                         {
06530                                 cvarString = "g_duelWeaponDisable";
06531                         }
06532                         else
06533                         {
06534                                 cvarString = "g_weaponDisable";
06535                         }
06536 
06537                         weaponDisable = trap_Cvar_VariableValue(cvarString);
06538 
06539                         // It was set to something, so might as well make sure it got all flags set.
06540                         if (weaponDisable)
06541                         {
06542                                 for (i=0;i<WP_NUM_WEAPONS;i++)
06543                                 {
06544                                         if (i!=WP_SABER)
06545                                         {
06546                                                 weaponDisable |= (1<<i);
06547                                         }
06548                                 }
06549 
06550                                 trap_Cvar_Set(cvarString, va("%i",weaponDisable));
06551                         }
06552                 } 
06553                 // If this is siege, change all the bots to humans, because we faked it earlier 
06554                 //  swapping humans for bots on the menu
06555                 else if (Q_stricmp(name, "setSiegeNoBots") == 0) 
06556                 {
06557                         int blueValue,redValue,i;
06558 
06559                         if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
06560                         {
06561                 //hmm, I guess I'll set bot_minplayers to 0 here too. -rww
06562                                 trap_Cvar_Set("bot_minplayers", "0");
06563 
06564                                 for (i=1;i<9;i++)
06565                                 {
06566                                         blueValue = trap_Cvar_VariableValue(va("ui_blueteam%i",i ));
06567                                         if (blueValue>1)
06568                                         {
06569                                                 trap_Cvar_Set(va("ui_blueteam%i",i ), "1");
06570                                         }
06571 
06572                                         redValue = trap_Cvar_VariableValue(va("ui_redteam%i",i ));
06573                                         if (redValue>1)
06574                                         {
06575                                                 trap_Cvar_Set(va("ui_redteam%i",i ), "1");
06576                                         }
06577 
06578                                 }
06579                         }
06580                 }
06581                 else if (Q_stricmp(name, "clearmouseover") == 0) 
06582                 {
06583                         itemDef_t *item;
06584                         menuDef_t *menu = Menu_GetFocused();
06585 
06586                         if (menu) 
06587                         {
06588                                 int count,j;
06589                                 const char *itemName;
06590                                 String_Parse(args, &itemName);
06591 
06592                                 count = Menu_ItemsMatchingGroup(menu, itemName);
06593 
06594                                 for (j = 0; j < count; j++) 
06595                                 {
06596                                         item = Menu_GetMatchingItemByNumber( menu, j, itemName);
06597                                         if (item != NULL) 
06598                                         {
06599                                                         item->window.flags &= ~WINDOW_MOUSEOVER;
06600                                         }
06601                                 }
06602                         }
06603 
06604                 }
06605                 else if (Q_stricmp(name, "updateForceStatus") == 0)
06606                 {
06607                         UpdateForceStatus();
06608                 }
06609                 else if (Q_stricmp(name, "update") == 0) 
06610                 {
06611                         if (String_Parse(args, &name2)) 
06612                         {
06613                                 UI_Update(name2);
06614                         }
06615                 }
06616                 else if (Q_stricmp(name, "setBotButtons") == 0)
06617                 {
06618                         UpdateBotButtons();
06619                 }
06620                 else if (Q_stricmp(name, "getsabercvars") == 0) 
06621                 {
06622                         UI_GetSaberCvars();
06623                 }
06624                 else if (Q_stricmp(name, "setsaberboxesandhilts") == 0) 
06625                 {
06626                         UI_SetSaberBoxesandHilts();
06627                 }
06628                 else if (Q_stricmp(name, "saber_type") == 0) 
06629                 {
06630                         UI_UpdateSaberType();
06631                 }
06632                 else if (Q_stricmp(name, "saber_hilt") == 0) 
06633                 {
06634                         UI_UpdateSaberHilt( qfalse );
06635                 }
06636                 else if (Q_stricmp(name, "saber_color") == 0) 
06637                 {
06638                         UI_UpdateSaberColor( qfalse );
06639                 }
06640                 else if (Q_stricmp(name, "setscreensaberhilt") == 0) 
06641                 {
06642                         menuDef_t *menu;
06643                         itemDef_t *item;
06644 
06645                         menu = Menu_GetFocused();       // Get current menu
06646                         if (menu)
06647                         {
06648                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut");
06649                                 if (item)
06650                                 {
06651                                         if (saberSingleHiltInfo[item->cursorPos])
06652                                         {
06653                                                 trap_Cvar_Set( "ui_saber", saberSingleHiltInfo[item->cursorPos] );
06654                                         }
06655                                 }
06656                         }
06657                 }
06658                 else if (Q_stricmp(name, "setscreensaberhilt1") == 0) 
06659                 {
06660                         menuDef_t *menu;
06661                         itemDef_t *item;
06662 
06663                         menu = Menu_GetFocused();       // Get current menu
06664                         if (menu)
06665                         {
06666                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut1");
06667                                 if (item)
06668                                 {
06669                                         if (saberSingleHiltInfo[item->cursorPos])
06670                                         {
06671                                                 trap_Cvar_Set( "ui_saber", saberSingleHiltInfo[item->cursorPos] );
06672                                         }
06673                                 }
06674                         }
06675                 }
06676                 else if (Q_stricmp(name, "setscreensaberhilt2") == 0) 
06677                 {
06678                         menuDef_t *menu;
06679                         itemDef_t *item;
06680 
06681                         menu = Menu_GetFocused();       // Get current menu
06682                         if (menu)
06683                         {
06684                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut2");
06685                                 if (item)
06686                                 {
06687                                         if (saberSingleHiltInfo[item->cursorPos])
06688                                         {
06689                                                 trap_Cvar_Set( "ui_saber2", saberSingleHiltInfo[item->cursorPos] );
06690                                         }
06691                                 }
06692                         }
06693                 }
06694                 else if (Q_stricmp(name, "setscreensaberstaff") == 0) 
06695                 {
06696                         menuDef_t *menu;
06697                         itemDef_t *item;
06698 
06699                         menu = Menu_GetFocused();       // Get current menu
06700                         if (menu)
06701                         {
06702                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut_staves");
06703                                 if (item)
06704                                 {
06705                                         if (saberSingleHiltInfo[item->cursorPos])
06706                                         {
06707                                                 trap_Cvar_Set( "ui_saber", saberStaffHiltInfo[item->cursorPos] );
06708                                         }
06709                                 }
06710                         }
06711                 }
06712                 else if (Q_stricmp(name, "saber2_hilt") == 0) 
06713                 {
06714                         UI_UpdateSaberHilt( qtrue );
06715                 }
06716                 else if (Q_stricmp(name, "saber2_color") == 0) 
06717                 {
06718                         UI_UpdateSaberColor( qtrue );
06719                 }
06720                 else if (Q_stricmp(name, "updatesabercvars") == 0) 
06721                 {
06722                         UI_UpdateSaberCvars();
06723                 }
06724                 else if (Q_stricmp(name, "updatesiegeobjgraphics") == 0) 
06725                 {
06726                         int team = (int)trap_Cvar_VariableValue("ui_team");
06727                         trap_Cvar_Set("ui_holdteam", va("%d", team));
06728 
06729                         UI_UpdateSiegeObjectiveGraphics();
06730                 }
06731                 else if (Q_stricmp(name, "setsiegeobjbuttons") == 0) 
06732                 {
06733                         const char *itemArg;
06734                         const char *cvarLitArg;
06735                         const char *cvarNormalArg;
06736                         char    string[512];
06737                         char    string2[512];
06738                         menuDef_t *menu;
06739                         itemDef_t *item;
06740 
06741                         menu = Menu_GetFocused();       // Get current menu
06742                         if (menu)
06743                         {
06744                                 // Set the new item to the background 
06745                                 if (String_Parse(args, &itemArg))
06746                                 {
06747 
06748                                         // Set the old button to it's original background
06749                                         trap_Cvar_VariableStringBuffer( "currentObjMapIconItem", string, sizeof(string) );
06750                                         item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, string);
06751                                         if (item)
06752                                         {
06753                                                         // A cvar holding the name of a cvar - how crazy is that?
06754                                                         trap_Cvar_VariableStringBuffer( "currentObjMapIconBackground", string, sizeof(string) );
06755                                                         trap_Cvar_VariableStringBuffer( string, string2, sizeof(string2) );
06756                                                         Menu_SetItemBackground(menu, item->window.name, string2);
06757 
06758                                                         // Re-enable this button
06759                                                         Menu_ItemDisable(menu,(char *) item->window.name, qfalse);
06760                                         }
06761 
06762                                         // Set the new item to the given background
06763                                         item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, itemArg);
06764                                         if (item)
06765                                         {       // store item name
06766                                                 trap_Cvar_Set("currentObjMapIconItem",   item->window.name);
06767                                                 if (String_Parse(args, &cvarNormalArg))
06768                                                 {       // Store normal background
06769                                                         trap_Cvar_Set("currentObjMapIconBackground", cvarNormalArg);
06770                                                         // Get higlight background
06771                                                         if (String_Parse(args, &cvarLitArg))
06772                                                         {       // set hightlight background
06773                                                                 trap_Cvar_VariableStringBuffer( cvarLitArg, string, sizeof(string) );
06774                                                                 Menu_SetItemBackground(menu, item->window.name, string);
06775                                                                 // Disable button
06776                                                                 Menu_ItemDisable(menu,(char *) item->window.name, qtrue);
06777                                                         }
06778                                                 }
06779                                         }
06780                                 }
06781                         }
06782 
06783 
06784                 }
06785                 else if (Q_stricmp(name, "updatesiegeclasscnt") == 0) 
06786                 {
06787                         const char *teamArg;
06788 
06789                         if (String_Parse(args, &teamArg))
06790                         {
06791                                         UI_SiegeClassCnt(atoi(teamArg));
06792                         }
06793                 }
06794                 else if (Q_stricmp(name, "updatesiegecvars") == 0) 
06795                 {
06796                         int team,baseClass; 
06797         
06798                         team = (int)trap_Cvar_VariableValue("ui_holdteam");
06799                         baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
06800 
06801                         UI_UpdateCvarsForClass(team, baseClass, 0);
06802 
06803                 }
06804                 // Save current team and class
06805                 else if (Q_stricmp(name, "setteamclassicons") == 0)
06806                 {
06807                         int team = (int)trap_Cvar_VariableValue("ui_holdteam");
06808                         char    classString[512];
06809 
06810                         trap_Cvar_VariableStringBuffer( "ui_mySiegeClass", classString, sizeof(classString) );
06811 
06812                         trap_Cvar_Set("ui_startsiegeteam", va("%d", team));
06813                         trap_Cvar_Set( "ui_startsiegeclass", classString);
06814 
06815                         // If player is already on a team, set up icons to show it.
06816                         UI_FindCurrentSiegeTeamClass();
06817 
06818                 }
06819                 else if (Q_stricmp(name, "updatesiegeweapondesc") == 0)
06820                 {
06821                         menuDef_t *menu;
06822                         itemDef_t *item;
06823 
06824                         menu = Menu_GetFocused();       // Get current menu
06825                         if (menu)
06826                         {
06827                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_weapons_feed");
06828                                 if (item)
06829                                 {
06830                                         char    info[MAX_INFO_VALUE];
06831                                         trap_Cvar_VariableStringBuffer( va("ui_class_weapondesc%i", item->cursorPos), info, sizeof(info) );
06832                                         trap_Cvar_Set( "ui_itemforceinvdesc", info );
06833                                 }
06834                         }
06835                 }
06836                 else if (Q_stricmp(name, "updatesiegeinventorydesc") == 0)
06837                 {
06838                         menuDef_t *menu;
06839                         itemDef_t *item;
06840 
06841                         menu = Menu_GetFocused();       // Get current menu
06842                         if (menu)
06843                         {
06844                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_inventory_feed");
06845                                 if (item)
06846                                 {
06847                                         char info[MAX_INFO_VALUE];
06848                                         trap_Cvar_VariableStringBuffer( va("ui_class_itemdesc%i", item->cursorPos), info, sizeof(info) );
06849                                         trap_Cvar_Set( "ui_itemforceinvdesc", info );
06850                                 }
06851                         }
06852                 }
06853                 else if (Q_stricmp(name, "updatesiegeforcedesc") == 0)
06854                 {
06855                         menuDef_t *menu;
06856                         itemDef_t *item;
06857 
06858                         menu = Menu_GetFocused();       // Get current menu
06859                         if (menu)
06860                         {
06861                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_force_feed");
06862                                 if (item)
06863                                 {
06864                                         int i;
06865                                         char info[MAX_STRING_CHARS];
06866 
06867                                         trap_Cvar_VariableStringBuffer( va("ui_class_power%i", item->cursorPos), info, sizeof(info) );
06868 
06869                                         //count them up
06870                                         for (i=0;i< NUM_FORCE_POWERS;i++)
06871                                         {
06872                                                 if (!strcmp(HolocronIcons[i],info))
06873                                                 {
06874                                                         trap_Cvar_Set( "ui_itemforceinvdesc", forcepowerDesc[i] );
06875                                                 }
06876                                         }
06877                                 }
06878                         }
06879                 }
06880                 else if (Q_stricmp(name, "resetitemdescription") == 0)
06881                 {
06882                         menuDef_t *menu;
06883                         itemDef_t *item;
06884 
06885                         menu = Menu_GetFocused();       // Get current menu
06886                         if (menu)
06887                         {
06888 
06889                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "itemdescription");
06890                                 if (item)
06891                                 {
06892                                         listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
06893                                         if (listPtr)
06894                                         {
06895                                                 listPtr->startPos = 0;
06896                                                 listPtr->cursorPos = 0;
06897                                         }
06898                                         item->cursorPos = 0;
06899                                 }
06900                         }
06901                 }
06902                 else if (Q_stricmp(name, "resetsiegelistboxes") == 0)
06903                 {
06904                         menuDef_t *menu;
06905                         itemDef_t *item;
06906 
06907                         menu = Menu_GetFocused();       // Get current menu
06908                         if (menu)
06909                         {
06910                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "description");
06911                                 if (item)
06912                                 {
06913                                         listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
06914                                         if (listPtr)
06915                                         {
06916                                                 listPtr->startPos = 0;
06917                                         }
06918                                         item->cursorPos = 0;
06919                                 }
06920                         }
06921 
06922                         menu = Menu_GetFocused();       // Get current menu
06923                         if (menu)
06924                         {
06925                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_weapons_feed");
06926                                 if (item)
06927                                 {
06928                                         listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
06929                                         if (listPtr)
06930                                         {
06931                                                 listPtr->startPos = 0;
06932                                         }
06933                                         item->cursorPos = 0;
06934                                 }
06935 
06936                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_inventory_feed");
06937                                 if (item)
06938                                 {
06939                                         listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
06940                                         if (listPtr)
06941                                         {
06942                                                 listPtr->startPos = 0;
06943                                         }
06944                                         item->cursorPos = 0;
06945                                 }
06946 
06947                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_force_feed");
06948                                 if (item)
06949                                 {
06950                                         listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
06951                                         if (listPtr)
06952                                         {
06953                                                 listPtr->startPos = 0;
06954                                         }
06955                                         item->cursorPos = 0;
06956                                 }       
06957                         }
06958                 }
06959                 else if (Q_stricmp(name, "updatesiegestatusicons") == 0) 
06960                 {
06961                         UI_UpdateSiegeStatusIcons();
06962                 }
06963                 else if (Q_stricmp(name, "setcurrentNetMap") == 0) 
06964                 {
06965                         menuDef_t *menu;
06966                         itemDef_t *item;
06967 
06968                         menu = Menu_GetFocused();       // Get current menu
06969                         if (menu)
06970                         {
06971                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "maplist");
06972                                 if (item)
06973                                 {
06974                                         listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
06975                                         if (listPtr)
06976                                         {
06977                                                 trap_Cvar_Set("ui_currentNetMap", va("%d",listPtr->cursorPos));
06978                                         }
06979                                 }
06980                         }
06981                 }
06982                 else if (Q_stricmp(name, "resetmaplist") == 0) 
06983                 {
06984                         menuDef_t *menu;
06985                         itemDef_t *item;
06986                 
06987                         menu = Menu_GetFocused();       // Get current menu
06988                         if (menu)
06989                         {
06990                                 item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "maplist");
06991                                 if (item)
06992                                 {
06993                                         uiInfo.uiDC.feederSelection(item->special, item->cursorPos, item);
06994                                 }
06995                         }
06996                 }
06997                 else if (Q_stricmp(name, "getmousepitch") == 0)
06998                 {
06999                         trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1");
07000                 }
07001                 else if (Q_stricmp(name, "clampmaxplayers") == 0)
07002                 {
07003                         UI_ClampMaxPlayers();
07004                 }
07005                 else 
07006                 {
07007                         Com_Printf("unknown UI script %s\n", name);
07008                 }
07009         }
07010 }
07011 
07012 static void UI_GetTeamColor(vec4_t *color) {
07013 }
07014 
07015 #include "../namespace_begin.h"
07016 int BG_SiegeCountBaseClass(const int team, const short classIndex);
07017 #include "../namespace_end.h"
07018 
07019 static void UI_SiegeClassCnt( const int team )
07020 {
07021         UI_SetSiegeTeams();
07022 
07023         trap_Cvar_Set("ui_infantry_cnt", va("%d", BG_SiegeCountBaseClass(team,0)));
07024         trap_Cvar_Set("ui_vanguard_cnt", va("%d", BG_SiegeCountBaseClass(team,1)));
07025         trap_Cvar_Set("ui_support_cnt", va("%d", BG_SiegeCountBaseClass(team,2)));
07026         trap_Cvar_Set("ui_jedi_cnt", va("%d", BG_SiegeCountBaseClass(team,3)));
07027         trap_Cvar_Set("ui_demo_cnt", va("%d", BG_SiegeCountBaseClass(team,4)));
07028         trap_Cvar_Set("ui_heavy_cnt", va("%d", BG_SiegeCountBaseClass(team,5)));
07029 
07030 }
07031 
07032 void UI_ClampMaxPlayers(void)
07033 {
07034         char    buf[32];
07035         // min checks
07036         //
07037         if( uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_DUEL ) //DUEL
07038         {
07039                 if( trap_Cvar_VariableValue("sv_maxClients") < 2 )
07040                 {
07041                         trap_Cvar_Set("sv_maxClients", "2");
07042                 }
07043         }
07044         else if( uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_POWERDUEL ) // POWER DUEL
07045         {
07046                 if( trap_Cvar_VariableValue("sv_maxClients") < 3 )
07047                 {
07048                         trap_Cvar_Set("sv_maxClients", "3");
07049                 }
07050         }
07051 
07052         
07053         // max check for all game types
07054         if( trap_Cvar_VariableValue("sv_maxClients") > MAX_CLIENTS )
07055         {
07056                 sprintf(buf,"%d",MAX_CLIENTS);
07057                 trap_Cvar_Set("sv_maxClients", buf);
07058         }
07059 
07060 }
07061 
07062 void    UI_UpdateSiegeStatusIcons(void)
07063 {
07064     menuDef_t *menu = Menu_GetFocused();
07065         int i;
07066 
07067         menu = Menu_GetFocused();       // Get current menu
07068 
07069         if (!menu)
07070         {
07071                 return;
07072         }
07073 
07074         for (i=0;i<7;i++)
07075         {
07076 
07077                 Menu_SetItemBackground(menu,va("wpnicon0%d",i), va("*ui_class_weapon%d",i));
07078         }
07079 
07080         for (i=0;i<7;i++)
07081         {
07082                 Menu_SetItemBackground(menu,va("itemicon0%d",i), va("*ui_class_item%d",i));
07083         }
07084 
07085         for (i=0;i<10;i++)
07086         {
07087                 Menu_SetItemBackground(menu,va("forceicon0%d",i), va("*ui_class_power%d",i));
07088         }
07089 
07090         for (i=10;i<15;i++)
07091         {
07092                 Menu_SetItemBackground(menu,va("forceicon%d",i), va("*ui_class_power%d",i));
07093         }
07094 
07095 }
07096 
07097 /*
07098 ==================
07099 UI_MapCountByGameType
07100 ==================
07101 */
07102 static int UI_MapCountByGameType(qboolean singlePlayer) {
07103         int i, c, game;
07104         c = 0;
07105         game = singlePlayer ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : uiInfo.gameTypes[ui_netGameType.integer].gtEnum;
07106         if (game == GT_SINGLE_PLAYER) {
07107                 game++;
07108         } 
07109         if (game == GT_TEAM) {
07110                 game = GT_FFA;
07111         }
07112         if (game == GT_HOLOCRON || game == GT_JEDIMASTER) {
07113                 game = GT_FFA;
07114         }
07115 
07116         for (i = 0; i < uiInfo.mapCount; i++) {
07117                 uiInfo.mapList[i].active = qfalse;
07118                 if ( uiInfo.mapList[i].typeBits & (1 << game)) {
07119                         if (singlePlayer) {
07120                                 if (!(uiInfo.mapList[i].typeBits & (1 << GT_SINGLE_PLAYER))) {
07121                                         continue;
07122                                 }
07123                         }
07124                         c++;
07125                         uiInfo.mapList[i].active = qtrue;
07126                 }
07127         }
07128         return c;
07129 }
07130 
07131 qboolean UI_hasSkinForBase(const char *base, const char *team) {
07132         char    test[1024];
07133         fileHandle_t    f;
07134         
07135         Com_sprintf( test, sizeof( test ), "models/players/%s/%s/lower_default.skin", base, team );
07136         trap_FS_FOpenFile(test, &f, FS_READ);
07137         if (f != 0) {
07138                 trap_FS_FCloseFile(f);
07139                 return qtrue;
07140         }
07141         Com_sprintf( test, sizeof( test ), "models/players/characters/%s/%s/lower_default.skin", base, team );
07142         trap_FS_FOpenFile(test, &f, FS_READ);
07143         if (f != 0) {
07144                 trap_FS_FCloseFile(f);
07145                 return qtrue;
07146         }
07147         return qfalse;
07148 }
07149 
07150 /*
07151 ==================
07152 UI_HeadCountByColor
07153 ==================
07154 */
07155 static int UI_HeadCountByColor() {
07156         int i, c;
07157         char *teamname;
07158 
07159         c = 0;
07160 
07161         switch(uiSkinColor)
07162         {
07163                 case TEAM_BLUE:
07164                         teamname = "/blue";
07165                         break;
07166                 case TEAM_RED:
07167                         teamname = "/red";
07168                         break;
07169                 default:
07170                         teamname = "/default";
07171         }
07172 
07173         // Count each head with this color
07174         for (i=0; i<uiInfo.q3HeadCount; i++)
07175         {
07176                 if (uiInfo.q3HeadNames[i] && strstr(uiInfo.q3HeadNames[i], teamname))
07177                 {
07178                         c++;
07179                 }
07180         }
07181         return c;
07182 }
07183 
07184 /*
07185 ==================
07186 UI_InsertServerIntoDisplayList
07187 ==================
07188 */
07189 static void UI_InsertServerIntoDisplayList(int num, int position) {
07190         int i;
07191 
07192         if (position < 0 || position > uiInfo.serverStatus.numDisplayServers ) {
07193                 return;
07194         }
07195         //
07196         uiInfo.serverStatus.numDisplayServers++;
07197         for (i = uiInfo.serverStatus.numDisplayServers; i > position; i--) {
07198                 uiInfo.serverStatus.displayServers[i] = uiInfo.serverStatus.displayServers[i-1];
07199         }
07200         uiInfo.serverStatus.displayServers[position] = num;
07201 }
07202 
07203 /*
07204 ==================
07205 UI_RemoveServerFromDisplayList
07206 ==================
07207 */
07208 static void UI_RemoveServerFromDisplayList(int num) {
07209         int i, j;
07210 
07211         for (i = 0; i < uiInfo.serverStatus.numDisplayServers; i++) {
07212                 if (uiInfo.serverStatus.displayServers[i] == num) {
07213                         uiInfo.serverStatus.numDisplayServers--;
07214                         for (j = i; j < uiInfo.serverStatus.numDisplayServers; j++) {
07215                                 uiInfo.serverStatus.displayServers[j] = uiInfo.serverStatus.displayServers[j+1];
07216                         }
07217                         return;
07218                 }
07219         }
07220 }
07221 
07222 /*
07223 ==================
07224 UI_BinaryServerInsertion
07225 ==================
07226 */
07227 static void UI_BinaryServerInsertion(int num) {
07228         int mid, offset, res, len;
07229 
07230         // use binary search to insert server
07231         len = uiInfo.serverStatus.numDisplayServers;
07232         mid = len;
07233         offset = 0;
07234         res = 0;
07235         while(mid > 0) {
07236                 mid = len >> 1;
07237                 //
07238                 res = trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey,
07239                                         uiInfo.serverStatus.sortDir, num, uiInfo.serverStatus.displayServers[offset+mid]);
07240                 // if equal
07241                 if (res == 0) {
07242                         UI_InsertServerIntoDisplayList(num, offset+mid);
07243                         return;
07244                 }
07245                 // if larger
07246                 else if (res == 1) {
07247                         offset += mid;
07248                         len -= mid;
07249                 }
07250                 // if smaller
07251                 else {
07252                         len -= mid;
07253                 }
07254         }
07255         if (res == 1) {
07256                 offset++;
07257         }
07258         UI_InsertServerIntoDisplayList(num, offset);
07259 }
07260 
07261 /*
07262 ==================
07263 UI_BuildServerDisplayList
07264 ==================
07265 */
07266 static void UI_BuildServerDisplayList(qboolean force) {
07267         int i, count, clients, maxClients, ping, game, len/*, visible*/;
07268         char info[MAX_STRING_CHARS];
07269 //      qboolean startRefresh = qtrue; TTimo: unused
07270         static int numinvisible;
07271 
07272         if (!(force || uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh)) {
07273                 return;
07274         }
07275         // if we shouldn't reset
07276         if ( force == 2 ) {
07277                 force = 0;
07278         }
07279 
07280         // do motd updates here too
07281         trap_Cvar_VariableStringBuffer( "cl_motdString", uiInfo.serverStatus.motd, sizeof(uiInfo.serverStatus.motd) );
07282         len = strlen(uiInfo.serverStatus.motd);
07283         if (len == 0) {
07284                 strcpy(uiInfo.serverStatus.motd, "Welcome to Jedi Academy MP!");
07285                 len = strlen(uiInfo.serverStatus.motd);
07286         } 
07287         if (len != uiInfo.serverStatus.motdLen) {
07288                 uiInfo.serverStatus.motdLen = len;
07289                 uiInfo.serverStatus.motdWidth = -1;
07290         } 
07291 
07292         if (force) {
07293                 numinvisible = 0;
07294                 // clear number of displayed servers
07295                 uiInfo.serverStatus.numDisplayServers = 0;
07296                 uiInfo.serverStatus.numPlayersOnServers = 0;
07297                 // set list box index to zero
07298                 Menu_SetFeederSelection(NULL, FEEDER_SERVERS, 0, NULL);
07299                 // mark all servers as visible so we store ping updates for them
07300                 trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue);
07301         }
07302 
07303         // get the server count (comes from the master)
07304         count = trap_LAN_GetServerCount(ui_netSource.integer);
07305         if (count == -1 || (ui_netSource.integer == AS_LOCAL && count == 0) ) {
07306                 // still waiting on a response from the master
07307                 uiInfo.serverStatus.numDisplayServers = 0;
07308                 uiInfo.serverStatus.numPlayersOnServers = 0;
07309                 uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 500;
07310                 return;
07311         }
07312 
07313 //      visible = qfalse;
07314         for (i = 0; i < count; i++) {
07315                 // if we already got info for this server
07316                 if (!trap_LAN_ServerIsVisible(ui_netSource.integer, i)) {
07317                         continue;
07318                 }
07319 //              visible = qtrue;
07320                 // get the ping for this server
07321                 ping = trap_LAN_GetServerPing(ui_netSource.integer, i);
07322                 if (ping > 0 || ui_netSource.integer == AS_FAVORITES) {
07323 
07324                         trap_LAN_GetServerInfo(ui_netSource.integer, i, info, MAX_STRING_CHARS);
07325 
07326                         clients = atoi(Info_ValueForKey(info, "clients"));
07327                         uiInfo.serverStatus.numPlayersOnServers += clients;
07328 
07329                         if (ui_browserShowEmpty.integer == 0) {
07330                                 if (clients == 0) {
07331                                         trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
07332                                         continue;
07333                                 }
07334                         }
07335 
07336                         if (ui_browserShowFull.integer == 0) {
07337                                 maxClients = atoi(Info_ValueForKey(info, "sv_maxclients"));
07338                                 if (clients == maxClients) {
07339                                         trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
07340                                         continue;
07341                                 }
07342                         }
07343 
07344                         if (uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum != -1) {
07345                                 game = atoi(Info_ValueForKey(info, "gametype"));
07346                                 if (game != uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum) {
07347                                         trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
07348                                         continue;
07349                                 }
07350                         }
07351                                 
07352                         if (ui_serverFilterType.integer > 0) {
07353                                 if (Q_stricmp(Info_ValueForKey(info, "game"), serverFilters[ui_serverFilterType.integer].basedir) != 0) {
07354                                         trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
07355                                         continue;
07356                                 }
07357                         }
07358                         // make sure we never add a favorite server twice
07359                         if (ui_netSource.integer == AS_FAVORITES) {
07360                                 UI_RemoveServerFromDisplayList(i);
07361                         }
07362                         // insert the server into the list
07363                         UI_BinaryServerInsertion(i);
07364                         // done with this server
07365                         if (ping > 0) {
07366                                 trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
07367                                 numinvisible++;
07368                         }
07369                 }
07370         }
07371 
07372         uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime;
07373 
07374         // if there were no servers visible for ping updates
07375 //      if (!visible) {
07376 //              UI_StopServerRefresh();
07377 //              uiInfo.serverStatus.nextDisplayRefresh = 0;
07378 //      }
07379 }
07380 
07381 typedef struct
07382 {
07383         char *name, *altName;
07384 } serverStatusCvar_t;
07385 
07386 serverStatusCvar_t serverStatusCvars[] = {
07387         {"sv_hostname", "Name"},
07388         {"Address", ""},
07389         {"gamename", "Game name"},
07390         {"g_gametype", "Game type"},
07391         {"mapname", "Map"},
07392         {"version", ""},
07393         {"protocol", ""},
07394         {"timelimit", ""},
07395         {"fraglimit", ""},
07396         {NULL, NULL}
07397 };
07398 
07399 /*
07400 ==================
07401 UI_SortServerStatusInfo
07402 ==================
07403 */
07404 static void UI_SortServerStatusInfo( serverStatusInfo_t *info ) {
07405         int i, j, index;
07406         char *tmp1, *tmp2;
07407 
07408         // FIXME: if "gamename" == "base" or "missionpack" then
07409         // replace the gametype number by FFA, CTF etc.
07410         //
07411         index = 0;
07412         for (i = 0; serverStatusCvars[i].name; i++) {
07413                 for (j = 0; j < info->numLines; j++) {
07414                         if ( !info->lines[j][1] || info->lines[j][1][0] ) {
07415                                 continue;
07416                         }
07417                         if ( !Q_stricmp(serverStatusCvars[i].name, info->lines[j][0]) ) {
07418                                 // swap lines
07419                                 tmp1 = info->lines[index][0];
07420                                 tmp2 = info->lines[index][3];
07421                                 info->lines[index][0] = info->lines[j][0];
07422                                 info->lines[index][3] = info->lines[j][3];
07423                                 info->lines[j][0] = tmp1;
07424                                 info->lines[j][3] = tmp2;
07425                                 //
07426                                 if ( strlen(serverStatusCvars[i].altName) ) {
07427                                         info->lines[index][0] = serverStatusCvars[i].altName;
07428                                 }
07429                                 index++;
07430                         }
07431                 }
07432         }
07433 }
07434 
07435 
07436 /*
07437 ==================
07438 UI_CheckPassword
07439 ==================
07440 */
07441 static qboolean UI_CheckPassword( void )
07442 {
07443         static char info[MAX_STRING_CHARS];
07444         
07445         int index = uiInfo.serverStatus.currentServer;
07446         if( (index < 0) || (index >= uiInfo.serverStatus.numDisplayServers) )
07447         {       // warning?
07448                 return qfalse;
07449         }
07450         
07451         trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
07452 
07453         if ( atoi(Info_ValueForKey(info, "needpass")) )
07454         {
07455 
07456                 Menus_OpenByName("password_request");
07457                 return qfalse;
07458                 
07459         }
07460 
07461         // This isn't going to make it (too late in dev), like James said I should check to see when we receive
07462         // a packet *if* we do indeed get a 0 ping just make it 1 so then a 0 ping is guaranteed to be bad
07463         /*
07464         // also check ping!
07465     ping = atoi(Info_ValueForKey(info, "ping"));
07466         // NOTE : PING -- it's very questionable as to whether a ping of < 0 or <= 0 indicates a bad server
07467         // what I do know, is that getting "ping" from the ServerInfo on a bad server returns 0.
07468         // So I'm left with no choice but to not allow you to enter a server with a ping of 0
07469         if( ping <= 0 )
07470         {
07471                 Menus_OpenByName("bad_server");
07472                 return qfalse;
07473         }
07474         */
07475 
07476 
07477         return qtrue;
07478         
07479 
07480 }
07481 
07482 /*
07483 ==================
07484 UI_JoinServer
07485 ==================
07486 */
07487 static void UI_JoinServer( void )
07488 {
07489         char buff[1024];
07490 
07491         trap_Cvar_Set("cg_thirdPerson", "0");
07492         trap_Cvar_Set("cg_cameraOrbit", "0");
07493         trap_Cvar_Set("ui_singlePlayerActive", "0");
07494 #ifdef _XBOX
07495         if (logged_on)
07496         { // Live server
07497                 XBL_MM_JoinServer( uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer] );
07498         }
07499         else
07500         { // System link
07501                 SysLink_JoinServer( uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer] );
07502         }
07503 #else
07504         if (uiInfo.serverStatus.currentServer >= 0 && uiInfo.serverStatus.currentServer < uiInfo.serverStatus.numDisplayServers)
07505         {
07506                 trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, 1024);
07507                 trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) );
07508         }
07509 #endif
07510         
07511 }
07512 
07513 
07514 
07515 /*
07516 ==================
07517 UI_CheckServerName
07518 ==================
07519 */
07520 static void UI_CheckServerName( void )
07521 {
07522         qboolean        changed = qfalse;
07523         
07524         char hostname[MAX_INFO_STRING];
07525         char *c = hostname;
07526                         
07527         trap_Cvar_VariableStringBuffer( "sv_hostname", hostname, MAX_INFO_STRING );
07528         
07529         while( *c )
07530         {
07531                 if ( (*c == '\\') || (*c == ';') || (*c == '"'))
07532                 {
07533                         *c = '.';
07534                         changed = qtrue;
07535                 }
07536                 c++;
07537         }
07538         if( changed )
07539         {
07540                 trap_Cvar_Set("sv_hostname", hostname );
07541         }
07542         
07543 }
07544 
07545 
07546 /*
07547 ==================
07548 UI_GetServerStatusInfo
07549 ==================
07550 */
07551 static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) {
07552         char *p, *score, *ping, *name;
07553         int i, len;
07554 
07555         if (!info) {
07556                 trap_LAN_ServerStatus( serverAddress, NULL, 0);
07557                 return qfalse;
07558         }
07559         memset(info, 0, sizeof(*info));
07560         if ( trap_LAN_ServerStatus( serverAddress, info->text, sizeof(info->text)) ) {
07561                 Q_strncpyz(info->address, serverAddress, sizeof(info->address));
07562                 p = info->text;
07563                 info->numLines = 0;
07564                 info->lines[info->numLines][0] = "Address";
07565                 info->lines[info->numLines][1] = "";
07566                 info->lines[info->numLines][2] = "";
07567                 info->lines[info->numLines][3] = info->address;
07568                 info->numLines++;
07569                 // get the cvars
07570                 while (p && *p) {
07571                         p = strchr(p, '\\');
07572                         if (!p) break;
07573                         *p++ = '\0';
07574                         if (*p == '\\')
07575                                 break;
07576                         info->lines[info->numLines][0] = p;
07577                         info->lines[info->numLines][1] = "";
07578                         info->lines[info->numLines][2] = "";
07579                         p = strchr(p, '\\');
07580                         if (!p) break;
07581                         *p++ = '\0';
07582                         info->lines[info->numLines][3] = p;
07583 
07584                         info->numLines++;
07585                         if (info->numLines >= MAX_SERVERSTATUS_LINES)
07586                                 break;
07587                 }
07588                 // get the player list
07589                 if (info->numLines < MAX_SERVERSTATUS_LINES-3) {
07590                         // empty line
07591                         info->lines[info->numLines][0] = "";
07592                         info->lines[info->numLines][1] = "";
07593                         info->lines[info->numLines][2] = "";
07594                         info->lines[info->numLines][3] = "";
07595                         info->numLines++;
07596                         // header
07597                         info->lines[info->numLines][0] = "num";
07598                         info->lines[info->numLines][1] = "score";
07599                         info->lines[info->numLines][2] = "ping";
07600                         info->lines[info->numLines][3] = "name";
07601                         info->numLines++;
07602                         // parse players
07603                         i = 0;
07604                         len = 0;
07605                         while (p && *p) {
07606                                 if (*p == '\\')
07607                                         *p++ = '\0';
07608                                 if (!p)
07609                                         break;
07610                                 score = p;
07611                                 p = strchr(p, ' ');
07612                                 if (!p)
07613                                         break;
07614                                 *p++ = '\0';
07615                                 ping = p;
07616                                 p = strchr(p, ' ');
07617                                 if (!p)
07618                                         break;
07619                                 *p++ = '\0';
07620                                 name = p;
07621                                 Com_sprintf(&info->pings[len], sizeof(info->pings)-len, "%d", i);
07622                                 info->lines[info->numLines][0] = &info->pings[len];
07623                                 len += strlen(&info->pings[len]) + 1;
07624                                 info->lines[info->numLines][1] = score;
07625                                 info->lines[info->numLines][2] = ping;
07626                                 info->lines[info->numLines][3] = name;
07627                                 info->numLines++;
07628                                 if (info->numLines >= MAX_SERVERSTATUS_LINES)
07629                                         break;
07630                                 p = strchr(p, '\\');
07631                                 if (!p)
07632                                         break;
07633                                 *p++ = '\0';
07634                                 //
07635                                 i++;
07636                         }
07637                 }
07638                 UI_SortServerStatusInfo( info );
07639                 return qtrue;
07640         }
07641         return qfalse;
07642 }
07643 
07644 /*
07645 ==================
07646 stristr
07647 ==================
07648 */
07649 static char *stristr(char *str, char *charset) {
07650         int i;
07651 
07652         while(*str) {
07653                 for (i = 0; charset[i] && str[i]; i++) {
07654                         if (toupper(charset[i]) != toupper(str[i])) break;
07655                 }
07656                 if (!charset[i]) return str;
07657                 str++;
07658         }
07659         return NULL;
07660 }
07661 
07662 /*
07663 ==================
07664 UI_BuildFindPlayerList
07665 ==================
07666 */
07667 static void UI_BuildFindPlayerList(qboolean force) {
07668         static int numFound, numTimeOuts;
07669         int i, j, resend;
07670         serverStatusInfo_t info;
07671         char name[MAX_NAME_LENGTH+2];
07672         char infoString[MAX_STRING_CHARS];
07673 
07674         if (!force) {
07675                 if (!uiInfo.nextFindPlayerRefresh || uiInfo.nextFindPlayerRefresh > uiInfo.uiDC.realTime) {
07676                         return;
07677                 }
07678         }
07679         else {
07680                 memset(&uiInfo.pendingServerStatus, 0, sizeof(uiInfo.pendingServerStatus));
07681                 uiInfo.numFoundPlayerServers = 0;
07682                 uiInfo.currentFoundPlayerServer = 0;
07683                 trap_Cvar_VariableStringBuffer( "ui_findPlayer", uiInfo.findPlayerName, sizeof(uiInfo.findPlayerName));
07684                 Q_CleanStr(uiInfo.findPlayerName);
07685                 // should have a string of some length
07686                 if (!strlen(uiInfo.findPlayerName)) {
07687                         uiInfo.nextFindPlayerRefresh = 0;
07688                         return;
07689                 }
07690                 // set resend time
07691                 resend = ui_serverStatusTimeOut.integer / 2 - 10;
07692                 if (resend < 50) {
07693                         resend = 50;
07694                 }
07695                 trap_Cvar_Set("cl_serverStatusResendTime", va("%d", resend));
07696                 // reset all server status requests
07697                 trap_LAN_ServerStatus( NULL, NULL, 0);
07698                 //
07699                 uiInfo.numFoundPlayerServers = 1;
07700 
07701                 trap_SP_GetStringTextString("MENUS_SEARCHING", holdSPString, sizeof(holdSPString));
07702                                 trap_Cvar_Set( "ui_playerServersFound", va(     holdSPString,uiInfo.pendingServerStatus.num, numFound));
07703         //      Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
07704         //                                      sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
07705         //                                              "searching %d...", uiInfo.pendingServerStatus.num);
07706                 numFound = 0;
07707                 numTimeOuts++;
07708         }
07709         for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
07710                 // if this pending server is valid
07711                 if (uiInfo.pendingServerStatus.server[i].valid) {
07712                         // try to get the server status for this server
07713                         if (UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, &info ) ) {
07714                                 //
07715                                 numFound++;
07716                                 // parse through the server status lines
07717                                 for (j = 0; j < info.numLines; j++) {
07718                                         // should have ping info
07719                                         if ( !info.lines[j][2] || !info.lines[j][2][0] ) {
07720                                                 continue;
07721                                         }
07722                                         // clean string first
07723                                         Q_strncpyz(name, info.lines[j][3], sizeof(name));
07724                                         Q_CleanStr(name);
07725                                         // if the player name is a substring
07726                                         if (stristr(name, uiInfo.findPlayerName)) {
07727                                                 // add to found server list if we have space (always leave space for a line with the number found)
07728                                                 if (uiInfo.numFoundPlayerServers < MAX_FOUNDPLAYER_SERVERS-1) {
07729                                                         //
07730                                                         Q_strncpyz(uiInfo.foundPlayerServerAddresses[uiInfo.numFoundPlayerServers-1],
07731                                                                                 uiInfo.pendingServerStatus.server[i].adrstr,
07732                                                                                         sizeof(uiInfo.foundPlayerServerAddresses[0]));
07733                                                         Q_strncpyz(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
07734                                                                                 uiInfo.pendingServerStatus.server[i].name,
07735                                                                                         sizeof(uiInfo.foundPlayerServerNames[0]));
07736                                                         uiInfo.numFoundPlayerServers++;
07737                                                 }
07738                                                 else {
07739                                                         // can't add any more so we're done
07740                                                         uiInfo.pendingServerStatus.num = uiInfo.serverStatus.numDisplayServers;
07741                                                 }
07742                                         }
07743                                 }
07744 
07745                                 trap_SP_GetStringTextString("MENUS_SEARCHING", holdSPString, sizeof(holdSPString));
07746                                 trap_Cvar_Set( "ui_playerServersFound", va(     holdSPString,uiInfo.pendingServerStatus.num, numFound));
07747                         //      Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
07748                         //                                      sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
07749                         //                                              "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound);
07750                                 // retrieved the server status so reuse this spot
07751                                 uiInfo.pendingServerStatus.server[i].valid = qfalse;
07752                         }
07753                 }
07754                 // if empty pending slot or timed out
07755                 if (!uiInfo.pendingServerStatus.server[i].valid ||
07756                         uiInfo.pendingServerStatus.server[i].startTime < uiInfo.uiDC.realTime - ui_serverStatusTimeOut.integer) {
07757                         if (uiInfo.pendingServerStatus.server[i].valid) {
07758                                 numTimeOuts++;
07759                         }
07760                         // reset server status request for this address
07761                         UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, NULL );
07762                         // reuse pending slot
07763                         uiInfo.pendingServerStatus.server[i].valid = qfalse;
07764                         // if we didn't try to get the status of all servers in the main browser yet
07765                         if (uiInfo.pendingServerStatus.num < uiInfo.serverStatus.numDisplayServers) {
07766                                 uiInfo.pendingServerStatus.server[i].startTime = uiInfo.uiDC.realTime;
07767                                 trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num],
07768                                                         uiInfo.pendingServerStatus.server[i].adrstr, sizeof(uiInfo.pendingServerStatus.server[i].adrstr));
07769                                 trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], infoString, sizeof(infoString));
07770                                 Q_strncpyz(uiInfo.pendingServerStatus.server[i].name, Info_ValueForKey(infoString, "hostname"), sizeof(uiInfo.pendingServerStatus.server[0].name));
07771                                 uiInfo.pendingServerStatus.server[i].valid = qtrue;
07772                                 uiInfo.pendingServerStatus.num++;
07773 
07774                                 trap_SP_GetStringTextString("MENUS_SEARCHING", holdSPString, sizeof(holdSPString));
07775                                 trap_Cvar_Set( "ui_playerServersFound", va(     holdSPString,uiInfo.pendingServerStatus.num, numFound));
07776                                                                                                                 
07777                         //      Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
07778                         //                                      sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
07779                         //                                              "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound);
07780                         }
07781                 }
07782         }
07783         for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
07784                 if (uiInfo.pendingServerStatus.server[i].valid) {
07785                         break;
07786                 }
07787         }
07788         // if still trying to retrieve server status info
07789         if (i < MAX_SERVERSTATUSREQUESTS) {
07790                 uiInfo.nextFindPlayerRefresh = uiInfo.uiDC.realTime + 25;
07791         }
07792         else {
07793                 // add a line that shows the number of servers found
07794                 if (!uiInfo.numFoundPlayerServers) 
07795                 {
07796                         Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]), "no servers found");
07797                 }
07798                 else 
07799                 {
07800                         trap_SP_GetStringTextString("MENUS_SERVERS_FOUNDWITH", holdSPString, sizeof(holdSPString));
07801                         trap_Cvar_Set( "ui_playerServersFound", va(     holdSPString,
07802                                                                                                                 uiInfo.numFoundPlayerServers-1,
07803                                                                                                                 uiInfo.numFoundPlayerServers == 2 ? "":"s",
07804                                                                                                                 uiInfo.findPlayerName) );
07805                 }
07806                 uiInfo.nextFindPlayerRefresh = 0;
07807                 // show the server status info for the selected server
07808                 UI_FeederSelection(FEEDER_FINDPLAYER, uiInfo.currentFoundPlayerServer, NULL);
07809         }
07810 }
07811 
07812 /*
07813 ==================
07814 UI_BuildServerStatus
07815 ==================
07816 */
07817 static void UI_BuildServerStatus(qboolean force) {
07818 
07819         if (uiInfo.nextFindPlayerRefresh) {
07820                 return;
07821         }
07822         if (!force) {
07823                 if (!uiInfo.nextServerStatusRefresh || uiInfo.nextServerStatusRefresh > uiInfo.uiDC.realTime) {
07824                         return;
07825                 }
07826         }
07827         else {
07828                 Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
07829                 uiInfo.serverStatusInfo.numLines = 0;
07830                 // reset all server status requests
07831                 trap_LAN_ServerStatus( NULL, NULL, 0);
07832         }
07833         if (uiInfo.serverStatus.currentServer < 0 || uiInfo.serverStatus.currentServer > uiInfo.serverStatus.numDisplayServers || uiInfo.serverStatus.numDisplayServers == 0) {
07834                 return;
07835         }
07836         if (UI_GetServerStatusInfo( uiInfo.serverStatusAddress, &uiInfo.serverStatusInfo ) ) {
07837                 uiInfo.nextServerStatusRefresh = 0;
07838                 UI_GetServerStatusInfo( uiInfo.serverStatusAddress, NULL );
07839         }
07840         else {
07841                 uiInfo.nextServerStatusRefresh = uiInfo.uiDC.realTime + 500;
07842         }
07843 }
07844 
07845 int UI_SiegeClassNum(siegeClass_t *scl)
07846 {
07847         int i = 0;
07848 
07849         while (i < bgNumSiegeClasses)
07850         {
07851                 if (&bgSiegeClasses[i] == scl)
07852                 {
07853                         return i;
07854                 }
07855                 i++;
07856         }
07857 
07858         return 0;
07859 }
07860 
07861 void UI_SetSiegeTeams(void)
07862 {
07863         char                    info[MAX_INFO_VALUE];
07864         char                    *mapname = NULL;
07865         char                    levelname[MAX_QPATH];
07866         char                    btime[1024];
07867         char                    teams[2048];
07868         char                    teamInfo[MAX_SIEGE_INFO_SIZE];
07869         char                    team1[1024];
07870         char                    team2[1024];
07871         int                             len = 0;
07872         int                             gametype;
07873         fileHandle_t    f;
07874 
07875         //Get the map name from the server info
07876         if (trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ))
07877         {
07878                 mapname = Info_ValueForKey( info, "mapname" );
07879         }
07880 
07881         if (!mapname || !mapname[0])
07882         {
07883                 return;
07884         }
07885 
07886         gametype = atoi(Info_ValueForKey(info, "g_gametype"));
07887 
07888         //If the server we are connected to is not siege we cannot choose a class anyway
07889         if (gametype != GT_SIEGE)
07890         {
07891                 return;
07892         }
07893 
07894         Com_sprintf(levelname, sizeof(levelname), "maps/%s.siege", mapname);
07895 
07896         if (!levelname || !levelname[0])
07897         {
07898                 return;
07899         }
07900 
07901         len = trap_FS_FOpenFile(levelname, &f, FS_READ);
07902 
07903         if (!f || len >= MAX_SIEGE_INFO_SIZE)
07904         {
07905                 return;
07906         }
07907 
07908         trap_FS_Read(siege_info, len, f);
07909         siege_info[len] = 0;    //ensure null terminated
07910 
07911         trap_FS_FCloseFile(f);
07912 
07913         //Found the .siege file
07914 
07915         if (BG_SiegeGetValueGroup(siege_info, "Teams", teams))
07916         {
07917                 char buf[1024];
07918 
07919                 trap_Cvar_VariableStringBuffer("cg_siegeTeam1", buf, 1024);
07920                 if (buf[0] && Q_stricmp(buf, "none"))
07921                 {
07922                         strcpy(team1, buf);
07923                 }
07924                 else
07925                 {
07926                         BG_SiegeGetPairedValue(teams, "team1", team1);
07927                 }
07928 
07929                 trap_Cvar_VariableStringBuffer("cg_siegeTeam2", buf, 1024);
07930                 if (buf[0] && Q_stricmp(buf, "none"))
07931                 {
07932                         strcpy(team2, buf);
07933                 }
07934                 else
07935                 {
07936                         BG_SiegeGetPairedValue(teams, "team2", team2);
07937                 }
07938         }
07939         else
07940         {
07941                 return;
07942         }
07943 
07944         //Set the team themes so we know what classes to make available for selection
07945         if (BG_SiegeGetValueGroup(siege_info, team1, teamInfo))
07946         {
07947                 if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
07948                 {
07949                         BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, btime);
07950                 }
07951         }
07952         if (BG_SiegeGetValueGroup(siege_info, team2, teamInfo))
07953         {
07954                 if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
07955                 {
07956                         BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, btime);
07957                 }
07958         }
07959 
07960         siegeTeam1 = BG_SiegeFindThemeForTeam(SIEGETEAM_TEAM1);
07961         siegeTeam2 = BG_SiegeFindThemeForTeam(SIEGETEAM_TEAM2);
07962 
07963         //set the default description for the default selection
07964         if (!siegeTeam1 || !siegeTeam1->classes[0])
07965         {
07966                 Com_Error(ERR_DROP, "Error loading teams in UI");
07967         }
07968 
07969         Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM1, 0, NULL);
07970         Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM2, -1, NULL);
07971 }
07972 
07973 /*
07974 ==================
07975 UI_FeederCount
07976 ==================
07977 */
07978 static int UI_FeederCount(float feederID) 
07979 {
07980         int team,baseClass,count=0,i; 
07981         static char info[MAX_STRING_CHARS];
07982         
07983         switch ( (int)feederID )
07984         {
07985 
07986                 case FEEDER_SABER_SINGLE_INFO:
07987 
07988                         for (i=0;i<MAX_SABER_HILTS;i++)
07989                         {
07990                                 if (saberSingleHiltInfo[i])
07991                                 {
07992                                         count++;
07993                                 }
07994                                 else
07995                                 {//done
07996                                         break;
07997                                 }
07998                         }
07999                         return count;
08000 
08001                 case FEEDER_SABER_STAFF_INFO:
08002 
08003                         for (i=0;i<MAX_SABER_HILTS;i++)
08004                         {
08005                                 if (saberStaffHiltInfo[i])
08006                                 {
08007                                         count++;
08008                                 }
08009                                 else
08010                                 {//done
08011                                         break;
08012                                 }
08013                         }
08014                         return count;
08015 
08016                 case FEEDER_Q3HEADS:
08017                         return UI_HeadCountByColor();
08018 
08019                 case FEEDER_SIEGE_TEAM1:
08020                         if (!siegeTeam1)
08021                         {
08022                                 UI_SetSiegeTeams();
08023                                 if (!siegeTeam1)
08024                                 {
08025                                         return 0;
08026                                 }
08027                         }
08028                         return siegeTeam1->numClasses;
08029                 case FEEDER_SIEGE_TEAM2:
08030                         if (!siegeTeam2)
08031                         {
08032                                 UI_SetSiegeTeams();
08033                                 if (!siegeTeam2)
08034                                 {
08035                                         return 0;
08036                                 }
08037                         }
08038                         return siegeTeam2->numClasses;
08039 
08040                 case FEEDER_FORCECFG:
08041                         if (uiForceSide == FORCE_LIGHTSIDE)
08042                         {
08043                                 return uiInfo.forceConfigCount-uiInfo.forceConfigLightIndexBegin;
08044                         }
08045                         else
08046                         {
08047                                 return uiInfo.forceConfigLightIndexBegin+1;
08048                         }
08049                         //return uiInfo.forceConfigCount;
08050 
08051                 case FEEDER_CINEMATICS:
08052                         return uiInfo.movieCount;
08053 
08054                 case FEEDER_MAPS:
08055                 case FEEDER_ALLMAPS:
08056                         return UI_MapCountByGameType(feederID == FEEDER_MAPS ? qtrue : qfalse);
08057         
08058                 case FEEDER_SERVERS:
08059                         return uiInfo.serverStatus.numDisplayServers;
08060         
08061                 case FEEDER_SERVERSTATUS:
08062                         return uiInfo.serverStatusInfo.numLines;
08063         
08064                 case FEEDER_FINDPLAYER:
08065                         return uiInfo.numFoundPlayerServers;
08066 
08067                 case FEEDER_PLAYER_LIST:
08068                         if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) 
08069                         {
08070                                 uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
08071                                 UI_BuildPlayerList();
08072                         }
08073                         return uiInfo.playerCount;
08074 
08075                 case FEEDER_TEAM_LIST:
08076                         if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) 
08077                         {
08078                                 uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
08079                                 UI_BuildPlayerList();
08080                         }
08081                         return uiInfo.myTeamCount;
08082 
08083                 case FEEDER_MODS:
08084                         return uiInfo.modCount;
08085         
08086                 case FEEDER_DEMOS:
08087                         return uiInfo.demoCount;
08088 
08089                 case FEEDER_MOVES :
08090 
08091                         for (i=0;i<MAX_MOVES;i++)
08092                         {
08093                                 if (datapadMoveData[uiInfo.movesTitleIndex][i].title)
08094                                 {
08095                                         count++;
08096                                 }
08097                         }
08098 
08099                         return count;
08100 
08101                 case FEEDER_MOVES_TITLES :
08102                         return (MD_MOVE_TITLE_MAX);
08103 
08104                 case FEEDER_PLAYER_SPECIES:
08105                         return uiInfo.playerSpeciesCount;
08106 
08107                 case FEEDER_PLAYER_SKIN_HEAD:
08108                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount;
08109 
08110                 case FEEDER_PLAYER_SKIN_TORSO:
08111                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount;
08112 
08113                 case FEEDER_PLAYER_SKIN_LEGS:
08114                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount;
08115 
08116                 case FEEDER_COLORCHOICES:
08117                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount;
08118 
08119                 case FEEDER_SIEGE_BASE_CLASS:           
08120                         team = (int)trap_Cvar_VariableValue("ui_team");
08121                         baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
08122 
08123                         if ((team == SIEGETEAM_TEAM1) || 
08124                                 (team == SIEGETEAM_TEAM2)) 
08125                         {
08126                                 // Is it a valid base class?
08127                                 if ((baseClass >= SPC_INFANTRY) && (baseClass < SPC_MAX))
08128                                 {
08129                                         return (BG_SiegeCountBaseClass( team, baseClass ));
08130                                 }
08131                         }
08132                         return 0;
08133 
08134                 // Get the count of weapons
08135                 case FEEDER_SIEGE_CLASS_WEAPONS:        
08136                         //count them up
08137                         for (i=0;i< WP_NUM_WEAPONS;i++)
08138                         {
08139                                 trap_Cvar_VariableStringBuffer( va("ui_class_weapon%i", i), info, sizeof(info) );
08140                                 if (stricmp(info,"gfx/2d/select")!=0)
08141                                 {
08142                                         count++;
08143                                 }
08144                         }
08145 
08146                         return count;
08147 
08148                 // Get the count of inventory
08149                 case FEEDER_SIEGE_CLASS_INVENTORY:      
08150                         //count them up
08151                         for (i=0;i< HI_NUM_HOLDABLE;i++)
08152                         {
08153                                 trap_Cvar_VariableStringBuffer( va("ui_class_item%i", i), info, sizeof(info) );
08154                                 // A hack so health and ammo dispenser icons don't show up.
08155                                 if ((stricmp(info,"gfx/2d/select")!=0) && (stricmp(info,"gfx/hud/i_icon_healthdisp")!=0) &&
08156                                         (stricmp(info,"gfx/hud/i_icon_ammodisp")!=0))
08157                                 {
08158                                         count++;
08159                                 }
08160                         }
08161                         return count;
08162 
08163                 // Get the count of force powers
08164                 case FEEDER_SIEGE_CLASS_FORCE:  
08165                         //count them up
08166                         for (i=0;i< NUM_FORCE_POWERS;i++)
08167                         {
08168                                 trap_Cvar_VariableStringBuffer( va("ui_class_power%i", i), info, sizeof(info) );
08169                                 if (stricmp(info,"gfx/2d/select")!=0)
08170                                 {
08171                                         count++;
08172                                 }
08173                         }
08174                         return count;
08175 
08176 #ifdef _XBOX
08177                 // Get the count of xbl accounts
08178                 case FEEDER_XBL_ACCOUNTS:
08179                         // VVFIXME - Again, SOF2 had all kinds of silliness here. Do we need it?
08180                         return XBL_GetNumAccounts( false );
08181 
08182                 // Number of active players, plus number in history list, plus one for divider
08183                 case FEEDER_XBL_PLAYERS:
08184                         return XBL_PL_GetNumPlayers() + 1;
08185 
08186                 // Number of friends
08187                 case FEEDER_XBL_FRIENDS:
08188                         return XBL_F_GetNumFriends();
08189 
08190                 // Number of results from an optimatch query
08191                 case FEEDER_XBL_SERVERS:
08192                         return XBL_MM_GetNumServers();
08193 #endif
08194         }
08195 
08196         return 0;
08197 }
08198 
08199 static const char *UI_SelectedMap(int index, int *actual) {
08200         int i, c;
08201         c = 0;
08202         *actual = 0;
08203 
08204         for (i = 0; i < uiInfo.mapCount; i++) {
08205                 if (uiInfo.mapList[i].active) {
08206                         if (c == index) {
08207                                 *actual = i;
08208                                 return uiInfo.mapList[i].mapName;
08209                         } else {
08210                                 c++;
08211                         }
08212                 }
08213         }
08214         return "";
08215 }
08216 
08217 /*
08218 ==================
08219 UI_HeadCountByColor
08220 ==================
08221 */
08222 static const char *UI_SelectedTeamHead(int index, int *actual) {
08223         char *teamname;
08224         int i,c=0;
08225 
08226         switch(uiSkinColor)
08227         {
08228                 case TEAM_BLUE:
08229                         teamname = "/blue";
08230                         break;
08231                 case TEAM_RED:
08232                         teamname = "/red";
08233                         break;
08234                 default:
08235                         teamname = "/default";
08236                         break;
08237         }
08238 
08239         // Count each head with this color
08240 
08241         for (i=0; i<uiInfo.q3HeadCount; i++)
08242         {
08243                 if (uiInfo.q3HeadNames[i] && strstr(uiInfo.q3HeadNames[i], teamname))
08244                 {
08245                         if (c==index)
08246                         {
08247                                 *actual = i;
08248                                 return uiInfo.q3HeadNames[i];
08249                         }
08250                         else
08251                         {
08252                                 c++;
08253                         }
08254                 }
08255         }
08256         return "";
08257 }
08258 
08259 
08260 static int UI_GetIndexFromSelection(int actual) {
08261         int i, c;
08262         c = 0;
08263         for (i = 0; i < uiInfo.mapCount; i++) {
08264                 if (uiInfo.mapList[i].active) {
08265                         if (i == actual) {
08266                                 return c;
08267                         }
08268                                 c++;
08269                 }
08270         }
08271   return 0;
08272 }
08273 
08274 static void UI_UpdatePendingPings() { 
08275         trap_LAN_ResetPings(ui_netSource.integer);
08276         uiInfo.serverStatus.refreshActive = qtrue;
08277         uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
08278 
08279 
08280 
08281 }
08282 
08283 static const char *UI_FeederItemText(float feederID, int index, int column, 
08284                                                                          qhandle_t *handle1, qhandle_t *handle2, qhandle_t *handle3) {
08285         static char info[MAX_STRING_CHARS]; // don't change this size without changing the sizes inside the SaberProperName calls
08286         static char hostname[1024];
08287         static char clientBuff[32];
08288         static char needPass[32];
08289         static int lastColumn = -1;
08290         static int lastTime = 0;
08291         *handle1 = *handle2 = *handle3 = -1;
08292 
08293         if (feederID == FEEDER_SABER_SINGLE_INFO)
08294         {
08295                 //char *saberProperName=0;
08296                 UI_SaberProperNameForSaber( saberSingleHiltInfo[index], info );
08297                 return info;
08298         }
08299         else if (feederID == FEEDER_SABER_STAFF_INFO)
08300         {
08301                 //char *saberProperName=0;
08302                 UI_SaberProperNameForSaber( saberStaffHiltInfo[index], info );
08303                 return info;
08304         }
08305         else if (feederID == FEEDER_Q3HEADS) {
08306                 int actual;
08307                 return UI_SelectedTeamHead(index, &actual);
08308         } 
08309         else if (feederID == FEEDER_SIEGE_TEAM1)
08310         {
08311                 return ""; //nothing I guess, the description part can cover this
08312                 /*
08313                 if (!siegeTeam1)
08314                 {
08315                         UI_SetSiegeTeams();
08316                         if (!siegeTeam1)
08317                         {
08318                                 return "";
08319                         }
08320                 }
08321 
08322                 if (siegeTeam1->classes[index])
08323                 {
08324                         return siegeTeam1->classes[index]->name;
08325                 }
08326                 return "";
08327                 */
08328         }
08329         else if (feederID == FEEDER_SIEGE_TEAM2)
08330         {
08331                 return ""; //nothing I guess, the description part can cover this
08332                 /*
08333                 if (!siegeTeam1)
08334                 {
08335                         UI_SetSiegeTeams();
08336                         if (!siegeTeam1)
08337                         {
08338                                 return "";
08339                         }
08340                 }
08341 
08342                 if (siegeTeam2->classes[index])
08343                 {
08344                         return siegeTeam2->classes[index]->name;
08345                 }
08346                 return "";
08347                 */
08348         }
08349         else if (feederID == FEEDER_FORCECFG) {
08350                 if (index >= 0 && index < uiInfo.forceConfigCount) {
08351                         if (index == 0)
08352                         { //always show "custom"
08353                                 return uiInfo.forceConfigNames[index];
08354                         }
08355                         else
08356                         {
08357                                 if (uiForceSide == FORCE_LIGHTSIDE)
08358                                 {
08359                                         index += uiInfo.forceConfigLightIndexBegin;
08360                                         if (index < 0)
08361                                         {
08362                                                 return NULL;
08363                                         }
08364                                         if (index >= uiInfo.forceConfigCount)
08365                                         {
08366                                                 return NULL;
08367                                         }
08368                                         return uiInfo.forceConfigNames[index];
08369                                 }
08370                                 else if (uiForceSide == FORCE_DARKSIDE)
08371                                 {
08372                                         index += uiInfo.forceConfigDarkIndexBegin;
08373                                         if (index < 0)
08374                                         {
08375                                                 return NULL;
08376                                         }
08377                                         if (index > uiInfo.forceConfigLightIndexBegin)
08378                                         { //dark gets read in before light
08379                                                 return NULL;
08380                                         }
08381                                         if (index >= uiInfo.forceConfigCount)
08382                                         {
08383                                                 return NULL;
08384                                         }
08385                                         return uiInfo.forceConfigNames[index];
08386                                 }
08387                                 else
08388                                 {
08389                                         return NULL;
08390                                 }
08391                         }
08392                 }
08393         } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) {
08394                 int actual;
08395                 return UI_SelectedMap(index, &actual);
08396         } else if (feederID == FEEDER_SERVERS) {
08397                 if (index >= 0 && index < uiInfo.serverStatus.numDisplayServers) {
08398                         int ping, game;
08399                         if (lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000) {
08400                                 trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
08401                                 lastColumn = column;
08402                                 lastTime = uiInfo.uiDC.realTime;
08403                         }
08404                         ping = atoi(Info_ValueForKey(info, "ping"));
08405                         if (ping == -1) {
08406                                 // if we ever see a ping that is out of date, do a server refresh
08407                                 // UI_UpdatePendingPings();
08408                         }
08409                         switch (column) {
08410                                 case SORT_HOST : 
08411                                         if (ping <= 0) {
08412                                                 return Info_ValueForKey(info, "addr");
08413                                         } else {
08414                                                 int gametype = 0;
08415                                                 //check for password
08416                                                 if ( atoi(Info_ValueForKey(info, "needpass")) )
08417                                                 {
08418                                                         *handle3 = uiInfo.uiDC.Assets.needPass;
08419                                                 }
08420                                                 //check for saberonly and restricted force powers
08421                                                 gametype = atoi(Info_ValueForKey(info, "gametype"));
08422                                                 if ( gametype != GT_JEDIMASTER )
08423                                                 {
08424                                                         qboolean saberOnly = qtrue;
08425                                                         qboolean restrictedForce = qfalse;
08426                                                         qboolean allForceDisabled = qfalse;
08427                                                         int wDisable, i = 0;
08428 
08429                                                         //check force
08430                                                         restrictedForce = atoi(Info_ValueForKey(info, "fdisable"));
08431                                                         if ( UI_AllForceDisabled( restrictedForce ) )
08432                                                         {//all force powers are disabled
08433                                                                 allForceDisabled = qtrue;
08434                                                                 *handle2 = uiInfo.uiDC.Assets.noForce;
08435                                                         }
08436                                                         else if ( restrictedForce )
08437                                                         {//at least one force power is disabled
08438                                                                 *handle2 = uiInfo.uiDC.Assets.forceRestrict;
08439                                                         }
08440                                                         
08441                                                         //check weaps
08442                                                         wDisable = atoi(Info_ValueForKey(info, "wdisable"));
08443 
08444                                                         while ( i < WP_NUM_WEAPONS )
08445                                                         {
08446                                                                 if ( !(wDisable & (1 << i)) && i != WP_SABER && i != WP_NONE )
08447                                                                 {
08448                                                                         saberOnly = qfalse;
08449                                                                 }
08450 
08451                                                                 i++;
08452                                                         }
08453                                                         if ( saberOnly )
08454                                                         {
08455                                                                 *handle1 = uiInfo.uiDC.Assets.saberOnly;
08456                                                         }
08457                                                         else if ( atoi(Info_ValueForKey(info, "truejedi")) != 0 )
08458                                                         {
08459                                                                 if ( gametype != GT_HOLOCRON 
08460                                                                         && gametype != GT_JEDIMASTER 
08461                                                                         && !saberOnly 
08462                                                                         && !allForceDisabled )
08463                                                                 {//truejedi is on and allowed in this mode
08464                                                                         *handle1 = uiInfo.uiDC.Assets.trueJedi;
08465                                                                 }
08466                                                         }
08467                                                 }
08468                                                 if ( ui_netSource.integer == AS_LOCAL ) {
08469                                                         Com_sprintf( hostname, sizeof(hostname), "%s [%s]",
08470                                                                                         Info_ValueForKey(info, "hostname"),
08471                                                                                         netnames[atoi(Info_ValueForKey(info, "nettype"))] );
08472                                                         return hostname;
08473                                                 }
08474                                                 else {
08475                                                         if (atoi(Info_ValueForKey(info, "sv_allowAnonymous")) != 0) {                           // anonymous server
08476                                                                 Com_sprintf( hostname, sizeof(hostname), "(A) %s",
08477                                                                                                 Info_ValueForKey(info, "hostname"));
08478                                                         } else {
08479                                                                 Com_sprintf( hostname, sizeof(hostname), "%s",
08480                                                                                                 Info_ValueForKey(info, "hostname"));
08481                                                         }
08482                                                         return hostname;
08483                                                 }
08484                                         }
08485                                 case SORT_MAP : 
08486                                         return Info_ValueForKey(info, "mapname");
08487                                 case SORT_CLIENTS : 
08488                                         Com_sprintf( clientBuff, sizeof(clientBuff), "%s (%s)", Info_ValueForKey(info, "clients"), Info_ValueForKey(info, "sv_maxclients"));
08489                                         return clientBuff;
08490                                 case SORT_GAME : 
08491                                         game = atoi(Info_ValueForKey(info, "gametype"));
08492                                         if (game >= 0 && game < numTeamArenaGameTypes) {
08493                                                 strcpy(needPass,teamArenaGameTypes[game]);
08494                                         } else {
08495                                                 if (ping <= 0)
08496                                                 {
08497                                                         strcpy(needPass,"Inactive");
08498                                                 }
08499                                                 strcpy(needPass,"Unknown");
08500                                         }
08501 
08502                                         return needPass;
08503                                 case SORT_PING : 
08504                                         if (ping <= 0) {
08505                                                 return "...";
08506                                         } else {
08507                                                 return Info_ValueForKey(info, "ping");
08508                                         }
08509                         }
08510                 }
08511         } else if (feederID == FEEDER_SERVERSTATUS) {
08512                 if ( index >= 0 && index < uiInfo.serverStatusInfo.numLines ) {
08513                         if ( column >= 0 && column < 4 ) {
08514                                 return uiInfo.serverStatusInfo.lines[index][column];
08515                         }
08516                 }
08517         } else if (feederID == FEEDER_FINDPLAYER) {
08518                 if ( index >= 0 && index < uiInfo.numFoundPlayerServers ) {
08519                         //return uiInfo.foundPlayerServerAddresses[index];
08520                         return uiInfo.foundPlayerServerNames[index];
08521                 }
08522         } else if (feederID == FEEDER_PLAYER_LIST) {
08523                 if (index >= 0 && index < uiInfo.playerCount) {
08524                         return uiInfo.playerNames[index];
08525                 }
08526         } else if (feederID == FEEDER_TEAM_LIST) {
08527                 if (index >= 0 && index < uiInfo.myTeamCount) {
08528                         return uiInfo.teamNames[index];
08529                 }
08530         } else if (feederID == FEEDER_MODS) {
08531                 if (index >= 0 && index < uiInfo.modCount) {
08532                         if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr) {
08533                                 return uiInfo.modList[index].modDescr;
08534                         } else {
08535                                 return uiInfo.modList[index].modName;
08536                         }
08537                 }
08538         } else if (feederID == FEEDER_CINEMATICS) {
08539                 if (index >= 0 && index < uiInfo.movieCount) {
08540                         return uiInfo.movieList[index];
08541                 }
08542         } else if (feederID == FEEDER_DEMOS) {
08543                 if (index >= 0 && index < uiInfo.demoCount) {
08544                         return uiInfo.demoList[index];
08545                 }
08546         } 
08547         else if (feederID == FEEDER_MOVES) 
08548         {
08549                 return datapadMoveData[uiInfo.movesTitleIndex][index].title;
08550         }
08551         else if (feederID == FEEDER_MOVES_TITLES) 
08552         {
08553                 return datapadMoveTitleData[index];
08554         }
08555         else if (feederID == FEEDER_PLAYER_SPECIES) 
08556         {
08557                 return uiInfo.playerSpecies[index].Name;
08558         } 
08559         else if (feederID == FEEDER_LANGUAGES) 
08560         {
08561                 return 0;
08562         } 
08563         else if (feederID == FEEDER_COLORCHOICES)
08564         {
08565                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount) 
08566                 {
08567                         *handle1 = trap_R_RegisterShaderNoMip( uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorShader[index]);
08568                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorShader[index];
08569                 }
08570         }
08571         else if (feederID == FEEDER_PLAYER_SKIN_HEAD)
08572         {
08573                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount) 
08574                 {
08575                         *handle1 = trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]));
08576                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index];
08577                 }
08578         }
08579         else if (feederID == FEEDER_PLAYER_SKIN_TORSO)
08580         {
08581                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount) 
08582                 {
08583                         *handle1 = trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index]));
08584                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index];
08585                 }
08586         }
08587         else if (feederID == FEEDER_PLAYER_SKIN_LEGS)
08588         {
08589                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount) 
08590                 {
08591                         *handle1 = trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index]));
08592                         return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index];
08593                 }
08594         }
08595         else if (feederID == FEEDER_SIEGE_BASE_CLASS)
08596         {
08597                 return ""; 
08598         }
08599         else if (feederID == FEEDER_SIEGE_CLASS_WEAPONS)
08600         {
08601                 return ""; 
08602         }
08603 #ifdef _XBOX
08604         else if (feederID == FEEDER_XBL_ACCOUNTS)
08605         {
08606                 // VVFIXME - SOF2 keeps track of old number of accounts, to force a
08607                 // refresh when someone yanks an MU. Probably necessary
08608                 int numAccounts = XBL_GetNumAccounts( false );
08609                 if (index >= 0 && index < numAccounts)
08610                 {
08611                         XONLINE_USER *pUser = XBL_GetUserInfo( index );
08612                         if (pUser)
08613                         {
08614                                 static char displayName[XONLINE_GAMERTAG_SIZE];
08615                                 strcpy( displayName, pUser->szGamertag );
08616                                 return displayName;
08617                         }
08618                 }
08619         }
08620         else if (feederID == FEEDER_XBL_PLAYERS)
08621         {
08622                 int numEntries = XBL_PL_GetNumPlayers() + 1;
08623 
08624                 if (index >= 0 && index < numEntries)
08625                 {
08626                         if (column == 0)
08627                                 return XBL_PL_GetPlayerName( index );
08628                         else if (column == 1)
08629                                 return XBL_PL_GetStatusIcon( index );
08630                         else if (column == 2)
08631                                 return XBL_PL_GetVoiceIcon( index );
08632                         else
08633                                 return "";
08634                 }
08635         }
08636         else if (feederID == FEEDER_XBL_FRIENDS)
08637         {
08638                 if (index >= 0 && index < XBL_F_GetNumFriends())
08639                 {
08640                         if (column == 0)
08641                                 return XBL_F_GetFriendName( index );
08642                         else if (column == 1)
08643                                 return XBL_F_GetStatusIcon( index );
08644                         else if (column == 2)
08645                                 return XBL_F_GetVoiceIcon( index );
08646                         else
08647                                 return "";
08648                 }
08649         }
08650         else if (feederID == FEEDER_XBL_SERVERS)
08651         {
08652                 // We handle the optimatch results listbox separately from the rest
08653                 // of the UI server browser code. It's just nasty otherwise.
08654                 if (index >= 0 && index < XBL_MM_GetNumServers())
08655                 {
08656                         switch (column)
08657                         {
08658                                 case SORT_HOST:
08659                                         return XBL_MM_GetServerName( index );
08660                                 case SORT_MAP:
08661                                         return XBL_MM_GetServerMap( index );
08662                                 case SORT_CLIENTS:
08663                                         return XBL_MM_GetServerClients( index );
08664                                 case SORT_GAME:
08665                                         return XBL_MM_GetServerGametype( index );
08666                                 case SORT_PING:
08667                                         return XBL_MM_GetServerPing( index );
08668                         }
08669                 }
08670         }
08671 #endif
08672 
08673         return "";
08674 }
08675 
08676 
08677 static qhandle_t UI_FeederItemImage(float feederID, int index) {
08678         int     validCnt,i;
08679         static char info[MAX_STRING_CHARS];
08680 
08681         if (feederID == FEEDER_SABER_SINGLE_INFO) 
08682         {
08683                 return 0;
08684         }
08685         else if (feederID == FEEDER_SABER_STAFF_INFO)
08686         {
08687                 return 0;
08688         }
08689         else if (feederID == FEEDER_Q3HEADS) 
08690         {
08691                 int actual;
08692                 UI_SelectedTeamHead(index, &actual);
08693                 index = actual;
08694 
08695                 if (index >= 0 && index < uiInfo.q3HeadCount)
08696                 { //we want it to load them as it draws them, like the TA feeder
08697                       //return uiInfo.q3HeadIcons[index];
08698                         int selModel = trap_Cvar_VariableValue("ui_selectedModelIndex");
08699 
08700                         if (selModel != -1)
08701                         {
08702                                 if (uiInfo.q3SelectedHead != selModel)
08703                                 {
08704                                         uiInfo.q3SelectedHead = selModel;
08705                                         //UI_FeederSelection(FEEDER_Q3HEADS, uiInfo.q3SelectedHead);
08706                                         Menu_SetFeederSelection(NULL, FEEDER_Q3HEADS, selModel, NULL);
08707                                 }
08708                         }
08709 
08710                         if (!uiInfo.q3HeadIcons[index])
08711                         { //this isn't the best way of doing this I guess, but I didn't want a whole seperate string array
08712                           //for storing shader names. I can't just replace q3HeadNames with the shader name, because we
08713                           //print what's in q3HeadNames and the icon name would look funny.
08714                                 char iconNameFromSkinName[256];
08715                                 int i = 0;
08716                                 int skinPlace;
08717 
08718                                 i = strlen(uiInfo.q3HeadNames[index]);
08719 
08720                                 while (uiInfo.q3HeadNames[index][i] != '/')
08721                                 {
08722                                         i--;
08723                                 }
08724 
08725                                 i++;
08726                                 skinPlace = i; //remember that this is where the skin name begins
08727 
08728                                 //now, build a full path out of what's in q3HeadNames, into iconNameFromSkinName
08729                                 Com_sprintf(iconNameFromSkinName, sizeof(iconNameFromSkinName), "models/players/%s", uiInfo.q3HeadNames[index]);
08730 
08731                                 i = strlen(iconNameFromSkinName);
08732 
08733                                 while (iconNameFromSkinName[i] != '/')
08734                                 {
08735                                         i--;
08736                                 }
08737                                 
08738                                 i++;
08739                                 iconNameFromSkinName[i] = 0; //terminate, and append..
08740                                 Q_strcat(iconNameFromSkinName, 256, "icon_");
08741 
08742                                 //and now, for the final step, append the skin name from q3HeadNames onto the end of iconNameFromSkinName
08743                                 i = strlen(iconNameFromSkinName);
08744 
08745                                 while (uiInfo.q3HeadNames[index][skinPlace])
08746                                 {
08747                                         iconNameFromSkinName[i] = uiInfo.q3HeadNames[index][skinPlace];
08748                                         i++;
08749                                         skinPlace++;
08750                                 }
08751                                 iconNameFromSkinName[i] = 0;
08752 
08753                                 //and now we are ready to register (thankfully this will only happen once)
08754                                 uiInfo.q3HeadIcons[index] = trap_R_RegisterShaderNoMip(iconNameFromSkinName);
08755                         }
08756                         return uiInfo.q3HeadIcons[index];
08757                 }
08758     }
08759         else if (feederID == FEEDER_SIEGE_TEAM1) 
08760         {
08761                 if (!siegeTeam1)
08762                 {
08763                         UI_SetSiegeTeams();
08764                         if (!siegeTeam1)
08765                         {
08766                                 return 0;
08767                         }
08768                 }
08769 
08770                 if (siegeTeam1->classes[index])
08771                 {
08772                         return siegeTeam1->classes[index]->uiPortraitShader;
08773                 }
08774                 return 0;
08775         }
08776         else if (feederID == FEEDER_SIEGE_TEAM2) 
08777         {
08778                 if (!siegeTeam2)
08779                 {
08780                         UI_SetSiegeTeams();
08781                         if (!siegeTeam2)
08782                         {
08783                                 return 0;
08784                         }
08785                 }
08786 
08787                 if (siegeTeam2->classes[index])
08788                 {
08789                         return siegeTeam2->classes[index]->uiPortraitShader;
08790                 }
08791                 return 0;
08792         }
08793         else if (feederID == FEEDER_ALLMAPS || feederID == FEEDER_MAPS) 
08794         {
08795                 int actual;
08796                 UI_SelectedMap(index, &actual);
08797                 index = actual;
08798                 if (index >= 0 && index < uiInfo.mapCount) {
08799                         if (uiInfo.mapList[index].levelShot == -1) {
08800                                 uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[index].imageName);
08801                         }
08802                         return uiInfo.mapList[index].levelShot;
08803                 }
08804         }
08805         else if (feederID == FEEDER_PLAYER_SKIN_HEAD) 
08806         {
08807                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount) 
08808                 {
08809                         //return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadIcons[index];
08810                         return trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]));
08811                 }
08812         } 
08813         else if (feederID == FEEDER_PLAYER_SKIN_TORSO) 
08814         {
08815                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount) 
08816                 {
08817                         //return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoIcons[index];
08818                         return trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index]));
08819                 }
08820         } 
08821         else if (feederID == FEEDER_PLAYER_SKIN_LEGS) 
08822         {
08823                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount) 
08824                 {
08825                         //return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegIcons[index];
08826                         return trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index]));
08827                 }
08828         } 
08829         else if (feederID == FEEDER_COLORCHOICES)
08830         {
08831                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount) 
08832                 {
08833                         return trap_R_RegisterShaderNoMip( uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorShader[index]);
08834                 }
08835         }
08836 
08837         else if ( feederID == FEEDER_SIEGE_BASE_CLASS)
08838         {
08839                 int team,baseClass; 
08840 
08841                 team = (int)trap_Cvar_VariableValue("ui_team");
08842                 baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
08843 
08844                 if ((team == SIEGETEAM_TEAM1) || 
08845                         (team == SIEGETEAM_TEAM2)) 
08846                 {
08847                         // Is it a valid base class?
08848                         if ((baseClass >= SPC_INFANTRY) && (baseClass < SPC_MAX))
08849                         {
08850                                 if (index >= 0) 
08851                                 {
08852                                         return(BG_GetUIPortrait(team, baseClass, index));
08853                                 }
08854                         }
08855                 }
08856         }
08857         else if ( feederID == FEEDER_SIEGE_CLASS_WEAPONS)
08858         {
08859                 validCnt = 0;
08860                 //count them up
08861                 for (i=0;i< WP_NUM_WEAPONS;i++)
08862                 {
08863                         trap_Cvar_VariableStringBuffer( va("ui_class_weapon%i", i), info, sizeof(info) );
08864                         if (stricmp(info,"gfx/2d/select")!=0)
08865                         {
08866                                 if (validCnt == index)
08867                                 {
08868                                         return(trap_R_RegisterShaderNoMip(info));
08869                                 }
08870                                 validCnt++;
08871                         }
08872                 }
08873         }
08874         else if ( feederID == FEEDER_SIEGE_CLASS_INVENTORY)
08875         {
08876                 validCnt = 0;
08877                 //count them up
08878                 for (i=0;i< HI_NUM_HOLDABLE;i++)
08879                 {
08880                         trap_Cvar_VariableStringBuffer( va("ui_class_item%i", i), info, sizeof(info) );
08881                         // A hack so health and ammo dispenser icons don't show up.
08882                         if ((stricmp(info,"gfx/2d/select")!=0) && (stricmp(info,"gfx/hud/i_icon_healthdisp")!=0) &&
08883                                 (stricmp(info,"gfx/hud/i_icon_ammodisp")!=0))
08884                         {
08885                                 if (validCnt == index)
08886                                 {
08887                                         return(trap_R_RegisterShaderNoMip(info));
08888                                 }
08889                                 validCnt++;
08890                         }
08891                 }
08892         }
08893         else if ( feederID == FEEDER_SIEGE_CLASS_FORCE)
08894         {
08895                 int slotI=0;
08896                 static char info2[MAX_STRING_CHARS];
08897                 menuDef_t *menu;
08898                 itemDef_t *item;
08899 
08900 
08901                 validCnt = 0;
08902 
08903 
08904                 menu = Menu_GetFocused();       // Get current menu
08905                 if (menu)
08906                 {
08907                         item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_force_feed");
08908                         if (item)
08909                         {
08910                                 listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
08911                                 if (listPtr)
08912                                 {
08913                                         slotI = listPtr->startPos;
08914                                 }
08915                         }
08916                 }
08917 
08918                 //count them up
08919                 for (i=0;i< NUM_FORCE_POWERS;i++)
08920                 {
08921                         trap_Cvar_VariableStringBuffer( va("ui_class_power%i", i), info, sizeof(info) );
08922                         if (stricmp(info,"gfx/2d/select")!=0)
08923                         {
08924                                 if (validCnt == index)
08925                                 {
08926                                         trap_Cvar_VariableStringBuffer( va("ui_class_powerlevel%i", validCnt), info2, sizeof(info2) );
08927 
08928                                         trap_Cvar_Set(va("ui_class_powerlevelslot%i", index-slotI), info2);
08929                                         return(trap_R_RegisterShaderNoMip(info));
08930                                 }
08931                                 validCnt++;
08932                         }
08933                 }
08934         }
08935 
08936   return 0;
08937 }
08938 
08939 
08940 
08941 //called every time a class is selected from a feeder, sets info
08942 //for shaders to be displayed in the menu about the class -rww
08943 extern qboolean UI_SaberTypeForSaber( const char *saberName, char *saberType );
08944 void UI_SiegeSetCvarsForClass(siegeClass_t *scl)
08945 {
08946         int i = 0;
08947         int count = 0;
08948         char shader[MAX_QPATH];
08949 
08950         //let's clear the things out first
08951         while (i < WP_NUM_WEAPONS)
08952         {
08953                 trap_Cvar_Set(va("ui_class_weapon%i", i), "gfx/2d/select");
08954                 i++;
08955         }
08956         //now for inventory items
08957         i = 0;
08958         while (i < HI_NUM_HOLDABLE)
08959         {
08960                 trap_Cvar_Set(va("ui_class_item%i", i), "gfx/2d/select");
08961                 i++;
08962         }
08963         //now for force powers
08964         i = 0;
08965         while (i < NUM_FORCE_POWERS)
08966         {
08967                 trap_Cvar_Set(va("ui_class_power%i", i), "gfx/2d/select");
08968                 i++;
08969         }
08970 
08971         //now health and armor
08972         trap_Cvar_Set("ui_class_health", "0");
08973         trap_Cvar_Set("ui_class_armor", "0");
08974 
08975         trap_Cvar_Set("ui_class_icon", "");
08976 
08977         if (!scl)
08978         { //no select?
08979                 return;
08980         }
08981 
08982         //set cvars for which weaps we have
08983         i = 0;
08984         trap_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
08985         while (i < WP_NUM_WEAPONS)
08986         {
08987 
08988                 if (scl->weapons & (1<<i))
08989                 {
08990 
08991                         if (i == WP_SABER)
08992                         { //we want to see what kind of saber they have, and set the cvar based on that
08993                                 char saberType[1024];
08994 
08995                                 if (scl->saber1[0] &&
08996                                         scl->saber2[0])
08997                                 {
08998                                         strcpy(saberType, "gfx/hud/w_icon_duallightsaber");
08999                                 } //fixme: need saber data access on ui to determine if staff, "gfx/hud/w_icon_saberstaff"
09000                                 else
09001                                 {
09002                                         char buf[1024];
09003                                         if (scl->saber1[0] && UI_SaberTypeForSaber(scl->saber1, buf))
09004                                         {
09005                                                 if ( !Q_stricmp( buf, "SABER_STAFF" ) )
09006                                                 {
09007                                                         strcpy(saberType, "gfx/hud/w_icon_saberstaff");
09008                                                 }
09009                                                 else
09010                                                 {
09011                                                         strcpy(saberType, "gfx/hud/w_icon_lightsaber");
09012                                                 }
09013                                         }
09014                                         else
09015                                         {
09016                                                 strcpy(saberType, "gfx/hud/w_icon_lightsaber");
09017                                         }
09018                                 }
09019 
09020                                 trap_Cvar_Set(va("ui_class_weapon%i", count), saberType);
09021                                 trap_Cvar_Set(va("ui_class_weapondesc%i", count), "@MENUS_AN_ELEGANT_WEAPON_FOR");
09022                                 count++;
09023                                 trap_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
09024                         }
09025                         else
09026                         {
09027                                 gitem_t *item = BG_FindItemForWeapon( i );
09028                                 trap_Cvar_Set(va("ui_class_weapon%i", count), item->icon);
09029                                 trap_Cvar_Set(va("ui_class_weapondesc%i", count), item->description);
09030                                 count++;
09031                                 trap_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
09032                         }
09033                 }
09034 
09035                 i++;
09036         }
09037 
09038         //now for inventory items
09039         i = 0;
09040         count = 0;
09041 
09042         while (i < HI_NUM_HOLDABLE)
09043         {
09044                 if (scl->invenItems & (1<<i))
09045                 {
09046                         gitem_t *item = BG_FindItemForHoldable(i);
09047                         trap_Cvar_Set(va("ui_class_item%i", count), item->icon);
09048                         trap_Cvar_Set(va("ui_class_itemdesc%i", count), item->description);
09049                         count++;
09050                 }
09051                 else
09052                 {
09053                         trap_Cvar_Set(va("ui_class_itemdesc%i", count), " ");
09054                 }
09055                 i++;
09056         }
09057 
09058         //now for force powers
09059         i = 0;
09060         count = 0;
09061 
09062         while (i < NUM_FORCE_POWERS)
09063         {
09064                 trap_Cvar_Set(va("ui_class_powerlevel%i", i), "0");     // Zero this out to start.
09065                 if (i<9)
09066                 {
09067                         trap_Cvar_Set(va("ui_class_powerlevelslot%i", i), "0"); // Zero this out to start.
09068                 }
09069 
09070                 if (scl->forcePowerLevels[i])
09071                 {
09072                         trap_Cvar_Set(va("ui_class_powerlevel%i", count), va("%i",scl->forcePowerLevels[i]));
09073                         trap_Cvar_Set(va("ui_class_power%i", count), HolocronIcons[i]);
09074                         count++;
09075                 }
09076 
09077                 i++;
09078         }
09079 
09080         //now health and armor
09081         trap_Cvar_Set("ui_class_health", va("%i", scl->maxhealth));
09082         trap_Cvar_Set("ui_class_armor", va("%i", scl->maxarmor));
09083         trap_Cvar_Set("ui_class_speed", va("%3.2f", scl->speed));
09084 
09085         //now get the icon path based on the shader index
09086         if (scl->classShader)
09087         {
09088                 trap_R_ShaderNameFromIndex(shader, scl->classShader);
09089         }
09090         else
09091         { //no shader
09092                 shader[0] = 0;
09093         }
09094         trap_Cvar_Set("ui_class_icon", shader);
09095 }
09096 
09097 int g_siegedFeederForcedSet = 0;
09098 
09099 void UI_UpdateCvarsForClass(const int team,const baseClass,const int index)
09100 {
09101         siegeClass_t *holdClass=0;
09102         char *holdBuf;
09103 
09104         // Is it a valid team
09105         if ((team == SIEGETEAM_TEAM1) || 
09106                 (team == SIEGETEAM_TEAM2)) 
09107         {
09108 
09109                 // Is it a valid base class?
09110                 if ((baseClass >= SPC_INFANTRY) && (baseClass < SPC_MAX))
09111                 {
09112                         // A valid index?
09113                         if ((index>=0) && (index < BG_SiegeCountBaseClass( team, baseClass )))
09114                         {
09115                                 if (!g_siegedFeederForcedSet)
09116                                 {
09117                                         holdClass = BG_GetClassOnBaseClass( team, baseClass, index);                                    
09118                                         if (holdClass)  //clicked a valid item
09119                                         {
09120                                                 g_UIGloballySelectedSiegeClass = UI_SiegeClassNum(holdClass);
09121                                                 trap_Cvar_Set("ui_classDesc", g_UIClassDescriptions[g_UIGloballySelectedSiegeClass].desc);
09122                                                 g_siegedFeederForcedSet = 1;
09123                                                 Menu_SetFeederSelection(NULL, FEEDER_SIEGE_BASE_CLASS, -1, NULL);
09124                                                 UI_SiegeSetCvarsForClass(holdClass);
09125 
09126                                                 holdBuf = BG_GetUIPortraitFile(team, baseClass, index);
09127                                                 if (holdBuf)
09128                                                 {
09129                                                         trap_Cvar_Set("ui_classPortrait",holdBuf);
09130                                                 }
09131                                         }
09132                                 }
09133                                 g_siegedFeederForcedSet = 0;
09134                         }
09135                         else
09136                         {
09137                                 trap_Cvar_Set("ui_classDesc", " ");
09138                         }
09139                 }
09140         }
09141 
09142 }
09143 
09144 
09145 qboolean UI_FeederSelection(float feederFloat, int index, itemDef_t *item) 
09146 {
09147         static char info[MAX_STRING_CHARS];
09148         const int feederID = feederFloat;
09149 
09150         if (feederID == FEEDER_Q3HEADS) 
09151         {
09152                 int actual;
09153                 UI_SelectedTeamHead(index, &actual);
09154                 uiInfo.q3SelectedHead = index;
09155                 trap_Cvar_Set("ui_selectedModelIndex", va("%i", index));
09156                 index = actual;
09157                 if (index >= 0 && index < uiInfo.q3HeadCount) 
09158                 {
09159                         trap_Cvar_Set( "model", uiInfo.q3HeadNames[index]);     //standard model
09160                         trap_Cvar_Set ( "char_color_red", "255" );                      //standard colors
09161                         trap_Cvar_Set ( "char_color_green", "255" );
09162                         trap_Cvar_Set ( "char_color_blue", "255" );
09163                 }
09164         } 
09165         else if (feederID == FEEDER_MOVES) 
09166         {
09167                 itemDef_t *item;
09168                 menuDef_t *menu;
09169                 modelDef_t *modelPtr;
09170 
09171                 menu = Menus_FindByName("rulesMenu_moves");
09172 
09173                 if (menu)
09174                 {
09175                         item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
09176                         if (item)
09177                         {
09178                                 modelPtr = (modelDef_t*)item->typeData;
09179                                 if (modelPtr)
09180                                 {
09181                                         char modelPath[MAX_QPATH];
09182                                         int animRunLength;
09183 
09184                                         ItemParse_model_g2anim_go( item,  datapadMoveData[uiInfo.movesTitleIndex][index].anim );
09185 
09186                                         Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
09187                                         ItemParse_asset_model_go( item, modelPath, &animRunLength );
09188                                         UI_UpdateCharacterSkin();
09189 
09190                                         uiInfo.moveAnimTime = uiInfo.uiDC.realTime + animRunLength;
09191 
09192                                         if (datapadMoveData[uiInfo.movesTitleIndex][index].anim)
09193                                         {
09194 
09195                                                 // Play sound for anim
09196                                                 if (datapadMoveData[uiInfo.movesTitleIndex][index].sound == MDS_FORCE_JUMP)
09197                                                 {
09198                                                         trap_S_StartLocalSound( uiInfo.uiDC.Assets.moveJumpSound, CHAN_LOCAL );
09199                                                 }
09200                                                 else if (datapadMoveData[uiInfo.movesTitleIndex][index].sound == MDS_ROLL)
09201                                                 {
09202                                                         trap_S_StartLocalSound( uiInfo.uiDC.Assets.moveRollSound, CHAN_LOCAL );
09203                                                 }
09204                                                 else if (datapadMoveData[uiInfo.movesTitleIndex][index].sound == MDS_SABER)
09205                                                 {
09206                                                         // Randomly choose one sound
09207                                                         int soundI = Q_irand( 1, 6 );
09208                                                         sfxHandle_t *soundPtr;
09209                                                         soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound1;
09210                                                         if (soundI == 2)
09211                                                         {
09212                                                                 soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound2;
09213                                                         }
09214                                                         else if (soundI == 3)
09215                                                         {
09216                                                                 soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound3;
09217                                                         }
09218                                                         else if (soundI == 4)
09219                                                         {
09220                                                                 soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound4;
09221                                                         }
09222                                                         else if (soundI == 5)
09223                                                         {
09224                                                                 soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound5;
09225                                                         }
09226                                                         else if (soundI == 6)
09227                                                         {
09228                                                                 soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound6;
09229                                                         }
09230 
09231                                                         trap_S_StartLocalSound( *soundPtr, CHAN_LOCAL );
09232                                                 }
09233 
09234                                                 if (datapadMoveData[uiInfo.movesTitleIndex][index].desc)
09235                                                 {
09236                                                         trap_Cvar_Set( "ui_move_desc", datapadMoveData[uiInfo.movesTitleIndex][index].desc);
09237                                                 }
09238                                         }
09239                                         UI_SaberAttachToChar( item );
09240                                 }
09241                         }
09242                 }
09243         } 
09244         else if (feederID == FEEDER_MOVES_TITLES) 
09245         {
09246                 itemDef_t *item;
09247                 menuDef_t *menu;
09248                 modelDef_t *modelPtr;
09249 
09250                 uiInfo.movesTitleIndex = index;
09251                 uiInfo.movesBaseAnim = datapadMoveTitleBaseAnims[uiInfo.movesTitleIndex];
09252                 menu = Menus_FindByName("rulesMenu_moves");
09253 
09254                 if (menu)
09255                 {
09256                         item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
09257                         if (item)
09258                         {
09259                                 modelPtr = (modelDef_t*)item->typeData;
09260                                 if (modelPtr)
09261                                 {
09262                                         char modelPath[MAX_QPATH];
09263                                         int     animRunLength;
09264 
09265                                         uiInfo.movesBaseAnim = datapadMoveTitleBaseAnims[uiInfo.movesTitleIndex];
09266                                         ItemParse_model_g2anim_go( item,  uiInfo.movesBaseAnim );
09267 
09268                                         Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
09269                                         ItemParse_asset_model_go( item, modelPath, &animRunLength );
09270 
09271                                         UI_UpdateCharacterSkin();
09272 
09273                                 }
09274                         }
09275                 }
09276         }
09277         else if (feederID == FEEDER_SIEGE_TEAM1)
09278         {
09279                 if (!g_siegedFeederForcedSet)
09280                 {
09281                         g_UIGloballySelectedSiegeClass = UI_SiegeClassNum(siegeTeam1->classes[index]);
09282                         trap_Cvar_Set("ui_classDesc", g_UIClassDescriptions[g_UIGloballySelectedSiegeClass].desc);
09283 
09284                         //g_siegedFeederForcedSet = 1;
09285                         //Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM2, -1, NULL);
09286 
09287                         UI_SiegeSetCvarsForClass(siegeTeam1->classes[index]);
09288                 }
09289                 g_siegedFeederForcedSet = 0;
09290         }
09291         else if (feederID == FEEDER_SIEGE_TEAM2)
09292         {
09293                 if (!g_siegedFeederForcedSet)
09294                 {
09295                         g_UIGloballySelectedSiegeClass = UI_SiegeClassNum(siegeTeam2->classes[index]);
09296                         trap_Cvar_Set("ui_classDesc", g_UIClassDescriptions[g_UIGloballySelectedSiegeClass].desc);
09297 
09298                         //g_siegedFeederForcedSet = 1;
09299                         //Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM2, -1, NULL);
09300 
09301                         UI_SiegeSetCvarsForClass(siegeTeam2->classes[index]);
09302                 }
09303                 g_siegedFeederForcedSet = 0;
09304         }
09305         else if (feederID == FEEDER_FORCECFG) 
09306         {
09307                 int newindex = index;
09308 
09309                 if (uiForceSide == FORCE_LIGHTSIDE)
09310                 {
09311                         newindex += uiInfo.forceConfigLightIndexBegin;
09312                         if (newindex >= uiInfo.forceConfigCount)
09313                         {
09314                                 return qfalse;
09315                         }
09316                 }
09317                 else
09318                 { //else dark
09319                         newindex += uiInfo.forceConfigDarkIndexBegin;
09320                         if (newindex >= uiInfo.forceConfigCount || newindex > uiInfo.forceConfigLightIndexBegin)
09321                         { //dark gets read in before light
09322                                 return qfalse;
09323                         }
09324                 }
09325 
09326                 if (index >= 0 && index < uiInfo.forceConfigCount) 
09327                 {
09328                                 UI_ForceConfigHandle(uiInfo.forceConfigSelected, index);
09329                                 uiInfo.forceConfigSelected = index;
09330                 }
09331         } 
09332         else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) 
09333         {
09334                 int actual, map;
09335                 const char *checkValid = NULL;
09336 
09337                 map = (feederID == FEEDER_ALLMAPS) ? ui_currentNetMap.integer : ui_currentMap.integer;
09338                 if (uiInfo.mapList[map].cinematic >= 0) {
09339                   trap_CIN_StopCinematic(uiInfo.mapList[map].cinematic);
09340                   uiInfo.mapList[map].cinematic = -1;
09341                 }
09342                 checkValid = UI_SelectedMap(index, &actual);
09343 
09344                 if (!checkValid || !checkValid[0])
09345                 { //this isn't a valid map to select, so reselect the current
09346                         index = ui_mapIndex.integer;
09347                         UI_SelectedMap(index, &actual);
09348                 }
09349 
09350                 trap_Cvar_Set("ui_mapIndex", va("%d", index));
09351                 gUISelectedMap = index;
09352                 ui_mapIndex.integer = index;
09353 
09354                 if (feederID == FEEDER_MAPS) {
09355                         ui_currentMap.integer = actual;
09356                         trap_Cvar_Set("ui_currentMap", va("%d", actual));
09357                 uiInfo.mapList[ui_currentMap.integer].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[ui_currentMap.integer].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
09358                         UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
09359                         //trap_Cvar_Set("ui_opponentModel", uiInfo.mapList[ui_currentMap.integer].opponentName);
09360                         //updateOpponentModel = qtrue;
09361                 } else {
09362                         ui_currentNetMap.integer = actual;
09363                         trap_Cvar_Set("ui_currentNetMap", va("%d", actual));
09364                 uiInfo.mapList[ui_currentNetMap.integer].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
09365                 }
09366 
09367         } else if (feederID == FEEDER_SERVERS) {
09368                 const char *mapName = NULL;
09369                 uiInfo.serverStatus.currentServer = index;
09370                 trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
09371                 uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip(va("levelshots/%s", Info_ValueForKey(info, "mapname")));
09372                 if (uiInfo.serverStatus.currentServerCinematic >= 0) {
09373                   trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
09374                         uiInfo.serverStatus.currentServerCinematic = -1;
09375                 }
09376                 mapName = Info_ValueForKey(info, "mapname");
09377                 if (mapName && *mapName) {
09378                         uiInfo.serverStatus.currentServerCinematic = trap_CIN_PlayCinematic(va("%s.roq", mapName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
09379                 }
09380         } else if (feederID == FEEDER_SERVERSTATUS) {
09381                 //
09382         } else if (feederID == FEEDER_FINDPLAYER) {
09383           uiInfo.currentFoundPlayerServer = index;
09384           //
09385           if ( index < uiInfo.numFoundPlayerServers-1) {
09386                         // build a new server status for this server
09387                         Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress));
09388                         Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
09389                         UI_BuildServerStatus(qtrue);
09390           }
09391         } else if (feederID == FEEDER_PLAYER_LIST) {
09392                 uiInfo.playerIndex = index;
09393         } else if (feederID == FEEDER_TEAM_LIST) {
09394                 uiInfo.teamIndex = index;
09395         } else if (feederID == FEEDER_MODS) {
09396                 uiInfo.modIndex = index;
09397         } else if (feederID == FEEDER_CINEMATICS) {
09398                 uiInfo.movieIndex = index;
09399                 if (uiInfo.previewMovie >= 0) {
09400                   trap_CIN_StopCinematic(uiInfo.previewMovie);
09401                 }
09402                 uiInfo.previewMovie = -1;
09403         } else if (feederID == FEEDER_DEMOS) {
09404                 uiInfo.demoIndex = index;
09405         }
09406         else if (feederID == FEEDER_COLORCHOICES) 
09407         {
09408                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount)
09409                 {
09410                         Item_RunScript(item, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorActionText[index]);
09411                 }
09412         }
09413         else if (feederID == FEEDER_PLAYER_SKIN_HEAD) 
09414         {
09415                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount)
09416                 {
09417                         trap_Cvar_Set("ui_char_skin_head", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]);
09418                 }
09419         } 
09420         else if (feederID == FEEDER_PLAYER_SKIN_TORSO) 
09421         {
09422                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount)
09423                 {
09424                         trap_Cvar_Set("ui_char_skin_torso", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index]);
09425                 }
09426         } 
09427         else if (feederID == FEEDER_PLAYER_SKIN_LEGS) 
09428         {
09429                 if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount)
09430                 {
09431                         trap_Cvar_Set("ui_char_skin_legs", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index]);
09432                 }
09433         } 
09434         else if (feederID == FEEDER_PLAYER_SPECIES) 
09435         {
09436                 uiInfo.playerSpeciesIndex = index;
09437         } 
09438         else if (feederID == FEEDER_LANGUAGES) 
09439         {
09440                 uiInfo.languageCountIndex = index;
09441         } 
09442         else if (  feederID == FEEDER_SIEGE_BASE_CLASS )
09443         {
09444                 int team,baseClass; 
09445 
09446                 team = (int)trap_Cvar_VariableValue("ui_team");
09447                 baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
09448 
09449                 UI_UpdateCvarsForClass(team, baseClass, index);
09450         }
09451         else if (feederID == FEEDER_SIEGE_CLASS_WEAPONS) 
09452         {
09453 //              trap_Cvar_VariableStringBuffer( va("ui_class_weapondesc%i", index), info, sizeof(info) );
09454 //              trap_Cvar_Set( "ui_itemforceinvdesc", info );
09455         } 
09456         else if (feederID == FEEDER_SIEGE_CLASS_INVENTORY) 
09457         {
09458 //              trap_Cvar_VariableStringBuffer( va("ui_class_itemdesc%i", index), info, sizeof(info) );
09459 //              trap_Cvar_Set( "ui_itemforceinvdesc", info );
09460         } 
09461         else if (feederID == FEEDER_SIEGE_CLASS_FORCE) 
09462         {
09463                 int i;
09464 //              int validCnt = 0;
09465 
09466                 trap_Cvar_VariableStringBuffer( va("ui_class_power%i", index), info, sizeof(info) );
09467 
09468                 //count them up
09469                 for (i=0;i< NUM_FORCE_POWERS;i++)
09470                 {
09471                         if (!strcmp(HolocronIcons[i],info))
09472                         {
09473                                 trap_Cvar_Set( "ui_itemforceinvdesc", forcepowerDesc[i] );
09474                         }
09475                 }
09476         } 
09477 #ifdef _XBOX
09478         else if (feederID == FEEDER_XBL_ACCOUNTS)
09479         {
09480                 XBL_SetAccountIndex( index );
09481         }
09482         else if (feederID == FEEDER_XBL_PLAYERS)
09483         {
09484                 XBL_PL_SetPlayerIndex( index );
09485         }
09486         else if (feederID == FEEDER_XBL_FRIENDS)
09487         {
09488                 XBL_F_SetChosenFriendIndex( index );
09489         }
09490         else if (feederID == FEEDER_XBL_SERVERS)
09491         {
09492                 XBL_MM_SetChosenServerIndex( index );
09493         }
09494 #endif
09495 
09496         return qtrue;
09497 }
09498 
09499 
09500 static qboolean GameType_Parse(char **p, qboolean join) {
09501         char *token;
09502 
09503         token = COM_ParseExt((const char **)p, qtrue);
09504 
09505         if (token[0] != '{') {
09506                 return qfalse;
09507         }
09508 
09509         if (join) {
09510                 uiInfo.numJoinGameTypes = 0;
09511         } else {
09512                 uiInfo.numGameTypes = 0;
09513         }
09514 
09515         while ( 1 ) {
09516                 token = COM_ParseExt((const char **)p, qtrue);
09517 
09518                 if (Q_stricmp(token, "}") == 0) {
09519                         return qtrue;
09520                 }
09521 
09522