diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index d06015e0600bff34e1a3632a4930558f8e1c14f7..1a59504ef85dc096e0a276f53e02d9cf4858e6f6 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -319,25 +319,15 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
 	/*
 		Report collisions
 	*/
-	bool bouncy_jump = false;
+
 	// Dont report if flying
 	if(collision_info && !(g_settings->getBool("free_move") && fly_allowed)) {
 		for(size_t i=0; i<result.collisions.size(); i++) {
 			const CollisionInfo &info = result.collisions[i];
 			collision_info->push_back(info);
-			if(info.new_speed.Y - info.old_speed.Y > 0.1*BS &&
-					info.bouncy)
-				bouncy_jump = true;
 		}
 	}
 
-	if(bouncy_jump && control.jump){
-		m_speed.Y += movement_speed_jump*BS;
-		touching_ground = false;
-		MtEvent *e = new SimpleTriggerEvent("PlayerJump");
-		m_gamedef->event()->put(e);
-	}
-
 	if(!touching_ground_was && touching_ground){
 		MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
 		m_gamedef->event()->put(e);
@@ -371,6 +361,19 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
 	m_can_jump = touching_ground && !in_liquid;
 	if(itemgroup_get(f.groups, "disable_jump"))
 		m_can_jump = false;
+	// Jump key pressed while jumping off from a bouncy block
+	if (m_can_jump && control.jump && itemgroup_get(f.groups, "bouncy") &&
+		m_speed.Y >= -0.5 * BS) {
+		float jumpspeed = movement_speed_jump * physics_override_jump;
+		if (m_speed.Y > 1) {
+			// Reduce boost when speed already is high
+			m_speed.Y += jumpspeed / (1 + (m_speed.Y / 16 ));
+		} else {
+			m_speed.Y += jumpspeed;
+		}
+		setSpeed(m_speed);
+		m_can_jump = false;
+	}
 }
 
 void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d)