A megawad compilation for doom
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

534 lines
16KB

  1. // written in BCS
  2. #include "../../compiler/lib/zcommon.h"
  3. #library "vote"
  4. strict namespace
  5. {
  6. #if 1
  7. // mess with this all you want
  8. #define TIME_START 60 // in ticks, 35 = 1 second; 15*35 = 15 seconds, ect
  9. #define TIME_YELLOW 15 // the time at which the timer goes yellow
  10. #define TIME_ORANGE 10 // same as above, just orange
  11. #define TIME_RED 5 // red
  12. // dont touch this
  13. #define STATE_VOTEWAIT 0
  14. #define STATE_COUNTDOWN 1
  15. #define STATE_CHECKTIE 2
  16. #define STATE_RESULTS 3
  17. #endif
  18. struct obj_confetti
  19. {
  20. int x;
  21. int y;
  22. int velx;
  23. int vely;
  24. int animnum;
  25. int confnum;
  26. str image;
  27. };
  28. struct obj_confetti objs_confetti[128];
  29. // this is where the names that show up in the votes are, and the map names to go to when that wad wins
  30. str votenames[64][2] =
  31. {
  32. // wad name // the map this vote will take players too
  33. { "Alien Vendetta", "AV01" }, // 0
  34. { "Combat Shock", "CS01" }, // 1 Slaughter Map
  35. { "Combat Shock 2", "CS201" }, // 2 Slaughter Map
  36. { "Hell Revealed", "HR01" }, // 3
  37. { "Hell Revealed 2", "HR201" }, // 4
  38. { "Kamasutra", "KS01" }, // 5
  39. { "New Gothic Movement 1", "NG101" }, // 6 Slaughter Map
  40. { "Shai'tans Luck", "SL20" }, // 7
  41. { "Speed Of Doom", "SOD01" }, // 8
  42. { "Dark Tartarus", "TAT01" }, // 9 Slaughter Map
  43. { "VanGaurd", "VAN01" }, // 10
  44. { "Scythe 2", "SC201" }, // 11
  45. { "Whispers Of Satan", "WOS01" }, // 12
  46. };
  47. int votes[64]; // holds the votes
  48. int votessorted[64][2]; // all the votes, sorted
  49. int votecount = 0; // amount of votes made
  50. int votechosen = 0; // the winner
  51. int time_ticks = TIME_START*35; // the time left in ticks
  52. int time_seconds = TIME_START; // the time left in seconds
  53. int players[64]; // all the player info
  54. fixed hud_width; // the position of the right of the screen
  55. fixed hud_height; // the position of the bottom of the screen
  56. fixed hud_width_half; // the position of the center of the screen on the x axis
  57. fixed hud_height_half; // the position of the center of the screen on the y axis
  58. int state; // state of the voting system
  59. int state_clock; // custom timer
  60. bool levelstarted = false; // false at the start of a level, goes true when the first player joins
  61. // when there are no players left, go back to the hub
  62. script "PlayerWatch" open
  63. {
  64. levelstarted = false;
  65. while(1)
  66. {
  67. // if a player has joined
  68. if(levelstarted)
  69. {
  70. // if the playercount goes back to 0
  71. if(playercount() == 0)
  72. {
  73. // go back to the hub
  74. hudmessagebold(s:"Going back to the hub in T Minus 5"; 0, 9997, 0, hud_width_half + 0.4, 112.0, 10.0);
  75. Delay(35 * 6);
  76. ChangeLevel("Hub", 0, 0, -1);
  77. }
  78. }
  79. // if nobody has joined yet
  80. else
  81. {
  82. // wait for someone to join
  83. if(playercount() > 0)
  84. {
  85. //the level has been started
  86. levelstarted = true;
  87. }
  88. }
  89. delay(1);
  90. }
  91. }
  92. // when a player enters the game, set them to have no vote
  93. script "PlayerEnter" enter
  94. {
  95. if(GetLevelInfo(LEVELINFO_LEVELNUM) != 99) { Terminate; } // this entire file should of been in the map script, oh well
  96. int pnum = playernumber();
  97. players[pnum] = -1;
  98. // sync the joining player's vars
  99. bubble_sort();
  100. ACS_Execute(568, 0, votechosen);
  101. ACS_Execute(569, 0, time_seconds);
  102. ACS_ExecuteAlways(570, 0, state);
  103. }
  104. // keeps track of votes and what to do with them
  105. script "VoteManager" (void)
  106. {
  107. // loop
  108. while(1)
  109. {
  110. switch(state)
  111. {
  112. case STATE_VOTEWAIT: state_waitforvote(); break;
  113. case STATE_COUNTDOWN: state_countdown(); break;
  114. case STATE_CHECKTIE: state_checktie(); break;
  115. case STATE_RESULTS: state_results(); break;
  116. }
  117. delay(1);
  118. }
  119. }
  120. // the hud
  121. script "VoteHud" enter clientside
  122. {
  123. if(GetLevelInfo(LEVELINFO_LEVELNUM) != 99) { Terminate; }
  124. // prevent this script from running multiple times on each client, for each client
  125. if(playernumber() != ConsolePlayerNumber()) { Terminate; }
  126. // set up the hud's sizes based on the user's current screen res
  127. HudSetup(0 ,0);
  128. // welcome
  129. setfont("hudfont");
  130. hudmessagebold(s:"\c[White]Welcome to the Lexicon Voting Room\n\c[White]Democracy in action!"; 0, 9997, 0, hud_width_half + 0.4, 112.0, 10.0);
  131. // setup the confetti
  132. for(int c = 0; c < 64; c++)
  133. {
  134. objs_confetti[c].x = 0;
  135. objs_confetti[c].y = (int)hud_height/65535;
  136. objs_confetti[c].velx = random(1, 64);
  137. objs_confetti[c].vely = random(-64, -1);
  138. objs_confetti[c].confnum = random(0, 17);
  139. objs_confetti[c].animnum = random(0, 7);
  140. }
  141. for(int c = 64; c < 128; c++)
  142. {
  143. objs_confetti[c].x = (int)hud_width/65535;
  144. objs_confetti[c].y = (int)hud_height/65535;
  145. objs_confetti[c].velx = random(-64, -1);
  146. objs_confetti[c].vely = random(-64, -1);
  147. objs_confetti[c].confnum = random(0, 17);
  148. objs_confetti[c].animnum = random(0, 7);
  149. }
  150. // loop
  151. while(1)
  152. {
  153. // system is in the countdown state
  154. if(state == STATE_COUNTDOWN)
  155. {
  156. setfont("HUDFONT");
  157. // timer
  158. if(time_seconds > TIME_YELLOW)
  159. {
  160. hudmessagebold(s:"\c[Green]", s:"Time Left: ", d:time_seconds; 0, 9998, 0, 192.1, 112.0, 0.1);
  161. }
  162. else if(time_seconds <= TIME_YELLOW && time_seconds > TIME_ORANGE)
  163. {
  164. hudmessagebold(s:"\c[Yellow]", s:"Time Left: ", d:time_seconds; 0, 9998, 0, 192.1, 112.0, 0.1);
  165. }
  166. else if(time_seconds <= TIME_ORANGE && time_seconds > TIME_RED)
  167. {
  168. hudmessagebold(s:"\c[Orange]", s:"Time Left: ", d:time_seconds; 0, 9998, 0, 192.1, 112.0, 0.1);
  169. }
  170. else if(time_seconds <= TIME_RED)
  171. {
  172. hudmessagebold(s:"\c[Red]", s:"Time Left: ", d:time_seconds; 0, 9998, 0, 192.1, 112.0, 0.1);
  173. }
  174. // vote header
  175. hudmessagebold(s:"\c[Cyan]Votes"; 0, 9999, 0, 192.1, 136.0, 0.1);
  176. // vote list
  177. fixed y = 136.0;
  178. for(int i = 0; i < 64; i++)
  179. {
  180. if(votessorted[i][0] > 0)
  181. {
  182. y += 23.0;
  183. hudmessagebold(s:"\c[Gold]", d:votessorted[i][0], s:" : ", s:votenames[votessorted[i][1]][0]; 0, i+10000, 0, 225.1, y, 0.1);
  184. }
  185. }
  186. // player's vote
  187. hudmessagebold(s:"\c[Green]Your Vote: \c[Gold]", s:votenames[players[playernumber()]][0]; 0, 9700, 0, hud_width_half, hud_height-128.0, 0.1);
  188. }
  189. // system is in the end results state
  190. else if(state == STATE_RESULTS)
  191. {
  192. setfont("hudfont");
  193. hudmessagebold(s:"\c[Green]", s:"Winner: \c[Gold]", s:votenames[votechosen][0]; 0, 9998, 0, hud_width_half, hud_height_half-128.0, 0.1);
  194. // confetti :D
  195. for(int c = 0; c < 128; c++)
  196. {
  197. // slow down the confetti
  198. if(objs_confetti[c].velx > 0){ objs_confetti[c].velx -= 1; }
  199. if(objs_confetti[c].velx < 0){ objs_confetti[c].velx += 1; }
  200. // add gravity
  201. objs_confetti[c].vely += 1;
  202. // apply velocities
  203. objs_confetti[c].x += objs_confetti[c].velx;
  204. objs_confetti[c].y += objs_confetti[c].vely;
  205. // animate it
  206. objs_confetti[c].animnum++;
  207. if(objs_confetti[c].animnum > 7) { objs_confetti[c].animnum = 0; }
  208. objs_confetti[c].image = StrParam(s:"CN", i:objs_confetti[c].confnum, i:objs_confetti[c].animnum);
  209. // show it
  210. setfont(objs_confetti[c].image);
  211. hudmessagebold(s:"a"; 0, c+9800, 0, (fixed)(objs_confetti[c].x*65535), (fixed)(objs_confetti[c].y*65535), 0.1);
  212. }
  213. }
  214. delay(1);
  215. }
  216. }
  217. // called by players to manage their votes
  218. script "VotePlayer" (int id)
  219. {
  220. if(playernumber() > -1)
  221. {
  222. // get player number
  223. int pnum = playernumber();
  224. //pnum = random(1,7);
  225. // if the player has not voted...
  226. if (players[pnum] < 0)
  227. {
  228. // keep track of player's vote
  229. players[pnum] = id;
  230. // count a vote for a specific id
  231. votes[id]++;
  232. // count up total votes
  233. votecount++;
  234. }
  235. // if the player has already voted
  236. else
  237. {
  238. // if the vote id is different
  239. if(players[pnum] != id)
  240. {
  241. // remove the vote from previous id
  242. votes[players[pnum]]--;
  243. // set the player's vote to the new id
  244. players[pnum] = id;
  245. // add the vote to the new id
  246. votes[id]++;
  247. }
  248. // if the vote id is the same
  249. else
  250. {
  251. // remove the player's vote
  252. players[pnum] = -1;
  253. // remove a vote for a specific id
  254. votes[id]--;
  255. // count down total votes
  256. votecount--;
  257. }
  258. }
  259. // sort votes
  260. bubble_sort();
  261. // sync player votes
  262. for(int i = 0; i < 63; i++)
  263. {
  264. ACS_ExecuteAlways(571, 0, i, players[pnum]);
  265. }
  266. }
  267. }
  268. // sync sorted votes to clients
  269. script 567 (int index, int votes, int id) clientside
  270. {
  271. votessorted[index][0] = votes;
  272. votessorted[index][1] = id;
  273. }
  274. // sync voted choice
  275. script 568 (int v) clientside
  276. {
  277. votechosen = v;
  278. }
  279. // sync timer
  280. script 569 (int time) clientside
  281. {
  282. time_seconds = time;
  283. }
  284. // sync state
  285. script 570 (int s) clientside
  286. {
  287. state = s;
  288. }
  289. // sync player choices
  290. script 571 (int pnum, int id) clientside
  291. {
  292. players[pnum] = id;
  293. }
  294. function void state_waitforvote(void)
  295. {
  296. // if a vote was made
  297. if(votecount > 0)
  298. {
  299. // set the system to the countdown state
  300. state = STATE_COUNTDOWN;
  301. // sync clients
  302. ACS_ExecuteAlways(570, 0, state);
  303. }
  304. }
  305. function void state_countdown(void)
  306. {
  307. // countdown timer
  308. time_ticks--;
  309. time_seconds = time_ticks/35;
  310. // if time up, or all players voted, or majority have voted
  311. if(time_ticks <= 0 || votecount >= playercount() || votessorted[0][0] > (playercount()/3)*2)
  312. {
  313. // set the system to the check tie state
  314. state = STATE_CHECKTIE;
  315. // sync
  316. ACS_ExecuteAlways(570, 0, state);
  317. }
  318. // if all votes were canceled
  319. if(votecount <= 0)
  320. {
  321. // reset timer
  322. time_ticks = TIME_START*35;
  323. // go back to the wait state
  324. state = STATE_VOTEWAIT;
  325. // sync
  326. ACS_ExecuteAlways(570, 0, state);
  327. }
  328. // sync clients every second
  329. if(!(time_ticks%35))
  330. {
  331. // sync the timer with the clients
  332. ACS_Execute(569, 0, time_seconds);
  333. }
  334. }
  335. function void state_checktie(void)
  336. {
  337. // sort votes
  338. bubble_sort();
  339. int tiecount = 0;
  340. // for every wad
  341. for(int i = 1; i < 64; i++)
  342. {
  343. // if a wad's vote count is the same as the winner
  344. if(votessorted[i][0] == votessorted[0][0])
  345. {
  346. // count up the tie amount
  347. tiecount++;
  348. }
  349. }
  350. // if there is a tie
  351. if(tiecount > 0)
  352. {
  353. // randomly choose a wad
  354. votechosen = votessorted[random(0, tiecount)][1];
  355. }
  356. else
  357. {
  358. // otherwise just choose the winner
  359. votechosen = votessorted[0][1];
  360. }
  361. // sync the clients
  362. ACS_Execute(568, 0, votechosen);
  363. // set the system to the results state
  364. state = STATE_RESULTS;
  365. // sync
  366. ACS_ExecuteAlways(570, 0, state);
  367. // reset timer
  368. state_clock = 0;
  369. AmbientSound("partyhorn", 127);
  370. }
  371. function void state_results(void)
  372. {
  373. // count up custom timer
  374. state_clock++;
  375. // if 5 seconds have past
  376. if(state_clock > 5*35)
  377. {
  378. // go to chosen level
  379. ChangeLevel(votenames[votechosen][1], 0, 0, -1);
  380. }
  381. }
  382. // sort voted list
  383. function void bubble_sort(void)
  384. {
  385. int t;
  386. int j = 64;
  387. int s = 1;
  388. int v;
  389. for (int i = 0; i < 64; i++)
  390. {
  391. votessorted[i][0] = votes[i];
  392. votessorted[i][1] = i;
  393. }
  394. while(s)
  395. {
  396. s = 0;
  397. for (int i = j; i >= 0; i--)
  398. {
  399. if (votessorted[i][0] < votessorted[i + 1][0])
  400. {
  401. t = votessorted[i][0];
  402. v = votessorted[i][1];
  403. votessorted[i][0] = votessorted[i + 1][0];
  404. votessorted[i][1] = votessorted[i + 1][1];
  405. votessorted[i + 1][0] = t;
  406. votessorted[i + 1][1] = v;
  407. s = 1;
  408. }
  409. }
  410. j--;
  411. }
  412. for(int i = 0; i < 63; i++)
  413. {
  414. ACS_ExecuteAlways(567, 0, i, votessorted[i][0], votessorted[i][1]);
  415. }
  416. }
  417. function void hudsetup(int xres, int yres)
  418. {
  419. int x = xres;
  420. int y = yres;
  421. if(x < 1) { x = GetCVar("vid_defwidth"); }
  422. if(y < 1) { y = GetCVar("vid_defheight"); }
  423. hud_width = (fixed)(x*65536);
  424. hud_height = (fixed)(y*65536);
  425. hud_width_half = hud_width/2.0;
  426. hud_height_half = hud_height/2.0;
  427. SetHudSize(x, y, true);
  428. SetFont("BIGFONT");
  429. }
  430. }