about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-11-08 12:50:46 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-11-08 12:50:46 +0000
commit388a04d957a0fd9af9287cbe6f1ee905371886c7 (patch)
treea493826c21bfca82dbd7b122d859025e0693c62e /src
parent4fa7806009ec4b6acfbf545e56d22e87ea5fa3f2 (diff)
downloadzcatch-388a04d957a0fd9af9287cbe6f1ee905371886c7.tar.gz
zcatch-388a04d957a0fd9af9287cbe6f1ee905371886c7.zip
better voting support
Diffstat (limited to 'src')
-rw-r--r--src/game/client/components/maplist.cpp45
-rw-r--r--src/game/client/components/maplist.hpp15
-rw-r--r--src/game/client/components/menus.hpp4
-rw-r--r--src/game/client/components/menus_ingame.cpp33
-rw-r--r--src/game/client/components/voting.cpp49
-rw-r--r--src/game/client/components/voting.hpp28
-rw-r--r--src/game/client/gameclient.cpp4
-rw-r--r--src/game/client/gameclient.hpp1
-rw-r--r--src/game/server/hooks.cpp85
9 files changed, 154 insertions, 110 deletions
diff --git a/src/game/client/components/maplist.cpp b/src/game/client/components/maplist.cpp
deleted file mode 100644
index 027ec449..00000000
--- a/src/game/client/components/maplist.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <engine/e_client_interface.h>
-#include <game/generated/g_protocol.hpp>
-
-#include "maplist.hpp"
-
-MAPLIST::MAPLIST()
-{
-	on_reset();
-}
-
-void MAPLIST::on_reset()
-{
-	buffer[0] = 0;
-	num_maps = 0;
-}
-
-static bool is_separator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
-
-void MAPLIST::on_message(int msgtype, void *rawmsg)
-{
-	if(msgtype == NETMSGTYPE_SV_MAPLIST)
-	{
-		NETMSG_SV_MAPLIST *msg = (NETMSG_SV_MAPLIST*)rawmsg;
-		str_copy(buffer, msg->names, sizeof(buffer));
-		
-		// parse list
-		num_maps = 0;
-		char *ptr = buffer;
-		while(*ptr)
-		{
-			while(*ptr && is_separator(*ptr))
-			{
-				*ptr = 0;
-				ptr++;
-			}
-
-			if(*ptr)
-			{
-				maps[num_maps++] = ptr;
-				while(*ptr && !is_separator(*ptr))
-					ptr++;
-			}
-		}
-	}
-}
diff --git a/src/game/client/components/maplist.hpp b/src/game/client/components/maplist.hpp
deleted file mode 100644
index 9b7ee1fd..00000000
--- a/src/game/client/components/maplist.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <game/client/component.hpp>
-
-class MAPLIST : public COMPONENT
-{
-	char buffer[2048];
-	const char *maps[128];
-	int num_maps;
-public:
-	MAPLIST();
-	virtual void on_reset();
-	virtual void on_message(int msgtype, void *rawmsg);
-	
-	int num() const { return num_maps; }
-	const char *name(int index) const { return maps[index]; }
-};
diff --git a/src/game/client/components/menus.hpp b/src/game/client/components/menus.hpp
index 6b72195e..ab4d5303 100644
--- a/src/game/client/components/menus.hpp
+++ b/src/game/client/components/menus.hpp
@@ -113,8 +113,8 @@ class MENUS : public COMPONENT
 	bool enter_pressed;
 	
 	// for call vote
+	int callvote_selectedoption;
 	int callvote_selectedplayer;
-	int callvote_selectedmap;
 	
 	// demo
 	struct DEMOITEM
@@ -146,7 +146,7 @@ class MENUS : public COMPONENT
 	void render_serverinfo(RECT main_view);
 	void render_servercontrol(RECT main_view);
 	void render_servercontrol_kick(RECT main_view);
