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/gc_hooks.cpp9
-rw-r--r--src/game/g_game.cpp40
-rw-r--r--src/game/g_game.h1
-rw-r--r--src/game/g_protocol.def2
-rw-r--r--src/game/g_vmath.h15
-rw-r--r--src/game/server/gs_server.cpp55
6 files changed, 64 insertions, 58 deletions
diff --git a/src/game/client/gc_hooks.cpp b/src/game/client/gc_hooks.cpp
index 6035d908..021228c1 100644
--- a/src/game/client/gc_hooks.cpp
+++ b/src/game/client/gc_hooks.cpp
@@ -51,6 +51,15 @@ extern "C" void modc_init()
 {
 	static FONT_SET default_font;
 	int64 start = time_get();
+	
+	vec2 v;
+	v = closest_point_on_line(vec2(0, 0), vec2(10, 0), vec2(5, 0));
+	dbg_msg("", "1: %f,%f", v.x, v.y);
+	v = closest_point_on_line(vec2(0, 0), vec2(20, 0), vec2(5, 0));
+	dbg_msg("", "2: %f,%f", v.x, v.y);
+	v = closest_point_on_line(vec2(0, 0), vec2(10, 0), vec2(20, 0));
+	dbg_msg("", "3: %f,%f", v.x, v.y);
+	
 
 	int before = gfx_memory_usage();
 	font_set_load(&default_font, "data/fonts/default_font%d.tfnt", "data/fonts/default_font%d.png", "data/fonts/default_font%d_b.png", 14, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 36);
diff --git a/src/game/g_game.cpp b/src/game/g_game.cpp
index f2ebadee..c31bb476 100644
--- a/src/game/g_game.cpp
+++ b/src/game/g_game.cpp
@@ -246,9 +246,19 @@ void player_core::tick()
 			hook_tick = 0;
 			triggered_events |= COREEVENT_HOOK_LAUNCH;
 		}
+		else if(hook_state == HOOK_GOING_TO_RETRACT)
+		{
+			triggered_events |= COREEVENT_HOOK_RETRACT;
+			hook_state = HOOK_RETRACTED;
+		}
 		else if(hook_state == HOOK_FLYING)
 		{
 			vec2 new_pos = hook_pos+hook_dir*world->tuning.hook_fire_speed;
+			if(distance(pos, new_pos) > world->tuning.hook_length)
+			{
+				hook_state = HOOK_GOING_TO_RETRACT;
+				new_pos = normalize(pos-new_pos) * world->tuning.hook_length;
+			}
 
 			// Check against other players first
 			for(int i = 0; i < MAX_CLIENTS; i++)
@@ -257,8 +267,9 @@ void player_core::tick()
 				if(!p || p == this)
 					continue;
 
-				//if(p != this && !p->dead && distance(p->pos, new_pos) < p->phys_size)
-				if(distance(p->pos, new_pos) < phys_size)
+
+				vec2 closest_point = closest_point_on_line(hook_pos, new_pos, p->pos);
+				if(distance(p->pos, closest_point) < phys_size+4.0f)
 				{
 					triggered_events |= COREEVENT_HOOK_ATTACH_PLAYER;
 					hook_state = HOOK_GRABBED;
@@ -266,20 +277,6 @@ void player_core::tick()
 					break;
 				}
 			}
-			/*
-			for(entity *ent = world.first_entity; ent; ent = ent->next_entity)
-			{
-				if(ent && ent->objtype == OBJTYPE_PLAYER)
-				{
-					player *p = (player*)ent;
-					if(p != this && !p->dead && distance(p->pos, new_pos) < p->phys_size)
-					{
-						hook_state = HOOK_GRABBED;
-						hooked_player = p;
-						break;
-					}
-				}
-			}*/
 			
 			if(hook_state == HOOK_FLYING)
 			{
@@ -290,20 +287,9 @@ void player_core::tick()
 					hook_state = HOOK_GRABBED;
 					hook_pos = new_pos;	
 				}
-				else if(distance(pos, new_pos) > world->tuning.hook_length)
-				{
-					triggered_events |= COREEVENT_HOOK_RETRACT;
-					hook_state = HOOK_RETRACTED;
-				}
 				else
 					hook_pos = new_pos;
 			}
-			
-			if(hook_state == HOOK_GRABBED)
-			{
-				//create_sound(pos, SOUND_HOOK_ATTACH);
-				//hook_tick = server_tick();
-			}
 		}
 	}
 	else
diff --git a/src/game/g_game.h b/src/game/g_game.h
index 6b13fb7b..3a98aac6 100644
--- a/src/game/g_game.h
+++ b/src/game/g_game.h
@@ -97,6 +97,7 @@ enum
 	HOOK_RETRACTED=-1,
 	HOOK_IDLE=0,
 	HOOK_FLYING,
