From 8a6e921cb8c9886db598dd77ddde3e7ba294085a Mon Sep 17 00:00:00 2001
From: BlockMen <nmuelll@web.de>
Date: Wed, 12 Aug 2015 17:13:19 +0200
Subject: [PATCH] Fix jittering sounds on entities (fixes #2974)

---
 src/collision.cpp   | 93 ++++++++++++++++++---------------------------
 src/collision.h     |  4 +-
 src/localplayer.cpp |  2 +-
 3 files changed, 40 insertions(+), 59 deletions(-)

diff --git a/src/collision.cpp b/src/collision.cpp
index 193330250..2b64547c3 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -379,16 +379,14 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 
 	int loopcount = 0;
 
-	while(dtime > BS*1e-10)
-	{
+	while(dtime > BS * 1e-10) {
 		//TimeTaker tt3("collisionMoveSimple dtime loop");
         ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG);
 
 		// Avoid infinite loop
 		loopcount++;
-		if(loopcount >= 100)
-		{
-			warningstream<<"collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop"<<std::endl;
+		if (loopcount >= 100) {
+			warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop" << std::endl;
 			dtime = 0;
 			break;
 		}
@@ -404,8 +402,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 		/*
 			Go through every nodebox, find nearest collision
 		*/
-		for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
-		{
+		for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
 			// Ignore if already stepped up this nodebox.
 			if(is_step_up[boxindex])
 				continue;
@@ -415,7 +412,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 			int collided = axisAlignedCollision(
 					cboxes[boxindex], movingbox, speed_f, d, dtime_tmp);
 
-			if(collided == -1 || dtime_tmp >= nearest_dtime)
+			if (collided == -1 || dtime_tmp >= nearest_dtime)
 				continue;
 
 			nearest_dtime = dtime_tmp;
@@ -423,18 +420,14 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 			nearest_boxindex = boxindex;
 		}
 
-		if(nearest_collided == -1)
-		{
+		if (nearest_collided == -1) {
 			// No collision with any collision box.
 			pos_f += speed_f * dtime;
 			dtime = 0;  // Set to 0 to avoid "infinite" loop due to small FP numbers
-		}
-		else
-		{
+		} else {
 			// Otherwise, a collision occurred.
 
 			const aabb3f& cbox = cboxes[nearest_boxindex];
-
 			// Check for stairs.
 			bool step_up = (nearest_collided != 1) && // must not be Y direction
 					(movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
@@ -448,67 +441,56 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 			float bounce = -(float)bouncy_values[nearest_boxindex] / 100.0;
 
 			// Move to the point of collision and reduce dtime by nearest_dtime
-			if(nearest_dtime < 0)
-			{
+			if (nearest_dtime < 0) {
 				// Handle negative nearest_dtime (can be caused by the d allowance)
-				if(!step_up)
-				{
-					if(nearest_collided == 0)
+				if (!step_up) {
+					if (nearest_collided == 0)
 						pos_f.X += speed_f.X * nearest_dtime;
-					if(nearest_collided == 1)
+					if (nearest_collided == 1)
 						pos_f.Y += speed_f.Y * nearest_dtime;
-					if(nearest_collided == 2)
+					if (nearest_collided == 2)
 						pos_f.Z += speed_f.Z * nearest_dtime;
 				}
-			}
-			else
-			{
+			} else {
 				pos_f += speed_f * nearest_dtime;
 				dtime -= nearest_dtime;
 			}
 
 			bool is_collision = true;
-			if(is_unloaded[nearest_boxindex])
+			if (is_unloaded[nearest_boxindex])
 				is_collision = false;
 
 			CollisionInfo info;
-			if (is_object[nearest_boxindex]) {
+			if (is_object[nearest_boxindex])
 				info.type = COLLISION_OBJECT;
-			}
-			else {
+			else
 				info.type = COLLISION_NODE;
-			}
+
 			info.node_p = node_positions[nearest_boxindex];
 			info.bouncy = bouncy;
 			info.old_speed = speed_f;
 
 			// Set the speed component that caused the collision to zero
-			if(step_up)
-			{
+			if (step_up) {
 				// Special case: Handle stairs
 				is_step_up[nearest_boxindex] = true;
 				is_collision = false;
-			}
-			else if(nearest_collided == 0) // X
-			{
-				if(fabs(speed_f.X) > BS*3)
+			} else if(nearest_collided == 0) { // X
+				if (fabs(speed_f.X) > BS * 3)
 					speed_f.X *= bounce;
 				else
 					speed_f.X = 0;
 				result.collides = true;
 				result.collides_xz = true;
 			}
-			else if(nearest_collided == 1) // Y
-			{
-				if(fabs(speed_f.Y) > BS*3)
+			else if(nearest_collided == 1) { // Y
+				if(fabs(speed_f.Y) > BS * 3)
 					speed_f.Y *= bounce;
 				else
 					speed_f.Y = 0;
 				result.collides = true;
-			}
-			else if(nearest_collided == 2) // Z
-			{
-				if(fabs(speed_f.Z) > BS*3)
+			} else if(nearest_collided == 2) { // Z
+				if (fabs(speed_f.Z) > BS * 3)
 					speed_f.Z *= bounce;
 				else
 					speed_f.Z = 0;
@@ -517,10 +499,10 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 			}
 
 			info.new_speed = speed_f;
-			if(info.new_speed.getDistanceFrom(info.old_speed) < 0.1*BS)
+			if (info.new_speed.getDistanceFrom(info.old_speed) < 0.1 * BS)
 				is_collision = false;
 
-			if(is_collision){
+			if (is_collision) {
 				result.collisions.push_back(info);
 			}
 		}
@@ -532,8 +514,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 	aabb3f box = box_0;
 	box.MinEdge += pos_f;
 	box.MaxEdge += pos_f;
-	for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
-	{
+	for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
 		const aabb3f& cbox = cboxes[boxindex];
 
 		/*
@@ -545,23 +526,21 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
 
 			Use 0.15*BS so that it is easier to get on a node.
 		*/
-		if(
-				cbox.MaxEdge.X-d > box.MinEdge.X &&
-				cbox.MinEdge.X+d < box.MaxEdge.X &&
-				cbox.MaxEdge.Z-d > box.MinEdge.Z &&
-				cbox.MinEdge.Z+d < box.MaxEdge.Z
-		){
-			if(is_step_up[boxindex])
-			{
+		if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X &&
+				cbox.MaxEdge.Z - d > box.MinEdge.Z &&
+				cbox.MinEdge.Z + d < box.MaxEdge.Z) {
+			if (is_step_up[boxindex]) {
 				pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
 				box = box_0;
 				box.MinEdge += pos_f;
 				box.MaxEdge += pos_f;
 			}
-			if(fabs(cbox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS)
-			{
+			if (fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.15 * BS) {
 				result.touching_ground = true;
-				if(is_unloaded[boxindex])
+
+				if (is_object[boxindex])
+					result.standing_on_object = true;
+				if (is_unloaded[boxindex])
 					result.standing_on_unloaded = true;
 			}
 		}
diff --git a/src/collision.h b/src/collision.h
index fc4187eda..d1234bef3 100644
--- a/src/collision.h
+++ b/src/collision.h
@@ -57,13 +57,15 @@ struct collisionMoveResult
 	bool collides;
 	bool collides_xz;
 	bool standing_on_unloaded;
+	bool standing_on_object;
 	std::vector<CollisionInfo> collisions;
 
 	collisionMoveResult():
 		touching_ground(false),
 		collides(false),
 		collides_xz(false),
-		standing_on_unloaded(false)
+		standing_on_unloaded(false),
+		standing_on_object(false)
 	{}
 };
 
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 77e7a9e16..96e2737c7 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -344,7 +344,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
 		}
 	}
 
-	if(!touching_ground_was && touching_ground){
+	if(!result.standing_on_object && !touching_ground_was && touching_ground) {
 		MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
 		m_gamedef->event()->put(e);
 
-- 
2.25.1