diff --git a/src/frontend/menu/menu.h b/src/frontend/menu/menu.h index aa9d7ed8..98c6c0e5 100644 --- a/src/frontend/menu/menu.h +++ b/src/frontend/menu/menu.h @@ -53,6 +53,12 @@ namespace menus { std::vector packs ); + void add_pack_to_world( + const ContentPack& pack, + Engine* engine, + LevelController* controller + ); + /// @brief Create development version label at the top-right screen corner void create_version_label(Engine* engine); void create_menus(Engine* engine); diff --git a/src/frontend/menu/menu_pause.cpp b/src/frontend/menu/menu_pause.cpp index c1463a9f..c2165dbe 100644 --- a/src/frontend/menu/menu_pause.cpp +++ b/src/frontend/menu/menu_pause.cpp @@ -164,13 +164,39 @@ void menus::remove_packs( } } +void menus::add_pack_to_world( + const ContentPack& pack, + Engine* engine, + LevelController* controller +) { + auto level = controller->getLevel(); + auto gui = engine->getGUI(); + auto world = level->getWorld(); + auto new_packs = PacksManager::getNames(world->getPacks()); + new_packs.push_back(pack.id); + + auto manager = engine->createPacksManager(world->wfile->getFolder()); + manager.scan(); + try { + new_packs = manager.assembly(new_packs); + } catch (const contentpack_error& err) { + guiutil::alert( + gui, langs::get(L"error.dependency-not-found")+ + L": "+util::str2wstr_utf8(err.getPackId()) + ); + return; + } + world->wfile->writePacks(manager.getAll(new_packs)); + controller->saveWorld(); + reopen_world(engine, world); +} + void create_content_panel(Engine* engine, LevelController* controller) { auto level = controller->getLevel(); auto menu = engine->getGUI()->getMenu(); auto mainPanel = menus::create_page(engine, "content", 550, 0.0f, 5); - auto paths = engine->getPaths(); - PacksManager manager = engine->createPacksManager(paths->getWorldFolder()); + PacksManager manager = engine->createPacksManager(level->getWorld()->wfile->getFolder()); manager.scan(); std::vector scanned = manager.getAll(manager.getAllNames()); @@ -194,24 +220,7 @@ void create_content_panel(Engine* engine, LevelController* controller) { langs::get(L"Add", L"content"), glm::vec4(10.0f), glm::vec4(1), [=](GUI* gui) { auto panel = menus::create_packs_panel(scanned, engine, true, [=](const ContentPack& pack) { - auto world = level->getWorld(); - auto new_packs = PacksManager::getNames(world->getPacks()); - new_packs.push_back(pack.id); - - auto manager = engine->createPacksManager(world->wfile->getFolder()); - manager.scan(); - try { - new_packs = manager.assembly(new_packs); - } catch (const contentpack_error& err) { - guiutil::alert( - gui, langs::get(L"error.dependency-not-found")+ - L": "+util::str2wstr_utf8(err.getPackId()) - ); - return; - } - world->wfile->writePacks(manager.getAll(new_packs)); - controller->saveWorld(); - reopen_world(engine, world); + menus::add_pack_to_world(pack, engine, controller); }, nullptr); menu->addPage("content-packs", panel); menu->setPage("content-packs"); diff --git a/src/logic/scripting/lua/libpack.cpp b/src/logic/scripting/lua/libpack.cpp index f2e2554c..03179b51 100644 --- a/src/logic/scripting/lua/libpack.cpp +++ b/src/logic/scripting/lua/libpack.cpp @@ -3,6 +3,9 @@ #include "../scripting.h" #include "../../../engine.h" #include "../../../files/engine_paths.h" +#include "../../../files/WorldFiles.h" +#include "../../../world/Level.h" +#include "../../../world/World.h" #include #include @@ -35,26 +38,27 @@ static int l_pack_get_installed(lua_State* L) { return 1; } -/// @brief pack.get_info(packid: str) -> { -/// title: str, -/// creator: str, -/// description: str, -/// version: str, -/// [optional] has_indices: bool -/// } or nil -static int l_pack_get_info(lua_State* L) { - auto packid = lua_tostring(L, 1); - - auto content = scripting::engine->getContent(); - auto& packs = scripting::engine->getContentPacks(); - auto found = std::find_if(packs.begin(), packs.end(), [packid](auto& pack) { - return pack.id == packid; - }); - if (found == packs.end()) { - return 0; - } - const auto& pack = *found; +/// @brief pack.get_available() -> array +static int l_pack_get_available(lua_State* L) { + auto worldFolder = scripting::level->getWorld()->wfile->getFolder(); + auto manager = scripting::engine->createPacksManager(worldFolder); + manager.scan(); + auto& installed = scripting::engine->getContentPacks(); + for (auto& pack : installed) { + manager.exclude(pack.id); + } + auto names = manager.getAllNames(); + + lua_createtable(L, names.size(), 0); + for (size_t i = 0; i < names.size(); i++) { + lua_pushstring(L, names[i].c_str()); + lua_rawseti(L, -2, i + 1); + } + return 1; +} + +static int l_pack_get_info(lua_State* L, const ContentPack& pack, const Content* content) { lua_createtable(L, 0, 5); lua_pushstring(L, pack.title.c_str()); @@ -77,9 +81,40 @@ static int l_pack_get_info(lua_State* L) { return 1; } +/// @brief pack.get_info(packid: str) -> { +/// title: str, +/// creator: str, +/// description: str, +/// version: str, +/// [optional] has_indices: bool +/// } or nil +static int l_pack_get_info(lua_State* L) { + auto packid = lua_tostring(L, 1); + + auto content = scripting::engine->getContent(); + auto& packs = scripting::engine->getContentPacks(); + auto found = std::find_if(packs.begin(), packs.end(), [packid](auto& pack) { + return pack.id == packid; + }); + if (found == packs.end()) { + // TODO: optimize + auto worldFolder = scripting::level->getWorld()->wfile->getFolder(); + auto manager = scripting::engine->createPacksManager(worldFolder); + manager.scan(); + auto vec = manager.getAll({packid}); + if (!vec.empty()) { + return l_pack_get_info(L, vec.at(0), content); + } + return 0; + } + const auto& pack = *found; + return l_pack_get_info(L, pack, content); +} + const luaL_Reg packlib [] = { {"get_folder", lua_wrap_errors}, {"get_installed", lua_wrap_errors}, + {"get_available", lua_wrap_errors}, {"get_info", lua_wrap_errors}, {NULL, NULL} };