[client] Implement the scoreboards and spectator

This gets the status bar/hud back into function state.
This commit is contained in:
Bill Currie 2022-11-13 04:04:27 +09:00
parent 47fb887724
commit 767b39b7bd
4 changed files with 288 additions and 271 deletions

View file

@ -38,6 +38,7 @@ void Sbar_Init (int *stats, float *item_gettime);
void Sbar_SetPlayers (struct player_info_s *players, int maxplayers); void Sbar_SetPlayers (struct player_info_s *players, int maxplayers);
void Sbar_SetLevelName (const char *levelname, const char *servername); void Sbar_SetLevelName (const char *levelname, const char *servername);
void Sbar_SetPlayerNum (int playernum, int spectator); void Sbar_SetPlayerNum (int playernum, int spectator);
void Sbar_SetAutotrack (int autotrack);
void Sbar_SetViewEntity (int viewentity); void Sbar_SetViewEntity (int viewentity);
void Sbar_SetTeamplay (int teamplay); void Sbar_SetTeamplay (int teamplay);
void Sbar_SetGameType (int gametype); void Sbar_SetGameType (int gametype);

View file

@ -83,6 +83,7 @@ static int sbar_maxplayers;
static int sbar_playernum; static int sbar_playernum;
static int sbar_viewplayer; static int sbar_viewplayer;
static int sbar_spectator; static int sbar_spectator;
static int sbar_autotrack = -1;
static int sbar_teamplay; static int sbar_teamplay;
static int sbar_gametype; static int sbar_gametype;
static int sbar_active; static int sbar_active;
@ -116,7 +117,8 @@ static view_t sbar_solo_anchor;
static view_t sbar_solo_name; static view_t sbar_solo_name;
static view_t sbar_tile[2]; static view_t sbar_tile[2];
static view_t sbar_tile[2]; static view_t sbar_tile[2];
static view_t dmo_view; static view_t spectator_view;
static view_t deathmatch_view;
typedef struct view_def_s { typedef struct view_def_s {
view_t *view; view_t *view;
@ -227,7 +229,12 @@ static view_def_t sbar_defs[] = {
{0, { 0, 0, 24, 24}, grav_northwest, &sbar_health, 3, 24, 0}, {0, { 0, 0, 24, 24}, grav_northwest, &sbar_health, 3, 24, 0},
{0, {10, 0, 24, 8}, grav_northwest, &sbar_miniammo, 4, 48, 0}, {0, {10, 0, 24, 8}, grav_northwest, &sbar_miniammo, 4, 48, 0},
{&dmo_view, { 0, 0,320, 200}, grav_center, &cl_screen_view}, {&spectator_view, { 0, 0,320, 32}, grav_south, &cl_screen_view},
{0, { 0, 0, 312, 8}, grav_north, &spectator_view, 1, 0, 0},
{0, { 0, 8, 320, 24}, grav_northwest, &spectator_view, 1, 0, 0},
{0, { 0, 12, 112, 8}, grav_north, &spectator_view, 1, 0, 0},
{0, { 0, 20, 232, 8}, grav_north, &spectator_view, 1, 0, 0},
{&deathmatch_view, { 0, 0,320, 200}, grav_center, &cl_screen_view},
{} {}
}; };
@ -237,6 +244,8 @@ static draw_charbuffer_t *fps_buff;
static draw_charbuffer_t *ping_buff; static draw_charbuffer_t *ping_buff;
static draw_charbuffer_t *pl_buff; static draw_charbuffer_t *pl_buff;
static draw_charbuffer_t *spec_buff[4];//0,1 no track, 2 lost track, 3 tracking
static draw_charbuffer_t *solo_monsters; static draw_charbuffer_t *solo_monsters;
static draw_charbuffer_t *solo_secrets; static draw_charbuffer_t *solo_secrets;
static draw_charbuffer_t *solo_time; static draw_charbuffer_t *solo_time;
@ -277,6 +286,12 @@ sbar_remcomponent (view_t view, uint32_t comp)
Ent_RemoveComponent (view.id, comp, view.reg); Ent_RemoveComponent (view.id, comp, view.reg);
} }
static inline void
set_update (view_t view, hud_update_f func)
{
sbar_setcomponent (view, hud_updateonce, &func);
}
#define STAT_MINUS 10 // num frame for '-' stats digit #define STAT_MINUS 10 // num frame for '-' stats digit
static qpic_t *sb_nums[2][11]; static qpic_t *sb_nums[2][11];
@ -308,7 +323,7 @@ static qpic_t *sb_face_invuln;
static qpic_t *sb_face_invis_invuln; static qpic_t *sb_face_invis_invuln;
qboolean sbar_showscores; qboolean sbar_showscores;
static qboolean sb_showteamscores; static qboolean sbar_showteamscores;
static int sb_lines; // scan lines to draw static int sb_lines; // scan lines to draw
@ -373,12 +388,43 @@ viewsize_f (int view_size)
} }
} }
static int __attribute__((used)) static int
Sbar_ColorForMap (int m) Sbar_ColorForMap (int m)
{ {
return (bound (0, m, 13) * 16) + 8; return (bound (0, m, 13) * 16) + 8;
} }
static int
write_charbuff_cl (draw_charbuffer_t *buffer, int x, int y, const char *str)
{
char *dst = buffer->chars;
int count = buffer->width - x;
int chars = 0;
dst += y * buffer->width + x;
while (*str && count-- > 0) {
*dst++ = *str++;
chars++;
}
while (count-- > 0) {
*dst++ = ' ';
}
return chars;
}
static int
write_charbuff (draw_charbuffer_t *buffer, int x, int y, const char *str)
{
char *dst = buffer->chars;
int count = buffer->width - x;
int chars = 0;
dst += y * buffer->width + x;
while (*str && count-- > 0) {
*dst++ = *str++;
chars++;
}
return chars;
}
static void static void
draw_num (view_t *view, int num, int digits, int color) draw_num (view_t *view, int num, int digits, int color)
{ {
@ -409,7 +455,7 @@ draw_num (view_t *view, int num, int digits, int color)
} }
} }
static inline void static void
draw_smallnum (view_t view, int n, int packed, int colored) draw_smallnum (view_t view, int n, int packed, int colored)
{ {
void *comp = sbar_getcomponent (view, hud_charbuff); void *comp = sbar_getcomponent (view, hud_charbuff);
@ -599,6 +645,8 @@ static draw_charbuffer_t *sb_pl[MAX_PLAYERS];
static draw_charbuffer_t *sb_uid[MAX_PLAYERS]; static draw_charbuffer_t *sb_uid[MAX_PLAYERS];
static draw_charbuffer_t *sb_name[MAX_PLAYERS]; static draw_charbuffer_t *sb_name[MAX_PLAYERS];
static draw_charbuffer_t *sb_team_frags[MAX_PLAYERS]; static draw_charbuffer_t *sb_team_frags[MAX_PLAYERS];
static draw_charbuffer_t *sb_team_players[MAX_PLAYERS];
static draw_charbuffer_t *sb_team_stats[MAX_PLAYERS];
static draw_charbuffer_t *sb_spectator; static draw_charbuffer_t *sb_spectator;
int scoreboardlines, scoreboardteams; int scoreboardlines, scoreboardteams;
@ -634,7 +682,7 @@ Sbar_SortFrags (qboolean includespec)
} }
} }
static void __attribute__((used)) static void
Sbar_SortTeams (void) Sbar_SortTeams (void)
{ {
char t[16 + 1]; char t[16 + 1];
@ -644,15 +692,13 @@ Sbar_SortTeams (void)
// request new ping times every two second // request new ping times every two second
scoreboardteams = 0; scoreboardteams = 0;
if (!sbar_teamplay)
return;
// sort the teams // sort the teams
memset (teams, 0, sizeof (teams)); memset (teams, 0, sizeof (teams));
for (i = 0; i < MAX_PLAYERS; i++) for (i = 0; i < sbar_maxplayers; i++)
teams[i].plow = 999; teams[i].plow = 999;
for (i = 0; i < MAX_PLAYERS; i++) { for (i = 0; i < sbar_maxplayers; i++) {
s = &sbar_players[i]; s = &sbar_players[i];
if (!s->name || !s->name->value[0]) if (!s->name || !s->name->value[0])
continue; continue;
@ -661,7 +707,8 @@ Sbar_SortTeams (void)
// find his team in the list // find his team in the list
t[16] = 0; t[16] = 0;
strncpy (t, s->team->value, 16); if (s->team)
strncpy (t, s->team->value, 16);
if (!t[0]) if (!t[0])
continue; // not on team continue; // not on team
for (j = 0; j < scoreboardteams; j++) for (j = 0; j < scoreboardteams; j++)
@ -683,6 +730,24 @@ Sbar_SortTeams (void)
teams[j].ptotal += s->ping; teams[j].ptotal += s->ping;
} }
} }
for (i = 0; i < sbar_maxplayers; i++) {
team_t *tm = teams + i;
int plow = tm->plow;
if (plow < 0 || plow > 999)
plow = 999;
int phigh = tm->phigh;
if (phigh < 0 || phigh > 999)
phigh = 999;
int pavg = !tm->players ? 999 : tm->ptotal / tm->players;
if (pavg < 0 || pavg > 999)
pavg = 999;
write_charbuff (sb_team_stats[i], 0, 0,
va (0, "%3i/%3i/%3i", plow, pavg, phigh));
write_charbuff (sb_team[i], 0, 0, tm->team);
write_charbuff (sb_team_frags[i], 0, 0, va (0, "%5d", tm->frags));
write_charbuff (sb_team_players[i], 0, 0, va (0, "%5d", tm->players));
}
// sort // sort
for (i = 0; i < scoreboardteams; i++) for (i = 0; i < scoreboardteams; i++)
@ -700,37 +765,6 @@ Sbar_SortTeams (void)
} }
} }
static int
write_charbuff_cl (draw_charbuffer_t *buffer, int x, int y, const char *str)
{
char *dst = buffer->chars;
int count = buffer->width - x;
int chars = 0;
dst += y * buffer->width + x;
while (*str && count-- > 0) {
*dst++ = *str++;
chars++;
}
while (count-- > 0) {
*dst++ = ' ';
}
return chars;
}
static int
write_charbuff (draw_charbuffer_t *buffer, int x, int y, const char *str)
{
char *dst = buffer->chars;
int count = buffer->width - x;
int chars = 0;
dst += y * buffer->width + x;
while (*str && count-- > 0) {
*dst++ = *str++;
chars++;
}
return chars;
}
static void static void
draw_solo_time (void) draw_solo_time (void)
{ {
@ -741,13 +775,23 @@ draw_solo_time (void)
} }
static void static void
draw_solo (void) draw_solo (view_t view)
{ {
draw_solo_time (); sbar_setcomponent (sbar_solo, hud_pic, &sb_scorebar);
view_pos_t len = View_GetLen (sbar_solo_name); sbar_setcomponent (sbar_solo_monsters, hud_charbuff, &solo_monsters);
len.x = 8 * solo_name->cursx; sbar_setcomponent (sbar_solo_secrets, hud_charbuff, &solo_secrets);
View_SetLen (sbar_solo_name, len.x, len.y); sbar_setcomponent (sbar_solo_time, hud_charbuff, &solo_time);
View_UpdateHierarchy (sbar_solo); sbar_setcomponent (sbar_solo_name, hud_charbuff, &solo_name);
}
static void
hide_solo (view_t view)
{
sbar_remcomponent (sbar_solo, hud_pic);
sbar_remcomponent (sbar_solo_monsters, hud_charbuff);
sbar_remcomponent (sbar_solo_secrets, hud_charbuff);
sbar_remcomponent (sbar_solo_time, hud_charbuff);
sbar_remcomponent (sbar_solo_name, hud_charbuff);
} }
static void static void
@ -973,30 +1017,46 @@ draw_face (view_t view)
sbar_setcomponent (view, hud_pic, &face); sbar_setcomponent (view, hud_pic, &face);
} }
static void __attribute__((used)) static void
draw_spectator (view_t *view) draw_spectator (view_t view)
{ {
#if 0 view_t tracking = View_GetChild (view, 0);
char st[512]; view_t back = View_GetChild (view, 1);
view_t notrack[] = {
View_GetChild (view, 2),
View_GetChild (view, 3),
};
if (autocam != CAM_TRACK) { if (sbar_autotrack < 0) {
draw_string (view, 160 - 7 * 8, 4, "SPECTATOR MODE"); sbar_setcomponent (back, hud_pic, &sb_scorebar);
draw_string (view, 160 - 14 * 8 + 4, 12, sbar_setcomponent (notrack[0], hud_charbuff, &spec_buff[0]);
"Press [ATTACK] for AutoCamera"); sbar_setcomponent (notrack[1], hud_charbuff, &spec_buff[1]);
sbar_remcomponent (tracking, hud_charbuff);
} else { } else {
// Sbar_DrawString (160-14*8+4,4, "SPECTATOR MODE - TRACK CAMERA"); sbar_remcomponent (back, hud_pic);
if (sbar_players[spec_track].name) { sbar_remcomponent (notrack[0], hud_charbuff);
snprintf (st, sizeof (st), "Tracking %-.13s, [JUMP] for next", sbar_remcomponent (notrack[1], hud_charbuff);
sbar_players[spec_track].name->value); if (sbar_players[sbar_autotrack].name) {
write_charbuff_cl (spec_buff[3], 0, 0,
va (0, "Tracking %.13s, [JUMP] for next",
sbar_players[sbar_autotrack].name->value));
sbar_setcomponent (tracking, hud_charbuff, &spec_buff[3]);
} else { } else {
snprintf (st, sizeof (st), "Lost player, [JUMP] for next"); sbar_setcomponent (tracking, hud_charbuff, &spec_buff[2]);
} }
draw_string (view, 0, -8, st);
} }
#endif
} }
static inline void static void
hide_spectator (view_t view)
{
for (int i = 0; i < 4; i++) {
sbar_remcomponent (View_GetChild (view, i), hud_charbuff);
sbar_remcomponent (View_GetChild (view, i), hud_pic);
}
}
static void
draw_armor (view_t view) draw_armor (view_t view)
{ {
view_t armor = View_GetChild (view, 0); view_t armor = View_GetChild (view, 0);
@ -1020,7 +1080,7 @@ draw_armor (view_t view)
} }
} }
static inline void static void
draw_health (view_t view) draw_health (view_t view)
{ {
view_t num[3] = { view_t num[3] = {
@ -1031,39 +1091,6 @@ draw_health (view_t view)
draw_num (num, sbar_stats[STAT_HEALTH], 3, sbar_stats[STAT_HEALTH] <= 25); draw_num (num, sbar_stats[STAT_HEALTH], 3, sbar_stats[STAT_HEALTH] <= 25);
} }
static void
draw_status (void )
{
sb_updates = 0;
sbar_setcomponent (sbar_solo, hud_pic, &sb_scorebar);
sbar_setcomponent (sbar_solo_monsters, hud_charbuff, &solo_monsters);
sbar_setcomponent (sbar_solo_secrets, hud_charbuff, &solo_secrets);
sbar_setcomponent (sbar_solo_time, hud_charbuff, &solo_time);
sbar_setcomponent (sbar_solo_name, hud_charbuff, &solo_name);
draw_solo ();
#if 0
if (sbar_spectator) {
draw_spectator (view);
if (autocam != CAM_TRACK)
return;
}
#endif
}
static void
hide_status (void)
{
sb_updates = 0;
sbar_remcomponent (sbar_solo, hud_pic);
sbar_remcomponent (sbar_solo_monsters, hud_charbuff);
sbar_remcomponent (sbar_solo_secrets, hud_charbuff);
sbar_remcomponent (sbar_solo_time, hud_charbuff);
sbar_remcomponent (sbar_solo_name, hud_charbuff);
}
static void static void
draw_rogue_ctf_face (view_t view) draw_rogue_ctf_face (view_t view)
{ {
@ -1106,16 +1133,19 @@ typedef struct dmo_def_s {
void (*setup) (view_t, int); void (*setup) (view_t, int);
} dmo_def_t; } dmo_def_t;
static dmo_def_t ping_def = { .width = 24, .buffer = sb_ping, }; static dmo_def_t ping_def = { .width = 24, .buffer = sb_ping };
static dmo_def_t pl_def = { .width = 24, .buffer = sb_pl, }; static dmo_def_t pl_def = { .width = 24, .buffer = sb_pl };
static dmo_def_t fph_def = { .width = 24, .buffer = sb_fph, }; static dmo_def_t fph_def = { .width = 24, .buffer = sb_fph };
static dmo_def_t time_def = { .width = 32, .buffer = sb_time, }; static dmo_def_t time_def = { .width = 32, .buffer = sb_time };
static dmo_def_t frags_def = { .width = 40, .setup = setup_frags, }; static dmo_def_t frags_def = { .width = 40, .setup = setup_frags };
static dmo_def_t team_def = { .width = 32, .buffer = sb_uid, }; static dmo_def_t team_def = { .width = 32, .buffer = sb_uid };
static dmo_def_t uid_def = { .width = 32, .buffer = sb_uid, }; static dmo_def_t uid_def = { .width = 32, .buffer = sb_uid };
static dmo_def_t name_def = { .width = 128, .buffer = sb_name, }; static dmo_def_t name_def = { .width = 128, .buffer = sb_name };
static dmo_def_t spectator_def = { .width = 112, .setup = setup_spect, }; static dmo_def_t spectator_def = { .width = 112, .setup = setup_spect };
static dmo_def_t spec_team_def = { .width = 32, }; static dmo_def_t spec_team_def = { .width = 32, };
static dmo_def_t team_frags_def = { .width = 40, .buffer = sb_team_frags };
static dmo_def_t team_stats_def = { .width = 88, .buffer = sb_team_stats };
static dmo_def_t team_players_def = { .width = 40, .buffer = sb_team_players };
static dmo_def_t *nq_dmo_defs[] = { static dmo_def_t *nq_dmo_defs[] = {
&frags_def, &frags_def,
@ -1164,15 +1194,6 @@ static dmo_def_t *qw_dmo_uid_ping_defs[] = {
0 0
}; };
static dmo_def_t *qw_dmo_uid_defs[] = { static dmo_def_t *qw_dmo_uid_defs[] = {
&ping_def,
&pl_def,
&fph_def,
&time_def,
&frags_def,
&name_def,
0
};
static dmo_def_t *qw_dmo_ping_defs[] = {
&uid_def, &uid_def,
&pl_def, &pl_def,
&fph_def, &fph_def,
@ -1181,16 +1202,26 @@ static dmo_def_t *qw_dmo_ping_defs[] = {
&name_def, &name_def,
0 0
}; };
static dmo_def_t *qw_dmo_spect_team_uid_ping_defs[] = { static dmo_def_t *qw_dmo_ping_defs[] = {
&ping_def, &ping_def,
&pl_def, &pl_def,
&fph_def,
&time_def,
&frags_def,
&name_def,
0
};
static dmo_def_t *qw_dmo_spect_team_uid_ping_defs[] = {
&uid_def,
&pl_def,
&spectator_def, &spectator_def,
&spec_team_def, &spec_team_def,
&ping_def,
&name_def, &name_def,
0 0
}; };
static dmo_def_t *qw_dmo_spect_team_uid_defs[] = { static dmo_def_t *qw_dmo_spect_team_uid_defs[] = {
&ping_def, &uid_def,
&pl_def, &pl_def,
&spectator_def, &spectator_def,
&spec_team_def, &spec_team_def,
@ -1209,11 +1240,12 @@ static dmo_def_t *qw_dmo_spect_uid_ping_defs[] = {
&ping_def, &ping_def,
&pl_def, &pl_def,
&spectator_def, &spectator_def,
&uid_def,
&name_def, &name_def,
0 0
}; };
static dmo_def_t *qw_dmo_spect_uid_defs[] = { static dmo_def_t *qw_dmo_spect_uid_defs[] = {
&ping_def, &uid_def,
&pl_def, &pl_def,
&spectator_def, &spectator_def,
&name_def, &name_def,
@ -1226,26 +1258,38 @@ static dmo_def_t *qw_dmo_spect_ping_defs[] = {
&name_def, &name_def,
0 0
}; };
static dmo_def_t *team_overlay_defs[] = {
&team_stats_def,
&team_def,
&team_frags_def,
&team_players_def,
0
};
static dmo_def_t **dmo_defs[] = { static dmo_def_t **dmo_defs[] = {
nq_dmo_defs, nq_dmo_defs,
team_overlay_defs,
qw_dmo_ping_defs, qw_dmo_ping_defs,
qw_dmo_uid_defs, qw_dmo_uid_defs,
qw_dmo_uid_ping_defs, qw_dmo_uid_ping_defs,
qw_dmo_team_ping_defs, qw_dmo_team_ping_defs,
qw_dmo_team_uid_defs, qw_dmo_team_uid_defs,
qw_dmo_team_uid_ping_defs, qw_dmo_team_uid_ping_defs,
qw_dmo_spect_ping_defs, qw_dmo_spect_ping_defs,
qw_dmo_spect_uid_defs, qw_dmo_spect_uid_defs,
qw_dmo_spect_uid_ping_defs, qw_dmo_spect_uid_ping_defs,
qw_dmo_spect_team_ping_defs, qw_dmo_spect_team_ping_defs,
qw_dmo_spect_team_uid_defs, qw_dmo_spect_team_uid_defs,
qw_dmo_spect_team_uid_ping_defs, qw_dmo_spect_team_uid_ping_defs,
}; };
static view_t static view_t
make_dmo_line (view_t parent, int player) make_dmo_line (view_t parent, int player, int line_type)
{ {
dmo_def_t **defs = dmo_defs[3]; //FIXME nq/qw/team/spec/cvar dmo_def_t **defs = dmo_defs[line_type];
int x = -8; int x = -8;
view_t line = sbar_view (0, 0, 0, 0, grav_north, parent); view_t line = sbar_view (0, 0, 0, 0, grav_north, parent);
@ -1272,14 +1316,9 @@ calc_fph (int frags, int total)
{ {
int fph; int fph;
if (total != 0) { if (total) {
fph = (3600 * frags) / total; fph = (3600 * frags) / total;
fph = bound (-999, fph, 999);
if (fph >= 999) {
fph = 999;
} else if (fph <= -999) {
fph = -999;
}
} else { } else {
fph = 0; fph = 0;
} }
@ -1287,32 +1326,46 @@ calc_fph (int frags, int total)
return fph; return fph;
} }
static int
dmo_line_type (void)
{
if (!sbar_servername) {
return 0;
} else if (sbar_showteamscores) {
return 1;
} else {
int team = !!sbar_teamplay;
int spect = !!sbar_spectator;
int mode = bound (0, hud_scoreboard_uid, 2);
return 2 + mode + team * 3 + spect * mode;
}
}
static void static void
Sbar_DeathmatchOverlay (view_t view) draw_deathmatch (view_t view)
{ {
Sbar_SortFrags (0); Sbar_SortFrags (0);
Sbar_SortTeams ();
int y = 40; int y = 40;
view_pos_t len = View_GetLen (view); view_pos_t len = View_GetLen (view);
int numbars = (len.y - y) / 10; int numbars = (len.y - y) / 10;
int count = min (scoreboardlines, numbars); int count = min (scoreboardlines, numbars);
int line_type = dmo_line_type ();
int i; int i;
if (sbar_stats[STAT_HEALTH] > 0) {
count = 0;
}
double cur_time = sbar_intermission ? sbar_completed_time : sbar_time; double cur_time = sbar_intermission ? sbar_completed_time : sbar_time;
for (i = 0; i < count; i++, y += 10) { for (i = 0; i < count; i++, y += 10) {
int k = fragsort[i]; int k = fragsort[i];
player_info_t *p = &sbar_players[k]; player_info_t *p = &sbar_players[k];
if (!View_Valid (sb_views[k])) { if (!View_Valid (sb_views[k])) {
sb_views[k] = make_dmo_line (view, k); sb_views[k] = make_dmo_line (view, k, line_type);
} }
int total = cur_time - p->entertime; int total = cur_time - p->entertime;
write_charbuff (sb_fph[k], 0, 0, va (0, "%3d", write_charbuff (sb_fph[k], 0, 0, va (0, "%3d",
calc_fph (p->frags, total))); calc_fph (p->frags, total)));
write_charbuff (sb_time[k], 0, 0, va (0, "%3d", total / 60)); write_charbuff (sb_time[k], 0, 0, va (0, "%4d", total / 60));
View_SetPos (sb_views[k], 0, y); View_SetPos (sb_views[k], 0, y);
} }
for (; i < MAX_PLAYERS; i++) { for (; i < MAX_PLAYERS; i++) {
@ -1324,106 +1377,40 @@ Sbar_DeathmatchOverlay (view_t view)
View_UpdateHierarchy (view); View_UpdateHierarchy (view);
} }
static void __attribute__((used))
Sbar_TeamOverlay (view_t *view)
{
#if 0
char num[20];
int pavg, plow, phigh, i, k, x, y;
team_t *tm;
info_key_t *player_team = sbar_players[sbar_playernum].team;
if (!sbar_teamplay) { // FIXME: if not teamplay, why teamoverlay?
Sbar_DeathmatchOverlay (view, 0);
return;
}
r_data->scr_copyeverything = 1;
r_data->scr_fullupdate = 0;
draw_cachepic (view, 0, 0, "gfx/ranking.lmp", 1);
y = 24;
x = 36;
draw_string (view, x, y, "low/avg/high team total players");
y += 8;
draw_string (view, x, y, "\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f "
"\x1d\x1e\x1e\x1f \x1d\x1e\x1e\x1e\x1f "
"\x1d\x1e\x1e\x1e\x1e\x1e\x1f");
y += 8;
// sort the teams
Sbar_SortTeams ();
// draw the text
for (i = 0; i < scoreboardteams && y <= view->ylen - 10; i++) {
k = teamsort[i];
tm = teams + k;
// draw pings
plow = tm->plow;
if (plow < 0 || plow > 999)
plow = 999;
phigh = tm->phigh;
if (phigh < 0 || phigh > 999)
phigh = 999;
if (!tm->players)
pavg = 999;
else
pavg = tm->ptotal / tm->players;
if (pavg < 0 || pavg > 999)
pavg = 999;
snprintf (num, sizeof (num), "%3i/%3i/%3i", plow, pavg, phigh);
draw_string (view, x, y, num);
// draw team
draw_nstring (view, x + 104, y, tm->team, 4);
// draw total
snprintf (num, sizeof (num), "%5i", tm->frags);
draw_string (view, x + 104 + 40, y, num);
// draw players
snprintf (num, sizeof (num), "%5i", tm->players);
draw_string (view, x + 104 + 88, y, num);
if (player_team && strnequal (player_team->value, tm->team, 16)) {
draw_character (view, x + 104 - 8, y, 16);
draw_character (view, x + 104 + 32, y, 17);
}
y += 8;
}
y += 8;
Sbar_DeathmatchOverlay (view, y);
#endif
}
#if 0
static void static void
Sbar_DrawScoreboard (void) hide_deathmatch (view_t view)
{ {
//Sbar_SoloScoreboard (); uint32_t count = View_ChildCount (view);
if (cl.gametype == GAME_DEATHMATCH) while (count-- > 0) {
Sbar_DeathmatchOverlay (hud_overlay_view); View_Delete (View_GetChild (view, count));
if (!sbar_active }
|| !((sbar_stats[STAT_HEALTH] <= 0 && !sbar_spectator) }
|| sbar_showscores || sb_showteamscores))
return; static void
// main screen deathmatch rankings draw_status (void )
// if we're dead show team scores in team games {
if (sbar_stats[STAT_HEALTH] <= 0 && !sbar_spectator) sb_updates = 0;
if (sbar_teamplay > 0 && !sbar_showscores)
Sbar_TeamOverlay (view);
else if (sbar_gametype) {
Sbar_DeathmatchOverlay (view, 0); draw_deathmatch (deathmatch_view);
else if (sbar_showscores) } else {
Sbar_DeathmatchOverlay (view, 0); if (sbar_spectator) {
else if (sb_showteamscores) if (sbar_autotrack < 0) {
Sbar_TeamOverlay (view); return;
}
}
draw_solo (sbar_solo);
}
}
static void
hide_status (void)
{
sb_updates = 0;
hide_solo (sbar_solo);
hide_deathmatch (deathmatch_view);
} }
#endif
/* autologging of frags after a match ended /* autologging of frags after a match ended
(called by recived network packet with command scv_intermission) (called by recived network packet with command scv_intermission)
@ -1710,25 +1697,28 @@ draw_cutscene (view_t view)
clear_views (view); clear_views (view);
} }
static inline void
set_update (view_t view, hud_update_f func)
{
sbar_setcomponent (view, hud_updateonce, &func);
}
void void
Sbar_Intermission (int mode, double completed_time) Sbar_Intermission (int mode, double completed_time)
{ {
static hud_update_f intermission_funcs[2][4] = { static hud_update_f intermission_funcs[2][3] = {
{ clear_views, draw_intermission, draw_finale, draw_cutscene, }, { draw_intermission, draw_finale, draw_cutscene, },
{ clear_views, Sbar_DeathmatchOverlay, draw_finale, draw_cutscene, }, { draw_deathmatch, draw_finale, draw_cutscene, },
};
static view_t *views[2][3] = {
{ &intermission_view, &intermission_view, &intermission_view },
{ &deathmatch_view, &intermission_view, &intermission_view },
}; };
sbar_completed_time = completed_time; sbar_completed_time = completed_time;
if ((unsigned) mode > 3) { if ((unsigned) mode > 3) {
mode = 0; mode = 0;
} }
sbar_intermission = mode; sbar_intermission = mode;
set_update (intermission_view, intermission_funcs[sbar_gametype][mode]); set_update (intermission_view, clear_views);
set_update (deathmatch_view, clear_views);
if (mode > 0) {
set_update (*views[sbar_gametype][mode - 1],
intermission_funcs[sbar_gametype][mode - 1]);
}
} }
void void
@ -1766,6 +1756,7 @@ Sbar_Update (double time)
sb_updates++; sb_updates++;
draw_weapons (sbar_weapons); draw_weapons (sbar_weapons);
draw_items (sbar_items); draw_items (sbar_items);
draw_face (sbar_face);
} }
} }
@ -1820,7 +1811,7 @@ update_health (int stat)
set_update (sbar_face, draw_face); set_update (sbar_face, draw_face);
if (sbar_stats[STAT_HEALTH] <= 0) { if (sbar_stats[STAT_HEALTH] <= 0) {
draw_status (); draw_status ();
} else if (!sbar_showscores) { } else if (1||!sbar_showscores) {
hide_status (); hide_status ();
} }
} }
@ -1832,7 +1823,7 @@ update_frags (int stat)
va (0, "%3d", sbar_stats[stat])); va (0, "%3d", sbar_stats[stat]));
set_update (sbar_frags, draw_frags);//FIXME set_update (sbar_frags, draw_frags);//FIXME
set_update (hud_minifrags, draw_minifrags);//FIXME set_update (hud_minifrags, draw_minifrags);//FIXME
set_update (dmo_view, Sbar_DeathmatchOverlay);//FIXME set_update (deathmatch_view, draw_deathmatch);//FIXME
if (sbar_teamplay) { if (sbar_teamplay) {
set_update (hud_miniteam, draw_miniteam);//FIXME set_update (hud_miniteam, draw_miniteam);//FIXME
} }
@ -1906,12 +1897,12 @@ update_monsters (int stat)
static void static void
update_items (int stat) update_items (int stat)
{ {
set_update (sbar_items, draw_items);//FIXME set_update (sbar_items, draw_items);
set_update (sbar_weapons, draw_weapons);
if (sb_item_count < 7) { if (sb_item_count < 7) {
// hipnotic and rogue don't use sigils // hipnotic and rogue don't use sigils
set_update (sbar_sigils, draw_sigils);//FIXME set_update (sbar_sigils, draw_sigils);
} }
set_update (sbar_weapons, draw_weapons);//FIXME
} }
typedef void (*stat_update_f) (int stat); typedef void (*stat_update_f) (int stat);
@ -1936,16 +1927,11 @@ static stat_update_f stat_update[MAX_CL_STATS] = {
void void
Sbar_UpdateStats (int stat) Sbar_UpdateStats (int stat)
{ {
if (stat == -1) { if ((unsigned) stat >= MAX_CL_STATS) {
for (int i = 0; i < MAX_CL_STATS; i++) { Sys_Error ("Sbar_UpdateStats: invalid stat: %d", stat);
if (stat_update[i]) { }
stat_update[i] (i); if (stat_update[stat]) {
} stat_update[stat] (stat);
}
} else {
if ((unsigned) stat < MAX_CL_STATS && stat_update[stat]) {
stat_update[stat] (stat);
}
} }
} }
@ -1960,6 +1946,23 @@ Sbar_SetPlayerNum (int playernum, int spectator)
{ {
sbar_playernum = playernum; sbar_playernum = playernum;
sbar_spectator = spectator; sbar_spectator = spectator;
if (sbar_spectator) {
set_update (spectator_view, draw_spectator);
} else {
set_update (spectator_view, hide_spectator);
}
}
void
Sbar_SetAutotrack (int autotrack)
{
sbar_autotrack = autotrack;
if (sbar_spectator) {
set_update (spectator_view, draw_spectator);
} else {
set_update (spectator_view, hide_spectator);
}
} }
void void
@ -1974,6 +1977,11 @@ Sbar_SetLevelName (const char *levelname, const char *servername)
sbar_levelname = levelname; sbar_levelname = levelname;
sbar_servername = servername; sbar_servername = servername;
solo_name->cursx = write_charbuff_cl (solo_name, 0, 0, sbar_levelname); solo_name->cursx = write_charbuff_cl (solo_name, 0, 0, sbar_levelname);
view_pos_t len = View_GetLen (sbar_solo_name);
len.x = 8 * solo_name->cursx;
View_SetLen (sbar_solo_name, len.x, len.y);
View_UpdateHierarchy (sbar_solo);
} }
void void
@ -2263,21 +2271,33 @@ init_views (void)
fps_buff = Draw_CreateBuffer (10, 1); fps_buff = Draw_CreateBuffer (10, 1);
ping_buff = Draw_CreateBuffer (6, 1); ping_buff = Draw_CreateBuffer (6, 1);
pl_buff = Draw_CreateBuffer (6, 1); pl_buff = Draw_CreateBuffer (6, 1);
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
sb_fph[i] = Draw_CreateBuffer (3, 1); sb_fph[i] = Draw_CreateBuffer (3, 1);
sb_time[i] = Draw_CreateBuffer (4, 1); sb_time[i] = Draw_CreateBuffer (4, 1);
sb_frags[i] = Draw_CreateBuffer (3, 1); sb_frags[i] = Draw_CreateBuffer (3, 1);
sb_team[i] = Draw_CreateBuffer (4, 1);
sb_ping[i] = Draw_CreateBuffer (3, 1); sb_ping[i] = Draw_CreateBuffer (3, 1);
sb_pl[i] = Draw_CreateBuffer (3, 1); sb_pl[i] = Draw_CreateBuffer (3, 1);
sb_uid[i] = Draw_CreateBuffer (4, 1); sb_uid[i] = Draw_CreateBuffer (4, 1);
sb_name[i] = Draw_CreateBuffer (16, 1); sb_name[i] = Draw_CreateBuffer (16, 1);
sb_team[i] = Draw_CreateBuffer (4, 1);
sb_team_stats[i] = Draw_CreateBuffer (11, 1);
sb_team_frags[i] = Draw_CreateBuffer (5, 1); sb_team_frags[i] = Draw_CreateBuffer (5, 1);
sb_team_players[i] = Draw_CreateBuffer (5, 1);
fragsort[i] = -1; fragsort[i] = -1;
} }
sb_spectator = Draw_CreateBuffer (11, 1); sb_spectator = Draw_CreateBuffer (11, 1);
write_charbuff (sb_spectator, 0, 0, "(spectator)"); write_charbuff (sb_spectator, 0, 0, "(spectator)");
spec_buff[0] = Draw_CreateBuffer (14, 1);
spec_buff[1] = Draw_CreateBuffer (29, 1);
spec_buff[2] = Draw_CreateBuffer (28, 1);
spec_buff[3] = Draw_CreateBuffer (39, 1);
write_charbuff (spec_buff[0], 0, 0, "SPECTATOR MODE");
write_charbuff (spec_buff[1], 0, 0, "Press [ATTACK] for AutoCamera");
write_charbuff (spec_buff[2], 0, 0, "Lost player, [JUMP] for next");
init_sbar_views (); init_sbar_views ();
} }
@ -2487,40 +2507,34 @@ load_pics (void)
static void static void
Sbar_ShowScores (void) Sbar_ShowScores (void)
{ {
if (sbar_showscores)
return;
sbar_showscores = true; sbar_showscores = true;
draw_status (); draw_status ();
} }
static void static void
Sbar_DontShowScores (void) Sbar_DontShowScores (void)
{ {
if (!sbar_showscores || sbar_stats[STAT_HEALTH] <= 0) { if (sbar_autotrack >= 0 && sbar_stats[STAT_HEALTH] <= 0) {
return; return;
} }
sbar_showscores = false; sbar_showscores = false;
hide_status (); hide_status ();
} }
static void static void
Sbar_ShowTeamScores (void) Sbar_ShowTeamScores (void)
{ {
if (sb_showteamscores) if (sbar_showteamscores)
return; return;
sb_showteamscores = true; sbar_showteamscores = true;
sb_updates = 0; sb_updates = 0;
} }
static void static void
Sbar_DontShowTeamScores (void) Sbar_DontShowTeamScores (void)
{ {
sb_showteamscores = false; sbar_showteamscores = false;
sb_updates = 0; sb_updates = 0;
} }

View file

@ -199,7 +199,7 @@ Cam_Unlock (void)
} }
autocam = CAM_NONE; autocam = CAM_NONE;
locked = false; locked = false;
Sbar_UpdateStats (-1); // update all stats Sbar_SetAutotrack (-1);
} }
} }
@ -221,7 +221,7 @@ Cam_Lock (int playernum)
last_lock = realtime; last_lock = realtime;
cam_forceview = true; cam_forceview = true;
locked = false; locked = false;
Sbar_UpdateStats (-1); // update all stats Sbar_SetAutotrack (spec_track);
} }
static trace_t static trace_t
@ -681,6 +681,7 @@ Cam_Reset (void)
autocam = CAM_NONE; autocam = CAM_NONE;
spec_track = 0; spec_track = 0;
ideal_track = 0; ideal_track = 0;
Sbar_SetAutotrack (-1);
} }
void void

View file

@ -775,11 +775,13 @@ CL_ParseServerData (void)
cl.viewentity = cl.playernum + 1; cl.viewentity = cl.playernum + 1;
cl.viewstate.bob_enabled = !cl.spectator; cl.viewstate.bob_enabled = !cl.spectator;
Sbar_SetPlayerNum (cl.playernum, cl.spectator);
// get the full level name // get the full level name
str = MSG_ReadString (net_message); str = MSG_ReadString (net_message);
strncpy (cl.levelname, str, sizeof (cl.levelname) - 1); strncpy (cl.levelname, str, sizeof (cl.levelname) - 1);
Sbar_SetLevelName (cl.levelname, cls.servername->str); Sbar_SetLevelName (cl.levelname, cls.servername->str);
Sbar_SetGameType (1);
// get the movevars // get the movevars
movevars.gravity = MSG_ReadFloat (net_message); movevars.gravity = MSG_ReadFloat (net_message);
@ -1139,7 +1141,6 @@ CL_ServerInfo (void)
// movevars.ktjump = atof (value); // movevars.ktjump = atof (value);
// FIXME: need to set to 0.5 otherwise, outside of else structure // FIXME: need to set to 0.5 otherwise, outside of else structure
} }
Sbar_SetGameType (0);
} }
static void static void