about summary refs log tree commit diff
path: root/src/game
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-10 15:32:30 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-10 15:32:30 +0000
commit294cbe18c17cd20f70f965e7f89a3250ef39b990 (patch)
treedb942402bd39bfb8336e2a2d134f96f2ad5b2ab1 /src/game
parentacffe66ebe63f3ecc970db0feab33a6e85a7d1f4 (diff)
downloadzcatch-294cbe18c17cd20f70f965e7f89a3250ef39b990.tar.gz
zcatch-294cbe18c17cd20f70f965e7f89a3250ef39b990.zip
done some more latency work. added the extra message for projectiles to reduce latency
Diffstat (limited to 'src/game')
-rw-r--r--src/game/client/gc_client.cpp2
-rw-r--r--src/game/client/gc_client.h14
-rw-r--r--src/game/client/gc_console.cpp4
-rw-r--r--src/game/client/gc_hooks.cpp28
-rw-r--r--src/game/client/gc_render.cpp12
-rw-r--r--src/game/client/gc_render_obj.cpp7
-rw-r--r--src/game/g_protocol.h2
-rw-r--r--src/game/g_version.h4
-rw-r--r--src/game/server/gs_common.h11
-rw-r--r--src/game/server/gs_server.cpp186
10 files changed, 242 insertions, 28 deletions
diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp
index 7032637f..d891ec84 100644
--- a/src/game/client/gc_client.cpp
+++ b/src/game/client/gc_client.cpp
@@ -25,7 +25,7 @@ extern "C" {
 #include "gc_console.h"
 
 struct data_container *data = 0;
-static int64 debug_firedelay = 0;
+int64 debug_firedelay = 0;
 
 player_input input_data = {0};
 int input_target_lock = 0;
diff --git a/src/game/client/gc_client.h b/src/game/client/gc_client.h
index 63c74d77..857a9088 100644
--- a/src/game/client/gc_client.h
+++ b/src/game/client/gc_client.h
@@ -36,6 +36,20 @@ extern int picked_up_weapon;
 extern player_input input_data;
 extern int input_target_lock;
 
+// debug
+extern int64 debug_firedelay;
+
+// extra projs
+enum
+{
+	MAX_EXTRA_PROJECTILES=32,
+};
+
+extern obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
+extern int extraproj_num;
+
+void extraproj_reset();
+
 // chat
 enum
 {
diff --git a/src/game/client/gc_console.cpp b/src/game/client/gc_console.cpp
index c04477a1..1f596e79 100644
--- a/src/game/client/gc_console.cpp
+++ b/src/game/client/gc_console.cpp
@@ -265,14 +265,14 @@ void console_render()
 
 	gfx_texture_set(data->images[IMAGE_CONSOLE_BG].id);
     gfx_quads_begin();
-    gfx_setcolor(0.2f, 0.2f, 0.2f,0.8f);
+    gfx_setcolor(0.2f, 0.2f, 0.2f,0.9f);
     gfx_quads_setsubset(0,-console_height*0.075f,screen.w*0.075f*0.5f,0);
     gfx_quads_drawTL(0,0,screen.w,console_height);
     gfx_quads_end();
 
 	gfx_texture_set(data->images[IMAGE_CONSOLE_BAR].id);
     gfx_quads_begin();
-    gfx_setcolor(1.0f, 1.0f, 1.0f, 0.8f);
+    gfx_setcolor(1.0f, 1.0f, 1.0f, 0.9f);
     gfx_quads_setsubset(0,0.1f,screen.w*0.015f,1-0.1f);
     gfx_quads_drawTL(0,console_height-10.0f,screen.w,10.0f);
     gfx_quads_end();
diff --git a/src/game/client/gc_hooks.cpp b/src/game/client/gc_hooks.cpp
index f04af5cb..4ab5cf6a 100644
--- a/src/game/client/gc_hooks.cpp
+++ b/src/game/client/gc_hooks.cpp
@@ -394,6 +394,15 @@ extern "C" void modc_statechange(int state, int old)
 	}
 }
 
+
+obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
+int extraproj_num;
+
+void extraproj_reset()
+{
+	extraproj_num = 0;
+}
+
 extern "C" void modc_message(int msg)
 {
 	if(msg == MSG_CHAT)
@@ -409,6 +418,23 @@ extern "C" void modc_message(int msg)
 		else
 			snd_play(CHN_GUI, data->sounds[SOUND_CHAT_SERVER].sounds[0].id, 0);
 	}
