diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp index 77ca5823880..6e7d133e549 100644 --- a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp @@ -15,6 +15,8 @@ extern PlayState* gPlayState; uint64_t GetUnixTimestamp(); } +static bool separateGameplay = false; +static float gameplayFontScale = 1.0f; static float fontScale = 1.0f; std::string timeDisplayTime = ""; ImTextureID textureDisplay = 0; @@ -46,6 +48,7 @@ const std::vector timeDisplayList = { }; static std::vector activeTimers; +static TimeObject gameplayTimer = timeDisplayList[DISPLAY_IN_GAME_TIMER]; std::string convertDayTime(uint32_t dayTime) { uint32_t totalSeconds = 24 * 60 * 60; @@ -89,6 +92,7 @@ static void TimeDisplayGetTimer(uint32_t timeID) { case DISPLAY_IN_GAME_TIMER: textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("GAMEPLAY_TIMER"); timeDisplayTime = formatTimeDisplay(GAMEPLAYSTAT_TOTAL_TIME).c_str(); + textColor = gSaveContext.ship.stats.gameComplete ? COLOR_LIGHT_GREEN : COLOR_WHITE; break; case DISPLAY_TIME_OF_DAY: if (gSaveContext.dayTime >= DAY_BEGINS && gSaveContext.dayTime < NIGHT_BEGINS) { @@ -140,6 +144,7 @@ static void TimeDisplayGetTimer(uint32_t timeID) { timeDisplayTime = std::to_string(FredsQuestWoodOnHand) + "/" + std::to_string(FredsQuestWoodCollected) + "/" + std::to_string(CVarGetInteger("gHoliday.Fredomato.FredsQuest.WoodNeeded", 300)); textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK"); + break; default: break; } @@ -152,19 +157,50 @@ void TimeDisplayUpdateDisplayOptions() { activeTimers.push_back(timer); } } +} - // if (pushBack) { - // activeTimers.push_back(timeDisplayList[timeID]); - // } else { - // uint32_t index = 0; - // for (auto& check : activeTimers) { - // if (check.timeID == timeID) { - // activeTimers.erase(activeTimers.begin() + index); - // return; - // } - // index++; - // } - // } +void DrawStandaloneGameplayTimer() { + ImGui::Begin("GameplayTimer", nullptr, + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar); + ImGui::SetWindowFontScale(gameplayFontScale); + ImGui::BeginTable("Gameplay Timer", 2, ImGuiTableFlags_NoClip); + ImGui::PushID(DISPLAY_IN_GAME_TIMER); + TimeDisplayGetTimer(DISPLAY_IN_GAME_TIMER); + ImGui::TableNextColumn(); + ImGui::Image(textureDisplay, ImVec2(16.0f * gameplayFontScale, 16.0f * gameplayFontScale)); + ImGui::TableNextColumn(); + if (timeDisplayTime != "-:--") { + char* textToDecode = new char[timeDisplayTime.size() + 1]; + textToDecode = std::strcpy(textToDecode, timeDisplayTime.c_str()); + size_t textLength = timeDisplayTime.length(); + uint16_t textureIndex = 0; + + for (size_t i = 0; i < textLength; i++) { + if (textToDecode[i] == ':' || textToDecode[i] == '.') { + textureIndex = 10; + } else { + textureIndex = textToDecode[i] - '0'; + } + if (textToDecode[i] == '.') { + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (8.0f * gameplayFontScale)); + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + digitList[textureIndex].first), + ImVec2(8.0f * gameplayFontScale, 8.0f * gameplayFontScale), ImVec2(0, 0.5f), ImVec2(1, 1), + textColor, ImVec4(0, 0, 0, 0)); + } else { + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + digitList[textureIndex].first), + ImVec2(8.0f * gameplayFontScale, 16.0f * gameplayFontScale), ImVec2(0, 0), ImVec2(1, 1), + textColor, ImVec4(0, 0, 0, 0)); + } + ImGui::SameLine(0, 0); + } + } + ImGui::PopID(); + ImGui::EndTable(); + ImGui::End(); } void TimeDisplayWindow::Draw() { @@ -179,6 +215,10 @@ void TimeDisplayWindow::Draw() { ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); + if (separateGameplay) { + DrawStandaloneGameplayTimer(); + } + ImGui::Begin("TimerDisplay", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | @@ -189,6 +229,10 @@ void TimeDisplayWindow::Draw() { } else { ImGui::BeginTable("Timer List", 2, ImGuiTableFlags_NoClip); for (auto& timers : activeTimers) { + if (separateGameplay && timers.timeID == DISPLAY_IN_GAME_TIMER) { + continue; + } + ImGui::PushID(timers.timeID); TimeDisplayGetTimer(timers.timeID); ImGui::TableNextColumn(); @@ -239,6 +283,8 @@ void TimeDisplayWindow::Draw() { } void TimeDisplayInitSettings() { + separateGameplay = CVarGetInteger(CVAR_TIME_DISPLAY("SeparateGameplay"), 0); + gameplayFontScale = CVarGetFloat(CVAR_TIME_DISPLAY("GameplayFontScale"), 1.0f); fontScale = CVarGetFloat(CVAR_TIME_DISPLAY("FontScale"), 1.0f); if (fontScale < 1.0f) { fontScale = 1.0f; diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index a02b539cb30..50eb41eb333 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1908,7 +1908,7 @@ void SohMenu::AddMenuEnhancements() { .RaceDisable(false) .WindowName("Additional Timers") .Options(WindowButtonOptions().Tooltip("Enables the separate Additional Timers Window.")); - AddWidget(path, "Font Scale: %.2fx", WIDGET_CVAR_SLIDER_FLOAT) + AddWidget(path, "Global Scale: %.2fx", WIDGET_CVAR_SLIDER_FLOAT) .CVar(CVAR_TIME_DISPLAY("FontScale")) .RaceDisable(false) .Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); }) @@ -1917,6 +1917,18 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_TIME_DISPLAY("ShowWindowBG")) .RaceDisable(false) .Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); }); + + AddWidget(path, "Gameplay Timer Options", WIDGET_SEPARATOR_TEXT); + AddWidget(path, "Separate Gameplay Timer", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_TIME_DISPLAY("SeparateGameplay")) + .RaceDisable(false) + .Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); }); + AddWidget(path, "Scale: %.2fx", WIDGET_CVAR_SLIDER_FLOAT) + .CVar(CVAR_TIME_DISPLAY("GameplayFontScale")) + .RaceDisable(false) + .Callback([](WidgetInfo& info) { TimeDisplayInitSettings(); }) + .Options(FloatSliderOptions().Min(1.0f).Max(5.0f).DefaultValue(1.0f).Format("%.2fx")); + AddWidget(path, "Display Options", WIDGET_SEPARATOR_TEXT); for (auto& timer : timeDisplayList) { AddWidget(path, timer.timeLabel, WIDGET_CVAR_CHECKBOX) .RaceDisable(false)