mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-20 14:44:24 -04:00
overhaul seed selection to be on file creation
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -289,6 +289,11 @@ struct UserSettings {
|
||||
std::array<ActionBindConfigVar, 4> openDusklightMenu;
|
||||
std::array<ActionBindConfigVar, 4> turboSpeedButton;
|
||||
} actionBindings;
|
||||
|
||||
// Randomizer seed hashes, 1 per file
|
||||
struct {
|
||||
std::array<ConfigVar<std::string>, 3> seedHashes;
|
||||
} randomizer;
|
||||
};
|
||||
|
||||
UserSettings& getSettings();
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -2984,6 +2984,7 @@ void dComIfGs_setupRandomizerSave() {
|
||||
execItemGet(itemId);
|
||||
}
|
||||
|
||||
g_randomizerState = RandomizerState();
|
||||
DuskLog.debug("Created Rando Save");
|
||||
randoData.mCreatingSave = false;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+137
-2
@@ -23,7 +23,13 @@
|
||||
#include "m_Do/m_Do_graphic.h"
|
||||
#include <cstring>
|
||||
|
||||
#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>(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<dusk::ui::FileSelectRandomizerWindow>(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,
|
||||
|
||||
+15
-2
@@ -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);
|
||||
|
||||
@@ -278,8 +278,11 @@ std::optional<std::string> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,6 +171,7 @@ public:
|
||||
void setRoomReloadingState(bool newState) { mRoomReloadingState = newState; }
|
||||
|
||||
bool mInitialized{false};
|
||||
int mFileNum{-1};
|
||||
u8 mEventItemStatus{};
|
||||
bool mHasPendingToDChange{false};
|
||||
u8 mTimeChange{};
|
||||
|
||||
@@ -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<std::string>{"randomizer.file1SeedHash", ""},
|
||||
ConfigVar<std::string>{"randomizer.file2SeedHash", ""},
|
||||
ConfigVar<std::string>{"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
|
||||
|
||||
+144
-109
@@ -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<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(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<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(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>(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";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user