CLIENT: Improved scoreboard on HUD

This commit is contained in:
MotoLegacy 2025-01-14 21:14:19 -08:00
parent a823256f6e
commit 06d0f9208d
12 changed files with 202 additions and 31 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View file

@ -126,8 +126,6 @@ float screenflash_worktime;
float screenflash_starttime;
.float stance;
.float points;
.float kills;
vector camang; // used for punches

View file

@ -1516,16 +1516,56 @@ void() HUD_Broadcast =
Draw_String([x, g_height/2, 0], broadcast_msg, [0.015*g_width, 0.015*g_width, 0], [1, 1, 1], 1, 0);
};
void(float y_pos) HUD_DrawMoneyBackDisplay =
{
int i;
// Center moneyback
drawpic([g_width/2 - 48, y_pos], "gfx/hud/moneyback.tga", [96, 24], [1,1,1], 1);
// Left
for(i = 0; i < 3; i++) {
drawpic([(g_width/2 - 48) - (70 * (i + 1)), y_pos], "gfx/hud/moneyback.tga", [96, 24], [1,1,1], 1);
}
// Right
for(i = 0; i < 3; i++) {
drawpic([(g_width/2 - 48) + (70 * (i + 1)), y_pos], "gfx/hud/moneyback.tga", [96, 24], [1,1,1], 1);
}
};
void() HUD_Scores =
{
int j;
vector TEXTCOLOR = [1, 1, 1];
float header_x_start = -75;
float header_x_increment = 65;
float scoreboard_text_size = 10;
float header_x_pos = header_x_start;
if(serverkey("constate") != "disconnected")
{
// Headers
Draw_String([g_width/2 + 15, 175], "Points", [12, 12], TEXTCOLOR, 1, 0);
Draw_String([g_width/2 + 170, 175], "Kills", [12, 12], TEXTCOLOR, 1, 0);
Draw_String([5, g_height - scoreboard_text_size - 5], sprintf("Nazi Zombies: Portable %s", build_datetime), [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
// Scoreboard header
drawfill([g_width/2 - 271, 177], [270 * 2 + 2, 1], [0.2, 0.2, 0.2], 1, 0);
drawfill([g_width/2 - 271, 178 + scoreboard_text_size + 4], [270 * 2 + 2, 1], [0.2, 0.2, 0.2], 1, 0);
drawfill([g_width/2 - 271, 178], [1, scoreboard_text_size + 4], [0.2, 0.2, 0.2], 1, 0);
drawfill([g_width/2 + 270, 178], [1, scoreboard_text_size + 4], [0.2, 0.2, 0.2], 1, 0);
drawfill([g_width/2 - 270, 178], [270 * 2, scoreboard_text_size + 4], [0, 0, 0], 0.80, 0);
// Name
string map_name = serverkey("mapname_pretty");
Draw_String([g_width/2 - 265, 180], map_name, [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
Draw_String([g_width/2 + (header_x_pos - getTextWidth("Score", scoreboard_text_size)/2), 180], "Score", [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
Draw_String([g_width/2 + (header_x_pos - getTextWidth("Kills", scoreboard_text_size)/2), 180], "Kills", [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
Draw_String([g_width/2 + (header_x_pos - getTextWidth("Downs", scoreboard_text_size)/2), 180], "Downs", [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
Draw_String([g_width/2 + (header_x_pos - getTextWidth("Revives", scoreboard_text_size)/2), 180], "Revives", [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
Draw_String([g_width/2 + (header_x_pos - getTextWidth("Headshots", scoreboard_text_size)/2), 180], "Headshots", [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
for (int i = 0; i < 4; i = i + 1)
{
@ -1542,35 +1582,87 @@ void() HUD_Scores =
default: TEXTCOLOR = [1, 1, 1]; break;
}
//
// Since positioning is center-aligned, we need to be careful how we do our X and Y
// pos. to keep things looking nicely centered and even with different aspect ratios.
//
float y_pos = (scoreboard_text_size + 5) * i;
// Fill
drawfill([g_width/2 - 270, 195 + y_pos], [270 * 2, scoreboard_text_size + 5], [0, 0, 0], 0.80, 0);
drawfill([g_width/2 + (header_x_start - header_x_increment/2), 195 + y_pos], [header_x_increment, scoreboard_text_size + 5], [0.3, 0, 0], 0.15, 0);
drawfill([g_width/2 + ((header_x_start + header_x_increment*2) - header_x_increment/2), 195 + y_pos], [header_x_increment, scoreboard_text_size + 5], [0.3, 0, 0], 0.15, 0);
drawfill([g_width/2 + ((header_x_start + header_x_increment*4) - header_x_increment/2), 195 + y_pos], [header_x_increment, scoreboard_text_size + 5], [0.3, 0, 0], 0.15, 0);
// Top
if (i == 0)
drawfill([g_width/2 - 271, 194 + y_pos], [270 * 2 + 2, 1], [0.2, 0.2, 0.2], 1, 0);
// Bottom
if (player_count == i + 1)
drawfill([g_width/2 - 271, 195 + y_pos + scoreboard_text_size + 4], [270 * 2 + 2, 1], [0.2, 0.2, 0.2], 1, 0);
// Center moneyback
drawpic([g_width/2 - 48, 195 + (30 * i)], "gfx/hud/moneyback.tga", [96, 24], [1,1,1], 1);
// Left
for(j = 0; j < 3; j++) {
drawpic([(g_width/2 - 48) - (70 * (j+1)), 195 + (30 * i)], "gfx/hud/moneyback.tga", [96, 24], [1,1,1], 1);
}
// Right
for(j = 0; j < 3; j++) {
drawpic([(g_width/2 - 48) + (70 * (j+1)), 195 + (30 * i)], "gfx/hud/moneyback.tga", [96, 24], [1,1,1], 1);
}
drawfill([g_width/2 - 271, 194 + y_pos], [1, scoreboard_text_size + 6], [0.2, 0.2, 0.2], 1, 0);
// Right
drawfill([g_width/2 + 270, 194 + y_pos], [1, scoreboard_text_size + 6], [0.2, 0.2, 0.2], 1, 0);
header_x_pos = header_x_start;
// Name
string player_name = getplayerkeyvalue(i, "name");
Draw_String([g_width/2 - 245, 200 + (30 * i)], player_name, [12, 12], TEXTCOLOR, 1, 0);
Draw_String([g_width/2 - 265, 197 + y_pos], player_name, [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
// Points
float point_width = getTextWidth(ftos(client.points), 12);
float point_x = ((g_width/2) - (point_width)/2) + 52;
Draw_String([point_x, 200 + (30 * i)], ftos(client.points), [12, 12], TEXTCOLOR, 1, 0);
// Score
string score_string = ftos(client.points);
Draw_String([g_width/2 + (header_x_pos - getTextWidth(score_string, scoreboard_text_size)/2), 197 + y_pos], score_string, [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
// Kills
float kill_width = getTextWidth(ftos(client.kills), 12);
float kill_x = ((g_width/2) - (kill_width)/2) + 210;
Draw_String([kill_x, 200 + (30 * i)], ftos(client.kills), [12, 12], TEXTCOLOR, 1, 0);
string kills_string = ftos(client.kills);
Draw_String([g_width/2 + (header_x_pos - getTextWidth(kills_string, scoreboard_text_size)/2), 197 + y_pos], kills_string, [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
// Downs
string downs_string = ftos(client.downs);
Draw_String([g_width/2 + (header_x_pos - getTextWidth(downs_string, scoreboard_text_size)/2), 197 + y_pos], downs_string, [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
// Revives
string revives_string = ftos(client.revives);
Draw_String([g_width/2 + (header_x_pos - getTextWidth(revives_string, scoreboard_text_size)/2), 197 + y_pos], revives_string, [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
header_x_pos += header_x_increment;
// Headshots
string headshots_string = ftos(client.headshots);
Draw_String([g_width/2 + (header_x_pos - getTextWidth(headshots_string, scoreboard_text_size)/2), 197 + y_pos], headshots_string, [scoreboard_text_size, scoreboard_text_size], TEXTCOLOR, 1, 0);
// Ping
float ping_num_bars;
vector ping_bar_color = [0, 1, 0];
if (client.ping < 100) {
ping_num_bars = 4;
} else if (client.ping < 200) {
ping_num_bars = 3;
} else if (client.ping < 300) {
ping_num_bars = 2;
ping_bar_color = [1, 0.5, 0];
} else {
ping_num_bars = 1;
ping_bar_color = [1, 0, 0];
}
header_x_pos += 5 + header_x_increment/2;
float ping_bar_width = 2;
float ping_bar_height = 4;
float ping_bar_height_increment = 2;
string ping_string = sprintf("%dms", client.ping);
Draw_String([g_width/2 + ((header_x_pos + 28) - getTextWidth(ping_string, scoreboard_text_size - 2)/2), 199 + y_pos], ping_string, [scoreboard_text_size - 2, scoreboard_text_size - 2], TEXTCOLOR, 1, 0);
for(float bars = ping_num_bars; bars > 0; bars--) {
drawfill([g_width/2 + header_x_pos, 197 + y_pos + (11 - ping_bar_height)], [ping_bar_width, ping_bar_height], ping_bar_color, 1, 0);
ping_bar_height += ping_bar_height_increment;
header_x_pos += 3;
}
}
}
}

View file

@ -419,8 +419,12 @@ noref void(float isnew) CSQC_Ent_Update =
self.stance = readbyte();
self.points = readfloat(); // FIXME: this should be made a short, but I know we use price of 1 for some test maps, so I can't do /10 *10 shenanigans.
self.kills = readshort();
self.headshots = readshort();
self.downs = readshort();
self.revives = readshort();
self.is_in_menu = readbyte();
self.is_spectator = readbyte();
self.ping = readshort();
// set for HUD_PlayerDebugInfo
player_velocity = self.velocity;

View file

@ -542,6 +542,8 @@ Player_SendEntity
=================
*/
float Player_SendEntity( entity ePVEnt, float flChanged ) {
self.ping = infokeyf(self, "ping");
WriteByte( MSG_ENTITY, 1 );
WriteCoord( MSG_ENTITY, self.origin_x ); // Position X
WriteCoord( MSG_ENTITY, self.origin_y ); // Position Y
@ -560,8 +562,12 @@ float Player_SendEntity( entity ePVEnt, float flChanged ) {
WriteByte( MSG_ENTITY, self.stance ); // Player Stance
WriteFloat( MSG_ENTITY, self.points ); // Player Score
WriteShort( MSG_ENTITY, self.kills ); // Player Kills
WriteShort( MSG_ENTITY, self.headshots ); // Player Headshots
WriteShort( MSG_ENTITY, self.downs ); // Player Downs
WriteShort( MSG_ENTITY, self.revives ); // Player Revives
WriteByte( MSG_ENTITY, self.is_in_menu ); // Player is in a Menu State
WriteByte( MSG_ENTITY, self.is_spectator ); // Player is spectating
WriteShort( MSG_ENTITY, self.ping ); // Player's latency to the server in ms
return TRUE;
}

View file

@ -100,14 +100,11 @@ entity local_client;
.vector new_ofs;
//money
.float points;
.float cost;
.float cost2;
//stats
.float score;
.float kills;
.float headshots;
#ifdef FTE

View file

@ -409,6 +409,27 @@ void() worldspawn =
// Update the cvar for the server.
cvar_set("sv_gravity", ftos(sv_gravity * world.gravity));
#ifdef FTE
// We need to get the currently loaded map's pretty name
// (if it exists) so we can send it to clients or broadcast
// it.
string mapname_pretty;
float map_txt_file = fopen(sprintf("maps/%s.txt", mapname), FILE_READ);
if (map_txt_file == -1) {
mapname_pretty = mapname;
} else {
mapname_pretty = strtrim((fgets(map_txt_file)));
fclose(map_txt_file);
}
cvar_set("mapname_pretty", mapname_pretty);
localcmd(sprintf("serverinfo mapname_pretty %s\n", mapname_pretty));
#endif // FTE
}
void() SpectatorConnect =

View file

@ -44,6 +44,9 @@ void() LastStand_SoloRevive =
// Give the player their score back.
Player_AddScore(self.owner, self.owner.requirespower, false);
// Technically, this counts as a revive, I suppose.
self.owner.revives++;
// No need for us to exist anymore, goodbye!
remove(self);
};
@ -93,6 +96,9 @@ void(entity client) LastStand_Penalize =
self = old_self;
}
}
// Increment stat
client.downs++;
};
//
@ -381,8 +387,10 @@ void() LastStand_TouchReviveTrigger =
// Reviving has been executed for the full duration..
if (self.ltime < time) {
// Reward the revivee with the points the downed client lost
// Reward the revivee with the points the downed client lost,
// and increment their revives stat.
Player_AddScore(other, self.owner.requirespower, false);
self.owner.revives++;
entity old_self = self;
self = self.owner;

View file

@ -310,8 +310,16 @@ float map_compatibility_mode;
#define STAT_WEAPONSKIN 68
#define STAT_PERKS 69
// Misc. player statistics
.float playernum;
.float is_spectator;
.float ping;
.float kills;
.float headshots;
.float downs;
.float revives;
.float points;
float game_over;
#ifdef FTE

6
tools/compile-and-run.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
./qc-compiler-gnu.sh
cp ../build/fte/* ~/nzp-mac/nzp/
cd ~/nzp-mac/
wine nzportable-sdl64.exe +map ndu

0
tools/conhistory.txt Normal file
View file

31
tools/test-dedicated.sh Executable file
View file

@ -0,0 +1,31 @@
# Compile and copy files
./qc-compiler-gnu.sh
cp ../build/fte/* ~/nzp-mac/nzp/
cp ../build/fte/* ~/nzp-dedi/nzp/
# Start the dedicated server
cd ~/nzp-dedi/
nohup wine nzportable64.exe -dedicated +map ndu +hostname dedi-test > dedi.log 2>&1 &
disown
sleep 5
# Start the first client
cd ~/nzp-mac/
nohup wine nzportable-sdl64.exe +vid_width 640 +vid_height 480 +name client_1 +connect localhost > client_0.log 2>&1 &
disown
sleep 3
# Start the second client
nohup wine nzportable-sdl64.exe +vid_width 640 +vid_height 480 +name client_2 +connect localhost > client_1.log 2>&1 &
disown
sleep 3
Start the third client
nohup wine nzportable-sdl64.exe +vid_width 640 +vid_height 480 +name client_3 +connect localhost > client_1.log 2>&1 &
disown
sleep 3
Start the fourth client
nohup wine nzportable-sdl64.exe +vid_width 640 +vid_height 480 +name client_4 +connect localhost > client_1.log 2>&1 &
disown
sleep 3