about summary refs log tree commit diff
path: root/src/game
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-07-21 18:07:27 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-07-21 18:07:27 +0000
commit9e4aea97bdb5a903150df57f8d546733ce4b4db2 (patch)
tree7e18776bd7ace981895bca01ac753c9c289a71a5 /src/game
parentf0e8502050ce27b9cef72fa385619d13faa35c27 (diff)
downloadzcatch-9e4aea97bdb5a903150df57f8d546733ce4b4db2.tar.gz
zcatch-9e4aea97bdb5a903150df57f8d546733ce4b4db2.zip
lots of cool new features :D new master server
Diffstat (limited to 'src/game')
-rw-r--r--src/game/client/game_client.cpp21
-rw-r--r--src/game/client/menu.cpp182
-rw-r--r--src/game/game.h5
-rw-r--r--src/game/server/game_server.cpp109
-rw-r--r--src/game/server/game_server.h25
5 files changed, 168 insertions, 174 deletions
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index e3a0ab76..359bb880 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -201,7 +201,7 @@ public:
 		{
 			i->pos = pos;
 			i->life = 0.75f;
-			i->dir = dir;
+			i->dir = dir*-1;
 			i->startangle = (( (float)rand()/(float)RAND_MAX) - 1.0f) * 2.0f * pi;
 		}
 	}
@@ -382,7 +382,7 @@ void modc_init()
 {
 	// load the data container
 	data = load_data_container("data/client.dat");
-	
+
 	// load sounds
 	for(int s = 0; s < data->num_sounds; s++)
 		for(int i = 0; i < data->sounds[s].num_sounds; i++)
@@ -505,15 +505,17 @@ static void render_projectile(obj_projectile *prev, obj_projectile *current)
 	gfx_quads_begin();
 	
 	select_sprite(data->weapons[current->type%data->num_weapons].sprite_proj);
-	vec2 vel(current->vx, current->vy);
+	vec2 vel = mix(vec2(prev->vx, prev->vy), vec2(current->vx, current->vy), client_intratick());
+	vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
 	
-	// TODO: interpolare angle aswell
 	if(length(vel) > 0.00001f)
 		gfx_quads_setrotation(get_angle(vel));
 	else
 		gfx_quads_setrotation(0);
 	
-	vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
+	// TODO: do this, but nice
+	//temp_system.new_particle(pos, vec2(0,0), 0.3f, 14.0f, 0, 0.95f);
+
 	gfx_quads_draw(pos.x, pos.y,32,32);
 	gfx_quads_setrotation(0);
 	gfx_quads_end();
@@ -898,7 +900,8 @@ void modc_render()
 		if(mouse_pos.x < 0)
 			a = a+pi;
 			
-		input.angle = (int)(a*256.0f);
+		input.target_x = (int)mouse_pos.x; //(int)(a*256.0f);
+		input.target_y = (int)mouse_pos.y; //(int)(a*256.0f);
 		input.activeweapon = -1;
 		
 		if(!chat_active)
@@ -912,10 +915,8 @@ void modc_render()
 			input.blink = inp_key_pressed('S');
 			
 			// Weapon switching
-			input.activeweapon = inp_key_pressed('1') ? 0 : input.activeweapon;
-			input.activeweapon = inp_key_pressed('2') ? 1 : input.activeweapon;
-			input.activeweapon = inp_key_pressed('3') ? 2 : input.activeweapon;
-			input.activeweapon = inp_key_pressed('4') ? 3 : input.activeweapon;
+			for(int i = 0; i < 8; i++)
+				input.activeweapon = inp_key_pressed('1'+i) ? i : input.activeweapon;
 		}
 
 		snap_input(&input, sizeof(input));
diff --git a/src/game/client/menu.cpp b/src/game/client/menu.cpp
index 0d10116f..96d75fd6 100644
--- a/src/game/client/menu.cpp
+++ b/src/game/client/menu.cpp
@@ -11,6 +11,7 @@
 #include <baselib/system.h>
 #include <baselib/input.h>
 #include <baselib/network.h>
