Update mainmenu/init.lua
This commit is contained in:
parent
a577b070e9
commit
e4bea7c082
1 changed files with 196 additions and 88 deletions
|
|
@ -12,18 +12,17 @@ size = window.max_formspec_size
|
|||
default_textures = minetest.get_texturepath_share().."/base/pack/"
|
||||
|
||||
--FIXME: Assets
|
||||
local assets = "/Users/iboettcher/eclipse-workspace/mods/mtmenu/"
|
||||
local assets = os.getenv("HOME").."/eclipse-workspace/mods/mtmenu/"
|
||||
|
||||
local version = minetest.get_version()
|
||||
|
||||
-- Holds all the interface parts
|
||||
-- This is where all view-specific state information goes.
|
||||
state = {}
|
||||
|
||||
local fe = minetest.formspec_escape
|
||||
local hte = minetest.hypertext_escape
|
||||
|
||||
--FIXME: Replace with /content because pause menu
|
||||
dofile(minetest.get_builtin_path().."mainmenu/settings/settingtypes.lua")
|
||||
dofile(minetest.get_builtin_path().."common/settings/settingtypes.lua")
|
||||
|
||||
---[[
|
||||
|
||||
|
|
@ -37,7 +36,6 @@ minetest.set_formspec_prepend("\
|
|||
style[nobg,nobg:hovered,nobg:focused,nobg:hovered+focused;border=false;bgimg="..default_textures.."blank.png;bgimg_middle=0]\
|
||||
")
|
||||
|
||||
-- Prepended to the meta menu's formspec.
|
||||
local meta_header = "formspec_version[8]\
|
||||
size["..size.x..","..size.y.."]\
|
||||
padding[0,0]\
|
||||
|
|
@ -47,7 +45,6 @@ local meta_header = "formspec_version[8]\
|
|||
"
|
||||
-- box[0,0;"..size.x..","..size.y..";]\
|
||||
|
||||
-- Prepended to game menus' formspecs.
|
||||
local game_header = "formspec_version[8]\
|
||||
size["..size.x..","..size.y.."]\
|
||||
padding[0,0]\
|
||||
|
|
@ -65,16 +62,20 @@ local content_header = "formspec_version[8]\
|
|||
bgcolor[#0000;true;#151618]\
|
||||
"
|
||||
|
||||
-- The default main menu for games.
|
||||
local default_game_menu = [[
|
||||
<meta>
|
||||
enable_clouds = true
|
||||
</meta>
|
||||
<main>
|
||||
@set:test:Hello
|
||||
label[2,2;Test]
|
||||
scroll_container[1,6;4,2;worldscroll;vertical;;0,0]
|
||||
@foreach:$WORLDS:worlds
|
||||
@if:@selected_world:fi2
|
||||
@set:list_width:@WIDTH * 0.3
|
||||
@else:fi2
|
||||
@set:list_width:@WIDTH * 0.8
|
||||
@endif:fi2
|
||||
|
||||
image[${@WIDTH * 0.1 +-0.1},${@HEIGHT * 0.1 +-0.1};${@WIDTH * 0.8 + 0.2},${@HEIGHT * 0.8 + 0.2};$DEFAULT_ASSET_PATH/bg_translucent.png;8,8]
|
||||
scroll_container[${@WIDTH * 0.1},${@HEIGHT * 0.1};${@list_width},${@HEIGHT * 0.8};worldscroll;vertical;;0,0]
|
||||
@foreach:@WORLDS:worlds
|
||||
@if:@i % 2:sel
|
||||
style[.select_world_${@name};bgimg=$DEFAULT_ASSET_PATH/white.png;bgimg_middle=0;bgcolor=#373530]
|
||||
style[.select_world_${@name}:hovered;bgimg=$DEFAULT_ASSET_PATH/white.png;bgimg_middle=0;bgcolor=#373530]
|
||||
|
|
@ -84,9 +85,21 @@ local default_game_menu = [[
|
|||
style[.select_world_${@name}:hovered;bgimg=$DEFAULT_ASSET_PATH/white.png;bgimg_middle=0;bgcolor=#403e39]
|
||||
style[.select_world_${@name}:hovered+focused;bgimg=$DEFAULT_ASSET_PATH/white.png;bgimg_middle=0;bgcolor=#403e39]
|
||||
@endif:sel
|
||||
button[0,${@i * 0.5};4,0.5;.select_world_${@name};${@test}]
|
||||
button[0,${(@i +-1) * 0.5};${@list_width},0.5;.select_world_${@name};${@name}]
|
||||
@endforeach:worlds
|
||||
scroll_container_end[]
|
||||
|
||||
@if:@selected_world:fi
|
||||
box[${@WIDTH * 0.4 +-0.05},${@HEIGHT * 0.1};0.1,${@HEIGHT * 0.8};#292d2fff]
|
||||
scroll_container[${@WIDTH * 0.4},${@HEIGHT * 0.1};${@WIDTH * 0.8},${@HEIGHT * 0.8};worldmodsscroll;vertical;;0,0]
|
||||
@foreach:@WORLDMODS:wm
|
||||
label[0,${@i};${@name}]
|
||||
@endforeach:wm
|
||||
scroll_container_end[]
|
||||
scrollbar[-800,6;0,2;vertical;worldmodsscroll;]
|
||||
@else:fi
|
||||
|
||||
@endif:fi
|
||||
scrollbaroptions[arrows=hide]
|
||||
scrollbar[-800,6;0,2;vertical;worldscroll;]
|
||||
</main>
|
||||
|
|
@ -99,7 +112,7 @@ local default_game_menu = [[
|
|||
@endforeach:myloop
|
||||
</addworld>
|
||||
]]
|
||||
|
||||
|
||||
function core.on_before_close()
|
||||
--minetest.settings:write()
|
||||
end
|
||||
|
|
@ -117,11 +130,6 @@ end
|
|||
minetest.async_event_handler = handle_job
|
||||
|
||||
function minetest.handle_async(func, parameter, callback)
|
||||
-- Serialize function
|
||||
local serialized_func = string.dump(func)
|
||||
|
||||
assert(serialized_func ~= nil)
|
||||
|
||||
-- Serialize parameters
|
||||
local serialized_param = minetest.serialize(parameter)
|
||||
|
||||
|
|
@ -129,7 +137,7 @@ function minetest.handle_async(func, parameter, callback)
|
|||
return false
|
||||
end
|
||||
|
||||
local jobid = minetest.do_async_callback(serialized_func, serialized_param)
|
||||
local jobid = minetest.do_async_callback(func, serialized_param)
|
||||
|
||||
minetest.async_jobs[jobid] = callback
|
||||
|
||||
|
|
@ -173,13 +181,44 @@ local function get_worlds_for_game(id)
|
|||
local out = {}
|
||||
for _, x in ipairs(minetest.get_worlds()) do
|
||||
if x.gameid == id then
|
||||
if math.random() > 0.5 then x.selected = true end
|
||||
out[#out +1] = x
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
function get_mods_for_game(id)
|
||||
local out = {}
|
||||
for _, x in ipairs(get_all_mods()) do
|
||||
local conf = Settings(x.path.."mod.conf")
|
||||
local unsupported_games = conf:get("unsupported_games")
|
||||
if unsupported_games then
|
||||
if table.indexof(unsupported_games:trim():split(","), id) == -1 then
|
||||
out[#out +1] = x
|
||||
end
|
||||
else
|
||||
local supported_games = conf:get("supported_games")
|
||||
if supported_games then
|
||||
if table.indexof(supported_games:trim():split(","), id) ~= -1 then
|
||||
out[#out +1] = x
|
||||
end
|
||||
else
|
||||
out[#out +1] = x
|
||||
end
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
function get_mods_for_world(world)
|
||||
local config = minetest.check_mod_configuration(world)
|
||||
for _, x in ipairs(config.unsatisfied_mods) do
|
||||
x.unsatisfied = true
|
||||
config.satisfied_mods[#config.satisfied_mods +1] = x
|
||||
end
|
||||
return config.satisfied_mods
|
||||
end
|
||||
|
||||
-- Returns a list of content available for download.
|
||||
function get_available_content()
|
||||
local version = minetest.get_version()
|
||||
|
|
@ -357,6 +396,10 @@ will define a dialog named 'main', with a label in it, and a dialog named 'other
|
|||
with a button in it. Every menu file must have a dialog named 'main', which serves
|
||||
as the entry point of the game's menu.
|
||||
|
||||
Note that to prevent dialog definitions from conflicting with the contents of
|
||||
hypertext[] elements, they must not have leading whitespace before the opening
|
||||
delimiter.
|
||||
|
||||
Being able to define these other dialogs would be pretty pointless if they couldn't
|
||||
be used for anything. Accordingly, you can use standard formspec actions, e.g. buttons,
|
||||
to segue to a different dialog. To do this, set the action name to
|
||||
|
|
@ -393,9 +436,13 @@ file's top-level object will correspond to a variable. (Note that variable names
|
|||
only contain letters or numbers, even if mapped from a JSON file.)
|
||||
|
||||
The menu-provided lists are:
|
||||
- $WORLDS: The list of worlds for this game. Exposes @name (the world name),
|
||||
- @WORLDS: The list of worlds for this game. Exposes @name (the world name),
|
||||
@path (the world's full absolute path), @gameid (the ID of the current game),
|
||||
and @selected (whether the world is currently selected).
|
||||
- @MODS: The list of installed mods that are not incompatible with this game.
|
||||
Exposes @name, @title, @description, @author, @path, @depends, and @optional_depends.
|
||||
- @WORLDMODS: The list of mods installed on the current world. No-op if no world
|
||||
is selected.
|
||||
|
||||
Expressions also support rudimentary mathematical operations, namely addition (+),
|
||||
subtraction (+-), multiplication (*), division (/), and exponentiation (^). Trying
|
||||
|
|
@ -436,6 +483,12 @@ Example:
|
|||
@endif:<name>
|
||||
```
|
||||
|
||||
Notes:
|
||||
- The only uniqueness requirements for the name of a block is that it not be
|
||||
the name of a statment of the same type contained in the body of that block.
|
||||
This is so that the parser knows which `end` belongs to which block without
|
||||
having to manage state.
|
||||
|
||||
Note: Because of the way the main menu works, image paths must be specified in full.
|
||||
To make this non-painful, when referencing images use '$ASSET_PATH/<image name>'
|
||||
instead of just the image name. $ASSET_PATH will be replaced with the actual path
|
||||
|
|
@ -444,7 +497,7 @@ there. You can use $ASSET_PATH in any context. Additionally, $DEFAULT_ASSET_PATH
|
|||
the path to the builtin assets folder, and $NO_IMAGE is the path to blank.png, in
|
||||
case you need to stylistically unset a background image defined by a global style.
|
||||
--]]
|
||||
local function build_template_dialog(fs)
|
||||
local function build_template_dialog(fs, depth)
|
||||
if fs:trim() == "" then return end
|
||||
local dialog = {}
|
||||
local i = 0
|
||||
|
|
@ -452,43 +505,44 @@ local function build_template_dialog(fs)
|
|||
-- Extract foreach loops
|
||||
local prev = 1
|
||||
while i < 1000 do
|
||||
local unfound = 0
|
||||
local a, b, pattern, name, content = fs:find("@foreach:([^:]+):(%w*)\n(.-)\n%s-@endforeach:%2", prev)
|
||||
if not a then break end
|
||||
-- print("for each "..pattern.." ("..name..")\n"..content.."\nend for each ("..name..")")
|
||||
dialog[#dialog +1] = build_template_dialog(fs:sub(prev +1, a -1))
|
||||
dialog[#dialog +1] = {
|
||||
foreach = pattern:trim(),
|
||||
name = name,
|
||||
content = build_template_dialog(content:trim())
|
||||
}
|
||||
prev = b
|
||||
i = i +1
|
||||
end
|
||||
|
||||
if i > 0 then
|
||||
dialog[#dialog +1] = build_template_dialog(fs:sub(prev +1))
|
||||
else
|
||||
-- Extract conditionals
|
||||
prev = 0
|
||||
while i < 1000 do
|
||||
local a, b, expr, name, content, else_content = fs:find("@if:([^:]+):(%w*)\n(.-)\n%s-@else:%2\n(.-\n?)@endif:%2", prev)
|
||||
if not a then break end
|
||||
-- print("for each "..pattern.." ("..name..")\n"..content.."\nend for each ("..name..")")
|
||||
dialog[#dialog +1] = fs:sub(prev +1, a -1)
|
||||
-- print(string.rep("-", 20)..(depth or 0))
|
||||
if a then
|
||||
-- print("for each "..pattern.." ("..name..")\n"..content.."\nend for each ("..name..")")
|
||||
dialog[#dialog +1] = build_template_dialog(fs:sub(prev, a -1), (depth or 0) +1)
|
||||
dialog[#dialog +1] = {
|
||||
condition = expr:trim(),
|
||||
foreach = pattern:trim(),
|
||||
name = name,
|
||||
content = build_template_dialog(content:trim()),
|
||||
else_content = build_template_dialog(else_content:trim())
|
||||
content = build_template_dialog(content:trim(), (depth or 0) +1)
|
||||
}
|
||||
prev = b
|
||||
i = i +1
|
||||
else
|
||||
unfound = unfound +1
|
||||
end
|
||||
if i > 0 then
|
||||
dialog[#dialog +1] = fs:sub(prev +1)
|
||||
local a, b, expr, name, content, else_content = fs:find("@if:([^:]+):(%w*)\n(.-)\n%s-@else:%2\n(.-\n?)@endif:%2", prev)
|
||||
if a then
|
||||
-- print("if "..expr.." ("..name..")\n"..content.."\nend if ("..name..")")
|
||||
dialog[#dialog +1] = build_template_dialog(fs:sub(prev +1, a -1), (depth or 0) +1)
|
||||
dialog[#dialog +1] = {
|
||||
condition = expr:trim(),
|
||||
name = name,
|
||||
content = build_template_dialog(content:trim(), (depth or 0) +1),
|
||||
else_content = build_template_dialog(else_content:trim(), (depth or 0) +1)
|
||||
}
|
||||
prev = b
|
||||
i = i +1
|
||||
else
|
||||
unfound = unfound +1
|
||||
end
|
||||
if unfound > 1 then break end
|
||||
end
|
||||
|
||||
if prev > 1 then
|
||||
dialog[#dialog +1] = build_template_dialog(fs:sub(prev +1))
|
||||
end
|
||||
|
||||
if #dialog == 1 then dialog = dialog[1] end
|
||||
if i == 0 then dialog = fs end
|
||||
-- minetest.log(dump(dialog, " "))
|
||||
|
|
@ -497,19 +551,20 @@ end
|
|||
|
||||
local function build_game_menu(input)
|
||||
-- MARK: Environment variables
|
||||
input = input
|
||||
input = "\n"..input
|
||||
:gsub("%$ASSET_PATH", fe(state.current_game.path.."/menu"))
|
||||
:gsub("%$DEFAULT_ASSET_PATH", fe(assets:sub(1, #assets -1)))
|
||||
:gsub("%$NO_IMAGE", fe(default_textures.."blank.png"))
|
||||
:gsub("/%*.-%*/", "")
|
||||
local menu = {}
|
||||
for name, fs in input:gmatch("<(%l+)>(.-)</%1>") do
|
||||
for name, fs in input:gmatch("%f[^\n]<(%l+)>(.-)%f[^\n]</%1>") do
|
||||
if name == "meta" then
|
||||
menu[name] = parse_conf_text(fs)
|
||||
else
|
||||
menu[name] = build_template_dialog(fs)
|
||||
end
|
||||
end
|
||||
-- print(dump(menu, " "))
|
||||
return menu
|
||||
end
|
||||
|
||||
|
|
@ -629,13 +684,25 @@ local function evaluate_template_expression(expr, vars, depth)
|
|||
-- Expand all variables so we can deal with a constexpr.
|
||||
local offset = 1
|
||||
while offset < 100000 do
|
||||
local a, b, name = expr:find("@([%a]+)", offset)
|
||||
local a, b, name = expr:find("@([%a_]+)", offset)
|
||||
if not a then break end
|
||||
-- If referencing an undefined variable, default to 0 because it's safest that way.
|
||||
local result = minetest.formspec_escape(tostring(vars[name] or "0"))
|
||||
expr = expr:sub(1, a -1)..result..expr:sub(b +1)
|
||||
offset = a +#result
|
||||
end
|
||||
|
||||
-- Condense sub-expressions.
|
||||
local offset = 1
|
||||
while offset < 100000 do
|
||||
local a, b, se = expr:find("(%b())", offset)
|
||||
if not a then break end
|
||||
se = se:gsub("^%((.*)%)$", "%1")
|
||||
local result = evaluate_template_expression(se, vars, depth +1)
|
||||
expr = expr:sub(1, a -1)..result..expr:sub(b +1)
|
||||
offset = a +#result
|
||||
end
|
||||
|
||||
-- If there are no operators, this is a constant expression and we can just return.
|
||||
if not expr:find("%p") then return expr end
|
||||
|
||||
|
|
@ -649,7 +716,7 @@ local function evaluate_template_block(fs, vars)
|
|||
-- Assignment statements
|
||||
local offset = 1
|
||||
while offset < #fs do
|
||||
local a, b, name, expr = fs:find("@set:(%w+):(.-)\n", offset)
|
||||
local a, b, name, expr = fs:find("@set:([%a_]+):([^\n]+)", offset)
|
||||
if not a then break end
|
||||
vars[name] = evaluate_template_expression(expr, vars)
|
||||
fs = fs:sub(1, a -1)..fs:sub(b +1)
|
||||
|
|
@ -673,8 +740,17 @@ local function evaluate_template_foreach(loop, vars)
|
|||
local list = {}
|
||||
if loop.foreach:sub(1,1) == "[" then
|
||||
list = loop.foreach:gsub("^%[(.*)%]$", "%1"):split(",")
|
||||
elseif loop.foreach == "$WORLDS" then
|
||||
list = get_worlds_for_game(state.current_game.id)
|
||||
elseif loop.foreach:sub(1, 1) == "@" then
|
||||
local var = loop.foreach:sub(2)
|
||||
if var == "WORLDS" then
|
||||
list = get_worlds_for_game(state.current_game.id)
|
||||
elseif var == "MODS" then
|
||||
list = get_mods_for_game(state.current_game.id)
|
||||
elseif var == "WORLDMODS" then
|
||||
list = state.current_world and get_mods_for_world(state.current_world) or {}
|
||||
else
|
||||
list = vars[var]
|
||||
end
|
||||
end
|
||||
for i, x in ipairs(list) do
|
||||
local vars2 = {}
|
||||
|
|
@ -704,21 +780,19 @@ local function evaluate_template_conditional(cond, vars)
|
|||
return out
|
||||
end
|
||||
|
||||
-- Game dialogs might contain e.g. foreach loops, so build those if needed.
|
||||
-- Process the syntax tree for a game dialog and output the resulting string.
|
||||
function evaluate_game_dialog(dialog, vars)
|
||||
local out = ""
|
||||
if type(dialog) == "string" then return evaluate_template_block(dialog, vars) end
|
||||
for _, x in ipairs(dialog) do
|
||||
if type(x) == "string" then
|
||||
out = out..evaluate_template_block(x, vars)
|
||||
elseif x.condition then
|
||||
out = out..evaluate_template_conditional(x, vars)
|
||||
elseif x.foreach then
|
||||
out = out..evaluate_template_foreach(x, vars)
|
||||
else
|
||||
for _, c in ipairs(x) do
|
||||
out = out..evaluate_game_dialog(c, vars)
|
||||
end
|
||||
if not dialog then return out end
|
||||
if type(dialog) == "string" then
|
||||
return evaluate_template_block(dialog, vars)
|
||||
elseif dialog.condition then
|
||||
out = out..evaluate_template_conditional(dialog, vars)
|
||||
elseif dialog.foreach then
|
||||
out = out..evaluate_template_foreach(dialog, vars)
|
||||
else
|
||||
for _, c in ipairs(dialog) do
|
||||
out = out..evaluate_game_dialog(c, vars)
|
||||
end
|
||||
end
|
||||
return out
|
||||
|
|
@ -763,12 +837,9 @@ function show_meta_menu(v)
|
|||
local dist = i -idx
|
||||
local scale = 4 /(math.abs(dist) +1)
|
||||
if scale > 0.1 then
|
||||
--This looks cool, but is useless for UI purposes: center +10^(1 /math.abs(dist)) *math.sign(dist)
|
||||
--This looks neat, but is useless for UI purposes: center +10^(1 /math.abs(dist)) *math.sign(dist)
|
||||
local lc = center +math.abs(dist *10)^0.55 *math.sign(dist)
|
||||
local test = io.open(x.menuicon_path)
|
||||
if test then
|
||||
test:close()
|
||||
else
|
||||
if x.menuicon_path == "" then
|
||||
x.menuicon_path = assets.."games.png"
|
||||
end
|
||||
--TODO: Do these need some kind of background?
|
||||
|
|
@ -852,7 +923,7 @@ function show_game_menu(args)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if #backgrounds > 0 then
|
||||
local path = game.path.."/menu/"..backgrounds[math.random(#backgrounds)]
|
||||
if minetest.set_background("background", path) then
|
||||
|
|
@ -898,6 +969,7 @@ function show_game_menu(args)
|
|||
for i, x in ipairs(state.menu_current) do
|
||||
fs = fs..evaluate_game_dialog(game.menu[x], setmetatable({WIDTH = size.x, HEIGHT = size.y}, {__index = state.menu_vars}))
|
||||
end
|
||||
-- print(fs)
|
||||
|
||||
minetest.update_formspec(game_header..fs.."\
|
||||
button[0,"..(size.y -1)..";1,1;to_meta_menu;<]\
|
||||
|
|
@ -912,6 +984,23 @@ function add_favorite_server(address, port)
|
|||
f:close()
|
||||
end
|
||||
|
||||
function remove_favorite_server(address, port)
|
||||
local idx
|
||||
for i, x in pairs(state.favorite_servers) do
|
||||
if x.address == address and x.port == port then
|
||||
idx = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if idx then
|
||||
table.remove(state.favorite_servers, idx)
|
||||
local f = io.open(minetest.get_user_path().."/client/serverlist/favoriteservers.json", "w")
|
||||
f:write(minetest.write_json(state.favorite_servers))
|
||||
f:flush()
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
|
||||
function refresh_server_list()
|
||||
minetest.handle_async(
|
||||
function(param)
|
||||
|
|
@ -934,6 +1023,9 @@ function refresh_server_list()
|
|||
local list = table.copy(state.favorite_servers)
|
||||
table.insert_all(list, result)
|
||||
state.serverlist = list
|
||||
if state.serverlist_filtered then
|
||||
state.serverlist_filtered = search_server_list(state.servers_filter)
|
||||
end
|
||||
if state.loc == "servers" then
|
||||
show_servers_menu()
|
||||
end
|
||||
|
|
@ -1363,15 +1455,18 @@ function show_content_menu()
|
|||
fs = fs.."\
|
||||
box[0,0;"..size.x..",1;#403e39ff]\
|
||||
box[0,1;"..size.x..",0.1;#292d2fff]\
|
||||
style[content_search,content_cancel;bgimg="..assets.."btn_bg_2.png;bgimg_middle=8,8]\
|
||||
style[content_search,content_cancel;bgimg="..assets.."btn_bg_2_dark.png;bgimg_middle=8,8]\
|
||||
image_button[0.125,0.125;0.75,0.75;"..assets.."search.png;content_search;]\
|
||||
tooltip[content_search;Search;#444;#aaa]\
|
||||
image_button[1,0.125;0.75,0.75;"..assets.."cancel.png;content_cancel;]\
|
||||
tooltip[content_cancel;Cancel;#444;#aaa]\
|
||||
style[test;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#403e39ff]\
|
||||
style[test:hovered;bgimg="..assets.."white.png;bgimg_middle=0]\
|
||||
image[2,0.125;"..(size.x -9)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
field[2.1,0.125;"..(size.x -9.2)..",0.75;content_filter;;]\
|
||||
button["..(w -7)..",0;4,1;test;Browse Online Content...]\
|
||||
button["..(w -3)..",0;3,1;test;Add Content...]\
|
||||
button["..(w -6)..",0;4,1;test;Browse Online Content...]\
|
||||
image_button["..(w -1.5)..",0.125;0.75,0.75;"..assets.."new_package.png;new_package;]\
|
||||
tooltip[new_package;New Package...;#444;#aaa]\
|
||||
"
|
||||
|
||||
local start = w /2 -(pages *0.125)
|
||||
|
|
@ -1392,7 +1487,8 @@ function show_content_menu()
|
|||
end
|
||||
|
||||
function minetest.button_handler(data)
|
||||
state.menu_vars = data
|
||||
if not state.menu_vars then state.menu_vars = {} end
|
||||
setmetatable(state.menu_vars, {__index = data})
|
||||
if state.loc == "games" then
|
||||
if data.content or data.ht == "action:content" then
|
||||
if state.loc ~= "content" then show_content() end
|
||||
|
|
@ -1422,11 +1518,16 @@ function minetest.button_handler(data)
|
|||
if data.servers_refresh then
|
||||
refresh_server_list()
|
||||
elseif data.servers_search or data.key_enter_field == "servers_filter" then
|
||||
state.servers_filter = data.servers_filter
|
||||
state.serverlist_filtered = search_server_list(data.servers_filter)
|
||||
show_servers_menu()
|
||||
elseif data.servers_cancel then
|
||||
state.serverlist_filtered = nil
|
||||
show_servers_menu()
|
||||
elseif data.unfavorite_server then
|
||||
state.current_server.favorite = nil
|
||||
remove_favorite_server(state.current_server.address, state.current_server.port)
|
||||
show_servers_menu()
|
||||
elseif data.show_server_mods then
|
||||
state.showing_server_mods = true
|
||||
show_servers_menu()
|
||||
|
|
@ -1449,23 +1550,23 @@ function minetest.button_handler(data)
|
|||
show_servers_menu()
|
||||
elseif data.confirm_join_server or data.key_enter_field == "server_username" or data.key_enter_field == "server_password" or data.key_enter_field == "server_address" then
|
||||
minetest.settings:set("name", data.server_username)
|
||||
if not tonumber(data.server_port) then
|
||||
state.server_connection_error = {
|
||||
msg = "Invalid port.",
|
||||
element = "server_port"
|
||||
}
|
||||
show_servers_menu()
|
||||
state.server_connection_error = nil
|
||||
return
|
||||
end
|
||||
local address
|
||||
local port
|
||||
if state.connecting_to_server then
|
||||
if not tonumber(data.server_port) then
|
||||
state.server_connection_error = {
|
||||
msg = "Invalid port.",
|
||||
element = "server_port"
|
||||
}
|
||||
show_servers_menu()
|
||||
state.server_connection_error = nil
|
||||
return
|
||||
end
|
||||
address = data.server_address:lower()
|
||||
port = data.server_port:lower()
|
||||
else
|
||||
address = state.current_server.address:lower()
|
||||
port = state.current_server.port:lower()
|
||||
port = state.current_server.port
|
||||
end
|
||||
local is_favorite = false
|
||||
for _, x in ipairs(state.favorite_servers) do
|
||||
|
|
@ -1523,10 +1624,17 @@ function minetest.button_handler(data)
|
|||
show_game_menu {
|
||||
overlay_dialog = k:sub(string.len(".overlay_dialog_>"))
|
||||
}
|
||||
elseif k:sub(1, string.len(".select_world_")) == ".select_world_" then
|
||||
state.menu_vars.selected_world = k:sub(string.len(".select_world_>"))
|
||||
show_game_menu()
|
||||
elseif k == ".unoverlay_dialog" then
|
||||
show_game_menu {
|
||||
unoverlay_dialog = true
|
||||
}
|
||||
elseif k:sub(1, string.len(".set_")) == ".set_" then
|
||||
local name, value = k:match "%.set_(.-)_to_(.*)"
|
||||
state.menu_vars[name] = value == "" and "0" or value
|
||||
show_game_menu()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue