From 22d88f81ccc63445fc319a128991de7de1446e73 Mon Sep 17 00:00:00 2001 From: Anthony Stewart Date: Thu, 10 Jul 2025 19:08:19 -0500 Subject: [PATCH] Initial LogicTrackerWindow::ShowRandomizerRegion. --- .../randomizer/randomizer_check_tracker.cpp | 4 +- .../randomizer/randomizer_logic_tracker.cpp | 269 ++++++++++++++---- .../randomizer/randomizer_logic_tracker.h | 3 +- 3 files changed, 217 insertions(+), 59 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 81ca6fa14..303c089fe 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1928,11 +1928,9 @@ void DrawLocation(RandomizerCheck rc) { } ImGui::SameLine(); - ImGui::PushID((std::to_string(rc) + "_SHOW_CHECK_LOGIC").c_str()); - if (ImGui::Button("Show Check Logic")) { + if (ImGui::Button(("Show Check Logic##" + std::to_string(rc)).c_str())) { LogicTrackerWindow::ShowRandomizerCheck(rc); } - ImGui::PopID(); } } diff --git a/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.cpp index 561feb3c5..67ebfb03c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.cpp @@ -1,6 +1,7 @@ #include "randomizer_logic_tracker.h" #include "location_access.h" +#include "entrance.h" #include "logic_expression.h" #include "../../OTRGlobals.h" @@ -14,23 +15,28 @@ extern PlayState* gPlayState; uint64_t GetUnixTimestamp(); } +struct ExpressionTable { + struct ExpressionRow { + std::shared_ptr Expression; + std::vector Children; + std::optional ChildDay; + std::optional ChildNight; + std::optional AdultDay; + std::optional AdultNight; + bool Expanded; + }; + + ExpressionRow Root; + bool CombineAll = false; + bool CombineChild = false; + bool CombineAdult = false; +}; + struct LogicTrackerCheck { struct Region { - struct ExpressionRow { - std::shared_ptr Expression; - std::vector Children; - std::optional ChildDay; - std::optional ChildNight; - std::optional AdultDay; - std::optional AdultNight; - bool Expanded; - }; - std::string RegionName; - ExpressionRow Root; - bool CombineAll = false; - bool CombineChild = false; - bool CombineAdult = false; + RandomizerRegion RandomizerRegion; + ExpressionTable ExpressionTable; bool ChildDayAccess = false; bool ChildNightAccess = false; @@ -42,10 +48,24 @@ struct LogicTrackerCheck { std::vector Regions; }; -std::unique_ptr check; +struct LogicTrackerRegion { + struct Entrance { + std::string ParentName; + RandomizerRegion ParentRandomizerRegion; + ExpressionTable ExpressionTable; -LogicTrackerCheck::Region::ExpressionRow CreateExpressionRows(const std::shared_ptr& expression) { - LogicTrackerCheck::Region::ExpressionRow row; + bool ChildDayAccess = false; + bool ChildNightAccess = false; + bool AdultDayAccess = false; + bool AdultNightAccess = false; + }; + + std::string RegionName; + std::vector Entrances; +}; + +static ExpressionTable::ExpressionRow CreateExpressionRows(const std::shared_ptr& expression) { + ExpressionTable::ExpressionRow row; row.Expression = expression; row.Expanded = false; @@ -66,7 +86,8 @@ enum class AgeTime { }; -static void PopulateExpressionValues(LogicTrackerCheck::Region::ExpressionRow& row, const ExpressionEvaluation& eval, AgeTime ageTime) { +static void PopulateExpressionValues(ExpressionTable::ExpressionRow& row, const ExpressionEvaluation& eval, + AgeTime ageTime) { if (ageTime == AgeTime::ChildDay) { row.ChildDay = eval.Result; } else if (ageTime == AgeTime::ChildNight) { @@ -87,7 +108,7 @@ static void PopulateExpressionValues(LogicTrackerCheck::Region::ExpressionRow& r } } -static std::tuple CalculateCombines(const LogicTrackerCheck::Region::ExpressionRow& row) { +static std::tuple CalculateCombines(const ExpressionTable::ExpressionRow& row) { bool combineChild = row.ChildDay == row.ChildNight; bool combineAdult = row.AdultDay == row.AdultNight; bool combineAll = combineChild && combineAdult && row.ChildDay == row.AdultDay; @@ -101,19 +122,23 @@ static std::tuple CalculateCombines(const LogicTrackerCheck::R } bool expandCheck = false; +std::unique_ptr logicTrackerCheck; void LogicTrackerWindow::ShowRandomizerCheck(RandomizerCheck randomizerCheck) { const auto& location = Rando::StaticData::GetLocation(randomizerCheck); - check = std::make_unique(); - check->CheckName = location->GetName(); + logicTrackerCheck = std::make_unique(); + logicTrackerCheck->CheckName = location->GetName(); - for (const auto& region : areaTable) { + //for (const auto& region : areaTable) { + for (int randomizerRegion = RR_NONE; randomizerRegion < RR_MAX; ++randomizerRegion) { + const auto& region = areaTable[randomizerRegion]; for (const auto& locationAccess : region.locations) { if (locationAccess.GetLocation() == randomizerCheck) { LogicTrackerCheck::Region regionAgeTime; regionAgeTime.RegionName = region.regionName; - regionAgeTime.Root = CreateExpressionRows(LogicExpression::Parse(locationAccess.GetConditionStr())); + regionAgeTime.RandomizerRegion = RandomizerRegion(randomizerRegion); + regionAgeTime.ExpressionTable.Root = CreateExpressionRows(LogicExpression::Parse(locationAccess.GetConditionStr())); regionAgeTime.ChildDayAccess = region.childDay; regionAgeTime.ChildNightAccess = region.childNight; regionAgeTime.AdultDayAccess = region.adultDay; @@ -123,8 +148,8 @@ void LogicTrackerWindow::ShowRandomizerCheck(RandomizerCheck randomizerCheck) { logic->IsChild = true; logic->AtDay = true; - const auto& eval = EvaluateExpression(regionAgeTime.Root.Expression); - PopulateExpressionValues(regionAgeTime.Root, eval, AgeTime::ChildDay); + const auto& eval = EvaluateExpression(regionAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(regionAgeTime.ExpressionTable.Root, eval, AgeTime::ChildDay); logic->IsChild = false; logic->AtDay = false; @@ -133,8 +158,8 @@ void LogicTrackerWindow::ShowRandomizerCheck(RandomizerCheck randomizerCheck) { logic->IsChild = true; logic->AtNight = true; - const auto& eval = EvaluateExpression(regionAgeTime.Root.Expression); - PopulateExpressionValues(regionAgeTime.Root, eval, AgeTime::ChildNight); + const auto& eval = EvaluateExpression(regionAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(regionAgeTime.ExpressionTable.Root, eval, AgeTime::ChildNight); logic->IsChild = false; logic->AtNight = false; @@ -143,8 +168,8 @@ void LogicTrackerWindow::ShowRandomizerCheck(RandomizerCheck randomizerCheck) { logic->IsAdult = true; logic->AtDay = true; - const auto& eval = EvaluateExpression(regionAgeTime.Root.Expression); - PopulateExpressionValues(regionAgeTime.Root, eval, AgeTime::AdultDay); + const auto& eval = EvaluateExpression(regionAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(regionAgeTime.ExpressionTable.Root, eval, AgeTime::AdultDay); logic->IsAdult = false; logic->AtDay = false; @@ -153,19 +178,19 @@ void LogicTrackerWindow::ShowRandomizerCheck(RandomizerCheck randomizerCheck) { logic->IsAdult = true; logic->AtNight = true; - const auto& eval = EvaluateExpression(regionAgeTime.Root.Expression); - PopulateExpressionValues(regionAgeTime.Root, eval, AgeTime::AdultNight); + const auto& eval = EvaluateExpression(regionAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(regionAgeTime.ExpressionTable.Root, eval, AgeTime::AdultNight); logic->IsAdult = false; logic->AtNight = false; } - auto [combineAll, combineChild, combineAdult] = CalculateCombines(regionAgeTime.Root); - regionAgeTime.CombineAll = combineAll; - regionAgeTime.CombineChild = combineChild; - regionAgeTime.CombineAdult = combineAdult; + auto [combineAll, combineChild, combineAdult] = CalculateCombines(regionAgeTime.ExpressionTable.Root); + regionAgeTime.ExpressionTable.CombineAll = combineAll; + regionAgeTime.ExpressionTable.CombineChild = combineChild; + regionAgeTime.ExpressionTable.CombineAdult = combineAdult; - check->Regions.emplace_back(std::move(regionAgeTime)); + logicTrackerCheck->Regions.emplace_back(std::move(regionAgeTime)); } } } @@ -176,6 +201,83 @@ void LogicTrackerWindow::ShowRandomizerCheck(RandomizerCheck randomizerCheck) { expandCheck = true; } +bool expandRegion = false; +std::unique_ptr logicTrackerRegion; + +void LogicTrackerWindow::ShowRandomizerRegion(RandomizerRegion randomizerRegion) { + const auto& region = RegionTable(randomizerRegion); + + logicTrackerRegion = std::make_unique(); + logicTrackerRegion->RegionName = region->regionName; + + for (const auto& entrance : region->entrances) { + const auto& parentRegion = entrance->GetParentRegion(); + + LogicTrackerRegion::Entrance entranceAgeTime; + entranceAgeTime.ParentName = parentRegion->regionName; + entranceAgeTime.ParentRandomizerRegion = entrance->GetParentRegionKey(); + entranceAgeTime.ExpressionTable.Root = + CreateExpressionRows(LogicExpression::Parse(entrance->GetConditionStr())); + entranceAgeTime.ChildDayAccess = parentRegion->childDay; + entranceAgeTime.ChildNightAccess = parentRegion->childNight; + entranceAgeTime.AdultDayAccess = parentRegion->adultDay; + entranceAgeTime.AdultNightAccess = parentRegion->adultNight; + + if (entranceAgeTime.ChildDayAccess) { + logic->IsChild = true; + logic->AtDay = true; + + const auto& eval = EvaluateExpression(entranceAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(entranceAgeTime.ExpressionTable.Root, eval, AgeTime::ChildDay); + + logic->IsChild = false; + logic->AtDay = false; + } + if (entranceAgeTime.ChildNightAccess) { + logic->IsChild = true; + logic->AtNight = true; + + const auto& eval = EvaluateExpression(entranceAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(entranceAgeTime.ExpressionTable.Root, eval, AgeTime::ChildNight); + + logic->IsChild = false; + logic->AtNight = false; + } + if (entranceAgeTime.AdultDayAccess) { + logic->IsAdult = true; + logic->AtDay = true; + + const auto& eval = EvaluateExpression(entranceAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(entranceAgeTime.ExpressionTable.Root, eval, AgeTime::AdultDay); + + logic->IsAdult = false; + logic->AtDay = false; + } + if (entranceAgeTime.AdultNightAccess) { + logic->IsAdult = true; + logic->AtNight = true; + + const auto& eval = EvaluateExpression(entranceAgeTime.ExpressionTable.Root.Expression); + PopulateExpressionValues(entranceAgeTime.ExpressionTable.Root, eval, AgeTime::AdultNight); + + logic->IsAdult = false; + logic->AtNight = false; + } + + auto [combineAll, combineChild, combineAdult] = CalculateCombines(entranceAgeTime.ExpressionTable.Root); + entranceAgeTime.ExpressionTable.CombineAll = combineAll; + entranceAgeTime.ExpressionTable.CombineChild = combineChild; + entranceAgeTime.ExpressionTable.CombineAdult = combineAdult; + + logicTrackerRegion->Entrances.emplace_back(std::move(entranceAgeTime)); + } + + auto window = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Logic Tracker"); + window->Show(); + ImGui::SetWindowFocus(window->GetName().c_str()); + expandRegion = true; +} + static std::string ToString(const std::optional& value) { if (!value.has_value()) { return ""; @@ -265,8 +367,7 @@ static void DrawCondition(const LogicExpression& expression) { } } -static void DrawExpressionRow(const LogicTrackerCheck::Region& region, LogicTrackerCheck::Region::ExpressionRow& row, - int level) { +static void DrawExpressionRow(const ExpressionTable& table, ExpressionTable::ExpressionRow& row, int level) { ImGui::TableNextRow(); ImGui::PushFont(OTRGlobals::Instance->fontMono); if (level > 0) { @@ -291,8 +392,8 @@ static void DrawExpressionRow(const LogicTrackerCheck::Region& region, LogicTrac ImGui::TableNextColumn(); ImGui::TextUnformatted(ToString(row.ChildDay).c_str()); - if (!region.CombineAll) { - if (!region.CombineChild) { + if (!table.CombineAll) { + if (!table.CombineChild) { ImGui::TableNextColumn(); ImGui::TextUnformatted(ToString(row.ChildNight).c_str()); } @@ -300,7 +401,7 @@ static void DrawExpressionRow(const LogicTrackerCheck::Region& region, LogicTrac ImGui::TableNextColumn(); ImGui::TextUnformatted(ToString(row.AdultDay).c_str()); - if (!region.CombineAdult) { + if (!table.CombineAdult) { ImGui::TableNextColumn(); ImGui::TextUnformatted(ToString(row.AdultNight).c_str()); } @@ -308,7 +409,7 @@ static void DrawExpressionRow(const LogicTrackerCheck::Region& region, LogicTrac if (row.Expanded) { for (auto& child : row.Children) { - DrawExpressionRow(region, child, level + 1); + DrawExpressionRow(table, child, level + 1); } } @@ -318,32 +419,32 @@ static void DrawExpressionRow(const LogicTrackerCheck::Region& region, LogicTrac ImGui::PopFont(); } -static void DrawCheckRegionTable(LogicTrackerCheck::Region& region) { +static void DrawExpressionTable(ExpressionTable& table) { int columnCount = 3; - if (!region.CombineAll) { - if (!region.CombineChild) { + if (!table.CombineAll) { + if (!table.CombineChild) { columnCount += 1; } columnCount += 1; - if (!region.CombineAdult) { + if (!table.CombineAdult) { columnCount += 1; } } - if (ImGui::BeginTable(region.RegionName.c_str(), columnCount, + if (ImGui::BeginTable("", columnCount, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit)) { ImGui::TableSetupColumn("Level", ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Expression", ImGuiTableColumnFlags_WidthStretch); - if (region.CombineAll) { + if (table.CombineAll) { ImGui::TableSetupColumn("All", ImGuiTableColumnFlags_WidthFixed); } else { - if (region.CombineChild) { + if (table.CombineChild) { ImGui::TableSetupColumn("Child", ImGuiTableColumnFlags_WidthFixed); } else { ImGui::TableSetupColumn("Child Day", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Child Night", ImGuiTableColumnFlags_WidthFixed); } - if (region.CombineAdult) { + if (table.CombineAdult) { ImGui::TableSetupColumn("Adult", ImGuiTableColumnFlags_WidthFixed); } else { ImGui::TableSetupColumn("Adult Day", ImGuiTableColumnFlags_WidthFixed); @@ -353,7 +454,7 @@ static void DrawCheckRegionTable(LogicTrackerCheck::Region& region) { ImGui::TableHeadersRow(); } - DrawExpressionRow(region, region.Root, 0); + DrawExpressionRow(table, table.Root, 0); ImGui::EndTable(); } @@ -392,12 +493,13 @@ static void DrawCheckRegion(LogicTrackerCheck::Region& region) { ImGui::SameLine(); if (ImGui::Button(("Show Entrance Logic##" + region.RegionName).c_str())) { + LogicTrackerWindow::ShowRandomizerRegion(region.RandomizerRegion); } ImGui::Dummy(ImVec2(0.0f, 10.0f)); ImGui::TextUnformatted("Check Access:"); - DrawCheckRegionTable(region); + DrawExpressionTable(region.ExpressionTable); } static void DrawCheck() { @@ -405,20 +507,77 @@ static void DrawCheck() { expandCheck = false; ImGui::SetNextItemOpen(true, ImGuiCond_Always); } - if (ImGui::CollapsingHeader(("Check: " + (check != nullptr ? check->CheckName : "")).c_str(), ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_SpanFullWidth)) { - if (check->Regions.empty()) { + if (ImGui::CollapsingHeader(("Check: " + (logicTrackerCheck != nullptr ? logicTrackerCheck->CheckName : "")).c_str(), ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_SpanFullWidth)) { + if (logicTrackerCheck->Regions.empty()) { ImGui::Text("No regions found for this check."); return; } - for (auto& region : check->Regions) { + for (auto& region : logicTrackerCheck->Regions) { DrawCheckRegion(region); ImGui::Dummy(ImVec2(0.0f, 20.0f)); } } } +static void DrawRegionEntrance(LogicTrackerRegion::Entrance& entrance) { + ImGui::SeparatorText(("Entrance: " + entrance.ParentName).c_str()); + ImGui::TextUnformatted("Entrance Access:"); + if (ImGui::BeginTable(("Entrance Access: " + entrance.ParentName).c_str(), 4, + ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoHostExtendX)) { + ImGui::TableSetupColumn("Child Day", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Child Night", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Adult Day", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Adult Night", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableHeadersRow(); + + ImGui::TableNextRow(); + + ImGui::PushFont(OTRGlobals::Instance->fontMono); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(entrance.ChildDayAccess ? "true" : "false"); + + ImGui::TableNextColumn(); + ImGui::TextUnformatted(entrance.ChildNightAccess ? "true" : "false"); + + ImGui::TableNextColumn(); + ImGui::TextUnformatted(entrance.AdultDayAccess ? "true" : "false"); + + ImGui::TableNextColumn(); + ImGui::TextUnformatted(entrance.AdultNightAccess ? "true" : "false"); + ImGui::PopFont(); + + ImGui::EndTable(); + } + + ImGui::SameLine(); + if (ImGui::Button(("Show Region Logic##" + entrance.ParentName).c_str())) { + LogicTrackerWindow::ShowRandomizerRegion(entrance.ParentRandomizerRegion); + } + + ImGui::Dummy(ImVec2(0.0f, 10.0f)); + DrawExpressionTable(entrance.ExpressionTable); +} + +static void DrawRegion() { + if (expandRegion) { + expandRegion = false; + ImGui::SetNextItemOpen(true, ImGuiCond_Always); + } + if (ImGui::CollapsingHeader(("Region: " + (logicTrackerRegion != nullptr ? logicTrackerRegion->RegionName : "")).c_str(), ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_SpanFullWidth)) { + if (logicTrackerRegion->Entrances.empty()) { + ImGui::Text("No entrances found for this region."); + return; + } + for (auto& entrance : logicTrackerRegion->Entrances) { + DrawRegionEntrance(entrance); + ImGui::Dummy(ImVec2(0.0f, 20.0f)); + } + } +} + void LogicTrackerWindow::DrawElement() { DrawCheck(); + DrawRegion(); } void LogicTrackerWindow::InitElement() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.h index 44b469366..466475117 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_logic_tracker.h @@ -7,7 +7,8 @@ class LogicTrackerWindow : public Ship::GuiWindow { using GuiWindow::GuiWindow; void DrawElement() override; - static void ShowRandomizerCheck(RandomizerCheck check); + static void ShowRandomizerCheck(RandomizerCheck randomizerCheck); + static void ShowRandomizerRegion(RandomizerRegion randomizerRegion); protected: void InitElement() override;