diff --git a/res/layouts/pages/generators.xml.lua b/res/layouts/pages/generators.xml.lua index 04c1d8bb..19e3ce60 100644 --- a/res/layouts/pages/generators.xml.lua +++ b/res/layouts/pages/generators.xml.lua @@ -5,11 +5,11 @@ function on_open() table.sort(names) local panel = document.root - for _,k in ipairs(names) do + for k, caption in pairs(names) do panel:add(gui.template("generator", { callback=string.format("settings.generator=%q menu:back()", k), id=k, - name=settings.generator_name(k) + name=settings.generator_name(caption) })) end panel:add("") diff --git a/res/layouts/pages/new_world.xml.lua b/res/layouts/pages/new_world.xml.lua index e92d5ae0..5c0c1480 100644 --- a/res/layouts/pages/new_world.xml.lua +++ b/res/layouts/pages/new_world.xml.lua @@ -10,12 +10,7 @@ function save_state() end function settings.generator_name(id) - local prefix, name = parse_path(id) - if prefix == "core" then - return gui.str(name, "world.generators") - else - return id - end + return gui.str(id, "world.generators"):gsub("^%l", string.upper) end function create_world() @@ -39,7 +34,7 @@ function on_open() document.generator_btn.text = string.format( "%s: %s", gui.str("World generator", "world"), - settings.generator_name(settings.generator) + settings.generator_name(generation.get_generators()[settings.generator]) ) document.name_box.text = settings.name or '' document.seed_box.text = settings.seed or '' diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index fbae5756..cd2168b2 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -42,7 +42,7 @@ menu.Contents Menu=Меню контентпаков world.Seed=Зерно world.Name=Название world.World generator=Генератор мира -world.generators.default=Обычный +world.generators.default=По-умолчанию world.generators.flat=Плоский world.Create World=Создать Мир world.convert-request=Есть изменения в индексах! Конвертировать мир? diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index bc03b810..89fabec0 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -54,7 +54,9 @@ static void detect_defs( continue; } if (fs::is_regular_file(file) && files::is_data_file(file)) { - detected.push_back(prefix.empty() ? name : prefix + ":" + name); + auto map = files::read_object(file); + std::string id = prefix.empty() ? name : prefix + ":" + name; + detected.emplace_back(id); } else if (fs::is_directory(file) && file.extension() != fs::u8path(".files")) { detect_defs(file, name, detected); @@ -63,11 +65,38 @@ static void detect_defs( } } -std::vector ContentLoader::scanContent( +static void detect_defs_pairs( + const fs::path& folder, + const std::string& prefix, + std::vector>& detected +) { + if (fs::is_directory(folder)) { + for (const auto& entry : fs::directory_iterator(folder)) { + const fs::path& file = entry.path(); + std::string name = file.stem().string(); + if (name[0] == '_') { + continue; + } + if (fs::is_regular_file(file) && files::is_data_file(file)) { + auto map = files::read_object(file); + std::string id = prefix.empty() ? name : prefix + ":" + name; + std::string caption = util::id_to_caption(id); + map.at("caption").get(caption); + detected.emplace_back(id, name); + } else if (fs::is_directory(file) && + file.extension() != fs::u8path(".files")) { + detect_defs_pairs(file, name, detected); + } + } + } +} + +std::vector> ContentLoader::scanContent( const ContentPack& pack, ContentType type ) { - std::vector detected; - detect_defs(pack.folder / ContentPack::getFolderFor(type), pack.id, detected); + std::vector> detected; + detect_defs_pairs( + pack.folder / ContentPack::getFolderFor(type), pack.id, detected); return detected; } diff --git a/src/content/ContentLoader.hpp b/src/content/ContentLoader.hpp index efd54efd..0f904172 100644 --- a/src/content/ContentLoader.hpp +++ b/src/content/ContentLoader.hpp @@ -70,7 +70,7 @@ public: const std::string& contentSection ); - static std::vector scanContent( + static std::vector> scanContent( const ContentPack& pack, ContentType type ); diff --git a/src/content/loading/GeneratorLoader.cpp b/src/content/loading/GeneratorLoader.cpp index 72cd330c..2c38de52 100644 --- a/src/content/loading/GeneratorLoader.cpp +++ b/src/content/loading/GeneratorLoader.cpp @@ -193,6 +193,7 @@ void ContentLoader::loadGenerator( return; } auto map = files::read_toml(generatorsDir / fs::u8path(name + ".toml")); + map.at("caption").get(def.caption); map.at("biome_parameters").get(def.biomeParameters); map.at("biome-bpd").get(def.biomesBPD); map.at("heights-bpd").get(def.heightsBPD); diff --git a/src/logic/scripting/lua/libs/libgeneration.cpp b/src/logic/scripting/lua/libs/libgeneration.cpp index d24fae0c..793dc868 100644 --- a/src/logic/scripting/lua/libs/libgeneration.cpp +++ b/src/logic/scripting/lua/libs/libgeneration.cpp @@ -52,10 +52,10 @@ static int l_get_generators(lua::State* L) { int i = 1; for (const auto& pack : packs) { - auto names = ContentLoader::scanContent(pack, ContentType::GENERATOR); - for (const auto& name : names) { - lua::pushstring(L, name); - lua::rawseti(L, i); + auto pairs = ContentLoader::scanContent(pack, ContentType::GENERATOR); + for (const auto& [name, caption] : pairs) { + lua::pushstring(L, caption); + lua::setfield(L, name); i++; } } diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index d1e5ef9f..c104bd5e 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -405,6 +405,13 @@ std::wstring util::capitalized(const std::wstring& str) { str.substr(1); } +std::string util::capitalized(const std::string& str) { + if (str.empty()) return str; + static const std::locale loc(""); + return std::string({static_cast(std::toupper(str[0], loc))}) + + str.substr(1); +} + std::wstring util::pascal_case(const std::wstring& str) { if (str.empty()) return str; static const std::locale loc(""); diff --git a/src/util/stringutil.hpp b/src/util/stringutil.hpp index cb251e83..c7bc2fb5 100644 --- a/src/util/stringutil.hpp +++ b/src/util/stringutil.hpp @@ -71,6 +71,8 @@ namespace util { double parse_double(const std::string& str); double parse_double(const std::string& str, size_t offset, size_t len); + std::string capitalized(const std::string& str); + std::wstring lower_case(const std::wstring& str); std::wstring upper_case(const std::wstring& str); std::wstring capitalized(const std::wstring& str); diff --git a/src/world/generator/GeneratorDef.cpp b/src/world/generator/GeneratorDef.cpp index 515d27e7..1dda81d9 100644 --- a/src/world/generator/GeneratorDef.cpp +++ b/src/world/generator/GeneratorDef.cpp @@ -10,8 +10,9 @@ VoxelStructure::VoxelStructure( std::unique_ptr structure ) : fragments({std::move(structure)}), meta(std::move(meta)) {} - -GeneratorDef::GeneratorDef(std::string name) : name(std::move(name)) {} +GeneratorDef::GeneratorDef(std::string name) + : name(std::move(name)), caption(util::id_to_caption(name)) { +} void GeneratorDef::prepare(const Content* content) { for (auto& biome : biomes) { diff --git a/src/world/generator/GeneratorDef.hpp b/src/world/generator/GeneratorDef.hpp index 10ab6ff4..d978a41c 100644 --- a/src/world/generator/GeneratorDef.hpp +++ b/src/world/generator/GeneratorDef.hpp @@ -192,6 +192,9 @@ struct VoxelStructure { struct GeneratorDef { /// @brief Generator full name - packid:name std::string name; + /// @brief Generator display name + std::string caption; + std::unique_ptr script; /// @brief Sea level (top of seaLayers)