local last_y_speeds = {}

core.register_globalstep(function(dtime)
	local players = core.get_connected_players()
	for p=1, #players do
		local player = players[p]
		local name = player:get_player_name()
		local y_speed = player:get_velocity().y
		if not last_y_speeds[name] then
			last_y_speeds[name] = y_speed
		else
			-- Play bounce effect when bouncing off a node (only when falling from bottom).
			-- We don’t know *directly* when the player bounced off a node,
			-- so we use a heurisitc instead.
			-- When the y_speed in the previous step was negative (below a threshold),
			-- and in the current step, it is close to the absolute value of that fall speed,
			-- we assume it was a bounce. This is because a bounce (roughly) inverts the speed.
			if y_speed > math.abs(last_y_speeds[name])*0.75 and last_y_speeds[name] < -0.5 then
				local pitch = 1 + math.min(0.25, math.abs(y_speed*0.01))
				core.sound_play({name="cow_sounds_bounce", gain=0.3, pitch=pitch}, {object=player}, true)
			end
			last_y_speeds[name] = y_speed
		end
	end
end)
core.register_on_leaveplayer(function(player)
	last_y_speeds[player:get_player_name()] = nil
end)