-	void render_servercontrol_map(RECT main_view);
+	void render_servercontrol_server(RECT main_view);
 	
 	// found in menus_browser.cpp
 	int selected_index;
diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp
index d4b2b609..1cf359ba 100644
--- a/src/game/client/components/menus_ingame.cpp
+++ b/src/game/client/components/menus_ingame.cpp
@@ -16,7 +16,6 @@
 #include "menus.hpp"
 #include "motd.hpp"
 #include "voting.hpp"
-#include "maplist.hpp"
 
 void MENUS::render_game(RECT main_view)
 {
@@ -265,32 +264,39 @@ void MENUS::render_serverinfo(RECT main_view)
 	gfx_text(0, motd.x+x, motd.y+y, 16, gameclient.motd->server_motd, (int)motd.w);
 }
 
-void MENUS::render_servercontrol_map(RECT main_view)
+static const char *format_command(const char *cmd)
+{
+	return cmd;
+}
+
+void MENUS::render_servercontrol_server(RECT main_view)
 {
 	// draw header
 	RECT header, footer;
 	ui_hsplit_t(&main_view, 20, &header, &main_view);
 	ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); 
-	ui_do_label(&header, "Maps", 18.0f, 0);
+	ui_do_label(&header, "Options", 18.0f, 0);
 
 	// draw footers
 	ui_hsplit_b(&main_view, 20, &main_view, &footer);
 	ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); 
 	ui_vsplit_l(&footer, 10.0f, 0, &footer);
 
-	// maps
+	// options
 	ui_draw_rect(&main_view, vec4(0,0,0,0.15f), 0, 0);
 	RECT list = main_view;
-	for(int i = 0; i < gameclient.maplist->num(); i++)
+	int i = 0;
+	for(VOTING::VOTEOPTION *option = gameclient.voting->first; option; option = option->next)
 	{
 		RECT button;
 		ui_hsplit_t(&list, button_height, &button, &list);
 		
-		if(ui_do_button((char *)&gameclient.snap+i, "", callvote_selectedmap == i, &button, ui_draw_list_row, 0))
-			callvote_selectedmap = i;
+		if(ui_do_button(option, "", callvote_selectedoption == i, &button, ui_draw_list_row, 0))
+			callvote_selectedoption = i;
 
 		ui_vmargin(&button, 5.0f, &button);
-		ui_do_label(&button, gameclient.maplist->name(i), 18.0f, -1);
+		ui_do_label(&button, format_command(option->command), 18.0f, -1);
+		i++;
 	}
 }
 
@@ -345,7 +351,7 @@ void MENUS::render_servercontrol(RECT main_view)
 	
 	RECT button;
 	
-	const char *tabs[] = {"Map", "Kick"};
+	const char *tabs[] = {"Options", "Kick"};
 	int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs));
 
 	for(int i = 0; i < num_tabs; i++)
@@ -356,7 +362,7 @@ void MENUS::render_servercontrol(RECT main_view)
 		{
 			control_page = i;
 			callvote_selectedplayer = -1;
-			callvote_selectedmap = -1;
+			callvote_selectedoption = -1;
 		}
 	}
 		
@@ -367,7 +373,7 @@ void MENUS::render_servercontrol(RECT main_view)
 	
 	// render page		
 	if(control_page == 0)
-		render_servercontrol_map(main_view);
+		render_servercontrol_server(main_view);
 	else if(control_page == 1)
 		render_servercontrol_kick(main_view);
 		
