From 7256502afa0babe60fcafbd2888cd3e33c3f9b6b Mon Sep 17 00:00:00 2001 From: xolatile Date: Wed, 16 Jul 2025 23:07:43 +0200 Subject: Source code, broken... --- src/fpsgame/scoreboard.cpp | 559 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 559 insertions(+) create mode 100644 src/fpsgame/scoreboard.cpp (limited to 'src/fpsgame/scoreboard.cpp') diff --git a/src/fpsgame/scoreboard.cpp b/src/fpsgame/scoreboard.cpp new file mode 100644 index 0000000..ec99dda --- /dev/null +++ b/src/fpsgame/scoreboard.cpp @@ -0,0 +1,559 @@ +// creation of scoreboard +#include "game.h" + +namespace game +{ + VARP(scoreboard2d, 0, 1, 1); + VARP(showservinfo, 0, 1, 1); + VARP(showclientnum, 0, 0, 1); + VARP(showpj, 0, 0, 1); + VARP(showping, 0, 1, 2); + VARP(showspectators, 0, 1, 1); + VARP(showspectatorping, 0, 0, 1); + VARP(highlightscore, 0, 1, 1); + VARP(showconnecting, 0, 0, 1); + VARP(hidefrags, 0, 1, 1); + VARP(showdeaths, 0, 0, 1); + + static hashset teaminfos; + + void clearteaminfo() + { + teaminfos.clear(); + } + + void setteaminfo(const char *team, int frags) + { + teaminfo *t = teaminfos.access(team); + if(!t) { t = &teaminfos[team]; copystring(t->team, team, sizeof(t->team)); } + t->frags = frags; + } + + static inline bool playersort(const fpsent *a, const fpsent *b) + { + if(a->state==CS_SPECTATOR) + { + if(b->state==CS_SPECTATOR) return strcmp(a->name, b->name) < 0; + else return false; + } + else if(b->state==CS_SPECTATOR) return true; + if(m_ctf || m_collect) + { + if(a->flags > b->flags) return true; + if(a->flags < b->flags) return false; + } + if(a->frags > b->frags) return true; + if(a->frags < b->frags) return false; + return strcmp(a->name, b->name) < 0; + } + + void getbestplayers(vector &best) + { + loopv(players) + { + fpsent *o = players[i]; + if(o->state!=CS_SPECTATOR) best.add(o); + } + best.sort(playersort); + while(best.length() > 1 && best.last()->frags < best[0]->frags) best.drop(); + } + + void getbestteams(vector &best) + { + if(cmode && cmode->hidefrags()) + { + vector teamscores; + cmode->getteamscores(teamscores); + teamscores.sort(teamscore::compare); + while(teamscores.length() > 1 && teamscores.last().score < teamscores[0].score) teamscores.drop(); + loopv(teamscores) best.add(teamscores[i].team); + } + else + { + int bestfrags = INT_MIN; + enumerate(teaminfos, teaminfo, t, bestfrags = max(bestfrags, t.frags)); + if(bestfrags <= 0) loopv(players) + { + fpsent *o = players[i]; + if(o->state!=CS_SPECTATOR && !teaminfos.access(o->team) && best.htfind(o->team) < 0) { bestfrags = 0; best.add(o->team); } + } + enumerate(teaminfos, teaminfo, t, if(t.frags >= bestfrags) best.add(t.team)); + } + } + + struct scoregroup : teamscore + { + vector players; + }; + static vector groups; + static vector spectators; + + static inline bool scoregroupcmp(const scoregroup *x, const scoregroup *y) + { + if(!x->team) + { + if(y->team) return false; + } + else if(!y->team) return true; + if(x->score > y->score) return true; + if(x->score < y->score) return false; + if(x->players.length() > y->players.length()) return true; + if(x->players.length() < y->players.length()) return false; + return x->team && y->team && strcmp(x->team, y->team) < 0; + } + + static int groupplayers() + { + int numgroups = 0; + spectators.setsize(0); + loopv(players) + { + fpsent *o = players[i]; + if(!showconnecting && !o->name[0]) continue; + if(o->state==CS_SPECTATOR) { spectators.add(o); continue; } + const char *team = m_teammode && o->team[0] ? o->team : NULL; + bool found = false; + loopj(numgroups) + { + scoregroup &g = *groups[j]; + if(team!=g.team && (!team || !g.team || strcmp(team, g.team))) continue; + g.players.add(o); + found = true; + } + if(found) continue; + if(numgroups>=groups.length()) groups.add(new scoregroup); + scoregroup &g = *groups[numgroups++]; + g.team = team; + if(!team) g.score = 0; + else if(cmode && cmode->hidefrags()) g.score = cmode->getteamscore(o->team); + else { teaminfo *ti = teaminfos.access(team); g.score = ti ? ti->frags : 0; } + g.players.setsize(0); + g.players.add(o); + } + loopi(numgroups) groups[i]->players.sort(playersort); + spectators.sort(playersort); + groups.sort(scoregroupcmp, 0, numgroups); + return numgroups; + } + + int statuscolor(fpsent *d, int color) + { + if(d->privilege) + { + color = d->privilege>=PRIV_ADMIN ? 0xFF8000 : (d->privilege>=PRIV_AUTH ? 0xC040C0 : 0x40FF80); + if(d->state==CS_DEAD) color = (color>>1)&0x7F7F7F; + } + else if(d->state==CS_DEAD) color = 0x606060; + return color; + } + + void renderscoreboard(g3d_gui &g, bool firstpass) + { + const ENetAddress *address = connectedpeer(); + if(showservinfo && address) + { + string hostname; + if(enet_address_get_host_ip(address, hostname, sizeof(hostname)) >= 0) + { + if(servinfo[0]) g.titlef("%.25s", 0xFFFF80, NULL, servinfo); + else g.titlef("%s:%d", 0xFFFF80, NULL, hostname, address->port); + } + } + + g.pushlist(); + g.spring(); + g.text(server::modename(gamemode), 0xFFFF80); + g.separator(); + const char *mname = getclientmap(); + g.text(mname[0] ? mname : "[new map]", 0xFFFF80); + extern int gamespeed; + if(gamespeed != 100) { g.separator(); g.textf("%d.%02dx", 0xFFFF80, NULL, gamespeed/100, gamespeed%100); } + if(m_timed && mname[0] && (maplimit >= 0 || intermission)) + { + g.separator(); + if(intermission) g.text("intermission", 0xFFFF80); + else + { + int secs = max(maplimit-lastmillis+999, 0)/1000, mins = secs/60; + secs %= 60; + g.pushlist(); + g.strut(mins >= 10 ? 4.5f : 3.5f); + g.textf("%d:%02d", 0xFFFF80, NULL, mins, secs); + g.poplist(); + } + } + if(ispaused()) { g.separator(); g.text("paused", 0xFFFF80); } + g.spring(); + g.poplist(); + + g.separator(); + + int numgroups = groupplayers(); + loopk(numgroups) + { + if((k%2)==0) g.pushlist(); // horizontal + + scoregroup &sg = *groups[k]; + int bgcolor = sg.team && m_teammode ? (isteam(player1->team, sg.team) ? 0x3030C0 : 0xC03030) : 0, + fgcolor = 0xFFFF80; + + g.pushlist(); // vertical + g.pushlist(); // horizontal + + #define loopscoregroup(o, b) \ + loopv(sg.players) \ + { \ + fpsent *o = sg.players[i]; \ + b; \ + } + + g.pushlist(); + if(sg.team && m_teammode) + { + g.pushlist(); + g.background(bgcolor, numgroups>1 ? 3 : 5); + g.strut(1); + g.poplist(); + } + g.text("", 0, " "); + loopscoregroup(o, + { + if(o==player1 && highlightscore && (multiplayer(false) || demoplayback || players.length() > 1)) + { + g.pushlist(); + g.background(0x808080, numgroups>1 ? 3 : 5); + } + const playermodelinfo &mdl = getplayermodelinfo(o); + const char *icon = sg.team && m_teammode ? (isteam(player1->team, sg.team) ? mdl.blueicon : mdl.redicon) : mdl.ffaicon; + g.text("", 0, icon); + if(o==player1 && highlightscore && (multiplayer(false) || demoplayback || players.length() > 1)) g.poplist(); + }); + g.poplist(); + + if(sg.team && m_teammode) + { + g.pushlist(); // vertical + + if(sg.score>=10000) g.textf("%s: WIN", fgcolor, NULL, sg.team); + else g.textf("%s: %d", fgcolor, NULL, sg.team, sg.score); + + g.pushlist(); // horizontal + } + + if(!cmode || !cmode->hidefrags() || !hidefrags) + { + g.pushlist(); + g.strut(6); + g.text("frags", fgcolor); + loopscoregroup(o, g.textf("%d", 0xFFFFDD, NULL, o->frags)); + g.poplist(); + } + + if(showdeaths) + { + g.pushlist(); + g.strut(6); + g.text("deaths", fgcolor); + loopscoregroup(o, g.textf("%d", 0xFFFFDD, NULL, o->deaths)); + g.poplist(); + } + + g.pushlist(); + g.text("name", fgcolor); + g.strut(12); + loopscoregroup(o, + { + g.textf("%s ", statuscolor(o, 0xFFFFDD), NULL, colorname(o)); + }); + g.poplist(); + + if(multiplayer(false) || demoplayback) + { + if(showpj || showping) g.space(1); + + if(showpj && showping <= 1) + { + g.pushlist(); + g.strut(6); + g.text("pj", fgcolor); + loopscoregroup(o, + { + if(o->state==CS_LAGGED) g.text("LAG", 0xFFFFDD); + else g.textf("%d", 0xFFFFDD, NULL, o->plag); + }); + g.poplist(); + } + + if(showping > 1) + { + g.pushlist(); + g.strut(6); + + g.pushlist(); + g.text("ping", fgcolor); + g.space(1); + g.spring(); + g.text("pj", fgcolor); + g.poplist(); + + loopscoregroup(o, + { + fpsent *p = o->ownernum >= 0 ? getclient(o->ownernum) : o; + if(!p) p = o; + g.pushlist(); + if(p->state==CS_LAGGED) g.text("LAG", 0xFFFFDD); + else + { + g.textf("%d", 0xFFFFDD, NULL, p->ping); + g.space(1); + g.spring(); + g.textf("%d", 0xFFFFDD, NULL, o->plag); + } + g.poplist(); + + }); + g.poplist(); + } + else if(showping) + { + g.pushlist(); + g.text("ping", fgcolor); + g.strut(6); + loopscoregroup(o, + { + fpsent *p = o->ownernum >= 0 ? getclient(o->ownernum) : o; + if(!p) p = o; + if(!showpj && p->state==CS_LAGGED) g.text("LAG", 0xFFFFDD); + else g.textf("%d", 0xFFFFDD, NULL, p->ping); + }); + g.poplist(); + } + } + + if(showclientnum || player1->privilege>=PRIV_MASTER) + { + g.space(1); + g.pushlist(); + g.text("cn", fgcolor); + loopscoregroup(o, g.textf("%d", 0xFFFFDD, NULL, o->clientnum)); + g.poplist(); + } + + if(sg.team && m_teammode) + { + g.poplist(); // horizontal + g.poplist(); // vertical + } + + g.poplist(); // horizontal + g.poplist(); // vertical + + if(k+1privilege>=PRIV_MASTER) + { + g.pushlist(); + + g.pushlist(); + g.text("spectator", 0xFFFF80, " "); + g.strut(12); + loopv(spectators) + { + fpsent *o = spectators[i]; + if(o==player1 && highlightscore) + { + g.pushlist(); + g.background(0x808080, 3); + } + g.text(colorname(o), statuscolor(o, 0xFFFFDD), "spectator"); + if(o==player1 && highlightscore) g.poplist(); + } + g.poplist(); + + if((multiplayer(false) || demoplayback) && showspectatorping) + { + g.space(1); + g.pushlist(); + g.text("ping", 0xFFFF80); + g.strut(6); + loopv(spectators) + { + fpsent *o = spectators[i]; + fpsent *p = o->ownernum >= 0 ? getclient(o->ownernum) : o; + if(!p) p = o; + if(p->state==CS_LAGGED) g.text("LAG", 0xFFFFDD); + else g.textf("%d", 0xFFFFDD, NULL, p->ping); + } + g.poplist(); + } + + g.space(1); + g.pushlist(); + g.text("cn", 0xFFFF80); + loopv(spectators) g.textf("%d", 0xFFFFDD, NULL, spectators[i]->clientnum); + g.poplist(); + + g.poplist(); + } + else + { + g.textf("%d spectator%s", 0xFFFF80, " ", spectators.length(), spectators.length()!=1 ? "s" : ""); + loopv(spectators) + { + if((i%3)==0) + { + g.pushlist(); + g.text("", 0xFFFFDD, "spectator"); + } + fpsent *o = spectators[i]; + if(o==player1 && highlightscore) + { + g.pushlist(); + g.background(0x808080); + } + g.text(colorname(o), statuscolor(o, 0xFFFFDD)); + if(o==player1 && highlightscore) g.poplist(); + if(i+1score; + best = isteam(player1->team, g->team); + if(numgroups > 1) + { + if(best) score2 = groups[1]->score; + else for(int i = 1; i < groups.length(); ++i) if(isteam(player1->team, groups[i]->team)) { score2 = groups[i]->score; break; } + if(score2 == INT_MIN) + { + fpsent *p = followingplayer(player1); + if(p->state==CS_SPECTATOR) score2 = groups[1]->score; + } + } + } + else + { + fpsent *p = followingplayer(player1); + score = g->players[0]->frags; + best = p == g->players[0]; + if(g->players.length() > 1) + { + if(best || p->state==CS_SPECTATOR) score2 = g->players[1]->frags; + else score2 = p->frags; + } + } + if(score == score2 && !best) best = true; + + score = clamp(score, -999, 9999); + defformatstring(buf, "%d", score); + int tw = 0, th = 0; + text_bounds(buf, tw, th); + + string buf2; + int tw2 = 0, th2 = 0; + if(score2 > INT_MIN) + { + score2 = clamp(score2, -999, 9999); + formatstring(buf2, "%d", score2); + text_bounds(buf2, tw2, th2); + } + + int fw = 0, fh = 0; + text_bounds("00", fw, fh); + fw = max(fw, max(tw, tw2)); + + vec2 offset = vec2(hudscorex, hudscorey).mul(vec2(w, h).div(hudscorescale)); + if(hudscorealign == 1) offset.x -= 2*fw + hudscoresep; + else if(hudscorealign == 0) offset.x -= (2*fw + hudscoresep) / 2.0f; + vec2 offset2 = offset; + offset.x += (fw-tw)/2.0f; + offset.y -= th/2.0f; + offset2.x += fw + hudscoresep + (fw-tw2)/2.0f; + offset2.y -= th2/2.0f; + + pushhudmatrix(); + hudmatrix.scale(hudscorescale, hudscorescale, 1); + flushhudmatrix(); + + int color = hudscoreplayercolour, color2 = hudscoreenemycolour; + if(!best) swap(color, color2); + + draw_text(buf, int(offset.x), int(offset.y), (color>>16)&0xFF, (color>>8)&0xFF, color&0xFF, hudscorealpha); + if(score2 > INT_MIN) draw_text(buf2, int(offset2.x), int(offset2.y), (color2>>16)&0xFF, (color2>>8)&0xFF, color2&0xFF, hudscorealpha); + + pophudmatrix(); + } +} + -- cgit v1.2.3