PageRenderTime 121ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 2ms

/OJRP Source/Enhanced/source/ui/ui_main.c

https://github.com/theGster/OJRP
C | 11766 lines | 9629 code | 944 blank | 1193 comment | 1727 complexity | c4d6bbad0b25fbae46bf8471d817834e MD5 | raw file
  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3. /*
  4. =======================================================================
  5. USER INTERFACE MAIN
  6. =======================================================================
  7. */
  8. // use this to get a demo build without an explicit demo build, i.e. to get the demo ui files to build
  9. //#define PRE_RELEASE_TADEMO
  10. #include "../ghoul2/G2.h"
  11. #include "ui_local.h"
  12. #include "../qcommon/qfiles.h"
  13. #include "../qcommon/game_version.h"
  14. #include "ui_force.h"
  15. #include "../cgame/animtable.h" //we want this to be compiled into the module because we access it in the shared module.
  16. #include "../game/bg_saga.h"
  17. //[Mac]
  18. #if MAC_PORT
  19. #include "../cgame/holocronicons.h"
  20. #else
  21. #include "..\cgame\holocronicons.h"
  22. #endif
  23. //[/Mac]
  24. extern void UI_SaberAttachToChar( itemDef_t *item );
  25. uiRank_t uiRank[NUM_TOTAL_SKILLS] =
  26. {
  27. {3,UI_FORCE_RANK_HEAL,FP_HEAL,FORCE_LIGHTSIDE,qfalse,0},
  28. {3,UI_FORCE_RANK_LEVITATION,FP_LEVITATION,0,qfalse,0},
  29. {3,UI_FORCE_RANK_SPEED,FP_SPEED,0,qfalse,0},
  30. {3,UI_FORCE_RANK_PUSH,FP_PUSH,0,qfalse,0},
  31. {3,UI_FORCE_RANK_PULL,FP_PULL,0,qfalse,0},
  32. {3,UI_FORCE_RANK_TELEPATHY,FP_TELEPATHY,FORCE_LIGHTSIDE,qfalse,0},
  33. {3,UI_FORCE_RANK_GRIP,FP_GRIP,FORCE_DARKSIDE,qfalse,0},
  34. {3,UI_FORCE_RANK_LIGHTNING,FP_LIGHTNING,FORCE_DARKSIDE,qfalse,0},
  35. {3,UI_FORCE_RANK_RAGE,FP_RAGE,FORCE_DARKSIDE,qfalse,0},
  36. {3,UI_FORCE_RANK_PROTECT,FP_PROTECT,FORCE_LIGHTSIDE,qfalse,0},
  37. {3,UI_FORCE_RANK_ABSORB,FP_ABSORB,FORCE_LIGHTSIDE,qfalse,0},
  38. {3,UI_FORCE_RANK_TEAM_HEAL,FP_TEAM_HEAL,FORCE_LIGHTSIDE,qfalse,0},
  39. {3,UI_FORCE_RANK_TEAM_FORCE,FP_TEAM_FORCE,FORCE_DARKSIDE,qfalse,0},
  40. {3,UI_FORCE_RANK_DRAIN,FP_DRAIN,FORCE_DARKSIDE,qfalse,0},
  41. {3,UI_FORCE_RANK_SEE,FP_SEE,0,qfalse,0},
  42. {3,UI_FORCE_RANK_SABERATTACK,FP_SABER_OFFENSE,0,qfalse,0},
  43. {3,UI_FORCE_RANK_SABERDEFEND,FP_SABER_DEFENSE,0,qfalse,0},
  44. {3,UI_FORCE_RANK_SABERTHROW,FP_SABERTHROW,0,qfalse,0},
  45. {1,UI_FORCE_RANK_JETPACK,NUM_FORCE_POWERS+SK_JETPACK,0,qfalse,0},
  46. {3,UI_FORCE_RANK_PISTOL,NUM_FORCE_POWERS+SK_PISTOL,0,qfalse,0},
  47. {3,UI_FORCE_RANK_BLASTER,NUM_FORCE_POWERS+SK_BLASTER,0,qfalse,0},
  48. {3,UI_FORCE_RANK_THERMALS,NUM_FORCE_POWERS+SK_THERMAL,0,qfalse,0},
  49. {3,UI_FORCE_RANK_ROCKETS,NUM_FORCE_POWERS+SK_ROCKET,0,qfalse,0},
  50. {2,UI_FORCE_RANK_BACTA,NUM_FORCE_POWERS+SK_BACTA,0,qfalse,0},
  51. {1,UI_FORCE_RANK_FLAMETHROWER,NUM_FORCE_POWERS+SK_FLAMETHROWER,0,qfalse,0},
  52. {3,UI_FORCE_RANK_BOWCASTER,NUM_FORCE_POWERS+SK_BOWCASTER,0,qfalse,0},
  53. {1,UI_FORCE_RANK_FORCEFIELD,NUM_FORCE_POWERS+SK_FORCEFIELD,0,qfalse,0},
  54. {1,UI_FORCE_RANK_CLOAK,NUM_FORCE_POWERS+SK_CLOAK,0,qfalse,0},
  55. {1,UI_FORCE_RANK_SEEKER,NUM_FORCE_POWERS+SK_SEEKER,0,qfalse,0},
  56. {1,UI_FORCE_RANK_SENTRY,NUM_FORCE_POWERS+SK_SENTRY,0,qfalse,0},
  57. {2,UI_FORCE_RANK_DETPACK,NUM_FORCE_POWERS+SK_DETPACK,0,qfalse,0},
  58. {3,UI_FORCE_RANK_REPEATER,NUM_FORCE_POWERS+SK_REPEATER,0,qfalse,0},
  59. {3,UI_FORCE_RANK_DISRUPTOR,NUM_FORCE_POWERS+SK_DISRUPTOR,0,qfalse,0},
  60. {1,UI_FORCE_RANK_BLUESTYLE,NUM_FORCE_POWERS+SK_BLUESTYLE,0,qfalse,0},
  61. {1,UI_FORCE_RANK_REDSTYLE,NUM_FORCE_POWERS+SK_REDSTYLE,0,qfalse,0},
  62. {1,UI_FORCE_RANK_PURPLESTYLE,NUM_FORCE_POWERS+SK_PURPLESTYLE,0,qfalse,0},
  63. {1,UI_FORCE_RANK_GREENSTYLE,NUM_FORCE_POWERS+SK_GREENSTYLE,0,qfalse,0},
  64. {1,UI_FORCE_RANK_DUALSTYLE,NUM_FORCE_POWERS+SK_DUALSTYLE,0,qfalse,0},
  65. {1,UI_FORCE_RANK_STAFFSTYLE,NUM_FORCE_POWERS+SK_STAFFSTYLE,0,qfalse,0},
  66. {1,UI_FORCE_RANK_REPEATERUPGRADE,NUM_FORCE_POWERS+SK_REPEATERUPGRADE,0,qfalse,0},
  67. {3,UI_FORCE_RANK_FLECHETTE,NUM_FORCE_POWERS+SK_FLECHETTE,0,qfalse,0},
  68. {1,UI_FORCE_RANK_BLASTERRATEOFFIRE,NUM_FORCE_POWERS+SK_BLASTERRATEOFFIREUPGRADE,0,qfalse,0}
  69. //Add new skills here
  70. };
  71. char *forcepowerDesc[NUM_FORCE_POWERS] =
  72. {
  73. "@MENUS_OF_EFFECT_JEDI_ONLY_NEFFECT",
  74. "@MENUS_DURATION_IMMEDIATE_NAREA",
  75. "@MENUS_DURATION_5_SECONDS_NAREA",
  76. "@MENUS_DURATION_INSTANTANEOUS",
  77. "@MENUS_INSTANTANEOUS_EFFECT_NAREA",
  78. "@MENUS_DURATION_VARIABLE_20",
  79. "@MENUS_DURATION_INSTANTANEOUS_NAREA",
  80. "@MENUS_OF_EFFECT_LIVING_PERSONS",
  81. "@MENUS_DURATION_VARIABLE_10",
  82. "@MENUS_DURATION_VARIABLE_NAREA",
  83. "@MENUS_DURATION_CONTINUOUS_NAREA",
  84. "@MENUS_OF_EFFECT_JEDI_ALLIES_NEFFECT",
  85. "@MENUS_EFFECT_JEDI_ALLIES_NEFFECT",
  86. "@MENUS_VARIABLE_NAREA_OF_EFFECT",
  87. "@MENUS_EFFECT_NAREA_OF_EFFECT",
  88. "@SP_INGAME_FORCE_SABER_OFFENSE_DESC",
  89. "@SP_INGAME_FORCE_SABER_DEFENSE_DESC",
  90. "@SP_INGAME_FORCE_SABER_THROW_DESC"
  91. };
  92. // Movedata Sounds
  93. typedef enum
  94. {
  95. MDS_NONE = 0,
  96. MDS_FORCE_JUMP,
  97. MDS_ROLL,
  98. MDS_SABER,
  99. MDS_MOVE_SOUNDS_MAX
  100. };
  101. typedef enum
  102. {
  103. MD_ACROBATICS = 0,
  104. MD_SINGLE_FAST,
  105. MD_SINGLE_MEDIUM,
  106. MD_SINGLE_STRONG,
  107. MD_DUAL_SABERS,
  108. MD_SABER_STAFF,
  109. MD_MOVE_TITLE_MAX
  110. };
  111. // Some hard coded badness
  112. // At some point maybe this should be externalized to a .dat file
  113. char *datapadMoveTitleData[MD_MOVE_TITLE_MAX] =
  114. {
  115. "@MENUS_ACROBATICS",
  116. "@MENUS_SINGLE_FAST",
  117. "@MENUS_SINGLE_MEDIUM",
  118. "@MENUS_SINGLE_STRONG",
  119. "@MENUS_DUAL_SABERS",
  120. "@MENUS_SABER_STAFF",
  121. };
  122. char *datapadMoveTitleBaseAnims[MD_MOVE_TITLE_MAX] =
  123. {
  124. "BOTH_RUN1",
  125. "BOTH_SABERFAST_STANCE",
  126. "BOTH_STAND2",
  127. "BOTH_SABERSLOW_STANCE",
  128. "BOTH_SABERDUAL_STANCE",
  129. "BOTH_SABERSTAFF_STANCE",
  130. };
  131. #define MAX_MOVES 16
  132. typedef struct
  133. {
  134. char *title;
  135. char *desc;
  136. char *anim;
  137. short sound;
  138. } datpadmovedata_t;
  139. static datpadmovedata_t datapadMoveData[MD_MOVE_TITLE_MAX][MAX_MOVES] =
  140. {
  141. // Acrobatics
  142. "@MENUS_FORCE_JUMP1", "@MENUS_FORCE_JUMP1_DESC", "BOTH_FORCEJUMP1", MDS_FORCE_JUMP,
  143. "@MENUS_FORCE_FLIP", "@MENUS_FORCE_FLIP_DESC", "BOTH_FLIP_F", MDS_FORCE_JUMP,
  144. "@MENUS_ROLL", "@MENUS_ROLL_DESC", "BOTH_ROLL_F", MDS_ROLL,
  145. "@MENUS_BACKFLIP_OFF_WALL", "@MENUS_BACKFLIP_OFF_WALL_DESC", "BOTH_WALL_FLIP_BACK1", MDS_FORCE_JUMP,
  146. "@MENUS_SIDEFLIP_OFF_WALL", "@MENUS_SIDEFLIP_OFF_WALL_DESC", "BOTH_WALL_FLIP_RIGHT", MDS_FORCE_JUMP,
  147. "@MENUS_WALL_RUN", "@MENUS_WALL_RUN_DESC", "BOTH_WALL_RUN_RIGHT", MDS_FORCE_JUMP,
  148. "@MENUS_WALL_GRAB_JUMP", "@MENUS_WALL_GRAB_JUMP_DESC", "BOTH_FORCEWALLREBOUND_FORWARD",MDS_FORCE_JUMP,
  149. "@MENUS_RUN_UP_WALL_BACKFLIP", "@MENUS_RUN_UP_WALL_BACKFLIP_DESC", "BOTH_FORCEWALLRUNFLIP_START", MDS_FORCE_JUMP,
  150. "@MENUS_JUMPUP_FROM_KNOCKDOWN", "@MENUS_JUMPUP_FROM_KNOCKDOWN_DESC","BOTH_KNOCKDOWN3", MDS_NONE,
  151. "@MENUS_JUMPKICK_FROM_KNOCKDOWN", "@MENUS_JUMPKICK_FROM_KNOCKDOWN_DESC","BOTH_KNOCKDOWN2", MDS_NONE,
  152. "@MENUS_ROLL_FROM_KNOCKDOWN", "@MENUS_ROLL_FROM_KNOCKDOWN_DESC", "BOTH_KNOCKDOWN1", MDS_NONE,
  153. NULL, NULL, 0, MDS_NONE,
  154. NULL, NULL, 0, MDS_NONE,
  155. NULL, NULL, 0, MDS_NONE,
  156. NULL, NULL, 0, MDS_NONE,
  157. NULL, NULL, 0, MDS_NONE,
  158. //Single Saber, Fast Style
  159. "@MENUS_STAB_BACK", "@MENUS_STAB_BACK_DESC", "BOTH_A2_STABBACK1", MDS_SABER,
  160. "@MENUS_LUNGE_ATTACK", "@MENUS_LUNGE_ATTACK_DESC", "BOTH_LUNGE2_B__T_", MDS_SABER,
  161. "@MENUS_FAST_ATTACK_KATA", "@MENUS_FAST_ATTACK_KATA_DESC", "BOTH_A1_SPECIAL", MDS_SABER,
  162. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN", MDS_FORCE_JUMP,
  163. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  164. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  165. NULL, NULL, 0, MDS_NONE,
  166. NULL, NULL, 0, MDS_NONE,
  167. NULL, NULL, 0, MDS_NONE,
  168. NULL, NULL, 0, MDS_NONE,
  169. NULL, NULL, 0, MDS_NONE,
  170. NULL, NULL, 0, MDS_NONE,
  171. NULL, NULL, 0, MDS_NONE,
  172. NULL, NULL, 0, MDS_NONE,
  173. NULL, NULL, 0, MDS_NONE,
  174. NULL, NULL, 0, MDS_NONE,
  175. //Single Saber, Medium Style
  176. "@MENUS_SLASH_BACK", "@MENUS_SLASH_BACK_DESC", "BOTH_ATTACK_BACK", MDS_SABER,
  177. "@MENUS_FLIP_ATTACK", "@MENUS_FLIP_ATTACK_DESC", "BOTH_JUMPFLIPSLASHDOWN1", MDS_FORCE_JUMP,
  178. "@MENUS_MEDIUM_ATTACK_KATA", "@MENUS_MEDIUM_ATTACK_KATA_DESC", "BOTH_A2_SPECIAL", MDS_SABER,
  179. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN", MDS_FORCE_JUMP,
  180. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  181. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  182. NULL, NULL, 0, MDS_NONE,
  183. NULL, NULL, 0, MDS_NONE,
  184. NULL, NULL, 0, MDS_NONE,
  185. NULL, NULL, 0, MDS_NONE,
  186. NULL, NULL, 0, MDS_NONE,
  187. NULL, NULL, 0, MDS_NONE,
  188. NULL, NULL, 0, MDS_NONE,
  189. NULL, NULL, 0, MDS_NONE,
  190. NULL, NULL, 0, MDS_NONE,
  191. NULL, NULL, 0, MDS_NONE,
  192. //Single Saber, Strong Style
  193. "@MENUS_SLASH_BACK", "@MENUS_SLASH_BACK_DESC", "BOTH_ATTACK_BACK", MDS_SABER,
  194. "@MENUS_JUMP_ATTACK", "@MENUS_JUMP_ATTACK_DESC", "BOTH_FORCELEAP2_T__B_", MDS_FORCE_JUMP,
  195. "@MENUS_STRONG_ATTACK_KATA", "@MENUS_STRONG_ATTACK_KATA_DESC", "BOTH_A3_SPECIAL", MDS_SABER,
  196. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN", MDS_FORCE_JUMP,
  197. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  198. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  199. NULL, NULL, 0, MDS_NONE,
  200. NULL, NULL, 0, MDS_NONE,
  201. NULL, NULL, 0, MDS_NONE,
  202. NULL, NULL, 0, MDS_NONE,
  203. NULL, NULL, 0, MDS_NONE,
  204. NULL, NULL, 0, MDS_NONE,
  205. NULL, NULL, 0, MDS_NONE,
  206. NULL, NULL, 0, MDS_NONE,
  207. NULL, NULL, 0, MDS_NONE,
  208. NULL, NULL, 0, MDS_NONE,
  209. //Dual Sabers
  210. "@MENUS_SLASH_BACK", "@MENUS_SLASH_BACK_DESC", "BOTH_ATTACK_BACK", MDS_SABER,
  211. "@MENUS_FLIP_FORWARD_ATTACK", "@MENUS_FLIP_FORWARD_ATTACK_DESC", "BOTH_JUMPATTACK6", MDS_FORCE_JUMP,
  212. "@MENUS_DUAL_SABERS_TWIRL", "@MENUS_DUAL_SABERS_TWIRL_DESC", "BOTH_SPINATTACK6", MDS_SABER,
  213. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN_DUAL", MDS_FORCE_JUMP,
  214. "@MENUS_DUAL_SABER_BARRIER", "@MENUS_DUAL_SABER_BARRIER_DESC", "BOTH_A6_SABERPROTECT", MDS_SABER,
  215. "@MENUS_DUAL_STAB_FRONT_BACK", "@MENUS_DUAL_STAB_FRONT_BACK_DESC", "BOTH_A6_FB", MDS_SABER,
  216. "@MENUS_DUAL_STAB_LEFT_RIGHT", "@MENUS_DUAL_STAB_LEFT_RIGHT_DESC", "BOTH_A6_LR", MDS_SABER,
  217. "@MENUS_CARTWHEEL", "@MENUS_CARTWHEEL_DESC", "BOTH_ARIAL_RIGHT", MDS_FORCE_JUMP,
  218. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  219. NULL, NULL, 0, MDS_NONE,
  220. NULL, NULL, 0, MDS_NONE,
  221. NULL, NULL, 0, MDS_NONE,
  222. NULL, NULL, 0, MDS_NONE,
  223. NULL, NULL, 0, MDS_NONE,
  224. NULL, NULL, 0, MDS_NONE,
  225. NULL, NULL, 0, MDS_NONE,
  226. // Saber Staff
  227. "@MENUS_STAB_BACK", "@MENUS_STAB_BACK_DESC", "BOTH_A2_STABBACK1", MDS_SABER,
  228. "@MENUS_BACK_FLIP_ATTACK", "@MENUS_BACK_FLIP_ATTACK_DESC", "BOTH_JUMPATTACK7", MDS_FORCE_JUMP,
  229. "@MENUS_SABER_STAFF_TWIRL", "@MENUS_SABER_STAFF_TWIRL_DESC", "BOTH_SPINATTACK7", MDS_SABER,
  230. "@MENUS_ATTACK_ENEMYONGROUND", "@MENUS_ATTACK_ENEMYONGROUND_DESC", "BOTH_STABDOWN_STAFF", MDS_FORCE_JUMP,
  231. "@MENUS_SPINNING_KATA", "@MENUS_SPINNING_KATA_DESC", "BOTH_A7_SOULCAL", MDS_SABER,
  232. "@MENUS_KICK1", "@MENUS_KICK1_DESC", "BOTH_A7_KICK_F", MDS_FORCE_JUMP,
  233. "@MENUS_JUMP_KICK", "@MENUS_JUMP_KICK_DESC", "BOTH_A7_KICK_F_AIR", MDS_FORCE_JUMP,
  234. "@MENUS_BUTTERFLY_ATTACK", "@MENUS_BUTTERFLY_ATTACK_DESC", "BOTH_BUTTERFLY_FR1", MDS_SABER,
  235. "@MENUS_BOTH_ROLL_STAB", "@MENUS_BOTH_ROLL_STAB2_DESC", "BOTH_ROLL_STAB", MDS_SABER,
  236. NULL, NULL, 0, MDS_NONE,
  237. NULL, NULL, 0, MDS_NONE,
  238. NULL, NULL, 0, MDS_NONE,
  239. NULL, NULL, 0, MDS_NONE,
  240. NULL, NULL, 0, MDS_NONE,
  241. NULL, NULL, 0, MDS_NONE,
  242. NULL, NULL, 0, MDS_NONE,
  243. };
  244. /*
  245. ================
  246. vmMain
  247. This is the only way control passes into the module.
  248. !!! This MUST BE THE VERY FIRST FUNCTION compiled into the .qvm file !!!
  249. ================
  250. */
  251. vmCvar_t ui_debug;
  252. vmCvar_t ui_initialized;
  253. vmCvar_t ui_char_color_red;
  254. vmCvar_t ui_char_color_green;
  255. vmCvar_t ui_char_color_blue;
  256. vmCvar_t ui_PrecacheModels;
  257. vmCvar_t ui_char_anim;
  258. void _UI_Init( qboolean );
  259. void _UI_Shutdown( void );
  260. void _UI_KeyEvent( int key, qboolean down );
  261. void _UI_MouseEvent( int dx, int dy );
  262. void _UI_Refresh( int realtime );
  263. qboolean _UI_IsFullscreen( void );
  264. void UI_SetSiegeTeams(void);
  265. extern qboolean UI_SaberModelForSaber( const char *saberName, char *saberModel );
  266. void UI_SiegeSetCvarsForClass(siegeClass_t *scl);
  267. int UI_SiegeClassNum(siegeClass_t *scl);
  268. //[VS2005]
  269. //VS2005's C doesn't assume int type anymore.
  270. void UI_UpdateCvarsForClass(const int team,const int baseClass,const int index);
  271. //void UI_UpdateCvarsForClass(const int team,const baseClass,const int index);
  272. //[/VS2005]
  273. void UI_UpdateSiegeStatusIcons(void);
  274. void UI_ClampMaxPlayers(void);
  275. static void UI_CheckServerName( void );
  276. static qboolean UI_CheckPassword( void );
  277. static void UI_JoinServer( void );
  278. //[DynamicMemory_Sabers]
  279. void UI_AllocMem(void **ptr, int sze);
  280. void UI_FreeMem(void *ptr);
  281. void UI_ReaAllocMem(void **ptr, int sze, int count);
  282. char *UI_GetSaberHiltInfo(qboolean TwoHanded, int index);
  283. //[/DynamicMemory_Sabers]
  284. #include "../namespace_begin.h"
  285. // Functions in BG or ui_shared
  286. void Menu_ShowGroup (menuDef_t *menu, char *itemName, qboolean showFlag);
  287. void Menu_ItemDisable(menuDef_t *menu, char *name,int disableFlag);
  288. int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name);
  289. itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name);
  290. int BG_GetUIPortrait(const int team, const short classIndex, const short cntIndex);
  291. char *BG_GetUIPortraitFile(const int team, const short classIndex, const short cntIndex);
  292. siegeClass_t *BG_GetClassOnBaseClass(const int team, const short classIndex, const short cntIndex);
  293. 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 ) {
  294. char buffer[MAX_QPATH]="";//[AutoUpdate]
  295. switch ( command ) {
  296. case UI_GETAPIVERSION:
  297. return UI_API_VERSION;
  298. case UI_INIT:
  299. trap_Cvar_VariableStringBuffer("fs_basepath",buffer,sizeof(buffer));
  300. //system(va("%s\\ojpenhanced\\update.exe",buffer));//[AutoUpdate]
  301. _UI_Init(arg0);
  302. return 0;
  303. case UI_SHUTDOWN:
  304. _UI_Shutdown();
  305. return 0;
  306. case UI_KEY_EVENT:
  307. _UI_KeyEvent( arg0, arg1 );
  308. return 0;
  309. case UI_MOUSE_EVENT:
  310. _UI_MouseEvent( arg0, arg1 );
  311. return 0;
  312. case UI_REFRESH:
  313. _UI_Refresh( arg0 );
  314. return 0;
  315. case UI_IS_FULLSCREEN:
  316. return _UI_IsFullscreen();
  317. case UI_SET_ACTIVE_MENU:
  318. _UI_SetActiveMenu( arg0 );
  319. return 0;
  320. case UI_CONSOLE_COMMAND:
  321. return UI_ConsoleCommand(arg0);
  322. case UI_DRAW_CONNECT_SCREEN:
  323. UI_DrawConnectScreen( arg0 );
  324. return 0;
  325. case UI_HASUNIQUECDKEY: // mod authors need to observe this
  326. return qtrue; // bk010117 - change this to qfalse for mods!
  327. case UI_MENU_RESET:
  328. Menu_Reset();
  329. return 0;
  330. }
  331. return -1;
  332. }
  333. #include "../namespace_end.h"
  334. siegeClassDesc_t g_UIClassDescriptions[MAX_SIEGE_CLASSES];
  335. siegeTeam_t *siegeTeam1 = NULL;
  336. siegeTeam_t *siegeTeam2 = NULL;
  337. int g_UIGloballySelectedSiegeClass = -1;
  338. //Cut down version of the stuff used in the game code
  339. //This is just the bare essentials of what we need to load animations properly for ui ghoul2 models.
  340. //This function doesn't need to be sync'd with the BG_ version in bg_panimate.c unless some sort of fundamental change
  341. //is made. Just make sure the variables/functions accessed in ui_shared.c exist in both modules.
  342. qboolean UIPAFtextLoaded = qfalse;
  343. animation_t uiHumanoidAnimations[MAX_TOTALANIMATIONS]; //humanoid animations are the only ones that are statically allocated.
  344. #include "../namespace_begin.h"
  345. bgLoadedAnim_t bgAllAnims[MAX_ANIM_FILES];
  346. int uiNumAllAnims = 1; //start off at 0, because 0 will always be assigned to humanoid.
  347. #include "../namespace_end.h"
  348. animation_t *UI_AnimsetAlloc(void)
  349. {
  350. assert (uiNumAllAnims < MAX_ANIM_FILES);
  351. bgAllAnims[uiNumAllAnims].anims = (animation_t *) BG_Alloc(sizeof(animation_t)*MAX_TOTALANIMATIONS);
  352. return bgAllAnims[uiNumAllAnims].anims;
  353. }
  354. //[SIEGECVARFIX]
  355. char *siege_Str(void) {
  356. static int cur;
  357. static char strings[1024][256];
  358. return strings[cur++];
  359. }
  360. /*
  361. ===============
  362. siege_Cvar_Set
  363. replacement for the trap to reduce cvar usage
  364. ===============
  365. */
  366. void siege_Cvar_Set( const char *cvarName, const char *value )
  367. {
  368. char **tmp;
  369. char ui_siegeInfo[MAX_STRING_CHARS];
  370. int i;
  371. if(!ui_siegeStruct)
  372. {
  373. trap_Cvar_VariableStringBuffer( "ui_siegeInfo", ui_siegeInfo, MAX_STRING_CHARS );
  374. sscanf(ui_siegeInfo,"%p",&ui_siegeStruct);
  375. if(!ui_siegeStruct) return;
  376. }
  377. for(tmp=ui_siegeStruct;*tmp;tmp+=2)
  378. {
  379. if(*tmp && !strcmp(*tmp,cvarName)) { //cvar already exists, overwrite existing value
  380. Q_strncpyz(*(tmp+1),value,256); //:nervou
  381. return;
  382. }
  383. }
  384. i = tmp - ui_siegeStruct;
  385. ui_siegeStruct[i] = siege_Str();
  386. Q_strncpyz( ui_siegeStruct[i], cvarName, 256 );
  387. ui_siegeStruct[i+1] = siege_Str();
  388. Q_strncpyz( ui_siegeStruct[i+1], value, 256 );
  389. ui_siegeStruct[i+2] = 0;
  390. return;
  391. }
  392. void siege_Cvar_VariableStringBuffer( char *var_name, char *buffer, int bufsize )
  393. {
  394. char **tmp;
  395. char ui_siegeInfo[MAX_STRING_CHARS];
  396. if(!ui_siegeStruct)
  397. {
  398. trap_Cvar_VariableStringBuffer( "ui_siegeInfo", ui_siegeInfo, MAX_STRING_CHARS );
  399. sscanf(ui_siegeInfo,"%p",&ui_siegeStruct);
  400. if(!ui_siegeStruct) return;
  401. }
  402. for(tmp=ui_siegeStruct;*tmp;tmp+=2)
  403. {
  404. if(*tmp && !strcmp(*tmp,var_name)) {
  405. Q_strncpyz(buffer,*(tmp+1),bufsize);
  406. return;
  407. }
  408. }
  409. trap_Cvar_VariableStringBuffer( var_name, buffer, bufsize );
  410. return;
  411. }
  412. int siege_Cvar_VariableValue( char *var_name )
  413. {
  414. char **tmp;
  415. char ui_siegeInfo[MAX_STRING_CHARS];
  416. if(!ui_siegeStruct)
  417. {
  418. trap_Cvar_VariableStringBuffer( "ui_siegeInfo", ui_siegeInfo, MAX_STRING_CHARS );
  419. sscanf(ui_siegeInfo,"%p",&ui_siegeStruct);
  420. if(!ui_siegeStruct) return trap_Cvar_VariableValue( var_name );
  421. }
  422. for(tmp=ui_siegeStruct;*tmp;tmp+=2)
  423. {
  424. if(*tmp && !strcmp(*tmp,var_name)) {
  425. return atoi(*(tmp+1));
  426. }
  427. }
  428. return trap_Cvar_VariableValue( var_name );
  429. }
  430. //[/SIEGECVARFIX]
  431. /*
  432. ======================
  433. UI_ParseAnimationFile
  434. Read a configuration file containing animation coutns and rates
  435. models/players/visor/animation.cfg, etc
  436. ======================
  437. */
  438. #include "../namespace_begin.h"
  439. static char UIPAFtext[60000];
  440. int UI_ParseAnimationFile(const char *filename, animation_t *animset, qboolean isHumanoid)
  441. {
  442. char *text_p;
  443. int len;
  444. int i;
  445. char *token;
  446. float fps;
  447. int skip;
  448. int usedIndex = -1;
  449. int nextIndex = uiNumAllAnims;
  450. fileHandle_t f;
  451. int animNum;
  452. if (!isHumanoid)
  453. {
  454. i = 1;
  455. while (i < uiNumAllAnims)
  456. { //see if it's been loaded already
  457. if (!Q_stricmp(bgAllAnims[i].filename, filename))
  458. {
  459. animset = bgAllAnims[i].anims;
  460. return i; //alright, we already have it.
  461. }
  462. i++;
  463. }
  464. //Looks like it has not yet been loaded. Allocate space for the anim set if we need to, and continue along.
  465. if (!animset)
  466. {
  467. if (strstr(filename, "players/_humanoid/"))
  468. { //then use the static humanoid set.
  469. animset = uiHumanoidAnimations;
  470. isHumanoid = qtrue;
  471. nextIndex = 0;
  472. }
  473. else
  474. {
  475. animset = UI_AnimsetAlloc();
  476. if (!animset)
  477. {
  478. assert(!"Anim set alloc failed!");
  479. return -1;
  480. }
  481. }
  482. }
  483. }
  484. #ifdef _DEBUG
  485. else
  486. {
  487. assert(animset);
  488. }
  489. #endif
  490. // load the file
  491. if (!UIPAFtextLoaded || !isHumanoid)
  492. { //rww - We are always using the same animation config now. So only load it once.
  493. len = trap_FS_FOpenFile( filename, &f, FS_READ );
  494. if ( (len <= 0) || (len >= sizeof( UIPAFtext ) - 1) )
  495. {
  496. if (len > 0)
  497. {
  498. Com_Error(ERR_DROP, "%s exceeds the allowed ui-side animation buffer!", filename);
  499. }
  500. return -1;
  501. }
  502. trap_FS_Read( UIPAFtext, len, f );
  503. UIPAFtext[len] = 0;
  504. trap_FS_FCloseFile( f );
  505. }
  506. else
  507. {
  508. return 0; //humanoid index
  509. }
  510. // parse the text
  511. text_p = UIPAFtext;
  512. skip = 0; // quiet the compiler warning
  513. //FIXME: have some way of playing anims backwards... negative numFrames?
  514. //initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100
  515. for(i = 0; i < MAX_ANIMATIONS; i++)
  516. {
  517. animset[i].firstFrame = 0;
  518. animset[i].numFrames = 0;
  519. animset[i].loopFrames = -1;
  520. animset[i].frameLerp = 100;
  521. // animset[i].initialLerp = 100;
  522. }
  523. // read information for each frame
  524. while(1)
  525. {
  526. token = COM_Parse( (const char **)(&text_p) );
  527. if ( !token || !token[0])
  528. {
  529. break;
  530. }
  531. animNum = GetIDForString(animTable, token);
  532. if(animNum == -1)
  533. {
  534. //#ifndef FINAL_BUILD
  535. #ifdef _DEBUG
  536. //Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename);
  537. #endif
  538. continue;
  539. }
  540. token = COM_Parse( (const char **)(&text_p) );
  541. if ( !token[0] ) //[TicketFix143]
  542. {
  543. break;
  544. }
  545. animset[animNum].firstFrame = atoi( token );
  546. token = COM_Parse( (const char **)(&text_p) );
  547. if ( !token[0] ) //[TicketFix143]
  548. {
  549. break;
  550. }
  551. animset[animNum].numFrames = atoi( token );
  552. token = COM_Parse( (const char **)(&text_p) );
  553. if ( !token[0] ) //[TicketFix143]
  554. {
  555. break;
  556. }
  557. animset[animNum].loopFrames = atoi( token );
  558. token = COM_Parse( (const char **)(&text_p) );
  559. if ( !token[0] ) //[TicketFix143]
  560. {
  561. break;
  562. }
  563. fps = atof( token );
  564. if ( fps == 0 )
  565. {
  566. fps = 1;//Don't allow divide by zero error
  567. }
  568. if ( fps < 0 )
  569. {//backwards
  570. animset[animNum].frameLerp = floor(1000.0f / fps);
  571. }
  572. else
  573. {
  574. animset[animNum].frameLerp = ceil(1000.0f / fps);
  575. }
  576. // animset[animNum].initialLerp = ceil(1000.0f / fabs(fps));
  577. }
  578. #ifdef _DEBUG
  579. //Check the array, and print the ones that have nothing in them.
  580. /*
  581. for(i = 0; i < MAX_ANIMATIONS; i++)
  582. {
  583. if (animTable[i].name != NULL) // This animation reference exists.
  584. {
  585. if (animset[i].firstFrame <= 0 && animset[i].numFrames <=0)
  586. { // This is an empty animation reference.
  587. Com_Printf("***ANIMTABLE reference #%d (%s) is empty!\n", i, animTable[i].name);
  588. }
  589. }
  590. }
  591. */
  592. #endif // _DEBUG
  593. if (isHumanoid)
  594. {
  595. bgAllAnims[0].anims = animset;
  596. strcpy(bgAllAnims[0].filename, filename);
  597. UIPAFtextLoaded = qtrue;
  598. usedIndex = 0;
  599. }
  600. else
  601. {
  602. bgAllAnims[nextIndex].anims = animset;
  603. strcpy(bgAllAnims[nextIndex].filename, filename);
  604. usedIndex = nextIndex;
  605. if (nextIndex)
  606. { //don't bother increasing the number if this ended up as a humanoid load.
  607. uiNumAllAnims++;
  608. }
  609. else
  610. {
  611. UIPAFtextLoaded = qtrue;
  612. usedIndex = 0;
  613. }
  614. }
  615. return usedIndex;
  616. }
  617. //menuDef_t *Menus_FindByName(const char *p);
  618. void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow);
  619. #include "../namespace_end.h"
  620. void UpdateForceUsed();
  621. char holdSPString[MAX_STRING_CHARS]={0};
  622. char holdSPString2[MAX_STRING_CHARS]={0};
  623. uiInfo_t uiInfo;
  624. static void UI_StartServerRefresh(qboolean full);
  625. static void UI_StopServerRefresh( void );
  626. static void UI_DoServerRefresh( void );
  627. static void UI_BuildServerDisplayList(qboolean force);
  628. static void UI_BuildServerStatus(qboolean force);
  629. static void UI_BuildFindPlayerList(qboolean force);
  630. static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 );
  631. static int UI_MapCountByGameType(qboolean singlePlayer);
  632. static int UI_HeadCountByColor( void );
  633. static void UI_ParseGameInfo(const char *teamFile);
  634. static const char *UI_SelectedMap(int index, int *actual);
  635. static int UI_GetIndexFromSelection(int actual);
  636. static void UI_SiegeClassCnt( const int team );
  637. int ProcessNewUI( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 );
  638. int uiSkinColor=TEAM_FREE;
  639. 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.
  640. static const serverFilter_t serverFilters[] = {
  641. //[SERVERFILTERS]
  642. //since OJP Enhanced only works with OJP Enhanced servers, only show them.
  643. {"OJP_MENUS_OJP_ENHANCED", "ojpenhanced"},
  644. //{"MENUS_ALL", "" },
  645. //{"MENUS_JEDI_ACADEMY", "" },
  646. //[/SERVERFILTERS]
  647. };
  648. static const int numServerFilters = sizeof(serverFilters) / sizeof(serverFilter_t);
  649. static const char *skillLevels[] = {
  650. "SKILL1",//"I Can Win",
  651. "SKILL2",//"Bring It On",
  652. "SKILL3",//"Hurt Me Plenty",
  653. "SKILL4",//"Hardcore",
  654. "SKILL5"//"Nightmare"
  655. };
  656. static const int numSkillLevels = sizeof(skillLevels) / sizeof(const char*);
  657. static const char *teamArenaGameTypes[] = {
  658. "FFA",
  659. "Holocron",
  660. "JediMaster",
  661. "Duel",
  662. "PowerDuel",
  663. "SP",
  664. "Team FFA",
  665. "Siege",
  666. "CTF",
  667. "CTY",
  668. "TeamTournament"
  669. };
  670. static int const numTeamArenaGameTypes = sizeof(teamArenaGameTypes) / sizeof(const char*);
  671. static char* netnames[] = {
  672. "???",
  673. "UDP",
  674. "IPX",
  675. NULL
  676. };
  677. static int gamecodetoui[] = {4,2,3,0,5,1,6};
  678. static int uitogamecode[] = {4,6,2,3,1,5,7};
  679. const char *UI_GetStringEdString(const char *refSection, const char *refName);
  680. const char *UI_TeamName(int team) {
  681. if (team==TEAM_RED)
  682. return "RED";
  683. else if (team==TEAM_BLUE)
  684. return "BLUE";
  685. else if (team==TEAM_SPECTATOR)
  686. return "SPECTATOR";
  687. return "FREE";
  688. }
  689. // returns either string or NULL for OOR...
  690. //
  691. static const char *GetCRDelineatedString( const char *psStripFileRef, const char *psStripStringRef, int iIndex)
  692. {
  693. static char sTemp[256];
  694. const char *psList = UI_GetStringEdString(psStripFileRef, psStripStringRef);
  695. char *p;
  696. while (iIndex--)
  697. {
  698. psList = strchr(psList,'\n');
  699. if (!psList){
  700. return NULL; // OOR
  701. }
  702. psList++;
  703. }
  704. strcpy(sTemp,psList);
  705. p = strchr(sTemp,'\n');
  706. if (p) {
  707. *p = '\0';
  708. }
  709. return sTemp;
  710. }
  711. static const char *GetMonthAbbrevString( int iMonth )
  712. {
  713. const char *p = GetCRDelineatedString("MP_INGAME","MONTHS", iMonth);
  714. return p ? p : "Jan"; // sanity
  715. }
  716. /*
  717. static const char *netSources[] = {
  718. "Local",
  719. "Internet",
  720. "Favorites"
  721. // "Mplayer"
  722. };
  723. static const int numNetSources = sizeof(netSources) / sizeof(const char*);
  724. */
  725. static const int numNetSources = 3; // now hard-entered in StringEd file
  726. static const char *GetNetSourceString(int iSource)
  727. {
  728. const char *p = GetCRDelineatedString("MP_INGAME","NET_SOURCES", iSource);
  729. return p ? p : "??";
  730. }
  731. void AssetCache() {
  732. int n;
  733. //if (Assets.textFont == NULL) {
  734. //}
  735. //Assets.background = trap_R_RegisterShaderNoMip( ASSET_BACKGROUND );
  736. //Com_Printf("Menu Size: %i bytes\n", sizeof(Menus));
  737. uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
  738. uiInfo.uiDC.Assets.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE );
  739. uiInfo.uiDC.Assets.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED );
  740. uiInfo.uiDC.Assets.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_ORANGE );//trap_R_RegisterShaderNoMip( ART_FX_YELLOW );
  741. uiInfo.uiDC.Assets.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW );//trap_R_RegisterShaderNoMip( ART_FX_GREEN );
  742. uiInfo.uiDC.Assets.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_GREEN );//trap_R_RegisterShaderNoMip( ART_FX_TEAL );
  743. uiInfo.uiDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE );
  744. uiInfo.uiDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_PURPLE );//trap_R_RegisterShaderNoMip( ART_FX_CYAN );
  745. uiInfo.uiDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE );
  746. uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
  747. uiInfo.uiDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
  748. uiInfo.uiDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
  749. uiInfo.uiDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
  750. uiInfo.uiDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
  751. uiInfo.uiDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
  752. uiInfo.uiDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
  753. uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
  754. // Icons for various server settings.
  755. uiInfo.uiDC.Assets.needPass = trap_R_RegisterShaderNoMip( "gfx/menus/needpass" );
  756. uiInfo.uiDC.Assets.noForce = trap_R_RegisterShaderNoMip( "gfx/menus/noforce" );
  757. uiInfo.uiDC.Assets.forceRestrict = trap_R_RegisterShaderNoMip( "gfx/menus/forcerestrict" );
  758. uiInfo.uiDC.Assets.saberOnly = trap_R_RegisterShaderNoMip( "gfx/menus/saberonly" );
  759. uiInfo.uiDC.Assets.trueJedi = trap_R_RegisterShaderNoMip( "gfx/menus/truejedi" );
  760. for( n = 0; n < NUM_CROSSHAIRS; n++ ) {
  761. uiInfo.uiDC.Assets.crosshairShader[n] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) );
  762. }
  763. uiInfo.newHighScoreSound = 0;//trap_S_RegisterSound("sound/feedback/voc_newhighscore.wav");
  764. }
  765. void _UI_DrawSides(float x, float y, float w, float h, float size) {
  766. size *= uiInfo.uiDC.xscale;
  767. trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  768. trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  769. }
  770. void _UI_DrawTopBottom(float x, float y, float w, float h, float size) {
  771. size *= uiInfo.uiDC.yscale;
  772. trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  773. trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
  774. }
  775. /*
  776. ================
  777. UI_DrawRect
  778. Coordinates are 640*480 virtual values
  779. =================
  780. */
  781. void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
  782. trap_R_SetColor( color );
  783. _UI_DrawTopBottom(x, y, width, height, size);
  784. _UI_DrawSides(x, y, width, height, size);
  785. trap_R_SetColor( NULL );
  786. }
  787. #include "../namespace_begin.h"
  788. int MenuFontToHandle(int iMenuFont)
  789. {
  790. switch (iMenuFont)
  791. {
  792. case 1: return uiInfo.uiDC.Assets.qhSmallFont;
  793. case 2: return uiInfo.uiDC.Assets.qhMediumFont;
  794. case 3: return uiInfo.uiDC.Assets.qhBigFont;
  795. case 4: return uiInfo.uiDC.Assets.qhSmall2Font;
  796. }
  797. return uiInfo.uiDC.Assets.qhMediumFont; // 0;
  798. }
  799. #include "../namespace_end.h"
  800. int Text_Width(const char *text, float scale, int iMenuFont)
  801. {
  802. int iFontIndex = MenuFontToHandle(iMenuFont);
  803. return trap_R_Font_StrLenPixels(text, iFontIndex, scale);
  804. }
  805. int Text_Height(const char *text, float scale, int iMenuFont)
  806. {
  807. int iFontIndex = MenuFontToHandle(iMenuFont);
  808. return trap_R_Font_HeightPixels(iFontIndex, scale);
  809. }
  810. void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style, int iMenuFont)
  811. {
  812. int iStyleOR = 0;
  813. int iFontIndex = MenuFontToHandle(iMenuFont);
  814. //
  815. // kludge.. convert JK2 menu styles to SOF2 printstring ctrl codes...
  816. //
  817. switch (style)
  818. {
  819. case ITEM_TEXTSTYLE_NORMAL: iStyleOR = 0;break; // JK2 normal text
  820. case ITEM_TEXTSTYLE_BLINK: iStyleOR = (int)STYLE_BLINK;break; // JK2 fast blinking
  821. case ITEM_TEXTSTYLE_PULSE: iStyleOR = (int)STYLE_BLINK;break; // JK2 slow pulsing
  822. case ITEM_TEXTSTYLE_SHADOWED: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  823. case ITEM_TEXTSTYLE_OUTLINED: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  824. case ITEM_TEXTSTYLE_OUTLINESHADOWED: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  825. case ITEM_TEXTSTYLE_SHADOWEDMORE: iStyleOR = (int)STYLE_DROPSHADOW;break; // JK2 drop shadow
  826. }
  827. trap_R_Font_DrawString( x, // int ox
  828. y, // int oy
  829. text, // const char *text
  830. color, // paletteRGBA_c c
  831. iStyleOR | iFontIndex, // const int iFontHandle
  832. !limit?-1:limit, // iCharLimit (-1 = none)
  833. scale // const float scale = 1.0f
  834. );
  835. }
  836. 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)
  837. {
  838. Text_Paint(x, y, scale, color, text, 0, limit, style, iMenuFont);
  839. // now print the cursor as well... (excuse the braces, it's for porting C++ to C)
  840. //
  841. {
  842. char sTemp[1024];
  843. int iCopyCount = limit ? min(strlen(text), limit) : strlen(text);
  844. iCopyCount = min(iCopyCount,cursorPos);
  845. iCopyCount = min(iCopyCount,sizeof(sTemp));
  846. // copy text into temp buffer for pixel measure...
  847. //
  848. strncpy(sTemp,text,iCopyCount);
  849. sTemp[iCopyCount] = '\0';
  850. {
  851. int iFontIndex = MenuFontToHandle( iMenuFont );
  852. int iNextXpos = trap_R_Font_StrLenPixels(sTemp, iFontIndex, scale );
  853. Text_Paint(x+iNextXpos, y, scale, color, va("%c",cursor), 0, limit, style|ITEM_TEXTSTYLE_BLINK, iMenuFont);
  854. }
  855. }
  856. }
  857. // maxX param is initially an X limit, but is also used as feedback. 0 = text was clipped to fit within, else maxX = next pos
  858. //
  859. 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)
  860. {
  861. // this is kinda dirty, but...
  862. //
  863. int iFontIndex = MenuFontToHandle(iMenuFont);
  864. //float fMax = *maxX;
  865. int iPixelLen = trap_R_Font_StrLenPixels(text, iFontIndex, scale);
  866. if (x + iPixelLen > *maxX)
  867. {
  868. // whole text won't fit, so we need to print just the amount that does...
  869. // Ok, this is slow and tacky, but only called occasionally, and it works...
  870. //
  871. char sTemp[4096]={0}; // lazy assumption
  872. const char *psText = text;
  873. char *psOut = &sTemp[0];
  874. char *psOutLastGood = psOut;
  875. unsigned int uiLetter;
  876. while (*psText && (x + trap_R_Font_StrLenPixels(sTemp, iFontIndex, scale)<=*maxX)
  877. && psOut < &sTemp[sizeof(sTemp)-1] // sanity
  878. )
  879. {
  880. int iAdvanceCount;
  881. psOutLastGood = psOut;
  882. uiLetter = trap_AnyLanguage_ReadCharFromString(psText, &iAdvanceCount, NULL);
  883. psText += iAdvanceCount;
  884. if (uiLetter > 255)
  885. {
  886. *psOut++ = uiLetter>>8;
  887. *psOut++ = uiLetter&0xFF;
  888. }
  889. else
  890. {
  891. *psOut++ = uiLetter&0xFF;
  892. }
  893. }
  894. *psOutLastGood = '\0';
  895. *maxX = 0; // feedback
  896. Text_Paint(x, y, scale, color, sTemp, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
  897. }
  898. else
  899. {
  900. // whole text fits fine, so print it all...
  901. //
  902. *maxX = x + iPixelLen; // feedback the next position, as the caller expects
  903. Text_Paint(x, y, scale, color, text, adjust, limit, ITEM_TEXTSTYLE_NORMAL, iMenuFont);
  904. }
  905. }
  906. void UI_ShowPostGame(qboolean newHigh) {
  907. trap_Cvar_Set ("cg_cameraOrbit", "0");
  908. trap_Cvar_Set("cg_thirdPerson", "0");
  909. trap_Cvar_Set( "sv_killserver", "1" );
  910. uiInfo.soundHighScore = newHigh;
  911. _UI_SetActiveMenu(UIMENU_POSTGAME);
  912. }
  913. /*
  914. =================
  915. _UI_Refresh
  916. =================
  917. */
  918. void UI_DrawCenteredPic(qhandle_t image, int w, int h) {
  919. int x, y;
  920. x = (SCREEN_WIDTH - w) / 2;
  921. y = (SCREEN_HEIGHT - h) / 2;
  922. UI_DrawHandlePic(x, y, w, h, image);
  923. }
  924. int frameCount = 0;
  925. int startTime;
  926. vmCvar_t ui_rankChange;
  927. static void UI_BuildPlayerList();
  928. //[UITweaks]
  929. /* not used in basejka code
  930. //char parsedFPMessage[1024];
  931. #include "../namespace_begin.h"
  932. extern int FPMessageTime;
  933. #include "../namespace_end.h"
  934. */
  935. //[/UITweaks]
  936. void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust, int iMenuFont);
  937. const char *UI_GetStringEdString(const char *refSection, const char *refName)
  938. {
  939. static char text[1024]={0};
  940. trap_SP_GetStringTextString(va("%s_%s", refSection, refName), text, sizeof(text));
  941. return text;
  942. }
  943. #define UI_FPS_FRAMES 4
  944. void _UI_Refresh( int realtime )
  945. {
  946. static int index;
  947. static int previousTimes[UI_FPS_FRAMES];
  948. //if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
  949. // return;
  950. //}
  951. trap_G2API_SetTime(realtime, 0);
  952. trap_G2API_SetTime(realtime, 1);
  953. //ghoul2 timer must be explicitly updated during ui rendering.
  954. uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime;
  955. uiInfo.uiDC.realTime = realtime;
  956. previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime;
  957. index++;
  958. if ( index > UI_FPS_FRAMES ) {
  959. int i, total;
  960. // average multiple frames together to smooth changes out a bit
  961. total = 0;
  962. for ( i = 0 ; i < UI_FPS_FRAMES ; i++ ) {
  963. total += previousTimes[i];
  964. }
  965. if ( !total ) {
  966. total = 1;
  967. }
  968. uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total;
  969. }
  970. UI_UpdateCvars();
  971. if (Menu_Count() > 0) {
  972. // paint all the menus
  973. Menu_PaintAll();
  974. // refresh server browser list
  975. UI_DoServerRefresh();
  976. // refresh server status
  977. UI_BuildServerStatus(qfalse);
  978. // refresh find player list
  979. UI_BuildFindPlayerList(qfalse);
  980. }
  981. // draw cursor
  982. UI_SetColor( NULL );
  983. if (Menu_Count() > 0) {
  984. uiClientState_t cstate;
  985. trap_GetClientState( &cstate );
  986. if(cstate.connState <= CA_DISCONNECTED || cstate.connState >= CA_ACTIVE) {
  987. UI_DrawHandlePic( uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory, 48, 48, uiInfo.uiDC.Assets.cursor);
  988. }
  989. }
  990. #ifndef NDEBUG
  991. if (uiInfo.uiDC.debug)
  992. {
  993. // cursor coordinates
  994. //FIXME
  995. //UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed );
  996. }
  997. #endif
  998. //[ExpSys]
  999. //only do this stuff when the your point total has changed.
  1000. if (ui_rankChange.integer != uiMaxRank)
  1001. //if (ui_rankChange.integer)
  1002. //[/ExpSys]
  1003. {
  1004. //[UITweaks]
  1005. //not used in basejka code
  1006. /*
  1007. FPMessageTime = realtime + 3000;
  1008. if (!parsedFPMessage[0] /*&& uiMaxRank > ui_rankChange.integer*//*)
  1009. {
  1010. const char *printMessage = UI_GetStringEdString("MP_INGAME", "SET_NEW_RANK");
  1011. int i = 0;
  1012. int p = 0;
  1013. int linecount = 0;
  1014. while (printMessage[i] && p < 1024)
  1015. {
  1016. parsedFPMessage[p] = printMessage[i];
  1017. p++;
  1018. i++;
  1019. linecount++;
  1020. if (linecount > 64 && printMessage[i] == ' ')
  1021. {
  1022. parsedFPMessage[p] = '\n';
  1023. p++;
  1024. linecount = 0;
  1025. }
  1026. }
  1027. parsedFPMessage[p] = '\0';
  1028. }
  1029. */
  1030. //[/UITweaks]
  1031. //if (uiMaxRank > ui_rankChange.integer)
  1032. {
  1033. uiMaxRank = ui_rankChange.integer;
  1034. uiForceRank = uiMaxRank;
  1035. /*
  1036. while (x < NUM_FORCE_POWERS)
  1037. {
  1038. //For now just go ahead and clear force powers upon rank change
  1039. uiRank[x].uiForcePowersRank = 0;
  1040. x++;
  1041. }
  1042. uiRank[FP_LEVITATION].uiForcePowersRank = 1;
  1043. uiForceUsed = 0;
  1044. */
  1045. //Use BG_LegalizedForcePowers and transfer the result into the UI force settings
  1046. UI_ReadLegalForce();
  1047. }
  1048. if (ui_freeSaber.integer && uiRank[FP_SABER_OFFENSE].uiForcePowersRank < 1)
  1049. {
  1050. uiRank[FP_SABER_OFFENSE].uiForcePowersRank = 1;
  1051. }
  1052. if (ui_freeSaber.integer && uiRank[FP_SABER_DEFENSE].uiForcePowersRank < 1)
  1053. {
  1054. uiRank[FP_SABER_DEFENSE].uiForcePowersRank = 1;
  1055. }
  1056. //[ExpSys]
  1057. //ui_rankChange is now treated like a variable rather than a message sender
  1058. //trap_Cvar_Set("ui_rankChange", "0");
  1059. //[/ExpSys]
  1060. //remember to update the force power count after changing the max rank
  1061. UpdateForceUsed();
  1062. }
  1063. if (ui_freeSaber.integer)
  1064. {
  1065. bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 0;
  1066. bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 0;
  1067. }
  1068. else
  1069. {
  1070. //[ExpSys]
  1071. //use defines since we're tweaking these values for the experience system.
  1072. bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = SABER_OFFENSE_L1;
  1073. bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = SABER_DEFENSE_L1;
  1074. //bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 1;
  1075. //bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 1;
  1076. //[/ExpSys]
  1077. }
  1078. /*
  1079. if (parsedFPMessage[0] && FPMessageTime > realtime)
  1080. {
  1081. vec4_t txtCol;
  1082. int txtStyle = ITEM_TEXTSTYLE_SHADOWED;
  1083. if ((FPMessageTime - realtime) < 2000)
  1084. {
  1085. txtCol[0] = colorWhite[0];
  1086. txtCol[1] = colorWhite[1];
  1087. txtCol[2] = colorWhite[2];
  1088. txtCol[3] = (((float)FPMessageTime - (float)realtime)/2000);
  1089. txtStyle = 0;
  1090. }
  1091. else
  1092. {
  1093. txtCol[0] = colorWhite[0];
  1094. txtCol[1] = colorWhite[1];
  1095. txtCol[2] = colorWhite[2];
  1096. txtCol[3] = colorWhite[3];
  1097. }
  1098. Text_Paint(10, 0, 1, txtCol, parsedFPMessage, 0, 1024, txtStyle, FONT_MEDIUM);
  1099. }
  1100. */
  1101. //For now, don't bother.
  1102. }
  1103. /*
  1104. =================
  1105. _UI_Shutdown
  1106. =================
  1107. */
  1108. #include "../namespace_begin.h"
  1109. void UI_CleanupGhoul2(void);
  1110. #include "../namespace_end.h"
  1111. //[DynamicMemory_Sabers]
  1112. void UI_FreeSabers(void);
  1113. //[/DynamicMemory_Sabers]
  1114. void _UI_Shutdown( void ) {
  1115. trap_LAN_SaveCachedServers();
  1116. UI_CleanupGhoul2();
  1117. //[DynamicMemory_Sabers]
  1118. UI_FreeSabers();
  1119. //[/DynamicMemory_Sabers]
  1120. }
  1121. char *defaultMenu = NULL;
  1122. char *GetMenuBuffer(const char *filename) {
  1123. int len;
  1124. fileHandle_t f;
  1125. static char buf[MAX_MENUFILE];
  1126. len = trap_FS_FOpenFile( filename, &f, FS_READ );
  1127. if ( !f ) {
  1128. trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
  1129. return defaultMenu;
  1130. }
  1131. if ( len >= MAX_MENUFILE ) {
  1132. trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) );
  1133. trap_FS_FCloseFile( f );
  1134. return defaultMenu;
  1135. }
  1136. trap_FS_Read( buf, len, f );
  1137. buf[len] = 0;
  1138. trap_FS_FCloseFile( f );
  1139. //COM_Compress(buf);
  1140. return buf;
  1141. }
  1142. qboolean Asset_Parse(int handle) {
  1143. pc_token_t token;
  1144. if (!trap_PC_ReadToken(handle, &token))
  1145. return qfalse;
  1146. if (Q_stricmp(token.string, "{") != 0) {
  1147. return qfalse;
  1148. }
  1149. while ( 1 ) {
  1150. memset(&token, 0, sizeof(pc_token_t));
  1151. if (!trap_PC_ReadToken(handle, &token))
  1152. return qfalse;
  1153. if (Q_stricmp(token.string, "}") == 0) {
  1154. return qtrue;
  1155. }
  1156. // font
  1157. if (Q_stricmp(token.string, "font") == 0) {
  1158. int pointSize;
  1159. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1160. return qfalse;
  1161. }
  1162. //trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont);
  1163. uiInfo.uiDC.Assets.qhMediumFont = trap_R_RegisterFont(token.string);
  1164. uiInfo.uiDC.Assets.fontRegistered = qtrue;
  1165. continue;
  1166. }
  1167. if (Q_stricmp(token.string, "smallFont") == 0) {
  1168. int pointSize;
  1169. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1170. return qfalse;
  1171. }
  1172. //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.smallFont);
  1173. uiInfo.uiDC.Assets.qhSmallFont = trap_R_RegisterFont(token.string);
  1174. continue;
  1175. }
  1176. if (Q_stricmp(token.string, "small2Font") == 0) {
  1177. int pointSize;
  1178. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1179. return qfalse;
  1180. }
  1181. //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.smallFont);
  1182. uiInfo.uiDC.Assets.qhSmall2Font = trap_R_RegisterFont(token.string);
  1183. continue;
  1184. }
  1185. if (Q_stricmp(token.string, "bigFont") == 0) {
  1186. int pointSize;
  1187. if (!trap_PC_ReadToken(handle, &token) || !PC_Int_Parse(handle,&pointSize)) {
  1188. return qfalse;
  1189. }
  1190. //trap_R_RegisterFont(token, pointSize, &uiInfo.uiDC.Assets.bigFont);
  1191. uiInfo.uiDC.Assets.qhBigFont = trap_R_RegisterFont(token.string);
  1192. continue;
  1193. }
  1194. if (Q_stricmp(token.string, "cursor") == 0)
  1195. {
  1196. if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr))
  1197. {
  1198. Com_Printf(S_COLOR_YELLOW,"Bad 1st parameter for keyword 'cursor'");
  1199. return qfalse;
  1200. }
  1201. uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr);
  1202. continue;
  1203. }
  1204. // gradientbar
  1205. if (Q_stricmp(token.string, "gradientbar") == 0) {
  1206. if (!trap_PC_ReadToken(handle, &token)) {
  1207. return qfalse;
  1208. }
  1209. uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(token.string);
  1210. continue;
  1211. }
  1212. // enterMenuSound
  1213. if (Q_stricmp(token.string, "menuEnterSound") == 0) {
  1214. if (!trap_PC_ReadToken(handle, &token)) {
  1215. return qfalse;
  1216. }
  1217. uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( token.string );
  1218. continue;
  1219. }
  1220. // exitMenuSound
  1221. if (Q_stricmp(token.string, "menuExitSound") == 0) {
  1222. if (!trap_PC_ReadToken(handle, &token)) {
  1223. return qfalse;
  1224. }
  1225. uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( token.string );
  1226. continue;
  1227. }
  1228. // itemFocusSound
  1229. if (Q_stricmp(token.string, "itemFocusSound") == 0) {
  1230. if (!trap_PC_ReadToken(handle, &token)) {
  1231. return qfalse;
  1232. }
  1233. uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( token.string );
  1234. continue;
  1235. }
  1236. // menuBuzzSound
  1237. if (Q_stricmp(token.string, "menuBuzzSound") == 0) {
  1238. if (!trap_PC_ReadToken(handle, &token)) {
  1239. return qfalse;
  1240. }
  1241. uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( token.string );
  1242. continue;
  1243. }
  1244. if (Q_stricmp(token.string, "fadeClamp") == 0) {
  1245. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp)) {
  1246. return qfalse;
  1247. }
  1248. continue;
  1249. }
  1250. if (Q_stricmp(token.string, "fadeCycle") == 0) {
  1251. if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle)) {
  1252. return qfalse;
  1253. }
  1254. continue;
  1255. }
  1256. if (Q_stricmp(token.string, "fadeAmount") == 0) {
  1257. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount)) {
  1258. return qfalse;
  1259. }
  1260. continue;
  1261. }
  1262. if (Q_stricmp(token.string, "shadowX") == 0) {
  1263. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX)) {
  1264. return qfalse;
  1265. }
  1266. continue;
  1267. }
  1268. if (Q_stricmp(token.string, "shadowY") == 0) {
  1269. if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY)) {
  1270. return qfalse;
  1271. }
  1272. continue;
  1273. }
  1274. if (Q_stricmp(token.string, "shadowColor") == 0) {
  1275. if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor)) {
  1276. return qfalse;
  1277. }
  1278. uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3];
  1279. continue;
  1280. }
  1281. if (Q_stricmp(token.string, "moveRollSound") == 0)
  1282. {
  1283. if (trap_PC_ReadToken(handle,&token))
  1284. {
  1285. uiInfo.uiDC.Assets.moveRollSound = trap_S_RegisterSound( token.string );
  1286. }
  1287. continue;
  1288. }
  1289. if (Q_stricmp(token.string, "moveJumpSound") == 0)
  1290. {
  1291. if (trap_PC_ReadToken(handle,&token))
  1292. {
  1293. uiInfo.uiDC.Assets.moveJumpSound = trap_S_RegisterSound( token.string );
  1294. }
  1295. continue;
  1296. }
  1297. if (Q_stricmp(token.string, "datapadmoveSaberSound1") == 0)
  1298. {
  1299. if (trap_PC_ReadToken(handle,&token))
  1300. {
  1301. uiInfo.uiDC.Assets.datapadmoveSaberSound1 = trap_S_RegisterSound( token.string );
  1302. }
  1303. continue;
  1304. }
  1305. if (Q_stricmp(token.string, "datapadmoveSaberSound2") == 0)
  1306. {
  1307. if (trap_PC_ReadToken(handle,&token))
  1308. {
  1309. uiInfo.uiDC.Assets.datapadmoveSaberSound2 = trap_S_RegisterSound( token.string );
  1310. }
  1311. continue;
  1312. }
  1313. if (Q_stricmp(token.string, "datapadmoveSaberSound3") == 0)
  1314. {
  1315. if (trap_PC_ReadToken(handle,&token))
  1316. {
  1317. uiInfo.uiDC.Assets.datapadmoveSaberSound3 = trap_S_RegisterSound( token.string );
  1318. }
  1319. continue;
  1320. }
  1321. if (Q_stricmp(token.string, "datapadmoveSaberSound4") == 0)
  1322. {
  1323. if (trap_PC_ReadToken(handle,&token))
  1324. {
  1325. uiInfo.uiDC.Assets.datapadmoveSaberSound4 = trap_S_RegisterSound( token.string );
  1326. }
  1327. continue;
  1328. }
  1329. if (Q_stricmp(token.string, "datapadmoveSaberSound5") == 0)
  1330. {
  1331. if (trap_PC_ReadToken(handle,&token))
  1332. {
  1333. uiInfo.uiDC.Assets.datapadmoveSaberSound5 = trap_S_RegisterSound( token.string );
  1334. }
  1335. continue;
  1336. }
  1337. if (Q_stricmp(token.string, "datapadmoveSaberSound6") == 0)
  1338. {
  1339. if (trap_PC_ReadToken(handle,&token))
  1340. {
  1341. uiInfo.uiDC.Assets.datapadmoveSaberSound6 = trap_S_RegisterSound( token.string );
  1342. }
  1343. continue;
  1344. }
  1345. // precaching various sound files used in the menus
  1346. if (Q_stricmp(token.string, "precacheSound") == 0)
  1347. {
  1348. const char *tempStr;
  1349. if (PC_Script_Parse(handle, &tempStr))
  1350. {
  1351. char *soundFile;
  1352. do
  1353. {
  1354. soundFile = COM_ParseExt(&tempStr, qfalse);
  1355. if (soundFile[0] != 0 && soundFile[0] != ';') {
  1356. trap_S_RegisterSound( soundFile);
  1357. }
  1358. } while (soundFile[0]);
  1359. }
  1360. continue;
  1361. }
  1362. }
  1363. return qfalse;
  1364. }
  1365. void UI_Report() {
  1366. String_Report();
  1367. //Font_Report();
  1368. }
  1369. void UI_ParseMenu(const char *menuFile) {
  1370. int handle;
  1371. pc_token_t token;
  1372. //Com_Printf("Parsing menu file: %s\n", menuFile);
  1373. handle = trap_PC_LoadSource(menuFile);
  1374. if (!handle) {
  1375. return;
  1376. }
  1377. while ( 1 ) {
  1378. memset(&token, 0, sizeof(pc_token_t));
  1379. if (!trap_PC_ReadToken( handle, &token )) {
  1380. break;
  1381. }
  1382. //if ( Q_stricmp( token, "{" ) ) {
  1383. // Com_Printf( "Missing { in menu file\n" );
  1384. // break;
  1385. //}
  1386. //if ( menuCount == MAX_MENUS ) {
  1387. // Com_Printf( "Too many menus!\n" );
  1388. // break;
  1389. //}
  1390. if ( token.string[0] == '}' ) {
  1391. break;
  1392. }
  1393. if (Q_stricmp(token.string, "assetGlobalDef") == 0) {
  1394. if (Asset_Parse(handle)) {
  1395. continue;
  1396. } else {
  1397. break;
  1398. }
  1399. }
  1400. if (Q_stricmp(token.string, "menudef") == 0) {
  1401. // start a new menu
  1402. Menu_New(handle);
  1403. }
  1404. }
  1405. trap_PC_FreeSource(handle);
  1406. }
  1407. //[CoOp]
  1408. void UI_LoadSingleMenuFile(const char *menuFile)
  1409. {//load in a single menu file
  1410. trap_PC_LoadGlobalDefines ( "ui/jamp/menudef.h" ); //Load globaldefines for parsing.
  1411. UI_ParseMenu(menuFile);
  1412. trap_PC_RemoveAllGlobalDefines ( ); //Close globaldefines.
  1413. }
  1414. //[/CoOp]
  1415. qboolean Load_Menu(int handle) {
  1416. pc_token_t token;
  1417. if (!trap_PC_ReadToken(handle, &token))
  1418. return qfalse;
  1419. if (token.string[0] != '{') {
  1420. return qfalse;
  1421. }
  1422. while ( 1 ) {
  1423. if (!trap_PC_ReadToken(handle, &token))
  1424. return qfalse;
  1425. if ( token.string[0] == 0 ) {
  1426. return qfalse;
  1427. }
  1428. if ( token.string[0] == '}' ) {
  1429. return qtrue;
  1430. }
  1431. UI_ParseMenu(token.string);
  1432. }
  1433. return qfalse;
  1434. }
  1435. void UI_LoadMenus(const char *menuFile, qboolean reset) {
  1436. pc_token_t token;
  1437. int handle;
  1438. int start;
  1439. start = trap_Milliseconds();
  1440. trap_PC_LoadGlobalDefines ( "ui/jamp/menudef.h" );
  1441. handle = trap_PC_LoadSource( menuFile );
  1442. if (!handle) {
  1443. Com_Printf( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile );
  1444. handle = trap_PC_LoadSource( "ui/jampmenus.txt" );
  1445. if (!handle) {
  1446. trap_Error( va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n", menuFile ) );
  1447. }
  1448. }
  1449. if (reset) {
  1450. Menu_Reset();
  1451. }
  1452. while ( 1 ) {
  1453. if (!trap_PC_ReadToken(handle, &token))
  1454. break;
  1455. if( token.string[0] == 0 || token.string[0] == '}') {
  1456. break;
  1457. }
  1458. if ( token.string[0] == '}' ) {
  1459. break;
  1460. }
  1461. if (Q_stricmp(token.string, "loadmenu") == 0) {
  1462. if (Load_Menu(handle)) {
  1463. continue;
  1464. } else {
  1465. break;
  1466. }
  1467. }
  1468. }
  1469. // Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start);
  1470. trap_PC_FreeSource( handle );
  1471. trap_PC_RemoveAllGlobalDefines ( );
  1472. }
  1473. void UI_Load() {
  1474. char *menuSet;
  1475. char lastName[1024];
  1476. menuDef_t *menu = Menu_GetFocused();
  1477. if (menu && menu->window.name) {
  1478. strcpy(lastName, menu->window.name);
  1479. }
  1480. else
  1481. {
  1482. lastName[0] = 0;
  1483. }
  1484. if (uiInfo.inGameLoad)
  1485. {
  1486. menuSet= "ui/jampingame.txt";
  1487. }
  1488. else
  1489. {
  1490. menuSet= UI_Cvar_VariableString("ui_menuFilesMP");
  1491. }
  1492. if (menuSet == NULL || menuSet[0] == '\0') {
  1493. menuSet = "ui/jampmenus.txt";
  1494. }
  1495. String_Init();
  1496. #ifdef PRE_RELEASE_TADEMO
  1497. UI_ParseGameInfo("demogameinfo.txt");
  1498. #else
  1499. UI_ParseGameInfo("ui/jamp/gameinfo.txt");
  1500. #endif
  1501. UI_LoadArenas();
  1502. UI_LoadBots();
  1503. UI_LoadMenus(menuSet, qtrue);
  1504. Menus_CloseAll();
  1505. Menus_ActivateByName(lastName);
  1506. }
  1507. 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};
  1508. static void UI_DrawHandicap(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  1509. int i, h;
  1510. h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
  1511. i = 20 - h / 5;
  1512. Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle, iMenuFont);
  1513. }
  1514. static void UI_DrawClanName(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  1515. Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_teamName"), 0, 0, textStyle, iMenuFont);
  1516. }
  1517. static void UI_SetCapFragLimits(qboolean uiVars) {
  1518. int cap = 5;
  1519. int frag = 10;
  1520. if (uiVars) {
  1521. trap_Cvar_Set("ui_captureLimit", va("%d", cap));
  1522. trap_Cvar_Set("ui_fragLimit", va("%d", frag));
  1523. } else {
  1524. trap_Cvar_Set("capturelimit", va("%d", cap));
  1525. trap_Cvar_Set("fraglimit", va("%d", frag));
  1526. }
  1527. }
  1528. static const char* UI_GetGameTypeName(int gtEnum)
  1529. {
  1530. switch ( gtEnum )
  1531. {
  1532. case GT_FFA:
  1533. return UI_GetStringEdString("MENUS", "FREE_FOR_ALL");//"Free For All";
  1534. case GT_HOLOCRON:
  1535. return UI_GetStringEdString("MENUS", "HOLOCRON_FFA");//"Holocron FFA";
  1536. case GT_JEDIMASTER:
  1537. //[OLDGAMETYPES]
  1538. //return UI_GetStringEdString("MENUS", "SAGA");//"Jedi Master";??
  1539. return UI_GetStringEdString("OJP_MENUS", "JEDIMASTER");//"Jedi Master";??
  1540. //[/OLDGAMETYPES]
  1541. case GT_SINGLE_PLAYER:
  1542. //[CoOp]
  1543. return UI_GetStringEdString("OJP_MENUS", "COOP");
  1544. //return UI_GetStringEdString("MENUS", "SAGA");//"Team FFA";
  1545. //[/CoOp]
  1546. case GT_DUEL:
  1547. return UI_GetStringEdString("MENUS", "DUEL");//"Team FFA";
  1548. case GT_POWERDUEL:
  1549. return UI_GetStringEdString("MENUS", "POWERDUEL");//"Team FFA";
  1550. case GT_TEAM:
  1551. return UI_GetStringEdString("MENUS", "TEAM_FFA");//"Team FFA";
  1552. case GT_SIEGE:
  1553. return UI_GetStringEdString("MENUS", "SIEGE");//"Siege";
  1554. case GT_CTF:
  1555. return UI_GetStringEdString("MENUS", "CAPTURE_THE_FLAG");//"Capture the Flag";
  1556. case GT_CTY:
  1557. return UI_GetStringEdString("MENUS", "CAPTURE_THE_YSALIMARI");//"Capture the Ysalamiri";
  1558. }
  1559. return UI_GetStringEdString("MENUS", "SAGA");//"Team FFA";
  1560. }
  1561. // ui_gameType assumes gametype 0 is -1 ALL and will not show
  1562. static void UI_DrawGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont)
  1563. {
  1564. Text_Paint(rect->x, rect->y, scale, color, UI_GetGameTypeName(uiInfo.gameTypes[ui_gameType.integer].gtEnum), 0, 0, textStyle, iMenuFont);
  1565. }
  1566. static void UI_DrawNetGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont)
  1567. {
  1568. if (ui_netGameType.integer < 0 || ui_netGameType.integer >= uiInfo.numGameTypes)
  1569. {
  1570. trap_Cvar_Set("ui_netGameType", "0");
  1571. trap_Cvar_Set("ui_actualNetGameType", "0");
  1572. }
  1573. Text_Paint(rect->x, rect->y, scale, color, UI_GetGameTypeName(uiInfo.gameTypes[ui_netGameType.integer].gtEnum) , 0, 0, textStyle, iMenuFont);
  1574. }
  1575. static void UI_DrawAutoSwitch(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  1576. int switchVal = trap_Cvar_VariableValue("cg_autoswitch");
  1577. const char *switchString = "AUTOSWITCH1";
  1578. const char *stripString = NULL;
  1579. switch(switchVal)
  1580. {
  1581. case 2:
  1582. switchString = "AUTOSWITCH2";
  1583. break;
  1584. case 3:
  1585. switchString = "AUTOSWITCH3";
  1586. break;
  1587. case 0:
  1588. switchString = "AUTOSWITCH0";
  1589. break;
  1590. default:
  1591. break;
  1592. }
  1593. stripString = UI_GetStringEdString("MP_INGAME", (char *)switchString);
  1594. if (stripString)
  1595. {
  1596. Text_Paint(rect->x, rect->y, scale, color, stripString, 0, 0, textStyle, iMenuFont);
  1597. }
  1598. }
  1599. static void UI_DrawJoinGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont)
  1600. {
  1601. if (ui_joinGameType.integer < 0 || ui_joinGameType.integer > uiInfo.numJoinGameTypes)
  1602. {
  1603. trap_Cvar_Set("ui_joinGameType", "0");
  1604. }
  1605. Text_Paint(rect->x, rect->y, scale, color, UI_GetGameTypeName(uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum) , 0, 0, textStyle, iMenuFont);
  1606. }
  1607. static int UI_TeamIndexFromName(const char *name) {
  1608. int i;
  1609. if (name && *name) {
  1610. for (i = 0; i < uiInfo.teamCount; i++) {
  1611. if (Q_stricmp(name, uiInfo.teamList[i].teamName) == 0) {
  1612. return i;
  1613. }
  1614. }
  1615. }
  1616. return 0;
  1617. }
  1618. static void UI_DrawClanLogo(rectDef_t *rect, float scale, vec4_t color) {
  1619. int i;
  1620. i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  1621. if (i >= 0 && i < uiInfo.teamCount) {
  1622. trap_R_SetColor( color );
  1623. if (uiInfo.teamList[i].teamIcon == -1) {
  1624. uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
  1625. uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
  1626. uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
  1627. }
  1628. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon);
  1629. trap_R_SetColor(NULL);
  1630. }
  1631. }
  1632. static void UI_DrawClanCinematic(rectDef_t *rect, float scale, vec4_t color) {
  1633. int i;
  1634. i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  1635. if (i >= 0 && i < uiInfo.teamCount) {
  1636. if (uiInfo.teamList[i].cinematic >= -2) {
  1637. if (uiInfo.teamList[i].cinematic == -1) {
  1638. uiInfo.teamList[i].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.teamList[i].imageName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
  1639. }
  1640. if (uiInfo.teamList[i].cinematic >= 0) {
  1641. trap_CIN_RunCinematic(uiInfo.teamList[i].cinematic);
  1642. trap_CIN_SetExtents(uiInfo.teamList[i].cinematic, rect->x, rect->y, rect->w, rect->h);
  1643. trap_CIN_DrawCinematic(uiInfo.teamList[i].cinematic);
  1644. } else {
  1645. trap_R_SetColor( color );
  1646. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal);
  1647. trap_R_SetColor(NULL);
  1648. uiInfo.teamList[i].cinematic = -2;
  1649. }
  1650. } else {
  1651. trap_R_SetColor( color );
  1652. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon);
  1653. trap_R_SetColor(NULL);
  1654. }
  1655. }
  1656. }
  1657. static void UI_DrawPreviewCinematic(rectDef_t *rect, float scale, vec4_t color) {
  1658. if (uiInfo.previewMovie > -2) {
  1659. uiInfo.previewMovie = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.movieList[uiInfo.movieIndex]), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
  1660. if (uiInfo.previewMovie >= 0) {
  1661. trap_CIN_RunCinematic(uiInfo.previewMovie);
  1662. trap_CIN_SetExtents(uiInfo.previewMovie, rect->x, rect->y, rect->w, rect->h);
  1663. trap_CIN_DrawCinematic(uiInfo.previewMovie);
  1664. } else {
  1665. uiInfo.previewMovie = -2;
  1666. }
  1667. }
  1668. }
  1669. static void UI_DrawSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  1670. int i;
  1671. i = trap_Cvar_VariableValue( "g_spSkill" );
  1672. if (i < 1 || i > numSkillLevels) {
  1673. i = 1;
  1674. }
  1675. Text_Paint(rect->x, rect->y, scale, color, (char *)UI_GetStringEdString("MP_INGAME", (char *)skillLevels[i-1]),0, 0, textStyle, iMenuFont);
  1676. }
  1677. static void UI_DrawGenericNum(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int type,int iMenuFont)
  1678. {
  1679. int i;
  1680. char s[256];
  1681. i = val;
  1682. if (i < min || i > max)
  1683. {
  1684. i = min;
  1685. }
  1686. Com_sprintf(s, sizeof(s), "%i", val);
  1687. Text_Paint(rect->x, rect->y, scale, color, s,0, 0, textStyle, iMenuFont);
  1688. }
  1689. static void UI_DrawForceMastery(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
  1690. {//racc - renders the player's current force mastery level to the screen.
  1691. int i;
  1692. //[ExpSys]
  1693. int x;
  1694. //[/ExpSys]
  1695. char *s;
  1696. i = val;
  1697. if (i < min)
  1698. {
  1699. i = min;
  1700. }
  1701. //[ExpSys]
  1702. //initialize s to make the compiler happy. However, the below code shouldn't ever NOT set s.
  1703. s = (char *)UI_GetStringEdString("MP_INGAME", forceMasteryLevels[0]);
  1704. //allowing for dynamic skill point totals. Determine rank based on the highest mastery
  1705. //level the player has points for.
  1706. for(x = NUM_FORCE_MASTERY_LEVELS-1; x >= 0; x--)
  1707. {
  1708. if(i >= forceMasteryPoints[x])
  1709. {//we've found the highest level mastery that we have the skill points for.
  1710. s = (char *)UI_GetStringEdString("MP_INGAME", forceMasteryLevels[x]);
  1711. break;
  1712. }
  1713. }
  1714. /* basejka code
  1715. if (i > max)
  1716. {
  1717. i = max;
  1718. }
  1719. s = (char *)UI_GetStringEdString("MP_INGAME", forceMasteryLevels[i]);
  1720. */
  1721. //[/ExpSys]
  1722. Text_Paint(rect->x, rect->y, scale, color, s, 0, 0, textStyle, iMenuFont);
  1723. }
  1724. static void UI_DrawSkinColor(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
  1725. {
  1726. char s[256];
  1727. switch(val)
  1728. {
  1729. case TEAM_RED:
  1730. trap_SP_GetStringTextString("MENUS_TEAM_RED", s, sizeof(s));
  1731. // Com_sprintf(s, sizeof(s), "Red\0");
  1732. break;
  1733. case TEAM_BLUE:
  1734. trap_SP_GetStringTextString("MENUS_TEAM_BLUE", s, sizeof(s));
  1735. // Com_sprintf(s, sizeof(s), "Blue\0");
  1736. break;
  1737. default:
  1738. trap_SP_GetStringTextString("MENUS_DEFAULT", s, sizeof(s));
  1739. // Com_sprintf(s, sizeof(s), "Default\0");
  1740. break;
  1741. }
  1742. Text_Paint(rect->x, rect->y, scale, color, s, 0, 0, textStyle, iMenuFont);
  1743. }
  1744. static void UI_DrawForceSide(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
  1745. {
  1746. char s[256];
  1747. menuDef_t *menu;
  1748. char info[MAX_INFO_VALUE];
  1749. info[0] = '\0';
  1750. trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
  1751. if (atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ))
  1752. {
  1753. switch((int)(trap_Cvar_VariableValue("ui_myteam")))
  1754. {
  1755. case TEAM_RED:
  1756. uiForceSide = FORCE_DARKSIDE;
  1757. color[0] = 0.2;
  1758. color[1] = 0.2;
  1759. color[2] = 0.2;
  1760. break;
  1761. case TEAM_BLUE:
  1762. uiForceSide = FORCE_LIGHTSIDE;
  1763. color[0] = 0.2;
  1764. color[1] = 0.2;
  1765. color[2] = 0.2;
  1766. break;
  1767. default:
  1768. break;
  1769. }
  1770. }
  1771. if (val == FORCE_LIGHTSIDE)
  1772. {
  1773. trap_SP_GetStringTextString("MENUS_FORCEDESC_LIGHT",s, sizeof(s));
  1774. menu = Menus_FindByName("forcealloc");
  1775. if (menu)
  1776. {
  1777. Menu_ShowItemByName(menu, "lightpowers", qtrue);
  1778. Menu_ShowItemByName(menu, "darkpowers", qfalse);
  1779. Menu_ShowItemByName(menu, "darkpowers_team", qfalse);
  1780. Menu_ShowItemByName(menu, "lightpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
  1781. }
  1782. menu = Menus_FindByName("ingame_playerforce");
  1783. if (menu)
  1784. {
  1785. Menu_ShowItemByName(menu, "lightpowers", qtrue);
  1786. Menu_ShowItemByName(menu, "darkpowers", qfalse);
  1787. Menu_ShowItemByName(menu, "darkpowers_team", qfalse);
  1788. Menu_ShowItemByName(menu, "lightpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
  1789. }
  1790. }
  1791. else
  1792. {
  1793. trap_SP_GetStringTextString("MENUS_FORCEDESC_DARK",s, sizeof(s));
  1794. menu = Menus_FindByName("forcealloc");
  1795. if (menu)
  1796. {
  1797. Menu_ShowItemByName(menu, "lightpowers", qfalse);
  1798. Menu_ShowItemByName(menu, "lightpowers_team", qfalse);
  1799. Menu_ShowItemByName(menu, "darkpowers", qtrue);
  1800. Menu_ShowItemByName(menu, "darkpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
  1801. }
  1802. menu = Menus_FindByName("ingame_playerforce");
  1803. if (menu)
  1804. {
  1805. Menu_ShowItemByName(menu, "lightpowers", qfalse);
  1806. Menu_ShowItemByName(menu, "lightpowers_team", qfalse);
  1807. Menu_ShowItemByName(menu, "darkpowers", qtrue);
  1808. Menu_ShowItemByName(menu, "darkpowers_team", qtrue);//(ui_gameType.integer >= GT_TEAM));
  1809. }
  1810. }
  1811. Text_Paint(rect->x, rect->y, scale, color, s,0, 0, textStyle, iMenuFont);
  1812. }
  1813. qboolean UI_HasSetSaberOnly( void )
  1814. {
  1815. char info[MAX_INFO_STRING];
  1816. int i = 0;
  1817. int wDisable = 0;
  1818. int gametype = 0;
  1819. gametype = atoi(Info_ValueForKey(info, "g_gametype"));
  1820. if ( gametype == GT_JEDIMASTER )
  1821. { //set to 0
  1822. return qfalse;
  1823. }
  1824. trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  1825. if (gametype == GT_DUEL || gametype == GT_POWERDUEL)
  1826. {
  1827. wDisable = atoi(Info_ValueForKey(info, "g_duelWeaponDisable"));
  1828. }
  1829. else
  1830. {
  1831. wDisable = atoi(Info_ValueForKey(info, "g_weaponDisable"));
  1832. }
  1833. while (i < WP_NUM_WEAPONS)
  1834. {
  1835. if (!(wDisable & (1 << i)) &&
  1836. i != WP_SABER && i != WP_NONE)
  1837. {
  1838. return qfalse;
  1839. }
  1840. i++;
  1841. }
  1842. return qtrue;
  1843. }
  1844. static qboolean UI_AllForceDisabled(int force)
  1845. {
  1846. int i;
  1847. if (force)
  1848. {
  1849. for (i=0;i<NUM_FORCE_POWERS;i++)
  1850. {
  1851. if (!(force & (1<<i)))
  1852. {
  1853. return qfalse;
  1854. }
  1855. }
  1856. return qtrue;
  1857. }
  1858. return qfalse;
  1859. }
  1860. qboolean UI_TrueJediEnabled( void )
  1861. {
  1862. char info[MAX_INFO_STRING];
  1863. int gametype = 0, disabledForce = 0, trueJedi = 0;
  1864. qboolean saberOnly = qfalse, allForceDisabled = qfalse;
  1865. trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  1866. //already have serverinfo at this point for stuff below. Don't bother trying to use ui_forcePowerDisable.
  1867. //if (ui_forcePowerDisable.integer)
  1868. //if (atoi(Info_ValueForKey(info, "g_forcePowerDisable")))
  1869. disabledForce = atoi(Info_ValueForKey(info, "g_forcePowerDisable"));
  1870. allForceDisabled = UI_AllForceDisabled(disabledForce);
  1871. gametype = atoi(Info_ValueForKey(info, "g_gametype"));
  1872. saberOnly = UI_HasSetSaberOnly();
  1873. if ( gametype == GT_HOLOCRON
  1874. || gametype == GT_JEDIMASTER
  1875. || saberOnly
  1876. || allForceDisabled )
  1877. {
  1878. trueJedi = 0;
  1879. }
  1880. else
  1881. {
  1882. trueJedi = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );
  1883. }
  1884. return (trueJedi != 0);
  1885. }
  1886. static void UI_DrawJediNonJedi(rectDef_t *rect, float scale, vec4_t color, int textStyle, int val, int min, int max, int iMenuFont)
  1887. {
  1888. int i;
  1889. char s[256];
  1890. //menuDef_t *menu;
  1891. char info[MAX_INFO_VALUE];
  1892. i = val;
  1893. if (i < min || i > max)
  1894. {
  1895. i = min;
  1896. }
  1897. info[0] = '\0';
  1898. trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
  1899. if ( !UI_TrueJediEnabled() )
  1900. {//true jedi mode is not on, do not draw this button type
  1901. return;
  1902. }
  1903. if ( val == FORCE_NONJEDI )
  1904. {
  1905. trap_SP_GetStringTextString("MENUS_NO",s, sizeof(s));
  1906. }
  1907. else
  1908. {
  1909. trap_SP_GetStringTextString("MENUS_YES",s, sizeof(s));
  1910. }
  1911. Text_Paint(rect->x, rect->y, scale, color, s,0, 0, textStyle, iMenuFont);
  1912. }
  1913. static void UI_DrawTeamName(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int textStyle, int iMenuFont) {
  1914. int i;
  1915. i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
  1916. if (i >= 0 && i < uiInfo.teamCount) {
  1917. Text_Paint(rect->x, rect->y, scale, color, va("%s: %s", (blue) ? "Blue" : "Red", uiInfo.teamList[i].teamName),0, 0, textStyle, iMenuFont);
  1918. }
  1919. }
  1920. static void UI_DrawTeamMember(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int num, int textStyle, int iMenuFont)
  1921. {
  1922. // 0 - None
  1923. // 1 - Human
  1924. // 2..NumCharacters - Bot
  1925. int value = trap_Cvar_VariableValue(va(blue ? "ui_blueteam%i" : "ui_redteam%i", num));
  1926. const char *text;
  1927. int maxcl = trap_Cvar_VariableValue( "sv_maxClients" );
  1928. vec4_t finalColor;
  1929. int numval = num;
  1930. numval *= 2;
  1931. if (blue)
  1932. {
  1933. numval -= 1;
  1934. }
  1935. finalColor[0] = color[0];
  1936. finalColor[1] = color[1];
  1937. finalColor[2] = color[2];
  1938. finalColor[3] = color[3];
  1939. if (numval > maxcl)
  1940. {
  1941. finalColor[0] *= 0.5;
  1942. finalColor[1] *= 0.5;
  1943. finalColor[2] *= 0.5;
  1944. value = -1;
  1945. }
  1946. //[UITweaks]
  1947. //allow players to use the addbots menu for the bots.
  1948. /*
  1949. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
  1950. {
  1951. if (value > 1 )
  1952. {
  1953. value = 1;
  1954. }
  1955. }
  1956. */
  1957. //[/UITweaks]
  1958. if (value <= 1) {
  1959. if (value == -1)
  1960. {
  1961. //text = "Closed";
  1962. text = UI_GetStringEdString("MENUS", "CLOSED");
  1963. }
  1964. else
  1965. {
  1966. //text = "Human";
  1967. text = UI_GetStringEdString("MENUS", "HUMAN");
  1968. }
  1969. } else {
  1970. value -= 2;
  1971. if (value >= UI_GetNumBots()) {
  1972. value = 1;
  1973. }
  1974. text = UI_GetBotNameByNumber(value);
  1975. }
  1976. Text_Paint(rect->x, rect->y, scale, finalColor, text, 0, 0, textStyle, iMenuFont);
  1977. }
  1978. static void UI_DrawEffects(rectDef_t *rect, float scale, vec4_t color)
  1979. {
  1980. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiSaberColorShaders[uiInfo.effectsColor]);
  1981. }
  1982. static void UI_DrawMapPreview(rectDef_t *rect, float scale, vec4_t color, qboolean net) {
  1983. int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
  1984. if (map < 0 || map > uiInfo.mapCount) {
  1985. if (net) {
  1986. ui_currentNetMap.integer = 0;
  1987. trap_Cvar_Set("ui_currentNetMap", "0");
  1988. } else {
  1989. ui_currentMap.integer = 0;
  1990. trap_Cvar_Set("ui_currentMap", "0");
  1991. }
  1992. map = 0;
  1993. }
  1994. if (uiInfo.mapList[map].levelShot == -1) {
  1995. uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[map].imageName);
  1996. }
  1997. if (uiInfo.mapList[map].levelShot > 0) {
  1998. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.mapList[map].levelShot);
  1999. } else {
  2000. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("menu/art/unknownmap_mp"));
  2001. }
  2002. }
  2003. static void UI_DrawMapTimeToBeat(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  2004. int minutes, seconds, time;
  2005. if (ui_currentMap.integer < 0 || ui_currentMap.integer > uiInfo.mapCount) {
  2006. ui_currentMap.integer = 0;
  2007. trap_Cvar_Set("ui_currentMap", "0");
  2008. }
  2009. time = uiInfo.mapList[ui_currentMap.integer].timeToBeat[uiInfo.gameTypes[ui_gameType.integer].gtEnum];
  2010. minutes = time / 60;
  2011. seconds = time % 60;
  2012. Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, textStyle, iMenuFont);
  2013. }
  2014. static void UI_DrawMapCinematic(rectDef_t *rect, float scale, vec4_t color, qboolean net) {
  2015. int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
  2016. if (map < 0 || map > uiInfo.mapCount) {
  2017. if (net) {
  2018. ui_currentNetMap.integer = 0;
  2019. trap_Cvar_Set("ui_currentNetMap", "0");
  2020. } else {
  2021. ui_currentMap.integer = 0;
  2022. trap_Cvar_Set("ui_currentMap", "0");
  2023. }
  2024. map = 0;
  2025. }
  2026. if (uiInfo.mapList[map].cinematic >= -1) {
  2027. if (uiInfo.mapList[map].cinematic == -1) {
  2028. uiInfo.mapList[map].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[map].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
  2029. }
  2030. if (uiInfo.mapList[map].cinematic >= 0) {
  2031. trap_CIN_RunCinematic(uiInfo.mapList[map].cinematic);
  2032. trap_CIN_SetExtents(uiInfo.mapList[map].cinematic, rect->x, rect->y, rect->w, rect->h);
  2033. trap_CIN_DrawCinematic(uiInfo.mapList[map].cinematic);
  2034. } else {
  2035. uiInfo.mapList[map].cinematic = -2;
  2036. }
  2037. } else {
  2038. UI_DrawMapPreview(rect, scale, color, net);
  2039. }
  2040. }
  2041. static void UI_SetForceDisabled(int force)
  2042. {//racc - Disables force powers in the menus based on current force powers disabled.
  2043. //This disables the individual force skill items in the menus and locks them to their desired "disabled" value.
  2044. int i = 0;
  2045. if (force)
  2046. {
  2047. while (i < NUM_FORCE_POWERS)
  2048. {
  2049. if (force & (1 << i))
  2050. {
  2051. uiRank[i].disabled = qtrue;
  2052. //[ExpSys]
  2053. //don't force Force Jump on players when that power is disabled.
  2054. if (i != FP_SABER_OFFENSE && i != FP_SABER_DEFENSE)
  2055. //if (i != FP_LEVITATION && i != FP_SABER_OFFENSE && i != FP_SABER_DEFENSE)
  2056. //[/ExpSys]
  2057. {
  2058. uiRank[i].uiForcePowersRank = 0;
  2059. }
  2060. else
  2061. {
  2062. //[ExpSys]
  2063. //don't force Force Jump on players when that power is disabled.
  2064. /*
  2065. if (i == FP_LEVITATION)
  2066. {
  2067. uiRank[i].uiForcePowersRank = 1;
  2068. }
  2069. else
  2070. */
  2071. //[/ExpSys]
  2072. {
  2073. uiRank[i].uiForcePowersRank = 3;
  2074. }
  2075. }
  2076. }
  2077. else
  2078. {
  2079. uiRank[i].disabled = qfalse;
  2080. }
  2081. i++;
  2082. }
  2083. }
  2084. else
  2085. {
  2086. i = 0;
  2087. while (i < NUM_FORCE_POWERS)
  2088. {
  2089. uiRank[i].disabled = qfalse;
  2090. i++;
  2091. }
  2092. }
  2093. }
  2094. // The game type on create server has changed - make the HUMAN/BOTS fields active
  2095. void UpdateBotButtons(void)
  2096. {
  2097. menuDef_t *menu;
  2098. menu = Menu_GetFocused();
  2099. if (!menu)
  2100. {
  2101. return;
  2102. }
  2103. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
  2104. {
  2105. Menu_ShowItemByName(menu, "humanbotfield", qfalse);
  2106. Menu_ShowItemByName(menu, "humanbotnonfield", qtrue);
  2107. }
  2108. else
  2109. {
  2110. Menu_ShowItemByName(menu, "humanbotfield", qtrue);
  2111. Menu_ShowItemByName(menu, "humanbotnonfield", qfalse);
  2112. }
  2113. }
  2114. void UpdateForceStatus()
  2115. {
  2116. menuDef_t *menu;
  2117. // Currently we don't make a distinction between those that wish to play Jedi of lower than maximum skill.
  2118. /* if (ui_forcePowerDisable.integer)
  2119. {
  2120. uiForceRank = 0;
  2121. uiForceAvailable = 0;
  2122. uiForceUsed = 0;
  2123. }
  2124. else
  2125. {
  2126. uiForceRank = uiMaxRank;
  2127. uiForceUsed = 0;
  2128. uiForceAvailable = forceMasteryPoints[uiForceRank];
  2129. }
  2130. */
  2131. menu = Menus_FindByName("ingame_player");
  2132. if (menu)
  2133. {
  2134. char info[MAX_INFO_STRING];
  2135. int disabledForce = 0;
  2136. qboolean trueJedi = qfalse, allForceDisabled = qfalse;
  2137. trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  2138. //already have serverinfo at this point for stuff below. Don't bother trying to use ui_forcePowerDisable.
  2139. //if (ui_forcePowerDisable.integer)
  2140. //if (atoi(Info_ValueForKey(info, "g_forcePowerDisable")))
  2141. disabledForce = atoi(Info_ValueForKey(info, "g_forcePowerDisable"));
  2142. allForceDisabled = UI_AllForceDisabled(disabledForce);
  2143. trueJedi = UI_TrueJediEnabled();
  2144. if ( !trueJedi || allForceDisabled )
  2145. {
  2146. Menu_ShowItemByName(menu, "jedinonjedi", qfalse);
  2147. }
  2148. else
  2149. {
  2150. Menu_ShowItemByName(menu, "jedinonjedi", qtrue);
  2151. }
  2152. if ( allForceDisabled == qtrue || (trueJedi && uiJediNonJedi == FORCE_NONJEDI) )
  2153. { // No force stuff
  2154. Menu_ShowItemByName(menu, "noforce", qtrue);
  2155. Menu_ShowItemByName(menu, "yesforce", qfalse);
  2156. // We don't want the saber explanation to say "configure saber attack 1" since we can't.
  2157. Menu_ShowItemByName(menu, "sabernoneconfigme", qfalse);
  2158. }
  2159. else
  2160. {
  2161. UI_SetForceDisabled(disabledForce);
  2162. Menu_ShowItemByName(menu, "noforce", qfalse);
  2163. Menu_ShowItemByName(menu, "yesforce", qtrue);
  2164. }
  2165. //[ExpSys]
  2166. //Made Force Seeing Level 1 a pre-req to taking any additional force powers, except in the case of free sabers.
  2167. if(uiRank[FP_SEE].uiForcePowersRank <= FORCE_LEVEL_0)
  2168. {//player isn't force sensitive
  2169. Menu_ShowItemByName(menu, "notforcesensitive", qtrue);
  2170. Menu_ShowItemByName(menu, "neutralpowers", qfalse);
  2171. Menu_ShowItemByName(menu, "darkpowers", qfalse);
  2172. Menu_ShowItemByName(menu, "lightpowers", qfalse);
  2173. Menu_ShowItemByName(menu, "nosaber", qtrue);
  2174. Menu_ShowItemByName(menu, "yessaber", qfalse);
  2175. }
  2176. else
  2177. {
  2178. Menu_ShowItemByName(menu, "notforcesensitive", qfalse);
  2179. Menu_ShowItemByName(menu, "neutralpowers", qtrue);
  2180. Menu_ShowItemByName(menu, "darkpowers", qtrue);
  2181. Menu_ShowItemByName(menu, "lightpowers", qtrue);
  2182. if(uiRank[FP_SABER_OFFENSE].uiForcePowersRank > 0 || ui_freeSaber.integer)
  2183. { // Show lightsaber stuff.
  2184. Menu_ShowItemByName(menu, "nosaber", qfalse);
  2185. Menu_ShowItemByName(menu, "yessaber", qtrue);
  2186. }
  2187. else
  2188. {
  2189. Menu_ShowItemByName(menu, "nosaber", qtrue);
  2190. Menu_ShowItemByName(menu, "yessaber", qfalse);
  2191. }
  2192. }
  2193. /* basejka code
  2194. //Moved this to happen after it's done with force power disabling stuff
  2195. if (uiRank[FP_SABER_OFFENSE].uiForcePowersRank > 0 || ui_freeSaber.integer)
  2196. { // Show lightsaber stuff.
  2197. Menu_ShowItemByName(menu, "nosaber", qfalse);
  2198. Menu_ShowItemByName(menu, "yessaber", qtrue);
  2199. }
  2200. else
  2201. {
  2202. Menu_ShowItemByName(menu, "nosaber", qtrue);
  2203. Menu_ShowItemByName(menu, "yessaber", qfalse);
  2204. }
  2205. */
  2206. //[/ExpSys]
  2207. // The leftmost button should be "apply" unless you are in spectator, where you can join any team.
  2208. if ((int)(trap_Cvar_VariableValue("ui_myteam")) != TEAM_SPECTATOR)
  2209. {
  2210. Menu_ShowItemByName(menu, "playerapply", qtrue);
  2211. Menu_ShowItemByName(menu, "playerforcejoin", qfalse);
  2212. Menu_ShowItemByName(menu, "playerforcered", qtrue);
  2213. Menu_ShowItemByName(menu, "playerforceblue", qtrue);
  2214. Menu_ShowItemByName(menu, "playerforcespectate", qtrue);
  2215. }
  2216. else
  2217. {
  2218. // Set or reset buttons based on choices
  2219. if (atoi(Info_ValueForKey(info, "g_gametype")) >= GT_TEAM)
  2220. { // This is a team-based game.
  2221. Menu_ShowItemByName(menu, "playerforcespectate", qtrue);
  2222. // This is disabled, always show both sides from spectator.
  2223. if ( 0 && atoi(Info_ValueForKey(info, "g_forceBasedTeams")))
  2224. { // Show red or blue based on what side is chosen.
  2225. if (uiForceSide==FORCE_LIGHTSIDE)
  2226. {
  2227. Menu_ShowItemByName(menu, "playerforcered", qfalse);
  2228. Menu_ShowItemByName(menu, "playerforceblue", qtrue);
  2229. }
  2230. else if (uiForceSide==FORCE_DARKSIDE)
  2231. {
  2232. Menu_ShowItemByName(menu, "playerforcered", qtrue);
  2233. Menu_ShowItemByName(menu, "playerforceblue", qfalse);
  2234. }
  2235. else
  2236. {
  2237. Menu_ShowItemByName(menu, "playerforcered", qtrue);
  2238. Menu_ShowItemByName(menu, "playerforceblue", qtrue);
  2239. }
  2240. }
  2241. else
  2242. {
  2243. Menu_ShowItemByName(menu, "playerforcered", qtrue);
  2244. Menu_ShowItemByName(menu, "playerforceblue", qtrue);
  2245. }
  2246. }
  2247. else
  2248. {
  2249. Menu_ShowItemByName(menu, "playerforcered", qfalse);
  2250. Menu_ShowItemByName(menu, "playerforceblue", qfalse);
  2251. }
  2252. Menu_ShowItemByName(menu, "playerapply", qfalse);
  2253. Menu_ShowItemByName(menu, "playerforcejoin", qtrue);
  2254. Menu_ShowItemByName(menu, "playerforcespectate", qtrue);
  2255. }
  2256. }
  2257. if ( !UI_TrueJediEnabled() )
  2258. {// Take the current team and force a skin color based on it.
  2259. char info[MAX_INFO_STRING];
  2260. //[CoOp]
  2261. int gametype;
  2262. trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  2263. gametype = atoi(Info_ValueForKey(info, "g_gametype"));
  2264. if (gametype == GT_SINGLE_PLAYER)
  2265. {//even thou players are on a team for CoOp, they act like they're not
  2266. uiSkinColor = uiHoldSkinColor;
  2267. }
  2268. else
  2269. {
  2270. switch((int)(trap_Cvar_VariableValue("ui_myteam")))
  2271. {
  2272. case TEAM_RED:
  2273. uiSkinColor = TEAM_RED;
  2274. uiInfo.effectsColor = SABER_RED;
  2275. break;
  2276. case TEAM_BLUE:
  2277. uiSkinColor = TEAM_BLUE;
  2278. uiInfo.effectsColor = SABER_BLUE;
  2279. break;
  2280. default:
  2281. //trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  2282. if(gametype >= GT_TEAM)
  2283. //if (atoi(Info_ValueForKey(info, "g_gametype")) >= GT_TEAM)
  2284. {
  2285. uiSkinColor = TEAM_FREE;
  2286. }
  2287. else // A bit of a hack so non-team games will remember which skin set you chose in the player menu
  2288. {
  2289. uiSkinColor = uiHoldSkinColor;
  2290. }
  2291. break;
  2292. }
  2293. }
  2294. /* basejka code
  2295. switch((int)(trap_Cvar_VariableValue("ui_myteam")))
  2296. {
  2297. case TEAM_RED:
  2298. uiSkinColor = TEAM_RED;
  2299. uiInfo.effectsColor = SABER_RED;
  2300. break;
  2301. case TEAM_BLUE:
  2302. uiSkinColor = TEAM_BLUE;
  2303. uiInfo.effectsColor = SABER_BLUE;
  2304. break;
  2305. default:
  2306. trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  2307. if (atoi(Info_ValueForKey(info, "g_gametype")) >= GT_TEAM)
  2308. {
  2309. uiSkinColor = TEAM_FREE;
  2310. }
  2311. else // A bit of a hack so non-team games will remember which skin set you chose in the player menu
  2312. {
  2313. uiSkinColor = uiHoldSkinColor;
  2314. }
  2315. break;
  2316. }
  2317. */
  2318. //[/CoOp]
  2319. }
  2320. }
  2321. static void UI_DrawNetSource(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont)
  2322. {
  2323. if (ui_netSource.integer < 0 || ui_netSource.integer > uiInfo.numGameTypes)
  2324. {
  2325. ui_netSource.integer = 0;
  2326. }
  2327. trap_SP_GetStringTextString("MENUS_SOURCE", holdSPString, sizeof(holdSPString) );
  2328. Text_Paint(rect->x, rect->y, scale, color, va("%s %s",holdSPString,
  2329. GetNetSourceString(ui_netSource.integer)), 0, 0, textStyle, iMenuFont);
  2330. }
  2331. static void UI_DrawNetMapPreview(rectDef_t *rect, float scale, vec4_t color) {
  2332. if (uiInfo.serverStatus.currentServerPreview > 0) {
  2333. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.serverStatus.currentServerPreview);
  2334. } else {
  2335. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("menu/art/unknownmap_mp"));
  2336. }
  2337. }
  2338. static void UI_DrawNetMapCinematic(rectDef_t *rect, float scale, vec4_t color) {
  2339. if (ui_currentNetMap.integer < 0 || ui_currentNetMap.integer > uiInfo.mapCount) {
  2340. ui_currentNetMap.integer = 0;
  2341. trap_Cvar_Set("ui_currentNetMap", "0");
  2342. }
  2343. if (uiInfo.serverStatus.currentServerCinematic >= 0) {
  2344. trap_CIN_RunCinematic(uiInfo.serverStatus.currentServerCinematic);
  2345. trap_CIN_SetExtents(uiInfo.serverStatus.currentServerCinematic, rect->x, rect->y, rect->w, rect->h);
  2346. trap_CIN_DrawCinematic(uiInfo.serverStatus.currentServerCinematic);
  2347. } else {
  2348. UI_DrawNetMapPreview(rect, scale, color);
  2349. }
  2350. }
  2351. static void UI_DrawNetFilter(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont)
  2352. {
  2353. if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters)
  2354. {
  2355. ui_serverFilterType.integer = 0;
  2356. }
  2357. trap_SP_GetStringTextString("MENUS_GAME", holdSPString, sizeof(holdSPString));
  2358. trap_SP_GetStringTextString(serverFilters[ui_serverFilterType.integer].description, holdSPString2, sizeof(holdSPString2));
  2359. Text_Paint(rect->x, rect->y, scale, color, va("%s %s",holdSPString,
  2360. holdSPString2), 0, 0, textStyle, iMenuFont);
  2361. }
  2362. static void UI_DrawTier(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  2363. int i;
  2364. i = trap_Cvar_VariableValue( "ui_currentTier" );
  2365. if (i < 0 || i >= uiInfo.tierCount) {
  2366. i = 0;
  2367. }
  2368. Text_Paint(rect->x, rect->y, scale, color, va("Tier: %s", uiInfo.tierList[i].tierName),0, 0, textStyle, iMenuFont);
  2369. }
  2370. static void UI_DrawTierMap(rectDef_t *rect, int index) {
  2371. int i;
  2372. i = trap_Cvar_VariableValue( "ui_currentTier" );
  2373. if (i < 0 || i >= uiInfo.tierCount) {
  2374. i = 0;
  2375. }
  2376. if (uiInfo.tierList[i].mapHandles[index] == -1) {
  2377. uiInfo.tierList[i].mapHandles[index] = trap_R_RegisterShaderNoMip(va("levelshots/%s", uiInfo.tierList[i].maps[index]));
  2378. }
  2379. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.tierList[i].mapHandles[index]);
  2380. }
  2381. static const char *UI_EnglishMapName(const char *map) {
  2382. int i;
  2383. for (i = 0; i < uiInfo.mapCount; i++) {
  2384. if (Q_stricmp(map, uiInfo.mapList[i].mapLoadName) == 0) {
  2385. return uiInfo.mapList[i].mapName;
  2386. }
  2387. }
  2388. return "";
  2389. }
  2390. static void UI_DrawTierMapName(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  2391. int i, j;
  2392. i = trap_Cvar_VariableValue( "ui_currentTier" );
  2393. if (i < 0 || i >= uiInfo.tierCount) {
  2394. i = 0;
  2395. }
  2396. j = trap_Cvar_VariableValue("ui_currentMap");
  2397. if (j < 0 || j > MAPS_PER_TIER) {
  2398. j = 0;
  2399. }
  2400. Text_Paint(rect->x, rect->y, scale, color, UI_EnglishMapName(uiInfo.tierList[i].maps[j]), 0, 0, textStyle, iMenuFont);
  2401. }
  2402. static void UI_DrawTierGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  2403. int i, j;
  2404. i = trap_Cvar_VariableValue( "ui_currentTier" );
  2405. if (i < 0 || i >= uiInfo.tierCount) {
  2406. i = 0;
  2407. }
  2408. j = trap_Cvar_VariableValue("ui_currentMap");
  2409. if (j < 0 || j > MAPS_PER_TIER) {
  2410. j = 0;
  2411. }
  2412. Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[uiInfo.tierList[i].gameTypes[j]].gameType , 0, 0, textStyle,iMenuFont);
  2413. }
  2414. static const char *UI_AIFromName(const char *name) {
  2415. int j;
  2416. for (j = 0; j < uiInfo.aliasCount; j++) {
  2417. if (Q_stricmp(uiInfo.aliasList[j].name, name) == 0) {
  2418. return uiInfo.aliasList[j].ai;
  2419. }
  2420. }
  2421. return "Kyle";
  2422. }
  2423. /*
  2424. static qboolean updateOpponentModel = qtrue;
  2425. static void UI_DrawOpponent(rectDef_t *rect) {
  2426. static playerInfo_t info2;
  2427. char model[MAX_QPATH];
  2428. char headmodel[MAX_QPATH];
  2429. char team[256];
  2430. vec3_t viewangles;
  2431. vec3_t moveangles;
  2432. if (updateOpponentModel) {
  2433. strcpy(model, UI_Cvar_VariableString("ui_opponentModel"));
  2434. strcpy(headmodel, UI_Cvar_VariableString("ui_opponentModel"));
  2435. team[0] = '\0';
  2436. memset( &info2, 0, sizeof(playerInfo_t) );
  2437. viewangles[YAW] = 180 - 10;
  2438. viewangles[PITCH] = 0;
  2439. viewangles[ROLL] = 0;
  2440. VectorClear( moveangles );
  2441. UI_PlayerInfo_SetModel( &info2, model, headmodel, "");
  2442. UI_PlayerInfo_SetInfo( &info2, TORSO_WEAPONREADY3, TORSO_WEAPONREADY3, viewangles, vec3_origin, WP_BRYAR_PISTOL, qfalse );
  2443. UI_RegisterClientModelname( &info2, model, headmodel, team);
  2444. updateOpponentModel = qfalse;
  2445. }
  2446. UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info2, uiInfo.uiDC.realTime / 2);
  2447. }
  2448. */
  2449. static void UI_NextOpponent() {
  2450. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  2451. int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  2452. i++;
  2453. if (i >= uiInfo.teamCount) {
  2454. i = 0;
  2455. }
  2456. if (i == j) {
  2457. i++;
  2458. if ( i >= uiInfo.teamCount) {
  2459. i = 0;
  2460. }
  2461. }
  2462. trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName );
  2463. }
  2464. static void UI_PriorOpponent() {
  2465. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  2466. int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  2467. i--;
  2468. if (i < 0) {
  2469. i = uiInfo.teamCount - 1;
  2470. }
  2471. if (i == j) {
  2472. i--;
  2473. if ( i < 0) {
  2474. i = uiInfo.teamCount - 1;
  2475. }
  2476. }
  2477. trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName );
  2478. }
  2479. static void UI_DrawPlayerLogo(rectDef_t *rect, vec3_t color) {
  2480. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  2481. if (uiInfo.teamList[i].teamIcon == -1) {
  2482. uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
  2483. uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
  2484. uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
  2485. }
  2486. trap_R_SetColor( color );
  2487. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon );
  2488. trap_R_SetColor( NULL );
  2489. }
  2490. static void UI_DrawPlayerLogoMetal(rectDef_t *rect, vec3_t color) {
  2491. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  2492. if (uiInfo.teamList[i].teamIcon == -1) {
  2493. uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
  2494. uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
  2495. uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
  2496. }
  2497. trap_R_SetColor( color );
  2498. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal );
  2499. trap_R_SetColor( NULL );
  2500. }
  2501. static void UI_DrawPlayerLogoName(rectDef_t *rect, vec3_t color) {
  2502. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  2503. if (uiInfo.teamList[i].teamIcon == -1) {
  2504. uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
  2505. uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
  2506. uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
  2507. }
  2508. trap_R_SetColor( color );
  2509. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name );
  2510. trap_R_SetColor( NULL );
  2511. }
  2512. static void UI_DrawOpponentLogo(rectDef_t *rect, vec3_t color) {
  2513. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  2514. if (uiInfo.teamList[i].teamIcon == -1) {
  2515. uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
  2516. uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
  2517. uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
  2518. }
  2519. trap_R_SetColor( color );
  2520. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon );
  2521. trap_R_SetColor( NULL );
  2522. }
  2523. static void UI_DrawOpponentLogoMetal(rectDef_t *rect, vec3_t color) {
  2524. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  2525. if (uiInfo.teamList[i].teamIcon == -1) {
  2526. uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
  2527. uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
  2528. uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
  2529. }
  2530. trap_R_SetColor( color );
  2531. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal );
  2532. trap_R_SetColor( NULL );
  2533. }
  2534. static void UI_DrawOpponentLogoName(rectDef_t *rect, vec3_t color) {
  2535. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  2536. if (uiInfo.teamList[i].teamIcon == -1) {
  2537. uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
  2538. uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
  2539. uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
  2540. }
  2541. trap_R_SetColor( color );
  2542. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name );
  2543. trap_R_SetColor( NULL );
  2544. }
  2545. static void UI_DrawAllMapsSelection(rectDef_t *rect, float scale, vec4_t color, int textStyle, qboolean net, int iMenuFont) {
  2546. int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
  2547. if (map >= 0 && map < uiInfo.mapCount) {
  2548. Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle, iMenuFont);
  2549. }
  2550. }
  2551. static void UI_DrawOpponentName(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  2552. Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, textStyle, iMenuFont);
  2553. }
  2554. static int UI_OwnerDrawWidth(int ownerDraw, float scale) {
  2555. int i, h, value, findex, iUse = 0;
  2556. const char *text;
  2557. const char *s = NULL;
  2558. //[NewUI]
  2559. if(IsForceRank(ownerDraw))
  2560. {
  2561. if(ownerDraw < UI_FORCE_RANK_JETPACK)
  2562. {
  2563. findex = (ownerDraw - UI_FORCE_RANK)-1;
  2564. }
  2565. else
  2566. {//use a different index shift for the addition skills
  2567. findex = (ownerDraw - UI_FORCE_RANK_JETPACK)+(UI_FORCE_RANK_SABERTHROW-UI_FORCE_RANK);
  2568. }
  2569. //findex = (ownerDraw - UI_FORCE_RANK)-1;
  2570. //[/ExpSys]
  2571. //this will give us the index as long as UI_FORCE_RANK is always one below the first force rank index
  2572. i = uiRank[findex].uiForcePowersRank;
  2573. if (i < 0 || i > NUM_FORCE_POWER_LEVELS-1)
  2574. {
  2575. i = 0;
  2576. }
  2577. s = va("%i",uiRank[findex].uiForcePowersRank);
  2578. }
  2579. //[/NewUI]
  2580. else
  2581. {
  2582. switch (ownerDraw) {
  2583. case UI_HANDICAP:
  2584. h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
  2585. i = 20 - h / 5;
  2586. s = handicapValues[i];
  2587. break;
  2588. case UI_SKIN_COLOR:
  2589. switch(uiSkinColor)
  2590. {
  2591. case TEAM_RED:
  2592. // s = "Red";
  2593. s = (char *)UI_GetStringEdString("MENUS", "TEAM_RED");
  2594. break;
  2595. case TEAM_BLUE:
  2596. // s = "Blue";
  2597. s = (char *)UI_GetStringEdString("MENUS", "TEAM_BLUE");
  2598. break;
  2599. default:
  2600. // s = "Default";
  2601. s = (char *)UI_GetStringEdString("MENUS", "DEFAULT");
  2602. break;
  2603. }
  2604. break;
  2605. case UI_FORCE_SIDE:
  2606. i = uiForceSide;
  2607. if (i < 1 || i > 2) {
  2608. i = 1;
  2609. }
  2610. if (i == FORCE_LIGHTSIDE)
  2611. {
  2612. // s = "Light";
  2613. s = (char *)UI_GetStringEdString("MENUS", "FORCEDESC_LIGHT");
  2614. }
  2615. else
  2616. {
  2617. // s = "Dark";
  2618. s = (char *)UI_GetStringEdString("MENUS", "FORCEDESC_DARK");
  2619. }
  2620. break;
  2621. case UI_JEDI_NONJEDI:
  2622. i = uiJediNonJedi;
  2623. if (i < 0 || i > 1)
  2624. {
  2625. i = 0;
  2626. }
  2627. if (i == FORCE_NONJEDI)
  2628. {
  2629. // s = "Non-Jedi";
  2630. s = (char *)UI_GetStringEdString("MENUS", "NO");
  2631. }
  2632. else
  2633. {
  2634. // s = "Jedi";
  2635. s = (char *)UI_GetStringEdString("MENUS", "YES");
  2636. }
  2637. break;
  2638. case UI_FORCE_RANK:
  2639. i = uiForceRank;
  2640. //[ExpSys]
  2641. //display rank based on player's current relative rank based on their current points.
  2642. for(findex = NUM_FORCE_MASTERY_LEVELS-1; findex >= 0; findex--)
  2643. {
  2644. if(i >= forceMasteryPoints[findex])
  2645. {//we've found the highest level mastery that we have the skill points for.
  2646. s = (char *)UI_GetStringEdString("MP_INGAME", forceMasteryLevels[findex]);
  2647. break;
  2648. }
  2649. }
  2650. /* basejka code
  2651. if (i < 1 || i > MAX_FORCE_RANK) {
  2652. i = 1;
  2653. }
  2654. s = (char *)UI_GetStringEdString("MP_INGAME", forceMasteryLevels[i]);
  2655. */
  2656. //[/ExpSys]
  2657. break;
  2658. case UI_CLANNAME:
  2659. s = UI_Cvar_VariableString("ui_teamName");
  2660. break;
  2661. case UI_GAMETYPE:
  2662. s = uiInfo.gameTypes[ui_gameType.integer].gameType;
  2663. break;
  2664. case UI_SKILL:
  2665. i = trap_Cvar_VariableValue( "g_spSkill" );
  2666. if (i < 1 || i > numSkillLevels) {
  2667. i = 1;
  2668. }
  2669. s = (char *)UI_GetStringEdString("MP_INGAME", (char *)skillLevels[i-1]);
  2670. break;
  2671. case UI_BLUETEAMNAME:
  2672. i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_blueTeam"));
  2673. if (i >= 0 && i < uiInfo.teamCount) {
  2674. s = va("%s: %s", (char *)UI_GetStringEdString("MENUS", "TEAM_BLUE"), uiInfo.teamList[i].teamName);
  2675. }
  2676. break;
  2677. case UI_REDTEAMNAME:
  2678. i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_redTeam"));
  2679. if (i >= 0 && i < uiInfo.teamCount) {
  2680. s = va("%s: %s", (char *)UI_GetStringEdString("MENUS", "TEAM_RED"), uiInfo.teamList[i].teamName);
  2681. }
  2682. break;
  2683. case UI_BLUETEAM1:
  2684. case UI_BLUETEAM2:
  2685. case UI_BLUETEAM3:
  2686. case UI_BLUETEAM4:
  2687. case UI_BLUETEAM5:
  2688. case UI_BLUETEAM6:
  2689. case UI_BLUETEAM7:
  2690. case UI_BLUETEAM8:
  2691. if (ownerDraw <= UI_BLUETEAM5)
  2692. {
  2693. iUse = ownerDraw-UI_BLUETEAM1 + 1;
  2694. }
  2695. else
  2696. {
  2697. iUse = ownerDraw-274; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
  2698. }
  2699. value = trap_Cvar_VariableValue(va("ui_blueteam%i", iUse));
  2700. if (value <= 1) {
  2701. text = "Human";
  2702. } else {
  2703. value -= 2;
  2704. if (value >= uiInfo.aliasCount) {
  2705. value = 1;
  2706. }
  2707. text = uiInfo.aliasList[value].name;
  2708. }
  2709. s = va("%i. %s", iUse, text);
  2710. break;
  2711. case UI_REDTEAM1:
  2712. case UI_REDTEAM2:
  2713. case UI_REDTEAM3:
  2714. case UI_REDTEAM4:
  2715. case UI_REDTEAM5:
  2716. case UI_REDTEAM6:
  2717. case UI_REDTEAM7:
  2718. case UI_REDTEAM8:
  2719. if (ownerDraw <= UI_REDTEAM5)
  2720. {
  2721. iUse = ownerDraw-UI_REDTEAM1 + 1;
  2722. }
  2723. else
  2724. {
  2725. iUse = ownerDraw-277; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
  2726. }
  2727. value = trap_Cvar_VariableValue(va("ui_redteam%i", iUse));
  2728. if (value <= 1) {
  2729. text = "Human";
  2730. } else {
  2731. value -= 2;
  2732. if (value >= uiInfo.aliasCount) {
  2733. value = 1;
  2734. }
  2735. text = uiInfo.aliasList[value].name;
  2736. }
  2737. s = va("%i. %s", iUse, text);
  2738. break;
  2739. case UI_NETSOURCE:
  2740. if (ui_netSource.integer < 0 || ui_netSource.integer > uiInfo.numJoinGameTypes) {
  2741. ui_netSource.integer = 0;
  2742. }
  2743. trap_SP_GetStringTextString("MENUS_SOURCE", holdSPString, sizeof(holdSPString));
  2744. s = va("%s %s", holdSPString, GetNetSourceString(ui_netSource.integer));
  2745. break;
  2746. case UI_NETFILTER:
  2747. if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) {
  2748. ui_serverFilterType.integer = 0;
  2749. }
  2750. trap_SP_GetStringTextString("MENUS_GAME", holdSPString, sizeof(holdSPString));
  2751. trap_SP_GetStringTextString(serverFilters[ui_serverFilterType.integer].description, holdSPString2, sizeof(holdSPString2));
  2752. s = va("%s %s", holdSPString, holdSPString2 );
  2753. break;
  2754. case UI_TIER:
  2755. break;
  2756. case UI_TIER_MAPNAME:
  2757. break;
  2758. case UI_TIER_GAMETYPE:
  2759. break;
  2760. case UI_ALLMAPS_SELECTION:
  2761. break;
  2762. case UI_OPPONENT_NAME:
  2763. break;
  2764. case UI_KEYBINDSTATUS:
  2765. if (Display_KeyBindPending()) {
  2766. s = UI_GetStringEdString("MP_INGAME", "WAITING_FOR_NEW_KEY");
  2767. } else {
  2768. // s = "Press ENTER or CLICK to change, Press BACKSPACE to clear";
  2769. }
  2770. break;
  2771. case UI_SERVERREFRESHDATE:
  2772. s = UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer));
  2773. break;
  2774. default:
  2775. break;
  2776. }
  2777. }
  2778. if (s) {
  2779. return Text_Width(s, scale, 0);
  2780. }
  2781. return 0;
  2782. }
  2783. static void UI_DrawBotName(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont)
  2784. {
  2785. int value = uiInfo.botIndex;
  2786. const char *text = "";
  2787. if (value >= UI_GetNumBots()) {
  2788. value = 0;
  2789. }
  2790. text = UI_GetBotNameByNumber(value);
  2791. Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle,iMenuFont);
  2792. }
  2793. static void UI_DrawBotSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont)
  2794. {
  2795. if (uiInfo.skillIndex >= 0 && uiInfo.skillIndex < numSkillLevels)
  2796. {
  2797. Text_Paint(rect->x, rect->y, scale, color, (char *)UI_GetStringEdString("MP_INGAME", (char *)skillLevels[uiInfo.skillIndex]), 0, 0, textStyle,iMenuFont);
  2798. }
  2799. }
  2800. static void UI_DrawRedBlue(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont)
  2801. {
  2802. //[CoOp]
  2803. if (trap_Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER)
  2804. {//print different team names for CoOp
  2805. Text_Paint(rect->x, rect->y, scale, color, (uiInfo.redBlue == 0) ? UI_GetStringEdString("OJP_MENUS","ENEMYTEAM") : UI_GetStringEdString("OJP_MENUS","PLAYERTEAM"), 0, 0, textStyle,iMenuFont);
  2806. }
  2807. else
  2808. {
  2809. 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);
  2810. }
  2811. //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);
  2812. //[/CoOp]
  2813. }
  2814. static void UI_DrawCrosshair(rectDef_t *rect, float scale, vec4_t color) {
  2815. trap_R_SetColor( color );
  2816. if (uiInfo.currentCrosshair < 0 || uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
  2817. uiInfo.currentCrosshair = 0;
  2818. }
  2819. UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.uiDC.Assets.crosshairShader[uiInfo.currentCrosshair]);
  2820. trap_R_SetColor( NULL );
  2821. }
  2822. /*
  2823. ===============
  2824. UI_BuildPlayerList
  2825. ===============
  2826. */
  2827. static void UI_BuildPlayerList() {
  2828. uiClientState_t cs;
  2829. int n, count, team, team2, playerTeamNumber;
  2830. char info[MAX_INFO_STRING];
  2831. trap_GetClientState( &cs );
  2832. trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING );
  2833. uiInfo.playerNumber = cs.clientNum;
  2834. uiInfo.teamLeader = atoi(Info_ValueForKey(info, "tl"));
  2835. team = atoi(Info_ValueForKey(info, "t"));
  2836. trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
  2837. count = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
  2838. uiInfo.playerCount = 0;
  2839. uiInfo.myTeamCount = 0;
  2840. playerTeamNumber = 0;
  2841. for( n = 0; n < count; n++ ) {
  2842. trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING );
  2843. if (info[0]) {
  2844. Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
  2845. Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] );
  2846. uiInfo.playerIndexes[uiInfo.playerCount] = n;
  2847. uiInfo.playerCount++;
  2848. team2 = atoi(Info_ValueForKey(info, "t"));
  2849. if (team2 == team && n != uiInfo.playerNumber) {
  2850. Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount], Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
  2851. Q_CleanStr( uiInfo.teamNames[uiInfo.myTeamCount] );
  2852. uiInfo.teamClientNums[uiInfo.myTeamCount] = n;
  2853. if (uiInfo.playerNumber == n) {
  2854. playerTeamNumber = uiInfo.myTeamCount;
  2855. }
  2856. uiInfo.myTeamCount++;
  2857. }
  2858. }
  2859. }
  2860. if (!uiInfo.teamLeader) {
  2861. trap_Cvar_Set("cg_selectedPlayer", va("%d", playerTeamNumber));
  2862. }
  2863. n = trap_Cvar_VariableValue("cg_selectedPlayer");
  2864. if (n < 0 || n > uiInfo.myTeamCount) {
  2865. n = 0;
  2866. }
  2867. if (n < uiInfo.myTeamCount) {
  2868. trap_Cvar_Set("cg_selectedPlayerName", uiInfo.teamNames[n]);
  2869. }
  2870. else
  2871. {
  2872. trap_Cvar_Set("cg_selectedPlayerName", "Everyone");
  2873. }
  2874. if (!team || team == TEAM_SPECTATOR || !uiInfo.teamLeader)
  2875. {
  2876. n = uiInfo.myTeamCount;
  2877. trap_Cvar_Set("cg_selectedPlayer", va("%d", n));
  2878. trap_Cvar_Set("cg_selectedPlayerName", "N/A");
  2879. }
  2880. }
  2881. static void UI_DrawSelectedPlayer(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont) {
  2882. if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) {
  2883. uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
  2884. UI_BuildPlayerList();
  2885. }
  2886. Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("cg_selectedPlayerName"), 0, 0, textStyle, iMenuFont);
  2887. }
  2888. static void UI_DrawServerRefreshDate(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iMenuFont)
  2889. {
  2890. if (uiInfo.serverStatus.refreshActive)
  2891. {
  2892. vec4_t lowLight, newColor;
  2893. lowLight[0] = 0.8 * color[0];
  2894. lowLight[1] = 0.8 * color[1];
  2895. lowLight[2] = 0.8 * color[2];
  2896. lowLight[3] = 0.8 * color[3];
  2897. LerpColor(color,lowLight,newColor,0.5+0.5*sin((float)(uiInfo.uiDC.realTime / PULSE_DIVISOR)));
  2898. trap_SP_GetStringTextString("MP_INGAME_GETTINGINFOFORSERVERS", holdSPString, sizeof(holdSPString));
  2899. Text_Paint(rect->x, rect->y, scale, newColor, va((char *) holdSPString, trap_LAN_GetServerCount(ui_netSource.integer)), 0, 0, textStyle, iMenuFont);
  2900. }
  2901. else
  2902. {
  2903. char buff[64];
  2904. Q_strncpyz(buff, UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)), 64);
  2905. trap_SP_GetStringTextString("MP_INGAME_SERVER_REFRESHTIME", holdSPString, sizeof(holdSPString));
  2906. Text_Paint(rect->x, rect->y, scale, color, va("%s: %s", holdSPString, buff), 0, 0, textStyle, iMenuFont);
  2907. }
  2908. }
  2909. static void UI_DrawServerMOTD(rectDef_t *rect, float scale, vec4_t color, int iMenuFont) {
  2910. if (uiInfo.serverStatus.motdLen) {
  2911. float maxX;
  2912. if (uiInfo.serverStatus.motdWidth == -1) {
  2913. uiInfo.serverStatus.motdWidth = 0;
  2914. uiInfo.serverStatus.motdPaintX = rect->x + 1;
  2915. uiInfo.serverStatus.motdPaintX2 = -1;
  2916. }
  2917. if (uiInfo.serverStatus.motdOffset > uiInfo.serverStatus.motdLen) {
  2918. uiInfo.serverStatus.motdOffset = 0;
  2919. uiInfo.serverStatus.motdPaintX = rect->x + 1;
  2920. uiInfo.serverStatus.motdPaintX2 = -1;
  2921. }
  2922. if (uiInfo.uiDC.realTime > uiInfo.serverStatus.motdTime) {
  2923. uiInfo.serverStatus.motdTime = uiInfo.uiDC.realTime + 10;
  2924. if (uiInfo.serverStatus.motdPaintX <= rect->x + 2) {
  2925. if (uiInfo.serverStatus.motdOffset < uiInfo.serverStatus.motdLen) {
  2926. uiInfo.serverStatus.motdPaintX += Text_Width(&uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], scale, 1) - 1;
  2927. uiInfo.serverStatus.motdOffset++;
  2928. } else {
  2929. uiInfo.serverStatus.motdOffset = 0;
  2930. if (uiInfo.serverStatus.motdPaintX2 >= 0) {
  2931. uiInfo.serverStatus.motdPaintX = uiInfo.serverStatus.motdPaintX2;
  2932. } else {
  2933. uiInfo.serverStatus.motdPaintX = rect->x + rect->w - 2;
  2934. }
  2935. uiInfo.serverStatus.motdPaintX2 = -1;
  2936. }
  2937. } else {
  2938. //serverStatus.motdPaintX--;
  2939. uiInfo.serverStatus.motdPaintX -= 2;
  2940. if (uiInfo.serverStatus.motdPaintX2 >= 0) {
  2941. //serverStatus.motdPaintX2--;
  2942. uiInfo.serverStatus.motdPaintX2 -= 2;
  2943. }
  2944. }
  2945. }
  2946. maxX = rect->x + rect->w - 2;
  2947. Text_Paint_Limit(&maxX, uiInfo.serverStatus.motdPaintX, rect->y + rect->h - 3, scale, color, &uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], 0, 0, iMenuFont);
  2948. if (uiInfo.serverStatus.motdPaintX2 >= 0) {
  2949. float maxX2 = rect->x + rect->w - 2;
  2950. Text_Paint_Limit(&maxX2, uiInfo.serverStatus.motdPaintX2, rect->y + rect->h - 3, scale, color, uiInfo.serverStatus.motd, 0, uiInfo.serverStatus.motdOffset, iMenuFont);
  2951. }
  2952. if (uiInfo.serverStatus.motdOffset && maxX > 0) {
  2953. // if we have an offset ( we are skipping the first part of the string ) and we fit the string
  2954. if (uiInfo.serverStatus.motdPaintX2 == -1) {
  2955. uiInfo.serverStatus.motdPaintX2 = rect->x + rect->w - 2;
  2956. }
  2957. } else {
  2958. uiInfo.serverStatus.motdPaintX2 = -1;
  2959. }
  2960. }
  2961. }
  2962. static void UI_DrawKeyBindStatus(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont) {
  2963. // int ofs = 0; TTimo: unused
  2964. if (Display_KeyBindPending())
  2965. {
  2966. Text_Paint(rect->x, rect->y, scale, color, UI_GetStringEdString("MP_INGAME", "WAITING_FOR_NEW_KEY"), 0, 0, textStyle,iMenuFont);
  2967. } else {
  2968. // Text_Paint(rect->x, rect->y, scale, color, "Press ENTER or CLICK to change, Press BACKSPACE to clear", 0, 0, textStyle,iMenuFont);
  2969. }
  2970. }
  2971. static void UI_DrawGLInfo(rectDef_t *rect, float scale, vec4_t color, int textStyle,int iMenuFont)
  2972. {
  2973. char * eptr;
  2974. char buff[4096];
  2975. const char *lines[128];
  2976. int y, numLines, i;
  2977. Text_Paint(rect->x + 2, rect->y, scale, color, va("GL_VENDOR: %s", uiInfo.uiDC.glconfig.vendor_string), 0, rect->w, textStyle,iMenuFont);
  2978. 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);
  2979. 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);
  2980. // build null terminated extension strings
  2981. Q_strncpyz(buff, uiInfo.uiDC.glconfig.extensions_string, 4096);
  2982. eptr = buff;
  2983. y = rect->y + 45;
  2984. numLines = 0;
  2985. while ( y < rect->y + rect->h && *eptr )
  2986. {
  2987. while ( *eptr && *eptr == ' ' )
  2988. *eptr++ = '\0';
  2989. // track start of valid string
  2990. if (*eptr && *eptr != ' ')
  2991. {
  2992. lines[numLines++] = eptr;
  2993. }
  2994. while ( *eptr && *eptr != ' ' )
  2995. eptr++;
  2996. }
  2997. i = 0;
  2998. while (i < numLines)
  2999. {
  3000. Text_Paint(rect->x + 2, y, scale, color, lines[i++], 0, (rect->w/2), textStyle,iMenuFont);
  3001. if (i < numLines)
  3002. {
  3003. Text_Paint(rect->x + rect->w / 2, y, scale, color, lines[i++], 0, (rect->w/2), textStyle,iMenuFont);
  3004. }
  3005. y += 10;
  3006. if (y > rect->y + rect->h - 11)
  3007. {
  3008. break;
  3009. }
  3010. }
  3011. }
  3012. /*
  3013. =================
  3014. UI_Version
  3015. =================
  3016. */
  3017. static void UI_Version(rectDef_t *rect, float scale, vec4_t color, int iMenuFont)
  3018. {
  3019. int width;
  3020. width = uiInfo.uiDC.textWidth(Q3_VERSION, scale, iMenuFont);
  3021. uiInfo.uiDC.drawText(rect->x - width, rect->y, scale, color, Q3_VERSION, 0, 0, 0, iMenuFont);
  3022. }
  3023. /*
  3024. =================
  3025. UI_OwnerDraw
  3026. =================
  3027. */
  3028. // FIXME: table drive
  3029. //
  3030. 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)
  3031. {
  3032. rectDef_t rect;
  3033. int findex;
  3034. int drawRank = 0, iUse = 0;
  3035. rect.x = x + text_x;
  3036. rect.y = y + text_y;
  3037. rect.w = w;
  3038. rect.h = h;
  3039. //[NewUI]
  3040. if(IsForceRank(ownerDraw))
  3041. {
  3042. //[ExpSys]
  3043. if(ownerDraw < UI_FORCE_RANK_JETPACK)
  3044. {
  3045. findex = (ownerDraw - UI_FORCE_RANK)-1;
  3046. }
  3047. else
  3048. {//use a different index shift for the addition skills
  3049. findex = (ownerDraw - UI_FORCE_RANK_JETPACK)+(UI_FORCE_RANK_SABERTHROW-UI_FORCE_RANK);
  3050. }
  3051. //findex = (ownerDraw - UI_FORCE_RANK)-1;
  3052. //[/ExpSys]
  3053. //this will give us the index as long as UI_FORCE_RANK is always one below the first force rank index
  3054. //[ForceSys]
  3055. //allow dark/light powers at the same time.
  3056. if (uiRank[findex].forceSide)
  3057. //if (uiForcePowerDarkLight[findex] && uiForceSide != uiForcePowerDarkLight[findex])
  3058. //[/ForceSys]
  3059. {
  3060. color[0] *= 0.5;
  3061. color[1] *= 0.5;
  3062. color[2] *= 0.5;
  3063. }
  3064. /*
  3065. else if (uiForceRank < UI_ForceColorMinRank[bgForcePowerCost[findex][FORCE_LEVEL_1]])
  3066. {
  3067. color[0] *= 0.5;
  3068. color[1] *= 0.5;
  3069. color[2] *= 0.5;
  3070. }
  3071. */
  3072. drawRank = uiRank[findex].uiForcePowersRank;
  3073. UI_DrawForceStars(&rect, scale, color, textStyle, findex, drawRank, 0, NUM_FORCE_POWER_LEVELS-1);
  3074. return;
  3075. }
  3076. //[/NewUI]
  3077. switch (ownerDraw)
  3078. {
  3079. case UI_HANDICAP:
  3080. UI_DrawHandicap(&rect, scale, color, textStyle, iMenuFont);
  3081. break;
  3082. case UI_SKIN_COLOR:
  3083. UI_DrawSkinColor(&rect, scale, color, textStyle, uiSkinColor, TEAM_FREE, TEAM_BLUE, iMenuFont);
  3084. break;
  3085. case UI_FORCE_SIDE:
  3086. UI_DrawForceSide(&rect, scale, color, textStyle, uiForceSide, 1, 2, iMenuFont);
  3087. break;
  3088. case UI_JEDI_NONJEDI:
  3089. UI_DrawJediNonJedi(&rect, scale, color, textStyle, uiJediNonJedi, 0, 1, iMenuFont);
  3090. break;
  3091. case UI_FORCE_POINTS:
  3092. UI_DrawGenericNum(&rect, scale, color, textStyle, uiForceAvailable, 1, forceMasteryPoints[MAX_FORCE_RANK], ownerDraw,iMenuFont);
  3093. break;
  3094. //racc - this shouldn't be used anymore since the experience system uses g_forceMaxRank differently.
  3095. case UI_FORCE_MASTERY_SET:
  3096. UI_DrawForceMastery(&rect, scale, color, textStyle, uiForceRank, 0, MAX_FORCE_RANK, iMenuFont);
  3097. break;
  3098. case UI_FORCE_RANK:
  3099. UI_DrawForceMastery(&rect, scale, color, textStyle, uiForceRank, 0, MAX_FORCE_RANK, iMenuFont);
  3100. break;
  3101. case UI_EFFECTS:
  3102. UI_DrawEffects(&rect, scale, color);
  3103. break;
  3104. case UI_PLAYERMODEL:
  3105. //UI_DrawPlayerModel(&rect);
  3106. break;
  3107. case UI_CLANNAME:
  3108. UI_DrawClanName(&rect, scale, color, textStyle, iMenuFont);
  3109. break;
  3110. case UI_CLANLOGO:
  3111. UI_DrawClanLogo(&rect, scale, color);
  3112. break;
  3113. case UI_CLANCINEMATIC:
  3114. UI_DrawClanCinematic(&rect, scale, color);
  3115. break;
  3116. case UI_PREVIEWCINEMATIC:
  3117. UI_DrawPreviewCinematic(&rect, scale, color);
  3118. break;
  3119. case UI_GAMETYPE:
  3120. UI_DrawGameType(&rect, scale, color, textStyle, iMenuFont);
  3121. break;
  3122. case UI_NETGAMETYPE:
  3123. UI_DrawNetGameType(&rect, scale, color, textStyle, iMenuFont);
  3124. break;
  3125. case UI_AUTOSWITCHLIST:
  3126. UI_DrawAutoSwitch(&rect, scale, color, textStyle, iMenuFont);
  3127. break;
  3128. case UI_JOINGAMETYPE:
  3129. UI_DrawJoinGameType(&rect, scale, color, textStyle, iMenuFont);
  3130. break;
  3131. case UI_MAPPREVIEW:
  3132. UI_DrawMapPreview(&rect, scale, color, qtrue);
  3133. break;
  3134. case UI_MAP_TIMETOBEAT:
  3135. UI_DrawMapTimeToBeat(&rect, scale, color, textStyle, iMenuFont);
  3136. break;
  3137. case UI_MAPCINEMATIC:
  3138. UI_DrawMapCinematic(&rect, scale, color, qfalse);
  3139. break;
  3140. case UI_STARTMAPCINEMATIC:
  3141. UI_DrawMapCinematic(&rect, scale, color, qtrue);
  3142. break;
  3143. case UI_SKILL:
  3144. UI_DrawSkill(&rect, scale, color, textStyle, iMenuFont);
  3145. break;
  3146. case UI_TOTALFORCESTARS:
  3147. // UI_DrawTotalForceStars(&rect, scale, color, textStyle);
  3148. break;
  3149. case UI_BLUETEAMNAME:
  3150. UI_DrawTeamName(&rect, scale, color, qtrue, textStyle, iMenuFont);
  3151. break;
  3152. case UI_REDTEAMNAME:
  3153. UI_DrawTeamName(&rect, scale, color, qfalse, textStyle, iMenuFont);
  3154. break;
  3155. case UI_BLUETEAM1:
  3156. case UI_BLUETEAM2:
  3157. case UI_BLUETEAM3:
  3158. case UI_BLUETEAM4:
  3159. case UI_BLUETEAM5:
  3160. case UI_BLUETEAM6:
  3161. case UI_BLUETEAM7:
  3162. case UI_BLUETEAM8:
  3163. if (ownerDraw <= UI_BLUETEAM5)
  3164. {
  3165. iUse = ownerDraw-UI_BLUETEAM1 + 1;
  3166. }
  3167. else
  3168. {
  3169. iUse = ownerDraw-274; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
  3170. }
  3171. UI_DrawTeamMember(&rect, scale, color, qtrue, iUse, textStyle, iMenuFont);
  3172. break;
  3173. case UI_REDTEAM1:
  3174. case UI_REDTEAM2:
  3175. case UI_REDTEAM3:
  3176. case UI_REDTEAM4:
  3177. case UI_REDTEAM5:
  3178. case UI_REDTEAM6:
  3179. case UI_REDTEAM7:
  3180. case UI_REDTEAM8:
  3181. if (ownerDraw <= UI_REDTEAM5)
  3182. {
  3183. iUse = ownerDraw-UI_REDTEAM1 + 1;
  3184. }
  3185. else
  3186. {
  3187. iUse = ownerDraw-277; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
  3188. }
  3189. UI_DrawTeamMember(&rect, scale, color, qfalse, iUse, textStyle, iMenuFont);
  3190. break;
  3191. case UI_NETSOURCE:
  3192. UI_DrawNetSource(&rect, scale, color, textStyle, iMenuFont);
  3193. break;
  3194. case UI_NETMAPPREVIEW:
  3195. UI_DrawNetMapPreview(&rect, scale, color);
  3196. break;
  3197. case UI_NETMAPCINEMATIC:
  3198. UI_DrawNetMapCinematic(&rect, scale, color);
  3199. break;
  3200. case UI_NETFILTER:
  3201. UI_DrawNetFilter(&rect, scale, color, textStyle, iMenuFont);
  3202. break;
  3203. case UI_TIER:
  3204. UI_DrawTier(&rect, scale, color, textStyle, iMenuFont);
  3205. break;
  3206. case UI_OPPONENTMODEL:
  3207. //UI_DrawOpponent(&rect);
  3208. break;
  3209. case UI_TIERMAP1:
  3210. UI_DrawTierMap(&rect, 0);
  3211. break;
  3212. case UI_TIERMAP2:
  3213. UI_DrawTierMap(&rect, 1);
  3214. break;
  3215. case UI_TIERMAP3:
  3216. UI_DrawTierMap(&rect, 2);
  3217. break;
  3218. case UI_PLAYERLOGO:
  3219. UI_DrawPlayerLogo(&rect, color);
  3220. break;
  3221. case UI_PLAYERLOGO_METAL:
  3222. UI_DrawPlayerLogoMetal(&rect, color);
  3223. break;
  3224. case UI_PLAYERLOGO_NAME:
  3225. UI_DrawPlayerLogoName(&rect, color);
  3226. break;
  3227. case UI_OPPONENTLOGO:
  3228. UI_DrawOpponentLogo(&rect, color);
  3229. break;
  3230. case UI_OPPONENTLOGO_METAL:
  3231. UI_DrawOpponentLogoMetal(&rect, color);
  3232. break;
  3233. case UI_OPPONENTLOGO_NAME:
  3234. UI_DrawOpponentLogoName(&rect, color);
  3235. break;
  3236. case UI_TIER_MAPNAME:
  3237. UI_DrawTierMapName(&rect, scale, color, textStyle, iMenuFont);
  3238. break;
  3239. case UI_TIER_GAMETYPE:
  3240. UI_DrawTierGameType(&rect, scale, color, textStyle, iMenuFont);
  3241. break;
  3242. case UI_ALLMAPS_SELECTION:
  3243. UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qtrue, iMenuFont);
  3244. break;
  3245. case UI_MAPS_SELECTION:
  3246. UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qfalse, iMenuFont);
  3247. break;
  3248. case UI_OPPONENT_NAME:
  3249. UI_DrawOpponentName(&rect, scale, color, textStyle, iMenuFont);
  3250. break;
  3251. case UI_BOTNAME:
  3252. UI_DrawBotName(&rect, scale, color, textStyle,iMenuFont);
  3253. break;
  3254. case UI_BOTSKILL:
  3255. UI_DrawBotSkill(&rect, scale, color, textStyle,iMenuFont);
  3256. break;
  3257. case UI_REDBLUE:
  3258. UI_DrawRedBlue(&rect, scale, color, textStyle,iMenuFont);
  3259. break;
  3260. case UI_CROSSHAIR:
  3261. UI_DrawCrosshair(&rect, scale, color);
  3262. break;
  3263. case UI_SELECTEDPLAYER:
  3264. UI_DrawSelectedPlayer(&rect, scale, color, textStyle, iMenuFont);
  3265. break;
  3266. case UI_SERVERREFRESHDATE:
  3267. UI_DrawServerRefreshDate(&rect, scale, color, textStyle, iMenuFont);
  3268. break;
  3269. case UI_SERVERMOTD:
  3270. UI_DrawServerMOTD(&rect, scale, color, iMenuFont);
  3271. break;
  3272. case UI_GLINFO:
  3273. UI_DrawGLInfo(&rect,scale, color, textStyle, iMenuFont);
  3274. break;
  3275. case UI_KEYBINDSTATUS:
  3276. UI_DrawKeyBindStatus(&rect,scale, color, textStyle,iMenuFont);
  3277. break;
  3278. case UI_VERSION:
  3279. UI_Version(&rect, scale, color, iMenuFont);
  3280. break;
  3281. default:
  3282. break;
  3283. }
  3284. }
  3285. static qboolean UI_OwnerDrawVisible(int flags) {
  3286. qboolean vis = qtrue;
  3287. while (flags) {
  3288. if (flags & UI_SHOW_FFA) {
  3289. if (trap_Cvar_VariableValue("g_gametype") != GT_FFA && trap_Cvar_VariableValue("g_gametype") != GT_HOLOCRON && trap_Cvar_VariableValue("g_gametype") != GT_JEDIMASTER) {
  3290. vis = qfalse;
  3291. }
  3292. flags &= ~UI_SHOW_FFA;
  3293. }
  3294. if (flags & UI_SHOW_NOTFFA) {
  3295. if (trap_Cvar_VariableValue("g_gametype") == GT_FFA || trap_Cvar_VariableValue("g_gametype") == GT_HOLOCRON || trap_Cvar_VariableValue("g_gametype") != GT_JEDIMASTER) {
  3296. vis = qfalse;
  3297. }
  3298. flags &= ~UI_SHOW_NOTFFA;
  3299. }
  3300. if (flags & UI_SHOW_LEADER) {
  3301. // these need to show when this client can give orders to a player or a group
  3302. if (!uiInfo.teamLeader) {
  3303. vis = qfalse;
  3304. } else {
  3305. // if showing yourself
  3306. if (ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber) {
  3307. vis = qfalse;
  3308. }
  3309. }
  3310. flags &= ~UI_SHOW_LEADER;
  3311. }
  3312. if (flags & UI_SHOW_NOTLEADER) {
  3313. // these need to show when this client is assigning their own status or they are NOT the leader
  3314. if (uiInfo.teamLeader) {
  3315. // if not showing yourself
  3316. if (!(ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber)) {
  3317. vis = qfalse;
  3318. }
  3319. // these need to show when this client can give orders to a player or a group
  3320. }
  3321. flags &= ~UI_SHOW_NOTLEADER;
  3322. }
  3323. if (flags & UI_SHOW_FAVORITESERVERS) {
  3324. // this assumes you only put this type of display flag on something showing in the proper context
  3325. if (ui_netSource.integer != AS_FAVORITES) {
  3326. vis = qfalse;
  3327. }
  3328. flags &= ~UI_SHOW_FAVORITESERVERS;
  3329. }
  3330. if (flags & UI_SHOW_NOTFAVORITESERVERS) {
  3331. // this assumes you only put this type of display flag on something showing in the proper context
  3332. if (ui_netSource.integer == AS_FAVORITES) {
  3333. vis = qfalse;
  3334. }
  3335. flags &= ~UI_SHOW_NOTFAVORITESERVERS;
  3336. }
  3337. if (flags & UI_SHOW_ANYTEAMGAME) {
  3338. if (uiInfo.gameTypes[ui_gameType.integer].gtEnum <= GT_TEAM ) {
  3339. vis = qfalse;
  3340. }
  3341. flags &= ~UI_SHOW_ANYTEAMGAME;
  3342. }
  3343. if (flags & UI_SHOW_ANYNONTEAMGAME) {
  3344. if (uiInfo.gameTypes[ui_gameType.integer].gtEnum > GT_TEAM ) {
  3345. vis = qfalse;
  3346. }
  3347. flags &= ~UI_SHOW_ANYNONTEAMGAME;
  3348. }
  3349. if (flags & UI_SHOW_NETANYTEAMGAME) {
  3350. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum <= GT_TEAM ) {
  3351. vis = qfalse;
  3352. }
  3353. flags &= ~UI_SHOW_NETANYTEAMGAME;
  3354. }
  3355. if (flags & UI_SHOW_NETANYNONTEAMGAME) {
  3356. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum > GT_TEAM ) {
  3357. vis = qfalse;
  3358. }
  3359. flags &= ~UI_SHOW_NETANYNONTEAMGAME;
  3360. }
  3361. if (flags & UI_SHOW_NEWHIGHSCORE) {
  3362. if (uiInfo.newHighScoreTime < uiInfo.uiDC.realTime) {
  3363. vis = qfalse;
  3364. } else {
  3365. if (uiInfo.soundHighScore) {
  3366. if (trap_Cvar_VariableValue("sv_killserver") == 0) {
  3367. // wait on server to go down before playing sound
  3368. //trap_S_StartLocalSound(uiInfo.newHighScoreSound, CHAN_ANNOUNCER);
  3369. uiInfo.soundHighScore = qfalse;
  3370. }
  3371. }
  3372. }
  3373. flags &= ~UI_SHOW_NEWHIGHSCORE;
  3374. }
  3375. if (flags & UI_SHOW_NEWBESTTIME) {
  3376. if (uiInfo.newBestTime < uiInfo.uiDC.realTime) {
  3377. vis = qfalse;
  3378. }
  3379. flags &= ~UI_SHOW_NEWBESTTIME;
  3380. }
  3381. if (flags & UI_SHOW_DEMOAVAILABLE) {
  3382. if (!uiInfo.demoAvailable) {
  3383. vis = qfalse;
  3384. }
  3385. flags &= ~UI_SHOW_DEMOAVAILABLE;
  3386. } else {
  3387. flags = 0;
  3388. }
  3389. }
  3390. return vis;
  3391. }
  3392. static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) {
  3393. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3394. int h;
  3395. h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
  3396. if (key == A_MOUSE2) {
  3397. h -= 5;
  3398. } else {
  3399. h += 5;
  3400. }
  3401. if (h > 100) {
  3402. h = 5;
  3403. } else if (h < 0) {
  3404. h = 100;
  3405. }
  3406. trap_Cvar_Set( "handicap", va( "%i", h) );
  3407. return qtrue;
  3408. }
  3409. return qfalse;
  3410. }
  3411. static qboolean UI_Effects_HandleKey(int flags, float *special, int key) {
  3412. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3413. if ( !UI_TrueJediEnabled() )
  3414. {
  3415. int team = (int)(trap_Cvar_VariableValue("ui_myteam"));
  3416. if (team == TEAM_RED || team==TEAM_BLUE)
  3417. {
  3418. return qfalse;
  3419. }
  3420. }
  3421. if (key == A_MOUSE2) {
  3422. uiInfo.effectsColor--;
  3423. } else {
  3424. uiInfo.effectsColor++;
  3425. }
  3426. if( uiInfo.effectsColor > 5 ) {
  3427. uiInfo.effectsColor = 0;
  3428. } else if (uiInfo.effectsColor < 0) {
  3429. uiInfo.effectsColor = 5;
  3430. }
  3431. trap_Cvar_SetValue( "color1", /*uitogamecode[uiInfo.effectsColor]*/uiInfo.effectsColor );
  3432. return qtrue;
  3433. }
  3434. return qfalse;
  3435. }
  3436. #include "../namespace_begin.h"
  3437. extern void Item_RunScript(itemDef_t *item, const char *s); //from ui_shared;
  3438. #include "../namespace_end.h"
  3439. // For hot keys on the chat main menu.
  3440. static qboolean UI_Chat_Main_HandleKey(int key)
  3441. {
  3442. menuDef_t *menu;
  3443. itemDef_t *item;
  3444. menu = Menu_GetFocused();
  3445. if (!menu)
  3446. {
  3447. return (qfalse);
  3448. }
  3449. if ((key == A_1) || ( key == A_PLING))
  3450. {
  3451. item = Menu_FindItemByName(menu, "attack");
  3452. }
  3453. else if ((key == A_2) || ( key == A_AT))
  3454. {
  3455. item = Menu_FindItemByName(menu, "defend");
  3456. }
  3457. else if ((key == A_3) || ( key == A_HASH))
  3458. {
  3459. item = Menu_FindItemByName(menu, "request");
  3460. }
  3461. else if ((key == A_4) || ( key == A_STRING))
  3462. {
  3463. item = Menu_FindItemByName(menu, "reply");
  3464. }
  3465. else if ((key == A_5) || ( key == A_PERCENT))
  3466. {
  3467. item = Menu_FindItemByName(menu, "spot");
  3468. }
  3469. else if ((key == A_6) || ( key == A_CARET))
  3470. {
  3471. item = Menu_FindItemByName(menu, "tactics");
  3472. }
  3473. else
  3474. {
  3475. return (qfalse);
  3476. }
  3477. if (item)
  3478. {
  3479. Item_RunScript(item, item->action);
  3480. }
  3481. return (qtrue);
  3482. }
  3483. // For hot keys on the chat main menu.
  3484. static qboolean UI_Chat_Attack_HandleKey(int key)
  3485. {
  3486. menuDef_t *menu;
  3487. itemDef_t *item;
  3488. menu = Menu_GetFocused();
  3489. if (!menu)
  3490. {
  3491. return (qfalse);
  3492. }
  3493. if ((key == A_1) || ( key == A_PLING))
  3494. {
  3495. item = Menu_FindItemByName(menu, "att_01");
  3496. }
  3497. else if ((key == A_2) || ( key == A_AT))
  3498. {
  3499. item = Menu_FindItemByName(menu, "att_02");
  3500. }
  3501. else if ((key == A_3) || ( key == A_HASH))
  3502. {
  3503. item = Menu_FindItemByName(menu, "att_03");
  3504. }
  3505. else
  3506. {
  3507. return (qfalse);
  3508. }
  3509. if (item)
  3510. {
  3511. Item_RunScript(item, item->action);
  3512. }
  3513. return (qtrue);
  3514. }
  3515. // For hot keys on the chat main menu.
  3516. static qboolean UI_Chat_Defend_HandleKey(int key)
  3517. {
  3518. menuDef_t *menu;
  3519. itemDef_t *item;
  3520. menu = Menu_GetFocused();
  3521. if (!menu)
  3522. {
  3523. return (qfalse);
  3524. }
  3525. if ((key == A_1) || ( key == A_PLING))
  3526. {
  3527. item = Menu_FindItemByName(menu, "def_01");
  3528. }
  3529. else if ((key == A_2) || ( key == A_AT))
  3530. {
  3531. item = Menu_FindItemByName(menu, "def_02");
  3532. }
  3533. else if ((key == A_3) || ( key == A_HASH))
  3534. {
  3535. item = Menu_FindItemByName(menu, "def_03");
  3536. }
  3537. else if ((key == A_4) || ( key == A_STRING))
  3538. {
  3539. item = Menu_FindItemByName(menu, "def_04");
  3540. }
  3541. else
  3542. {
  3543. return (qfalse);
  3544. }
  3545. if (item)
  3546. {
  3547. Item_RunScript(item, item->action);
  3548. }
  3549. return (qtrue);
  3550. }
  3551. // For hot keys on the chat main menu.
  3552. static qboolean UI_Chat_Request_HandleKey(int key)
  3553. {
  3554. menuDef_t *menu;
  3555. itemDef_t *item;
  3556. menu = Menu_GetFocused();
  3557. if (!menu)
  3558. {
  3559. return (qfalse);
  3560. }
  3561. if ((key == A_1) || ( key == A_PLING))
  3562. {
  3563. item = Menu_FindItemByName(menu, "req_01");
  3564. }
  3565. else if ((key == A_2) || ( key == A_AT))
  3566. {
  3567. item = Menu_FindItemByName(menu, "req_02");
  3568. }
  3569. else if ((key == A_3) || ( key == A_HASH))
  3570. {
  3571. item = Menu_FindItemByName(menu, "req_03");
  3572. }
  3573. else if ((key == A_4) || ( key == A_STRING))
  3574. {
  3575. item = Menu_FindItemByName(menu, "req_04");
  3576. }
  3577. else if ((key == A_5) || ( key == A_PERCENT))
  3578. {
  3579. item = Menu_FindItemByName(menu, "req_05");
  3580. }
  3581. else if ((key == A_6) || ( key == A_CARET))
  3582. {
  3583. item = Menu_FindItemByName(menu, "req_06");
  3584. }
  3585. else
  3586. {
  3587. return (qfalse);
  3588. }
  3589. if (item)
  3590. {
  3591. Item_RunScript(item, item->action);
  3592. }
  3593. return (qtrue);
  3594. }
  3595. // For hot keys on the chat main menu.
  3596. static qboolean UI_Chat_Reply_HandleKey(int key)
  3597. {
  3598. menuDef_t *menu;
  3599. itemDef_t *item;
  3600. menu = Menu_GetFocused();
  3601. if (!menu)
  3602. {
  3603. return (qfalse);
  3604. }
  3605. if ((key == A_1) || ( key == A_PLING))
  3606. {
  3607. item = Menu_FindItemByName(menu, "rep_01");
  3608. }
  3609. else if ((key == A_2) || ( key == A_AT))
  3610. {
  3611. item = Menu_FindItemByName(menu, "rep_02");
  3612. }
  3613. else if ((key == A_3) || ( key == A_HASH))
  3614. {
  3615. item = Menu_FindItemByName(menu, "rep_03");
  3616. }
  3617. else if ((key == A_4) || ( key == A_STRING))
  3618. {
  3619. item = Menu_FindItemByName(menu, "rep_04");
  3620. }
  3621. else if ((key == A_5) || ( key == A_PERCENT))
  3622. {
  3623. item = Menu_FindItemByName(menu, "rep_05");
  3624. }
  3625. else
  3626. {
  3627. return (qfalse);
  3628. }
  3629. if (item)
  3630. {
  3631. Item_RunScript(item, item->action);
  3632. }
  3633. return (qtrue);
  3634. }
  3635. // For hot keys on the chat main menu.
  3636. static qboolean UI_Chat_Spot_HandleKey(int key)
  3637. {
  3638. menuDef_t *menu;
  3639. itemDef_t *item;
  3640. menu = Menu_GetFocused();
  3641. if (!menu)
  3642. {
  3643. return (qfalse);
  3644. }
  3645. if ((key == A_1) || ( key == A_PLING))
  3646. {
  3647. item = Menu_FindItemByName(menu, "spot_01");
  3648. }
  3649. else if ((key == A_2) || ( key == A_AT))
  3650. {
  3651. item = Menu_FindItemByName(menu, "spot_02");
  3652. }
  3653. else if ((key == A_3) || ( key == A_HASH))
  3654. {
  3655. item = Menu_FindItemByName(menu, "spot_03");
  3656. }
  3657. else if ((key == A_4) || ( key == A_STRING))
  3658. {
  3659. item = Menu_FindItemByName(menu, "spot_04");
  3660. }
  3661. else
  3662. {
  3663. return (qfalse);
  3664. }
  3665. if (item)
  3666. {
  3667. Item_RunScript(item, item->action);
  3668. }
  3669. return (qtrue);
  3670. }
  3671. // For hot keys on the chat main menu.
  3672. static qboolean UI_Chat_Tactical_HandleKey(int key)
  3673. {
  3674. menuDef_t *menu;
  3675. itemDef_t *item;
  3676. menu = Menu_GetFocused();
  3677. if (!menu)
  3678. {
  3679. return (qfalse);
  3680. }
  3681. if ((key == A_1) || ( key == A_PLING))
  3682. {
  3683. item = Menu_FindItemByName(menu, "tac_01");
  3684. }
  3685. else if ((key == A_2) || ( key == A_AT))
  3686. {
  3687. item = Menu_FindItemByName(menu, "tac_02");
  3688. }
  3689. else if ((key == A_3) || ( key == A_HASH))
  3690. {
  3691. item = Menu_FindItemByName(menu, "tac_03");
  3692. }
  3693. else if ((key == A_4) || ( key == A_STRING))
  3694. {
  3695. item = Menu_FindItemByName(menu, "tac_04");
  3696. }
  3697. else if ((key == A_5) || ( key == A_PERCENT))
  3698. {
  3699. item = Menu_FindItemByName(menu, "tac_05");
  3700. }
  3701. else if ((key == A_6) || ( key == A_CARET))
  3702. {
  3703. item = Menu_FindItemByName(menu, "tac_06");
  3704. }
  3705. else
  3706. {
  3707. return (qfalse);
  3708. }
  3709. if (item)
  3710. {
  3711. Item_RunScript(item, item->action);
  3712. }
  3713. return (qtrue);
  3714. }
  3715. static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) {
  3716. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3717. int oldCount = UI_MapCountByGameType(qtrue);
  3718. // hard coded mess here
  3719. if (key == A_MOUSE2) {
  3720. ui_gameType.integer--;
  3721. if (ui_gameType.integer == 2) {
  3722. ui_gameType.integer = 1;
  3723. } else if (ui_gameType.integer < 2) {
  3724. ui_gameType.integer = uiInfo.numGameTypes - 1;
  3725. }
  3726. } else {
  3727. ui_gameType.integer++;
  3728. if (ui_gameType.integer >= uiInfo.numGameTypes) {
  3729. ui_gameType.integer = 1;
  3730. } else if (ui_gameType.integer == 2) {
  3731. ui_gameType.integer = 3;
  3732. }
  3733. }
  3734. trap_Cvar_Set("ui_gameType", va("%d", ui_gameType.integer));
  3735. UI_SetCapFragLimits(qtrue);
  3736. UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
  3737. if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) {
  3738. trap_Cvar_Set( "ui_currentMap", "0");
  3739. Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL);
  3740. }
  3741. return qtrue;
  3742. }
  3743. return qfalse;
  3744. }
  3745. //[UITweaks]
  3746. //we want to be able to select seige in solo mode.
  3747. /*
  3748. // If we're in the solo menu, don't let them see siege maps.
  3749. static qboolean UI_InSoloMenu( void )
  3750. {
  3751. menuDef_t *menu;
  3752. itemDef_t *item;
  3753. char *name = "solo_gametypefield";
  3754. menu = Menu_GetFocused(); // Get current menu (either video or ingame video, I would assume)
  3755. if (!menu)
  3756. {
  3757. return (qfalse);
  3758. }
  3759. item = Menu_FindItemByName(menu, name);
  3760. if (item)
  3761. {
  3762. return qtrue;
  3763. }
  3764. return (qfalse);
  3765. }
  3766. */
  3767. //[/UITweaks]
  3768. static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key)
  3769. {
  3770. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER)
  3771. {
  3772. if (key == A_MOUSE2)
  3773. {
  3774. ui_netGameType.integer--;
  3775. //[UITweaks]
  3776. //we want to be able to select seige in solo mode.
  3777. /*
  3778. if (UI_InSoloMenu())
  3779. {
  3780. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
  3781. {
  3782. ui_netGameType.integer--;
  3783. }
  3784. }
  3785. */
  3786. //[/UITweaks]
  3787. }
  3788. else
  3789. {
  3790. ui_netGameType.integer++;
  3791. //[UITweaks]
  3792. //we want to be able to select seige in solo mode.
  3793. /*
  3794. if (UI_InSoloMenu())
  3795. {
  3796. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
  3797. {
  3798. ui_netGameType.integer++;
  3799. }
  3800. }
  3801. */
  3802. //[/UITweaks]
  3803. }
  3804. if (ui_netGameType.integer < 0)
  3805. {
  3806. ui_netGameType.integer = uiInfo.numGameTypes - 1;
  3807. }
  3808. else if (ui_netGameType.integer >= uiInfo.numGameTypes)
  3809. {
  3810. ui_netGameType.integer = 0;
  3811. }
  3812. trap_Cvar_Set( "ui_netGameType", va("%d", ui_netGameType.integer));
  3813. trap_Cvar_Set( "ui_actualnetGameType", va("%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum));
  3814. trap_Cvar_Set( "ui_currentNetMap", "0");
  3815. UI_MapCountByGameType(qfalse);
  3816. Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL);
  3817. return qtrue;
  3818. }
  3819. return qfalse;
  3820. }
  3821. static qboolean UI_AutoSwitch_HandleKey(int flags, float *special, int key) {
  3822. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3823. int switchVal = trap_Cvar_VariableValue("cg_autoswitch");
  3824. if (key == A_MOUSE2) {
  3825. switchVal--;
  3826. } else {
  3827. switchVal++;
  3828. }
  3829. if (switchVal < 0)
  3830. {
  3831. switchVal = 2;
  3832. }
  3833. else if (switchVal >= 3)
  3834. {
  3835. switchVal = 0;
  3836. }
  3837. trap_Cvar_Set( "cg_autoswitch", va("%i", switchVal));
  3838. return qtrue;
  3839. }
  3840. return qfalse;
  3841. }
  3842. static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
  3843. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3844. if (key == A_MOUSE2) {
  3845. ui_joinGameType.integer--;
  3846. } else {
  3847. ui_joinGameType.integer++;
  3848. }
  3849. if (ui_joinGameType.integer < 0) {
  3850. ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1;
  3851. } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) {
  3852. ui_joinGameType.integer = 0;
  3853. }
  3854. trap_Cvar_Set( "ui_joinGameType", va("%d", ui_joinGameType.integer));
  3855. UI_BuildServerDisplayList(qtrue);
  3856. return qtrue;
  3857. }
  3858. return qfalse;
  3859. }
  3860. static qboolean UI_Skill_HandleKey(int flags, float *special, int key) {
  3861. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3862. int i = trap_Cvar_VariableValue( "g_spSkill" );
  3863. if (key == A_MOUSE2) {
  3864. i--;
  3865. } else {
  3866. i++;
  3867. }
  3868. if (i < 1) {
  3869. i = numSkillLevels;
  3870. } else if (i > numSkillLevels) {
  3871. i = 1;
  3872. }
  3873. trap_Cvar_Set("g_spSkill", va("%i", i));
  3874. return qtrue;
  3875. }
  3876. return qfalse;
  3877. }
  3878. static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) {
  3879. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3880. int i;
  3881. i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
  3882. if (key == A_MOUSE2) {
  3883. i--;
  3884. } else {
  3885. i++;
  3886. }
  3887. if (i >= uiInfo.teamCount) {
  3888. i = 0;
  3889. } else if (i < 0) {
  3890. i = uiInfo.teamCount - 1;
  3891. }
  3892. trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName);
  3893. return qtrue;
  3894. }
  3895. return qfalse;
  3896. }
  3897. static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) {
  3898. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3899. // 0 - None
  3900. // 1 - Human
  3901. // 2..NumCharacters - Bot
  3902. char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num);
  3903. int value = trap_Cvar_VariableValue(cvar);
  3904. int maxcl = trap_Cvar_VariableValue( "sv_maxClients" );
  3905. int numval = num;
  3906. numval *= 2;
  3907. if (blue)
  3908. {
  3909. numval -= 1;
  3910. }
  3911. if (numval > maxcl)
  3912. {
  3913. return qfalse;
  3914. }
  3915. if (value < 1)
  3916. {
  3917. value = 1;
  3918. }
  3919. if (key == A_MOUSE2) {
  3920. value--;
  3921. } else {
  3922. value++;
  3923. }
  3924. /*if (ui_actualNetGameType.integer >= GT_TEAM) {
  3925. if (value >= uiInfo.characterCount + 2) {
  3926. value = 0;
  3927. } else if (value < 0) {
  3928. value = uiInfo.characterCount + 2 - 1;
  3929. }
  3930. } else {*/
  3931. if (value >= UI_GetNumBots() + 2) {
  3932. value = 1;
  3933. } else if (value < 1) {
  3934. value = UI_GetNumBots() + 2 - 1;
  3935. }
  3936. //}
  3937. trap_Cvar_Set(cvar, va("%i", value));
  3938. return qtrue;
  3939. }
  3940. return qfalse;
  3941. }
  3942. static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
  3943. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3944. if (key == A_MOUSE2) {
  3945. ui_netSource.integer--;
  3946. } else {
  3947. ui_netSource.integer++;
  3948. }
  3949. if (ui_netSource.integer >= numNetSources) {
  3950. ui_netSource.integer = 0;
  3951. } else if (ui_netSource.integer < 0) {
  3952. ui_netSource.integer = numNetSources - 1;
  3953. }
  3954. UI_BuildServerDisplayList(qtrue);
  3955. if (ui_netSource.integer != AS_GLOBAL) {
  3956. UI_StartServerRefresh(qtrue);
  3957. }
  3958. trap_Cvar_Set( "ui_netSource", va("%d", ui_netSource.integer));
  3959. return qtrue;
  3960. }
  3961. return qfalse;
  3962. }
  3963. static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) {
  3964. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3965. if (key == A_MOUSE2) {
  3966. ui_serverFilterType.integer--;
  3967. } else {
  3968. ui_serverFilterType.integer++;
  3969. }
  3970. if (ui_serverFilterType.integer >= numServerFilters) {
  3971. ui_serverFilterType.integer = 0;
  3972. } else if (ui_serverFilterType.integer < 0) {
  3973. ui_serverFilterType.integer = numServerFilters - 1;
  3974. }
  3975. UI_BuildServerDisplayList(qtrue);
  3976. return qtrue;
  3977. }
  3978. return qfalse;
  3979. }
  3980. static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) {
  3981. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3982. if (key == A_MOUSE2) {
  3983. UI_PriorOpponent();
  3984. } else {
  3985. UI_NextOpponent();
  3986. }
  3987. return qtrue;
  3988. }
  3989. return qfalse;
  3990. }
  3991. static qboolean UI_BotName_HandleKey(int flags, float *special, int key) {
  3992. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  3993. // int game = trap_Cvar_VariableValue("g_gametype");
  3994. int value = uiInfo.botIndex;
  3995. if (key == A_MOUSE2) {
  3996. value--;
  3997. } else {
  3998. value++;
  3999. }
  4000. /*
  4001. if (game >= GT_TEAM) {
  4002. if (value >= uiInfo.characterCount + 2) {
  4003. value = 0;
  4004. } else if (value < 0) {
  4005. value = uiInfo.characterCount + 2 - 1;
  4006. }
  4007. } else {
  4008. */
  4009. if (value >= UI_GetNumBots()/* + 2*/) {
  4010. value = 0;
  4011. } else if (value < 0) {
  4012. value = UI_GetNumBots()/* + 2*/ - 1;
  4013. }
  4014. //}
  4015. uiInfo.botIndex = value;
  4016. return qtrue;
  4017. }
  4018. return qfalse;
  4019. }
  4020. static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) {
  4021. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  4022. if (key == A_MOUSE2) {
  4023. uiInfo.skillIndex--;
  4024. } else {
  4025. uiInfo.skillIndex++;
  4026. }
  4027. if (uiInfo.skillIndex >= numSkillLevels) {
  4028. uiInfo.skillIndex = 0;
  4029. } else if (uiInfo.skillIndex < 0) {
  4030. uiInfo.skillIndex = numSkillLevels-1;
  4031. }
  4032. return qtrue;
  4033. }
  4034. return qfalse;
  4035. }
  4036. static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) {
  4037. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  4038. uiInfo.redBlue ^= 1;
  4039. return qtrue;
  4040. }
  4041. return qfalse;
  4042. }
  4043. static qboolean UI_Crosshair_HandleKey(int flags, float *special, int key) {
  4044. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  4045. if (key == A_MOUSE2) {
  4046. uiInfo.currentCrosshair--;
  4047. } else {
  4048. uiInfo.currentCrosshair++;
  4049. }
  4050. if (uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
  4051. uiInfo.currentCrosshair = 0;
  4052. } else if (uiInfo.currentCrosshair < 0) {
  4053. uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
  4054. }
  4055. trap_Cvar_Set("cg_drawCrosshair", va("%d", uiInfo.currentCrosshair));
  4056. return qtrue;
  4057. }
  4058. return qfalse;
  4059. }
  4060. static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) {
  4061. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER) {
  4062. int selected;
  4063. UI_BuildPlayerList();
  4064. if (!uiInfo.teamLeader) {
  4065. return qfalse;
  4066. }
  4067. selected = trap_Cvar_VariableValue("cg_selectedPlayer");
  4068. if (key == A_MOUSE2) {
  4069. selected--;
  4070. } else {
  4071. selected++;
  4072. }
  4073. if (selected > uiInfo.myTeamCount) {
  4074. selected = 0;
  4075. } else if (selected < 0) {
  4076. selected = uiInfo.myTeamCount;
  4077. }
  4078. if (selected == uiInfo.myTeamCount) {
  4079. trap_Cvar_Set( "cg_selectedPlayerName", "Everyone");
  4080. } else {
  4081. trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]);
  4082. }
  4083. trap_Cvar_Set( "cg_selectedPlayer", va("%d", selected));
  4084. }
  4085. return qfalse;
  4086. }
  4087. /*
  4088. static qboolean UI_VoiceChat_HandleKey(int flags, float *special, int key)
  4089. {
  4090. qboolean ret = qfalse;
  4091. switch(key)
  4092. {
  4093. case A_1:
  4094. case A_KP_1:
  4095. ret = qtrue;
  4096. break;
  4097. case A_2:
  4098. case A_KP_2:
  4099. ret = qtrue;
  4100. break;
  4101. }
  4102. return ret;
  4103. }
  4104. */
  4105. static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) {
  4106. int findex, iUse = 0;
  4107. //[NewUI]
  4108. if(IsForceRank(ownerDraw))
  4109. {
  4110. if(ownerDraw < UI_FORCE_RANK_JETPACK)
  4111. {
  4112. findex = (ownerDraw - UI_FORCE_RANK)-1;
  4113. }
  4114. else
  4115. {//use a different index shift for the addition skills
  4116. findex = (ownerDraw - UI_FORCE_RANK_JETPACK)+(UI_FORCE_RANK_SABERTHROW-UI_FORCE_RANK);
  4117. }
  4118. //this will give us the index as long as UI_FORCE_RANK is always one below the first force rank index
  4119. return UI_ForcePowerRank_HandleKey(flags, special, key, uiRank[findex].uiForcePowersRank, 0, NUM_FORCE_POWER_LEVELS-1, ownerDraw);
  4120. }
  4121. //[/NewUI]
  4122. switch (ownerDraw) {
  4123. case UI_HANDICAP:
  4124. return UI_Handicap_HandleKey(flags, special, key);
  4125. break;
  4126. case UI_SKIN_COLOR:
  4127. return UI_SkinColor_HandleKey(flags, special, key, uiSkinColor, TEAM_FREE, TEAM_BLUE, ownerDraw);
  4128. break;
  4129. case UI_FORCE_SIDE:
  4130. return UI_ForceSide_HandleKey(flags, special, key, uiForceSide, 1, 2, ownerDraw);
  4131. break;
  4132. case UI_JEDI_NONJEDI:
  4133. return UI_JediNonJedi_HandleKey(flags, special, key, uiJediNonJedi, 0, 1, ownerDraw);
  4134. break;
  4135. //racc - this shouldn't be used anymore since the experience system uses g_forceMaxRank differently.
  4136. case UI_FORCE_MASTERY_SET:
  4137. return UI_ForceMaxRank_HandleKey(flags, special, key, uiForceRank, 1, MAX_FORCE_RANK, ownerDraw);
  4138. break;
  4139. case UI_FORCE_RANK:
  4140. break;
  4141. case UI_CHAT_MAIN:
  4142. return UI_Chat_Main_HandleKey(key);
  4143. break;
  4144. case UI_CHAT_ATTACK:
  4145. return UI_Chat_Attack_HandleKey(key);
  4146. break;
  4147. case UI_CHAT_DEFEND:
  4148. return UI_Chat_Defend_HandleKey(key);
  4149. break;
  4150. case UI_CHAT_REQUEST:
  4151. return UI_Chat_Request_HandleKey(key);
  4152. break;
  4153. case UI_CHAT_REPLY:
  4154. return UI_Chat_Reply_HandleKey(key);
  4155. break;
  4156. case UI_CHAT_SPOT:
  4157. return UI_Chat_Spot_HandleKey(key);
  4158. break;
  4159. case UI_CHAT_TACTICAL:
  4160. return UI_Chat_Tactical_HandleKey(key);
  4161. break;
  4162. case UI_EFFECTS:
  4163. return UI_Effects_HandleKey(flags, special, key);
  4164. break;
  4165. case UI_GAMETYPE:
  4166. return UI_GameType_HandleKey(flags, special, key, qtrue);
  4167. break;
  4168. case UI_NETGAMETYPE:
  4169. return UI_NetGameType_HandleKey(flags, special, key);
  4170. break;
  4171. case UI_AUTOSWITCHLIST:
  4172. return UI_AutoSwitch_HandleKey(flags, special, key);
  4173. break;
  4174. case UI_JOINGAMETYPE:
  4175. return UI_JoinGameType_HandleKey(flags, special, key);
  4176. break;
  4177. case UI_SKILL:
  4178. return UI_Skill_HandleKey(flags, special, key);
  4179. break;
  4180. case UI_BLUETEAMNAME:
  4181. return UI_TeamName_HandleKey(flags, special, key, qtrue);
  4182. break;
  4183. case UI_REDTEAMNAME:
  4184. return UI_TeamName_HandleKey(flags, special, key, qfalse);
  4185. break;
  4186. case UI_BLUETEAM1:
  4187. case UI_BLUETEAM2:
  4188. case UI_BLUETEAM3:
  4189. case UI_BLUETEAM4:
  4190. case UI_BLUETEAM5:
  4191. case UI_BLUETEAM6:
  4192. case UI_BLUETEAM7:
  4193. case UI_BLUETEAM8:
  4194. if (ownerDraw <= UI_BLUETEAM5)
  4195. {
  4196. iUse = ownerDraw-UI_BLUETEAM1 + 1;
  4197. }
  4198. else
  4199. {
  4200. iUse = ownerDraw-274; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
  4201. }
  4202. UI_TeamMember_HandleKey(flags, special, key, qtrue, iUse);
  4203. break;
  4204. case UI_REDTEAM1:
  4205. case UI_REDTEAM2:
  4206. case UI_REDTEAM3:
  4207. case UI_REDTEAM4:
  4208. case UI_REDTEAM5:
  4209. case UI_REDTEAM6:
  4210. case UI_REDTEAM7:
  4211. case UI_REDTEAM8:
  4212. if (ownerDraw <= UI_REDTEAM5)
  4213. {
  4214. iUse = ownerDraw-UI_REDTEAM1 + 1;
  4215. }
  4216. else
  4217. {
  4218. iUse = ownerDraw-277; //unpleasent hack because I don't want to move up all the UI_BLAHTEAM# defines
  4219. }
  4220. UI_TeamMember_HandleKey(flags, special, key, qfalse, iUse);
  4221. break;
  4222. case UI_NETSOURCE:
  4223. UI_NetSource_HandleKey(flags, special, key);
  4224. break;
  4225. case UI_NETFILTER:
  4226. UI_NetFilter_HandleKey(flags, special, key);
  4227. break;
  4228. case UI_OPPONENT_NAME:
  4229. UI_OpponentName_HandleKey(flags, special, key);
  4230. break;
  4231. case UI_BOTNAME:
  4232. return UI_BotName_HandleKey(flags, special, key);
  4233. break;
  4234. case UI_BOTSKILL:
  4235. return UI_BotSkill_HandleKey(flags, special, key);
  4236. break;
  4237. case UI_REDBLUE:
  4238. UI_RedBlue_HandleKey(flags, special, key);
  4239. break;
  4240. case UI_CROSSHAIR:
  4241. UI_Crosshair_HandleKey(flags, special, key);
  4242. break;
  4243. case UI_SELECTEDPLAYER:
  4244. UI_SelectedPlayer_HandleKey(flags, special, key);
  4245. break;
  4246. // case UI_VOICECHAT:
  4247. // UI_VoiceChat_HandleKey(flags, special, key);
  4248. // break;
  4249. default:
  4250. break;
  4251. }
  4252. return qfalse;
  4253. }
  4254. static float UI_GetValue(int ownerDraw) {
  4255. return 0;
  4256. }
  4257. /*
  4258. =================
  4259. UI_ServersQsortCompare
  4260. =================
  4261. */
  4262. static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ) {
  4263. return trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, uiInfo.serverStatus.sortDir, *(int*)arg1, *(int*)arg2);
  4264. }
  4265. /*
  4266. =================
  4267. UI_ServersSort
  4268. =================
  4269. */
  4270. void UI_ServersSort(int column, qboolean force) {
  4271. if ( !force ) {
  4272. if ( uiInfo.serverStatus.sortKey == column ) {
  4273. return;
  4274. }
  4275. }
  4276. uiInfo.serverStatus.sortKey = column;
  4277. qsort( &uiInfo.serverStatus.displayServers[0], uiInfo.serverStatus.numDisplayServers, sizeof(int), UI_ServersQsortCompare);
  4278. }
  4279. /*
  4280. static void UI_StartSinglePlayer() {
  4281. int i,j, k, skill;
  4282. char buff[1024];
  4283. i = trap_Cvar_VariableValue( "ui_currentTier" );
  4284. if (i < 0 || i >= tierCount) {
  4285. i = 0;
  4286. }
  4287. j = trap_Cvar_VariableValue("ui_currentMap");
  4288. if (j < 0 || j > MAPS_PER_TIER) {
  4289. j = 0;
  4290. }
  4291. trap_Cvar_SetValue( "singleplayer", 1 );
  4292. trap_Cvar_SetValue( "g_gametype", Com_Clamp( 0, 7, tierList[i].gameTypes[j] ) );
  4293. trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", tierList[i].maps[j] ) );
  4294. skill = trap_Cvar_VariableValue( "g_spSkill" );
  4295. if (j == MAPS_PER_TIER-1) {
  4296. k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  4297. Com_sprintf( buff, sizeof(buff), "wait ; addbot %s %i %s 250 %s\n", UI_AIFromName(teamList[k].teamMembers[0]), skill, "", teamList[k].teamMembers[0]);
  4298. } else {
  4299. k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  4300. for (i = 0; i < PLAYERS_PER_TEAM; i++) {
  4301. 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]);
  4302. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  4303. }
  4304. k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  4305. for (i = 1; i < PLAYERS_PER_TEAM; i++) {
  4306. 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]);
  4307. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  4308. }
  4309. trap_Cmd_ExecuteText( EXEC_APPEND, "wait 5; team Red\n" );
  4310. }
  4311. }
  4312. */
  4313. /*
  4314. ===============
  4315. UI_LoadMods
  4316. ===============
  4317. */
  4318. static void UI_LoadMods() {
  4319. int numdirs;
  4320. char dirlist[2048];
  4321. char *dirptr;
  4322. char *descptr;
  4323. int i;
  4324. int dirlen;
  4325. uiInfo.modCount = 0;
  4326. numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) );
  4327. dirptr = dirlist;
  4328. for( i = 0; i < numdirs; i++ ) {
  4329. dirlen = strlen( dirptr ) + 1;
  4330. descptr = dirptr + dirlen;
  4331. uiInfo.modList[uiInfo.modCount].modName = String_Alloc(dirptr);
  4332. uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc(descptr);
  4333. dirptr += dirlen + strlen(descptr) + 1;
  4334. uiInfo.modCount++;
  4335. if (uiInfo.modCount >= MAX_MODS) {
  4336. break;
  4337. }
  4338. }
  4339. }
  4340. /*
  4341. ===============
  4342. UI_LoadMovies
  4343. ===============
  4344. */
  4345. static void UI_LoadMovies() {
  4346. char movielist[4096];
  4347. char *moviename;
  4348. int i, len;
  4349. uiInfo.movieCount = trap_FS_GetFileList( "video", "roq", movielist, 4096 );
  4350. if (uiInfo.movieCount) {
  4351. if (uiInfo.movieCount > MAX_MOVIES) {
  4352. uiInfo.movieCount = MAX_MOVIES;
  4353. }
  4354. moviename = movielist;
  4355. for ( i = 0; i < uiInfo.movieCount; i++ ) {
  4356. len = strlen( moviename );
  4357. if (!Q_stricmp(moviename + len - 4,".roq")) {
  4358. moviename[len-4] = '\0';
  4359. }
  4360. Q_strupr(moviename);
  4361. uiInfo.movieList[i] = String_Alloc(moviename);
  4362. moviename += len + 1;
  4363. }
  4364. }
  4365. }
  4366. /*
  4367. ===============
  4368. UI_LoadDemos
  4369. ===============
  4370. */
  4371. static void UI_LoadDemos() {
  4372. char demolist[4096];
  4373. char demoExt[32];
  4374. char *demoname;
  4375. int i, len;
  4376. Com_sprintf(demoExt, sizeof(demoExt), "dm_%d", (int)trap_Cvar_VariableValue("protocol"));
  4377. uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 );
  4378. Com_sprintf(demoExt, sizeof(demoExt), ".dm_%d", (int)trap_Cvar_VariableValue("protocol"));
  4379. if (uiInfo.demoCount) {
  4380. if (uiInfo.demoCount > MAX_DEMOS) {
  4381. uiInfo.demoCount = MAX_DEMOS;
  4382. }
  4383. demoname = demolist;
  4384. for ( i = 0; i < uiInfo.demoCount; i++ ) {
  4385. len = strlen( demoname );
  4386. if (!Q_stricmp(demoname + len - strlen(demoExt), demoExt)) {
  4387. demoname[len-strlen(demoExt)] = '\0';
  4388. }
  4389. Q_strupr(demoname);
  4390. uiInfo.demoList[i] = String_Alloc(demoname);
  4391. demoname += len + 1;
  4392. }
  4393. }
  4394. }
  4395. static qboolean UI_SetNextMap(int actual, int index) {
  4396. int i;
  4397. for (i = actual + 1; i < uiInfo.mapCount; i++) {
  4398. if (uiInfo.mapList[i].active) {
  4399. Menu_SetFeederSelection(NULL, FEEDER_MAPS, index + 1, "skirmish");
  4400. return qtrue;
  4401. }
  4402. }
  4403. return qfalse;
  4404. }
  4405. static void UI_StartSkirmish(qboolean next) {
  4406. int i, k, g, delay, temp;
  4407. float skill;
  4408. char buff[MAX_STRING_CHARS];
  4409. temp = trap_Cvar_VariableValue( "g_gametype" );
  4410. trap_Cvar_Set("ui_gameType", va("%i", temp));
  4411. if (next) {
  4412. int actual;
  4413. int index = trap_Cvar_VariableValue("ui_mapIndex");
  4414. UI_MapCountByGameType(qtrue);
  4415. UI_SelectedMap(index, &actual);
  4416. if (UI_SetNextMap(actual, index)) {
  4417. } else {
  4418. UI_GameType_HandleKey(0, 0, A_MOUSE1, qfalse);
  4419. UI_MapCountByGameType(qtrue);
  4420. Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, "skirmish");
  4421. }
  4422. }
  4423. g = uiInfo.gameTypes[ui_gameType.integer].gtEnum;
  4424. trap_Cvar_SetValue( "g_gametype", g );
  4425. trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName) );
  4426. skill = trap_Cvar_VariableValue( "g_spSkill" );
  4427. trap_Cvar_Set("ui_scoreMap", uiInfo.mapList[ui_currentMap.integer].mapName);
  4428. k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
  4429. trap_Cvar_Set("ui_singlePlayerActive", "1");
  4430. // set up sp overrides, will be replaced on postgame
  4431. temp = trap_Cvar_VariableValue( "capturelimit" );
  4432. trap_Cvar_Set("ui_saveCaptureLimit", va("%i", temp));
  4433. temp = trap_Cvar_VariableValue( "fraglimit" );
  4434. trap_Cvar_Set("ui_saveFragLimit", va("%i", temp));
  4435. temp = trap_Cvar_VariableValue( "duel_fraglimit" );
  4436. trap_Cvar_Set("ui_saveDuelLimit", va("%i", temp));
  4437. UI_SetCapFragLimits(qfalse);
  4438. temp = trap_Cvar_VariableValue( "cg_drawTimer" );
  4439. trap_Cvar_Set("ui_drawTimer", va("%i", temp));
  4440. temp = trap_Cvar_VariableValue( "g_doWarmup" );
  4441. trap_Cvar_Set("ui_doWarmup", va("%i", temp));
  4442. temp = trap_Cvar_VariableValue( "g_friendlyFire" );
  4443. trap_Cvar_Set("ui_friendlyFire", va("%i", temp));
  4444. temp = trap_Cvar_VariableValue( "sv_maxClients" );
  4445. trap_Cvar_Set("ui_maxClients", va("%i", temp));
  4446. temp = trap_Cvar_VariableValue( "g_warmup" );
  4447. trap_Cvar_Set("ui_Warmup", va("%i", temp));
  4448. temp = trap_Cvar_VariableValue( "sv_pure" );
  4449. trap_Cvar_Set("ui_pure", va("%i", temp));
  4450. trap_Cvar_Set("cg_cameraOrbit", "0");
  4451. trap_Cvar_Set("cg_thirdPerson", "0");
  4452. trap_Cvar_Set("cg_drawTimer", "1");
  4453. trap_Cvar_Set("g_doWarmup", "1");
  4454. trap_Cvar_Set("g_warmup", "15");
  4455. trap_Cvar_Set("sv_pure", "0");
  4456. trap_Cvar_Set("g_friendlyFire", "0");
  4457. // trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName"));
  4458. // trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName"));
  4459. if (trap_Cvar_VariableValue("ui_recordSPDemo")) {
  4460. Com_sprintf(buff, MAX_STRING_CHARS, "%s_%i", uiInfo.mapList[ui_currentMap.integer].mapLoadName, g);
  4461. trap_Cvar_Set("ui_recordSPDemoName", buff);
  4462. }
  4463. delay = 500;
  4464. if (g == GT_DUEL || g == GT_POWERDUEL) {
  4465. temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2;
  4466. trap_Cvar_Set("sv_maxClients", va("%d", temp));
  4467. Com_sprintf( buff, sizeof(buff), "wait ; addbot %s %f "", %i \n", uiInfo.mapList[ui_currentMap.integer].opponentName, skill, delay);
  4468. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  4469. } else if (g == GT_HOLOCRON || g == GT_JEDIMASTER) {
  4470. temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2;
  4471. trap_Cvar_Set("sv_maxClients", va("%d", temp));
  4472. for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers; i++) {
  4473. 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]);
  4474. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  4475. delay += 500;
  4476. }
  4477. k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  4478. for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers-1; i++) {
  4479. 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]);
  4480. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  4481. delay += 500;
  4482. }
  4483. } else {
  4484. temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2;
  4485. trap_Cvar_Set("sv_maxClients", va("%d", temp));
  4486. for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers; i++) {
  4487. 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]);
  4488. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  4489. delay += 500;
  4490. }
  4491. k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  4492. for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers-1; i++) {
  4493. 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]);
  4494. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  4495. delay += 500;
  4496. }
  4497. }
  4498. if (g >= GT_TEAM ) {
  4499. trap_Cmd_ExecuteText( EXEC_APPEND, "wait 5; team Red\n" );
  4500. }
  4501. }
  4502. static void UI_Update(const char *name) {
  4503. int val = trap_Cvar_VariableValue(name);
  4504. if (Q_stricmp(name, "s_khz") == 0)
  4505. {
  4506. trap_Cmd_ExecuteText( EXEC_APPEND, "snd_restart\n" );
  4507. return;
  4508. }
  4509. if (Q_stricmp(name, "ui_SetName") == 0) {
  4510. trap_Cvar_Set( "name", UI_Cvar_VariableString("ui_Name"));
  4511. } else if (Q_stricmp(name, "ui_setRate") == 0) {
  4512. float rate = trap_Cvar_VariableValue("rate");
  4513. if (rate >= 5000) {
  4514. trap_Cvar_Set("cl_maxpackets", "30");
  4515. trap_Cvar_Set("cl_packetdup", "1");
  4516. } else if (rate >= 4000) {
  4517. trap_Cvar_Set("cl_maxpackets", "15");
  4518. trap_Cvar_Set("cl_packetdup", "2"); // favor less prediction errors when there's packet loss
  4519. } else {
  4520. trap_Cvar_Set("cl_maxpackets", "15");
  4521. trap_Cvar_Set("cl_packetdup", "1"); // favor lower bandwidth
  4522. }
  4523. }
  4524. else if (Q_stricmp(name, "ui_GetName") == 0)
  4525. {
  4526. trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString("name"));
  4527. }
  4528. else if (Q_stricmp(name, "ui_r_colorbits") == 0)
  4529. {
  4530. switch (val)
  4531. {
  4532. case 0:
  4533. trap_Cvar_SetValue( "ui_r_depthbits", 0 );
  4534. break;
  4535. case 16:
  4536. trap_Cvar_SetValue( "ui_r_depthbits", 16 );
  4537. break;
  4538. case 32:
  4539. trap_Cvar_SetValue( "ui_r_depthbits", 24 );
  4540. break;
  4541. }
  4542. }
  4543. else if (Q_stricmp(name, "ui_r_lodbias") == 0)
  4544. {
  4545. switch (val)
  4546. {
  4547. case 0:
  4548. trap_Cvar_SetValue( "ui_r_subdivisions", 4 );
  4549. break;
  4550. case 1:
  4551. trap_Cvar_SetValue( "ui_r_subdivisions", 12 );
  4552. break;
  4553. case 2:
  4554. trap_Cvar_SetValue( "ui_r_subdivisions", 20 );
  4555. break;
  4556. }
  4557. }
  4558. else if (Q_stricmp(name, "ui_r_glCustom") == 0)
  4559. {
  4560. switch (val)
  4561. {
  4562. case 0: // high quality
  4563. trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
  4564. trap_Cvar_SetValue( "ui_r_subdivisions", 4 );
  4565. trap_Cvar_SetValue( "ui_r_lodbias", 0 );
  4566. trap_Cvar_SetValue( "ui_r_colorbits", 32 );
  4567. trap_Cvar_SetValue( "ui_r_depthbits", 24 );
  4568. trap_Cvar_SetValue( "ui_r_picmip", 0 );
  4569. trap_Cvar_SetValue( "ui_r_mode", 4 );
  4570. trap_Cvar_SetValue( "ui_r_texturebits", 32 );
  4571. trap_Cvar_SetValue( "ui_r_fastSky", 0 );
  4572. trap_Cvar_SetValue( "ui_r_inGameVideo", 1 );
  4573. //trap_Cvar_SetValue( "ui_cg_shadows", 2 );//stencil
  4574. trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
  4575. break;
  4576. case 1: // normal
  4577. trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
  4578. trap_Cvar_SetValue( "ui_r_subdivisions", 4 );
  4579. trap_Cvar_SetValue( "ui_r_lodbias", 0 );
  4580. trap_Cvar_SetValue( "ui_r_colorbits", 0 );
  4581. trap_Cvar_SetValue( "ui_r_depthbits", 24 );
  4582. trap_Cvar_SetValue( "ui_r_picmip", 1 );
  4583. trap_Cvar_SetValue( "ui_r_mode", 3 );
  4584. trap_Cvar_SetValue( "ui_r_texturebits", 0 );
  4585. trap_Cvar_SetValue( "ui_r_fastSky", 0 );
  4586. trap_Cvar_SetValue( "ui_r_inGameVideo", 1 );
  4587. //trap_Cvar_SetValue( "ui_cg_shadows", 2 );
  4588. trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
  4589. break;
  4590. case 2: // fast
  4591. trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
  4592. trap_Cvar_SetValue( "ui_r_subdivisions", 12 );
  4593. trap_Cvar_SetValue( "ui_r_lodbias", 1 );
  4594. trap_Cvar_SetValue( "ui_r_colorbits", 0 );
  4595. trap_Cvar_SetValue( "ui_r_depthbits", 0 );
  4596. trap_Cvar_SetValue( "ui_r_picmip", 2 );
  4597. trap_Cvar_SetValue( "ui_r_mode", 3 );
  4598. trap_Cvar_SetValue( "ui_r_texturebits", 0 );
  4599. trap_Cvar_SetValue( "ui_r_fastSky", 1 );
  4600. trap_Cvar_SetValue( "ui_r_inGameVideo", 0 );
  4601. //trap_Cvar_SetValue( "ui_cg_shadows", 1 );
  4602. trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
  4603. break;
  4604. case 3: // fastest
  4605. trap_Cvar_SetValue( "ui_r_fullScreen", 1 );
  4606. trap_Cvar_SetValue( "ui_r_subdivisions", 20 );
  4607. trap_Cvar_SetValue( "ui_r_lodbias", 2 );
  4608. trap_Cvar_SetValue( "ui_r_colorbits", 16 );
  4609. trap_Cvar_SetValue( "ui_r_depthbits", 16 );
  4610. trap_Cvar_SetValue( "ui_r_mode", 3 );
  4611. trap_Cvar_SetValue( "ui_r_picmip", 3 );
  4612. trap_Cvar_SetValue( "ui_r_texturebits", 16 );
  4613. trap_Cvar_SetValue( "ui_r_fastSky", 1 );
  4614. trap_Cvar_SetValue( "ui_r_inGameVideo", 0 );
  4615. //trap_Cvar_SetValue( "ui_cg_shadows", 0 );
  4616. trap_Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
  4617. break;
  4618. }
  4619. }
  4620. else if (Q_stricmp(name, "ui_mousePitch") == 0)
  4621. {
  4622. if (val == 0)
  4623. {
  4624. trap_Cvar_SetValue( "m_pitch", 0.022f );
  4625. }
  4626. else
  4627. {
  4628. trap_Cvar_SetValue( "m_pitch", -0.022f );
  4629. }
  4630. }
  4631. else if (Q_stricmp(name, "ui_mousePitchVeh") == 0)
  4632. {
  4633. if (val == 0)
  4634. {
  4635. trap_Cvar_SetValue( "m_pitchVeh", 0.022f );
  4636. }
  4637. else
  4638. {
  4639. trap_Cvar_SetValue( "m_pitchVeh", -0.022f );
  4640. }
  4641. }
  4642. }
  4643. int gUISelectedMap = 0;
  4644. /*
  4645. ===============
  4646. UI_DeferMenuScript
  4647. Return true if the menu script should be deferred for later
  4648. ===============
  4649. */
  4650. static qboolean UI_DeferMenuScript ( char **args )
  4651. {
  4652. const char* name;
  4653. // Whats the reason for being deferred?
  4654. if (!String_Parse( (char**)args, &name))
  4655. {
  4656. return qfalse;
  4657. }
  4658. // Handle the custom cases
  4659. if ( !Q_stricmp ( name, "VideoSetup" ) )
  4660. {
  4661. const char* warningMenuName;
  4662. qboolean deferred;
  4663. // No warning menu specified
  4664. if ( !String_Parse( (char**)args, &warningMenuName) )
  4665. {
  4666. return qfalse;
  4667. }
  4668. // Defer if the video options were modified
  4669. deferred = trap_Cvar_VariableValue ( "ui_r_modified" ) ? qtrue : qfalse;
  4670. if ( deferred )
  4671. {
  4672. // Open the warning menu
  4673. Menus_OpenByName(warningMenuName);
  4674. }
  4675. return deferred;
  4676. }
  4677. else if ( !Q_stricmp ( name, "RulesBackout" ) )
  4678. {
  4679. qboolean deferred;
  4680. deferred = trap_Cvar_VariableValue ( "ui_rules_backout" ) ? qtrue : qfalse ;
  4681. trap_Cvar_Set ( "ui_rules_backout", "0" );
  4682. return deferred;
  4683. }
  4684. return qfalse;
  4685. }
  4686. /*
  4687. =================
  4688. UI_UpdateVideoSetup
  4689. Copies the temporary user interface version of the video cvars into
  4690. their real counterparts. This is to create a interface which allows
  4691. you to discard your changes if you did something you didnt want
  4692. =================
  4693. */
  4694. void UI_UpdateVideoSetup ( void )
  4695. {
  4696. trap_Cvar_Set ( "r_mode", UI_Cvar_VariableString ( "ui_r_mode" ) );
  4697. trap_Cvar_Set ( "r_fullscreen", UI_Cvar_VariableString ( "ui_r_fullscreen" ) );
  4698. trap_Cvar_Set ( "r_colorbits", UI_Cvar_VariableString ( "ui_r_colorbits" ) );
  4699. trap_Cvar_Set ( "r_lodbias", UI_Cvar_VariableString ( "ui_r_lodbias" ) );
  4700. trap_Cvar_Set ( "r_picmip", UI_Cvar_VariableString ( "ui_r_picmip" ) );
  4701. trap_Cvar_Set ( "r_texturebits", UI_Cvar_VariableString ( "ui_r_texturebits" ) );
  4702. trap_Cvar_Set ( "r_texturemode", UI_Cvar_VariableString ( "ui_r_texturemode" ) );
  4703. trap_Cvar_Set ( "r_detailtextures", UI_Cvar_VariableString ( "ui_r_detailtextures" ) );
  4704. trap_Cvar_Set ( "r_ext_compress_textures", UI_Cvar_VariableString ( "ui_r_ext_compress_textures" ) );
  4705. trap_Cvar_Set ( "r_depthbits", UI_Cvar_VariableString ( "ui_r_depthbits" ) );
  4706. trap_Cvar_Set ( "r_subdivisions", UI_Cvar_VariableString ( "ui_r_subdivisions" ) );
  4707. trap_Cvar_Set ( "r_fastSky", UI_Cvar_VariableString ( "ui_r_fastSky" ) );
  4708. trap_Cvar_Set ( "r_inGameVideo", UI_Cvar_VariableString ( "ui_r_inGameVideo" ) );
  4709. trap_Cvar_Set ( "r_allowExtensions", UI_Cvar_VariableString ( "ui_r_allowExtensions" ) );
  4710. trap_Cvar_Set ( "cg_shadows", UI_Cvar_VariableString ( "ui_cg_shadows" ) );
  4711. trap_Cvar_Set ( "ui_r_modified", "0" );
  4712. trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
  4713. }
  4714. /*
  4715. =================
  4716. UI_GetVideoSetup
  4717. Retrieves the current actual video settings into the temporary user
  4718. interface versions of the cvars.
  4719. =================
  4720. */
  4721. void UI_GetVideoSetup ( void )
  4722. {
  4723. // Make sure the cvars are registered as read only.
  4724. trap_Cvar_Register ( NULL, "ui_r_glCustom", "4", CVAR_ROM|CVAR_INTERNAL|CVAR_ARCHIVE );
  4725. trap_Cvar_Register ( NULL, "ui_r_mode", "0", CVAR_ROM|CVAR_INTERNAL );
  4726. trap_Cvar_Register ( NULL, "ui_r_fullscreen", "0", CVAR_ROM|CVAR_INTERNAL );
  4727. trap_Cvar_Register ( NULL, "ui_r_colorbits", "0", CVAR_ROM|CVAR_INTERNAL );
  4728. trap_Cvar_Register ( NULL, "ui_r_lodbias", "0", CVAR_ROM|CVAR_INTERNAL );
  4729. trap_Cvar_Register ( NULL, "ui_r_picmip", "0", CVAR_ROM|CVAR_INTERNAL );
  4730. trap_Cvar_Register ( NULL, "ui_r_texturebits", "0", CVAR_ROM|CVAR_INTERNAL );
  4731. trap_Cvar_Register ( NULL, "ui_r_texturemode", "0", CVAR_ROM|CVAR_INTERNAL );
  4732. trap_Cvar_Register ( NULL, "ui_r_detailtextures", "0", CVAR_ROM|CVAR_INTERNAL );
  4733. trap_Cvar_Register ( NULL, "ui_r_ext_compress_textures","0", CVAR_ROM|CVAR_INTERNAL );
  4734. trap_Cvar_Register ( NULL, "ui_r_depthbits", "0", CVAR_ROM|CVAR_INTERNAL );
  4735. trap_Cvar_Register ( NULL, "ui_r_subdivisions", "0", CVAR_ROM|CVAR_INTERNAL );
  4736. trap_Cvar_Register ( NULL, "ui_r_fastSky", "0", CVAR_ROM|CVAR_INTERNAL );
  4737. trap_Cvar_Register ( NULL, "ui_r_inGameVideo", "0", CVAR_ROM|CVAR_INTERNAL );
  4738. trap_Cvar_Register ( NULL, "ui_r_allowExtensions", "0", CVAR_ROM|CVAR_INTERNAL );
  4739. trap_Cvar_Register ( NULL, "ui_cg_shadows", "0", CVAR_ROM|CVAR_INTERNAL );
  4740. trap_Cvar_Register ( NULL, "ui_r_modified", "0", CVAR_ROM|CVAR_INTERNAL );
  4741. // Copy over the real video cvars into their temporary counterparts
  4742. trap_Cvar_Set ( "ui_r_mode", UI_Cvar_VariableString ( "r_mode" ) );
  4743. trap_Cvar_Set ( "ui_r_colorbits", UI_Cvar_VariableString ( "r_colorbits" ) );
  4744. trap_Cvar_Set ( "ui_r_fullscreen", UI_Cvar_VariableString ( "r_fullscreen" ) );
  4745. trap_Cvar_Set ( "ui_r_lodbias", UI_Cvar_VariableString ( "r_lodbias" ) );
  4746. trap_Cvar_Set ( "ui_r_picmip", UI_Cvar_VariableString ( "r_picmip" ) );
  4747. trap_Cvar_Set ( "ui_r_texturebits", UI_Cvar_VariableString ( "r_texturebits" ) );
  4748. trap_Cvar_Set ( "ui_r_texturemode", UI_Cvar_VariableString ( "r_texturemode" ) );
  4749. trap_Cvar_Set ( "ui_r_detailtextures", UI_Cvar_VariableString ( "r_detailtextures" ) );
  4750. trap_Cvar_Set ( "ui_r_ext_compress_textures", UI_Cvar_VariableString ( "r_ext_compress_textures" ) );
  4751. trap_Cvar_Set ( "ui_r_depthbits", UI_Cvar_VariableString ( "r_depthbits" ) );
  4752. trap_Cvar_Set ( "ui_r_subdivisions", UI_Cvar_VariableString ( "r_subdivisions" ) );
  4753. trap_Cvar_Set ( "ui_r_fastSky", UI_Cvar_VariableString ( "r_fastSky" ) );
  4754. trap_Cvar_Set ( "ui_r_inGameVideo", UI_Cvar_VariableString ( "r_inGameVideo" ) );
  4755. trap_Cvar_Set ( "ui_r_allowExtensions", UI_Cvar_VariableString ( "r_allowExtensions" ) );
  4756. trap_Cvar_Set ( "ui_cg_shadows", UI_Cvar_VariableString ( "cg_shadows" ) );
  4757. trap_Cvar_Set ( "ui_r_modified", "0" );
  4758. }
  4759. // If the game type is siege, hide the addbot button. I would have done a cvar text on that item,
  4760. // but it already had one on it.
  4761. static void UI_SetBotButton ( void )
  4762. {
  4763. int gameType = trap_Cvar_VariableValue( "g_gametype" );
  4764. int server;
  4765. menuDef_t *menu;
  4766. itemDef_t *item;
  4767. char *name = "addBot";
  4768. server = trap_Cvar_VariableValue( "sv_running" );
  4769. // If in siege or a client, don't show add bot button
  4770. //[BotTweaks]
  4771. //show the addbot button in all non-team gametypes
  4772. if ((gameType >= GT_TEAM) || (server==0))
  4773. //if ((gameType==GT_SIEGE) || (server==0)) // If it's not siege, don't worry about it
  4774. //[/BotTweaks]
  4775. {
  4776. menu = Menu_GetFocused(); // Get current menu (either video or ingame video, I would assume)
  4777. if (!menu)
  4778. {
  4779. return;
  4780. }
  4781. item = Menu_FindItemByName(menu, name);
  4782. if (item)
  4783. {
  4784. Menu_ShowItemByName(menu, name, qfalse);
  4785. }
  4786. }
  4787. }
  4788. // Update the model cvar and everything is good.
  4789. static void UI_UpdateCharacterCvars ( void )
  4790. {
  4791. char skin[MAX_QPATH];
  4792. char model[MAX_QPATH];
  4793. char head[MAX_QPATH];
  4794. char torso[MAX_QPATH];
  4795. char legs[MAX_QPATH];
  4796. trap_Cvar_VariableStringBuffer("ui_char_model", model, sizeof(model));
  4797. trap_Cvar_VariableStringBuffer("ui_char_skin_head", head, sizeof(head));
  4798. trap_Cvar_VariableStringBuffer("ui_char_skin_torso", torso, sizeof(torso));
  4799. trap_Cvar_VariableStringBuffer("ui_char_skin_legs", legs, sizeof(legs));
  4800. Com_sprintf( skin, sizeof( skin ), "%s/%s|%s|%s",
  4801. model,
  4802. head,
  4803. torso,
  4804. legs
  4805. );
  4806. trap_Cvar_Set ( "model", skin );
  4807. trap_Cvar_Set ( "char_color_red", UI_Cvar_VariableString ( "ui_char_color_red" ) );
  4808. trap_Cvar_Set ( "char_color_green", UI_Cvar_VariableString ( "ui_char_color_green" ) );
  4809. trap_Cvar_Set ( "char_color_blue", UI_Cvar_VariableString ( "ui_char_color_blue" ) );
  4810. trap_Cvar_Set ( "ui_selectedModelIndex", "-1");
  4811. }
  4812. static void UI_GetCharacterCvars ( void )
  4813. {
  4814. char *model;
  4815. char *skin;
  4816. int i;
  4817. trap_Cvar_Set ( "ui_char_color_red", UI_Cvar_VariableString ( "char_color_red" ) );
  4818. trap_Cvar_Set ( "ui_char_color_green", UI_Cvar_VariableString ( "char_color_green" ) );
  4819. trap_Cvar_Set ( "ui_char_color_blue", UI_Cvar_VariableString ( "char_color_blue" ) );
  4820. model = UI_Cvar_VariableString ( "model" );
  4821. skin = strrchr(model,'/');
  4822. if (skin && strchr(model,'|')) //we have a multipart custom jedi
  4823. {
  4824. char skinhead[MAX_QPATH];
  4825. char skintorso[MAX_QPATH];
  4826. char skinlower[MAX_QPATH];
  4827. char *p2;
  4828. *skin=0;
  4829. skin++;
  4830. //now get the the individual files
  4831. //advance to second
  4832. p2 = strchr(skin, '|');
  4833. assert(p2);
  4834. *p2=0;
  4835. p2++;
  4836. strcpy (skinhead, skin);
  4837. //advance to third
  4838. skin = strchr(p2, '|');
  4839. assert(skin);
  4840. *skin=0;
  4841. skin++;
  4842. strcpy (skintorso,p2);
  4843. strcpy (skinlower,skin);
  4844. trap_Cvar_Set("ui_char_model", model);
  4845. trap_Cvar_Set("ui_char_skin_head", skinhead);
  4846. trap_Cvar_Set("ui_char_skin_torso", skintorso);
  4847. trap_Cvar_Set("ui_char_skin_legs", skinlower);
  4848. for (i = 0; i < uiInfo.playerSpeciesCount; i++)
  4849. {
  4850. if ( !stricmp(model, uiInfo.playerSpecies[i].Name) )
  4851. {
  4852. uiInfo.playerSpeciesIndex = i;
  4853. break;
  4854. }
  4855. }
  4856. }
  4857. else
  4858. {
  4859. model = UI_Cvar_VariableString ( "ui_char_model" );
  4860. for (i = 0; i < uiInfo.playerSpeciesCount; i++)
  4861. {
  4862. if ( !stricmp(model, uiInfo.playerSpecies[i].Name) )
  4863. {
  4864. uiInfo.playerSpeciesIndex = i;
  4865. return; //FOUND IT, don't fall through
  4866. }
  4867. }
  4868. //nope, didn't find it.
  4869. uiInfo.playerSpeciesIndex = 0;//jic
  4870. trap_Cvar_Set("ui_char_model", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name);
  4871. trap_Cvar_Set("ui_char_skin_head", "head_a1");
  4872. trap_Cvar_Set("ui_char_skin_torso","torso_a1");
  4873. trap_Cvar_Set("ui_char_skin_legs", "lower_a1");
  4874. }
  4875. }
  4876. void UI_SetSiegeObjectiveGraphicPos(menuDef_t *menu,const char *itemName,const char *cvarName)
  4877. {
  4878. itemDef_t *item;
  4879. char cvarBuf[1024];
  4880. const char *holdVal;
  4881. char *holdBuf;
  4882. item = Menu_FindItemByName(menu, itemName);
  4883. if (item)
  4884. {
  4885. // get cvar data
  4886. //[SIEGECVARFIX]
  4887. siege_Cvar_VariableStringBuffer((char *)cvarName, cvarBuf, sizeof((char *)cvarBuf));
  4888. //trap_Cvar_VariableStringBuffer(cvarName, cvarBuf, sizeof(cvarBuf));
  4889. //[/SIEGECVARFIX]
  4890. holdBuf = cvarBuf;
  4891. if (String_Parse(&holdBuf,&holdVal))
  4892. {
  4893. item->window.rectClient.x = atof(holdVal);
  4894. if (String_Parse(&holdBuf,&holdVal))
  4895. {
  4896. item->window.rectClient.y = atof(holdVal);
  4897. if (String_Parse(&holdBuf,&holdVal))
  4898. {
  4899. item->window.rectClient.w = atof(holdVal);
  4900. if (String_Parse(&holdBuf,&holdVal))
  4901. {
  4902. item->window.rectClient.h = atof(holdVal);
  4903. item->window.rect.x = item->window.rectClient.x;
  4904. item->window.rect.y = item->window.rectClient.y;
  4905. item->window.rect.w = item->window.rectClient.w;
  4906. item->window.rect.h = item->window.rectClient.h;
  4907. }
  4908. }
  4909. }
  4910. }
  4911. }
  4912. }
  4913. void UI_FindCurrentSiegeTeamClass( void )
  4914. {
  4915. menuDef_t *menu;
  4916. int myTeam = (int)(trap_Cvar_VariableValue("ui_myteam"));
  4917. char *itemname;
  4918. itemDef_t *item;
  4919. int baseClass;
  4920. menu = Menu_GetFocused(); // Get current menu
  4921. if (!menu)
  4922. {
  4923. return;
  4924. }
  4925. if (( myTeam != TEAM_RED ) && ( myTeam != TEAM_BLUE ))
  4926. {
  4927. return;
  4928. }
  4929. // If the player is on a team,
  4930. if ( myTeam == TEAM_RED )
  4931. {
  4932. itemDef_t *item;
  4933. item = (itemDef_t *) Menu_FindItemByName(menu, "onteam1" );
  4934. if (item)
  4935. {
  4936. Item_RunScript(item, item->action);
  4937. }
  4938. }
  4939. else if ( myTeam == TEAM_BLUE )
  4940. {
  4941. itemDef_t *item;
  4942. item = (itemDef_t *) Menu_FindItemByName(menu, "onteam2" );
  4943. if (item)
  4944. {
  4945. Item_RunScript(item, item->action);
  4946. }
  4947. }
  4948. //[SIEGECVARFIX]
  4949. baseClass = (int)siege_Cvar_VariableValue("ui_siege_class");
  4950. //baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
  4951. //[/SIEGECVARFIX]
  4952. // Find correct class button and activate it.
  4953. if (baseClass == SPC_INFANTRY)
  4954. {
  4955. itemname = "class1_button";
  4956. }
  4957. else if (baseClass == SPC_HEAVY_WEAPONS)
  4958. {
  4959. itemname = "class2_button";
  4960. }
  4961. else if (baseClass == SPC_DEMOLITIONIST)
  4962. {
  4963. itemname = "class3_button";
  4964. }
  4965. else if (baseClass == SPC_VANGUARD)
  4966. {
  4967. itemname = "class4_button";
  4968. }
  4969. else if (baseClass == SPC_SUPPORT)
  4970. {
  4971. itemname = "class5_button";
  4972. }
  4973. else if (baseClass == SPC_SUPPORT)
  4974. {
  4975. itemname = "class5_button";
  4976. }
  4977. else if (baseClass == SPC_JEDI)
  4978. {
  4979. itemname = "class6_button";
  4980. }
  4981. else
  4982. {
  4983. return;
  4984. }
  4985. item = (itemDef_t *) Menu_FindItemByName(menu, itemname );
  4986. if (item)
  4987. {
  4988. Item_RunScript(item, item->action);
  4989. }
  4990. }
  4991. void UI_UpdateSiegeObjectiveGraphics( void )
  4992. {
  4993. menuDef_t *menu;
  4994. int teamI,objI;
  4995. menu = Menu_GetFocused(); // Get current menu
  4996. if (!menu)
  4997. {
  4998. return;
  4999. }
  5000. // Hiding a bunch of fields because the opening section of the siege menu was getting too long
  5001. Menu_ShowGroup(menu,"class_button",qfalse);
  5002. Menu_ShowGroup(menu,"class_count",qfalse);
  5003. Menu_ShowGroup(menu,"feeders",qfalse);
  5004. Menu_ShowGroup(menu,"classdescription",qfalse);
  5005. Menu_ShowGroup(menu,"minidesc",qfalse);
  5006. Menu_ShowGroup(menu,"obj_longdesc",qfalse);
  5007. Menu_ShowGroup(menu,"objective_pic",qfalse);
  5008. Menu_ShowGroup(menu,"stats",qfalse);
  5009. Menu_ShowGroup(menu,"forcepowerlevel",qfalse);
  5010. // Get objective icons for each team
  5011. for (teamI=1;teamI<3;teamI++)
  5012. {
  5013. for (objI=1;objI<8;objI++)
  5014. {
  5015. Menu_SetItemBackground(menu,va("tm%i_icon%i",teamI,objI),va("*team%i_objective%i_mapicon",teamI,objI));
  5016. Menu_SetItemBackground(menu,va("tm%i_l_icon%i",teamI,objI),va("*team%i_objective%i_mapicon",teamI,objI));
  5017. }
  5018. }
  5019. // Now get their placement on the map
  5020. for (teamI=1;teamI<3;teamI++)
  5021. {
  5022. for (objI=1;objI<8;objI++)
  5023. {
  5024. UI_SetSiegeObjectiveGraphicPos(menu,va("tm%i_icon%i",teamI,objI),va("team%i_objective%i_mappos",teamI,objI));
  5025. }
  5026. }
  5027. }
  5028. saber_colors_t TranslateSaberColor( const char *name );
  5029. static void UI_UpdateSaberCvars ( void )
  5030. {
  5031. saber_colors_t colorI;
  5032. trap_Cvar_Set ( "saber1", UI_Cvar_VariableString ( "ui_saber" ) );
  5033. trap_Cvar_Set ( "saber2", UI_Cvar_VariableString ( "ui_saber2" ) );
  5034. colorI = TranslateSaberColor( UI_Cvar_VariableString ( "ui_saber_color" ) );
  5035. trap_Cvar_Set ( "color1", va("%d",colorI));
  5036. trap_Cvar_Set ( "g_saber_color", UI_Cvar_VariableString ( "ui_saber_color" ));
  5037. colorI = TranslateSaberColor( UI_Cvar_VariableString ( "ui_saber2_color" ) );
  5038. trap_Cvar_Set ( "color2", va("%d",colorI) );
  5039. trap_Cvar_Set ( "g_saber2_color", UI_Cvar_VariableString ( "ui_saber2_color" ));
  5040. }
  5041. // More hard coded goodness for the menus.
  5042. static void UI_SetSaberBoxesandHilts (void)
  5043. {
  5044. menuDef_t *menu;
  5045. itemDef_t *item;
  5046. qboolean getBig = qfalse;
  5047. char sType[MAX_QPATH];
  5048. menu = Menu_GetFocused(); // Get current menu (either video or ingame video, I would assume)
  5049. if (!menu)
  5050. {
  5051. return;
  5052. }
  5053. trap_Cvar_VariableStringBuffer( "ui_saber_type", sType, sizeof(sType) );
  5054. if ( Q_stricmp( "dual", sType ) != 0 )
  5055. {
  5056. // trap_Cvar_Set("ui_saber", "single_1");
  5057. // trap_Cvar_Set("ui_saber2", "single_1");
  5058. getBig = qtrue;
  5059. }
  5060. else if (Q_stricmp( "staff", sType ) != 0 )
  5061. {
  5062. // trap_Cvar_Set("ui_saber", "dual_1");
  5063. // trap_Cvar_Set("ui_saber2", "none");
  5064. getBig = qtrue;
  5065. }
  5066. if (!getBig)
  5067. {
  5068. return;
  5069. }
  5070. item = (itemDef_t *) Menu_FindItemByName(menu, "box2middle" );
  5071. if(item)
  5072. {
  5073. item->window.rect.x = 212;
  5074. item->window.rect.y = 126;
  5075. item->window.rect.w = 219;
  5076. item->window.rect.h = 44;
  5077. }
  5078. item = (itemDef_t *) Menu_FindItemByName(menu, "box2bottom" );
  5079. if(item)
  5080. {
  5081. item->window.rect.x = 212;
  5082. item->window.rect.y = 170;
  5083. item->window.rect.w = 219;
  5084. item->window.rect.h = 60;
  5085. }
  5086. item = (itemDef_t *) Menu_FindItemByName(menu, "box3middle" );
  5087. if(item)
  5088. {
  5089. item->window.rect.x = 418;
  5090. item->window.rect.y = 126;
  5091. item->window.rect.w = 219;
  5092. item->window.rect.h = 44;
  5093. }
  5094. item = (itemDef_t *) Menu_FindItemByName(menu, "box3bottom" );
  5095. if(item)
  5096. {
  5097. item->window.rect.x = 418;
  5098. item->window.rect.y = 170;
  5099. item->window.rect.w = 219;
  5100. item->window.rect.h = 60;
  5101. }
  5102. }
  5103. //extern qboolean UI_SaberModelForSaber( const char *saberName, char *saberModel );
  5104. extern qboolean UI_SaberSkinForSaber( const char *saberName, char *saberSkin );
  5105. #include "../namespace_begin.h"
  5106. extern qboolean ItemParse_asset_model_go( itemDef_t *item, const char *name,int *runTimeLength );
  5107. extern qboolean ItemParse_model_g2skin_go( itemDef_t *item, const char *skinName );
  5108. #include "../namespace_end.h"
  5109. static void UI_UpdateSaberType( void )
  5110. {
  5111. char sType[MAX_QPATH];
  5112. trap_Cvar_VariableStringBuffer( "ui_saber_type", sType, sizeof(sType) );
  5113. if ( Q_stricmp( "single", sType ) == 0 ||
  5114. Q_stricmp( "staff", sType ) == 0 )
  5115. {
  5116. trap_Cvar_Set( "ui_saber2", "" );
  5117. }
  5118. }
  5119. static void UI_UpdateSaberHilt( qboolean secondSaber )
  5120. {
  5121. menuDef_t *menu;
  5122. itemDef_t *item;
  5123. char model[MAX_QPATH];
  5124. char modelPath[MAX_QPATH];
  5125. char skinPath[MAX_QPATH];
  5126. char *itemName;
  5127. char *saberCvarName;
  5128. int animRunLength;
  5129. menu = Menu_GetFocused(); // Get current menu (either video or ingame video, I would assume)
  5130. if (!menu)
  5131. {
  5132. return;
  5133. }
  5134. if ( secondSaber )
  5135. {
  5136. itemName = "saber2";
  5137. saberCvarName = "ui_saber2";
  5138. }
  5139. else
  5140. {
  5141. itemName = "saber";
  5142. saberCvarName = "ui_saber";
  5143. }
  5144. item = (itemDef_t *) Menu_FindItemByName(menu, itemName );
  5145. if(!item)
  5146. {
  5147. Com_Error( ERR_FATAL, "UI_UpdateSaberHilt: Could not find item (%s) in menu (%s)", itemName, menu->window.name);
  5148. }
  5149. trap_Cvar_VariableStringBuffer( saberCvarName, model, sizeof(model) );
  5150. item->text = model;
  5151. //read this from the sabers.cfg
  5152. if ( UI_SaberModelForSaber( model, modelPath ) )
  5153. {//successfully found a model
  5154. ItemParse_asset_model_go( item, modelPath, &animRunLength );//set the model
  5155. //get the customSkin, if any
  5156. //COM_StripExtension( modelPath, skinPath );
  5157. //COM_DefaultExtension( skinPath, sizeof( skinPath ), ".skin" );
  5158. if ( UI_SaberSkinForSaber( model, skinPath ) )
  5159. {
  5160. ItemParse_model_g2skin_go( item, skinPath );//apply the skin
  5161. }
  5162. else
  5163. {
  5164. ItemParse_model_g2skin_go( item, NULL );//apply the skin
  5165. }
  5166. }
  5167. }
  5168. static void UI_UpdateSaberColor( qboolean secondSaber )
  5169. {
  5170. //[RGBSabers]
  5171. char str[32];
  5172. str[0] = '\0';
  5173. strncat(str,va("%i,%i,%i",ui_sab1_r.integer,ui_sab1_g.integer,ui_sab1_b.integer),sizeof(str));
  5174. trap_Cvar_Set("rgb_saber1", str);
  5175. str[0] = '\0';
  5176. strncat(str,va("%i,%i,%i",ui_sab2_r.integer,ui_sab2_g.integer,ui_sab2_b.integer),sizeof(str));
  5177. trap_Cvar_Set("rgb_saber2", str);
  5178. // Com_Printf("update saber : %i\n",secondSaber);
  5179. //[/RGBSabers]
  5180. }
  5181. extern char * SaberColorToString(saber_colors_t color);
  5182. //[RGBSabers]
  5183. void ParseRGBSaber(char * str, vec3_t c);
  5184. void UI_ParseScriptedSaber(char *script, int snum);
  5185. //[/RGBSabers]
  5186. static void UI_GetSaberCvars ( void )
  5187. {
  5188. //[RGBSabers]
  5189. char strgb1[64],strgb2[64];
  5190. char scr1[256],scr2[256];
  5191. vec3_t c1,c2;
  5192. //[/RGBSabers]
  5193. // trap_Cvar_Set ( "ui_saber_type", UI_Cvar_VariableString ( "g_saber_type" ) );
  5194. trap_Cvar_Set ( "ui_saber", UI_Cvar_VariableString ( "saber1" ) );
  5195. trap_Cvar_Set ( "ui_saber2", UI_Cvar_VariableString ( "saber2" ));
  5196. trap_Cvar_Set("g_saber_color", SaberColorToString(trap_Cvar_VariableValue("color1")));
  5197. trap_Cvar_Set("g_saber2_color", SaberColorToString(trap_Cvar_VariableValue("color2")));
  5198. trap_Cvar_Set ( "ui_saber_color", UI_Cvar_VariableString ( "g_saber_color" ) );
  5199. trap_Cvar_Set ( "ui_saber2_color", UI_Cvar_VariableString ( "g_saber2_color" ) );
  5200. //[RGBSabers]
  5201. strncpy(strgb1, UI_Cvar_VariableString("rgb_saber1"),sizeof(strgb1));
  5202. strncpy(strgb2, UI_Cvar_VariableString("rgb_saber2"),sizeof(strgb2));
  5203. ParseRGBSaber(strgb1,c1);
  5204. ParseRGBSaber(strgb2,c2);
  5205. trap_Cvar_Set("ui_sab1_r", va("%f",c1[0]));
  5206. trap_Cvar_Set("ui_sab1_g", va("%f",c1[1]));
  5207. trap_Cvar_Set("ui_sab1_b", va("%f",c1[2]));
  5208. trap_Cvar_Set("ui_sab2_r", va("%f",c2[0]));
  5209. trap_Cvar_Set("ui_sab2_g", va("%f",c2[1]));
  5210. trap_Cvar_Set("ui_sab2_b", va("%f",c2[2]));
  5211. /*
  5212. fs(set,"%f",c1[0]);
  5213. trap_Cvar_Set("ui_sab1_r",set);
  5214. fs(set,"%f",c1[1]);
  5215. trap_Cvar_Set("ui_sab1_g",set);
  5216. fs(set,"%f",c1[2]);
  5217. trap_Cvar_Set("ui_sab1_b",set);
  5218. fs(set,"%f",c2[0]);
  5219. trap_Cvar_Set("ui_sab2_r",set);
  5220. fs(set,"%f",c2[1]);
  5221. trap_Cvar_Set("ui_sab2_g",set);
  5222. fs(set,"%f",c2[2]);
  5223. trap_Cvar_Set("ui_sab2_b",set);
  5224. */
  5225. strncpy(scr1, UI_Cvar_VariableString("rgb_script1"),sizeof(scr1));
  5226. strncpy(scr2, UI_Cvar_VariableString("rgb_script2"),sizeof(scr2));
  5227. if(scr1[0] != ':')
  5228. {
  5229. trap_Cvar_Set("rgb_script1",":255,0,255:500:0,0,255:500:");
  5230. strncpy(scr1,":255,0,255:500:0,0,255:500:\0",sizeof(scr1));
  5231. }
  5232. if(scr2[0] != ':')
  5233. {
  5234. trap_Cvar_Set("rgb_script2",":0,255,255:500:0,0,255:500:");
  5235. strncpy(scr2,":0,255,255:500:0,0,255:500:\0",sizeof(scr2));
  5236. }
  5237. UI_ParseScriptedSaber(scr1,0);
  5238. UI_ParseScriptedSaber(scr2,1);
  5239. // Com_Printf("ui_getsabercvar > %i,%i,%i %i,%i,%i\n",ui_sab1_r.integer,ui_sab1_g.integer,ui_sab1_b.integer,ui_sab2_r.integer,ui_sab2_g.integer,ui_sab2_b.integer);
  5240. //[/RGBSabers]
  5241. }
  5242. //extern qboolean ItemParse_model_g2skin_go( itemDef_t *item, const char *skinName );
  5243. #include "../namespace_begin.h"
  5244. extern qboolean ItemParse_model_g2anim_go( itemDef_t *item, const char *animName );
  5245. #include "../namespace_end.h"
  5246. //extern qboolean ItemParse_asset_model_go( itemDef_t *item, const char *name );
  5247. void UI_UpdateCharacterSkin( void )
  5248. {
  5249. menuDef_t *menu;
  5250. itemDef_t *item;
  5251. char skin[MAX_QPATH];
  5252. char model[MAX_QPATH];
  5253. char head[MAX_QPATH];
  5254. char torso[MAX_QPATH];
  5255. char legs[MAX_QPATH];
  5256. menu = Menu_GetFocused(); // Get current menu
  5257. if (!menu)
  5258. {
  5259. return;
  5260. }
  5261. item = (itemDef_t *) Menu_FindItemByName(menu, "character");
  5262. if (!item)
  5263. {
  5264. Com_Error( ERR_FATAL, "UI_UpdateCharacterSkin: Could not find item (character) in menu (%s)", menu->window.name);
  5265. }
  5266. trap_Cvar_VariableStringBuffer("ui_char_model", model, sizeof(model));
  5267. trap_Cvar_VariableStringBuffer("ui_char_skin_head", head, sizeof(head));
  5268. trap_Cvar_VariableStringBuffer("ui_char_skin_torso", torso, sizeof(torso));
  5269. trap_Cvar_VariableStringBuffer("ui_char_skin_legs", legs, sizeof(legs));
  5270. Com_sprintf( skin, sizeof( skin ), "models/players/%s/|%s|%s|%s",
  5271. model,
  5272. head,
  5273. torso,
  5274. legs
  5275. );
  5276. ItemParse_model_g2skin_go( item, skin );
  5277. }
  5278. static void UI_ResetCharacterListBoxes( void )
  5279. {
  5280. itemDef_t *item;
  5281. menuDef_t *menu;
  5282. listBoxDef_t *listPtr;
  5283. menu = Menu_GetFocused();
  5284. if (menu)
  5285. {
  5286. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "headlistbox");
  5287. if (item)
  5288. {
  5289. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  5290. if( listPtr )
  5291. {
  5292. listPtr->cursorPos = 0;
  5293. }
  5294. item->cursorPos = 0;
  5295. }
  5296. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "torsolistbox");
  5297. if (item)
  5298. {
  5299. listPtr = (listBoxDef_t*)item->typeData;
  5300. if( listPtr )
  5301. {
  5302. listPtr->cursorPos = 0;
  5303. }
  5304. item->cursorPos = 0;
  5305. }
  5306. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "lowerlistbox");
  5307. if (item)
  5308. {
  5309. listPtr = (listBoxDef_t*)item->typeData;
  5310. if( listPtr )
  5311. {
  5312. listPtr->cursorPos = 0;
  5313. }
  5314. item->cursorPos = 0;
  5315. }
  5316. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "colorbox");
  5317. if (item)
  5318. {
  5319. listPtr = (listBoxDef_t*)item->typeData;
  5320. if( listPtr )
  5321. {
  5322. listPtr->cursorPos = 0;
  5323. }
  5324. item->cursorPos = 0;
  5325. }
  5326. }
  5327. }
  5328. //[DynamicMemory_Sabers]
  5329. /*moved all saber code into ui_saber.c
  5330. #define MAX_SABER_HILTS 64
  5331. char *saberSingleHiltInfo [MAX_SABER_HILTS];
  5332. char *saberStaffHiltInfo [MAX_SABER_HILTS];
  5333. */
  5334. void UI_SaberGetHiltInfo(void);
  5335. qboolean UI_SaberProperNameForSaber( const char *saberName, char *saberProperName );
  5336. //[/DynamicMemory_Sabers]
  5337. static void UI_UpdateCharacter( qboolean changedModel )
  5338. {
  5339. menuDef_t *menu;
  5340. itemDef_t *item;
  5341. char modelPath[MAX_QPATH];
  5342. int animRunLength;
  5343. menu = Menu_GetFocused(); // Get current menu
  5344. if (!menu)
  5345. {
  5346. return;
  5347. }
  5348. item = (itemDef_t *) Menu_FindItemByName(menu, "character");
  5349. if (!item)
  5350. {
  5351. Com_Error( ERR_FATAL, "UI_UpdateCharacter: Could not find item (character) in menu (%s)", menu->window.name);
  5352. }
  5353. ItemParse_model_g2anim_go( item, ui_char_anim.string );
  5354. Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
  5355. ItemParse_asset_model_go( item, modelPath, &animRunLength );
  5356. if ( changedModel )
  5357. {//set all skins to first skin since we don't know you always have all skins
  5358. //FIXME: could try to keep the same spot in each list as you swtich models
  5359. UI_FeederSelection(FEEDER_PLAYER_SKIN_HEAD, 0, item); //fixme, this is not really the right item!!
  5360. UI_FeederSelection(FEEDER_PLAYER_SKIN_TORSO, 0, item);
  5361. UI_FeederSelection(FEEDER_PLAYER_SKIN_LEGS, 0, item);
  5362. UI_FeederSelection(FEEDER_COLORCHOICES, 0, item);
  5363. }
  5364. UI_UpdateCharacterSkin();
  5365. }
  5366. static void UI_RunMenuScript(char **args)
  5367. {
  5368. const char *name, *name2;
  5369. char buff[1024];
  5370. if (String_Parse(args, &name))
  5371. {
  5372. if (Q_stricmp(name, "StartServer") == 0)
  5373. {//racc - UI script for starting game.
  5374. int i, added = 0;
  5375. float skill;
  5376. int warmupTime = 0;
  5377. int doWarmup = 0;
  5378. trap_Cvar_Set("cg_thirdPerson", "0");
  5379. trap_Cvar_Set("cg_cameraOrbit", "0");
  5380. // for Solo games I set this to 1 in the menu and don't want it stomped here,
  5381. // this cvar seems to be reset to 0 in all the proper places so... -dmv
  5382. // trap_Cvar_Set("ui_singlePlayerActive", "0");
  5383. // if a solo game is started, automatically turn dedicated off here (don't want to do it in the menu, might get annoying)
  5384. if( trap_Cvar_VariableValue( "ui_singlePlayerActive" ) )
  5385. {
  5386. trap_Cvar_Set( "dedicated", "0" );
  5387. }
  5388. else
  5389. {
  5390. trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, ui_dedicated.integer ) );
  5391. }
  5392. //[OLDGAMETYPES]
  5393. trap_Cvar_SetValue( "g_gametype", Com_Clamp( GT_FFA, GT_CTY, uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) );
  5394. //trap_Cvar_SetValue( "g_gametype", Com_Clamp( 0, 8, uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) );
  5395. //[/OLDGAMETYPES]
  5396. //trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName"));
  5397. //trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName"));
  5398. trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) );
  5399. skill = trap_Cvar_VariableValue( "g_spSkill" );
  5400. //Cap the warmup values in case the user tries a dumb setting.
  5401. warmupTime = trap_Cvar_VariableValue( "g_warmup" );
  5402. doWarmup = trap_Cvar_VariableValue( "g_doWarmup" );
  5403. if (doWarmup && warmupTime < 1)
  5404. {
  5405. trap_Cvar_Set("g_doWarmup", "0");
  5406. }
  5407. if (warmupTime < 5)
  5408. {
  5409. trap_Cvar_Set("g_warmup", "5");
  5410. }
  5411. if (warmupTime > 120)
  5412. {
  5413. trap_Cvar_Set("g_warmup", "120");
  5414. }
  5415. if (trap_Cvar_VariableValue( "g_gametype" ) == GT_DUEL ||
  5416. trap_Cvar_VariableValue( "g_gametype" ) == GT_POWERDUEL)
  5417. { //always set fraglimit 1 when starting a duel game
  5418. trap_Cvar_Set("fraglimit", "1");
  5419. trap_Cvar_Set("timelimit", "0");
  5420. }
  5421. for (i = 0; i < PLAYERS_PER_TEAM; i++)
  5422. {
  5423. int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1));
  5424. int maxcl = trap_Cvar_VariableValue( "sv_maxClients" );
  5425. if (bot > 1)
  5426. {
  5427. int numval = i+1;
  5428. numval *= 2;
  5429. numval -= 1;
  5430. if (numval <= maxcl)
  5431. {
  5432. if (ui_actualNetGameType.integer >= GT_TEAM) {
  5433. Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Blue");
  5434. } else {
  5435. Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f \n", UI_GetBotNameByNumber(bot-2), skill);
  5436. }
  5437. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  5438. added++;
  5439. }
  5440. }
  5441. bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1));
  5442. if (bot > 1) {
  5443. int numval = i+1;
  5444. numval *= 2;
  5445. if (numval <= maxcl)
  5446. {
  5447. if (ui_actualNetGameType.integer >= GT_TEAM) {
  5448. Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f %s\n", UI_GetBotNameByNumber(bot-2), skill, "Red");
  5449. } else {
  5450. Com_sprintf( buff, sizeof(buff), "addbot \"%s\" %f \n", UI_GetBotNameByNumber(bot-2), skill);
  5451. }
  5452. trap_Cmd_ExecuteText( EXEC_APPEND, buff );
  5453. added++;
  5454. }
  5455. }
  5456. if (added >= maxcl)
  5457. { //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.
  5458. trap_Cvar_Set("sv_maxClients", va("%i", added+1));
  5459. break;
  5460. }
  5461. }
  5462. } else if (Q_stricmp(name, "updateSPMenu") == 0) {
  5463. UI_SetCapFragLimits(qtrue);
  5464. UI_MapCountByGameType(qtrue);
  5465. ui_mapIndex.integer = UI_GetIndexFromSelection(ui_currentMap.integer);
  5466. trap_Cvar_Set("ui_mapIndex", va("%d", ui_mapIndex.integer));
  5467. Menu_SetFeederSelection(NULL, FEEDER_MAPS, ui_mapIndex.integer, "skirmish");
  5468. UI_GameType_HandleKey(0, 0, A_MOUSE1, qfalse);
  5469. UI_GameType_HandleKey(0, 0, A_MOUSE2, qfalse);
  5470. } else if (Q_stricmp(name, "resetDefaults") == 0) {
  5471. trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n");
  5472. trap_Cmd_ExecuteText( EXEC_APPEND, "exec mpdefault.cfg\n");
  5473. trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
  5474. trap_Cvar_Set("com_introPlayed", "1" );
  5475. #ifdef USE_CD_KEY
  5476. } else if (Q_stricmp(name, "getCDKey") == 0) {
  5477. char out[17];
  5478. trap_GetCDKey(buff, 17);
  5479. trap_Cvar_Set("cdkey1", "");
  5480. trap_Cvar_Set("cdkey2", "");
  5481. trap_Cvar_Set("cdkey3", "");
  5482. trap_Cvar_Set("cdkey4", "");
  5483. if (strlen(buff) == CDKEY_LEN) {
  5484. Q_strncpyz(out, buff, 5);
  5485. trap_Cvar_Set("cdkey1", out);
  5486. Q_strncpyz(out, buff + 4, 5);
  5487. trap_Cvar_Set("cdkey2", out);
  5488. Q_strncpyz(out, buff + 8, 5);
  5489. trap_Cvar_Set("cdkey3", out);
  5490. Q_strncpyz(out, buff + 12, 5);
  5491. trap_Cvar_Set("cdkey4", out);
  5492. }
  5493. } else if (Q_stricmp(name, "verifyCDKey") == 0) {
  5494. buff[0] = '\0';
  5495. Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey1"));
  5496. Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey2"));
  5497. Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey3"));
  5498. Q_strcat(buff, 1024, UI_Cvar_VariableString("cdkey4"));
  5499. trap_Cvar_Set("cdkey", buff);
  5500. if (trap_VerifyCDKey(buff, UI_Cvar_VariableString("cdkeychecksum"))) {
  5501. trap_Cvar_Set("ui_cdkeyvalid", "CD Key Appears to be valid.");
  5502. trap_SetCDKey(buff);
  5503. } else {
  5504. trap_Cvar_Set("ui_cdkeyvalid", "CD Key does not appear to be valid.");
  5505. }
  5506. #endif // USE_CD_KEY
  5507. } else if (Q_stricmp(name, "loadArenas") == 0) {
  5508. UI_LoadArenas();
  5509. UI_MapCountByGameType(qfalse);
  5510. Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, gUISelectedMap, "createserver");
  5511. uiForceRank = trap_Cvar_VariableValue("g_maxForceRank");
  5512. } else if (Q_stricmp(name, "saveControls") == 0) {
  5513. Controls_SetConfig(qtrue);
  5514. } else if (Q_stricmp(name, "loadControls") == 0) {
  5515. Controls_GetConfig();
  5516. } else if (Q_stricmp(name, "clearError") == 0) {
  5517. trap_Cvar_Set("com_errorMessage", "");
  5518. } else if (Q_stricmp(name, "loadGameInfo") == 0) {
  5519. UI_ParseGameInfo("ui/jamp/gameinfo.txt");
  5520. UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
  5521. } else if (Q_stricmp(name, "resetScores") == 0) {
  5522. UI_ClearScores();
  5523. } else if (Q_stricmp(name, "RefreshServers") == 0) {
  5524. UI_StartServerRefresh(qtrue);
  5525. UI_BuildServerDisplayList(qtrue);
  5526. } else if (Q_stricmp(name, "RefreshFilter") == 0) {
  5527. UI_StartServerRefresh(qfalse);
  5528. UI_BuildServerDisplayList(qtrue);
  5529. } else if (Q_stricmp(name, "RunSPDemo") == 0) {
  5530. if (uiInfo.demoAvailable) {
  5531. trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s_%i\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum));
  5532. }
  5533. } else if (Q_stricmp(name, "LoadDemos") == 0) {
  5534. UI_LoadDemos();
  5535. } else if (Q_stricmp(name, "LoadMovies") == 0) {
  5536. UI_LoadMovies();
  5537. } else if (Q_stricmp(name, "LoadMods") == 0) {
  5538. UI_LoadMods();
  5539. } else if (Q_stricmp(name, "playMovie") == 0) {
  5540. if (uiInfo.previewMovie >= 0) {
  5541. trap_CIN_StopCinematic(uiInfo.previewMovie);
  5542. }
  5543. trap_Cmd_ExecuteText( EXEC_APPEND, va("cinematic %s.roq 2\n", uiInfo.movieList[uiInfo.movieIndex]));
  5544. } else if (Q_stricmp(name, "RunMod") == 0) {
  5545. trap_Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName);
  5546. trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
  5547. } else if (Q_stricmp(name, "RunDemo") == 0) {
  5548. trap_Cmd_ExecuteText( EXEC_APPEND, va("demo \"%s\"\n", uiInfo.demoList[uiInfo.demoIndex]));
  5549. } else if (Q_stricmp(name, "Quake3") == 0) {
  5550. trap_Cvar_Set( "fs_game", "");
  5551. trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
  5552. } else if (Q_stricmp(name, "closeJoin") == 0) {
  5553. if (uiInfo.serverStatus.refreshActive) {
  5554. UI_StopServerRefresh();
  5555. uiInfo.serverStatus.nextDisplayRefresh = 0;
  5556. uiInfo.nextServerStatusRefresh = 0;
  5557. uiInfo.nextFindPlayerRefresh = 0;
  5558. UI_BuildServerDisplayList(qtrue);
  5559. } else {
  5560. Menus_CloseByName("joinserver");
  5561. Menus_OpenByName("main");
  5562. }
  5563. } else if (Q_stricmp(name, "StopRefresh") == 0) {
  5564. UI_StopServerRefresh();
  5565. uiInfo.serverStatus.nextDisplayRefresh = 0;
  5566. uiInfo.nextServerStatusRefresh = 0;
  5567. uiInfo.nextFindPlayerRefresh = 0;
  5568. } else if (Q_stricmp(name, "UpdateFilter") == 0) {
  5569. if (ui_netSource.integer == AS_LOCAL) {
  5570. UI_StartServerRefresh(qtrue);
  5571. }
  5572. UI_BuildServerDisplayList(qtrue);
  5573. UI_FeederSelection(FEEDER_SERVERS, 0, NULL );
  5574. } else if (Q_stricmp(name, "ServerStatus") == 0) {
  5575. trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], uiInfo.serverStatusAddress, sizeof(uiInfo.serverStatusAddress));
  5576. UI_BuildServerStatus(qtrue);
  5577. } else if (Q_stricmp(name, "FoundPlayerServerStatus") == 0) {
  5578. Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress));
  5579. UI_BuildServerStatus(qtrue);
  5580. Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
  5581. } else if (Q_stricmp(name, "FindPlayer") == 0) {
  5582. UI_BuildFindPlayerList(qtrue);
  5583. // clear the displayed server status info
  5584. uiInfo.serverStatusInfo.numLines = 0;
  5585. Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
  5586. }
  5587. else if (Q_stricmp(name, "checkservername") == 0)
  5588. {
  5589. UI_CheckServerName();
  5590. }
  5591. else if (Q_stricmp(name, "checkpassword") == 0)
  5592. {
  5593. if( UI_CheckPassword() )
  5594. {
  5595. UI_JoinServer();
  5596. }
  5597. }
  5598. else if (Q_stricmp(name, "JoinServer") == 0)
  5599. {
  5600. UI_JoinServer();
  5601. }
  5602. else if (Q_stricmp(name, "FoundPlayerJoinServer") == 0) {
  5603. trap_Cvar_Set("ui_singlePlayerActive", "0");
  5604. if (uiInfo.currentFoundPlayerServer >= 0 && uiInfo.currentFoundPlayerServer < uiInfo.numFoundPlayerServers) {
  5605. trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer] ) );
  5606. }
  5607. } else if (Q_stricmp(name, "Quit") == 0) {
  5608. trap_Cvar_Set("ui_singlePlayerActive", "0");
  5609. trap_Cmd_ExecuteText( EXEC_NOW, "quit");
  5610. } else if (Q_stricmp(name, "Controls") == 0) {
  5611. trap_Cvar_Set( "cl_paused", "1" );
  5612. trap_Key_SetCatcher( KEYCATCH_UI );
  5613. Menus_CloseAll();
  5614. Menus_ActivateByName("setup_menu2");
  5615. }
  5616. else if (Q_stricmp(name, "Leave") == 0)
  5617. {
  5618. trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" );
  5619. trap_Key_SetCatcher( KEYCATCH_UI );
  5620. Menus_CloseAll();
  5621. Menus_ActivateByName("main");
  5622. }
  5623. else if (Q_stricmp(name, "getvideosetup") == 0)
  5624. {
  5625. UI_GetVideoSetup ( );
  5626. }
  5627. else if (Q_stricmp(name, "getsaberhiltinfo") == 0)
  5628. {
  5629. //[DynamicMemory_Sabers]
  5630. UI_SaberGetHiltInfo();
  5631. //UI_SaberGetHiltInfo(saberSingleHiltInfo,saberStaffHiltInfo);
  5632. ///[DynamicMemory_Sabers]
  5633. }
  5634. // On the solo game creation screen, we can't see siege maps
  5635. else if (Q_stricmp(name, "checkforsiege") == 0)
  5636. {
  5637. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
  5638. {
  5639. // fake out the handler to advance to the next game type
  5640. UI_NetGameType_HandleKey(0, NULL, A_MOUSE1);
  5641. }
  5642. }
  5643. else if (Q_stricmp(name, "updatevideosetup") == 0)
  5644. {
  5645. UI_UpdateVideoSetup ( );
  5646. }
  5647. else if (Q_stricmp(name, "ServerSort") == 0)
  5648. {
  5649. int sortColumn;
  5650. if (Int_Parse(args, &sortColumn)) {
  5651. // if same column we're already sorting on then flip the direction
  5652. if (sortColumn == uiInfo.serverStatus.sortKey) {
  5653. uiInfo.serverStatus.sortDir = !uiInfo.serverStatus.sortDir;
  5654. }
  5655. // make sure we sort again
  5656. UI_ServersSort(sortColumn, qtrue);
  5657. }
  5658. } else if (Q_stricmp(name, "nextSkirmish") == 0) {
  5659. UI_StartSkirmish(qtrue);
  5660. } else if (Q_stricmp(name, "SkirmishStart") == 0) {
  5661. UI_StartSkirmish(qfalse);
  5662. } else if (Q_stricmp(name, "closeingame") == 0) {
  5663. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  5664. trap_Key_ClearStates();
  5665. trap_Cvar_Set( "cl_paused", "0" );
  5666. Menus_CloseAll();
  5667. } else if (Q_stricmp(name, "voteMap") == 0) {
  5668. if (ui_currentNetMap.integer >=0 && ui_currentNetMap.integer < uiInfo.mapCount) {
  5669. trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote map %s\n",uiInfo.mapList[ui_currentNetMap.integer].mapLoadName) );
  5670. }
  5671. } else if (Q_stricmp(name, "voteKick") == 0) {
  5672. if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount) {
  5673. //trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote kick \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex]) );
  5674. trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote clientkick \"%i\"\n",uiInfo.playerIndexes[uiInfo.playerIndex]) );
  5675. }
  5676. } else if (Q_stricmp(name, "voteGame") == 0) {
  5677. if (ui_netGameType.integer >= 0 && ui_netGameType.integer < uiInfo.numGameTypes) {
  5678. trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote g_gametype %i\n",uiInfo.gameTypes[ui_netGameType.integer].gtEnum) );
  5679. }
  5680. } else if (Q_stricmp(name, "voteLeader") == 0) {
  5681. if (uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount) {
  5682. trap_Cmd_ExecuteText( EXEC_APPEND, va("callteamvote leader \"%s\"\n",uiInfo.teamNames[uiInfo.teamIndex]) );
  5683. }
  5684. //[Asteroids]
  5685. } else if (Q_stricmp(name, "voteTeamKick") == 0) {
  5686. if (uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount) {
  5687. trap_Cmd_ExecuteText( EXEC_APPEND, va("callteamvote kick \"%s\"\n",uiInfo.teamNames[uiInfo.teamIndex]) );
  5688. }
  5689. //[/Asteroids]
  5690. } else if (Q_stricmp(name, "addBot") == 0) {
  5691. //[TABBot]
  5692. int bottype = trap_Cvar_VariableValue("ui_bottype");
  5693. //[CoOp]
  5694. //allow team bot selection in CoOp Games.
  5695. if (trap_Cvar_VariableValue("g_gametype") >= GT_SINGLE_PLAYER) {
  5696. //if (trap_Cvar_VariableValue("g_gametype") >= GT_TEAM) {
  5697. //[/CoOp]
  5698. trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot \"%s\" %i %s 0 \"%s\" %i\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue", UI_GetBotNameByNumber(uiInfo.botIndex), bottype) );
  5699. //trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot \"%s\" %i %s\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue") );
  5700. } else {
  5701. trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot \"%s\" %i %s 0 \"%s\" %i\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue", UI_GetBotNameByNumber(uiInfo.botIndex), bottype) );
  5702. //trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot \"%s\" %i %s\n", UI_GetBotNameByNumber(uiInfo.botIndex), uiInfo.skillIndex+1, (uiInfo.redBlue == 0) ? "Red" : "Blue") );
  5703. //[/TABBot]
  5704. }
  5705. } else if (Q_stricmp(name, "addFavorite") == 0)
  5706. {
  5707. if (ui_netSource.integer != AS_FAVORITES)
  5708. {
  5709. char name[MAX_NAME_LENGTH];
  5710. char addr[MAX_NAME_LENGTH];
  5711. int res;
  5712. trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
  5713. name[0] = addr[0] = '\0';
  5714. Q_strncpyz(name, Info_ValueForKey(buff, "hostname"), MAX_NAME_LENGTH);
  5715. Q_strncpyz(addr, Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
  5716. if (strlen(name) > 0 && strlen(addr) > 0)
  5717. {
  5718. res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
  5719. if (res == 0)
  5720. {
  5721. // server already in the list
  5722. Com_Printf("Favorite already in list\n");
  5723. }
  5724. else if (res == -1)
  5725. {
  5726. // list full
  5727. Com_Printf("Favorite list full\n");
  5728. }
  5729. else
  5730. {
  5731. // successfully added
  5732. Com_Printf("Added favorite server %s\n", addr);
  5733. // trap_SP_GetStringTextString((char *)va("%s_GETTINGINFOFORSERVERS",uiInfo.uiDC.Assets.stringedFile), holdSPString, sizeof(holdSPString));
  5734. // Text_Paint(rect->x, rect->y, scale, newColor, va((char *) holdSPString, trap_LAN_GetServerCount(ui_netSource.integer)), 0, 0, textStyle);
  5735. }
  5736. }
  5737. }
  5738. }
  5739. else if (Q_stricmp(name, "deleteFavorite") == 0)
  5740. {
  5741. if (ui_netSource.integer == AS_FAVORITES)
  5742. {
  5743. char addr[MAX_NAME_LENGTH];
  5744. trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
  5745. addr[0] = '\0';
  5746. Q_strncpyz(addr, Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
  5747. if (strlen(addr) > 0)
  5748. {
  5749. trap_LAN_RemoveServer(AS_FAVORITES, addr);
  5750. }
  5751. }
  5752. }
  5753. else if (Q_stricmp(name, "createFavorite") == 0)
  5754. {
  5755. // if (ui_netSource.integer == AS_FAVORITES)
  5756. //rww - don't know why this check was here.. why would you want to only add new favorites when the filter was favorites?
  5757. {
  5758. char name[MAX_NAME_LENGTH];
  5759. char addr[MAX_NAME_LENGTH];
  5760. int res;
  5761. name[0] = addr[0] = '\0';
  5762. Q_strncpyz(name, UI_Cvar_VariableString("ui_favoriteName"), MAX_NAME_LENGTH);
  5763. Q_strncpyz(addr, UI_Cvar_VariableString("ui_favoriteAddress"), MAX_NAME_LENGTH);
  5764. if (/*strlen(name) > 0 &&*/ strlen(addr) > 0) {
  5765. res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
  5766. if (res == 0) {
  5767. // server already in the list
  5768. Com_Printf("Favorite already in list\n");
  5769. }
  5770. else if (res == -1) {
  5771. // list full
  5772. Com_Printf("Favorite list full\n");
  5773. }
  5774. else {
  5775. // successfully added
  5776. Com_Printf("Added favorite server %s\n", addr);
  5777. }
  5778. }
  5779. }
  5780. } else if (Q_stricmp(name, "orders") == 0) {
  5781. const char *orders;
  5782. if (String_Parse(args, &orders)) {
  5783. int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
  5784. if (selectedPlayer < uiInfo.myTeamCount) {
  5785. strcpy(buff, orders);
  5786. trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) );
  5787. trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
  5788. } else {
  5789. int i;
  5790. for (i = 0; i < uiInfo.myTeamCount; i++) {
  5791. if (Q_stricmp(UI_Cvar_VariableString("name"), uiInfo.teamNames[i]) == 0) {
  5792. continue;
  5793. }
  5794. strcpy(buff, orders);
  5795. trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamNames[i]) );
  5796. trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
  5797. }
  5798. }
  5799. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  5800. trap_Key_ClearStates();
  5801. trap_Cvar_Set( "cl_paused", "0" );
  5802. Menus_CloseAll();
  5803. }
  5804. } else if (Q_stricmp(name, "voiceOrdersTeam") == 0) {
  5805. const char *orders;
  5806. if (String_Parse(args, &orders)) {
  5807. int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
  5808. if (selectedPlayer == uiInfo.myTeamCount) {
  5809. trap_Cmd_ExecuteText( EXEC_APPEND, orders );
  5810. trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
  5811. }
  5812. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  5813. trap_Key_ClearStates();
  5814. trap_Cvar_Set( "cl_paused", "0" );
  5815. Menus_CloseAll();
  5816. }
  5817. } else if (Q_stricmp(name, "voiceOrders") == 0) {
  5818. const char *orders;
  5819. if (String_Parse(args, &orders)) {
  5820. int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
  5821. if (selectedPlayer == uiInfo.myTeamCount)
  5822. {
  5823. selectedPlayer = -1;
  5824. strcpy(buff, orders);
  5825. trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, selectedPlayer) );
  5826. }
  5827. else
  5828. {
  5829. strcpy(buff, orders);
  5830. trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) );
  5831. }
  5832. trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
  5833. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  5834. trap_Key_ClearStates();
  5835. trap_Cvar_Set( "cl_paused", "0" );
  5836. Menus_CloseAll();
  5837. }
  5838. }
  5839. else if (Q_stricmp(name, "setForce") == 0)
  5840. {
  5841. const char *teamArg;
  5842. if (String_Parse(args, &teamArg))
  5843. {
  5844. if ( Q_stricmp( "none", teamArg ) == 0 )
  5845. {
  5846. UI_UpdateClientForcePowers(NULL);
  5847. }
  5848. else if ( Q_stricmp( "same", teamArg ) == 0 )
  5849. {//stay on current team
  5850. int myTeam = (int)(trap_Cvar_VariableValue("ui_myteam"));
  5851. if ( myTeam != TEAM_SPECTATOR )
  5852. {
  5853. UI_UpdateClientForcePowers(UI_TeamName(myTeam));//will cause him to respawn, if it's been 5 seconds since last one
  5854. }
  5855. else
  5856. {
  5857. UI_UpdateClientForcePowers(NULL);//just update powers
  5858. }
  5859. }
  5860. else
  5861. {
  5862. //[ExpSys]
  5863. //somehow my experience system changes broke the join game button.
  5864. //Manually setting the approprate variable to send the team change command.
  5865. gTouchedForce = qtrue;
  5866. //[/ExpSys]
  5867. UI_UpdateClientForcePowers(teamArg);
  5868. }
  5869. }
  5870. else
  5871. {
  5872. UI_UpdateClientForcePowers(NULL);
  5873. }
  5874. }
  5875. else if (Q_stricmp(name, "setsiegeclassandteam") == 0)
  5876. {
  5877. //[SIEGECVARFIX]
  5878. int team = (int)siege_Cvar_VariableValue("ui_holdteam");
  5879. int oldteam = (int)siege_Cvar_VariableValue("ui_startsiegeteam");
  5880. // int team = (int)trap_Cvar_VariableValue("ui_holdteam");
  5881. // int oldteam = (int)trap_Cvar_VariableValue("ui_startsiegeteam");
  5882. //[/SIEGECVARFIX]
  5883. qboolean goTeam = qtrue;
  5884. char newclassString[512];
  5885. char startclassString[512];
  5886. //[SIEGECVARFIX]
  5887. siege_Cvar_VariableStringBuffer( "ui_mySiegeClass", newclassString, sizeof(newclassString) );
  5888. siege_Cvar_VariableStringBuffer( "ui_startsiegeclass", startclassString, sizeof(startclassString) );
  5889. //trap_Cvar_VariableStringBuffer( "ui_mySiegeClass", newclassString, sizeof(newclassString) );
  5890. //trap_Cvar_VariableStringBuffer( "ui_startsiegeclass", startclassString, sizeof(startclassString) );
  5891. //[/SIEGECVARFIX]
  5892. // Was just a spectator - is still just a spectator
  5893. if ((oldteam == team) && (oldteam == 3))
  5894. {
  5895. goTeam = qfalse;
  5896. }
  5897. // If new team and class match old team and class, just return to the game.
  5898. else if ((oldteam == team))
  5899. { // Classes match?
  5900. if (g_UIGloballySelectedSiegeClass != -1)
  5901. {
  5902. if (!strcmp(startclassString,bgSiegeClasses[g_UIGloballySelectedSiegeClass].name))
  5903. {
  5904. goTeam = qfalse;
  5905. }
  5906. }
  5907. }
  5908. if (goTeam)
  5909. {
  5910. if (team == 1) // Team red
  5911. {
  5912. trap_Cvar_Set("ui_team", va("%d", team));
  5913. }
  5914. else if (team == 2) // Team blue
  5915. {
  5916. trap_Cvar_Set("ui_team", va("%d", team));
  5917. }
  5918. else if (team == 3) // Team spectator
  5919. {
  5920. trap_Cvar_Set("ui_team", va("%d", team));
  5921. }
  5922. if (g_UIGloballySelectedSiegeClass != -1)
  5923. {
  5924. trap_Cmd_ExecuteText( EXEC_APPEND, va("siegeclass \"%s\"\n", bgSiegeClasses[g_UIGloballySelectedSiegeClass].name) );
  5925. }
  5926. }
  5927. }
  5928. else if (Q_stricmp(name, "setBotButton") == 0)
  5929. {
  5930. UI_SetBotButton();
  5931. }
  5932. else if (Q_stricmp(name, "saveTemplate") == 0) {
  5933. UI_SaveForceTemplate();
  5934. } else if (Q_stricmp(name, "refreshForce") == 0) {
  5935. UI_UpdateForcePowers();
  5936. } else if (Q_stricmp(name, "glCustom") == 0) {
  5937. trap_Cvar_Set("ui_r_glCustom", "4");
  5938. }
  5939. else if (Q_stricmp(name, "setMovesListDefault") == 0)
  5940. {
  5941. uiInfo.movesTitleIndex = 2;
  5942. }
  5943. else if (Q_stricmp(name, "resetMovesList") == 0)
  5944. {
  5945. menuDef_t *menu;
  5946. menu = Menus_FindByName("rulesMenu_moves");
  5947. //update saber models
  5948. if (menu)
  5949. {
  5950. itemDef_t *item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
  5951. if (item)
  5952. {
  5953. UI_SaberAttachToChar( item );
  5954. }
  5955. }
  5956. trap_Cvar_Set( "ui_move_desc", " " );
  5957. }
  5958. else if (Q_stricmp(name, "resetcharacterlistboxes") == 0)
  5959. {
  5960. UI_ResetCharacterListBoxes();
  5961. }
  5962. else if (Q_stricmp(name, "setMoveCharacter") == 0)
  5963. {
  5964. itemDef_t *item;
  5965. menuDef_t *menu;
  5966. modelDef_t *modelPtr;
  5967. int animRunLength;
  5968. UI_GetCharacterCvars();
  5969. uiInfo.movesTitleIndex = 0;
  5970. menu = Menus_FindByName("rulesMenu_moves");
  5971. if (menu)
  5972. {
  5973. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
  5974. if (item)
  5975. {
  5976. modelPtr = (modelDef_t*)item->typeData;
  5977. if (modelPtr)
  5978. {
  5979. char modelPath[MAX_QPATH];
  5980. uiInfo.movesBaseAnim = datapadMoveTitleBaseAnims[uiInfo.movesTitleIndex];
  5981. ItemParse_model_g2anim_go( item, uiInfo.movesBaseAnim );
  5982. uiInfo.moveAnimTime = 0 ;
  5983. Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
  5984. ItemParse_asset_model_go( item, modelPath, &animRunLength);
  5985. UI_UpdateCharacterSkin();
  5986. UI_SaberAttachToChar( item );
  5987. }
  5988. }
  5989. }
  5990. }
  5991. else if (Q_stricmp(name, "character") == 0)
  5992. {
  5993. UI_UpdateCharacter( qfalse );
  5994. }
  5995. else if (Q_stricmp(name, "characterchanged") == 0)
  5996. {
  5997. UI_UpdateCharacter( qtrue );
  5998. }
  5999. else if (Q_stricmp(name, "updatecharcvars") == 0
  6000. || (Q_stricmp(name, "updatecharmodel") == 0) )
  6001. {
  6002. UI_UpdateCharacterCvars();
  6003. }
  6004. else if (Q_stricmp(name, "getcharcvars") == 0)
  6005. {
  6006. UI_GetCharacterCvars();
  6007. }
  6008. else if (Q_stricmp(name, "char_skin") == 0)
  6009. {
  6010. UI_UpdateCharacterSkin();
  6011. }
  6012. //[/MOREFORCEOPTIONS]
  6013. //Don't need this stuff anymore with the new menu items.
  6014. /*
  6015. else if (Q_stricmp(name, "setui_dualforcepower") == 0)
  6016. {
  6017. int forcePowerDisable = trap_Cvar_VariableValue("g_forcePowerDisable");
  6018. int i, forceBitFlag=0;
  6019. // Turn off all powers but a few
  6020. for (i=0;i<NUM_FORCE_POWERS;i++)
  6021. {
  6022. if ((i != FP_LEVITATION) &&
  6023. (i != FP_PUSH) &&
  6024. (i != FP_PULL) &&
  6025. (i != FP_SABERTHROW) &&
  6026. (i != FP_SABER_DEFENSE) &&
  6027. (i != FP_SABER_OFFENSE))
  6028. {
  6029. forceBitFlag |= (1<<i);
  6030. }
  6031. }
  6032. if (forcePowerDisable==0)
  6033. {
  6034. trap_Cvar_Set("ui_dualforcepower", "0");
  6035. }
  6036. else if (forcePowerDisable==forceBitFlag)
  6037. {
  6038. trap_Cvar_Set("ui_dualforcepower", "2");
  6039. }
  6040. else
  6041. {
  6042. trap_Cvar_Set("ui_dualforcepower", "1");
  6043. }
  6044. }
  6045. else if (Q_stricmp(name, "dualForcePowers") == 0)
  6046. {
  6047. int dualforcePower,i, forcePowerDisable;
  6048. dualforcePower = trap_Cvar_VariableValue("ui_dualforcepower");
  6049. if (dualforcePower==0) // All force powers
  6050. {
  6051. forcePowerDisable = 0;
  6052. }
  6053. else if (dualforcePower==1) // Remove All force powers
  6054. {
  6055. // It was set to something, so might as well make sure it got all flags set.
  6056. for (i=0;i<NUM_FORCE_POWERS;i++)
  6057. {
  6058. forcePowerDisable |= (1<<i);
  6059. }
  6060. }
  6061. else if (dualforcePower==2) // Limited force powers
  6062. {
  6063. forcePowerDisable = 0;
  6064. // Turn off all powers but a few
  6065. for (i=0;i<NUM_FORCE_POWERS;i++)
  6066. {
  6067. if ((i != FP_LEVITATION) &&
  6068. (i != FP_PUSH) &&
  6069. (i != FP_PULL) &&
  6070. (i != FP_SABERTHROW) &&
  6071. (i != FP_SABER_DEFENSE) &&
  6072. (i != FP_SABER_OFFENSE))
  6073. {
  6074. forcePowerDisable |= (1<<i);
  6075. }
  6076. }
  6077. }
  6078. trap_Cvar_Set("g_forcePowerDisable", va("%i",forcePowerDisable));
  6079. }
  6080. else if (Q_stricmp(name, "forcePowersDisable") == 0)
  6081. {
  6082. int forcePowerDisable,i;
  6083. forcePowerDisable = trap_Cvar_VariableValue("g_forcePowerDisable");
  6084. // It was set to something, so might as well make sure it got all flags set.
  6085. if (forcePowerDisable)
  6086. {
  6087. for (i=0;i<NUM_FORCE_POWERS;i++)
  6088. {
  6089. forcePowerDisable |= (1<<i);
  6090. }
  6091. trap_Cvar_Set("g_forcePowerDisable", va("%i",forcePowerDisable));
  6092. }
  6093. }
  6094. */
  6095. //[/MOREFORCEOPTIONS]
  6096. //[MOREWEAPOPTIONS]
  6097. /*
  6098. else if (Q_stricmp(name, "weaponDisable") == 0)
  6099. {
  6100. int weaponDisable,i;
  6101. const char *cvarString;
  6102. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_DUEL ||
  6103. uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_POWERDUEL)
  6104. {
  6105. cvarString = "g_duelWeaponDisable";
  6106. }
  6107. else
  6108. {
  6109. cvarString = "g_weaponDisable";
  6110. }
  6111. weaponDisable = trap_Cvar_VariableValue(cvarString);
  6112. // It was set to something, so might as well make sure it got all flags set.
  6113. if (weaponDisable)
  6114. {
  6115. for (i=0;i<WP_NUM_WEAPONS;i++)
  6116. {
  6117. if (i!=WP_SABER)
  6118. {
  6119. weaponDisable |= (1<<i);
  6120. }
  6121. }
  6122. trap_Cvar_Set(cvarString, va("%i",weaponDisable));
  6123. }
  6124. }
  6125. */
  6126. //[/MOREWEAPOPTIONS]
  6127. // If this is siege, change all the bots to humans, because we faked it earlier
  6128. // swapping humans for bots on the menu
  6129. else if (Q_stricmp(name, "setSiegeNoBots") == 0)
  6130. {
  6131. int blueValue,redValue,i;
  6132. if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_SIEGE)
  6133. {
  6134. //hmm, I guess I'll set bot_minplayers to 0 here too. -rww
  6135. trap_Cvar_Set("bot_minplayers", "0");
  6136. for (i=1;i<9;i++)
  6137. {
  6138. blueValue = trap_Cvar_VariableValue(va("ui_blueteam%i",i ));
  6139. if (blueValue>1)
  6140. {
  6141. trap_Cvar_Set(va("ui_blueteam%i",i ), "1");
  6142. }
  6143. redValue = trap_Cvar_VariableValue(va("ui_redteam%i",i ));
  6144. if (redValue>1)
  6145. {
  6146. trap_Cvar_Set(va("ui_redteam%i",i ), "1");
  6147. }
  6148. }
  6149. }
  6150. }
  6151. else if (Q_stricmp(name, "clearmouseover") == 0)
  6152. {
  6153. itemDef_t *item;
  6154. menuDef_t *menu = Menu_GetFocused();
  6155. if (menu)
  6156. {
  6157. int count,j;
  6158. const char *itemName;
  6159. String_Parse(args, &itemName);
  6160. count = Menu_ItemsMatchingGroup(menu, itemName);
  6161. for (j = 0; j < count; j++)
  6162. {
  6163. item = Menu_GetMatchingItemByNumber( menu, j, itemName);
  6164. if (item != NULL)
  6165. {
  6166. item->window.flags &= ~WINDOW_MOUSEOVER;
  6167. }
  6168. }
  6169. }
  6170. }
  6171. else if (Q_stricmp(name, "updateForceStatus") == 0)
  6172. {
  6173. UpdateForceStatus();
  6174. }
  6175. else if (Q_stricmp(name, "update") == 0)
  6176. {
  6177. if (String_Parse(args, &name2))
  6178. {
  6179. UI_Update(name2);
  6180. }
  6181. }
  6182. else if (Q_stricmp(name, "setBotButtons") == 0)
  6183. {
  6184. UpdateBotButtons();
  6185. }
  6186. else if (Q_stricmp(name, "getsabercvars") == 0)
  6187. {
  6188. UI_GetSaberCvars();
  6189. }
  6190. else if (Q_stricmp(name, "setsaberboxesandhilts") == 0)
  6191. {
  6192. UI_SetSaberBoxesandHilts();
  6193. }
  6194. else if (Q_stricmp(name, "saber_type") == 0)
  6195. {
  6196. UI_UpdateSaberType();
  6197. }
  6198. else if (Q_stricmp(name, "saber_hilt") == 0)
  6199. {
  6200. UI_UpdateSaberHilt( qfalse );
  6201. }
  6202. else if (Q_stricmp(name, "saber_color") == 0)
  6203. {
  6204. UI_UpdateSaberColor( qfalse );
  6205. }
  6206. else if (Q_stricmp(name, "setscreensaberhilt") == 0)
  6207. {
  6208. menuDef_t *menu;
  6209. itemDef_t *item;
  6210. menu = Menu_GetFocused(); // Get current menu
  6211. if (menu)
  6212. {
  6213. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut");
  6214. if (item)
  6215. {
  6216. //[DynamicMemory_Sabers]
  6217. if (UI_GetSaberHiltInfo(qfalse, item->cursorPos))
  6218. //if (saberSingleHiltInfo[item->cursorPos])
  6219. {
  6220. trap_Cvar_Set( "ui_saber", UI_GetSaberHiltInfo(qfalse, item->cursorPos));
  6221. //trap_Cvar_Set( "ui_saber", saberSingleHiltInfo[item->cursorPos] );
  6222. }
  6223. //[/DynamicMemory_Sabers]
  6224. }
  6225. }
  6226. }
  6227. else if (Q_stricmp(name, "setscreensaberhilt1") == 0)
  6228. {
  6229. menuDef_t *menu;
  6230. itemDef_t *item;
  6231. menu = Menu_GetFocused(); // Get current menu
  6232. if (menu)
  6233. {
  6234. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut1");
  6235. if (item)
  6236. {
  6237. //[DynamicMemory_Sabers]
  6238. if (UI_GetSaberHiltInfo(qfalse, item->cursorPos))
  6239. //if (saberSingleHiltInfo[item->cursorPos])
  6240. {
  6241. trap_Cvar_Set( "ui_saber", UI_GetSaberHiltInfo(qfalse, item->cursorPos));
  6242. //trap_Cvar_Set( "ui_saber", saberSingleHiltInfo[item->cursorPos] );
  6243. }
  6244. //[/DynamicMemory_Sabers]
  6245. }
  6246. }
  6247. }
  6248. else if (Q_stricmp(name, "setscreensaberhilt2") == 0)
  6249. {
  6250. menuDef_t *menu;
  6251. itemDef_t *item;
  6252. menu = Menu_GetFocused(); // Get current menu
  6253. if (menu)
  6254. {
  6255. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut2");
  6256. if (item)
  6257. {
  6258. //[DynamicMemory_Sabers]
  6259. if (UI_GetSaberHiltInfo(qfalse, item->cursorPos))
  6260. //if (saberSingleHiltInfo[item->cursorPos])
  6261. {
  6262. trap_Cvar_Set( "ui_saber2", UI_GetSaberHiltInfo(qfalse, item->cursorPos));
  6263. //trap_Cvar_Set( "ui_saber2", saberSingleHiltInfo[item->cursorPos] );
  6264. }
  6265. //[/DynamicMemory_Sabers]
  6266. }
  6267. }
  6268. }
  6269. else if (Q_stricmp(name, "setscreensaberstaff") == 0)
  6270. {
  6271. menuDef_t *menu;
  6272. itemDef_t *item;
  6273. menu = Menu_GetFocused(); // Get current menu
  6274. if (menu)
  6275. {
  6276. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "hiltbut_staves");
  6277. if (item)
  6278. {
  6279. //[DynamicMemory_Sabers]
  6280. if (UI_GetSaberHiltInfo(qtrue, item->cursorPos))
  6281. //there was a bug here, we were checking for a single hilt, but we ment to check for staff
  6282. //if (saberSingleHiltInfo[item->cursorPos])
  6283. {
  6284. trap_Cvar_Set( "ui_saber", UI_GetSaberHiltInfo(qtrue, item->cursorPos));
  6285. //trap_Cvar_Set( "ui_saber", saberStaffHiltInfo[item->cursorPos] );
  6286. }
  6287. //[/DynamicMemory_Sabers]
  6288. }
  6289. }
  6290. }
  6291. else if (Q_stricmp(name, "saber2_hilt") == 0)
  6292. {
  6293. UI_UpdateSaberHilt( qtrue );
  6294. }
  6295. else if (Q_stricmp(name, "saber2_color") == 0)
  6296. {
  6297. UI_UpdateSaberColor( qtrue );
  6298. }
  6299. else if (Q_stricmp(name, "updatesabercvars") == 0)
  6300. {
  6301. UI_UpdateSaberCvars();
  6302. }
  6303. else if (Q_stricmp(name, "updatesiegeobjgraphics") == 0)
  6304. {
  6305. int team = (int)trap_Cvar_VariableValue("ui_team");
  6306. trap_Cvar_Set("ui_holdteam", va("%d", team));
  6307. UI_UpdateSiegeObjectiveGraphics();
  6308. }
  6309. else if (Q_stricmp(name, "setsiegeobjbuttons") == 0)
  6310. {
  6311. const char *itemArg;
  6312. const char *cvarLitArg;
  6313. const char *cvarNormalArg;
  6314. char string[512];
  6315. char string2[512];
  6316. menuDef_t *menu;
  6317. itemDef_t *item;
  6318. menu = Menu_GetFocused(); // Get current menu
  6319. if (menu)
  6320. {
  6321. // Set the new item to the background
  6322. if (String_Parse(args, &itemArg))
  6323. {
  6324. // Set the old button to it's original background
  6325. //[SIEGECVARFIX]
  6326. siege_Cvar_VariableStringBuffer( "currentObjMapIconItem", string, sizeof(string) );
  6327. //trap_Cvar_VariableStringBuffer( "currentObjMapIconItem", string, sizeof(string) );
  6328. //[/SIEGECVARFIX]
  6329. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, string);
  6330. if (item)
  6331. {
  6332. // A cvar holding the name of a cvar - how crazy is that?
  6333. //[SIEGECVARFIX]
  6334. siege_Cvar_VariableStringBuffer( "currentObjMapIconBackground", string, sizeof(string) );
  6335. siege_Cvar_VariableStringBuffer( string, string2, sizeof(string2) );
  6336. //trap_Cvar_VariableStringBuffer( "currentObjMapIconBackground", string, sizeof(string) );
  6337. //trap_Cvar_VariableStringBuffer( string, string2, sizeof(string2) );
  6338. //[/SIEGECVARFIX]
  6339. Menu_SetItemBackground(menu, item->window.name, string2);
  6340. // Re-enable this button
  6341. Menu_ItemDisable(menu,(char *) item->window.name, qfalse);
  6342. }
  6343. // Set the new item to the given background
  6344. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, itemArg);
  6345. if (item)
  6346. { // store item name
  6347. //[SIEGECVARFIX]
  6348. siege_Cvar_Set("currentObjMapIconItem", item->window.name);
  6349. //trap_Cvar_Set("currentObjMapIconItem", item->window.name);
  6350. //[/SIEGECVARFIX]
  6351. if (String_Parse(args, &cvarNormalArg))
  6352. { // Store normal background
  6353. //[SIEGECVARFIX]
  6354. siege_Cvar_Set("currentObjMapIconBackground", (char *)cvarNormalArg);
  6355. //trap_Cvar_Set("currentObjMapIconBackground", cvarNormalArg);
  6356. //[/SIEGECVARFIX]
  6357. // Get higlight background
  6358. if (String_Parse(args, &cvarLitArg))
  6359. { // set hightlight background
  6360. //[SIEGECVARFIX]
  6361. siege_Cvar_VariableStringBuffer( (char *)cvarLitArg, string, sizeof(string) );
  6362. //trap_Cvar_VariableStringBuffer( cvarLitArg, string, sizeof(string) );
  6363. //[/SIEGECVARFIX]
  6364. Menu_SetItemBackground(menu, item->window.name, string);
  6365. // Disable button
  6366. Menu_ItemDisable(menu,(char *) item->window.name, qtrue);
  6367. }
  6368. }
  6369. }
  6370. }
  6371. }
  6372. }
  6373. else if (Q_stricmp(name, "updatesiegeclasscnt") == 0)
  6374. {
  6375. const char *teamArg;
  6376. if (String_Parse(args, &teamArg))
  6377. {
  6378. UI_SiegeClassCnt(atoi(teamArg));
  6379. }
  6380. }
  6381. else if (Q_stricmp(name, "updatesiegecvars") == 0)
  6382. {
  6383. int team,baseClass;
  6384. team = (int)trap_Cvar_VariableValue("ui_holdteam");
  6385. //[SIEGECVARFIX]
  6386. baseClass = (int)siege_Cvar_VariableValue("ui_siege_class");
  6387. //baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
  6388. //[/SIEGECVARFIX]
  6389. UI_UpdateCvarsForClass(team, baseClass, 0);
  6390. }
  6391. // Save current team and class
  6392. else if (Q_stricmp(name, "setteamclassicons") == 0)
  6393. {
  6394. int team = (int)trap_Cvar_VariableValue("ui_holdteam");
  6395. char classString[512];
  6396. //[SIEGECVARFIX]
  6397. siege_Cvar_VariableStringBuffer( "ui_mySiegeClass", classString, sizeof(classString) );
  6398. siege_Cvar_Set("ui_startsiegeteam", va("%d", team));
  6399. siege_Cvar_Set( "ui_startsiegeclass", classString);
  6400. //trap_Cvar_VariableStringBuffer( "ui_mySiegeClass", classString, sizeof(classString) );
  6401. //trap_Cvar_Set("ui_startsiegeteam", va("%d", team));
  6402. //trap_Cvar_Set( "ui_startsiegeclass", classString);
  6403. //[/SIEGECVARFIX]
  6404. // If player is already on a team, set up icons to show it.
  6405. UI_FindCurrentSiegeTeamClass();
  6406. }
  6407. else if (Q_stricmp(name, "updatesiegeweapondesc") == 0)
  6408. {
  6409. menuDef_t *menu;
  6410. itemDef_t *item;
  6411. menu = Menu_GetFocused(); // Get current menu
  6412. if (menu)
  6413. {
  6414. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_weapons_feed");
  6415. if (item)
  6416. {
  6417. char info[MAX_INFO_VALUE];
  6418. //[SIEGECVARFIX]
  6419. siege_Cvar_VariableStringBuffer( va("ui_class_weapondesc%i", item->cursorPos), info, sizeof(info) );
  6420. //trap_Cvar_VariableStringBuffer( va("ui_class_weapondesc%i", item->cursorPos), info, sizeof(info) );
  6421. //[/SIEGECVARFIX]
  6422. trap_Cvar_Set( "ui_itemforceinvdesc", info );
  6423. }
  6424. }
  6425. }
  6426. else if (Q_stricmp(name, "updatesiegeinventorydesc") == 0)
  6427. {
  6428. menuDef_t *menu;
  6429. itemDef_t *item;
  6430. menu = Menu_GetFocused(); // Get current menu
  6431. if (menu)
  6432. {
  6433. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_inventory_feed");
  6434. if (item)
  6435. {
  6436. char info[MAX_INFO_VALUE];
  6437. //[SIEGECVARFIX]
  6438. siege_Cvar_VariableStringBuffer( va("ui_class_itemdesc%i", item->cursorPos), info, sizeof(info) );
  6439. //trap_Cvar_VariableStringBuffer( va("ui_class_itemdesc%i", item->cursorPos), info, sizeof(info) );
  6440. //[/SIEGECVARFIX]
  6441. trap_Cvar_Set( "ui_itemforceinvdesc", info );
  6442. }
  6443. }
  6444. }
  6445. else if (Q_stricmp(name, "updatesiegeforcedesc") == 0)
  6446. {
  6447. menuDef_t *menu;
  6448. itemDef_t *item;
  6449. menu = Menu_GetFocused(); // Get current menu
  6450. if (menu)
  6451. {
  6452. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_force_feed");
  6453. if (item)
  6454. {
  6455. int i;
  6456. char info[MAX_STRING_CHARS];
  6457. //[SIEGECVARFIX]
  6458. siege_Cvar_VariableStringBuffer( va("ui_class_power%i", item->cursorPos), info, sizeof(info) );
  6459. //trap_Cvar_VariableStringBuffer( va("ui_class_power%i", item->cursorPos), info, sizeof(info) );
  6460. //[SIEGECVARFIX]
  6461. //count them up
  6462. for (i=0;i< NUM_FORCE_POWERS;i++)
  6463. {
  6464. if (!strcmp(HolocronIcons[i],info))
  6465. {
  6466. trap_Cvar_Set( "ui_itemforceinvdesc", forcepowerDesc[i] );
  6467. }
  6468. }
  6469. }
  6470. }
  6471. }
  6472. else if (Q_stricmp(name, "resetitemdescription") == 0)
  6473. {
  6474. menuDef_t *menu;
  6475. itemDef_t *item;
  6476. menu = Menu_GetFocused(); // Get current menu
  6477. if (menu)
  6478. {
  6479. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "itemdescription");
  6480. if (item)
  6481. {
  6482. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  6483. if (listPtr)
  6484. {
  6485. listPtr->startPos = 0;
  6486. listPtr->cursorPos = 0;
  6487. }
  6488. item->cursorPos = 0;
  6489. }
  6490. }
  6491. }
  6492. else if (Q_stricmp(name, "resetsiegelistboxes") == 0)
  6493. {
  6494. menuDef_t *menu;
  6495. itemDef_t *item;
  6496. menu = Menu_GetFocused(); // Get current menu
  6497. if (menu)
  6498. {
  6499. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "description");
  6500. if (item)
  6501. {
  6502. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  6503. if (listPtr)
  6504. {
  6505. listPtr->startPos = 0;
  6506. }
  6507. item->cursorPos = 0;
  6508. }
  6509. }
  6510. menu = Menu_GetFocused(); // Get current menu
  6511. if (menu)
  6512. {
  6513. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_weapons_feed");
  6514. if (item)
  6515. {
  6516. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  6517. if (listPtr)
  6518. {
  6519. listPtr->startPos = 0;
  6520. }
  6521. item->cursorPos = 0;
  6522. }
  6523. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_inventory_feed");
  6524. if (item)
  6525. {
  6526. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  6527. if (listPtr)
  6528. {
  6529. listPtr->startPos = 0;
  6530. }
  6531. item->cursorPos = 0;
  6532. }
  6533. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_force_feed");
  6534. if (item)
  6535. {
  6536. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  6537. if (listPtr)
  6538. {
  6539. listPtr->startPos = 0;
  6540. }
  6541. item->cursorPos = 0;
  6542. }
  6543. }
  6544. }
  6545. else if (Q_stricmp(name, "updatesiegestatusicons") == 0)
  6546. {
  6547. UI_UpdateSiegeStatusIcons();
  6548. }
  6549. else if (Q_stricmp(name, "setcurrentNetMap") == 0)
  6550. {
  6551. menuDef_t *menu;
  6552. itemDef_t *item;
  6553. menu = Menu_GetFocused(); // Get current menu
  6554. if (menu)
  6555. {
  6556. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "maplist");
  6557. if (item)
  6558. {
  6559. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  6560. if (listPtr)
  6561. {
  6562. trap_Cvar_Set("ui_currentNetMap", va("%d",listPtr->cursorPos));
  6563. }
  6564. }
  6565. }
  6566. }
  6567. else if (Q_stricmp(name, "resetmaplist") == 0)
  6568. {
  6569. menuDef_t *menu;
  6570. itemDef_t *item;
  6571. menu = Menu_GetFocused(); // Get current menu
  6572. if (menu)
  6573. {
  6574. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "maplist");
  6575. if (item)
  6576. {
  6577. uiInfo.uiDC.feederSelection(item->special, item->cursorPos, item);
  6578. }
  6579. }
  6580. }
  6581. else if (Q_stricmp(name, "getmousepitch") == 0)
  6582. {
  6583. trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1");
  6584. }
  6585. else if (Q_stricmp(name, "clampmaxplayers") == 0)
  6586. {
  6587. UI_ClampMaxPlayers();
  6588. }
  6589. //[CoOp]
  6590. else if (Q_stricmp(name, "loadmissionselectmenu") == 0)
  6591. {//used by menus to load up the approprate menus for the mission selection menus
  6592. //for now, I'm just going to buckshot load stuff at this point.
  6593. //UI_LoadSingleMenuFile("ui/ingameforcestatus.menu");
  6594. //UI_LoadSingleMenuFile("ui/ingameMissionSelect1.menu");
  6595. //UI_LoadSingleMenuFile("ui/ingameMissionSelect2.menu");
  6596. //UI_LoadSingleMenuFile("ui/ingameMissionSelect3.menu");
  6597. }
  6598. //[/CoOp]
  6599. else
  6600. {
  6601. Com_Printf("unknown UI script %s\n", name);
  6602. }
  6603. }
  6604. }
  6605. static void UI_GetTeamColor(vec4_t *color) {
  6606. }
  6607. #include "../namespace_begin.h"
  6608. int BG_SiegeCountBaseClass(const int team, const short classIndex);
  6609. #include "../namespace_end.h"
  6610. static void UI_SiegeClassCnt( const int team )
  6611. {
  6612. UI_SetSiegeTeams();
  6613. //[SIEGECVARFIX]
  6614. siege_Cvar_Set("ui_infantry_cnt", va("%d", BG_SiegeCountBaseClass(team,0)));
  6615. siege_Cvar_Set("ui_vanguard_cnt", va("%d", BG_SiegeCountBaseClass(team,1)));
  6616. siege_Cvar_Set("ui_support_cnt", va("%d", BG_SiegeCountBaseClass(team,2)));
  6617. siege_Cvar_Set("ui_jedi_cnt", va("%d", BG_SiegeCountBaseClass(team,3)));
  6618. siege_Cvar_Set("ui_demo_cnt", va("%d", BG_SiegeCountBaseClass(team,4)));
  6619. siege_Cvar_Set("ui_heavy_cnt", va("%d", BG_SiegeCountBaseClass(team,5)));
  6620. /*trap_Cvar_Set("ui_infantry_cnt", va("%d", BG_SiegeCountBaseClass(team,0)));
  6621. trap_Cvar_Set("ui_vanguard_cnt", va("%d", BG_SiegeCountBaseClass(team,1)));
  6622. trap_Cvar_Set("ui_support_cnt", va("%d", BG_SiegeCountBaseClass(team,2)));
  6623. trap_Cvar_Set("ui_jedi_cnt", va("%d", BG_SiegeCountBaseClass(team,3)));
  6624. trap_Cvar_Set("ui_demo_cnt", va("%d", BG_SiegeCountBaseClass(team,4)));
  6625. trap_Cvar_Set("ui_heavy_cnt", va("%d", BG_SiegeCountBaseClass(team,5)));*/
  6626. //[/SIEGECVARFIX]
  6627. }
  6628. void UI_ClampMaxPlayers(void)
  6629. {
  6630. char buf[32];
  6631. // min checks
  6632. //
  6633. if( uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_DUEL ) //DUEL
  6634. {
  6635. if( trap_Cvar_VariableValue("sv_maxClients") < 2 )
  6636. {
  6637. trap_Cvar_Set("sv_maxClients", "2");
  6638. }
  6639. }
  6640. else if( uiInfo.gameTypes[ui_netGameType.integer].gtEnum == GT_POWERDUEL ) // POWER DUEL
  6641. {
  6642. if( trap_Cvar_VariableValue("sv_maxClients") < 3 )
  6643. {
  6644. trap_Cvar_Set("sv_maxClients", "3");
  6645. }
  6646. }
  6647. // max check for all game types
  6648. if( trap_Cvar_VariableValue("sv_maxClients") > MAX_CLIENTS )
  6649. {
  6650. sprintf(buf,"%d",MAX_CLIENTS);
  6651. trap_Cvar_Set("sv_maxClients", buf);
  6652. }
  6653. }
  6654. void UI_UpdateSiegeStatusIcons(void)
  6655. {
  6656. menuDef_t *menu = Menu_GetFocused();
  6657. int i;
  6658. menu = Menu_GetFocused(); // Get current menu
  6659. if (!menu)
  6660. {
  6661. return;
  6662. }
  6663. for (i=0;i<7;i++)
  6664. {
  6665. Menu_SetItemBackground(menu,va("wpnicon0%d",i), va("*ui_class_weapon%d",i));
  6666. }
  6667. for (i=0;i<7;i++)
  6668. {
  6669. Menu_SetItemBackground(menu,va("itemicon0%d",i), va("*ui_class_item%d",i));
  6670. }
  6671. for (i=0;i<10;i++)
  6672. {
  6673. Menu_SetItemBackground(menu,va("forceicon0%d",i), va("*ui_class_power%d",i));
  6674. }
  6675. for (i=10;i<15;i++)
  6676. {
  6677. Menu_SetItemBackground(menu,va("forceicon%d",i), va("*ui_class_power%d",i));
  6678. }
  6679. }
  6680. /*
  6681. ==================
  6682. UI_MapCountByGameType
  6683. ==================
  6684. */
  6685. static int UI_MapCountByGameType(qboolean singlePlayer) {
  6686. int i, c, game;
  6687. c = 0;
  6688. game = singlePlayer ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : uiInfo.gameTypes[ui_netGameType.integer].gtEnum;
  6689. //[CoOp]
  6690. /* we want CoOp to show up in the menus too.
  6691. if (game == GT_SINGLE_PLAYER) {
  6692. game++;
  6693. }
  6694. */
  6695. //[/CoOp]
  6696. //[Asteroids]
  6697. //RACC - Asteroids makes this no longer always true so require seperate tags from now on.
  6698. /*
  6699. if (game == GT_TEAM) {
  6700. game = GT_FFA;
  6701. }
  6702. */
  6703. //[/Asteroids]
  6704. //[OLDGAMETYPES]
  6705. //Since GT_CTY uses the same entities as CTF, use the same map sets
  6706. if (game == GT_CTY)
  6707. {
  6708. game = GT_CTF;
  6709. }
  6710. //This isn't true for GT_HOLOCRON and GT_JEDIMASTER. Require each gametype to be listed in the arena file for them to work.
  6711. /*
  6712. if (game == GT_HOLOCRON || game == GT_JEDIMASTER) {
  6713. game = GT_FFA;
  6714. */
  6715. //[/OLDGAMETYPES]
  6716. for (i = 0; i < uiInfo.mapCount; i++) {
  6717. uiInfo.mapList[i].active = qfalse;
  6718. if ( uiInfo.mapList[i].typeBits & (1 << game)) {
  6719. if (singlePlayer) {
  6720. if (!(uiInfo.mapList[i].typeBits & (1 << GT_SINGLE_PLAYER))) {
  6721. continue;
  6722. }
  6723. }
  6724. c++;
  6725. uiInfo.mapList[i].active = qtrue;
  6726. }
  6727. }
  6728. return c;
  6729. }
  6730. qboolean UI_hasSkinForBase(const char *base, const char *team) {
  6731. char test[1024];
  6732. fileHandle_t f;
  6733. Com_sprintf( test, sizeof( test ), "models/players/%s/%s/lower_default.skin", base, team );
  6734. trap_FS_FOpenFile(test, &f, FS_READ);
  6735. if (f != 0) {
  6736. trap_FS_FCloseFile(f);
  6737. return qtrue;
  6738. }
  6739. Com_sprintf( test, sizeof( test ), "models/players/characters/%s/%s/lower_default.skin", base, team );
  6740. trap_FS_FOpenFile(test, &f, FS_READ);
  6741. if (f != 0) {
  6742. trap_FS_FCloseFile(f);
  6743. return qtrue;
  6744. }
  6745. return qfalse;
  6746. }
  6747. /*
  6748. ==================
  6749. UI_HeadCountByColor
  6750. ==================
  6751. */
  6752. static int UI_HeadCountByColor() {
  6753. int i, c;
  6754. char *teamname;
  6755. c = 0;
  6756. switch(uiSkinColor)
  6757. {
  6758. case TEAM_BLUE:
  6759. teamname = "/blue";
  6760. break;
  6761. case TEAM_RED:
  6762. teamname = "/red";
  6763. break;
  6764. default:
  6765. teamname = "/default";
  6766. }
  6767. // Count each head with this color
  6768. for (i=0; i<uiInfo.q3HeadCount; i++)
  6769. {
  6770. if (uiInfo.q3HeadNames[i] && strstr(uiInfo.q3HeadNames[i], teamname))
  6771. {
  6772. c++;
  6773. }
  6774. }
  6775. return c;
  6776. }
  6777. /*
  6778. ==================
  6779. UI_InsertServerIntoDisplayList
  6780. ==================
  6781. */
  6782. static void UI_InsertServerIntoDisplayList(int num, int position) {
  6783. int i;
  6784. if (position < 0 || position > uiInfo.serverStatus.numDisplayServers ) {
  6785. return;
  6786. }
  6787. //
  6788. uiInfo.serverStatus.numDisplayServers++;
  6789. for (i = uiInfo.serverStatus.numDisplayServers; i > position; i--) {
  6790. uiInfo.serverStatus.displayServers[i] = uiInfo.serverStatus.displayServers[i-1];
  6791. }
  6792. uiInfo.serverStatus.displayServers[position] = num;
  6793. }
  6794. /*
  6795. ==================
  6796. UI_RemoveServerFromDisplayList
  6797. ==================
  6798. */
  6799. static void UI_RemoveServerFromDisplayList(int num) {
  6800. int i, j;
  6801. for (i = 0; i < uiInfo.serverStatus.numDisplayServers; i++) {
  6802. if (uiInfo.serverStatus.displayServers[i] == num) {
  6803. uiInfo.serverStatus.numDisplayServers--;
  6804. for (j = i; j < uiInfo.serverStatus.numDisplayServers; j++) {
  6805. uiInfo.serverStatus.displayServers[j] = uiInfo.serverStatus.displayServers[j+1];
  6806. }
  6807. return;
  6808. }
  6809. }
  6810. }
  6811. /*
  6812. ==================
  6813. UI_BinaryServerInsertion
  6814. ==================
  6815. */
  6816. static void UI_BinaryServerInsertion(int num) {
  6817. int mid, offset, res, len;
  6818. // use binary search to insert server
  6819. len = uiInfo.serverStatus.numDisplayServers;
  6820. mid = len;
  6821. offset = 0;
  6822. res = 0;
  6823. while(mid > 0) {
  6824. mid = len >> 1;
  6825. //
  6826. res = trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey,
  6827. uiInfo.serverStatus.sortDir, num, uiInfo.serverStatus.displayServers[offset+mid]);
  6828. // if equal
  6829. if (res == 0) {
  6830. UI_InsertServerIntoDisplayList(num, offset+mid);
  6831. return;
  6832. }
  6833. // if larger
  6834. else if (res == 1) {
  6835. offset += mid;
  6836. len -= mid;
  6837. }
  6838. // if smaller
  6839. else {
  6840. len -= mid;
  6841. }
  6842. }
  6843. if (res == 1) {
  6844. offset++;
  6845. }
  6846. UI_InsertServerIntoDisplayList(num, offset);
  6847. }
  6848. /*
  6849. ==================
  6850. UI_BuildServerDisplayList
  6851. ==================
  6852. */
  6853. static void UI_BuildServerDisplayList(qboolean force) {
  6854. int i, count, clients, maxClients, ping, game, len/*, visible*/;
  6855. char info[MAX_STRING_CHARS];
  6856. // qboolean startRefresh = qtrue; TTimo: unused
  6857. static int numinvisible;
  6858. if (!(force || uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh)) {
  6859. return;
  6860. }
  6861. // if we shouldn't reset
  6862. if ( force == 2 ) {
  6863. force = 0;
  6864. }
  6865. // do motd updates here too
  6866. trap_Cvar_VariableStringBuffer( "cl_motdString", uiInfo.serverStatus.motd, sizeof(uiInfo.serverStatus.motd) );
  6867. len = strlen(uiInfo.serverStatus.motd);
  6868. if (len == 0) {
  6869. strcpy(uiInfo.serverStatus.motd, "Welcome to Jedi Academy MP!");
  6870. len = strlen(uiInfo.serverStatus.motd);
  6871. }
  6872. if (len != uiInfo.serverStatus.motdLen) {
  6873. uiInfo.serverStatus.motdLen = len;
  6874. uiInfo.serverStatus.motdWidth = -1;
  6875. }
  6876. if (force) {
  6877. numinvisible = 0;
  6878. // clear number of displayed servers
  6879. uiInfo.serverStatus.numDisplayServers = 0;
  6880. uiInfo.serverStatus.numPlayersOnServers = 0;
  6881. // set list box index to zero
  6882. Menu_SetFeederSelection(NULL, FEEDER_SERVERS, 0, NULL);
  6883. // mark all servers as visible so we store ping updates for them
  6884. trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue);
  6885. }
  6886. // get the server count (comes from the master)
  6887. count = trap_LAN_GetServerCount(ui_netSource.integer);
  6888. if (count == -1 || (ui_netSource.integer == AS_LOCAL && count == 0) ) {
  6889. // still waiting on a response from the master
  6890. uiInfo.serverStatus.numDisplayServers = 0;
  6891. uiInfo.serverStatus.numPlayersOnServers = 0;
  6892. uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 500;
  6893. return;
  6894. }
  6895. // visible = qfalse;
  6896. for (i = 0; i < count; i++) {
  6897. // if we already got info for this server
  6898. if (!trap_LAN_ServerIsVisible(ui_netSource.integer, i)) {
  6899. continue;
  6900. }
  6901. // visible = qtrue;
  6902. // get the ping for this server
  6903. ping = trap_LAN_GetServerPing(ui_netSource.integer, i);
  6904. if (ping > 0 || ui_netSource.integer == AS_FAVORITES) {
  6905. trap_LAN_GetServerInfo(ui_netSource.integer, i, info, MAX_STRING_CHARS);
  6906. clients = atoi(Info_ValueForKey(info, "clients"));
  6907. uiInfo.serverStatus.numPlayersOnServers += clients;
  6908. if (ui_browserShowEmpty.integer == 0) {
  6909. if (clients == 0) {
  6910. trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
  6911. continue;
  6912. }
  6913. }
  6914. if (ui_browserShowFull.integer == 0) {
  6915. maxClients = atoi(Info_ValueForKey(info, "sv_maxclients"));
  6916. if (clients == maxClients) {
  6917. trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
  6918. continue;
  6919. }
  6920. }
  6921. if (uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum != -1) {
  6922. game = atoi(Info_ValueForKey(info, "gametype"));
  6923. if (game != uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum) {
  6924. trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
  6925. continue;
  6926. }
  6927. }
  6928. //[SERVERFILTERS]
  6929. // removed the ui_serverFilterType check to allow our first filter to be for OJP servers.
  6930. if (Q_stricmp(Info_ValueForKey(info, "game"), serverFilters[ui_serverFilterType.integer].basedir) != 0) {
  6931. trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
  6932. continue;
  6933. }
  6934. /*
  6935. if (ui_serverFilterType.integer > 0) {
  6936. if (Q_stricmp(Info_ValueForKey(info, "game"), serverFilters[ui_serverFilterType.integer].basedir) != 0) {
  6937. trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
  6938. continue;
  6939. }
  6940. }
  6941. */
  6942. //[/SERVERFILTERS]
  6943. // make sure we never add a favorite server twice
  6944. if (ui_netSource.integer == AS_FAVORITES) {
  6945. UI_RemoveServerFromDisplayList(i);
  6946. }
  6947. // insert the server into the list
  6948. UI_BinaryServerInsertion(i);
  6949. // done with this server
  6950. if (ping > 0) {
  6951. trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
  6952. numinvisible++;
  6953. }
  6954. }
  6955. }
  6956. uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime;
  6957. // if there were no servers visible for ping updates
  6958. // if (!visible) {
  6959. // UI_StopServerRefresh();
  6960. // uiInfo.serverStatus.nextDisplayRefresh = 0;
  6961. // }
  6962. }
  6963. typedef struct
  6964. {
  6965. char *name, *altName;
  6966. } serverStatusCvar_t;
  6967. serverStatusCvar_t serverStatusCvars[] = {
  6968. {"sv_hostname", "Name"},
  6969. {"Address", ""},
  6970. {"gamename", "Game name"},
  6971. {"g_gametype", "Game type"},
  6972. {"mapname", "Map"},
  6973. {"version", ""},
  6974. {"protocol", ""},
  6975. {"timelimit", ""},
  6976. {"fraglimit", ""},
  6977. {NULL, NULL}
  6978. };
  6979. /*
  6980. ==================
  6981. UI_SortServerStatusInfo
  6982. ==================
  6983. */
  6984. static void UI_SortServerStatusInfo( serverStatusInfo_t *info ) {
  6985. int i, j, index;
  6986. char *tmp1, *tmp2;
  6987. // FIXME: if "gamename" == "base" or "missionpack" then
  6988. // replace the gametype number by FFA, CTF etc.
  6989. //
  6990. index = 0;
  6991. for (i = 0; serverStatusCvars[i].name; i++) {
  6992. for (j = 0; j < info->numLines; j++) {
  6993. if ( !info->lines[j][1] || info->lines[j][1][0] ) {
  6994. continue;
  6995. }
  6996. if ( !Q_stricmp(serverStatusCvars[i].name, info->lines[j][0]) ) {
  6997. // swap lines
  6998. tmp1 = info->lines[index][0];
  6999. tmp2 = info->lines[index][3];
  7000. info->lines[index][0] = info->lines[j][0];
  7001. info->lines[index][3] = info->lines[j][3];
  7002. info->lines[j][0] = tmp1;
  7003. info->lines[j][3] = tmp2;
  7004. //
  7005. if ( strlen(serverStatusCvars[i].altName) ) {
  7006. info->lines[index][0] = serverStatusCvars[i].altName;
  7007. }
  7008. index++;
  7009. }
  7010. }
  7011. }
  7012. }
  7013. /*
  7014. ==================
  7015. UI_CheckPassword
  7016. ==================
  7017. */
  7018. static qboolean UI_CheckPassword( void )
  7019. {
  7020. static char info[MAX_STRING_CHARS];
  7021. int index = uiInfo.serverStatus.currentServer;
  7022. if( (index < 0) || (index >= uiInfo.serverStatus.numDisplayServers) )
  7023. { // warning?
  7024. return qfalse;
  7025. }
  7026. trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
  7027. if ( atoi(Info_ValueForKey(info, "needpass")) )
  7028. {
  7029. Menus_OpenByName("password_request");
  7030. return qfalse;
  7031. }
  7032. // This isn't going to make it (too late in dev), like James said I should check to see when we receive
  7033. // a packet *if* we do indeed get a 0 ping just make it 1 so then a 0 ping is guaranteed to be bad
  7034. /*
  7035. // also check ping!
  7036. ping = atoi(Info_ValueForKey(info, "ping"));
  7037. // NOTE : PING -- it's very questionable as to whether a ping of < 0 or <= 0 indicates a bad server
  7038. // what I do know, is that getting "ping" from the ServerInfo on a bad server returns 0.
  7039. // So I'm left with no choice but to not allow you to enter a server with a ping of 0
  7040. if( ping <= 0 )
  7041. {
  7042. Menus_OpenByName("bad_server");
  7043. return qfalse;
  7044. }
  7045. */
  7046. return qtrue;
  7047. }
  7048. /*
  7049. ==================
  7050. UI_JoinServer
  7051. ==================
  7052. */
  7053. static void UI_JoinServer( void )
  7054. {
  7055. char buff[1024];
  7056. trap_Cvar_Set("cg_thirdPerson", "0");
  7057. trap_Cvar_Set("cg_cameraOrbit", "0");
  7058. trap_Cvar_Set("ui_singlePlayerActive", "0");
  7059. if (uiInfo.serverStatus.currentServer >= 0 && uiInfo.serverStatus.currentServer < uiInfo.serverStatus.numDisplayServers)
  7060. {
  7061. trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, 1024);
  7062. trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) );
  7063. }
  7064. }
  7065. /*
  7066. ==================
  7067. UI_CheckServerName
  7068. ==================
  7069. */
  7070. static void UI_CheckServerName( void )
  7071. {
  7072. qboolean changed = qfalse;
  7073. char hostname[MAX_INFO_STRING];
  7074. char *c = hostname;
  7075. trap_Cvar_VariableStringBuffer( "sv_hostname", hostname, MAX_INFO_STRING );
  7076. while( *c )
  7077. {
  7078. if ( (*c == '\\') || (*c == ';') || (*c == '"'))
  7079. {
  7080. *c = '.';
  7081. changed = qtrue;
  7082. }
  7083. c++;
  7084. }
  7085. if( changed )
  7086. {
  7087. trap_Cvar_Set("sv_hostname", hostname );
  7088. }
  7089. }
  7090. /*
  7091. ==================
  7092. UI_GetServerStatusInfo
  7093. ==================
  7094. */
  7095. static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) {
  7096. char *p, *score, *ping, *name;
  7097. int i, len;
  7098. if (!info) {
  7099. trap_LAN_ServerStatus( serverAddress, NULL, 0);
  7100. return qfalse;
  7101. }
  7102. memset(info, 0, sizeof(*info));
  7103. if ( trap_LAN_ServerStatus( serverAddress, info->text, sizeof(info->text)) ) {
  7104. Q_strncpyz(info->address, serverAddress, sizeof(info->address));
  7105. p = info->text;
  7106. info->numLines = 0;
  7107. info->lines[info->numLines][0] = "Address";
  7108. info->lines[info->numLines][1] = "";
  7109. info->lines[info->numLines][2] = "";
  7110. info->lines[info->numLines][3] = info->address;
  7111. info->numLines++;
  7112. // get the cvars
  7113. while (p && *p) {
  7114. p = strchr(p, '\\');
  7115. if (!p) break;
  7116. *p++ = '\0';
  7117. if (*p == '\\')
  7118. break;
  7119. info->lines[info->numLines][0] = p;
  7120. info->lines[info->numLines][1] = "";
  7121. info->lines[info->numLines][2] = "";
  7122. p = strchr(p, '\\');
  7123. if (!p) break;
  7124. *p++ = '\0';
  7125. info->lines[info->numLines][3] = p;
  7126. info->numLines++;
  7127. if (info->numLines >= MAX_SERVERSTATUS_LINES)
  7128. break;
  7129. }
  7130. // get the player list
  7131. if (info->numLines < MAX_SERVERSTATUS_LINES-3) {
  7132. // empty line
  7133. info->lines[info->numLines][0] = "";
  7134. info->lines[info->numLines][1] = "";
  7135. info->lines[info->numLines][2] = "";
  7136. info->lines[info->numLines][3] = "";
  7137. info->numLines++;
  7138. // header
  7139. info->lines[info->numLines][0] = "num";
  7140. info->lines[info->numLines][1] = "score";
  7141. info->lines[info->numLines][2] = "ping";
  7142. info->lines[info->numLines][3] = "name";
  7143. info->numLines++;
  7144. // parse players
  7145. i = 0;
  7146. len = 0;
  7147. while (p && *p) {
  7148. if (*p == '\\')
  7149. *p++ = '\0';
  7150. if (!p)
  7151. break;
  7152. score = p;
  7153. p = strchr(p, ' ');
  7154. if (!p)
  7155. break;
  7156. *p++ = '\0';
  7157. ping = p;
  7158. p = strchr(p, ' ');
  7159. if (!p)
  7160. break;
  7161. *p++ = '\0';
  7162. name = p;
  7163. Com_sprintf(&info->pings[len], sizeof(info->pings)-len, "%d", i);
  7164. info->lines[info->numLines][0] = &info->pings[len];
  7165. len += strlen(&info->pings[len]) + 1;
  7166. info->lines[info->numLines][1] = score;
  7167. info->lines[info->numLines][2] = ping;
  7168. info->lines[info->numLines][3] = name;
  7169. info->numLines++;
  7170. if (info->numLines >= MAX_SERVERSTATUS_LINES)
  7171. break;
  7172. p = strchr(p, '\\');
  7173. if (!p)
  7174. break;
  7175. *p++ = '\0';
  7176. //
  7177. i++;
  7178. }
  7179. }
  7180. UI_SortServerStatusInfo( info );
  7181. return qtrue;
  7182. }
  7183. return qfalse;
  7184. }
  7185. /*
  7186. ==================
  7187. stristr
  7188. ==================
  7189. */
  7190. static char *stristr(char *str, char *charset) {
  7191. int i;
  7192. while(*str) {
  7193. for (i = 0; charset[i] && str[i]; i++) {
  7194. if (toupper(charset[i]) != toupper(str[i])) break;
  7195. }
  7196. if (!charset[i]) return str;
  7197. str++;
  7198. }
  7199. return NULL;
  7200. }
  7201. /*
  7202. ==================
  7203. UI_BuildFindPlayerList
  7204. ==================
  7205. */
  7206. static void UI_BuildFindPlayerList(qboolean force) {
  7207. static int numFound, numTimeOuts;
  7208. int i, j, resend;
  7209. serverStatusInfo_t info;
  7210. char name[MAX_NAME_LENGTH+2];
  7211. char infoString[MAX_STRING_CHARS];
  7212. if (!force) {
  7213. if (!uiInfo.nextFindPlayerRefresh || uiInfo.nextFindPlayerRefresh > uiInfo.uiDC.realTime) {
  7214. return;
  7215. }
  7216. }
  7217. else {
  7218. memset(&uiInfo.pendingServerStatus, 0, sizeof(uiInfo.pendingServerStatus));
  7219. uiInfo.numFoundPlayerServers = 0;
  7220. uiInfo.currentFoundPlayerServer = 0;
  7221. trap_Cvar_VariableStringBuffer( "ui_findPlayer", uiInfo.findPlayerName, sizeof(uiInfo.findPlayerName));
  7222. Q_CleanStr(uiInfo.findPlayerName);
  7223. // should have a string of some length
  7224. if (!strlen(uiInfo.findPlayerName)) {
  7225. uiInfo.nextFindPlayerRefresh = 0;
  7226. return;
  7227. }
  7228. // set resend time
  7229. resend = ui_serverStatusTimeOut.integer / 2 - 10;
  7230. if (resend < 50) {
  7231. resend = 50;
  7232. }
  7233. trap_Cvar_Set("cl_serverStatusResendTime", va("%d", resend));
  7234. // reset all server status requests
  7235. trap_LAN_ServerStatus( NULL, NULL, 0);
  7236. //
  7237. uiInfo.numFoundPlayerServers = 1;
  7238. trap_SP_GetStringTextString("MENUS_SEARCHING", holdSPString, sizeof(holdSPString));
  7239. trap_Cvar_Set( "ui_playerServersFound", va( holdSPString,uiInfo.pendingServerStatus.num, numFound));
  7240. // Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
  7241. // sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
  7242. // "searching %d...", uiInfo.pendingServerStatus.num);
  7243. numFound = 0;
  7244. numTimeOuts++;
  7245. }
  7246. for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
  7247. // if this pending server is valid
  7248. if (uiInfo.pendingServerStatus.server[i].valid) {
  7249. // try to get the server status for this server
  7250. if (UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, &info ) ) {
  7251. //
  7252. numFound++;
  7253. // parse through the server status lines
  7254. for (j = 0; j < info.numLines; j++) {
  7255. // should have ping info
  7256. if ( !info.lines[j][2] || !info.lines[j][2][0] ) {
  7257. continue;
  7258. }
  7259. // clean string first
  7260. Q_strncpyz(name, info.lines[j][3], sizeof(name));
  7261. Q_CleanStr(name);
  7262. // if the player name is a substring
  7263. if (stristr(name, uiInfo.findPlayerName)) {
  7264. // add to found server list if we have space (always leave space for a line with the number found)
  7265. if (uiInfo.numFoundPlayerServers < MAX_FOUNDPLAYER_SERVERS-1) {
  7266. //
  7267. Q_strncpyz(uiInfo.foundPlayerServerAddresses[uiInfo.numFoundPlayerServers-1],
  7268. uiInfo.pendingServerStatus.server[i].adrstr,
  7269. sizeof(uiInfo.foundPlayerServerAddresses[0]));
  7270. Q_strncpyz(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
  7271. uiInfo.pendingServerStatus.server[i].name,
  7272. sizeof(uiInfo.foundPlayerServerNames[0]));
  7273. uiInfo.numFoundPlayerServers++;
  7274. }
  7275. else {
  7276. // can't add any more so we're done
  7277. uiInfo.pendingServerStatus.num = uiInfo.serverStatus.numDisplayServers;
  7278. }
  7279. }
  7280. }
  7281. trap_SP_GetStringTextString("MENUS_SEARCHING", holdSPString, sizeof(holdSPString));
  7282. trap_Cvar_Set( "ui_playerServersFound", va( holdSPString,uiInfo.pendingServerStatus.num, numFound));
  7283. // Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
  7284. // sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
  7285. // "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound);
  7286. // retrieved the server status so reuse this spot
  7287. uiInfo.pendingServerStatus.server[i].valid = qfalse;
  7288. }
  7289. }
  7290. // if empty pending slot or timed out
  7291. if (!uiInfo.pendingServerStatus.server[i].valid ||
  7292. uiInfo.pendingServerStatus.server[i].startTime < uiInfo.uiDC.realTime - ui_serverStatusTimeOut.integer) {
  7293. if (uiInfo.pendingServerStatus.server[i].valid) {
  7294. numTimeOuts++;
  7295. }
  7296. // reset server status request for this address
  7297. UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, NULL );
  7298. // reuse pending slot
  7299. uiInfo.pendingServerStatus.server[i].valid = qfalse;
  7300. // if we didn't try to get the status of all servers in the main browser yet
  7301. if (uiInfo.pendingServerStatus.num < uiInfo.serverStatus.numDisplayServers) {
  7302. uiInfo.pendingServerStatus.server[i].startTime = uiInfo.uiDC.realTime;
  7303. trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num],
  7304. uiInfo.pendingServerStatus.server[i].adrstr, sizeof(uiInfo.pendingServerStatus.server[i].adrstr));
  7305. trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], infoString, sizeof(infoString));
  7306. Q_strncpyz(uiInfo.pendingServerStatus.server[i].name, Info_ValueForKey(infoString, "hostname"), sizeof(uiInfo.pendingServerStatus.server[0].name));
  7307. uiInfo.pendingServerStatus.server[i].valid = qtrue;
  7308. uiInfo.pendingServerStatus.num++;
  7309. trap_SP_GetStringTextString("MENUS_SEARCHING", holdSPString, sizeof(holdSPString));
  7310. trap_Cvar_Set( "ui_playerServersFound", va( holdSPString,uiInfo.pendingServerStatus.num, numFound));
  7311. // Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
  7312. // sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
  7313. // "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound);
  7314. }
  7315. }
  7316. }
  7317. for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
  7318. if (uiInfo.pendingServerStatus.server[i].valid) {
  7319. break;
  7320. }
  7321. }
  7322. // if still trying to retrieve server status info
  7323. if (i < MAX_SERVERSTATUSREQUESTS) {
  7324. uiInfo.nextFindPlayerRefresh = uiInfo.uiDC.realTime + 25;
  7325. }
  7326. else {
  7327. // add a line that shows the number of servers found
  7328. if (!uiInfo.numFoundPlayerServers)
  7329. {
  7330. Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]), "no servers found");
  7331. }
  7332. else
  7333. {
  7334. trap_SP_GetStringTextString("MENUS_SERVERS_FOUNDWITH", holdSPString, sizeof(holdSPString));
  7335. trap_Cvar_Set( "ui_playerServersFound", va( holdSPString,
  7336. uiInfo.numFoundPlayerServers-1,
  7337. uiInfo.numFoundPlayerServers == 2 ? "":"s",
  7338. uiInfo.findPlayerName) );
  7339. }
  7340. uiInfo.nextFindPlayerRefresh = 0;
  7341. // show the server status info for the selected server
  7342. UI_FeederSelection(FEEDER_FINDPLAYER, uiInfo.currentFoundPlayerServer, NULL);
  7343. }
  7344. }
  7345. /*
  7346. ==================
  7347. UI_BuildServerStatus
  7348. ==================
  7349. */
  7350. static void UI_BuildServerStatus(qboolean force) {
  7351. if (uiInfo.nextFindPlayerRefresh) {
  7352. return;
  7353. }
  7354. if (!force) {
  7355. if (!uiInfo.nextServerStatusRefresh || uiInfo.nextServerStatusRefresh > uiInfo.uiDC.realTime) {
  7356. return;
  7357. }
  7358. }
  7359. else {
  7360. Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
  7361. uiInfo.serverStatusInfo.numLines = 0;
  7362. // reset all server status requests
  7363. trap_LAN_ServerStatus( NULL, NULL, 0);
  7364. }
  7365. if (uiInfo.serverStatus.currentServer < 0 || uiInfo.serverStatus.currentServer > uiInfo.serverStatus.numDisplayServers || uiInfo.serverStatus.numDisplayServers == 0) {
  7366. return;
  7367. }
  7368. if (UI_GetServerStatusInfo( uiInfo.serverStatusAddress, &uiInfo.serverStatusInfo ) ) {
  7369. uiInfo.nextServerStatusRefresh = 0;
  7370. UI_GetServerStatusInfo( uiInfo.serverStatusAddress, NULL );
  7371. }
  7372. else {
  7373. uiInfo.nextServerStatusRefresh = uiInfo.uiDC.realTime + 500;
  7374. }
  7375. }
  7376. int UI_SiegeClassNum(siegeClass_t *scl)
  7377. {
  7378. int i = 0;
  7379. while (i < bgNumSiegeClasses)
  7380. {
  7381. if (&bgSiegeClasses[i] == scl)
  7382. {
  7383. return i;
  7384. }
  7385. i++;
  7386. }
  7387. return 0;
  7388. }
  7389. void UI_SetSiegeTeams(void)
  7390. {
  7391. char info[MAX_INFO_VALUE];
  7392. char *mapname = NULL;
  7393. char levelname[MAX_QPATH];
  7394. char btime[1024];
  7395. char teams[2048];
  7396. char teamInfo[MAX_SIEGE_INFO_SIZE];
  7397. char team1[1024];
  7398. char team2[1024];
  7399. int len = 0;
  7400. int gametype;
  7401. fileHandle_t f;
  7402. //Get the map name from the server info
  7403. if (trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ))
  7404. {
  7405. mapname = Info_ValueForKey( info, "mapname" );
  7406. }
  7407. if (!mapname || !mapname[0])
  7408. {
  7409. return;
  7410. }
  7411. gametype = atoi(Info_ValueForKey(info, "g_gametype"));
  7412. //If the server we are connected to is not siege we cannot choose a class anyway
  7413. if (gametype != GT_SIEGE)
  7414. {
  7415. return;
  7416. }
  7417. Com_sprintf(levelname, sizeof(levelname), "maps/%s.siege", mapname);
  7418. if (!levelname || !levelname[0])
  7419. {
  7420. return;
  7421. }
  7422. len = trap_FS_FOpenFile(levelname, &f, FS_READ);
  7423. if (!f || len >= MAX_SIEGE_INFO_SIZE)
  7424. {
  7425. return;
  7426. }
  7427. trap_FS_Read(siege_info, len, f);
  7428. siege_info[len] = 0; //ensure null terminated
  7429. trap_FS_FCloseFile(f);
  7430. //Found the .siege file
  7431. if (BG_SiegeGetValueGroup(siege_info, "Teams", teams))
  7432. {
  7433. char buf[1024];
  7434. //[SIEGECVARFIX]
  7435. siege_Cvar_VariableStringBuffer("cg_siegeTeam1", buf, 1024);
  7436. //trap_Cvar_VariableStringBuffer("cg_siegeTeam1", buf, 1024);
  7437. //[/SIEGECVARFIX]
  7438. if (buf[0] && Q_stricmp(buf, "none"))
  7439. {
  7440. strcpy(team1, buf);
  7441. }
  7442. else
  7443. {
  7444. BG_SiegeGetPairedValue(teams, "team1", team1);
  7445. }
  7446. //[SIEGECVARFIX]
  7447. siege_Cvar_VariableStringBuffer("cg_siegeTeam2", buf, 1024);
  7448. //trap_Cvar_VariableStringBuffer("cg_siegeTeam2", buf, 1024);
  7449. //[/SIEGECVARFIX]
  7450. if (buf[0] && Q_stricmp(buf, "none"))
  7451. {
  7452. strcpy(team2, buf);
  7453. }
  7454. else
  7455. {
  7456. BG_SiegeGetPairedValue(teams, "team2", team2);
  7457. }
  7458. }
  7459. else
  7460. {
  7461. return;
  7462. }
  7463. //Set the team themes so we know what classes to make available for selection
  7464. if (BG_SiegeGetValueGroup(siege_info, team1, teamInfo))
  7465. {
  7466. if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
  7467. {
  7468. BG_SiegeSetTeamTheme(SIEGETEAM_TEAM1, btime);
  7469. }
  7470. }
  7471. if (BG_SiegeGetValueGroup(siege_info, team2, teamInfo))
  7472. {
  7473. if (BG_SiegeGetPairedValue(teamInfo, "UseTeam", btime))
  7474. {
  7475. BG_SiegeSetTeamTheme(SIEGETEAM_TEAM2, btime);
  7476. }
  7477. }
  7478. siegeTeam1 = BG_SiegeFindThemeForTeam(SIEGETEAM_TEAM1);
  7479. siegeTeam2 = BG_SiegeFindThemeForTeam(SIEGETEAM_TEAM2);
  7480. //set the default description for the default selection
  7481. if (!siegeTeam1 || !siegeTeam1->classes[0])
  7482. {
  7483. Com_Error(ERR_DROP, "Error loading teams in UI");
  7484. }
  7485. Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM1, 0, NULL);
  7486. Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM2, -1, NULL);
  7487. }
  7488. /*
  7489. ==================
  7490. UI_FeederCount
  7491. ==================
  7492. */
  7493. //[DynamicMemory_Sabers]
  7494. int UI_GetSaberCount(qboolean TwoHanded);
  7495. //[/DynamicMemory_Sabers]
  7496. static int UI_FeederCount(float feederID)
  7497. {
  7498. int team,baseClass,count=0,i;
  7499. static char info[MAX_STRING_CHARS];
  7500. switch ( (int)feederID )
  7501. {
  7502. case FEEDER_SABER_SINGLE_INFO:
  7503. //[DynamicMemory_Sabers]
  7504. /*
  7505. for (i=0;i<MAX_SABER_HILTS;i++)
  7506. {
  7507. if (saberSingleHiltInfo[i])
  7508. {
  7509. count++;
  7510. }
  7511. else
  7512. {//done
  7513. break;
  7514. }
  7515. }
  7516. return count;
  7517. */
  7518. return UI_GetSaberCount(qfalse);
  7519. //[/DynamicMemory_Sabers]
  7520. case FEEDER_SABER_STAFF_INFO:
  7521. //[DynamicMemory_Sabers]
  7522. /*
  7523. for (i=0;i<MAX_SABER_HILTS;i++)
  7524. {
  7525. if (saberStaffHiltInfo[i])
  7526. {
  7527. count++;
  7528. }
  7529. else
  7530. {//done
  7531. break;
  7532. }
  7533. }
  7534. return count;
  7535. */
  7536. return UI_GetSaberCount(qtrue);
  7537. //[/DynamicMemory_Sabers]
  7538. case FEEDER_Q3HEADS:
  7539. return UI_HeadCountByColor();
  7540. case FEEDER_SIEGE_TEAM1:
  7541. if (!siegeTeam1)
  7542. {
  7543. UI_SetSiegeTeams();
  7544. if (!siegeTeam1)
  7545. {
  7546. return 0;
  7547. }
  7548. }
  7549. return siegeTeam1->numClasses;
  7550. case FEEDER_SIEGE_TEAM2:
  7551. if (!siegeTeam2)
  7552. {
  7553. UI_SetSiegeTeams();
  7554. if (!siegeTeam2)
  7555. {
  7556. return 0;
  7557. }
  7558. }
  7559. return siegeTeam2->numClasses;
  7560. case FEEDER_FORCECFG:
  7561. if (uiForceSide == FORCE_LIGHTSIDE)
  7562. {
  7563. return uiInfo.forceConfigCount-uiInfo.forceConfigLightIndexBegin;
  7564. }
  7565. else
  7566. {
  7567. return uiInfo.forceConfigLightIndexBegin+1;
  7568. }
  7569. //return uiInfo.forceConfigCount;
  7570. case FEEDER_CINEMATICS:
  7571. return uiInfo.movieCount;
  7572. case FEEDER_MAPS:
  7573. case FEEDER_ALLMAPS:
  7574. return UI_MapCountByGameType(feederID == FEEDER_MAPS ? qtrue : qfalse);
  7575. case FEEDER_SERVERS:
  7576. return uiInfo.serverStatus.numDisplayServers;
  7577. case FEEDER_SERVERSTATUS:
  7578. return uiInfo.serverStatusInfo.numLines;
  7579. case FEEDER_FINDPLAYER:
  7580. return uiInfo.numFoundPlayerServers;
  7581. case FEEDER_PLAYER_LIST:
  7582. if (uiInfo.uiDC.realTime > uiInfo.playerRefresh)
  7583. {
  7584. uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
  7585. UI_BuildPlayerList();
  7586. }
  7587. return uiInfo.playerCount;
  7588. case FEEDER_TEAM_LIST:
  7589. if (uiInfo.uiDC.realTime > uiInfo.playerRefresh)
  7590. {
  7591. uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
  7592. UI_BuildPlayerList();
  7593. }
  7594. return uiInfo.myTeamCount;
  7595. case FEEDER_MODS:
  7596. return uiInfo.modCount;
  7597. case FEEDER_DEMOS:
  7598. return uiInfo.demoCount;
  7599. case FEEDER_MOVES :
  7600. for (i=0;i<MAX_MOVES;i++)
  7601. {
  7602. if (datapadMoveData[uiInfo.movesTitleIndex][i].title)
  7603. {
  7604. count++;
  7605. }
  7606. }
  7607. return count;
  7608. case FEEDER_MOVES_TITLES :
  7609. return (MD_MOVE_TITLE_MAX);
  7610. case FEEDER_PLAYER_SPECIES:
  7611. return uiInfo.playerSpeciesCount;
  7612. case FEEDER_PLAYER_SKIN_HEAD:
  7613. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount;
  7614. case FEEDER_PLAYER_SKIN_TORSO:
  7615. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount;
  7616. case FEEDER_PLAYER_SKIN_LEGS:
  7617. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount;
  7618. case FEEDER_COLORCHOICES:
  7619. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount;
  7620. case FEEDER_SIEGE_BASE_CLASS:
  7621. team = (int)trap_Cvar_VariableValue("ui_team");
  7622. //[SIEGECVARFIX]
  7623. baseClass = (int)siege_Cvar_VariableValue("ui_siege_class");
  7624. //baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
  7625. //[/SIEGECVARFIX]
  7626. if ((team == SIEGETEAM_TEAM1) ||
  7627. (team == SIEGETEAM_TEAM2))
  7628. {
  7629. // Is it a valid base class?
  7630. if ((baseClass >= SPC_INFANTRY) && (baseClass < SPC_MAX))
  7631. {
  7632. return (BG_SiegeCountBaseClass( team, baseClass ));
  7633. }
  7634. }
  7635. return 0;
  7636. // Get the count of weapons
  7637. case FEEDER_SIEGE_CLASS_WEAPONS:
  7638. //count them up
  7639. for (i=0;i< WP_NUM_WEAPONS;i++)
  7640. {
  7641. //[SIEGECVARFIX]
  7642. siege_Cvar_VariableStringBuffer( va("ui_class_weapon%i", i), info, sizeof(info) );
  7643. //trap_Cvar_VariableStringBuffer( va("ui_class_weapon%i", i), info, sizeof(info) );
  7644. //[/SIEGECVARFIX]
  7645. if (stricmp(info,"gfx/2d/select")!=0)
  7646. {
  7647. count++;
  7648. }
  7649. }
  7650. return count;
  7651. // Get the count of inventory
  7652. case FEEDER_SIEGE_CLASS_INVENTORY:
  7653. //count them up
  7654. for (i=0;i< HI_NUM_HOLDABLE;i++)
  7655. {
  7656. //[SIEGECVARFIX]
  7657. siege_Cvar_VariableStringBuffer( va("ui_class_item%i", i), info, sizeof(info) );
  7658. //trap_Cvar_VariableStringBuffer( va("ui_class_item%i", i), info, sizeof(info) );
  7659. //[/SIEGECVARFIX]
  7660. // A hack so health and ammo dispenser icons don't show up.
  7661. if ((stricmp(info,"gfx/2d/select")!=0) && (stricmp(info,"gfx/hud/i_icon_healthdisp")!=0) &&
  7662. (stricmp(info,"gfx/hud/i_icon_ammodisp")!=0))
  7663. {
  7664. count++;
  7665. }
  7666. }
  7667. return count;
  7668. // Get the count of force powers
  7669. case FEEDER_SIEGE_CLASS_FORCE:
  7670. //count them up
  7671. for (i=0;i< NUM_FORCE_POWERS;i++)
  7672. {
  7673. //[SIEGECVARFIX]
  7674. siege_Cvar_VariableStringBuffer( va("ui_class_power%i", i), info, sizeof(info) );
  7675. //trap_Cvar_VariableStringBuffer( va("ui_class_power%i", i), info, sizeof(info) );
  7676. //[/SIEGECVARFIX]
  7677. if (stricmp(info,"gfx/2d/select")!=0)
  7678. {
  7679. count++;
  7680. }
  7681. }
  7682. return count;
  7683. }
  7684. return 0;
  7685. }
  7686. static const char *UI_SelectedMap(int index, int *actual) {
  7687. int i, c;
  7688. c = 0;
  7689. *actual = 0;
  7690. for (i = 0; i < uiInfo.mapCount; i++) {
  7691. if (uiInfo.mapList[i].active) {
  7692. if (c == index) {
  7693. *actual = i;
  7694. return uiInfo.mapList[i].mapName;
  7695. } else {
  7696. c++;
  7697. }
  7698. }
  7699. }
  7700. return "";
  7701. }
  7702. /*
  7703. ==================
  7704. UI_HeadCountByColor
  7705. ==================
  7706. */
  7707. static const char *UI_SelectedTeamHead(int index, int *actual) {
  7708. char *teamname;
  7709. int i,c=0;
  7710. switch(uiSkinColor)
  7711. {
  7712. case TEAM_BLUE:
  7713. teamname = "/blue";
  7714. break;
  7715. case TEAM_RED:
  7716. teamname = "/red";
  7717. break;
  7718. default:
  7719. teamname = "/default";
  7720. break;
  7721. }
  7722. // Count each head with this color
  7723. for (i=0; i<uiInfo.q3HeadCount; i++)
  7724. {
  7725. if (uiInfo.q3HeadNames[i] && strstr(uiInfo.q3HeadNames[i], teamname))
  7726. {
  7727. if (c==index)
  7728. {
  7729. *actual = i;
  7730. return uiInfo.q3HeadNames[i];
  7731. }
  7732. else
  7733. {
  7734. c++;
  7735. }
  7736. }
  7737. }
  7738. return "";
  7739. }
  7740. static int UI_GetIndexFromSelection(int actual) {
  7741. int i, c;
  7742. c = 0;
  7743. for (i = 0; i < uiInfo.mapCount; i++) {
  7744. if (uiInfo.mapList[i].active) {
  7745. if (i == actual) {
  7746. return c;
  7747. }
  7748. c++;
  7749. }
  7750. }
  7751. return 0;
  7752. }
  7753. static void UI_UpdatePendingPings() {
  7754. trap_LAN_ResetPings(ui_netSource.integer);
  7755. uiInfo.serverStatus.refreshActive = qtrue;
  7756. uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
  7757. }
  7758. static const char *UI_FeederItemText(float feederID, int index, int column,
  7759. qhandle_t *handle1, qhandle_t *handle2, qhandle_t *handle3) {
  7760. static char info[MAX_STRING_CHARS]; // don't change this size without changing the sizes inside the SaberProperName calls
  7761. static char hostname[1024];
  7762. static char clientBuff[32];
  7763. static char needPass[32];
  7764. static int lastColumn = -1;
  7765. static int lastTime = 0;
  7766. *handle1 = *handle2 = *handle3 = -1;
  7767. if (feederID == FEEDER_SABER_SINGLE_INFO)
  7768. {
  7769. //char *saberProperName=0;
  7770. //[DynamicMemory_Sabers]
  7771. UI_SaberProperNameForSaber( UI_GetSaberHiltInfo(qfalse, index), info );
  7772. //UI_SaberProperNameForSaber( saberSingleHiltInfo[index], info );
  7773. //[/DynamicMemory_Sabers]
  7774. return info;
  7775. }
  7776. else if (feederID == FEEDER_SABER_STAFF_INFO)
  7777. {
  7778. //char *saberProperName=0;
  7779. //[DynamicMemory_Sabers]
  7780. UI_SaberProperNameForSaber( UI_GetSaberHiltInfo(qtrue, index), info );
  7781. //UI_SaberProperNameForSaber( saberStaffHiltInfo[index], info );
  7782. //[/DynamicMemory_Sabers]
  7783. return info;
  7784. }
  7785. else if (feederID == FEEDER_Q3HEADS) {
  7786. int actual;
  7787. return UI_SelectedTeamHead(index, &actual);
  7788. }
  7789. else if (feederID == FEEDER_SIEGE_TEAM1)
  7790. {
  7791. return ""; //nothing I guess, the description part can cover this
  7792. /*
  7793. if (!siegeTeam1)
  7794. {
  7795. UI_SetSiegeTeams();
  7796. if (!siegeTeam1)
  7797. {
  7798. return "";
  7799. }
  7800. }
  7801. if (siegeTeam1->classes[index])
  7802. {
  7803. return siegeTeam1->classes[index]->name;
  7804. }
  7805. return "";
  7806. */
  7807. }
  7808. else if (feederID == FEEDER_SIEGE_TEAM2)
  7809. {
  7810. return ""; //nothing I guess, the description part can cover this
  7811. /*
  7812. if (!siegeTeam1)
  7813. {
  7814. UI_SetSiegeTeams();
  7815. if (!siegeTeam1)
  7816. {
  7817. return "";
  7818. }
  7819. }
  7820. if (siegeTeam2->classes[index])
  7821. {
  7822. return siegeTeam2->classes[index]->name;
  7823. }
  7824. return "";
  7825. */
  7826. }
  7827. else if (feederID == FEEDER_FORCECFG) {
  7828. if (index >= 0 && index < uiInfo.forceConfigCount) {
  7829. if (index == 0)
  7830. { //always show "custom"
  7831. return uiInfo.forceConfigNames[index];
  7832. }
  7833. else
  7834. {
  7835. if (uiForceSide == FORCE_LIGHTSIDE)
  7836. {
  7837. index += uiInfo.forceConfigLightIndexBegin;
  7838. if (index < 0)
  7839. {
  7840. return NULL;
  7841. }
  7842. if (index >= uiInfo.forceConfigCount)
  7843. {
  7844. return NULL;
  7845. }
  7846. return uiInfo.forceConfigNames[index];
  7847. }
  7848. else if (uiForceSide == FORCE_DARKSIDE)
  7849. {
  7850. index += uiInfo.forceConfigDarkIndexBegin;
  7851. if (index < 0)
  7852. {
  7853. return NULL;
  7854. }
  7855. if (index > uiInfo.forceConfigLightIndexBegin)
  7856. { //dark gets read in before light
  7857. return NULL;
  7858. }
  7859. if (index >= uiInfo.forceConfigCount)
  7860. {
  7861. return NULL;
  7862. }
  7863. return uiInfo.forceConfigNames[index];
  7864. }
  7865. else
  7866. {
  7867. return NULL;
  7868. }
  7869. }
  7870. }
  7871. } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) {
  7872. int actual;
  7873. return UI_SelectedMap(index, &actual);
  7874. } else if (feederID == FEEDER_SERVERS) {
  7875. if (index >= 0 && index < uiInfo.serverStatus.numDisplayServers) {
  7876. int ping, game;
  7877. if (lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000) {
  7878. trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
  7879. lastColumn = column;
  7880. lastTime = uiInfo.uiDC.realTime;
  7881. }
  7882. ping = atoi(Info_ValueForKey(info, "ping"));
  7883. if (ping == -1) {
  7884. // if we ever see a ping that is out of date, do a server refresh
  7885. // UI_UpdatePendingPings();
  7886. }
  7887. switch (column) {
  7888. case SORT_HOST :
  7889. if (ping <= 0) {
  7890. return Info_ValueForKey(info, "addr");
  7891. } else {
  7892. int gametype = 0;
  7893. //check for password
  7894. if ( atoi(Info_ValueForKey(info, "needpass")) )
  7895. {
  7896. *handle3 = uiInfo.uiDC.Assets.needPass;
  7897. }
  7898. //check for saberonly and restricted force powers
  7899. gametype = atoi(Info_ValueForKey(info, "gametype"));
  7900. if ( gametype != GT_JEDIMASTER )
  7901. {
  7902. qboolean saberOnly = qtrue;
  7903. qboolean restrictedForce = qfalse;
  7904. qboolean allForceDisabled = qfalse;
  7905. int wDisable, i = 0;
  7906. //check force
  7907. restrictedForce = atoi(Info_ValueForKey(info, "fdisable"));
  7908. if ( UI_AllForceDisabled( restrictedForce ) )
  7909. {//all force powers are disabled
  7910. allForceDisabled = qtrue;
  7911. *handle2 = uiInfo.uiDC.Assets.noForce;
  7912. }
  7913. else if ( restrictedForce )
  7914. {//at least one force power is disabled
  7915. *handle2 = uiInfo.uiDC.Assets.forceRestrict;
  7916. }
  7917. //check weaps
  7918. wDisable = atoi(Info_ValueForKey(info, "wdisable"));
  7919. while ( i < WP_NUM_WEAPONS )
  7920. {
  7921. if ( !(wDisable & (1 << i)) && i != WP_SABER && i != WP_NONE )
  7922. {
  7923. saberOnly = qfalse;
  7924. }
  7925. i++;
  7926. }
  7927. if ( saberOnly )
  7928. {
  7929. *handle1 = uiInfo.uiDC.Assets.saberOnly;
  7930. }
  7931. else if ( atoi(Info_ValueForKey(info, "truejedi")) != 0 )
  7932. {
  7933. if ( gametype != GT_HOLOCRON
  7934. && gametype != GT_JEDIMASTER
  7935. && !saberOnly
  7936. && !allForceDisabled )
  7937. {//truejedi is on and allowed in this mode
  7938. *handle1 = uiInfo.uiDC.Assets.trueJedi;
  7939. }
  7940. }
  7941. }
  7942. if ( ui_netSource.integer == AS_LOCAL ) {
  7943. Com_sprintf( hostname, sizeof(hostname), "%s [%s]",
  7944. Info_ValueForKey(info, "hostname"),
  7945. netnames[atoi(Info_ValueForKey(info, "nettype"))] );
  7946. return hostname;
  7947. }
  7948. else {
  7949. if (atoi(Info_ValueForKey(info, "sv_allowAnonymous")) != 0) { // anonymous server
  7950. Com_sprintf( hostname, sizeof(hostname), "(A) %s",
  7951. Info_ValueForKey(info, "hostname"));
  7952. } else {
  7953. Com_sprintf( hostname, sizeof(hostname), "%s",
  7954. Info_ValueForKey(info, "hostname"));
  7955. }
  7956. return hostname;
  7957. }
  7958. }
  7959. case SORT_MAP :
  7960. return Info_ValueForKey(info, "mapname");
  7961. case SORT_CLIENTS :
  7962. Com_sprintf( clientBuff, sizeof(clientBuff), "%s (%s)", Info_ValueForKey(info, "clients"), Info_ValueForKey(info, "sv_maxclients"));
  7963. return clientBuff;
  7964. case SORT_GAME :
  7965. game = atoi(Info_ValueForKey(info, "gametype"));
  7966. if (game >= 0 && game < numTeamArenaGameTypes) {
  7967. strcpy(needPass,teamArenaGameTypes[game]);
  7968. } else {
  7969. if (ping <= 0)
  7970. {
  7971. strcpy(needPass,"Inactive");
  7972. }
  7973. strcpy(needPass,"Unknown");
  7974. }
  7975. return needPass;
  7976. case SORT_PING :
  7977. if (ping <= 0) {
  7978. return "...";
  7979. } else {
  7980. return Info_ValueForKey(info, "ping");
  7981. }
  7982. }
  7983. }
  7984. } else if (feederID == FEEDER_SERVERSTATUS) {
  7985. if ( index >= 0 && index < uiInfo.serverStatusInfo.numLines ) {
  7986. if ( column >= 0 && column < 4 ) {
  7987. return uiInfo.serverStatusInfo.lines[index][column];
  7988. }
  7989. }
  7990. } else if (feederID == FEEDER_FINDPLAYER) {
  7991. if ( index >= 0 && index < uiInfo.numFoundPlayerServers ) {
  7992. //return uiInfo.foundPlayerServerAddresses[index];
  7993. return uiInfo.foundPlayerServerNames[index];
  7994. }
  7995. } else if (feederID == FEEDER_PLAYER_LIST) {
  7996. if (index >= 0 && index < uiInfo.playerCount) {
  7997. return uiInfo.playerNames[index];
  7998. }
  7999. } else if (feederID == FEEDER_TEAM_LIST) {
  8000. if (index >= 0 && index < uiInfo.myTeamCount) {
  8001. return uiInfo.teamNames[index];
  8002. }
  8003. } else if (feederID == FEEDER_MODS) {
  8004. if (index >= 0 && index < uiInfo.modCount) {
  8005. if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr) {
  8006. return uiInfo.modList[index].modDescr;
  8007. } else {
  8008. return uiInfo.modList[index].modName;
  8009. }
  8010. }
  8011. } else if (feederID == FEEDER_CINEMATICS) {
  8012. if (index >= 0 && index < uiInfo.movieCount) {
  8013. return uiInfo.movieList[index];
  8014. }
  8015. } else if (feederID == FEEDER_DEMOS) {
  8016. if (index >= 0 && index < uiInfo.demoCount) {
  8017. return uiInfo.demoList[index];
  8018. }
  8019. }
  8020. else if (feederID == FEEDER_MOVES)
  8021. {
  8022. return datapadMoveData[uiInfo.movesTitleIndex][index].title;
  8023. }
  8024. else if (feederID == FEEDER_MOVES_TITLES)
  8025. {
  8026. return datapadMoveTitleData[index];
  8027. }
  8028. else if (feederID == FEEDER_PLAYER_SPECIES)
  8029. {
  8030. return uiInfo.playerSpecies[index].Name;
  8031. }
  8032. else if (feederID == FEEDER_LANGUAGES)
  8033. {
  8034. return 0;
  8035. }
  8036. else if (feederID == FEEDER_COLORCHOICES)
  8037. {
  8038. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount)
  8039. {
  8040. *handle1 = trap_R_RegisterShaderNoMip( uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorShader[index]);
  8041. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorShader[index];
  8042. }
  8043. }
  8044. else if (feederID == FEEDER_PLAYER_SKIN_HEAD)
  8045. {
  8046. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount)
  8047. {
  8048. *handle1 = trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]));
  8049. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index];
  8050. }
  8051. }
  8052. else if (feederID == FEEDER_PLAYER_SKIN_TORSO)
  8053. {
  8054. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount)
  8055. {
  8056. *handle1 = trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index]));
  8057. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index];
  8058. }
  8059. }
  8060. else if (feederID == FEEDER_PLAYER_SKIN_LEGS)
  8061. {
  8062. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount)
  8063. {
  8064. *handle1 = trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index]));
  8065. return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index];
  8066. }
  8067. }
  8068. else if (feederID == FEEDER_SIEGE_BASE_CLASS)
  8069. {
  8070. return "";
  8071. }
  8072. else if (feederID == FEEDER_SIEGE_CLASS_WEAPONS)
  8073. {
  8074. return "";
  8075. }
  8076. return "";
  8077. }
  8078. static qhandle_t UI_FeederItemImage(float feederID, int index) {
  8079. int validCnt,i;
  8080. static char info[MAX_STRING_CHARS];
  8081. if (feederID == FEEDER_SABER_SINGLE_INFO)
  8082. {
  8083. return 0;
  8084. }
  8085. else if (feederID == FEEDER_SABER_STAFF_INFO)
  8086. {
  8087. return 0;
  8088. }
  8089. else if (feederID == FEEDER_Q3HEADS)
  8090. {
  8091. int actual;
  8092. UI_SelectedTeamHead(index, &actual);
  8093. index = actual;
  8094. if (index >= 0 && index < uiInfo.q3HeadCount)
  8095. { //we want it to load them as it draws them, like the TA feeder
  8096. //return uiInfo.q3HeadIcons[index];
  8097. int selModel = trap_Cvar_VariableValue("ui_selectedModelIndex");
  8098. if (selModel != -1)
  8099. {
  8100. if (uiInfo.q3SelectedHead != selModel)
  8101. {
  8102. uiInfo.q3SelectedHead = selModel;
  8103. //UI_FeederSelection(FEEDER_Q3HEADS, uiInfo.q3SelectedHead);
  8104. Menu_SetFeederSelection(NULL, FEEDER_Q3HEADS, selModel, NULL);
  8105. }
  8106. }
  8107. if (!uiInfo.q3HeadIcons[index])
  8108. { //this isn't the best way of doing this I guess, but I didn't want a whole seperate string array
  8109. //for storing shader names. I can't just replace q3HeadNames with the shader name, because we
  8110. //print what's in q3HeadNames and the icon name would look funny.
  8111. char iconNameFromSkinName[256];
  8112. int i = 0;
  8113. int skinPlace;
  8114. i = strlen(uiInfo.q3HeadNames[index]);
  8115. while (uiInfo.q3HeadNames[index][i] != '/')
  8116. {
  8117. i--;
  8118. }
  8119. i++;
  8120. skinPlace = i; //remember that this is where the skin name begins
  8121. //now, build a full path out of what's in q3HeadNames, into iconNameFromSkinName
  8122. Com_sprintf(iconNameFromSkinName, sizeof(iconNameFromSkinName), "models/players/%s", uiInfo.q3HeadNames[index]);
  8123. i = strlen(iconNameFromSkinName);
  8124. while (iconNameFromSkinName[i] != '/')
  8125. {
  8126. i--;
  8127. }
  8128. i++;
  8129. iconNameFromSkinName[i] = 0; //terminate, and append..
  8130. Q_strcat(iconNameFromSkinName, 256, "icon_");
  8131. //and now, for the final step, append the skin name from q3HeadNames onto the end of iconNameFromSkinName
  8132. i = strlen(iconNameFromSkinName);
  8133. while (uiInfo.q3HeadNames[index][skinPlace])
  8134. {
  8135. iconNameFromSkinName[i] = uiInfo.q3HeadNames[index][skinPlace];
  8136. i++;
  8137. skinPlace++;
  8138. }
  8139. iconNameFromSkinName[i] = 0;
  8140. //and now we are ready to register (thankfully this will only happen once)
  8141. uiInfo.q3HeadIcons[index] = trap_R_RegisterShaderNoMip(iconNameFromSkinName);
  8142. }
  8143. return uiInfo.q3HeadIcons[index];
  8144. }
  8145. }
  8146. else if (feederID == FEEDER_SIEGE_TEAM1)
  8147. {
  8148. if (!siegeTeam1)
  8149. {
  8150. UI_SetSiegeTeams();
  8151. if (!siegeTeam1)
  8152. {
  8153. return 0;
  8154. }
  8155. }
  8156. if (siegeTeam1->classes[index])
  8157. {
  8158. return siegeTeam1->classes[index]->uiPortraitShader;
  8159. }
  8160. return 0;
  8161. }
  8162. else if (feederID == FEEDER_SIEGE_TEAM2)
  8163. {
  8164. if (!siegeTeam2)
  8165. {
  8166. UI_SetSiegeTeams();
  8167. if (!siegeTeam2)
  8168. {
  8169. return 0;
  8170. }
  8171. }
  8172. if (siegeTeam2->classes[index])
  8173. {
  8174. return siegeTeam2->classes[index]->uiPortraitShader;
  8175. }
  8176. return 0;
  8177. }
  8178. else if (feederID == FEEDER_ALLMAPS || feederID == FEEDER_MAPS)
  8179. {
  8180. int actual;
  8181. UI_SelectedMap(index, &actual);
  8182. index = actual;
  8183. if (index >= 0 && index < uiInfo.mapCount) {
  8184. if (uiInfo.mapList[index].levelShot == -1) {
  8185. uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[index].imageName);
  8186. }
  8187. return uiInfo.mapList[index].levelShot;
  8188. }
  8189. }
  8190. else if (feederID == FEEDER_PLAYER_SKIN_HEAD)
  8191. {
  8192. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount)
  8193. {
  8194. //return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadIcons[index];
  8195. return trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]));
  8196. }
  8197. }
  8198. else if (feederID == FEEDER_PLAYER_SKIN_TORSO)
  8199. {
  8200. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount)
  8201. {
  8202. //return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoIcons[index];
  8203. return trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index]));
  8204. }
  8205. }
  8206. else if (feederID == FEEDER_PLAYER_SKIN_LEGS)
  8207. {
  8208. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount)
  8209. {
  8210. //return uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegIcons[index];
  8211. return trap_R_RegisterShaderNoMip(va("models/players/%s/icon_%s", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].Name, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index]));
  8212. }
  8213. }
  8214. else if (feederID == FEEDER_COLORCHOICES)
  8215. {
  8216. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount)
  8217. {
  8218. return trap_R_RegisterShaderNoMip( uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorShader[index]);
  8219. }
  8220. }
  8221. else if ( feederID == FEEDER_SIEGE_BASE_CLASS)
  8222. {
  8223. int team,baseClass;
  8224. team = (int)trap_Cvar_VariableValue("ui_team");
  8225. //[SIEGECVARFIX]
  8226. baseClass = (int)siege_Cvar_VariableValue("ui_siege_class");
  8227. //baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
  8228. //[/SIEGECVARFIX]
  8229. if ((team == SIEGETEAM_TEAM1) ||
  8230. (team == SIEGETEAM_TEAM2))
  8231. {
  8232. // Is it a valid base class?
  8233. if ((baseClass >= SPC_INFANTRY) && (baseClass < SPC_MAX))
  8234. {
  8235. if (index >= 0)
  8236. {
  8237. return(BG_GetUIPortrait(team, baseClass, index));
  8238. }
  8239. }
  8240. }
  8241. }
  8242. else if ( feederID == FEEDER_SIEGE_CLASS_WEAPONS)
  8243. {
  8244. validCnt = 0;
  8245. //count them up
  8246. for (i=0;i< WP_NUM_WEAPONS;i++)
  8247. {
  8248. //[SIEGECVARFIX]
  8249. siege_Cvar_VariableStringBuffer( va("ui_class_weapon%i", i), info, sizeof(info) );
  8250. //trap_Cvar_VariableStringBuffer( va("ui_class_weapon%i", i), info, sizeof(info) );
  8251. //[/SIEGECVARFIX]
  8252. if (stricmp(info,"gfx/2d/select")!=0)
  8253. {
  8254. if (validCnt == index)
  8255. {
  8256. return(trap_R_RegisterShaderNoMip(info));
  8257. }
  8258. validCnt++;
  8259. }
  8260. }
  8261. }
  8262. else if ( feederID == FEEDER_SIEGE_CLASS_INVENTORY)
  8263. {
  8264. validCnt = 0;
  8265. //count them up
  8266. for (i=0;i< HI_NUM_HOLDABLE;i++)
  8267. {
  8268. //[SIEGECVARFIX]
  8269. siege_Cvar_VariableStringBuffer( va("ui_class_item%i", i), info, sizeof(info) );
  8270. //trap_Cvar_VariableStringBuffer( va("ui_class_item%i", i), info, sizeof(info) );
  8271. //[/SIEGECVARFIX]
  8272. // A hack so health and ammo dispenser icons don't show up.
  8273. if ((stricmp(info,"gfx/2d/select")!=0) && (stricmp(info,"gfx/hud/i_icon_healthdisp")!=0) &&
  8274. (stricmp(info,"gfx/hud/i_icon_ammodisp")!=0))
  8275. {
  8276. if (validCnt == index)
  8277. {
  8278. return(trap_R_RegisterShaderNoMip(info));
  8279. }
  8280. validCnt++;
  8281. }
  8282. }
  8283. }
  8284. else if ( feederID == FEEDER_SIEGE_CLASS_FORCE)
  8285. {
  8286. int slotI=0;
  8287. static char info2[MAX_STRING_CHARS];
  8288. menuDef_t *menu;
  8289. itemDef_t *item;
  8290. validCnt = 0;
  8291. menu = Menu_GetFocused(); // Get current menu
  8292. if (menu)
  8293. {
  8294. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "base_class_force_feed");
  8295. if (item)
  8296. {
  8297. listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
  8298. if (listPtr)
  8299. {
  8300. slotI = listPtr->startPos;
  8301. }
  8302. }
  8303. }
  8304. //count them up
  8305. for (i=0;i< NUM_FORCE_POWERS;i++)
  8306. {
  8307. //[SIEGECVARFIX]
  8308. siege_Cvar_VariableStringBuffer( va("ui_class_power%i", i), info, sizeof(info) );
  8309. //trap_Cvar_VariableStringBuffer( va("ui_class_power%i", i), info, sizeof(info) );
  8310. //[/SIEGECVARFIX]
  8311. if (stricmp(info,"gfx/2d/select")!=0)
  8312. {
  8313. if (validCnt == index)
  8314. {
  8315. //[SIEGECVARFIX]
  8316. siege_Cvar_VariableStringBuffer( va("ui_class_powerlevel%i", validCnt), info2, sizeof(info2) );
  8317. //trap_Cvar_VariableStringBuffer( va("ui_class_powerlevel%i", validCnt), info2, sizeof(info2) );
  8318. siege_Cvar_Set(va("ui_class_powerlevelslot%i", index-slotI), info2);
  8319. //trap_Cvar_Set(va("ui_class_powerlevelslot%i", index-slotI), info2);
  8320. //[/SIEGECVARFIX]
  8321. return(trap_R_RegisterShaderNoMip(info));
  8322. }
  8323. validCnt++;
  8324. }
  8325. }
  8326. }
  8327. return 0;
  8328. }
  8329. //called every time a class is selected from a feeder, sets info
  8330. //for shaders to be displayed in the menu about the class -rww
  8331. extern qboolean UI_SaberTypeForSaber( const char *saberName, char *saberType );
  8332. void UI_SiegeSetCvarsForClass(siegeClass_t *scl)
  8333. {
  8334. int i = 0;
  8335. int count = 0;
  8336. char shader[MAX_QPATH];
  8337. //let's clear the things out first
  8338. while (i < WP_NUM_WEAPONS)
  8339. {
  8340. //[SIEGECVARFIX]
  8341. siege_Cvar_Set(va("ui_class_weapon%i", i), "gfx/2d/select");
  8342. //trap_Cvar_Set(va("ui_class_weapon%i", i), "gfx/2d/select");
  8343. //[/SIEGECVARFIX]
  8344. i++;
  8345. }
  8346. //now for inventory items
  8347. i = 0;
  8348. while (i < HI_NUM_HOLDABLE)
  8349. {
  8350. //[SIEGECVARFIX]
  8351. siege_Cvar_Set(va("ui_class_item%i", i), "gfx/2d/select");
  8352. //trap_Cvar_Set(va("ui_class_item%i", i), "gfx/2d/select");
  8353. //[/SIEGECVARFIX]
  8354. i++;
  8355. }
  8356. //now for force powers
  8357. i = 0;
  8358. while (i < NUM_FORCE_POWERS)
  8359. {
  8360. //[SIEGECVARFIX]
  8361. siege_Cvar_Set(va("ui_class_force%i", i), "gfx/2d/select");
  8362. //trap_Cvar_Set(va("ui_class_power%i", i), "gfx/2d/select");
  8363. //[/SIEGECVARFIX]
  8364. i++;
  8365. }
  8366. //now health and armor
  8367. trap_Cvar_Set("ui_class_health", "0");
  8368. trap_Cvar_Set("ui_class_armor", "0");
  8369. trap_Cvar_Set("ui_class_icon", "");
  8370. if (!scl)
  8371. { //no select?
  8372. return;
  8373. }
  8374. //set cvars for which weaps we have
  8375. i = 0;
  8376. //[SIEGECVARFIX]
  8377. siege_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
  8378. //trap_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
  8379. //[/SIEGECVARFIX]
  8380. while (i < WP_NUM_WEAPONS)
  8381. {
  8382. if (scl->weapons & (1<<i))
  8383. {
  8384. if (i == WP_SABER)
  8385. { //we want to see what kind of saber they have, and set the cvar based on that
  8386. char saberType[1024];
  8387. if (scl->saber1[0] &&
  8388. scl->saber2[0])
  8389. {
  8390. strcpy(saberType, "gfx/hud/w_icon_duallightsaber");
  8391. } //fixme: need saber data access on ui to determine if staff, "gfx/hud/w_icon_saberstaff"
  8392. else
  8393. {
  8394. char buf[1024];
  8395. if (scl->saber1[0] && UI_SaberTypeForSaber(scl->saber1, buf))
  8396. {
  8397. if ( !Q_stricmp( buf, "SABER_STAFF" ) )
  8398. {
  8399. strcpy(saberType, "gfx/hud/w_icon_saberstaff");
  8400. }
  8401. else
  8402. {
  8403. strcpy(saberType, "gfx/hud/w_icon_lightsaber");
  8404. }
  8405. }
  8406. else
  8407. {
  8408. strcpy(saberType, "gfx/hud/w_icon_lightsaber");
  8409. }
  8410. }
  8411. //[SIEGECVARFIX]
  8412. siege_Cvar_Set(va("ui_class_weapon%i", count), saberType);
  8413. siege_Cvar_Set(va("ui_class_weapondesc%i", count), "@MENUS_AN_ELEGANT_WEAPON_FOR");
  8414. //trap_Cvar_Set(va("ui_class_weapon%i", count), saberType);
  8415. //trap_Cvar_Set(va("ui_class_weapondesc%i", count), "@MENUS_AN_ELEGANT_WEAPON_FOR");
  8416. //[/SIEGECVARFIX]
  8417. count++;
  8418. //[SIEGECVARFIX]
  8419. siege_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
  8420. //trap_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
  8421. //[SIEGECVARFIX]
  8422. }
  8423. else
  8424. {
  8425. gitem_t *item = BG_FindItemForWeapon( i );
  8426. //[SIEGECVARFIX]
  8427. siege_Cvar_Set(va("ui_class_weapon%i", count), item->icon);
  8428. siege_Cvar_Set(va("ui_class_weapondesc%i", count), item->description);
  8429. //trap_Cvar_Set(va("ui_class_weapon%i", count), item->icon);
  8430. //trap_Cvar_Set(va("ui_class_weapondesc%i", count), item->description);
  8431. //[/SIEGECVARFIX]
  8432. count++;
  8433. //[SIEGECVARFIX]
  8434. siege_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
  8435. //trap_Cvar_Set(va("ui_class_weapondesc%i", count), " "); // Blank it out to start with
  8436. //[/SIEGECVARFIX]
  8437. }
  8438. }
  8439. i++;
  8440. }
  8441. //now for inventory items
  8442. i = 0;
  8443. count = 0;
  8444. while (i < HI_NUM_HOLDABLE)
  8445. {
  8446. if (scl->invenItems & (1<<i))
  8447. {
  8448. gitem_t *item = BG_FindItemForHoldable(i);
  8449. //[SIEGECVARFIX]
  8450. siege_Cvar_Set(va("ui_class_item%i", count), item->icon);
  8451. siege_Cvar_Set(va("ui_class_itemdesc%i", count), item->description);
  8452. //trap_Cvar_Set(va("ui_class_item%i", count), item->icon);
  8453. //trap_Cvar_Set(va("ui_class_itemdesc%i", count), item->description);
  8454. //[/SIEGECVARFIX]
  8455. count++;
  8456. }
  8457. else
  8458. {
  8459. //[SIEGECVARFIX]
  8460. siege_Cvar_Set(va("ui_class_itemdesc%i", count), " ");
  8461. //trap_Cvar_Set(va("ui_class_itemdesc%i", count), " ");
  8462. //[/SIEGECVARFIX]
  8463. }
  8464. i++;
  8465. }
  8466. //now for force powers
  8467. i = 0;
  8468. count = 0;
  8469. while (i < NUM_FORCE_POWERS)
  8470. {
  8471. //[SIEGECVARFIX]
  8472. siege_Cvar_Set(va("ui_class_powerlevel%i", i), "0"); // Zero this out to start.
  8473. //trap_Cvar_Set(va("ui_class_powerlevel%i", i), "0"); // Zero this out to start.
  8474. //[/SIEGECVARFIX]
  8475. if (i<9)
  8476. {
  8477. //[SIEGECVARFIX]
  8478. siege_Cvar_Set(va("ui_class_powerlevelslot%i", i), "0"); // Zero this out to start.
  8479. //trap_Cvar_Set(va("ui_class_powerlevelslot%i", i), "0"); // Zero this out to start.
  8480. //[/SIEGECVARFIX]
  8481. }
  8482. if (scl->forcePowerLevels[i])
  8483. {
  8484. //[SIEGECVARFIX]
  8485. siege_Cvar_Set(va("ui_class_powerlevel%i", count), va("%i",scl->forcePowerLevels[i]));
  8486. siege_Cvar_Set(va("ui_class_power%i", count), HolocronIcons[i]);
  8487. //trap_Cvar_Set(va("ui_class_powerlevel%i", count), va("%i",scl->forcePowerLevels[i]));
  8488. //trap_Cvar_Set(va("ui_class_power%i", count), HolocronIcons[i]);
  8489. //[/SIEGECVARFIX]
  8490. count++;
  8491. }
  8492. i++;
  8493. }
  8494. //now health and armor
  8495. trap_Cvar_Set("ui_class_health", va("%i", scl->maxhealth));
  8496. trap_Cvar_Set("ui_class_armor", va("%i", scl->maxarmor));
  8497. trap_Cvar_Set("ui_class_speed", va("%3.2f", scl->speed));
  8498. //now get the icon path based on the shader index
  8499. if (scl->classShader)
  8500. {
  8501. trap_R_ShaderNameFromIndex(shader, scl->classShader);
  8502. }
  8503. else
  8504. { //no shader
  8505. shader[0] = 0;
  8506. }
  8507. trap_Cvar_Set("ui_class_icon", shader);
  8508. }
  8509. int g_siegedFeederForcedSet = 0;
  8510. //[VS2005]
  8511. //VS2005's C doesn't assume int type anymore.
  8512. void UI_UpdateCvarsForClass(const int team,const int baseClass,const int index)
  8513. //void UI_UpdateCvarsForClass(const int team,const baseClass,const int index)
  8514. //[/VS2005]
  8515. {
  8516. siegeClass_t *holdClass=0;
  8517. char *holdBuf;
  8518. // Is it a valid team
  8519. if ((team == SIEGETEAM_TEAM1) ||
  8520. (team == SIEGETEAM_TEAM2))
  8521. {
  8522. // Is it a valid base class?
  8523. if ((baseClass >= SPC_INFANTRY) && (baseClass < SPC_MAX))
  8524. {
  8525. // A valid index?
  8526. if ((index>=0) && (index < BG_SiegeCountBaseClass( team, baseClass )))
  8527. {
  8528. if (!g_siegedFeederForcedSet)
  8529. {
  8530. holdClass = BG_GetClassOnBaseClass( team, baseClass, index);
  8531. if (holdClass) //clicked a valid item
  8532. {
  8533. g_UIGloballySelectedSiegeClass = UI_SiegeClassNum(holdClass);
  8534. trap_Cvar_Set("ui_classDesc", g_UIClassDescriptions[g_UIGloballySelectedSiegeClass].desc);
  8535. g_siegedFeederForcedSet = 1;
  8536. Menu_SetFeederSelection(NULL, FEEDER_SIEGE_BASE_CLASS, -1, NULL);
  8537. UI_SiegeSetCvarsForClass(holdClass);
  8538. holdBuf = BG_GetUIPortraitFile(team, baseClass, index);
  8539. if (holdBuf)
  8540. {
  8541. trap_Cvar_Set("ui_classPortrait",holdBuf);
  8542. }
  8543. }
  8544. }
  8545. g_siegedFeederForcedSet = 0;
  8546. }
  8547. else
  8548. {
  8549. trap_Cvar_Set("ui_classDesc", " ");
  8550. }
  8551. }
  8552. }
  8553. }
  8554. qboolean UI_FeederSelection(float feederFloat, int index, itemDef_t *item)
  8555. {
  8556. static char info[MAX_STRING_CHARS];
  8557. const int feederID = feederFloat;
  8558. if (feederID == FEEDER_Q3HEADS)
  8559. {
  8560. int actual;
  8561. UI_SelectedTeamHead(index, &actual);
  8562. uiInfo.q3SelectedHead = index;
  8563. trap_Cvar_Set("ui_selectedModelIndex", va("%i", index));
  8564. index = actual;
  8565. if (index >= 0 && index < uiInfo.q3HeadCount)
  8566. {
  8567. trap_Cvar_Set( "model", uiInfo.q3HeadNames[index]); //standard model
  8568. trap_Cvar_Set ( "char_color_red", "255" ); //standard colors
  8569. trap_Cvar_Set ( "char_color_green", "255" );
  8570. trap_Cvar_Set ( "char_color_blue", "255" );
  8571. }
  8572. }
  8573. else if (feederID == FEEDER_MOVES)
  8574. {
  8575. itemDef_t *item;
  8576. menuDef_t *menu;
  8577. modelDef_t *modelPtr;
  8578. menu = Menus_FindByName("rulesMenu_moves");
  8579. if (menu)
  8580. {
  8581. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
  8582. if (item)
  8583. {
  8584. modelPtr = (modelDef_t*)item->typeData;
  8585. if (modelPtr)
  8586. {
  8587. char modelPath[MAX_QPATH];
  8588. int animRunLength;
  8589. ItemParse_model_g2anim_go( item, datapadMoveData[uiInfo.movesTitleIndex][index].anim );
  8590. Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
  8591. ItemParse_asset_model_go( item, modelPath, &animRunLength );
  8592. UI_UpdateCharacterSkin();
  8593. uiInfo.moveAnimTime = uiInfo.uiDC.realTime + animRunLength;
  8594. if (datapadMoveData[uiInfo.movesTitleIndex][index].anim)
  8595. {
  8596. // Play sound for anim
  8597. if (datapadMoveData[uiInfo.movesTitleIndex][index].sound == MDS_FORCE_JUMP)
  8598. {
  8599. trap_S_StartLocalSound( uiInfo.uiDC.Assets.moveJumpSound, CHAN_LOCAL );
  8600. }
  8601. else if (datapadMoveData[uiInfo.movesTitleIndex][index].sound == MDS_ROLL)
  8602. {
  8603. trap_S_StartLocalSound( uiInfo.uiDC.Assets.moveRollSound, CHAN_LOCAL );
  8604. }
  8605. else if (datapadMoveData[uiInfo.movesTitleIndex][index].sound == MDS_SABER)
  8606. {
  8607. // Randomly choose one sound
  8608. int soundI = Q_irand( 1, 6 );
  8609. sfxHandle_t *soundPtr;
  8610. soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound1;
  8611. if (soundI == 2)
  8612. {
  8613. soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound2;
  8614. }
  8615. else if (soundI == 3)
  8616. {
  8617. soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound3;
  8618. }
  8619. else if (soundI == 4)
  8620. {
  8621. soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound4;
  8622. }
  8623. else if (soundI == 5)
  8624. {
  8625. soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound5;
  8626. }
  8627. else if (soundI == 6)
  8628. {
  8629. soundPtr = &uiInfo.uiDC.Assets.datapadmoveSaberSound6;
  8630. }
  8631. trap_S_StartLocalSound( *soundPtr, CHAN_LOCAL );
  8632. }
  8633. if (datapadMoveData[uiInfo.movesTitleIndex][index].desc)
  8634. {
  8635. trap_Cvar_Set( "ui_move_desc", datapadMoveData[uiInfo.movesTitleIndex][index].desc);
  8636. }
  8637. }
  8638. UI_SaberAttachToChar( item );
  8639. }
  8640. }
  8641. }
  8642. }
  8643. else if (feederID == FEEDER_MOVES_TITLES)
  8644. {
  8645. itemDef_t *item;
  8646. menuDef_t *menu;
  8647. modelDef_t *modelPtr;
  8648. uiInfo.movesTitleIndex = index;
  8649. uiInfo.movesBaseAnim = datapadMoveTitleBaseAnims[uiInfo.movesTitleIndex];
  8650. menu = Menus_FindByName("rulesMenu_moves");
  8651. if (menu)
  8652. {
  8653. item = (itemDef_t *) Menu_FindItemByName((menuDef_t *) menu, "character");
  8654. if (item)
  8655. {
  8656. modelPtr = (modelDef_t*)item->typeData;
  8657. if (modelPtr)
  8658. {
  8659. char modelPath[MAX_QPATH];
  8660. int animRunLength;
  8661. uiInfo.movesBaseAnim = datapadMoveTitleBaseAnims[uiInfo.movesTitleIndex];
  8662. ItemParse_model_g2anim_go( item, uiInfo.movesBaseAnim );
  8663. Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
  8664. ItemParse_asset_model_go( item, modelPath, &animRunLength );
  8665. UI_UpdateCharacterSkin();
  8666. }
  8667. }
  8668. }
  8669. }
  8670. else if (feederID == FEEDER_SIEGE_TEAM1)
  8671. {
  8672. if (!g_siegedFeederForcedSet)
  8673. {
  8674. g_UIGloballySelectedSiegeClass = UI_SiegeClassNum(siegeTeam1->classes[index]);
  8675. trap_Cvar_Set("ui_classDesc", g_UIClassDescriptions[g_UIGloballySelectedSiegeClass].desc);
  8676. //g_siegedFeederForcedSet = 1;
  8677. //Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM2, -1, NULL);
  8678. UI_SiegeSetCvarsForClass(siegeTeam1->classes[index]);
  8679. }
  8680. g_siegedFeederForcedSet = 0;
  8681. }
  8682. else if (feederID == FEEDER_SIEGE_TEAM2)
  8683. {
  8684. if (!g_siegedFeederForcedSet)
  8685. {
  8686. g_UIGloballySelectedSiegeClass = UI_SiegeClassNum(siegeTeam2->classes[index]);
  8687. trap_Cvar_Set("ui_classDesc", g_UIClassDescriptions[g_UIGloballySelectedSiegeClass].desc);
  8688. //g_siegedFeederForcedSet = 1;
  8689. //Menu_SetFeederSelection(NULL, FEEDER_SIEGE_TEAM2, -1, NULL);
  8690. UI_SiegeSetCvarsForClass(siegeTeam2->classes[index]);
  8691. }
  8692. g_siegedFeederForcedSet = 0;
  8693. }
  8694. else if (feederID == FEEDER_FORCECFG)
  8695. {
  8696. int newindex = index;
  8697. if (uiForceSide == FORCE_LIGHTSIDE)
  8698. {
  8699. newindex += uiInfo.forceConfigLightIndexBegin;
  8700. if (newindex >= uiInfo.forceConfigCount)
  8701. {
  8702. return qfalse;
  8703. }
  8704. }
  8705. else
  8706. { //else dark
  8707. newindex += uiInfo.forceConfigDarkIndexBegin;
  8708. if (newindex >= uiInfo.forceConfigCount || newindex > uiInfo.forceConfigLightIndexBegin)
  8709. { //dark gets read in before light
  8710. return qfalse;
  8711. }
  8712. }
  8713. if (index >= 0 && index < uiInfo.forceConfigCount)
  8714. {
  8715. UI_ForceConfigHandle(uiInfo.forceConfigSelected, index);
  8716. uiInfo.forceConfigSelected = index;
  8717. }
  8718. }
  8719. else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS)
  8720. {
  8721. int actual, map;
  8722. const char *checkValid = NULL;
  8723. map = (feederID == FEEDER_ALLMAPS) ? ui_currentNetMap.integer : ui_currentMap.integer;
  8724. if (uiInfo.mapList[map].cinematic >= 0) {
  8725. trap_CIN_StopCinematic(uiInfo.mapList[map].cinematic);
  8726. uiInfo.mapList[map].cinematic = -1;
  8727. }
  8728. checkValid = UI_SelectedMap(index, &actual);
  8729. if (!checkValid || !checkValid[0])
  8730. { //this isn't a valid map to select, so reselect the current
  8731. index = ui_mapIndex.integer;
  8732. UI_SelectedMap(index, &actual);
  8733. }
  8734. trap_Cvar_Set("ui_mapIndex", va("%d", index));
  8735. gUISelectedMap = index;
  8736. ui_mapIndex.integer = index;
  8737. if (feederID == FEEDER_MAPS) {
  8738. ui_currentMap.integer = actual;
  8739. trap_Cvar_Set("ui_currentMap", va("%d", actual));
  8740. 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) );
  8741. UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
  8742. //trap_Cvar_Set("ui_opponentModel", uiInfo.mapList[ui_currentMap.integer].opponentName);
  8743. //updateOpponentModel = qtrue;
  8744. } else {
  8745. ui_currentNetMap.integer = actual;
  8746. trap_Cvar_Set("ui_currentNetMap", va("%d", actual));
  8747. 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) );
  8748. }
  8749. } else if (feederID == FEEDER_SERVERS) {
  8750. const char *mapName = NULL;
  8751. uiInfo.serverStatus.currentServer = index;
  8752. trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
  8753. uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip(va("levelshots/%s", Info_ValueForKey(info, "mapname")));
  8754. if (uiInfo.serverStatus.currentServerCinematic >= 0) {
  8755. trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
  8756. uiInfo.serverStatus.currentServerCinematic = -1;
  8757. }
  8758. mapName = Info_ValueForKey(info, "mapname");
  8759. if (mapName && *mapName) {
  8760. uiInfo.serverStatus.currentServerCinematic = trap_CIN_PlayCinematic(va("%s.roq", mapName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
  8761. }
  8762. } else if (feederID == FEEDER_SERVERSTATUS) {
  8763. //
  8764. } else if (feederID == FEEDER_FINDPLAYER) {
  8765. uiInfo.currentFoundPlayerServer = index;
  8766. //
  8767. if ( index < uiInfo.numFoundPlayerServers-1) {
  8768. // build a new server status for this server
  8769. Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress));
  8770. Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
  8771. UI_BuildServerStatus(qtrue);
  8772. }
  8773. } else if (feederID == FEEDER_PLAYER_LIST) {
  8774. uiInfo.playerIndex = index;
  8775. } else if (feederID == FEEDER_TEAM_LIST) {
  8776. uiInfo.teamIndex = index;
  8777. } else if (feederID == FEEDER_MODS) {
  8778. uiInfo.modIndex = index;
  8779. } else if (feederID == FEEDER_CINEMATICS) {
  8780. uiInfo.movieIndex = index;
  8781. if (uiInfo.previewMovie >= 0) {
  8782. trap_CIN_StopCinematic(uiInfo.previewMovie);
  8783. }
  8784. uiInfo.previewMovie = -1;
  8785. } else if (feederID == FEEDER_DEMOS) {
  8786. uiInfo.demoIndex = index;
  8787. }
  8788. else if (feederID == FEEDER_COLORCHOICES)
  8789. {
  8790. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorCount)
  8791. {
  8792. Item_RunScript(item, uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].ColorActionText[index]);
  8793. }
  8794. }
  8795. else if (feederID == FEEDER_PLAYER_SKIN_HEAD)
  8796. {
  8797. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadCount)
  8798. {
  8799. trap_Cvar_Set("ui_char_skin_head", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinHeadNames[index]);
  8800. }
  8801. }
  8802. else if (feederID == FEEDER_PLAYER_SKIN_TORSO)
  8803. {
  8804. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoCount)
  8805. {
  8806. trap_Cvar_Set("ui_char_skin_torso", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinTorsoNames[index]);
  8807. }
  8808. }
  8809. else if (feederID == FEEDER_PLAYER_SKIN_LEGS)
  8810. {
  8811. if (index >= 0 && index < uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegCount)
  8812. {
  8813. trap_Cvar_Set("ui_char_skin_legs", uiInfo.playerSpecies[uiInfo.playerSpeciesIndex].SkinLegNames[index]);
  8814. }
  8815. }
  8816. else if (feederID == FEEDER_PLAYER_SPECIES)
  8817. {
  8818. uiInfo.playerSpeciesIndex = index;
  8819. }
  8820. else if (feederID == FEEDER_LANGUAGES)
  8821. {
  8822. uiInfo.languageCountIndex = index;
  8823. }
  8824. else if ( feederID == FEEDER_SIEGE_BASE_CLASS )
  8825. {
  8826. int team,baseClass;
  8827. team = (int)trap_Cvar_VariableValue("ui_team");
  8828. //[SIEGECVARFIX]
  8829. baseClass = (int)siege_Cvar_VariableValue("ui_siege_class");
  8830. //baseClass = (int)trap_Cvar_VariableValue("ui_siege_class");
  8831. //[/SIEGECVARFIX]
  8832. UI_UpdateCvarsForClass(team, baseClass, index);
  8833. }
  8834. else if (feederID == FEEDER_SIEGE_CLASS_WEAPONS)
  8835. {
  8836. // trap_Cvar_VariableStringBuffer( va("ui_class_weapondesc%i", index), info, sizeof(info) );
  8837. // trap_Cvar_Set( "ui_itemforceinvdesc", info );
  8838. }
  8839. else if (feederID == FEEDER_SIEGE_CLASS_INVENTORY)
  8840. {
  8841. // trap_Cvar_VariableStringBuffer( va("ui_class_itemdesc%i", index), info, sizeof(info) );
  8842. // trap_Cvar_Set( "ui_itemforceinvdesc", info );
  8843. }
  8844. else if (feederID == FEEDER_SIEGE_CLASS_FORCE)
  8845. {
  8846. int i;
  8847. // int validCnt = 0;
  8848. //[SIEGECVARFIX]
  8849. siege_Cvar_VariableStringBuffer( va("ui_class_power%i", index), info, sizeof(info) );
  8850. //trap_Cvar_VariableStringBuffer( va("ui_class_power%i", index), info, sizeof(info) );
  8851. //[/SIEGECVARFIX]
  8852. //count them up
  8853. for (i=0;i< NUM_FORCE_POWERS;i++)
  8854. {
  8855. if (!strcmp(HolocronIcons[i],info))
  8856. {
  8857. trap_Cvar_Set( "ui_itemforceinvdesc", forcepowerDesc[i] );
  8858. }
  8859. }
  8860. }
  8861. return qtrue;
  8862. }
  8863. static qboolean GameType_Parse(char **p, qboolean join) {
  8864. char *token;
  8865. token = COM_ParseExt((const char **)p, qtrue);
  8866. if (token[0] != '{') {
  8867. return qfalse;
  8868. }
  8869. if (join) {
  8870. uiInfo.numJoinGameTypes = 0;
  8871. } else {
  8872. uiInfo.numGameTypes = 0;
  8873. }
  8874. while ( 1 ) {
  8875. token = COM_ParseExt((const char **)p, qtrue);
  8876. if (Q_stricmp(token, "}") == 0) {
  8877. return qtrue;
  8878. }
  8879. if ( !token || token[0] == 0 ) {
  8880. return qfalse;
  8881. }
  8882. if (token[0] == '{') {
  8883. // two tokens per line, character name and sex
  8884. if (join) {
  8885. if (!String_Parse(p, &uiInfo.joinGameTypes[uiInfo.numJoinGameTypes].gameType) || !Int_Parse(p, &uiInfo.joinGameTypes[uiInfo.numJoinGameTypes].gtEnum)) {
  8886. return qfalse;
  8887. }
  8888. } else {
  8889. if (!String_Parse(p, &uiInfo.gameTypes[uiInfo.numGameTypes].gameType) || !Int_Parse(p, &uiInfo.gameTypes[uiInfo.numGameTypes].gtEnum)) {
  8890. return qfalse;
  8891. }
  8892. }
  8893. if (join) {
  8894. if (uiInfo.numJoinGameTypes < MAX_GAMETYPES) {
  8895. uiInfo.numJoinGameTypes++;
  8896. } else {
  8897. Com_Printf("Too many net game types, last one replace!\n");
  8898. }
  8899. } else {
  8900. if (uiInfo.numGameTypes < MAX_GAMETYPES) {
  8901. uiInfo.numGameTypes++;
  8902. } else {
  8903. Com_Printf("Too many game types, last one replace!\n");
  8904. }
  8905. }
  8906. token = COM_ParseExt((const char **)p, qtrue);
  8907. if (token[0] != '}') {
  8908. return qfalse;
  8909. }
  8910. }
  8911. }
  8912. return qfalse;
  8913. }
  8914. static qboolean MapList_Parse(char **p) {
  8915. char *token;
  8916. token = COM_ParseExt((const char **)p, qtrue);
  8917. if (token[0] != '{') {
  8918. return qfalse;
  8919. }
  8920. uiInfo.mapCount = 0;
  8921. while ( 1 ) {
  8922. token = COM_ParseExt((const char **)p, qtrue);
  8923. if (Q_stricmp(token, "}") == 0) {
  8924. return qtrue;
  8925. }
  8926. if ( !token || token[0] == 0 ) {
  8927. return qfalse;
  8928. }
  8929. if (token[0] == '{') {
  8930. if (!String_Parse(p, &uiInfo.mapList[uiInfo.mapCount].mapName) || !String_Parse(p, &uiInfo.mapList[uiInfo.mapCount].mapLoadName)
  8931. ||!Int_Parse(p, &uiInfo.mapList[uiInfo.mapCount].teamMembers) ) {
  8932. return qfalse;
  8933. }
  8934. if (!String_Parse(p, &uiInfo.mapList[uiInfo.mapCount].opponentName)) {
  8935. return qfalse;
  8936. }
  8937. uiInfo.mapList[uiInfo.mapCount].typeBits = 0;
  8938. while (1) {
  8939. token = COM_ParseExt((const char **)p, qtrue);
  8940. if (token[0] >= '0' && token[0] <= '9') {
  8941. uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << (token[0] - 0x030));
  8942. if (!Int_Parse(p, &uiInfo.mapList[uiInfo.mapCount].timeToBeat[token[0] - 0x30])) {
  8943. return qfalse;
  8944. }
  8945. } else {
  8946. break;
  8947. }
  8948. }
  8949. //mapList[mapCount].imageName = String_Alloc(va("levelshots/%s", mapList[mapCount].mapLoadName));
  8950. //if (uiInfo.mapCount == 0) {
  8951. // only load the first cinematic, selection loads the others
  8952. // uiInfo.mapList[uiInfo.mapCount].cinematic = trap_CIN_PlayCinematic(va("%s.roq",uiInfo.mapList[uiInfo.mapCount].mapLoadName), qfalse, qfalse, qtrue, 0, 0, 0, 0);
  8953. //}
  8954. uiInfo.mapList[uiInfo.mapCount].cinematic = -1;
  8955. uiInfo.mapList[uiInfo.mapCount].levelShot = trap_R_RegisterShaderNoMip(va("levelshots/%s_small", uiInfo.mapList[uiInfo.mapCount].mapLoadName));
  8956. if (uiInfo.mapCount < MAX_MAPS) {
  8957. uiInfo.mapCount++;
  8958. } else {
  8959. Com_Printf("Too many maps, last one replaced!\n");
  8960. }
  8961. }
  8962. }
  8963. return qfalse;
  8964. }
  8965. static void UI_ParseGameInfo(const char *teamFile) {
  8966. char *token;
  8967. char *p;
  8968. char *buff = NULL;
  8969. //int mode = 0; TTimo: unused
  8970. buff = GetMenuBuffer(teamFile);
  8971. if (!buff) {
  8972. return;
  8973. }
  8974. p = buff;
  8975. while ( 1 ) {
  8976. token = COM_ParseExt( (const char **)(&p), qtrue );
  8977. if( !token || token[0] == 0 || token[0] == '}') {
  8978. break;
  8979. }
  8980. if ( Q_stricmp( token, "}" ) == 0 ) {
  8981. break;
  8982. }
  8983. if (Q_stricmp(token, "gametypes") == 0) {
  8984. if (GameType_Parse(&p, qfalse)) {
  8985. continue;
  8986. } else {
  8987. break;
  8988. }
  8989. }
  8990. if (Q_stricmp(token, "joingametypes") == 0) {
  8991. if (GameType_Parse(&p, qtrue)) {
  8992. continue;
  8993. } else {
  8994. break;
  8995. }
  8996. }
  8997. if (Q_stricmp(token, "maps") == 0) {
  8998. // start a new menu
  8999. MapList_Parse(&p);
  9000. }
  9001. }
  9002. }
  9003. static void UI_Pause(qboolean b) {
  9004. if (b) {
  9005. // pause the game and set the ui keycatcher
  9006. trap_Cvar_Set( "cl_paused", "1" );
  9007. trap_Key_SetCatcher( KEYCATCH_UI );
  9008. } else {
  9009. // unpause the game and clear the ui keycatcher
  9010. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  9011. trap_Key_ClearStates();
  9012. trap_Cvar_Set( "cl_paused", "0" );
  9013. }
  9014. }
  9015. static int UI_PlayCinematic(const char *name, float x, float y, float w, float h) {
  9016. return trap_CIN_PlayCinematic(name, x, y, w, h, (CIN_loop | CIN_silent));
  9017. }
  9018. static void UI_StopCinematic(int handle) {
  9019. if (handle >= 0) {
  9020. trap_CIN_StopCinematic(handle);
  9021. } else {
  9022. handle = abs(handle);
  9023. if (handle == UI_MAPCINEMATIC) {
  9024. if (uiInfo.mapList[ui_currentMap.integer].cinematic >= 0) {
  9025. trap_CIN_StopCinematic(uiInfo.mapList[ui_currentMap.integer].cinematic);
  9026. uiInfo.mapList[ui_currentMap.integer].cinematic = -1;
  9027. }
  9028. } else if (handle == UI_NETMAPCINEMATIC) {
  9029. if (uiInfo.serverStatus.currentServerCinematic >= 0) {
  9030. trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
  9031. uiInfo.serverStatus.currentServerCinematic = -1;
  9032. }
  9033. } else if (handle == UI_CLANCINEMATIC) {
  9034. int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
  9035. if (i >= 0 && i < uiInfo.teamCount) {
  9036. if (uiInfo.teamList[i].cinematic >= 0) {
  9037. trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic);
  9038. uiInfo.teamList[i].cinematic = -1;
  9039. }
  9040. }
  9041. }
  9042. }
  9043. }
  9044. static void UI_DrawCinematic(int handle, float x, float y, float w, float h) {
  9045. trap_CIN_SetExtents(handle, x, y, w, h);
  9046. trap_CIN_DrawCinematic(handle);
  9047. }
  9048. static void UI_RunCinematicFrame(int handle) {
  9049. trap_CIN_RunCinematic(handle);
  9050. }
  9051. /*
  9052. =================
  9053. UI_LoadForceConfig_List
  9054. =================
  9055. Looks in the directory for force config files (.fcf) and loads the name in
  9056. */
  9057. void UI_LoadForceConfig_List( void )
  9058. {
  9059. int numfiles = 0;
  9060. char filelist[2048];
  9061. char configname[128];
  9062. char *fileptr = NULL;
  9063. int j = 0;
  9064. int filelen = 0;
  9065. qboolean lightSearch = qfalse;
  9066. uiInfo.forceConfigCount = 0;
  9067. Com_sprintf( uiInfo.forceConfigNames[uiInfo.forceConfigCount], sizeof(uiInfo.forceConfigNames[uiInfo.forceConfigCount]), "Custom");
  9068. uiInfo.forceConfigCount++;
  9069. //Always reserve index 0 as the "custom" config
  9070. nextSearch:
  9071. if (lightSearch)
  9072. { //search light side folder
  9073. numfiles = trap_FS_GetFileList("forcecfg/light", "fcf", filelist, 2048 );
  9074. uiInfo.forceConfigLightIndexBegin = uiInfo.forceConfigCount-1;
  9075. }
  9076. else
  9077. { //search dark side folder
  9078. numfiles = trap_FS_GetFileList("forcecfg/dark", "fcf", filelist, 2048 );
  9079. uiInfo.forceConfigDarkIndexBegin = uiInfo.forceConfigCount-1;
  9080. }
  9081. fileptr = filelist;
  9082. for (j=0; j<numfiles && uiInfo.forceConfigCount < MAX_FORCE_CONFIGS;j++,fileptr+=filelen+1)
  9083. {
  9084. filelen = strlen(fileptr);
  9085. COM_StripExtension(fileptr, configname);
  9086. if (lightSearch)
  9087. {
  9088. uiInfo.forceConfigSide[uiInfo.forceConfigCount] = qtrue; //light side config
  9089. }
  9090. else
  9091. {
  9092. uiInfo.forceConfigSide[uiInfo.forceConfigCount] = qfalse; //dark side config
  9093. }
  9094. Com_sprintf( uiInfo.forceConfigNames[uiInfo.forceConfigCount], sizeof(uiInfo.forceConfigNames[uiInfo.forceConfigCount]), configname);
  9095. uiInfo.forceConfigCount++;
  9096. }
  9097. if (!lightSearch)
  9098. {
  9099. lightSearch = qtrue;
  9100. goto nextSearch;
  9101. }
  9102. }
  9103. /*
  9104. =================
  9105. bIsImageFile
  9106. builds path and scans for valid image extentions
  9107. =================
  9108. */
  9109. static qboolean bIsImageFile(const char* dirptr, const char* skinname)
  9110. {
  9111. char fpath[MAX_QPATH];
  9112. int f;
  9113. Com_sprintf(fpath, MAX_QPATH, "models/players/%s/icon_%s.jpg", dirptr, skinname);
  9114. trap_FS_FOpenFile(fpath, &f, FS_READ);
  9115. #if defined(_DEBUG)
  9116. if (!f)
  9117. { //not there, try png
  9118. Com_sprintf(fpath, MAX_QPATH, "models/players/%s/icon_%s.png", dirptr, skinname);
  9119. trap_FS_FOpenFile(fpath, &f, FS_READ);
  9120. }
  9121. if (!f)
  9122. { //not there, try tga
  9123. Com_sprintf(fpath, MAX_QPATH, "models/players/%s/icon_%s.tga", dirptr, skinname);
  9124. trap_FS_FOpenFile(fpath, &f, FS_READ);
  9125. }
  9126. #endif
  9127. if (f)
  9128. {
  9129. trap_FS_FCloseFile(f);
  9130. return qtrue;
  9131. }
  9132. return qfalse;
  9133. }
  9134. /*
  9135. =================
  9136. PlayerModel_BuildList
  9137. =================
  9138. */
  9139. static void UI_BuildQ3Model_List( void )
  9140. {
  9141. int numdirs;
  9142. int numfiles;
  9143. char dirlist[2048];
  9144. char filelist[2048];
  9145. char skinname[64];
  9146. char* dirptr;
  9147. char* fileptr;
  9148. char* check;
  9149. int i;
  9150. int j, k, p, s;
  9151. int dirlen;
  9152. int filelen;
  9153. uiInfo.q3HeadCount = 0;
  9154. // iterate directory of all player models
  9155. numdirs = trap_FS_GetFileList("models/players", "/", dirlist, 2048 );
  9156. dirptr = dirlist;
  9157. for (i=0; i<numdirs && uiInfo.q3HeadCount < MAX_Q3PLAYERMODELS; i++,dirptr+=dirlen+1)
  9158. {
  9159. dirlen = strlen(dirptr);
  9160. if (dirlen && dirptr[dirlen-1]=='/') dirptr[dirlen-1]='\0';
  9161. if (!strcmp(dirptr,".") || !strcmp(dirptr,".."))
  9162. continue;
  9163. numfiles = trap_FS_GetFileList( va("models/players/%s",dirptr), "skin", filelist, 2048 );
  9164. fileptr = filelist;
  9165. for (j=0; j<numfiles && uiInfo.q3HeadCount < MAX_Q3PLAYERMODELS;j++,fileptr+=filelen+1)
  9166. {
  9167. int skinLen = 0;
  9168. filelen = strlen(fileptr);
  9169. COM_StripExtension(fileptr,skinname);
  9170. skinLen = strlen(skinname);
  9171. k = 0;
  9172. while (k < skinLen && skinname[k] && skinname[k] != '_')
  9173. {
  9174. k++;
  9175. }
  9176. if (skinname[k] == '_')
  9177. {
  9178. p = 0;
  9179. while (skinname[k])
  9180. {
  9181. skinname[p] = skinname[k];
  9182. k++;
  9183. p++;
  9184. }
  9185. skinname[p] = '\0';
  9186. }
  9187. /*
  9188. Com_sprintf(fpath, 2048, "models/players/%s/icon%s.jpg", dirptr, skinname);
  9189. trap_FS_FOpenFile(fpath, &f, FS_READ);
  9190. if (f)
  9191. */
  9192. check = &skinname[1];
  9193. if (bIsImageFile(dirptr, check))
  9194. { //if it exists
  9195. qboolean iconExists = qfalse;
  9196. //trap_FS_FCloseFile(f);
  9197. if (skinname[0] == '_')
  9198. { //change character to append properly
  9199. skinname[0] = '/';
  9200. }
  9201. s = 0;
  9202. while (s < uiInfo.q3HeadCount)
  9203. { //check for dupes
  9204. if (!Q_stricmp(va("%s%s", dirptr, skinname), uiInfo.q3HeadNames[s]))
  9205. {
  9206. iconExists = qtrue;
  9207. break;
  9208. }
  9209. s++;
  9210. }
  9211. if (iconExists)
  9212. {
  9213. continue;
  9214. }
  9215. Com_sprintf( uiInfo.q3HeadNames[uiInfo.q3HeadCount], sizeof(uiInfo.q3HeadNames[uiInfo.q3HeadCount]), va("%s%s", dirptr, skinname));
  9216. uiInfo.q3HeadIcons[uiInfo.q3HeadCount++] = 0;//trap_R_RegisterShaderNoMip(fpath);
  9217. //rww - we are now registering them as they are drawn like the TA feeder, so as to decrease UI load time.
  9218. }
  9219. if (uiInfo.q3HeadCount >= MAX_Q3PLAYERMODELS)
  9220. {
  9221. return;
  9222. }
  9223. }
  9224. }
  9225. }
  9226. void UI_SiegeInit(void)
  9227. {
  9228. //[SIEGECVARFIX]
  9229. int i;
  9230. //used to minimize cvar usage
  9231. for(i=0;i<256;i++)
  9232. {
  9233. ui_siegeStruct[i] = 0;
  9234. }
  9235. trap_Cvar_Set( "ui_siegeInfo", va("%p",ui_siegeStruct) );
  9236. //[/SIEGECVARFIX]
  9237. //Load the player class types
  9238. BG_SiegeLoadClasses(g_UIClassDescriptions);
  9239. if (!bgNumSiegeClasses)
  9240. { //We didn't find any?!
  9241. Com_Error(ERR_DROP, "Couldn't find any player classes for Siege");
  9242. }
  9243. //Now load the teams since we have class data.
  9244. BG_SiegeLoadTeams();
  9245. if (!bgNumSiegeTeams)
  9246. { //React same as with classes.
  9247. Com_Error(ERR_DROP, "Couldn't find any player teams for Siege");
  9248. }
  9249. }
  9250. /*
  9251. =================
  9252. UI_ParseColorData
  9253. =================
  9254. */
  9255. //static qboolean UI_ParseColorData(char* buf, playerSpeciesInfo_t &species)
  9256. static qboolean UI_ParseColorData(char* buf, playerSpeciesInfo_t *species,char* file)
  9257. {
  9258. const char *token;
  9259. const char *p;
  9260. p = buf;
  9261. COM_BeginParseSession(file);
  9262. species->ColorCount = 0;
  9263. while ( p )
  9264. {
  9265. token = COM_ParseExt( &p, qtrue ); //looking for the shader
  9266. if ( token[0] == 0 )
  9267. {
  9268. return species->ColorCount;
  9269. }
  9270. Q_strncpyz( species->ColorShader[species->ColorCount], token, sizeof(species->ColorShader[0]) );
  9271. token = COM_ParseExt( &p, qtrue ); //looking for action block {
  9272. if ( token[0] != '{' )
  9273. {
  9274. return qfalse;
  9275. }
  9276. assert(!species->ColorActionText[species->ColorCount][0]);
  9277. token = COM_ParseExt( &p, qtrue ); //looking for action commands
  9278. while (token[0] != '}')
  9279. {
  9280. if ( token[0] == 0)
  9281. { //EOF
  9282. return qfalse;
  9283. }
  9284. assert(species->ColorCount < sizeof(species->ColorActionText)/sizeof(species->ColorActionText[0]) );
  9285. Q_strcat(species->ColorActionText[species->ColorCount], sizeof(species->ColorActionText[0]), token);
  9286. Q_strcat(species->ColorActionText[species->ColorCount], sizeof(species->ColorActionText[0]), " ");
  9287. token = COM_ParseExt( &p, qtrue ); //looking for action commands or final }
  9288. }
  9289. species->ColorCount++; //next color please
  9290. }
  9291. return qtrue;//never get here
  9292. }
  9293. /*
  9294. =================
  9295. UI_BuildPlayerModel_List
  9296. =================
  9297. */
  9298. static void UI_BuildPlayerModel_List( qboolean inGameLoad )
  9299. {
  9300. int numdirs;
  9301. char dirlist[2048];
  9302. char* dirptr;
  9303. int dirlen;
  9304. int i;
  9305. int j;
  9306. uiInfo.playerSpeciesCount = 0;
  9307. uiInfo.playerSpeciesIndex = 0;
  9308. memset(uiInfo.playerSpecies, 0, sizeof (uiInfo.playerSpecies) );
  9309. // iterate directory of all player models
  9310. numdirs = trap_FS_GetFileList("models/players", "/", dirlist, 2048 );
  9311. dirptr = dirlist;
  9312. for (i=0; i<numdirs; i++,dirptr+=dirlen+1)
  9313. {
  9314. char filelist[2048];
  9315. char* fileptr;
  9316. int filelen;
  9317. int f = 0;
  9318. char fpath[2048];
  9319. dirlen = strlen(dirptr);
  9320. if (dirlen)
  9321. {
  9322. if (dirptr[dirlen-1]=='/')
  9323. dirptr[dirlen-1]='\0';
  9324. }
  9325. else
  9326. {
  9327. continue;
  9328. }
  9329. if (!strcmp(dirptr,".") || !strcmp(dirptr,".."))
  9330. continue;
  9331. Com_sprintf(fpath, 2048, "models/players/%s/PlayerChoice.txt", dirptr);
  9332. filelen = trap_FS_FOpenFile(fpath, &f, FS_READ);
  9333. if (f)
  9334. {
  9335. char buffer[2048];
  9336. char skinname[64];
  9337. int numfiles;
  9338. int iSkinParts=0;
  9339. trap_FS_Read(&buffer, filelen, f);
  9340. trap_FS_FCloseFile(f);
  9341. buffer[filelen] = 0; //ensure trailing NULL
  9342. //record this species
  9343. Q_strncpyz( uiInfo.playerSpecies[uiInfo.playerSpeciesCount].Name, dirptr, sizeof(uiInfo.playerSpecies[0].Name) );
  9344. if (!UI_ParseColorData(buffer,&uiInfo.playerSpecies[uiInfo.playerSpeciesCount],fpath))
  9345. {
  9346. Com_Printf(S_COLOR_RED"UI_BuildPlayerModel_List: Errors parsing '%s'\n", fpath);
  9347. }
  9348. numfiles = trap_FS_GetFileList( va("models/players/%s",dirptr), ".skin", filelist, 2048 );
  9349. fileptr = filelist;
  9350. for (j=0; j<numfiles; j++,fileptr+=filelen+1)
  9351. {
  9352. if (trap_Cvar_VariableValue("fs_copyfiles") > 0 )
  9353. {
  9354. trap_FS_FOpenFile(va("models/players/%s/%s",dirptr,fileptr), &f, FS_READ);
  9355. if (f) trap_FS_FCloseFile(f);
  9356. }
  9357. filelen = strlen(fileptr);
  9358. COM_StripExtension(fileptr,skinname);
  9359. if (bIsImageFile(dirptr, skinname))
  9360. { //if it exists
  9361. if (strnicmp(skinname,"head_",5) == 0)
  9362. {
  9363. if (uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinHeadCount < MAX_PLAYERMODELS)
  9364. {
  9365. Q_strncpyz(
  9366. uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinHeadNames[uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinHeadCount++],
  9367. skinname,
  9368. sizeof(uiInfo.playerSpecies[0].SkinHeadNames[0])
  9369. );
  9370. iSkinParts |= 1<<0;
  9371. }
  9372. } else
  9373. if (strnicmp(skinname,"torso_",6) == 0)
  9374. {
  9375. if (uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinTorsoCount < MAX_PLAYERMODELS)
  9376. {
  9377. Q_strncpyz(uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinTorsoNames[uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinTorsoCount++],
  9378. skinname,
  9379. sizeof(uiInfo.playerSpecies[0].SkinTorsoNames[0])
  9380. );
  9381. iSkinParts |= 1<<1;
  9382. }
  9383. } else
  9384. if (strnicmp(skinname,"lower_",6) == 0)
  9385. {
  9386. if (uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinLegCount < MAX_PLAYERMODELS)
  9387. {
  9388. Q_strncpyz(uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinLegNames[uiInfo.playerSpecies[uiInfo.playerSpeciesCount].SkinLegCount++],
  9389. skinname,
  9390. sizeof(uiInfo.playerSpecies[0].SkinLegNames[0])
  9391. );
  9392. iSkinParts |= 1<<2;
  9393. }
  9394. }
  9395. }
  9396. }
  9397. if (iSkinParts != 7)
  9398. { //didn't get a skin for each, then skip this model.
  9399. memset(&uiInfo.playerSpecies[uiInfo.playerSpeciesCount], 0, sizeof(uiInfo.playerSpecies[uiInfo.playerSpeciesCount]));//undo the colors
  9400. continue;
  9401. }
  9402. uiInfo.playerSpeciesCount++;
  9403. if (!inGameLoad && ui_PrecacheModels.integer)
  9404. {
  9405. int g2Model;
  9406. void *ghoul2 = 0;
  9407. Com_sprintf( fpath, sizeof( fpath ), "models/players/%s/model.glm", dirptr );
  9408. g2Model = trap_G2API_InitGhoul2Model(&ghoul2, fpath, 0, 0, 0, 0, 0);
  9409. if (g2Model >= 0)
  9410. {
  9411. // trap_G2API_RemoveGhoul2Model( &ghoul2, 0 );
  9412. trap_G2API_CleanGhoul2Models (&ghoul2);
  9413. }
  9414. }
  9415. if (uiInfo.playerSpeciesCount >= MAX_PLAYERMODELS)
  9416. {
  9417. return;
  9418. }
  9419. }
  9420. }
  9421. }
  9422. /*
  9423. =================
  9424. UI_Init
  9425. =================
  9426. */
  9427. void _UI_Init( qboolean inGameLoad ) {
  9428. const char *menuSet;
  9429. int start;
  9430. int i=0;
  9431. //register this freakin thing now
  9432. vmCvar_t siegeTeamSwitch;
  9433. trap_Cvar_Register(&siegeTeamSwitch, "g_siegeTeamSwitch", "1", CVAR_SERVERINFO|CVAR_ARCHIVE);
  9434. // Get the list of possible languages
  9435. uiInfo.languageCount = trap_SP_GetNumLanguages(); // this does a dir scan, so use carefully
  9436. uiInfo.inGameLoad = inGameLoad;
  9437. //initialize all these cvars to "0"
  9438. UI_SiegeSetCvarsForClass(NULL);
  9439. UI_SiegeInit();
  9440. UI_UpdateForcePowers();
  9441. UI_RegisterCvars();
  9442. UI_InitMemory();
  9443. // cache redundant calulations
  9444. trap_GetGlconfig( &uiInfo.uiDC.glconfig );
  9445. // for 640x480 virtualized screen
  9446. uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0/480.0);
  9447. uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0/640.0);
  9448. if ( uiInfo.uiDC.glconfig.vidWidth * 480 > uiInfo.uiDC.glconfig.vidHeight * 640 ) {
  9449. // wide screen
  9450. uiInfo.uiDC.bias = 0.5 * ( uiInfo.uiDC.glconfig.vidWidth - ( uiInfo.uiDC.glconfig.vidHeight * (640.0/480.0) ) );
  9451. }
  9452. else {
  9453. // no wide screen
  9454. uiInfo.uiDC.bias = 0;
  9455. }
  9456. //UI_Load();
  9457. uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
  9458. uiInfo.uiDC.setColor = &UI_SetColor;
  9459. uiInfo.uiDC.drawHandlePic = &UI_DrawHandlePic;
  9460. uiInfo.uiDC.drawStretchPic = &trap_R_DrawStretchPic;
  9461. uiInfo.uiDC.drawText = &Text_Paint;
  9462. uiInfo.uiDC.textWidth = &Text_Width;
  9463. uiInfo.uiDC.textHeight = &Text_Height;
  9464. uiInfo.uiDC.registerModel = &trap_R_RegisterModel;
  9465. uiInfo.uiDC.modelBounds = &trap_R_ModelBounds;
  9466. uiInfo.uiDC.fillRect = &UI_FillRect;
  9467. uiInfo.uiDC.drawRect = &_UI_DrawRect;
  9468. uiInfo.uiDC.drawSides = &_UI_DrawSides;
  9469. uiInfo.uiDC.drawTopBottom = &_UI_DrawTopBottom;
  9470. uiInfo.uiDC.clearScene = &trap_R_ClearScene;
  9471. uiInfo.uiDC.drawSides = &_UI_DrawSides;
  9472. uiInfo.uiDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
  9473. uiInfo.uiDC.renderScene = &trap_R_RenderScene;
  9474. uiInfo.uiDC.RegisterFont = &trap_R_RegisterFont;
  9475. uiInfo.uiDC.Font_StrLenPixels = trap_R_Font_StrLenPixels;
  9476. uiInfo.uiDC.Font_StrLenChars = trap_R_Font_StrLenChars;
  9477. uiInfo.uiDC.Font_HeightPixels = trap_R_Font_HeightPixels;
  9478. uiInfo.uiDC.Font_DrawString = trap_R_Font_DrawString;
  9479. uiInfo.uiDC.Language_IsAsian = trap_Language_IsAsian;
  9480. uiInfo.uiDC.Language_UsesSpaces = trap_Language_UsesSpaces;
  9481. uiInfo.uiDC.AnyLanguage_ReadCharFromString = trap_AnyLanguage_ReadCharFromString;
  9482. uiInfo.uiDC.ownerDrawItem = &UI_OwnerDraw;
  9483. uiInfo.uiDC.getValue = &UI_GetValue;
  9484. uiInfo.uiDC.ownerDrawVisible = &UI_OwnerDrawVisible;
  9485. uiInfo.uiDC.runScript = &UI_RunMenuScript;
  9486. uiInfo.uiDC.deferScript = &UI_DeferMenuScript;
  9487. uiInfo.uiDC.getTeamColor = &UI_GetTeamColor;
  9488. uiInfo.uiDC.setCVar = trap_Cvar_Set;
  9489. uiInfo.uiDC.getCVarString = trap_Cvar_VariableStringBuffer;
  9490. uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue;
  9491. uiInfo.uiDC.drawTextWithCursor = &Text_PaintWithCursor;
  9492. uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
  9493. uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
  9494. uiInfo.uiDC.startLocalSound = &trap_S_StartLocalSound;
  9495. uiInfo.uiDC.ownerDrawHandleKey = &UI_OwnerDrawHandleKey;
  9496. uiInfo.uiDC.feederCount = &UI_FeederCount;
  9497. uiInfo.uiDC.feederItemImage = &UI_FeederItemImage;
  9498. uiInfo.uiDC.feederItemText = &UI_FeederItemText;
  9499. uiInfo.uiDC.feederSelection = &UI_FeederSelection;
  9500. uiInfo.uiDC.setBinding = &trap_Key_SetBinding;
  9501. uiInfo.uiDC.getBindingBuf = &trap_Key_GetBindingBuf;
  9502. uiInfo.uiDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
  9503. uiInfo.uiDC.executeText = &trap_Cmd_ExecuteText;
  9504. uiInfo.uiDC.Error = &Com_Error;
  9505. uiInfo.uiDC.Print = &Com_Printf;
  9506. uiInfo.uiDC.Pause = &UI_Pause;
  9507. uiInfo.uiDC.ownerDrawWidth = &UI_OwnerDrawWidth;
  9508. uiInfo.uiDC.registerSound = &trap_S_RegisterSound;
  9509. uiInfo.uiDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
  9510. uiInfo.uiDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
  9511. uiInfo.uiDC.playCinematic = &UI_PlayCinematic;
  9512. uiInfo.uiDC.stopCinematic = &UI_StopCinematic;
  9513. uiInfo.uiDC.drawCinematic = &UI_DrawCinematic;
  9514. uiInfo.uiDC.runCinematicFrame = &UI_RunCinematicFrame;
  9515. Init_Display(&uiInfo.uiDC);
  9516. UI_BuildPlayerModel_List(inGameLoad);
  9517. String_Init();
  9518. uiInfo.uiDC.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" );
  9519. uiInfo.uiDC.whiteShader = trap_R_RegisterShaderNoMip( "white" );
  9520. AssetCache();
  9521. start = trap_Milliseconds();
  9522. uiInfo.teamCount = 0;
  9523. uiInfo.characterCount = 0;
  9524. uiInfo.aliasCount = 0;
  9525. UI_ParseGameInfo("ui/jamp/gameinfo.txt");
  9526. menuSet = UI_Cvar_VariableString("ui_menuFilesMP");
  9527. if (menuSet == NULL || menuSet[0] == '\0') {
  9528. menuSet = "ui/jampmenus.txt";
  9529. }
  9530. #if 1
  9531. if (inGameLoad)
  9532. {
  9533. UI_LoadMenus("ui/jampingame.txt", qtrue);
  9534. //[CoOp]
  9535. //load the SP menu files as well.
  9536. UI_LoadMenus("ui/menutest.txt", qfalse);
  9537. //UI_LoadMenus("ui/ingame.txt", qfalse);
  9538. //[/CoOp]
  9539. }
  9540. else if (!ui_bypassMainMenuLoad.integer)
  9541. {
  9542. UI_LoadMenus(menuSet, qtrue);
  9543. }
  9544. #else //this was adding quite a giant amount of time to the load time
  9545. UI_LoadMenus(menuSet, qtrue);
  9546. UI_LoadMenus("ui/jampingame.txt", qtrue);
  9547. #endif
  9548. trap_Cvar_Register(NULL, "ui_name", UI_Cvar_VariableString("name"), CVAR_INTERNAL ); //get this now, jic the menus change again trying to setName before getName
  9549. Menus_CloseAll();
  9550. trap_LAN_LoadCachedServers();
  9551. UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
  9552. UI_BuildQ3Model_List();
  9553. UI_LoadBots();
  9554. UI_LoadForceConfig_List();
  9555. UI_InitForceShaders();
  9556. // sets defaults for ui temp cvars
  9557. uiInfo.effectsColor = /*gamecodetoui[*/(int)trap_Cvar_VariableValue("color1");//-1];
  9558. uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue("cg_drawCrosshair");
  9559. trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1");
  9560. trap_Cvar_Set("ui_mousePitchVeh", (trap_Cvar_VariableValue("m_pitchVeh") >= 0) ? "0" : "1");
  9561. uiInfo.serverStatus.currentServerCinematic = -1;
  9562. uiInfo.previewMovie = -1;
  9563. trap_Cvar_Register(NULL, "debug_protocol", "", 0 );
  9564. trap_Cvar_Set("ui_actualNetGameType", va("%d", ui_netGameType.integer));
  9565. }
  9566. /*
  9567. =================
  9568. UI_KeyEvent
  9569. =================
  9570. */
  9571. void _UI_KeyEvent( int key, qboolean down ) {
  9572. if (Menu_Count() > 0) {
  9573. menuDef_t *menu = Menu_GetFocused();
  9574. if (menu) {
  9575. if (key == A_ESCAPE && down && !Menus_AnyFullScreenVisible()) {
  9576. Menus_CloseAll();
  9577. } else {
  9578. Menu_HandleKey(menu, key, down );
  9579. }
  9580. } else {
  9581. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  9582. trap_Key_ClearStates();
  9583. trap_Cvar_Set( "cl_paused", "0" );
  9584. }
  9585. }
  9586. //if ((s > 0) && (s != menu_null_sound)) {
  9587. // trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND );
  9588. //}
  9589. }
  9590. /*
  9591. =================
  9592. UI_MouseEvent
  9593. =================
  9594. */
  9595. void _UI_MouseEvent( int dx, int dy )
  9596. {
  9597. // update mouse screen position
  9598. uiInfo.uiDC.cursorx += dx;
  9599. if (uiInfo.uiDC.cursorx < 0)
  9600. uiInfo.uiDC.cursorx = 0;
  9601. else if (uiInfo.uiDC.cursorx > SCREEN_WIDTH)
  9602. uiInfo.uiDC.cursorx = SCREEN_WIDTH;
  9603. uiInfo.uiDC.cursory += dy;
  9604. if (uiInfo.uiDC.cursory < 0)
  9605. uiInfo.uiDC.cursory = 0;
  9606. else if (uiInfo.uiDC.cursory > SCREEN_HEIGHT)
  9607. uiInfo.uiDC.cursory = SCREEN_HEIGHT;
  9608. if (Menu_Count() > 0) {
  9609. //menuDef_t *menu = Menu_GetFocused();
  9610. //Menu_HandleMouseMove(menu, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
  9611. Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
  9612. }
  9613. }
  9614. void UI_LoadNonIngame() {
  9615. const char *menuSet = UI_Cvar_VariableString("ui_menuFilesMP");
  9616. if (menuSet == NULL || menuSet[0] == '\0') {
  9617. menuSet = "ui/jampmenus.txt";
  9618. }
  9619. UI_LoadMenus(menuSet, qfalse);
  9620. uiInfo.inGameLoad = qfalse;
  9621. }
  9622. void _UI_SetActiveMenu( uiMenuCommand_t menu ) {
  9623. char buf[256];
  9624. // this should be the ONLY way the menu system is brought up
  9625. // enusure minumum menu data is cached
  9626. if (Menu_Count() > 0) {
  9627. vec3_t v;
  9628. v[0] = v[1] = v[2] = 0;
  9629. switch ( menu ) {
  9630. case UIMENU_NONE:
  9631. trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
  9632. trap_Key_ClearStates();
  9633. trap_Cvar_Set( "cl_paused", "0" );
  9634. Menus_CloseAll();
  9635. return;
  9636. case UIMENU_MAIN:
  9637. {
  9638. qboolean active = qfalse;
  9639. //trap_Cvar_Set( "sv_killserver", "1" );
  9640. trap_Key_SetCatcher( KEYCATCH_UI );
  9641. //trap_S_StartLocalSound( trap_S_RegisterSound("sound/misc/menu_background.wav", qfalse) , CHAN_LOCAL_SOUND );
  9642. //trap_S_StartBackgroundTrack("sound/misc/menu_background.wav", NULL);
  9643. if (uiInfo.inGameLoad)
  9644. {
  9645. // UI_LoadNonIngame();
  9646. }
  9647. Menus_CloseAll();
  9648. Menus_ActivateByName("main");
  9649. trap_Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf));
  9650. if (buf[0])
  9651. {
  9652. if (!ui_singlePlayerActive.integer)
  9653. {
  9654. Menus_ActivateByName("error_popmenu");
  9655. active = qtrue;
  9656. }
  9657. else
  9658. {
  9659. trap_Cvar_Set("com_errorMessage", "");
  9660. }
  9661. }
  9662. return;
  9663. }
  9664. case UIMENU_TEAM:
  9665. trap_Key_SetCatcher( KEYCATCH_UI );
  9666. Menus_ActivateByName("team");
  9667. return;
  9668. case UIMENU_POSTGAME:
  9669. //trap_Cvar_Set( "sv_killserver", "1" );
  9670. trap_Key_SetCatcher( KEYCATCH_UI );
  9671. if (uiInfo.inGameLoad) {
  9672. // UI_LoadNonIngame();
  9673. }
  9674. Menus_CloseAll();
  9675. Menus_ActivateByName("endofgame");
  9676. //UI_ConfirmMenu( "Bad CD Key", NULL, NeedCDKeyAction );
  9677. return;
  9678. case UIMENU_INGAME:
  9679. trap_Cvar_Set( "cl_paused", "1" );
  9680. trap_Key_SetCatcher( KEYCATCH_UI );
  9681. UI_BuildPlayerList();
  9682. Menus_CloseAll();
  9683. Menus_ActivateByName("ingame");
  9684. return;
  9685. case UIMENU_PLAYERCONFIG:
  9686. // trap_Cvar_Set( "cl_paused", "1" );
  9687. trap_Key_SetCatcher( KEYCATCH_UI );
  9688. UI_BuildPlayerList();
  9689. Menus_CloseAll();
  9690. Menus_ActivateByName("ingame_player");
  9691. UpdateForceUsed();
  9692. return;
  9693. case UIMENU_PLAYERFORCE:
  9694. // trap_Cvar_Set( "cl_paused", "1" );
  9695. trap_Key_SetCatcher( KEYCATCH_UI );
  9696. UI_BuildPlayerList();
  9697. Menus_CloseAll();
  9698. Menus_ActivateByName("ingame_playerforce");
  9699. UpdateForceUsed();
  9700. return;
  9701. case UIMENU_SIEGEMESSAGE:
  9702. // trap_Cvar_Set( "cl_paused", "1" );
  9703. trap_Key_SetCatcher( KEYCATCH_UI );
  9704. Menus_CloseAll();
  9705. Menus_ActivateByName("siege_popmenu");
  9706. return;
  9707. case UIMENU_SIEGEOBJECTIVES:
  9708. // trap_Cvar_Set( "cl_paused", "1" );
  9709. trap_Key_SetCatcher( KEYCATCH_UI );
  9710. Menus_CloseAll();
  9711. Menus_ActivateByName("ingame_siegeobjectives");
  9712. return;
  9713. case UIMENU_VOICECHAT:
  9714. // trap_Cvar_Set( "cl_paused", "1" );
  9715. // No chatin non-siege games.
  9716. if (trap_Cvar_VariableValue( "g_gametype" ) < GT_TEAM)
  9717. {
  9718. return;
  9719. }
  9720. trap_Key_SetCatcher( KEYCATCH_UI );
  9721. Menus_CloseAll();
  9722. Menus_ActivateByName("ingame_voicechat");
  9723. return;
  9724. case UIMENU_CLOSEALL:
  9725. Menus_CloseAll();
  9726. return;
  9727. case UIMENU_CLASSSEL:
  9728. trap_Key_SetCatcher( KEYCATCH_UI );
  9729. Menus_CloseAll();
  9730. Menus_ActivateByName("ingame_siegeclass");
  9731. return;
  9732. //[CoOp]
  9733. case UIMENU_BRIEFING:
  9734. trap_Cvar_VariableStringBuffer("ui_menubrief", buf, sizeof(buf) );
  9735. trap_Key_SetCatcher( KEYCATCH_UI );
  9736. Menus_CloseAll();
  9737. if(!Menus_ActivateByName(buf))
  9738. {//menu not loaded. Try loading a .menu with the same name as this menu.
  9739. UI_LoadSingleMenuFile(va("ui/%s.menu", buf));
  9740. Menus_ActivateByName(buf);
  9741. }
  9742. return;
  9743. //[/CoOp]
  9744. //[Commander]
  9745. /*
  9746. case UIMENU_BUILDLIST:
  9747. trap_Key_SetCatcher( KEYCATCH_UI );
  9748. Menus_CloseAll();
  9749. Menus_ActivateByName("commander_build");
  9750. return;
  9751. */
  9752. //[/Commander]
  9753. }
  9754. }
  9755. }
  9756. qboolean _UI_IsFullscreen( void ) {
  9757. return Menus_AnyFullScreenVisible();
  9758. }
  9759. static connstate_t lastConnState;
  9760. static char lastLoadingText[MAX_INFO_VALUE];
  9761. static void UI_ReadableSize ( char *buf, int bufsize, int value )
  9762. {
  9763. if (value > 1024*1024*1024 ) { // gigs
  9764. Com_sprintf( buf, bufsize, "%d", value / (1024*1024*1024) );
  9765. Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d GB",
  9766. (value % (1024*1024*1024))*100 / (1024*1024*1024) );
  9767. } else if (value > 1024*1024 ) { // megs
  9768. Com_sprintf( buf, bufsize, "%d", value / (1024*1024) );
  9769. Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d MB",
  9770. (value % (1024*1024))*100 / (1024*1024) );
  9771. } else if (value > 1024 ) { // kilos
  9772. Com_sprintf( buf, bufsize, "%d KB", value / 1024 );
  9773. } else { // bytes
  9774. Com_sprintf( buf, bufsize, "%d bytes", value );
  9775. }
  9776. }
  9777. // Assumes time is in msec
  9778. static void UI_PrintTime ( char *buf, int bufsize, int time ) {
  9779. time /= 1000; // change to seconds
  9780. if (time > 3600) { // in the hours range
  9781. Com_sprintf( buf, bufsize, "%d hr %2d min", time / 3600, (time % 3600) / 60 );
  9782. } else if (time > 60) { // mins
  9783. Com_sprintf( buf, bufsize, "%2d min %2d sec", time / 60, time % 60 );
  9784. } else { // secs
  9785. Com_sprintf( buf, bufsize, "%2d sec", time );
  9786. }
  9787. }
  9788. void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust, int iMenuFont) {
  9789. int len = Text_Width(text, scale, iMenuFont);
  9790. Text_Paint(x - len / 2, y, scale, color, text, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE, iMenuFont);
  9791. }
  9792. static void UI_DisplayDownloadInfo( const char *downloadName, float centerPoint, float yStart, float scale, int iMenuFont) {
  9793. char sDownLoading[256];
  9794. char sEstimatedTimeLeft[256];
  9795. char sTransferRate[256];
  9796. char sOf[20];
  9797. char sCopied[256];
  9798. char sSec[20];
  9799. //
  9800. int downloadSize, downloadCount, downloadTime;
  9801. char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64];
  9802. int xferRate;
  9803. int leftWidth;
  9804. const char *s;
  9805. vec4_t colorLtGreyAlpha = {0, 0, 0, .5};
  9806. UI_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, colorLtGreyAlpha );
  9807. s = GetCRDelineatedString("MENUS","DOWNLOAD_STUFF", 0); // "Downloading:"
  9808. strcpy(sDownLoading,s?s:"");
  9809. s = GetCRDelineatedString("MENUS","DOWNLOAD_STUFF", 1); // "Estimated time left:"
  9810. strcpy(sEstimatedTimeLeft,s?s:"");
  9811. s = GetCRDelineatedString("MENUS","DOWNLOAD_STUFF", 2); // "Transfer rate:"
  9812. strcpy(sTransferRate,s?s:"");
  9813. s = GetCRDelineatedString("MENUS","DOWNLOAD_STUFF", 3); // "of"
  9814. strcpy(sOf,s?s:"");
  9815. s = GetCRDelineatedString("MENUS","DOWNLOAD_STUFF", 4); // "copied"
  9816. strcpy(sCopied,s?s:"");
  9817. s = GetCRDelineatedString("MENUS","DOWNLOAD_STUFF", 5); // "sec."
  9818. strcpy(sSec,s?s:"");
  9819. downloadSize = trap_Cvar_VariableValue( "cl_downloadSize" );
  9820. downloadCount = trap_Cvar_VariableValue( "cl_downloadCount" );
  9821. downloadTime = trap_Cvar_VariableValue( "cl_downloadTime" );
  9822. leftWidth = 320;
  9823. UI_SetColor(colorWhite);
  9824. Text_PaintCenter(centerPoint, yStart + 112, scale, colorWhite, sDownLoading, 0, iMenuFont);
  9825. Text_PaintCenter(centerPoint, yStart + 192, scale, colorWhite, sEstimatedTimeLeft, 0, iMenuFont);
  9826. Text_PaintCenter(centerPoint, yStart + 248, scale, colorWhite, sTransferRate, 0, iMenuFont);
  9827. if (downloadSize > 0) {
  9828. s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize );
  9829. } else {
  9830. s = downloadName;
  9831. }
  9832. Text_PaintCenter(centerPoint, yStart+136, scale, colorWhite, s, 0, iMenuFont);
  9833. UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount );
  9834. UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize );
  9835. if (downloadCount < 4096 || !downloadTime) {
  9836. Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0, iMenuFont);
  9837. Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s %s %s %s)", dlSizeBuf, sOf, totalSizeBuf, sCopied), 0, iMenuFont);
  9838. } else {
  9839. if ((uiInfo.uiDC.realTime - downloadTime) / 1000) {
  9840. xferRate = downloadCount / ((uiInfo.uiDC.realTime - downloadTime) / 1000);
  9841. } else {
  9842. xferRate = 0;
  9843. }
  9844. UI_ReadableSize( xferRateBuf, sizeof xferRateBuf, xferRate );
  9845. // Extrapolate estimated completion time
  9846. if (downloadSize && xferRate) {
  9847. int n = downloadSize / xferRate; // estimated time for entire d/l in secs
  9848. // We do it in K (/1024) because we'd overflow around 4MB
  9849. UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf,
  9850. (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000);
  9851. Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, dlTimeBuf, 0, iMenuFont);
  9852. Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s %s %s %s)", dlSizeBuf, sOf, totalSizeBuf, sCopied), 0, iMenuFont);
  9853. } else {
  9854. Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0, iMenuFont);
  9855. if (downloadSize) {
  9856. Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s %s %s %s)", dlSizeBuf, sOf, totalSizeBuf, sCopied), 0, iMenuFont);
  9857. } else {
  9858. Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s %s)", dlSizeBuf, sCopied), 0, iMenuFont);
  9859. }
  9860. }
  9861. if (xferRate) {
  9862. Text_PaintCenter(leftWidth, yStart+272, scale, colorWhite, va("%s/%s", xferRateBuf,sSec), 0, iMenuFont);
  9863. }
  9864. }
  9865. }
  9866. /*
  9867. ========================
  9868. UI_DrawConnectScreen
  9869. This will also be overlaid on the cgame info screen during loading
  9870. to prevent it from blinking away too rapidly on local or lan games.
  9871. ========================
  9872. */
  9873. void UI_DrawConnectScreen( qboolean overlay ) {
  9874. const char *s;
  9875. uiClientState_t cstate;
  9876. char info[MAX_INFO_VALUE];
  9877. char text[256];
  9878. float centerPoint, yStart, scale;
  9879. char sStringEdTemp[256];
  9880. menuDef_t *menu = Menus_FindByName("Connect");
  9881. if ( !overlay && menu ) {
  9882. Menu_Paint(menu, qtrue);
  9883. }
  9884. if (!overlay) {
  9885. centerPoint = 320;
  9886. yStart = 130;
  9887. scale = 1.0f; // -ste
  9888. } else {
  9889. centerPoint = 320;
  9890. yStart = 32;
  9891. scale = 1.0f; // -ste
  9892. return;
  9893. }
  9894. // see what information we should display
  9895. trap_GetClientState( &cstate );
  9896. info[0] = '\0';
  9897. if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) {
  9898. trap_SP_GetStringTextString("MENUS_LOADING_MAPNAME", sStringEdTemp, sizeof(sStringEdTemp));
  9899. Text_PaintCenter(centerPoint, yStart, scale, colorWhite, va( /*"Loading %s"*/sStringEdTemp, Info_ValueForKey( info, "mapname" )), 0, FONT_MEDIUM);
  9900. }
  9901. if (!Q_stricmp(cstate.servername,"localhost")) {
  9902. trap_SP_GetStringTextString("MENUS_STARTING_UP", sStringEdTemp, sizeof(sStringEdTemp));
  9903. Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, sStringEdTemp, ITEM_TEXTSTYLE_SHADOWEDMORE, FONT_MEDIUM);
  9904. } else {
  9905. trap_SP_GetStringTextString("MENUS_CONNECTING_TO", sStringEdTemp, sizeof(sStringEdTemp));
  9906. strcpy(text, va(/*"Connecting to %s"*/sStringEdTemp, cstate.servername));
  9907. Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite,text , ITEM_TEXTSTYLE_SHADOWEDMORE, FONT_MEDIUM);
  9908. }
  9909. //UI_DrawProportionalString( 320, 96, "Press Esc to abort", UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color );
  9910. // display global MOTD at bottom
  9911. Text_PaintCenter(centerPoint, 425, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0, FONT_MEDIUM);
  9912. // print any server info (server full, bad version, etc)
  9913. if ( cstate.connState < CA_CONNECTED ) {
  9914. Text_PaintCenter(centerPoint, yStart + 176, scale, colorWhite, cstate.messageString, 0, FONT_MEDIUM);
  9915. }
  9916. if ( lastConnState > cstate.connState ) {
  9917. lastLoadingText[0] = '\0';
  9918. }
  9919. lastConnState = cstate.connState;
  9920. switch ( cstate.connState ) {
  9921. case CA_CONNECTING:
  9922. {
  9923. trap_SP_GetStringTextString("MENUS_AWAITING_CONNECTION", sStringEdTemp, sizeof(sStringEdTemp));
  9924. s = va(/*"Awaiting connection...%i"*/sStringEdTemp, cstate.connectPacketCount);
  9925. }
  9926. break;
  9927. case CA_CHALLENGING:
  9928. {
  9929. trap_SP_GetStringTextString("MENUS_AWAITING_CHALLENGE", sStringEdTemp, sizeof(sStringEdTemp));
  9930. s = va(/*"Awaiting challenge...%i"*/sStringEdTemp, cstate.connectPacketCount);
  9931. }
  9932. break;
  9933. case CA_CONNECTED: {
  9934. char downloadName[MAX_INFO_VALUE];
  9935. trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) );
  9936. if (*downloadName) {
  9937. UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, scale, FONT_MEDIUM );
  9938. return;
  9939. }
  9940. }
  9941. trap_SP_GetStringTextString("MENUS_AWAITING_GAMESTATE", sStringEdTemp, sizeof(sStringEdTemp));
  9942. s = /*"Awaiting gamestate..."*/sStringEdTemp;
  9943. break;
  9944. case CA_LOADING:
  9945. return;
  9946. case CA_PRIMED:
  9947. return;
  9948. default:
  9949. return;
  9950. }
  9951. if (Q_stricmp(cstate.servername,"localhost")) {
  9952. Text_PaintCenter(centerPoint, yStart + 80, scale, colorWhite, s, 0, FONT_MEDIUM);
  9953. }
  9954. // password required / connection rejected information goes here
  9955. }
  9956. /*
  9957. ================
  9958. cvars
  9959. ================
  9960. */
  9961. typedef struct {
  9962. vmCvar_t *vmCvar;
  9963. char *cvarName;
  9964. char *defaultString;
  9965. int cvarFlags;
  9966. } cvarTable_t;
  9967. vmCvar_t ui_ffa_fraglimit;
  9968. vmCvar_t ui_ffa_timelimit;
  9969. vmCvar_t ui_selectedModelIndex;
  9970. vmCvar_t ui_char_model;
  9971. vmCvar_t ui_char_skin_head;
  9972. vmCvar_t ui_char_skin_torso;
  9973. vmCvar_t ui_char_skin_legs;
  9974. vmCvar_t ui_saber_type;
  9975. vmCvar_t ui_saber;
  9976. vmCvar_t ui_saber2;
  9977. vmCvar_t ui_saber_color;
  9978. vmCvar_t ui_saber2_color;
  9979. vmCvar_t ui_team_fraglimit;
  9980. vmCvar_t ui_team_timelimit;
  9981. vmCvar_t ui_team_friendly;
  9982. vmCvar_t ui_ctf_capturelimit;
  9983. vmCvar_t ui_ctf_timelimit;
  9984. vmCvar_t ui_ctf_friendly;
  9985. vmCvar_t ui_arenasFile;
  9986. vmCvar_t ui_botsFile;
  9987. vmCvar_t ui_spSkill;
  9988. //[TABBot]
  9989. vmCvar_t ui_bottype;
  9990. //[TABBot]
  9991. vmCvar_t ui_browserMaster;
  9992. vmCvar_t ui_browserGameType;
  9993. vmCvar_t ui_browserSortKey;
  9994. vmCvar_t ui_browserShowFull;
  9995. vmCvar_t ui_browserShowEmpty;
  9996. vmCvar_t ui_drawCrosshair;
  9997. vmCvar_t ui_drawCrosshairNames;
  9998. vmCvar_t ui_marks;
  9999. vmCvar_t ui_redteam;
  10000. vmCvar_t ui_redteam1;
  10001. vmCvar_t ui_redteam2;
  10002. vmCvar_t ui_redteam3;
  10003. vmCvar_t ui_redteam4;
  10004. vmCvar_t ui_redteam5;
  10005. vmCvar_t ui_redteam6;
  10006. vmCvar_t ui_redteam7;
  10007. vmCvar_t ui_redteam8;
  10008. vmCvar_t ui_blueteam;
  10009. vmCvar_t ui_blueteam1;
  10010. vmCvar_t ui_blueteam2;
  10011. vmCvar_t ui_blueteam3;
  10012. vmCvar_t ui_blueteam4;
  10013. vmCvar_t ui_blueteam5;
  10014. vmCvar_t ui_blueteam6;
  10015. vmCvar_t ui_blueteam7;
  10016. vmCvar_t ui_blueteam8;
  10017. vmCvar_t ui_teamName;
  10018. vmCvar_t ui_dedicated;
  10019. vmCvar_t ui_gameType;
  10020. vmCvar_t ui_netGameType;
  10021. vmCvar_t ui_actualNetGameType;
  10022. vmCvar_t ui_joinGameType;
  10023. vmCvar_t ui_netSource;
  10024. vmCvar_t ui_serverFilterType;
  10025. vmCvar_t ui_opponentName;
  10026. vmCvar_t ui_menuFiles;
  10027. vmCvar_t ui_currentMap;
  10028. vmCvar_t ui_currentNetMap;
  10029. vmCvar_t ui_mapIndex;
  10030. vmCvar_t ui_currentOpponent;
  10031. vmCvar_t ui_selectedPlayer;
  10032. vmCvar_t ui_selectedPlayerName;
  10033. vmCvar_t ui_lastServerRefresh_0;
  10034. vmCvar_t ui_lastServerRefresh_1;
  10035. vmCvar_t ui_lastServerRefresh_2;
  10036. vmCvar_t ui_lastServerRefresh_3;
  10037. vmCvar_t ui_singlePlayerActive;
  10038. vmCvar_t ui_scoreAccuracy;
  10039. vmCvar_t ui_scoreImpressives;
  10040. vmCvar_t ui_scoreExcellents;
  10041. vmCvar_t ui_scoreCaptures;
  10042. vmCvar_t ui_scoreDefends;
  10043. vmCvar_t ui_scoreAssists;
  10044. vmCvar_t ui_scoreGauntlets;
  10045. vmCvar_t ui_scoreScore;
  10046. vmCvar_t ui_scorePerfect;
  10047. vmCvar_t ui_scoreTeam;
  10048. vmCvar_t ui_scoreBase;
  10049. vmCvar_t ui_scoreTimeBonus;
  10050. vmCvar_t ui_scoreSkillBonus;
  10051. vmCvar_t ui_scoreShutoutBonus;
  10052. vmCvar_t ui_scoreTime;
  10053. vmCvar_t ui_captureLimit;
  10054. vmCvar_t ui_fragLimit;
  10055. vmCvar_t ui_findPlayer;
  10056. vmCvar_t ui_hudFiles;
  10057. vmCvar_t ui_recordSPDemo;
  10058. vmCvar_t ui_realCaptureLimit;
  10059. vmCvar_t ui_realWarmUp;
  10060. vmCvar_t ui_serverStatusTimeOut;
  10061. vmCvar_t se_language;
  10062. vmCvar_t ui_bypassMainMenuLoad;
  10063. //[SIEGECVARFIX]
  10064. vmCvar_t ui_siegeInfo;
  10065. char *ui_siegeStruct[1024];
  10066. //[/SIEGECVARFIX]
  10067. //[RGBSabers]
  10068. vmCvar_t ui_sab1_r;
  10069. vmCvar_t ui_sab1_g;
  10070. vmCvar_t ui_sab1_b;
  10071. vmCvar_t ui_sab2_r;
  10072. vmCvar_t ui_sab2_g;
  10073. vmCvar_t ui_sab2_b;
  10074. //[/RGBSabers]
  10075. // bk001129 - made static to avoid aliasing
  10076. static cvarTable_t cvarTable[] = {
  10077. { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE|CVAR_INTERNAL },
  10078. { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10079. { &ui_selectedModelIndex, "ui_selectedModelIndex", "16", CVAR_ARCHIVE|CVAR_INTERNAL },
  10080. { &ui_char_model, "ui_char_model", "jedi_tf",CVAR_ROM|CVAR_INTERNAL},
  10081. { &ui_char_skin_head, "ui_char_skin_head", "head_a1",CVAR_ROM|CVAR_INTERNAL},
  10082. { &ui_char_skin_torso, "ui_char_skin_torso", "torso_a1",CVAR_ROM|CVAR_INTERNAL},
  10083. { &ui_char_skin_legs, "ui_char_skin_legs", "lower_a1",CVAR_ROM|CVAR_INTERNAL},
  10084. { &ui_char_anim, "ui_char_anim", "BOTH_WALK1",CVAR_ROM|CVAR_INTERNAL},
  10085. { &ui_saber_type, "ui_saber_type", "single",CVAR_ROM|CVAR_INTERNAL},
  10086. { &ui_saber, "ui_saber", "single_1",CVAR_ROM|CVAR_INTERNAL},
  10087. { &ui_saber2, "ui_saber2", "none",CVAR_ROM|CVAR_INTERNAL},
  10088. { &ui_saber_color, "ui_saber_color", "yellow",CVAR_ROM|CVAR_INTERNAL},
  10089. { &ui_saber2_color, "ui_saber2_color", "yellow",CVAR_ROM|CVAR_INTERNAL},
  10090. { &ui_char_color_red, "ui_char_color_red", "255", CVAR_ROM|CVAR_INTERNAL},
  10091. { &ui_char_color_green, "ui_char_color_green", "255", CVAR_ROM|CVAR_INTERNAL},
  10092. { &ui_char_color_blue, "ui_char_color_blue", "255", CVAR_ROM|CVAR_INTERNAL},
  10093. { &ui_PrecacheModels, "ui_PrecacheModels", "0", CVAR_ARCHIVE},
  10094. { &ui_team_fraglimit, "ui_team_fraglimit", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10095. { &ui_team_timelimit, "ui_team_timelimit", "20", CVAR_ARCHIVE|CVAR_INTERNAL },
  10096. { &ui_team_friendly, "ui_team_friendly", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10097. { &ui_ctf_capturelimit, "ui_ctf_capturelimit", "8", CVAR_ARCHIVE|CVAR_INTERNAL },
  10098. { &ui_ctf_timelimit, "ui_ctf_timelimit", "30", CVAR_ARCHIVE|CVAR_INTERNAL },
  10099. { &ui_ctf_friendly, "ui_ctf_friendly", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10100. { &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM },
  10101. { &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE|CVAR_INTERNAL },
  10102. //[TABBot]
  10103. { &ui_bottype, "ui_bottype", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10104. //[TABBot]
  10105. { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10106. { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10107. { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE|CVAR_INTERNAL },
  10108. { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10109. { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10110. { &ui_drawCrosshair, "cg_drawCrosshair", "1", CVAR_ARCHIVE },
  10111. { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
  10112. { &ui_marks, "cg_marks", "1", CVAR_ARCHIVE },
  10113. { &ui_debug, "ui_debug", "0", CVAR_TEMP|CVAR_INTERNAL },
  10114. { &ui_initialized, "ui_initialized", "0", CVAR_TEMP|CVAR_INTERNAL },
  10115. //{ &ui_teamName, "ui_teamName", "Empire", CVAR_ARCHIVE|CVAR_INTERNAL },
  10116. { &ui_opponentName, "ui_opponentName", "Rebellion", CVAR_ARCHIVE|CVAR_INTERNAL },
  10117. { &ui_rankChange, "ui_rankChange", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10118. { &ui_freeSaber, "ui_freeSaber", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10119. { &ui_forcePowerDisable, "ui_forcePowerDisable", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10120. { &ui_redteam, "ui_redteam", "Empire", CVAR_ARCHIVE|CVAR_INTERNAL },
  10121. { &ui_blueteam, "ui_blueteam", "Rebellion", CVAR_ARCHIVE|CVAR_INTERNAL },
  10122. { &ui_dedicated, "ui_dedicated", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10123. { &ui_gameType, "ui_gametype", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10124. { &ui_joinGameType, "ui_joinGametype", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10125. { &ui_netGameType, "ui_netGametype", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10126. { &ui_actualNetGameType, "ui_actualNetGametype", "3", CVAR_ARCHIVE|CVAR_INTERNAL },
  10127. { &ui_redteam1, "ui_redteam1", "1", CVAR_ARCHIVE|CVAR_INTERNAL }, //rww - these used to all default to 0 (closed).. I changed them to 1 (human)
  10128. { &ui_redteam2, "ui_redteam2", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10129. { &ui_redteam3, "ui_redteam3", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10130. { &ui_redteam4, "ui_redteam4", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10131. { &ui_redteam5, "ui_redteam5", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10132. { &ui_redteam6, "ui_redteam6", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10133. { &ui_redteam7, "ui_redteam7", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10134. { &ui_redteam8, "ui_redteam8", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10135. { &ui_blueteam1, "ui_blueteam1", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10136. { &ui_blueteam2, "ui_blueteam2", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10137. { &ui_blueteam3, "ui_blueteam3", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10138. { &ui_blueteam4, "ui_blueteam4", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10139. { &ui_blueteam5, "ui_blueteam5", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10140. { &ui_blueteam6, "ui_blueteam6", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10141. { &ui_blueteam7, "ui_blueteam7", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10142. { &ui_blueteam8, "ui_blueteam8", "1", CVAR_ARCHIVE|CVAR_INTERNAL },
  10143. { &ui_netSource, "ui_netSource", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10144. { &ui_menuFiles, "ui_menuFilesMP", "ui/jampmenus.txt", CVAR_ARCHIVE|CVAR_INTERNAL },
  10145. { &ui_currentMap, "ui_currentMap", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10146. { &ui_currentNetMap, "ui_currentNetMap", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10147. { &ui_mapIndex, "ui_mapIndex", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10148. { &ui_currentOpponent, "ui_currentOpponent", "0", CVAR_ARCHIVE|CVAR_INTERNAL },
  10149. { &ui_selectedPlayer, "cg_selectedPlayer", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10150. { &ui_selectedPlayerName, "cg_selectedPlayerName", "", CVAR_ARCHIVE|CVAR_INTERNAL},
  10151. { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0", "", CVAR_ARCHIVE|CVAR_INTERNAL},
  10152. { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1", "", CVAR_ARCHIVE|CVAR_INTERNAL},
  10153. { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2", "", CVAR_ARCHIVE|CVAR_INTERNAL},
  10154. { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3", "", CVAR_ARCHIVE|CVAR_INTERNAL},
  10155. { &ui_singlePlayerActive, "ui_singlePlayerActive", "0", CVAR_INTERNAL},
  10156. { &ui_scoreAccuracy, "ui_scoreAccuracy", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10157. { &ui_scoreImpressives, "ui_scoreImpressives", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10158. { &ui_scoreExcellents, "ui_scoreExcellents", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10159. { &ui_scoreCaptures, "ui_scoreCaptures", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10160. { &ui_scoreDefends, "ui_scoreDefends", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10161. { &ui_scoreAssists, "ui_scoreAssists", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10162. { &ui_scoreGauntlets, "ui_scoreGauntlets", "0",CVAR_ARCHIVE|CVAR_INTERNAL},
  10163. { &ui_scoreScore, "ui_scoreScore", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10164. { &ui_scorePerfect, "ui_scorePerfect", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10165. { &ui_scoreTeam, "ui_scoreTeam", "0 to 0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10166. { &ui_scoreBase, "ui_scoreBase", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10167. { &ui_scoreTime, "ui_scoreTime", "00:00", CVAR_ARCHIVE|CVAR_INTERNAL},
  10168. { &ui_scoreTimeBonus, "ui_scoreTimeBonus", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10169. { &ui_scoreSkillBonus, "ui_scoreSkillBonus", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10170. { &ui_scoreShutoutBonus, "ui_scoreShutoutBonus", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10171. { &ui_fragLimit, "ui_fragLimit", "10", CVAR_INTERNAL},
  10172. { &ui_captureLimit, "ui_captureLimit", "5", CVAR_INTERNAL},
  10173. { &ui_findPlayer, "ui_findPlayer", "Kyle", CVAR_ARCHIVE|CVAR_INTERNAL},
  10174. { &ui_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE|CVAR_INTERNAL},
  10175. { &ui_realWarmUp, "g_warmup", "20", CVAR_ARCHIVE},
  10176. { &ui_realCaptureLimit, "capturelimit", "0", CVAR_SERVERINFO | CVAR_ARCHIVE| CVAR_NORESTART},
  10177. { &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE|CVAR_INTERNAL},
  10178. { &se_language, "se_language","english", CVAR_ARCHIVE | CVAR_NORESTART}, //text (string ed)
  10179. { &ui_bypassMainMenuLoad, "ui_bypassMainMenuLoad", "0", CVAR_INTERNAL },
  10180. //[RGBSabers]
  10181. { &ui_sab1_r, "ui_sab1_r", "255", CVAR_INTERNAL},
  10182. { &ui_sab1_g, "ui_sab1_g", "255", CVAR_INTERNAL},
  10183. { &ui_sab1_b, "ui_sab1_b", "255", CVAR_INTERNAL},
  10184. { &ui_sab2_r, "ui_sab2_r", "255", CVAR_INTERNAL},
  10185. { &ui_sab2_g, "ui_sab2_g", "255", CVAR_INTERNAL},
  10186. { &ui_sab2_b, "ui_sab2_b", "255", CVAR_INTERNAL},
  10187. //[/RGBSabers]
  10188. };
  10189. // bk001129 - made static to avoid aliasing
  10190. static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]);
  10191. /*
  10192. =================
  10193. UI_RegisterCvars
  10194. =================
  10195. */
  10196. void UI_RegisterCvars( void ) {
  10197. int i;
  10198. cvarTable_t *cv;
  10199. for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
  10200. trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags );
  10201. }
  10202. }
  10203. /*
  10204. =================
  10205. UI_UpdateCvars
  10206. =================
  10207. */
  10208. void UI_UpdateCvars( void ) {
  10209. int i;
  10210. cvarTable_t *cv;
  10211. for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
  10212. trap_Cvar_Update( cv->vmCvar );
  10213. }
  10214. }
  10215. /*
  10216. =================
  10217. ArenaServers_StopRefresh
  10218. =================
  10219. */
  10220. static void UI_StopServerRefresh( void )
  10221. {
  10222. int count;
  10223. if (!uiInfo.serverStatus.refreshActive) {
  10224. // not currently refreshing
  10225. return;
  10226. }
  10227. uiInfo.serverStatus.refreshActive = qfalse;
  10228. Com_Printf("%d servers listed in browser with %d players.\n",
  10229. uiInfo.serverStatus.numDisplayServers,
  10230. uiInfo.serverStatus.numPlayersOnServers);
  10231. count = trap_LAN_GetServerCount(ui_netSource.integer);
  10232. if (count - uiInfo.serverStatus.numDisplayServers > 0) {
  10233. Com_Printf("%d servers not listed due to filters, packet loss, or pings higher than %d\n",
  10234. count - uiInfo.serverStatus.numDisplayServers,
  10235. (int) trap_Cvar_VariableValue("cl_maxPing"));
  10236. }
  10237. }
  10238. /*
  10239. =================
  10240. UI_DoServerRefresh
  10241. =================
  10242. */
  10243. static void UI_DoServerRefresh( void )
  10244. {
  10245. qboolean wait = qfalse;
  10246. if (!uiInfo.serverStatus.refreshActive) {
  10247. return;
  10248. }
  10249. if (ui_netSource.integer != AS_FAVORITES) {
  10250. if (ui_netSource.integer == AS_LOCAL) {
  10251. if (!trap_LAN_GetServerCount(ui_netSource.integer)) {
  10252. wait = qtrue;
  10253. }
  10254. } else {
  10255. if (trap_LAN_GetServerCount(ui_netSource.integer) < 0) {
  10256. wait = qtrue;
  10257. }
  10258. }
  10259. }
  10260. if (uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime) {
  10261. if (wait) {
  10262. return;
  10263. }
  10264. }
  10265. // if still trying to retrieve pings
  10266. if (trap_LAN_UpdateVisiblePings(ui_netSource.integer)) {
  10267. uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
  10268. } else if (!wait) {
  10269. // get the last servers in the list
  10270. UI_BuildServerDisplayList(2);
  10271. // stop the refresh
  10272. UI_StopServerRefresh();
  10273. }
  10274. //
  10275. UI_BuildServerDisplayList(qfalse);
  10276. }
  10277. /*
  10278. =================
  10279. UI_StartServerRefresh
  10280. =================
  10281. */
  10282. static void UI_StartServerRefresh(qboolean full)
  10283. {
  10284. int i;
  10285. char *ptr;
  10286. qtime_t q;
  10287. trap_RealTime(&q);
  10288. trap_Cvar_Set( va("ui_lastServerRefresh_%i", ui_netSource.integer), va("%s-%i, %i @ %i:%2i", GetMonthAbbrevString(q.tm_mon),q.tm_mday, 1900+q.tm_year,q.tm_hour,q.tm_min));
  10289. if (!full) {
  10290. UI_UpdatePendingPings();
  10291. return;
  10292. }
  10293. uiInfo.serverStatus.refreshActive = qtrue;
  10294. uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 1000;
  10295. // clear number of displayed servers
  10296. uiInfo.serverStatus.numDisplayServers = 0;
  10297. uiInfo.serverStatus.numPlayersOnServers = 0;
  10298. // mark all servers as visible so we store ping updates for them
  10299. trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue);
  10300. // reset all the pings
  10301. trap_LAN_ResetPings(ui_netSource.integer);
  10302. //
  10303. if( ui_netSource.integer == AS_LOCAL ) {
  10304. trap_Cmd_ExecuteText( EXEC_NOW, "localservers\n" );
  10305. uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
  10306. return;
  10307. }
  10308. uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000;
  10309. if( ui_netSource.integer == AS_GLOBAL || ui_netSource.integer == AS_MPLAYER ) {
  10310. if( ui_netSource.integer == AS_GLOBAL ) {
  10311. i = 0;
  10312. }
  10313. else {
  10314. i = 1;
  10315. }
  10316. ptr = UI_Cvar_VariableString("debug_protocol");
  10317. if (strlen(ptr)) {
  10318. trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %s\n", i, ptr));
  10319. }
  10320. else {
  10321. trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %d\n", i, (int)trap_Cvar_VariableValue( "protocol" ) ) );
  10322. }
  10323. }
  10324. }
  10325. //[DynamicMemory_Sabers]
  10326. void UI_AllocMem(void **ptr, int sze){
  10327. *ptr = malloc(sze);
  10328. }
  10329. void UI_FreeMem(void *ptr){
  10330. free(ptr);
  10331. }
  10332. void UI_ReaAllocMem(void **ptr, int sze, int count){
  10333. *ptr = realloc(*ptr, sze * count);
  10334. }
  10335. //[/DynamicMemory_Sabers]