diff --git a/mods/randomizer/CMakeLists.txt b/mods/randomizer/CMakeLists.txt index d040aa7a9f..f41c9f1eac 100644 --- a/mods/randomizer/CMakeLists.txt +++ b/mods/randomizer/CMakeLists.txt @@ -87,6 +87,8 @@ set(RANDOMIZER_SOURCES src/session.cpp src/ui/config_store.cpp src/ui/rando_seed_generation.cpp + src/ui/rando_config.cpp + src/ui/ui.cpp ) # Embed the generator's YAML data into the mod library. Paths are relative to this diff --git a/mods/randomizer/src/mod.cpp b/mods/randomizer/src/mod.cpp index d026780452..4421193432 100644 --- a/mods/randomizer/src/mod.cpp +++ b/mods/randomizer/src/mod.cpp @@ -2,6 +2,7 @@ #include "mods/svc/log.h" #include "session.hpp" +#include "ui/ui.hpp" DEFINE_MOD(); IMPORT_SERVICE(HostService, svc_host); @@ -31,11 +32,17 @@ MOD_EXPORT ModResult mod_initialize(ModError* error) { return mods::set_error(error, result, "failed to initialize session"); } + result = randomizer::ui::initialize(); + if (result != MOD_OK) { + return mods::set_error(error, result, "failed to initialize ui"); + } + svc_log->info(mod_ctx, "randomizer initialized"); return MOD_OK; } MOD_EXPORT ModResult mod_update(ModError*) { + randomizer::ui::update(); return MOD_OK; } diff --git a/mods/randomizer/src/ui/config_store.cpp b/mods/randomizer/src/ui/config_store.cpp index f14867efc9..b0a31a7d78 100644 --- a/mods/randomizer/src/ui/config_store.cpp +++ b/mods/randomizer/src/ui/config_store.cpp @@ -18,22 +18,9 @@ void SaveRandomizerConfig() { paths::GetRandomizerPreferencesPath()); } -seedgen::settings::Setting* FindSetting(const std::string& key) { - if (key.empty()) { - return nullptr; - } - auto& settings = GetRandomizerConfig().GetSettings(); - auto& map = settings.GetMap(); - auto it = map.find(key); - if (it == map.end()) { - mods::log::error("randomizer: failed to get settings key: {}", key); - return nullptr; - } - return &it->second; -} - bool TryCreateRandomSeed() { auto& config = GetRandomizerConfig(); + if (config.GetSeed().empty()) { config.SetSeed(seedgen::seed::GenerateSeed()); SaveRandomizerConfig(); diff --git a/mods/randomizer/src/ui/rando_config.cpp b/mods/randomizer/src/ui/rando_config.cpp new file mode 100644 index 0000000000..d817474d7c --- /dev/null +++ b/mods/randomizer/src/ui/rando_config.cpp @@ -0,0 +1,118 @@ +#include "rando_config.hpp" + +#include + +#include "../session.hpp" +#include "../tools.h" +#include "../paths.hpp" +#include "../../generator/seedgen/seed.hpp" +#include "../../generator/utility/string.hpp" + +#include "rando_seed_generation.hpp" +#include "config_store.hpp" + +#include +#include +#include + +namespace randomizer::ui { + +seedgen::settings::Setting* FindSetting(const std::string& key) { + if (key.empty()) { + mods::log::error("Key is empty! Unable to find setting."); + } + + // TODO: handle multi-world selection + auto& settings = GetRandomizerConfig().GetSettings(); + try { + return &settings.GetMap().at(key); + } catch (std::exception e) { + mods::log::error("Failed to get Settings Key: {}", key); + } +} + +const std::vector>& GetStartingInventoryLayoutOrder() { + static const std::vector> layoutOrder = { + // { display name , logic item name } + {"Shadow Crystal", "Shadow Crystal"}, + {"Horse Call", "Horse Call"}, + {"Fishing Rod", "Progressive Fishing Rod"}, + {"Slingshot", "Slingshot"}, + {"Lantern", "Lantern"}, + {"Gale Boomerang", "Gale Boomerang"}, + {"Iron Boots", "Iron Boots"}, + {"Bow", "Progressive Bow"}, + {"Hawkeye", "Hawkeye"}, + {"Bomb Bags", "Bomb Bag"}, + {"Giant Bomb Bags", "Giant Bomb Bag"}, + {"Clawshot", "Progressive Clawshot"}, + {"Spinner", "Spinner"}, + {"Ball and Chain", "Ball and Chain"}, + {"Dominion Rod", "Progressive Dominion Rod"}, + {"Empty Bottle", "Empty Bottle"}, + {"Auru's Memo", "Aurus Memo"}, + {"Ashei's Sketch", "Asheis Sketch"}, + {"Sky Book", "Progressive Sky Book"}, + {"Sword", "Progressive Sword"}, + {"Ordon Shield", "Ordon Shield"}, + {"Hylian Shield", "Hylian Shield"}, + {"Zora Armor", "Zora Armor"}, + {"Magic Armor", "Magic Armor"}, + {"Wallet", "Progressive Wallet"}, + {"Hidden Skills", "Progressive Hidden Skill"}, + {"Poe Souls", "Poe Soul"}, + {"Fused Shadows", "Progressive Fused Shadow"}, + {"Mirror Shards", "Progressive Mirror Shard"}, + {"Gate Keys", "Gate Keys"}, + {"Gerudo Desert Bulblin Camp Key", "Gerudo Desert Bulblin Camp Key"}, + {"Forest Temple Small Keys", "Forest Temple Small Key"}, + {"Goron Mines Small Keys", "Goron Mines Small Key"}, + {"Lakebed Temple Small Keys", "Lakebed Temple Small Key"}, + {"Arbiter's Grounds Small Keys", "Arbiters Grounds Small Key"}, + {"Snowpeak Ruins Small Keys", "Snowpeak Ruins Small Key"}, + {"Ordon Pumpkin", "Ordon Pumpkin"}, + {"Ordon Cheese", "Ordon Cheese"}, + {"Temple of Time Small Keys", "Temple of Time Small Key"}, + {"City in the Sky Small Keys", "City in the Sky Small Key"}, + {"Palace of Twilight Small Keys", "Palace of Twilight Small Key"}, + {"Hyrule Castle Small Keys", "Hyrule Castle Small Key"}, + {"Forest Temple Big Key", "Forest Temple Big Key"}, + {"Goron Mines Key Shards", "Goron Mines Key Shard"}, + {"Lakebed Temple Big Key", "Lakebed Temple Big Key"}, + {"Arbiter's Grounds Big Key", "Arbiters Grounds Big Key"}, + {"Snowpeak Ruins Bedroom Key", "Snowpeak Ruins Bedroom Key"}, + {"Temple of Time Big Key", "Temple of Time Big Key"}, + {"City in the Sky Big Key", "City in the Sky Big Key"}, + {"Palace of Twilight Big Key", "Palace of Twilight Big Key"}, + {"Hyrule Castle Big Key", "Hyrule Castle Big Key"}, + {"Gerudo Desert Portal", "Gerudo Desert Portal"}, + {"Mirror Chamber Portal", "Mirror Chamber Portal"}, + {"Snowpeak Portal", "Snowpeak Portal"}, + {"Sacred Grove Portal", "Sacred Grove Portal"}, + {"Bridge of Eldin Portal", "Bridge of Eldin Portal"}, + {"Upper Zora's River Portal", "Upper Zoras River Portal"} + }; + return layoutOrder; +} + +std::filesystem::path GetRandomizerPath() { + return paths::GetRandomizerPath() / "randomizer"; +} + +std::filesystem::path GetRandomizerSettingsPath() { + return GetRandomizerPath() / "settings.yaml"; +} + +std::filesystem::path GetRandomizerPreferencesPath() { + return GetRandomizerPath() / "preferences.yaml"; +} + +std::filesystem::path GetRandomizerPresetsPath() { + return GetRandomizerPath() / "presets"; +} + +std::filesystem::path GetRandomizerSeedsPath() { + return GetRandomizerPath() / "seeds"; +} + +} // namespace dusk::ui diff --git a/mods/randomizer/src/ui/rando_config.hpp b/mods/randomizer/src/ui/rando_config.hpp new file mode 100644 index 0000000000..1c5457e0c9 --- /dev/null +++ b/mods/randomizer/src/ui/rando_config.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include + +// Forward declaration +namespace randomizer::seedgen::config { +class Config; +} +class dFile_select_c; + +namespace randomizer::ui { + +void SaveNewRandomizerPreset(const std::string& presetName, bool overwriteExisting = false); +void ApplyExistingRandomizerPreset(const std::filesystem::path& presetFilePath); +void CopyPermalinkToClipboard(); +void PastePermalinkFromClipboard(); + +std::filesystem::path GetRandomizerPath(); +std::filesystem::path GetRandomizerSettingsPath(); +std::filesystem::path GetRandomizerPreferencesPath(); +std::filesystem::path GetRandomizerSeedsPath(); +std::filesystem::path GetRandomizerPresetsPath(); + +} diff --git a/mods/randomizer/src/ui/ui.cpp b/mods/randomizer/src/ui/ui.cpp new file mode 100644 index 0000000000..2914b2b2af --- /dev/null +++ b/mods/randomizer/src/ui/ui.cpp @@ -0,0 +1,81 @@ +#include "ui.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../session.hpp" +#include "../randomizer_context.hpp" +#include "../paths.hpp" + +#include "config_store.hpp" +#include "rando_seed_generation.hpp" + +namespace randomizer::ui { +namespace { +// Seed Tab +ModResult buildSeedTab(ModContext* ctx, UiWindowHandle, UiElementHandle leftPane, + UiElementHandle rightPane, void*, ModError*) +{ + return MOD_OK; +} + +ModResult updateSeedTab(ModContext* ctx, void*, ModError*) { + return MOD_OK; +} + +// Settings Tab +ModResult buildSettingsTab(ModContext* ctx, UiWindowHandle, UiElementHandle leftPane, + UiElementHandle rightPane, void*, ModError*) +{ + return MOD_OK; +} + +// Menu Tab +void OnMenuTabSelected(ModContext* ctx, void*) { + UiTabDesc tabs[2]{}; + + tabs[0].struct_size = sizeof(UiTabDesc); + tabs[0].title = "Seed"; + tabs[0].build = buildSeedTab; + tabs[0].update = updateSeedTab; + + tabs[1].struct_size = sizeof(UiTabDesc); + tabs[1].title = "Settings"; + tabs[1].build = buildSettingsTab; + + UiWindowDesc desc = UI_WINDOW_DESC_INIT; + desc.tabs = tabs; + desc.tab_count = 2; + UiWindowHandle window{}; + session::svc_mng.ui->window_push(ctx, &desc, &window); +} +} + +UiMenuTabHandle g_menu_tab{}; + +ModResult initialize() { + UiMenuTabDesc desc = UI_MENU_TAB_DESC_INIT; + desc.label = "Randomizer"; + desc.on_selected = OnMenuTabSelected; + + ModResult res = + session::svc_mng.ui->register_menu_tab(session::svc_mng.mod_ctx, &desc, &g_menu_tab); + if (res != MOD_OK) { + return res; + } + + return MOD_OK; +} + +void update() { + UpdateSeedGenerationDialog(); +} + +} \ No newline at end of file diff --git a/mods/randomizer/src/ui/ui.hpp b/mods/randomizer/src/ui/ui.hpp new file mode 100644 index 0000000000..a62ee956e0 --- /dev/null +++ b/mods/randomizer/src/ui/ui.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace randomizer::ui { +ModResult initialize(); +void update(); +} \ No newline at end of file