+	HOOK_GOING_TO_RETRACT,
 	HOOK_GRABBED,
 	
 	COREEVENT_GROUND_JUMP=0x01,
diff --git a/src/game/g_protocol.def b/src/game/g_protocol.def
index cac4bfdf..c832fb14 100644
--- a/src/game/g_protocol.def
+++ b/src/game/g_protocol.def
@@ -114,7 +114,7 @@ object player_core
 	range(0, 3) jumped
 
 	range(-1,MAX_CLIENTS-1) hooked_player
-	range(-1,2) hook_state
+	range(-1,3) hook_state
 	range(0, max_int) hook_tick
 
 	any hook_x
diff --git a/src/game/g_vmath.h b/src/game/g_vmath.h
index db7f4a50..ac3e1870 100644
--- a/src/game/g_vmath.h
+++ b/src/game/g_vmath.h
@@ -65,6 +65,21 @@ inline vector2_base<T> normalize(const vector2_base<T> &v)
 typedef vector2_base<float> vec2;
 typedef vector2_base<bool> bvec2;
 typedef vector2_base<int> ivec2;
+
+template<typename T>
+inline vector2_base<T> closest_point_on_line(vector2_base<T> line_point0, vector2_base<T> line_point1, vector2_base<T> target_point)
+{
+	vector2_base<T> c = target_point - line_point0;
+	vector2_base<T> v = (line_point1 - line_point0);
+	v = normalize(v);
+	T d = length(line_point0-line_point1);
+	T t = dot(v, c)/d;
+	return mix(line_point0, line_point1, clamp(t, (T)0, (T)1));
+	/*
+	if (t < 0) t = 0;
+	if (t > 1.0f) return 1.0f;
+	return t;*/
+}
 	
 // ------------------------------------
 template<typename T>
diff --git a/src/game/server/gs_server.cpp b/src/game/server/gs_server.cpp
index 3b7d4392..1993aa90 100644
--- a/src/game/server/gs_server.cpp
+++ b/src/game/server/gs_server.cpp
@@ -1439,20 +1439,30 @@ bool player::take_damage(vec2 force, int dmg, int from, int weapon)
 		create_damageind(pos, 0, dmg);
 	}
 
-	if(armor)
+	if(dmg)
 	{
-		armor -= 1;
-		dmg--;
-	}
-
-	if(dmg > armor)
-	{
-		dmg -= armor;
-		armor = 0;
+		if(armor)
+		{
+			if(dmg > 1)
+			{
+				health--;
+				dmg--;
+			}
+			
+			if(dmg > armor)
+			{
+				dmg -= armor;
+				armor = 0;
+			}
+			else
+			{
+				armor -= dmg;
+				dmg = 0;
+			}
+		}
+		
 		health -= dmg;
 	}
-	else
-		armor -= dmg;
 
 	damage_taken_tick = server_tick();
 
@@ -1822,25 +1832,11 @@ void create_sound_global(int sound, int target)
 	server_send_msg(target);
 }
 
-float closest_point_on_line(vec2 line_point0, vec2 line_point1, vec2 target_point)
-{
-	vec2 c = target_point - line_point0;
-	vec2 v = (line_point1 - line_point0);
-	v = normalize(v);
-	float d = length(line_point0-line_point1);
-	float t = dot(v, c);
-
-	if (t < 0) return 0;
-	if (t > d) return 1;
-
-	return t;
-}
-
 // TODO: should be more general
 player *intersect_player(vec2 pos0, vec2 pos1, float radius, vec2& new_pos, entity *notthis)
 {
 	// Find other players
-	float closest_time = distance(pos0, pos1) * 100.0f;
+	float closest_len = distance(pos0, pos1) * 100.0f;
 	vec2 line_dir = normalize(pos1-pos0);
 	player *closest = 0;
 		
@@ -1852,15 +1848,14 @@ player *intersect_player(vec2 pos0, vec2 pos1, float radius, vec2& new_pos, enti
 		if(!(players[i].flags&entity::FLAG_PHYSICS))
 			continue;
 
-		float t = closest_point_on_line(pos0, pos1, players[i].pos);
-		vec2 intersect_pos = pos0 + line_dir*t;
+		vec2 intersect_pos = closest_point_on_line(pos0, pos1, players[i].pos);
 		float len = distance(players[i].pos, intersect_pos);
 		if(len < player::phys_size+radius)
 		{
-			if(t < closest_time)
+			if(len < closest_len)
 			{
 				new_pos = intersect_pos;
-				closest_time = t;
+				closest_len = len;
 				closest = &players[i];
 			}
 		}