diff --git a/include/d/d_file_select.h b/include/d/d_file_select.h index d478126b38..4ecc0b7c24 100644 --- a/include/d/d_file_select.h +++ b/include/d/d_file_select.h @@ -203,6 +203,9 @@ public: DATASELPROC_DATA_SELECT_MOVE_ANIME, DATASELPROC_SELECT_DATA_OPEN_MOVE, DATASELPROC_SELECT_DATA_NAME_MOVE, +#if TARGET_PC + DATASELPROC_SELECT_DATA_PLAY_MOVE, // Select between vanilla or randomizer play +#endif DATASELPROC_SELECT_DATA_OPENERASE_MOVE, DATASELPROC_MENU_SELECT, DATASELPROC_MENU_SELECT_MOVE_ANM, @@ -326,6 +329,9 @@ public: void makeRecInfo(u8); void selectDataOpenMove(); void selectDataNameMove(); +#if TARGET_PC + void selectDataPlayTypeMove(); +#endif void selectDataOpenEraseMove(); void menuSelect(); void menuSelectStart(); @@ -719,7 +725,12 @@ public: /* 0x2378 */ J2DPicture* mpFadePict; #endif #ifdef TARGET_PC - dDlst_FileSelFade_c mFadeDlst; + struct mDusk { + dDlst_FileSelFade_c mFadeDlst; + bool mStartNameAnm; + bool mBackToFileSelect; + int mPendingRmlCloseFrames{0}; + } mDusk; #endif #if PLATFORM_WII || PLATFORM_SHIELD @@ -730,7 +741,7 @@ public: }; #ifdef TARGET_PC -STATIC_ASSERT(sizeof(dFile_select_c) == 0x237C + sizeof(dDlst_FileSelFade_c)); +STATIC_ASSERT(sizeof(dFile_select_c) == 0x237C + sizeof(dFile_select_c::mDusk)); #else STATIC_ASSERT(sizeof(dFile_select_c) == 0x237C); #endif diff --git a/include/dusk/settings.h b/include/dusk/settings.h index e676e425d3..36269e87fd 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -289,6 +289,11 @@ struct UserSettings { std::array openDusklightMenu; std::array turboSpeedButton; } actionBindings; + + // Randomizer seed hashes, 1 per file + struct { + std::array, 3> seedHashes; + } randomizer; }; UserSettings& getSettings(); diff --git a/libs/JSystem/include/JSystem/J2DGraph/J2DTextBox.h b/libs/JSystem/include/JSystem/J2DGraph/J2DTextBox.h index 0d875ad652..46495fac1b 100644 --- a/libs/JSystem/include/JSystem/J2DGraph/J2DTextBox.h +++ b/libs/JSystem/include/JSystem/J2DGraph/J2DTextBox.h @@ -154,6 +154,18 @@ public: return (J2DTextBoxHBinding)((mFlags >> 2) & 3); } +#if TARGET_PC + void setVBinding(J2DTextBoxVBinding vBinding) { + mFlags &= 0b1100; + mFlags |= (vBinding & 3); + } + + void setHBinding(J2DTextBoxHBinding hBinding) { + mFlags &= 0b0011; + mFlags |= ((hBinding & 3) << 2); + } +#endif + JUtility::TColor getCharColor() { return mCharColor; } JUtility::TColor getGradColor() { return mGradientColor; } u16 getStringAllocByte() const { return mStringLength; } diff --git a/src/d/d_com_inf_game.cpp b/src/d/d_com_inf_game.cpp index 71449ff7a9..db6d243f9a 100644 --- a/src/d/d_com_inf_game.cpp +++ b/src/d/d_com_inf_game.cpp @@ -2984,6 +2984,7 @@ void dComIfGs_setupRandomizerSave() { execItemGet(itemId); } + g_randomizerState = RandomizerState(); DuskLog.debug("Created Rando Save"); randoData.mCreatingSave = false; } diff --git a/src/d/d_file_sel_info.cpp b/src/d/d_file_sel_info.cpp index d54bc4424d..f99ff7ef4c 100644 --- a/src/d/d_file_sel_info.cpp +++ b/src/d/d_file_sel_info.cpp @@ -116,6 +116,24 @@ int dFile_info_c::setSaveData(dSv_save_c* i_savedata, BOOL i_validChksum, u8 i_d SAFE_STRCPY(mPlayerName, player_name); setSaveDate(i_savedata); setPlayTime(i_savedata); +#if TARGET_PC + // If this is a randomizer file + auto curFileSeedHash = dusk::getSettings().randomizer.seedHashes.at(i_dataNo).getValue(); + if (!curFileSeedHash.empty()) { + // Overwrite "Save time" text with "Randomizer" + auto saveTimeText = (J2DTextBox*)mFileInfo.Scr->search(MULTI_CHAR('f_s_t_02')); + dusk::SafeStringCopy(saveTimeText->getStringPtr(), "Randomizer"); + saveTimeText->setHBinding(J2DTextBoxHBinding::HBIND_LEFT); + + // Overwrite the "Total play time" text with the seed hash + auto playTimeText = (J2DTextBox*)mFileInfo.Scr->search(MULTI_CHAR('f_p_t_02')); + dusk::SafeStringCopy(playTimeText->getStringPtr(), curFileSeedHash.c_str()); + + // Give the text double the space on the menu incase the seed hash is long + playTimeText->setHBinding(J2DTextBoxHBinding::HBIND_LEFT); + playTimeText->resize(playTimeText->getWidth() * 2, playTimeText->getHeight()); + } +#endif result = 0; } } else { diff --git a/src/d/d_file_select.cpp b/src/d/d_file_select.cpp index b660f79fcb..e3d4d56569 100644 --- a/src/d/d_file_select.cpp +++ b/src/d/d_file_select.cpp @@ -23,7 +23,13 @@ #include "m_Do/m_Do_graphic.h" #include +#if TARGET_PC +#include "dusk/config.hpp" #include "dusk/string.hpp" +#include "dusk/ui/modal.hpp" +#include "dusk/ui/rando_config.hpp" +#include "dusk/ui/ui.hpp" +#endif static s32 SelStartFrameTbl[3] = { 59, @@ -279,6 +285,9 @@ static DataSelProcFunc DataSelProc[] = { &dFile_select_c::dataSelectMoveAnime, &dFile_select_c::selectDataOpenMove, &dFile_select_c::selectDataNameMove, +#if TARGET_PC + &dFile_select_c::selectDataPlayTypeMove, +#endif &dFile_select_c::selectDataOpenEraseMove, &dFile_select_c::menuSelect, &dFile_select_c::menuSelectMoveAnm, @@ -843,7 +852,12 @@ void dFile_select_c::dataSelectStart() { mpName->initial(); modoruTxtChange(1); +#if TARGET_PC + mDataSelProc = DATASELPROC_SELECT_DATA_PLAY_MOVE; + mDusk.mStartNameAnm = false; +#else mDataSelProc = DATASELPROC_SELECT_DATA_NAME_MOVE; +#endif } else { #if PLATFORM_GCN dComIfGs_setNewFile(0); @@ -1138,6 +1152,93 @@ void dFile_select_c::selectDataNameMove() { } } +#if TARGET_PC +// Custom Proc to allow the player to select the play type and a randomizer seed +// Initially copied and expanded upon from dFile_select_c::selectDataNameMove +void dFile_select_c::selectDataPlayTypeMove() { + bool isHeaderTxtChange = headerTxtChangeAnm(); + bool isFileRecScale = fileRecScaleAnm2(); + bool isModoruTxtDisp = modoruTxtDispAnm(); + + // If we want to start bringing in the name input + if (mDusk.mStartNameAnm) { + // Only do so when no documents are visible + if (!dusk::ui::any_document_visible()) { + if (mDusk.mBackToFileSelect) { + // Code below copied from dFile_select_c::nameInput to initiate going back + // to the file selection + headerTxtSet(0x43, 1, 0); + fileRecScaleAnmInitSet2(0.0f, 1.0f); + nameMoveAnmInitSet(0xd29, 0xd1f); + modoruTxtDispAnmInit(0); + mDataSelProc = DATASELPROC_NAME_TO_DATA_SELECT_MOVE; + } else { + // Show the name pane if we went forward + field_0x0128 = true; + mNameBasePane->show(); + if (mDusk.mPendingRmlCloseFrames > 0) { + mDusk.mPendingRmlCloseFrames -= 1; + } + if (mDusk.mPendingRmlCloseFrames == 0 && nameMoveAnm()) { + mDataSelProc = DATASELPROC_NAME_INPUT_WAIT; + mDusk.mStartNameAnm = false; + } + } + } + } + // If the file select elements have disappeared, setup the play type modal + else if (isHeaderTxtChange == true && isFileRecScale == true && + isModoruTxtDisp == true) + { + // Push our modal for selecting the play type + auto& playTypeModal = dusk::ui::push_document(std::make_unique(dusk::ui::Modal::Props{ + .title = "Play Type", + .bodyRml = "What mode would you like to play?", + .actions = { + // If vanilla is selected, proceed to name entry and reset randomizer context + dusk::ui::ModalAction{ + .label = "Vanilla", + .onPressed = [this](dusk::ui::Modal& modal) { + mDusk.mBackToFileSelect = false; + mDoAud_seStartMenu(Z2SE_SY_CURSOR_OK); + modal.hide(true); + randomizer_GetContext() = RandomizerContext(); + }}, + // If randomizer is selected, proceed to the randomizer menu + dusk::ui::ModalAction{ + .label = "Randomizer", + .onPressed = [this](dusk::ui::Modal& modal) { + mDoAud_seStartMenu(Z2SE_SY_CURSOR_OK); + modal.hide(true); + dusk::ui::push_document(std::make_unique(this)); + }}, + }, + // If we dismiss this modal, go back to file selection + .onDismiss = [this](dusk::ui::Modal& modal) { + mDoAud_seStartMenu(Z2SE_SY_MENU_BACK); + modal.hide(true); + }, + .icon = "question-mark", + })); + + // The next time we call this function, begin waiting to show the name input + mDusk.mStartNameAnm = true; + + // By default, go back to the file selection after closing the various menus. + mDusk.mBackToFileSelect = true; + + // Wait 6 frames for the rmlui window transition after it closes + mDusk.mPendingRmlCloseFrames = 6; + + // Hide the name pane incase we go back + field_0x0128 = false; + mNameBasePane->hide(); + + playTypeModal.focus(); + } +} +#endif + void dFile_select_c::selectDataOpenEraseMove() { bool isHeaderTxtChange = headerTxtChangeAnm(); bool isSelDataMove = selectDataMoveAnm(); @@ -1204,6 +1305,21 @@ void dFile_select_c::menuSelectStart() { mIsSelectEnd = true; mDataSelProc = DATASELPROC_NEXT_MODE_WAIT; dComIfGs_setDataNum(mSelectNum); + #if TARGET_PC + // Load the randomizer seed if one is tied to this file + auto curFileSeedHash = dusk::getSettings().randomizer.seedHashes.at(mSelectNum).getValue(); + // If this is a vanilla file, clear rando data structures + if (curFileSeedHash.empty()) { + g_randomizerState = RandomizerState(); + randomizer_GetContext() = RandomizerContext(); + } + // Reset randomizer state if we're switching to a different file + else if (curFileSeedHash != randomizer_GetContext().mHash || g_randomizerState.mFileNum != mSelectNum) { + g_randomizerState = RandomizerState(); + randomizer_GetContext() = RandomizerContext(); + randomizer_GetContext().LoadFromHash(curFileSeedHash); + } + #endif } else if (mSelectMenuNum == 0) { mSelIcon->setAlphaRate(0.0f); yesnoMenuMoveAnmInitSet(0x473, 0x47d); @@ -1447,6 +1563,14 @@ void dFile_select_c::nameInput() { } void dFile_select_c::nameToDataSelectMove() { +#if TARGET_PC + // Delay this animation to make for a smoother transition from the Rmlui menus + if (mDusk.mPendingRmlCloseFrames > 0) { + mDusk.mPendingRmlCloseFrames -= 1; + return; + } +#endif + bool isHeaderTxtChange = headerTxtChangeAnm(); bool isFileRecScale = fileRecScaleAnm2(); bool isNameMove = nameMoveAnm(); @@ -2368,6 +2492,12 @@ void dFile_select_c::CommandExec() { mDoMemCd_setCopyToPos(mCpDataToNum); dataSave(); mDataSelProc = DATASELPROC_DATA_COPY_WAIT; +#if TARGET_PC + // Copy over the seed hash as well + auto& seedHashes = dusk::getSettings().randomizer.seedHashes; + seedHashes[mCpDataToNum].setValue(seedHashes[mCpDataNum]); + dusk::config::Save(); +#endif break; } @@ -2426,6 +2556,11 @@ void dFile_select_c::ErasePaneMoveOk() { if (iVar1 == 1 && iVar2 == 1) { field_0x0208 = 0; setSaveData(); +#if TARGET_PC + // Clear the seed hash for this file when it gets erased + dusk::getSettings().randomizer.seedHashes.at(mSelectNum).setValue(""); + dusk::config::Save(); +#endif makeRecInfo(mSelectNum); headerTxtSet(0x4b, 0, 0); mpFileWarning->closeInit(); @@ -3197,7 +3332,7 @@ void dFile_select_c::screenSet() { mpFadePict->setBlackWhite(black, white); mpFadePict->setAlpha(0); #ifdef TARGET_PC - mFadeDlst.mpPict = mpFadePict; + mDusk.mFadeDlst.mpPict = mpFadePict; #endif #endif } @@ -3999,7 +4134,7 @@ void dFile_select_c::_draw() { #if PLATFORM_GCN #if TARGET_PC - dComIfGd_set2DOpaTop(&mFadeDlst); + dComIfGd_set2DOpaTop(&mDusk.mFadeDlst); #else mpFadePict->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(), mDoGph_gInf_c::getWidthF(), mDoGph_gInf_c::getHeightF(), false, false, diff --git a/src/d/d_menu_save.cpp b/src/d/d_menu_save.cpp index d73e4ff5e8..0c891dccf1 100644 --- a/src/d/d_menu_save.cpp +++ b/src/d/d_menu_save.cpp @@ -18,11 +18,15 @@ #include "m_Do/m_Do_controller_pad.h" #include "m_Do/m_Do_graphic.h" #include "d/d_msg_scrn_explain.h" -#include "dusk/frame_interpolation.h" -#include "dusk/settings.h" #include "JSystem/J2DGraph/J2DAnmLoader.h" #include "f_op/f_op_msg_mng.h" +#if TARGET_PC +#include "dusk/config.hpp" +#include "dusk/frame_interpolation.h" +#include "dusk/settings.h" +#endif + static int SelStartFrameTbl[3] = { 59, 99, @@ -1341,6 +1345,15 @@ void dMenu_save_c::dataWrite() { dComIfGs_setMemoryToCard(mSaveBuffer, mSelectedFile); mDoMemCdRWm_SetCheckSumGameData(mSaveBuffer, mSelectedFile); +#if TARGET_PC + // Save randomizer hash + dusk::getSettings().randomizer.seedHashes[mSelectedFile].setValue(randomizer_GetContext().mHash); + dusk::config::Save(); + if (randomizer_IsActive()) { + g_randomizerState.mFileNum = mSelectedFile; + } +#endif + u8* save = mSaveBuffer; for (int i = 0; i < 3; i++) { mDoMemCdRWm_TestCheckSumGameData(save); diff --git a/src/dusk/randomizer/game/randomizer_context.cpp b/src/dusk/randomizer/game/randomizer_context.cpp index a845c54f80..64e159a50b 100644 --- a/src/dusk/randomizer/game/randomizer_context.cpp +++ b/src/dusk/randomizer/game/randomizer_context.cpp @@ -278,8 +278,11 @@ std::optional RandomizerContext::LoadFromHash(const std::string& ha } } - DuskLog.debug("Loaded Randomizer Seed {}", this->mHash); - + dusk::ui::push_toast(dusk::ui::Toast{ + .title = "Randomizer", + .content = fmt::format("Loaded Randomizer Seed {}", this->mHash), + .duration = std::chrono::seconds(3), + }); return std::nullopt; } diff --git a/src/dusk/randomizer/game/randomizer_context.hpp b/src/dusk/randomizer/game/randomizer_context.hpp index ee74d1d8c7..7f5fcf8bf0 100644 --- a/src/dusk/randomizer/game/randomizer_context.hpp +++ b/src/dusk/randomizer/game/randomizer_context.hpp @@ -171,6 +171,7 @@ public: void setRoomReloadingState(bool newState) { mRoomReloadingState = newState; } bool mInitialized{false}; + int mFileNum{-1}; u8 mEventItemStatus{}; bool mHasPendingToDChange{false}; u8 mTimeChange{}; diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 0a58dfd1ec..0422c6fcba 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -185,6 +185,12 @@ UserSettings g_userSettings = { ActionBindConfigVar{"actionBindings.turboButton_port2", PAD_NATIVE_BUTTON_INVALID}, ActionBindConfigVar{"actionBindings.turboButton_port3", PAD_NATIVE_BUTTON_INVALID}, }, + }, + + .randomizer = { + ConfigVar{"randomizer.file1SeedHash", ""}, + ConfigVar{"randomizer.file2SeedHash", ""}, + ConfigVar{"randomizer.file3SeedHash", ""}, } }; @@ -339,6 +345,10 @@ void registerSettings() { Register(g_userSettings.actionBindings.turboSpeedButton[1]); Register(g_userSettings.actionBindings.turboSpeedButton[2]); Register(g_userSettings.actionBindings.turboSpeedButton[3]); + + Register(g_userSettings.randomizer.seedHashes[0]); + Register(g_userSettings.randomizer.seedHashes[1]); + Register(g_userSettings.randomizer.seedHashes[2]); } // Transient settings diff --git a/src/dusk/ui/rando_config.cpp b/src/dusk/ui/rando_config.cpp index 3a9187865a..842969f00a 100644 --- a/src/dusk/ui/rando_config.cpp +++ b/src/dusk/ui/rando_config.cpp @@ -16,6 +16,8 @@ #include "rando_seed_generation.hpp" #include "string_button.hpp" +#include "d/d_file_select.h" + namespace dusk::ui { struct ConfigBoolProps { Rml::String key; @@ -682,111 +684,131 @@ bool focus_closest_child_on_next_pane(Pane& currentPane, Pane& nextPane) { return false; } -RandomizerWindow::RandomizerWindow() { +void delete_seed_callback(Pane& pane) { + pane.clear(); + std::filesystem::path seedDirectory = GetRandomizerSeedsPath(); + + if (std::filesystem::is_empty(seedDirectory)) { + pane.add_rml( + "No seeds generated."); + return; + } + + pane.add_rml( + "Delete any seed not currently being used."); + + for (const auto& entry : std::filesystem::directory_iterator(seedDirectory)) { + if (entry.is_directory()) { + std::string hash = entry.path().filename().string(); + + // If the hash is attached to any files, add the file number(s) afterward + auto& seedHashes = getSettings().randomizer.seedHashes; + auto hashCopy = hash; + for (int i = 0; i < seedHashes.size(); ++i) { + if (seedHashes[i].getValue() == hashCopy) { + hash += " (File " + std::to_string(i + 1) + ")"; + } + } + + // TODO: our ui lib doesnt have an easy way to either refresh or remove values from the right pane + pane.add_button( + { + .text = hash, + .isDisabled = [hash] { + return !playerIsOnTitleScreen() || hash.ends_with(')'); + } + }) + .on_pressed([entry, &pane] { + std::filesystem::remove_all(entry); + delete_seed_callback(pane); + }); + } + } +}; + +RandomizerWindow::RandomizerWindow(dFile_select_c* fileSelect /*= nullptr*/) : mFileSelectMenu(fileSelect) { // Create rando directories if they don't exist if (!std::filesystem::exists(GetRandomizerSeedsPath())) { std::filesystem::create_directories(GetRandomizerSeedsPath()); } + // If we're bringing this menu up during file selection + if (mFileSelectMenu) { + // Don't allow going back to the main dusklight menu while this menu + // is active + mTabBar->listen(Rml::EventId::Keydown, [](Rml::Event& event) { + auto cmd = map_nav_event(event); + if (cmd == NavCommand::Menu || cmd == NavCommand::Cancel) { + event.StopPropagation(); + } + }); + + add_tab("Play", [this](Rml::Element* content) { + auto& leftPane = add_child(content, Pane::Type::Controlled); + auto& rightPane = add_child(content, Pane::Type::Controlled); + + leftPane.register_control( + leftPane.add_select_button({ + .key = "Selected Seed", + .getValue = + [] { + return randomizer_GetContext().mHash.empty() ? + "None" : + randomizer_GetContext().mHash; + }, + }), + rightPane, [](Pane& pane) { + std::filesystem::path seedDirectory = GetRandomizerSeedsPath(); + + if (std::filesystem::is_empty(seedDirectory)) { + pane.add_rml( + "No seeds generated! You can generate a seed from the Seed Management Tab."); + return; + } + + pane.add_rml( + "Choose which seed you want to play."); + + for (const auto& entry : std::filesystem::directory_iterator(seedDirectory)) { + if (entry.is_directory()) { + std::string hash = entry.path().filename().string(); + + pane.add_button( + { + .text = hash, + .isSelected = [hash] { + return randomizer_GetContext().mHash == hash; + }, + }) + .on_pressed([hash] { + randomizer_GetContext() = RandomizerContext(); + randomizer_GetContext().LoadFromHash(hash); + }); + } + } + }); + + leftPane.add_button({ + .text = "Start Randomizer", + .isDisabled = []{return randomizer_GetContext().mHash.empty();}, + }) + .on_pressed([this]{ + if (mFileSelectMenu) { + mFileSelectMenu->mDusk.mBackToFileSelect = false; + } + mDoAud_seStartMenu(Z2SE_SY_CURSOR_OK); + this->hide(true); + }); + }); + } + add_tab("Seed Management", [this](Rml::Element* content) { auto& leftPane = add_child(content, Pane::Type::Controlled); auto& rightPane = add_child(content, Pane::Type::Controlled); - leftPane.register_control( - leftPane.add_select_button({ - .key = "Selected Seed", - .getValue = - [] { - return randomizer_GetContext().mHash.empty() ? - "None" : - randomizer_GetContext().mHash; - }, - }), - rightPane, [](Pane& pane) { - std::filesystem::path seedDirectory = GetRandomizerSeedsPath(); - - if (std::filesystem::is_empty(seedDirectory)) { - pane.add_rml( - "No seeds generated! Check out the options tab and generate a seed using the button below."); - return; - } - - pane.add_rml( - "Apply a seed generated using the randomizer generator. (Note: must be done before selecting a save file)."); - - for (const auto& entry : std::filesystem::directory_iterator(seedDirectory)) { - if (entry.is_directory()) { - std::string hash = entry.path().filename().string(); - - pane.add_button( - { - .text = hash, - .isSelected = [hash] { - return randomizer_GetContext().mHash == hash; - }, - }) - .on_pressed([hash] { - randomizer_GetContext() = RandomizerContext(); - randomizer_GetContext().LoadFromHash(hash); - }); - } - } - }); - - leftPane.register_control( - leftPane.add_button("Delete Seeds"), - rightPane, [](Pane& pane) { - std::filesystem::path seedDirectory = GetRandomizerSeedsPath(); - - if (std::filesystem::is_empty(seedDirectory)) { - pane.add_rml( - "No seeds generated."); - return; - } - - pane.add_rml( - "Delete any seed currently not active in the randomizer."); - - for (const auto& entry : std::filesystem::directory_iterator(seedDirectory)) { - if (entry.is_directory()) { - std::string hash = entry.path().filename().string(); - - // TODO: our ui lib doesnt have an easy way to either refresh or remove values from the right pane - pane.add_button( - { - .text = hash, - .isDisabled = [hash] { - return !playerIsOnTitleScreen() || randomizer_GetContext().mHash == hash; - } - }) - .on_pressed([hash, entry] { - if (randomizer_GetContext().mHash != hash) { - std::filesystem::remove_all(entry); - } else if (!randomizer_IsActive()){ - // If the user selected the currently seed, but it's not active, we'll allow the delete - std::filesystem::remove_all(entry); - randomizer_GetContext() = RandomizerContext(); - } - }); - } - } - }); - - leftPane.register_control(leftPane.add_button(ControlledButton::Props{ - .text = "Deactivate Seed", - .isDisabled = [] { return randomizer_GetContext().mHash.empty() || !playerIsOnTitleScreen(); } - }).on_pressed([] { - if (!randomizer_IsActive()) { - randomizer_GetContext() = RandomizerContext(); - } - }), rightPane, [](Pane& pane) { - pane.clear(); - pane.add_rml("Disables currently chosen seed."); - }); - leftPane.register_control(leftPane.add_button("Generate Seed").on_pressed( - [this, &rightPane] { + [] { if (TryCreateRandomSeed()) { DuskLog.info("Created new Seed for generator."); } @@ -800,21 +822,26 @@ RandomizerWindow::RandomizerWindow() { }); leftPane.register_control(leftPane.add_child(StringButton::Props{ - .key = "Seed String", - .getValue = [] { - return GetRandomizerConfig().GetSeed(); - }, - .setValue = [](Rml::String value) { - GetRandomizerConfig().SetSeed(value); - SaveRandomizerConfig(); - }, - .maxLength = 32, - }), - rightPane, [](Pane& pane) { - pane.clear(); - pane.add_rml( - "Current value of the seed used by the randomizer for generation. Leave blank for a random value."); - }); + .key = "Seed String", + .getValue = [] { + return GetRandomizerConfig().GetSeed(); + }, + .setValue = [](Rml::String value) { + GetRandomizerConfig().SetSeed(value); + SaveRandomizerConfig(); + }, + .maxLength = 32, + }), + rightPane, [](Pane& pane) { + pane.clear(); + pane.add_rml( + "Current value of the seed used by the randomizer for generation. Leave blank for a random value."); + }); + + leftPane.register_control( + leftPane.add_button("Delete Seeds"), + rightPane, delete_seed_callback + ); }); add_tab("Seed Options", [this](Rml::Element* content) { @@ -1141,6 +1168,14 @@ RandomizerWindow::RandomizerWindow() { } } +FileSelectRandomizerWindow::FileSelectRandomizerWindow(dFile_select_c* fileSelectMenu) : + RandomizerWindow(fileSelectMenu) { } + +bool FileSelectRandomizerWindow::consume_close_request() { + hide(true); + return true; +} + std::filesystem::path GetRandomizerPath() { return data::configured_data_path() / "randomizer"; } diff --git a/src/dusk/ui/rando_config.hpp b/src/dusk/ui/rando_config.hpp index 46518a35be..2cf59082fb 100644 --- a/src/dusk/ui/rando_config.hpp +++ b/src/dusk/ui/rando_config.hpp @@ -5,6 +5,7 @@ namespace randomizer::seedgen::config { class Config; } +class dFile_select_c; namespace dusk::ui { class Pane; @@ -19,10 +20,21 @@ class Pane; class RandomizerWindow : public Window { public: - RandomizerWindow(); + explicit RandomizerWindow(dFile_select_c* fileSelectMenu = nullptr); void rando_excluded_locations_update_left_pane(Pane& innerLeftPane, Pane& rightPane, bool forceUpdate = false); auto& get_locations_for_left_pane(); + + protected: + dFile_select_c* mFileSelectMenu{nullptr}; private: std::string m_excludedLocationsFilter{}; }; + + class FileSelectRandomizerWindow : public RandomizerWindow { + public: + FileSelectRandomizerWindow(dFile_select_c* fileSelectMenu = nullptr); + + protected: + bool consume_close_request() override; + }; } diff --git a/src/f_pc/f_pc_manager.cpp b/src/f_pc/f_pc_manager.cpp index 3cc923a492..f095597b57 100644 --- a/src/f_pc/f_pc_manager.cpp +++ b/src/f_pc/f_pc_manager.cpp @@ -100,8 +100,6 @@ void fpcM_Management(fpcM_ManagementFunc i_preExecuteFn, fpcM_ManagementFunc i_p g_randomizerState._create(); } g_randomizerState.execute(); - } else if (g_randomizerState.mInitialized) { - g_randomizerState = RandomizerState{}; } #endif if (!fapGm_HIO_c::isCaptureScreen()) {