Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2011
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.75 KB | None | 0 0
  1. // creation of scoreboard pseudo-menu
  2.  
  3. #include "cube.h"
  4. #define SCORERATIO(F,D) (float)(F >= 0 ? F : 0) / (float)(D > 0 ? D : 1)
  5.  
  6. void *scoremenu = NULL, *teammenu = NULL, *ctfmenu = NULL;
  7.  
  8. void showscores(int on)
  9. {
  10. if(on) showmenu(m_flags ? "ctf score" : (m_teammode ? "team score" : "score"), false);
  11. else if (!intermission)
  12. {
  13. closemenu("score");
  14. closemenu("team score");
  15. closemenu("ctf score");
  16. }
  17. }
  18.  
  19. COMMAND(showscores, ARG_1INT);
  20.  
  21. struct sline
  22. {
  23. string s;
  24. color *bgcolor;
  25. sline() : bgcolor(NULL) {}
  26. };
  27.  
  28. static vector<sline> scorelines;
  29. vector<discscore> discscores;
  30.  
  31. struct teamscore
  32. {
  33. int team, frags, deaths, flagscore, points;
  34. vector<playerent *> teammembers;
  35. teamscore(int t) : team(t), frags(0), deaths(0), flagscore(0), points(0) {}
  36.  
  37. void addplayer(playerent *d)
  38. {
  39. if(!d) return;
  40. teammembers.add(d);
  41. frags += d->frags;
  42. deaths += d->deaths;
  43. points += d->points;
  44. if(m_flags) flagscore += d->flagscore;
  45. }
  46.  
  47. void addscore(discscore &d)
  48. {
  49. frags += d.frags;
  50. deaths += d.deaths;
  51. points += d.points;
  52. if(m_flags) flagscore += d.flags;
  53. }
  54. };
  55.  
  56. static int teamscorecmp(const teamscore *x, const teamscore *y)
  57. {
  58. if(x->flagscore > y->flagscore) return -1;
  59. if(x->flagscore < y->flagscore) return 1;
  60. if(x->frags > y->frags) return -1;
  61. if(x->frags < y->frags) return 1;
  62. if(x->points > y->points) return -1;
  63. if(x->points < y->points) return 1;
  64. if(x->deaths < y->deaths) return -1;
  65. return 1;
  66. }
  67.  
  68. static int scorecmp(const playerent **x, const playerent **y)
  69. {
  70. if((*x)->flagscore > (*y)->flagscore) return -1;
  71. if((*x)->flagscore < (*y)->flagscore) return 1;
  72. if((*x)->frags > (*y)->frags) return -1;
  73. if((*x)->frags < (*y)->frags) return 1;
  74. if((*x)->points > (*y)->points) return -1;
  75. if((*x)->points < (*y)->points) return 1;
  76. if((*x)->deaths > (*y)->deaths) return 1;
  77. if((*x)->deaths < (*y)->deaths) return -1;
  78. if((*x)->lifesequence > (*y)->lifesequence) return 1;
  79. if((*x)->lifesequence < (*y)->lifesequence) return -1;
  80. return strcmp((*x)->name, (*y)->name);
  81. }
  82.  
  83. static int discscorecmp(const discscore *x, const discscore *y)
  84. {
  85. if(x->team < y->team) return -1;
  86. if(x->team > y->team) return 1;
  87. if(m_flags && x->flags > y->flags) return -1;
  88. if(m_flags && x->flags < y->flags) return 1;
  89. if(x->frags > y->frags) return -1;
  90. if(x->frags < y->frags) return 1;
  91. if(x->deaths > y->deaths) return 1;
  92. if(x->deaths < y->deaths) return -1;
  93. return strcmp(x->name, y->name);
  94. }
  95.  
  96. const char *scoreratio(int frags, int deaths, int precis = 0)
  97. {
  98. static string res;
  99. float ratio = SCORERATIO(frags, deaths);
  100. int precision = precis;
  101. if(!precision)
  102. {
  103. if(ratio<10.0f) precision = 2;
  104. else if(ratio<100.0f) precision = 1;
  105. }
  106. formatstring(res)("%.*f", precision, ratio);
  107. return res;
  108. }
  109.  
  110. void renderdiscscores(int team)
  111. {
  112. loopv(discscores) if(team == team_group(discscores[i].team))
  113. {
  114. discscore &d = discscores[i];
  115. sline &line = scorelines.add();
  116. const char *spect = team_isspect(d.team) ? "\f4" : "";
  117. float ratio = SCORERATIO(d.frags, d.deaths);
  118. const char *clag = team_isspect(d.team) ? "SPECT" : "";
  119. switch(orderscorecolumns)
  120. {
  121. case 1:
  122. {
  123. if(m_flags) formatstring(line.s)("%s%s\t%d\t%d\t%d\t%.2f\t%d\t%s\tDISC", spect, d.name, d.flags, d.frags, d.deaths, ratio, d.points > 0 ? d.points : 0, clag);
  124. else formatstring(line.s)("%s%s\t%d\t%d\t%.2f\t%d\t%s\tDISC", spect, d.name, d.frags, d.deaths, ratio, d.points > 0 ? d.points : 0, clag);
  125. break;
  126. }
  127. case 0:
  128. default:
  129. {
  130. if(m_flags) formatstring(line.s)("%s%d\t%d\t%d\t%.2f\t%d\t%s\tDISC\t%s", spect, d.flags, d.frags, d.deaths, ratio, d.points > 0 ? d.points : 0, clag, d.name);
  131. else formatstring(line.s)("%s%d\t%d\t%.2f\t%d\t%s\tDISC\t%s", spect, d.frags, d.deaths, ratio, d.points > 0 ? d.points : 0, clag, d.name);
  132. break;
  133. }
  134. }
  135. }
  136. }
  137.  
  138. VARP(cncolumncolor, 0, 5, 9);
  139. char lagping[20];
  140.  
  141. void renderscore(playerent *d)
  142. {
  143. const char *status = "";
  144. static color localplayerc(0.2f, 0.2f, 0.2f, 0.2f);
  145. if(d->clientrole==CR_ADMIN) status = d->state==CS_DEAD ? "\f7" : "\f3";
  146. else if(d->state==CS_DEAD) status = "\f4";
  147. const char *spect = team_isspect(d->team) ? "\f4" : "";
  148. float ratio = SCORERATIO(d->frags, d->deaths);
  149. if ( team_isspect(d->team) )
  150. {
  151. strncpy(lagping,"SPECT",5);
  152. lagping[5]='\0';
  153. }
  154. else if ( d->state==CS_LAGGED || (d->ping > 999 && d->plag > 99) )
  155. {
  156. strncpy(lagping,"LAG",3);
  157. lagping[3]='\0';
  158. }
  159. else
  160. {
  161. sprintf(lagping,"%s/%s",colorpj(d->plag),colorping(d->ping));
  162. }
  163. /* const char *clag = team_isspect(d->team) ? "SPECT" : (d->state==CS_LAGGED ? "LAG" : colorpj(d->plag));
  164. const char *cping = colorping(d->ping);*/
  165. const char *ign = d->ignored ? " (ignored)" : (d->muted ? " (muted)" : "");
  166. sline &line = scorelines.add();
  167. line.bgcolor = d==player1 ? &localplayerc : NULL;
  168. string &s = line.s;
  169. switch(orderscorecolumns)
  170. {
  171. case 1:
  172. {
  173. if(m_flags) formatstring(s)("%s\fs\f%d%d\fr\t%s%s\t%d\t%d\t%d\t%.2f\t%d\t%s\t%s", spect, cncolumncolor, d->clientnum, status, colorname(d), d->flagscore, d->frags, d->deaths, ratio, d->points > 0 ? d->points : 0, lagping, ign);
  174. else formatstring(s)("%s\fs\f%d%d\fr\t%s%s\t%d\t%d\t%.2f\t%d\t%s\t%s", spect, cncolumncolor, d->clientnum, status, colorname(d), d->frags, d->deaths, ratio, d->points > 0 ? d->points : 0, lagping, ign);
  175. break;
  176. }
  177. case 0:
  178. default:
  179. {
  180. if(m_flags) formatstring(s)("%s%d\t%d\t%d\t%.2f\t%d\t%s\t\fs\f%d%d\fr\t%s%s%s", spect, d->flagscore, d->frags, d->deaths, ratio, d->points > 0 ? d->points : 0, lagping, cncolumncolor, d->clientnum, status, colorname(d), ign);
  181. else formatstring(s)("%s%d\t%d\t%.2f\t%d\t%s\t\fs\f%d%d\fr\t%s%s%s", spect, d->frags, d->deaths, ratio, d->points > 0 ? d->points : 0, lagping, cncolumncolor, d->clientnum, status, colorname(d), ign);
  182. break;
  183. }
  184. }
  185. }
  186.  
  187. int totalplayers = 0;
  188.  
  189. int renderteamscore(teamscore *t)
  190. {
  191. if(!scorelines.empty()) // space between teams
  192. {
  193. sline &space = scorelines.add();
  194. space.s[0] = 0;
  195. }
  196. sline &line = scorelines.add();
  197. int n = t->teammembers.length();
  198. defformatstring(plrs)("(%d %s)", n, n == 1 ? "player" : "players");
  199. float ratio = SCORERATIO(t->frags, t->deaths);
  200. switch(orderscorecolumns)
  201. {
  202. case 1:
  203. {
  204. if(m_flags) formatstring(line.s)("%s\t%s\t%d\t%d\t%d\t%.2f\t%d", team_string(t->team), plrs, t->flagscore, t->frags, t->deaths, ratio, t->points > 0 ? t->points : 0);
  205. else formatstring(line.s)("%s\t%s\t%d\t%d\t%.2f\t%d", team_string(t->team), plrs, t->frags, t->deaths, ratio, t->points > 0 ? t->points : 0);
  206. break;
  207. }
  208. case 0:
  209. default:
  210. {
  211. if(m_flags) formatstring(line.s)("%d\t%d\t%d\t%.2f\t%d\t\t\t%s\t\t%s", t->flagscore, t->frags, t->deaths, ratio, t->points > 0 ? t->points : 0, team_string(t->team), plrs);
  212. else formatstring(line.s)("%d\t%d\t%.2f\t%d\t\t\t%s\t\t%s", t->frags, t->deaths, ratio, t->points > 0 ? t->points : 0, team_string(t->team), plrs);
  213. break;
  214. }
  215. }
  216. static color teamcolors[2] = { color(1.0f, 0, 0, 0.2f), color(0, 0, 1.0f, 0.2f) };
  217. line.bgcolor = &teamcolors[team_base(t->team)];
  218. loopv(t->teammembers) renderscore(t->teammembers[i]);
  219. return n;
  220. }
  221.  
  222. extern bool watchingdemo;
  223.  
  224. void renderscores(void *menu, bool init)
  225. {
  226. static string modeline, serverline;
  227.  
  228. modeline[0] = '\0';
  229. serverline[0] = '\0';
  230. scorelines.shrink(0);
  231.  
  232. vector<playerent *> scores;
  233. if(!watchingdemo) scores.add(player1);
  234. totalplayers = 1;
  235. loopv(players) if(players[i]) { scores.add(players[i]); totalplayers++; }
  236. scores.sort(scorecmp);
  237. discscores.sort(discscorecmp);
  238.  
  239. int spectators = 0;
  240. loopv(scores) if(scores[i]->team == TEAM_SPECT) spectators++;
  241. loopv(discscores) if(discscores[i].team == TEAM_SPECT) spectators++;
  242.  
  243. if(getclientmap()[0])
  244. {
  245. bool fldrprefix = !strncmp(getclientmap(), "maps/", strlen("maps/"));
  246. formatstring(modeline)("\"%s\" on map %s", modestr(gamemode, modeacronyms > 0), fldrprefix ? getclientmap()+strlen("maps/") : getclientmap());
  247. }
  248.  
  249. extern int minutesremaining;
  250. if((gamemode>1 || (gamemode==0 && (multiplayer(false) || watchingdemo))) && minutesremaining >= 0)
  251. {
  252. if(!minutesremaining) concatstring(modeline, ", intermission");
  253. else
  254. {
  255. defformatstring(timestr)(", %d %s remaining", minutesremaining, minutesremaining==1 ? "minute" : "minutes");
  256. concatstring(modeline, timestr);
  257. }
  258. }
  259.  
  260. if(multiplayer(false))
  261. {
  262. serverinfo *s = getconnectedserverinfo();
  263. if(s)
  264. {
  265. if(servstate.mastermode > MM_OPEN) concatformatstring(serverline, servstate.mastermode == MM_MATCH ? "M%d " : "P ", servstate.matchteamsize);
  266. // ft: 2010jun12: this can write over the menu boundary
  267. //concatformatstring(serverline, "%s:%d %s", s->name, s->port, s->sdesc);
  268. // for now we'll just cut it off, same as the serverbrowser
  269. // but we might want to consider wrapping the bottom-line to accomodate longer descriptions - to a limit.
  270. string text;
  271. filtertext(text, s->sdesc);
  272. //for(char *p = text; (p = strchr(p, '\"')); *p++ = ' ');
  273. //text[30] = '\0'; // serverbrowser has less room - +8 chars here - 2010AUG03 - seems it was too much, falling back to 30 (for now): TODO get real width of menu as reference-width. FIXME: cutoff
  274. concatformatstring(serverline, "%s:%d %s", s->name, s->port, text);
  275. //printf("SERVERLINE: %s\n", serverline);
  276. }
  277. }
  278.  
  279. if(m_teammode)
  280. {
  281. teamscore teamscores[2] = { teamscore(TEAM_CLA), teamscore(TEAM_RVSF) };
  282.  
  283. loopv(scores) if(scores[i]->team != TEAM_SPECT)
  284. {
  285. teamscores[team_base(scores[i]->team)].addplayer(scores[i]);
  286. }
  287.  
  288. loopv(discscores) if(discscores[i].team != TEAM_SPECT)
  289. {
  290. teamscores[team_base(discscores[i].team)].addscore(discscores[i]);
  291. }
  292.  
  293. int sort = teamscorecmp(&teamscores[TEAM_CLA], &teamscores[TEAM_RVSF]) < 0 ? 0 : 1;
  294. loopi(2)
  295. {
  296. renderteamscore(&teamscores[sort ^ i]);
  297. renderdiscscores(sort ^ i);
  298. }
  299. }
  300. else
  301. { // ffa mode
  302.  
  303. loopv(scores) if(scores[i]->team != TEAM_SPECT) renderscore(scores[i]);
  304. loopi(2) renderdiscscores(i);
  305. }
  306. if(spectators)
  307. {
  308. if(!scorelines.empty()) // space between teams and spectators
  309. {
  310. sline &space = scorelines.add();
  311. space.s[0] = 0;
  312. }
  313. renderdiscscores(TEAM_SPECT);
  314. loopv(scores) if(scores[i]->team == TEAM_SPECT) renderscore(scores[i]);
  315. }
  316. menureset(menu);
  317. loopv(scorelines) menumanual(menu, scorelines[i].s, NULL, scorelines[i].bgcolor);
  318. menuheader(menu, modeline, serverline);
  319.  
  320. // update server stats
  321. static int lastrefresh = 0;
  322. if(!lastrefresh || lastrefresh+5000<lastmillis)
  323. {
  324. refreshservers(NULL, init);
  325. lastrefresh = lastmillis;
  326. }
  327. }
  328.  
  329. #define MAXJPGCOM 65533 // maximum JPEG comment length
  330.  
  331. void addstr(char *dest, const char *src) { if(strlen(dest) + strlen(src) < MAXJPGCOM) strcat(dest, src); }
  332.  
  333. const char *asciiscores(bool destjpg)
  334. {
  335. static char *buf = NULL;
  336. static string team, flags, text;
  337. playerent *d;
  338. vector<playerent *> scores;
  339.  
  340. if(!buf) buf = (char *) malloc(MAXJPGCOM +1);
  341. if(!buf) return "";
  342.  
  343. if(!watchingdemo) scores.add(player1);
  344. loopv(players) if(players[i]) scores.add(players[i]);
  345. scores.sort(scorecmp);
  346.  
  347. buf[0] = '\0';
  348. if(destjpg)
  349. {
  350. formatstring(text)("AssaultCube Screenshot (%s)\n", asctime());
  351. addstr(buf, text);
  352. }
  353. if(getclientmap()[0])
  354. {
  355. formatstring(text)("\n\"%s\" on map %s", modestr(gamemode, 0), getclientmap(), asctime());
  356. addstr(buf, text);
  357. }
  358. if(multiplayer(false))
  359. {
  360. serverinfo *s = getconnectedserverinfo();
  361. if(s)
  362. {
  363. string sdesc;
  364. filtertext(sdesc, s->sdesc, 1);
  365. formatstring(text)(", %s:%d %s", s->name, s->port, sdesc);
  366. addstr(buf, text);
  367. }
  368. }
  369. if(destjpg)
  370. addstr(buf, "\n");
  371. else
  372. {
  373. formatstring(text)("\n%sfrags deaths cn%s name\n", m_flags ? "flags " : "", m_teammode ? " team" : "");
  374. addstr(buf, text);
  375. }
  376. loopv(scores)
  377. {
  378. d = scores[i];
  379. const char *sr = scoreratio(d->frags, d->deaths);
  380. formatstring(team)(destjpg ? ", %s" : " %-4s", team_string(d->team, true));
  381. formatstring(flags)(destjpg ? "%d/" : " %4d ", d->flagscore);
  382. if(destjpg)
  383. formatstring(text)("%s%s (%s%d/%d)\n", d->name, m_teammode ? team : "", m_flags ? flags : "", d->frags, d->deaths);
  384. else
  385. formatstring(text)("%s %4d %4d %2d%s %s%s\n", m_flags ? flags : "", d->frags, d->deaths, d->clientnum,
  386. m_teammode ? team : "", d->name, d->clientrole==CR_ADMIN ? " (admin)" : d==player1 ? " (you)" : "");
  387. addstr(buf, text);
  388. }
  389. discscores.sort(discscorecmp);
  390. loopv(discscores)
  391. {
  392. discscore &d = discscores[i];
  393. const char *sr = scoreratio(d.frags, d.deaths);
  394. formatstring(team)(destjpg ? ", %s" : " %-4s", team_string(d.team, true));
  395. formatstring(flags)(destjpg ? "%d/" : " %4d ", d.flags);
  396. if(destjpg)
  397. formatstring(text)("%s(disconnected)%s (%s%d/%d)\n", d.name, m_teammode ? team : "", m_flags ? flags : "", d.frags, d.deaths);
  398. else
  399. formatstring(text)("%s %4d %4d --%s %s(disconnected)\n", m_flags ? flags : "", d.frags, d.deaths, m_teammode ? team : "", d.name);
  400. addstr(buf, text);
  401. }
  402. if(destjpg)
  403. {
  404. extern int minutesremaining;
  405. formatstring(text)("(%sfrags/deaths), %d minute%s remaining\n", m_flags ? "flags/" : "", minutesremaining, minutesremaining == 1 ? "" : "s");
  406. addstr(buf, text);
  407. }
  408. return buf;
  409. }
  410.  
  411. void consolescores()
  412. {
  413. printf("%s\n", asciiscores());
  414. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement