summaryrefslogtreecommitdiff
path: root/mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp')
-rw-r--r--mm/2s2h/Enhancements/Trackers/TimeSplits/Timesplits.cpp305
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() {
+// }