+	else if(msg == MSG_EXTRA_PROJECTILE)
+	{
+		int num = msg_unpack_int();
+		
+		for(int k = 0; k < num; k++)
+		{
+			obj_projectile proj;
+			for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+				((int *)&proj)[i] = msg_unpack_int();
+				
+			if(extraproj_num != MAX_EXTRA_PROJECTILES)
+			{
+				extraproj_projectiles[extraproj_num] = proj;
+				extraproj_num++;
+			}
+		}
+	}
 	else if(msg == MSG_SETINFO)
 	{
 		int cid = msg_unpack_int();
@@ -487,8 +513,8 @@ extern "C" void modc_connected()
 	
 	//tilemap_init();
 	chat_reset();
-
 	particle_reset();
+	extraproj_reset();
 	
 	clear_object_pointers();
 	last_new_predicted_tick = -1;
diff --git a/src/game/client/gc_render.cpp b/src/game/client/gc_render.cpp
index f201a87c..1d276ec3 100644
--- a/src/game/client/gc_render.cpp
+++ b/src/game/client/gc_render.cpp
@@ -370,6 +370,18 @@ static void render_items()
 				render_flag((const obj_flag *)prev, (const obj_flag *)data);
 		}
 	}
+
+	// render extra projectiles	
+	for(int i = 0; i < extraproj_num; i++)
+	{
+		if(extraproj_projectiles[i].start_tick < client_tick())
+		{
+			extraproj_projectiles[i] = extraproj_projectiles[extraproj_num-1];
+			extraproj_num--;
+		}
+		else
+			render_projectile(&extraproj_projectiles[i], 0);
+	}
 }
 
 
diff --git a/src/game/client/gc_render_obj.cpp b/src/game/client/gc_render_obj.cpp
index 39705444..cedfc129 100644
--- a/src/game/client/gc_render_obj.cpp
+++ b/src/game/client/gc_render_obj.cpp
@@ -13,13 +13,12 @@
 
 void render_projectile(const obj_projectile *current, int itemid)
 {
-	/*
 	if(debug_firedelay)
 	{
-		debug_firedelay = time_get()-debug_firedelay;
-		dbg_msg("game", "firedelay=%.2f ms", debug_firedelay/(float)time_freq()*1000.0f);
+		int64 delay = time_get()-debug_firedelay;
+		dbg_msg("game", "firedelay=%.2f ms", delay/(float)time_freq()*1000.0f);
 		debug_firedelay = 0;
-	}*/
+	}
 	
 	gfx_texture_set(data->images[IMAGE_GAME].id);
 	gfx_quads_begin();
diff --git a/src/game/g_protocol.h b/src/game/g_protocol.h
index ada685bb..f4878729 100644
--- a/src/game/g_protocol.h
+++ b/src/game/g_protocol.h
@@ -44,6 +44,8 @@ enum
     MSG_SOUND_GLOBAL,
     MSG_TUNE_PARAMS,
 	MSG_KILL,
+    MSG_EXTRA_PROJECTILE, // server -> client
+	
 };
 
 enum
diff --git a/src/game/g_version.h b/src/game/g_version.h
index d77410dd..c10af7af 100644
--- a/src/game/g_version.h
+++ b/src/game/g_version.h
@@ -1,4 +1,4 @@
 /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
 #include "generated/nethash.c"
-#define TEEWARS_VERSION "0.3.3"
-#define TEEWARS_NETVERSION "0.3 " TEEWARS_NETVERSION_HASH
+#define TEEWARS_VERSION "0.4.0-dev"
+#define TEEWARS_NETVERSION "0.4 " TEEWARS_NETVERSION_HASH
diff --git a/src/game/server/gs_common.h b/src/game/server/gs_common.h
index 838b192f..194751b2 100644
--- a/src/game/server/gs_common.h
+++ b/src/game/server/gs_common.h
@@ -186,11 +186,6 @@ public:
 	enum
 	{
 		PROJECTILE_FLAGS_EXPLODE = 1 << 0,
-
-		WEAPON_PROJECTILETYPE_GUN		= 0,
-		WEAPON_PROJECTILETYPE_ROCKET	= 1,
-		WEAPON_PROJECTILETYPE_SHOTGUN	= 2,
-		WEAPON_PROJECTILETYPE_SNIPER	= 6,
 	};
 	
 	vec2 vel;
