mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-04-23 08:14:31 +00:00
Integrate Randomizer Window into Modern Menu Properly (#6017)
Also comes with a menu reorganization
This commit is contained in:
parent
9e6c9a478e
commit
14a241ed3f
|
|
@ -1,7 +1,7 @@
|
|||
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
#include "soh/Enhancements/randomizer/SeedContext.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include "soh/SohGui/MenuTypes.h"
|
||||
#include "soh/SohGui/SohMenu.h"
|
||||
#include "soh/SohGui/SohGui.hpp"
|
||||
#include "soh/Enhancements/randomizer/randomizer_settings_window.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_check_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_item_tracker.h"
|
||||
|
|
@ -20,7 +19,6 @@ namespace fs = std::filesystem;
|
|||
|
||||
namespace SohGui {
|
||||
extern std::shared_ptr<SohMenu> mSohMenu;
|
||||
extern std::shared_ptr<RandomizerSettingsWindow> mRandomizerSettingsWindow;
|
||||
} // namespace SohGui
|
||||
|
||||
struct PresetInfo {
|
||||
|
|
@ -124,7 +122,7 @@ void applyPreset(std::string presetName, std::vector<PresetSection> includeSecti
|
|||
}
|
||||
}
|
||||
if (i == PRESET_SECTION_RANDOMIZER) {
|
||||
SohGui::mRandomizerSettingsWindow->SetNeedsUpdate();
|
||||
Rando::Settings::GetInstance()->UpdateAllOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
#include "soh/Enhancements/randomizer/SeedContext.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
#include "soh/Enhancements/randomizer/SeedContext.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "functions.h"
|
||||
#include "macros.h"
|
||||
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
#include "soh/Enhancements/randomizer/SeedContext.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "variables.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "fill.hpp"
|
||||
|
||||
#include "../dungeon.h"
|
||||
#include "../context.h"
|
||||
#include "../SeedContext.h"
|
||||
#include "item_pool.hpp"
|
||||
#include "random.hpp"
|
||||
#include "spoiler_log.hpp"
|
||||
|
|
|
|||
|
|
@ -74,3 +74,5 @@ void GeneratePlaythrough();
|
|||
bool CheckBeatable(RandomizerGet ignore = RG_NONE);
|
||||
|
||||
void ValidateEntrances(bool checkOtherEntranceAccess);
|
||||
|
||||
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include "custom_messages.hpp"
|
||||
|
||||
#include "../randomizerTypes.h"
|
||||
#include "../context.h"
|
||||
#include "../SeedContext.h"
|
||||
#include "../static_data.h"
|
||||
|
||||
using namespace CustomMessages;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "../dungeon.h"
|
||||
#include "fill.hpp"
|
||||
#include "../static_data.h"
|
||||
#include "../context.h"
|
||||
#include "../SeedContext.h"
|
||||
#include "pool_functions.hpp"
|
||||
#include "random.hpp"
|
||||
#include "spoiler_log.hpp"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "../context.h"
|
||||
#include "../SeedContext.h"
|
||||
|
||||
namespace Playthrough {
|
||||
int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
|
||||
std::set<RandomizerTrick> enabledTricks);
|
||||
int Playthrough_Repeat(std::set<RandomizerCheck> excludedLocations, std::set<RandomizerTrick> enabledTricks,
|
||||
int count = 1);
|
||||
} // namespace Playthrough
|
||||
} // namespace Playthrough
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include "../item_location.h"
|
||||
#include "../location_access.h"
|
||||
#include "rando_main.hpp"
|
||||
#include "../context.h"
|
||||
#include "../SeedContext.h"
|
||||
#include <libultraship/bridge.h>
|
||||
#include <ship/Context.h>
|
||||
#include <libultraship/libultra/types.h>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "soh/Enhancements/randomizer/item.h"
|
||||
|
||||
#include <set>
|
||||
namespace RandoMain {
|
||||
void GenerateRando(std::set<RandomizerCheck> excludedLocations, std::set<RandomizerTrick> enabledTricks,
|
||||
std::string seedInput);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
#include "../context.h"
|
||||
#include "../SeedContext.h"
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ std::string RemoveLineBreaks(std::string s) {
|
|||
static void WriteExcludedLocations() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
|
||||
for (size_t i = 1; i < Rando::Settings::GetInstance()->GetExcludeLocationsOptions().size(); i++) {
|
||||
for (size_t i = 0; i < Rando::Settings::GetInstance()->GetExcludeLocationsOptions().size() - 1; i++) {
|
||||
for (const auto& location : Rando::Settings::GetInstance()->GetExcludeLocationsOptions()[i]) {
|
||||
if (ctx->GetLocationOption(static_cast<RandomizerCheck>(location->GetKey())).Get() == RO_LOCATION_INCLUDE) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "starting_inventory.hpp"
|
||||
|
||||
#include "../dungeon.h"
|
||||
#include "../context.h"
|
||||
#include "../SeedContext.h"
|
||||
#include "../logic.h"
|
||||
#include "pool_functions.hpp"
|
||||
#include "soh/Enhancements/randomizer/static_data.h"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include "static_data.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/item-tables/ItemTableManager.h"
|
||||
|
|
@ -620,4 +620,4 @@ uint32_t Context::GetSeed() const {
|
|||
void Context::SetSeed(const uint32_t seed) {
|
||||
mFinalSeed = seed;
|
||||
}
|
||||
} // namespace Rando
|
||||
} // namespace Rando
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "3drando/pool_functions.hpp"
|
||||
#include "static_data.h"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
|
||||
namespace Rando {
|
||||
DungeonInfo::DungeonInfo(std::string name_, const RandomizerHintTextKey hintKey_, const RandomizerGet map_,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
|
|
@ -157,4 +158,4 @@ extern "C" {
|
|||
EntranceOverride* Randomizer_GetEntranceOverrides();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include "hint.h"
|
||||
#include "map"
|
||||
#include "string"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
#include "static_data.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "item.h"
|
||||
#include "item_location.h"
|
||||
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include "logic.h"
|
||||
#include "3drando/item_pool.hpp"
|
||||
#include "z64item.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "static_data.h"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include "logic.h"
|
||||
#include "z64object.h"
|
||||
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "item_location.h"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include "logic.h"
|
||||
|
||||
namespace Rando {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "soh/Enhancements/randomizer/dungeon.h"
|
||||
#include "soh/Enhancements/randomizer/static_data.h"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
#include "soh/Enhancements/randomizer/SeedContext.h"
|
||||
#include "soh/Enhancements/randomizer/3drando/item_pool.hpp"
|
||||
#include "soh/Enhancements/randomizer/3drando/spoiler_log.hpp"
|
||||
#include "soh/Enhancements/randomizer/trial.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <set>
|
||||
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
#include "soh/Enhancements/randomizer/SeedContext.h"
|
||||
#include "soh/Enhancements/randomizer/logic.h"
|
||||
|
||||
#define TIME_PASSES true
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "static_data.h"
|
||||
#include "z64save.h"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include "dungeon.h"
|
||||
|
||||
std::array<Rando::Location, RC_MAX> Rando::StaticData::locationTable;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "dungeon.h"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include "macros.h"
|
||||
#include "variables.h"
|
||||
#include <spdlog/spdlog.h>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace Rando {
|
||||
|
|
|
|||
|
|
@ -2,34 +2,60 @@
|
|||
#include "libultraship/bridge.h"
|
||||
#include <ship/Context.h>
|
||||
#include <imgui.h>
|
||||
#include "soh/Enhancements/randomizer/settings.h"
|
||||
#include "soh/SohGui/SohGui.hpp"
|
||||
#include "soh/SohGui/SohMenu.h"
|
||||
#include "soh/SohGui/UIWidgets.hpp"
|
||||
#include <soh/cvar_prefixes.h>
|
||||
|
||||
namespace SohGui {
|
||||
extern std::shared_ptr<SohMenu> mSohMenu;
|
||||
}
|
||||
|
||||
namespace Rando {
|
||||
Option Option::Bool(RandomizerSettingKey key_, std::string name_, std::vector<std::string> options_,
|
||||
const OptionCategory category_, std::string cvarName_, std::string description_,
|
||||
WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_, int imFlags_) {
|
||||
return { static_cast<size_t>(key_), std::move(name_), std::move(options_), category_, std::move(cvarName_),
|
||||
std::move(description_), widgetType_, defaultOption_, defaultHidden_, imFlags_ };
|
||||
WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_,
|
||||
WidgetFunc callback_, int imFlags_) {
|
||||
return { static_cast<size_t>(key_),
|
||||
std::move(name_),
|
||||
std::move(options_),
|
||||
category_,
|
||||
std::move(cvarName_),
|
||||
std::move(description_),
|
||||
widgetType_,
|
||||
defaultOption_,
|
||||
defaultHidden_,
|
||||
callback_,
|
||||
imFlags_ };
|
||||
}
|
||||
|
||||
Option Option::Bool(RandomizerSettingKey key_, std::string name_, std::string cvarName_, std::string description_,
|
||||
const int imFlags_, const WidgetType widgetType_, const bool defaultOption_) {
|
||||
const int imFlags_, const WidgetType widgetType_, const bool defaultOption_, WidgetFunc callback_) {
|
||||
return Option(key_, std::move(name_), { "Off", "On" }, OptionCategory::Setting, std::move(cvarName_),
|
||||
std::move(description_), widgetType_, defaultOption_, false, imFlags_);
|
||||
std::move(description_), widgetType_, defaultOption_, false, callback_, imFlags_);
|
||||
}
|
||||
|
||||
Option Option::U8(RandomizerSettingKey key_, std::string name_, std::vector<std::string> options_,
|
||||
const OptionCategory category_, std::string cvarName_, std::string description_,
|
||||
WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_, int imFlags_) {
|
||||
return { static_cast<size_t>(key_), std::move(name_), std::move(options_), category_, std::move(cvarName_),
|
||||
std::move(description_), widgetType_, defaultOption_, defaultHidden_, imFlags_ };
|
||||
WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_, WidgetFunc callback_,
|
||||
int imFlags_) {
|
||||
return { static_cast<size_t>(key_),
|
||||
std::move(name_),
|
||||
std::move(options_),
|
||||
category_,
|
||||
std::move(cvarName_),
|
||||
std::move(description_),
|
||||
widgetType_,
|
||||
defaultOption_,
|
||||
defaultHidden_,
|
||||
callback_,
|
||||
imFlags_ };
|
||||
}
|
||||
|
||||
Option Option::LogicTrick(RandomizerTrick rt_, std::string name_) {
|
||||
return Option(rt_, std::move(name_), { "Disabled", "Enabled" }, OptionCategory::Setting, "", "",
|
||||
WidgetType::Checkbox, 0, false, IMFLAG_NONE);
|
||||
WIDGET_CVAR_CHECKBOX, 0, false, nullptr, IMFLAG_NONE);
|
||||
}
|
||||
|
||||
OptionValue::OptionValue(uint8_t val) : mVal(val) {
|
||||
|
|
@ -125,24 +151,6 @@ bool Option::IsCategory(const OptionCategory category) const {
|
|||
return category == this->category;
|
||||
}
|
||||
|
||||
bool Option::RenderImGui() {
|
||||
bool changed = false;
|
||||
ImGui::BeginGroup();
|
||||
switch (widgetType) {
|
||||
case WidgetType::Checkbox:
|
||||
changed = RenderCheckbox();
|
||||
break;
|
||||
case WidgetType::Combobox:
|
||||
changed = RenderCombobox();
|
||||
break;
|
||||
case WidgetType::Slider:
|
||||
changed = RenderSlider();
|
||||
break;
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool Option::HasFlag(const int imFlag_) const {
|
||||
return imFlag_ & imFlags;
|
||||
}
|
||||
|
|
@ -180,12 +188,52 @@ void Option::SetContextIndexFromText(const std::string text) {
|
|||
|
||||
Option::Option(size_t key_, std::string name_, std::vector<std::string> options_, OptionCategory category_,
|
||||
std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_,
|
||||
bool defaultHidden_, int imFlags_)
|
||||
bool defaultHidden_, WidgetFunc callback_, int imFlags_)
|
||||
: key(key_), name(std::move(name_)), options(std::move(options_)), category(category_),
|
||||
cvarName(std::move(cvarName_)), description(std::move(description_)), widgetType(widgetType_),
|
||||
defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_) {
|
||||
defaultOption(defaultOption_), defaultHidden(defaultHidden_), callback(callback_), imFlags(imFlags_) {
|
||||
contextSelection = defaultOption;
|
||||
hidden = defaultHidden;
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
optionsMap.emplace(i, options[i].c_str());
|
||||
}
|
||||
UIWidgets::LabelPositions labelPosition;
|
||||
switch (widgetType) {
|
||||
case WIDGET_CVAR_CHECKBOX:
|
||||
// labelPosition = UIWidgets::LabelPositions::Near;
|
||||
// if (imFlags_ & IMFLAG_LABEL_INLINE) {
|
||||
// labelPosition = UIWidgets::LabelPositions::Near;
|
||||
// }
|
||||
widgetOptions = std::make_shared<UIWidgets::CheckboxOptions>(
|
||||
UIWidgets::CheckboxOptions().DefaultValue(defaultOption).Tooltip(description.c_str()));
|
||||
break;
|
||||
case WIDGET_CVAR_COMBOBOX:
|
||||
labelPosition = UIWidgets::LabelPositions::Above;
|
||||
if (imFlags_ & IMFLAG_LABEL_INLINE) {
|
||||
labelPosition = UIWidgets::LabelPositions::Near;
|
||||
}
|
||||
widgetOptions = std::make_shared<UIWidgets::ComboboxOptions>(UIWidgets::ComboboxOptions()
|
||||
.DefaultIndex(defaultOption)
|
||||
.ComboMap(optionsMap)
|
||||
.Tooltip(description.c_str())
|
||||
.LabelPosition(labelPosition));
|
||||
break;
|
||||
case WIDGET_CVAR_SLIDER_INT:
|
||||
labelPosition = UIWidgets::LabelPositions::Above;
|
||||
if (imFlags_ & IMFLAG_LABEL_INLINE) {
|
||||
labelPosition = UIWidgets::LabelPositions::Near;
|
||||
}
|
||||
widgetOptions = std::make_shared<UIWidgets::IntSliderOptions>(UIWidgets::IntSliderOptions()
|
||||
.DefaultValue(defaultOption)
|
||||
.Tooltip(description.c_str())
|
||||
.Min(0)
|
||||
.Max(options.size() - 1)
|
||||
.Format(options[defaultOption].c_str())
|
||||
.LabelPosition(labelPosition));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
PopulateTextToNum();
|
||||
}
|
||||
|
||||
|
|
@ -260,15 +308,49 @@ bool Option::RenderSlider() {
|
|||
return changed;
|
||||
}
|
||||
|
||||
void Option::AddWidget(WidgetPath& path) {
|
||||
auto widget = SohGui::mSohMenu->AddWidget(path, name, widgetType)
|
||||
.Callback(callback)
|
||||
.PreFunc([this](WidgetInfo& info) {
|
||||
info.isHidden = this->IsHidden();
|
||||
info.options->disabled = this->disabled;
|
||||
info.options->disabledTooltip = this->disabledText.c_str();
|
||||
info.options->tooltip = this->description.c_str();
|
||||
if (info.type == WIDGET_CVAR_SLIDER_INT) {
|
||||
UIWidgets::IntSliderOptions* sliderOpts =
|
||||
(UIWidgets::IntSliderOptions*)info.options.get();
|
||||
sliderOpts->Format(this->GetOptionText(this->GetOptionIndex()).c_str());
|
||||
sliderOpts->Max(this->options.size() - 1);
|
||||
}
|
||||
})
|
||||
.CVar(cvarName.c_str())
|
||||
.Options(widgetOptions)
|
||||
.SameLine(imFlags & IMFLAG_SAME_LINE);
|
||||
widgetInfo = widget;
|
||||
if (callback != nullptr) {
|
||||
callback(widgetInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void Option::PopulateTextToNum() {
|
||||
for (uint8_t count = 0; count < options.size(); count++) {
|
||||
optionsTextToVar[options[count]] = count;
|
||||
}
|
||||
}
|
||||
|
||||
void Option::SetCallback(WidgetFunc callback) {
|
||||
this->callback = callback;
|
||||
}
|
||||
|
||||
void Option::RunCallback() {
|
||||
if (callback != nullptr) {
|
||||
this->callback(widgetInfo);
|
||||
}
|
||||
}
|
||||
|
||||
LocationOption::LocationOption(RandomizerCheck key_, const std::string& name_)
|
||||
: Option(key_, name_, { "Included", "Excluded" }, OptionCategory::Setting, "", "", WidgetType::Checkbox,
|
||||
RO_LOCATION_INCLUDE, false, IMFLAG_NONE) {
|
||||
: Option(key_, name_, { "Included", "Excluded" }, OptionCategory::Setting, "", "", WIDGET_CVAR_CHECKBOX,
|
||||
RO_LOCATION_INCLUDE, false, nullptr, IMFLAG_NONE) {
|
||||
}
|
||||
|
||||
RandomizerCheck LocationOption::GetKey() const {
|
||||
|
|
@ -278,7 +360,7 @@ RandomizerCheck LocationOption::GetKey() const {
|
|||
TrickOption::TrickOption(RandomizerTrick key_, const RandomizerCheckQuest quest_, const RandomizerArea area_,
|
||||
std::set<Tricks::Tag> tags_, const std::string& name_, std::string description_)
|
||||
: Option(key_, name_, { "Disabled", "Enabled" }, OptionCategory::Setting, "", std::move(description_),
|
||||
WidgetType::Checkbox, 0, false, IMFLAG_NONE),
|
||||
WIDGET_CVAR_CHECKBOX, 0, false, nullptr, IMFLAG_NONE),
|
||||
mQuest(quest_), mArea(area_), mTags(std::move(tags_)) {
|
||||
}
|
||||
|
||||
|
|
@ -365,75 +447,29 @@ void OptionGroup::Disable() {
|
|||
mDisabled = true;
|
||||
}
|
||||
|
||||
bool OptionGroup::RenderImGui() const { // NOLINT(*-no-recursion)
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
bool changed = false;
|
||||
ImGui::BeginDisabled(mDisabled || CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) ||
|
||||
CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) ||
|
||||
CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0));
|
||||
void OptionGroup::AddWidgets(WidgetPath& path) const {
|
||||
if (mContainerType == WidgetContainerType::TABLE) {
|
||||
if (ImGui::BeginTable(mName.c_str(), static_cast<int>(mSubGroups.size()),
|
||||
ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
for (const auto column : mSubGroups) {
|
||||
if (column->GetContainerType() == WidgetContainerType::COLUMN) {
|
||||
ImGui::TableSetupColumn(column->GetName().c_str(), ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
}
|
||||
}
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_NoNav, true);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
for (int i = 0; i < mSubGroups.size(); i++) {
|
||||
ImGui::TableSetColumnIndex(i);
|
||||
ImGui::TableHeader(mSubGroups[i]->GetName().c_str());
|
||||
if (!mSubGroups[i]->GetDescription().empty()) {
|
||||
UIWidgets::Tooltip(mSubGroups[i]->GetDescription().c_str());
|
||||
}
|
||||
}
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::TableNextRow();
|
||||
}
|
||||
path.column = SECTION_COLUMN_1;
|
||||
path.sidebarName = mName;
|
||||
SohGui::mSohMenu->AddSidebarEntry("Randomizer", path.sidebarName, mSubGroups.size());
|
||||
}
|
||||
if (mContainerType == WidgetContainerType::SECTION && !mName.empty()) {
|
||||
ImGui::SeparatorText(mName.c_str());
|
||||
if (!mDescription.empty()) {
|
||||
UIWidgets::Tooltip(mDescription.c_str());
|
||||
if (mContainerType == WidgetContainerType::SECTION || mContainerType == WidgetContainerType::COLUMN) {
|
||||
if (!mName.empty()) {
|
||||
SohGui::mSohMenu->AddWidget(path, mName.c_str(), WIDGET_SEPARATOR_TEXT);
|
||||
}
|
||||
}
|
||||
if (mContainerType == WidgetContainerType::COLUMN) {
|
||||
ImGui::TableNextColumn();
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
ImGui::BeginChild(mName.c_str(), ImVec2(0, -8));
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
}
|
||||
if (mContainsType == OptionGroupType::SUBGROUP) {
|
||||
for (const auto optionGroup : mSubGroups) {
|
||||
if (optionGroup->RenderImGui()) {
|
||||
changed = true;
|
||||
}
|
||||
optionGroup->AddWidgets(path);
|
||||
}
|
||||
} else {
|
||||
for (const auto option : mOptions) {
|
||||
if (option->IsHidden()) {
|
||||
continue;
|
||||
}
|
||||
if (option->HasFlag(IMFLAG_INDENT)) {
|
||||
ImGui::Indent();
|
||||
}
|
||||
// If any options changed, changed will end up being true
|
||||
if (option->RenderImGui()) {
|
||||
changed = true;
|
||||
}
|
||||
if (option->HasFlag(IMFLAG_UNINDENT)) {
|
||||
ImGui::Unindent();
|
||||
}
|
||||
option->AddWidget(path);
|
||||
}
|
||||
}
|
||||
if (mContainerType == WidgetContainerType::COLUMN) {
|
||||
ImGui::EndChild();
|
||||
assert(path.column < 3);
|
||||
path.column = static_cast<SectionColumns>(path.column + 1);
|
||||
}
|
||||
if (mContainerType == WidgetContainerType::TABLE) {
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
return changed;
|
||||
}
|
||||
} // namespace Rando
|
||||
|
|
@ -8,11 +8,11 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <type_traits>
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include "tricks.h"
|
||||
#include "soh/SohGui/MenuTypes.h"
|
||||
|
||||
namespace Rando {
|
||||
enum ImGuiMenuFlags {
|
||||
|
|
@ -21,6 +21,8 @@ enum ImGuiMenuFlags {
|
|||
IMFLAG_SEPARATOR_TOP = 1 << 1, /** Adds a padded separator above the widget. */
|
||||
IMFLAG_INDENT = 1 << 2, /** Indents this widget and all proceeding widgets. */
|
||||
IMFLAG_UNINDENT = 1 << 3, /** Unindents this widget and all proceeding widgets. */
|
||||
IMFLAG_SAME_LINE = 1 << 4,
|
||||
IMFLAG_LABEL_INLINE = 1 << 5,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -33,16 +35,6 @@ enum class OptionCategory {
|
|||
for randomizing the values of other options. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Controls how this option is rendered in the menu.
|
||||
*/
|
||||
enum class WidgetType {
|
||||
Checkbox, /** Default for Bools, not compatible if options.size() > 2. */
|
||||
Combobox, /** Default for U8s, works with U8s and Bools. */
|
||||
Slider, /** Compatible with U8s. If constructed with NumOpts, consider using this. Technically can be used for Bool
|
||||
or non-NumOpts options but it would be a bit weird semantically. */
|
||||
};
|
||||
|
||||
class OptionValue {
|
||||
public:
|
||||
OptionValue() = default;
|
||||
|
|
@ -127,8 +119,9 @@ class Option {
|
|||
static Option Bool(RandomizerSettingKey key_, std::string name_,
|
||||
std::vector<std::string> options_ = { "Off", "On" },
|
||||
OptionCategory category_ = OptionCategory::Setting, std::string cvarName_ = "",
|
||||
std::string description_ = "", WidgetType widgetType_ = WidgetType::Checkbox,
|
||||
uint8_t defaultOption_ = 0, bool defaultHidden_ = false, int imFlags_ = IMFLAG_SEPARATOR_BOTTOM);
|
||||
std::string description_ = "", WidgetType widgetType_ = WIDGET_CVAR_CHECKBOX,
|
||||
uint8_t defaultOption_ = 0, bool defaultHidden_ = false, WidgetFunc callback_ = nullptr,
|
||||
int imFlags_ = IMFLAG_SEPARATOR_BOTTOM);
|
||||
|
||||
/**
|
||||
* @brief Constructs a boolean option. This constructor was added later for convenience so that a cvarName
|
||||
|
|
@ -150,7 +143,8 @@ class Option {
|
|||
*/
|
||||
static Option Bool(RandomizerSettingKey key_, std::string name_, std::string cvarName_,
|
||||
std::string description_ = "", int imFlags_ = IMFLAG_SEPARATOR_BOTTOM,
|
||||
WidgetType widgetType_ = WidgetType::Checkbox, bool defaultOption_ = false);
|
||||
WidgetType widgetType_ = WIDGET_CVAR_CHECKBOX, bool defaultOption_ = false,
|
||||
WidgetFunc callback_ = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Constructs a U8 Option.
|
||||
|
|
@ -175,8 +169,9 @@ class Option {
|
|||
*/
|
||||
static Option U8(RandomizerSettingKey key_, std::string name_, std::vector<std::string> options_,
|
||||
OptionCategory category_ = OptionCategory::Setting, std::string cvarName_ = "",
|
||||
std::string description_ = "", WidgetType widgetType_ = WidgetType::Combobox,
|
||||
uint8_t defaultOption_ = 0, bool defaultHidden_ = false, int imFlags_ = IMFLAG_SEPARATOR_BOTTOM);
|
||||
std::string description_ = "", WidgetType widgetType_ = WIDGET_CVAR_COMBOBOX,
|
||||
uint8_t defaultOption_ = 0, bool defaultHidden_ = false, WidgetFunc callback_ = nullptr,
|
||||
int imFlags_ = IMFLAG_SEPARATOR_BOTTOM);
|
||||
|
||||
/**
|
||||
* @brief A convenience function for constructing the Option for a trick.
|
||||
|
|
@ -299,13 +294,7 @@ class Option {
|
|||
void Disable(std::string text);
|
||||
bool IsCategory(OptionCategory category) const;
|
||||
|
||||
/**
|
||||
* @brief Automatically renders a widget for this option in ImGui, based on the various
|
||||
* properties of this Option. Typically, Bool options are rendered as Checkboxes and
|
||||
* U8 options are rendered as Comboboxes, but this can be overridden during construction with
|
||||
* the `widgetType` property.
|
||||
*/
|
||||
bool RenderImGui();
|
||||
void AddWidget(WidgetPath& path);
|
||||
|
||||
bool HasFlag(int imFlag_) const;
|
||||
void AddFlag(int imFlag_);
|
||||
|
|
@ -315,10 +304,13 @@ class Option {
|
|||
uint8_t GetValueFromText(std::string text);
|
||||
void SetContextIndexFromText(std::string text);
|
||||
|
||||
void SetCallback(WidgetFunc callback);
|
||||
void RunCallback();
|
||||
|
||||
protected:
|
||||
Option(size_t key_, std::string name_, std::vector<std::string> options_, OptionCategory category_,
|
||||
std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_,
|
||||
bool defaultHidden_, int imFlags_);
|
||||
bool defaultHidden_, WidgetFunc callback_, int imFlags_);
|
||||
size_t key;
|
||||
|
||||
private:
|
||||
|
|
@ -334,13 +326,17 @@ class Option {
|
|||
OptionCategory category = OptionCategory::Setting;
|
||||
std::string cvarName;
|
||||
std::string description;
|
||||
WidgetType widgetType = WidgetType::Checkbox;
|
||||
WidgetType widgetType;
|
||||
uint8_t defaultOption = false;
|
||||
bool defaultHidden = false;
|
||||
int imFlags = IMFLAG_NONE;
|
||||
bool disabled = false;
|
||||
std::string disabledText;
|
||||
std::unordered_map<std::string, uint8_t> optionsTextToVar = {};
|
||||
std::shared_ptr<UIWidgets::WidgetOptions> widgetOptions;
|
||||
struct WidgetInfo widgetInfo;
|
||||
WidgetFunc callback;
|
||||
std::unordered_map<int32_t, const char*> optionsMap = {};
|
||||
};
|
||||
|
||||
class LocationOption : public Option {
|
||||
|
|
@ -515,10 +511,7 @@ class OptionGroup {
|
|||
|
||||
const std::string& GetDescription() const;
|
||||
|
||||
/**
|
||||
* @brief Renders all of the options contained within this `OptionGroup` in the ImGui menu.
|
||||
*/
|
||||
bool RenderImGui() const;
|
||||
void AddWidgets(WidgetPath& path) const;
|
||||
void Disable();
|
||||
void Enable();
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include "soh/SohGui/UIWidgets.hpp"
|
||||
#include "static_data.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "randomizer_settings_window.h"
|
||||
#include "savefile.h"
|
||||
#include "entrance.h"
|
||||
#include "dungeon.h"
|
||||
|
|
@ -4021,672 +4020,11 @@ bool GenerateRandomizer(std::string seed /*= ""*/) {
|
|||
static bool locationsTabOpen = false;
|
||||
static bool tricksTabOpen = false;
|
||||
|
||||
void RandomizerSettingsWindow::DrawElement() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
void JoinRandoGenerationThread() {
|
||||
if (generated) {
|
||||
generated = 0;
|
||||
randoThread.join();
|
||||
}
|
||||
bool generating = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0);
|
||||
bool disableEditingRandoSettings = generating || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0);
|
||||
|
||||
DrawPresetSelector({ PRESET_SECTION_RANDOMIZER }, "Randomizer", generating);
|
||||
|
||||
// UIWidgets::Spacer(0);
|
||||
UIWidgets::CVarCheckbox("Manual seed entry", CVAR_RANDOMIZER_SETTING("ManualSeedEntry"),
|
||||
UIWidgets::CheckboxOptions().Color(THEME_COLOR));
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0)) {
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
ImGui::InputText("##RandomizerSeed", seedString, MAX_SEED_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter,
|
||||
UIWidgets::TextFilters::FilterAlphaNum);
|
||||
UIWidgets::Tooltip("Characters from a-z, A-Z, and 0-9 are supported.\n"
|
||||
"Character limit is 1023, after which the seed will be truncated.\n");
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button(
|
||||
ICON_FA_RANDOM,
|
||||
UIWidgets::ButtonOptions()
|
||||
.Size(UIWidgets::Sizes::Inline)
|
||||
.Color(THEME_COLOR)
|
||||
.Padding(ImVec2(10.f, 6.f))
|
||||
.Tooltip("Creates a new random seed value to be used when generating a randomizer"))) {
|
||||
SohUtils::CopyStringToCharArray(seedString, std::to_string(rand() & 0xFFFFFFFF), MAX_SEED_STRING_SIZE);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button(ICON_FA_ERASER, UIWidgets::ButtonOptions()
|
||||
.Size(UIWidgets::Sizes::Inline)
|
||||
.Color(THEME_COLOR)
|
||||
.Padding(ImVec2(10.f, 6.f)))) {
|
||||
memset(seedString, 0, MAX_SEED_STRING_SIZE);
|
||||
}
|
||||
if (strnlen(seedString, MAX_SEED_STRING_SIZE) == 0) {
|
||||
ImGui::SameLine(17.0f);
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Leave blank for random seed");
|
||||
}
|
||||
UIWidgets::PopStyleInput();
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
UIWidgets::ButtonOptions options = UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR);
|
||||
options.Disabled((gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || GameInteractor::IsSaveLoaded());
|
||||
if (options.disabled) {
|
||||
options.DisabledTooltip("Must be on File Select to generate a randomizer seed.");
|
||||
}
|
||||
if (UIWidgets::Button("Generate Randomizer", options)) {
|
||||
ctx->SetSpoilerLoaded(false);
|
||||
GenerateRandomizer(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0) ? seedString : "");
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
|
||||
std::string spoilerfilepath = CVarGetString(CVAR_GENERAL("SpoilerLog"), "");
|
||||
ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str());
|
||||
}
|
||||
|
||||
UIWidgets::Separator(true, true, 0.f, 0.f);
|
||||
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
static ImVec2 cellPadding(8.0f, 8.0f);
|
||||
|
||||
UIWidgets::PushStyleTabs(THEME_COLOR);
|
||||
if (ImGui::BeginTabBar("Randomizer Settings", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
|
||||
if (ImGui::BeginTabItem("World")) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
if (mSettings->GetOptionGroup(RSG_WORLD_IMGUI_TABLE).RenderImGui()) {
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Items")) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
if (mSettings->GetOptionGroup(RSG_ITEMS_IMGUI_TABLE).RenderImGui()) {
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Gameplay")) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
if (mSettings->GetOptionGroup(RSG_GAMEPLAY_IMGUI_TABLE).RenderImGui()) {
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Locations")) {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
if (!locationsTabOpen) {
|
||||
locationsTabOpen = true;
|
||||
RandomizerCheckObjects::UpdateImGuiVisibility();
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::stringstream excludedLocationStringStream(
|
||||
CVarGetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), ""));
|
||||
std::string excludedLocationString;
|
||||
excludedLocations.clear();
|
||||
while (getline(excludedLocationStringStream, excludedLocationString, ',')) {
|
||||
excludedLocations.insert((RandomizerCheck)std::stoi(excludedLocationString));
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("tableRandoLocations", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("Included", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableSetupColumn("Excluded", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::TableNextRow();
|
||||
|
||||
// COLUMN 1 - INCLUDED LOCATIONS
|
||||
ImGui::TableNextColumn();
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
static ImGuiTextFilter locationSearch;
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
locationSearch.Draw();
|
||||
UIWidgets::PopStyleInput();
|
||||
|
||||
ImGui::BeginChild("ChildIncludedLocations", ImVec2(0, -8));
|
||||
for (auto& [rcArea, locations] : RandomizerCheckObjects::GetAllRCObjectsByArea()) {
|
||||
bool hasItems = false;
|
||||
for (RandomizerCheck rc : locations) {
|
||||
if (ctx->GetItemLocation(rc)->IsVisible() && !excludedLocations.count(rc) &&
|
||||
locationSearch.PassFilter(Rando::StaticData::GetLocation(rc)->GetName().c_str())) {
|
||||
|
||||
hasItems = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasItems) {
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) {
|
||||
for (auto& location : locations) {
|
||||
if (ctx->GetItemLocation(location)->IsVisible() && !excludedLocations.count(location) &&
|
||||
locationSearch.PassFilter(
|
||||
Rando::StaticData::GetLocation(location)->GetName().c_str())) {
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(location).c_str(), ImGuiDir_Right)) {
|
||||
excludedLocations.insert(location);
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::string excludedLocationString = "";
|
||||
for (auto excludedLocationIt : excludedLocations) {
|
||||
excludedLocationString += std::to_string(excludedLocationIt);
|
||||
excludedLocationString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"),
|
||||
excludedLocationString.c_str());
|
||||
Ship::Context::GetInstance()
|
||||
->GetWindow()
|
||||
->GetGui()
|
||||
->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", Rando::StaticData::GetLocation(location)->GetShortName().c_str());
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// COLUMN 2 - EXCLUDED LOCATIONS
|
||||
ImGui::TableNextColumn();
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
ImGui::BeginChild("ChildExcludedLocations", ImVec2(0, -8));
|
||||
for (auto& [rcArea, locations] : RandomizerCheckObjects::GetAllRCObjectsByArea()) {
|
||||
bool hasItems = false;
|
||||
for (RandomizerCheck rc : locations) {
|
||||
if (ctx->GetItemLocation(rc)->IsVisible() && excludedLocations.count(rc)) {
|
||||
hasItems = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasItems) {
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) {
|
||||
for (auto& location : locations) {
|
||||
auto elfound = excludedLocations.find(location);
|
||||
if (ctx->GetItemLocation(location)->IsVisible() && elfound != excludedLocations.end()) {
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(location).c_str(), ImGuiDir_Left)) {
|
||||
excludedLocations.erase(elfound);
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::string excludedLocationString = "";
|
||||
for (auto excludedLocationIt : excludedLocations) {
|
||||
excludedLocationString += std::to_string(excludedLocationIt);
|
||||
excludedLocationString += ",";
|
||||
}
|
||||
if (excludedLocationString == "") {
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("ExcludedLocations"));
|
||||
} else {
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"),
|
||||
excludedLocationString.c_str());
|
||||
}
|
||||
Ship::Context::GetInstance()
|
||||
->GetWindow()
|
||||
->GetGui()
|
||||
->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", Rando::StaticData::GetLocation(location)->GetShortName().c_str());
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTabItem();
|
||||
ImGui::EndDisabled();
|
||||
} else {
|
||||
locationsTabOpen = false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Tricks/Glitches")) {
|
||||
if (!tricksTabOpen) {
|
||||
tricksTabOpen = true;
|
||||
// RandomizerTricks::UpdateImGuiVisibility();
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::stringstream enabledTrickStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), ""));
|
||||
std::string enabledTrickString;
|
||||
enabledTricks.clear();
|
||||
while (getline(enabledTrickStringStream, enabledTrickString, ',')) {
|
||||
enabledTricks.insert((RandomizerTrick)std::stoi(enabledTrickString));
|
||||
}
|
||||
std::stringstream enabledGlitchStringStream(
|
||||
CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledGlitches"), ""));
|
||||
std::string enabledGlitchString;
|
||||
enabledGlitches.clear();
|
||||
while (getline(enabledGlitchStringStream, enabledGlitchString, ',')) {
|
||||
enabledGlitches.insert((RandomizerTrick)std::stoi(enabledGlitchString));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
if (ImGui::BeginTable("tableRandoLogic", 1, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(170.0);
|
||||
if (mSettings->GetOption(RSK_LOGIC_RULES).RenderImGui()) {
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
// RANDOTODO: Implement Disalbling of Options for Vanilla Logic
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_GLITCHLESS) {
|
||||
ImGui::SameLine();
|
||||
if (mSettings->GetOption(RSK_ALL_LOCATIONS_REACHABLE).RenderImGui()) {
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings);
|
||||
|
||||
// Tricks
|
||||
static std::unordered_map<RandomizerArea, bool> areaTreeDisabled{
|
||||
{ RA_NONE, true },
|
||||
{ RA_KOKIRI_FOREST, true },
|
||||
{ RA_THE_LOST_WOODS, true },
|
||||
{ RA_SACRED_FOREST_MEADOW, true },
|
||||
{ RA_HYRULE_FIELD, true },
|
||||
{ RA_LAKE_HYLIA, true },
|
||||
{ RA_GERUDO_VALLEY, true },
|
||||
{ RA_GERUDO_FORTRESS, true },
|
||||
{ RA_HAUNTED_WASTELAND, true },
|
||||
{ RA_DESERT_COLOSSUS, true },
|
||||
{ RA_THE_MARKET, true },
|
||||
{ RA_HYRULE_CASTLE, true },
|
||||
{ RA_KAKARIKO_VILLAGE, true },
|
||||
{ RA_THE_GRAVEYARD, true },
|
||||
{ RA_DEATH_MOUNTAIN_TRAIL, true },
|
||||
{ RA_GORON_CITY, true },
|
||||
{ RA_DEATH_MOUNTAIN_CRATER, true },
|
||||
{ RA_ZORAS_RIVER, true },
|
||||
{ RA_ZORAS_DOMAIN, true },
|
||||
{ RA_ZORAS_FOUNTAIN, true },
|
||||
{ RA_LON_LON_RANCH, true },
|
||||
{ RA_DEKU_TREE, true },
|
||||
{ RA_DODONGOS_CAVERN, true },
|
||||
{ RA_JABU_JABUS_BELLY, true },
|
||||
{ RA_FOREST_TEMPLE, true },
|
||||
{ RA_FIRE_TEMPLE, true },
|
||||
{ RA_WATER_TEMPLE, true },
|
||||
{ RA_SPIRIT_TEMPLE, true },
|
||||
{ RA_SHADOW_TEMPLE, true },
|
||||
{ RA_BOTTOM_OF_THE_WELL, true },
|
||||
{ RA_ICE_CAVERN, true },
|
||||
{ RA_GERUDO_TRAINING_GROUND, true },
|
||||
{ RA_GANONS_CASTLE, true },
|
||||
};
|
||||
static std::unordered_map<RandomizerArea, bool> areaTreeEnabled{
|
||||
{ RA_NONE, true },
|
||||
{ RA_KOKIRI_FOREST, true },
|
||||
{ RA_THE_LOST_WOODS, true },
|
||||
{ RA_SACRED_FOREST_MEADOW, true },
|
||||
{ RA_HYRULE_FIELD, true },
|
||||
{ RA_LAKE_HYLIA, true },
|
||||
{ RA_GERUDO_VALLEY, true },
|
||||
{ RA_GERUDO_FORTRESS, true },
|
||||
{ RA_HAUNTED_WASTELAND, true },
|
||||
{ RA_DESERT_COLOSSUS, true },
|
||||
{ RA_THE_MARKET, true },
|
||||
{ RA_HYRULE_CASTLE, true },
|
||||
{ RA_KAKARIKO_VILLAGE, true },
|
||||
{ RA_THE_GRAVEYARD, true },
|
||||
{ RA_DEATH_MOUNTAIN_TRAIL, true },
|
||||
{ RA_GORON_CITY, true },
|
||||
{ RA_DEATH_MOUNTAIN_CRATER, true },
|
||||
{ RA_ZORAS_RIVER, true },
|
||||
{ RA_ZORAS_DOMAIN, true },
|
||||
{ RA_ZORAS_FOUNTAIN, true },
|
||||
{ RA_LON_LON_RANCH, true },
|
||||
{ RA_DEKU_TREE, true },
|
||||
{ RA_DODONGOS_CAVERN, true },
|
||||
{ RA_JABU_JABUS_BELLY, true },
|
||||
{ RA_FOREST_TEMPLE, true },
|
||||
{ RA_FIRE_TEMPLE, true },
|
||||
{ RA_WATER_TEMPLE, true },
|
||||
{ RA_SPIRIT_TEMPLE, true },
|
||||
{ RA_SHADOW_TEMPLE, true },
|
||||
{ RA_BOTTOM_OF_THE_WELL, true },
|
||||
{ RA_ICE_CAVERN, true },
|
||||
{ RA_GERUDO_TRAINING_GROUND, true },
|
||||
{ RA_GANONS_CASTLE, true },
|
||||
};
|
||||
|
||||
static std::map<Rando::Tricks::Tag, bool> showTag{
|
||||
{ Rando::Tricks::Tag::NOVICE, true }, { Rando::Tricks::Tag::INTERMEDIATE, true },
|
||||
{ Rando::Tricks::Tag::ADVANCED, true }, { Rando::Tricks::Tag::EXPERT, true },
|
||||
{ Rando::Tricks::Tag::EXTREME, true }, { Rando::Tricks::Tag::EXPERIMENTAL, true },
|
||||
{ Rando::Tricks::Tag::GLITCH, false },
|
||||
};
|
||||
static ImGuiTextFilter trickSearch;
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
trickSearch.Draw("Filter (inc,-exc)", 490.0f);
|
||||
UIWidgets::PopStyleInput();
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) {
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Disable All",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
auto etfound = enabledTricks.find(static_cast<RandomizerTrick>(i));
|
||||
if (etfound != enabledTricks.end()) {
|
||||
enabledTricks.erase(etfound);
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks"));
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Enable All",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
if (!enabledTricks.count(static_cast<RandomizerTrick>(i))) {
|
||||
enabledTricks.insert(static_cast<RandomizerTrick>(i));
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str());
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginTable("trickTags", static_cast<int>(showTag.size()),
|
||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings |
|
||||
ImGuiTableFlags_Borders)) {
|
||||
for (auto [rtTag, isShown] : showTag) {
|
||||
ImGui::TableNextColumn();
|
||||
if (isShown) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Rando::Tricks::GetTextColor(rtTag));
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, { 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
}
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, Rando::Tricks::GetTagColor(rtTag));
|
||||
ImGui::Selectable(Rando::Tricks::GetTagName(rtTag).c_str(), &showTag[rtTag]);
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("tableRandoTricks", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("Disabled Tricks", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableSetupColumn("Enabled Tricks", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::TableNextRow();
|
||||
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) {
|
||||
// COLUMN 1 - DISABLED TRICKS
|
||||
ImGui::TableNextColumn();
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
if (UIWidgets::Button("Collapse All##disabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeDisabled[static_cast<RandomizerArea>(i)] = false;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Open All##disabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeDisabled[static_cast<RandomizerArea>(i)] = true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Enable Visible",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
auto option = mSettings->GetTrickOption(static_cast<RandomizerTrick>(i));
|
||||
if (!enabledTricks.count(static_cast<RandomizerTrick>(i)) &&
|
||||
trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
areaTreeDisabled[option.GetArea()] &&
|
||||
Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
enabledTricks.insert(static_cast<RandomizerTrick>(i));
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str());
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
|
||||
ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8), false,
|
||||
ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
for (auto [area, trickIds] : mSettings->mTricksByArea) {
|
||||
bool hasTricks = false;
|
||||
for (auto rt : trickIds) {
|
||||
auto option = mSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
!enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
hasTricks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasTricks) {
|
||||
ImGui::TreeNodeSetOpen(
|
||||
ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##disabled").c_str()),
|
||||
areaTreeDisabled[area]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##disabled").c_str())) {
|
||||
for (auto rt : trickIds) {
|
||||
auto option = mSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
!enabledTricks.count(rt) &&
|
||||
Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
ImGui::TreeNodeSetOpen(
|
||||
ImGui::GetID(
|
||||
(Rando::Tricks::GetAreaName(option.GetArea()) + "##disabled").c_str()),
|
||||
areaTreeDisabled[option.GetArea()]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Right)) {
|
||||
enabledTricks.insert(rt);
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"),
|
||||
enabledTrickString.c_str());
|
||||
Ship::Context::GetInstance()
|
||||
->GetWindow()
|
||||
->GetGui()
|
||||
->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName());
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", option.GetName().c_str());
|
||||
UIWidgets::Tooltip(option.GetDescription().c_str());
|
||||
}
|
||||
}
|
||||
areaTreeDisabled[area] = true;
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
areaTreeDisabled[area] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// COLUMN 2 - ENABLED TRICKS
|
||||
ImGui::TableNextColumn();
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
if (UIWidgets::Button("Collapse All##enabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeEnabled[static_cast<RandomizerArea>(i)] = false;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Open All##enabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeEnabled[static_cast<RandomizerArea>(i)] = true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Disable Visible",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
auto option = mSettings->GetTrickOption(static_cast<RandomizerTrick>(i));
|
||||
if (enabledTricks.count(static_cast<RandomizerTrick>(i)) &&
|
||||
trickSearch.PassFilter(option.GetName().c_str()) && areaTreeEnabled[option.GetArea()] &&
|
||||
Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
enabledTricks.erase(static_cast<RandomizerTrick>(i));
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
if (enabledTricks.size() == 0) {
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks"));
|
||||
} else {
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str());
|
||||
}
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
|
||||
ImGui::BeginChild("ChildTricksEnabled", ImVec2(0, -8), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
for (auto [area, trickIds] : mSettings->mTricksByArea) {
|
||||
bool hasTricks = false;
|
||||
for (auto rt : trickIds) {
|
||||
auto option = mSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
hasTricks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasTricks) {
|
||||
ImGui::TreeNodeSetOpen(
|
||||
ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##enabled").c_str()),
|
||||
areaTreeEnabled[area]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##enabled").c_str())) {
|
||||
for (auto rt : trickIds) {
|
||||
auto option = mSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
enabledTricks.count(rt) &&
|
||||
Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
ImGui::TreeNodeSetOpen(
|
||||
ImGui::GetID(
|
||||
(Rando::Tricks::GetAreaName(option.GetArea()) + "##enabled").c_str()),
|
||||
areaTreeEnabled[option.GetArea()]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Left)) {
|
||||
enabledTricks.erase(rt);
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
if (enabledTrickString == "") {
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks"));
|
||||
} else {
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"),
|
||||
enabledTrickString.c_str());
|
||||
}
|
||||
Ship::Context::GetInstance()
|
||||
->GetWindow()
|
||||
->GetGui()
|
||||
->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName());
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", option.GetName().c_str());
|
||||
UIWidgets::Tooltip(option.GetDescription().c_str());
|
||||
}
|
||||
}
|
||||
areaTreeEnabled[area] = true;
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
areaTreeEnabled[area] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
} else {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8));
|
||||
ImGui::Text("Requires Logic Turned On.");
|
||||
ImGui::EndChild();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginChild("ChildTricksEnabled", ImVec2(0, -8));
|
||||
ImGui::Text("Requires Logic Turned On.");
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTabItem();
|
||||
} else {
|
||||
tricksTabOpen = false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Starting Inventory")) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
if (mSettings->GetOptionGroup(RSG_STARTING_INVENTORY_IMGUI_TABLE).RenderImGui()) {
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
UIWidgets::PopStyleTabs();
|
||||
}
|
||||
|
||||
void RandomizerSettingsWindow::SetNeedsUpdate() {
|
||||
mNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void RandomizerSettingsWindow::UpdateElement() {
|
||||
if (mNeedsUpdate) {
|
||||
RandomizerCheckObjects::UpdateImGuiVisibility();
|
||||
mSettings->UpdateOptionProperties();
|
||||
locationsTabOpen = false;
|
||||
tricksTabOpen = false;
|
||||
mNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) {
|
||||
|
|
@ -5985,13 +5323,6 @@ class ExtendedVanillaTableInvalidItemIdException : public std::exception {
|
|||
}
|
||||
};
|
||||
|
||||
void RandomizerSettingsWindow::InitElement() {
|
||||
mSettings = Rando::Settings::GetInstance();
|
||||
Randomizer::CreateCustomMessages();
|
||||
seedString = (char*)calloc(MAX_SEED_STRING_SIZE, sizeof(char));
|
||||
mSettings->UpdateOptionProperties();
|
||||
}
|
||||
|
||||
static std::unordered_map<RandomizerGet, GameplayStatTimestamp> randomizerGetToStatsTimeStamp = {
|
||||
{ RG_GOHMA_SOUL, TIMESTAMP_FOUND_GOHMA_SOUL },
|
||||
{ RG_KING_DODONGO_SOUL, TIMESTAMP_FOUND_KING_DODONGO_SOUL },
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <libultraship/libultra.h>
|
||||
#include "z64item.h"
|
||||
#include <memory>
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include <soh/Enhancements/randomizer/randomizerTypes.h>
|
||||
#include "soh/Enhancements/randomizer/randomizer_check_objects.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_check_tracker.h"
|
||||
|
|
@ -82,6 +82,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
bool GenerateRandomizer(std::string seed = "");
|
||||
void JoinRandoGenerationThread();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6145,26 +6145,41 @@ typedef enum {
|
|||
RSG_EXCLUDES,
|
||||
RSG_TRICKS,
|
||||
RSG_GLITCHES,
|
||||
RSG_AREA_ACCESS_IMGUI,
|
||||
RSG_WORLD_IMGUI,
|
||||
RSG_SHUFFLE_ENTRANCES_IMGUI,
|
||||
RSG_WORLD_IMGUI_TABLE,
|
||||
RSG_SHUFFLE_ITEMS_IMGUI,
|
||||
RSG_SHUFFLE_NPCS_IMGUI,
|
||||
RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI,
|
||||
RSG_ITEMS_IMGUI_TABLE,
|
||||
RSG_TIMESAVERS_IMGUI,
|
||||
RSG_ITEM_POOL_HINTS_IMGUI,
|
||||
RSG_EXTRA_HINTS_IMGUI,
|
||||
RSG_ITEM_POOL_HINTS_IMGUI_COLUMN,
|
||||
RSG_ADDITIONAL_FEATURES_IMGUI,
|
||||
RSG_GAMEPLAY_IMGUI_TABLE,
|
||||
RSG_STARTING_EQUIPMENT_IMGUI,
|
||||
RSG_STARTING_ITEMS_IMGUI,
|
||||
RSG_STARTING_NORMAL_SONGS_IMGUI,
|
||||
RSG_STARTING_WARP_SONGS_IMGUI,
|
||||
RSG_STARTING_SONGS_IMGUI,
|
||||
RSG_STARTING_INVENTORY_IMGUI_TABLE,
|
||||
RSG_MENU_SIDEBAR_LOGIC_ACCESS,
|
||||
RSG_MENU_COLUMN_LOGIC_WINCON,
|
||||
RSG_MENU_SECTION_LOGIC,
|
||||
RSG_MENU_SECTION_WINCON,
|
||||
RSG_MENU_COLUMN_AREA_ACCESS,
|
||||
RSG_MENU_SECTION_AREA_ACCESS,
|
||||
RSG_MENU_SECTION_ENTRANCES,
|
||||
RSG_MENU_COLUMN_ENTRANCES,
|
||||
RSG_MENU_SIDEBAR_DUNGEONS,
|
||||
RSG_MENU_COLUMN_DUNGEON_ITEMS,
|
||||
RSG_MENU_SECTION_DUNGEON_ITEMS,
|
||||
RSG_MENU_COLUMN_KEYRINGS,
|
||||
RSG_MENU_SECTION_KEYRINGS,
|
||||
RSG_MENU_COLUMN_MQ,
|
||||
RSG_MENU_SECTION_MQ,
|
||||
RSG_MENU_SIDEBAR_SHUFFLES,
|
||||
RSG_MENU_COLUMN_BASIC_SHUFFLES,
|
||||
RSG_MENU_SECTION_BASIC_SHUFFLES,
|
||||
RSG_MENU_COLUMN_SHOP_SHUFFLES,
|
||||
RSG_MENU_SECTION_SHOP_SHUFFLES,
|
||||
RSG_MENU_COLUMN_ADDITIONAL_ITEMS,
|
||||
RSG_MENU_SECTION_ADDITIONAL_ITEMS,
|
||||
RSG_MENU_SIDEBAR_HINTS_TRAPS,
|
||||
RSG_MENU_COLUMN_HINTS_TRAPS,
|
||||
RSG_MENU_SECTION_HINTS,
|
||||
RSG_MENU_SECTION_TRAPS,
|
||||
RSG_MENU_COLUMN_STATIC_HINTS,
|
||||
RSG_MENU_SECTION_STATIC_HINTS,
|
||||
RSG_MENU_SIDEBAR_STARTING_ITEMS,
|
||||
RSG_MENU_COLUMN_STARTING_EQUIPMENT,
|
||||
RSG_MENU_SECTION_STARTING_EQUIPS,
|
||||
RSG_MENU_SECTION_STARTING_ITEMS,
|
||||
RSG_MENU_COLUMN_STARTING_SONGS,
|
||||
RSG_MENU_SECTION_NORMAL_SONGS,
|
||||
RSG_MENU_SECTION_WARP_SONGS,
|
||||
RSG_OPEN,
|
||||
RSG_WORLD,
|
||||
RSG_SHUFFLE,
|
||||
|
|
@ -7050,4 +7065,4 @@ typedef enum {
|
|||
/* 0x1F */ GROTTO_GV_OCTOROK_OFFSET,
|
||||
/* 0x20 */ GROTTO_LW_DEKU_THEATRE_OFFSET,
|
||||
/* 0x21 */ GROTTO_OFFSET_MAX,
|
||||
} GrottoEntranceOffsets;
|
||||
} GrottoEntranceOffsets;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include "randomizer_check_objects.h"
|
||||
#include "static_data.h"
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <libultraship/bridge.h>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "randomizerTypes.h"
|
||||
#include "z64actor_enum.h"
|
||||
#include "z64scene.h"
|
||||
|
|
@ -14,4 +15,4 @@ std::map<RandomizerCheckArea, std::vector<RandomizerCheck>> GetAllRCObjectsByAre
|
|||
std::map<SceneID, RandomizerCheckArea> GetAllRCAreaBySceneID();
|
||||
RandomizerCheckArea GetRCAreaBySceneID(SceneID sceneId);
|
||||
void UpdateImGuiVisibility();
|
||||
} // namespace RandomizerCheckObjects
|
||||
} // namespace RandomizerCheckObjects
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "randomizerTypes.h"
|
||||
#include "randomizer_check_objects.h"
|
||||
|
|
|
|||
|
|
@ -2099,4 +2099,4 @@ DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6)
|
|||
DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7)
|
||||
DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8)
|
||||
// End Grass
|
||||
DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER)
|
||||
DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER)
|
||||
|
|
|
|||
|
|
@ -66,4 +66,4 @@ class ItemTrackerWindow final : public Ship::GuiWindow {
|
|||
void InitElement() override;
|
||||
void DrawElement() override;
|
||||
void UpdateElement() override{};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
namespace Rando {
|
||||
class Settings;
|
||||
}
|
||||
|
||||
class RandomizerSettingsWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
void InitElement() override;
|
||||
void DrawElement() override;
|
||||
void UpdateElement() override;
|
||||
void SetNeedsUpdate();
|
||||
|
||||
private:
|
||||
bool mNeedsUpdate = false;
|
||||
std::shared_ptr<Rando::Settings> mSettings;
|
||||
};
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "context.h"
|
||||
#include "SeedContext.h"
|
||||
#include "option.h"
|
||||
#include "randomizerTypes.h"
|
||||
#include "3drando/spoiler_log.hpp"
|
||||
|
|
@ -20,6 +20,16 @@ class Settings {
|
|||
*/
|
||||
void HandleShopsanityPriceUI();
|
||||
|
||||
/**
|
||||
* @brief Hides or Unhides the UI of Mixed Entrance Pools
|
||||
*/
|
||||
void HandleMixedEntrancePoolsUI();
|
||||
|
||||
/**
|
||||
* @brief UI Callback for handling UI state of Starting Age shuffle.
|
||||
*/
|
||||
void HandleStartingAgeUI();
|
||||
|
||||
/**
|
||||
* @brief Creates the `Option` and `OptionGroup` objects. This happens after construction because certain
|
||||
* other events in the codebase need to happen before all of the `Option`s can be created.
|
||||
|
|
@ -97,16 +107,11 @@ class Settings {
|
|||
const OptionGroup& GetOptionGroup(RandomizerSettingGroupKey key);
|
||||
|
||||
/**
|
||||
* @brief Updates various properties of options based on the value of other options.
|
||||
* Used to update visibility, whether or not interaction is disabled, and what the
|
||||
* actual option values are. Actually changing option values should be handled in
|
||||
* `FinalizeSettings`
|
||||
*
|
||||
* For example, this function handles setting the maximum possible keyring count to 9
|
||||
* when Gerudo's Fortress options are set such that a keyring is possible for that
|
||||
* dungeon.
|
||||
* @brief Runs the Callback on every option, to ensure they are all
|
||||
* hidden/unhidden and/or disabled/enabled properly after applying a
|
||||
* preset or dropping a file.
|
||||
*/
|
||||
void UpdateOptionProperties();
|
||||
void UpdateAllOptions();
|
||||
|
||||
/**
|
||||
* @brief Parse Options from a JSON file.
|
||||
|
|
|
|||
|
|
@ -87,4 +87,4 @@ class StaticData {
|
|||
StaticData();
|
||||
~StaticData();
|
||||
};
|
||||
} // namespace Rando
|
||||
} // namespace Rando
|
||||
|
|
|
|||
|
|
@ -427,7 +427,6 @@ void OTRGlobals::Initialize() {
|
|||
Rando::Settings::GetInstance()->AssignContext(gRandoContext);
|
||||
Rando::StaticData::InitItemTable(); // RANDOTODO make this not rely on context's logic so it can be initialised in
|
||||
// InitStaticData
|
||||
Rando::Settings::GetInstance()->CreateOptions();
|
||||
gRandomizer = std::make_shared<Randomizer>();
|
||||
|
||||
hasMasterQuest = hasOriginal = false;
|
||||
|
|
@ -2853,8 +2852,6 @@ bool SoH_HandleConfigDrop(char* filePath) {
|
|||
}
|
||||
}
|
||||
|
||||
Rando::Settings::GetInstance()->UpdateOptionProperties();
|
||||
|
||||
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
|
||||
gui->GetGuiWindow("Console")->Hide();
|
||||
gui->GetGuiWindow("Actor Viewer")->Hide();
|
||||
|
|
@ -2866,6 +2863,7 @@ bool SoH_HandleConfigDrop(char* filePath) {
|
|||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))
|
||||
->ClearBindings();
|
||||
|
||||
Rando::Settings::GetInstance()->UpdateAllOptions();
|
||||
gui->SaveConsoleVariablesNextFrame();
|
||||
ShipInit::Init("*");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "SaveManager.h"
|
||||
#include "OTRGlobals.h"
|
||||
#include "Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "Enhancements/randomizer/context.h"
|
||||
#include "Enhancements/randomizer/SeedContext.h"
|
||||
#include "Enhancements/randomizer/entrance.h"
|
||||
#include "Enhancements/randomizer/dungeon.h"
|
||||
#include "Enhancements/randomizer/trial.h"
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ std::shared_ptr<ItemTrackerSettingsWindow> mItemTrackerSettingsWindow;
|
|||
std::shared_ptr<ItemTrackerWindow> mItemTrackerWindow;
|
||||
std::shared_ptr<TimeSplitWindow> mTimeSplitWindow;
|
||||
std::shared_ptr<PlandomizerWindow> mPlandomizerWindow;
|
||||
std::shared_ptr<RandomizerSettingsWindow> mRandomizerSettingsWindow;
|
||||
std::shared_ptr<SohModalWindow> mModalWindow;
|
||||
std::shared_ptr<Notification::Window> mNotificationWindow;
|
||||
std::shared_ptr<TimeDisplayWindow> mTimeDisplayWindow;
|
||||
|
|
@ -191,9 +190,6 @@ void SetupGuiElements() {
|
|||
mItemTrackerSettingsWindow = std::make_shared<ItemTrackerSettingsWindow>(CVAR_WINDOW("ItemTrackerSettings"),
|
||||
"Item Tracker Settings", ImVec2(733, 472));
|
||||
gui->AddGuiWindow(mItemTrackerSettingsWindow);
|
||||
mRandomizerSettingsWindow = std::make_shared<RandomizerSettingsWindow>(CVAR_WINDOW("RandomizerSettings"),
|
||||
"Randomizer Settings", ImVec2(920, 600));
|
||||
gui->AddGuiWindow(mRandomizerSettingsWindow);
|
||||
mTimeSplitWindow = std::make_shared<TimeSplitWindow>(CVAR_WINDOW("TimeSplits"), "Time Splits", ImVec2(450, 660));
|
||||
gui->AddGuiWindow(mTimeSplitWindow);
|
||||
mPlandomizerWindow =
|
||||
|
|
@ -217,7 +213,6 @@ void Destroy() {
|
|||
|
||||
mNotificationWindow = nullptr;
|
||||
mModalWindow = nullptr;
|
||||
mRandomizerSettingsWindow = nullptr;
|
||||
mItemTrackerWindow = nullptr;
|
||||
mItemTrackerSettingsWindow = nullptr;
|
||||
mEntranceTrackerWindow = nullptr;
|
||||
|
|
@ -253,6 +248,8 @@ void RegisterPopup(std::string title, std::string message, std::string button1,
|
|||
}
|
||||
|
||||
void ShowRandomizerSettingsMenu() {
|
||||
mRandomizerSettingsWindow->Show();
|
||||
CVarSetString(CVAR_SETTING("Menu.ActiveHeader"), "Randomizer");
|
||||
CVarSetString(CVAR_SETTING("Menu.RandomizerSidebarSection"), "General");
|
||||
mSohMenu->Show();
|
||||
}
|
||||
} // namespace SohGui
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "soh/Enhancements/randomizer/randomizer_check_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_item_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_settings_window.h"
|
||||
#include "soh/Enhancements/timesplits/TimeSplits.h"
|
||||
#include "soh/Enhancements/randomizer/Plandomizer.h"
|
||||
#include "SohModals.h"
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
#include "soh/Enhancements/randomizer/randomizer_check_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_item_tracker.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_settings_window.h"
|
||||
#include "soh/Enhancements/enemyrandomizer.h"
|
||||
#include "soh/Enhancements/timesplits/TimeSplits.h"
|
||||
#include "soh/Enhancements/randomizer/Plandomizer.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
#include "SohMenu.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/SohGui/SohGui.hpp"
|
||||
|
||||
namespace SohGui {
|
||||
|
||||
|
|
@ -12,23 +15,603 @@ static const std::unordered_map<int32_t, const char*> skipGetItemAnimationOption
|
|||
{ SGIA_ALL, "All Items" },
|
||||
};
|
||||
|
||||
static bool locationsDirty = true;
|
||||
static bool tricksDirty = true;
|
||||
static char seedString[MAX_SEED_STRING_SIZE];
|
||||
static std::set<RandomizerCheck> excludedLocations;
|
||||
static std::set<RandomizerTrick> enabledTricks;
|
||||
static std::set<RandomizerTrick> enabledGlitches;
|
||||
|
||||
void DrawLocationsMenu(WidgetInfo& info) {
|
||||
auto ctx = OTRGlobals::Instance->gRandoContext;
|
||||
static ImVec2 cellPadding(8.0f, 8.0f);
|
||||
bool generating = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0);
|
||||
bool disableEditingRandoSettings = generating || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0);
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
if (locationsDirty) {
|
||||
RandomizerCheckObjects::UpdateImGuiVisibility();
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::stringstream excludedLocationStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), ""));
|
||||
std::string excludedLocationString;
|
||||
excludedLocations.clear();
|
||||
while (getline(excludedLocationStringStream, excludedLocationString, ',')) {
|
||||
excludedLocations.insert((RandomizerCheck)std::stoi(excludedLocationString));
|
||||
}
|
||||
locationsDirty = false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("tableRandoLocations", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("Included", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableSetupColumn("Excluded", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::TableNextRow();
|
||||
|
||||
// COLUMN 1 - INCLUDED LOCATIONS
|
||||
ImGui::TableNextColumn();
|
||||
// window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
static ImGuiTextFilter locationSearch;
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
locationSearch.Draw();
|
||||
UIWidgets::PopStyleInput();
|
||||
|
||||
ImGui::BeginChild("ChildIncludedLocations", ImVec2(0, -8));
|
||||
for (auto& [rcArea, locations] : RandomizerCheckObjects::GetAllRCObjectsByArea()) {
|
||||
bool hasItems = false;
|
||||
for (RandomizerCheck rc : locations) {
|
||||
if (ctx->GetItemLocation(rc)->IsVisible() && !excludedLocations.count(rc) &&
|
||||
locationSearch.PassFilter(Rando::StaticData::GetLocation(rc)->GetName().c_str())) {
|
||||
|
||||
hasItems = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasItems) {
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) {
|
||||
for (auto& location : locations) {
|
||||
if (ctx->GetItemLocation(location)->IsVisible() && !excludedLocations.count(location) &&
|
||||
locationSearch.PassFilter(Rando::StaticData::GetLocation(location)->GetName().c_str())) {
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(location).c_str(), ImGuiDir_Right)) {
|
||||
excludedLocations.insert(location);
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::string excludedLocationString = "";
|
||||
for (auto excludedLocationIt : excludedLocations) {
|
||||
excludedLocationString += std::to_string(excludedLocationIt);
|
||||
excludedLocationString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"),
|
||||
excludedLocationString.c_str());
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
locationsDirty = true;
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", Rando::StaticData::GetLocation(location)->GetShortName().c_str());
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// COLUMN 2 - EXCLUDED LOCATIONS
|
||||
ImGui::TableNextColumn();
|
||||
// window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
ImGui::BeginChild("ChildExcludedLocations", ImVec2(0, -8));
|
||||
for (auto& [rcArea, locations] : RandomizerCheckObjects::GetAllRCObjectsByArea()) {
|
||||
bool hasItems = false;
|
||||
for (RandomizerCheck rc : locations) {
|
||||
if (ctx->GetItemLocation(rc)->IsVisible() && excludedLocations.count(rc)) {
|
||||
hasItems = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasItems) {
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) {
|
||||
for (auto& location : locations) {
|
||||
auto elfound = excludedLocations.find(location);
|
||||
if (ctx->GetItemLocation(location)->IsVisible() && elfound != excludedLocations.end()) {
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(location).c_str(), ImGuiDir_Left)) {
|
||||
excludedLocations.erase(elfound);
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::string excludedLocationString = "";
|
||||
for (auto excludedLocationIt : excludedLocations) {
|
||||
excludedLocationString += std::to_string(excludedLocationIt);
|
||||
excludedLocationString += ",";
|
||||
}
|
||||
if (excludedLocationString == "") {
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("ExcludedLocations"));
|
||||
} else {
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"),
|
||||
excludedLocationString.c_str());
|
||||
}
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
locationsDirty = true;
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", Rando::StaticData::GetLocation(location)->GetShortName().c_str());
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
// ImGui::EndTabItem();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void DrawTricksMenu(WidgetInfo& info) {
|
||||
auto ctx = OTRGlobals::Instance->gRandoContext;
|
||||
auto randoSettings = Rando::Settings::GetInstance();
|
||||
static ImVec2 cellPadding(8.0f, 8.0f);
|
||||
bool generating = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0);
|
||||
bool disableEditingRandoSettings = generating || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0);
|
||||
if (tricksDirty) {
|
||||
tricksDirty = false;
|
||||
// RandomizerTricks::UpdateImGuiVisibility();
|
||||
// todo: this efficently when we build out cvar array support
|
||||
std::stringstream enabledTrickStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), ""));
|
||||
std::string enabledTrickString;
|
||||
enabledTricks.clear();
|
||||
while (getline(enabledTrickStringStream, enabledTrickString, ',')) {
|
||||
enabledTricks.insert((RandomizerTrick)std::stoi(enabledTrickString));
|
||||
}
|
||||
std::stringstream enabledGlitchStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledGlitches"), ""));
|
||||
std::string enabledGlitchString;
|
||||
enabledGlitches.clear();
|
||||
while (getline(enabledGlitchStringStream, enabledGlitchString, ',')) {
|
||||
enabledGlitches.insert((RandomizerTrick)std::stoi(enabledGlitchString));
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings);
|
||||
|
||||
// Tricks
|
||||
static std::unordered_map<RandomizerArea, bool> areaTreeDisabled{
|
||||
{ RA_NONE, true },
|
||||
{ RA_KOKIRI_FOREST, true },
|
||||
{ RA_THE_LOST_WOODS, true },
|
||||
{ RA_SACRED_FOREST_MEADOW, true },
|
||||
{ RA_HYRULE_FIELD, true },
|
||||
{ RA_LAKE_HYLIA, true },
|
||||
{ RA_GERUDO_VALLEY, true },
|
||||
{ RA_GERUDO_FORTRESS, true },
|
||||
{ RA_HAUNTED_WASTELAND, true },
|
||||
{ RA_DESERT_COLOSSUS, true },
|
||||
{ RA_THE_MARKET, true },
|
||||
{ RA_HYRULE_CASTLE, true },
|
||||
{ RA_KAKARIKO_VILLAGE, true },
|
||||
{ RA_THE_GRAVEYARD, true },
|
||||
{ RA_DEATH_MOUNTAIN_TRAIL, true },
|
||||
{ RA_GORON_CITY, true },
|
||||
{ RA_DEATH_MOUNTAIN_CRATER, true },
|
||||
{ RA_ZORAS_RIVER, true },
|
||||
{ RA_ZORAS_DOMAIN, true },
|
||||
{ RA_ZORAS_FOUNTAIN, true },
|
||||
{ RA_LON_LON_RANCH, true },
|
||||
{ RA_DEKU_TREE, true },
|
||||
{ RA_DODONGOS_CAVERN, true },
|
||||
{ RA_JABU_JABUS_BELLY, true },
|
||||
{ RA_FOREST_TEMPLE, true },
|
||||
{ RA_FIRE_TEMPLE, true },
|
||||
{ RA_WATER_TEMPLE, true },
|
||||
{ RA_SPIRIT_TEMPLE, true },
|
||||
{ RA_SHADOW_TEMPLE, true },
|
||||
{ RA_BOTTOM_OF_THE_WELL, true },
|
||||
{ RA_ICE_CAVERN, true },
|
||||
{ RA_GERUDO_TRAINING_GROUND, true },
|
||||
{ RA_GANONS_CASTLE, true },
|
||||
};
|
||||
static std::unordered_map<RandomizerArea, bool> areaTreeEnabled{
|
||||
{ RA_NONE, true },
|
||||
{ RA_KOKIRI_FOREST, true },
|
||||
{ RA_THE_LOST_WOODS, true },
|
||||
{ RA_SACRED_FOREST_MEADOW, true },
|
||||
{ RA_HYRULE_FIELD, true },
|
||||
{ RA_LAKE_HYLIA, true },
|
||||
{ RA_GERUDO_VALLEY, true },
|
||||
{ RA_GERUDO_FORTRESS, true },
|
||||
{ RA_HAUNTED_WASTELAND, true },
|
||||
{ RA_DESERT_COLOSSUS, true },
|
||||
{ RA_THE_MARKET, true },
|
||||
{ RA_HYRULE_CASTLE, true },
|
||||
{ RA_KAKARIKO_VILLAGE, true },
|
||||
{ RA_THE_GRAVEYARD, true },
|
||||
{ RA_DEATH_MOUNTAIN_TRAIL, true },
|
||||
{ RA_GORON_CITY, true },
|
||||
{ RA_DEATH_MOUNTAIN_CRATER, true },
|
||||
{ RA_ZORAS_RIVER, true },
|
||||
{ RA_ZORAS_DOMAIN, true },
|
||||
{ RA_ZORAS_FOUNTAIN, true },
|
||||
{ RA_LON_LON_RANCH, true },
|
||||
{ RA_DEKU_TREE, true },
|
||||
{ RA_DODONGOS_CAVERN, true },
|
||||
{ RA_JABU_JABUS_BELLY, true },
|
||||
{ RA_FOREST_TEMPLE, true },
|
||||
{ RA_FIRE_TEMPLE, true },
|
||||
{ RA_WATER_TEMPLE, true },
|
||||
{ RA_SPIRIT_TEMPLE, true },
|
||||
{ RA_SHADOW_TEMPLE, true },
|
||||
{ RA_BOTTOM_OF_THE_WELL, true },
|
||||
{ RA_ICE_CAVERN, true },
|
||||
{ RA_GERUDO_TRAINING_GROUND, true },
|
||||
{ RA_GANONS_CASTLE, true },
|
||||
};
|
||||
|
||||
static std::map<Rando::Tricks::Tag, bool> showTag{
|
||||
{ Rando::Tricks::Tag::NOVICE, true }, { Rando::Tricks::Tag::INTERMEDIATE, true },
|
||||
{ Rando::Tricks::Tag::ADVANCED, true }, { Rando::Tricks::Tag::EXPERT, true },
|
||||
{ Rando::Tricks::Tag::EXTREME, true }, { Rando::Tricks::Tag::EXPERIMENTAL, true },
|
||||
{ Rando::Tricks::Tag::GLITCH, false },
|
||||
};
|
||||
static ImGuiTextFilter trickSearch;
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
trickSearch.Draw("Filter (inc,-exc)", 490.0f);
|
||||
UIWidgets::PopStyleInput();
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) {
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Disable All", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
auto etfound = enabledTricks.find(static_cast<RandomizerTrick>(i));
|
||||
if (etfound != enabledTricks.end()) {
|
||||
enabledTricks.erase(etfound);
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks"));
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
tricksDirty = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Enable All", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
if (!enabledTricks.count(static_cast<RandomizerTrick>(i))) {
|
||||
enabledTricks.insert(static_cast<RandomizerTrick>(i));
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str());
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
tricksDirty = true;
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginTable("trickTags", static_cast<int>(showTag.size()),
|
||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) {
|
||||
for (auto [rtTag, isShown] : showTag) {
|
||||
ImGui::TableNextColumn();
|
||||
if (isShown) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Rando::Tricks::GetTextColor(rtTag));
|
||||
} else {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, { 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
}
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, Rando::Tricks::GetTagColor(rtTag));
|
||||
ImGui::Selectable(Rando::Tricks::GetTagName(rtTag).c_str(), &showTag[rtTag]);
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("tableRandoTricks", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("Disabled Tricks", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableSetupColumn("Enabled Tricks", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::TableNextRow();
|
||||
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) {
|
||||
// COLUMN 1 - DISABLED TRICKS
|
||||
ImGui::TableNextColumn();
|
||||
// window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
if (UIWidgets::Button("Collapse All##disabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeDisabled[static_cast<RandomizerArea>(i)] = false;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Open All##disabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeDisabled[static_cast<RandomizerArea>(i)] = true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Enable Visible",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
auto option = randoSettings->GetTrickOption(static_cast<RandomizerTrick>(i));
|
||||
if (!enabledTricks.count(static_cast<RandomizerTrick>(i)) &&
|
||||
trickSearch.PassFilter(option.GetName().c_str()) && areaTreeDisabled[option.GetArea()] &&
|
||||
Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
enabledTricks.insert(static_cast<RandomizerTrick>(i));
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str());
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
tricksDirty = true;
|
||||
}
|
||||
|
||||
ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
for (auto [area, trickIds] : randoSettings->mTricksByArea) {
|
||||
bool hasTricks = false;
|
||||
for (auto rt : trickIds) {
|
||||
auto option = randoSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
!enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
hasTricks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasTricks) {
|
||||
ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##disabled").c_str()),
|
||||
areaTreeDisabled[area]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##disabled").c_str())) {
|
||||
for (auto rt : trickIds) {
|
||||
auto option = randoSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
!enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
ImGui::TreeNodeSetOpen(
|
||||
ImGui::GetID((Rando::Tricks::GetAreaName(option.GetArea()) + "##disabled").c_str()),
|
||||
areaTreeDisabled[option.GetArea()]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Right)) {
|
||||
enabledTricks.insert(rt);
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str());
|
||||
Ship::Context::GetInstance()
|
||||
->GetWindow()
|
||||
->GetGui()
|
||||
->SaveConsoleVariablesNextFrame();
|
||||
tricksDirty = true;
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName());
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", option.GetName().c_str());
|
||||
UIWidgets::Tooltip(option.GetDescription().c_str());
|
||||
}
|
||||
}
|
||||
areaTreeDisabled[area] = true;
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
areaTreeDisabled[area] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
// COLUMN 2 - ENABLED TRICKS
|
||||
ImGui::TableNextColumn();
|
||||
// window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
if (UIWidgets::Button("Collapse All##enabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeEnabled[static_cast<RandomizerArea>(i)] = false;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Open All##enabled",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RA_MAX; i++) {
|
||||
areaTreeEnabled[static_cast<RandomizerArea>(i)] = true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Disable Visible",
|
||||
UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) {
|
||||
for (int i = 0; i < RT_MAX; i++) {
|
||||
auto option = randoSettings->GetTrickOption(static_cast<RandomizerTrick>(i));
|
||||
if (enabledTricks.count(static_cast<RandomizerTrick>(i)) &&
|
||||
trickSearch.PassFilter(option.GetName().c_str()) && areaTreeEnabled[option.GetArea()] &&
|
||||
Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
enabledTricks.erase(static_cast<RandomizerTrick>(i));
|
||||
}
|
||||
}
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
if (enabledTricks.size() == 0) {
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks"));
|
||||
} else {
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str());
|
||||
}
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
tricksDirty = true;
|
||||
}
|
||||
|
||||
ImGui::BeginChild("ChildTricksEnabled", ImVec2(0, -8), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
for (auto [area, trickIds] : randoSettings->mTricksByArea) {
|
||||
bool hasTricks = false;
|
||||
for (auto rt : trickIds) {
|
||||
auto option = randoSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
hasTricks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasTricks) {
|
||||
ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##enabled").c_str()),
|
||||
areaTreeEnabled[area]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##enabled").c_str())) {
|
||||
for (auto rt : trickIds) {
|
||||
auto option = randoSettings->GetTrickOption(rt);
|
||||
if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) &&
|
||||
enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) {
|
||||
ImGui::TreeNodeSetOpen(
|
||||
ImGui::GetID((Rando::Tricks::GetAreaName(option.GetArea()) + "##enabled").c_str()),
|
||||
areaTreeEnabled[option.GetArea()]);
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f));
|
||||
if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Left)) {
|
||||
enabledTricks.erase(rt);
|
||||
std::string enabledTrickString = "";
|
||||
for (auto enabledTrickIt : enabledTricks) {
|
||||
enabledTrickString += std::to_string(enabledTrickIt);
|
||||
enabledTrickString += ",";
|
||||
}
|
||||
if (enabledTrickString == "") {
|
||||
CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks"));
|
||||
} else {
|
||||
CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"),
|
||||
enabledTrickString.c_str());
|
||||
}
|
||||
Ship::Context::GetInstance()
|
||||
->GetWindow()
|
||||
->GetGui()
|
||||
->SaveConsoleVariablesNextFrame();
|
||||
tricksDirty = true;
|
||||
}
|
||||
UIWidgets::PopStyleButton();
|
||||
Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName());
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", option.GetName().c_str());
|
||||
UIWidgets::Tooltip(option.GetDescription().c_str());
|
||||
}
|
||||
}
|
||||
areaTreeEnabled[area] = true;
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
areaTreeEnabled[area] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
} else {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8));
|
||||
ImGui::Text("Requires Logic Turned On.");
|
||||
ImGui::EndChild();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::BeginChild("ChildTricksEnabled", ImVec2(0, -8));
|
||||
ImGui::Text("Requires Logic Turned On.");
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopStyleVar(1);
|
||||
}
|
||||
|
||||
void SohMenu::AddMenuRandomizer() {
|
||||
Randomizer::CreateCustomMessages();
|
||||
// Add Randomizer Menu
|
||||
AddMenuEntry("Randomizer", CVAR_SETTING("Menu.RandomizerSidebarSection"));
|
||||
|
||||
// Seed Settings
|
||||
WidgetPath path = { "Randomizer", "Seed Settings", SECTION_COLUMN_1 };
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 1);
|
||||
AddWidget(path, "Popout Randomizer Settings Window", WIDGET_WINDOW_BUTTON)
|
||||
.CVar(CVAR_WINDOW("RandomizerSettings"))
|
||||
.WindowName("Randomizer Settings")
|
||||
.HideInSearch(true)
|
||||
.Options(WindowButtonOptions().Tooltip("Enables the separate Randomizer Settings Window."));
|
||||
WidgetPath path = { "Randomizer", "General", SECTION_COLUMN_1 };
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 2);
|
||||
AddWidget(path,
|
||||
"Be sure to explore the Presets and Enhancements Menus for various Speedups and Quality of life changes!",
|
||||
WIDGET_TEXT)
|
||||
.Options(TextOptions().Color(UIWidgets::Colors::Gray));
|
||||
AddWidget(path, "Seed Entry", WIDGET_SEPARATOR_TEXT);
|
||||
AddWidget(path, "Manual seed entry", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"))
|
||||
.Options(CheckboxOptions().DefaultValue(true));
|
||||
AddWidget(path, "Seed", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) {
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0)) {
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
ImGui::InputText("##RandomizerSeed", seedString, MAX_SEED_STRING_SIZE,
|
||||
ImGuiInputTextFlags_CallbackCharFilter, UIWidgets::TextFilters::FilterAlphaNum);
|
||||
UIWidgets::Tooltip("Characters from a-z, A-Z, and 0-9 are supported.\n"
|
||||
"Character limit is 1023, after which the seed will be truncated.\n");
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button(
|
||||
ICON_FA_RANDOM,
|
||||
UIWidgets::ButtonOptions()
|
||||
.Size(UIWidgets::Sizes::Inline)
|
||||
.Color(THEME_COLOR)
|
||||
.Padding(ImVec2(10.f, 6.f))
|
||||
.Tooltip("Creates a new random seed value to be used when generating a randomizer"))) {
|
||||
SohUtils::CopyStringToCharArray(seedString, std::to_string(rand() & 0xFFFFFFFF), MAX_SEED_STRING_SIZE);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button(ICON_FA_ERASER, UIWidgets::ButtonOptions()
|
||||
.Size(UIWidgets::Sizes::Inline)
|
||||
.Color(THEME_COLOR)
|
||||
.Padding(ImVec2(10.f, 6.f)))) {
|
||||
memset(seedString, 0, MAX_SEED_STRING_SIZE);
|
||||
}
|
||||
if (strnlen(seedString, MAX_SEED_STRING_SIZE) == 0) {
|
||||
ImGui::SameLine(17.0f);
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Leave blank for random seed");
|
||||
}
|
||||
UIWidgets::PopStyleInput();
|
||||
}
|
||||
});
|
||||
AddWidget(path, "Generate Randomizer", WIDGET_BUTTON)
|
||||
.Callback([](WidgetInfo& info) {
|
||||
OTRGlobals::Instance->gRandoContext->SetSpoilerLoaded(false);
|
||||
GenerateRandomizer(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0) ? seedString : "");
|
||||
})
|
||||
.PreFunc([](WidgetInfo& info) {
|
||||
info.options->Disabled((gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || GameInteractor::IsSaveLoaded());
|
||||
})
|
||||
.Options(ButtonOptions()
|
||||
.Size(ImVec2(250.f, 0.f))
|
||||
.DisabledTooltip("Must be on File Select to generate a randomizer seed."));
|
||||
AddWidget(path, "Spoiler File", WIDGET_CUSTOM)
|
||||
.CustomFunction([](WidgetInfo& info) {
|
||||
JoinRandoGenerationThread();
|
||||
if (!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
|
||||
std::string spoilerfilepath = CVarGetString(CVAR_GENERAL("SpoilerLog"), "");
|
||||
ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str());
|
||||
}
|
||||
})
|
||||
.SameLine(true);
|
||||
|
||||
// Enhancements
|
||||
path.sidebarName = "Enhancements";
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 3);
|
||||
AddWidget(path, "Randomizer Enhancements", WIDGET_SEPARATOR_TEXT);
|
||||
AddWidget(path, "Enhancements", WIDGET_SEPARATOR_TEXT);
|
||||
AddWidget(path, "These enhancements are only useful in the Randomizer mode but do not affect the randomizer logic.",
|
||||
WIDGET_TEXT)
|
||||
.Options(TextOptions().Color(UIWidgets::Colors::Gray));
|
||||
AddWidget(path, "Rando-Relevant Navi Hints", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"))
|
||||
.Options(CheckboxOptions()
|
||||
|
|
@ -98,6 +681,20 @@ void SohMenu::AddMenuRandomizer() {
|
|||
.Options(FloatSliderOptions().Min(5.0f).Max(15.0f).Format("%.2f").DefaultValue(10.0f).Tooltip(
|
||||
"The size of the item when it is picked up."));
|
||||
|
||||
auto randoSettings = Rando::Settings::GetInstance();
|
||||
randoSettings->CreateOptions();
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_LOGIC_ACCESS).AddWidgets(path);
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_DUNGEONS).AddWidgets(path);
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_SHUFFLES).AddWidgets(path);
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_HINTS_TRAPS).AddWidgets(path);
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_STARTING_ITEMS).AddWidgets(path);
|
||||
path.sidebarName = "Locations";
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 1);
|
||||
AddWidget(path, "Excluded Locations", WIDGET_CUSTOM).CustomFunction(DrawLocationsMenu);
|
||||
path.sidebarName = "Tricks/Glitches";
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 1);
|
||||
AddWidget(path, "Tricks/Glitches", WIDGET_CUSTOM).CustomFunction(DrawTricksMenu);
|
||||
|
||||
// Plandomizer
|
||||
path.sidebarName = "Plandomizer";
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 1);
|
||||
|
|
|
|||
|
|
@ -160,6 +160,10 @@ struct ButtonOptions : WidgetOptions {
|
|||
color = color_;
|
||||
return *this;
|
||||
}
|
||||
ButtonOptions& DisabledTooltip(const char* disabledTooltip_) {
|
||||
WidgetOptions::disabledTooltip = disabledTooltip_;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct ColorPickerOptions : WidgetOptions {
|
||||
|
|
|
|||
Loading…
Reference in a new issue