about summary refs log tree commit diff
path: root/src/game/client/components/scoreboard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/client/components/scoreboard.cpp')
-rw-r--r--src/game/client/components/scoreboard.cpp254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp
new file mode 100644
index 00000000..075f249e
--- /dev/null
+++ b/src/game/client/components/scoreboard.cpp
@@ -0,0 +1,254 @@
+#include <string.h>
+
+#include <engine/e_client_interface.h>
+#include <game/generated/g_protocol.hpp>
+#include <game/generated/gc_data.hpp>
+#include <game/client/gameclient.hpp>
+#include <game/client/animstate.hpp>
+#include <game/client/gc_render.hpp>
+#include "scoreboard.hpp"
+
+void SCOREBOARD::render_goals(float x, float y, float w)
+{
+	float h = 50.0f;
+
+	gfx_blend_normal();
+	gfx_texture_set(-1);
+	gfx_quads_begin();
+	gfx_setcolor(0,0,0,0.5f);
+	draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
+	gfx_quads_end();
+
+	// render goals
+	//y = ystart+h-54;
+	if(gameclient.snap.gameobj && gameclient.snap.gameobj->time_limit)
+	{
+		char buf[64];
+		str_format(buf, sizeof(buf), "Time Limit: %d min", gameclient.snap.gameobj->time_limit);
+		gfx_text(0, x+w/2, y, 24.0f, buf, -1);
+	}
+	if(gameclient.snap.gameobj && gameclient.snap.gameobj->score_limit)
+	{
+		char buf[64];
+		str_format(buf, sizeof(buf), "Score Limit: %d", gameclient.snap.gameobj->score_limit);
+		gfx_text(0, x+40, y, 24.0f, buf, -1);
+	}
+}
+
+void SCOREBOARD::render_spectators(float x, float y, float w)
+{
+	char buffer[1024*4];
+	int count = 0;
+	float h = 120.0f;
+	
+	str_copy(buffer, "Spectators: ", sizeof(buffer));
+
+	gfx_blend_normal();
+	gfx_texture_set(-1);
+	gfx_quads_begin();
+	gfx_setcolor(0,0,0,0.5f);
+	draw_round_rect(x-10.f, y-10.f, w, h, 10.0f);
+	gfx_quads_end();
+	
+	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
+	{
+		SNAP_ITEM item;
+		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
+
+		if(item.type == NETOBJTYPE_PLAYER_INFO)
+		{
+			const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
+			if(info->team == -1)
+			{
+				if(count)
+					strcat(buffer, ", ");
+				strcat(buffer, gameclient.clients[info->cid].name);
+				count++;
+			}
+		}
+	}
+	
+	gfx_text(0, x+10, y, 32, buffer, (int)w-20);
+}
+
+void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const char *title)
+{
+	//float ystart = y;
+	float h = 750.0f;
+
+	gfx_blend_normal();
+	gfx_texture_set(-1);
+	gfx_quads_begin();
+	gfx_setcolor(0,0,0,0.5f);
+	draw_round_rect(x-10.f, y-10.f, w, h, 40.0f);
+	gfx_quads_end();
+
+	// render title
+	if(!title)
+	{
+		if(gameclient.snap.gameobj->game_over)
+			title = "Game Over";
+		else
+			title = "Score Board";
+	}
+
+	float tw = gfx_text_width(0, 48, title, -1);
+
+	if(team == -1)
+	{
+		gfx_text(0, x+w/2-tw/2, y, 48, title, -1);
+	}
+	else
+	{
+		gfx_text(0, x+10, y, 48, title, -1);
+
+		if(gameclient.snap.gameobj)
+		{
+			char buf[128];
+			int score = team ? gameclient.snap.gameobj->teamscore_blue : gameclient.snap.gameobj->teamscore_red;
+			str_format(buf, sizeof(buf), "%d", score);
+			tw = gfx_text_width(0, 48, buf, -1);
+			gfx_text(0, x+w-tw-30, y, 48, buf, -1);
+		}
+	}
+
+	y += 54.0f;
+
+	// find players
+	const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0};
+	int num_players = 0;
+	for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
+	{
+		SNAP_ITEM item;
+		const void *data = snap_get_item(SNAP_CURRENT, i, &item);
+
+		if(item.type == NETOBJTYPE_PLAYER_INFO)
+		{
+			players[num_players] = (const NETOBJ_PLAYER_INFO *)data;
+			num_players++;
+		}
+	}
+
+	// sort players
+	for(int k = 0; k < num_players; k++) // ffs, bubblesort
+	{
+		for(int i = 0; i < num_players-k-1; i++)
+		{
+			if(players[i]->score < players[i+1]->score)
+			{
+				const NETOBJ_PLAYER_INFO *tmp = players[i];
+				players[i] = players[i+1];
+				players[i+1] = tmp;
+			}
+		}
+	}
+
+	// render headlines
+	gfx_text(0, x+10, y, 24.0f, "Score", -1);
+	gfx_text(0, x+125, y, 24.0f, "Name", -1);
+	gfx_text(0, x+w-70, y, 24.0f, "Ping", -1);
+	y += 29.0f;
+
+	// render player scores
+	for(int i = 0; i < num_players; i++)
+	{
+		const NETOBJ_PLAYER_INFO *info = players[i];
+
+		// make sure that we render the correct team
+		if(team == -1 || info->team != team)
+			continue;
+
+		char buf[128];
+		float font_size = 35.0f;
+		if(info->local)
+		{
+			// background so it's easy to find the local player
+			gfx_texture_set(-1);
+			gfx_quads_begin();
+			gfx_setcolor(1,1,1,0.25f);
+			draw_round_rect(x, y, w-20, 48, 20.0f);
+			gfx_quads_end();
+		}
+
+		str_format(buf, sizeof(buf), "%4d", info->score);
+		gfx_text(0, x+60-gfx_text_width(0, font_size,buf,-1), y, font_size, buf, -1);
+		
+		gfx_text(0, x+128, y, font_size, gameclient.clients[info->cid].name, -1);
+
+		str_format(buf, sizeof(buf), "%4d", info->latency);
+		float tw = gfx_text_width(0, font_size, buf, -1);
+		gfx_text(0, x+w-tw-35, y, font_size, buf, -1);
+
+		// render avatar
+		if((gameclient.snap.flags[0] && gameclient.snap.flags[0]->carried_by == info->cid) ||
+			(gameclient.snap.flags[1] && gameclient.snap.flags[1]->carried_by == info->cid))
+		{
+			gfx_blend_normal();
+			gfx_texture_set(data->images[IMAGE_GAME].id);
+			gfx_quads_begin();
+
+			if(info->team == 0) select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
+			else select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
+			
+			float size = 64.0f;
+			gfx_quads_drawTL(x+55, y-15, size/2, size);
+			gfx_quads_end();
+		}
+		
+		render_tee(ANIMSTATE::get_idle(), &gameclient.clients[info->cid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
+
+		
+		y += 50.0f;
+	}
+}
+
+void SCOREBOARD::on_render()
+{
+	
+	// TODO: repair me
+	/*
+	bool do_scoreboard = false;
+
+	// if we are dead
+	if(!spectate && (!gameclient.snap.local_character || gameclient.snap.local_character->health < 0))
+		do_scoreboard = true;
+	
+	// if we the game is over
+	if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)
+		do_scoreboard = true;*/
+
+	
+	float width = 400*3.0f*gfx_screenaspect();
+	float height = 400*3.0f;
+	
+	gfx_mapscreen(0, 0, width, height);
+
+	float w = 650.0f;
+
+	if(gameclient.snap.gameobj && !(gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS))
+	{
+		render_scoreboard(width/2-w/2, 150.0f, w, 0, 0);
+		//render_scoreboard(gameobj, 0, 0, -1, 0);
+	}
+	else
+	{
+			
+		if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)
+		{
+			const char *text = "DRAW!";
+			if(gameclient.snap.gameobj->teamscore_red > gameclient.snap.gameobj->teamscore_blue)
+				text = "Red Team Wins!";
+			else if(gameclient.snap.gameobj->teamscore_blue > gameclient.snap.gameobj->teamscore_red)
+				text = "Blue Team Wins!";
+				
+			float w = gfx_text_width(0, 92.0f, text, -1);
+			gfx_text(0, width/2-w/2, 45, 92.0f, text, -1);
+		}
+		
+		render_scoreboard(width/2-w-20, 150.0f, w, 0, "Red Team");
+		render_scoreboard(width/2 + 20, 150.0f, w, 1, "Blue Team");
+	}
+
+	render_goals(width/2-w/2, 150+750+25, w);
+	render_spectators(width/2-w/2, 150+750+25+50+25, w);
+}