@@ -208,6 +203,9 @@ public:
 	
 	projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner,
 		int damage, int flags, float force, int sound_impact, int weapon);
+
+	void fill_info(obj_projectile *proj);
+
 	virtual void reset();
 	virtual void tick();
 	virtual void snap(int snapping_client);
@@ -333,6 +331,9 @@ public:
 	
 	int handle_weapons();
 	int handle_ninja();
+	
+	void on_direct_input(player_input *input);
+	void fire_weapon();
 
 	virtual void tick();
 	virtual void tick_defered();
diff --git a/src/game/server/gs_server.cpp b/src/game/server/gs_server.cpp
index b9f78996..bcab00e5 100644
--- a/src/game/server/gs_server.cpp
+++ b/src/game/server/gs_server.cpp
@@ -437,6 +437,16 @@ void projectile::tick()
 	}
 }
 
+void projectile::fill_info(obj_projectile *proj)
+{
+	proj->x = (int)pos.x;
+	proj->y = (int)pos.y;
+	proj->vx = (int)vel.x;
+	proj->vy = (int)vel.y;
+	proj->start_tick = start_tick;
+	proj->type = type;
+}
+
 void projectile::snap(int snapping_client)
 {
 	float ct = (server_tick()-start_tick)/(float)server_tickspeed();
@@ -446,12 +456,7 @@ void projectile::snap(int snapping_client)
 		return;
 
 	obj_projectile *proj = (obj_projectile *)snap_new_item(OBJTYPE_PROJECTILE, id, sizeof(obj_projectile));
-	proj->x = (int)pos.x;
-	proj->y = (int)pos.y;
-	proj->vx = (int)vel.x;
-	proj->vy = (int)vel.y;
-	proj->start_tick = start_tick;
-	proj->type = type;
+	fill_info(proj);
 }
 
 
@@ -940,6 +945,138 @@ int player::handle_ninja()
 	return 0;
 }
 
+void player::fire_weapon()
+{
+	if(reload_timer != 0)
+		return;
+	
+	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
+	
+	bool fullauto = false;
+	if(active_weapon == WEAPON_GRENADE || active_weapon == WEAPON_SHOTGUN)
+		fullauto = true;
+
+	//if(count_input(latest_previnput.fire, latest_input.fire).presses) || ((fullauto && latest_input.fire&1) && weapons[active_weapon].ammo))
+	if(!count_input(latest_previnput.fire, latest_input.fire).presses)
+		return;
+	
+	// check for ammo
+	if(!weapons[active_weapon].ammo)
+	{
+		create_sound(pos, SOUND_WEAPON_NOAMMO);
+		return;
+	}
+
+	
+	switch(active_weapon)
+	{
+		case WEAPON_HAMMER:
+		{
+			// reset objects hit
+			numobjectshit = 0;
+			create_sound(pos, SOUND_HAMMER_FIRE);
+			break;
+		}
+
+		case WEAPON_GUN:
+		{
+			projectile *proj = new projectile(WEAPON_GUN,
+				client_id,
+				pos+vec2(0,0),
+				direction*tuning.gun_speed,
+				server_tickspeed(),
+				this,
+				1, 0, 0, -1, WEAPON_GUN);
+				
+			// pack the projectile and send it to the client directly
+			obj_projectile p;
+			proj->fill_info(&p);
+			
+			msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
+			msg_pack_int(1);
+			for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+				msg_pack_int(((int *)&p)[i]);
+			msg_pack_end();
+			server_send_msg(client_id);
+							
+			create_sound(pos, SOUND_GUN_FIRE);
+			break;
+		}
+		case WEAPON_GRENADE:
+		{
+			projectile *proj = new projectile(WEAPON_GRENADE,
+				client_id,
+				pos+vec2(0,0),
+				direction*tuning.grenade_speed,
+				100,
+				this,
+				1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
+
+			// pack the projectile and send it to the client directly
+			obj_projectile p;
+			proj->fill_info(&p);
+			
+			msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
+			msg_pack_int(1);
+			for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+				msg_pack_int(((int *)&p)[i]);
+			msg_pack_end();
+			server_send_msg(client_id);
+
+			create_sound(pos, SOUND_GRENADE_FIRE);
+			break;
+		}
+		case WEAPON_SHOTGUN:
+		{
+			int shotspread = 2;
+
+			msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
+			msg_pack_int(shotspread*2+1);
+			
+			for(int i = -shotspread; i <= shotspread; i++)
+			{
+				float spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
+				float a = get_angle(direction);
+				float v = 1.0f-fabs(i/(float)shotspread);
+				a += spreading[i+2];
+				float speed = mix((float)tuning.shotgun_speed_wide, (float)tuning.shotgun_speed_center, v);
+				projectile *proj = new projectile(WEAPON_SHOTGUN,
+					client_id,
+					pos+vec2(0,0),
+					vec2(cosf(a), sinf(a))*speed,
+					(int)(server_tickspeed()*0.25f),
+					this,
+					1, 0, 0, -1, WEAPON_SHOTGUN);
+					
+				// pack the projectile and send it to the client directly
+				obj_projectile p;
+				proj->fill_info(&p);
+				
+				for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
+					msg_pack_int(((int *)&p)[i]);
+			}
+
+			msg_pack_end();
+			server_send_msg(client_id);					
+			
+			create_sound(pos, SOUND_SHOTGUN_FIRE);
+			break;
+		}
+		
+		case WEAPON_RIFLE:
+		{
+			new laser(pos, direction, tuning.laser_reach, this);
+			create_sound(pos, SOUND_RIFLE_FIRE);
+			break;
+		}
+		
+	}
+
+	weapons[active_weapon].ammo--;
+	attack_tick = server_tick();
+	reload_timer = data->weapons[active_weapon].firedelay * server_tickspeed() / 1000;
+}
+
 int player::handle_weapons()
 {
 	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
@@ -1011,8 +1148,10 @@ int player::handle_weapons()
 		}
 	}
 
-	if(reload_timer == 0)
-	{
+	//if(reload_timer == 0)
+	fire_weapon();
+	//}
+	/*
 		bool fullauto = false;
 		if(active_weapon == WEAPON_GRENADE || active_weapon == WEAPON_SHOTGUN)
 			fullauto = true;
@@ -1096,7 +1235,7 @@ int player::handle_weapons()
 				create_sound(pos, SOUND_WEAPON_NOAMMO);
 			}
 		}
-	}
+	}*/
 
 	// Update weapons
 	if (active_weapon == WEAPON_HAMMER && reload_timer > 0)
@@ -1178,11 +1317,19 @@ int player::handle_weapons()
 	return 0;
 }
 
+void player::on_direct_input(player_input *new_input)
+{
+	mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
+	mem_copy(&latest_input, new_input, sizeof(latest_input));
+	fire_weapon();
+}
+
 void player::tick()
 {
 	server_setclientscore(client_id, score);
 
 	// grab latest input
+	/*
 	{
 		int size = 0;
 		int *input = server_latestinput(client_id, &size);
@@ -1191,7 +1338,7 @@ void player::tick()
 			mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
 			mem_copy(&latest_input, input, sizeof(latest_input));
 		}
-	}
+	}*/
 	
 	// check if we have enough input
 	// this is to prevent initial weird clicks
@@ -1434,7 +1581,7 @@ void player::snap(int snaping_client)
 	{
 		obj_player_info *info = (obj_player_info *)snap_new_item(OBJTYPE_PLAYER_INFO, client_id, sizeof(obj_player_info));
 
-		info->latency = latency_avg;
+		info->latency = latency_min;
 		info->latency_flux = latency_max-latency_min;
 		info->local = 0;
 		info->clientid = client_id;
@@ -1892,7 +2039,21 @@ void mods_snap(int client_id)
 	events.snap(client_id);
 }
 
-void mods_client_input(int client_id, void *input)
+void mods_client_direct_input(int client_id, void *input)
+{
+	if(!world->paused)
+		players[client_id].on_direct_input((player_input *)input);
+	
+	/*
+	if(i->fire)
+	{
+		msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
+		msg_pack_end();
+		server_send_msg(client_id);
+	}*/
+}
+
+void mods_client_predicted_input(int client_id, void *input)
 {
 	if(!world->paused)
 	{
@@ -1905,7 +2066,6 @@ void mods_client_input(int client_id, void *input)
 		
 		if(players[client_id].input.target_x == 0 && players[client_id].input.target_y == 0)
 			players[client_id].input.target_y = -1;
-			
 	}
 }