PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/codemp/ui/ui_force.c

https://github.com/Stoiss/jaMME
C | 1343 lines | 1087 code | 180 blank | 76 comment | 291 complexity | 4345834c75fcbd5b2d016f668d6b0a6e MD5 | raw file
Possible License(s): GPL-2.0
  1. //
  2. /*
  3. =======================================================================
  4. FORCE INTERFACE
  5. =======================================================================
  6. */
  7. // use this to get a demo build without an explicit demo build, i.e. to get the demo ui files to build
  8. #include "ui_local.h"
  9. #include "qcommon/qfiles.h"
  10. #include "ui_force.h"
  11. int uiForceSide = FORCE_LIGHTSIDE;
  12. int uiJediNonJedi = -1;
  13. int uiForceRank = FORCE_MASTERY_JEDI_KNIGHT;
  14. int uiMaxRank = MAX_FORCE_RANK;
  15. int uiMaxPoints = 20;
  16. int uiForceUsed = 0;
  17. int uiForceAvailable=0;
  18. extern const char *UI_TeamName(int team);
  19. qboolean gTouchedForce = qfalse;
  20. vmCvar_t ui_freeSaber, ui_forcePowerDisable;
  21. void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow);
  22. qboolean uiForcePowersDisabled[NUM_FORCE_POWERS] = {
  23. qfalse,//FP_HEAL,//instant
  24. qfalse,//FP_LEVITATION,//hold/duration
  25. qfalse,//FP_SPEED,//duration
  26. qfalse,//FP_PUSH,//hold/duration
  27. qfalse,//FP_PULL,//hold/duration
  28. qfalse,//FP_TELEPATHY,//instant
  29. qfalse,//FP_GRIP,//hold/duration
  30. qfalse,//FP_LIGHTNING,//hold/duration
  31. qfalse,//FP_RAGE,//duration
  32. qfalse,//FP_PROTECT,
  33. qfalse,//FP_ABSORB,
  34. qfalse,//FP_TEAM_HEAL,
  35. qfalse,//FP_TEAM_FORCE,
  36. qfalse,//FP_DRAIN,
  37. qfalse,//FP_SEE,
  38. qfalse,//FP_SABER_OFFENSE,
  39. qfalse,//FP_SABER_DEFENSE,
  40. qfalse//FP_SABERTHROW,
  41. };
  42. int uiForcePowersRank[NUM_FORCE_POWERS] = {
  43. 0,//FP_HEAL = 0,//instant
  44. 1,//FP_LEVITATION,//hold/duration, this one defaults to 1 (gives a free point)
  45. 0,//FP_SPEED,//duration
  46. 0,//FP_PUSH,//hold/duration
  47. 0,//FP_PULL,//hold/duration
  48. 0,//FP_TELEPATHY,//instant
  49. 0,//FP_GRIP,//hold/duration
  50. 0,//FP_LIGHTNING,//hold/duration
  51. 0,//FP_RAGE,//duration
  52. 0,//FP_PROTECT,
  53. 0,//FP_ABSORB,
  54. 0,//FP_TEAM_HEAL,
  55. 0,//FP_TEAM_FORCE,
  56. 0,//FP_DRAIN,
  57. 0,//FP_SEE,
  58. 1,//FP_SABER_OFFENSE, //default to 1 point in attack
  59. 1,//FP_SABER_DEFENSE, //defualt to 1 point in defense
  60. 0//FP_SABERTHROW,
  61. };
  62. int uiForcePowerDarkLight[NUM_FORCE_POWERS] = //0 == neutral
  63. { //nothing should be usable at rank 0..
  64. FORCE_LIGHTSIDE,//FP_HEAL,//instant
  65. 0,//FP_LEVITATION,//hold/duration
  66. 0,//FP_SPEED,//duration
  67. 0,//FP_PUSH,//hold/duration
  68. 0,//FP_PULL,//hold/duration
  69. FORCE_LIGHTSIDE,//FP_TELEPATHY,//instant
  70. FORCE_DARKSIDE,//FP_GRIP,//hold/duration
  71. FORCE_DARKSIDE,//FP_LIGHTNING,//hold/duration
  72. FORCE_DARKSIDE,//FP_RAGE,//duration
  73. FORCE_LIGHTSIDE,//FP_PROTECT,//duration
  74. FORCE_LIGHTSIDE,//FP_ABSORB,//duration
  75. FORCE_LIGHTSIDE,//FP_TEAM_HEAL,//instant
  76. FORCE_DARKSIDE,//FP_TEAM_FORCE,//instant
  77. FORCE_DARKSIDE,//FP_DRAIN,//hold/duration
  78. 0,//FP_SEE,//duration
  79. 0,//FP_SABER_OFFENSE,
  80. 0,//FP_SABER_DEFENSE,
  81. 0//FP_SABERTHROW,
  82. //NUM_FORCE_POWERS
  83. };
  84. int uiForceStarShaders[NUM_FORCE_STAR_IMAGES][2];
  85. int uiSaberColorShaders[NUM_SABER_COLORS];
  86. void UI_InitForceShaders(void)
  87. {
  88. uiForceStarShaders[0][0] = trap_R_RegisterShaderNoMip("forcestar0");
  89. uiForceStarShaders[0][1] = trap_R_RegisterShaderNoMip("forcestar0");
  90. uiForceStarShaders[1][0] = trap_R_RegisterShaderNoMip("forcecircle1");
  91. uiForceStarShaders[1][1] = trap_R_RegisterShaderNoMip("forcestar1");
  92. uiForceStarShaders[2][0] = trap_R_RegisterShaderNoMip("forcecircle2");
  93. uiForceStarShaders[2][1] = trap_R_RegisterShaderNoMip("forcestar2");
  94. uiForceStarShaders[3][0] = trap_R_RegisterShaderNoMip("forcecircle3");
  95. uiForceStarShaders[3][1] = trap_R_RegisterShaderNoMip("forcestar3");
  96. uiForceStarShaders[4][0] = trap_R_RegisterShaderNoMip("forcecircle4");
  97. uiForceStarShaders[4][1] = trap_R_RegisterShaderNoMip("forcestar4");
  98. uiForceStarShaders[5][0] = trap_R_RegisterShaderNoMip("forcecircle5");
  99. uiForceStarShaders[5][1] = trap_R_RegisterShaderNoMip("forcestar5");
  100. uiForceStarShaders[6][0] = trap_R_RegisterShaderNoMip("forcecircle6");
  101. uiForceStarShaders[6][1] = trap_R_RegisterShaderNoMip("forcestar6");
  102. uiForceStarShaders[7][0] = trap_R_RegisterShaderNoMip("forcecircle7");
  103. uiForceStarShaders[7][1] = trap_R_RegisterShaderNoMip("forcestar7");
  104. uiForceStarShaders[8][0] = trap_R_RegisterShaderNoMip("forcecircle8");
  105. uiForceStarShaders[8][1] = trap_R_RegisterShaderNoMip("forcestar8");
  106. uiSaberColorShaders[SABER_RED] = trap_R_RegisterShaderNoMip("menu/art/saber_red");
  107. uiSaberColorShaders[SABER_ORANGE] = trap_R_RegisterShaderNoMip("menu/art/saber_orange");
  108. uiSaberColorShaders[SABER_YELLOW] = trap_R_RegisterShaderNoMip("menu/art/saber_yellow");
  109. uiSaberColorShaders[SABER_GREEN] = trap_R_RegisterShaderNoMip("menu/art/saber_green");
  110. uiSaberColorShaders[SABER_BLUE] = trap_R_RegisterShaderNoMip("menu/art/saber_blue");
  111. uiSaberColorShaders[SABER_PURPLE] = trap_R_RegisterShaderNoMip("menu/art/saber_purple");
  112. }
  113. // Draw the stars spent on the current force power
  114. void UI_DrawForceStars(rectDef_t *rect, float scale, vec4_t color, int textStyle, int forceindex, int val, int min, int max)
  115. {
  116. int i,pad = 4;
  117. int xPos,width = 16;
  118. int starcolor;
  119. if (val < min || val > max)
  120. {
  121. val = min;
  122. }
  123. if (1) // if (val)
  124. {
  125. xPos = rect->x;
  126. for (i=FORCE_LEVEL_1;i<=max;i++)
  127. {
  128. starcolor = bgForcePowerCost[forceindex][i];
  129. if (uiForcePowersDisabled[forceindex])
  130. {
  131. vec4_t grColor = {0.2f, 0.2f, 0.2f, 1.0f};
  132. trap_R_SetColor(grColor);
  133. }
  134. if (val >= i)
  135. { // Draw a star.
  136. UI_DrawHandlePic( xPos, rect->y+6, width, width, uiForceStarShaders[starcolor][1] );
  137. }
  138. else
  139. { // Draw a circle.
  140. UI_DrawHandlePic( xPos, rect->y+6, width, width, uiForceStarShaders[starcolor][0] );
  141. }
  142. if (uiForcePowersDisabled[forceindex])
  143. {
  144. trap_R_SetColor(NULL);
  145. }
  146. xPos += width + pad;
  147. }
  148. }
  149. }
  150. // Set the client's force power layout.
  151. void UI_UpdateClientForcePowers(const char *teamArg)
  152. {
  153. trap_Cvar_Set( "forcepowers", va("%i-%i-%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i",
  154. uiForceRank, uiForceSide, uiForcePowersRank[0], uiForcePowersRank[1],
  155. uiForcePowersRank[2], uiForcePowersRank[3], uiForcePowersRank[4],
  156. uiForcePowersRank[5], uiForcePowersRank[6], uiForcePowersRank[7],
  157. uiForcePowersRank[8], uiForcePowersRank[9], uiForcePowersRank[10],
  158. uiForcePowersRank[11], uiForcePowersRank[12], uiForcePowersRank[13],
  159. uiForcePowersRank[14], uiForcePowersRank[15], uiForcePowersRank[16],
  160. uiForcePowersRank[17]) );
  161. if (gTouchedForce)
  162. {
  163. if (teamArg && teamArg[0])
  164. {
  165. trap_Cmd_ExecuteText( EXEC_APPEND, va("forcechanged \"%s\"\n", teamArg) );
  166. }
  167. else
  168. {
  169. trap_Cmd_ExecuteText( EXEC_APPEND, "forcechanged\n" );
  170. }
  171. }
  172. gTouchedForce = qfalse;
  173. }
  174. int UI_TranslateFCFIndex(int index)
  175. {
  176. if (uiForceSide == FORCE_LIGHTSIDE)
  177. {
  178. return index-uiInfo.forceConfigLightIndexBegin;
  179. }
  180. return index-uiInfo.forceConfigDarkIndexBegin;
  181. }
  182. void UI_SaveForceTemplate()
  183. {
  184. char *selectedName = UI_Cvar_VariableString("ui_SaveFCF");
  185. char fcfString[512];
  186. char forceStringValue[4];
  187. fileHandle_t f;
  188. int strPlace = 0;
  189. int forcePlace = 0;
  190. int i = 0;
  191. qboolean foundFeederItem = qfalse;
  192. if (!selectedName || !selectedName[0])
  193. {
  194. Com_Printf("You did not provide a name for the template.\n");
  195. return;
  196. }
  197. if (uiForceSide == FORCE_LIGHTSIDE)
  198. { //write it into the light side folder
  199. trap_FS_FOpenFile(va("forcecfg/light/%s.fcf", selectedName), &f, FS_WRITE);
  200. }
  201. else
  202. { //if it isn't light it must be dark
  203. trap_FS_FOpenFile(va("forcecfg/dark/%s.fcf", selectedName), &f, FS_WRITE);
  204. }
  205. if (!f)
  206. {
  207. Com_Printf("There was an error writing the template file (read-only?).\n");
  208. return;
  209. }
  210. Com_sprintf(fcfString, sizeof(fcfString), "%i-%i-", uiForceRank, uiForceSide);
  211. strPlace = strlen(fcfString);
  212. while (forcePlace < NUM_FORCE_POWERS)
  213. {
  214. Com_sprintf(forceStringValue, sizeof(forceStringValue), "%i", uiForcePowersRank[forcePlace]);
  215. //Just use the force digit even if multiple digits. Shouldn't be longer than 1.
  216. fcfString[strPlace] = forceStringValue[0];
  217. strPlace++;
  218. forcePlace++;
  219. }
  220. fcfString[strPlace] = '\n';
  221. fcfString[strPlace+1] = 0;
  222. trap_FS_Write(fcfString, strlen(fcfString), f);
  223. trap_FS_FCloseFile(f);
  224. Com_Printf("Template saved as \"%s\".\n", selectedName);
  225. //Now, update the FCF list
  226. UI_LoadForceConfig_List();
  227. //Then, scroll through and select the template for the file we just saved
  228. while (i < uiInfo.forceConfigCount)
  229. {
  230. if (!Q_stricmp(uiInfo.forceConfigNames[i], selectedName))
  231. {
  232. if ((uiForceSide == FORCE_LIGHTSIDE && uiInfo.forceConfigSide[i]) ||
  233. (uiForceSide == FORCE_DARKSIDE && !uiInfo.forceConfigSide[i]))
  234. {
  235. Menu_SetFeederSelection(NULL, FEEDER_FORCECFG, UI_TranslateFCFIndex(i), NULL);
  236. foundFeederItem = qtrue;
  237. }
  238. }
  239. i++;
  240. }
  241. //Else, go back to 0
  242. if (!foundFeederItem)
  243. {
  244. Menu_SetFeederSelection(NULL, FEEDER_FORCECFG, 0, NULL);
  245. }
  246. }
  247. //
  248. extern qboolean UI_TrueJediEnabled( void );
  249. void UpdateForceUsed()
  250. {
  251. int curpower, currank;
  252. menuDef_t *menu;
  253. // Currently we don't make a distinction between those that wish to play Jedi of lower than maximum skill.
  254. uiForceRank = uiMaxRank;
  255. uiForceUsed = 0;
  256. uiForceAvailable = forceMasteryPoints[uiForceRank];
  257. // Make sure that we have one freebie in jump.
  258. if (uiForcePowersRank[FP_LEVITATION]<1)
  259. {
  260. uiForcePowersRank[FP_LEVITATION]=1;
  261. }
  262. if ( UI_TrueJediEnabled() )
  263. {//true jedi mode is set
  264. if ( uiJediNonJedi == -1 )
  265. {
  266. int x = 0;
  267. qboolean clear = qfalse, update = qfalse;
  268. uiJediNonJedi = FORCE_NONJEDI;
  269. while ( x < NUM_FORCE_POWERS )
  270. {//if any force power is set, we must be a jedi
  271. if ( x == FP_LEVITATION || x == FP_SABER_OFFENSE )
  272. {
  273. if ( uiForcePowersRank[x] > 1 )
  274. {
  275. uiJediNonJedi = FORCE_JEDI;
  276. break;
  277. }
  278. else if ( uiForcePowersRank[x] > 0 )
  279. {
  280. clear = qtrue;
  281. }
  282. }
  283. else if ( uiForcePowersRank[x] > 0 )
  284. {
  285. uiJediNonJedi = FORCE_JEDI;
  286. break;
  287. }
  288. x++;
  289. }
  290. if ( uiJediNonJedi == FORCE_JEDI )
  291. {
  292. if ( uiForcePowersRank[FP_SABER_OFFENSE] < 1 )
  293. {
  294. uiForcePowersRank[FP_SABER_OFFENSE]=1;
  295. update = qtrue;
  296. }
  297. }
  298. else if ( clear )
  299. {
  300. x = 0;
  301. while ( x < NUM_FORCE_POWERS )
  302. {//clear all force
  303. uiForcePowersRank[x] = 0;
  304. x++;
  305. }
  306. update = qtrue;
  307. }
  308. if ( update )
  309. {
  310. int myTeam;
  311. myTeam = (int)(trap_Cvar_VariableValue("ui_myteam"));
  312. if ( myTeam != TEAM_SPECTATOR )
  313. {
  314. UI_UpdateClientForcePowers(UI_TeamName(myTeam));//will cause him to respawn, if it's been 5 seconds since last one
  315. }
  316. else
  317. {
  318. UI_UpdateClientForcePowers(NULL);//just update powers
  319. }
  320. }
  321. }
  322. }
  323. menu = Menus_FindByName("ingame_playerforce");
  324. // Set the cost of the saberattack according to whether its free.
  325. if (ui_freeSaber.integer)
  326. { // Make saber free
  327. bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 0;
  328. bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 0;
  329. // Make sure that we have one freebie in saber if applicable.
  330. if (uiForcePowersRank[FP_SABER_OFFENSE]<1)
  331. {
  332. uiForcePowersRank[FP_SABER_OFFENSE]=1;
  333. }
  334. if (uiForcePowersRank[FP_SABER_DEFENSE]<1)
  335. {
  336. uiForcePowersRank[FP_SABER_DEFENSE]=1;
  337. }
  338. if (menu)
  339. {
  340. Menu_ShowItemByName(menu, "setFP_SABER_DEFENSE", qtrue);
  341. Menu_ShowItemByName(menu, "setfp_saberthrow", qtrue);
  342. Menu_ShowItemByName(menu, "effectentry", qtrue);
  343. Menu_ShowItemByName(menu, "effectfield", qtrue);
  344. Menu_ShowItemByName(menu, "nosaber", qfalse);
  345. }
  346. }
  347. else
  348. { // Make saber normal cost
  349. bgForcePowerCost[FP_SABER_OFFENSE][FORCE_LEVEL_1] = 1;
  350. bgForcePowerCost[FP_SABER_DEFENSE][FORCE_LEVEL_1] = 1;
  351. // Also, check if there is no saberattack. If there isn't, there had better not be any defense or throw!
  352. if (uiForcePowersRank[FP_SABER_OFFENSE]<1)
  353. {
  354. uiForcePowersRank[FP_SABER_DEFENSE]=0;
  355. uiForcePowersRank[FP_SABERTHROW]=0;
  356. if (menu)
  357. {
  358. Menu_ShowItemByName(menu, "setfp_saberdefend", qfalse);
  359. Menu_ShowItemByName(menu, "setfp_saberthrow", qfalse);
  360. Menu_ShowItemByName(menu, "effectentry", qfalse);
  361. Menu_ShowItemByName(menu, "effectfield", qfalse);
  362. Menu_ShowItemByName(menu, "nosaber", qtrue);
  363. }
  364. }
  365. else
  366. {
  367. if (menu)
  368. {
  369. Menu_ShowItemByName(menu, "setfp_saberdefend", qtrue);
  370. Menu_ShowItemByName(menu, "setfp_saberthrow", qtrue);
  371. Menu_ShowItemByName(menu, "effectentry", qtrue);
  372. Menu_ShowItemByName(menu, "effectfield", qtrue);
  373. Menu_ShowItemByName(menu, "nosaber", qfalse);
  374. }
  375. }
  376. }
  377. // Make sure that we're still legal.
  378. for (curpower=0;curpower<NUM_FORCE_POWERS;curpower++)
  379. { // Make sure that our ranks are within legal limits.
  380. if (uiForcePowersRank[curpower]<0)
  381. uiForcePowersRank[curpower]=0;
  382. else if (uiForcePowersRank[curpower]>=NUM_FORCE_POWER_LEVELS)
  383. uiForcePowersRank[curpower]=(NUM_FORCE_POWER_LEVELS-1);
  384. for (currank=FORCE_LEVEL_1;currank<=uiForcePowersRank[curpower];currank++)
  385. { // Check on this force power
  386. if (uiForcePowersRank[curpower]>0)
  387. { // Do not charge the player for the one freebie in jump, or if there is one in saber.
  388. if ( (curpower == FP_LEVITATION && currank == FORCE_LEVEL_1) ||
  389. (curpower == FP_SABER_OFFENSE && currank == FORCE_LEVEL_1 && ui_freeSaber.integer) ||
  390. (curpower == FP_SABER_DEFENSE && currank == FORCE_LEVEL_1 && ui_freeSaber.integer) )
  391. {
  392. // Do nothing (written this way for clarity)
  393. }
  394. else
  395. { // Check if we can accrue the cost of this power.
  396. if (bgForcePowerCost[curpower][currank] > uiForceAvailable)
  397. { // We can't afford this power. Break to the next one.
  398. // Remove this power from the player's roster.
  399. uiForcePowersRank[curpower] = currank-1;
  400. break;
  401. }
  402. else
  403. { // Sure we can afford it.
  404. uiForceUsed += bgForcePowerCost[curpower][currank];
  405. uiForceAvailable -= bgForcePowerCost[curpower][currank];
  406. }
  407. }
  408. }
  409. }
  410. }
  411. }
  412. //Mostly parts of other functions merged into one another.
  413. //Puts the current UI stuff into a string, legalizes it, and then reads it back out.
  414. void UI_ReadLegalForce(void)
  415. {
  416. char fcfString[512];
  417. char forceStringValue[4];
  418. int strPlace = 0;
  419. int forcePlace = 0;
  420. int i = 0;
  421. char singleBuf[64];
  422. char info[MAX_INFO_VALUE];
  423. int c = 0;
  424. int iBuf = 0;
  425. int forcePowerRank = 0;
  426. int currank = 0;
  427. int forceTeam = 0;
  428. qboolean updateForceLater = qfalse;
  429. //First, stick them into a string.
  430. Com_sprintf(fcfString, sizeof(fcfString), "%i-%i-", uiForceRank, uiForceSide);
  431. strPlace = strlen(fcfString);
  432. while (forcePlace < NUM_FORCE_POWERS)
  433. {
  434. Com_sprintf(forceStringValue, sizeof(forceStringValue), "%i", uiForcePowersRank[forcePlace]);
  435. //Just use the force digit even if multiple digits. Shouldn't be longer than 1.
  436. fcfString[strPlace] = forceStringValue[0];
  437. strPlace++;
  438. forcePlace++;
  439. }
  440. fcfString[strPlace] = '\n';
  441. fcfString[strPlace+1] = 0;
  442. info[0] = '\0';
  443. trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
  444. if (atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ))
  445. {
  446. switch((int)(trap_Cvar_VariableValue("ui_myteam")))
  447. {
  448. case TEAM_RED:
  449. forceTeam = FORCE_DARKSIDE;
  450. break;
  451. case TEAM_BLUE:
  452. forceTeam = FORCE_LIGHTSIDE;
  453. break;
  454. default:
  455. break;
  456. }
  457. }
  458. //Second, legalize them.
  459. if (!BG_LegalizedForcePowers(fcfString, uiMaxRank, ui_freeSaber.integer, forceTeam, atoi( Info_ValueForKey( info, "g_gametype" )), 0))
  460. { //if they were illegal, we should refresh them.
  461. updateForceLater = qtrue;
  462. }
  463. //Lastly, put them back into the UI storage from the legalized string
  464. i = 0;
  465. while (fcfString[i] && fcfString[i] != '-')
  466. {
  467. singleBuf[c] = fcfString[i];
  468. c++;
  469. i++;
  470. }
  471. singleBuf[c] = 0;
  472. c = 0;
  473. i++;
  474. iBuf = atoi(singleBuf);
  475. if (iBuf > uiMaxRank || iBuf < 0)
  476. { //this force config uses a rank level higher than our currently restricted level.. so we can't use it
  477. //FIXME: Print a message indicating this to the user
  478. // return;
  479. }
  480. uiForceRank = iBuf;
  481. while (fcfString[i] && fcfString[i] != '-')
  482. {
  483. singleBuf[c] = fcfString[i];
  484. c++;
  485. i++;
  486. }
  487. singleBuf[c] = 0;
  488. c = 0;
  489. i++;
  490. uiForceSide = atoi(singleBuf);
  491. if (uiForceSide != FORCE_LIGHTSIDE &&
  492. uiForceSide != FORCE_DARKSIDE)
  493. {
  494. uiForceSide = FORCE_LIGHTSIDE;
  495. return;
  496. }
  497. //clear out the existing powers
  498. while (c < NUM_FORCE_POWERS)
  499. {
  500. uiForcePowersRank[c] = 0;
  501. c++;
  502. }
  503. uiForceUsed = 0;
  504. uiForceAvailable = forceMasteryPoints[uiForceRank];
  505. gTouchedForce = qtrue;
  506. for (c=0;fcfString[i]&&c<NUM_FORCE_POWERS;c++,i++)
  507. {
  508. singleBuf[0] = fcfString[i];
  509. singleBuf[1] = 0;
  510. iBuf = atoi(singleBuf); // So, that means that Force Power "c" wants to be set to rank "iBuf".
  511. if (iBuf < 0)
  512. {
  513. iBuf = 0;
  514. }
  515. forcePowerRank = iBuf;
  516. if (forcePowerRank > FORCE_LEVEL_3 || forcePowerRank < 0)
  517. { //err.. not correct
  518. continue; // skip this power
  519. }
  520. if (uiForcePowerDarkLight[c] && uiForcePowerDarkLight[c] != uiForceSide)
  521. { //Apparently the user has crafted a force config that has powers that don't fit with the config's side.
  522. continue; // skip this power
  523. }
  524. // Accrue cost for each assigned rank for this power.
  525. for (currank=FORCE_LEVEL_1;currank<=forcePowerRank;currank++)
  526. {
  527. if (bgForcePowerCost[c][currank] > uiForceAvailable)
  528. { // Break out, we can't afford any more power.
  529. break;
  530. }
  531. // Pay for this rank of this power.
  532. uiForceUsed += bgForcePowerCost[c][currank];
  533. uiForceAvailable -= bgForcePowerCost[c][currank];
  534. uiForcePowersRank[c]++;
  535. }
  536. }
  537. if (uiForcePowersRank[FP_LEVITATION] < 1)
  538. {
  539. uiForcePowersRank[FP_LEVITATION]=1;
  540. }
  541. if (uiForcePowersRank[FP_SABER_OFFENSE] < 1 && ui_freeSaber.integer)
  542. {
  543. uiForcePowersRank[FP_SABER_OFFENSE]=1;
  544. }
  545. if (uiForcePowersRank[FP_SABER_DEFENSE] < 1 && ui_freeSaber.integer)
  546. {
  547. uiForcePowersRank[FP_SABER_DEFENSE]=1;
  548. }
  549. UpdateForceUsed();
  550. if (updateForceLater)
  551. {
  552. gTouchedForce = qtrue;
  553. UI_UpdateClientForcePowers(NULL);
  554. }
  555. }
  556. void UI_UpdateForcePowers()
  557. {
  558. char *forcePowers = UI_Cvar_VariableString("forcepowers");
  559. char readBuf[256];
  560. int i = 0, i_f = 0, i_r = 0;
  561. uiForceSide = 0;
  562. if (forcePowers && forcePowers[0])
  563. {
  564. while (forcePowers[i])
  565. {
  566. i_r = 0;
  567. while (forcePowers[i] && forcePowers[i] != '-' && i_r < 255)
  568. {
  569. readBuf[i_r] = forcePowers[i];
  570. i_r++;
  571. i++;
  572. }
  573. readBuf[i_r] = '\0';
  574. if (i_r >= 255 || !forcePowers[i] || forcePowers[i] != '-')
  575. {
  576. uiForceSide = 0;
  577. goto validitycheck;
  578. }
  579. uiForceRank = atoi(readBuf);
  580. i_r = 0;
  581. if (uiForceRank > uiMaxRank)
  582. {
  583. uiForceRank = uiMaxRank;
  584. }
  585. i++;
  586. while (forcePowers[i] && forcePowers[i] != '-' && i_r < 255)
  587. {
  588. readBuf[i_r] = forcePowers[i];
  589. i_r++;
  590. i++;
  591. }
  592. readBuf[i_r] = '\0';
  593. if (i_r >= 255 || !forcePowers[i] || forcePowers[i] != '-')
  594. {
  595. uiForceSide = 0;
  596. goto validitycheck;
  597. }
  598. uiForceSide = atoi(readBuf);
  599. i_r = 0;
  600. i++;
  601. i_f = FP_HEAL;
  602. while (forcePowers[i] && i_f < NUM_FORCE_POWERS)
  603. {
  604. readBuf[0] = forcePowers[i];
  605. readBuf[1] = '\0';
  606. uiForcePowersRank[i_f] = atoi(readBuf);
  607. if (i_f == FP_LEVITATION &&
  608. uiForcePowersRank[i_f] < 1)
  609. {
  610. uiForcePowersRank[i_f] = 1;
  611. }
  612. if (i_f == FP_SABER_OFFENSE &&
  613. uiForcePowersRank[i_f] < 1 &&
  614. ui_freeSaber.integer)
  615. {
  616. uiForcePowersRank[i_f] = 1;
  617. }
  618. if (i_f == FP_SABER_DEFENSE &&
  619. uiForcePowersRank[i_f] < 1 &&
  620. ui_freeSaber.integer)
  621. {
  622. uiForcePowersRank[i_f] = 1;
  623. }
  624. i_f++;
  625. i++;
  626. }
  627. if (i_f < NUM_FORCE_POWERS)
  628. { //info for all the powers wasn't there..
  629. uiForceSide = 0;
  630. goto validitycheck;
  631. }
  632. i++;
  633. }
  634. }
  635. validitycheck:
  636. if (!uiForceSide)
  637. {
  638. uiForceSide = 1;
  639. uiForceRank = 1;
  640. i = 0;
  641. while (i < NUM_FORCE_POWERS)
  642. {
  643. if (i == FP_LEVITATION)
  644. {
  645. uiForcePowersRank[i] = 1;
  646. }
  647. else if (i == FP_SABER_OFFENSE && ui_freeSaber.integer)
  648. {
  649. uiForcePowersRank[i] = 1;
  650. }
  651. else if (i == FP_SABER_DEFENSE && ui_freeSaber.integer)
  652. {
  653. uiForcePowersRank[i] = 1;
  654. }
  655. else
  656. {
  657. uiForcePowersRank[i] = 0;
  658. }
  659. i++;
  660. }
  661. UI_UpdateClientForcePowers(NULL);
  662. }
  663. UpdateForceUsed();
  664. }
  665. extern int uiSkinColor;
  666. extern int uiHoldSkinColor;
  667. qboolean UI_SkinColor_HandleKey(int flags, float *special, int key, int num, int min, int max, int type)
  668. {
  669. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER)
  670. {
  671. int i = num;
  672. if (key == A_MOUSE2)
  673. {
  674. i--;
  675. }
  676. else
  677. {
  678. i++;
  679. }
  680. if (i < min)
  681. {
  682. i = max;
  683. }
  684. else if (i > max)
  685. {
  686. i = min;
  687. }
  688. num = i;
  689. uiSkinColor = num;
  690. uiHoldSkinColor = uiSkinColor;
  691. UI_FeederSelection(FEEDER_Q3HEADS, uiInfo.q3SelectedHead, NULL);
  692. return qtrue;
  693. }
  694. return qfalse;
  695. }
  696. qboolean UI_ForceSide_HandleKey(int flags, float *special, int key, int num, int min, int max, int type)
  697. {
  698. char info[MAX_INFO_VALUE];
  699. info[0] = '\0';
  700. trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
  701. if (atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ))
  702. {
  703. switch((int)(trap_Cvar_VariableValue("ui_myteam")))
  704. {
  705. case TEAM_RED:
  706. return qfalse;
  707. case TEAM_BLUE:
  708. return qfalse;
  709. default:
  710. break;
  711. }
  712. }
  713. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER)
  714. {
  715. int i = num;
  716. int x = 0;
  717. //update the feeder item selection, it might be different depending on side
  718. Menu_SetFeederSelection(NULL, FEEDER_FORCECFG, 0, NULL);
  719. if (key == A_MOUSE2)
  720. {
  721. i--;
  722. }
  723. else
  724. {
  725. i++;
  726. }
  727. if (i < min)
  728. {
  729. i = max;
  730. }
  731. else if (i > max)
  732. {
  733. i = min;
  734. }
  735. num = i;
  736. uiForceSide = num;
  737. // Resetting power ranks based on if light or dark side is chosen
  738. while (x < NUM_FORCE_POWERS)
  739. {
  740. if (uiForcePowerDarkLight[x] && uiForceSide != uiForcePowerDarkLight[x])
  741. {
  742. uiForcePowersRank[x] = 0;
  743. }
  744. x++;
  745. }
  746. UpdateForceUsed();
  747. gTouchedForce = qtrue;
  748. return qtrue;
  749. }
  750. return qfalse;
  751. }
  752. qboolean UI_JediNonJedi_HandleKey(int flags, float *special, int key, int num, int min, int max, int type)
  753. {
  754. char info[MAX_INFO_VALUE];
  755. info[0] = '\0';
  756. trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
  757. if ( !UI_TrueJediEnabled() )
  758. {//true jedi mode is not set
  759. return qfalse;
  760. }
  761. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER)
  762. {
  763. int i = num;
  764. int x = 0;
  765. if (key == A_MOUSE2)
  766. {
  767. i--;
  768. }
  769. else
  770. {
  771. i++;
  772. }
  773. if (i < min)
  774. {
  775. i = max;
  776. }
  777. else if (i > max)
  778. {
  779. i = min;
  780. }
  781. num = i;
  782. uiJediNonJedi = num;
  783. // Resetting power ranks based on if light or dark side is chosen
  784. if ( !num )
  785. {//not a jedi?
  786. int myTeam = (int)(trap_Cvar_VariableValue("ui_myteam"));
  787. while ( x < NUM_FORCE_POWERS )
  788. {//clear all force powers
  789. uiForcePowersRank[x] = 0;
  790. x++;
  791. }
  792. if ( myTeam != TEAM_SPECTATOR )
  793. {
  794. UI_UpdateClientForcePowers(UI_TeamName(myTeam));//will cause him to respawn, if it's been 5 seconds since last one
  795. }
  796. else
  797. {
  798. UI_UpdateClientForcePowers(NULL);//just update powers
  799. }
  800. }
  801. else if ( num )
  802. {//a jedi, set the minimums, hopefuly they know to set the rest!
  803. if ( uiForcePowersRank[FP_LEVITATION] < FORCE_LEVEL_1 )
  804. {//force jump 1 minimum
  805. uiForcePowersRank[FP_LEVITATION] = FORCE_LEVEL_1;
  806. }
  807. if ( uiForcePowersRank[FP_SABER_OFFENSE] < FORCE_LEVEL_1 )
  808. {//saber attack 1, minimum
  809. uiForcePowersRank[FP_SABER_OFFENSE] = FORCE_LEVEL_1;
  810. }
  811. }
  812. UpdateForceUsed();
  813. gTouchedForce = qtrue;
  814. return qtrue;
  815. }
  816. return qfalse;
  817. }
  818. qboolean UI_ForceMaxRank_HandleKey(int flags, float *special, int key, int num, int min, int max, int type)
  819. {
  820. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER)
  821. {
  822. int i = num;
  823. if (key == A_MOUSE2)
  824. {
  825. i--;
  826. }
  827. else
  828. {
  829. i++;
  830. }
  831. if (i < min)
  832. {
  833. i = max;
  834. }
  835. else if (i > max)
  836. {
  837. i = min;
  838. }
  839. num = i;
  840. uiMaxRank = num;
  841. trap_Cvar_Set( "g_maxForceRank", va("%i", num));
  842. // The update force used will remove overallocated powers automatically.
  843. UpdateForceUsed();
  844. gTouchedForce = qtrue;
  845. return qtrue;
  846. }
  847. return qfalse;
  848. }
  849. // This function will either raise or lower a power by one rank.
  850. qboolean UI_ForcePowerRank_HandleKey(int flags, float *special, int key, int num, int min, int max, int type)
  851. {
  852. qboolean raising;
  853. if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER || key == A_KP_ENTER || key == A_BACKSPACE)
  854. {
  855. int forcepower, rank;
  856. //this will give us the index as long as UI_FORCE_RANK is always one below the first force rank index
  857. forcepower = (type-UI_FORCE_RANK)-1;
  858. //the power is disabled on the server
  859. if (uiForcePowersDisabled[forcepower])
  860. {
  861. return qtrue;
  862. }
  863. // If we are not on the same side as a power, or if we are not of any rank at all.
  864. if (uiForcePowerDarkLight[forcepower] && uiForceSide != uiForcePowerDarkLight[forcepower])
  865. {
  866. return qtrue;
  867. }
  868. else if (forcepower == FP_SABER_DEFENSE || forcepower == FP_SABERTHROW)
  869. { // Saberdefend and saberthrow can't be bought if there is no saberattack
  870. if (uiForcePowersRank[FP_SABER_OFFENSE] < 1)
  871. {
  872. return qtrue;
  873. }
  874. }
  875. if (type == UI_FORCE_RANK_LEVITATION)
  876. {
  877. min += 1;
  878. }
  879. if (type == UI_FORCE_RANK_SABERATTACK && ui_freeSaber.integer)
  880. {
  881. min += 1;
  882. }
  883. if (type == UI_FORCE_RANK_SABERDEFEND && ui_freeSaber.integer)
  884. {
  885. min += 1;
  886. }
  887. if (key == A_MOUSE2 || key == A_BACKSPACE)
  888. { // Lower a point.
  889. if (uiForcePowersRank[forcepower]<=min)
  890. {
  891. return qtrue;
  892. }
  893. raising = qfalse;
  894. }
  895. else
  896. { // Raise a point.
  897. if (uiForcePowersRank[forcepower]>=max)
  898. {
  899. return qtrue;
  900. }
  901. raising = qtrue;
  902. }
  903. if (raising)
  904. { // Check if we can accrue the cost of this power.
  905. rank = uiForcePowersRank[forcepower]+1;
  906. if (bgForcePowerCost[forcepower][rank] > uiForceAvailable)
  907. { // We can't afford this power. Abandon ship.
  908. return qtrue;
  909. }
  910. else
  911. { // Sure we can afford it.
  912. uiForceUsed += bgForcePowerCost[forcepower][rank];
  913. uiForceAvailable -= bgForcePowerCost[forcepower][rank];
  914. uiForcePowersRank[forcepower]=rank;
  915. }
  916. }
  917. else
  918. { // Lower the point.
  919. rank = uiForcePowersRank[forcepower];
  920. uiForceUsed -= bgForcePowerCost[forcepower][rank];
  921. uiForceAvailable += bgForcePowerCost[forcepower][rank];
  922. uiForcePowersRank[forcepower]--;
  923. }
  924. UpdateForceUsed();
  925. gTouchedForce = qtrue;
  926. return qtrue;
  927. }
  928. return qfalse;
  929. }
  930. int gCustRank = 0;
  931. int gCustSide = 0;
  932. int gCustPowersRank[NUM_FORCE_POWERS] = {
  933. 0,//FP_HEAL = 0,//instant
  934. 1,//FP_LEVITATION,//hold/duration, this one defaults to 1 (gives a free point)
  935. 0,//FP_SPEED,//duration
  936. 0,//FP_PUSH,//hold/duration
  937. 0,//FP_PULL,//hold/duration
  938. 0,//FP_TELEPATHY,//instant
  939. 0,//FP_GRIP,//hold/duration
  940. 0,//FP_LIGHTNING,//hold/duration
  941. 0,//FP_RAGE,//duration
  942. 0,//FP_PROTECT,
  943. 0,//FP_ABSORB,
  944. 0,//FP_TEAM_HEAL,
  945. 0,//FP_TEAM_FORCE,
  946. 0,//FP_DRAIN,
  947. 0,//FP_SEE,
  948. 0,//FP_SABER_OFFENSE,
  949. 0,//FP_SABER_DEFENSE,
  950. 0//FP_SABERTHROW,
  951. };
  952. /*
  953. =================
  954. UI_ForceConfigHandle
  955. =================
  956. */
  957. void UI_ForceConfigHandle( int oldindex, int newindex )
  958. {
  959. fileHandle_t f;
  960. int len = 0;
  961. int i = 0;
  962. int c = 0;
  963. int iBuf = 0, forcePowerRank, currank;
  964. char fcfBuffer[8192];
  965. char singleBuf[64];
  966. char info[MAX_INFO_VALUE];
  967. int forceTeam = 0;
  968. if (oldindex == 0)
  969. { //switching out from custom config, so first shove the current values into the custom storage
  970. i = 0;
  971. while (i < NUM_FORCE_POWERS)
  972. {
  973. gCustPowersRank[i] = uiForcePowersRank[i];
  974. i++;
  975. }
  976. gCustRank = uiForceRank;
  977. gCustSide = uiForceSide;
  978. }
  979. if (newindex == 0)
  980. { //switching back to custom, shove the values back in from the custom storage
  981. i = 0;
  982. uiForceUsed = 0;
  983. gTouchedForce = qtrue;
  984. while (i < NUM_FORCE_POWERS)
  985. {
  986. uiForcePowersRank[i] = gCustPowersRank[i];
  987. uiForceUsed += uiForcePowersRank[i];
  988. i++;
  989. }
  990. uiForceRank = gCustRank;
  991. uiForceSide = gCustSide;
  992. UpdateForceUsed();
  993. return;
  994. }
  995. //If we made it here, we want to load in a new config
  996. if (uiForceSide == FORCE_LIGHTSIDE)
  997. { //we should only be displaying lightside configs, so.. look in the light folder
  998. newindex += uiInfo.forceConfigLightIndexBegin;
  999. if (newindex >= uiInfo.forceConfigCount)
  1000. {
  1001. return;
  1002. }
  1003. len = trap_FS_FOpenFile(va("forcecfg/light/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
  1004. }
  1005. else
  1006. { //else dark
  1007. newindex += uiInfo.forceConfigDarkIndexBegin;
  1008. if (newindex >= uiInfo.forceConfigCount || newindex > uiInfo.forceConfigLightIndexBegin)
  1009. { //dark gets read in before light
  1010. return;
  1011. }
  1012. len = trap_FS_FOpenFile(va("forcecfg/dark/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
  1013. }
  1014. if (len <= 0)
  1015. { //This should not have happened. But, before we quit out, attempt searching the other light/dark folder for the file.
  1016. if (uiForceSide == FORCE_LIGHTSIDE)
  1017. {
  1018. len = trap_FS_FOpenFile(va("forcecfg/dark/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
  1019. }
  1020. else
  1021. {
  1022. len = trap_FS_FOpenFile(va("forcecfg/light/%s.fcf", uiInfo.forceConfigNames[newindex]), &f, FS_READ);
  1023. }
  1024. if (len <= 0)
  1025. { //still failure? Oh well.
  1026. return;
  1027. }
  1028. }
  1029. if (len >= 8192)
  1030. {
  1031. return;
  1032. }
  1033. trap_FS_Read(fcfBuffer, len, f);
  1034. fcfBuffer[len] = 0;
  1035. trap_FS_FCloseFile(f);
  1036. i = 0;
  1037. info[0] = '\0';
  1038. trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
  1039. if (atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ))
  1040. {
  1041. switch((int)(trap_Cvar_VariableValue("ui_myteam")))
  1042. {
  1043. case TEAM_RED:
  1044. forceTeam = FORCE_DARKSIDE;
  1045. break;
  1046. case TEAM_BLUE:
  1047. forceTeam = FORCE_LIGHTSIDE;
  1048. break;
  1049. default:
  1050. break;
  1051. }
  1052. }
  1053. BG_LegalizedForcePowers(fcfBuffer, uiMaxRank, ui_freeSaber.integer, forceTeam, atoi( Info_ValueForKey( info, "g_gametype" )), 0);
  1054. //legalize the config based on the max rank
  1055. //now that we're done with the handle, it's time to parse our force data out of the string
  1056. //we store strings in rank-side-xxxxxxxxx format (where the x's are individual force power levels)
  1057. while (fcfBuffer[i] && fcfBuffer[i] != '-')
  1058. {
  1059. singleBuf[c] = fcfBuffer[i];
  1060. c++;
  1061. i++;
  1062. }
  1063. singleBuf[c] = 0;
  1064. c = 0;
  1065. i++;
  1066. iBuf = atoi(singleBuf);
  1067. if (iBuf > uiMaxRank || iBuf < 0)
  1068. { //this force config uses a rank level higher than our currently restricted level.. so we can't use it
  1069. //FIXME: Print a message indicating this to the user
  1070. return;
  1071. }
  1072. uiForceRank = iBuf;
  1073. while (fcfBuffer[i] && fcfBuffer[i] != '-')
  1074. {
  1075. singleBuf[c] = fcfBuffer[i];
  1076. c++;
  1077. i++;
  1078. }
  1079. singleBuf[c] = 0;
  1080. c = 0;
  1081. i++;
  1082. uiForceSide = atoi(singleBuf);
  1083. if (uiForceSide != FORCE_LIGHTSIDE &&
  1084. uiForceSide != FORCE_DARKSIDE)
  1085. {
  1086. uiForceSide = FORCE_LIGHTSIDE;
  1087. return;
  1088. }
  1089. //clear out the existing powers
  1090. while (c < NUM_FORCE_POWERS)
  1091. {
  1092. /*
  1093. if (c==FP_LEVITATION)
  1094. {
  1095. uiForcePowersRank[c]=1;
  1096. }
  1097. else if (c==FP_SABER_OFFENSE && ui_freeSaber.integer)
  1098. {
  1099. uiForcePowersRank[c]=1;
  1100. }
  1101. else if (c==FP_SABER_DEFENSE && ui_freeSaber.integer)
  1102. {
  1103. uiForcePowersRank[c]=1;
  1104. }
  1105. else
  1106. {
  1107. uiForcePowersRank[c] = 0;
  1108. }
  1109. */
  1110. //rww - don't need to do these checks. Just trust whatever the saber config says.
  1111. uiForcePowersRank[c] = 0;
  1112. c++;
  1113. }
  1114. uiForceUsed = 0;
  1115. uiForceAvailable = forceMasteryPoints[uiForceRank];
  1116. gTouchedForce = qtrue;
  1117. for (c=0;fcfBuffer[i]&&c<NUM_FORCE_POWERS;c++,i++)
  1118. {
  1119. singleBuf[0] = fcfBuffer[i];
  1120. singleBuf[1] = 0;
  1121. iBuf = atoi(singleBuf); // So, that means that Force Power "c" wants to be set to rank "iBuf".
  1122. if (iBuf < 0)
  1123. {
  1124. iBuf = 0;
  1125. }
  1126. forcePowerRank = iBuf;
  1127. if (forcePowerRank > FORCE_LEVEL_3 || forcePowerRank < 0)
  1128. { //err.. not correct
  1129. continue; // skip this power
  1130. }
  1131. if (uiForcePowerDarkLight[c] && uiForcePowerDarkLight[c] != uiForceSide)
  1132. { //Apparently the user has crafted a force config that has powers that don't fit with the config's side.
  1133. continue; // skip this power
  1134. }
  1135. // Accrue cost for each assigned rank for this power.
  1136. for (currank=FORCE_LEVEL_1;currank<=forcePowerRank;currank++)
  1137. {
  1138. if (bgForcePowerCost[c][currank] > uiForceAvailable)
  1139. { // Break out, we can't afford any more power.
  1140. break;
  1141. }
  1142. // Pay for this rank of this power.
  1143. uiForceUsed += bgForcePowerCost[c][currank];
  1144. uiForceAvailable -= bgForcePowerCost[c][currank];
  1145. uiForcePowersRank[c]++;
  1146. }
  1147. }
  1148. if (uiForcePowersRank[FP_LEVITATION] < 1)
  1149. {
  1150. uiForcePowersRank[FP_LEVITATION]=1;
  1151. }
  1152. if (uiForcePowersRank[FP_SABER_OFFENSE] < 1 && ui_freeSaber.integer)
  1153. {
  1154. uiForcePowersRank[FP_SABER_OFFENSE]=1;
  1155. }
  1156. if (uiForcePowersRank[FP_SABER_DEFENSE] < 1 && ui_freeSaber.integer)
  1157. {
  1158. uiForcePowersRank[FP_SABER_DEFENSE]=1;
  1159. }
  1160. UpdateForceUsed();
  1161. }