From fe528cd1da33748fd371c645d08cfa67c173b905 Mon Sep 17 00:00:00 2001 From: driAn Date: Sun, 4 Nov 2007 14:18:01 +0000 Subject: [PATCH] Scoreboard git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1409 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/entity.h | 1 + source/src/main.cpp | 6 +- source/src/menus.cpp | 45 +++++++------ source/src/protos.h | 49 ++++++++++++-- source/src/rendergl.cpp | 44 +++++++----- source/src/renderhud.cpp | 9 +-- source/src/scoreboard.cpp | 126 ++++++++++++++++++++--------------- source/src/serverbrowser.cpp | 77 +++++++++++++-------- source/src/sound.cpp | 1 + 9 files changed, 228 insertions(+), 130 deletions(-) diff --git a/source/src/entity.h b/source/src/entity.h index cadcf42c..e2b96da2 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -309,6 +309,7 @@ struct playerent : dynent, playerstate int clientnum, lastupdate, plag, ping; int lifesequence; // sequence id for each respawn, used in damage test int frags, flagscore; + int deaths() { return lifesequence + (state==CS_DEAD ? 1 : 0); } int lastaction, lastattackgun, lastmove, lastpain, lastteamkill; int clientrole; bool attacking; diff --git a/source/src/main.cpp b/source/src/main.cpp index 80c9c9cc..06ad6c88 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -374,9 +374,9 @@ int main(int argc, char **argv) initlog("cfg"); extern void *scoremenu, *teammenu, *ctfmenu, *servmenu, *kickmenu, *banmenu, *forceteammenu, *givemastermenu, *docmenu; - scoremenu = addmenu("score", "frags\tdeath\tpj\tping\tname\tcn", false, renderscores); - teammenu = addmenu("team score", "frags\tdeath\tpj\tping\tteam\tname\tcn", false, renderscores); - ctfmenu = addmenu("ctf score", "flags\tfrags\tdeath\tpj\tping\tteam\tname\tcn", false, renderscores); + scoremenu = addmenu("score", "frags\tdeath\tpj\tping\t\cn\tname", false, renderscores); + teammenu = addmenu("team score", "frags\tdeath\tpj\tping\tcn\tname", false, renderscores); + ctfmenu = addmenu("ctf score", "flags\tfrags\tdeath\tpj\tping\tteam\tcn\tname", false, renderscores); servmenu = addmenu("server", "ping\tplr\tserver", true, refreshservers); kickmenu = addmenu("kick player", NULL, true, refreshsopmenu); banmenu = addmenu("ban player", NULL, true, refreshsopmenu); diff --git a/source/src/menus.cpp b/source/src/menus.cpp index 60329fec..dca6322f 100644 --- a/source/src/menus.cpp +++ b/source/src/menus.cpp @@ -2,20 +2,6 @@ #include "cube.h" -struct mitem { char *text, *action, *hoveraction; }; - -struct gmenu -{ - char *name, *title, *header, *footer; - vector items; - int mwidth; - int menusel; - char *mdl; // (optional) md2 mdl - int anim, rotspeed, scale; - bool allowinput, inited; - void (__cdecl *refreshfunc)(void *, bool); -}; - hashtable menus; gmenu *curmenu = NULL, *lastmenu = NULL; @@ -71,10 +57,18 @@ void drawmenubg(int x1, int y1, int x2, int y2, bool border) #define MAXMENU 17 -bool rendermenu() -{ - if(!curmenu) { menustack.setsize(0); return false; } - +bool menuvisible() +{ + if(!curmenu) + { + menustack.setsize(0); + return false; + }; + return true; +} + +void rendermenu() +{ setscope(false); gmenu &m = *curmenu; @@ -107,8 +101,8 @@ bool rendermenu() } int step = (FONTH*5)/4; int h = (mdisp+hitems+2)*step; - int y = (VIRTH-h)/2; - int x = (VIRTW-w)/2; + int y = (2*VIRTH-h)/2; + int x = (2*VIRTW-w)/2; drawmenubg(x-FONTH*3/2, y-FONTH, x+w+FONTH*3/2, y+h+FONTH, true); if(offset>0) drawarrow(1, x+w+FONTH*3/2-FONTH*5/6, y-FONTH*5/6, FONTH*2/3); if(offset+pagesize items; + int mwidth; + int menusel; + char *mdl; // (optional) md2 mdl + int anim, rotspeed, scale; + bool allowinput, inited; + void (__cdecl *refreshfunc)(void *, bool); +}; + // serverbrowser extern void addserver(char *servername, char *serverport); extern char *getservername(int n); @@ -56,6 +83,20 @@ extern int connectwithtimeout(ENetSocket sock, char *hostname, ENetAddress &remo extern void writeservercfg(); extern void refreshservers(void *menu, bool init); +struct serverinfo +{ + char *name; + string full; + string map; + string sdesc; + string cmd; + int mode, numplayers, maxclients, ping, protocol, minremain, resolved, port; + ENetAddress address; +}; + +extern serverinfo *getconnectedserverinfo(); +extern void pingservers(); + // rendergl extern void gl_init(int w, int h, int bpp, int depth, int fsaa); extern void cleangl(); @@ -63,7 +104,7 @@ extern void line(int x1, int y1, float z1, int x2, int y2, float z2); extern void box(block &b, float z1, float z2, float z3, float z4); extern void dot(int x, int y, float z); extern void linestyle(float width, int r, int g, int b); -extern void blendbox(int x1, int y1, int x2, int y2, bool border, int tex = -1); +extern void blendbox(int x1, int y1, int x2, int y2, bool border, int tex = -1, color *c = NULL); extern void quad(GLuint tex, float x, float y, float s, float tx, float ty, float tsx, float tsy = 0); extern void circle(GLuint tex, float x, float y, float r, float tx, float ty, float tr, int subdiv = 32); extern void gl_drawframe(int w, int h, float changelod, float curfps); @@ -406,4 +447,4 @@ struct demoheader { char magic[16]; int version, protocol; -}; +}; \ No newline at end of file diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index 14e0ce23..7f717ecc 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -150,7 +150,7 @@ void dot(int x, int y, float z) xtraverts += 4; } -void blendbox(int x1, int y1, int x2, int y2, bool border, int tex) +void blendbox(int x1, int y1, int x2, int y2, bool border, int tex, color *c) { glDepthMask(GL_FALSE); glDisable(GL_TEXTURE_2D); @@ -198,9 +198,17 @@ void blendbox(int x1, int y1, int x2, int y2, bool border, int tex) } else { - if(border) glColor3f(0.7f, 0.7f, 0.7f); //glColor3d(0.5, 0.3, 0.4); - else glColor3f(1, 1, 1); - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + if(c) + { + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glColor4f(c->r, c->g, c->b, c->alpha); + } + else + { + glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + glColor3f(1, 1, 1); + } + glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2i(x1, y1); glTexCoord2f(1, 0); glVertex2i(x2, y1); @@ -210,18 +218,22 @@ void blendbox(int x1, int y1, int x2, int y2, bool border, int tex) xtraverts += 4; } - glDisable(GL_BLEND); - if(tex>=0) glDisable(GL_TEXTURE_2D); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glBegin(GL_POLYGON); - glColor3f(0.6f, 0.6f, 0.6f); //glColor3d(0.2, 0.7, 0.4); - glVertex2i(x1, y1); - glVertex2i(x2, y1); - glVertex2i(x2, y2); - glVertex2i(x1, y2); - glEnd(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnable(GL_BLEND); + if(border) + { + glDisable(GL_BLEND); + if(tex>=0) glDisable(GL_TEXTURE_2D); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glBegin(GL_POLYGON); + glColor3f(0.6f, 0.6f, 0.6f); + glVertex2i(x1, y1); + glVertex2i(x2, y1); + glVertex2i(x2, y2); + glVertex2i(x1, y2); + glEnd(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_BLEND); + } + glEnable(GL_TEXTURE_2D); glDepthMask(GL_TRUE); } diff --git a/source/src/renderhud.cpp b/source/src/renderhud.cpp index df9c2626..390a1d09 100644 --- a/source/src/renderhud.cpp +++ b/source/src/renderhud.cpp @@ -302,10 +302,10 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat playerent *targetplayer = playerincrosshair(); bool didteamkill = player1->lastteamkill && player1->lastteamkill + 5000 > lastmillis; - bool menuvisible = rendermenu(); + bool menu = menuvisible(); bool command = getcurcommand() ? true : false; - if(player1->state==CS_ALIVE && !player1->reloading && !didteamkill && !menuvisible) + if(player1->state==CS_ALIVE && !player1->reloading && !didteamkill && !menu) { bool drawteamwarning = targetplayer ? (isteam(targetplayer->team, player1->team) && targetplayer->state!=CS_DEAD) : false; if(player1->gunselect==GUN_SNIPER && scoped) drawscope(); @@ -315,7 +315,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat drawequipicons(); glMatrixMode(GL_MODELVIEW); - if(!menuvisible && !hideradar) drawradar(w, h); + if(!menu && !hideradar) drawradar(w, h); else drawteamicons(w, h); glMatrixMode(GL_PROJECTION); @@ -328,7 +328,8 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat glOrtho(0, VIRTW*2, VIRTH*2, 0, -1, 1); renderconsole(); - if(command) renderdoc(40, VIRTH); + if(menu) rendermenu(); + else if(command) renderdoc(40, VIRTH); if(!hidestats) { const int left = (VIRTW-225-10)*2, top = (VIRTH*7/8)*2; diff --git a/source/src/scoreboard.cpp b/source/src/scoreboard.cpp index 5a66ec03..a20e4653 100644 --- a/source/src/scoreboard.cpp +++ b/source/src/scoreboard.cpp @@ -11,22 +11,40 @@ void showscores(bool on) COMMAND(showscores, ARG_DOWN); -struct sline { string s; }; -static vector scorelines; -static string modeline, teamline; +struct sline +{ + string s; + color *bgcolor; + sline() : bgcolor(NULL) {} +}; -void renderscore(void *menu, playerent *d, int cn) +static vector scorelines; + +struct teamscore { - const char *status = ""; - if(d->clientrole==CR_MASTER) status = "\f0"; - else if(d->clientrole==CR_ADMIN) status = "\f3"; - else if(d->state==CS_DEAD) status = "\f4"; - s_sprintfd(lag)("%d", d->plag); - string &s = scorelines.add().s; - int deaths = d->lifesequence + (d->state==CS_DEAD ? 1 : 0); - if(m_ctf) s_sprintf(s)("%d\t%d\t%d\t%s\t%s\t%s\t%s%s\t%d", d->flagscore, d->frags, deaths, d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->team, status, colorname(d), cn); - else if(m_teammode) s_sprintf(s)("%d\t%d\t%s\t%s\t%s\t%s%s\t%d", d->frags, deaths, d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), m_teammode ? d->team : "", status, colorname(d), cn); - else s_sprintf(s)("%d\t%d\t%s\t%s\t%s%s\t%d", d->frags, deaths, d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), status, colorname(d), cn); + int team, frags, deaths, flagscore; + vector teammembers; + teamscore(int t) : team(t), frags(0), deaths(0), flagscore(0) {} + + void addscore(playerent *d) + { + if(!d) return; + teammembers.add(d); + frags += d->frags; + deaths += d->deaths(); + if(m_ctf) flagscore += d->flagscore; + } +}; + +static int teamscorecmp(const teamscore *x, const teamscore *y) +{ + if(x->flagscore > y->flagscore) return -1; + if(x->flagscore < y->flagscore) return 1; + if(x->frags > y->frags) return -1; + if(x->frags < y->frags) return 1; + if(x->deaths < y->deaths) return -1; + if(x->deaths > y->deaths) return 1; + return x->team > y->team; } static int scorecmp(const playerent **x, const playerent **y) @@ -40,48 +58,42 @@ static int scorecmp(const playerent **x, const playerent **y) return strcmp((*x)->name, (*y)->name); } -struct teamscore +void renderscore(void *menu, playerent *d) { - char *team; - int score, flagscore; - teamscore() {} - teamscore(char *s, int n, int f = 0) : team(s), score(n), flagscore(f) {} -}; - -static int teamscorecmp(const teamscore *x, const teamscore *y) -{ - if(x->flagscore > y->flagscore) return -1; - if(x->flagscore < y->flagscore) return 1; - if(x->score > y->score) return -1; - if(x->score < y->score) return 1; - return strcmp(x->team, y->team); + const char *status = ""; + if(d->clientrole==CR_MASTER) status = "\f0"; + else if(d->clientrole==CR_ADMIN) status = "\f3"; + else if(d->state==CS_DEAD) status = "\f4"; + s_sprintfd(lag)("%d", d->plag); + sline &line = scorelines.add(); + line.bgcolor = NULL; + string &s = line.s; + if(m_ctf) s_sprintf(s)("%d\t%d\t%d\t%s\t%s\t%d\t%s%s", d->flagscore, d->frags, d->deaths(), d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->clientnum, status, colorname(d)); + else if(m_teammode) s_sprintf(s)("%d\t%d\t%s\t%s\t%d\t%s%s", d->frags, d->deaths(), d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->clientnum, status, colorname(d)); + else s_sprintf(s)("%d\t%d\t%s\t%s\t%d\t%s%s", d->frags, d->deaths(), d->state==CS_LAGGED ? "LAG" : lag, colorping(d->ping), d->clientnum, status, colorname(d)); } -vector teamscores; - -void addteamscore(playerent *d) +void renderteamscore(void *menu, teamscore *t) { - if(!d || !d->team[0]) return; - loopv(teamscores) if(!strcmp(teamscores[i].team, d->team)) - { - teamscores[i].score += d->frags; - if(m_ctf) teamscores[i].flagscore += d->flagscore; - return; - } - teamscores.add(teamscore(d->team, d->frags, m_ctf ? d->flagscore : 0)); + sline &line = scorelines.add(); + if(m_teammode) s_sprintf(line.s)("%d\t%d\t\t\t\t%s\t\t(%d players)", t->frags, t->deaths, team_string(t->team), t->teammembers.length()); + static color teamcolors[2] = { color(1, 0, 0, 0.2f), color(0, 0, 1, 0.2f) }; + line.bgcolor = &teamcolors[t->team]; + loopv(t->teammembers) renderscore(menu, t->teammembers[i]); } void renderscores(void *menu, bool init) { + static string modeline, serverline; + modeline[0] = '\0'; - teamline[0] = '\0'; + serverline[0] = '\0'; scorelines.setsize(0); vector scores; scores.add(player1); loopv(players) if(players[i]) scores.add(players[i]); scores.sort(scorecmp); - loopv(scores) renderscore(menu, scores[i], scores[i]->clientnum); if(init) { @@ -95,6 +107,7 @@ void renderscores(void *menu, bool init) s_strcat(modeline, ": "); s_strcat(modeline, getclientmap()); } + extern int minutesremaining; if((gamemode>1 || (gamemode==0 && multiplayer(false))) && minutesremaining >= 0) { @@ -106,22 +119,31 @@ void renderscores(void *menu, bool init) } } + if(multiplayer(false)) + { + serverinfo *s = getconnectedserverinfo(); + if(s) s_sprintf(serverline)("%s:%d -- %s", s->name, s->port, s->sdesc); + } + if(m_teammode) { - teamscores.setsize(0); - loopv(players) addteamscore(players[i]); - addteamscore(player1); - teamscores.sort(teamscorecmp); - loopv(teamscores) + teamscore teamscores[2] = { teamscore(0), teamscore(1) }; + teamscores[team_int(player1->team)].addscore(player1); + loopv(players) { - string s; - if(m_ctf) s_sprintf(s)("[ %s: %d flags %d frags ]", teamscores[i].team, teamscores[i].flagscore, teamscores[i].score); - else s_sprintf(s)("[ %s: %d ]", teamscores[i].team, teamscores[i].score); - s_strcat(teamline, s); + if(!players[i]) continue; + teamscores[team_int(players[i]->team)].addscore(players[i]); } + loopi(2) renderteamscore(menu, &teamscores[i]); + } + else + { + loopv(scores) renderscore(menu, scores[i]); } - loopv(scorelines) menumanual(menu, i, scorelines[i].s); - menuheader(menu, modeline, teamline); + loopv(scorelines) menumanual(menu, i, scorelines[i].s, NULL, scorelines[i].bgcolor); + menuheader(menu, modeline, serverline); + + refreshservers(NULL, init); // update server stats } diff --git a/source/src/serverbrowser.cpp b/source/src/serverbrowser.cpp index 47398efb..1bdf9c6f 100644 --- a/source/src/serverbrowser.cpp +++ b/source/src/serverbrowser.cpp @@ -283,17 +283,6 @@ int connectwithtimeout(ENetSocket sock, char *hostname, ENetAddress &address) return cd.result; } -struct serverinfo -{ - char *name; - string full; - string map; - string sdesc; - string cmd; - int mode, numplayers, maxclients, ping, protocol, minremain, resolved, port; - ENetAddress address; -}; - enum { UNRESOLVED = 0, RESOLVING, RESOLVED }; vector servers; @@ -302,12 +291,28 @@ int lastinfo = 0; char *getservername(int n) { return servers[n].name; } +serverinfo *findserverinfo(ENetAddress address) +{ + loopv(servers) if(servers[i].address.host == address.host && servers[i].port == address.port) return &servers[i]; + return NULL; +} + +serverinfo *getconnectedserverinfo() +{ + extern ENetPeer *curpeer; + if(!curpeer) return NULL; + return findserverinfo(curpeer->address); +} + void addserver(char *servername, char *serverport) { - loopv(servers) if(strcmp(servers[i].name, servername)==0 && servers[i].port == atoi(serverport)) return; + int port = atoi(serverport); + if(port == 0) port = CUBE_DEFAULT_SERVER_PORT; + + loopv(servers) if(strcmp(servers[i].name, servername)==0 && servers[i].port == port) return; serverinfo &si = servers.insert(0, serverinfo()); si.name = newstring(servername); - si.port = atoi(serverport); + si.port = port; si.full[0] = 0; si.mode = 0; si.numplayers = 0; @@ -442,22 +447,25 @@ void refreshservers(void *menu, bool init) checkpings(); if(lastmillis - lastinfo >= 5000) pingservers(); servers.sort(sicompare); - loopv(servers) + if(menu) { - serverinfo &si = servers[i]; - if(si.address.host != ENET_HOST_ANY && si.ping != 9999) + loopv(servers) { - if(si.protocol!=PROTOCOL_VERSION) s_sprintf(si.full)("%s:%d [%s protocol]", si.name, si.port, si.protocol") || strstr((char *)reply, "")) conoutf("master server not replying"); else - { + { + // preserve currently connected server from deletion + serverinfo *curserver = getconnectedserverinfo(); + string curname, curport; + if(curserver) + { + s_strcpy(curname, curserver->name); + s_sprintf(curport)("%d", curserver->port); + } + loopv(servers) delete[] servers[i].name; - servers.setsize(0); - execute((char *)reply); + servers.setsize(0); + execute((char *)reply); + + if(curserver) addserver(curname, curport); } } diff --git a/source/src/sound.cpp b/source/src/sound.cpp index 28b7d6f0..4570bb06 100644 --- a/source/src/sound.cpp +++ b/source/src/sound.cpp @@ -335,6 +335,7 @@ void updatechanvol(int chan, int svol, soundloc *sl) if(sl->pse->type == ENT_PLAYER || sl->pse->type == ENT_BOT) { playerent *p = (playerent *)sl->pse; + ASSERT(p); bool nofootsteps = p->state != CS_ALIVE || lastmillis-p->lastpain < 300 || (!p->onfloor && p->timeinair>50) || (!p->move && !p->strafe); if(nofootsteps) vol = 0; // TODO: fade out? }