@@ -381,8 +387,11 @@ void MENUS::render_servercontrol(RECT main_view)
 		{
 			if(control_page == 0)
 			{
+				//
+				gameclient.voting->callvote_option(callvote_selectedoption);
+				/*
 				if(callvote_selectedmap >= 0 && callvote_selectedmap < gameclient.maplist->num())
-					gameclient.voting->callvote_map(gameclient.maplist->name(callvote_selectedmap));
+					gameclient.voting->callvote_map(gameclient.maplist->name(callvote_selectedmap));*/
 			}
 			else if(control_page == 1)
 			{
diff --git a/src/game/client/components/voting.cpp b/src/game/client/components/voting.cpp
index 7411e2ca..f267542b 100644
--- a/src/game/client/components/voting.cpp
+++ b/src/game/client/components/voting.cpp
@@ -36,9 +36,20 @@ void VOTING::callvote_kick(int client_id)
 	callvote("kick", buf);
 }
 
-void VOTING::callvote_map(const char *map)
+void VOTING::callvote_option(int option_id)
 {
-	callvote("map", map);
+	VOTEOPTION *option = this->first;
+	while(option && option_id >= 0)
+	{
+		if(option_id == 0)
+		{
+			callvote("option", option->command);
+			break;
+		}
+		
+		option_id--;
+		option = option->next;
+	}
 }
 
 void VOTING::vote(int v)
@@ -50,9 +61,22 @@ void VOTING::vote(int v)
 
 VOTING::VOTING()
 {
+	heap = 0;
+	clearoptions();
 	on_reset();
 }
 
+
+void VOTING::clearoptions()
+{
+	if(heap)
+		memheap_destroy(heap);
+	heap = memheap_create();
+	
+	first = 0;
+	last = 0;
+}
+
 void VOTING::on_reset()
 {
 	closetime = 0;
@@ -91,6 +115,27 @@ void VOTING::on_message(int msgtype, void *rawmsg)
 		pass = msg->pass;
 		total = msg->total;
 	}	
+	else if(msgtype == NETMSGTYPE_SV_VOTE_CLEAROPTIONS)
+	{
+		clearoptions();
+	}
+	else if(msgtype == NETMSGTYPE_SV_VOTE_OPTION)
+	{
+		NETMSG_SV_VOTE_OPTION *msg = (NETMSG_SV_VOTE_OPTION *)rawmsg;
+		int len = str_length(msg->command);
+	
+		VOTEOPTION *option = (VOTEOPTION *)memheap_allocate(heap, sizeof(VOTEOPTION) + len);
+		option->next = 0;
+		option->prev = last;
+		if(option->prev)
+			option->prev->next = option;
+		last = option;
+		if(!first)
+			first = option;
+		
+		mem_copy(option->command, msg->command, len+1);
+
+	}
 }
 
 void VOTING::on_render()
diff --git a/src/game/client/components/voting.hpp b/src/game/client/components/voting.hpp
index 78e561c7..3341edea 100644
--- a/src/game/client/components/voting.hpp
+++ b/src/game/client/components/voting.hpp
@@ -1,17 +1,14 @@
 #include <game/client/component.hpp>
 #include <game/client/ui.hpp>
 
