diff options
Diffstat (limited to 'mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp')
| -rw-r--r-- | mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp b/mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp new file mode 100644 index 000000000..138201f2d --- /dev/null +++ b/mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp @@ -0,0 +1,305 @@ + +#include "Timesplits.h" +#include "public/bridge/consolevariablebridge.h" +#include "Context.h" +#include "Window.h" +#include "2s2h/BenGui/UIWidgets.hpp" + +extern "C" { +#include "variables.h" +uint64_t GetUnixTimestamp(); +} + +#include "ShipUtils.h" +#include "interface/parameter_static/parameter_static.h" +#include "assets/archives/icon_item_static/icon_item_static_yar.h" +#include "GameInteractor/GameInteractor.h" + +#define BLANK_SPLIT "--:--:--.-" + +// ImVec4 Colors +#define COLOR_WHITE ImVec4(1.00f, 1.00f, 1.00f, 1.00f) +#define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f) +#define COLOR_GREEN ImVec4(0.10f, 1.00f, 0.10f, 1.00f) +#define COLOR_RED ImVec4(1.00f, 0.00f, 0.00f, 1.00f) +#define COLOR_LIGHTGREEN ImVec4(0.42f, 0.86f, 0.38f, 1.0f) +#define COLOR_LIGHTRED ImVec4(0.87f, 0.40f, 0.40f, 1.0f) + +std::vector<TimesplitObject> splitList; +std::vector<TimesplitObject> comparisonList; +ImGuiTableFlags tableColumnFlags = ImGuiTableColumnFlags_None; +ImVec4 splitOpacity = { 0, 0, 0, 0.5f }; + +uint32_t GetTotalTime() { + return ((GetUnixTimestamp() - gSaveContext.save.shipSaveInfo.fileCreatedAt) / 100); +} + +SplitTextObject GetCurrentTimeTextDisplay(TimesplitObject split) { + SplitTextObject textDisplay; + + switch (split.splitStatus) { + case SPLIT_INACTIVE: + case SPLIT_SKIPPED: + textDisplay.timeDisplay = 0; + textDisplay.colorDisplay = COLOR_GREY; + return textDisplay; + case SPLIT_ACTIVE: + textDisplay.timeDisplay = GetTotalTime(); + textDisplay.colorDisplay = COLOR_WHITE; + return textDisplay; + case SPLIT_COMPLETE: + textDisplay.timeDisplay = split.splitCurrentTime; + if (split.splitCurrentTime > split.splitPreviousBest) { + textDisplay.colorDisplay = COLOR_RED; + } else if (split.splitCurrentTime == split.splitPreviousBest) { + textDisplay.colorDisplay = COLOR_WHITE; + } else if (split.splitCurrentTime < split.splitPreviousBest) { + textDisplay.colorDisplay = COLOR_GREEN; + } + if (split.splitPreviousBest == 0) { + textDisplay.colorDisplay = COLOR_WHITE; + } + return textDisplay; + default: + break; + } +} + +SplitTextObject GetComparisonTimeTextDisplay(TimesplitObject split, TimesplitObject splitCompare) { + SplitTextObject textDisplay; + + textDisplay.timeDisplay = splitCompare.splitPreviousBest; + if (splitCompare.splitPreviousBest == 0) { + textDisplay.timeDisplay = splitCompare.splitPreviousBest; + textDisplay.colorDisplay = COLOR_GREY; + } else { + if (split.splitStatus == SPLIT_ACTIVE) { + if (GetTotalTime() <= splitCompare.splitPreviousBest) { + textDisplay.colorDisplay = COLOR_LIGHTGREEN; + } else { + textDisplay.colorDisplay = COLOR_LIGHTRED; + } + } else { + if (split.splitCurrentTime <= splitCompare.splitPreviousBest) { + textDisplay.colorDisplay = COLOR_LIGHTRED; + } else { + textDisplay.colorDisplay = COLOR_LIGHTGREEN; + } + } + } + + return textDisplay; +} + +SplitTextObject GetTimeDiffTextDisplay(TimesplitObject split) { + SplitTextObject textDisplay; + + switch (split.splitStatus) { + case SPLIT_INACTIVE: + case SPLIT_SKIPPED: + textDisplay.timeDisplay = split.splitPreviousBest; + textDisplay.colorDisplay = COLOR_GREY; + return textDisplay; + case SPLIT_ACTIVE: + if (GetTotalTime() > split.splitPreviousBest) { + textDisplay.timeDisplay = GetTotalTime() - split.splitPreviousBest; + textDisplay.colorDisplay = COLOR_RED; + } else if (GetTotalTime() == split.splitPreviousBest) { + textDisplay.timeDisplay = GetTotalTime(); + textDisplay.colorDisplay = COLOR_WHITE; + } else if (GetTotalTime() < split.splitPreviousBest) { + textDisplay.timeDisplay = split.splitPreviousBest - GetTotalTime(); + textDisplay.colorDisplay = COLOR_GREEN; + } + if (split.splitPreviousBest == 0) { + textDisplay.colorDisplay = COLOR_WHITE; + } + return textDisplay; + case SPLIT_COMPLETE: + if (split.splitCurrentTime > split.splitPreviousBest) { + textDisplay.timeDisplay = split.splitCurrentTime - split.splitPreviousBest; + textDisplay.colorDisplay = COLOR_RED; + } else if (split.splitCurrentTime == split.splitPreviousBest) { + textDisplay.timeDisplay = split.splitCurrentTime; + textDisplay.colorDisplay = COLOR_WHITE; + } else if (split.splitCurrentTime < split.splitPreviousBest) { + textDisplay.timeDisplay = split.splitPreviousBest - split.splitCurrentTime; + textDisplay.colorDisplay = COLOR_GREEN; + } + if (split.splitPreviousBest == 0) { + textDisplay.colorDisplay = COLOR_WHITE; + } + return textDisplay; + default: + break; + } +} + +void TableCellCenteredText(ImVec4 color, const char* text) { + float textHeight = ImGui::GetTextLineHeight(); + float offsetY = (32.0f - textHeight + 10.0f) * 0.5f; + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + offsetY); + ImGui::TextColored(color, text); +} + +void SplitsPushImageButtonStyle() { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.1f)); +} + +void SplitsPopImageButtonStyle() { + ImGui::PopStyleColor(3); +} + +void DrawSplitsList(bool isMain) { + float columnSizeMultiplier = isMain ? 1.0f : 1.5f; + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 7.0f); + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(10, 0)); + + if (isMain) { + ImGui::Begin("Timesplits", nullptr, + ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoDocking | + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollWithMouse | + ImGuiWindowFlags_NoScrollbar); + } + + if (ImGui::BeginChild("SplitChild", ImVec2(0, 0), true, ImGuiWindowFlags_NoScrollbar)) { + if (ImGui::BeginTable("Splits", 5, + ImGuiTableFlags_ScrollY | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable)) { + ImGui::TableSetupColumn("Item Image", + ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, + (28.0f * columnSizeMultiplier)); + ImGui::TableSetupColumn("Item Name"); + ImGui::TableSetupColumn("Current Time"); + ImGui::TableSetupColumn("+/-"); + ImGui::TableSetupColumn("Previous Best "); + if (tableColumnFlags != ImGuiTableColumnFlags_None) { + ImGui::TableSetupScrollFreeze(0, 1); + ImGui::TableHeadersRow(); + } + + for (size_t i = 0; i < splitList.size(); i++) { + ImGui::PushID(i); + + // Item Image Column + ImGui::TableNextColumn(); + + if (CVarGetInteger("gSettings.TimeSplits.Highlight", 0) && splitList[i].splitStatus == SPLIT_ACTIVE) { + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); + } + + SplitsPushImageButtonStyle(); + if (ImGui::ImageButton( + std::to_string(i).c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + splitList[i].splitType == SPLIT_TYPE_NORMAL ? GetItemImageById(splitList[i].splitId) + : gPauseUnusedCursorTex), + splitList[i].splitType == SPLIT_TYPE_NORMAL ? GetItemImageSizeById(splitList[i].splitId) + : ImVec2(32.0f, 32.0f), + ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), + splitList[i].splitType == SPLIT_TYPE_NORMAL ? Ship_GetItemColorTint(splitList[i].splitId) + : ImVec4(1, 1, 1, 1))) { + SkipSplitEntry(i); + }; + SplitsPopImageButtonStyle(); + + // Item Name Column + ImGui::TableNextColumn(); + TableCellCenteredText(COLOR_WHITE, splitList[i].splitName.c_str()); + + // Current Time Column + ImGui::TableNextColumn(); + TableCellCenteredText( + GetCurrentTimeTextDisplay(splitList[i]).colorDisplay, + !gPlayState ? BLANK_SPLIT + : Ship_FormatTimeDisplay(GetCurrentTimeTextDisplay(splitList[i]).timeDisplay).c_str()); + + // +/- Column + ImGui::TableNextColumn(); + TableCellCenteredText( + GetTimeDiffTextDisplay(splitList[i]).colorDisplay, + !gPlayState ? BLANK_SPLIT + : Ship_FormatTimeDisplay(GetTimeDiffTextDisplay(splitList[i]).timeDisplay).c_str()); + if (CVarGetInteger("gSettings.TimeSplits.Compare", 0) && comparisonList.size() != 0) { + !gPlayState ? ImGui::TextColored(COLOR_WHITE, BLANK_SPLIT) + : i < comparisonList.size() + ? ImGui::TextColored( + GetComparisonTimeTextDisplay(splitList[i], comparisonList[i]).colorDisplay, + Ship_FormatTimeDisplay( + GetComparisonTimeTextDisplay(splitList[i], comparisonList[i]).timeDisplay) + .c_str()) + : ImGui::TextColored(COLOR_GREY, "No Data"); + } + + // Previous Best Column + ImGui::TableNextColumn(); + TableCellCenteredText(COLOR_WHITE, Ship_FormatTimeDisplay(splitList[i].splitPreviousBest).c_str()); + if (CVarGetInteger("gSettings.TimeSplits.Compare", 0) && comparisonList.size() != 0) { + ImGui::TextColored(COLOR_GREY, + i < comparisonList.size() + ? Ship_FormatTimeDisplay(comparisonList[i].splitPreviousBest).c_str() + : "No Data"); + } + + ImGui::PopID(); + + if (CVarGetInteger("gSettings.TimeSplits.Follow", 0) && splitList[i].splitStatus == SPLIT_ACTIVE) { + ImGui::SetScrollHereY(); + } + } + + ImGui::EndTable(); + } + } + ImGui::EndChild(); + + if (isMain) { + ImGui::End(); + } + + ImGui::PopStyleVar(2); + ImGui::PopStyleColor(1); +} + +void UpdateSplitSettings(uint32_t settingName) { + switch (settingName) { + case SPLIT_HEADERS: + tableColumnFlags = CVarGetInteger("gSettings.TimeSplits.ShowHeaders", 0) + ? ImGuiTableColumnFlags_NoHeaderLabel + : ImGuiTableColumnFlags_None; + break; + case SPLIT_OPACITY: + splitOpacity.w = CVarGetInteger("gSettings.TimeSplits.Opacity", 0) ? 0 : 0.5f; + break; + case SPLIT_COMPARE: + if (CVarGetInteger("gSettings.TimeSplits.Compare", 0)) { + SplitSaveFileAction(SPLIT_RETRIEVE, ""); + if (savedLists.size() != 0) { + SplitLoadComparisonList(); + } + } + break; + default: + break; + } +} + +void TimesplitsWindow::Draw() { + if (!CVarGetInteger("gSettings.TimeSplits.Enable", 0)) { + return; + } + ImGui::PushStyleColor(ImGuiCol_WindowBg, splitOpacity); + DrawSplitsList(true); + ImGui::PopStyleColor(); +} + +void TimesplitsWindow::InitElement() { + UpdateSplitSettings(SPLIT_HEADERS); + UpdateSplitSettings(SPLIT_OPACITY); + UpdateSplitSettings(SPLIT_COMPARE); +} + +// void TimesplitsWindow::DrawElement() { +// } |
