diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index 185ec9f5..c682182b 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -7,6 +7,7 @@ rem_packs = {} function apply() core.reconfig_packs(add_packs, rem_packs) + menu:back() end function refresh_changes() @@ -74,6 +75,7 @@ end function refresh() packs_installed = pack.get_installed() packs_available = pack.get_available() + base_packs = pack.get_base_packs() packs_all = {unpack(packs_installed)} required = {} for i,k in ipairs(packs_available) do @@ -82,14 +84,13 @@ function refresh() local packs_cur = document.packs_cur local packs_add = document.packs_add - packs_cur:clear() packs_add:clear() for i,id in ipairs(packs_installed) do local packinfo = pack.get_info(id) packinfo.index = i - callback = id ~= "base" and string.format('move_pack("%s")', id) or nil + callback = not table.has(base_packs, id) and string.format('move_pack("%s")', id) or nil packinfo.error = check_dependencies(packinfo) place_pack(packs_cur, packinfo, callback) end diff --git a/res/layouts/pages/new_world.xml b/res/layouts/pages/new_world.xml index 9828acda..9042ea57 100644 --- a/res/layouts/pages/new_world.xml +++ b/res/layouts/pages/new_world.xml @@ -10,6 +10,7 @@ + diff --git a/res/layouts/pages/new_world.xml.lua b/res/layouts/pages/new_world.xml.lua index 625ccbba..e92d5ae0 100644 --- a/res/layouts/pages/new_world.xml.lua +++ b/res/layouts/pages/new_world.xml.lua @@ -30,6 +30,9 @@ function create_world() end function on_open() + document.content_btn.text = string.format( + "%s [%s]", gui.str("Content", "menu"), #pack.get_installed() + ) if settings.generator == nil then settings.generator = core.get_default_generator() end diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 422a6edb..2db25fbf 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -263,6 +263,17 @@ function table.remove_value(t, x) end end +function table.tostring(t) + local s = '[' + for i,v in ipairs(t) do + s = s..tostring(v) + if i < #t then + s = s..', ' + end + end + return s..']' +end + -- Deprecated functions block_index = block.index block_name = block.name diff --git a/src/engine.cpp b/src/engine.cpp index 54bb6fce..c05fed2d 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -247,6 +247,13 @@ void Engine::loadContent() { onAssetsLoaded(); } +void Engine::resetContent() { + auto manager = createPacksManager(fs::path()); + manager.scan(); + contentPacks = manager.getAll(basePacks); + loadContent(); +} + void Engine::loadWorldContent(const fs::path& folder) { contentPacks.clear(); auto packNames = ContentPack::worldPacksList(folder); @@ -304,6 +311,10 @@ std::vector& Engine::getContentPacks() { return contentPacks; } +std::vector& Engine::getBasePacks() { + return basePacks; +} + EnginePaths* Engine::getPaths() { return paths; } diff --git a/src/engine.h b/src/engine.h index f99dadf4..47f2c187 100644 --- a/src/engine.h +++ b/src/engine.h @@ -52,6 +52,7 @@ class Engine : public util::ObjectsKeeper { std::queue postRunnables; std::recursive_mutex postRunnablesMutex; std::unique_ptr controller; + std::vector basePacks {"base"}; uint64_t frame = 0; double lastTime = 0.0; @@ -87,6 +88,8 @@ public: /// @brief Load all selected content-packs and reload assets void loadContent(); + + void resetContent(); /// @brief Collect world content-packs and load content /// @see loadContent @@ -120,6 +123,8 @@ public: /// @brief Get selected content packs std::vector& getContentPacks(); + std::vector& getBasePacks(); + /// @brief Get current screen std::shared_ptr getScreen(); diff --git a/src/frontend/screens/MenuScreen.cpp b/src/frontend/screens/MenuScreen.cpp index 1ddc317d..c61cda05 100644 --- a/src/frontend/screens/MenuScreen.cpp +++ b/src/frontend/screens/MenuScreen.cpp @@ -10,9 +10,8 @@ #include "../../engine.h" MenuScreen::MenuScreen(Engine* engine) : Screen(engine) { - engine->getContentPacks().clear(); - engine->loadContent(); - + engine->resetContent(); + auto menu = engine->getGUI()->getMenu(); menu->reset(); menu->setPage("main"); diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index 79670eb1..2df1338a 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -178,7 +178,6 @@ void EngineController::createWorld( EnginePaths* paths = engine->getPaths(); auto folder = paths->getWorldsFolder()/fs::u8path(name); try { - engine->loadAllPacks(); engine->loadContent(); paths->setWorldFolder(folder); } catch (const contentpack_error& error) { @@ -223,7 +222,6 @@ void EngineController::reconfigPacks( std::vector packsToRemove ) { auto content = engine->getContent(); - auto world = controller->getLevel()->getWorld(); bool hasIndices = false; std::stringstream ss; @@ -238,21 +236,33 @@ void EngineController::reconfigPacks( } runnable removeFunc = [=]() { - controller->saveWorld(); - auto manager = engine->createPacksManager(world->wfile->getFolder()); - manager.scan(); + if (controller == nullptr) { + auto manager = engine->createPacksManager(fs::path("")); + manager.scan(); + std::vector names = engine->getBasePacks(); + for (auto& name : packsToAdd) { + names.push_back(name); + } + engine->getContentPacks() = manager.getAll(names); + } else { + auto world = controller->getLevel()->getWorld(); + auto wfile = world->wfile.get(); + controller->saveWorld(); + auto manager = engine->createPacksManager(wfile->getFolder()); + manager.scan(); - auto names = PacksManager::getNames(world->getPacks()); - for (const auto& id : packsToAdd) { - names.push_back(id); + auto names = PacksManager::getNames(world->getPacks()); + for (const auto& id : packsToAdd) { + names.push_back(id); + } + for (const auto& id : packsToRemove) { + manager.exclude(id); + names.erase(std::find(names.begin(), names.end(), id)); + } + wfile->removeIndices(packsToRemove); + wfile->writePacks(manager.getAll(names)); + reopenWorld(world); } - for (const auto& id : packsToRemove) { - manager.exclude(id); - names.erase(std::find(names.begin(), names.end(), id)); - } - world->wfile->removeIndices(packsToRemove); - world->wfile->writePacks(manager.getAll(names)); - reopenWorld(world); }; if (hasIndices) { diff --git a/src/logic/scripting/lua/libpack.cpp b/src/logic/scripting/lua/libpack.cpp index 88418362..efb12c77 100644 --- a/src/logic/scripting/lua/libpack.cpp +++ b/src/logic/scripting/lua/libpack.cpp @@ -30,6 +30,7 @@ static int l_pack_get_folder(lua_State* L) { return 1; } +/// @brief pack.get_installed() -> array static int l_pack_get_installed(lua_State* L) { auto& packs = scripting::engine->getContentPacks(); lua_createtable(L, packs.size(), 0); @@ -40,9 +41,12 @@ static int l_pack_get_installed(lua_State* L) { return 1; } -/// @brief pack.get_available() -> array +/// @brief pack.get_available() -> array static int l_pack_get_available(lua_State* L) { - auto worldFolder = scripting::level->getWorld()->wfile->getFolder(); + fs::path worldFolder(""); + if (scripting::level) { + worldFolder = scripting::level->getWorld()->wfile->getFolder(); + } auto manager = scripting::engine->createPacksManager(worldFolder); manager.scan(); @@ -131,7 +135,10 @@ static int l_pack_get_info(lua_State* L) { }); if (found == packs.end()) { // TODO: optimize - auto worldFolder = scripting::level->getWorld()->wfile->getFolder(); + fs::path worldFolder(""); + if (scripting::level) { + worldFolder = scripting::level->getWorld()->wfile->getFolder(); + } auto manager = scripting::engine->createPacksManager(worldFolder); manager.scan(); auto vec = manager.getAll({packid}); @@ -144,10 +151,21 @@ static int l_pack_get_info(lua_State* L) { return l_pack_get_info(L, pack, content); } +static int l_pack_get_base_packs(lua_State* L) { + auto& packs = scripting::engine->getBasePacks(); + lua_createtable(L, packs.size(), 0); + for (size_t i = 0; i < packs.size(); i++) { + lua_pushstring(L, packs[i].c_str()); + lua_rawseti(L, -2, i + 1); + } + return 1; +} + const luaL_Reg packlib [] = { {"get_folder", lua_wrap_errors}, {"get_installed", lua_wrap_errors}, {"get_available", lua_wrap_errors}, {"get_info", lua_wrap_errors}, + {"get_base_packs", lua_wrap_errors}, {NULL, NULL} };