-class VOTING : public COMPONENT
+extern "C"
 {
-	/*
-	void render_goals(float x, float y, float w);
-	void render_spectators(float x, float y, float w);
-	void render_scoreboard(float x, float y, float w, int team, const char *title);
+	#include <engine/e_memheap.h>
+}
 
-	static void con_key_scoreboard(void *result, void *user_data);
-	
-	bool active;
-	*/
+class VOTING : public COMPONENT
+{
+	HEAP *heap;
 
 	static void con_callvote(void *result, void *user_data);
 	static void con_vote(void *result, void *user_data);
@@ -21,9 +18,20 @@ class VOTING : public COMPONENT
 	char command[512];
 	int voted;
 	
+	void clearoptions();
 	void callvote(const char *type, const char *value);
 	
 public:
+
+	struct VOTEOPTION
+	{
+		VOTEOPTION *next;
+		VOTEOPTION *prev;
+		char command[1];
+	};
+	VOTEOPTION *first;
+	VOTEOPTION *last;
+
 	VOTING();
 	virtual void on_reset();
 	virtual void on_console_init();
@@ -33,7 +41,7 @@ public:
 	void render_bars(RECT bars, bool text);
 	
 	void callvote_kick(int client_id);
-	void callvote_map(const char *map);
+	void callvote_option(int option);
 	
 	void vote(int v); // -1 = no, 1 = yes
 	
diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp
index 912a0c5d..dc5d4225 100644
--- a/src/game/client/gameclient.cpp
+++ b/src/game/client/gameclient.cpp
@@ -24,7 +24,6 @@
 #include "components/killmessages.hpp"
 #include "components/mapimages.hpp"
 #include "components/maplayers.hpp"
-#include "components/maplist.hpp"
 #include "components/menus.hpp"
 #include "components/motd.hpp"
 #include "components/particles.hpp"
@@ -63,7 +62,6 @@ static PLAYERS players;
 static NAMEPLATES nameplates;
 static ITEMS items;
 static MAPIMAGES mapimages;
-static MAPLIST maplist;
 
 static MAPLAYERS maplayers_background(MAPLAYERS::TYPE_BACKGROUND);
 static MAPLAYERS maplayers_foreground(MAPLAYERS::TYPE_FOREGROUND);
@@ -110,7 +108,6 @@ void GAMECLIENT::on_console_init()
 	damageind = &::damageind;
 	mapimages = &::mapimages;
 	voting = &::voting;
-	maplist = &::maplist;
 	
 	// make a list of all the systems, make sure to add them in the corrent render order
 	all.add(skins);
@@ -122,7 +119,6 @@ void GAMECLIENT::on_console_init()
 	all.add(camera);
 	all.add(sounds);
 	all.add(voting);
-	all.add(maplist);
 	all.add(particles); // doesn't render anything, just updates all the particles
 	
 	all.add(&maplayers_background); // first to render
diff --git a/src/game/client/gameclient.hpp b/src/game/client/gameclient.hpp
index c93a9168..d4c8510a 100644
--- a/src/game/client/gameclient.hpp
+++ b/src/game/client/gameclient.hpp
@@ -142,7 +142,6 @@ public:
 	class MOTD *motd;
 	class MAPIMAGES *mapimages;
 	class VOTING *voting;
-	class MAPLIST *maplist;
 };
 
 extern GAMECLIENT gameclient;
diff --git a/src/game/server/hooks.cpp b/src/game/server/hooks.cpp
index f75df009..991c06c1 100644
--- a/src/game/server/hooks.cpp
+++ b/src/game/server/hooks.cpp
@@ -7,6 +7,10 @@
 
 #include <engine/e_config.h>
 #include <engine/e_server_interface.h>
+extern "C"
+{
+	#include <engine/e_memheap.h>
+}
 #include <game/version.hpp>
 #include <game/collision.hpp>
 #include <game/layers.hpp>
@@ -20,6 +24,16 @@
 
 TUNING_PARAMS tuning;
 
+struct VOTEOPTION
+{
+	VOTEOPTION *next;
+	VOTEOPTION *prev;
+	char command[1];
+};
+
+static HEAP *voteoption_heap = 0;
+static VOTEOPTION *voteoption_first = 0;
+static VOTEOPTION *voteoption_last = 0;
 
 void send_tuning_params(int cid)
 {
@@ -120,7 +134,7 @@ void mods_client_drop(int client_id)
 	(void) game.controller->check_team_balance();
 }
 
-static bool is_separator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
+/*static bool is_separator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
 
 static const char *liststr_find(const char *str, const char *needle)
 {
@@ -138,7 +152,7 @@ static const char *liststr_find(const char *str, const char *needle)
 	}
 	
 	return 0;
-}
+}*/
 
 void mods_message(int msgtype, int client_id)
 {
@@ -189,23 +203,28 @@ void mods_message(int msgtype, int client_id)
 		char desc[512] = {0};
 		char cmd[512] = {0};
 		NETMSG_CL_CALLVOTE *msg = (NETMSG_CL_CALLVOTE *)rawmsg;
-		if(str_comp_nocase(msg->type, "map") == 0)
+		if(str_comp_nocase(msg->type, "option") == 0)
 		{
-			if(!config.sv_vote_map)
+			VOTEOPTION *option = voteoption_first;
+			while(option)
 			{
-				game.send_chat(-1, client_id, "Server does not allow voting on map");
-				return;
+				if(str_comp_nocase(msg->value, option->command) == 0)
+				{
+					str_format(chatmsg, sizeof(chatmsg), "Vote called to change server option '%s'", option->command);
+					str_format(desc, sizeof(desc), "%s", option->command);
+					str_format(cmd, sizeof(cmd), "%s", option->command);
+					break;
+				}
+
+				option = option->next;
 			}
 			
-			if(!liststr_find(config.sv_maplist, msg->value))
+			if(!option)
 			{
-				game.send_chat(-1, client_id, "Map is not in the map list");
+				str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value);
+				game.send_chat(-1, client_id, chatmsg);
 				return;
 			}
-			
-			str_format(chatmsg, sizeof(chatmsg), "Vote called to change map to '%s'", msg->value);
-			str_format(desc, sizeof(desc), "Change map to '%s'", msg->value);
-			str_format(cmd, sizeof(cmd), "change_map %s", msg->value);
 		}
 		else if(str_comp_nocase(msg->type, "kick") == 0)
 		{
@@ -316,17 +335,23 @@ void mods_message(int msgtype, int client_id)
 		
 		if(msgtype == NETMSGTYPE_CL_STARTINFO)
 		{
-			// send tuning parameters to client
-			send_tuning_params(client_id);
-			
-			// send maps to the client
+			// send vote options
+			NETMSG_SV_VOTE_CLEAROPTIONS clearmsg;
+			clearmsg.pack(MSGFLAG_VITAL);
+			server_send_msg(client_id);
+			VOTEOPTION *current = voteoption_first;
+			while(current)
 			{
-				NETMSG_SV_MAPLIST m;
-				m.names = config.sv_maplist;
-				m.pack(MSGFLAG_VITAL);
+				NETMSG_SV_VOTE_OPTION optionmsg;
+				optionmsg.command = current->command;
+				optionmsg.pack(MSGFLAG_VITAL);
 				server_send_msg(client_id);
+				current = current->next;
 			}
 			
+			// send tuning parameters to client
+			send_tuning_params(client_id);
+
 			//
 			NETMSG_SV_READYTOENTER m;
 			m.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH);
@@ -425,6 +450,26 @@ static void con_set_team(void *result, void *user_data)
 	(void) game.controller->check_team_balance();
 }
 
+static void con_addvote(void *result, void *user_data)
+{
+	int len = strlen(console_arg_string(result, 0));
+	
+	if(!voteoption_heap)
+		voteoption_heap = memheap_create();
+	
+	VOTEOPTION *option = (VOTEOPTION *)memheap_allocate(voteoption_heap, sizeof(VOTEOPTION) + len);
+	option->next = 0;
+	option->prev = voteoption_last;
+	if(option->prev)
+		option->prev->next = option;
+	voteoption_last = option;
+	if(!voteoption_first)
+		voteoption_first = option;
+	
+	mem_copy(option->command, console_arg_string(result, 0), len+1);
+	dbg_msg("server", "added option '%s'", option->command);
+}
+
 void mods_console_init()
 {
 	MACRO_REGISTER_COMMAND("tune", "si", con_tune_param, 0);
@@ -436,6 +481,8 @@ void mods_console_init()
 	MACRO_REGISTER_COMMAND("broadcast", "r", con_broadcast, 0);
 	MACRO_REGISTER_COMMAND("say", "r", con_say, 0);
 	MACRO_REGISTER_COMMAND("set_team", "ii", con_set_team, 0);
+
+	MACRO_REGISTER_COMMAND("addvote", "r", con_addvote, 0);
 }
 
 void mods_init()