From b4ae604ad4f65c628799ab8f7c8192069a719c81 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 2 Feb 2026 16:17:36 -0500 Subject: [PATCH] Implement Entrance Tracker plus more cleanup --- include/macro_presets.h | 2 +- src/game/save_file.h | 1 + src/port/Rando/CheckTracker/CheckTracker.cpp | 90 +++------ src/port/Rando/CheckTracker/CheckTracker.h | 1 - .../Rando/EntranceTracker/EntranceTracker.cpp | 187 ++++++++++++++++++ .../Rando/EntranceTracker/EntranceTracker.h | 36 ++++ src/port/Rando/GhostshipMenuRando.cpp | 13 +- src/port/Rando/Logic/GeneratePools.cpp | 3 +- src/port/Rando/Logic/NoLogic.cpp | 1 + src/port/Rando/MiscBehavior/MiscBehavior.cpp | 6 + src/port/Rando/MiscBehavior/OnFileLoad.cpp | 1 + src/port/Rando/MiscBehavior/OnFileSave.cpp | 20 +- src/port/Rando/Rando.cpp | 2 + src/port/Rando/Spoiler/Generate.cpp | 1 + src/port/ShipUtils.cpp | 28 +++ src/port/ShipUtils.h | 3 + src/port/data/SaveConversion.h | 2 +- src/port/ui/GhostshipGui.cpp | 14 ++ src/port/ui/SaveEditor.cpp | 2 - 19 files changed, 333 insertions(+), 80 deletions(-) create mode 100644 src/port/Rando/EntranceTracker/EntranceTracker.cpp create mode 100644 src/port/Rando/EntranceTracker/EntranceTracker.h diff --git a/include/macro_presets.h b/include/macro_presets.h index 38b1eb69b..cb8399bac 100644 --- a/include/macro_presets.h +++ b/include/macro_presets.h @@ -11,7 +11,7 @@ struct MacroPreset { /*0x06*/ s16 param; }; -struct MacroPreset MacroObjectPresets[] = { +static struct MacroPreset MacroObjectPresets[] = { {bhvYellowCoin, MODEL_YELLOW_COIN, 0}, {bhvOneCoin, MODEL_YELLOW_COIN, 0}, {bhvMovingBlueCoin, MODEL_BLUE_COIN, 0}, diff --git a/src/game/save_file.h b/src/game/save_file.h index c0d5a1aaa..f5c411b27 100644 --- a/src/game/save_file.h +++ b/src/game/save_file.h @@ -29,6 +29,7 @@ struct RandoSaveCheck { struct RandoSaveEntrance { RandoEntranceId randoEntranceId; int16_t destinationId; + bool found; }; struct RandoSaveOption { diff --git a/src/port/Rando/CheckTracker/CheckTracker.cpp b/src/port/Rando/CheckTracker/CheckTracker.cpp index 990a60910..321fddc09 100644 --- a/src/port/Rando/CheckTracker/CheckTracker.cpp +++ b/src/port/Rando/CheckTracker/CheckTracker.cpp @@ -12,64 +12,35 @@ namespace GhostshipGui { extern std::shared_ptr mRandoCheckTrackerWindow; } -#define WIDGET_COLOR UIWidgets::Colors(CVarGetInteger("gSettings.Menu.Theme", 5)) #define DEFAULT_COLLECTED_COLOR Color_RGBA8(100, 255, 100, 255) #define DEFAULT_SKIPPED_COLOR Color_RGBA8(255, 100, 255, 255) #define DEFAULT_ITEM_COLOR Color_RGBA8(79, 0, 221, 255) #define CVAR_NAME_SHOW_CHECK_TRACKER "gWindows.CheckTracker" -#define CVAR_NAME_TRACKER_OPACITY "gRando.CheckTracker.Opacity" -#define CVAR_NAME_TRACKER_SCALE "gRando.CheckTracker.Scale" +#define CVAR_NAME_CHECK_TRACKER_OPACITY "gRando.CheckTracker.Opacity" +#define CVAR_NAME_CHECK_TRACKER_SCALE "gRando.CheckTracker.Scale" #define CVAR_NAME_SHOW_CURRENT_LEVEL "gRando.CheckTracker.ShowCurrentLevel" #define CVAR_NAME_COLLECTED_COLOR "gRando.CheckTracker.CollectedColor" #define CVAR_NAME_SKIPPED_COLOR "gRando.CheckTracker.SkippedColor" #define CVAR_NAME_ITEM_COLOR "gRando.CheckTracker.ItemColor" #define CVAR_SHOW_CHECK_TRACKER CVarGetInteger(CVAR_NAME_SHOW_CHECK_TRACKER, 0) -#define CVAR_TRACKER_OPACITY CVarGetFloat(CVAR_NAME_TRACKER_OPACITY, 0.5f) -#define CVAR_TRACKER_SCALE CVarGetFloat(CVAR_NAME_TRACKER_SCALE, 1.0f) +#define CVAR_CHECK_TRACKER_OPACITY CVarGetFloat(CVAR_NAME_CHECK_TRACKER_OPACITY, 0.5f) +#define CVAR_CHECK_TRACKER_SCALE CVarGetFloat(CVAR_NAME_CHECK_TRACKER_SCALE, 1.0f) #define CVAR_SHOW_CURRENT_LEVEL CVarGetInteger(CVAR_NAME_SHOW_CURRENT_LEVEL, 0) #define CVAR_COLLECTED_COLOR CVarGetColor(CVAR_NAME_COLLECTED_COLOR ".Value", DEFAULT_COLLECTED_COLOR) #define CVAR_SKIPPED_COLOR CVarGetColor(CVAR_NAME_SKIPPED_COLOR ".Value", DEFAULT_SKIPPED_COLOR) #define CVAR_ITEM_COLOR CVarGetColor(CVAR_NAME_ITEM_COLOR ".Value", DEFAULT_ITEM_COLOR) -std::vector> defaultColorList = { +std::vector> defaultCheckColorList = { { CVAR_NAME_COLLECTED_COLOR, DEFAULT_COLLECTED_COLOR, "Check Obtained" }, { CVAR_NAME_SKIPPED_COLOR, DEFAULT_SKIPPED_COLOR, "Check Skipped" }, { CVAR_NAME_ITEM_COLOR, DEFAULT_ITEM_COLOR, "Obtained Item" }, }; -std::map levelIdList = { - { LEVEL_BOB, "Bob Omb Battlefield" }, - { LEVEL_WF, "Whomp's Fortress" }, - { LEVEL_JRB, "Jolly Rodger's Bay" }, - { LEVEL_CASTLE, "Castle Interior" }, - { LEVEL_CCM, "Cool Cool Mountain" }, - { LEVEL_BBH, "Big Boo's Haunt" }, - { LEVEL_HMC, "Hazy Maze Cave" }, - { LEVEL_LLL, "Lethal Lava Land" }, - { LEVEL_SSL, "Shifting Sand Land" }, - { LEVEL_DDD, "Dire Dire Docks" }, - { LEVEL_SL, "Snowman's Land" }, - { LEVEL_WDW, "Wet Dry World" }, - { LEVEL_TTM, "Tall Tall Mountain" }, - { LEVEL_THI, "Tiny Huge Island" }, - { LEVEL_TTC, "Tick Tock Clock" }, - { LEVEL_RR, "Rainbow Ride" }, - { LEVEL_BITDW, "Bowser in the Dark World" }, - { LEVEL_BITFS, "Bowser in the Fire Sea" }, - { LEVEL_BITS, "Bowser in the Sky" }, - { LEVEL_PSS, "Princess's Secret Slide" }, - { LEVEL_COTMC, "Cavern of the Metal Cap" }, - { LEVEL_TOTWC, "Tower of the Wing Cap" }, - { LEVEL_VCUTM, "Vanish Cap Under the Moat" }, - { LEVEL_WMOTR, "Winged Mario over the Rainbow" }, - { LEVEL_SA, "Secret Aquarium" }, -}; - -bool trackerPopoutState = false; -ImVec4 trackerBG = ImVec4{ 0, 0, 0, 0.5f }; -float trackerScale = 1.0f; +bool checkTrackerPopoutState = false; +ImVec4 checkTrackerBG = ImVec4{ 0, 0, 0, 0.5f }; +float checkTrackerScale = 1.0f; bool expandState = true; @@ -89,7 +60,7 @@ void DrawCheckTrackerList() { if (ImGui::CollapsingHeader(name.c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Indent(20.0f); if (ImGui::BeginTable("CheckList", 2)) { - ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, (16.0f * trackerScale)); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, (16.0f * checkTrackerScale)); ImGui::TableSetupColumn("Check"); ImGui::TableNextColumn(); @@ -114,7 +85,7 @@ void DrawCheckTrackerList() { Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(texture); ImGui::BeginGroup(); - ImGui::Image(textureId, ImVec2(16.0f * trackerScale, 16.0f * trackerScale)); + ImGui::Image(textureId, ImVec2(16.0f * checkTrackerScale, 16.0f * checkTrackerScale)); ImGui::TableNextColumn(); ImGui::TextColored(checkTextColor, Rando::StaticData::Checks[entry.randoCheckId].name); if (randoSaveCheck.obtained) { @@ -153,17 +124,17 @@ void CheckTrackerWindow::Draw() { return; } - ImGui::PushStyleColor(ImGuiCol_TitleBgActive, trackerBG); - ImGui::PushStyleColor(ImGuiCol_TitleBg, trackerBG); - ImGui::PushStyleColor(ImGuiCol_WindowBg, trackerBG); + ImGui::PushStyleColor(ImGuiCol_TitleBgActive, checkTrackerBG); + ImGui::PushStyleColor(ImGuiCol_TitleBg, checkTrackerBG); + ImGui::PushStyleColor(ImGuiCol_WindowBg, checkTrackerBG); ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); ImGui::SetNextWindowSize(ImVec2(485.0f, 500.0f), ImGuiCond_FirstUseEver); if (ImGui::Begin("Check Tracker", nullptr, ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing)) { - trackerBG.w = ImGui::IsWindowDocked() ? 1.0f : CVAR_TRACKER_OPACITY; - ImGui::SetWindowFontScale(trackerScale); + checkTrackerBG.w = ImGui::IsWindowDocked() ? 1.0f : CVAR_CHECK_TRACKER_OPACITY; + ImGui::SetWindowFontScale(checkTrackerScale); if (Rando::Logic::shuffledPool.empty()) { ImGui::TextColored(UIWidgets::ColorValues.at(UIWidgets::Colors::Orange), "No Rando Save Loaded"); ImGui::End(); @@ -186,11 +157,11 @@ void CheckTrackerWindow::Draw() { void SettingsWindow::DrawElement() { if (CVarGetInteger("gWindows.CheckTracker", 0)) { - trackerPopoutState = true; + checkTrackerPopoutState = true; UIWidgets::WindowButton("Return Check Tracker", "gWindows.CheckTracker", GhostshipGui::mRandoCheckTrackerWindow, { .size = UIWidgets::Sizes::Inline, .color = UIWidgets::Colors::Red }); } else { - trackerPopoutState = false; + checkTrackerPopoutState = false; UIWidgets::WindowButton("Popout Check Tracker", "gWindows.CheckTracker", GhostshipGui::mRandoCheckTrackerWindow, { .size = UIWidgets::Sizes::Inline, .color = UIWidgets::Colors::Green }); } @@ -200,7 +171,7 @@ void SettingsWindow::DrawElement() { ImGui::TableNextColumn(); ImGui::SeparatorText("Check Tracker"); - if (!trackerPopoutState) { + if (!checkTrackerPopoutState) { if (ImGui::BeginChild("Checks", ImVec2(ImGui::GetContentRegionAvail().x, 0))) { DrawCheckTrackerList(); ImGui::EndChild(); @@ -227,7 +198,7 @@ void SettingsWindow::DrawElement() { // UIWidgets::CheckboxOptions().DefaultValue(true)); UIWidgets::CVarCheckbox("Show Check Type Filters", // CVAR_NAME_SHOW_CHECK_TYPE_FILTER); - if (UIWidgets::CVarSliderFloat("", CVAR_NAME_TRACKER_OPACITY, + if (UIWidgets::CVarSliderFloat("", CVAR_NAME_CHECK_TRACKER_OPACITY, { .format = "Opacity: %.1f", .step = 0.10f, @@ -237,10 +208,10 @@ void SettingsWindow::DrawElement() { .labelPosition = UIWidgets::LabelPositions::None, .color = WIDGET_COLOR, })) { - trackerBG.w = CVAR_TRACKER_OPACITY; + checkTrackerBG.w = CVAR_CHECK_TRACKER_OPACITY; } - if (UIWidgets::CVarSliderFloat(" ", CVAR_NAME_TRACKER_SCALE, + if (UIWidgets::CVarSliderFloat(" ", CVAR_NAME_CHECK_TRACKER_SCALE, { .format = "Scale: %.1f", .step = 0.10f, @@ -250,19 +221,19 @@ void SettingsWindow::DrawElement() { .labelPosition = UIWidgets::LabelPositions::None, .color = WIDGET_COLOR, })) { - trackerScale = CVAR_TRACKER_SCALE; + checkTrackerScale = CVAR_CHECK_TRACKER_SCALE; } - int16_t colorIndex = 0; - for (auto& [cvar, color, label] : defaultColorList) { + int16_t checkColorIndex = 0; + for (auto& [cvar, color, label] : defaultCheckColorList) { std::string cvarText = cvar; cvarText += ".Value"; std::string colorText = label; colorText += " Color"; std::string widgetLabel = "##"; - widgetLabel += std::to_string(colorIndex); + widgetLabel += std::to_string(checkColorIndex); - ImGui::PushID(colorIndex); + ImGui::PushID(checkColorIndex); UIWidgets::CVarColorPicker(widgetLabel.c_str(), cvar, color, true); ImGui::SameLine(); if (UIWidgets::Button(ICON_FA_REFRESH, { .size = ImVec2(32.0f, 32.0f), .color = WIDGET_COLOR })) { @@ -272,17 +243,16 @@ void SettingsWindow::DrawElement() { ImGui::SameLine(); ImGui::Text(colorText.c_str()); ImGui::PopID(); - colorIndex++; + checkColorIndex++; } ImGui::EndTable(); } } -bool isInitialized = false; void Init() { - trackerPopoutState = CVarGetInteger("gWindows.CheckTracker", 0); - trackerBG = { 0, 0, 0, CVAR_TRACKER_OPACITY }; - trackerScale = CVAR_TRACKER_SCALE; + checkTrackerPopoutState = CVarGetInteger("gWindows.CheckTracker", 0); + checkTrackerBG = { 0, 0, 0, CVAR_CHECK_TRACKER_OPACITY }; + checkTrackerScale = CVAR_CHECK_TRACKER_SCALE; } } // namespace CheckTracker diff --git a/src/port/Rando/CheckTracker/CheckTracker.h b/src/port/Rando/CheckTracker/CheckTracker.h index 0babc84d6..451ba5a48 100644 --- a/src/port/Rando/CheckTracker/CheckTracker.h +++ b/src/port/Rando/CheckTracker/CheckTracker.h @@ -9,7 +9,6 @@ namespace Rando { namespace CheckTracker { void Init(); -//void OnFileLoad(); class CheckTrackerWindow : public Ship::GuiWindow { public: diff --git a/src/port/Rando/EntranceTracker/EntranceTracker.cpp b/src/port/Rando/EntranceTracker/EntranceTracker.cpp new file mode 100644 index 000000000..27442dc04 --- /dev/null +++ b/src/port/Rando/EntranceTracker/EntranceTracker.cpp @@ -0,0 +1,187 @@ +#include "EntranceTracker.h" +#include "port/Rando/Logic/Logic.h" +#include "port/ShipUtils.h" +#include "port/ui/UIWidgets.hpp" +#include + +namespace GhostshipGui { +extern std::shared_ptr mRandoEntranceTrackerWindow; +} + +#define DEFAULT_FOUND_COLOR Color_RGBA8(100, 255, 100, 255) + +#define CVAR_NAME_SHOW_ENTRANCE_TRACKER "gWindows.EntranceTracker" +#define CVAR_NAME_ENTRANCE_TRACKER_OPACITY "gRando.EntranceTracker.Opacity" +#define CVAR_NAME_ENTRANCE_TRACKER_SCALE "gRando.EntranceTracker.Scale" +#define CVAR_NAME_FOUND_COLOR "gRando.EntranceTracker.FoundColor" + +#define CVAR_SHOW_ENTRANCE_TRACKER CVarGetInteger(CVAR_NAME_SHOW_ENTRANCE_TRACKER, 0) +#define CVAR_ENTRANCE_TRACKER_OPACITY CVarGetFloat(CVAR_NAME_ENTRANCE_TRACKER_OPACITY, 0.5f) +#define CVAR_ENTRANCE_TRACKER_SCALE CVarGetFloat(CVAR_NAME_ENTRANCE_TRACKER_SCALE, 1.0f) +#define CVAR_FOUND_COLOR CVarGetColor(CVAR_NAME_FOUND_COLOR ".Value", DEFAULT_FOUND_COLOR) + +std::vector> defaultEntranceColorList = { + { CVAR_NAME_FOUND_COLOR, DEFAULT_FOUND_COLOR, "Entrance Found" }, +}; + +bool entranceTrackerPopoutState = false; +ImVec4 entranceTrackerBG = ImVec4{ 0, 0, 0, 0.5f }; +float entranceTrackerScale = 1.0f; + +void DrawEntranceTrackerList() { + if (Rando::Logic::shuffledEntrances.empty()) { + return; + } + + if (ImGui::BeginTable("EntranceList", 2)) { + ImGui::TableNextColumn(); + for (auto& [entranceId, destinationId, isFound] : Rando::Logic::shuffledEntrances) { + if (entranceId == RE_UNKNOWN) { + continue; + } + + const char* entranceName = levelIdList.at(Rando::StaticData::Entrances[entranceId].destinationId).c_str(); + const char* destinationName = levelIdList.at(destinationId).c_str(); + ImVec4 foundTextColor = VecFromRGBA8(CVAR_FOUND_COLOR); + + ImGui::Text(entranceName); + ImGui::TableNextColumn(); + if (isFound) { + ImGui::TextColored(foundTextColor, "(%s)", destinationName); + } + ImGui::TableNextColumn(); + } + ImGui::EndTable(); + } +} + +namespace Rando { + +namespace EntranceTracker { + +void EntranceTrackerWindow::Draw() { + if (!CVAR_SHOW_ENTRANCE_TRACKER) { + return; + } + + ImGui::PushStyleColor(ImGuiCol_TitleBgActive, entranceTrackerBG); + ImGui::PushStyleColor(ImGuiCol_TitleBg, entranceTrackerBG); + ImGui::PushStyleColor(ImGuiCol_WindowBg, entranceTrackerBG); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); + + ImGui::SetNextWindowSize(ImVec2(485.0f, 500.0f), ImGuiCond_FirstUseEver); + + if (ImGui::Begin("Entrance Tracker", nullptr, ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing)) { + ImGui::SetWindowFontScale(entranceTrackerScale); + + if (Rando::Logic::shuffledEntrances.empty()) { + ImGui::TextColored(UIWidgets::ColorValues.at(UIWidgets::Colors::Orange), "No Rando Save Loaded"); + ImGui::End(); + ImGui::PopStyleColor(4); + ImGui::PopStyleVar(1); + return; + } + + if (ImGui::BeginChild("Entrances")) { + DrawEntranceTrackerList(); + ImGui::EndChild(); + } + + ImGui::End(); + ImGui::PopStyleColor(4); + ImGui::PopStyleVar(1); + } +} + +void SettingsWindow::DrawElement() { + if (CVarGetInteger("gWindows.EntranceTracker", 0)) { + entranceTrackerPopoutState = true; + UIWidgets::WindowButton("Return Entrance Tracker", "gWindows.EntranceTracker", + GhostshipGui::mRandoEntranceTrackerWindow, + { .size = UIWidgets::Sizes::Inline, .color = UIWidgets::Colors::Red }); + } else { + entranceTrackerPopoutState = false; + UIWidgets::WindowButton("Popout Entrance Tracker", "gWindows.EntranceTracker", + GhostshipGui::mRandoEntranceTrackerWindow, + { .size = UIWidgets::Sizes::Inline, .color = UIWidgets::Colors::Green }); + } + if (ImGui::BeginTable("Settings Table", 2)) { + ImGui::TableSetupColumn("col1", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("col2", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableNextColumn(); + + ImGui::SeparatorText("Entrance Tracker"); + if (!entranceTrackerPopoutState) { + if (ImGui::BeginChild("Entrances", ImVec2(ImGui::GetContentRegionAvail().x, 0))) { + DrawEntranceTrackerList(); + ImGui::EndChild(); + } + } else { + ImGui::TextColored(UIWidgets::ColorValues.at(WIDGET_COLOR), "Tracker popped out"); + } + + ImGui::TableNextColumn(); + ImGui::SeparatorText("Window Settings"); + // UIWidgets::CVarCheckbox("Show Search", CVAR_NAME_SHOW_SEARCH, + + if (UIWidgets::CVarSliderFloat("", CVAR_NAME_ENTRANCE_TRACKER_OPACITY, + { + .format = "Opacity: %.1f", + .step = 0.10f, + .min = 0.0f, + .max = 1.0f, + .defaultValue = 0.5f, + .labelPosition = UIWidgets::LabelPositions::None, + .color = WIDGET_COLOR, + })) { + entranceTrackerBG.w = CVAR_ENTRANCE_TRACKER_OPACITY; + } + + if (UIWidgets::CVarSliderFloat(" ", CVAR_NAME_ENTRANCE_TRACKER_SCALE, + { + .format = "Scale: %.1f", + .step = 0.10f, + .min = 0.7f, + .max = 2.5f, + .defaultValue = 1.0f, + .labelPosition = UIWidgets::LabelPositions::None, + .color = WIDGET_COLOR, + })) { + entranceTrackerScale = CVAR_ENTRANCE_TRACKER_SCALE; + } + + int16_t entranceColorIndex = 0; + for (auto& [cvar, color, label] : defaultEntranceColorList) { + std::string cvarText = cvar; + cvarText += ".Value"; + std::string colorText = label; + colorText += " Color"; + std::string widgetLabel = "##"; + widgetLabel += std::to_string(entranceColorIndex); + + ImGui::PushID(entranceColorIndex); + UIWidgets::CVarColorPicker(widgetLabel.c_str(), cvar, color, true); + ImGui::SameLine(); + if (UIWidgets::Button(ICON_FA_REFRESH, { .size = ImVec2(32.0f, 32.0f), .color = WIDGET_COLOR })) { + CVarSetColor(cvarText.c_str(), color); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + } + ImGui::SameLine(); + ImGui::Text(colorText.c_str()); + ImGui::PopID(); + entranceColorIndex++; + } + + ImGui::EndTable(); + } +} + +void Init() { + entranceTrackerPopoutState = CVarGetInteger("gWindows.EntranceTracker", 0); + entranceTrackerBG = { 0, 0, 0, CVAR_ENTRANCE_TRACKER_OPACITY }; + entranceTrackerScale = CVAR_ENTRANCE_TRACKER_SCALE; +} + +} // namespace EntranceTracker +} // namespace Rando \ No newline at end of file diff --git a/src/port/Rando/EntranceTracker/EntranceTracker.h b/src/port/Rando/EntranceTracker/EntranceTracker.h new file mode 100644 index 000000000..4460a40b5 --- /dev/null +++ b/src/port/Rando/EntranceTracker/EntranceTracker.h @@ -0,0 +1,36 @@ +#ifndef RANDO_ENTRANCE_TRACKER_H +#define RANDO_ENTRANCE_TRACKER_H + +#include "port/Rando/Rando.h" +#include + +namespace Rando { + +namespace EntranceTracker { + +void Init(); + +class EntranceTrackerWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override{}; + void DrawElement() override{}; + void Draw() override; + void UpdateElement() override{}; +}; + +class SettingsWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override{}; + void DrawElement() override; + void UpdateElement() override{}; +}; + +} // namespace EntranceTracker + +} // namespace Rando + +#endif // RANDO_ENTRANCE_TRACKER_H \ No newline at end of file diff --git a/src/port/Rando/GhostshipMenuRando.cpp b/src/port/Rando/GhostshipMenuRando.cpp index 2c6b1ae90..66ac2d412 100644 --- a/src/port/Rando/GhostshipMenuRando.cpp +++ b/src/port/Rando/GhostshipMenuRando.cpp @@ -1,15 +1,16 @@ #include "port/ui/GhostshipMenu.h" #include "port/Rando/CheckTracker/CheckTracker.h" +#include "port/Rando/EntranceTracker/EntranceTracker.h" #include "port/Rando/Spoiler/Spoiler.h" #include "port/ui/Notification.h" -#define WIDGET_COLOR UIWidgets::Colors(CVarGetInteger("gSettings.Menu.Theme", 5)) - namespace GhostshipGui { extern std::shared_ptr mGhostshipMenu; extern std::shared_ptr mRandoCheckTrackerWindow; extern std::shared_ptr mRandoCheckTrackerSettingsWindow; +extern std::shared_ptr mRandoEntranceTrackerWindow; +extern std::shared_ptr mRandoEntranceTrackerSettingsWindow; using namespace UIWidgets; void GhostshipMenu::AddMenuRando() { @@ -168,6 +169,14 @@ void GhostshipMenu::AddMenuRando() { AddWidget(path, "Popout Settings", WIDGET_WINDOW_BUTTON) .CVar("gWindows.CheckTrackerSettings") .WindowName("Check Tracker Settings"); + + path = { "Rando", "Entrance Tracker", SECTION_COLUMN_1 }; + AddSidebarEntry("Rando", path.sidebarName, 1); + path.column = SECTION_COLUMN_1; + + AddWidget(path, "Popout Settings", WIDGET_WINDOW_BUTTON) + .CVar("gWindows.EntranceTrackerSettings") + .WindowName("Entrance Tracker Settings"); } } // namespace GhostshipGui diff --git a/src/port/Rando/Logic/GeneratePools.cpp b/src/port/Rando/Logic/GeneratePools.cpp index 2c44ce673..908c1082c 100644 --- a/src/port/Rando/Logic/GeneratePools.cpp +++ b/src/port/Rando/Logic/GeneratePools.cpp @@ -75,7 +75,8 @@ void InitializeSaveChecks() { void InitializeSaveEntrances() { for (auto& [randoEntranceId, randoStaticEntrance] : Rando::StaticData::Entrances) { RandoSaveEntrance randoSaveEntrance = { .randoEntranceId = randoEntranceId, - .destinationId = randoStaticEntrance.destinationId }; + .destinationId = randoStaticEntrance.destinationId, + .found = false }; RANDO_SAVE_ENTRANCES(selectedFileNum)[randoEntranceId] = randoSaveEntrance; } } diff --git a/src/port/Rando/Logic/NoLogic.cpp b/src/port/Rando/Logic/NoLogic.cpp index e6cb935ce..d7c50381b 100644 --- a/src/port/Rando/Logic/NoLogic.cpp +++ b/src/port/Rando/Logic/NoLogic.cpp @@ -41,6 +41,7 @@ void ApplyNoLogicToSaveContext(std::vector>& init RandoSaveEntrance randoSaveEntrance; randoSaveEntrance.randoEntranceId = entranceIds[e]; randoSaveEntrance.destinationId = initialLevelPool[e]; + randoSaveEntrance.found = false; entrancePool.push_back(randoSaveEntrance); } } diff --git a/src/port/Rando/MiscBehavior/MiscBehavior.cpp b/src/port/Rando/MiscBehavior/MiscBehavior.cpp index 05b455ad7..c477c5a6d 100644 --- a/src/port/Rando/MiscBehavior/MiscBehavior.cpp +++ b/src/port/Rando/MiscBehavior/MiscBehavior.cpp @@ -1,4 +1,5 @@ #include "MiscBehavior.h" +#include "port/Rando/Logic/Logic.h" #include "port/hooks/list/EngineEvent.h" extern "C" { @@ -72,6 +73,11 @@ void Rando::MiscBehavior::Init() { // TODO: Handle Tiny Huge Islands size changes, Wet Dry World water level, and Tick Tock Clocks // clock. ev->warpNode->destLevel = RANDO_SAVE_ENTRANCES(selectedFileNum)[randoEntranceId].destinationId; + for (auto& entrance : Rando::Logic::shuffledEntrances) { + if (entrance.randoEntranceId == randoEntranceId) { + entrance.found = true; + } + } currentEntrance = randoEntranceId; break; } diff --git a/src/port/Rando/MiscBehavior/OnFileLoad.cpp b/src/port/Rando/MiscBehavior/OnFileLoad.cpp index db459a26b..6ea1c5efc 100644 --- a/src/port/Rando/MiscBehavior/OnFileLoad.cpp +++ b/src/port/Rando/MiscBehavior/OnFileLoad.cpp @@ -68,6 +68,7 @@ void Rando::MiscBehavior::OnFileLoad() { RandoSaveEntrance randoSaveEntrance; randoSaveEntrance.randoEntranceId = entrance.randoEntranceId; randoSaveEntrance.destinationId = entrance.destinationId; + randoSaveEntrance.found = entrance.found; RANDO_SAVE_ENTRANCES(selectedFileNum)[entrance.randoEntranceId] = randoSaveEntrance; } diff --git a/src/port/Rando/MiscBehavior/OnFileSave.cpp b/src/port/Rando/MiscBehavior/OnFileSave.cpp index 32fb3457e..3302ba3ec 100644 --- a/src/port/Rando/MiscBehavior/OnFileSave.cpp +++ b/src/port/Rando/MiscBehavior/OnFileSave.cpp @@ -11,21 +11,17 @@ void Rando::MiscBehavior::OnFileSave() { return; } - for (auto& pool : Rando::Logic::shuffledPool) { + for (auto& check : Rando::Logic::shuffledPool) { RandoSaveCheck randoSaveCheck; - randoSaveCheck.randoItemId = pool.randoItemId; - randoSaveCheck.randoAct = pool.randoAct; - randoSaveCheck.obtained = pool.obtained; + randoSaveCheck.randoItemId = check.randoItemId; + randoSaveCheck.randoAct = check.randoAct; + randoSaveCheck.obtained = check.obtained; - RANDO_SAVE_CHECKS(selectedFileNum)[pool.randoCheckId] = randoSaveCheck; + RANDO_SAVE_CHECKS(selectedFileNum)[check.randoCheckId] = randoSaveCheck; } - // TODO: Inject Save File with spoiler data - // gSaveBuffer.files[ev->fileNum]->shipSaveData.randoSaveData.isRando = true; - - // bcopy(&gSaveBuffer.files[ev->fileNum][0], &gSaveBuffer.files[ev->fileNum][1], - // sizeof(gSaveBuffer.files[ev->fileNum][1])); - - // write_eeprom_data(&gSaveBuffer.menuData[ev->fileNum], sizeof(gSaveBuffer.menuData[ev->fileNum])); + for (auto& entrance : Rando::Logic::shuffledEntrances) { + RANDO_SAVE_ENTRANCES(selectedFileNum)[entrance.randoEntranceId].found = entrance.found; + } }); } \ No newline at end of file diff --git a/src/port/Rando/Rando.cpp b/src/port/Rando/Rando.cpp index c8e5a4677..0986c716c 100644 --- a/src/port/Rando/Rando.cpp +++ b/src/port/Rando/Rando.cpp @@ -3,6 +3,7 @@ #include "ObjectBehavior/ObjectBehavior.h" #include "MiscBehavior/MiscBehavior.h" #include "port/Rando/CheckTracker/CheckTracker.h" +#include "port/Rando/EntranceTracker/EntranceTracker.h" #include "port/Rando/Spoiler/Spoiler.h" #include "port/ShipInit.hpp" @@ -23,6 +24,7 @@ void Rando::Init() { Rando::MiscBehavior::Init(); Rando::ObjectBehavior::Init(); Rando::CheckTracker::Init(); + Rando::EntranceTracker::Init(); // Ship::Context::GetInstance()->GetFileDropMgr()->RegisterDropHandler(Rando::Spoiler::HandleFileDropped); } diff --git a/src/port/Rando/Spoiler/Generate.cpp b/src/port/Rando/Spoiler/Generate.cpp index f04a5d275..771f714e0 100644 --- a/src/port/Rando/Spoiler/Generate.cpp +++ b/src/port/Rando/Spoiler/Generate.cpp @@ -90,6 +90,7 @@ void GenerateFromSpoiler(nlohmann::json spoiler) { for (auto& [entranceId, staticEntrance] : Rando::StaticData::Entrances) { if (staticEntrance.name == data.key()) { randoSaveEntrance.randoEntranceId = entranceId; + randoSaveEntrance.found = false; } if (staticEntrance.name == data.value()) { randoSaveEntrance.destinationId = staticEntrance.destinationId; diff --git a/src/port/ShipUtils.cpp b/src/port/ShipUtils.cpp index 8023ae685..2ba07ff40 100644 --- a/src/port/ShipUtils.cpp +++ b/src/port/ShipUtils.cpp @@ -34,6 +34,34 @@ std::vector levelAbbreviations = { "THI", "TTC", "RR", "BITDW", "BITFS", "BITS", "PSS", "COTMC", "TOTWC", "VCUTM", "WMOTR", "SA", }; +std::map levelIdList = { + { LEVEL_BOB, "Bob Omb Battlefield" }, + { LEVEL_WF, "Whomp's Fortress" }, + { LEVEL_JRB, "Jolly Roger's Bay" }, + { LEVEL_CASTLE, "Castle Interior" }, + { LEVEL_CCM, "Cool Cool Mountain" }, + { LEVEL_BBH, "Big Boo's Haunt" }, + { LEVEL_HMC, "Hazy Maze Cave" }, + { LEVEL_LLL, "Lethal Lava Land" }, + { LEVEL_SSL, "Shifting Sand Land" }, + { LEVEL_DDD, "Dire Dire Docks" }, + { LEVEL_SL, "Snowman's Land" }, + { LEVEL_WDW, "Wet Dry World" }, + { LEVEL_TTM, "Tall Tall Mountain" }, + { LEVEL_THI, "Tiny Huge Island" }, + { LEVEL_TTC, "Tick Tock Clock" }, + { LEVEL_RR, "Rainbow Ride" }, + { LEVEL_BITDW, "Bowser in the Dark World" }, + { LEVEL_BITFS, "Bowser in the Fire Sea" }, + { LEVEL_BITS, "Bowser in the Sky" }, + { LEVEL_PSS, "Princess's Secret Slide" }, + { LEVEL_COTMC, "Cavern of the Metal Cap" }, + { LEVEL_TOTWC, "Tower of the Wing Cap" }, + { LEVEL_VCUTM, "Vanish Cap Under the Moat" }, + { LEVEL_WMOTR, "Winged Mario over the Rainbow" }, + { LEVEL_SA, "Secret Aquarium" }, +}; + std::map levelToCourseMap = { { LEVEL_BBH, COURSE_BBH }, { LEVEL_CASTLE, COURSE_NONE }, { LEVEL_CCM, COURSE_CCM }, { LEVEL_HMC, COURSE_HMC }, { LEVEL_SSL, COURSE_SSL }, { LEVEL_BOB, COURSE_BOB }, diff --git a/src/port/ShipUtils.h b/src/port/ShipUtils.h index 40396de4f..f1277e16e 100644 --- a/src/port/ShipUtils.h +++ b/src/port/ShipUtils.h @@ -5,6 +5,8 @@ #ifdef __cplusplus +#define WIDGET_COLOR UIWidgets::Colors(CVarGetInteger("gSettings.Menu.Theme", 5)) + #define MAX_SEED_STRING_SIZE 1024 extern char seedString[MAX_SEED_STRING_SIZE]; extern u32 finalSeed; @@ -13,6 +15,7 @@ uint32_t Ship_Hash(std::string str); void LoadGuiTextures(); extern std::array digitList; +extern std::map levelIdList; extern "C" { #endif diff --git a/src/port/data/SaveConversion.h b/src/port/data/SaveConversion.h index 5d95216e1..b5fcf4fab 100644 --- a/src/port/data/SaveConversion.h +++ b/src/port/data/SaveConversion.h @@ -6,7 +6,7 @@ #include NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(RandoSaveCheck, randoItemId, randoAct, obtained, skipped) -NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(RandoSaveEntrance, randoEntranceId, destinationId) +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(RandoSaveEntrance, randoEntranceId, destinationId, found) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(RandoSaveData, randoSaveChecks, randoSaveEntrances, randoSaveOptions, finalSeed) using json = nlohmann::json; diff --git a/src/port/ui/GhostshipGui.cpp b/src/port/ui/GhostshipGui.cpp index 91e4e315a..3a121fccf 100644 --- a/src/port/ui/GhostshipGui.cpp +++ b/src/port/ui/GhostshipGui.cpp @@ -16,6 +16,7 @@ #include "GhostshipInputEditorWindow.h" #include "SaveEditor.h" #include "port/Rando/CheckTracker/CheckTracker.h" +#include "port/Rando/EntranceTracker/EntranceTracker.h" namespace GhostshipGui { // MARK: - Delegates @@ -30,6 +31,9 @@ std::shared_ptr mModalWindow; std::shared_ptr mRandoCheckTrackerWindow; std::shared_ptr mRandoCheckTrackerSettingsWindow; +std::shared_ptr mRandoEntranceTrackerWindow; +std::shared_ptr mRandoEntranceTrackerSettingsWindow; + UIWidgets::Colors GetMenuThemeColor() { return mGhostshipMenu->GetMenuThemeColor(); } @@ -72,6 +76,14 @@ void SetupGuiElements() { mRandoCheckTrackerSettingsWindow = std::make_shared( "gWindows.CheckTrackerSettings", "Check Tracker Settings"); gui->AddGuiWindow(mRandoCheckTrackerSettingsWindow); + + mRandoEntranceTrackerWindow = std::make_shared( + "gWindows.EntranceTracker", "Entrance Tracker", ImVec2(375, 460)); + gui->AddGuiWindow(mRandoEntranceTrackerWindow); + + mRandoEntranceTrackerSettingsWindow = std::make_shared( + "gWindows.EntranceTrackerSettings", "Entrance Tracker Settings"); + gui->AddGuiWindow(mRandoEntranceTrackerSettingsWindow); } void Destroy() { @@ -87,6 +99,8 @@ void Destroy() { mInputViewerSettings = nullptr; mRandoCheckTrackerWindow = nullptr; mRandoCheckTrackerSettingsWindow = nullptr; + mRandoEntranceTrackerWindow = nullptr; + mRandoEntranceTrackerSettingsWindow = nullptr; } void RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, diff --git a/src/port/ui/SaveEditor.cpp b/src/port/ui/SaveEditor.cpp index 871760302..38866f46b 100644 --- a/src/port/ui/SaveEditor.cpp +++ b/src/port/ui/SaveEditor.cpp @@ -22,8 +22,6 @@ extern SaveBuffer gSaveBuffer; extern MarioState* gMarioState; } -#define WIDGET_COLOR UIWidgets::Colors(CVarGetInteger("gSettings.Menu.Theme", 5)) - #define DEFINE_COURSE(_0, _1, name) name, #define DEFINE_COURSES_END() #define DEFINE_BONUS_COURSE(_0, _1, name) name,