-- LUALOCALS < ---------------------------------------------------------
local ipairs, klots, minetest, pairs, string, vector
    = ipairs, klots, minetest, pairs, string, vector
local string_format
    = string.format
-- LUALOCALS > ---------------------------------------------------------

-- Make the "kill" command reset the current level

minetest.unregister_chatcommand("kill")

local function resetlevel(curlv)
	local started = minetest.get_us_time()
	local dirty = klots.mapblock_dirty(curlv.minp, curlv.maxp)
	for i = 1, #dirty do
		local p = dirty[i]
		minetest.delete_area(p, p)
	end
	minetest.log("warning", string_format(
			"reset %d mapblocks from %s to %s in %0.3fms",
			#dirty,
			minetest.pos_to_string(curlv.minp),
			minetest.pos_to_string(curlv.maxp),
			(minetest.get_us_time() - started) / 1000))

	for _, player in ipairs(minetest.get_connected_players()) do
		local pos = player:get_pos()
		if pos.x >= curlv.minp.x and pos.x <= curlv.maxp.x
		and pos.y >= curlv.minp.y and pos.y <= curlv.maxp.y
		and pos.z >= curlv.minp.z and pos.z <= curlv.maxp.z then
			klots.player_teleport(player, pos, curlv.pos)
		end
	end
end

local function delay(ticks, func, ...)
	if ticks <= 0 then return func(...) end
	return minetest.after(0, delay, ticks - 1, func, ...)
end

minetest.register_chatcommand("kill", {
		description = "Reset the current level",
		func = function(name)
			if not minetest.is_singleplayer() then
				return false, "this command is for singleplayer only"
			end

			local player = minetest.get_player_by_name(name)
			if not player then return false, "invalid player" end

			local ppos = player:get_pos()
			local curlv, curdist
			for _, lvdata in pairs(klots.leveldata) do
				local dist = vector.distance(lvdata.pos, ppos)
				if (not curlv) or dist < curdist then
					curdist = dist
					curlv = lvdata
				end
			end
			if not curlv then return false, "current level not found" end

			klots.player_control_set(player, "frozen")
			klots.flash_screen(player, true)
			return delay(3, resetlevel, curlv)
		end
	})
