Guest User

csqc_hud_vanilla.qc laser cannon/mjolnir pick-up animation (hooray)

a guest
Jul 23rd, 2021
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.83 KB | None | 0 0
  1. // This file implements NQ, QW, and N64-style huds in csqc. Its meant to be complete, while not otherwise being that different.
  2. // The hud layout+items used are specific to vanilla Quake. For the mission packs, you should use the appropriate alternative huds.
  3. //
  4. // The entry points are at the bottom of the file.
  5. // You can just add this file (and fteextensions.qc or qsextensions.qc) into any mod and then just adapt it as desired.
  6. //
  7. // Note that it doesn't understand viewsizes all that well, but no worse than eg scr_sbaralpha<1 in QS (its default). (this keeps the api spec simpler.)
  8. // the 'simple csqc' api means that this file (and api defs) is all you need for a hud, and can be directly embedded into a regular nq progs.dat, if needed.
  9. //
  10. // I have made attempts to avoid copying the engine code, however I will not be held liable if there's any GPL contagion.
  11. // There is otherwise no license for the code in this file.
  12.  
  13.  
  14. /*autocvars:
  15. cl_sbar: alternative layouts (sorry for this complication, but mneh).
  16. 0: QuakeWorld style hud
  17. 1: Vanilla style hud
  18. 2: n64-style hud
  19. 3: n64-style with meshes instead of models, where supported.
  20. cl_hudswap: QW/n64 ammo+weapons are on the
  21. 0: right
  22. 1: left
  23. scr_sbaralpha: opacity of backgroundy elements
  24. */
  25.  
  26. // items. FIXME: you should share these with your ssqc...
  27. float IT_SHOTGUN = 1<<0;
  28. float IT_SUPER_SHOTGUN = 1<<1;
  29. float IT_NAILGUN = 1<<2;
  30. float IT_SUPER_NAILGUN = 1<<3;
  31. float IT_GRENADE_LAUNCHER = 1<<4;
  32. float IT_ROCKET_LAUNCHER = 1<<5;
  33. float IT_LIGHTNING = 1<<6;
  34.  
  35. float IT_MJOLNIR = 1<<7;
  36.  
  37. float IT_SHELLS = 1<<8;
  38. float IT_NAILS = 1<<9;
  39. float IT_ROCKETS = 1<<10;
  40. float IT_CELLS = 1<<11;
  41. float IT_AXE = 1<<12;
  42.  
  43. float IT_ARMOR1 = 1<<13;
  44. float IT_ARMOR2 = 1<<14;
  45. float IT_ARMOR3 = 1<<15;
  46. //float IT_SUPERHEALTH = 1<<16;
  47.  
  48. float IT_KEY1 = 1<<17;
  49. float IT_KEY2 = 1<<18;
  50. float IT_INVISIBILITY = 1<<19;
  51. float IT_INVULNERABILITY = 1<<20;
  52. float IT_SUIT = 1<<21;
  53. float IT_QUAD = 1<<22;
  54. float IT_LASER_CANNON = 1<<23;
  55.  
  56. float IT2_RUNE1 = 1<<5;
  57. float IT2_RUNE2 = 1<<6;
  58. float IT2_RUNE3 = 1<<7;
  59. float IT2_RUNE4 = 1<<8;
  60.  
  61.  
  62. //wad image names in array form, for easier access.
  63. static string number[10] = {
  64. "gfx/num_0",
  65. "gfx/num_1",
  66. "gfx/num_2",
  67. "gfx/num_3",
  68. "gfx/num_4",
  69. "gfx/num_5",
  70. "gfx/num_6",
  71. "gfx/num_7",
  72. "gfx/num_8",
  73. "gfx/num_9"
  74. };
  75. static string anumber[10] = {
  76. "gfx/anum_0",
  77. "gfx/anum_1",
  78. "gfx/anum_2",
  79. "gfx/anum_3",
  80. "gfx/anum_4",
  81. "gfx/anum_5",
  82. "gfx/anum_6",
  83. "gfx/anum_7",
  84. "gfx/anum_8",
  85. "gfx/anum_9"
  86. };
  87. static string weaponnames[] = {
  88. "shotgun",
  89. "sshotgun",
  90. "nailgun",
  91. "snailgun",
  92. "rlaunch",
  93. "srlaunch",
  94. "lightng",
  95. "laser",
  96. "mjolnir",
  97. #define WEAPONICONS 9
  98. #define LIGHTNING_WIDTH 48
  99. };
  100. static string facetab[] = {
  101. "gfx/face5", "gfx/face4", "gfx/face3", "gfx/face2", "gfx/face1",
  102. "gfx/face_p5", "gfx/face_p4", "gfx/face_p3", "gfx/face_p2", "gfx/face_p1",
  103. "gfx/face_inv2", "gfx/face_quad", "gfx/face_invis", "gfx/face_invul2"
  104. };
  105.  
  106.  
  107.  
  108. //copies of stats, for easier access
  109. static float sitems; //copy of .items
  110. static float sitems2; //copy of .items2 (or serverflags)
  111. static float sweapon; //copy of .weapon
  112. static float shealth; //copy of .health
  113.  
  114. //Note: these are not tracked for splitscreen, which limits them to one player. We're lazy and just don't update them.
  115. static float flashtime[WEAPONICONS]; //tracks the time that various items were obtained, so we can flash stuff accordingly.
  116. static float painfinishtime;//tracks when we took damage, for flinching.
  117.  
  118.  
  119. //registers the various pics so they're ready as needed.
  120. static void() Hud_Init
  121. {
  122. float i;
  123. precache_pic("gfx/sbar", TRUE);
  124. precache_pic("gfx/ibar", TRUE);
  125. for (i = 0; i < 10; i++)
  126. {
  127. precache_pic(number[i], TRUE);
  128. precache_pic(anumber[i], TRUE);
  129. }
  130.  
  131. precache_pic("gfx/sb_armor1", TRUE);
  132. precache_pic("gfx/sb_armor2", TRUE);
  133. precache_pic("gfx/sb_armor3", TRUE);
  134. precache_pic("gfx/disc", TRUE);
  135.  
  136. precache_pic("gfx/sb_shells", TRUE);
  137. precache_pic("gfx/sb_nails", TRUE);
  138. precache_pic("gfx/sb_rocket", TRUE);
  139. precache_pic("gfx/sb_cells", TRUE);
  140.  
  141. precache_pic("gfx/sb_key1", TRUE);
  142. precache_pic("gfx/sb_key2", TRUE);
  143. precache_pic("gfx/sb_invis", TRUE);
  144. precache_pic("gfx/sb_invuln", TRUE);
  145. precache_pic("gfx/sb_suit", TRUE);
  146. precache_pic("gfx/sb_quad", TRUE);
  147.  
  148. precache_pic("gfx/sb_sigil1", TRUE);
  149. precache_pic("gfx/sb_sigil2", TRUE);
  150. precache_pic("gfx/sb_sigil3", TRUE);
  151. precache_pic("gfx/sb_sigil4", TRUE);
  152.  
  153. for (i = 0; i < weaponnames.length; i++)
  154. {
  155. precache_pic(strcat("gfx/inv_", weaponnames[i]), TRUE);
  156. precache_pic(strcat("gfx/inv2_", weaponnames[i]), TRUE);
  157. precache_pic(strcat("gfx/inva1_", weaponnames[i]), TRUE);
  158. precache_pic(strcat("gfx/inva2_", weaponnames[i]), TRUE);
  159. precache_pic(strcat("gfx/inva3_", weaponnames[i]), TRUE);
  160. precache_pic(strcat("gfx/inva4_", weaponnames[i]), TRUE);
  161. precache_pic(strcat("gfx/inva5_", weaponnames[i]), TRUE);
  162. }
  163. for (i = 0; i < facetab.length; i++)
  164. precache_pic(facetab[i], TRUE);
  165. };
  166.  
  167.  
  168.  
  169.  
  170. static void(vector pos, float value, float threshhold) Hud_DrawLargeValue =
  171. {
  172. float c;
  173. float len;
  174. string s;
  175. if (value < 0)
  176. value = 0; //hrm
  177. if (value>999)
  178. value = 999;
  179.  
  180. s = ftos(floor(value));
  181. len = strlen(s);
  182.  
  183. pos_x += 24 * (3-len);
  184.  
  185.  
  186. if (value <= threshhold)
  187. { //use alternate (red) numbers
  188.  
  189. while(len>0)
  190. {
  191. len--;
  192. c = str2chr(s, len);
  193.  
  194. drawpic(pos+len * '24 0 0', anumber[c-'0'], '24 24 0', '1 1 1', 1, 0);
  195. }
  196. }
  197. else
  198. { //use normal numbers
  199.  
  200. while(len>0)
  201. {
  202. len--;
  203. c = str2chr(s, len);
  204.  
  205. drawpic(pos+len * '24 0 0', number[c-'0'], '24 24 0', '1 1 1', 1, 0);
  206. }
  207. }
  208. };
  209.  
  210. static void(float type, vector pos, float drawback) Hud_DrawAmmoCount =
  211. {
  212. string s;
  213. float value;
  214. float len;
  215. float c;
  216. value = getstatf(STAT_SHELLS+type);
  217. if (value < 0)
  218. value = 0; //hrm
  219. if (value>999)
  220. value = 999;
  221.  
  222. if (drawback)
  223. {
  224. drawsubpic(pos, '42 11', "gfx/ibar", [(3.0/320)+type*(48.0/320), 0], [42.0/320, 11.0/24], '1 1 1', autocvar(scr_sbaralpha, 0.75), 0);
  225. pos_x += 8;
  226. }
  227.  
  228. s = ftos(floor(value));
  229. len = strlen(s);
  230.  
  231. pos_x += 8 * (3-len);
  232. while(len>0)
  233. {
  234. len--;
  235. c = str2chr(s, len);
  236. drawcharacter(pos+len * '8 0 0', (18-'0') + c, '8 8 0', '1 1 1', 1, 0);
  237. }
  238. };
  239.  
  240. static void(float num, vector pos) Hud_DrawWeapon =
  241. {
  242. string prefix;
  243. float flash = (time - flashtime[num])*10;
  244. if (flash >= 10)
  245. {
  246. if (sweapon == (1<<num))
  247. prefix = "gfx/inv2_";
  248. else
  249. prefix = "gfx/inv_";
  250. }
  251. else
  252. {
  253. static string tab[] = {"gfx/inva1_","gfx/inva2_","gfx/inva3_","gfx/inva4_","gfx/inva5_"};
  254. if (flash >= 5)
  255. flash -= 5;
  256. prefix = tab[flash];
  257. }
  258.  
  259. drawpic(pos, strcat(prefix, weaponnames[num]), '24 16 0', '1 1 1', 1, 0);
  260. };
  261. static void(float num, float lflashtime, float iscurrent, vector pos, float drawwidth, float imgwidth, float alt) Hud_DrawWeaponEx =
  262. {
  263. string prefix;
  264. float flash = (time - lflashtime)*10;
  265. if (flash >= 10)
  266. {
  267. if (iscurrent)
  268. prefix = "gfx/inv2_";
  269. else
  270. prefix = "gfx/inv_";
  271. }
  272. else
  273. {
  274. static string tab[] = {"gfx/inva1_","gfx/inva2_","gfx/inva3_","gfx/inva4_","gfx/inva5_"};
  275. if (flash >= 5)
  276. flash -= 5;
  277. prefix = tab[flash];
  278. }
  279. if (alt)
  280. drawsubpic(pos, [drawwidth, 16], "gfx/R_PLASMA.lmp", '0 0 0', [drawwidth/imgwidth, 1], '1 1 1', 1, 0);
  281. else
  282. drawsubpic(pos, [drawwidth, 16], strcat(prefix, weaponnames[num]), '0 0 0', [drawwidth/imgwidth, 1], '1 1 1', 1, 0);
  283. };
  284.  
  285. static string(float f, float chars, string lead) FormatFloat
  286. {
  287. string s = ftos(f);
  288. if (f < 10 && chars >= 3)
  289. s = strcat(lead, lead, s);
  290. else if (f < 10 && chars == 2)
  291. s = strcat(lead, s);
  292. else if (f < 100 && chars >= 3)
  293. s = strcat(lead, s);
  294. return s;
  295. };
  296.  
  297. static void(vector pos) Hud_CoopScores_SBar =
  298. {
  299. string s;
  300. float nsecs;
  301. float nmins;
  302. vector sbar = pos;
  303. drawpic(sbar, "gfx/scorebar", '320 24 0', '1 1 1', autocvar(scr_sbaralpha, 0.75), 0);
  304.  
  305. s = strcat("Monsters:", FormatFloat(getstatf(STAT_KILLEDMONSTERS), 3, " "), "/", FormatFloat(getstatf(STAT_TOTALMONSTERS), 3, " "));
  306. drawstring(sbar + '8 4', s, '8 8 0', '1 1 1', 1, 0);
  307. s = strcat("Secrets :", FormatFloat(getstatf(STAT_FOUNDSECRETS), 3, " "), "/", FormatFloat(getstatf(STAT_TOTALSECRETS), 3, " "));
  308. drawstring(sbar + '8 12', s, '8 8 0', '1 1 1', 1, 0);
  309.  
  310. nmins = floor(time/60);
  311. nsecs = floor(time - nmins*60);
  312. s = strcat("Time :", FormatFloat(nmins, 3, " "), ":", FormatFloat(nsecs, 2, "0"));
  313. drawstring(sbar + '184 4', s, '8 8 0', '1 1 1', 1, 0);
  314.  
  315. drawstring(sbar + '232 12' - strlen(world.message)*'4 0', world.message, '8 8 0', '1 1 1', 1, 0);
  316. };
  317.  
  318. static void Hud_PicOrModel(vector topleft, string pic, string showmodel, float showskin, float speed)
  319. {
  320. vector sz = '24 24';
  321. #ifdef DP_QC_RENDER_SCENE //requires fteextensions.qc instead of qsextensions.qc
  322. if (autocvar(cl_sbar, 1) >= 3)
  323. if (checkextension("DP_QC_RENDER_SCENE"))
  324. {
  325. //reset view props and wipe entity lists
  326. clearscene();
  327.  
  328. //set up the various view details, set up the renderer to be a little larger than the intended size... it avoids harsh cuts.
  329. setviewprop(VF_MIN, topleft - sz);
  330. setviewprop(VF_SIZE, sz * 3);
  331. setviewprop(VF_DRAWENGINESBAR, FALSE);
  332. setviewprop(VF_DRAWCROSSHAIR, FALSE);
  333. setviewprop(VF_DRAWWORLD, FALSE);
  334. setviewprop(VF_AFOV, 30); //a small fov reduces perspective distortions without making it look like its isometric.
  335. setviewprop(VF_ANGLES, '15 0 0'); //angle downwards slightly
  336. makevectors('15 0 0');
  337. setviewprop(VF_ORIGIN, v_forward*-256); //and move the camera away so that we can position the model at the center without needing to worry about the tilt.
  338.  
  339. //spawn a (reusable) entity for our scene
  340. static entity hudpicent;
  341. if (!hudpicent)
  342. hudpicent = spawn();
  343. precache_model(showmodel);
  344. setmodel(hudpicent, showmodel);
  345. hudpicent.angles_y = cltime*speed;
  346. hudpicent.skin = showskin;
  347. makevectors(hudpicent.angles);
  348. //make sure its centered
  349. vector org = (hudpicent.maxs+hudpicent.mins)*0.5;
  350. setorigin(hudpicent, - v_forward*org_x + v_right*org_y - v_up*org_z);
  351. //and now copy it into the scene
  352. addentity(hudpicent);
  353.  
  354. //and ask the engine to actually draw that single-entity scene. Think of this as a drawpic call.
  355. renderscene();
  356.  
  357. return;
  358. }
  359. #endif
  360. drawpic(topleft, pic, '24 24 0', '1 1 1', 1, 0);
  361. };
  362.  
  363. static void Hud_DrawFace(vector pos)
  364. {
  365. string face;
  366. if (sitems & IT_INVISIBILITY)
  367. { //invis can go first, because its the most obvious image difference.
  368. if (sitems & IT_INVULNERABILITY)
  369. face = facetab[10]; //special double-powerup image!
  370. else
  371. face = facetab[12];
  372. }
  373. else if (sitems & IT_QUAD)
  374. face = facetab[11];
  375. else if (sitems & IT_INVULNERABILITY)
  376. face = facetab[13];
  377. else
  378. {
  379. float frame = shealth/20;
  380. if (frame < 0)
  381. frame = 0;
  382. else if (frame > 4)
  383. frame = 4;
  384. if (painfinishtime > time)
  385. frame += 5; //pain.
  386. face = facetab[frame];
  387. }
  388.  
  389. if (shealth > 100)
  390. Hud_PicOrModel(pos, face, "maps/b_bh100.bsp", 0, -90);
  391. else if (shealth > 50)
  392. Hud_PicOrModel(pos, face, "maps/b_bh25.bsp", 0, -90);
  393. else
  394. Hud_PicOrModel(pos, face, "maps/b_bh10.bsp", 0, -90);
  395. };
  396.  
  397. static float WellDoWeHaveAnyFuckingCustomGunsOrWhat()
  398. {
  399. if (sweapon == IT_NAILGUN && getstatf(NAILGUNMODE) == 1)
  400. return TRUE;
  401. else if (sweapon == IT_SUPER_NAILGUN && getstatf(SUPERNAILGUNMODE) == 1)
  402. return TRUE;
  403. else if (sweapon == IT_GRENADE_LAUNCHER && getstatf(GRENADELAUNCHERMODE) == 1)
  404. return TRUE;
  405. else if (sweapon == IT_ROCKET_LAUNCHER && getstatf(ROCKETLAUNCHERMODE) == 1)
  406. return TRUE;
  407. else if (sweapon == IT_LIGHTNING && getstatf(LIGHTNINGGUNMODE) == 1)
  408. return TRUE;
  409. else if (sweapon == IT_LASER_CANNON && getstatf(LASERCANNONMODE) == 3)
  410. return TRUE;
  411. else
  412. return FALSE;
  413. }
  414. static void Hud_DrawSBar(vector pos, vector virtsize)
  415. {
  416. drawpic(pos, "gfx/sbar", '320 24 0', '1 1 1', autocvar(scr_sbaralpha, 0.75), 0);
  417.  
  418. if (sitems & IT_INVULNERABILITY)
  419. {
  420. drawpic(pos, "gfx/disc", '24 24 0', '1 1 1', 1, 0);
  421. Hud_DrawLargeValue(pos+'24 0 0', 999, 25);
  422. }
  423. else
  424. {
  425. Hud_DrawLargeValue(pos+'24 0 0', getstatf(STAT_ARMOR), 25);
  426. if (sitems & IT_ARMOR3)
  427. drawpic(pos, "gfx/sb_armor3", '24 24 0', '1 1 1', 1, 0);
  428. else if (sitems & IT_ARMOR2)
  429. drawpic(pos, "gfx/sb_armor2", '24 24 0', '1 1 1', 1, 0);
  430. else if (sitems & IT_ARMOR1)
  431. drawpic(pos, "gfx/sb_armor1", '24 24 0', '1 1 1', 1, 0);
  432. }
  433.  
  434.  
  435. Hud_DrawFace(pos+'112 0 0');
  436. Hud_DrawLargeValue(pos+'136 0 0', shealth, 25);
  437.  
  438. if (sitems & IT_SHELLS)
  439. drawpic(pos+'224 0 0', "gfx/sb_shells", '24 24 0', '1 1 1', 1, 0);
  440. else if (sitems & IT_NAILS)
  441. drawpic(pos+'224 0 0', "gfx/sb_nails", '24 24 0', '1 1 1', 1, 0);
  442. else if (sitems & IT_ROCKETS)
  443. drawpic(pos+'224 0 0', "gfx/sb_rocket", '24 24 0', '1 1 1', 1, 0);
  444. else if (sitems & IT_CELLS)
  445. drawpic(pos+'224 0 0', "gfx/sb_cells", '24 24 0', '1 1 1', 1, 0);
  446. else if ((sweapon == IT_NAILGUN && getstatf(NAILGUNMODE) == 1) || (sweapon == IT_SUPER_NAILGUN && getstatf(SUPERNAILGUNMODE) == 1))
  447. drawpic(pos+'224 0 0', "gfx/R_AMMOLAVA.lmp", '24 24 0', '1 1 1', 1, 0);
  448. else if ((sweapon == IT_GRENADE_LAUNCHER && getstatf(GRENADELAUNCHERMODE) == 1) || (sweapon == IT_ROCKET_LAUNCHER && getstatf(ROCKETLAUNCHERMODE) == 1))
  449. drawpic(pos+'224 0 0', "gfx/R_AMMOPLASMA.lmp", '24 24 0', '1 1 1', 1, 0);
  450. else if ((sweapon == IT_LIGHTNING && getstatf(LIGHTNINGGUNMODE) == 1) || (sweapon == IT_LASER_CANNON && getstatf(LASERCANNONMODE) == 3))
  451. drawpic(pos+'224 0 0', "gfx/R_AMMOMULTI.lmp", '24 24 0', '1 1 1', 1, 0);
  452. Hud_DrawLargeValue(pos+'248 0 0', getstatf(STAT_AMMO), 10);
  453. };
  454.  
  455. static void Hud_DrawIBar(vector pos, vector br)
  456. {
  457. //standard nq sbar
  458. drawpic(pos+'0 9 0', "gfx/IBAR1.lmp", '320 16 0', '1 1 1', autocvar(scr_sbaralpha, 0.75), 0);
  459.  
  460. if (sitems & IT_SHOTGUN) Hud_DrawWeapon(0, pos+[24*1.7,9]);
  461. if (sitems & IT_SUPER_SHOTGUN) Hud_DrawWeapon(1, pos+[24*2.7,9]);
  462. if (sitems & IT_NAILGUN) Hud_DrawWeapon(2, pos+[24*3.7,9]);
  463. if (sitems & IT_SUPER_NAILGUN) Hud_DrawWeapon(3, pos+[24*4.7,9]);
  464. if (sitems & IT_GRENADE_LAUNCHER) Hud_DrawWeapon(4, pos+[24*5.7,9]);
  465. if (sitems & IT_ROCKET_LAUNCHER) Hud_DrawWeapon(5, pos+[24*6.7,9]);
  466. if (sitems & IT_LIGHTNING) Hud_DrawWeaponEx(6, flashtime[6], sweapon==IT_LIGHTNING, pos+[24*7.7,9], LIGHTNING_WIDTH, LIGHTNING_WIDTH, 0);
  467. if (sitems & IT_LASER_CANNON) Hud_DrawWeaponEx(7, flashtime[8], sweapon==IT_LASER_CANNON, pos+[24*9.7,9], 24, 24, 0);
  468. if (sitems & IT_MJOLNIR) Hud_DrawWeaponEx(8, flashtime[8], sweapon==IT_MJOLNIR, pos+[24*10.7,9], 24, 24, 0);
  469. if (sweapon == IT_NAILGUN && getstatf(NAILGUNMODE) == 1) drawpic(pos+[24*3.7,9], "gfx/R_LAVA.lmp", '24 16 0', '1 1 1', 1, 0);
  470. if (sweapon == IT_SUPER_NAILGUN && getstatf(SUPERNAILGUNMODE) == 1) drawpic(pos+[24*4.7,9], "gfx/R_SUPERLAVA.lmp", '24 16 0', '1 1 1', 1, 0);
  471. if (sweapon == IT_GRENADE_LAUNCHER && getstatf(GRENADELAUNCHERMODE) == 1) drawpic(pos+[24*5.7,9], "gfx/R_GREN.lmp", '24 16 0', '1 1 1', 1, 0);
  472. if (sweapon == IT_GRENADE_LAUNCHER && getstatf(GRENADELAUNCHERMODE) == 2) drawpic(pos+[24*5.7,9], "gfx/INV2_PROX_GREN.lmp", '24 16 0', '1 1 1', 1, 0);
  473. if (sweapon == IT_ROCKET_LAUNCHER && getstatf(ROCKETLAUNCHERMODE) == 1) drawpic(pos+[24*6.7,9], "gfx/R_MULTIROCK.lmp", '24 16 0', '1 1 1', 1, 0);
  474. if (sweapon == IT_LIGHTNING && getstatf(LIGHTNINGGUNMODE) == 1) Hud_DrawWeaponEx(6, flashtime[6], sweapon==IT_LIGHTNING, pos+[24*7.7,9], LIGHTNING_WIDTH, LIGHTNING_WIDTH, 1);
  475. if (sweapon == IT_LASER_CANNON && getstatf(LASERCANNONMODE) == 2) drawpic(pos+[24*9.7,9], "gfx/INV2_LR.lmp", '24 16 0', '1 1 1', 1, 0);
  476. if (sweapon == IT_LASER_CANNON && getstatf(LASERCANNONMODE) == 3) drawpic(pos+[24*9.7,9], "gfx/INV2_RG.lmp", '24 16 0', '1 1 1', 1, 0);
  477.  
  478. if (deathmatch)
  479. { //should probably show team scores, but this mimics vanilla
  480. pos_x += 194;
  481. for (float i = -1; i >= -4; i--)
  482. {
  483. string frags = getplayerkeyvalue(i, "frags");
  484. if not (frags)
  485. break;
  486. vector top = stov(getplayerkeyvalue(i, "topcolor_rgb"));
  487. vector bot = stov(getplayerkeyvalue(i, "bottomcolor_rgb"));
  488. drawfill(pos+[0,1], [28,3], top, 0.75, 0);
  489. drawfill(pos+[0,4], [28,4], bot, 0.75, 0);
  490. drawstring(pos+[2,0], strpad(-3, frags), [8,8], [1,1,1],1,0);
  491. if (player_localentnum == stof(getplayerkeyvalue(i, "viewentity")))
  492. {
  493. drawcharacter(pos+[-4,0], 0xe010, [8,8], [1,1,1],1, 0);
  494. drawcharacter(pos+[24,0], 0xe011, [8,8], [1,1,1],1, 0);
  495. }
  496. pos_x += 8*4;
  497. }
  498. }
  499.  
  500. pos = [(br_x-320)/2];
  501.  
  502. if (WellDoWeHaveAnyFuckingCustomGunsOrWhat())
  503. drawpic(pos+'64 0 0', "gfx/IBAR2_1.lmp", '192 24 0', '1 1 1', autocvar(scr_sbaralpha, 0.75), 0);
  504. else
  505. drawpic(pos+'64 0 0', "gfx/IBAR2_2.lmp", '192 24 0', '1 1 1', autocvar(scr_sbaralpha, 0.75), 0);
  506.  
  507. Hud_DrawAmmoCount(0, pos + '76 0 0', FALSE);
  508. Hud_DrawAmmoCount(1, pos + '124 0 0', FALSE);
  509. Hud_DrawAmmoCount(2, pos + '172 0 0', FALSE);
  510. Hud_DrawAmmoCount(3, pos + '218 0 0', FALSE);
  511.  
  512. if (sitems & IT_KEY1)
  513. drawpic(pos+'80 8 0', "gfx/sb_key1", '16 16 0', '1 1 1', 1, 0);
  514. if (sitems & IT_KEY2)
  515. drawpic(pos+'96 8 0', "gfx/sb_key2", '16 16 0', '1 1 1', 1, 0);
  516. if (sitems & IT_INVISIBILITY)
  517. drawpic(pos+'112 8 0', "gfx/sb_invis", '16 16 0', '1 1 1', 1, 0);
  518. if (sitems & IT_INVULNERABILITY)
  519. drawpic(pos+'128 8 0', "gfx/sb_invuln", '16 16 0', '1 1 1', 1, 0);
  520. if (sitems & IT_SUIT)
  521. drawpic(pos+'144 8 0', "gfx/sb_suit", '16 16 0', '1 1 1', 1, 0);
  522. if (sitems & IT_QUAD)
  523. drawpic(pos+'160 8 0', "gfx/sb_quad", '16 16 0', '1 1 1', 1, 0);
  524. if (getstatf(WETON))
  525. drawpic(pos+'176 8 0', "gfx/SB_WSUIT.lmp", '16 16 0', '1 1 1', 1, 0);
  526. if (getstatf(EMPATHYON))
  527. drawpic(pos+'192 8 0', "gfx/SB_ESHLD.lmp", '16 16 0', '1 1 1', 1, 0);
  528. if (sitems2 & IT2_RUNE2) // power shield
  529. drawpic(pos+'208 8 0', "gfx/R_SHIELD1.lmp", '16 16 0', '1 1 1', 1, 0);
  530. if (sitems2 & IT2_RUNE3) // anti-grav belt
  531. drawpic(pos+'224 8 0', "gfx/R_AGRAV1.lmp", '16 16 0', '1 1 1', 1, 0);
  532. };
  533.  
  534. float numclientseats;
  535. static void Hud_Draw(vector virtsize, float scoreboard)
  536. {
  537. vector pos;
  538. float oitems = sitems;
  539. float oitems2 = sitems2;
  540. float ohealth = shealth;
  541.  
  542. pos_x = (virtsize_x-320)/2;
  543. pos_y = virtsize_y;
  544.  
  545. sitems = getstatbits(STAT_ITEMS, 0, 24); //note that we could use getstati to read the items stat, but it'd degrade when then cast to a float, and QSS+DP don't support ints, so we have to use two floats.
  546. sitems2 = getstatbits(STAT_ITEMS, 23, 9);
  547. sweapon = getstatf(STAT_ACTIVEWEAPON);
  548. shealth = getstatf(STAT_HEALTH);
  549. //note that ssqc can provide custom stats, eg: clientstat(STAT_USER+n, EV_FLOAT, items3); can then be read by us with float items3 = getstatf(STAT_USER+n);
  550.  
  551. if (shealth <= 0)
  552. scoreboard = TRUE;
  553.  
  554. if (numclientseats <= 1)
  555. { //note that we only track one player's stats. with splitscreen we need to stop looking for changes otherwise we'd see them all the time.
  556. if (ohealth && sitems != oitems)
  557. {
  558. for (float f = 0; f < 7; f++)
  559. {
  560. if ((sitems & (1<<f)) && !(oitems & (1<<f)))
  561. flashtime[f] = time;
  562. }
  563. if ((sitems2 & IT_LASER_CANNON) && !(oitems2 & IT_LASER_CANNON))
  564. flashtime[7] = time;
  565. if ((sitems & IT_MJOLNIR) && !(oitems & IT_MJOLNIR))
  566. flashtime[8] = time;
  567. }
  568. }
  569.  
  570. if (autocvar(viewsize, 100) < 120)
  571. {
  572. if (scoreboard)
  573. Hud_CoopScores_SBar(pos - '0 24 0');
  574. else
  575. Hud_DrawSBar(pos - '0 24 0', virtsize);
  576.  
  577. if (autocvar(viewsize, 100) < 110)
  578. Hud_DrawIBar(pos - '0 48 0', virtsize);
  579. }
  580. };
  581.  
  582. //lame entry point, just so that we know when damage was taken
  583. float(float save, float take, vector dir) CSQC_Parse_Damage =
  584. {
  585. if (numclientseats <= 1)
  586. painfinishtime = time + 0.2;
  587. return FALSE; //let the engine handle any red tints etc
  588. };
  589.  
  590. //Hud entry point!
  591. //showscores is set if +scores is held (check health yourself).
  592. void(vector virtsize, float showscores) CSQC_DrawHud =
  593. {
  594. Hud_Draw(virtsize, showscores);
  595. };
  596.  
  597. void(float apilevel, string enginename, float engineversion) CSQC_Init =
  598. {
  599. Hud_Init();
  600. };
  601.  
  602.  
Advertisement
Add Comment
Please, Sign In to add comment