-- Minimal mod to temporarily slow down player

local SLOWDOWN_SPEED_FACTOR = 0.5
local SLOWDOWN_JUMP_FACTOR = 0.5

local slowdown_timers = {}

lzr_slowdown = {}

-- Slow down player for a few seconds. This will add to the time
-- the player is slowed down.
-- * player: Player to slow down
-- * time: Time to add to player's slow down time
-- * max_time: (optional) The new total player slowdown time will not exceed this value
lzr_slowdown.slowdown = function(player, time, max_time)
	local name = player:get_player_name()
	if not slowdown_timers[name] or slowdown_timers[name] < 0 then
		slowdown_timers[name] = 0
	end
	if max_time then
		slowdown_timers[name] = math.min(slowdown_timers[name] + time, max_time)
	else
		slowdown_timers[name] = slowdown_timers[name] + time
	end
	if slowdown_timers[name] > 0 then
		playerphysics.add_physics_factor(player, "speed", "lzr_slowdown:slowdown", SLOWDOWN_SPEED_FACTOR)
		playerphysics.add_physics_factor(player, "jump", "lzr_slowdown:slowdown", SLOWDOWN_JUMP_FACTOR)
	end
end

-- Remove slowdown effect
lzr_slowdown.stop_slowdown = function(player)
	playerphysics.remove_physics_factor(player, "speed", "lzr_slowdown:slowdown")
	playerphysics.remove_physics_factor(player, "jump", "lzr_slowdown:slowdown")
	slowdown_timers[player:get_player_name()] = 0
end

minetest.register_globalstep(function(dtime)
	for player_name, timer in pairs(slowdown_timers) do
		if timer > 0 then
			timer = timer - dtime
			if timer <= 0 then
				local player = minetest.get_player_by_name(player_name)
				if player then
					playerphysics.remove_physics_factor(player, "speed", "lzr_slowdown:slowdown")
					playerphysics.remove_physics_factor(player, "jump", "lzr_slowdown:slowdown")
				end
			end
			slowdown_timers[player_name] = timer
		end
	end
end)

minetest.register_on_leaveplayer(function(player)
	slowdown_timers[player:get_player_name()] = nil
end)

-- Reset player slowdown when entering any state but the level states
lzr_gamestate.register_on_enter_state(function(new_state)
	if new_state ~= lzr_gamestate.LEVEL and new_state ~= lzr_gamestate.LEVEL_COMPLETE and new_state ~= lzr_gamestate.LEVEL_TEST then
		local player = minetest.get_player_by_name("singleplayer")
		if player then
			playerphysics.remove_physics_factor(player, "speed", "lzr_slowdown:slowdown")
			playerphysics.remove_physics_factor(player, "jump", "lzr_slowdown:slowdown")
			local player_name = player:get_player_name()
			slowdown_timers[player_name] = 0
		end
	end
end)
