From d6c82c3f7c7d676d35d9976e684e6a0d7c363544 Mon Sep 17 00:00:00 2001 From: luk3yx Date: Tue, 14 Jun 2022 20:58:04 +1200 Subject: [PATCH] Improve main menu (#60) Co-authored-by: Maksim --- .github/workflows/lua_lint.yml | 2 +- builtin/fstk/buttonbar.lua | 16 ++- builtin/fstk/dialog.lua | 27 ++-- builtin/fstk/tabview.lua | 61 ++++++--- builtin/fstk/ui.lua | 5 +- builtin/mainmenu/dlg_contentstore.lua | 14 +- builtin/mainmenu/dlg_create_world.lua | 18 +-- builtin/mainmenu/dlg_create_world_default.lua | 15 +-- builtin/mainmenu/dlg_delete_content.lua | 12 +- builtin/mainmenu/dlg_delete_world.lua | 6 +- builtin/mainmenu/dlg_outdated_server.lua | 70 ++++++++++ builtin/mainmenu/dlg_rename_modpack.lua | 8 +- builtin/mainmenu/dlg_settings_advanced.lua | 7 +- builtin/mainmenu/init.lua | 30 ++--- builtin/mainmenu/pkgmgr.lua | 2 +- builtin/mainmenu/tab_content.lua | 4 +- builtin/mainmenu/tab_local.lua | 127 ++++++++++-------- builtin/mainmenu/tab_local_default.lua | 94 ++++++++----- builtin/mainmenu/tab_online.lua | 67 +++++---- builtin/mainmenu/textures.lua | 10 +- src/client/client.cpp | 2 +- src/client/game.cpp | 2 +- src/client/renderingengine.h | 4 +- src/defaultsettings.cpp | 4 +- src/gui/guiEngine.cpp | 21 ++- src/gui/guiFormSpecMenu.cpp | 2 +- textures/base/pack/attention.png | Bin 0 -> 259 bytes textures/base/pack/select_btn.png | Bin 0 -> 714 bytes textures/base/pack/switch_local.png | Bin 0 -> 1125 bytes textures/base/pack/switch_local_default.png | Bin 0 -> 2657 bytes .../base/pack/switch_local_default_hover.png | Bin 0 -> 2661 bytes textures/base/pack/switch_local_hover.png | Bin 0 -> 1118 bytes textures/base/pack/trash.png | Bin 232 -> 329 bytes textures/base/pack/trash_hover.png | Bin 0 -> 329 bytes 34 files changed, 393 insertions(+), 237 deletions(-) create mode 100644 builtin/mainmenu/dlg_outdated_server.lua create mode 100644 textures/base/pack/attention.png create mode 100644 textures/base/pack/select_btn.png create mode 100644 textures/base/pack/switch_local.png create mode 100644 textures/base/pack/switch_local_default.png create mode 100644 textures/base/pack/switch_local_default_hover.png create mode 100644 textures/base/pack/switch_local_hover.png create mode 100644 textures/base/pack/trash_hover.png diff --git a/.github/workflows/lua_lint.yml b/.github/workflows/lua_lint.yml index 82374193a..f6d670d9b 100644 --- a/.github/workflows/lua_lint.yml +++ b/.github/workflows/lua_lint.yml @@ -14,7 +14,7 @@ on: jobs: luacheck: name: "Builtin Luacheck and Unit Tests" - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - uses: leafo/gh-actions-lua@v9 diff --git a/builtin/fstk/buttonbar.lua b/builtin/fstk/buttonbar.lua index cb8bb5ac5..451e1e7ec 100644 --- a/builtin/fstk/buttonbar.lua +++ b/builtin/fstk/buttonbar.lua @@ -71,21 +71,23 @@ local function buttonbar_formspec(self) if (self.have_move_buttons) then local btn_dec_pos = {} - btn_dec_pos.x = self.pos.x + (self.btn_size * 0.05) - btn_dec_pos.y = self.pos.y + (self.btn_size * 0.05) local btn_inc_pos = {} local btn_size = {} if self.orientation == "horizontal" then btn_size.x = 0.5 btn_size.y = self.btn_size + btn_dec_pos.x = self.pos.x + (self.btn_size * 0.05) + btn_dec_pos.y = self.pos.y + (self.btn_size * 0.05) btn_inc_pos.x = self.pos.x + self.size.x - 0.5 btn_inc_pos.y = self.pos.y + (self.btn_size * 0.05) else btn_size.x = self.btn_size btn_size.y = 0.5 - btn_inc_pos.x = self.pos.x + (self.btn_size * 0.05) - btn_inc_pos.y = self.pos.y + self.size.y - 0.5 + btn_dec_pos.x = self.pos.x + (self.btn_size * 0.1) + btn_dec_pos.y = self.pos.y + (self.btn_size * 0.05) + btn_inc_pos.x = self.pos.x + (self.btn_size * 0.1) + btn_inc_pos.y = self.pos.y + self.size.y - (self.btn_size * 0.4) end local text_dec = "<" @@ -103,7 +105,7 @@ local function buttonbar_formspec(self) formspec = formspec .. string.format("image_button[%f,%f;%f,%f;;btnbar_inc_%s;%s;true;true]", btn_inc_pos.x, btn_inc_pos.y, btn_size.x, btn_size.y, - self.name, text_inc) + self.name, text_inc) end return formspec @@ -112,7 +114,7 @@ end local function buttonbar_buttonhandler(self, fields) if fields["btnbar_inc_" .. self.name] ~= nil and - self.startbutton < #self.buttons then + self.startbutton < #self.buttons - 4 then self.startbutton = self.startbutton + 1 return true @@ -187,7 +189,7 @@ function buttonbar_create(name, cbf_buttonhandler, pos, orientation, size) local self = {} self.name = name self.type = "addon" - self.bgcolor = "#8fb9de" + self.bgcolor = "#7f9dd5" self.pos = pos self.size = size self.orientation = orientation diff --git a/builtin/fstk/dialog.lua b/builtin/fstk/dialog.lua index c87b8f12e..7bd835cb8 100644 --- a/builtin/fstk/dialog.lua +++ b/builtin/fstk/dialog.lua @@ -50,7 +50,8 @@ local dialog_metatable = { } dialog_metatable.__index = dialog_metatable -function dialog_create(name,get_formspec,buttonhandler,eventhandler) +local bg = core.formspec_escape(defaulttexturedir .. "bg_common.png") +function dialog_create(name, get_formspec, buttonhandler, eventhandler, add_background) local self = {} self.name = name @@ -58,7 +59,21 @@ function dialog_create(name,get_formspec,buttonhandler,eventhandler) self.hidden = true self.data = {} - self.formspec = get_formspec + if add_background then + function self.formspec(data) + return ([[ + size[14,5.4,false] + container[1,0] + bgcolor[#0000] + background9[-0.2,-0.26;12.4,6.15;%s;false;40] + %s + container_end[] + ]]):format(bg, get_formspec(data)) + end + else + self.formspec = get_formspec + end + self.buttonhandler = buttonhandler self.user_eventhandler = eventhandler @@ -69,16 +84,12 @@ function dialog_create(name,get_formspec,buttonhandler,eventhandler) end function messagebox(name, message) - local bg = core.formspec_escape(defaulttexturedir .. "bg_common.png") return dialog_create(name, function() return ([[ - size[12,5.4,false] - bgcolor[#0000] - background9[0,0;14,8;%s;true;40] textarea[1,1;10,4;;;%s] button[5,4.5;2,0.8;ok;%s] - ]]):format(bg, message, fgettext("OK")) + ]]):format(message, fgettext("OK")) end, function(this, fields) if fields.ok then @@ -86,5 +97,5 @@ function messagebox(name, message) return true end end, - nil) + nil, true) end diff --git a/builtin/fstk/tabview.lua b/builtin/fstk/tabview.lua index 1fa586c5e..19bcb284a 100644 --- a/builtin/fstk/tabview.lua +++ b/builtin/fstk/tabview.lua @@ -46,9 +46,19 @@ local function add_tab(self,tab) tabdata = {}, } - self.tablist[#self.tablist + 1] = newtab + -- Hidden tabs have a negative index + local i + if tab.hidden then + i = -1 + while self.tablist[i] do + i = i - 1 + end + else + i = #self.tablist + 1 + end + self.tablist[i] = newtab - if self.last_tab_index == #self.tablist then + if self.last_tab_index == i then self.current_tab = tab.name if tab.on_activate ~= nil then tab.on_activate(nil,tab.name) @@ -68,10 +78,13 @@ local function get_formspec(self) {width=self.width, height=self.height} local defaulttexturedir = core.formspec_escape(defaulttexturedir) formspec = formspec .. - string.format("size[%f,%f,%s]",tsize.width,tsize.height, + string.format("size[%f,%f,%s]",tsize.width + 2,tsize.height, dump(self.fixed_size)) .. "bgcolor[#0000]" .. - "background9[0,0;0,0;" .. defaulttexturedir .. "bg_common.png;true;40]" .. + "container[1,0]" .. + "background9[-0.2,-0.26;" .. tsize.width + 0.4 .. "," .. + tsize.height + 0.75 .. ";" .. defaulttexturedir .. + "bg_common.png;false;40]" .. "style[settings_tab;content_offset=0]" .. "image_button[12.02,1.3;1,1.55;" .. defaulttexturedir .. "settings_menu.png;settings_tab;;true;false;" .. @@ -81,6 +94,7 @@ local function get_formspec(self) defaulttexturedir .. "authors_menu.png;authors_tab;;true;false;" .. defaulttexturedir .. "authors_menu_pressed.png]" end + formspec = formspec .. self:tab_header() formspec = formspec .. self.tablist[self.last_tab_index].get_formspec( @@ -89,6 +103,10 @@ local function get_formspec(self) self.tablist[self.last_tab_index].tabdata, self.tablist[self.last_tab_index].tabsize ) + + if self.parent == nil then + formspec = formspec .. "container_end[]" + end end return formspec end @@ -160,18 +178,15 @@ end -------------------------------------------------------------------------------- local function tab_header(self) - local toadd = "" - - for i=1,#self.tablist,1 do - - if toadd ~= "" then - toadd = toadd .. "," - end - - toadd = toadd .. self.tablist[i].caption + local captions = {} + for i = 1, #self.tablist do + captions[i] = self.tablist[i].caption end + + local toadd = table.concat(captions, ",") return string.format("tabheader[%f,%f;%s;%s;%i;true;false]", - self.header_x, self.header_y, self.name, toadd, self.last_tab_index); + self.header_x, self.header_y, self.name, toadd, + math.max(self.last_tab_index, 1)) end -------------------------------------------------------------------------------- @@ -179,7 +194,7 @@ local function switch_to_tab(self, index) --first call on_change for tab to leave if self.tablist[self.last_tab_index].on_change ~= nil then self.tablist[self.last_tab_index].on_change("LEAVE", - self.current_tab, self.tablist[index].name) + self.current_tab, self.tablist[index].name, self) end --update tabview data @@ -194,7 +209,7 @@ local function switch_to_tab(self, index) -- call for tab to enter if self.tablist[index].on_change ~= nil then self.tablist[index].on_change("ENTER", - old_tab,self.current_tab) + old_tab,self.current_tab,self) end end @@ -213,9 +228,16 @@ end -------------------------------------------------------------------------------- -- Declared as a local variable above handle_buttons function set_tab_by_name(self, name) - for i=1,#self.tablist,1 do - if self.tablist[i].name == name then + -- This uses pairs so that hidden tabs (with a negative index) are searched + -- as well + for i, tab in pairs(self.tablist) do + if tab.name == name then switch_to_tab(self, i) + + if name ~= "local" then + mm_texture.set_dirt_bg() + end + return true end end @@ -241,7 +263,7 @@ local function show_tabview(self) -- call for tab to enter if self.tablist[self.last_tab_index].on_change ~= nil then self.tablist[self.last_tab_index].on_change("ENTER", - nil,self.current_tab) + nil,self.current_tab,self) end end @@ -270,6 +292,7 @@ local tabview_metatable = { tabview_metatable.__index = tabview_metatable -------------------------------------------------------------------------------- +tabview_uses_container = true function tabview_create(name, size, tabheaderpos) local self = {} diff --git a/builtin/fstk/ui.lua b/builtin/fstk/ui.lua index c5b0722ee..f8cc8d03f 100644 --- a/builtin/fstk/ui.lua +++ b/builtin/fstk/ui.lua @@ -85,13 +85,14 @@ function ui.update() local error_message = core.formspec_escape(gamedata.errormessage) local error_title - if gamedata.errormessage:find("ModError") then + local mod_error = gamedata.errormessage:find("ModError") or gamedata.errormessage:find("LuaError") + if mod_error then error_title = fgettext("An error occurred in a Lua script:") else error_title = fgettext("An error occurred:") end local restart_btn - if (maintab == "local" or maintab == "local_default") and + if (maintab == "local" or maintab == "local_default") and mod_error and core.get_us_time() - connect_time > 30 then restart_btn = "button[2,6.6;4,1;btn_reconnect_yes;" .. fgettext("Restart") .. "]" .. diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index 2ccb0a7c3..f7f728d43 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -705,21 +705,20 @@ function store.get_formspec(dlgdata) "bgcolor[#0000]" .. "background9[0,0;0,0;" .. core.formspec_escape(defaulttexturedir .. "bg_common.png") .. ";true;40]", - "position[0.5,0.55]", "style[status,downloading,queued;border=false]", "container[0.375,0.375]", "field[0,0;7.225,0.8;search_string;;", core.formspec_escape(search_string), "]", "field_close_on_enter[search_string;false]", - "image_button[7.3,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "search.png"), ";search;]", - "image_button[8.125,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "clear.png"), ";clear;]", - "dropdown[9.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]", + "image_button[7.3,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "search.png"), ";search;;true;false]", + -- "image_button[8.125,0;0.8,0.8;", core.formspec_escape(defaulttexturedir .. "clear.png"), ";clear;;true;false]", + -- "dropdown[9.6,0;2.4,0.8;type;", table.concat(filter_types_titles, ","), ";", filter_type, "]", "container_end[]", -- Page nav buttons "container[0,", H - 0.8 - 0.375, "]", - "button[0.375,0;4,0.8;back;", fgettext("Back to Main Menu"), "]", + "button[0.375,0;5,0.8;back;", "< " .. fgettext("Back to Main Menu"), "]", "container[", W - 0.375 - 0.8*4 - 2, ",0]", "image_button[0,0;0.8,0.8;", core.formspec_escape(defaulttexturedir), "start_icon.png;pstart;]", @@ -752,7 +751,7 @@ function store.get_formspec(dlgdata) end if num_avail_updates == 0 then - formspec[#formspec + 1] = "button[12.75,0.375;2.625,0.8;status;" + formspec[#formspec + 1] = "button[12.65,0.375;2.825,0.8;status;" formspec[#formspec + 1] = fgettext("No updates") formspec[#formspec + 1] = "]" else @@ -773,7 +772,6 @@ function store.get_formspec(dlgdata) "bgcolor[#0000]" .. "background9[0,0;0,0;" .. core.formspec_escape(defaulttexturedir .. "bg_common.png") .. ";true;40]", - "position[0.5,0.55]", "label[4,3;", fgettext("No packages could be retrieved"), "]", "container[0,", H - 0.8 - 0.375, "]", "button[0,0;4,0.8;back;", fgettext("Back to Main Menu"), "]", @@ -851,11 +849,13 @@ function store.get_formspec(dlgdata) -- description local description_width = W - 0.375*5 - 0.85 - 2*0.7 + formspec[#formspec + 1] = "style_type[textarea;font_size=-2]" formspec[#formspec + 1] = "textarea[1.855,0.3;" formspec[#formspec + 1] = tostring(description_width) formspec[#formspec + 1] = ",0.8;;;" formspec[#formspec + 1] = core.formspec_escape(package.short_description) formspec[#formspec + 1] = "]" + formspec[#formspec + 1] = "style_type[textarea;font_size=]" formspec[#formspec + 1] = "container_end[]" end diff --git a/builtin/mainmenu/dlg_create_world.lua b/builtin/mainmenu/dlg_create_world.lua index 320af36d6..f7c0945b9 100644 --- a/builtin/mainmenu/dlg_create_world.lua +++ b/builtin/mainmenu/dlg_create_world.lua @@ -275,7 +275,7 @@ local function create_world_formspec(dialogdata) end y = y + 0.3 - form = form .. "label[0,"..(y+0.1)..";" .. fgettext("Biomes") .. "]" + form = form .. "label[0,"..(y+0.1)..";" .. fgettext("Biomes") .. ":]" y = y + 0.6 form = form .. "dropdown[0,"..y..";6.3;mgv6_biomes;" @@ -306,7 +306,7 @@ local function create_world_formspec(dialogdata) y = y + 0.3 str_flags, y = mg_main_flags(current_mg, y) if str_flags ~= "" then - label_flags = "label[0,"..y_start..";" .. fgettext("Mapgen flags") .. "]" + label_flags = "label[0,"..y_start..";" .. fgettext("Mapgen flags") .. ":]" y_start = y + 0.4 else y_start = 0.0 @@ -314,7 +314,7 @@ local function create_world_formspec(dialogdata) y = y_start + 0.3 str_spflags = mg_specific_flags(current_mg, y) if str_spflags ~= "" then - label_spflags = "label[0,"..y_start..";" .. fgettext("Mapgen-specific flags") .. "]" + label_spflags = "label[0,"..y_start..";" .. fgettext("Mapgen-specific flags") .. ":]" end -- Warning if only devtest is installed @@ -343,16 +343,16 @@ local function create_world_formspec(dialogdata) "container[0,0]".. "field[0.3,0.6;6,0.5;te_world_name;" .. fgettext("World name") .. - ";" .. core.formspec_escape(worldname) .. "]" .. + ":;" .. core.formspec_escape(worldname) .. "]" .. "field[0.3,1.7;6,0.5;te_seed;" .. fgettext("Seed") .. - ";".. current_seed .. "]" .. + ":;".. current_seed .. "]" .. - "label[0,2;" .. fgettext("Mapgen") .. "]".. + "label[0,2;" .. fgettext("Mapgen") .. ":]".. "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" .. - "label[0,3.35;" .. fgettext("Game") .. "]".. + "label[0,3.35;" .. fgettext("Game") .. ":]".. "textlist[0,3.85;5.8,"..gamelist_height..";games;" .. pkgmgr.gamelist() .. ";" .. _gameidx .. ";false]" .. "container[0,4.5]" .. @@ -402,7 +402,9 @@ local function create_world_buttonhandler(this, fields) worldname = "World " .. worldnum_max + 1 end - core.settings:set("fixed_map_seed", fields["te_seed"]) + if fields["te_seed"] then + core.settings:set("fixed_map_seed", fields["te_seed"]) + end local message if not menudata.worldlist:uid_exists_raw(worldname) then diff --git a/builtin/mainmenu/dlg_create_world_default.lua b/builtin/mainmenu/dlg_create_world_default.lua index 15ce190b0..0abd82dde 100644 --- a/builtin/mainmenu/dlg_create_world_default.lua +++ b/builtin/mainmenu/dlg_create_world_default.lua @@ -56,11 +56,7 @@ local function create_world_formspec() end mglist = mglist:sub(1, -2) - local retval = - "size[12,5.4,false]" .. - "bgcolor[#0000]" .. - "background9[0,0;0,0;" .. core.formspec_escape(defaulttexturedir .. - "bg_common.png") .. ";true;40]" .. + return "label[1.5,0.9;" .. fgettext("World name") .. ":" .. "]".. "field[4.5,1.2;6,0.5;te_world_name;;]" .. @@ -73,9 +69,6 @@ local function create_world_formspec() "style[world_create_confirm;bgcolor=#00d12b]" .. "button[3.5,4.4;2.5,0.5;world_create_confirm;" .. fgettext("Create") .. "]" .. "button[6,4.4;2.5,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]" - - return retval - end local function create_world_buttonhandler(this, fields) @@ -110,7 +103,9 @@ local function create_world_buttonhandler(this, fields) worldname = "World " .. worldnum_max + 1 end - core.settings:set("fixed_map_seed", fields["te_seed"]) + if fields["te_seed"] then + core.settings:set("fixed_map_seed", fields["te_seed"]) + end local message if not menudata.worldlist:uid_exists_raw(worldname) then @@ -169,7 +164,7 @@ function create_create_world_default_dlg(update_worldlistfilter) local retval = dialog_create("sp_create_world", create_world_formspec, create_world_buttonhandler, - nil) + nil, true) retval.update_worldlist_filter = update_worldlistfilter return retval diff --git a/builtin/mainmenu/dlg_delete_content.lua b/builtin/mainmenu/dlg_delete_content.lua index f1d425787..f583b25ce 100644 --- a/builtin/mainmenu/dlg_delete_content.lua +++ b/builtin/mainmenu/dlg_delete_content.lua @@ -18,13 +18,11 @@ -------------------------------------------------------------------------------- local function delete_content_formspec(dialogdata) + local title = dialogdata.content.title or dialogdata.content.name local retval = - "size[12,5.4,false]" .. - "bgcolor[#0000]" .. - "background9[0,0;0,0;" .. core.formspec_escape(defaulttexturedir .. - "bg_common.png") .. ";true;40]" .. - "label[2,2;" .. - fgettext("Are you sure you want to delete \"$1\"?", dialogdata.content.name) .. "]".. + "image_button[2,1;8,3;" .. core.formspec_escape(defaulttexturedir) .. + "blank.png;;" .. fgettext("Are you sure you want to delete \"$1\"?", title) .. + ";true;false;]" .. "style[dlg_delete_content_confirm;bgcolor=red]" .. "button[3,4.8;3,0.5;dlg_delete_content_confirm;" .. fgettext("Delete") .. "]" .. "button[6,4.8;3,0.5;dlg_delete_content_cancel;" .. fgettext("Cancel") .. "]" @@ -75,7 +73,7 @@ function create_delete_content_dlg(content) local retval = dialog_create("dlg_delete_content", delete_content_formspec, delete_content_buttonhandler, - nil) + nil, true) retval.data.content = content return retval end diff --git a/builtin/mainmenu/dlg_delete_world.lua b/builtin/mainmenu/dlg_delete_world.lua index 652c297bf..b566bc61d 100644 --- a/builtin/mainmenu/dlg_delete_world.lua +++ b/builtin/mainmenu/dlg_delete_world.lua @@ -24,10 +24,6 @@ local function delete_world_formspec(dialogdata) end local retval = - "size[12,5.4,false]" .. - "bgcolor[#0000]" .. - "background9[0,0;0,0;" .. core.formspec_escape(defaulttexturedir .. - "bg_common.png") .. ";true;40]" .. "image_button[2,1;8,3;" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. ";;" .. fgettext("Delete World \"$1\"?", delete_name) .. ";true;false;]" .. @@ -64,7 +60,7 @@ function create_delete_world_dlg(name_to_del, index_to_del, game_to_del) local retval = dialog_create("delete_world", delete_world_formspec, delete_world_buttonhandler, - nil) + nil, true) retval.data.delete_name = name_to_del retval.data.delete_game = game_to_del retval.data.delete_index = index_to_del diff --git a/builtin/mainmenu/dlg_outdated_server.lua b/builtin/mainmenu/dlg_outdated_server.lua new file mode 100644 index 000000000..a82fb9324 --- /dev/null +++ b/builtin/mainmenu/dlg_outdated_server.lua @@ -0,0 +1,70 @@ +--MultiCraft +--Copyright (C) 2022 MultiCraft Development Team +-- +--This program is free software; you can redistribute it and/or modify +--it under the terms of the GNU Lesser General Public License as published by +--the Free Software Foundation; either version 3.0 of the License, or +--(at your option) any later version. +-- +--This program is distributed in the hope that it will be useful, +--but WITHOUT ANY WARRANTY; without even the implied warranty of +--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +--GNU Lesser General Public License for more details. +-- +--You should have received a copy of the GNU Lesser General Public License along +--with this program; if not, write to the Free Software Foundation, Inc., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +local blank = core.formspec_escape(defaulttexturedir .. "blank.png") +local function outdated_server_formspec(this) + return ([[ + style_type[image_button;content_offset=0] + image[4.9,0.3;2.5,2.5;%s] + image_button[1,2.5;10,0.8;%s;;%s;false;false] + image_button[1,3.2;10,0.8;%s;;%s;false;false] + button[2,4.5;4,0.8;cancel;%s] + style[continue;bgcolor=yellow] + button[6,4.5;4,0.8;continue;%s] + ]]):format( + core.formspec_escape(defaulttexturedir .. "attention.png"), + blank, + fgettext("The server you are trying to connect to is outdated!"), + blank, + fgettext("Support for older servers may be removed at any time."), + fgettext("Cancel"), + fgettext("Join anyway") + ) +end + +local function outdated_server_buttonhandler(this, fields) + if fields.cancel then + this:delete() + return true + end + + if fields.continue then + serverlistmgr.add_favorite(this.server) + + gamedata.servername = this.server.name + gamedata.serverdescription = this.server.description + + core.settings:set_bool("auto_connect", false) + core.settings:set("connect_time", os.time()) + core.settings:set("maintab_LAST", "online") + core.settings:set("address", gamedata.address) + core.settings:set("remote_port", gamedata.port) + + core.start() + end +end + + +function create_outdated_server_dlg(server) + local retval = dialog_create("outdated_server_dlg", + outdated_server_formspec, + outdated_server_buttonhandler, + nil, true) + retval.server = server + + return retval +end diff --git a/builtin/mainmenu/dlg_rename_modpack.lua b/builtin/mainmenu/dlg_rename_modpack.lua index 06f821e91..de39abb23 100644 --- a/builtin/mainmenu/dlg_rename_modpack.lua +++ b/builtin/mainmenu/dlg_rename_modpack.lua @@ -19,13 +19,9 @@ local function rename_modpack_formspec(dialogdata) local retval = - "size[12,5.4,false]" .. - "bgcolor[#0000]" .. - "background9[0,0;0,0;" .. core.formspec_escape(defaulttexturedir .. - "bg_common.png") .. ";true;40]" .. "button[3,4.8;3,0.5;dlg_rename_modpack_confirm;".. fgettext("Accept") .. "]" .. - "button[3,4.8;3,0.5;dlg_rename_modpack_cancel;".. + "button[6,4.8;3,0.5;dlg_rename_modpack_cancel;".. fgettext("Cancel") .. "]" local input_y = 2 @@ -70,7 +66,7 @@ function create_rename_modpack_dlg(modpack) local retval = dialog_create("dlg_delete_mod", rename_modpack_formspec, rename_modpack_buttonhandler, - nil) + nil, true) retval.data.mod = modpack return retval end diff --git a/builtin/mainmenu/dlg_settings_advanced.lua b/builtin/mainmenu/dlg_settings_advanced.lua index 509432ee4..a2791c59b 100644 --- a/builtin/mainmenu/dlg_settings_advanced.lua +++ b/builtin/mainmenu/dlg_settings_advanced.lua @@ -952,10 +952,7 @@ local function handle_change_setting_buttons(this, fields) end local function create_settings_formspec(tabview, _, tabdata) - local formspec = "size[12,5.4;false]" .. - "bgcolor[#0000]" .. - "background9[0,0;0,0;" .. core.formspec_escape(defaulttexturedir .. - "bg_common.png") .. ";true;40]" .. + local formspec = "tablecolumns[color;tree;text,width=28;text]" .. "tableoptions[background=#00000000;border=false]" .. "field[0.3,0.1;10.2,1;search_string;;" .. core.formspec_escape(search_string) .. "]" .. @@ -1103,7 +1100,7 @@ function create_adv_settings_dlg() local dlg = dialog_create("settings_advanced", create_settings_formspec, handle_settings_buttons, - nil) + nil, true) return dlg end diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua index 3dda43186..6be81c243 100644 --- a/builtin/mainmenu/init.lua +++ b/builtin/mainmenu/init.lua @@ -38,15 +38,16 @@ dofile(menupath .. DIR_DELIM .. "pkgmgr.lua") dofile(menupath .. DIR_DELIM .. "serverlistmgr.lua") dofile(menupath .. DIR_DELIM .. "textures.lua") +dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua") +dofile(menupath .. DIR_DELIM .. "dlg_contentstore.lua") dofile(menupath .. DIR_DELIM .. "dlg_create_world.lua") dofile(menupath .. DIR_DELIM .. "dlg_create_world_default.lua") +dofile(menupath .. DIR_DELIM .. "dlg_delete_content.lua") dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua") +dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua") +dofile(menupath .. DIR_DELIM .. "dlg_outdated_server.lua") if not mobile then - dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua") - dofile(menupath .. DIR_DELIM .. "dlg_delete_content.lua") - dofile(menupath .. DIR_DELIM .. "dlg_contentstore.lua") - dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua") dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua") end @@ -54,11 +55,11 @@ local tabs = {} if not mobile then tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua") - tabs.content = dofile(menupath .. DIR_DELIM .. "tab_content.lua") else tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings_simple.lua") end +tabs.content = dofile(menupath .. DIR_DELIM .. "tab_content.lua") tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.lua") tabs.local_default_game = dofile(menupath .. DIR_DELIM .. "tab_local_default.lua") tabs.local_game = dofile(menupath .. DIR_DELIM .. "tab_local.lua") @@ -96,7 +97,7 @@ function menudata.init_tabs() menudata.worldlist:set_sortmode("alphabetic") if not core.settings:get("menu_last_game") then - local default_game = core.settings:get("default_game") or "minetest" + local default_game = core.settings:get("default_game") or "default" core.settings:set("menu_last_game", default_game) end @@ -112,21 +113,13 @@ function menudata.init_tabs() end end - for i = 1, #pkgmgr.games do - if pkgmgr.games[i].id ~= "default" then - tv_main:add(tabs.local_game) - break - end - end - + tv_main:add(tabs.local_game) if func then func(tv_main) end tv_main:add(tabs.play_online) - if not mobile then - tv_main:add(tabs.content) - end + tv_main:add(tabs.content) tv_main:add(tabs.settings) tv_main:add(tabs.credits) @@ -139,7 +132,8 @@ function menudata.init_tabs() tv_main:set_tab(last_tab) end - if last_tab ~= "local" and not core.settings:get_bool("menu_clouds") then + if last_tab ~= "local" then + core.set_clouds(false) mm_texture.set_dirt_bg() end @@ -155,8 +149,6 @@ function menudata.init_tabs() ui.set_default("maintab") tv_main:show() - core.set_clouds(core.settings:get_bool("menu_clouds")) - ui.update() end diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua index f043dc75b..912375255 100644 --- a/builtin/mainmenu/pkgmgr.lua +++ b/builtin/mainmenu/pkgmgr.lua @@ -919,8 +919,8 @@ function pkgmgr.gamelist() local retval = "" if #pkgmgr.games > 0 then for i = 1, #pkgmgr.games do - if retval ~= "" then retval = retval .. "," end if pkgmgr.games[i].id ~= "default" then + if retval ~= "" then retval = retval .. "," end retval = retval .. core.formspec_escape(pkgmgr.games[i].name) end end diff --git a/builtin/mainmenu/tab_content.lua b/builtin/mainmenu/tab_content.lua index 71da25080..c68251e05 100644 --- a/builtin/mainmenu/tab_content.lua +++ b/builtin/mainmenu/tab_content.lua @@ -96,7 +96,7 @@ local function get_formspec(tabview, name, tabdata) retval = retval .. "image[5.5,0;3,2;" .. core.formspec_escape(modscreenshot) .. "]" .. "label[8.25,0.6;" .. core.formspec_escape(selected_pkg.name) .. "]" .. - "box[5.5,2.2;6.15,2.35;#000]" + "box[5.5,2.2;6.2,2.4;#000]" if selected_pkg.type == "mod" then if selected_pkg.is_modpack then @@ -209,7 +209,7 @@ end -------------------------------------------------------------------------------- return { name = "content", - caption = fgettext("Content"), + caption = "", -- fgettext("Content"), cbf_formspec = get_formspec, cbf_button_handler = handle_buttons, on_change = pkgmgr.update_gamelist diff --git a/builtin/mainmenu/tab_local.lua b/builtin/mainmenu/tab_local.lua index 866e00db7..88b40e689 100644 --- a/builtin/mainmenu/tab_local.lua +++ b/builtin/mainmenu/tab_local.lua @@ -17,9 +17,9 @@ local lang = core.settings:get("language") if not lang or lang == "" then lang = os.getenv("LANG") end -local mobile = PLATFORM == "Android" or PLATFORM == "iOS" local esc = core.formspec_escape +local defaulttexturedir = esc(defaulttexturedir) local function current_game() local last_game_id = core.settings:get("menu_last_game") @@ -36,14 +36,14 @@ local function singleplayer_refresh_gamebar() end local function game_buttonbar_button_handler(fields) - if fields.game_open_cdb then + --[[if fields.game_open_cdb then local maintab = ui.find_by_name("maintab") local dlg = create_store_dlg("game") dlg:set_parent(maintab) maintab:hide() dlg:show() return true - end + end]] for key, value in pairs(fields) do for j=1, #pkgmgr.games do @@ -71,7 +71,7 @@ local function singleplayer_refresh_gamebar() local btnbar = buttonbar_create("game_button_bar", game_buttonbar_button_handler, - {x=-1.35, y=-0.32}, "vertical", {x=1, y=6.14}) + {x=-0.35, y=-0.32}, "vertical", {x=1, y=6.14}) for i=1, #pkgmgr.games do if pkgmgr.games[i].id ~= "default" then @@ -100,29 +100,11 @@ local function singleplayer_refresh_gamebar() end end - if not mobile then - local plus_image = esc(defaulttexturedir .. "plus.png") - btnbar:add_button("game_open_cdb", "", plus_image, fgettext("Install games from ContentDB")) - end -end - -local function filter_default() - local gameid = core.settings:get("menu_last_game") - if not gameid or gameid == "" or gameid == "default" then - for j=1, #pkgmgr.games do - local name = pkgmgr.games[j].id - if name and name ~= "default" then - menudata.worldlist:set_filtercriteria(name) - core.settings:set("menu_last_game", name) - mm_texture.update("singleplayer", current_game()) - return - end - end - end + local plus_image = defaulttexturedir .. "plus.png" + btnbar:add_button("game_open_cdb", "", plus_image, fgettext("Install games from ContentDB")) end local function get_formspec() - filter_default() local index = filterlist.get_current_index(menudata.worldlist, tonumber(core.settings:get("mainmenu_last_selected_world"))) @@ -138,52 +120,58 @@ local function get_formspec() end local retval = - "style[world_delete;fgimg=" .. esc(defaulttexturedir .. "world_delete.png") .. - ";fgimg_hovered=" .. esc(defaulttexturedir .. "world_delete_hover.png") .. "]" .. + "style[world_delete;fgimg=" .. defaulttexturedir .. + "world_delete.png;fgimg_hovered=" .. defaulttexturedir .. "world_delete_hover.png]" .. "image_button[-0.1,4.84;3.45,0.92;;world_delete;;true;false]" .. "tooltip[world_delete;".. fgettext("Delete") .. "]" .. - "style[world_create;fgimg=" .. esc(defaulttexturedir .. "world_new.png") .. - ";fgimg_hovered=" .. esc(defaulttexturedir .. "world_new_hover.png") .. "]" .. + "style[world_create;fgimg=" .. defaulttexturedir .. + "world_new.png;fgimg_hovered=" .. defaulttexturedir .. "world_new_hover.png]" .. "image_button[3.15,4.84;3.45,0.92;;world_create;;true;false]" .. "tooltip[world_create;".. fgettext("New") .. "]" .. - "button[9.5,4.8;2.5,1;world_configure;".. fgettext("Configure") .. "]" .. - - "style[play;fgimg=" .. esc(defaulttexturedir .. "btn_play.png") .. - ";fgimg_hovered=" .. esc(defaulttexturedir .. "btn_play_hover.png") .. "]" .. + "style[play;fgimg=" .. defaulttexturedir .. "btn_play.png;fgimg_hovered=" .. + defaulttexturedir .. "btn_play_hover.png]" .. "image_button[6.72,1.43;4.96,1.41;;play;;true;false]" .. "tooltip[play;".. fgettext("Play Game") .. "]" .. - "image_button[7.2,3.09;4,0.83;" .. - esc(defaulttexturedir) .. creative_bg .. ";;;true;false]" .. + "image_button[7.2,3.09;4,0.83;" .. defaulttexturedir .. creative_bg .. ";;;true;false]" .. "style[cb_creative_mode;content_offset=0]" .. - "image_button[7.2,3.09;4,0.83;" .. - esc(defaulttexturedir) .. creative_checkbox .. ";cb_creative_mode;;true;false]" .. + "image_button[7.2,3.09;4,0.83;" .. defaulttexturedir .. creative_checkbox .. + ";cb_creative_mode;;true;false]" .. - "background9[0,0;6.5,4.8;" .. - esc(defaulttexturedir) .. "worldlist_bg.png" .. ";false;40]" .. + "background9[0,0;6.5,4.8;" .. defaulttexturedir .. "worldlist_bg.png" .. ";false;40]" .. "tableoptions[background=#0000;border=false]" .. - "table[0,0;6.28,4.64;sp_worlds;" .. - menu_render_worldlist() .. ";" .. index .. "]" + "table[0,0;6.28,4.64;sp_worlds;" .. menu_render_worldlist() .. ";" .. index .. "]" .. - if not mobile then + "style[switch_local_default;fgimg=" .. defaulttexturedir .. "switch_local_default.png;fgimg_hovered=" .. + defaulttexturedir .. "switch_local_default_hover.png]" .. + "image_button[10.6,-0.1;1.5,1.5;;switch_local_default;;true;false]" + + if PLATFORM ~= "Android" and PLATFORM ~= "iOS" then retval = retval .. - "checkbox[6.6,5;cb_server;".. fgettext("Create Server") ..";" .. - dump(core.settings:get_bool("enable_server")) .. "]" + "image_button[9.33,4.84;2.67,0.87;" .. defaulttexturedir .. + "select_btn.png;world_configure;".. fgettext("Select Mods") .. ";false;false]" end - if core.settings:get_bool("enable_server") then + local enable_server = core.settings:get_bool("enable_server") + if enable_server then retval = retval .. - "checkbox[6.6,0.65;cb_server_announce;" .. fgettext("Announce Server") .. ";" .. - dump(core.settings:get_bool("server_announce")) .. "]" .. + "checkbox[6.6,5;cb_server;".. fgettext("Create Server") ..";" .. + dump(enable_server) .. "]" + end - -- Name / Password - "label[6.6,-0.3;" .. fgettext("Name") .. ":" .. "]" .. - "label[9.3,-0.3;" .. fgettext("Password") .. ":" .. "]" .. - "field[6.9,0.6;2.8,0.5;te_playername;;" .. - esc(core.settings:get("name")) .. "]" .. - "pwdfield[9.6,0.6;2.8,0.5;te_passwd;]" + if enable_server then + if core.settings:get_bool("server_announce") then + retval = retval .. + "checkbox[9.3,5;cb_server_announce;" .. fgettext("Announce Server") .. ";true]" + end + + retval = retval .. + -- Name / Password + "field[6.9,4.6;2.8,0.5;te_playername;" .. fgettext("Name") .. ":;" .. + esc(core.settings:get("name")) .. "]" .. + "pwdfield[9.6,4.6;2.8,0.5;te_passwd;" .. fgettext("Password") .. ":]" end return retval @@ -324,18 +312,48 @@ local function main_button_handler(this, fields, name) return true end + + if fields["switch_local_default"] then + core.settings:set("menu_last_game", "default") + this:set_tab("local_default") + + return true + end + + if fields["game_open_cdb"] then + this:set_tab("content") + + return true + end end local function on_change(type, old_tab, new_tab) if (type == "ENTER") then + local gameid = core.settings:get("menu_last_game") + if not gameid or gameid == "" or gameid == "default" then + local game_set + for _, game in ipairs(pkgmgr.games) do + local name = game.id + if name and name ~= "default" then + core.settings:set("menu_last_game", name) + game_set = true + break + end + end + if not game_set then + menudata.worldlist:set_filtercriteria("empty") + end + end + local game = current_game() if game then menudata.worldlist:set_filtercriteria(game.id) - core.set_topleft_text("Powered by Minetest Engine") mm_texture.update("singleplayer",game) end + core.set_topleft_text("Powered by Minetest Engine") + singleplayer_refresh_gamebar() ui.find_by_name("game_button_bar"):show() else @@ -352,7 +370,8 @@ end -------------------------------------------------------------------------------- return { name = "local", - caption = fgettext("Other games"), + caption = fgettext("Singleplayer"), + hidden = true, cbf_formspec = get_formspec, cbf_button_handler = main_button_handler, on_change = on_change diff --git a/builtin/mainmenu/tab_local_default.lua b/builtin/mainmenu/tab_local_default.lua index 9ee408333..4fdd11be9 100644 --- a/builtin/mainmenu/tab_local_default.lua +++ b/builtin/mainmenu/tab_local_default.lua @@ -17,9 +17,9 @@ local lang = core.settings:get("language") if not lang or lang == "" then lang = os.getenv("LANG") end -local mobile = PLATFORM == "Android" or PLATFORM == "iOS" local esc = core.formspec_escape +local defaulttexturedir = esc(defaulttexturedir) local default_worlds = { {name = "World 1", mg_name = "v7p", seed = "15823438331521897617"}, @@ -60,10 +60,7 @@ local function create_default_worlds() end local checked_worlds = false -local function get_formspec() - mm_texture.set_dirt_bg() - menudata.worldlist:set_filtercriteria("default") - +local function get_formspec(this) -- Only check the worlds once (on restart) if not checked_worlds and #menudata.worldlist:get_list() == 0 then create_default_worlds() @@ -90,57 +87,62 @@ local function get_formspec() end local retval = - "style[world_delete;fgimg=" .. esc(defaulttexturedir .. "world_delete.png") .. - ";fgimg_hovered=" .. esc(defaulttexturedir .. "world_delete_hover.png") .. "]" .. + "style[world_delete;fgimg=" .. defaulttexturedir .. + "world_delete.png;fgimg_hovered=" .. defaulttexturedir .. "world_delete_hover.png]" .. "image_button[-0.1,4.84;3.45,0.92;;world_delete;;true;false]" .. "tooltip[world_delete;".. fgettext("Delete") .. "]" .. - "style[world_create;fgimg=" .. esc(defaulttexturedir .. "world_new.png") .. - ";fgimg_hovered=" .. esc(defaulttexturedir .. "world_new_hover.png") .. "]" .. + "style[world_create;fgimg=" .. defaulttexturedir .. + "world_new.png;fgimg_hovered=" .. defaulttexturedir .. "world_new_hover.png]" .. "image_button[3.15,4.84;3.45,0.92;;world_create;;true;false]" .. "tooltip[world_create;".. fgettext("New") .. "]" .. - "style[play;fgimg=" .. esc(defaulttexturedir .. "btn_play.png") .. - ";fgimg_hovered=" .. esc(defaulttexturedir .. "btn_play_hover.png") .. "]" .. + "style[play;fgimg=" .. defaulttexturedir .. "btn_play.png;fgimg_hovered=" .. + defaulttexturedir .. "btn_play_hover.png]" .. "image_button[6.72,1.43;4.96,1.41;;play;;true;false]" .. "tooltip[play;".. fgettext("Play Game") .. "]" .. - "image_button[7.2,3.09;4,0.83;" .. - esc(defaulttexturedir) .. creative_bg .. ";;;true;false]" .. + "image_button[7.2,3.09;4,0.83;" .. defaulttexturedir .. creative_bg .. ";;;true;false]" .. "style[cb_creative_mode;content_offset=0]" .. - "image_button[7.2,3.09;4,0.83;" .. - esc(defaulttexturedir) .. creative_checkbox .. ";cb_creative_mode;;true;false]" .. + "image_button[7.2,3.09;4,0.83;" .. defaulttexturedir .. creative_checkbox .. + ";cb_creative_mode;;true;false]" .. - "background9[0,0;6.5,4.8;" .. - esc(defaulttexturedir) .. "worldlist_bg.png" .. ";false;40]" .. + "background9[0,0;6.5,4.8;" .. defaulttexturedir .. "worldlist_bg.png" .. ";false;40]" .. "tableoptions[background=#0000;border=false]" .. - "table[0,0;6.28,4.64;sp_worlds;" .. - menu_render_worldlist() .. ";" .. index .. "]" + "table[0,0;6.28,4.64;sp_worlds;" .. menu_render_worldlist() .. ";" .. index .. "]" if PLATFORM == "Android" then retval = retval .. - "image_button[10.6,-0.1;1.5,1.5;" .. - esc(defaulttexturedir) .. "gift_btn.png;upgrade;;true;false;" .. - esc(defaulttexturedir) .. "gift_btn_pressed.png]" + "image_button[6.6,-0.1;1.5,1.5;" .. + defaulttexturedir .. "gift_btn.png;upgrade;;true;false;" .. + defaulttexturedir .. "gift_btn_pressed.png]" end - if not mobile then + if PLATFORM ~= "Android" and PLATFORM ~= "iOS" then retval = retval .. - "checkbox[6.6,5;cb_server;".. fgettext("Create Server") ..";" .. - dump(core.settings:get_bool("enable_server")) .. "]" + "style[switch_local;fgimg=" .. defaulttexturedir .. "switch_local.png;fgimg_hovered=" .. + defaulttexturedir .. "switch_local_hover.png]" .. + "image_button[10.6,-0.1;1.5,1.5;;switch_local;;true;false]" end - if core.settings:get_bool("enable_server") then + local enable_server = core.settings:get_bool("enable_server") + if enable_server then retval = retval .. - "checkbox[6.6,0.65;cb_server_announce;" .. fgettext("Announce Server") .. ";" .. - dump(core.settings:get_bool("server_announce")) .. "]" .. + "checkbox[6.6,5;cb_server;".. fgettext("Create Server") ..";" .. + dump(enable_server) .. "]" + end - -- Name / Password - "label[6.6,-0.3;" .. fgettext("Name") .. ":" .. "]" .. - "label[9.3,-0.3;" .. fgettext("Password") .. ":" .. "]" .. - "field[6.9,0.6;2.8,0.5;te_playername;;" .. - esc(core.settings:get("name")) .. "]" .. - "pwdfield[9.6,0.6;2.8,0.5;te_passwd;]" + if enable_server then + if core.settings:get_bool("server_announce") then + retval = retval .. + "checkbox[9.3,5;cb_server_announce;" .. fgettext("Announce Server") .. ";true]" + end + + retval = retval .. + -- Name / Password + "field[6.9,4.6;2.8,0.5;te_playername;" .. fgettext("Name") .. ":;" .. + esc(core.settings:get("name")) .. "]" .. + "pwdfield[9.6,4.6;2.8,0.5;te_passwd;" .. fgettext("Password") .. ":]" end return retval @@ -266,6 +268,11 @@ local function main_button_handler(this, fields, name) return true end + if fields["switch_local"] then + this:set_tab("local") + return true + end + if fields["upgrade"] then core.upgrade("") end @@ -288,10 +295,27 @@ local function main_button_handler(this, fields, name) end]] end +local function on_change(type, _, _, this) + if (type == "ENTER") then + local gameid = core.settings:get("menu_last_game") + + local game = pkgmgr.find_by_gameid(gameid) + if game then + if gameid ~= "default" then + this:set_tab("local") + else + mm_texture.update("singleplayer",game) + menudata.worldlist:set_filtercriteria("default") + end + end + end +end + -------------------------------------------------------------------------------- return { name = "local_default", caption = fgettext("Singleplayer"), cbf_formspec = get_formspec, - cbf_button_handler = main_button_handler + cbf_button_handler = main_button_handler, + on_change = on_change } diff --git a/builtin/mainmenu/tab_online.lua b/builtin/mainmenu/tab_online.lua index 5bd4d4d99..9ff746396 100644 --- a/builtin/mainmenu/tab_online.lua +++ b/builtin/mainmenu/tab_online.lua @@ -20,6 +20,7 @@ local password_save = core.settings:get_bool("password_save") local password_tmp = "" local esc = core.formspec_escape +local defaulttexturedir = esc(defaulttexturedir) local lower = utf8.lower local mobile = PLATFORM == "Android" or PLATFORM == "iOS" @@ -42,20 +43,20 @@ local function get_formspec(tabview, name, tabdata) if mobile then search_panel = "field[0.2,0.1;5.1,1;Dte_search;;" .. esc(tabdata.search_for) .. "]" .. - "image_button[4.87,-0.13;0.83,0.83;" .. esc(defaulttexturedir .. "search.png") .. - ";btn_mp_search;;true;false]" .. - "image_button[5.62,-0.13;0.83,0.83;" .. esc(defaulttexturedir .. "refresh.png") .. - ";btn_mp_refresh;;true;false]" .. - "image_button[6.37,-0.13;0.83,0.83;" .. esc(defaulttexturedir .. - (serverlistmgr.mobile_only and "online_mobile" or "online_pc") .. ".png") .. + "image_button[4.87,-0.13;0.83,0.83;" .. defaulttexturedir .. + "search.png;btn_mp_search;;true;false]" .. + "image_button[5.62,-0.13;0.83,0.83;" .. defaulttexturedir .. + "refresh.png;btn_mp_refresh;;true;false]" .. + "image_button[6.37,-0.13;0.83,0.83;" .. defaulttexturedir .. + (serverlistmgr.mobile_only and "online_mobile" or "online_pc") .. ".png" .. ";btn_mp_mobile;;true;false]" else search_panel = "field[0.2,0.1;5.8,1;Dte_search;;" .. esc(tabdata.search_for) .. "]" .. - "image_button[5.62,-0.13;0.83,0.83;" .. esc(defaulttexturedir .. "search.png") .. - ";btn_mp_search;;true;false]" .. - "image_button[6.37,-0.13;0.83,0.83;" .. esc(defaulttexturedir .. "refresh.png") .. - ";btn_mp_refresh;;true;false]" + "image_button[5.62,-0.13;0.83,0.83;" .. defaulttexturedir .. + "search.png;btn_mp_search;;true;false]" .. + "image_button[6.37,-0.13;0.83,0.83;" .. defaulttexturedir .. + "refresh.png;btn_mp_refresh;;true;false]" end local retval = @@ -76,8 +77,8 @@ local function get_formspec(tabview, name, tabdata) "box[7.1,2.1;4.8,2.65;#33314B99]" .. -- Connect - "style[btn_mp_connect;fgimg=" .. esc(defaulttexturedir .. "btn_play.png") .. - ";fgimg_hovered=" .. esc(defaulttexturedir .. "btn_play_hover.png") .. "]" .. + "style[btn_mp_connect;fgimg=" .. defaulttexturedir .. + "btn_play.png;fgimg_hovered=" .. defaulttexturedir .. "btn_play_hover.png]" .. "image_button[8.8,4.88;3.3,0.9;;btn_mp_connect;;true;false]" .. "tooltip[btn_mp_connect;".. fgettext("Connect") .. "]" @@ -88,8 +89,10 @@ local function get_formspec(tabview, name, tabdata) if tabdata.selected and selected then if gamedata.fav then - retval = retval .. "image_button[7.1,4.91;0.83,0.83;" .. - esc(defaulttexturedir .. "trash.png") .. ";btn_delete_favorite;;true;false]" + retval = retval .. + "style[btn_delete_favorite;fgimg=" .. defaulttexturedir .. + "trash.png;fgimg_hovered=" .. defaulttexturedir .. "trash_hover.png]" .. + "image_button[7.1,4.91;0.83,0.83;;btn_delete_favorite;;true;false]" end if selected.description then retval = retval .. "textarea[7.5,2.2;4.8,3;;" .. @@ -100,7 +103,7 @@ local function get_formspec(tabview, name, tabdata) --favorites retval = retval .. "background9[-0.07,0.7;7.19,5.08;" .. - esc(defaulttexturedir) .. "worldlist_bg.png" .. ";false;40]" .. + defaulttexturedir .. "worldlist_bg.png" .. ";false;40]" .. "tableoptions[background=#0000;border=false]" .. "tablecolumns[" .. image_column(fgettext("Favorite")) .. ",align=center;" .. @@ -162,6 +165,17 @@ local function get_formspec(tabview, name, tabdata) return retval end +local function is_favorite(server) + local favs = serverlistmgr.get_favorites() + for fav_id = 1, #favs do + if server.address == favs[fav_id].address and + server.port == favs[fav_id].port then + return true + end + end + return false +end + -------------------------------------------------------------------------------- local function main_button_handler(tabview, fields, name, tabdata) local serverlist = menudata.search_result or serverlistmgr.servers @@ -343,9 +357,11 @@ local function main_button_handler(tabview, fields, name, tabdata) end) menudata.search_result = search_result local first_server = search_result[1] - core.settings:set("address", first_server.address) - core.settings:set("remote_port", first_server.port) - gamedata.serverdescription = first_server.description + if first_server.address and first_server.port then + core.settings:set("address", first_server.address) + core.settings:set("remote_port", first_server.port) + gamedata.serverdescription = first_server.description + end end return true end @@ -363,16 +379,21 @@ local function main_button_handler(tabview, fields, name, tabdata) if fav_idx and fav_idx <= #serverlist and fav.address == gamedata.address and fav.port == gamedata.port then + if not is_server_protocol_compat_or_error( + fav.proto_min, fav.proto_max) then + return true + elseif fav.proto_max and fav.proto_max < 37 and not is_favorite(fav) then + local dlg = create_outdated_server_dlg(fav) + dlg:set_parent(tabview) + tabview:hide() + dlg:show() + return true + end serverlistmgr.add_favorite(fav) gamedata.servername = fav.name gamedata.serverdescription = fav.description - - if not is_server_protocol_compat_or_error( - fav.proto_min, fav.proto_max) then - return true - end else gamedata.servername = "" gamedata.serverdescription = "" diff --git a/builtin/mainmenu/textures.lua b/builtin/mainmenu/textures.lua index c93d8817e..b2e613238 100644 --- a/builtin/mainmenu/textures.lua +++ b/builtin/mainmenu/textures.lua @@ -61,11 +61,11 @@ function mm_texture.reset() mm_texture.set_generic("header") if not have_bg then - if core.settings:get_bool("menu_clouds") then - core.set_clouds(true) - else + -- if core.settings:get_bool("menu_clouds") then + -- core.set_clouds(true) + -- else mm_texture.set_dirt_bg() - end + -- end end end @@ -87,7 +87,7 @@ function mm_texture.update_game(gamedetails) core.set_clouds(false) if not have_bg then - if core.settings:get_bool("menu_clouds") then + if core.settings:get_bool("menu_clouds") and gamedetails.id ~= "default" then core.set_clouds(true) else mm_texture.set_dirt_bg() diff --git a/src/client/client.cpp b/src/client/client.cpp index b7f0a8ac2..264a9f276 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1762,7 +1762,7 @@ void texture_update_progress(void *args, u32 progress, u32 max_progress) std::basic_stringstream strm; strm << targs->text_base << " " << targs->last_percent << "%..."; RenderingEngine::draw_load_screen(strm.str(), targs->guienv, targs->tsrc, 0, - 72 + (u16) ((18. / 100.) * (double) targs->last_percent), true); + 72 + (u16) ((18. / 100.) * (double) targs->last_percent)); } } diff --git a/src/client/game.cpp b/src/client/game.cpp index ac557aebb..98cea3b64 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -799,7 +799,7 @@ protected: void limitFps(FpsControl *fps_timings, f32 *dtime); void showOverlayMessage(const char *msg, float dtime, int percent, - bool draw_clouds = true); + bool draw_clouds = false); static void settingChangedCallback(const std::string &setting_name, void *data); void readSettings(); diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h index d644c328a..b527ea74a 100644 --- a/src/client/renderingengine.h +++ b/src/client/renderingengine.h @@ -104,7 +104,7 @@ public: inline static void draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv, ITextureSource *tsrc, - float dtime = 0, int percent = 0, bool clouds = true) + float dtime = 0, int percent = 0, bool clouds = false) { s_singleton->_draw_load_screen( text, guienv, tsrc, dtime, percent, clouds); @@ -142,7 +142,7 @@ public: private: void _draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime = 0, int percent = 0, - bool clouds = true); + bool clouds = false); void _draw_menu_scene(gui::IGUIEnvironment *guienv, float dtime = 0, bool clouds = true); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index eeea5d4c6..1e93a8df4 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -220,7 +220,7 @@ void set_default_settings() settings->setDefault("fall_bobbing_amount", "1.0"); settings->setDefault("enable_3d_clouds", "true"); settings->setDefault("cloud_radius", "12"); - settings->setDefault("menu_clouds", "false"); + settings->setDefault("menu_clouds", "true"); settings->setDefault("opaque_water", "false"); settings->setDefault("console_height", "0.6"); settings->setDefault("console_color", "(0,0,0)"); @@ -363,7 +363,7 @@ void set_default_settings() settings->setDefault("chat_font_size", "0"); // Default "font_size" // ContentDB - settings->setDefault("contentdb_url", "https://content.minetest.net"); + settings->setDefault("contentdb_url", "https://content.multicraft.world"); settings->setDefault("contentdb_max_concurrent_downloads", "3"); #ifdef __ANDROID__ diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index 6a0f24ec7..5f4889d40 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -515,19 +515,28 @@ void GUIEngine::drawHeader(video::IVideoDriver *driver) v2s32 splashsize(((f32)texture->getOriginalSize().Width) * mult, ((f32)texture->getOriginalSize().Height) * mult); +#if !defined(__ANDROID__) && !defined(__IOS__) // Don't draw the header if there isn't enough room s32 free_space = (((s32)screensize.Height)-320)/2; - if (free_space > splashsize.Y) { - core::rect splashrect(0, 0, splashsize.X, splashsize.Y); - splashrect += v2s32((screensize.Width/2)-(splashsize.X/2), - ((free_space/2)-splashsize.Y/2)); + if (free_space <= splashsize.Y) + return; + + core::rect splashrect(0, 0, splashsize.X, splashsize.Y); + splashrect += v2s32((screensize.Width/2)-(splashsize.X/2), + ((free_space/2)-splashsize.Y/2)); +#else + core::rect splashrect(0, 0, splashsize.X, splashsize.Y); + splashrect += v2s32((screensize.Width/2)-(splashsize.X/2), 0); + + if (g_settings->getBool("device_is_tablet")) + splashrect += v2s32(0, splashsize.Y/4); +#endif draw2DImageFilterScaled(driver, texture, splashrect, core::rect(core::position2d(0,0), core::dimension2di(texture->getOriginalSize())), NULL, NULL, true); - } } /******************************************************************************/ @@ -630,7 +639,7 @@ void GUIEngine::updateTopLeftTextSize() { core::rect rect(0, 0, g_fontengine->getTextWidth(m_toplefttext.c_str()), g_fontengine->getTextHeight()); - rect += v2s32(4, 0); + rect += v2s32(5 + g_settings->getU16("round_screen"), 0); m_irr_toplefttext->remove(); m_irr_toplefttext = gui::StaticText::add(RenderingEngine::get_gui_env(), diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 3a348c232..5b3417fcf 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -3299,7 +3299,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) #if defined(__ANDROID__) || defined(__IOS__) v2f padded_screensize( - mydata.screensize.X * 0.9f, + mydata.screensize.X, mydata.screensize.Y ); #else diff --git a/textures/base/pack/attention.png b/textures/base/pack/attention.png new file mode 100644 index 0000000000000000000000000000000000000000..e204d93b575d60987a0778e154e7b42a1147f4af GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyiUB?$u3s-J=qoZG>J@l*Nb~M-r07HD=X(I~Zj|7Rcsrdyvym-qBDd&bvb-W4}wn zTQ&}He}__L6|sd4d|nHFU1WOA>ZI|(f#bxy1knk3+83LR8@^QETix)TWwK9#(gBMg wpL1^xJAN^`$UDQ}K)Croy^`B@=jt2ut-_>EXa4)p33L&Ir>mdKI;Vst05$$-B>(^b literal 0 HcmV?d00001 diff --git a/textures/base/pack/select_btn.png b/textures/base/pack/select_btn.png new file mode 100644 index 0000000000000000000000000000000000000000..90c54f41e1f7b68eb40a761c9a306e1a5e096656 GIT binary patch literal 714 zcmV;*0yX`KP)0i0000UP)t-s00030 z|Nkd5S0^%7C^J_lGgek)msVt$S7n%2WSFJfRn`Ci00DGTPE!Ct=GbNc00LS`L_t(| z+U1(Tj(zco)0y=LNP||Dvrv9D=wtpi)*_%d+Gpcc0D!=t=B$_dzzX8~(Du zHp`aYsShYi0t#^nu)JcJGcq?UlwL~6xA+04^G+A|wahzQb(p|X)d+A&mW zGIDYQ1O{_?@GHPTX>bFWLAqn8WFSC!ZUe{w*6blzHTM+ zDp=iv_W%Ykc@YAF)f&7ARgju}98UD?vjCtq`Yb?rYy<3KBu7613_u!v7U1Mn*ud~1 zNCYwYQj`d?J$eyB*`rtC#NcajWksendI$n@8(@K>XMmfW{R9{cPF{so2&O0B2UOJP zO)zJ#!b?CPHTiEaqo(fxl|6VBW(KeZ-w9&&DlCJ+8vU6Zg4vUYAOi4;p;}Ewp*{Lm zILn&-iA>6~XTa#M#fd0PJ_{rw0z+Hi22TT=xd}+XX%wt^gV2`2(?m&943i`gaS0$L zx7U(w%UW*P(i1$1C0PgF#BTV*0{g53zti@wNM!s9OtgC~Nw%(B`*5D%NiN@NZ(=w6 zVS#;?wWD_TRijA6T>uk>B#LAb1QK`vzL3kv%uVcuKP<4%La{a!#9<}kuLzQ?B#8X~ w7Z1QEAx07*qoM6N<$g3(nniU0rr literal 0 HcmV?d00001 diff --git a/textures/base/pack/switch_local.png b/textures/base/pack/switch_local.png new file mode 100644 index 0000000000000000000000000000000000000000..5c41dfa916789bf80bef3b40c7836510bd98143a GIT binary patch literal 1125 zcmV-r1e*JaP)4B$O82n<>+9?P@hp&~ z=C0ZQvBBnK!| zGi$w|prA}lOtz(^9Xx8+&CTVB0LOO#W|Y>g+5f_gjSghJm8$66IAZw#0004WQchC< zK<3zH000AkNklh@WP?D23oY^k*((p93`?>7*BWruuSeENnLSPXyd<4?0JqK%O^Em$)Y&BVfyW%s)QxIYKNJ4W&W^)&THy z5U9QoAK+(GQwg9?S0(`#3*Ijvfan5o)_qM6&;qCntgGrSPW5wo8iW(f7Bl*`z0DSQ zWZ+H-^e`O)Sp5JXx7i0colmC;fZ0p{xlIKgtLhEHTbwiSke*;BK)g)_met)G6U6Ww zz{7IthT|BLH%V_Opw(S#<#%Ujb@5wX1^5^SltF;q*2KKqT;V9OCzCwK7~VAq3mR z;%)YTS_C5Sa0XV$5E3|A{^VG|5$Zlr*9_nikuj^^5ab9Z(EbNU!ilQu1UQ}ajT8a_ zZ3bZjvl{>3Q3*}JKeJrOz&0l=+Q*3{F7# ze9i!J00)BsjVAJu3JOGv*0N69H z5C7Lw061q53s(S6_c=!ZUOnd50i6p_VlTog-j9KsP!|AOC?NT=`~*q>ZsPF8;V+p2 zB!pDJzVsmgkmLv{5KQO`FC_5(1$!Q{dj-w{D8a_W5977Y1=tC&KZ>AP&UCU|rD6Zy&F-Cn z{r;E;P&90ly#i+z)JRL$yg%REFp%BuHxOdimy+)J-?q({y61Mg-3|55dpg4N=IaIt r?>GPp+4C2BqG*migl~sA`u_TV#C!KJ26`!c00000NkvXXu0mjfWD)>` literal 0 HcmV?d00001 diff --git a/textures/base/pack/switch_local_default.png b/textures/base/pack/switch_local_default.png new file mode 100644 index 0000000000000000000000000000000000000000..bbb00ec71fcb1d5748a314c965b0a2f2e630bec6 GIT binary patch literal 2657 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 P00000NkvXXu0mjfclep@ literal 0 HcmV?d00001 diff --git a/textures/base/pack/switch_local_default_hover.png b/textures/base/pack/switch_local_default_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..0a6abed74483e4068cd97a64703a1ed6a8f1db6f GIT binary patch literal 2661 zcmV-r3YztaP)>yUFm(*7UHy?xnZup0VkdtLROB#^2@mftliQjoSbJ|B|QYL~5d3e9PM5 z_dRO~ zEJ$`PL1HXKgfB&TE<}bgKXooZaxO%2E=6-KKT;}4dM-g^D?({3L~$)ZZ!JlYF;S&7 zHBc%(axO)PFhE)>MszJcWh_2!EtMwc>1axF)JFH4ItHd8A~ zpfjyrJ%UO#HC8K*P&iGgGf0jxiA^;|oHF66TAfun#&$-PQaM3=FF|=PMsF=dUn@(T zGEAW}vSK|oQY)-oJ-TT@zivX?ol=iaH-t?!M2|8?l`=$hEjUsuOQbWnXh67UKh=;; z=CWR;T05F%PmE1AwPruXbw#dTJ*kj%C{qgGrrPIoGRh+@Mr;Ofs2SImEZCt6w`dQ7ddlFq~yOz>`nltX#HeK#^NH zv4cj!bwjL)O3uHtgj6-*saNB?e!qxWmV8aQqh-BxNSs>Xga=;PO@%4ymLa#f=QlTL*b`Z+MH3^ol<^NG>ua?#C1dBuwBuO zO_5YMxp6_*n^DiDYR!vFpm;%$rRJJbIGR>D#-3(}WI4fnMoeqCpjtY;dq%s0N3v%> z)~#QwYd)lOK)jb>+NoO4s9c?2JDF}iqqXZjSC=|feXDUm9m*A|00001bW%=J06^y0 zW&i*O6G=otRCocL%+&$IFcihmxL@KxFWb(kPXTa>aQG#i;Hkt9F- z@Y^unD1Ir068NSBMs>nA3dF#Gov=%UiSPG(N@FP0fvWH8#zfo%2gM#zzu&eZ$*^A$ zl`sOnsQ_QkG6NDl7u=K00s<+5{-34xJrsFJeyJ`#ycPc2+s-`w8aKa2w&_37bx@%UzG z-Os}2xo8dlHClfn&yIVK5`D{JL5Agqu zr>MBNBnhLw-ne-GEbxtH*wh@(olamMFuU&k^UIg~#~9d1{}I|hX*GJAvACFbI0}T) z+vfpg<#a_QMNw7N9D$1Omgw@px4UKu{0V0rKLsPTR z((1s863k-MWa#eR@gL)RjjiUBrpValBs~S~9jQWRW7l~A0^P7o?CH&W?#^~4C#RDM zQ6^KyHC;xA-CmQKXi3D#G$NIy`uYbL5b93@gMMIWn0`Kz<{lm6vGFX!2aQgrF}<(( zgpuZnG|pQ{5BM77!KQNoMFjwY??XQr=K0;6>d~KsnRI?E$}q+LGXMV5p3dFBf0-%& z+b4s6m4hMR?FnFVQWYTpD)iBLm#0!4`EFwpjyZL<_-Q<;ozA=e^8O4xC^yW`A{6RR z1FAX)A%JjR5@sIKREGm2c}I-NYFt?GEH?X_`wT70;w(f*6F3emp=C5VIfxLHq-PAx zQXK{D#^j%0tceSY?JI%gzOM(&0U1q(C-Ckh&<)@!oE#LNB zjpkr-Uy?VWvV1?%pZZV$f&eMqKvtHKuV?VDPY|}YN2?Z$JG*;<#1Ej&K_!&?`!hfp zKxNCyJ&xABCdJbV zeV{#%eav8HW@ctcueUlGQmXp@(*A~r7njUF1>|Wi{Z{Go070!*OToE5V48$ZZ<;PA z)4PXfR;158?aP2o8B=!Hhp;+1iLr-+Npj%Kh+MT|u6+R*C5{=8f&0KtS_JRUCduJ5 z-J_PzwJ~L2dvqS^bU{(b9`-f>AF!tud96Sl)eb)J^=8{zI&u>ctQn2{{p869oky>jpVgNI#Vs{tQB(!3hbjRa70h?c>* z$4{Qpvop_6HJ8EckG2|@YF-Vf&?VXozAvrOi*Kd{snkX`wXZj+bf)LJg z`jpx`tZ&l6h4H@900tMpt?>`fN@BaJ$pgLFJ`&#E^puu1agF!ls zU&{9WPgoEJwr%N_6BPN2_5ir^0eleyl7&)56&m|YJ1uW2VBa*aYt{N_6T2s8?3 zE9N$SGb2zgQlkL5lS~*sx2-O52URtv0i00000NkvXXu0mjfBDLr~ literal 0 HcmV?d00001 diff --git a/textures/base/pack/switch_local_hover.png b/textures/base/pack/switch_local_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..a0b8084b3be7457b9bb9570fb90f03a6722248ab GIT binary patch literal 1118 zcmV-k1flzhP)iE*7QtkxPh7C-{tsWkkzHP>yD)6V`F2mzwSL(m$q(hTztz-e#W@o|H_=4 ztA~fItgOGWv5=+aL~5ek)6+Utedw1V&WIs;qT8dj>n(W32RCr#U*X3>;K@f#eHw?lugPB9`|8}WcwNukWE8Ab>IEr-7mRtFg8|qJ% z?SD{)t<0C}^^!Z+9j;cEWuE8z2O+ZaZns-g5P)b`iF~`AlYj$u=`#621iWV?WXm1z zbMEOW|56a<^ZR!K_Um0UN8?1Au2vy&Pe4Y%8hf69eBf)0sHzpEf&xnco)8Ew83+gb zUL{lyXg*z;K2cTJR}h2<0i6ZkhYtXNLSUKacRJOt$*~h(Fs-Ka$IEM8fHQ!*fI!ca z9)Q&^0HCNgfSUPa(g!e`3c#-!0Ove^W#P4+19T*$0@wT!DcT^fd$EQ08(z2#f*fBMv$} z0Ov~#$Rk>9@HO)gknUh7gBn`5Qst6OuNNBmm?Qk)b6gCm2WjUxjl)Rj;^$0fV*V)0?MZ|09?cX;UjR{$f$4S+Fs0isa=d))>A&c-kK0Jdxwz#hC&;GahTP-Hj= zR{&1;DIy?6p6Azra1Nm0y$C0d^Bh`G1AvV~0QsU&pkN?cMEDJ-Lg)b`xSk;U!aK)+ zgcF7U+}ILcNWlI@_86+r2Mhr$#4VxTUxqah4+9Vaz(6=%?w1zg7}E!MEGZEA;&jrz z2s9r7AUHu3hWW=q`{w@!z)jx4K80&E}T+#GX!gn1A0O;gb)5kUe~} kcM5atS@>}`+RxYj0q5B9M^dnZy#N3J07*qoM6N<$f*@r22><{9 literal 0 HcmV?d00001 diff --git a/textures/base/pack/trash.png b/textures/base/pack/trash.png index 263b5674985a50a7f0913e0f84a4dfec8fc01757..d22ba206f77cfd9f253c241937adc34c8736a630 100644 GIT binary patch delta 302 zcmV+}0nz^G0m%Z8B!4GROjJex|Ns900mQz(ga82J-rihSS2Z&;n30k2?Ck&l|E#5@ zgnWGeg@ve%m*W5c00DGTPE!Ct=GbNc007WQL_t(|Ue(n>4Z|=Dh2c>Mg-{3uQwW7p zFa=Wxg;EHGfLhz#Cyx(Pr`0R4HeOknW<8G!sP7@wREl-O5%;CT2V#RnK-@9YD^++f}30uX3%+q$Bg zK=_Kjy&3?-&nJQsK!i!m2SowyUcLL5_x|;N1ElbhR3#5Mi~s-t07*qoM6N<$f;`KG A>;M1& delta 204 zcmV;-05ku|0_XvdB!3T3OjJex|Nn#l0RI31|AmGB|Nojf&7}YU00DGTPE!Ct=GbNc z004(cL_t(|UhUPv4Zt7>1<O+PaFU3;}a)7_2QE^KK)-B`*BE?RI%#-0000eRyA z+~w(g|zzjJSq2IGt4d)1Yc-8!5W%x#-7bB>!U>xFyW7sNiM2Qpr0w-JzMzxdBn zQ2w>!6oHJrUTfH8PBL`Ga4Q%!>=SZGark|{S(7=KTY&jVe&gMzw;Hxv*Ghj-dhK_g ztwQitv9v)ZTc)RU!v#GB&4ufkvlPDR*L WiN77oSstL@7(8A5T-G@yGywozaf2lQ literal 0 HcmV?d00001