about summary refs log tree commit diff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/client/game_client.cpp50
-rw-r--r--src/game/game_protocol.h7
-rw-r--r--src/game/server/game_server.cpp61
3 files changed, 84 insertions, 34 deletions
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index 332a84d9..dc135509 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -1786,6 +1786,14 @@ void render_world(float center_x, float center_y, float zoom)
 	damageind.render();	
 }
 
+static void do_input(int *v, int key)
+{
+	*v += inp_key_presses(key) + inp_key_releases(key);
+	if((*v&1) != inp_key_state(key))
+		(*v)++;
+	*v &= INPUT_STATE_MASK;
+}
+
 void render_game()
 {	
 	float width = 400*3.0f;
@@ -1934,12 +1942,10 @@ void render_game()
 	
 	// snap input
 	{
-		player_input input;
-		mem_zero(&input, sizeof(input));
+		static player_input input = {0};
 			
 		input.target_x = (int)mouse_pos.x;
 		input.target_y = (int)mouse_pos.y;
-		input.activeweapon = 0;
 	
 		if(chat_mode != CHATMODE_NONE)
 			input.state = STATE_CHATTING;
@@ -1948,27 +1954,36 @@ void render_game()
 		else
 		{
 			input.state = STATE_PLAYING;
-			input.left = inp_key_pressed(config.key_move_left);
-			input.right = inp_key_pressed(config.key_move_right);
-			input.jump = inp_key_pressed(config.key_jump);
-			// TODO: this is not very well done. it should check this some other way
-			input.fire = emoticon_selector_active ? 0 : inp_key_pressed(config.key_fire);
-			input.hook = inp_key_pressed(config.key_hook);
+			input.left = inp_key_state(config.key_move_left);
+			input.right = inp_key_state(config.key_move_right);
+			input.hook = inp_key_state(config.key_hook);
+			input.jump  = inp_key_state(config.key_jump);
+			
+			if(!emoticon_selector_active)
+				do_input(&input.fire, config.key_fire);
+			
+			// weapon selection
+			do_input(&input.next_weapon, config.key_next_weapon);
+			do_input(&input.prev_weapon, config.key_prev_weapon);
 			
-			// Weapon switching
-			if(inp_key_pressed(config.key_next_weapon)) input.activeweapon = -1;
-			if(inp_key_pressed(config.key_prev_weapon)) input.activeweapon = -2;
-			if(inp_key_pressed(config.key_weapon1)) input.activeweapon = 1;
-			if(inp_key_pressed(config.key_weapon2)) input.activeweapon = 2;
-			if(inp_key_pressed(config.key_weapon3)) input.activeweapon = 3;
-			if(inp_key_pressed(config.key_weapon4)) input.activeweapon = 4;
+			if(inp_key_presses(config.key_next_weapon) || inp_key_presses(config.key_prev_weapon))
+				input.wanted_weapon = 0;
+			else
+			{
+				if(inp_key_presses(config.key_weapon1)) input.wanted_weapon = 1;
+				if(inp_key_presses(config.key_weapon2)) input.wanted_weapon = 2;
+				if(inp_key_presses(config.key_weapon3)) input.wanted_weapon = 3;
+				if(inp_key_presses(config.key_weapon4)) input.wanted_weapon = 4;
+			}
 		}
 		
 		// stress testing
 		if(config.stress)
 		{
-			float t = client_localtime();
+			//float t = client_localtime();
 			mem_zero(&input, sizeof(input));
+			
+			/*
 			input.left = 1;
 			input.jump = ((int)t)&1;
 			input.fire = ((int)(t*10))&1;
@@ -1976,6 +1991,7 @@ void render_game()
 			input.activeweapon = ((int)t)%NUM_WEAPONS;
 			input.target_x = (int)(sinf(t*3)*100.0f);
 			input.target_y = (int)(cosf(t*3)*100.0f);
+			*/
 			
 			//input.target_x = (int)((rand()/(float)RAND_MAX)*64-32);
 			//input.target_y = (int)((rand()/(float)RAND_MAX)*64-32);
diff --git a/src/game/game_protocol.h b/src/game/game_protocol.h
index 56156e24..0300c88a 100644
--- a/src/game/game_protocol.h
+++ b/src/game/game_protocol.h
@@ -60,6 +60,11 @@ enum
 
 enum
 {
+	INPUT_STATE_MASK=0x1f,
+};
+
+enum
+{
 	STATE_UNKNOWN=0,
 	STATE_PLAYING,
 	STATE_IN_MENU,
@@ -82,9 +87,9 @@ struct player_input
 	int fire;
 	int hook;
 	int blink;
-	int activeweapon;
 	int state;
 	
+	int wanted_weapon;
 	int next_weapon;
 	int prev_weapon;
 };
diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp
index ff5dbd84..9821c87f 100644
--- a/src/game/server/game_server.cpp
+++ b/src/game/server/game_server.cpp
@@ -602,6 +602,30 @@ int player::handle_ninja()
 	return 0;
 }
 
+struct input_count
+{
+	int presses;
+	int releases;
+};
+
+static input_count count_input(int prev, int cur)
+{
+	input_count c = {0,0};
+	prev &= INPUT_STATE_MASK;
+	cur &= INPUT_STATE_MASK;
+	int i = prev;
+	while(i != cur)
+	{
+		i = (i+1)&INPUT_STATE_MASK;
+		if(i&1)
+			c.presses++;
+		else
+			c.releases++;
+	}
+	
+	return c;		
+}
+
 int player::handle_weapons()
 {
 	vec2 direction = normalize(vec2(input.target_x, input.target_y));
@@ -630,26 +654,30 @@ int player::handle_weapons()
 		return handle_ninja();
 	}
 
-	// switch weapon if wanted		
-	if(input.activeweapon && data->weapons[active_weapon].duration <= 0)
+	// switch weapon if wanted
+	if(data->weapons[active_weapon].duration <= 0)
 	{
 		int new_weapon = active_weapon;
-		if(input.activeweapon > 0) // straight selection
-			new_weapon = input.activeweapon-1;
-		else if(input.activeweapon == -1 && !previnput.activeweapon) // next weapon
+		int next = count_input(previnput.next_weapon, input.next_weapon).presses;
+		int prev = count_input(previnput.prev_weapon, input.prev_weapon).presses;
+		while(next) // next weapon selection
 		{
-			do
-				new_weapon = (new_weapon+1)%NUM_WEAPONS;
-			while(!weapons[new_weapon].got);
+			new_weapon = (new_weapon+1)%NUM_WEAPONS;
+			if(weapons[new_weapon].got)
+				next--;
 		}
-		else if(input.activeweapon == -2 && !previnput.activeweapon)
+
+		while(prev) // prev weapon selection
 		{
-			do
-				new_weapon = (new_weapon-1)<0?NUM_WEAPONS-1:new_weapon-1;
-			while(!weapons[new_weapon].got);
+			new_weapon = (new_weapon-1)<0?NUM_WEAPONS-1:new_weapon-1;
+			if(weapons[new_weapon].got)
+				prev--;
 		}
-			
-		if(new_weapon >= 0 && new_weapon < NUM_WEAPONS && weapons[new_weapon].got)
+		
+		if(input.wanted_weapon) // direct weapon selection
+			new_weapon = input.wanted_weapon-1;
+				
+		if(new_weapon != active_weapon && new_weapon >= 0 && new_weapon < NUM_WEAPONS && weapons[new_weapon].got)
 		{
 			if(active_weapon != new_weapon)
 				create_sound(pos, SOUND_WEAPON_SWITCH);
@@ -659,7 +687,7 @@ int player::handle_weapons()
 		}
 	}
 	
-	if(!previnput.fire && input.fire)
+	if(count_input(previnput.fire, input.fire).presses) //previnput.fire != input.fire && (input.fire&1))
 	{
 		if(reload_timer == 0)
 		{
@@ -727,6 +755,7 @@ int player::handle_weapons()
 			}
 		}
 	}
+	
 	// Update weapons
 	if (active_weapon == WEAPON_HAMMER && reload_timer > 0)
 	{
@@ -841,7 +870,7 @@ void player::tick()
 	{
 		if(server_tick()-die_tick >= server_tickspeed()*5) // auto respawn after 3 sec
 			respawn();
-		if(input.fire && server_tick()-die_tick >= server_tickspeed()/2) // auto respawn after 0.5 sec
+		if((input.fire&1) && server_tick()-die_tick >= server_tickspeed()/2) // auto respawn after 0.5 sec
 			respawn();
 		return;
 	}