173 lines
5.4 KiB
Lua
173 lines
5.4 KiB
Lua
local S = minetest.get_translator("lzr_level_select")
|
|
local F = minetest.formspec_escape
|
|
|
|
lzr_level_select = {}
|
|
|
|
local current_level_selection = nil
|
|
local current_custom_level_selection = nil
|
|
local custom_levels
|
|
|
|
local no_levels_form = function(player, message)
|
|
return "formspec_version[4]size[8,3.5]"..
|
|
"textarea[0.5,0.5;7,1.8;;;"..F(message).."]"..
|
|
"button_exit[3,2.5;2,0.6;okay;"..F(S("OK")).."]"
|
|
end
|
|
|
|
lzr_level_select.open_dialog = function(player, level_set)
|
|
local caption
|
|
if level_set == "core" then
|
|
caption = S("Select level:")
|
|
elseif level_set == "custom" then
|
|
caption = S("Select custom level:")
|
|
else
|
|
minetest.log("error", "[lzr_level_select] open_dialog called with unknown level_set!")
|
|
return false
|
|
end
|
|
local form = "formspec_version[4]size[6,10]"..
|
|
"label[0.5,0.4;"..F(caption).."]"..
|
|
"button_exit[1.5,8.5;3,1;okay;"..F(S("Start")).."]"..
|
|
"tablecolumns[color;text]"..
|
|
"table[0.5,0.8;5,7.5;levellist;"
|
|
local list = {}
|
|
local entry_header = ""
|
|
local first_uncompleted_level = nil
|
|
if level_set == "core" then
|
|
-- Built-in level set
|
|
local completed_levels = lzr_levels.get_completed_levels()
|
|
for l=1, lzr_levels.LAST_LEVEL do
|
|
if completed_levels[l] then
|
|
entry_header = "#00FF00"
|
|
else
|
|
if not first_uncompleted_level then
|
|
first_uncompleted_level = l
|
|
end
|
|
entry_header = ""
|
|
end
|
|
table.insert(list, entry_header..","..F(lzr_levels.get_level_name(l, nil, true)))
|
|
end
|
|
if not first_uncompleted_level then
|
|
first_uncompleted_level = 1
|
|
end
|
|
current_level_selection = first_uncompleted_level
|
|
else
|
|
-- Custom level set (editor levels)
|
|
local list_levels = lzr_editor.get_custom_levels()
|
|
custom_levels = {}
|
|
for l=1, #list_levels do
|
|
local levelname = list_levels[l]
|
|
-- Hide the autosave level because it's not meant
|
|
-- for playing
|
|
if levelname ~= lzr_globals.AUTOSAVE_NAME then
|
|
table.insert(custom_levels, levelname)
|
|
|
|
local proper_name = lzr_editor.get_custom_level_name(levelname, true)
|
|
table.insert(list, entry_header..","..F(proper_name))
|
|
end
|
|
end
|
|
first_uncompleted_level = 1
|
|
current_custom_level_selection = 1
|
|
end
|
|
if not first_uncompleted_level then
|
|
first_uncompleted_level = 1
|
|
end
|
|
local list_str = table.concat(list, ",")
|
|
form = form .. list_str .. ";"..first_uncompleted_level.."]"
|
|
local formname
|
|
if level_set == "core" then
|
|
if #list == 0 then
|
|
form = no_levels_form(player, S("There are no levels."))
|
|
end
|
|
formname = "lzr_level_select:levellist"
|
|
else
|
|
if #list == 0 then
|
|
form = no_levels_form(player,
|
|
S("There are no custom levels.").."\n"..
|
|
S("Install levels from your friends or use the level editor to build your own."))
|
|
end
|
|
formname = "lzr_level_select:levellist_custom"
|
|
end
|
|
minetest.show_formspec(player:get_player_name(), formname, form)
|
|
end
|
|
|
|
local load_custom_level = function(level, player)
|
|
minetest.log("action", "[lzr_level_select] Player selects custom level: "..level)
|
|
local csv = minetest.get_worldpath().."/levels/"..level..".csv"
|
|
local levels_path = minetest.get_worldpath().."/levels"
|
|
|
|
local custom_level_data = lzr_levels.analyze_levels(csv, levels_path)
|
|
if custom_level_data then
|
|
-- Load level with metadata (preferred)
|
|
lzr_levels.start_level(1, custom_level_data)
|
|
else
|
|
-- Fallback when CSV file could not be read
|
|
custom_level_data = lzr_levels.create_fallback_level_data(level, levels_path)
|
|
lzr_levels.start_level(1, custom_level_data)
|
|
minetest.log("action", "[lzr_level_select] No CSV file found for custom level: "..tostring(level)..". Using fallback")
|
|
end
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname == "lzr_level_select:levellist" then
|
|
if fields.okay then
|
|
if current_level_selection then
|
|
lzr_levels.start_level(current_level_selection)
|
|
end
|
|
elseif fields.levellist then
|
|
local expl = minetest.explode_table_event(fields.levellist)
|
|
if expl.type == "CHG" then
|
|
current_level_selection = expl.row
|
|
elseif expl.type == "DCL" then
|
|
current_level_selection = expl.row
|
|
lzr_levels.start_level(current_level_selection)
|
|
minetest.close_formspec(player:get_player_name(), "lzr_level_select:levellist")
|
|
elseif expl.type == "INV" then
|
|
current_level_selection = nil
|
|
end
|
|
end
|
|
elseif formname == "lzr_level_select:levellist_custom" then
|
|
if fields.okay then
|
|
if custom_levels and current_custom_level_selection then
|
|
local level = custom_levels[current_custom_level_selection]
|
|
if level then
|
|
load_custom_level(level, player)
|
|
end
|
|
end
|
|
elseif fields.levellist then
|
|
local expl = minetest.explode_table_event(fields.levellist)
|
|
if expl.type == "CHG" then
|
|
current_custom_level_selection = expl.row
|
|
elseif expl.type == "DCL" then
|
|
current_custom_level_selection = expl.row
|
|
if custom_levels then
|
|
local level = custom_levels[current_custom_level_selection]
|
|
if level then
|
|
load_custom_level(level, player)
|
|
end
|
|
end
|
|
minetest.close_formspec(player:get_player_name(), "lzr_level_select:levellist_custom")
|
|
elseif expl.type == "INV" then
|
|
current_custom_level_selection = nil
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_chatcommand("level", {
|
|
privs = { server = true },
|
|
description = S("Go to level"),
|
|
params = S("<level>"),
|
|
func = function(name, param)
|
|
local level = tonumber(param)
|
|
if not level then
|
|
return false
|
|
end
|
|
if level < 1 or level > lzr_levels.LAST_LEVEL then
|
|
return false, S("Invalid level!")
|
|
end
|
|
lzr_levels.start_level(level)
|
|
return true
|
|
end,
|
|
|
|
})
|
|
|