+#include <baselib/math.h>
 
 #include <engine/interface.h>
 #include <engine/versions.h>
@@ -22,6 +23,7 @@
 #include <engine/config.h>
 
 #include "data.h"
+#include <mastersrv/mastersrv.h>
 
 extern data_container *data;
 
@@ -234,6 +236,7 @@ void draw_teewars_button(void *id, const char *text, int checked, float x, float
 	ui_do_label(x + w/2 - text_width/2, y, text, 46);
 }
 
+/*
 struct server_info
 {
 	int version;
@@ -242,11 +245,10 @@ struct server_info
 	netaddr4 address;
 	char name[129];
 	char map[65];
-};
+};*/
 
 struct server_list
 {   
-    server_info infos[10];
 	int active_count, info_count;
 	int scroll_index;
 	int selected_index;
@@ -555,7 +557,7 @@ int do_scroll_bar_vert(void *id, float x, float y, float height, int steps, int
 	return r;
 }
 
-static int do_server_list(server_list *list, float x, float y, int visible_items)
+static int do_server_list(float x, float y, int *scroll_index, int *selected_index, int visible_items)
 {
 	const float spacing = 3.f;
 	const float item_height = 28;
@@ -563,22 +565,27 @@ static int do_server_list(server_list *list, float x, float y, int visible_items
 	const float real_width = item_width + 20;
 	const float real_height = item_height * visible_items + spacing * (visible_items - 1);
 
+	server_info *servers;
+	int num_servers = client_serverbrowse_getlist(&servers);
+
 	int r = -1;
 
 	for (int i = 0; i < visible_items; i++)
 	{
-		int item_index = i + list->scroll_index;
-		if (item_index >= list->active_count);
+		int item_index = i + *scroll_index;
+		if (item_index >= num_servers)
+			;
 			//ui_do_image(empty_item_texture, x, y + i * item_height + i * spacing, item_width, item_height);
 		else
 		{
-			server_info *item = &list->infos[item_index];
+			server_info *item = &servers[item_index];
 
 			bool clicked = false;
-			clicked = ui_do_button(item, item->name, 0, x, y + i * item_height + i * spacing, item_width, item_height, draw_menu_button, (list->selected_index == item_index) ? (void *)1 : 0);
+			clicked = ui_do_button(item, item->name, 0, x, y + i * item_height + i * spacing, item_width, item_height,
+				draw_menu_button, (*selected_index == item_index) ? (void *)1 : 0);
 
 			char temp[64]; // plenty of extra room so we don't get sad :o
-			sprintf(temp, "%i/%i", item->players, item->max_players);
+			sprintf(temp, "%i/%i  %3d", item->num_players, item->max_players, item->latency);
 
 			ui_do_label(x + 600, y + i * item_height + i * spacing, temp, item_height);
 			ui_do_label(x + 360, y + i * item_height + i * spacing, item->map, item_height);
@@ -586,136 +593,17 @@ static int do_server_list(server_list *list, float x, float y, int visible_items
 			if (clicked)
 			{
 				r = item_index;
-				list->selected_index = item_index;
+				*selected_index = item_index;
 			}
 		}
 	}
 
-	list->scroll_index = do_scroll_bar_vert(&list->scroll_index, x + real_width - 16, y, real_height, list->active_count - visible_items, list->scroll_index);
+	*scroll_index = do_scroll_bar_vert(scroll_index, x + real_width - 16, y, real_height,
+		min(num_servers - visible_items, 0), *scroll_index);
 	
 	return r;
 }
 
-static char *read_int(char *buffer, int *value)
-{
-    *value = buffer[0] << 24;
-    *value |= buffer[1] << 16;
-    *value |= buffer[2] << 8;
-    *value |= buffer[3];
-
-	return buffer + 4;
-}
-
-static char *read_netaddr(char *buffer, netaddr4 *addr)
-{
-	addr->ip[0] = *buffer++;
-	addr->ip[1] = *buffer++;
-	addr->ip[2] = *buffer++;
-	addr->ip[3] = *buffer++;
-
-	int port;
-	buffer = read_int(buffer, &port);
-
-	addr->port = port;
-
-	return buffer;
-}
-
-static void refresh_list(server_list *list)
-{
-	netaddr4 addr;
-	netaddr4 me(0, 0, 0, 0, 0);
-
-	list->selected_index = -1;
-	
-	if (net_host_lookup(MASTER_SERVER_ADDRESS, MASTER_SERVER_PORT, &addr) == 0)
-    {
-        socket_tcp4 sock;
-        sock.open(&me);
-
-		//sock.set_non_blocking();
-
-		// try and connect with a timeout of 1 second
-        if (sock.connect_non_blocking(&addr))
-        {
-            char data[256];
-            int total_received = 0;
-            int received;
-
-            int master_server_version = -1;
-            int server_count = -1;
-
-            // read header
-            while (total_received < 12 && (received = sock.recv(data + total_received, 12 - total_received)) > 0)
-                total_received += received;
-
-            // see if we have the header
-            if (total_received == 12)
-            {
-                int signature;
-                read_int(data, &signature);
-    
-                // check signature
-                if(signature == 'TWSL')
-                {
-                    read_int(data + 4, &master_server_version);
-                    read_int(data + 8, &server_count);
-
-                    // TODO: handle master server version O.o
-                        
-                    const int server_info_size = 212;
-
-                    list->active_count = 0;
-    
-                    for (int i = 0; i < server_count; i++)
-                    { 
-                         total_received = 0;
-
-                        // read data for a server
-                        while (sock.is_connected() && total_received < server_info_size && (received = sock.recv(data + total_received, server_info_size - total_received)) > 0)
-                            total_received += received;
-
-                        // check if we got enough data
-                        if (total_received == server_info_size)
-                        {
-                            char *d = data;
-
-                            server_info *info = &list->infos[i];
-
-                            d = read_int(d, &info->version);
-                            d = read_netaddr(d, &info->address);
-
-							//dbg_msg("menu/got_serverinfo", "IP: %i.%i.%i.%i:%i", (int)info->address.ip[0], (int)info->address.ip[1], (int)info->address.ip[2], (int)info->address.ip[3], info->address.port);
-
-                            d = read_int(d, &info->players);
-                            d = read_int(d, &info->max_players);
-                            memcpy(info->name, d, 128);
-                            d += 128;
-							memcpy(info->map, d, 64);
-
-                            // let's be safe.
-                            info->name[128] = 0;
-                            info->map[64] = 0;
-
-                            ++list->active_count;
-                        }
-                        else
-                            break;
-                    }
-
-                    if (list->scroll_index >= list->active_count)
-                        list->scroll_index = list->active_count - 1;
-
-                    if (list->scroll_index < 0)
-                        list->scroll_index = 0;
-                }
-            }
-
-            sock.close();
-        }
-	}
-}
-
 enum
 {
 	SCREEN_MAIN,
@@ -737,41 +625,45 @@ const float row2_y = row1_y + 40;
 const float row3_y = row2_y + 40;
 const float row4_y = row3_y + 40;
 
-static int main_render(netaddr4 *server_address)
+static int main_render()
 {
-	static server_list list;
 	static bool inited = false;
 
 	if (!inited)
 	{
+		/*
 		list.info_count = 256;
 
 		list.scroll_index = 0;
 		list.selected_index = -1;
+		*/
 
 		inited = true;
 
-		refresh_list(&list);
+		client_serverbrowse_refresh();
 	}
 
-	do_server_list(&list, 20, 160, 8);
+	static int scoll_index = 0, selected_index = -1;
+	do_server_list(20, 160, &scoll_index, &selected_index, 8);
 
 	static int refresh_button, join_button, quit_button;
 
 	if (ui_do_button(&refresh_button, "Refresh", 0, 440, 420, 170, 48, draw_teewars_button))
-	{
-		refresh_list(&list);
-	} 
+		client_serverbrowse_refresh();
 
-	if (list.selected_index == -1)
+	if (selected_index == -1)
 	{
 		ui_do_button(&join_button, "Join", 0, 620, 420, 128, 48, draw_teewars_button, (void *)1);
 	}
 	else if (ui_do_button(&join_button, "Join", 0, 620, 420, 128, 48, draw_teewars_button))
 	{
-		*server_address = list.infos[list.selected_index].address;
+		// *server_address = list.infos[list.selected_index].address;
+		
+		server_info *servers;
+		int num_servers = client_serverbrowse_getlist(&servers);
 
-		dbg_msg("menu/join_button", "IP: %i.%i.%i.%i:%i", (int)server_address->ip[0], (int)server_address->ip[1], (int)server_address->ip[2], (int)server_address->ip[3], server_address->port);
+		client_connect(servers[selected_index].address);
+		//dbg_msg("menu/join_button", "IP: %i.%i.%i.%i:%i", (int)server_address->ip[0], (int)server_address->ip[1], (int)server_address->ip[2], (int)server_address->ip[3], server_address->port);
 
 		return 1;
 	}
@@ -1123,7 +1015,7 @@ static int kerning_render()
 	return 0;
 }
 
-static int menu_render(netaddr4 *server_address)
+static int menu_render()
 {
 	// background color
 	gfx_clear(0.65f,0.78f,0.9f);
@@ -1147,7 +1039,7 @@ static int menu_render(netaddr4 *server_address)
 
 	switch (screen)
 	{
-		case SCREEN_MAIN: return main_render(server_address);
+		case SCREEN_MAIN: return main_render();
 		case SCREEN_SETTINGS_GENERAL:
 		case SCREEN_SETTINGS_CONTROLS:
 		case SCREEN_SETTINGS_VIDEO:
@@ -1176,7 +1068,7 @@ void modmenu_shutdown()
 {
 }
 
-int modmenu_render(void *ptr)
+int modmenu_render()
 {
 	static int mouse_x = 0;
 	static int mouse_y = 0;
@@ -1187,8 +1079,6 @@ int modmenu_render(void *ptr)
 		music_menu_id = snd_play(music_menu, SND_LOOP);
 	}
 
-	netaddr4 *server_address = (netaddr4 *)ptr;	
-
     // handle mouse movement
     float mx, my;
     {
@@ -1214,7 +1104,7 @@ int modmenu_render(void *ptr)
     }
 
     //int r = menu_render(server_address, str, max_len);
-	int r = menu_render(server_address);
+	int r = menu_render();
 
     // render butt ugly mouse cursor
     // TODO: render nice cursor
diff --git a/src/game/game.h b/src/game/game.h
index 917abab1..5f69ef9e 100644
--- a/src/game/game.h
+++ b/src/game/game.h
@@ -58,7 +58,10 @@ struct player_input
 {
 	int left;
 	int right;
-	int angle;
+	
+	int target_x;
+	int target_y;
+	
 	int jump;
 	int fire;
 	int hook;
diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp
index cf8cea90..12685fe8 100644
--- a/src/game/server/game_server.cpp
+++ b/src/game/server/game_server.cpp
@@ -464,7 +464,8 @@ void projectile::tick()
 	lifespan--;
 	
 	// check player intersection as well
-	entity *targetplayer = (entity*)intersect_player(oldpos, pos, oldpos, powner);
+	vec2 new_pos;
+	entity *targetplayer = (entity*)intersect_player(oldpos, pos, new_pos, powner);
 	if(targetplayer || lifespan < 0 || col_check_point((int)pos.x, (int)pos.y))
 	{
 		if (lifespan >= 0)
@@ -489,6 +490,74 @@ void projectile::snap(int snapping_client)
 	proj->type = type;
 }
 
+
+//////////////////////////////////////////////////
+// projectile_backpackrocket
+//////////////////////////////////////////////////
+projectile_backpackrocket::projectile_backpackrocket(baselib::vec2 pos, baselib::vec2 target, int owner, entity* powner)
+: projectile(WEAPON_PROJECTILETYPE_ROCKET, owner, pos, vec2(0,0), 100, powner, 0, 0, 0, -1, WEAPON_ROCKET_BACKPACK)
+{
+	stage = 0;
+	start_tick = server_tick();
+	vel = vec2(0,-10.0f);
+	this->target = target;
+	start = pos;
+	midpoint = pos;
+	midpoint.y = target.y;
+	direction = normalize(target-midpoint);
+	deply_ticks = (int)( distance(start, midpoint)/(float)server_tickspeed() * 5.0f );
+	dbg_msg("rocket_bp", "%f %d", distance(start, midpoint), deply_ticks);
+}
+
+void projectile_backpackrocket::tick()
+{
+	lifespan--;
+	if(!lifespan)
+		world.destroy_entity(this);
+		
+	vec2 oldpos = pos;
+		
+	if(stage == 0)
+	{
+		float time = (server_tick()-start_tick)/(float)(deply_ticks);
+		if(midpoint.y > start.y)
+			pos.y = mix(start.y, midpoint.y, 1-sinf((1-time)*pi/2));
+		else
+			pos.y = mix(start.y, midpoint.y, sinf(time*pi/2));
+
+		float a = (server_tick()-start_tick)/(float)server_tickspeed()*pi*7.5f;
+		vel.x = sinf(a)*30.0f;
+		vel.y = cosf(a)*30.0f;
+		
+		if(server_tick() > start_tick+deply_ticks)
+		{
+			pos = midpoint;
+			direction = normalize(target-pos);
+			vel = vec2(0,0);
+			stage = 1;
+		}
+	}
+	else if(stage == 1)
+	{
+		vel += direction*1.5f;
+		vel.x = clamp(vel.x, -20.0f, 20.0f);
+		pos += vel;
+	}
+
+	// check player intersection as well
+	vec2 new_pos;
+	entity *targetplayer = (entity*)intersect_player(oldpos, pos, new_pos, powner);
+	if(targetplayer || lifespan < 0 || col_check_point((int)pos.x, (int)pos.y))
+	{
+		if (lifespan >= 0)
+			create_sound(pos, sound_impact);
+			
+		create_explosion(oldpos, owner, weapon, false);
+			
+		world.destroy_entity(this);
+	}	
+}
+
 //////////////////////////////////////////////////
 // player
 //////////////////////////////////////////////////
@@ -556,6 +625,11 @@ void player::respawn()
 	weapons[WEAPON_HAMMER].ammo = -1;
 	weapons[WEAPON_GUN].got = true;
 	weapons[WEAPON_GUN].ammo = 10;
+
+	// TEMP DEBUG
+	weapons[WEAPON_ROCKET_BACKPACK].got = true;
+	weapons[WEAPON_ROCKET_BACKPACK].ammo = 10;
+
 	active_weapon = WEAPON_GUN;
 	reload_timer = 0;
 	
@@ -620,7 +694,7 @@ void player::handle_weapons()
 						break;
 
 					case WEAPON_GUN:
-						new projectile(WEAPON_PROJECTILETYPE_GUN,
+						new projectile(projectile::WEAPON_PROJECTILETYPE_GUN,
 							client_id,
 							pos+vec2(0,0),
 							direction*30.0f,
@@ -630,7 +704,7 @@ void player::handle_weapons()
 						create_sound(pos, SOUND_GUN_FIRE);
 						break;
 					case WEAPON_ROCKET:
-						new projectile(WEAPON_PROJECTILETYPE_ROCKET,
+						new projectile(projectile::WEAPON_PROJECTILETYPE_ROCKET,
 							client_id,
 							pos+vec2(0,0),
 							direction*15.0f,
@@ -644,7 +718,7 @@ void player::handle_weapons()
 						{
 							float a = get_angle(direction);
 							a += i*0.075f;
-							new projectile(WEAPON_PROJECTILETYPE_SHOTGUN,
+							new projectile(projectile::WEAPON_PROJECTILETYPE_SHOTGUN,
 								client_id,
 								pos+vec2(0,0),
 								vec2(cosf(a), sinf(a))*25.0f,
@@ -655,6 +729,13 @@ void player::handle_weapons()
 						}
 						create_sound(pos, SOUND_SHOTGUN_FIRE);
 						break;
+					case WEAPON_ROCKET_BACKPACK:
+						new projectile_backpackrocket(
+							pos+vec2(0,0),
+							pos+vec2(input.target_x,input.target_y),
+							client_id,
+							this);
+						break;						
 				}
 				
 				weapons[active_weapon].ammo--;
@@ -662,10 +743,11 @@ void player::handle_weapons()
 			else
 			{
 				// click!!! click
+				// TODO: make sound here
 			}
 			
 			attack_tick = server_tick();
-			reload_timer = 10; // make this variable depending on weapon
+			reload_timer = 10; // TODO: make this variable depending on weapon
 		}
 	}
 }
@@ -685,7 +767,7 @@ void player::tick()
 	
 	// fetch some info
 	bool grounded = is_grounded();
-	direction = get_direction(input.angle);
+	direction = normalize(vec2(input.target_x, input.target_y));
 	
 	float max_speed = grounded ? ground_control_speed : air_control_speed;
 	float accel = grounded ? ground_control_accel : air_control_accel;
@@ -950,8 +1032,13 @@ void player::snap(int snaping_client)
 	player->hook_active = hook_state>0?1:0;
 	player->hook_x = (int)hook_pos.x;
 	player->hook_y = (int)hook_pos.y;
+
+	float a = atan((float)input.target_y/(float)input.target_x);
+	if(input.target_x < 0)
+		a = a+pi;
 		
-	player->angle = input.angle;
+	player->angle = (int)(a*256.0f);
+	
 	player->score = score;
 }
 
@@ -1079,15 +1166,17 @@ void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
 		// deal damage
 		entity *ents[64];
 		const float radius = 128.0f;
+		const float innerradius = 42.0f;
 		int num = world.find_entities(p, radius, ents, 64);
 		for(int i = 0; i < num; i++)
 		{
 			vec2 diff = ents[i]->pos - p;
 			vec2 forcedir(0,1);
-			if (length(diff))
-				forcedir = normalize(diff);
 			float l = length(diff);
-			float dmg = 5 * (1 - (l/radius));
+			if(l)
+				forcedir = normalize(diff);
+			l = 1-clamp((l-innerradius)/(radius-innerradius), 0.0f, 1.0f);
+			float dmg = 6 * l;
 			if((int)dmg)
 				ents[i]->take_damage(forcedir*dmg*2, (int)dmg, owner, weapon);
 		}
diff --git a/src/game/server/game_server.h b/src/game/server/game_server.h
index 027a140f..ec3d597a 100644
--- a/src/game/server/game_server.h
+++ b/src/game/server/game_server.h
@@ -146,6 +146,10 @@ public:
 	enum
 	{
 		PROJECTILE_FLAGS_EXPLODE = 1 << 0,
+		
+		WEAPON_PROJECTILETYPE_GUN		= 0,
+		WEAPON_PROJECTILETYPE_ROCKET	= 1,
+		WEAPON_PROJECTILETYPE_SHOTGUN	= 2,
 	};
 	
 	baselib::vec2 vel;
@@ -166,19 +170,26 @@ public:
 	virtual void snap(int snapping_client);
 };
 
+class projectile_backpackrocket : public projectile
+{
+	int stage;
+	int start_tick;
+	int deply_ticks;
+	baselib::vec2 target;
+	baselib::vec2 start;
+	baselib::vec2 midpoint;
+	baselib::vec2 direction;
+public:
+	projectile_backpackrocket(baselib::vec2 pos, baselib::vec2 target, int owner, entity* powner);
+	virtual void tick();
+};
+
 // player entity
 class player : public entity
 {
 public:
 	static const int phys_size = 28;
 	
-	enum // what are these?
-	{
-		WEAPON_PROJECTILETYPE_GUN		= 0,
-		WEAPON_PROJECTILETYPE_ROCKET	= 1,
-		WEAPON_PROJECTILETYPE_SHOTGUN	= 2,
-	};
-	
 	// weapon info
 	struct weaponstat
 	{