diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index aba6a2df..f4e1d1b8 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -18,9 +18,9 @@ menu.Controls=Управление menu.Back to Main Menu=Вернуться в Меню menu.Settings=Настройки menu.Content=Контент -world.Seed=Зерно -world.Name=Название -world.Create World=Создать Мир +menu.Seed=Зерно +menu.Name=Название +menu.Create World=Создать Мир world.convert-request=Есть изменения в индексах! Конвертировать мир? diff --git a/res/texts/su_SU.txt b/res/texts/su_SU.txt index b57bb587..8756e3a7 100644 --- a/res/texts/su_SU.txt +++ b/res/texts/su_SU.txt @@ -18,9 +18,9 @@ menu.Controls=Управление menu.Back to Main Menu=Вернуться на Главную menu.Settings=Настройки menu.Content=Наполнение -world.Seed=Семя -world.Name=Название -world.Create World=Создать Мир +menu.Seed=Семя +menu.Name=Название +menu.Create World=Создать Мир world.convert-request=Есть изменения в индексах! Преобразовать мир? diff --git a/src/frontend/gui/controls.cpp b/src/frontend/gui/controls.cpp index 5a1b72a4..95ebf1c1 100644 --- a/src/frontend/gui/controls.cpp +++ b/src/frontend/gui/controls.cpp @@ -64,7 +64,9 @@ Button::Button(shared_ptr content, glm::vec4 padding) : Panel(vec2(32,32 scrollable(false); } -Button::Button(wstring text, glm::vec4 padding) : Panel(vec2(32,32), padding, 0) { +Button::Button(wstring text, glm::vec4 padding, glm::vec4 margin) + : Panel(vec2(32,32), padding, 0) { + this->margin(margin); Label* label = new Label(text); label->align(Align::center); this->label = shared_ptr(label); diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index 925a5259..4d710833 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -48,7 +48,9 @@ namespace gui { std::shared_ptr label = nullptr; public: Button(std::shared_ptr content, glm::vec4 padding=glm::vec4(2.0f)); - Button(std::wstring text, glm::vec4 padding=glm::vec4(2.0f)); + Button(std::wstring text, + glm::vec4 padding=glm::vec4(2.0f), + glm::vec4 margin=glm::vec4(1.0f)); virtual void drawBackground(Batch2D* batch, Assets* assets); diff --git a/src/frontend/gui/gui_util.cpp b/src/frontend/gui/gui_util.cpp index da1d15f1..da6dfdde 100644 --- a/src/frontend/gui/gui_util.cpp +++ b/src/frontend/gui/gui_util.cpp @@ -19,6 +19,7 @@ Button* guiutil::backButton(PagesControl* menu) { } Button* guiutil::gotoButton(wstring text, string page, PagesControl* menu) { + text = langs::get(text, L"menu"); return (new Button(text, vec4(10.f)))->listenAction([=](GUI* gui) { menu->set(page); }); diff --git a/src/frontend/menu.cpp b/src/frontend/menu.cpp index 49f3abec..9f471e24 100644 --- a/src/frontend/menu.cpp +++ b/src/frontend/menu.cpp @@ -28,47 +28,55 @@ using glm::vec2; using glm::vec4; -using std::make_unique; -using std::unique_ptr; -using std::shared_ptr; namespace fs = std::filesystem; using namespace gui; -Panel* create_main_menu_panel(Engine* engine, PagesControl* menu); -Panel* create_new_world_panel(Engine* engine, PagesControl* menu); -Panel* create_controls_panel(Engine* engine, PagesControl* menu); -Panel* create_settings_panel(Engine* engine, PagesControl* menu); -Panel* create_pause_panel(Engine* engine, PagesControl* menu); -Panel* create_languages_panel(Engine* engine, PagesControl* menu); -Panel* create_content_panel(Engine* engine, PagesControl* menu); - -void menus::create_menus(Engine* engine, PagesControl* menu) { - menu->add("new-world", create_new_world_panel(engine, menu)); - menu->add("settings", create_settings_panel(engine, menu)); - menu->add("controls", create_controls_panel(engine, menu)); - menu->add("pause", create_pause_panel(engine, menu)); - menu->add("languages", create_languages_panel(engine, menu)); - menu->add("content", create_content_panel(engine, menu)); - menu->add("main", create_main_menu_panel(engine, menu)); +inline uint64_t randU64() { + return rand() ^ (rand() << 8) ^ + (rand() << 16) ^ (rand() << 24) ^ + ((uint64_t)rand() << 32) ^ + ((uint64_t)rand() << 40) ^ + ((uint64_t)rand() << 56); } -void menus::refresh_menus(Engine* engine, PagesControl* menu) { - menu->add("main", create_main_menu_panel(engine, menu)); +std::shared_ptr create_page( + Engine* engine, + std::string name, + int width, + float opacity, + int interval) { + PagesControl* menu = engine->getGUI()->getMenu(); + Panel* panel = new Panel(vec2(width, 200), vec4(8.0f), interval); + panel->color(vec4(0.0f, 0.0f, 0.0f, opacity)); + + std::shared_ptr ptr (panel); + menu->add(name, ptr); + return ptr; } -void show_content_select(GUI* gui, const EnginePaths* paths, - std::vector& packs) { +Button* create_button(std::wstring text, + glm::vec4 padding, + glm::vec4 margin, + gui::onaction action) { + + auto btn = new Button(langs::get(text, L"menu"), + padding, margin); + btn->listenAction(action); + return btn; +} + +void show_content_select(GUI* gui, Engine* engine) { PagesControl* menu = gui->getMenu(); Panel* panel = new Panel(vec2(200, 200), vec4(8.0f), 8.0f); - auto resdir = paths->getResources(); + auto resdir = engine->getPaths()->getResources(); std::vector allpacks; ContentPack::scan(resdir / fs::path("content"), allpacks); for (ContentPack& pack : allpacks) { bool selected = false; - for (ContentPack& spack : packs) { + for (ContentPack& spack : engine->getContentPacks()) { if (spack.id == pack.id) { selected = true; break; @@ -91,10 +99,11 @@ void show_content_select(GUI* gui, const EnginePaths* paths, menu->set("content-select"); } -void show_content_missing(GUI* gui, const Content* content, ContentLUT* lut) { - PagesControl* menu = gui->getMenu(); - Panel* panel = new Panel(vec2(500, 200), vec4(8.0f), 8.0f); - panel->color(vec4(0.0f, 0.0f, 0.0f, 0.5f)); +void show_content_missing(Engine* engine, const Content* content, ContentLUT* lut) { + auto* gui = engine->getGUI(); + auto* menu = gui->getMenu(); + auto panel = create_page(engine, "missing-content", 500, 0.5f, 8); + panel->add(new Label(langs::get(L"menu.missing-content"))); Panel* subpanel = new Panel(vec2(500, 100)); @@ -121,20 +130,23 @@ void show_content_missing(GUI* gui, const Content* content, ContentLUT* lut) { subpanel->maxLength(400); panel->add(subpanel); - panel->add((new Button(langs::get(L"Back to Main Menu", L"menu"), vec4(8.0f)))->listenAction([=](GUI*){ + panel->add((new Button(langs::get(L"Back to Main Menu", L"menu"), + vec4(8.0f))) + ->listenAction([=](GUI*){ menu->back(); })); - menu->add("missing-content", panel); menu->set("missing-content"); } -void show_convert_request(GUI* gui, const Content* content, ContentLUT* lut, - fs::path folder) { - guiutil::confirm(gui, langs::get(L"world.convert-request"), +void show_convert_request( + Engine* engine, + const Content* content, + ContentLUT* lut, + fs::path folder) { + guiutil::confirm(engine->getGUI(), langs::get(L"world.convert-request"), [=]() { - std::cout << "Convert the world: " << folder.string() << std::endl; // TODO: add multithreading here - auto converter = make_unique(folder, content, lut); + auto converter = std::make_unique(folder, content, lut); while (converter->hasNext()) { converter->convertNext(); } @@ -143,9 +155,10 @@ void show_convert_request(GUI* gui, const Content* content, ContentLUT* lut, }, L"", langs::get(L"Cancel")); } -Panel* create_languages_panel(Engine* engine, PagesControl* menu) { - Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f); +void create_languages_panel(Engine* engine, PagesControl* menu) { + auto panel = create_page(engine, "languages", 400, 0.5f, 1); panel->scrollable(true); + std::vector locales; for (auto& entry : langs::locales_info) { locales.push_back(entry.first); @@ -164,96 +177,110 @@ Panel* create_languages_panel(Engine* engine, PagesControl* menu) { panel->add(button); } panel->add(guiutil::backButton(menu)); - return panel; } -Panel* create_main_menu_panel(Engine* engine, PagesControl* menu) { - EnginePaths* paths = engine->getPaths(); +void open_world(std::string name, Engine* engine) { + // TODO: complete and move somewhere + auto paths = engine->getPaths(); + auto resdir = paths->getResources(); + auto folder = paths->getWorldsFolder()/fs::u8path(name); + + auto& packs = engine->getContentPacks(); + packs.clear(); + auto packnames = ContentPack::worldPacksList(folder); + for (auto name : packnames) { + fs::path packfolder; + try { + packfolder = ContentPack::findPack(paths, name); + } catch (std::runtime_error& error) { + guiutil::alert(engine->getGUI(), + langs::get(L"error.pack-not-found")+ + L": "+util::str2wstr_utf8(name)); + return; + } + packs.push_back(ContentPack::read(packfolder)); + } + engine->loadContent(); - Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f); - panel->color(vec4(0.0f)); + auto* content = engine->getContent(); + auto& settings = engine->getSettings(); + fs::create_directories(folder); + ContentLUT* lut = World::checkIndices(folder, content); + if (lut) { + if (lut->hasMissingContent()) { + show_content_missing(engine, content, lut); + delete lut; + } else { + show_convert_request(engine, content, lut, folder); + } + } else { + Level* level = World::load(folder, settings, content); + engine->setScreen(std::make_shared(engine, level)); + } +} - panel->add(guiutil::gotoButton(langs::get(L"New World", L"menu"), "new-world", menu)); +Panel* create_worlds_panel(Engine* engine) { + auto panel = new Panel(vec2(390, 200), vec4(5.0f)); + panel->color(vec4(1.0f, 1.0f, 1.0f, 0.07f)); + panel->maxLength(400); - Panel* worldsPanel = new Panel(vec2(390, 200), vec4(5.0f)); - worldsPanel->color(vec4(1.0f, 1.0f, 1.0f, 0.07f)); - worldsPanel->maxLength(400); + auto paths = engine->getPaths(); fs::path worldsFolder = paths->getWorldsFolder(); - if (std::filesystem::is_directory(worldsFolder)) { - for (auto const& entry : fs::directory_iterator(worldsFolder)) { + if (fs::is_directory(worldsFolder)) { + for (auto entry : fs::directory_iterator(worldsFolder)) { if (!entry.is_directory()) { continue; } - std::string name = entry.path().filename().u8string(); - Button* button = new Button(util::str2wstr_utf8(name), - vec4(10.0f, 8.0f, 10.0f, 8.0f)); - button->color(vec4(1.0f, 1.0f, 1.0f, 0.1f)); - button->listenAction([=](GUI* gui) { - // TODO: complete and move somewhere - - auto folder = paths->getWorldsFolder()/fs::u8path(name); - auto resdir = engine->getPaths()->getResources(); - auto& packs = engine->getContentPacks(); - packs.clear(); - auto packnames = ContentPack::worldPacksList(folder); - for (auto name : packnames) { - fs::path packfolder; - try { - packfolder = ContentPack::findPack(paths, name); - } catch (std::runtime_error& error) { - guiutil::alert(gui, langs::get(L"error.pack-not-found")+ - L": "+util::str2wstr_utf8(name)); - return; - } - packs.push_back(ContentPack::read(packfolder)); - } - engine->loadContent(); - - auto* content = engine->getContent(); - auto& settings = engine->getSettings(); - std::filesystem::create_directories(folder); - ContentLUT* lut = World::checkIndices(folder, content); - if (lut) { - if (lut->hasMissingContent()) { - show_content_missing(gui, content, lut); - delete lut; - } else { - show_convert_request(gui, content, lut, folder); - } - } else { - Level* level = World::load(folder, settings, content); - auto screen = new LevelScreen(engine, level); - engine->setScreen(shared_ptr(screen)); - } + auto name = entry.path().filename().u8string(); + auto btn = new Button(util::str2wstr_utf8(name), + vec4(10.0f, 8.0f, 10.0f, 8.0f)); + btn->color(vec4(1.0f, 1.0f, 1.0f, 0.1f)); + btn->listenAction([=](GUI*) { + open_world(name, engine); }); - worldsPanel->add(button); + panel->add(btn); } } - panel->add(worldsPanel); - panel->add(guiutil::gotoButton(langs::get(L"Settings", L"menu"), "settings", menu)); - panel->add(guiutil::gotoButton(langs::get(L"Content", L"menu"), "content", menu)); - panel->add((new Button(langs::get(L"Quit", L"menu"), vec4(10.f)))->listenAction([](GUI* gui) { + return panel; +} + +void create_main_menu_panel(Engine* engine, PagesControl* menu) { + auto panel = create_page(engine, "main", 400, 0.0f, 1); + panel->add(guiutil::gotoButton(L"New World", "new-world", menu)); + panel->add(create_worlds_panel(engine)); + panel->add(guiutil::gotoButton(L"Settings", "settings", menu)); + panel->add(guiutil::gotoButton(L"Content", "content", menu)); + + panel->add((new Button(langs::get(L"Quit", L"menu"), vec4(10.f))) + ->listenAction([](GUI* gui) { Window::setShouldClose(true); })); - return panel; } -Panel* create_content_panel(Engine* engine, PagesControl* menu) { - Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 5.0f); - panel->color(vec4(0.0f)); - +void create_content_panel(Engine* engine, PagesControl* menu) { + auto panel = create_page(engine, "content", 400, 0.0f, 5); panel->add(new Label(L"work in progress")); - panel->add(guiutil::backButton(menu)); - return panel; } -Panel* create_new_world_panel(Engine* engine, PagesControl* menu) { - Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f); - panel->color(vec4(0.0f)); +inline uint64_t str2seed(std::wstring seedstr) { + if (util::is_integer(seedstr)) { + try { + return std::stoull(seedstr); + } catch (const std::out_of_range& err) { + std::hash hash; + return hash(seedstr); + } + } else { + std::hash hash; + return hash(seedstr); + } +} - TextBox* worldNameInput; - { +void create_new_world_panel(Engine* engine, PagesControl* menu) { + auto panel = create_page(engine, "new-world", 400, 0.0f, 1); + + TextBox* worldNameInput; { Label* label = new Label(langs::get(L"Name", L"world")); panel->add(label); @@ -262,93 +289,66 @@ Panel* create_new_world_panel(Engine* engine, PagesControl* menu) { worldNameInput = input; } - TextBox* seedInput; - { - Label* label = new Label(langs::get(L"Seed", L"world")); - panel->add(shared_ptr(label)); - - uint64_t randseed = rand() ^ (rand() << 8) ^ - (rand() << 16) ^ (rand() << 24) ^ - ((uint64_t)rand() << 32) ^ - ((uint64_t)rand() << 40) ^ - ((uint64_t)rand() << 56); - - seedInput = new TextBox(std::to_wstring(randseed), vec4(6.0f)); + TextBox* seedInput; { + panel->add(std::make_shared