From 79eb74871bf4748a6c60ae08e892534ee29bd808 Mon Sep 17 00:00:00 2001 From: Caladius Date: Sun, 11 Feb 2024 16:31:11 -0500 Subject: [PATCH 01/40] Adding Splits, Collection Updates, Basic Save Feature. --- soh/soh/Enhancements/gameplaystats.cpp | 217 +++++++++++++++++++++++++ soh/soh/Enhancements/gameplaystats.h | 166 ++++++++++++++++++- 2 files changed, 382 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index efcf44efb90..2f25e4e0012 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -15,6 +15,8 @@ extern "C" { #include #include "soh/Enhancements/enhancementTypes.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" + extern "C" { #include #include "variables.h" @@ -243,6 +245,36 @@ const char* const countMappings[] = { char itemTimestampDisplayName[TIMESTAMP_MAX][21] = { "" }; ImVec4 itemTimestampDisplayColor[TIMESTAMP_MAX]; +static const char* splitEntries[156] { + "Deku Stick", "Deku Nut", "Bombs", "Fairy Bow", "Fire Arrow", "Din's Fire", + "Slingshot", "Fairy Ocarina", "Ocarina of Time", "Bombchus", "Hookshot", "Longshot", + "Ice Arrow", "Farore's Wind", "Boomerang", "Lens of Truth", "Magic Beans", "Megaton Hammer", + "Light Arrow", "Nayru's Love", "Bottle", "Red Potion", "Green Potion", "Blue Potion", + "Fairy", "Fish", "Milk (Full)", "Ruto's Letter", "Blue Fire", "Bugs", + "Big Poe", "Milk (Half)", "Poe", "Weird Egg", "Chicken", "Zelda's Letter", + "Keaton Mask", "Skull Mask", "Spooky Mask", "Bunny Hood", "Goron Mask", "Zora Mask", + "Gerudo Mask", "Mask of Truth", "Sold Out", "Pocket Egg", "Pocket Cucco", "Cojiro", + "Odd Mushroom", "Odd Potion", "Poacher's Saw", "Broken Goron Sword", "Prescription", "Eyeball Frog", + "Eye Drops", "Claim Check", "SPLIT_BOW_ARROW_FIRE", "SPLIT_BOW_ARROW_ICE", "SPLIT_BOW_ARROW_LIGHT", "Kokiri Sword", + "Master Sword", "Biggoron's Sword", "Deku Shield", "Hylian Shield", "Mirror Shield", "Kokiri Tunic", + "Goron Tunic", "Zora Tunic", "Kokiri Boots", "Iron Boots", "Hover Boots", "Bullet Bag (30)", + "Bullet Bag (40)", "Bullet Bag (50)", "Quiver (30)", "Quiver (40)", "Quiver (50)", "Bomb Bag (20)", + "Bomb Bag (30)", "Bomb Bag (40)", "Goron's Bracelet", "Silver Gauntlets", "Gold Gauntlets", "Silver Scale", + "Golden Scale", "Giant's Knife", "Adult Wallet", "Giant's Wallet", "Seeds", "Fishing Pole", + "Minuet of Forest", "Bolero of Fire", "Serenade of Water", "Requiem of Spirit", "Nocturne of Shadow", "Prelude of Light", + "Zelda's Lullaby", "Epona's Song", "Saria's Song", "Sun's Song", "Song of Time", "Song of Storms", + "Forest Medallion", "Fire Medallion", "Water Medallion", "Spirit Medallion", "Shadow Medallion", "Light Medallion", + "Kokiri's Emerald", "Goron's Ruby", "Zora's Sapphire", "Stone of Agony", "Gerudo Membership Card", "Skulltula Token", + "Heart Container", "Piece of Heart", "Boss Key", "Compass", "Map", "Small Key", + "Magic Refill (Small)", "Magic Refill (Large)", "Piece of Heart (2)", "Magic Meter (Single)", "Magic Meter (Double)", "Double Defense", + "Null 4", "Null 5", "Null 6", "Null 7", "Milk", "Recovery Heart", + "Green Rupee", "Blue Rupee", "Red Rupee", "Purple Rupee", "Gold Rupee", "Null 8", + "Deku Sticks (5)", "Deku Sticks (10)", "Deku Nuts (5)", "Deku Nuts (10)", "Bombs (5)", "Bombs (10)", + "Bombs (20)", "Bombs (30)", "Arrows (Small)", "Arrows (Medium)", "Arrows (Large)", "Seeds (30)", + "Bombchus (5)", "Bombchus (10)", "Deku Stick Upgrade (20)", "Deku Stick Upgrade (30)", + "Deku Nut Upgrade (30)","Deku Nut Upgrade (40)", +}; + typedef struct { char name[40]; u32 time; @@ -617,6 +649,181 @@ void DrawGameplayStatsOptionsTab() { UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", "gGameplayStats.ShowDebugInfo"); } +static std::string listItem; +static std::vector splitItem; +static std::vector splitTime; +static std::vector splitStatus; +static uint32_t itemReference; +std::string status = ""; +ImVec4 statusColor= COLOR_WHITE; + +void GameplayStatsSplitSave(const char* saveType, int itemSplit, std::string timeSplit, std::string statusSplit) { + if (saveType == "New Item") { + std::string splitItemSave(CVarGetString("gTimeSplitter.CurrentItems", "")); + std::string splitTimeSave(CVarGetString("gTimeSplitter.CurrentTimes", "")); + std::string splitStatusSave(CVarGetString("gTimeSplitter.CurrentStatus", "")); + if (splitItemSave == "NULL") { + splitItemSave = std::to_string(itemSplit); + } else { + splitItemSave += std::to_string(itemSplit); + } + splitItemSave += ","; + CVarSetString("gTimeSplitter.CurrentItems", splitItemSave.c_str()); + if (splitTimeSave == "NULL") { + splitTimeSave = timeSplit; + } else { + splitTimeSave += timeSplit; + } + splitTimeSave += ","; + CVarSetString("gTimeSplitter.CurrentTimes", splitTimeSave.c_str()); + if (splitStatusSave == "NULL") { + splitStatusSave = statusSplit; + } else { + splitStatusSave += statusSplit; + } + splitStatusSave += ","; + CVarSetString("gTimeSplitter.CurrentStatus", splitStatusSave.c_str()); + LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } + + if (saveType == "Collect") { + // Times + std::string inputTimes(CVarGetString("gTimeSplitter.CurrentTimes", "")); + std::stringstream timeStream(inputTimes); + std::vector timeTokens; + std::string timeToken; + + while (std::getline(timeStream, timeToken, ',')) { + timeTokens.push_back(timeToken); + } + + timeTokens[itemSplit] = timeSplit; + + inputTimes = ""; + for (size_t i = 0; i < timeTokens.size(); i++) { + if (i > 0) { + inputTimes += ","; + } + inputTimes += timeTokens[i]; + } + CVarSetString("gTimeSplitter.CurrentTimes", inputTimes.c_str()); + + // Status + std::string inputStatus(CVarGetString("gTimeSplitter.CurrentStatus", "")); + std::stringstream statusStream(inputStatus); + std::vector statusTokens; + std::string statusToken; + + while (std::getline(statusStream, statusToken, ',')) { + statusTokens.push_back(statusToken); + } + + statusTokens[itemSplit] = statusSplit; + + inputStatus = ""; + for (size_t v = 0; v < statusTokens.size(); v++) { + if (v > 0) { + inputStatus += ","; + } + inputStatus += statusTokens[v]; + } + CVarSetString("gTimeSplitter.CurrentStatus", inputStatus.c_str()); + LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } + + if (saveType == "Reset") { + CVarSetString("gTimeSplitter.CurrentItems", "NULL"); + CVarSetString("gTimeSplitter.CurrentTimes", "NULL"); + CVarSetString("gTimeSplitter.CurrentStatus", "NULL"); + LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } +} + +void GameplayStatsSplitsHandler(GetItemEntry itemEntry) { + if (itemEntry.modIndex != 0) { + return; + } + uint32_t loopCounter = 0; + for (auto &str : splitItem) { + const char* itemRef = splitEntries[itemEntry.itemId]; + if (itemRef == splitItem[loopCounter]) { + uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; + std::string temp = formatTimestampGameplayStat(num); + const char* itemTime = temp.c_str(); + splitTime[loopCounter] = itemTime; + splitStatus[loopCounter] = "1"; + GameplayStatsSplitSave("Collect", loopCounter, itemTime, "1"); + } + loopCounter++; + } +} + +void DrawGameplayStatsSplitsTab() { + uint32_t loopCounter = 0; + + ImGui::BeginTable("Splits", 2); + + for (auto &str : splitItem) { + std::string itemEntry = splitItem[loopCounter]; + uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; + std::string temp = formatTimestampGameplayStat(num); + //std::string str = std::to_string(temp); + const char* itemTime = temp.c_str(); + + ImGui::TableNextColumn(); + ImGui::TextColored(COLOR_WHITE, itemEntry.c_str()); + ImGui::TableNextColumn(); + if (splitStatus[loopCounter] == "0") { + ImGui::TextColored(COLOR_WHITE, itemTime); + } else { + ImGui::TextColored(COLOR_GREEN, splitTime[loopCounter].c_str()); + } + + loopCounter++; + } + ImGui::EndTable(); +} + +void DrawGameplayStatsSplitsOptionsTab() { + itemReference = SplitItemList(CVarGetInteger("gSelectedSplitItem", 0)); + + if (UIWidgets::EnhancementCombobox("gSelectedSplitItem", splitEntries, 0)) { + itemReference = SplitItemList(CVarGetInteger("gSelectedSplitItem", 0)); + } + + if (ImGui::Button("Add Item")) { + splitItem.push_back(splitEntries[itemReference]); + splitTime.push_back(""); + splitStatus.push_back("0"); + status = (splitEntries[itemReference]) + std::string(" Added to List"); + statusColor = COLOR_GREEN; + GameplayStatsSplitSave("New Item", itemReference, "", "0"); + } + ImGui::SameLine(0); + if (ImGui::Button("Reset List")) { + splitItem.clear(); + splitTime.clear(); + status = "List Cleared"; + statusColor = COLOR_RED; + GameplayStatsSplitSave("Reset", 0, "", ""); + } + ImGui::TextColored(statusColor, status.c_str()); +} + +void DrawGameplayStatsTimeSplitterTab() { + if (ImGui::BeginTabBar("Time Splitter")) { + if (ImGui::BeginTabItem("Splits")) { + DrawGameplayStatsSplitsTab(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Split Options")) { + DrawGameplayStatsSplitsOptionsTab(); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); +} + void GameplayStatsWindow::DrawElement() { ImGui::SetNextWindowSize(ImVec2(480, 550), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Gameplay Stats", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { @@ -643,6 +850,10 @@ void GameplayStatsWindow::DrawElement() { DrawGameplayStatsOptionsTab(); ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("Time Splitter")) { + DrawGameplayStatsTimeSplitterTab(); + ImGui::EndTabItem(); + } ImGui::EndTabBar(); } @@ -858,4 +1069,10 @@ void GameplayStatsWindow::InitElement() { SaveManager::Instance->AddSaveFunction("entrances", 1, SaveStats, false, SECTION_ID_STATS); SaveManager::Instance->AddSaveFunction("scenes", 1, SaveStats, false, SECTION_ID_STATS); SaveManager::Instance->AddInitFunction(InitStats); + + GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { + // to do: call GameplayStatsSplitsHandler() here + GameplayStatsSplitsHandler(itemEntry); + }); + } diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index 8772dd37f15..85951b2bd23 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -154,4 +154,168 @@ typedef enum { COUNT_MAX -} GameplayStatCount; \ No newline at end of file +} GameplayStatCount; + +typedef enum { + SPLIT_STICK, + SPLIT_NUT, + SPLIT_BOMB, + SPLIT_BOW, + SPLIT_ARROW_FIRE, + SPLIT_DINS_FIRE, + SPLIT_SLINGSHOT, + SPLIT_OCARINA_FAIRY, + SPLIT_OCARINA_TIME, + SPLIT_BOMBCHU, + SPLIT_HOOKSHOT, + SPLIT_LONGSHOT, + SPLIT_ARROW_ICE, + SPLIT_FARORES_WIND, + SPLIT_BOOMERANG, + SPLIT_LENS, + SPLIT_BEAN, + SPLIT_HAMMER, + SPLIT_ARROW_LIGHT, + SPLIT_NAYRUS_LOVE, + SPLIT_BOTTLE, + SPLIT_POTION_RED, + SPLIT_POTION_GREEN, + SPLIT_POTION_BLUE, + SPLIT_FAIRY, + SPLIT_FISH, + SPLIT_MILK_BOTTLE, + SPLIT_LETTER_RUTO, + SPLIT_BLUE_FIRE, + SPLIT_BUG, + SPLIT_BIG_POE, + SPLIT_MILK_HALF, + SPLIT_POE, + SPLIT_WEIRD_EGG, + SPLIT_CHICKEN, + SPLIT_LETTER_ZELDA, + SPLIT_MASK_KEATON, + SPLIT_MASK_SKULL, + SPLIT_MASK_SPOOKY, + SPLIT_MASK_BUNNY, + SPLIT_MASK_GORON, + SPLIT_MASK_ZORA, + SPLIT_MASK_GERUDO, + SPLIT_MASK_TRUTH, + SPLIT_SOLD_OUT, + SPLIT_POCKET_EGG, + SPLIT_POCKET_CUCCO, + SPLIT_COJIRO, + SPLIT_ODD_MUSHROOM, + SPLIT_ODD_POTION, + SPLIT_SAW, + SPLIT_SWORD_BROKEN, + SPLIT_PRESCRIPTION, + SPLIT_FROG, + SPLIT_EYEDROPS, + SPLIT_CLAIM_CHECK, + SPLIT_BOW_ARROW_FIRE, + SPLIT_BOW_ARROW_ICE, + SPLIT_BOW_ARROW_LIGHT, + SPLIT_SWORD_KOKIRI, + SPLIT_SWORD_MASTER, + SPLIT_SWORD_BGS, + SPLIT_SHIELD_DEKU, + SPLIT_SHIELD_HYLIAN, + SPLIT_SHIELD_MIRROR, + SPLIT_TUNIC_KOKIRI, + SPLIT_TUNIC_GORON, + SPLIT_TUNIC_ZORA, + SPLIT_BOOTS_KOKIRI, + SPLIT_BOOTS_IRON, + SPLIT_BOOTS_HOVER, + SPLIT_BULLET_BAG_30, + SPLIT_BULLET_BAG_40, + SPLIT_BULLET_BAG_50, + SPLIT_QUIVER_30, + SPLIT_QUIVER_40, + SPLIT_QUIVER_50, + SPLIT_BOMB_BAG_20, + SPLIT_BOMB_BAG_30, + SPLIT_BOMB_BAG_40, + SPLIT_BRACELET, + SPLIT_GAUNTLETS_SILVER, + SPLIT_GAUNTLETS_GOLD, + SPLIT_SCALE_SILVER, + SPLIT_SCALE_GOLDEN, + SPLIT_SWORD_KNIFE, + SPLIT_WALLET_ADULT, + SPLIT_WALLET_GIANT, + SPLIT_SEEDS, + SPLIT_FISHING_POLE, + SPLIT_SONG_MINUET, + SPLIT_SONG_BOLERO, + SPLIT_SONG_SERENADE, + SPLIT_SONG_REQUIEM, + SPLIT_SONG_NOCTURNE, + SPLIT_SONG_PRELUDE, + SPLIT_SONG_LULLABY, + SPLIT_SONG_EPONA, + SPLIT_SONG_SARIA, + SPLIT_SONG_SUN, + SPLIT_SONG_TIME, + SPLIT_SONG_STORMS, + SPLIT_MEDALLION_FOREST, + SPLIT_MEDALLION_FIRE, + SPLIT_MEDALLION_WATER, + SPLIT_MEDALLION_SPIRIT, + SPLIT_MEDALLION_SHADOW, + SPLIT_MEDALLION_LIGHT, + SPLIT_KOKIRI_EMERALD, + SPLIT_GORON_RUBY, + SPLIT_ZORA_SAPPHIRE, + SPLIT_STONE_OF_AGONY, + SPLIT_GERUDO_CARD, + SPLIT_SKULL_TOKEN, + SPLIT_HEART_CONTAINER, + SPLIT_HEART_PIECE, + SPLIT_KEY_BOSS, + SPLIT_COMPASS, + SPLIT_DUNGEON_MAP, + SPLIT_KEY_SMALL, + SPLIT_MAGIC_SMALL, + SPLIT_MAGIC_LARGE, + SPLIT_HEART_PIECE_2, + SPLIT_SINGLE_MAGIC, + SPLIT_DOUBLE_MAGIC, + SPLIT_DOUBLE_DEFENSE, + SPLIT_INVALID_4, + SPLIT_INVALID_5, + SPLIT_INVALID_6, + SPLIT_INVALID_7, + SPLIT_MILK, + SPLIT_HEART, + SPLIT_RUPEE_GREEN, + SPLIT_RUPEE_BLUE, + SPLIT_RUPEE_RED, + SPLIT_RUPEE_PURPLE, + SPLIT_RUPEE_GOLD, + SPLIT_INVALID_8, + SPLIT_STICKS_5, + SPLIT_STICKS_10, + SPLIT_NUTS_5, + SPLIT_NUTS_10, + SPLIT_BOMBS_5, + SPLIT_BOMBS_10, + SPLIT_BOMBS_20, + SPLIT_BOMBS_30, + SPLIT_ARROWS_SMALL, + SPLIT_ARROWS_MEDIUM, + SPLIT_ARROWS_LARGE, + SPLIT_SEEDS_30, + SPLIT_BOMBCHUS_5, + SPLIT_BOMBCHUS_20, + SPLIT_STICK_UPGRADE_20, + SPLIT_STICK_UPGRADE_30, + SPLIT_NUT_UPGRADE_30, + SPLIT_NUT_UPGRADE_40, +} SplitItemList; + +typedef enum { + COLLECTED, + SKIPPED, +} SplitEvent; \ No newline at end of file From 4db8de6ef58492e2395f15149de61874e12f40cc Mon Sep 17 00:00:00 2001 From: Caladius Date: Tue, 13 Feb 2024 19:09:18 -0500 Subject: [PATCH 02/40] New Time Splitter file/window, reverting GameplayStats back to unaltered. --- soh/soh/Enhancements/gameplaystats.cpp | 185 ------------------ soh/soh/Enhancements/gameplaystats.h | 166 +--------------- .../Enhancements/timesplits/TimeSplits.cpp | 161 +++++++++++++++ soh/soh/Enhancements/timesplits/TimeSplits.h | 15 ++ soh/soh/SohGui.cpp | 8 +- soh/soh/SohGui.hpp | 1 + soh/soh/SohMenuBar.cpp | 9 + soh/soh/util.cpp | 2 +- soh/soh/util.h | 3 + 9 files changed, 198 insertions(+), 352 deletions(-) create mode 100644 soh/soh/Enhancements/timesplits/TimeSplits.cpp create mode 100644 soh/soh/Enhancements/timesplits/TimeSplits.h diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 2f25e4e0012..e895ad0163d 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -649,181 +649,6 @@ void DrawGameplayStatsOptionsTab() { UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", "gGameplayStats.ShowDebugInfo"); } -static std::string listItem; -static std::vector splitItem; -static std::vector splitTime; -static std::vector splitStatus; -static uint32_t itemReference; -std::string status = ""; -ImVec4 statusColor= COLOR_WHITE; - -void GameplayStatsSplitSave(const char* saveType, int itemSplit, std::string timeSplit, std::string statusSplit) { - if (saveType == "New Item") { - std::string splitItemSave(CVarGetString("gTimeSplitter.CurrentItems", "")); - std::string splitTimeSave(CVarGetString("gTimeSplitter.CurrentTimes", "")); - std::string splitStatusSave(CVarGetString("gTimeSplitter.CurrentStatus", "")); - if (splitItemSave == "NULL") { - splitItemSave = std::to_string(itemSplit); - } else { - splitItemSave += std::to_string(itemSplit); - } - splitItemSave += ","; - CVarSetString("gTimeSplitter.CurrentItems", splitItemSave.c_str()); - if (splitTimeSave == "NULL") { - splitTimeSave = timeSplit; - } else { - splitTimeSave += timeSplit; - } - splitTimeSave += ","; - CVarSetString("gTimeSplitter.CurrentTimes", splitTimeSave.c_str()); - if (splitStatusSave == "NULL") { - splitStatusSave = statusSplit; - } else { - splitStatusSave += statusSplit; - } - splitStatusSave += ","; - CVarSetString("gTimeSplitter.CurrentStatus", splitStatusSave.c_str()); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - - if (saveType == "Collect") { - // Times - std::string inputTimes(CVarGetString("gTimeSplitter.CurrentTimes", "")); - std::stringstream timeStream(inputTimes); - std::vector timeTokens; - std::string timeToken; - - while (std::getline(timeStream, timeToken, ',')) { - timeTokens.push_back(timeToken); - } - - timeTokens[itemSplit] = timeSplit; - - inputTimes = ""; - for (size_t i = 0; i < timeTokens.size(); i++) { - if (i > 0) { - inputTimes += ","; - } - inputTimes += timeTokens[i]; - } - CVarSetString("gTimeSplitter.CurrentTimes", inputTimes.c_str()); - - // Status - std::string inputStatus(CVarGetString("gTimeSplitter.CurrentStatus", "")); - std::stringstream statusStream(inputStatus); - std::vector statusTokens; - std::string statusToken; - - while (std::getline(statusStream, statusToken, ',')) { - statusTokens.push_back(statusToken); - } - - statusTokens[itemSplit] = statusSplit; - - inputStatus = ""; - for (size_t v = 0; v < statusTokens.size(); v++) { - if (v > 0) { - inputStatus += ","; - } - inputStatus += statusTokens[v]; - } - CVarSetString("gTimeSplitter.CurrentStatus", inputStatus.c_str()); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } - - if (saveType == "Reset") { - CVarSetString("gTimeSplitter.CurrentItems", "NULL"); - CVarSetString("gTimeSplitter.CurrentTimes", "NULL"); - CVarSetString("gTimeSplitter.CurrentStatus", "NULL"); - LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } -} - -void GameplayStatsSplitsHandler(GetItemEntry itemEntry) { - if (itemEntry.modIndex != 0) { - return; - } - uint32_t loopCounter = 0; - for (auto &str : splitItem) { - const char* itemRef = splitEntries[itemEntry.itemId]; - if (itemRef == splitItem[loopCounter]) { - uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; - std::string temp = formatTimestampGameplayStat(num); - const char* itemTime = temp.c_str(); - splitTime[loopCounter] = itemTime; - splitStatus[loopCounter] = "1"; - GameplayStatsSplitSave("Collect", loopCounter, itemTime, "1"); - } - loopCounter++; - } -} - -void DrawGameplayStatsSplitsTab() { - uint32_t loopCounter = 0; - - ImGui::BeginTable("Splits", 2); - - for (auto &str : splitItem) { - std::string itemEntry = splitItem[loopCounter]; - uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; - std::string temp = formatTimestampGameplayStat(num); - //std::string str = std::to_string(temp); - const char* itemTime = temp.c_str(); - - ImGui::TableNextColumn(); - ImGui::TextColored(COLOR_WHITE, itemEntry.c_str()); - ImGui::TableNextColumn(); - if (splitStatus[loopCounter] == "0") { - ImGui::TextColored(COLOR_WHITE, itemTime); - } else { - ImGui::TextColored(COLOR_GREEN, splitTime[loopCounter].c_str()); - } - - loopCounter++; - } - ImGui::EndTable(); -} - -void DrawGameplayStatsSplitsOptionsTab() { - itemReference = SplitItemList(CVarGetInteger("gSelectedSplitItem", 0)); - - if (UIWidgets::EnhancementCombobox("gSelectedSplitItem", splitEntries, 0)) { - itemReference = SplitItemList(CVarGetInteger("gSelectedSplitItem", 0)); - } - - if (ImGui::Button("Add Item")) { - splitItem.push_back(splitEntries[itemReference]); - splitTime.push_back(""); - splitStatus.push_back("0"); - status = (splitEntries[itemReference]) + std::string(" Added to List"); - statusColor = COLOR_GREEN; - GameplayStatsSplitSave("New Item", itemReference, "", "0"); - } - ImGui::SameLine(0); - if (ImGui::Button("Reset List")) { - splitItem.clear(); - splitTime.clear(); - status = "List Cleared"; - statusColor = COLOR_RED; - GameplayStatsSplitSave("Reset", 0, "", ""); - } - ImGui::TextColored(statusColor, status.c_str()); -} - -void DrawGameplayStatsTimeSplitterTab() { - if (ImGui::BeginTabBar("Time Splitter")) { - if (ImGui::BeginTabItem("Splits")) { - DrawGameplayStatsSplitsTab(); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Split Options")) { - DrawGameplayStatsSplitsOptionsTab(); - ImGui::EndTabItem(); - } - } - ImGui::EndTabBar(); -} - void GameplayStatsWindow::DrawElement() { ImGui::SetNextWindowSize(ImVec2(480, 550), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Gameplay Stats", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { @@ -850,10 +675,6 @@ void GameplayStatsWindow::DrawElement() { DrawGameplayStatsOptionsTab(); ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("Time Splitter")) { - DrawGameplayStatsTimeSplitterTab(); - ImGui::EndTabItem(); - } ImGui::EndTabBar(); } @@ -1069,10 +890,4 @@ void GameplayStatsWindow::InitElement() { SaveManager::Instance->AddSaveFunction("entrances", 1, SaveStats, false, SECTION_ID_STATS); SaveManager::Instance->AddSaveFunction("scenes", 1, SaveStats, false, SECTION_ID_STATS); SaveManager::Instance->AddInitFunction(InitStats); - - GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { - // to do: call GameplayStatsSplitsHandler() here - GameplayStatsSplitsHandler(itemEntry); - }); - } diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index 85951b2bd23..8772dd37f15 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -154,168 +154,4 @@ typedef enum { COUNT_MAX -} GameplayStatCount; - -typedef enum { - SPLIT_STICK, - SPLIT_NUT, - SPLIT_BOMB, - SPLIT_BOW, - SPLIT_ARROW_FIRE, - SPLIT_DINS_FIRE, - SPLIT_SLINGSHOT, - SPLIT_OCARINA_FAIRY, - SPLIT_OCARINA_TIME, - SPLIT_BOMBCHU, - SPLIT_HOOKSHOT, - SPLIT_LONGSHOT, - SPLIT_ARROW_ICE, - SPLIT_FARORES_WIND, - SPLIT_BOOMERANG, - SPLIT_LENS, - SPLIT_BEAN, - SPLIT_HAMMER, - SPLIT_ARROW_LIGHT, - SPLIT_NAYRUS_LOVE, - SPLIT_BOTTLE, - SPLIT_POTION_RED, - SPLIT_POTION_GREEN, - SPLIT_POTION_BLUE, - SPLIT_FAIRY, - SPLIT_FISH, - SPLIT_MILK_BOTTLE, - SPLIT_LETTER_RUTO, - SPLIT_BLUE_FIRE, - SPLIT_BUG, - SPLIT_BIG_POE, - SPLIT_MILK_HALF, - SPLIT_POE, - SPLIT_WEIRD_EGG, - SPLIT_CHICKEN, - SPLIT_LETTER_ZELDA, - SPLIT_MASK_KEATON, - SPLIT_MASK_SKULL, - SPLIT_MASK_SPOOKY, - SPLIT_MASK_BUNNY, - SPLIT_MASK_GORON, - SPLIT_MASK_ZORA, - SPLIT_MASK_GERUDO, - SPLIT_MASK_TRUTH, - SPLIT_SOLD_OUT, - SPLIT_POCKET_EGG, - SPLIT_POCKET_CUCCO, - SPLIT_COJIRO, - SPLIT_ODD_MUSHROOM, - SPLIT_ODD_POTION, - SPLIT_SAW, - SPLIT_SWORD_BROKEN, - SPLIT_PRESCRIPTION, - SPLIT_FROG, - SPLIT_EYEDROPS, - SPLIT_CLAIM_CHECK, - SPLIT_BOW_ARROW_FIRE, - SPLIT_BOW_ARROW_ICE, - SPLIT_BOW_ARROW_LIGHT, - SPLIT_SWORD_KOKIRI, - SPLIT_SWORD_MASTER, - SPLIT_SWORD_BGS, - SPLIT_SHIELD_DEKU, - SPLIT_SHIELD_HYLIAN, - SPLIT_SHIELD_MIRROR, - SPLIT_TUNIC_KOKIRI, - SPLIT_TUNIC_GORON, - SPLIT_TUNIC_ZORA, - SPLIT_BOOTS_KOKIRI, - SPLIT_BOOTS_IRON, - SPLIT_BOOTS_HOVER, - SPLIT_BULLET_BAG_30, - SPLIT_BULLET_BAG_40, - SPLIT_BULLET_BAG_50, - SPLIT_QUIVER_30, - SPLIT_QUIVER_40, - SPLIT_QUIVER_50, - SPLIT_BOMB_BAG_20, - SPLIT_BOMB_BAG_30, - SPLIT_BOMB_BAG_40, - SPLIT_BRACELET, - SPLIT_GAUNTLETS_SILVER, - SPLIT_GAUNTLETS_GOLD, - SPLIT_SCALE_SILVER, - SPLIT_SCALE_GOLDEN, - SPLIT_SWORD_KNIFE, - SPLIT_WALLET_ADULT, - SPLIT_WALLET_GIANT, - SPLIT_SEEDS, - SPLIT_FISHING_POLE, - SPLIT_SONG_MINUET, - SPLIT_SONG_BOLERO, - SPLIT_SONG_SERENADE, - SPLIT_SONG_REQUIEM, - SPLIT_SONG_NOCTURNE, - SPLIT_SONG_PRELUDE, - SPLIT_SONG_LULLABY, - SPLIT_SONG_EPONA, - SPLIT_SONG_SARIA, - SPLIT_SONG_SUN, - SPLIT_SONG_TIME, - SPLIT_SONG_STORMS, - SPLIT_MEDALLION_FOREST, - SPLIT_MEDALLION_FIRE, - SPLIT_MEDALLION_WATER, - SPLIT_MEDALLION_SPIRIT, - SPLIT_MEDALLION_SHADOW, - SPLIT_MEDALLION_LIGHT, - SPLIT_KOKIRI_EMERALD, - SPLIT_GORON_RUBY, - SPLIT_ZORA_SAPPHIRE, - SPLIT_STONE_OF_AGONY, - SPLIT_GERUDO_CARD, - SPLIT_SKULL_TOKEN, - SPLIT_HEART_CONTAINER, - SPLIT_HEART_PIECE, - SPLIT_KEY_BOSS, - SPLIT_COMPASS, - SPLIT_DUNGEON_MAP, - SPLIT_KEY_SMALL, - SPLIT_MAGIC_SMALL, - SPLIT_MAGIC_LARGE, - SPLIT_HEART_PIECE_2, - SPLIT_SINGLE_MAGIC, - SPLIT_DOUBLE_MAGIC, - SPLIT_DOUBLE_DEFENSE, - SPLIT_INVALID_4, - SPLIT_INVALID_5, - SPLIT_INVALID_6, - SPLIT_INVALID_7, - SPLIT_MILK, - SPLIT_HEART, - SPLIT_RUPEE_GREEN, - SPLIT_RUPEE_BLUE, - SPLIT_RUPEE_RED, - SPLIT_RUPEE_PURPLE, - SPLIT_RUPEE_GOLD, - SPLIT_INVALID_8, - SPLIT_STICKS_5, - SPLIT_STICKS_10, - SPLIT_NUTS_5, - SPLIT_NUTS_10, - SPLIT_BOMBS_5, - SPLIT_BOMBS_10, - SPLIT_BOMBS_20, - SPLIT_BOMBS_30, - SPLIT_ARROWS_SMALL, - SPLIT_ARROWS_MEDIUM, - SPLIT_ARROWS_LARGE, - SPLIT_SEEDS_30, - SPLIT_BOMBCHUS_5, - SPLIT_BOMBCHUS_20, - SPLIT_STICK_UPGRADE_20, - SPLIT_STICK_UPGRADE_30, - SPLIT_NUT_UPGRADE_30, - SPLIT_NUT_UPGRADE_40, -} SplitItemList; - -typedef enum { - COLLECTED, - SKIPPED, -} SplitEvent; \ No newline at end of file +} GameplayStatCount; \ No newline at end of file diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp new file mode 100644 index 00000000000..acf940dc49e --- /dev/null +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -0,0 +1,161 @@ +#include "TimeSplits.h" +#include "soh/UIWidgets.hpp" +#include "soh/Enhancements/randomizer/3drando/item_list.hpp" +#include "soh/Enhancements/gameplaystats.h" +#include "soh/SaveManager.h" +#include "soh/util.h" +#include + +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" + +extern "C" { + extern SaveContext gSaveContext; +} + + +// ImVec4 Colors +#define COLOR_WHITE ImVec4(1.00f, 1.00f, 1.00f, 1.00f) +#define COLOR_RED ImVec4(1.00f, 0.00f, 0.00f, 1.00f) +#define COLOR_GREEN ImVec4(0.10f, 1.00f, 0.10f, 1.00f) +#define COLOR_BLUE ImVec4(0.00f, 0.33f, 1.00f, 1.00f) +#define COLOR_PURPLE ImVec4(0.54f, 0.19f, 0.89f, 1.00f) +#define COLOR_YELLOW ImVec4(1.00f, 1.00f, 0.00f, 1.00f) +#define COLOR_ORANGE ImVec4(1.00f, 0.67f, 0.11f, 1.00f) +#define COLOR_LIGHT_BLUE ImVec4(0.00f, 0.88f, 1.00f, 1.00f) +#define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f) + +static std::vector splitItem; +static std::vector splitTime; +static std::vector splitStatus; +static uint32_t itemReference = ITEM_STICK; +static std::string status = ""; +static ImVec4 statusColor = COLOR_WHITE; +std::time_t convertedTime; +const char* itemTime; + +std::string formatTimestampTimeSplit(uint32_t value) { + uint32_t sec = value / 10; + uint32_t hh = sec / 3600; + uint32_t mm = (sec - hh * 3600) / 60; + uint32_t ss = sec - hh * 3600 - mm * 60; + uint32_t ds = value % 10; + return fmt::format("{}:{:0>2}:{:0>2}.{}", hh, mm, ss, ds); +} + +void TimeSplitTimeHandler() { + uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; + std::string temp = formatTimestampTimeSplit(num); + itemTime = temp.c_str(); +} + +void TimeSplitSplitsHandler(GetItemEntry itemEntry) { + if (itemEntry.modIndex != 0) { + return; + } + uint32_t loopCounter = 0; + for (auto& str : splitItem) { + uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; + std::string temp = formatTimestampTimeSplit(num); + const char* timeValue = temp.c_str(); + + if (itemEntry.itemId == splitItem[loopCounter]) { + splitTime[loopCounter] = timeValue; + splitStatus[loopCounter] = 1; + } + loopCounter++; + } +} + +void DrawTimeSplitSplits(){ + uint32_t loopCounter = 0; + + ImGui::BeginTable("Splits", 4); + ImGui::TableNextColumn(); + ImGui::TextColored(COLOR_LIGHT_BLUE, "Items"); + ImGui::TableNextColumn(); + ImGui::TextColored(COLOR_LIGHT_BLUE, "Current Times"); + ImGui::TableNextColumn(); + ImGui::TextColored(COLOR_LIGHT_BLUE, "+/-"); + ImGui::TableNextColumn(); + ImGui::TextColored(COLOR_LIGHT_BLUE, "Previous Best"); + + for (auto& str : splitItem) { + ImGui::TableNextColumn(); + ImGui::TextColored(COLOR_WHITE, SohUtils::itemNames[splitItem[loopCounter]].c_str()); + ImGui::TableNextColumn(); + + if (splitStatus[loopCounter] == 0) { + uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; + std::string temp = formatTimestampTimeSplit(num); + itemTime = temp.c_str(); + //TimeSplitTimeHandler(); + ImGui::TextColored(COLOR_WHITE, itemTime); + } else { + ImGui::TextColored(COLOR_GREEN, splitTime[loopCounter].c_str()); + } + ImGui::TableNextColumn(); + // to-do: split difference +/- with colored indicators + + ImGui::TextColored(COLOR_WHITE, "Not Supported"); + ImGui::TableNextColumn(); + ImGui::Text("0:00:00.0"); + + loopCounter++; + } + ImGui::EndTable(); +} + +void DrawTimeSplitOptions() { + if (ImGui::BeginCombo("Item List", SohUtils::itemNames[itemReference].c_str())) { + for (int i = 0; i < SohUtils::itemNames.size(); i++) { + if (ImGui::Selectable(SohUtils::itemNames[i].c_str())) { + itemReference = i; + } + } + ImGui::EndCombo(); + } + + if (ImGui::Button("Add Item")) { + + splitItem.push_back(itemReference); + splitTime.push_back(""); + splitStatus.push_back(0); + std::string itemEntry = SohUtils::itemNames[itemReference]; + status = itemEntry + std::string(" Added to List"); + statusColor = COLOR_GREEN; + } + ImGui::SameLine(0); + if (ImGui::Button("Reset List")) { + splitItem.clear(); + splitTime.clear(); + splitStatus.clear(); + status = "List has been reset"; + statusColor = COLOR_RED; + } + ImGui::SameLine(0); + if (ImGui::Button("Load List")) { + + } + ImGui::TextColored(statusColor, status.c_str()); + UIWidgets::PaddedSeparator(); +} + +void TimeSplitWindow::DrawElement() { + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Time Splitter Window", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { + ImGui::End(); + return; + } + if (ImGui::CollapsingHeader("Time Splitter")) { + DrawTimeSplitOptions(); + } + DrawTimeSplitSplits(); + ImGui::End(); +} + +void TimeSplitWindow::InitElement() { + GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { + TimeSplitSplitsHandler(itemEntry); + }); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h new file mode 100644 index 00000000000..938f812e61d --- /dev/null +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +class TimeSplitWindow : public LUS::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override; + void DrawElement() override; + void UpdateElement() override{}; +}; + +#endif \ No newline at end of file diff --git a/soh/soh/SohGui.cpp b/soh/soh/SohGui.cpp index 49f84068a30..5282869ef2e 100644 --- a/soh/soh/SohGui.cpp +++ b/soh/soh/SohGui.cpp @@ -108,7 +108,7 @@ namespace SohGui { // MARK: - Delegates - + std::shared_ptr mSohMenuBar; std::shared_ptr mConsoleWindow; @@ -130,6 +130,8 @@ namespace SohGui { std::shared_ptr mItemTrackerWindow; std::shared_ptr mRandomizerSettingsWindow; + std::shared_ptr mTimeSplitWindow; + std::shared_ptr mAdvancedResolutionSettingsWindow; void SetupGuiElements() { @@ -191,6 +193,9 @@ namespace SohGui { gui->AddGuiWindow(mRandomizerSettingsWindow); mAdvancedResolutionSettingsWindow = std::make_shared("gAdvancedResolutionEditorEnabled", "Advanced Resolution Settings"); gui->AddGuiWindow(mAdvancedResolutionSettingsWindow); + + mTimeSplitWindow = std::make_shared("gTimeSplitEnabled", "Time Splits"); + gui->AddGuiWindow(mTimeSplitWindow); } void Destroy() { @@ -213,5 +218,6 @@ namespace SohGui { mStatsWindow = nullptr; mConsoleWindow = nullptr; mSohMenuBar = nullptr; + mTimeSplitWindow = nullptr; } } diff --git a/soh/soh/SohGui.hpp b/soh/soh/SohGui.hpp index 73a3addd43f..39a672cc1a4 100644 --- a/soh/soh/SohGui.hpp +++ b/soh/soh/SohGui.hpp @@ -22,6 +22,7 @@ #include "Enhancements/randomizer/randomizer_entrance_tracker.h" #include "Enhancements/randomizer/randomizer_item_tracker.h" #include "Enhancements/randomizer/randomizer_settings_window.h" +#include "Enhancements/timesplits/TimeSplits.h" #ifdef __cplusplus extern "C" { diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index f59e3a343c1..766d257a19d 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -34,6 +34,8 @@ #include "Enhancements/randomizer/randomizer_settings_window.h" #include "Enhancements/resolution-editor/ResolutionEditor.h" +#include "Enhancements/timesplits/TimeSplits.h" + extern bool ToggleAltAssetsAtEndOfFrame; extern bool isBetaQuestEnabled; @@ -533,6 +535,7 @@ void DrawSettingsMenu() { extern std::shared_ptr mAudioEditorWindow; extern std::shared_ptr mCosmeticsEditorWindow; extern std::shared_ptr mGameplayStatsWindow; +extern std::shared_ptr mTimeSplitWindow; void DrawEnhancementsMenu() { if (ImGui::BeginMenu("Enhancements")) @@ -1371,6 +1374,12 @@ void DrawEnhancementsMenu() { mGameplayStatsWindow->ToggleVisibility(); } } + + if (mTimeSplitWindow) { + if (ImGui::Button(GetWindowButtonText("Time Splits", CVarGetInteger("gTimeSplitEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { + mTimeSplitWindow->ToggleVisibility(); + } + } ImGui::PopStyleVar(3); ImGui::PopStyleColor(1); diff --git a/soh/soh/util.cpp b/soh/soh/util.cpp index 856432cbbd2..95af1f99f59 100644 --- a/soh/soh/util.cpp +++ b/soh/soh/util.cpp @@ -117,7 +117,7 @@ std::vector sceneNames = { "Treasure Chest Room", }; -std::vector itemNames = { +std::vector SohUtils::itemNames = { "Deku Stick", "Deku Nut", "Bomb", diff --git a/soh/soh/util.h b/soh/soh/util.h index db5af8636a3..4850a150116 100644 --- a/soh/soh/util.h +++ b/soh/soh/util.h @@ -1,8 +1,11 @@ #pragma once #include #include +#include namespace SohUtils { + extern std::vector itemNames; + const std::string& GetSceneName(int32_t scene); const std::string& GetItemName(int32_t item); From 413cb1ce024b573e9a5bd6e2f9ae1e9de82ef3fc Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 19 Feb 2024 17:17:36 -0500 Subject: [PATCH 03/40] PRing for review --- soh/soh/Enhancements/gameplaystats.cpp | 30 --- .../Enhancements/timesplits/TimeSplits.cpp | 226 ++++++++++++++---- soh/soh/Enhancements/timesplits/TimeSplits.h | 32 ++- 3 files changed, 214 insertions(+), 74 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index e895ad0163d..9a6a63c0f6f 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -245,36 +245,6 @@ const char* const countMappings[] = { char itemTimestampDisplayName[TIMESTAMP_MAX][21] = { "" }; ImVec4 itemTimestampDisplayColor[TIMESTAMP_MAX]; -static const char* splitEntries[156] { - "Deku Stick", "Deku Nut", "Bombs", "Fairy Bow", "Fire Arrow", "Din's Fire", - "Slingshot", "Fairy Ocarina", "Ocarina of Time", "Bombchus", "Hookshot", "Longshot", - "Ice Arrow", "Farore's Wind", "Boomerang", "Lens of Truth", "Magic Beans", "Megaton Hammer", - "Light Arrow", "Nayru's Love", "Bottle", "Red Potion", "Green Potion", "Blue Potion", - "Fairy", "Fish", "Milk (Full)", "Ruto's Letter", "Blue Fire", "Bugs", - "Big Poe", "Milk (Half)", "Poe", "Weird Egg", "Chicken", "Zelda's Letter", - "Keaton Mask", "Skull Mask", "Spooky Mask", "Bunny Hood", "Goron Mask", "Zora Mask", - "Gerudo Mask", "Mask of Truth", "Sold Out", "Pocket Egg", "Pocket Cucco", "Cojiro", - "Odd Mushroom", "Odd Potion", "Poacher's Saw", "Broken Goron Sword", "Prescription", "Eyeball Frog", - "Eye Drops", "Claim Check", "SPLIT_BOW_ARROW_FIRE", "SPLIT_BOW_ARROW_ICE", "SPLIT_BOW_ARROW_LIGHT", "Kokiri Sword", - "Master Sword", "Biggoron's Sword", "Deku Shield", "Hylian Shield", "Mirror Shield", "Kokiri Tunic", - "Goron Tunic", "Zora Tunic", "Kokiri Boots", "Iron Boots", "Hover Boots", "Bullet Bag (30)", - "Bullet Bag (40)", "Bullet Bag (50)", "Quiver (30)", "Quiver (40)", "Quiver (50)", "Bomb Bag (20)", - "Bomb Bag (30)", "Bomb Bag (40)", "Goron's Bracelet", "Silver Gauntlets", "Gold Gauntlets", "Silver Scale", - "Golden Scale", "Giant's Knife", "Adult Wallet", "Giant's Wallet", "Seeds", "Fishing Pole", - "Minuet of Forest", "Bolero of Fire", "Serenade of Water", "Requiem of Spirit", "Nocturne of Shadow", "Prelude of Light", - "Zelda's Lullaby", "Epona's Song", "Saria's Song", "Sun's Song", "Song of Time", "Song of Storms", - "Forest Medallion", "Fire Medallion", "Water Medallion", "Spirit Medallion", "Shadow Medallion", "Light Medallion", - "Kokiri's Emerald", "Goron's Ruby", "Zora's Sapphire", "Stone of Agony", "Gerudo Membership Card", "Skulltula Token", - "Heart Container", "Piece of Heart", "Boss Key", "Compass", "Map", "Small Key", - "Magic Refill (Small)", "Magic Refill (Large)", "Piece of Heart (2)", "Magic Meter (Single)", "Magic Meter (Double)", "Double Defense", - "Null 4", "Null 5", "Null 6", "Null 7", "Milk", "Recovery Heart", - "Green Rupee", "Blue Rupee", "Red Rupee", "Purple Rupee", "Gold Rupee", "Null 8", - "Deku Sticks (5)", "Deku Sticks (10)", "Deku Nuts (5)", "Deku Nuts (10)", "Bombs (5)", "Bombs (10)", - "Bombs (20)", "Bombs (30)", "Arrows (Small)", "Arrows (Medium)", "Arrows (Large)", "Seeds (30)", - "Bombchus (5)", "Bombchus (10)", "Deku Stick Upgrade (20)", "Deku Stick Upgrade (30)", - "Deku Nut Upgrade (30)","Deku Nut Upgrade (40)", -}; - typedef struct { char name[40]; u32 time; diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index acf940dc49e..df72d1813a4 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -5,9 +5,15 @@ #include "soh/SaveManager.h" #include "soh/util.h" #include +#include "include/z64item.h" + +#include "nlohmann-json/include/nlohmann/json.hpp" +#include +#include #include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/debugger/debugSaveEditor.h" extern "C" { extern SaveContext gSaveContext; @@ -16,7 +22,9 @@ extern "C" { // ImVec4 Colors #define COLOR_WHITE ImVec4(1.00f, 1.00f, 1.00f, 1.00f) +#define COLOR_LIGHT_RED ImVec4(1.0f, 0.05f, 0.0f, 1.0f) #define COLOR_RED ImVec4(1.00f, 0.00f, 0.00f, 1.00f) +#define COLOR_LIGHT_GREEN ImVec4(0.52f, 1.0f, 0.23f, 1.0f) #define COLOR_GREEN ImVec4(0.10f, 1.00f, 0.10f, 1.00f) #define COLOR_BLUE ImVec4(0.00f, 0.33f, 1.00f, 1.00f) #define COLOR_PURPLE ImVec4(0.54f, 0.19f, 0.89f, 1.00f) @@ -25,14 +33,21 @@ extern "C" { #define COLOR_LIGHT_BLUE ImVec4(0.00f, 0.88f, 1.00f, 1.00f) #define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f) -static std::vector splitItem; -static std::vector splitTime; -static std::vector splitStatus; +static std::vector splitItem; +static std::vector splitTime; +static std::vector splitBest; +static std::vector splitPreviousBest; +static std::vector splitStatus; static uint32_t itemReference = ITEM_STICK; static std::string status = ""; static ImVec4 statusColor = COLOR_WHITE; -std::time_t convertedTime; -const char* itemTime; +static uint32_t splitCurNum = 0; +std::string splitAttempt = "Attempt #: 0"; +static std::string splitNumDisp = "Attempt #: "; +static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); +static const char* backgroundColor; + +using json = nlohmann::json; std::string formatTimestampTimeSplit(uint32_t value) { uint32_t sec = value / 10; @@ -43,25 +58,18 @@ std::string formatTimestampTimeSplit(uint32_t value) { return fmt::format("{}:{:0>2}:{:0>2}.{}", hh, mm, ss, ds); } -void TimeSplitTimeHandler() { - uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; - std::string temp = formatTimestampTimeSplit(num); - itemTime = temp.c_str(); -} - void TimeSplitSplitsHandler(GetItemEntry itemEntry) { if (itemEntry.modIndex != 0) { return; } uint32_t loopCounter = 0; for (auto& str : splitItem) { - uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; - std::string temp = formatTimestampTimeSplit(num); - const char* timeValue = temp.c_str(); - if (itemEntry.itemId == splitItem[loopCounter]) { - splitTime[loopCounter] = timeValue; + splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; splitStatus[loopCounter] = 1; + if (splitTime[loopCounter] < splitBest[loopCounter]) { + splitBest[loopCounter] = splitTime[loopCounter]; + } } loopCounter++; } @@ -69,38 +77,61 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { void DrawTimeSplitSplits(){ uint32_t loopCounter = 0; + ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); - ImGui::BeginTable("Splits", 4); - ImGui::TableNextColumn(); - ImGui::TextColored(COLOR_LIGHT_BLUE, "Items"); - ImGui::TableNextColumn(); - ImGui::TextColored(COLOR_LIGHT_BLUE, "Current Times"); - ImGui::TableNextColumn(); - ImGui::TextColored(COLOR_LIGHT_BLUE, "+/-"); - ImGui::TableNextColumn(); - ImGui::TextColored(COLOR_LIGHT_BLUE, "Previous Best"); + ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 22.0f); + ImGui::TableSetupColumn("Item Name"); + ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, 80.0f); + ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableHeadersRow(); for (auto& str : splitItem) { ImGui::TableNextColumn(); - ImGui::TextColored(COLOR_WHITE, SohUtils::itemNames[splitItem[loopCounter]].c_str()); + // Item Image + ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImage[splitItem[loopCounter]]), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1)); ImGui::TableNextColumn(); - - if (splitStatus[loopCounter] == 0) { - uint32_t num = GAMEPLAYSTAT_TOTAL_TIME; - std::string temp = formatTimestampTimeSplit(num); - itemTime = temp.c_str(); - //TimeSplitTimeHandler(); - ImGui::TextColored(COLOR_WHITE, itemTime); + // Item Name + ImGui::Text(SohUtils::itemNames[splitItem[loopCounter]].c_str()); + ImGui::TableNextColumn(); + // Current Time + if (splitTime[loopCounter] == 0) { + ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); } else { - ImGui::TextColored(COLOR_GREEN, splitTime[loopCounter].c_str()); + ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); } ImGui::TableNextColumn(); - // to-do: split difference +/- with colored indicators - - ImGui::TextColored(COLOR_WHITE, "Not Supported"); + // +/- + if (splitStatus[loopCounter] == 0) { + if (splitPreviousBest[loopCounter] == 0) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else { + if (GAMEPLAYSTAT_TOTAL_TIME < splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_LIGHT_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else if (GAMEPLAYSTAT_TOTAL_TIME == splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + } else if (GAMEPLAYSTAT_TOTAL_TIME > splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_LIGHT_RED, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME - splitPreviousBest[loopCounter]).c_str()); + } + } + } else { + if (splitPreviousBest[loopCounter] == 0) { + ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); + } else { + if (splitTime[loopCounter] < splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - splitTime[loopCounter]).c_str()); + } else if (splitTime[loopCounter] == splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + } else if (splitTime[loopCounter] > splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_RED, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + } + } + } ImGui::TableNextColumn(); - ImGui::Text("0:00:00.0"); - + // Previous Best + ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + loopCounter++; } ImGui::EndTable(); @@ -119,7 +150,9 @@ void DrawTimeSplitOptions() { if (ImGui::Button("Add Item")) { splitItem.push_back(itemReference); - splitTime.push_back(""); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); splitStatus.push_back(0); std::string itemEntry = SohUtils::itemNames[itemReference]; status = itemEntry + std::string(" Added to List"); @@ -130,21 +163,127 @@ void DrawTimeSplitOptions() { splitItem.clear(); splitTime.clear(); splitStatus.clear(); + splitPreviousBest.clear(); status = "List has been reset"; statusColor = COLOR_RED; } ImGui::SameLine(0); + if (ImGui::Button("Save List")) { + json j; + j["splitItem"] = splitItem; + j["splitTime"] = splitTime; + j["splitPreviousBest"] = splitPreviousBest; + j["backgroundColor.r"] = colorChoice.x; + j["backgroundColor.g"] = colorChoice.y; + j["backgroundColor.b"] = colorChoice.z; + j["backgroundColor.a"] = colorChoice.w; + std::ofstream file("SplitofHarkinian.json"); + file << j.dump(4); + file.close(); + status = "List has been saved to disk"; + statusColor = COLOR_LIGHT_BLUE; + } + ImGui::SameLine(0); if (ImGui::Button("Load List")) { - + std::ifstream file("SplitofHarkinian.json"); + json j; + + if (file.is_open()) { + file >> j; + file.close(); + } + int itemSize = j["splitItem"].size(); + splitItem.clear(); + splitTime.clear(); + splitPreviousBest.clear(); + splitBest.clear(); + splitStatus.clear(); + + for (int i = 0; i < itemSize; i++) { + splitItem.push_back(0); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); + splitStatus.push_back(0); + } + splitItem = j["splitItem"].get>(); + splitTime = j["splitTime"].get>(); + splitPreviousBest = j["splitPreviousBest"].get>(); + colorChoice.x = j["backgroundColor.r"]; + colorChoice.y = j["backgroundColor.g"]; + colorChoice.z = j["backgroundColor.b"]; + colorChoice.w = j["backgroundColor.a"]; + file.close(); + status = "List has been loaded from Save Data"; + statusColor = COLOR_LIGHT_BLUE; + } + if (ImGui::Button("New Attempt")) { + splitStatus.clear(); + splitTime.clear(); + for (int i = 0; i < splitItem.size(); i++) { + splitStatus.push_back(0); + splitTime.push_back(0); + } + splitCurNum++; + std::stringstream ss; + ss << splitCurNum; + splitAttempt = (splitNumDisp).c_str() + ss.str(); + DrawTimeSplitSplits(); + } + ImGui::SameLine(); + if (ImGui::Button("Update Splits")) { + for (int i = 0; i < splitItem.size(); i++) { + if (splitPreviousBest[i] == 0) { + splitPreviousBest[i] = splitBest[i]; + } else if (splitPreviousBest[i] > splitBest[i]) { + splitPreviousBest[i] = splitBest[i]; + } + } + DrawTimeSplitSplits(); + } + + if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + Color_RGBA8 color; + color.r = colorChoice.x; + color.g = colorChoice.y; + color.b = colorChoice.z; + color.a = colorChoice.w; + } + ImGui::SameLine(); + if (ImGui::Button("Reset")) { + colorChoice = { 0.0f, 0.0f, 0.0f, 1.0f }; } ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } +void InitializeSplitFile() { + if (!std::filesystem::exists("SplitofHarkinian.json")) { + json j; + j["splitItem"] = splitItem; + j["splitTime"] = splitTime; + j["splitPreviousBest"] = splitPreviousBest; + j["backgroundColor.r"] = colorChoice.x; + j["backgroundColor.g"] = colorChoice.y; + j["backgroundColor.b"] = colorChoice.z; + j["backgroundColor.a"] = colorChoice.w; + std::ofstream file("SplitofHarkinian.json"); + file << j.dump(4); + file.close(); + } +} + +static bool initialized = false; + void TimeSplitWindow::DrawElement() { - ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!initialized) { + InitializeSplitFile(); + initialized = true; + } + ImGui::PushStyleColor(ImGuiCol_WindowBg, colorChoice); if (!ImGui::Begin("Time Splitter Window", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { ImGui::End(); + ImGui::PopStyleColor(); return; } if (ImGui::CollapsingHeader("Time Splitter")) { @@ -152,10 +291,11 @@ void TimeSplitWindow::DrawElement() { } DrawTimeSplitSplits(); ImGui::End(); + ImGui::PopStyleColor(); } void TimeSplitWindow::InitElement() { GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { - TimeSplitSplitsHandler(itemEntry); + TimeSplitSplitsHandler(itemEntry); }); } \ No newline at end of file diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index 938f812e61d..5cbeafaac4f 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -12,4 +12,34 @@ class TimeSplitWindow : public LUS::GuiWindow { void UpdateElement() override{}; }; -#endif \ No newline at end of file +#endif + + +static const char* itemImage[156] { + "ITEM_STICK", "ITEM_NUT", "ITEM_BOMB", "ITEM_BOW", "ITEM_ARROW_FIRE", "ITEM_DINS_FIRE", + "ITEM_SLINGSHOT", "ITEM_OCARINA_FAIRY", "ITEM_OCARINA_TIME", "ITEM_BOMBCHU", "ITEM_HOOKSHOT", "ITEM_LONGSHOT", + "ITEM_ARROW_ICE", "ITEM_FARORES_WIND", "ITEM_BOOMERANG", "ITEM_LENS", "ITEM_BEAN", "ITEM_HAMMER", + "ITEM_ARROW_LIGHT", "ITEM_NAYRUS_LOVE", "ITEM_BOTTLE", "ITEM_POTION_RED", "ITEM_POTION_GREEN", "ITEM_POTION_BLUE", + "ITEM_FAIRY", "ITEM_FISH", "ITEM_MILK_BOTTLE", "ITEM_LETTER_RUTO", "ITEM_BLUE_FIRE", "ITEM_BUG", + "ITEM_BIG_POE", "ITEM_MILK_HALF", "ITEM_POE", "ITEM_WEIRD_EGG", "ITEM_CHICKEN", "ITEM_LETTER_ZELDA", + "ITEM_MASK_KEATON", "ITEM_MASK_SKULL", "ITEM_MASK_SPOOKY", "ITEM_MASK_BUNNY", "ITEM_MASK_GORON", "ITEM_MASK_ZORA", + "ITEM_MASK_GERUDO", "ITEM_MASK_TRUTH", "ITEM_SOLD_OUT", "ITEM_POCKET_EGG", "ITEM_POCKET_CUCCO", "ITEM_COJIRO", + "ITEM_ODD_MUSHROOM", "ITEM_ODD_POTION", "ITEM_SAW", "ITEM_SWORD_BROKEN", "ITEM_PRESCRIPTION", "ITEM_FROG", + "ITEM_EYEDROPS", "ITEM_CLAIM_CHECK", "ITEM_BOW_ARROW_FIRE", "ITEM_BOW_ARROW_ICE", "ITEM_BOW_ARROW_LIGHT", "ITEM_SWORD_KOKIRI", + "ITEM_SWORD_MASTER", "ITEM_SWORD_BGS", "ITEM_SHIELD_DEKU", "ITEM_SHIELD_HYLIAN", "ITEM_SHIELD_MIRROR", "ITEM_TUNIC_KOKIRI", + "ITEM_TUNIC_GORON", "ITEM_TUNIC_ZORA", "ITEM_BOOTS_KOKIRI", "ITEM_BOOTS_IRON", "ITEM_BOOTS_HOVER", "ITEM_BULLET_BAG_30", + "ITEM_BULLET_BAG_40", "ITEM_BULLET_BAG_50", "ITEM_QUIVER_30", "ITEM_QUIVER_40", "ITEM_QUIVER_50", "ITEM_BOMB_BAG_20", + "ITEM_BOMB_BAG_30", "ITEM_BOMB_BAG_40", "ITEM_BRACELET", "ITEM_GAUNTLETS_SILVER", "ITEM_GAUNTLETS_GOLD", "ITEM_SCALE_SILVER", + "ITEM_SCALE_GOLDEN", "ITEM_SWORD_KNIFE", "ITEM_WALLET_ADULT", "ITEM_WALLET_GIANT", "ITEM_SEEDS", "ITEM_FISHING_POLE", + "QUEST_SONG_MINUET", "QUEST_SONG_BOLERO", "QUEST_SONG_SERENADE", "QUEST_SONG_REQUIEM", "QUEST_SONG_NOCTURNE", "QUEST_SONG_PRELUDE", + "QUEST_SONG_LULLABY", "QUEST_SONG_EPONA", "QUEST_SONG_SARIA", "QUEST_SONG_SUN", "QUEST_SONG_TIME", "QUEST_SONG_STORMS", + "QUEST_MEDALLION_FOREST", "QUEST_MEDALLION_FIRE", "QUEST_MEDALLION_WATER", "QUEST_MEDALLION_SPIRIT", "QUEST_MEDALLION_SHADOW", "QUEST_MEDALLION_LIGHT", + "QUEST_KOKIRI_EMERALD", "QUEST_GORON_RUBY", "QUEST_ZORA_SAPPHIRE", "QUEST_STONE_OF_AGONY", "QUEST_GERUDO_CARD", "QUEST_SKULL_TOKEN", + "ITEM_HEART_CONTAINER", "ITEM_HEART_PIECE", "ITEM_KEY_BOSS", "ITEM_COMPASS", "ITEM_DUNGEON_MAP", "ITEM_KEY_SMALL", + "ITEM_MAGIC_SMALL", "ITEM_MAGIC_LARGE", "ITEM_HEART_PIECE_2", "ITEM_SINGLE_MAGIC", "ITEM_DOUBLE_MAGIC", "ITEM_DOUBLE_DEFENSE", + "ITEM_INVALID_4", "ITEM_INVALID_5", "ITEM_INVALID_6", "ITEM_INVALID_7", "ITEM_MILK", "ITEM_HEART", + "ITEM_RUPEE_GREEN", "ITEM_RUPEE_BLUE", "ITEM_RUPEE_RED", "ITEM_RUPEE_PURPLE", "ITEM_RUPEE_GOLD", "ITEM_INVALID_8", + "ITEM_STICKS_5", "ITEM_STICKS_10", "ITEM_NUTS_5", "ITEM_NUTS_10", "ITEM_BOMBS_5", "ITEM_BOMBS_10", + "ITEM_BOMBS_20", "ITEM_BOMBS_30", "ITEM_ARROWS_SMALL", "ITEM_ARROWS_MEDIUM", "ITEM_ARROWS_LARGE", "ITEM_SEEDS_30", + "ITEM_BOMBCHUS_5", "ITEM_BOMBCHUS_20", "ITEM_STICK_UPGRADE_20", "ITEM_STICK_UPGRADE_30", "ITEM_NUT_UPGRADE_30", "ITEM_NUT_UPGRADE_40" +}; \ No newline at end of file From 4e20f75bdc88fd3da2c8bd50ba480d9297883f24 Mon Sep 17 00:00:00 2001 From: Caladius Date: Tue, 20 Feb 2024 20:05:15 -0500 Subject: [PATCH 04/40] Better Item List Display for adding items. --- .../Enhancements/timesplits/TimeSplits.cpp | 339 +++++++++++++----- soh/soh/Enhancements/timesplits/TimeSplits.h | 8 +- 2 files changed, 249 insertions(+), 98 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index df72d1813a4..fd177fbe842 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -38,7 +38,6 @@ static std::vector splitTime; static std::vector splitBest; static std::vector splitPreviousBest; static std::vector splitStatus; -static uint32_t itemReference = ITEM_STICK; static std::string status = ""; static ImVec4 statusColor = COLOR_WHITE; static uint32_t splitCurNum = 0; @@ -46,9 +45,127 @@ std::string splitAttempt = "Attempt #: 0"; static std::string splitNumDisp = "Attempt #: "; static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); static const char* backgroundColor; +static std::string itemImager; using json = nlohmann::json; +std::vector splitObjects = { + // ID, Item Name Image Name +TimeSplitObject( 0, "Deku Stick", "ITEM_STICK"), +TimeSplitObject( 1, "Deku Nut", "ITEM_NUT"), +TimeSplitObject( 3, "Fairy Bow", "ITEM_BOW"), +TimeSplitObject( 4, "Fire Arrow", "ITEM_ARROW_FIRE"), +TimeSplitObject( 5, "Din's Fire", "ITEM_DINS_FIRE"), +TimeSplitObject( 6, "Fairy Slingshot", "ITEM_SLINGSHOT"), +TimeSplitObject( 7, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"), +TimeSplitObject( 8, "Ocarina of Time", "ITEM_OCARINA_TIME"), +TimeSplitObject( 9, "Bombchu", "ITEM_BOMBCHU"), +TimeSplitObject( 10, "Hookshot", "ITEM_HOOKSHOT"), +TimeSplitObject( 11, "Longshot", "ITEM_LONGSHOT"), +TimeSplitObject( 12, "Ice Arrow", "ITEM_ARROW_ICE"), +TimeSplitObject( 13, "Farore's Wind", "ITEM_FARORES_WIND"), +TimeSplitObject( 14, "Boomerang", "ITEM_BOOMERANG"), +TimeSplitObject( 15, "Lens of Truth", "ITEM_LENS"), +TimeSplitObject( 16, "Magic Bean", "ITEM_BEAN"), +TimeSplitObject( 17, "Megaton Hammer", "ITEM_HAMMER"), +TimeSplitObject( 18, "Light Arrow", "ITEM_ARROW_LIGHT"), +TimeSplitObject( 19, "Nayru's Love", "ITEM_NAYRUS_LOVE"), +TimeSplitObject( 20, "Empty Bottle", "ITEM_BOTTLE"), +TimeSplitObject( 21, "Red Potion", "ITEM_POTION_RED"), +TimeSplitObject( 22, "Green Potion", "ITEM_POTION_GREEN"), +TimeSplitObject( 23, "Blue Potion", "ITEM_POTION_BLUE"), +TimeSplitObject( 24, "Bottled Fairy", "ITEM_FAIRY"), +TimeSplitObject( 25, "Fish", "ITEM_FISH"), +TimeSplitObject( 26, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"), +TimeSplitObject( 27, "Ruto's Letter", "ITEM_LETTER_RUTO"), +TimeSplitObject( 28, "Blue Fire", "ITEM_BLUE_FIRE"), +TimeSplitObject( 29, "Bug", "ITEM_BUG"), +TimeSplitObject( 30, "Big Poe", "ITEM_BIG_POE"), +TimeSplitObject( 32, "Poe", "ITEM_POE"), +TimeSplitObject( 33, "Weird Egg", "ITEM_WEIRD_EGG"), +TimeSplitObject( 34, "Chicken", "ITEM_CHICKEN"), +TimeSplitObject( 35, "Zelda's Letter", "ITEM_LETTER_ZELDA"), +TimeSplitObject( 36, "Keaton Mask", "ITEM_MASK_KEATON"), +TimeSplitObject( 37, "Skull Mask", "ITEM_MASK_SKULL"), +TimeSplitObject( 38, "Spooky Mask", "ITEM_MASK_SPOOKY"), +TimeSplitObject( 39, "Bunny Hood", "ITEM_MASK_BUNNY"), +TimeSplitObject( 40, "Goron Mask", "ITEM_MASK_GORON"), +TimeSplitObject( 41, "Zora Mask", "ITEM_MASK_ZORA"), +TimeSplitObject( 42, "Gerudo Mask", "ITEM_MASK_GERUDO"), +TimeSplitObject( 43, "Mask of Truth", "ITEM_MASK_TRUTH"), +TimeSplitObject( 45, "Pocket Egg", "ITEM_POCKET_EGG"), +TimeSplitObject( 46, "Pocket Cucco", "ITEM_POCKET_CUCCO"), +TimeSplitObject( 47, "Cojiro", "ITEM_COJIRO"), +TimeSplitObject( 48, "Odd Mushroom", "ITEM_ODD_MUSHROOM"), +TimeSplitObject( 49, "Odd Potion", "ITEM_ODD_POTION"), +TimeSplitObject( 50, "Poacher's Saw", "ITEM_SAW"), +TimeSplitObject( 51, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"), +TimeSplitObject( 52, "Prescription", "ITEM_PRESCRIPTION"), +TimeSplitObject( 53, "Eyeball Frog", "ITEM_FROG"), +TimeSplitObject( 54, "Eye Drops", "ITEM_EYEDROPS"), +TimeSplitObject( 55, "Claim Check", "ITEM_CLAIM_CHECK"), +TimeSplitObject( 59, "Kokiri Sword", "ITEM_SWORD_KOKIRI"), +TimeSplitObject( 60, "Master Sword", "ITEM_SWORD_MASTER"), +TimeSplitObject( 61, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"), +TimeSplitObject( 62, "Deku Shield", "ITEM_SHIELD_DEKU"), +TimeSplitObject( 63, "Hylian Shield", "ITEM_SHIELD_HYLIAN"), +TimeSplitObject( 64, "Mirror Shield", "ITEM_SHIELD_MIRROR"), +TimeSplitObject( 65, "Kokiri Tunic", "ITEM_TUNIC_KOKIRI"), +TimeSplitObject( 66, "Goron Tunic", "ITEM_TUNIC_GORON"), +TimeSplitObject( 67, "Zora Tunic", "ITEM_TUNIC_ZORA"), +TimeSplitObject( 68, "Kokiri Boots", "ITEM_BOOTS_KOKIRI"), +TimeSplitObject( 69, "Iron Boots", "ITEM_BOOTS_IRON"), +TimeSplitObject( 70, "Hover Boots", "ITEM_BOOTS_HOVER"), +TimeSplitObject( 71, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"), +TimeSplitObject( 72, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"), +TimeSplitObject( 73, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"), +TimeSplitObject( 74, "Quiver (30)", "ITEM_QUIVER_30"), +TimeSplitObject( 75, "Big Quiver (40)", "ITEM_QUIVER_40"), +TimeSplitObject( 76, "Biggest Quiver (50)", "ITEM_QUIVER_50"), +TimeSplitObject( 77, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"), +TimeSplitObject( 78, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"), +TimeSplitObject( 79, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"), +TimeSplitObject( 80, "Goron's Bracelet", "ITEM_BRACELET"), +TimeSplitObject( 81, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"), +TimeSplitObject( 82, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"), +TimeSplitObject( 83, "Silver Scale", "ITEM_SCALE_SILVER"), +TimeSplitObject( 84, "Golden Scale", "ITEM_SCALE_GOLDEN"), +TimeSplitObject( 85, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"), +TimeSplitObject( 86, "Adult's Wallet", "ITEM_WALLET_ADULT"), +TimeSplitObject( 87, "Giant's Wallet", "ITEM_WALLET_GIANT"), +TimeSplitObject( 89, "Fishing Pole", "ITEM_FISHING_POLE"), +TimeSplitObject( 90, "Minuet of Forest", "QUEST_SONG_MINUET"), +TimeSplitObject( 91, "Bolero of Fire", "QUEST_SONG_BOLERO"), +TimeSplitObject( 92, "Serenade of Water", "QUEST_SONG_SERENADE"), +TimeSplitObject( 93, "Requiem of Spirit", "QUEST_SONG_REQUIEM"), +TimeSplitObject( 94, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"), +TimeSplitObject( 95, "Prelude of Light", "QUEST_SONG_PRELUDE"), +TimeSplitObject( 96, "Zelda's Lullaby", "QUEST_SONG_LULLABY"), +TimeSplitObject( 97, "Epona's Song", "QUEST_SONG_EPONA"), +TimeSplitObject( 98, "Saria's Song", "QUEST_SONG_SARIA"), +TimeSplitObject( 99, "Sun's Song", "QUEST_SONG_SUN"), +TimeSplitObject( 100, "Song of Time", "QUEST_SONG_TIME"), +TimeSplitObject( 101, "Song of Storms", "QUEST_SONG_STORMS"), +TimeSplitObject( 102, "Forest Medallion", "QUEST_MEDALLION_FOREST"), +TimeSplitObject( 103, "Fire Medallion", "QUEST_MEDALLION_FIRE"), +TimeSplitObject( 104, "Water Medallion", "QUEST_MEDALLION_WATER"), +TimeSplitObject( 105, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"), +TimeSplitObject( 106, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"), +TimeSplitObject( 107, "Light Medallion", "QUEST_MEDALLION_LIGHT"), +TimeSplitObject( 108, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"), +TimeSplitObject( 109, "Goron's Ruby", "QUEST_GORON_RUBY"), +TimeSplitObject( 110, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"), +TimeSplitObject( 111, "Stone of Agony", "QUEST_STONE_OF_AGONY"), +TimeSplitObject( 112, "Gerudo's Card", "QUEST_GERUDO_CARD"), +TimeSplitObject( 123, "Magic Meter", "ITEM_MAGIC_SMALL"), +TimeSplitObject( 124, "Double Magic Meter", "ITEM_MAGIC_LARGE"), +TimeSplitObject( 125, "Double Defense", "ITEM_HEART_CONTAINER"), +TimeSplitObject( 152, "Deku Stick Upgrade (20)", "ITEM_STICK"), +TimeSplitObject( 153, "Deku Stick Upgrade (30)", "ITEM_STICK"), +TimeSplitObject( 154, "Deku Nut Upgrade (30)", "ITEM_NUT"), +TimeSplitObject( 155, "Deku Nut Upgrade (40)", "ITEM_NUT") +}; + std::string formatTimestampTimeSplit(uint32_t value) { uint32_t sec = value / 10; uint32_t hh = sec / 3600; @@ -75,90 +192,7 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { } } -void DrawTimeSplitSplits(){ - uint32_t loopCounter = 0; - ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); - - ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); - ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 22.0f); - ImGui::TableSetupColumn("Item Name"); - ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, 90.0f); - ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, 80.0f); - ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, 90.0f); - ImGui::TableHeadersRow(); - - for (auto& str : splitItem) { - ImGui::TableNextColumn(); - // Item Image - ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImage[splitItem[loopCounter]]), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1)); - ImGui::TableNextColumn(); - // Item Name - ImGui::Text(SohUtils::itemNames[splitItem[loopCounter]].c_str()); - ImGui::TableNextColumn(); - // Current Time - if (splitTime[loopCounter] == 0) { - ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else { - ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); - } - ImGui::TableNextColumn(); - // +/- - if (splitStatus[loopCounter] == 0) { - if (splitPreviousBest[loopCounter] == 0) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else { - if (GAMEPLAYSTAT_TOTAL_TIME < splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_LIGHT_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else if (GAMEPLAYSTAT_TOTAL_TIME == splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); - } else if (GAMEPLAYSTAT_TOTAL_TIME > splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_LIGHT_RED, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME - splitPreviousBest[loopCounter]).c_str()); - } - } - } else { - if (splitPreviousBest[loopCounter] == 0) { - ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); - } else { - if (splitTime[loopCounter] < splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - splitTime[loopCounter]).c_str()); - } else if (splitTime[loopCounter] == splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); - } else if (splitTime[loopCounter] > splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_RED, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); - } - } - } - ImGui::TableNextColumn(); - // Previous Best - ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); - - loopCounter++; - } - ImGui::EndTable(); -} - void DrawTimeSplitOptions() { - if (ImGui::BeginCombo("Item List", SohUtils::itemNames[itemReference].c_str())) { - for (int i = 0; i < SohUtils::itemNames.size(); i++) { - if (ImGui::Selectable(SohUtils::itemNames[i].c_str())) { - itemReference = i; - } - } - ImGui::EndCombo(); - } - - if (ImGui::Button("Add Item")) { - - splitItem.push_back(itemReference); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(100000); - splitStatus.push_back(0); - std::string itemEntry = SohUtils::itemNames[itemReference]; - status = itemEntry + std::string(" Added to List"); - statusColor = COLOR_GREEN; - } - ImGui::SameLine(0); if (ImGui::Button("Reset List")) { splitItem.clear(); splitTime.clear(); @@ -228,7 +262,6 @@ void DrawTimeSplitOptions() { std::stringstream ss; ss << splitCurNum; splitAttempt = (splitNumDisp).c_str() + ss.str(); - DrawTimeSplitSplits(); } ImGui::SameLine(); if (ImGui::Button("Update Splits")) { @@ -239,24 +272,100 @@ void DrawTimeSplitOptions() { splitPreviousBest[i] = splitBest[i]; } } - DrawTimeSplitSplits(); } - - if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { - Color_RGBA8 color; - color.r = colorChoice.x; - color.g = colorChoice.y; - color.b = colorChoice.z; - color.a = colorChoice.w; + UIWidgets::Spacer(0); + ImGui::Text("Background Color"); + if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, + ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + Color_RGBA8 color; + color.r = colorChoice.x; + color.g = colorChoice.y; + color.b = colorChoice.z; + color.a = colorChoice.w; } ImGui::SameLine(); if (ImGui::Button("Reset")) { - colorChoice = { 0.0f, 0.0f, 0.0f, 1.0f }; + colorChoice = { 0.0f, 0.0f, 0.0f, 1.0f }; } + ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } +void DrawTimeSplitSplits(){ + if (ImGui::CollapsingHeader("Time Splitter")) { + DrawTimeSplitOptions(); + } + + uint32_t loopCounter = 0; + ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); + + ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 22.0f); + ImGui::TableSetupColumn("Item Name"); + ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, 80.0f); + ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableHeadersRow(); + + for (auto& str : splitItem) { + ImGui::TableNextColumn(); + // Item Image + for (const auto& obj : splitObjects) { + if (obj.itemID == splitItem[loopCounter]) { + itemImager = obj.itemImage; + } + } + ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1)); + ImGui::TableNextColumn(); + // Item Name + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(SohUtils::itemNames[splitItem[loopCounter]].c_str()); + ImGui::TableNextColumn(); + // Current Time + if (splitTime[loopCounter] == 0) { + ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else { + ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); + } + ImGui::TableNextColumn(); + // +/- + if (splitStatus[loopCounter] == 0) { + if (splitPreviousBest[loopCounter] == 0) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else { + if (GAMEPLAYSTAT_TOTAL_TIME < splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_LIGHT_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else if (GAMEPLAYSTAT_TOTAL_TIME == splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + } else if (GAMEPLAYSTAT_TOTAL_TIME > splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_LIGHT_RED, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME - splitPreviousBest[loopCounter]).c_str()); + } + } + } else { + if (splitPreviousBest[loopCounter] == 0) { + ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); + } else { + if (splitTime[loopCounter] < splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - splitTime[loopCounter]).c_str()); + } else if (splitTime[loopCounter] == splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + } else if (splitTime[loopCounter] > splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_RED, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + } + } + } + ImGui::PopStyleVar(); + ImGui::TableNextColumn(); + // Previous Best + ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + + loopCounter++; + } + ImGui::EndTable(); +} + void InitializeSplitFile() { if (!std::filesystem::exists("SplitofHarkinian.json")) { json j; @@ -275,6 +384,31 @@ void InitializeSplitFile() { static bool initialized = false; +void DrawTimeSplitManageList() { + uint32_t itemLoop = 0; + ImGui::BeginTable("Items", 1); + ImGui::TableNextColumn(); + for (const auto& obj : splitObjects) { + if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1))) { + uint32_t itemReference = obj.itemID; + splitItem.push_back(itemReference); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); + splitStatus.push_back(0); + statusColor = COLOR_GREEN; + status = obj.itemName + std::string(" added to list"); + } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 8.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(obj.itemName); + ImGui::PopStyleVar(); + ImGui::TableNextColumn(); + } + ImGui::EndTable(); +} + void TimeSplitWindow::DrawElement() { if (!initialized) { InitializeSplitFile(); @@ -286,10 +420,21 @@ void TimeSplitWindow::DrawElement() { ImGui::PopStyleColor(); return; } - if (ImGui::CollapsingHeader("Time Splitter")) { - DrawTimeSplitOptions(); + ImGui::BeginTabBar("Split Tabs"); + if (ImGui::BeginTabItem("Splits")) { + status = ""; + DrawTimeSplitSplits(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Manage List")) { + ImGui::TextColored(statusColor, status.c_str()); + UIWidgets::PaddedSeparator(); + ImGui::BeginChild("Split List"); + DrawTimeSplitManageList(); + ImGui::EndChild(); + ImGui::EndTabItem(); } - DrawTimeSplitSplits(); + ImGui::EndTabBar(); ImGui::End(); ImGui::PopStyleColor(); } diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index 5cbeafaac4f..ea7b82a15ce 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -42,4 +42,10 @@ static const char* itemImage[156] { "ITEM_STICKS_5", "ITEM_STICKS_10", "ITEM_NUTS_5", "ITEM_NUTS_10", "ITEM_BOMBS_5", "ITEM_BOMBS_10", "ITEM_BOMBS_20", "ITEM_BOMBS_30", "ITEM_ARROWS_SMALL", "ITEM_ARROWS_MEDIUM", "ITEM_ARROWS_LARGE", "ITEM_SEEDS_30", "ITEM_BOMBCHUS_5", "ITEM_BOMBCHUS_20", "ITEM_STICK_UPGRADE_20", "ITEM_STICK_UPGRADE_30", "ITEM_NUT_UPGRADE_30", "ITEM_NUT_UPGRADE_40" -}; \ No newline at end of file +}; + +typedef struct { + uint32_t itemID; + const char* itemName; + const char* itemImage; +} TimeSplitObject; \ No newline at end of file From 33ecd9c0bb31e6ae52203ad2b1d32b8249a802b2 Mon Sep 17 00:00:00 2001 From: Caladius Date: Wed, 21 Feb 2024 21:18:55 -0500 Subject: [PATCH 05/40] Fix Object issue on macOS Build. Remove old array from header. --- .../Enhancements/timesplits/TimeSplits.cpp | 244 +++++++++--------- soh/soh/Enhancements/timesplits/TimeSplits.h | 30 --- 2 files changed, 122 insertions(+), 152 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index fd177fbe842..5abba92eb25 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -46,124 +46,125 @@ static std::string splitNumDisp = "Attempt #: "; static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); static const char* backgroundColor; static std::string itemImager; +static std::string itemNamer; using json = nlohmann::json; std::vector splitObjects = { - // ID, Item Name Image Name -TimeSplitObject( 0, "Deku Stick", "ITEM_STICK"), -TimeSplitObject( 1, "Deku Nut", "ITEM_NUT"), -TimeSplitObject( 3, "Fairy Bow", "ITEM_BOW"), -TimeSplitObject( 4, "Fire Arrow", "ITEM_ARROW_FIRE"), -TimeSplitObject( 5, "Din's Fire", "ITEM_DINS_FIRE"), -TimeSplitObject( 6, "Fairy Slingshot", "ITEM_SLINGSHOT"), -TimeSplitObject( 7, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"), -TimeSplitObject( 8, "Ocarina of Time", "ITEM_OCARINA_TIME"), -TimeSplitObject( 9, "Bombchu", "ITEM_BOMBCHU"), -TimeSplitObject( 10, "Hookshot", "ITEM_HOOKSHOT"), -TimeSplitObject( 11, "Longshot", "ITEM_LONGSHOT"), -TimeSplitObject( 12, "Ice Arrow", "ITEM_ARROW_ICE"), -TimeSplitObject( 13, "Farore's Wind", "ITEM_FARORES_WIND"), -TimeSplitObject( 14, "Boomerang", "ITEM_BOOMERANG"), -TimeSplitObject( 15, "Lens of Truth", "ITEM_LENS"), -TimeSplitObject( 16, "Magic Bean", "ITEM_BEAN"), -TimeSplitObject( 17, "Megaton Hammer", "ITEM_HAMMER"), -TimeSplitObject( 18, "Light Arrow", "ITEM_ARROW_LIGHT"), -TimeSplitObject( 19, "Nayru's Love", "ITEM_NAYRUS_LOVE"), -TimeSplitObject( 20, "Empty Bottle", "ITEM_BOTTLE"), -TimeSplitObject( 21, "Red Potion", "ITEM_POTION_RED"), -TimeSplitObject( 22, "Green Potion", "ITEM_POTION_GREEN"), -TimeSplitObject( 23, "Blue Potion", "ITEM_POTION_BLUE"), -TimeSplitObject( 24, "Bottled Fairy", "ITEM_FAIRY"), -TimeSplitObject( 25, "Fish", "ITEM_FISH"), -TimeSplitObject( 26, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"), -TimeSplitObject( 27, "Ruto's Letter", "ITEM_LETTER_RUTO"), -TimeSplitObject( 28, "Blue Fire", "ITEM_BLUE_FIRE"), -TimeSplitObject( 29, "Bug", "ITEM_BUG"), -TimeSplitObject( 30, "Big Poe", "ITEM_BIG_POE"), -TimeSplitObject( 32, "Poe", "ITEM_POE"), -TimeSplitObject( 33, "Weird Egg", "ITEM_WEIRD_EGG"), -TimeSplitObject( 34, "Chicken", "ITEM_CHICKEN"), -TimeSplitObject( 35, "Zelda's Letter", "ITEM_LETTER_ZELDA"), -TimeSplitObject( 36, "Keaton Mask", "ITEM_MASK_KEATON"), -TimeSplitObject( 37, "Skull Mask", "ITEM_MASK_SKULL"), -TimeSplitObject( 38, "Spooky Mask", "ITEM_MASK_SPOOKY"), -TimeSplitObject( 39, "Bunny Hood", "ITEM_MASK_BUNNY"), -TimeSplitObject( 40, "Goron Mask", "ITEM_MASK_GORON"), -TimeSplitObject( 41, "Zora Mask", "ITEM_MASK_ZORA"), -TimeSplitObject( 42, "Gerudo Mask", "ITEM_MASK_GERUDO"), -TimeSplitObject( 43, "Mask of Truth", "ITEM_MASK_TRUTH"), -TimeSplitObject( 45, "Pocket Egg", "ITEM_POCKET_EGG"), -TimeSplitObject( 46, "Pocket Cucco", "ITEM_POCKET_CUCCO"), -TimeSplitObject( 47, "Cojiro", "ITEM_COJIRO"), -TimeSplitObject( 48, "Odd Mushroom", "ITEM_ODD_MUSHROOM"), -TimeSplitObject( 49, "Odd Potion", "ITEM_ODD_POTION"), -TimeSplitObject( 50, "Poacher's Saw", "ITEM_SAW"), -TimeSplitObject( 51, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"), -TimeSplitObject( 52, "Prescription", "ITEM_PRESCRIPTION"), -TimeSplitObject( 53, "Eyeball Frog", "ITEM_FROG"), -TimeSplitObject( 54, "Eye Drops", "ITEM_EYEDROPS"), -TimeSplitObject( 55, "Claim Check", "ITEM_CLAIM_CHECK"), -TimeSplitObject( 59, "Kokiri Sword", "ITEM_SWORD_KOKIRI"), -TimeSplitObject( 60, "Master Sword", "ITEM_SWORD_MASTER"), -TimeSplitObject( 61, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"), -TimeSplitObject( 62, "Deku Shield", "ITEM_SHIELD_DEKU"), -TimeSplitObject( 63, "Hylian Shield", "ITEM_SHIELD_HYLIAN"), -TimeSplitObject( 64, "Mirror Shield", "ITEM_SHIELD_MIRROR"), -TimeSplitObject( 65, "Kokiri Tunic", "ITEM_TUNIC_KOKIRI"), -TimeSplitObject( 66, "Goron Tunic", "ITEM_TUNIC_GORON"), -TimeSplitObject( 67, "Zora Tunic", "ITEM_TUNIC_ZORA"), -TimeSplitObject( 68, "Kokiri Boots", "ITEM_BOOTS_KOKIRI"), -TimeSplitObject( 69, "Iron Boots", "ITEM_BOOTS_IRON"), -TimeSplitObject( 70, "Hover Boots", "ITEM_BOOTS_HOVER"), -TimeSplitObject( 71, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"), -TimeSplitObject( 72, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"), -TimeSplitObject( 73, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"), -TimeSplitObject( 74, "Quiver (30)", "ITEM_QUIVER_30"), -TimeSplitObject( 75, "Big Quiver (40)", "ITEM_QUIVER_40"), -TimeSplitObject( 76, "Biggest Quiver (50)", "ITEM_QUIVER_50"), -TimeSplitObject( 77, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"), -TimeSplitObject( 78, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"), -TimeSplitObject( 79, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"), -TimeSplitObject( 80, "Goron's Bracelet", "ITEM_BRACELET"), -TimeSplitObject( 81, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"), -TimeSplitObject( 82, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"), -TimeSplitObject( 83, "Silver Scale", "ITEM_SCALE_SILVER"), -TimeSplitObject( 84, "Golden Scale", "ITEM_SCALE_GOLDEN"), -TimeSplitObject( 85, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"), -TimeSplitObject( 86, "Adult's Wallet", "ITEM_WALLET_ADULT"), -TimeSplitObject( 87, "Giant's Wallet", "ITEM_WALLET_GIANT"), -TimeSplitObject( 89, "Fishing Pole", "ITEM_FISHING_POLE"), -TimeSplitObject( 90, "Minuet of Forest", "QUEST_SONG_MINUET"), -TimeSplitObject( 91, "Bolero of Fire", "QUEST_SONG_BOLERO"), -TimeSplitObject( 92, "Serenade of Water", "QUEST_SONG_SERENADE"), -TimeSplitObject( 93, "Requiem of Spirit", "QUEST_SONG_REQUIEM"), -TimeSplitObject( 94, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"), -TimeSplitObject( 95, "Prelude of Light", "QUEST_SONG_PRELUDE"), -TimeSplitObject( 96, "Zelda's Lullaby", "QUEST_SONG_LULLABY"), -TimeSplitObject( 97, "Epona's Song", "QUEST_SONG_EPONA"), -TimeSplitObject( 98, "Saria's Song", "QUEST_SONG_SARIA"), -TimeSplitObject( 99, "Sun's Song", "QUEST_SONG_SUN"), -TimeSplitObject( 100, "Song of Time", "QUEST_SONG_TIME"), -TimeSplitObject( 101, "Song of Storms", "QUEST_SONG_STORMS"), -TimeSplitObject( 102, "Forest Medallion", "QUEST_MEDALLION_FOREST"), -TimeSplitObject( 103, "Fire Medallion", "QUEST_MEDALLION_FIRE"), -TimeSplitObject( 104, "Water Medallion", "QUEST_MEDALLION_WATER"), -TimeSplitObject( 105, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"), -TimeSplitObject( 106, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"), -TimeSplitObject( 107, "Light Medallion", "QUEST_MEDALLION_LIGHT"), -TimeSplitObject( 108, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"), -TimeSplitObject( 109, "Goron's Ruby", "QUEST_GORON_RUBY"), -TimeSplitObject( 110, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"), -TimeSplitObject( 111, "Stone of Agony", "QUEST_STONE_OF_AGONY"), -TimeSplitObject( 112, "Gerudo's Card", "QUEST_GERUDO_CARD"), -TimeSplitObject( 123, "Magic Meter", "ITEM_MAGIC_SMALL"), -TimeSplitObject( 124, "Double Magic Meter", "ITEM_MAGIC_LARGE"), -TimeSplitObject( 125, "Double Defense", "ITEM_HEART_CONTAINER"), -TimeSplitObject( 152, "Deku Stick Upgrade (20)", "ITEM_STICK"), -TimeSplitObject( 153, "Deku Stick Upgrade (30)", "ITEM_STICK"), -TimeSplitObject( 154, "Deku Nut Upgrade (30)", "ITEM_NUT"), -TimeSplitObject( 155, "Deku Nut Upgrade (40)", "ITEM_NUT") + // ID, Item Name Image Name +{ 0, "Deku Stick", "ITEM_STICK"}, +{ 1, "Deku Nut", "ITEM_NUT"}, +{ 3, "Fairy Bow", "ITEM_BOW"}, +{ 4, "Fire Arrow", "ITEM_ARROW_FIRE"}, +{ 5, "Din's Fire", "ITEM_DINS_FIRE"}, +{ 6, "Fairy Slingshot", "ITEM_SLINGSHOT"}, +{ 7, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, +{ 8, "Ocarina of Time", "ITEM_OCARINA_TIME"}, +{ 9, "Bombchu", "ITEM_BOMBCHU"}, +{ 10, "Hookshot", "ITEM_HOOKSHOT"}, +{ 11, "Longshot", "ITEM_LONGSHOT"}, +{ 12, "Ice Arrow", "ITEM_ARROW_ICE"}, +{ 13, "Farore's Wind", "ITEM_FARORES_WIND"}, +{ 14, "Boomerang", "ITEM_BOOMERANG"}, +{ 15, "Lens of Truth", "ITEM_LENS"}, +{ 16, "Magic Bean", "ITEM_BEAN"}, +{ 17, "Megaton Hammer", "ITEM_HAMMER"}, +{ 18, "Light Arrow", "ITEM_ARROW_LIGHT"}, +{ 19, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, +{ 20, "Empty Bottle", "ITEM_BOTTLE"}, +{ 21, "Red Potion", "ITEM_POTION_RED"}, +{ 22, "Green Potion", "ITEM_POTION_GREEN"}, +{ 23, "Blue Potion", "ITEM_POTION_BLUE"}, +{ 24, "Bottled Fairy", "ITEM_FAIRY"}, +{ 25, "Fish", "ITEM_FISH"}, +{ 26, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"}, +{ 27, "Ruto's Letter", "ITEM_LETTER_RUTO"}, +{ 28, "Blue Fire", "ITEM_BLUE_FIRE"}, +{ 29, "Bug", "ITEM_BUG"}, +{ 30, "Big Poe", "ITEM_BIG_POE"}, +{ 32, "Poe", "ITEM_POE"}, +{ 33, "Weird Egg", "ITEM_WEIRD_EGG"}, +{ 34, "Chicken", "ITEM_CHICKEN"}, +{ 35, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, +{ 36, "Keaton Mask", "ITEM_MASK_KEATON"}, +{ 37, "Skull Mask", "ITEM_MASK_SKULL"}, +{ 38, "Spooky Mask", "ITEM_MASK_SPOOKY"}, +{ 39, "Bunny Hood", "ITEM_MASK_BUNNY"}, +{ 40, "Goron Mask", "ITEM_MASK_GORON"}, +{ 41, "Zora Mask", "ITEM_MASK_ZORA"}, +{ 42, "Gerudo Mask", "ITEM_MASK_GERUDO"}, +{ 43, "Mask of Truth", "ITEM_MASK_TRUTH"}, +{ 45, "Pocket Egg", "ITEM_POCKET_EGG"}, +{ 46, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, +{ 47, "Cojiro", "ITEM_COJIRO"}, +{ 48, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, +{ 49, "Odd Potion", "ITEM_ODD_POTION"}, +{ 50, "Poacher's Saw", "ITEM_SAW"}, +{ 51, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, +{ 52, "Prescription", "ITEM_PRESCRIPTION"}, +{ 53, "Eyeball Frog", "ITEM_FROG"}, +{ 54, "Eye Drops", "ITEM_EYEDROPS"}, +{ 55, "Claim Check", "ITEM_CLAIM_CHECK"}, +{ 59, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, +{ 60, "Master Sword", "ITEM_SWORD_MASTER"}, +{ 61, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, +{ 62, "Deku Shield", "ITEM_SHIELD_DEKU"}, +{ 63, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, +{ 64, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, +{ 65, "Kokiri Tunic", "ITEM_TUNIC_KOKIRI"}, +{ 66, "Goron Tunic", "ITEM_TUNIC_GORON"}, +{ 67, "Zora Tunic", "ITEM_TUNIC_ZORA"}, +{ 68, "Kokiri Boots", "ITEM_BOOTS_KOKIRI"}, +{ 69, "Iron Boots", "ITEM_BOOTS_IRON"}, +{ 70, "Hover Boots", "ITEM_BOOTS_HOVER"}, +{ 71, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, +{ 72, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, +{ 73, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, +{ 74, "Quiver (30)", "ITEM_QUIVER_30"}, +{ 75, "Big Quiver (40)", "ITEM_QUIVER_40"}, +{ 76, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, +{ 77, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, +{ 78, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, +{ 79, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, +{ 80, "Goron's Bracelet", "ITEM_BRACELET"}, +{ 81, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, +{ 82, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, +{ 83, "Silver Scale", "ITEM_SCALE_SILVER"}, +{ 84, "Golden Scale", "ITEM_SCALE_GOLDEN"}, +{ 85, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, +{ 86, "Adult's Wallet", "ITEM_WALLET_ADULT"}, +{ 87, "Giant's Wallet", "ITEM_WALLET_GIANT"}, +{ 89, "Fishing Pole", "ITEM_FISHING_POLE"}, +{ 90, "Minuet of Forest", "QUEST_SONG_MINUET"}, +{ 91, "Bolero of Fire", "QUEST_SONG_BOLERO"}, +{ 92, "Serenade of Water", "QUEST_SONG_SERENADE"}, +{ 93, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, +{ 94, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, +{ 95, "Prelude of Light", "QUEST_SONG_PRELUDE"}, +{ 96, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, +{ 97, "Epona's Song", "QUEST_SONG_EPONA"}, +{ 98, "Saria's Song", "QUEST_SONG_SARIA"}, +{ 99, "Sun's Song", "QUEST_SONG_SUN"}, +{ 100, "Song of Time", "QUEST_SONG_TIME"}, +{ 101, "Song of Storms", "QUEST_SONG_STORMS"}, +{ 102, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, +{ 103, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, +{ 104, "Water Medallion", "QUEST_MEDALLION_WATER"}, +{ 105, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, +{ 106, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, +{ 107, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, +{ 108, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, +{ 109, "Goron's Ruby", "QUEST_GORON_RUBY"}, +{ 110, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, +{ 111, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, +{ 112, "Gerudo's Card", "QUEST_GERUDO_CARD"}, +{ 123, "Magic Meter", "ITEM_MAGIC_SMALL"}, +{ 124, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, +{ 125, "Double Defense", "ITEM_HEART_CONTAINER"}, +{ 152, "Deku Stick Upgrade (20)", "ITEM_STICK"}, +{ 153, "Deku Stick Upgrade (30)", "ITEM_STICK"}, +{ 154, "Deku Nut Upgrade (30)", "ITEM_NUT"}, +{ 155, "Deku Nut Upgrade (40)", "ITEM_NUT"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -211,7 +212,7 @@ void DrawTimeSplitOptions() { j["backgroundColor.g"] = colorChoice.y; j["backgroundColor.b"] = colorChoice.z; j["backgroundColor.a"] = colorChoice.w; - std::ofstream file("SplitofHarkinian.json"); + std::ofstream file("splitdata.json"); file << j.dump(4); file.close(); status = "List has been saved to disk"; @@ -219,7 +220,7 @@ void DrawTimeSplitOptions() { } ImGui::SameLine(0); if (ImGui::Button("Load List")) { - std::ifstream file("SplitofHarkinian.json"); + std::ifstream file("splitdata.json"); json j; if (file.is_open()) { @@ -275,8 +276,7 @@ void DrawTimeSplitOptions() { } UIWidgets::Spacer(0); ImGui::Text("Background Color"); - if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, - ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { Color_RGBA8 color; color.r = colorChoice.x; color.g = colorChoice.y; @@ -287,7 +287,6 @@ void DrawTimeSplitOptions() { if (ImGui::Button("Reset")) { colorChoice = { 0.0f, 0.0f, 0.0f, 1.0f }; } - ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } @@ -314,6 +313,7 @@ void DrawTimeSplitSplits(){ for (const auto& obj : splitObjects) { if (obj.itemID == splitItem[loopCounter]) { itemImager = obj.itemImage; + itemNamer = obj.itemName; } } ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1)); @@ -321,7 +321,7 @@ void DrawTimeSplitSplits(){ // Item Name ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); ImGui::AlignTextToFramePadding(); - ImGui::Text(SohUtils::itemNames[splitItem[loopCounter]].c_str()); + ImGui::Text(itemNamer.c_str()); ImGui::TableNextColumn(); // Current Time if (splitTime[loopCounter] == 0) { @@ -367,7 +367,7 @@ void DrawTimeSplitSplits(){ } void InitializeSplitFile() { - if (!std::filesystem::exists("SplitofHarkinian.json")) { + if (!std::filesystem::exists("splitdata.json")) { json j; j["splitItem"] = splitItem; j["splitTime"] = splitTime; @@ -376,7 +376,7 @@ void InitializeSplitFile() { j["backgroundColor.g"] = colorChoice.y; j["backgroundColor.b"] = colorChoice.z; j["backgroundColor.a"] = colorChoice.w; - std::ofstream file("SplitofHarkinian.json"); + std::ofstream file("splitdata.json"); file << j.dump(4); file.close(); } diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index ea7b82a15ce..2a42553ed61 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -14,36 +14,6 @@ class TimeSplitWindow : public LUS::GuiWindow { #endif - -static const char* itemImage[156] { - "ITEM_STICK", "ITEM_NUT", "ITEM_BOMB", "ITEM_BOW", "ITEM_ARROW_FIRE", "ITEM_DINS_FIRE", - "ITEM_SLINGSHOT", "ITEM_OCARINA_FAIRY", "ITEM_OCARINA_TIME", "ITEM_BOMBCHU", "ITEM_HOOKSHOT", "ITEM_LONGSHOT", - "ITEM_ARROW_ICE", "ITEM_FARORES_WIND", "ITEM_BOOMERANG", "ITEM_LENS", "ITEM_BEAN", "ITEM_HAMMER", - "ITEM_ARROW_LIGHT", "ITEM_NAYRUS_LOVE", "ITEM_BOTTLE", "ITEM_POTION_RED", "ITEM_POTION_GREEN", "ITEM_POTION_BLUE", - "ITEM_FAIRY", "ITEM_FISH", "ITEM_MILK_BOTTLE", "ITEM_LETTER_RUTO", "ITEM_BLUE_FIRE", "ITEM_BUG", - "ITEM_BIG_POE", "ITEM_MILK_HALF", "ITEM_POE", "ITEM_WEIRD_EGG", "ITEM_CHICKEN", "ITEM_LETTER_ZELDA", - "ITEM_MASK_KEATON", "ITEM_MASK_SKULL", "ITEM_MASK_SPOOKY", "ITEM_MASK_BUNNY", "ITEM_MASK_GORON", "ITEM_MASK_ZORA", - "ITEM_MASK_GERUDO", "ITEM_MASK_TRUTH", "ITEM_SOLD_OUT", "ITEM_POCKET_EGG", "ITEM_POCKET_CUCCO", "ITEM_COJIRO", - "ITEM_ODD_MUSHROOM", "ITEM_ODD_POTION", "ITEM_SAW", "ITEM_SWORD_BROKEN", "ITEM_PRESCRIPTION", "ITEM_FROG", - "ITEM_EYEDROPS", "ITEM_CLAIM_CHECK", "ITEM_BOW_ARROW_FIRE", "ITEM_BOW_ARROW_ICE", "ITEM_BOW_ARROW_LIGHT", "ITEM_SWORD_KOKIRI", - "ITEM_SWORD_MASTER", "ITEM_SWORD_BGS", "ITEM_SHIELD_DEKU", "ITEM_SHIELD_HYLIAN", "ITEM_SHIELD_MIRROR", "ITEM_TUNIC_KOKIRI", - "ITEM_TUNIC_GORON", "ITEM_TUNIC_ZORA", "ITEM_BOOTS_KOKIRI", "ITEM_BOOTS_IRON", "ITEM_BOOTS_HOVER", "ITEM_BULLET_BAG_30", - "ITEM_BULLET_BAG_40", "ITEM_BULLET_BAG_50", "ITEM_QUIVER_30", "ITEM_QUIVER_40", "ITEM_QUIVER_50", "ITEM_BOMB_BAG_20", - "ITEM_BOMB_BAG_30", "ITEM_BOMB_BAG_40", "ITEM_BRACELET", "ITEM_GAUNTLETS_SILVER", "ITEM_GAUNTLETS_GOLD", "ITEM_SCALE_SILVER", - "ITEM_SCALE_GOLDEN", "ITEM_SWORD_KNIFE", "ITEM_WALLET_ADULT", "ITEM_WALLET_GIANT", "ITEM_SEEDS", "ITEM_FISHING_POLE", - "QUEST_SONG_MINUET", "QUEST_SONG_BOLERO", "QUEST_SONG_SERENADE", "QUEST_SONG_REQUIEM", "QUEST_SONG_NOCTURNE", "QUEST_SONG_PRELUDE", - "QUEST_SONG_LULLABY", "QUEST_SONG_EPONA", "QUEST_SONG_SARIA", "QUEST_SONG_SUN", "QUEST_SONG_TIME", "QUEST_SONG_STORMS", - "QUEST_MEDALLION_FOREST", "QUEST_MEDALLION_FIRE", "QUEST_MEDALLION_WATER", "QUEST_MEDALLION_SPIRIT", "QUEST_MEDALLION_SHADOW", "QUEST_MEDALLION_LIGHT", - "QUEST_KOKIRI_EMERALD", "QUEST_GORON_RUBY", "QUEST_ZORA_SAPPHIRE", "QUEST_STONE_OF_AGONY", "QUEST_GERUDO_CARD", "QUEST_SKULL_TOKEN", - "ITEM_HEART_CONTAINER", "ITEM_HEART_PIECE", "ITEM_KEY_BOSS", "ITEM_COMPASS", "ITEM_DUNGEON_MAP", "ITEM_KEY_SMALL", - "ITEM_MAGIC_SMALL", "ITEM_MAGIC_LARGE", "ITEM_HEART_PIECE_2", "ITEM_SINGLE_MAGIC", "ITEM_DOUBLE_MAGIC", "ITEM_DOUBLE_DEFENSE", - "ITEM_INVALID_4", "ITEM_INVALID_5", "ITEM_INVALID_6", "ITEM_INVALID_7", "ITEM_MILK", "ITEM_HEART", - "ITEM_RUPEE_GREEN", "ITEM_RUPEE_BLUE", "ITEM_RUPEE_RED", "ITEM_RUPEE_PURPLE", "ITEM_RUPEE_GOLD", "ITEM_INVALID_8", - "ITEM_STICKS_5", "ITEM_STICKS_10", "ITEM_NUTS_5", "ITEM_NUTS_10", "ITEM_BOMBS_5", "ITEM_BOMBS_10", - "ITEM_BOMBS_20", "ITEM_BOMBS_30", "ITEM_ARROWS_SMALL", "ITEM_ARROWS_MEDIUM", "ITEM_ARROWS_LARGE", "ITEM_SEEDS_30", - "ITEM_BOMBCHUS_5", "ITEM_BOMBCHUS_20", "ITEM_STICK_UPGRADE_20", "ITEM_STICK_UPGRADE_30", "ITEM_NUT_UPGRADE_30", "ITEM_NUT_UPGRADE_40" -}; - typedef struct { uint32_t itemID; const char* itemName; From 89a297f93dc0912e583a4ff9069a0670280ac662 Mon Sep 17 00:00:00 2001 From: Caladius Date: Wed, 21 Feb 2024 21:24:20 -0500 Subject: [PATCH 06/40] Reverting util files to original. --- soh/soh/util.cpp | 2 +- soh/soh/util.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/soh/soh/util.cpp b/soh/soh/util.cpp index 95af1f99f59..856432cbbd2 100644 --- a/soh/soh/util.cpp +++ b/soh/soh/util.cpp @@ -117,7 +117,7 @@ std::vector sceneNames = { "Treasure Chest Room", }; -std::vector SohUtils::itemNames = { +std::vector itemNames = { "Deku Stick", "Deku Nut", "Bomb", diff --git a/soh/soh/util.h b/soh/soh/util.h index 4850a150116..db5af8636a3 100644 --- a/soh/soh/util.h +++ b/soh/soh/util.h @@ -1,11 +1,8 @@ #pragma once #include #include -#include namespace SohUtils { - extern std::vector itemNames; - const std::string& GetSceneName(int32_t scene); const std::string& GetItemName(int32_t item); From fe24ac67c0858f408ac95cd8464a421d647db730 Mon Sep 17 00:00:00 2001 From: Caladius Date: Sat, 24 Feb 2024 17:12:13 -0500 Subject: [PATCH 07/40] Fix Great Fairy rewards not triggering Splits. Starting work on changing List Order (WIP) --- .../Enhancements/timesplits/TimeSplits.cpp | 113 +++++++++++++++++- soh/soh/Enhancements/timesplits/TimeSplits.h | 17 ++- .../ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 8 ++ 3 files changed, 133 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 5abba92eb25..6f60fea77d5 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -19,7 +19,6 @@ extern "C" { extern SaveContext gSaveContext; } - // ImVec4 Colors #define COLOR_WHITE ImVec4(1.00f, 1.00f, 1.00f, 1.00f) #define COLOR_LIGHT_RED ImVec4(1.0f, 0.05f, 0.0f, 1.0f) @@ -47,6 +46,9 @@ static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); static const char* backgroundColor; static std::string itemImager; static std::string itemNamer; +static uint32_t splitCounter; +//static uint32_t buttonNum; +//static std::string buttonAction; using json = nlohmann::json; @@ -176,6 +178,20 @@ std::string formatTimestampTimeSplit(uint32_t value) { return fmt::format("{}:{:0>2}:{:0>2}.{}", hh, mm, ss, ds); } +void TimeSplitSplitsHandlerS(uint32_t itemID) { + uint32_t loopCounter = 0; + for (auto& str : splitItem) { + if (itemID == splitItem[loopCounter]) { + splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; + splitStatus[loopCounter] = 1; + if (splitTime[loopCounter] < splitBest[loopCounter]) { + splitBest[loopCounter] = splitTime[loopCounter]; + } + } + loopCounter++; + } +} + void TimeSplitSplitsHandler(GetItemEntry itemEntry) { if (itemEntry.modIndex != 0) { return; @@ -409,6 +425,86 @@ void DrawTimeSplitManageList() { ImGui::EndTable(); } +void ListManagerButtonHandler(std::string action, uint32_t buttonNum) { + if (action == "minus") { + uint32_t curTemp = splitItem[buttonNum]; + uint32_t newTemp = splitItem[buttonNum + 1]; + splitItem[buttonNum] = newTemp; + splitItem[buttonNum + 1] = curTemp; + } + if (action == "plus") { + uint32_t curTemp = splitItem[buttonNum]; + uint32_t newTemp = splitItem[buttonNum - 1]; + splitItem[buttonNum] = newTemp; + splitItem[buttonNum - 1] = curTemp; + } + +} + +void DrawTimeSplitListManager() { + std::string buttonLabelP; + std::string buttonLabelM; + uint32_t loopCounter = 0; + + ImGui::BeginTable("List Manager", 3); + ImGui::TableSetupColumn("List Order", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 80.0f); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 22.0f); + ImGui::TableSetupColumn("Item Name"); + ImGui::TableNextColumn(); + for (auto& str : splitItem) { + for (const auto& obj : splitObjects) { + if (obj.itemID == splitItem[loopCounter]) { + splitCounter = loopCounter; + itemImager = obj.itemImage; + itemNamer = obj.itemName; + } + } + + if (loopCounter - 1 > splitItem.size() || loopCounter > splitItem.size()) { + buttonLabelP = "x"; + } else { + buttonLabelP = std::to_string(splitCounter).c_str(); + } + + if (loopCounter + 1 >= splitItem.size()) { + buttonLabelM = "x"; + } else { + buttonLabelM = std::to_string(splitCounter).c_str(); + } + + if (ImGui::Button(buttonLabelP.c_str())) { + if (buttonLabelP == "x") { + + } else { + std::string buttonAction = "plus"; + uint32_t buttonID = std::stoi(buttonLabelP); + ListManagerButtonHandler(buttonAction, buttonID); + } + } + + ImGui::SameLine(); + ImGui::Text(std::to_string(loopCounter).c_str()); + ImGui::SameLine(); + if (ImGui::Button(buttonLabelM.c_str())) { + if (buttonLabelM == "x") { + + } else { + std::string buttonAction = "minus"; + uint32_t buttonID = std::stoi(buttonLabelM); + ListManagerButtonHandler(buttonAction, buttonID); + } + } + + ImGui::TableNextColumn(); + ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1)); + ImGui::TableNextColumn(); + ImGui::Text(itemNamer.c_str()); + ImGui::TableNextColumn(); + loopCounter++; + } + ImGui::EndTable(); +} + void TimeSplitWindow::DrawElement() { if (!initialized) { InitializeSplitFile(); @@ -429,9 +525,18 @@ void TimeSplitWindow::DrawElement() { if (ImGui::BeginTabItem("Manage List")) { ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); - ImGui::BeginChild("Split List"); - DrawTimeSplitManageList(); - ImGui::EndChild(); + ImGui::BeginTabBar("List Options"); + if (ImGui::BeginTabItem("Add Items")) { + ImGui::BeginChild("Split List"); + DrawTimeSplitManageList(); + ImGui::EndChild(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Change Order")) { + //DrawTimeSplitListManager(); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); ImGui::EndTabItem(); } ImGui::EndTabBar(); diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index 2a42553ed61..ca8571173d8 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -1,4 +1,20 @@ #pragma once +#ifndef TIMESPLITS_H +#define TIMESPLITS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void TimeSplitSplitsHandlerS(uint32_t itemID); + +#ifdef __cplusplus +} +#endif + +#endif // TIMESPLITS_H #include @@ -11,7 +27,6 @@ class TimeSplitWindow : public LUS::GuiWindow { void DrawElement() override; void UpdateElement() override{}; }; - #endif typedef struct { diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index e8b2be4df50..bc7413cc066 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -12,6 +12,8 @@ #include "scenes/indoors/daiyousei_izumi/daiyousei_izumi_scene.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) typedef enum { @@ -238,16 +240,19 @@ void BgDyYoseizo_ChooseType(BgDyYoseizo* this, PlayState* play) { switch (this->fountainType) { case FAIRY_SPELL_FARORES_WIND: if (!Flags_GetItemGetInf(ITEMGETINF_18)) { + TimeSplitSplitsHandlerS(ITEM_FARORES_WIND); givingReward = true; } break; case FAIRY_SPELL_DINS_FIRE: if (!Flags_GetItemGetInf(ITEMGETINF_19)) { + TimeSplitSplitsHandlerS(ITEM_DINS_FIRE); givingReward = true; } break; case FAIRY_SPELL_NAYRUS_LOVE: if (!Flags_GetItemGetInf(ITEMGETINF_1A)) { + TimeSplitSplitsHandlerS(ITEM_NAYRUS_LOVE); givingReward = true; } break; @@ -742,6 +747,7 @@ void BgDyYoseizo_Give_Reward(BgDyYoseizo* this, PlayState* play) { case FAIRY_UPGRADE_MAGIC: gSaveContext.isMagicAcquired = true; gSaveContext.magicFillTarget = MAGIC_NORMAL_METER; + TimeSplitSplitsHandlerS(ITEM_SINGLE_MAGIC); Interface_ChangeAlpha(9); break; case FAIRY_UPGRADE_DOUBLE_MAGIC: @@ -751,10 +757,12 @@ void BgDyYoseizo_Give_Reward(BgDyYoseizo* this, PlayState* play) { gSaveContext.isDoubleMagicAcquired = true; gSaveContext.magicFillTarget = MAGIC_DOUBLE_METER; gSaveContext.magicLevel = 0; + TimeSplitSplitsHandlerS(ITEM_DOUBLE_MAGIC); Interface_ChangeAlpha(9); break; case FAIRY_UPGRADE_HALF_DAMAGE: gSaveContext.isDoubleDefenseAcquired = true; + TimeSplitSplitsHandlerS(ITEM_DOUBLE_DEFENSE); Interface_ChangeAlpha(9); break; } From e822a244b86efa69b242af17d5ce0b9877fcdee1 Mon Sep 17 00:00:00 2001 From: Caladius Date: Thu, 29 Feb 2024 12:30:37 -0500 Subject: [PATCH 08/40] Added in Boss Kill splits, needs a better image for the buttons but a temporary placeholder in the form of a regular button is used until then. --- .../Enhancements/timesplits/TimeSplits.cpp | 220 +++++++++--------- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 3 + .../overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 3 + .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 2 + .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 2 + .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 3 + .../actors/ovl_Boss_Goma/z_boss_goma.c | 3 + .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 2 + .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 3 + .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 2 + .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 3 + 11 files changed, 130 insertions(+), 116 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 6f60fea77d5..0949fb7a778 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -40,15 +40,14 @@ static std::vector splitStatus; static std::string status = ""; static ImVec4 statusColor = COLOR_WHITE; static uint32_t splitCurNum = 0; -std::string splitAttempt = "Attempt #: 0"; +std::string splitAttempt = "Attempt #: 1"; static std::string splitNumDisp = "Attempt #: "; static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); static const char* backgroundColor; static std::string itemImager; static std::string itemNamer; static uint32_t splitCounter; -//static uint32_t buttonNum; -//static std::string buttonAction; +static uint32_t totalPreviousBest; using json = nlohmann::json; @@ -163,10 +162,20 @@ std::vector splitObjects = { { 123, "Magic Meter", "ITEM_MAGIC_SMALL"}, { 124, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, { 125, "Double Defense", "ITEM_HEART_CONTAINER"}, -{ 152, "Deku Stick Upgrade (20)", "ITEM_STICK"}, -{ 153, "Deku Stick Upgrade (30)", "ITEM_STICK"}, -{ 154, "Deku Nut Upgrade (30)", "ITEM_NUT"}, -{ 155, "Deku Nut Upgrade (40)", "ITEM_NUT"}, +{ 152, "Deku Stick Upgrade (20)", "ITEM_STICK_UPGRADE_20"}, +{ 153, "Deku Stick Upgrade (30)", "ITEM_STICK_UPGRADE_30"}, +{ 154, "Deku Nut Upgrade (30)", "ITEM_NUT_UPGRADE_30"}, +{ 155, "Deku Nut Upgrade (40)", "ITEM_NUT_UPGRADE_40"}, +{ 657, "Queen Gohma", "RG_TRIFORCE_PIECE_GOHMA"}, +{ 658, "King Dodongo", "RG_TRIFORCE_PIECE_DODONGO"}, +{ 659, "Barinade", "RG_TRIFORCE_PIECE_BARINADE"}, +{ 660, "Phantom Ganon", "RG_TRIFORCE_PIECE_PHANTOM_GANON"}, +{ 661, "Volvagia", "RG_TRIFORCE_PIECE_VOLVAGIA"}, +{ 662, "Morpha", "RG_TRIFORCE_PIECE_MORPHA"}, +{ 663, "Bongo Bongo", "RG_TRIFORCE_PIECE_BONGO"}, +{ 664, "Twinrova", "RG_TRIFORCE_PIECE_TWINROVA"}, +{ 665, "Ganondorf", "RG_TRIFORCE_PIECE_GANONDORF"}, +{ 666, "Ganon", "RG_TRIFORCE_PIECE"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -312,11 +321,18 @@ void DrawTimeSplitSplits(){ DrawTimeSplitOptions(); } + totalPreviousBest = 0; + for (int i = 0; i < splitItem.size(); i++) { + totalPreviousBest += splitPreviousBest[i]; + } + uint32_t loopCounter = 0; + uint32_t buttonID = 0; ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); - ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 22.0f); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 27.0f); ImGui::TableSetupColumn("Item Name"); ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, 90.0f); ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, 80.0f); @@ -325,6 +341,7 @@ void DrawTimeSplitSplits(){ for (auto& str : splitItem) { ImGui::TableNextColumn(); + // Item Image for (const auto& obj : splitObjects) { if (obj.itemID == splitItem[loopCounter]) { @@ -332,7 +349,47 @@ void DrawTimeSplitSplits(){ itemNamer = obj.itemName; } } - ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1)); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); + if (LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager) == nullptr) { + ImGui::Button(std::to_string(buttonID).c_str()); + buttonID++; + } else { + ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1)); + } + ImGui::PopStyleColor(); + + if (ImGui::IsItemActive()) { + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ImGui::GetColorU32(ImGuiCol_HeaderHovered)); + static ImVec2 mousePos = ImGui::GetMousePos(); + float curPos = ImGui::GetMousePos().y; + if (ImGui::IsMouseDragging(0)) { + ImVec2 dragDelta = ImGui::GetMouseDragDelta(0); + int direction = (dragDelta.y < 0.0f) ? -1 : 1; + int nextIndex = loopCounter + direction; + if (ImGui::GetMousePos().y >= mousePos.y + 27.4f || ImGui::GetMousePos().y <= mousePos.y - 27.4f) { + ImGui::ResetMouseDragDelta(0); + mousePos = ImGui::GetMousePos(); + if (nextIndex >= 0 && nextIndex < splitItem.size()) { + uint32_t itemTemp = splitItem[loopCounter]; + uint32_t timeTemp = splitTime[loopCounter]; + uint32_t bestTemp = splitBest[loopCounter]; + uint32_t prevTemp = splitPreviousBest[loopCounter]; + uint32_t statusTemp = splitStatus[loopCounter]; + splitItem[loopCounter] = splitItem[nextIndex]; + splitTime[loopCounter] = splitTime[nextIndex]; + splitBest[loopCounter] = splitBest[nextIndex]; + splitPreviousBest[loopCounter] = splitPreviousBest[nextIndex]; + splitStatus[loopCounter] = splitStatus[nextIndex]; + splitItem[nextIndex] = itemTemp; + splitTime[nextIndex] = timeTemp; + splitBest[nextIndex] = bestTemp; + splitPreviousBest[nextIndex] - prevTemp; + splitStatus[nextIndex] = statusTemp; + } + } + } + } + ImGui::TableNextColumn(); // Item Name ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); @@ -372,14 +429,20 @@ void DrawTimeSplitSplits(){ } } } - ImGui::PopStyleVar(); ImGui::TableNextColumn(); // Previous Best ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); - + ImGui::PopStyleVar(); loopCounter++; } ImGui::EndTable(); + ImGui::PopStyleVar(1); + + ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); + ImGui::SameLine(); + ImGui::Text(" / "); + ImGui::SameLine(); + ImGui::Text(formatTimestampTimeSplit(totalPreviousBest).c_str()); } void InitializeSplitFile() { @@ -401,106 +464,40 @@ void InitializeSplitFile() { static bool initialized = false; void DrawTimeSplitManageList() { - uint32_t itemLoop = 0; ImGui::BeginTable("Items", 1); ImGui::TableNextColumn(); + uint32_t buttonID = 0; for (const auto& obj : splitObjects) { - if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1))) { - uint32_t itemReference = obj.itemID; - splitItem.push_back(itemReference); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(100000); - splitStatus.push_back(0); - statusColor = COLOR_GREEN; - status = obj.itemName + std::string(" added to list"); - } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 8.0f)); - ImGui::AlignTextToFramePadding(); - ImGui::Text(obj.itemName); - ImGui::PopStyleVar(); - ImGui::TableNextColumn(); - } - ImGui::EndTable(); -} - -void ListManagerButtonHandler(std::string action, uint32_t buttonNum) { - if (action == "minus") { - uint32_t curTemp = splitItem[buttonNum]; - uint32_t newTemp = splitItem[buttonNum + 1]; - splitItem[buttonNum] = newTemp; - splitItem[buttonNum + 1] = curTemp; - } - if (action == "plus") { - uint32_t curTemp = splitItem[buttonNum]; - uint32_t newTemp = splitItem[buttonNum - 1]; - splitItem[buttonNum] = newTemp; - splitItem[buttonNum - 1] = curTemp; - } - -} - -void DrawTimeSplitListManager() { - std::string buttonLabelP; - std::string buttonLabelM; - uint32_t loopCounter = 0; - - ImGui::BeginTable("List Manager", 3); - ImGui::TableSetupColumn("List Order", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 80.0f); - ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 22.0f); - ImGui::TableSetupColumn("Item Name"); - ImGui::TableNextColumn(); - for (auto& str : splitItem) { - for (const auto& obj : splitObjects) { - if (obj.itemID == splitItem[loopCounter]) { - splitCounter = loopCounter; - itemImager = obj.itemImage; - itemNamer = obj.itemName; + + if (LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage) == nullptr) { + if (ImGui::Button(std::to_string(buttonID).c_str())) { + splitItem.push_back(obj.itemID); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); + splitStatus.push_back(0); + statusColor = COLOR_GREEN; + status = obj.itemName + std::string(" added to list"); } - } - - if (loopCounter - 1 > splitItem.size() || loopCounter > splitItem.size()) { - buttonLabelP = "x"; - } else { - buttonLabelP = std::to_string(splitCounter).c_str(); - } - - if (loopCounter + 1 >= splitItem.size()) { - buttonLabelM = "x"; + buttonID++; } else { - buttonLabelM = std::to_string(splitCounter).c_str(); - } - - if (ImGui::Button(buttonLabelP.c_str())) { - if (buttonLabelP == "x") { - - } else { - std::string buttonAction = "plus"; - uint32_t buttonID = std::stoi(buttonLabelP); - ListManagerButtonHandler(buttonAction, buttonID); - } + if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1))) { + splitItem.push_back(obj.itemID); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); + splitStatus.push_back(0); + statusColor = COLOR_GREEN; + status = obj.itemName + std::string(" added to list"); } - ImGui::SameLine(); - ImGui::Text(std::to_string(loopCounter).c_str()); - ImGui::SameLine(); - if (ImGui::Button(buttonLabelM.c_str())) { - if (buttonLabelM == "x") { - - } else { - std::string buttonAction = "minus"; - uint32_t buttonID = std::stoi(buttonLabelM); - ListManagerButtonHandler(buttonAction, buttonID); - } } - - ImGui::TableNextColumn(); - ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1)); - ImGui::TableNextColumn(); - ImGui::Text(itemNamer.c_str()); + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 8.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(obj.itemName); + ImGui::PopStyleVar(1); ImGui::TableNextColumn(); - loopCounter++; } ImGui::EndTable(); } @@ -513,7 +510,7 @@ void TimeSplitWindow::DrawElement() { ImGui::PushStyleColor(ImGuiCol_WindowBg, colorChoice); if (!ImGui::Begin("Time Splitter Window", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { ImGui::End(); - ImGui::PopStyleColor(); + ImGui::PopStyleColor(1); return; } ImGui::BeginTabBar("Split Tabs"); @@ -525,23 +522,14 @@ void TimeSplitWindow::DrawElement() { if (ImGui::BeginTabItem("Manage List")) { ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); - ImGui::BeginTabBar("List Options"); - if (ImGui::BeginTabItem("Add Items")) { - ImGui::BeginChild("Split List"); - DrawTimeSplitManageList(); - ImGui::EndChild(); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Change Order")) { - //DrawTimeSplitListManager(); - ImGui::EndTabItem(); - } - ImGui::EndTabBar(); + ImGui::BeginChild("Add Items"); + DrawTimeSplitManageList(); + ImGui::EndChild(); ImGui::EndTabItem(); } ImGui::EndTabBar(); ImGui::End(); - ImGui::PopStyleColor(); + ImGui::PopStyleColor(1); } void TimeSplitWindow::InitElement() { diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index 30455e8e5bc..ee0204c7ad2 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -10,6 +10,8 @@ #include // malloc #include // memcpy +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) #define LAVA_TEX_WIDTH 32 @@ -1547,6 +1549,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { this->cameraAt.y = camera->at.y; this->cameraAt.z = camera->at.z; gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(658); BossRush_HandleCompleteBoss(play); break; case 5: diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index fb14c5ebe47..060e8f79a0f 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -12,6 +12,8 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) typedef enum { @@ -900,6 +902,7 @@ void BossFd2_CollisionCheck(BossFd2* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_VALVAISA_DEAD); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(661); BossRush_HandleCompleteBoss(play); } else if (damage) { BossFd2_SetupDamaged(this, play); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index ebc244d7414..4e20fa99526 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -14,6 +14,7 @@ #include "soh/Enhancements/boss-rush/BossRush.h" #include +#include "soh/Enhancements/timesplits/TimeSplits.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -2813,6 +2814,7 @@ void BossGanon_UpdateDamage(BossGanon* this, PlayState* play) { Audio_QueueSeqCmd(0x100100FF); this->screenFlashTimer = 4; gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(665); BossRush_HandleCompleteBoss(play); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_DAMAGE2); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index 5ec12f093ba..0718b900640 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -10,6 +10,7 @@ #include "soh/Enhancements/boss-rush/BossRush.h" #include +#include "soh/Enhancements/timesplits/TimeSplits.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -1691,6 +1692,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; BossRush_HandleCompleteBoss(play); gSaveContext.sohStats.gameComplete = true; + TimeSplitSplitsHandlerS(666); this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index 111380f0b11..de415ede73b 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -13,6 +13,8 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) typedef enum { @@ -1249,6 +1251,7 @@ void BossGanondrof_CollisionCheck(BossGanondrof* this, PlayState* play) { BossGanondrof_SetupDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(660); BossRush_HandleCompleteBoss(play); return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index 6de72fd2dff..44f087356ad 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -6,6 +6,8 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) // IRIS_FOLLOW: gohma looks towards the player (iris rotation) @@ -1842,6 +1844,7 @@ void BossGoma_UpdateHit(BossGoma* this, PlayState* play) { BossGoma_SetupDefeated(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(657); BossRush_HandleCompleteBoss(play); } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index 78534e85141..3ee12292b55 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -15,6 +15,7 @@ #include "soh/Enhancements/boss-rush/BossRush.h" #include +#include "soh/Enhancements/timesplits/TimeSplits.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -1794,6 +1795,7 @@ void BossMo_CoreCollisionCheck(BossMo* this, PlayState* play) { ((sMorphaTent1->csCamera == 0) && (sMorphaTent2 != NULL) && (sMorphaTent2->csCamera == 0))) { Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(662); BossRush_HandleCompleteBoss(play); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); this->csState = MO_DEATH_START; diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index f7a48f8736a..6c9ff1c05b0 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -13,6 +13,8 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT) #define vParity actionVar @@ -2564,6 +2566,7 @@ void BossSst_HeadCollisionCheck(BossSst* this, PlayState* play) { Enemy_StartFinishingBlow(play, &this->actor); BossSst_HeadSetupDeath(this, play); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(663); BossRush_HandleCompleteBoss(play); } else { BossSst_HeadSetupDamage(this); diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 5360eef0221..d8be5d5f5d4 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -7,6 +7,7 @@ #include "soh/Enhancements/boss-rush/BossRush.h" #include +#include "soh/Enhancements/timesplits/TimeSplits.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -5290,6 +5291,7 @@ void BossTw_TwinrovaDamage(BossTw* this, PlayState* play, u8 damage) { Enemy_StartFinishingBlow(play, &this->actor); Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_YOUNG_DEAD); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(664); BossRush_HandleCompleteBoss(play); return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index ee62b141ed9..f42779664c8 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -17,6 +17,8 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) #define GET_BODY(this) ((BossVa*)(this)->actor.parent) @@ -1398,6 +1400,7 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) { BossVa_SetupBodyDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME; + TimeSplitSplitsHandlerS(659); BossRush_HandleCompleteBoss(play); return; } From a26bc78c084e2d335ff101b55ea742fb7e5c91d9 Mon Sep 17 00:00:00 2001 From: Caladius Date: Thu, 29 Feb 2024 15:13:18 -0500 Subject: [PATCH 09/40] Permanent ImageButtons for all items, Thank you Archez! --- .../Enhancements/timesplits/TimeSplits.cpp | 66 +++++++------------ 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 0949fb7a778..4f345cbafa7 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -162,19 +162,19 @@ std::vector splitObjects = { { 123, "Magic Meter", "ITEM_MAGIC_SMALL"}, { 124, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, { 125, "Double Defense", "ITEM_HEART_CONTAINER"}, -{ 152, "Deku Stick Upgrade (20)", "ITEM_STICK_UPGRADE_20"}, -{ 153, "Deku Stick Upgrade (30)", "ITEM_STICK_UPGRADE_30"}, -{ 154, "Deku Nut Upgrade (30)", "ITEM_NUT_UPGRADE_30"}, -{ 155, "Deku Nut Upgrade (40)", "ITEM_NUT_UPGRADE_40"}, -{ 657, "Queen Gohma", "RG_TRIFORCE_PIECE_GOHMA"}, -{ 658, "King Dodongo", "RG_TRIFORCE_PIECE_DODONGO"}, -{ 659, "Barinade", "RG_TRIFORCE_PIECE_BARINADE"}, -{ 660, "Phantom Ganon", "RG_TRIFORCE_PIECE_PHANTOM_GANON"}, -{ 661, "Volvagia", "RG_TRIFORCE_PIECE_VOLVAGIA"}, -{ 662, "Morpha", "RG_TRIFORCE_PIECE_MORPHA"}, -{ 663, "Bongo Bongo", "RG_TRIFORCE_PIECE_BONGO"}, -{ 664, "Twinrova", "RG_TRIFORCE_PIECE_TWINROVA"}, -{ 665, "Ganondorf", "RG_TRIFORCE_PIECE_GANONDORF"}, +{ 152, "Deku Stick Upgrade (20)", "ITEM_STICK"}, +{ 153, "Deku Stick Upgrade (30)", "ITEM_STICK"}, +{ 154, "Deku Nut Upgrade (30)", "ITEM_NUT"}, +{ 155, "Deku Nut Upgrade (40)", "ITEM_NUT"}, +{ 657, "Queen Gohma", "RG_TRIFORCE_PIECE"}, +{ 658, "King Dodongo", "RG_TRIFORCE_PIECE"}, +{ 659, "Barinade", "RG_TRIFORCE_PIECE"}, +{ 660, "Phantom Ganon", "RG_TRIFORCE_PIECE"}, +{ 661, "Volvagia", "RG_TRIFORCE_PIECE"}, +{ 662, "Morpha", "RG_TRIFORCE_PIECE"}, +{ 663, "Bongo Bongo", "RG_TRIFORCE_PIECE"}, +{ 664, "Twinrova", "RG_TRIFORCE_PIECE"}, +{ 665, "Ganondorf", "RG_TRIFORCE_PIECE"}, { 666, "Ganon", "RG_TRIFORCE_PIECE"}, }; @@ -350,12 +350,7 @@ void DrawTimeSplitSplits(){ } } ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - if (LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager) == nullptr) { - ImGui::Button(std::to_string(buttonID).c_str()); - buttonID++; - } else { - ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1)); - } + ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1)); ImGui::PopStyleColor(); if (ImGui::IsItemActive()) { @@ -434,6 +429,7 @@ void DrawTimeSplitSplits(){ ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); ImGui::PopStyleVar(); loopCounter++; + buttonID++; } ImGui::EndTable(); ImGui::PopStyleVar(1); @@ -468,29 +464,14 @@ void DrawTimeSplitManageList() { ImGui::TableNextColumn(); uint32_t buttonID = 0; for (const auto& obj : splitObjects) { - - if (LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage) == nullptr) { - if (ImGui::Button(std::to_string(buttonID).c_str())) { - splitItem.push_back(obj.itemID); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(100000); - splitStatus.push_back(0); - statusColor = COLOR_GREEN; - status = obj.itemName + std::string(" added to list"); - } - buttonID++; - } else { - if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1))) { - splitItem.push_back(obj.itemID); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(100000); - splitStatus.push_back(0); - statusColor = COLOR_GREEN; - status = obj.itemName + std::string(" added to list"); - } - + if (ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1))) { + splitItem.push_back(obj.itemID); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); + splitStatus.push_back(0); + statusColor = COLOR_GREEN; + status = obj.itemName + std::string(" added to list"); } ImGui::SameLine(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 8.0f)); @@ -498,6 +479,7 @@ void DrawTimeSplitManageList() { ImGui::Text(obj.itemName); ImGui::PopStyleVar(1); ImGui::TableNextColumn(); + buttonID++; } ImGui::EndTable(); } From d1d3c56a9e7bdc66e66a8dc1c58a388c4bd1f450 Mon Sep 17 00:00:00 2001 From: Caladius Date: Sat, 2 Mar 2024 16:31:20 -0500 Subject: [PATCH 10/40] Multiple Saved Lists, boss kills w/ images, drag and reorder lists. --- soh/assets/soh_assets.h | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index 2b193053c3b..d8f771ea07f 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -73,6 +73,7 @@ static const ALIGN_ASSET(2) char gArrowDownTex[] = dgArrowDown; #define dgTriforcePiece "__OTR__textures/parameter_static/gTriforcePiece" static const ALIGN_ASSET(2) char gTriforcePieceTex[] = dgTriforcePiece; +static const ALIGN_ASSET(2) char gWTriforcePieceTex[] = dgWTriforcePiece; #define dgFileSelMQButtonTex "__OTR__textures/title_static/gFileSelMQButtonTex" static const ALIGN_ASSET(2) char gFileSelMQButtonTex[] = dgFileSelMQButtonTex; From 37131d7b108583008db9aa719f4a188f711eb366 Mon Sep 17 00:00:00 2001 From: Caladius Date: Sat, 2 Mar 2024 16:31:34 -0500 Subject: [PATCH 11/40] - --- .../gWTriforcePiece.rgba32.png | Bin 0 -> 1486 bytes soh/assets/soh_assets.h | 2 + .../Enhancements/timesplits/TimeSplits.cpp | 527 ++++++++++-------- 3 files changed, 310 insertions(+), 219 deletions(-) create mode 100644 soh/assets/custom/textures/parameter_static/gWTriforcePiece.rgba32.png diff --git a/soh/assets/custom/textures/parameter_static/gWTriforcePiece.rgba32.png b/soh/assets/custom/textures/parameter_static/gWTriforcePiece.rgba32.png new file mode 100644 index 0000000000000000000000000000000000000000..dfdd947f551c32dd167e85bf79bee896aa817157 GIT binary patch literal 1486 zcmV;<1u^=GP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vG?BLDy{BLR4&KXw2B1!GA>K~z{r?N>`| z8&wp&_RQGh8GCHkP1?q85-2HYQUPkasX&4v(W>1e1Qiks5G+8fx`GOc6+fw{hy_Im zRxCheS0PmbAt4o|ZThE;(zCPSao9BobY~k)P)G-aF@hXKd?q zI`AlAw~mht>k^R3yQX!XH07X$sqodn?7~MYni6}bft*Je+CJ)TaCO+u2J0l*C3~rAb$-Pjm zR=qPb@%PW3|NB&{Ww@-VJ+W#5YPmWdxs^I%v)RFBvw>G}Lm&_Uj^j{71r`_8T{os8 zpIOs;V$}jJT%7vG>-7koP8)Q+4nD68qA0?aEd$VMHKA6kK_r@bH<`-5Y%N(4s}e95 zNxa2z{IhiKa0nm>9284c2o40m>2yM0|0WcmL95wJoNag^S%gNl{Xf&a!)nIF=4`fLKNs`esD5BMpC(d2_rB^;Yw1BDbtz&LkRzwlW zaX6gYodlG?EXh>*u?I%>KO`Nc9577A?!x7&^3X+Rs3_0r|(6Qxpl%-Zq}^c0Xv=RVZ6 z+7n(yV#HK>_`?>4i|sb%1wn8iF%S8Cfdn%z4GsozQU|@$rs|OXnz(Y3jA5HD!-@hh zi^mhm+!4hiG0Pb_J+PW53F1)zd4Q^b=HzlEc1>%BhX+|Mkf?H58$Eme>Irk@ZLBC@ zHj?@l8F@((O{)>a-RUYokQZ1ea8Q_Z>;si*ja~bFZU_dcKNw6zJf1l`I~RY$TFUT1 z0qIQs?P9UKcLQ$1z?hL5N4sqfIw!Am1@IUK8ktNUEpM@Bfq()Y#e)J`OvvQq^{pwK35c(H5*2X!@#U2OK4DrlL(3lB_0!i9&k9!L|w=h**sdScsx)n zE@DV4=$*3k`yUf0sZS8seFe~z9h4R2G zOCo3II0(7yA|w(SNG2oT^=?2f0$ z-d-Z1QZ%!&dw=qk$j^`ey+U{C+ zo79f3wLt@u%e1m9;x;J}kYlI;MWYcs)?pwx#F~-U>(lqY^ul|G4(>aIC99e%aJA`5 zz<0Sm9=;j7EIJ+Ba*N0dYFWpAzX0>;B&ekVjEz4H+ee0QRW~FZ6lPH0fK)02vFI!a z4kz1};=VN$I``tfy|4RxN|@bTh9v>9_`=8Ka^)ylSI0LTepui;Acu`51NFL&Z$BAi z*%cYw8azET6#6X?@Yga6`5)0ZH|2+h-v;6EO)Z&>+Wh`LN2OA%i=xc$+5Oa~yLavU z2#qm`?!q14gw<+o5B7AwVKj5~T0P*B8;)Nss~i13Uj#4FP@93HZ9eUd obqiQ8?&$;nHvSjzUl#!I4;WvzDY1oMy8r+H07*qoM6N<$g7g-trT_o{ literal 0 HcmV?d00001 diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index d8f771ea07f..973b54f46db 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -73,7 +73,9 @@ static const ALIGN_ASSET(2) char gArrowDownTex[] = dgArrowDown; #define dgTriforcePiece "__OTR__textures/parameter_static/gTriforcePiece" static const ALIGN_ASSET(2) char gTriforcePieceTex[] = dgTriforcePiece; +#define dgWTriforcePiece "__OTR__textures/parameter_static/gWTriforcePiece" static const ALIGN_ASSET(2) char gWTriforcePieceTex[] = dgWTriforcePiece; + #define dgFileSelMQButtonTex "__OTR__textures/title_static/gFileSelMQButtonTex" static const ALIGN_ASSET(2) char gFileSelMQButtonTex[] = dgFileSelMQButtonTex; diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 4f345cbafa7..f015f05e3ce 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -14,6 +14,7 @@ #include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/debugger/debugSaveEditor.h" +#include "soh_assets.h" extern "C" { extern SaveContext gSaveContext; @@ -37,145 +38,146 @@ static std::vector splitTime; static std::vector splitBest; static std::vector splitPreviousBest; static std::vector splitStatus; -static std::string status = ""; +static std::string status; static ImVec4 statusColor = COLOR_WHITE; static uint32_t splitCurNum = 0; std::string splitAttempt = "Attempt #: 1"; static std::string splitNumDisp = "Attempt #: "; static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); static const char* backgroundColor; +static uint32_t itemNum; static std::string itemImager; static std::string itemNamer; static uint32_t splitCounter; static uint32_t totalPreviousBest; +char textBuffer[25]; +static ImVec4 pieceTint; using json = nlohmann::json; std::vector splitObjects = { - // ID, Item Name Image Name -{ 0, "Deku Stick", "ITEM_STICK"}, -{ 1, "Deku Nut", "ITEM_NUT"}, -{ 3, "Fairy Bow", "ITEM_BOW"}, -{ 4, "Fire Arrow", "ITEM_ARROW_FIRE"}, -{ 5, "Din's Fire", "ITEM_DINS_FIRE"}, -{ 6, "Fairy Slingshot", "ITEM_SLINGSHOT"}, -{ 7, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, -{ 8, "Ocarina of Time", "ITEM_OCARINA_TIME"}, -{ 9, "Bombchu", "ITEM_BOMBCHU"}, -{ 10, "Hookshot", "ITEM_HOOKSHOT"}, -{ 11, "Longshot", "ITEM_LONGSHOT"}, -{ 12, "Ice Arrow", "ITEM_ARROW_ICE"}, -{ 13, "Farore's Wind", "ITEM_FARORES_WIND"}, -{ 14, "Boomerang", "ITEM_BOOMERANG"}, -{ 15, "Lens of Truth", "ITEM_LENS"}, -{ 16, "Magic Bean", "ITEM_BEAN"}, -{ 17, "Megaton Hammer", "ITEM_HAMMER"}, -{ 18, "Light Arrow", "ITEM_ARROW_LIGHT"}, -{ 19, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, -{ 20, "Empty Bottle", "ITEM_BOTTLE"}, -{ 21, "Red Potion", "ITEM_POTION_RED"}, -{ 22, "Green Potion", "ITEM_POTION_GREEN"}, -{ 23, "Blue Potion", "ITEM_POTION_BLUE"}, -{ 24, "Bottled Fairy", "ITEM_FAIRY"}, -{ 25, "Fish", "ITEM_FISH"}, -{ 26, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"}, -{ 27, "Ruto's Letter", "ITEM_LETTER_RUTO"}, -{ 28, "Blue Fire", "ITEM_BLUE_FIRE"}, -{ 29, "Bug", "ITEM_BUG"}, -{ 30, "Big Poe", "ITEM_BIG_POE"}, -{ 32, "Poe", "ITEM_POE"}, -{ 33, "Weird Egg", "ITEM_WEIRD_EGG"}, -{ 34, "Chicken", "ITEM_CHICKEN"}, -{ 35, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, -{ 36, "Keaton Mask", "ITEM_MASK_KEATON"}, -{ 37, "Skull Mask", "ITEM_MASK_SKULL"}, -{ 38, "Spooky Mask", "ITEM_MASK_SPOOKY"}, -{ 39, "Bunny Hood", "ITEM_MASK_BUNNY"}, -{ 40, "Goron Mask", "ITEM_MASK_GORON"}, -{ 41, "Zora Mask", "ITEM_MASK_ZORA"}, -{ 42, "Gerudo Mask", "ITEM_MASK_GERUDO"}, -{ 43, "Mask of Truth", "ITEM_MASK_TRUTH"}, -{ 45, "Pocket Egg", "ITEM_POCKET_EGG"}, -{ 46, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, -{ 47, "Cojiro", "ITEM_COJIRO"}, -{ 48, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, -{ 49, "Odd Potion", "ITEM_ODD_POTION"}, -{ 50, "Poacher's Saw", "ITEM_SAW"}, -{ 51, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, -{ 52, "Prescription", "ITEM_PRESCRIPTION"}, -{ 53, "Eyeball Frog", "ITEM_FROG"}, -{ 54, "Eye Drops", "ITEM_EYEDROPS"}, -{ 55, "Claim Check", "ITEM_CLAIM_CHECK"}, -{ 59, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, -{ 60, "Master Sword", "ITEM_SWORD_MASTER"}, -{ 61, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, -{ 62, "Deku Shield", "ITEM_SHIELD_DEKU"}, -{ 63, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, -{ 64, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, -{ 65, "Kokiri Tunic", "ITEM_TUNIC_KOKIRI"}, -{ 66, "Goron Tunic", "ITEM_TUNIC_GORON"}, -{ 67, "Zora Tunic", "ITEM_TUNIC_ZORA"}, -{ 68, "Kokiri Boots", "ITEM_BOOTS_KOKIRI"}, -{ 69, "Iron Boots", "ITEM_BOOTS_IRON"}, -{ 70, "Hover Boots", "ITEM_BOOTS_HOVER"}, -{ 71, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, -{ 72, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, -{ 73, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, -{ 74, "Quiver (30)", "ITEM_QUIVER_30"}, -{ 75, "Big Quiver (40)", "ITEM_QUIVER_40"}, -{ 76, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, -{ 77, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, -{ 78, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, -{ 79, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, -{ 80, "Goron's Bracelet", "ITEM_BRACELET"}, -{ 81, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, -{ 82, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, -{ 83, "Silver Scale", "ITEM_SCALE_SILVER"}, -{ 84, "Golden Scale", "ITEM_SCALE_GOLDEN"}, -{ 85, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, -{ 86, "Adult's Wallet", "ITEM_WALLET_ADULT"}, -{ 87, "Giant's Wallet", "ITEM_WALLET_GIANT"}, -{ 89, "Fishing Pole", "ITEM_FISHING_POLE"}, -{ 90, "Minuet of Forest", "QUEST_SONG_MINUET"}, -{ 91, "Bolero of Fire", "QUEST_SONG_BOLERO"}, -{ 92, "Serenade of Water", "QUEST_SONG_SERENADE"}, -{ 93, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, -{ 94, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, -{ 95, "Prelude of Light", "QUEST_SONG_PRELUDE"}, -{ 96, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, -{ 97, "Epona's Song", "QUEST_SONG_EPONA"}, -{ 98, "Saria's Song", "QUEST_SONG_SARIA"}, -{ 99, "Sun's Song", "QUEST_SONG_SUN"}, -{ 100, "Song of Time", "QUEST_SONG_TIME"}, -{ 101, "Song of Storms", "QUEST_SONG_STORMS"}, -{ 102, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, -{ 103, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, -{ 104, "Water Medallion", "QUEST_MEDALLION_WATER"}, -{ 105, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, -{ 106, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, -{ 107, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, -{ 108, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, -{ 109, "Goron's Ruby", "QUEST_GORON_RUBY"}, -{ 110, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, -{ 111, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, -{ 112, "Gerudo's Card", "QUEST_GERUDO_CARD"}, -{ 123, "Magic Meter", "ITEM_MAGIC_SMALL"}, -{ 124, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, -{ 125, "Double Defense", "ITEM_HEART_CONTAINER"}, -{ 152, "Deku Stick Upgrade (20)", "ITEM_STICK"}, -{ 153, "Deku Stick Upgrade (30)", "ITEM_STICK"}, -{ 154, "Deku Nut Upgrade (30)", "ITEM_NUT"}, -{ 155, "Deku Nut Upgrade (40)", "ITEM_NUT"}, -{ 657, "Queen Gohma", "RG_TRIFORCE_PIECE"}, -{ 658, "King Dodongo", "RG_TRIFORCE_PIECE"}, -{ 659, "Barinade", "RG_TRIFORCE_PIECE"}, -{ 660, "Phantom Ganon", "RG_TRIFORCE_PIECE"}, -{ 661, "Volvagia", "RG_TRIFORCE_PIECE"}, -{ 662, "Morpha", "RG_TRIFORCE_PIECE"}, -{ 663, "Bongo Bongo", "RG_TRIFORCE_PIECE"}, -{ 664, "Twinrova", "RG_TRIFORCE_PIECE"}, -{ 665, "Ganondorf", "RG_TRIFORCE_PIECE"}, -{ 666, "Ganon", "RG_TRIFORCE_PIECE"}, + // ID, Item Name Image Name +{ ITEM_STICK, "Deku Stick", "ITEM_STICK"}, +{ ITEM_NUT, "Deku Nut", "ITEM_NUT"}, +{ ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, +{ ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, +{ ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, +{ ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, +{ ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, +{ ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME"}, +{ ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, +{ ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, +{ ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT"}, +{ ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, +{ ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, +{ ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, +{ ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, +{ ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, +{ ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, +{ ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, +{ ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, +{ ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, +{ ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED"}, +{ ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN"}, +{ ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE"}, +{ ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY"}, +{ ITEM_FISH, "Fish", "ITEM_FISH"}, +{ ITEM_MILK_BOTTLE, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"}, +{ ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO"}, +{ ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE"}, +{ ITEM_BUG, "Bug", "ITEM_BUG"}, +{ ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE"}, +{ ITEM_POE, "Poe", "ITEM_POE"}, +{ ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, +{ ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN"}, +{ ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, +{ ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON"}, +{ ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL"}, +{ ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY"}, +{ ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY"}, +{ ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON"}, +{ ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA"}, +{ ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO"}, +{ ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH"}, +{ ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, +{ ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, +{ ITEM_COJIRO, "Cojiro", "ITEM_COJIRO"}, +{ ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, +{ ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION"}, +{ ITEM_SAW, "Poacher's Saw", "ITEM_SAW"}, +{ ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, +{ ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION"}, +{ ITEM_FROG, "Eyeball Frog", "ITEM_FROG"}, +{ ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS"}, +{ ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK"}, +{ ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, +{ ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, +{ ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, +{ ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, +{ ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, +{ ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, +{ ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, +{ ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, +{ ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, +{ ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, +{ ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, +{ ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, +{ ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, +{ ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30"}, +{ ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40"}, +{ ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, +{ ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, +{ ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, +{ ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, +{ ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, +{ ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, +{ ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, +{ ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, +{ ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN"}, +{ ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, +{ ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, +{ ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT"}, +{ ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, +{ ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, +{ ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, +{ ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, +{ ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, +{ ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, +{ ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, +{ ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, +{ ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, +{ ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, +{ ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, +{ ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, +{ ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, +{ ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, +{ ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, +{ ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, +{ ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, +{ ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, +{ ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, +{ ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, +{ ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, +{ ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, +{ ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, +{ ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, +{ ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, +{ ITEM_MAGIC_LARGE, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, +{ ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, +{ ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK"}, +{ ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, +{ ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT"}, +{ ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT"}, +{ 657, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 658, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 659, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 660, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 661, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 662, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 663, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 664, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 665, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ 666, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -219,27 +221,28 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { } void DrawTimeSplitOptions() { - if (ImGui::Button("Reset List")) { - splitItem.clear(); - splitTime.clear(); - splitStatus.clear(); - splitPreviousBest.clear(); - status = "List has been reset"; - statusColor = COLOR_RED; - } + ImGui::Text("List Name"); ImGui::SameLine(0); + ImGui::PushItemWidth(165.0f); + ImGui::InputText("##List Name", textBuffer, sizeof(textBuffer)); + ImGui::PopItemWidth(); if (ImGui::Button("Save List")) { - json j; - j["splitItem"] = splitItem; - j["splitTime"] = splitTime; - j["splitPreviousBest"] = splitPreviousBest; - j["backgroundColor.r"] = colorChoice.x; - j["backgroundColor.g"] = colorChoice.y; - j["backgroundColor.b"] = colorChoice.z; - j["backgroundColor.a"] = colorChoice.w; - std::ofstream file("splitdata.json"); - file << j.dump(4); - file.close(); + std::ifstream existingFile("splitdata.json"); + json existingData; + existingFile >> existingData; + existingFile.close(); + + existingData[textBuffer]["splitItem"] = splitItem; + existingData[textBuffer]["splitTime"] = splitTime; + existingData[textBuffer]["splitPreviousBest"] = splitPreviousBest; + existingData[textBuffer]["backgroundColor.r"] = colorChoice.x; + existingData[textBuffer]["backgroundColor.g"] = colorChoice.y; + existingData[textBuffer]["backgroundColor.b"] = colorChoice.z; + existingData[textBuffer]["backgroundColor.a"] = colorChoice.w; + + std::ofstream newFile("splitdata.json"); + newFile << existingData.dump(4); + newFile.close(); status = "List has been saved to disk"; statusColor = COLOR_LIGHT_BLUE; } @@ -252,31 +255,59 @@ void DrawTimeSplitOptions() { file >> j; file.close(); } - int itemSize = j["splitItem"].size(); + if (j[textBuffer]["splitItem"].size() > 0) { + splitItem.clear(); + splitTime.clear(); + splitPreviousBest.clear(); + splitBest.clear(); + splitStatus.clear(); + + for (int i = 0; i < j[textBuffer]["splitItem"].size(); i++) { + splitItem.push_back(0); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); + splitStatus.push_back(0); + } + splitItem = j[textBuffer]["splitItem"].get>(); + splitTime = j[textBuffer]["splitTime"].get>(); + splitPreviousBest = j[textBuffer]["splitPreviousBest"].get>(); + colorChoice.x = j[textBuffer]["backgroundColor.r"]; + colorChoice.y = j[textBuffer]["backgroundColor.g"]; + colorChoice.z = j[textBuffer]["backgroundColor.b"]; + colorChoice.w = j[textBuffer]["backgroundColor.a"]; + file.close(); + status = "List has been loaded from Save Data"; + statusColor = COLOR_LIGHT_BLUE; + } else { + status = "List does not exist in Save Data"; + statusColor = COLOR_RED; + } + + } + ImGui::SameLine(); + if (ImGui::Button("Reset List")) { splitItem.clear(); splitTime.clear(); - splitPreviousBest.clear(); - splitBest.clear(); splitStatus.clear(); - - for (int i = 0; i < itemSize; i++) { - splitItem.push_back(0); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(100000); - splitStatus.push_back(0); - } - splitItem = j["splitItem"].get>(); - splitTime = j["splitTime"].get>(); - splitPreviousBest = j["splitPreviousBest"].get>(); - colorChoice.x = j["backgroundColor.r"]; - colorChoice.y = j["backgroundColor.g"]; - colorChoice.z = j["backgroundColor.b"]; - colorChoice.w = j["backgroundColor.a"]; - file.close(); - status = "List has been loaded from Save Data"; - statusColor = COLOR_LIGHT_BLUE; + splitPreviousBest.clear(); + status = "List has been reset"; + statusColor = COLOR_RED; } + UIWidgets::Spacer(0); + ImGui::Text("Background Color"); + if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + Color_RGBA8 color; + color.r = colorChoice.x; + color.g = colorChoice.y; + color.b = colorChoice.z; + color.a = colorChoice.w; + } + ImGui::SameLine(); + if (ImGui::Button("Reset")) { + colorChoice = { 0.0f, 0.0f, 0.0f, 1.0f }; + } + UIWidgets::Spacer(0); if (ImGui::Button("New Attempt")) { splitStatus.clear(); splitTime.clear(); @@ -299,37 +330,59 @@ void DrawTimeSplitOptions() { } } } - UIWidgets::Spacer(0); - ImGui::Text("Background Color"); - if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { - Color_RGBA8 color; - color.r = colorChoice.x; - color.g = colorChoice.y; - color.b = colorChoice.z; - color.a = colorChoice.w; - } - ImGui::SameLine(); - if (ImGui::Button("Reset")) { - colorChoice = { 0.0f, 0.0f, 0.0f, 1.0f }; - } ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } +void TimeSplitColorTint() { + switch (itemNum) { + case 657: + pieceTint = COLOR_LIGHT_GREEN; + break; + case 658: + pieceTint = COLOR_LIGHT_RED; + break; + case 659: + pieceTint = COLOR_LIGHT_BLUE; + break; + case 660: + pieceTint = COLOR_GREEN; + break; + case 661: + pieceTint = COLOR_RED; + break; + case 662: + pieceTint = COLOR_BLUE; + break; + case 663: + pieceTint = COLOR_PURPLE; + break; + case 664: + pieceTint = COLOR_ORANGE; + break; + case 665: + pieceTint = COLOR_GREY; + break; + case 666: + pieceTint = COLOR_YELLOW; + break; + default: + pieceTint = COLOR_WHITE; + break; + } +} + void DrawTimeSplitSplits(){ + uint32_t loopCounter = 0; + uint32_t buttonID = 0; if (ImGui::CollapsingHeader("Time Splitter")) { DrawTimeSplitOptions(); } - totalPreviousBest = 0; for (int i = 0; i < splitItem.size(); i++) { totalPreviousBest += splitPreviousBest[i]; } - - uint32_t loopCounter = 0; - uint32_t buttonID = 0; ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 27.0f); @@ -338,53 +391,71 @@ void DrawTimeSplitSplits(){ ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, 80.0f); ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, 90.0f); ImGui::TableHeadersRow(); - for (auto& str : splitItem) { ImGui::TableNextColumn(); - // Item Image for (const auto& obj : splitObjects) { if (obj.itemID == splitItem[loopCounter]) { + itemNum = obj.itemID; itemImager = obj.itemImage; itemNamer = obj.itemName; + if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { + TimeSplitColorTint(); + } } } ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1)); + ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), + ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); ImGui::PopStyleColor(); - - if (ImGui::IsItemActive()) { - ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ImGui::GetColorU32(ImGuiCol_HeaderHovered)); - static ImVec2 mousePos = ImGui::GetMousePos(); - float curPos = ImGui::GetMousePos().y; - if (ImGui::IsMouseDragging(0)) { - ImVec2 dragDelta = ImGui::GetMouseDragDelta(0); - int direction = (dragDelta.y < 0.0f) ? -1 : 1; - int nextIndex = loopCounter + direction; - if (ImGui::GetMousePos().y >= mousePos.y + 27.4f || ImGui::GetMousePos().y <= mousePos.y - 27.4f) { - ImGui::ResetMouseDragDelta(0); - mousePos = ImGui::GetMousePos(); - if (nextIndex >= 0 && nextIndex < splitItem.size()) { - uint32_t itemTemp = splitItem[loopCounter]; - uint32_t timeTemp = splitTime[loopCounter]; - uint32_t bestTemp = splitBest[loopCounter]; - uint32_t prevTemp = splitPreviousBest[loopCounter]; - uint32_t statusTemp = splitStatus[loopCounter]; - splitItem[loopCounter] = splitItem[nextIndex]; - splitTime[loopCounter] = splitTime[nextIndex]; - splitBest[loopCounter] = splitBest[nextIndex]; - splitPreviousBest[loopCounter] = splitPreviousBest[nextIndex]; - splitStatus[loopCounter] = splitStatus[nextIndex]; - splitItem[nextIndex] = itemTemp; - splitTime[nextIndex] = timeTemp; - splitBest[nextIndex] = bestTemp; - splitPreviousBest[nextIndex] - prevTemp; - splitStatus[nextIndex] = statusTemp; + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { + ImGui::SetDragDropPayload("DragMove", &buttonID, sizeof(uint32_t)); + + ImGui::Text("Move %s", itemNamer.c_str()); + ImGui::EndDragDropSource(); + } + if (ImGui::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DragMove")) { + IM_ASSERT(payload->DataSize == sizeof(uint32_t)); + int nextIndex = *(const int*)payload->Data; + uint32_t draggedItem = splitItem[nextIndex]; + uint32_t draggedTime = splitTime[nextIndex]; + uint32_t draggedBest = splitBest[nextIndex]; + uint32_t draggedPreviousBest = splitPreviousBest[nextIndex]; + uint32_t draggedStatus = splitStatus[nextIndex]; + if (loopCounter < nextIndex) { + int v = 0; + int o = nextIndex - v - 1; + for (int i = loopCounter + 1; i < nextIndex + 1; ++i) { + splitItem[nextIndex - v] = splitItem[o]; + splitTime[nextIndex - v] = splitTime[o]; + splitBest[nextIndex - v] = splitBest[o]; + splitPreviousBest[nextIndex - v] = splitPreviousBest[o]; + splitStatus[nextIndex - v] = splitStatus[o]; + v++; + o--; + } + } else { + int v = 0; + int o = nextIndex + v + 1; + for (int i = loopCounter - 1; i > nextIndex - 1; i--) { + splitItem[nextIndex + v] = splitItem[o]; + splitTime[nextIndex + v] = splitTime[o]; + splitBest[nextIndex + v] = splitBest[o]; + splitPreviousBest[nextIndex + v] = splitPreviousBest[o]; + splitStatus[nextIndex + v] = splitStatus[o]; + v++; + o++; } } + splitItem[loopCounter] = draggedItem; + splitTime[loopCounter] = draggedTime; + splitBest[loopCounter] = draggedBest; + splitPreviousBest[loopCounter] = draggedPreviousBest; + splitStatus[loopCounter] = draggedStatus; } + ImGui::EndDragDropTarget(); } - ImGui::TableNextColumn(); // Item Name ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); @@ -433,12 +504,20 @@ void DrawTimeSplitSplits(){ } ImGui::EndTable(); ImGui::PopStyleVar(1); - + UIWidgets::PaddedSeparator(); + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - + ImGui::CalcTextSize(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()).x - + ImGui::CalcTextSize(formatTimestampTimeSplit(totalPreviousBest).c_str()).x - 60); ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); ImGui::SameLine(); ImGui::Text(" / "); ImGui::SameLine(); - ImGui::Text(formatTimestampTimeSplit(totalPreviousBest).c_str()); + if (splitItem.size() > 0) { + uint32_t lastIndex = splitItem.size() - 1; + ImGui::Text(formatTimestampTimeSplit(splitTime[lastIndex]).c_str()); + } else { + ImGui::Text(formatTimestampTimeSplit(totalPreviousBest).c_str()); + } } void InitializeSplitFile() { @@ -464,7 +543,15 @@ void DrawTimeSplitManageList() { ImGui::TableNextColumn(); uint32_t buttonID = 0; for (const auto& obj : splitObjects) { - if (ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1))) { + if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { + itemNum = obj.itemID; + TimeSplitColorTint(); + } else { + pieceTint = { 1, 1, 1, 1 }; + } + if (ImGui::ImageButton(std::to_string(buttonID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { splitItem.push_back(obj.itemID); splitTime.push_back(0); splitPreviousBest.push_back(0); @@ -497,7 +584,6 @@ void TimeSplitWindow::DrawElement() { } ImGui::BeginTabBar("Split Tabs"); if (ImGui::BeginTabItem("Splits")) { - status = ""; DrawTimeSplitSplits(); ImGui::EndTabItem(); } @@ -515,6 +601,9 @@ void TimeSplitWindow::DrawElement() { } void TimeSplitWindow::InitElement() { + LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); + //LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DPAD_MINUS", gDPadMinusTex, ImVec4(1, 1, 1, 1)); + LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DPAD_PLUS", gDPadTex, ImVec4(1, 1, 1, 1)); GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { TimeSplitSplitsHandler(itemEntry); }); From eebc78d39924c58c65407b626c70bde2f78bc4d5 Mon Sep 17 00:00:00 2001 From: Caladius Date: Sat, 2 Mar 2024 18:01:14 -0500 Subject: [PATCH 12/40] Updated Boss Kills to Enums instead of numbers, fixed some Tinting weirdness --- .../Enhancements/timesplits/TimeSplits.cpp | 22 ++++++++++--------- soh/soh/Enhancements/timesplits/TimeSplits.h | 16 +++++++++++++- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 2 +- .../overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 2 +- .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 2 +- .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 2 +- .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 2 +- .../actors/ovl_Boss_Goma/z_boss_goma.c | 2 +- .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 2 +- .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 2 +- .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 2 +- .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 2 +- 12 files changed, 37 insertions(+), 21 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index f015f05e3ce..cdd4ad21e42 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -168,16 +168,16 @@ std::vector splitObjects = { { ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, { ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT"}, { ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT"}, -{ 657, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 658, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 659, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 660, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 661, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 662, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 663, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 664, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 665, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ 666, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +{ BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -401,6 +401,8 @@ void DrawTimeSplitSplits(){ itemNamer = obj.itemName; if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { TimeSplitColorTint(); + } else { + pieceTint = { 1, 1, 1, 1 }; } } } diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index ca8571173d8..b9b2929a817 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -33,4 +33,18 @@ typedef struct { uint32_t itemID; const char* itemName; const char* itemImage; -} TimeSplitObject; \ No newline at end of file +} TimeSplitObject; + +typedef enum { + START_VALUE = 656, + BOSS_QUEEN_GOHMA, + BOSS_KING_DODONGO, + BOSS_BARINADE, + BOSS_PHANTOM_GANON, + BOSS_VOLVAGIA, + BOSS_MORPHA, + BOSS_TWINROVA, + BOSS_BONGO_BONGO, + BOSS_GANONDORF, + BOSS_GANON +}; \ No newline at end of file diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index ee0204c7ad2..ab85ba78bc1 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -1549,7 +1549,7 @@ void BossDodongo_DeathCutscene(BossDodongo* this, PlayState* play) { this->cameraAt.y = camera->at.y; this->cameraAt.z = camera->at.z; gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(658); + TimeSplitSplitsHandlerS(BOSS_KING_DODONGO); BossRush_HandleCompleteBoss(play); break; case 5: diff --git a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c index 060e8f79a0f..d56c85afa3c 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c @@ -902,7 +902,7 @@ void BossFd2_CollisionCheck(BossFd2* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_VALVAISA_DEAD); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(661); + TimeSplitSplitsHandlerS(BOSS_VOLVAGIA); BossRush_HandleCompleteBoss(play); } else if (damage) { BossFd2_SetupDamaged(this, play); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index 91b22a13657..8733c6a7c35 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -2814,7 +2814,7 @@ void BossGanon_UpdateDamage(BossGanon* this, PlayState* play) { Audio_QueueSeqCmd(0x100100FF); this->screenFlashTimer = 4; gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(665); + TimeSplitSplitsHandlerS(BOSS_GANONDORF); BossRush_HandleCompleteBoss(play); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_DAMAGE2); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index ec58508dfda..4ae262f75d5 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -1692,7 +1692,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; BossRush_HandleCompleteBoss(play); gSaveContext.sohStats.gameComplete = true; - TimeSplitSplitsHandlerS(666); + TimeSplitSplitsHandlerS(BOSS_GANON); this->unk_39E = Play_CreateSubCamera(play); Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT); Play_ChangeCameraStatus(play, this->unk_39E, CAM_STAT_ACTIVE); diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index de415ede73b..5e1619edba3 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -1251,7 +1251,7 @@ void BossGanondrof_CollisionCheck(BossGanondrof* this, PlayState* play) { BossGanondrof_SetupDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(660); + TimeSplitSplitsHandlerS(BOSS_PHANTOM_GANON); BossRush_HandleCompleteBoss(play); return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index 44f087356ad..ce2bb3db413 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -1844,7 +1844,7 @@ void BossGoma_UpdateHit(BossGoma* this, PlayState* play) { BossGoma_SetupDefeated(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(657); + TimeSplitSplitsHandlerS(BOSS_QUEEN_GOHMA); BossRush_HandleCompleteBoss(play); } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index 3440d67406d..c9bbf23b8e1 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -1795,7 +1795,7 @@ void BossMo_CoreCollisionCheck(BossMo* this, PlayState* play) { ((sMorphaTent1->csCamera == 0) && (sMorphaTent2 != NULL) && (sMorphaTent2->csCamera == 0))) { Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(662); + TimeSplitSplitsHandlerS(BOSS_MORPHA); BossRush_HandleCompleteBoss(play); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); this->csState = MO_DEATH_START; diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index 20bc44c2ff0..69e3c740563 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -2566,7 +2566,7 @@ void BossSst_HeadCollisionCheck(BossSst* this, PlayState* play) { Enemy_StartFinishingBlow(play, &this->actor); BossSst_HeadSetupDeath(this, play); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(663); + TimeSplitSplitsHandlerS(BOSS_BONGO_BONGO); BossRush_HandleCompleteBoss(play); } else { BossSst_HeadSetupDamage(this); diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index 0f1df2cfa56..90194f2e36c 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -5291,7 +5291,7 @@ void BossTw_TwinrovaDamage(BossTw* this, PlayState* play, u8 damage) { Enemy_StartFinishingBlow(play, &this->actor); Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_YOUNG_DEAD); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(664); + TimeSplitSplitsHandlerS(BOSS_TWINROVA); BossRush_HandleCompleteBoss(play); return; } diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index 8f4be5276cf..8a6fcd88637 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -1400,7 +1400,7 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) { BossVa_SetupBodyDeath(this, play); Enemy_StartFinishingBlow(play, &this->actor); gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME; - TimeSplitSplitsHandlerS(659); + TimeSplitSplitsHandlerS(BOSS_BARINADE); BossRush_HandleCompleteBoss(play); return; } From 1de7f0dc1720d52f5f41bd380d4fb9cd991214e8 Mon Sep 17 00:00:00 2001 From: Caladius Date: Sun, 3 Mar 2024 14:02:27 -0500 Subject: [PATCH 13/40] Last Split in the list becomes gameComplete status. --- .../Enhancements/timesplits/TimeSplits.cpp | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index cdd4ad21e42..dc41cacbdd2 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -195,6 +195,9 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { if (itemID == splitItem[loopCounter]) { splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; splitStatus[loopCounter] = 1; + if (loopCounter < (splitItem.size() - 1)) { + splitStatus[loopCounter + 1] = 2; + } if (splitTime[loopCounter] < splitBest[loopCounter]) { splitBest[loopCounter] = splitTime[loopCounter]; } @@ -209,12 +212,24 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { } uint32_t loopCounter = 0; for (auto& str : splitItem) { + if (itemEntry.itemId == ITEM_NUTS_5 || itemEntry.itemId == ITEM_NUTS_10) { + itemEntry.itemId = ITEM_NUT; + } else if (itemEntry.itemId == ITEM_STICKS_5 || itemEntry.itemId == ITEM_STICKS_10) { + itemEntry.itemId == ITEM_STICK; + } if (itemEntry.itemId == splitItem[loopCounter]) { splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; splitStatus[loopCounter] = 1; + if (loopCounter < (splitItem.size() - 1)) { + splitStatus[loopCounter + 1] = 2; + } if (splitTime[loopCounter] < splitBest[loopCounter]) { splitBest[loopCounter] = splitTime[loopCounter]; } + if (loopCounter == (splitItem.size() - 1)) { + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; + } } loopCounter++; } @@ -267,7 +282,12 @@ void DrawTimeSplitOptions() { splitTime.push_back(0); splitPreviousBest.push_back(0); splitBest.push_back(100000); - splitStatus.push_back(0); + // set the first entry in the splits to active (2) + if (i == 0) { + splitStatus.push_back(2); + } else { + splitStatus.push_back(0); + } } splitItem = j[textBuffer]["splitItem"].get>(); splitTime = j[textBuffer]["splitTime"].get>(); @@ -312,7 +332,12 @@ void DrawTimeSplitOptions() { splitStatus.clear(); splitTime.clear(); for (int i = 0; i < splitItem.size(); i++) { - splitStatus.push_back(0); + // set the first entry in the splits to active (2) + if (i == 0) { + splitStatus.push_back(2); + } else { + splitStatus.push_back(0); + } splitTime.push_back(0); } splitCurNum++; @@ -406,6 +431,9 @@ void DrawTimeSplitSplits(){ } } } + if (splitStatus[buttonID] == 2) { + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); + } ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); @@ -472,7 +500,7 @@ void DrawTimeSplitSplits(){ } ImGui::TableNextColumn(); // +/- - if (splitStatus[loopCounter] == 0) { + if (splitStatus[loopCounter] != 1) { if (splitPreviousBest[loopCounter] == 0) { ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); } else { @@ -558,7 +586,12 @@ void DrawTimeSplitManageList() { splitTime.push_back(0); splitPreviousBest.push_back(0); splitBest.push_back(100000); - splitStatus.push_back(0); + // Check Active Split 0: uncollected 1: collected 2: active + if (splitItem.size() == 1) { + splitStatus.push_back(2); + } else { + splitStatus.push_back(0); + } statusColor = COLOR_GREEN; status = obj.itemName + std::string(" added to list"); } From 38b4bcad0e4d79a8cbc975348fa3d4a67d08c6ed Mon Sep 17 00:00:00 2001 From: Caladius Date: Sun, 3 Mar 2024 14:03:20 -0500 Subject: [PATCH 14/40] Clean up comments --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index dc41cacbdd2..80fec590501 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -282,7 +282,6 @@ void DrawTimeSplitOptions() { splitTime.push_back(0); splitPreviousBest.push_back(0); splitBest.push_back(100000); - // set the first entry in the splits to active (2) if (i == 0) { splitStatus.push_back(2); } else { @@ -332,7 +331,6 @@ void DrawTimeSplitOptions() { splitStatus.clear(); splitTime.clear(); for (int i = 0; i < splitItem.size(); i++) { - // set the first entry in the splits to active (2) if (i == 0) { splitStatus.push_back(2); } else { @@ -586,7 +584,6 @@ void DrawTimeSplitManageList() { splitTime.push_back(0); splitPreviousBest.push_back(0); splitBest.push_back(100000); - // Check Active Split 0: uncollected 1: collected 2: active if (splitItem.size() == 1) { splitStatus.push_back(2); } else { @@ -637,8 +634,6 @@ void TimeSplitWindow::DrawElement() { void TimeSplitWindow::InitElement() { LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); - //LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DPAD_MINUS", gDPadMinusTex, ImVec4(1, 1, 1, 1)); - LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DPAD_PLUS", gDPadTex, ImVec4(1, 1, 1, 1)); GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { TimeSplitSplitsHandler(itemEntry); }); From 10f7b0c6eba3e0efa4dff79c5b0780b0fdbffb8e Mon Sep 17 00:00:00 2001 From: Caladius Date: Sun, 3 Mar 2024 15:25:23 -0500 Subject: [PATCH 15/40] Fix Master Sword split --- .../Enhancements/timesplits/TimeSplits.cpp | 36 +++++++++++++++++++ .../actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c | 3 ++ 2 files changed, 39 insertions(+) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 80fec590501..5862568279f 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -603,6 +603,42 @@ void DrawTimeSplitManageList() { ImGui::EndTable(); } +//void DrawTimeSplitListManager() { +// uint32_t buttonID = 0; +// ImGui::BeginTable("Equipment", 4); +// ImGui::TableSetupColumn("Special"); +// ImGui::TableSetupColumn("Kokiri"); +// ImGui::TableSetupColumn("Goron"); +// ImGui::TableSetupColumn("Zora"); +// ImGui::TableNextColumn(); +// +// for (const auto& obj : splitObjects) { +// if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { +// itemNum = obj.itemID; +// TimeSplitColorTint(); +// } else { +// pieceTint = { 1, 1, 1, 1 }; +// } +// if (obj.itemID == ITEM_BULLET_BAG_30) { +// if (ImGui::ImageButton(std::to_string(buttonID).c_str(), +// LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), +// ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { +// splitItem.push_back(obj.itemID); +// splitTime.push_back(0); +// splitPreviousBest.push_back(0); +// splitBest.push_back(100000); +// if (splitItem.size() == 1) { +// splitStatus.push_back(2); +// } else { +// splitStatus.push_back(0); +// } +// statusColor = COLOR_GREEN; +// status = obj.itemName + std::string(" added to list"); +// } +// } +// } +//} + void TimeSplitWindow::DrawElement() { if (!initialized) { InitializeSplitFile(); diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c index 26a02aa96ed..445ebdb013e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c @@ -7,6 +7,8 @@ #include "z_bg_toki_swd.h" #include "objects/object_toki_objects/object_toki_objects.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED void BgTokiSwd_Init(Actor* thisx, PlayState* play); @@ -124,6 +126,7 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) { if (!LINK_IS_ADULT) { if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) { Item_Give(play, ITEM_SWORD_MASTER); + TimeSplitSplitsHandlerS(ITEM_SWORD_MASTER); } play->csCtx.segment = D_808BB2F0; } else { From 1dbacef2618036241adf58869f28494f573b4295 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 4 Mar 2024 19:26:03 -0500 Subject: [PATCH 16/40] New Item Menu! Splits will only split in order. Fixed Bottle contents not splitting when swing collecting (needs thorough testing but looked good. Dumping bottle contents no longer awards empty bottle split. --- .../Enhancements/timesplits/TimeSplits.cpp | 1043 +++++++++++++---- soh/src/code/z_parameter.c | 3 + 2 files changed, 845 insertions(+), 201 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 5862568279f..80391e66c7a 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -38,6 +38,7 @@ static std::vector splitTime; static std::vector splitBest; static std::vector splitPreviousBest; static std::vector splitStatus; +static uint32_t splitTokens; static std::string status; static ImVec4 statusColor = COLOR_WHITE; static uint32_t splitCurNum = 0; @@ -56,128 +57,211 @@ static ImVec4 pieceTint; using json = nlohmann::json; std::vector splitObjects = { - // ID, Item Name Image Name -{ ITEM_STICK, "Deku Stick", "ITEM_STICK"}, -{ ITEM_NUT, "Deku Nut", "ITEM_NUT"}, -{ ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, -{ ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, -{ ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, -{ ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, -{ ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, -{ ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME"}, -{ ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, -{ ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, -{ ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT"}, -{ ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, -{ ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, -{ ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, -{ ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, -{ ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, -{ ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, -{ ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, -{ ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, -{ ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, -{ ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED"}, -{ ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN"}, -{ ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE"}, -{ ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY"}, -{ ITEM_FISH, "Fish", "ITEM_FISH"}, -{ ITEM_MILK_BOTTLE, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"}, -{ ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO"}, -{ ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE"}, -{ ITEM_BUG, "Bug", "ITEM_BUG"}, -{ ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE"}, -{ ITEM_POE, "Poe", "ITEM_POE"}, -{ ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, -{ ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN"}, -{ ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, -{ ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON"}, -{ ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL"}, -{ ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY"}, -{ ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY"}, -{ ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON"}, -{ ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA"}, -{ ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO"}, -{ ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH"}, -{ ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, -{ ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, -{ ITEM_COJIRO, "Cojiro", "ITEM_COJIRO"}, -{ ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, -{ ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION"}, -{ ITEM_SAW, "Poacher's Saw", "ITEM_SAW"}, -{ ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, -{ ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION"}, -{ ITEM_FROG, "Eyeball Frog", "ITEM_FROG"}, -{ ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS"}, -{ ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK"}, -{ ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, -{ ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, -{ ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, -{ ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, -{ ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, -{ ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, -{ ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, -{ ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, -{ ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, -{ ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, -{ ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, -{ ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, -{ ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, -{ ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30"}, -{ ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40"}, -{ ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, -{ ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, -{ ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, -{ ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, -{ ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, -{ ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, -{ ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, -{ ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, -{ ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN"}, -{ ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, -{ ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, -{ ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT"}, -{ ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, -{ ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, -{ ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, -{ ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, -{ ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, -{ ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, -{ ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, -{ ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, -{ ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, -{ ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, -{ ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, -{ ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, -{ ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, -{ ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, -{ ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, -{ ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, -{ ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, -{ ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, -{ ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, -{ ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, -{ ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, -{ ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, -{ ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, -{ ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, -{ ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, -{ ITEM_MAGIC_LARGE, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, -{ ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, -{ ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK"}, -{ ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, -{ ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT"}, -{ ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT"}, -{ BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, -{ BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + // ID, Item Name Image Name + { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, + { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, + { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, + { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, + { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, + { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, + { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, + { ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME"}, + { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, + { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, + { ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT"}, + { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, + { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, + { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, + { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, + { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, + { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, + { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, + { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, + { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, + { ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED"}, + { ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN"}, + { ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE"}, + { ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY"}, + { ITEM_FISH, "Fish", "ITEM_FISH"}, + { ITEM_MILK_BOTTLE, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"}, + { ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO"}, + { ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE"}, + { ITEM_BUG, "Bug", "ITEM_BUG"}, + { ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE"}, + { ITEM_POE, "Poe", "ITEM_POE"}, + { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, + { ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN"}, + { ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, + { ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON"}, + { ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL"}, + { ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY"}, + { ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY"}, + { ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON"}, + { ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA"}, + { ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO"}, + { ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH"}, + { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, + { ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, + { ITEM_COJIRO, "Cojiro", "ITEM_COJIRO"}, + { ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, + { ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION"}, + { ITEM_SAW, "Poacher's Saw", "ITEM_SAW"}, + { ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, + { ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION"}, + { ITEM_FROG, "Eyeball Frog", "ITEM_FROG"}, + { ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS"}, + { ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK"}, + { ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, + { ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, + { ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, + { ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, + { ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, + { ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, + { ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, + { ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, + { ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, + { ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, + { ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, + { ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, + { ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, + { ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30"}, + { ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40"}, + { ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, + { ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, + { ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, + { ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, + { ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, + { ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, + { ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, + { ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, + { ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN"}, + { ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, + { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, + { ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT"}, + { ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, + { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, + { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, + { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, + { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, + { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, + { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, + { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, + { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, + { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, + { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, + { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, + { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, + { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, + { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, + { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, + { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, + { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, + { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, + { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, + { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, + { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, + { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, + { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, + { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, + { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, + { ITEM_MAGIC_LARGE, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, + { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, + { ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK"}, + { ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, + { ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT"}, + { ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT"}, + { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +}; + +std::vector equipmentObjects = { + { ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, + { ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, + { ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, + { ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, + { ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, + { ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, + { ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, + { ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, + { ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, + { ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, + { ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, + { ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, +}; + +std::vector questObjects = { + { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, + { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, + { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, + { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, + { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, + { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, + { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, + { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, + { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, + { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, + { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, + { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, + { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, + { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, + { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, + { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, + { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, + { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, + { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, + { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, + { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, + { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, + { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, + { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, +}; + +std::vector inventoryObjects = { + { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, + { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, + { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, + { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, + { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, + { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, + { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, + { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, + { ITEM_BOMB, "Bombs", "ITEM_BOMB"}, + { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, + { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, + { ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, + { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, + { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, + { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, + { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, + { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, + { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, + { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, + { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, + { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, + { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, + { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, + { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, +}; + +std::vector bossObjects = { + { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -193,13 +277,19 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { uint32_t loopCounter = 0; for (auto& str : splitItem) { if (itemID == splitItem[loopCounter]) { - splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; - splitStatus[loopCounter] = 1; - if (loopCounter < (splitItem.size() - 1)) { - splitStatus[loopCounter + 1] = 2; - } - if (splitTime[loopCounter] < splitBest[loopCounter]) { - splitBest[loopCounter] = splitTime[loopCounter]; + if (splitStatus[loopCounter] == 2) { + splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; + splitStatus[loopCounter] = 1; + if (loopCounter < (splitItem.size() - 1)) { + splitStatus[loopCounter + 1] = 2; + } + if (splitTime[loopCounter] < splitBest[loopCounter]) { + splitBest[loopCounter] = splitTime[loopCounter]; + } + if (loopCounter == (splitItem.size() - 1)) { + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; + } } } loopCounter++; @@ -216,19 +306,25 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { itemEntry.itemId = ITEM_NUT; } else if (itemEntry.itemId == ITEM_STICKS_5 || itemEntry.itemId == ITEM_STICKS_10) { itemEntry.itemId == ITEM_STICK; + } else if (itemEntry.itemId == ITEM_SKULL_TOKEN) { + if (gSaveContext.inventory.gsTokens != splitTokens) { + return; + } } if (itemEntry.itemId == splitItem[loopCounter]) { - splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; - splitStatus[loopCounter] = 1; - if (loopCounter < (splitItem.size() - 1)) { - splitStatus[loopCounter + 1] = 2; - } - if (splitTime[loopCounter] < splitBest[loopCounter]) { - splitBest[loopCounter] = splitTime[loopCounter]; - } - if (loopCounter == (splitItem.size() - 1)) { - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; - gSaveContext.sohStats.gameComplete = true; + if (splitStatus[loopCounter] == 2) { + splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; + splitStatus[loopCounter] = 1; + if (loopCounter < (splitItem.size() - 1)) { + splitStatus[loopCounter + 1] = 2; + } + if (splitTime[loopCounter] < splitBest[loopCounter]) { + splitBest[loopCounter] = splitTime[loopCounter]; + } + if (loopCounter == (splitItem.size() - 1)) { + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; + } } } loopCounter++; @@ -249,6 +345,7 @@ void DrawTimeSplitOptions() { existingData[textBuffer]["splitItem"] = splitItem; existingData[textBuffer]["splitTime"] = splitTime; + existingData[textBuffer]["splitTokens"] = splitTokens; existingData[textBuffer]["splitPreviousBest"] = splitPreviousBest; existingData[textBuffer]["backgroundColor.r"] = colorChoice.x; existingData[textBuffer]["backgroundColor.g"] = colorChoice.y; @@ -290,6 +387,7 @@ void DrawTimeSplitOptions() { } splitItem = j[textBuffer]["splitItem"].get>(); splitTime = j[textBuffer]["splitTime"].get>(); + splitTokens = j[textBuffer]["splitTokens"]; splitPreviousBest = j[textBuffer]["splitPreviousBest"].get>(); colorChoice.x = j[textBuffer]["backgroundColor.r"]; colorChoice.y = j[textBuffer]["backgroundColor.g"]; @@ -308,6 +406,7 @@ void DrawTimeSplitOptions() { if (ImGui::Button("Reset List")) { splitItem.clear(); splitTime.clear(); + splitTokens = 0; splitStatus.clear(); splitPreviousBest.clear(); status = "List has been reset"; @@ -488,7 +587,15 @@ void DrawTimeSplitSplits(){ // Item Name ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); ImGui::AlignTextToFramePadding(); - ImGui::Text(itemNamer.c_str()); + if (itemNum == ITEM_SKULL_TOKEN) { + std::string skullText = itemNamer.c_str(); + skullText += " ("; + skullText += std::to_string(splitTokens).c_str(); + skullText += ")"; + ImGui::Text(skullText.c_str()); + } else { + ImGui::Text(itemNamer.c_str()); + } ImGui::TableNextColumn(); // Current Time if (splitTime[loopCounter] == 0) { @@ -552,6 +659,7 @@ void InitializeSplitFile() { if (!std::filesystem::exists("splitdata.json")) { json j; j["splitItem"] = splitItem; + j["splitTokens"] = splitTokens; j["splitTime"] = splitTime; j["splitPreviousBest"] = splitPreviousBest; j["backgroundColor.r"] = colorChoice.x; @@ -566,79 +674,612 @@ void InitializeSplitFile() { static bool initialized = false; -void DrawTimeSplitManageList() { - ImGui::BeginTable("Items", 1); - ImGui::TableNextColumn(); - uint32_t buttonID = 0; +void TimeSplitAddToSplits(uint32_t itemToAdd) { + std::string itemStatus; for (const auto& obj : splitObjects) { - if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { - itemNum = obj.itemID; - TimeSplitColorTint(); - } else { - pieceTint = { 1, 1, 1, 1 }; + if (obj.itemID == itemToAdd) { + itemStatus = obj.itemName; } - if (ImGui::ImageButton(std::to_string(buttonID).c_str(), + } + splitItem.push_back(itemToAdd); + splitTime.push_back(0); + splitPreviousBest.push_back(0); + splitBest.push_back(100000); + if (splitItem.size() == 1) { + splitStatus.push_back(2); + } else { + splitStatus.push_back(0); + } + statusColor = COLOR_GREEN; + status = itemStatus + std::string(" added to list"); +} + +void DrawTimeSplitListManager() { + uint32_t equipmentID = 0; + uint32_t questID = 0; + uint32_t inventoryID = 0; + uint32_t bossID = 0; + + ImGui::BeginTable("Equipment", 3); + ImGui::TableSetupColumn("Equip1", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Equip2", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Equip3", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableNextColumn(); + for (const auto& obj : equipmentObjects) { + + if (equipmentID == 4 || equipmentID == 8) { + ImGui::TableNextColumn(); + } + if (ImGui::ImageButton(std::to_string(equipmentID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { - splitItem.push_back(obj.itemID); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(100000); - if (splitItem.size() == 1) { - splitStatus.push_back(2); + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (obj.itemID == ITEM_BRACELET) { + ImGui::OpenPopup("Strength"); + } else if (obj.itemID == ITEM_SCALE_SILVER) { + ImGui::OpenPopup("Scale"); } else { - splitStatus.push_back(0); + TimeSplitAddToSplits(obj.itemID); + } + } + equipmentID++; + } + if (ImGui::BeginPopupContextItem("Strength")) { + if (ImGui::ImageButton(std::to_string(ITEM_BRACELET).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BRACELET"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BRACELET); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_SILVER).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_SILVER"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_GAUNTLETS_SILVER); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_GOLD).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_GOLD"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_GAUNTLETS_GOLD); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Scale")) { + if (ImGui::ImageButton(std::to_string(ITEM_SCALE_SILVER).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_SILVER"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SCALE_SILVER); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_SCALE_GOLDEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_GOLDEN"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SCALE_GOLDEN); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + ImGui::EndTable(); + ImGui::SameLine(129.0f); + + ImGui::BeginTable("Quest", 6); + ImGui::TableSetupColumn("Quest1", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Quest2", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Quest3", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Quest4", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Quest5", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Quest6", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableNextColumn(); + + for (const auto& obj : questObjects) { + if (questID == 4 || questID == 8 || questID == 12 || questID == 16 || questID == 20) { + ImGui::TableNextColumn(); + } + if (ImGui::ImageButton(std::to_string(questID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (obj.itemID == ITEM_SKULL_TOKEN) { + ImGui::OpenPopup("Skull Count"); + } else { + TimeSplitAddToSplits(obj.itemID); + } + } + questID++; + } + if (ImGui::BeginPopupContextItem("Skull Count")) { + UIWidgets::PaddedEnhancementSliderInt("Skulltula Count: %d Tokens", "##splitToken", "gTimeSplit.SkullTokens", 0, 100, "", 0, true, true, false); + if (ImGui::Button("Set", ImVec2(30.0f, 20.0f))) { + splitTokens = CVarGetInteger("gTimeSplit.SkullTokens", 0); + TimeSplitAddToSplits(ITEM_SKULL_TOKEN); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + ImGui::EndTable(); + + ImGui::BeginTable("Inventory", 6); + ImGui::TableSetupColumn("Inv1", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Inv2", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Inv3", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Inv4", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Inv5", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableSetupColumn("Inv6", ImGuiTableColumnFlags_WidthFixed, 35.0f); + ImGui::TableNextColumn(); + + for (const auto& obj : inventoryObjects) { + if (inventoryID == 4 || inventoryID == 8 || inventoryID == 12 || inventoryID == 16 || inventoryID == 20) { + ImGui::TableNextColumn(); + } + if (ImGui::ImageButton(std::to_string(inventoryID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (obj.itemID == ITEM_STICK) { + //ImGui::OpenPopup("Stick"); + TimeSplitAddToSplits(obj.itemID); + } else if (obj.itemID == ITEM_SLINGSHOT) { + ImGui::OpenPopup("Slingshot"); + } else if (obj.itemID == ITEM_NUT) { + //ImGui::OpenPopup("Nut"); + TimeSplitAddToSplits(obj.itemID); + } else if (obj.itemID == ITEM_OCARINA_FAIRY) { + ImGui::OpenPopup("Ocarina"); + } else if (obj.itemID == ITEM_BOMB) { + ImGui::OpenPopup("Bomb"); + } else if (obj.itemID == ITEM_BOW) { + ImGui::OpenPopup("Bow"); + } else if (obj.itemID == ITEM_HOOKSHOT) { + ImGui::OpenPopup("Hookshot"); + } else if (obj.itemID == ITEM_BOTTLE) { + ImGui::OpenPopup("Bottles"); + } else if (obj.itemID == ITEM_WALLET_ADULT) { + ImGui::OpenPopup("Wallet"); + } else if (obj.itemID == ITEM_POCKET_EGG) { + ImGui::OpenPopup("AdultTrade"); + } else if (obj.itemID == ITEM_WEIRD_EGG) { + ImGui::OpenPopup("ChildTrade"); + } else { + TimeSplitAddToSplits(obj.itemID); } - statusColor = COLOR_GREEN; - status = obj.itemName + std::string(" added to list"); + } + inventoryID++; + } + if (ImGui::BeginPopupContextItem("Stick")) { + if (ImGui::ImageButton(std::to_string(ITEM_STICK).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_STICK); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_20).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_20"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_STICK_UPGRADE_20); + ImGui::CloseCurrentPopup(); } ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 8.0f)); + if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_30).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_30"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_STICK_UPGRADE_30); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Slingshot")) { + if (ImGui::ImageButton(std::to_string(ITEM_SLINGSHOT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SLINGSHOT"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SLINGSHOT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_40"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BULLET_BAG_40); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_50).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_50"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BULLET_BAG_50); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Nut")) { + if (ImGui::ImageButton(std::to_string(ITEM_NUT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_NUT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_30).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_30"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_NUT_UPGRADE_30); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_40"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_NUT_UPGRADE_40); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Ocarina")) { + if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_FAIRY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_FAIRY"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_OCARINA_FAIRY); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_TIME).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_TIME"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_OCARINA_TIME); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Bomb")) { + if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_20).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_20"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOMB_BAG_20); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_30).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_30"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOMB_BAG_30); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_40"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOMB_BAG_40); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Bow")) { + if (ImGui::ImageButton(std::to_string(ITEM_BOW).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOW"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOW); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_40"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_QUIVER_40); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_50).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_50"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_QUIVER_50); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Hookshot")) { + if (ImGui::ImageButton(std::to_string(ITEM_HOOKSHOT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_HOOKSHOT"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_HOOKSHOT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_LONGSHOT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LONGSHOT"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_LONGSHOT); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Bottles")) { + if (ImGui::ImageButton(std::to_string(ITEM_BOTTLE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOTTLE"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOTTLE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POTION_RED).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_RED"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POTION_RED); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POTION_GREEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_GREEN"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POTION_GREEN); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POTION_BLUE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_BLUE"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POTION_BLUE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_FAIRY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FAIRY"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_FAIRY); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_FISH).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FISH"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_FISH); + ImGui::CloseCurrentPopup(); + } + if (ImGui::ImageButton(std::to_string(ITEM_MILK_BOTTLE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MILK_BOTTLE"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MILK_BOTTLE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_LETTER_RUTO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_RUTO"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_LETTER_RUTO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BLUE_FIRE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BLUE_FIRE"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BLUE_FIRE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BUG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BUG"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BUG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BIG_POE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BIG_POE"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BIG_POE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POE"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POE); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Wallet")) { + if (ImGui::ImageButton(std::to_string(ITEM_WALLET_ADULT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_ADULT"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_WALLET_ADULT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_WALLET_GIANT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_GIANT"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_WALLET_GIANT); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("AdultTrade")) { + if (ImGui::ImageButton(std::to_string(ITEM_POCKET_EGG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_EGG"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POCKET_EGG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POCKET_CUCCO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_CUCCO"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POCKET_CUCCO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_COJIRO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_COJIRO"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_COJIRO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_ODD_MUSHROOM).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_MUSHROOM"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_ODD_MUSHROOM); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_ODD_POTION).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_POTION"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_ODD_POTION); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_SAW).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SAW"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SAW); + ImGui::CloseCurrentPopup(); + } + if (ImGui::ImageButton(std::to_string(ITEM_SWORD_BROKEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SWORD_BROKEN"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SWORD_BROKEN); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_PRESCRIPTION).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_PRESCRIPTION"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_PRESCRIPTION); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_FROG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FROG"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_FROG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_EYEDROPS).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_EYEDROPS"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_EYEDROPS); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_CLAIM_CHECK).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CLAIM_CHECK"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_CLAIM_CHECK); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("ChildTrade")) { + if (ImGui::ImageButton(std::to_string(ITEM_WEIRD_EGG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WEIRD_EGG"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_WEIRD_EGG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_CHICKEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CHICKEN"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_CHICKEN); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_LETTER_ZELDA).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_ZELDA"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_LETTER_ZELDA); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_KEATON).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_KEATON"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_KEATON); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_SKULL).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SKULL"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_SKULL); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_SPOOKY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SPOOKY"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_SPOOKY); + ImGui::CloseCurrentPopup(); + } + if (ImGui::ImageButton(std::to_string(ITEM_MASK_BUNNY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_BUNNY"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_BUNNY); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_GORON).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GORON"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_GORON); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_ZORA).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_ZORA"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_ZORA); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_GERUDO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GERUDO"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_GERUDO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_TRUTH).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_TRUTH"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_TRUTH); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + ImGui::EndTable(); + + // SPACE SAVE FOR MISC ITEMS (12 SLOTS/3 COLUMNS x4) + + ImGui::BeginTable("Bosses", 2); + ImGui::TableSetupColumn("Boss1", ImGuiTableColumnFlags_WidthFixed, 150.0f); + ImGui::TableSetupColumn("Boss2", ImGuiTableColumnFlags_WidthFixed, 150.0f); + ImGui::TableNextColumn(); + + for (const auto& obj : bossObjects) { + if (bossID == 5) { + ImGui::TableNextColumn(); + } + itemNum = obj.itemID; + TimeSplitColorTint(); + if (ImGui::ImageButton(std::to_string(bossID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { + TimeSplitAddToSplits(obj.itemID); + } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); ImGui::AlignTextToFramePadding(); ImGui::Text(obj.itemName); ImGui::PopStyleVar(1); - ImGui::TableNextColumn(); - buttonID++; + bossID++; } ImGui::EndTable(); } -//void DrawTimeSplitListManager() { -// uint32_t buttonID = 0; -// ImGui::BeginTable("Equipment", 4); -// ImGui::TableSetupColumn("Special"); -// ImGui::TableSetupColumn("Kokiri"); -// ImGui::TableSetupColumn("Goron"); -// ImGui::TableSetupColumn("Zora"); -// ImGui::TableNextColumn(); -// -// for (const auto& obj : splitObjects) { -// if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { -// itemNum = obj.itemID; -// TimeSplitColorTint(); -// } else { -// pieceTint = { 1, 1, 1, 1 }; -// } -// if (obj.itemID == ITEM_BULLET_BAG_30) { -// if (ImGui::ImageButton(std::to_string(buttonID).c_str(), -// LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), -// ImVec2(24.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { -// splitItem.push_back(obj.itemID); -// splitTime.push_back(0); -// splitPreviousBest.push_back(0); -// splitBest.push_back(100000); -// if (splitItem.size() == 1) { -// splitStatus.push_back(2); -// } else { -// splitStatus.push_back(0); -// } -// statusColor = COLOR_GREEN; -// status = obj.itemName + std::string(" added to list"); -// } -// } -// } -//} - void TimeSplitWindow::DrawElement() { if (!initialized) { InitializeSplitFile(); @@ -659,7 +1300,7 @@ void TimeSplitWindow::DrawElement() { ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); ImGui::BeginChild("Add Items"); - DrawTimeSplitManageList(); + DrawTimeSplitListManager(); ImGui::EndChild(); ImGui::EndTabItem(); } diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 1881ea0e8af..9a8a06fae68 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2919,6 +2919,9 @@ void Inventory_UpdateBottleItem(PlayState* play, u8 item, u8 button) { play->pauseCtx.cursorItem[PAUSE_ITEM] = item; gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(button)] = BTN_ENABLED; + if (item != ITEM_BOTTLE) { + TimeSplitSplitsHandlerS(item); + } } s32 Inventory_ConsumeFairy(PlayState* play) { From 34e91a4500b26f4022295c412360081f39d22003 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 4 Mar 2024 19:47:16 -0500 Subject: [PATCH 17/40] Forgot Magic like a peasant! --- .../Enhancements/timesplits/TimeSplits.cpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 80391e66c7a..396e790d668 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -236,7 +236,7 @@ std::vector inventoryObjects = { { ITEM_BOMB, "Bombs", "ITEM_BOMB"}, { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, - { ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, + { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, @@ -834,6 +834,8 @@ void DrawTimeSplitListManager() { ImGui::OpenPopup("Hookshot"); } else if (obj.itemID == ITEM_BOTTLE) { ImGui::OpenPopup("Bottles"); + } else if (obj.itemID == ITEM_MAGIC_SMALL) { + ImGui::OpenPopup("Magic"); } else if (obj.itemID == ITEM_WALLET_ADULT) { ImGui::OpenPopup("Wallet"); } else if (obj.itemID == ITEM_POCKET_EGG) { @@ -1078,6 +1080,22 @@ void DrawTimeSplitListManager() { } ImGui::EndPopup(); } + if (ImGui::BeginPopupContextItem("Magic")) { + if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_SMALL).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_SMALL"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MAGIC_SMALL); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_LARGE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_LARGE"), + ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MAGIC_LARGE); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } if (ImGui::BeginPopupContextItem("Wallet")) { if (ImGui::ImageButton(std::to_string(ITEM_WALLET_ADULT).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_ADULT"), From 2257d282a21e1f427f46cc17699d7b2cfc5fe379 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 4 Mar 2024 19:51:14 -0500 Subject: [PATCH 18/40] Fix magic numbers tint. --- .../Enhancements/timesplits/TimeSplits.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 396e790d668..6f5e755c298 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -458,34 +458,34 @@ void DrawTimeSplitOptions() { void TimeSplitColorTint() { switch (itemNum) { - case 657: + case BOSS_QUEEN_GOHMA: pieceTint = COLOR_LIGHT_GREEN; break; - case 658: + case BOSS_KING_DODONGO: pieceTint = COLOR_LIGHT_RED; break; - case 659: + case BOSS_BARINADE: pieceTint = COLOR_LIGHT_BLUE; break; - case 660: + case BOSS_PHANTOM_GANON: pieceTint = COLOR_GREEN; break; - case 661: + case BOSS_VOLVAGIA: pieceTint = COLOR_RED; break; - case 662: + case BOSS_MORPHA: pieceTint = COLOR_BLUE; break; - case 663: + case BOSS_BONGO_BONGO: pieceTint = COLOR_PURPLE; break; - case 664: + case BOSS_TWINROVA: pieceTint = COLOR_ORANGE; break; - case 665: + case BOSS_GANONDORF: pieceTint = COLOR_GREY; break; - case 666: + case BOSS_GANON: pieceTint = COLOR_YELLOW; break; default: From dd1814c7a1d5ee0cf114240c9caf5dbbbc592363 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 4 Mar 2024 20:12:00 -0500 Subject: [PATCH 19/40] fix header in z_param. --- soh/src/code/z_parameter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 9a8a06fae68..2eab8e55377 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -22,6 +22,8 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" + #define DO_ACTION_TEX_WIDTH() 48 #define DO_ACTION_TEX_HEIGHT() 16 #define DO_ACTION_TEX_SIZE() ((DO_ACTION_TEX_WIDTH() * DO_ACTION_TEX_HEIGHT()) / 2) From 5e9d9fb78f7fdd7a03532c0b89ff30c8d5097a86 Mon Sep 17 00:00:00 2001 From: Caladius Date: Tue, 5 Mar 2024 20:03:32 -0500 Subject: [PATCH 20/40] Scaling fix, Dungeon entrance splits added, collapsible headers for cleanliness. --- .../Enhancements/timesplits/TimeSplits.cpp | 1519 +++++++++-------- soh/soh/Enhancements/timesplits/TimeSplits.h | 19 + 2 files changed, 830 insertions(+), 708 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 6f5e755c298..c3a727f32f1 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -15,9 +15,11 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/debugger/debugSaveEditor.h" #include "soh_assets.h" +#include "assets/textures/parameter_static/parameter_static.h" extern "C" { extern SaveContext gSaveContext; + extern PlayState* gPlayState; } // ImVec4 Colors @@ -41,7 +43,7 @@ static std::vector splitStatus; static uint32_t splitTokens; static std::string status; static ImVec4 statusColor = COLOR_WHITE; -static uint32_t splitCurNum = 0; +static uint32_t splitCurNum = 1; std::string splitAttempt = "Attempt #: 1"; static std::string splitNumDisp = "Attempt #: "; static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); @@ -53,133 +55,150 @@ static uint32_t splitCounter; static uint32_t totalPreviousBest; char textBuffer[25]; static ImVec4 pieceTint; +static uint32_t uiScale; using json = nlohmann::json; std::vector splitObjects = { - // ID, Item Name Image Name - { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, - { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, - { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, - { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, - { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, - { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, - { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, - { ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME"}, - { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, - { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, - { ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT"}, - { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, - { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, - { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, - { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, - { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, - { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, - { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, - { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, - { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, - { ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED"}, - { ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN"}, - { ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE"}, - { ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY"}, - { ITEM_FISH, "Fish", "ITEM_FISH"}, - { ITEM_MILK_BOTTLE, "Lon Lon Milk & Bottle", "ITEM_MILK_BOTTLE"}, - { ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO"}, - { ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE"}, - { ITEM_BUG, "Bug", "ITEM_BUG"}, - { ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE"}, - { ITEM_POE, "Poe", "ITEM_POE"}, - { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, - { ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN"}, - { ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, - { ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON"}, - { ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL"}, - { ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY"}, - { ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY"}, - { ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON"}, - { ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA"}, - { ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO"}, - { ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH"}, - { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, - { ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, - { ITEM_COJIRO, "Cojiro", "ITEM_COJIRO"}, - { ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, - { ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION"}, - { ITEM_SAW, "Poacher's Saw", "ITEM_SAW"}, - { ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, - { ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION"}, - { ITEM_FROG, "Eyeball Frog", "ITEM_FROG"}, - { ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS"}, - { ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK"}, - { ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, - { ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, - { ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, - { ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, - { ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, - { ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, - { ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, - { ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, - { ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, - { ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, - { ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, - { ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, - { ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, - { ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30"}, - { ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40"}, - { ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, - { ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, - { ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, - { ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, - { ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, - { ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, - { ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, - { ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, - { ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN"}, - { ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, - { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, - { ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT"}, - { ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, - { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, - { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, - { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, - { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, - { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, - { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, - { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, - { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, - { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, - { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, - { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, - { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, - { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, - { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, - { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, - { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, - { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, - { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, - { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, - { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, - { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, - { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, - { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, - { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, - { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, - { ITEM_MAGIC_LARGE, "Double Magic Meter", "ITEM_MAGIC_LARGE"}, - { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, - { ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK"}, - { ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, - { ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT"}, - { ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT"}, - { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + // ID, Item Name Image Name + { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, + { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, + { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, + { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, + { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, + { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, + { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, + { ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME"}, + { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, + { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, + { ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT"}, + { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, + { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, + { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, + { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, + { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, + { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, + { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, + { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, + { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, + { ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED"}, + { ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN"}, + { ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE"}, + { ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY"}, + { ITEM_FISH, "Fish", "ITEM_FISH"}, + { ITEM_MILK_BOTTLE, "Milk", "ITEM_MILK_BOTTLE"}, + { ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO"}, + { ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE"}, + { ITEM_BUG, "Bug", "ITEM_BUG"}, + { ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE"}, + { ITEM_POE, "Poe", "ITEM_POE"}, + { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, + { ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN"}, + { ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, + { ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON"}, + { ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL"}, + { ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY"}, + { ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY"}, + { ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON"}, + { ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA"}, + { ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO"}, + { ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH"}, + { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, + { ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, + { ITEM_COJIRO, "Cojiro", "ITEM_COJIRO"}, + { ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, + { ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION"}, + { ITEM_SAW, "Poacher's Saw", "ITEM_SAW"}, + { ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, + { ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION"}, + { ITEM_FROG, "Eyeball Frog", "ITEM_FROG"}, + { ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS"}, + { ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK"}, + { ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, + { ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, + { ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, + { ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, + { ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, + { ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, + { ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, + { ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, + { ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, + { ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, + { ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, + { ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, + { ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, + { ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30"}, + { ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40"}, + { ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, + { ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, + { ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, + { ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, + { ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, + { ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, + { ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, + { ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, + { ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN"}, + { ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, + { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, + { ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT"}, + { ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, + { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, + { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, + { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, + { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, + { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, + { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, + { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, + { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, + { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, + { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, + { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, + { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, + { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, + { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, + { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, + { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, + { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, + { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, + { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, + { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, + { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, + { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, + { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, + { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, + { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, + { ITEM_MAGIC_LARGE, "Double Magic", "ITEM_MAGIC_LARGE"}, + { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, + { ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK"}, + { ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, + { ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT"}, + { ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT"}, + { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; std::vector equipmentObjects = { @@ -264,6 +283,25 @@ std::vector bossObjects = { { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; +std::vector sceneObjects = { + { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +}; + std::string formatTimestampTimeSplit(uint32_t value) { uint32_t sec = value / 10; uint32_t hh = sec / 3600; @@ -296,6 +334,29 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { } } +void TimeSplitSceneSplitHandler(uint32_t sceneNum) { + uint32_t loopCounter = 0; + for (auto& str : splitItem) { + if (sceneNum == splitItem[loopCounter]) { + if (splitStatus[loopCounter] == 2) { + splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; + splitStatus[loopCounter] = 1; + if (loopCounter < (splitItem.size() - 1)) { + splitStatus[loopCounter + 1] = 2; + } + if (splitTime[loopCounter] < splitBest[loopCounter]) { + splitBest[loopCounter] = splitTime[loopCounter]; + } + if (loopCounter == (splitItem.size() - 1)) { + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; + } + } + } + loopCounter++; + } +} + void TimeSplitSplitsHandler(GetItemEntry itemEntry) { if (itemEntry.modIndex != 0) { return; @@ -507,11 +568,11 @@ void DrawTimeSplitSplits(){ ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); - ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 27.0f); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (27.0f * uiScale)); ImGui::TableSetupColumn("Item Name"); - ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, 90.0f); - ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, 80.0f); - ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); + ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, (80.0f * uiScale)); + ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); ImGui::TableHeadersRow(); for (auto& str : splitItem) { ImGui::TableNextColumn(); @@ -533,7 +594,7 @@ void DrawTimeSplitSplits(){ } ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), - ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); + ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); ImGui::PopStyleColor(); if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { ImGui::SetDragDropPayload("DragMove", &buttonID, sizeof(uint32_t)); @@ -585,7 +646,7 @@ void DrawTimeSplitSplits(){ } ImGui::TableNextColumn(); // Item Name - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f * uiScale)); ImGui::AlignTextToFramePadding(); if (itemNum == ITEM_SKULL_TOKEN) { std::string skullText = itemNamer.c_str(); @@ -642,7 +703,7 @@ void DrawTimeSplitSplits(){ UIWidgets::PaddedSeparator(); ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ImGui::CalcTextSize(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()).x - - ImGui::CalcTextSize(formatTimestampTimeSplit(totalPreviousBest).c_str()).x - 60); + ImGui::CalcTextSize(formatTimestampTimeSplit(totalPreviousBest).c_str()).x - (60 * uiScale)); ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); ImGui::SameLine(); ImGui::Text(" / "); @@ -699,603 +760,640 @@ void DrawTimeSplitListManager() { uint32_t questID = 0; uint32_t inventoryID = 0; uint32_t bossID = 0; + uint32_t sceneID = 0; - ImGui::BeginTable("Equipment", 3); - ImGui::TableSetupColumn("Equip1", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Equip2", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Equip3", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableNextColumn(); - for (const auto& obj : equipmentObjects) { - - if (equipmentID == 4 || equipmentID == 8) { - ImGui::TableNextColumn(); - } - if (ImGui::ImageButton(std::to_string(equipmentID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (obj.itemID == ITEM_BRACELET) { - ImGui::OpenPopup("Strength"); - } else if (obj.itemID == ITEM_SCALE_SILVER) { - ImGui::OpenPopup("Scale"); - } else { - TimeSplitAddToSplits(obj.itemID); + if (ImGui::CollapsingHeader("Equipment & Quest Status")) { + ImGui::BeginTable("Equipment", 3); + ImGui::TableSetupColumn("Equip1", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Equip2", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Equip3", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableNextColumn(); + for (const auto& obj : equipmentObjects) { + + if (equipmentID == 4 || equipmentID == 8) { + ImGui::TableNextColumn(); } + if (ImGui::ImageButton(std::to_string(equipmentID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (obj.itemID == ITEM_BRACELET) { + ImGui::OpenPopup("Strength"); + } else if (obj.itemID == ITEM_SCALE_SILVER) { + ImGui::OpenPopup("Scale"); + } else { + TimeSplitAddToSplits(obj.itemID); + } + } + equipmentID++; + } + if (ImGui::BeginPopupContextItem("Strength")) { + if (ImGui::ImageButton(std::to_string(ITEM_BRACELET).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BRACELET"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BRACELET); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_SILVER).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_SILVER"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_GAUNTLETS_SILVER); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_GOLD).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_GOLD"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_GAUNTLETS_GOLD); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Scale")) { + if (ImGui::ImageButton(std::to_string(ITEM_SCALE_SILVER).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_SILVER"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SCALE_SILVER); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_SCALE_GOLDEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_GOLDEN"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SCALE_GOLDEN); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); } - equipmentID++; - } - if (ImGui::BeginPopupContextItem("Strength")) { - if (ImGui::ImageButton(std::to_string(ITEM_BRACELET).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BRACELET"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BRACELET); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_SILVER).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_SILVER"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_GAUNTLETS_SILVER); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_GOLD).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_GOLD"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_GAUNTLETS_GOLD); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Scale")) { - if (ImGui::ImageButton(std::to_string(ITEM_SCALE_SILVER).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_SILVER"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SCALE_SILVER); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_SCALE_GOLDEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_GOLDEN"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SCALE_GOLDEN); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - ImGui::EndTable(); - ImGui::SameLine(129.0f); + ImGui::EndTable(); + ImGui::SameLine(129.0f * uiScale); - ImGui::BeginTable("Quest", 6); - ImGui::TableSetupColumn("Quest1", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Quest2", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Quest3", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Quest4", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Quest5", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Quest6", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableNextColumn(); + ImGui::BeginTable("Quest", 6); + ImGui::TableSetupColumn("Quest1", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Quest2", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Quest3", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Quest4", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Quest5", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Quest6", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableNextColumn(); - for (const auto& obj : questObjects) { - if (questID == 4 || questID == 8 || questID == 12 || questID == 16 || questID == 20) { - ImGui::TableNextColumn(); - } - if (ImGui::ImageButton(std::to_string(questID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (obj.itemID == ITEM_SKULL_TOKEN) { - ImGui::OpenPopup("Skull Count"); - } else { - TimeSplitAddToSplits(obj.itemID); + for (const auto& obj : questObjects) { + if (questID == 4 || questID == 8 || questID == 12 || questID == 16 || questID == 20) { + ImGui::TableNextColumn(); } + if (ImGui::ImageButton(std::to_string(questID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (obj.itemID == ITEM_SKULL_TOKEN) { + ImGui::OpenPopup("Skull Count"); + } else { + TimeSplitAddToSplits(obj.itemID); + } + } + questID++; + } + if (ImGui::BeginPopupContextItem("Skull Count")) { + UIWidgets::PaddedEnhancementSliderInt("Skulltula Count: %d Tokens", "##splitToken", "gTimeSplit.SkullTokens", 0, 100, "", 0, true, true, false); + if (ImGui::Button("Set", ImVec2(30.0f, 20.0f))) { + splitTokens = CVarGetInteger("gTimeSplit.SkullTokens", 0); + TimeSplitAddToSplits(ITEM_SKULL_TOKEN); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); } - questID++; - } - if (ImGui::BeginPopupContextItem("Skull Count")) { - UIWidgets::PaddedEnhancementSliderInt("Skulltula Count: %d Tokens", "##splitToken", "gTimeSplit.SkullTokens", 0, 100, "", 0, true, true, false); - if (ImGui::Button("Set", ImVec2(30.0f, 20.0f))) { - splitTokens = CVarGetInteger("gTimeSplit.SkullTokens", 0); - TimeSplitAddToSplits(ITEM_SKULL_TOKEN); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); + ImGui::EndTable(); } - ImGui::EndTable(); - ImGui::BeginTable("Inventory", 6); - ImGui::TableSetupColumn("Inv1", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Inv2", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Inv3", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Inv4", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Inv5", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableSetupColumn("Inv6", ImGuiTableColumnFlags_WidthFixed, 35.0f); - ImGui::TableNextColumn(); + if (ImGui::CollapsingHeader("Inventory")) { + ImGui::BeginTable("Inventory", 6); + ImGui::TableSetupColumn("Inv1", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Inv2", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Inv3", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Inv4", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Inv5", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableSetupColumn("Inv6", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + ImGui::TableNextColumn(); - for (const auto& obj : inventoryObjects) { - if (inventoryID == 4 || inventoryID == 8 || inventoryID == 12 || inventoryID == 16 || inventoryID == 20) { - ImGui::TableNextColumn(); - } - if (ImGui::ImageButton(std::to_string(inventoryID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (obj.itemID == ITEM_STICK) { - //ImGui::OpenPopup("Stick"); - TimeSplitAddToSplits(obj.itemID); - } else if (obj.itemID == ITEM_SLINGSHOT) { - ImGui::OpenPopup("Slingshot"); - } else if (obj.itemID == ITEM_NUT) { - //ImGui::OpenPopup("Nut"); - TimeSplitAddToSplits(obj.itemID); - } else if (obj.itemID == ITEM_OCARINA_FAIRY) { - ImGui::OpenPopup("Ocarina"); - } else if (obj.itemID == ITEM_BOMB) { - ImGui::OpenPopup("Bomb"); - } else if (obj.itemID == ITEM_BOW) { - ImGui::OpenPopup("Bow"); - } else if (obj.itemID == ITEM_HOOKSHOT) { - ImGui::OpenPopup("Hookshot"); - } else if (obj.itemID == ITEM_BOTTLE) { - ImGui::OpenPopup("Bottles"); - } else if (obj.itemID == ITEM_MAGIC_SMALL) { - ImGui::OpenPopup("Magic"); - } else if (obj.itemID == ITEM_WALLET_ADULT) { - ImGui::OpenPopup("Wallet"); - } else if (obj.itemID == ITEM_POCKET_EGG) { - ImGui::OpenPopup("AdultTrade"); - } else if (obj.itemID == ITEM_WEIRD_EGG) { - ImGui::OpenPopup("ChildTrade"); - } else { - TimeSplitAddToSplits(obj.itemID); + for (const auto& obj : inventoryObjects) { + if (inventoryID == 4 || inventoryID == 8 || inventoryID == 12 || inventoryID == 16 || inventoryID == 20) { + ImGui::TableNextColumn(); } + if (ImGui::ImageButton(std::to_string(inventoryID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (obj.itemID == ITEM_STICK) { + //ImGui::OpenPopup("Stick"); + TimeSplitAddToSplits(obj.itemID); + } else if (obj.itemID == ITEM_SLINGSHOT) { + ImGui::OpenPopup("Slingshot"); + } else if (obj.itemID == ITEM_NUT) { + //ImGui::OpenPopup("Nut"); + TimeSplitAddToSplits(obj.itemID); + } else if (obj.itemID == ITEM_OCARINA_FAIRY) { + ImGui::OpenPopup("Ocarina"); + } else if (obj.itemID == ITEM_BOMB) { + ImGui::OpenPopup("Bomb"); + } else if (obj.itemID == ITEM_BOW) { + ImGui::OpenPopup("Bow"); + } else if (obj.itemID == ITEM_HOOKSHOT) { + ImGui::OpenPopup("Hookshot"); + } else if (obj.itemID == ITEM_BOTTLE) { + ImGui::OpenPopup("Bottles"); + } else if (obj.itemID == ITEM_MAGIC_SMALL) { + ImGui::OpenPopup("Magic"); + } else if (obj.itemID == ITEM_WALLET_ADULT) { + ImGui::OpenPopup("Wallet"); + } else if (obj.itemID == ITEM_POCKET_EGG) { + ImGui::OpenPopup("AdultTrade"); + } else if (obj.itemID == ITEM_WEIRD_EGG) { + ImGui::OpenPopup("ChildTrade"); + } else { + TimeSplitAddToSplits(obj.itemID); + } + } + inventoryID++; + } + if (ImGui::BeginPopupContextItem("Stick")) { + if (ImGui::ImageButton(std::to_string(ITEM_STICK).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_STICK); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_20).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_20"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_STICK_UPGRADE_20); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_30).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_30"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_STICK_UPGRADE_30); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Slingshot")) { + if (ImGui::ImageButton(std::to_string(ITEM_SLINGSHOT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SLINGSHOT"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SLINGSHOT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_40"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BULLET_BAG_40); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_50).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_50"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BULLET_BAG_50); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Nut")) { + if (ImGui::ImageButton(std::to_string(ITEM_NUT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_NUT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_30).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_30"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_NUT_UPGRADE_30); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_40"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_NUT_UPGRADE_40); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Ocarina")) { + if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_FAIRY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_FAIRY"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_OCARINA_FAIRY); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_TIME).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_TIME"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_OCARINA_TIME); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Bomb")) { + if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_20).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_20"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOMB_BAG_20); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_30).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_30"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOMB_BAG_30); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_40"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOMB_BAG_40); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Bow")) { + if (ImGui::ImageButton(std::to_string(ITEM_BOW).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOW"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOW); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_40).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_40"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_QUIVER_40); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_50).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_50"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_QUIVER_50); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Hookshot")) { + if (ImGui::ImageButton(std::to_string(ITEM_HOOKSHOT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_HOOKSHOT"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_HOOKSHOT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_LONGSHOT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LONGSHOT"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_LONGSHOT); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Bottles")) { + if (ImGui::ImageButton(std::to_string(ITEM_BOTTLE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOTTLE"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BOTTLE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POTION_RED).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_RED"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POTION_RED); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POTION_GREEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_GREEN"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POTION_GREEN); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POTION_BLUE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_BLUE"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POTION_BLUE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_FAIRY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FAIRY"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_FAIRY); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_FISH).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FISH"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_FISH); + ImGui::CloseCurrentPopup(); + } + if (ImGui::ImageButton(std::to_string(ITEM_MILK_BOTTLE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MILK_BOTTLE"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MILK_BOTTLE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_LETTER_RUTO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_RUTO"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_LETTER_RUTO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BLUE_FIRE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BLUE_FIRE"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BLUE_FIRE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BUG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BUG"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BUG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_BIG_POE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BIG_POE"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_BIG_POE); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POE"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POE); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Magic")) { + if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_SMALL).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_SMALL"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MAGIC_SMALL); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_LARGE).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_LARGE"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MAGIC_LARGE); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("Wallet")) { + if (ImGui::ImageButton(std::to_string(ITEM_WALLET_ADULT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_ADULT"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_WALLET_ADULT); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_WALLET_GIANT).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_GIANT"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_WALLET_GIANT); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("AdultTrade")) { + if (ImGui::ImageButton(std::to_string(ITEM_POCKET_EGG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_EGG"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POCKET_EGG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_POCKET_CUCCO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_CUCCO"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_POCKET_CUCCO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_COJIRO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_COJIRO"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_COJIRO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_ODD_MUSHROOM).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_MUSHROOM"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_ODD_MUSHROOM); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_ODD_POTION).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_POTION"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_ODD_POTION); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_SAW).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SAW"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SAW); + ImGui::CloseCurrentPopup(); + } + if (ImGui::ImageButton(std::to_string(ITEM_SWORD_BROKEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SWORD_BROKEN"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_SWORD_BROKEN); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_PRESCRIPTION).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_PRESCRIPTION"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_PRESCRIPTION); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_FROG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FROG"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_FROG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_EYEDROPS).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_EYEDROPS"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_EYEDROPS); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_CLAIM_CHECK).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CLAIM_CHECK"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_CLAIM_CHECK); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextItem("ChildTrade")) { + if (ImGui::ImageButton(std::to_string(ITEM_WEIRD_EGG).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WEIRD_EGG"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_WEIRD_EGG); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_CHICKEN).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CHICKEN"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_CHICKEN); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_LETTER_ZELDA).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_ZELDA"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_LETTER_ZELDA); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_KEATON).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_KEATON"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_KEATON); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_SKULL).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SKULL"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_SKULL); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_SPOOKY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SPOOKY"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_SPOOKY); + ImGui::CloseCurrentPopup(); + } + if (ImGui::ImageButton(std::to_string(ITEM_MASK_BUNNY).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_BUNNY"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_BUNNY); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_GORON).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GORON"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_GORON); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_ZORA).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_ZORA"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_ZORA); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_GERUDO).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GERUDO"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_GERUDO); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::ImageButton(std::to_string(ITEM_MASK_TRUTH).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_TRUTH"), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(ITEM_MASK_TRUTH); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); } - inventoryID++; - } - if (ImGui::BeginPopupContextItem("Stick")) { - if (ImGui::ImageButton(std::to_string(ITEM_STICK).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_STICK); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_20).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_20"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_STICK_UPGRADE_20); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_30).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_30"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_STICK_UPGRADE_30); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Slingshot")) { - if (ImGui::ImageButton(std::to_string(ITEM_SLINGSHOT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SLINGSHOT"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SLINGSHOT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_40"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BULLET_BAG_40); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_50).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_50"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BULLET_BAG_50); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Nut")) { - if (ImGui::ImageButton(std::to_string(ITEM_NUT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_NUT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_30).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_30"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_NUT_UPGRADE_30); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_40"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_NUT_UPGRADE_40); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Ocarina")) { - if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_FAIRY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_FAIRY"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_OCARINA_FAIRY); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_TIME).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_TIME"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_OCARINA_TIME); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Bomb")) { - if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_20).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_20"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOMB_BAG_20); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_30).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_30"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOMB_BAG_30); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_40"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOMB_BAG_40); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Bow")) { - if (ImGui::ImageButton(std::to_string(ITEM_BOW).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOW"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOW); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_40"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_QUIVER_40); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_50).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_50"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_QUIVER_50); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Hookshot")) { - if (ImGui::ImageButton(std::to_string(ITEM_HOOKSHOT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_HOOKSHOT"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_HOOKSHOT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_LONGSHOT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LONGSHOT"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_LONGSHOT); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Bottles")) { - if (ImGui::ImageButton(std::to_string(ITEM_BOTTLE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOTTLE"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOTTLE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POTION_RED).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_RED"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POTION_RED); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POTION_GREEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_GREEN"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POTION_GREEN); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POTION_BLUE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_BLUE"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POTION_BLUE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_FAIRY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FAIRY"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_FAIRY); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_FISH).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FISH"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_FISH); - ImGui::CloseCurrentPopup(); - } - if (ImGui::ImageButton(std::to_string(ITEM_MILK_BOTTLE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MILK_BOTTLE"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MILK_BOTTLE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_LETTER_RUTO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_RUTO"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_LETTER_RUTO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BLUE_FIRE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BLUE_FIRE"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BLUE_FIRE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BUG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BUG"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BUG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BIG_POE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BIG_POE"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BIG_POE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POE"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POE); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Magic")) { - if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_SMALL).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_SMALL"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MAGIC_SMALL); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_LARGE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_LARGE"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MAGIC_LARGE); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Wallet")) { - if (ImGui::ImageButton(std::to_string(ITEM_WALLET_ADULT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_ADULT"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_WALLET_ADULT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_WALLET_GIANT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_GIANT"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_WALLET_GIANT); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("AdultTrade")) { - if (ImGui::ImageButton(std::to_string(ITEM_POCKET_EGG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_EGG"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POCKET_EGG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POCKET_CUCCO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_CUCCO"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POCKET_CUCCO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_COJIRO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_COJIRO"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_COJIRO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_ODD_MUSHROOM).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_MUSHROOM"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_ODD_MUSHROOM); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_ODD_POTION).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_POTION"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_ODD_POTION); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_SAW).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SAW"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SAW); - ImGui::CloseCurrentPopup(); - } - if (ImGui::ImageButton(std::to_string(ITEM_SWORD_BROKEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SWORD_BROKEN"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SWORD_BROKEN); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_PRESCRIPTION).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_PRESCRIPTION"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_PRESCRIPTION); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_FROG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FROG"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_FROG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_EYEDROPS).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_EYEDROPS"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_EYEDROPS); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_CLAIM_CHECK).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CLAIM_CHECK"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_CLAIM_CHECK); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("ChildTrade")) { - if (ImGui::ImageButton(std::to_string(ITEM_WEIRD_EGG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WEIRD_EGG"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_WEIRD_EGG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_CHICKEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CHICKEN"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_CHICKEN); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_LETTER_ZELDA).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_ZELDA"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_LETTER_ZELDA); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_KEATON).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_KEATON"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_KEATON); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_SKULL).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SKULL"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_SKULL); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_SPOOKY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SPOOKY"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_SPOOKY); - ImGui::CloseCurrentPopup(); - } - if (ImGui::ImageButton(std::to_string(ITEM_MASK_BUNNY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_BUNNY"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_BUNNY); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_GORON).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GORON"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_GORON); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_ZORA).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_ZORA"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_ZORA); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_GERUDO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GERUDO"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_GERUDO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_TRUTH).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_TRUTH"), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_TRUTH); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); + ImGui::EndTable(); } - ImGui::EndTable(); // SPACE SAVE FOR MISC ITEMS (12 SLOTS/3 COLUMNS x4) + if (ImGui::CollapsingHeader("Bosses")) { + ImGui::BeginTable("Bosses", 2); + ImGui::TableSetupColumn("Boss1", ImGuiTableColumnFlags_WidthFixed, (150.0f * uiScale)); + ImGui::TableSetupColumn("Boss2", ImGuiTableColumnFlags_WidthFixed, (150.0f * uiScale)); + ImGui::TableNextColumn(); - ImGui::BeginTable("Bosses", 2); - ImGui::TableSetupColumn("Boss1", ImGuiTableColumnFlags_WidthFixed, 150.0f); - ImGui::TableSetupColumn("Boss2", ImGuiTableColumnFlags_WidthFixed, 150.0f); - ImGui::TableNextColumn(); + for (const auto& obj : bossObjects) { + if (bossID == 5) { + ImGui::TableNextColumn(); + } + itemNum = obj.itemID; + TimeSplitColorTint(); + if (ImGui::ImageButton(std::to_string(bossID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { + TimeSplitAddToSplits(obj.itemID); + } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(obj.itemName); + ImGui::PopStyleVar(1); + bossID++; + } + ImGui::EndTable(); + } + - for (const auto& obj : bossObjects) { - if (bossID == 5) { + if (ImGui::CollapsingHeader("Scenes")) { + if (ImGui::CollapsingHeader("Dungeon Entrances")) { + ImGui::BeginTable("Scenes", 2); + ImGui::TableSetupColumn("Scene1", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); + ImGui::TableSetupColumn("Scene2", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); ImGui::TableNextColumn(); + + for (const auto& obj : sceneObjects) { + if (sceneID == 8) { + ImGui::TableNextColumn(); + } + itemNum = obj.itemID; + //TimeSplitColorTint(); + if (ImGui::ImageButton(std::to_string(sceneID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(obj.itemID); + } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(obj.itemName); + ImGui::PopStyleVar(1); + sceneID++; + } + ImGui::EndTable(); } - itemNum = obj.itemID; - TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(bossID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { - TimeSplitAddToSplits(obj.itemID); - } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); - ImGui::AlignTextToFramePadding(); - ImGui::Text(obj.itemName); - ImGui::PopStyleVar(1); - bossID++; } - ImGui::EndTable(); + } void TimeSplitWindow::DrawElement() { @@ -1303,6 +1401,8 @@ void TimeSplitWindow::DrawElement() { InitializeSplitFile(); initialized = true; } + + uiScale = CVarGetInteger("gImGuiScale", 0); ImGui::PushStyleColor(ImGuiCol_WindowBg, colorChoice); if (!ImGui::Begin("Time Splitter Window", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { ImGui::End(); @@ -1332,4 +1432,7 @@ void TimeSplitWindow::InitElement() { GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { TimeSplitSplitsHandler(itemEntry); }); + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + TimeSplitSceneSplitHandler(gPlayState->sceneNum + 667); + }); } \ No newline at end of file diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index b9b2929a817..e223d17121a 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -47,4 +47,23 @@ typedef enum { BOSS_BONGO_BONGO, BOSS_GANONDORF, BOSS_GANON +}; + +typedef enum { + ENTER_DEKU_TREE = 667, + ENTER_DODONGOS_CAVERN, + ENTER_JABU_JABU, + ENTER_FOREST_TEMPLE, + ENTER_FIRE_TEMPLE, + ENTER_WATER_TEMPLE, + ENTER_SPIRIT_TEMPLE, + ENTER_SHADOW_TEMPLE, + ENTER_BOTTOM_OF_THE_WELL, + ENTER_ICE_CAVERN, + ENTER_GANONS_TOWER, + ENTER_GERUDO_TRAINING_GROUND, + ENTER_THIEVES_HIDEOUT, + ENTER_INSIDE_GANONS_CASTLE, + ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, + ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, }; \ No newline at end of file From 45fc800c57ca137209c078128f6a7143a57b316d Mon Sep 17 00:00:00 2001 From: Caladius Date: Thu, 7 Mar 2024 13:07:54 -0500 Subject: [PATCH 21/40] Entrance splits for unique cases. Placeholder for new gameComplete Timestamp (wip). Clean up --- soh/soh/Enhancements/gameplaystats.cpp | 30 +-- soh/soh/Enhancements/gameplaystats.h | 3 +- .../Enhancements/timesplits/TimeSplits.cpp | 201 ++++++++++-------- soh/soh/Enhancements/timesplits/TimeSplits.h | 5 +- 4 files changed, 139 insertions(+), 100 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 9a6a63c0f6f..22cddab495c 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -242,7 +242,7 @@ const char* const countMappings[] = { #define COLOR_LIGHT_BLUE ImVec4(0.00f, 0.88f, 1.00f, 1.00f) #define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f) -char itemTimestampDisplayName[TIMESTAMP_MAX][21] = { "" }; +char itemTimestampDisplayName[TIMESTAMP_MAX][23] = { "" }; ImVec4 itemTimestampDisplayColor[TIMESTAMP_MAX]; typedef struct { @@ -773,19 +773,20 @@ void SetupDisplayNames() { strcpy(itemTimestampDisplayName[ITEM_DOUBLE_DEFENSE], "Double Defense: "); // Other events - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GOHMA], "Gohma Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_KING_DODONGO], "KD Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BARINADE], "Barinade Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_PHANTOM_GANON], "PG Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_VOLVAGIA], "Volvagia Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_MORPHA], "Morpha Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BONGO_BONGO], "Bongo Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_TWINROVA], "Twinrova Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANONDORF], "Ganondorf Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANON], "Ganon Defeated: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_BOSSRUSH_FINISH], "Boss Rush Finished: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: "); - strcpy(itemTimestampDisplayName[TIMESTAMP_TRIFORCE_COMPLETED], "Triforce Completed: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GOHMA], "Gohma Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_KING_DODONGO], "KD Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BARINADE], "Barinade Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_PHANTOM_GANON], "PG Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_VOLVAGIA], "Volvagia Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_MORPHA], "Morpha Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_BONGO_BONGO], "Bongo Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_TWINROVA], "Twinrova Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANONDORF], "Ganondorf Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANON], "Ganon Defeated: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_BOSSRUSH_FINISH], "Boss Rush Finished: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_TRIFORCE_COMPLETED], "Triforce Completed: "); + strcpy(itemTimestampDisplayName[TIMESTAMP_TIMESPLIT_COMPLETED], "Time Split Completed: "); } void SetupDisplayColors() { @@ -833,6 +834,7 @@ void SetupDisplayColors() { case TIMESTAMP_DEFEAT_GANONDORF: case TIMESTAMP_DEFEAT_GANON: case TIMESTAMP_TRIFORCE_COMPLETED: + case TIMESTAMP_TIMESPLIT_COMPLETED: itemTimestampDisplayColor[i] = COLOR_YELLOW; break; case ITEM_SONG_STORMS: diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index 8772dd37f15..928efc6043b 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -36,7 +36,8 @@ typedef enum { /* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c /* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c /* 0xAA */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c - /* 0xAB */ TIMESTAMP_MAX + /* 0xAB */ TIMESTAMP_TIMESPLIT_COMPLETED, // TimeSplits.cpp + /* 0xAC */ TIMESTAMP_MAX }GameplayStatTimestamp; diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index c3a727f32f1..0374bf0c084 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -199,6 +199,8 @@ std::vector splitObjects = { { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_TRIFORCE_PIECE_WHITE"}, { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_TRIFORCE_PIECE_WHITE"}, { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; std::vector equipmentObjects = { @@ -217,70 +219,70 @@ std::vector equipmentObjects = { }; std::vector questObjects = { - { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, - { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, - { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, - { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, - { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, - { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, - { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, - { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, - { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, - { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, - { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, - { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, - { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, - { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, - { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, - { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, - { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, - { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, - { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, - { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, - { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, - { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, - { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, - { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, + { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, + { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, + { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, + { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, + { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, + { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, + { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, + { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, + { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, + { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, + { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, + { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, + { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, + { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, + { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, + { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, + { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, + { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, + { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, + { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, + { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, + { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, + { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, + { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, }; std::vector inventoryObjects = { - { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, - { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, - { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, - { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, - { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, - { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, - { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, - { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, - { ITEM_BOMB, "Bombs", "ITEM_BOMB"}, - { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, - { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, - { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, - { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, - { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, - { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, - { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, - { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, - { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, - { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, - { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, - { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, - { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, - { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, - { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, + { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, + { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, + { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, + { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, + { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, + { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, + { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, + { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, + { ITEM_BOMB, "Bombs", "ITEM_BOMB"}, + { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, + { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, + { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, + { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, + { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, + { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, + { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, + { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, + { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, + { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, + { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, + { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, + { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, + { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, + { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, }; std::vector bossObjects = { - { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; std::vector sceneObjects = { @@ -300,6 +302,8 @@ std::vector sceneObjects = { { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_TRIFORCE_PIECE_WHITE"}, { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_TRIFORCE_PIECE_WHITE"}, { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -311,6 +315,11 @@ std::string formatTimestampTimeSplit(uint32_t value) { return fmt::format("{}:{:0>2}:{:0>2}.{}", hh, mm, ss, ds); } +void TimeSplitCompleteSplits() { + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; +} + void TimeSplitSplitsHandlerS(uint32_t itemID) { uint32_t loopCounter = 0; for (auto& str : splitItem) { @@ -325,8 +334,7 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { splitBest[loopCounter] = splitTime[loopCounter]; } if (loopCounter == (splitItem.size() - 1)) { - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; - gSaveContext.sohStats.gameComplete = true; + TimeSplitCompleteSplits(); } } } @@ -334,10 +342,13 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { } } -void TimeSplitSceneSplitHandler(uint32_t sceneNum) { +void TimeSplitSceneSplitHandler(uint32_t entrance) { uint32_t loopCounter = 0; for (auto& str : splitItem) { - if (sceneNum == splitItem[loopCounter]) { + if (entrance == ESCAPE_KOKIRI_FOREST && gSaveContext.cutsceneIndex != 0xfff0) { + return; + } + if (entrance == splitItem[loopCounter]) { if (splitStatus[loopCounter] == 2) { splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; splitStatus[loopCounter] = 1; @@ -348,8 +359,7 @@ void TimeSplitSceneSplitHandler(uint32_t sceneNum) { splitBest[loopCounter] = splitTime[loopCounter]; } if (loopCounter == (splitItem.size() - 1)) { - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; - gSaveContext.sohStats.gameComplete = true; + TimeSplitCompleteSplits(); } } } @@ -383,8 +393,7 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { splitBest[loopCounter] = splitTime[loopCounter]; } if (loopCounter == (splitItem.size() - 1)) { - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; - gSaveContext.sohStats.gameComplete = true; + TimeSplitCompleteSplits(); } } } @@ -1367,28 +1376,54 @@ void DrawTimeSplitListManager() { if (ImGui::CollapsingHeader("Scenes")) { if (ImGui::CollapsingHeader("Dungeon Entrances")) { - ImGui::BeginTable("Scenes", 2); - ImGui::TableSetupColumn("Scene1", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); - ImGui::TableSetupColumn("Scene2", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); + ImGui::BeginTable("Dungeons", 2); + ImGui::TableSetupColumn("Dungeon1", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); + ImGui::TableSetupColumn("Dungeon2", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); ImGui::TableNextColumn(); for (const auto& obj : sceneObjects) { if (sceneID == 8) { ImGui::TableNextColumn(); } - itemNum = obj.itemID; - //TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(sceneID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(obj.itemID); + if (obj.itemID >= ENTER_DEKU_TREE) { + itemNum = obj.itemID; + //TimeSplitColorTint(); + if (ImGui::ImageButton(std::to_string(sceneID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(obj.itemID); + } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(obj.itemName); + ImGui::PopStyleVar(1); + sceneID++; + } + } + ImGui::EndTable(); + } + if (ImGui::CollapsingHeader("Overworld Entrances")) { + ImGui::BeginTable("Overworld", 1); + ImGui::TableSetupColumn("Overworld1", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); + ImGui::TableNextColumn(); + + for (const auto& obj : sceneObjects) { + if (obj.itemID < ENTER_DEKU_TREE) { + itemNum = obj.itemID; + //TimeSplitColorTint(); + if (ImGui::ImageButton(std::to_string(sceneID).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(obj.itemID); + } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(obj.itemName); + ImGui::PopStyleVar(1); + sceneID++; } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); - ImGui::AlignTextToFramePadding(); - ImGui::Text(obj.itemName); - ImGui::PopStyleVar(1); - sceneID++; } ImGui::EndTable(); } @@ -1432,7 +1467,7 @@ void TimeSplitWindow::InitElement() { GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { TimeSplitSplitsHandler(itemEntry); }); - GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { - TimeSplitSceneSplitHandler(gPlayState->sceneNum + 667); + GameInteractor::Instance->RegisterGameHook([]() { + TimeSplitSceneSplitHandler(gSaveContext.entranceIndex); }); } \ No newline at end of file diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index e223d17121a..88e91615607 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -36,8 +36,7 @@ typedef struct { } TimeSplitObject; typedef enum { - START_VALUE = 656, - BOSS_QUEEN_GOHMA, + BOSS_QUEEN_GOHMA = 657, BOSS_KING_DODONGO, BOSS_BARINADE, BOSS_PHANTOM_GANON, @@ -66,4 +65,6 @@ typedef enum { ENTER_INSIDE_GANONS_CASTLE, ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, + ESCAPE_KOKIRI_FOREST = 286, + ESCAPE_LOST_WOODS = 477 }; \ No newline at end of file From 318e6089a0f054c6e4b462c99eface8cf24c7efc Mon Sep 17 00:00:00 2001 From: Caladius Date: Thu, 7 Mar 2024 14:15:17 -0500 Subject: [PATCH 22/40] Fix Entrances --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 0374bf0c084..9115bbc4e6d 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -344,10 +344,13 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { void TimeSplitSceneSplitHandler(uint32_t entrance) { uint32_t loopCounter = 0; + if (entrance == ESCAPE_KOKIRI_FOREST && gSaveContext.cutsceneIndex != 0xfff0) { + return; + } + if (entrance != ESCAPE_LOST_WOODS && entrance != ESCAPE_KOKIRI_FOREST) { + entrance += 667; + } for (auto& str : splitItem) { - if (entrance == ESCAPE_KOKIRI_FOREST && gSaveContext.cutsceneIndex != 0xfff0) { - return; - } if (entrance == splitItem[loopCounter]) { if (splitStatus[loopCounter] == 2) { splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; @@ -364,7 +367,7 @@ void TimeSplitSceneSplitHandler(uint32_t entrance) { } } loopCounter++; - } + } } void TimeSplitSplitsHandler(GetItemEntry itemEntry) { From a50d79c7fb6e383eac48fe6d1637ef0f6e30a6d0 Mon Sep 17 00:00:00 2001 From: Caladius Date: Thu, 7 Mar 2024 15:29:03 -0500 Subject: [PATCH 23/40] Hopefully fixing item tints --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 9115bbc4e6d..a804382e9ca 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -594,11 +594,12 @@ void DrawTimeSplitSplits(){ itemNum = obj.itemID; itemImager = obj.itemImage; itemNamer = obj.itemName; - if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { - TimeSplitColorTint(); - } else { - pieceTint = { 1, 1, 1, 1 }; - } + //if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { + // TimeSplitColorTint(); + //} else { + // pieceTint = COLOR_WHITE; + //} + TimeSplitColorTint(); } } if (splitStatus[buttonID] == 2) { From 2b8690efbc5cec8969ce00473af9fd35b445c457 Mon Sep 17 00:00:00 2001 From: Caladius Date: Fri, 8 Mar 2024 10:00:26 -0500 Subject: [PATCH 24/40] Code clean up, adding Entrance image for Entrance Splits, Text Wrapping to allow narrower windows for streaming. --- .../gSplitEntrance.rgba32.png | Bin 0 -> 315 bytes soh/assets/soh_assets.h | 3 + .../Enhancements/timesplits/TimeSplits.cpp | 913 +++++++----------- 3 files changed, 337 insertions(+), 579 deletions(-) create mode 100644 soh/assets/custom/textures/parameter_static/gSplitEntrance.rgba32.png diff --git a/soh/assets/custom/textures/parameter_static/gSplitEntrance.rgba32.png b/soh/assets/custom/textures/parameter_static/gSplitEntrance.rgba32.png new file mode 100644 index 0000000000000000000000000000000000000000..f53685c22e59ac9e25b6ea1adc89149496946659 GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNq$1fP z$d`ekN|k}3p_zf<=YJsml7XSrfPvvv0t1893n@#G`>H6 zx;pTf#H%%Irs1dUF07PdEKXqhqJ7GexjI2u?FqyBbF06rUs&1IxRyICQ1pO~&y8A! zl2vU77&HFuc+G0Smo)jd@rEw~=ZupdN*y}!_>FIDL!-OHgIi2bcS){&SfxMxQm*s1 zUq!rct>!%_(q?~A`tO0VPy+*t0s|w50|S#l149 splitObjects = { { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE"}, + { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE"}, + { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE"}, }; std::vector equipmentObjects = { @@ -286,24 +286,24 @@ std::vector bossObjects = { }; std::vector sceneObjects = { - { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_TRIFORCE_PIECE_WHITE"}, + { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_SPLIT_ENTRANCE"}, + { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE"}, + { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE"}, + { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -410,6 +410,7 @@ void DrawTimeSplitOptions() { ImGui::PushItemWidth(165.0f); ImGui::InputText("##List Name", textBuffer, sizeof(textBuffer)); ImGui::PopItemWidth(); + ImGui::SameLine(); if (ImGui::Button("Save List")) { std::ifstream existingFile("splitdata.json"); json existingData; @@ -431,7 +432,34 @@ void DrawTimeSplitOptions() { status = "List has been saved to disk"; statusColor = COLOR_LIGHT_BLUE; } - ImGui::SameLine(0); + UIWidgets::Spacer(0); + ImGui::Text("Saved Lists"); + ImGui::SameLine(); + std::ifstream lists("splitdata.json"); + json comboList; + lists >> comboList; + std::vector keys; + for (auto& entry : comboList.items()) { + keys.push_back(entry.key()); + } + static uint32_t selectedItem = 0; + static std::string listItem = keys[0]; + ImGui::PushItemWidth(151.0f); + if (ImGui::BeginCombo("##lists", keys[selectedItem].c_str())) { + for (int i = 0; i < keys.size(); i++) { + bool isSelected = (selectedItem == i); + if (ImGui::Selectable(keys[i].c_str(), isSelected)) { + selectedItem = i; + listItem = keys[i].c_str(); + } + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); + ImGui::SameLine(); if (ImGui::Button("Load List")) { std::ifstream file("splitdata.json"); json j; @@ -440,14 +468,14 @@ void DrawTimeSplitOptions() { file >> j; file.close(); } - if (j[textBuffer]["splitItem"].size() > 0) { + if (j[listItem]["splitItem"].size() > 0) { splitItem.clear(); splitTime.clear(); splitPreviousBest.clear(); splitBest.clear(); splitStatus.clear(); - for (int i = 0; i < j[textBuffer]["splitItem"].size(); i++) { + for (int i = 0; i < j[listItem]["splitItem"].size(); i++) { splitItem.push_back(0); splitTime.push_back(0); splitPreviousBest.push_back(0); @@ -458,14 +486,14 @@ void DrawTimeSplitOptions() { splitStatus.push_back(0); } } - splitItem = j[textBuffer]["splitItem"].get>(); - splitTime = j[textBuffer]["splitTime"].get>(); - splitTokens = j[textBuffer]["splitTokens"]; - splitPreviousBest = j[textBuffer]["splitPreviousBest"].get>(); - colorChoice.x = j[textBuffer]["backgroundColor.r"]; - colorChoice.y = j[textBuffer]["backgroundColor.g"]; - colorChoice.z = j[textBuffer]["backgroundColor.b"]; - colorChoice.w = j[textBuffer]["backgroundColor.a"]; + splitItem = j[listItem]["splitItem"].get>(); + splitTime = j[listItem]["splitTime"].get>(); + splitTokens = j[listItem]["splitTokens"]; + splitPreviousBest = j[listItem]["splitPreviousBest"].get>(); + colorChoice.x = j[listItem]["backgroundColor.r"]; + colorChoice.y = j[listItem]["backgroundColor.g"]; + colorChoice.z = j[listItem]["backgroundColor.b"]; + colorChoice.w = j[listItem]["backgroundColor.a"]; file.close(); status = "List has been loaded from Save Data"; statusColor = COLOR_LIGHT_BLUE; @@ -475,16 +503,6 @@ void DrawTimeSplitOptions() { } } - ImGui::SameLine(); - if (ImGui::Button("Reset List")) { - splitItem.clear(); - splitTime.clear(); - splitTokens = 0; - splitStatus.clear(); - splitPreviousBest.clear(); - status = "List has been reset"; - statusColor = COLOR_RED; - } UIWidgets::Spacer(0); ImGui::Text("Background Color"); if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { @@ -525,6 +543,16 @@ void DrawTimeSplitOptions() { } } } + ImGui::SameLine(); + if (ImGui::Button("Reset List")) { + splitItem.clear(); + splitTime.clear(); + splitTokens = 0; + splitStatus.clear(); + splitPreviousBest.clear(); + status = "List has been reset"; + statusColor = COLOR_RED; + } ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } @@ -594,11 +622,6 @@ void DrawTimeSplitSplits(){ itemNum = obj.itemID; itemImager = obj.itemImage; itemNamer = obj.itemName; - //if (obj.itemImage == "SPECIAL_TRIFORCE_PIECE_WHITE") { - // TimeSplitColorTint(); - //} else { - // pieceTint = COLOR_WHITE; - //} TimeSplitColorTint(); } } @@ -666,9 +689,9 @@ void DrawTimeSplitSplits(){ skullText += " ("; skullText += std::to_string(splitTokens).c_str(); skullText += ")"; - ImGui::Text(skullText.c_str()); + ImGui::TextWrapped(skullText.c_str()); } else { - ImGui::Text(itemNamer.c_str()); + ImGui::TextWrapped(itemNamer.c_str()); } ImGui::TableNextColumn(); // Current Time @@ -769,72 +792,54 @@ void TimeSplitAddToSplits(uint32_t itemToAdd) { } void DrawTimeSplitListManager() { - uint32_t equipmentID = 0; - uint32_t questID = 0; - uint32_t inventoryID = 0; - uint32_t bossID = 0; - uint32_t sceneID = 0; - if (ImGui::CollapsingHeader("Equipment & Quest Status")) { ImGui::BeginTable("Equipment", 3); - ImGui::TableSetupColumn("Equip1", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Equip2", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Equip3", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + for (int i = 0; i < 3; i++) { + ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + } ImGui::TableNextColumn(); - for (const auto& obj : equipmentObjects) { - - if (equipmentID == 4 || equipmentID == 8) { + for (int i = 0; i < 12; i++) { + if (i == 4 || i == 8) { ImGui::TableNextColumn(); } - if (ImGui::ImageButton(std::to_string(equipmentID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (obj.itemID == ITEM_BRACELET) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(equipmentObjects[i].itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (equipmentObjects[i].itemID == ITEM_BRACELET) { ImGui::OpenPopup("Strength"); - } else if (obj.itemID == ITEM_SCALE_SILVER) { + } else if (equipmentObjects[i].itemID == ITEM_SCALE_SILVER) { ImGui::OpenPopup("Scale"); } else { - TimeSplitAddToSplits(obj.itemID); + TimeSplitAddToSplits(equipmentObjects[i].itemID); } } - equipmentID++; } if (ImGui::BeginPopupContextItem("Strength")) { - if (ImGui::ImageButton(std::to_string(ITEM_BRACELET).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BRACELET"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BRACELET); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_SILVER).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_SILVER"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_GAUNTLETS_SILVER); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_GAUNTLETS_GOLD).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_GAUNTLETS_GOLD"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_GAUNTLETS_GOLD); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_BRACELET; i <= ITEM_GAUNTLETS_GOLD; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Scale")) { - if (ImGui::ImageButton(std::to_string(ITEM_SCALE_SILVER).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_SILVER"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SCALE_SILVER); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_SCALE_GOLDEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SCALE_GOLDEN"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SCALE_GOLDEN); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_SCALE_SILVER; i <= ITEM_SCALE_GOLDEN; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } } ImGui::EndPopup(); } @@ -842,28 +847,22 @@ void DrawTimeSplitListManager() { ImGui::SameLine(129.0f * uiScale); ImGui::BeginTable("Quest", 6); - ImGui::TableSetupColumn("Quest1", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Quest2", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Quest3", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Quest4", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Quest5", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Quest6", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + for (int i = 0; i < 6; i++) { + ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + } ImGui::TableNextColumn(); - - for (const auto& obj : questObjects) { - if (questID == 4 || questID == 8 || questID == 12 || questID == 16 || questID == 20) { + for (int i = 0; i < 24; i++) { + if (i == 4 || i == 8 || i == 12 || i == 16 || i == 20) { ImGui::TableNextColumn(); } - if (ImGui::ImageButton(std::to_string(questID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (obj.itemID == ITEM_SKULL_TOKEN) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(questObjects[i].itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (questObjects[i].itemID == ITEM_SKULL_TOKEN) { ImGui::OpenPopup("Skull Count"); } else { - TimeSplitAddToSplits(obj.itemID); + TimeSplitAddToSplits(questObjects[i].itemID); } } - questID++; } if (ImGui::BeginPopupContextItem("Skull Count")) { UIWidgets::PaddedEnhancementSliderInt("Skulltula Count: %d Tokens", "##splitToken", "gTimeSplit.SkullTokens", 0, 100, "", 0, true, true, false); @@ -876,563 +875,318 @@ void DrawTimeSplitListManager() { } ImGui::EndTable(); } - if (ImGui::CollapsingHeader("Inventory")) { ImGui::BeginTable("Inventory", 6); - ImGui::TableSetupColumn("Inv1", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Inv2", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Inv3", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Inv4", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Inv5", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - ImGui::TableSetupColumn("Inv6", ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + for (int i = 0; i < 6; i++) { + ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); + } ImGui::TableNextColumn(); - - for (const auto& obj : inventoryObjects) { - if (inventoryID == 4 || inventoryID == 8 || inventoryID == 12 || inventoryID == 16 || inventoryID == 20) { + for (int i = 0; i < 24; i++) { + if (i == 4 || i == 8 || i == 12 || i == 16 || i == 20) { ImGui::TableNextColumn(); } - if (ImGui::ImageButton(std::to_string(inventoryID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), + LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(inventoryObjects[i].itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (obj.itemID == ITEM_STICK) { + if (inventoryObjects[i].itemID == ITEM_STICK) { //ImGui::OpenPopup("Stick"); - TimeSplitAddToSplits(obj.itemID); - } else if (obj.itemID == ITEM_SLINGSHOT) { + TimeSplitAddToSplits(inventoryObjects[i].itemID); + } else if (inventoryObjects[i].itemID == ITEM_SLINGSHOT) { ImGui::OpenPopup("Slingshot"); - } else if (obj.itemID == ITEM_NUT) { + } else if (inventoryObjects[i].itemID == ITEM_NUT) { //ImGui::OpenPopup("Nut"); - TimeSplitAddToSplits(obj.itemID); - } else if (obj.itemID == ITEM_OCARINA_FAIRY) { + TimeSplitAddToSplits(inventoryObjects[i].itemID); + } else if (inventoryObjects[i].itemID == ITEM_OCARINA_FAIRY) { ImGui::OpenPopup("Ocarina"); - } else if (obj.itemID == ITEM_BOMB) { + } else if (inventoryObjects[i].itemID == ITEM_BOMB) { ImGui::OpenPopup("Bomb"); - } else if (obj.itemID == ITEM_BOW) { + } else if (inventoryObjects[i].itemID == ITEM_BOW) { ImGui::OpenPopup("Bow"); - } else if (obj.itemID == ITEM_HOOKSHOT) { + } else if (inventoryObjects[i].itemID == ITEM_HOOKSHOT) { ImGui::OpenPopup("Hookshot"); - } else if (obj.itemID == ITEM_BOTTLE) { + } else if (inventoryObjects[i].itemID == ITEM_BOTTLE) { ImGui::OpenPopup("Bottles"); - } else if (obj.itemID == ITEM_MAGIC_SMALL) { + } else if (inventoryObjects[i].itemID == ITEM_MAGIC_SMALL) { ImGui::OpenPopup("Magic"); - } else if (obj.itemID == ITEM_WALLET_ADULT) { + } else if (inventoryObjects[i].itemID == ITEM_WALLET_ADULT) { ImGui::OpenPopup("Wallet"); - } else if (obj.itemID == ITEM_POCKET_EGG) { + } else if (inventoryObjects[i].itemID == ITEM_POCKET_EGG) { ImGui::OpenPopup("AdultTrade"); - } else if (obj.itemID == ITEM_WEIRD_EGG) { + } else if (inventoryObjects[i].itemID == ITEM_WEIRD_EGG) { ImGui::OpenPopup("ChildTrade"); } else { - TimeSplitAddToSplits(obj.itemID); + TimeSplitAddToSplits(inventoryObjects[i].itemID); } } - inventoryID++; } if (ImGui::BeginPopupContextItem("Stick")) { - if (ImGui::ImageButton(std::to_string(ITEM_STICK).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_STICK); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_20).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_20"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_STICK_UPGRADE_20); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_STICK_UPGRADE_30).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK_UPGRADE_30"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_STICK_UPGRADE_30); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_STICK; i <= ITEM_STICK_UPGRADE_30; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } + if (i == ITEM_STICK) { + i = (ITEM_STICK_UPGRADE_20 - 1); + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Slingshot")) { - if (ImGui::ImageButton(std::to_string(ITEM_SLINGSHOT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SLINGSHOT"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SLINGSHOT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_40"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BULLET_BAG_40); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BULLET_BAG_50).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BULLET_BAG_50"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BULLET_BAG_50); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_SLINGSHOT; i <= ITEM_BULLET_BAG_50; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } + if (i == ITEM_SLINGSHOT) { + i = (ITEM_BULLET_BAG_40 - 1); + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Nut")) { - if (ImGui::ImageButton(std::to_string(ITEM_NUT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_NUT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_30).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_30"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_NUT_UPGRADE_30); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_NUT_UPGRADE_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_NUT_UPGRADE_40"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_NUT_UPGRADE_40); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_NUT; i <= ITEM_NUT_UPGRADE_40; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } + if (i == ITEM_NUT) { + i = (ITEM_NUT_UPGRADE_30 - 1); + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Ocarina")) { - if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_FAIRY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_FAIRY"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_OCARINA_FAIRY); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_OCARINA_TIME).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_TIME"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_OCARINA_TIME); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_OCARINA_FAIRY; i <= ITEM_OCARINA_TIME; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Bomb")) { - if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_20).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_20"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOMB_BAG_20); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_30).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_30"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOMB_BAG_30); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BOMB_BAG_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOMB_BAG_40"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOMB_BAG_40); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_BOMB_BAG_20; i <= ITEM_BOMB_BAG_40; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Bow")) { - if (ImGui::ImageButton(std::to_string(ITEM_BOW).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOW"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOW); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_40).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_40"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_QUIVER_40); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_QUIVER_50).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_QUIVER_50"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_QUIVER_50); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_BOW; i <= ITEM_QUIVER_50; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } + if (i == ITEM_BOW) { + i = (ITEM_QUIVER_40 - 1); + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Hookshot")) { - if (ImGui::ImageButton(std::to_string(ITEM_HOOKSHOT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_HOOKSHOT"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_HOOKSHOT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_LONGSHOT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LONGSHOT"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_LONGSHOT); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_HOOKSHOT; i <= ITEM_LONGSHOT; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Bottles")) { - if (ImGui::ImageButton(std::to_string(ITEM_BOTTLE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BOTTLE"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BOTTLE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POTION_RED).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_RED"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POTION_RED); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POTION_GREEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_GREEN"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POTION_GREEN); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POTION_BLUE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POTION_BLUE"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POTION_BLUE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_FAIRY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FAIRY"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_FAIRY); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_FISH).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FISH"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_FISH); - ImGui::CloseCurrentPopup(); - } - if (ImGui::ImageButton(std::to_string(ITEM_MILK_BOTTLE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MILK_BOTTLE"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MILK_BOTTLE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_LETTER_RUTO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_RUTO"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_LETTER_RUTO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BLUE_FIRE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BLUE_FIRE"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BLUE_FIRE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BUG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BUG"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BUG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_BIG_POE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_BIG_POE"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_BIG_POE); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POE"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POE); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_BOTTLE; i <= ITEM_POE; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + if (i != ITEM_FISH) { + ImGui::SameLine(); + } + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Magic")) { - if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_SMALL).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_SMALL"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MAGIC_SMALL); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MAGIC_LARGE).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MAGIC_LARGE"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MAGIC_LARGE); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_MAGIC_SMALL; i <= ITEM_MAGIC_LARGE; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Wallet")) { - if (ImGui::ImageButton(std::to_string(ITEM_WALLET_ADULT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_ADULT"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_WALLET_ADULT); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_WALLET_GIANT).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WALLET_GIANT"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_WALLET_GIANT); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_WALLET_ADULT; i <= ITEM_WALLET_GIANT; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("AdultTrade")) { - if (ImGui::ImageButton(std::to_string(ITEM_POCKET_EGG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_EGG"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POCKET_EGG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_POCKET_CUCCO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_POCKET_CUCCO"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_POCKET_CUCCO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_COJIRO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_COJIRO"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_COJIRO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_ODD_MUSHROOM).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_MUSHROOM"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_ODD_MUSHROOM); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_ODD_POTION).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_ODD_POTION"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_ODD_POTION); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_SAW).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SAW"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SAW); - ImGui::CloseCurrentPopup(); - } - if (ImGui::ImageButton(std::to_string(ITEM_SWORD_BROKEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_SWORD_BROKEN"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_SWORD_BROKEN); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_PRESCRIPTION).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_PRESCRIPTION"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_PRESCRIPTION); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_FROG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_FROG"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_FROG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_EYEDROPS).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_EYEDROPS"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_EYEDROPS); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_CLAIM_CHECK).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CLAIM_CHECK"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_CLAIM_CHECK); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + if (i != ITEM_SAW) { + ImGui::SameLine(); + } + } + } } ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("ChildTrade")) { - if (ImGui::ImageButton(std::to_string(ITEM_WEIRD_EGG).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_WEIRD_EGG"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_WEIRD_EGG); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_CHICKEN).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_CHICKEN"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_CHICKEN); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_LETTER_ZELDA).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_LETTER_ZELDA"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_LETTER_ZELDA); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_KEATON).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_KEATON"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_KEATON); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_SKULL).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SKULL"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_SKULL); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_SPOOKY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_SPOOKY"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_SPOOKY); - ImGui::CloseCurrentPopup(); - } - if (ImGui::ImageButton(std::to_string(ITEM_MASK_BUNNY).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_BUNNY"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_BUNNY); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_GORON).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GORON"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_GORON); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_ZORA).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_ZORA"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_ZORA); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_GERUDO).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_GERUDO"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_GERUDO); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::ImageButton(std::to_string(ITEM_MASK_TRUTH).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_MASK_TRUTH"), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(ITEM_MASK_TRUTH); - ImGui::CloseCurrentPopup(); + for (int i = ITEM_WEIRD_EGG; i <= ITEM_MASK_TRUTH; i++) { + for (auto& obj : splitObjects) { + if (obj.itemID == i) { + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(i); + ImGui::CloseCurrentPopup(); + } + if (i != ITEM_MASK_SPOOKY) { + ImGui::SameLine(); + } + } + } } ImGui::EndPopup(); } ImGui::EndTable(); } - // SPACE SAVE FOR MISC ITEMS (12 SLOTS/3 COLUMNS x4) if (ImGui::CollapsingHeader("Bosses")) { ImGui::BeginTable("Bosses", 2); ImGui::TableSetupColumn("Boss1", ImGuiTableColumnFlags_WidthFixed, (150.0f * uiScale)); ImGui::TableSetupColumn("Boss2", ImGuiTableColumnFlags_WidthFixed, (150.0f * uiScale)); ImGui::TableNextColumn(); - - for (const auto& obj : bossObjects) { - if (bossID == 5) { + for (int i = 0; i < 10; i++) { + if (i == 5) { ImGui::TableNextColumn(); } - itemNum = obj.itemID; + itemNum = bossObjects[i].itemID; TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(bossID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { - TimeSplitAddToSplits(obj.itemID); + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(bossObjects[i].itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { + TimeSplitAddToSplits(bossObjects[i].itemID); } ImGui::SameLine(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); ImGui::AlignTextToFramePadding(); - ImGui::Text(obj.itemName); + ImGui::Text(bossObjects[i].itemName); ImGui::PopStyleVar(1); - bossID++; } ImGui::EndTable(); } - - if (ImGui::CollapsingHeader("Scenes")) { if (ImGui::CollapsingHeader("Dungeon Entrances")) { ImGui::BeginTable("Dungeons", 2); - ImGui::TableSetupColumn("Dungeon1", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); - ImGui::TableSetupColumn("Dungeon2", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); + ImGui::TableSetupColumn("Dungeon1", ImGuiTableColumnFlags_WidthFixed, (220.0f * uiScale)); + ImGui::TableSetupColumn("Dungeon2", ImGuiTableColumnFlags_WidthFixed, (220.0f * uiScale)); ImGui::TableNextColumn(); - - for (const auto& obj : sceneObjects) { - if (sceneID == 8) { + for (int i = 0; i < 16; i++) { + if (i == 8) { ImGui::TableNextColumn(); } - if (obj.itemID >= ENTER_DEKU_TREE) { - itemNum = obj.itemID; - //TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(sceneID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(obj.itemID); - } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); - ImGui::AlignTextToFramePadding(); - ImGui::Text(obj.itemName); - ImGui::PopStyleVar(1); - sceneID++; + //itemNum = sceneObjects[i].itemID; + //TimeSplitColorTint(); + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(sceneObjects[i].itemID); } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::TextWrapped(sceneObjects[i].itemName); + ImGui::PopStyleVar(1); } ImGui::EndTable(); } if (ImGui::CollapsingHeader("Overworld Entrances")) { ImGui::BeginTable("Overworld", 1); - ImGui::TableSetupColumn("Overworld1", ImGuiTableColumnFlags_WidthFixed, (250.0f * uiScale)); + ImGui::TableSetupColumn("Overworld1", ImGuiTableColumnFlags_WidthFixed, (220.0f * uiScale)); ImGui::TableNextColumn(); - - for (const auto& obj : sceneObjects) { - if (obj.itemID < ENTER_DEKU_TREE) { - itemNum = obj.itemID; - //TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(sceneID).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(obj.itemID); - } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); - ImGui::AlignTextToFramePadding(); - ImGui::Text(obj.itemName); - ImGui::PopStyleVar(1); - sceneID++; + for (int i = 16; i <= 17; i++) { + //itemNum = obj.itemID; + //TimeSplitColorTint(); + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + TimeSplitAddToSplits(sceneObjects[i].itemID); } + ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::TextWrapped(sceneObjects[i].itemName); + ImGui::PopStyleVar(1); } ImGui::EndTable(); } } - } void TimeSplitWindow::DrawElement() { @@ -1468,6 +1222,7 @@ void TimeSplitWindow::DrawElement() { void TimeSplitWindow::InitElement() { LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); + LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_SPLIT_ENTRANCE", gSplitEntranceTex, ImVec4(1, 1, 1, 1)); GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { TimeSplitSplitsHandler(itemEntry); }); From 82414a49bd13c5a283a9c4d8cf73171f95cd8c2e Mon Sep 17 00:00:00 2001 From: Caladius Date: Sat, 9 Mar 2024 14:07:13 -0500 Subject: [PATCH 25/40] Add Checkbox to allow removing items from list directly. --- .../Enhancements/timesplits/TimeSplits.cpp | 334 +++++++++++------- 1 file changed, 199 insertions(+), 135 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index d74f9a42dbf..36067fcbca6 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -542,6 +542,8 @@ void DrawTimeSplitOptions() { splitPreviousBest[i] = splitBest[i]; } } + status = "Splits updated"; + statusColor = COLOR_GREEN; } ImGui::SameLine(); if (ImGui::Button("Reset List")) { @@ -553,6 +555,7 @@ void DrawTimeSplitOptions() { status = "List has been reset"; statusColor = COLOR_RED; } + UIWidgets::EnhancementCheckbox("Enable Removals", "gTimeSplit.EnableEdits", false); ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } @@ -601,154 +604,215 @@ void DrawTimeSplitSplits(){ if (ImGui::CollapsingHeader("Time Splitter")) { DrawTimeSplitOptions(); } - totalPreviousBest = 0; - for (int i = 0; i < splitItem.size(); i++) { - totalPreviousBest += splitPreviousBest[i]; - } - ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); - ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); - ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (27.0f * uiScale)); - ImGui::TableSetupColumn("Item Name"); - ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); - ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, (80.0f * uiScale)); - ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); - ImGui::TableHeadersRow(); - for (auto& str : splitItem) { + //List Removals + if (CVarGetInteger("gTimeSplit.EnableEdits", 0)) { + ImGui::BeginTable("Remove Entries", 2); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (28.0f * uiScale)); + ImGui::TableSetupColumn("Item Name"); + ImGui::TableHeadersRow(); ImGui::TableNextColumn(); - // Item Image - for (const auto& obj : splitObjects) { - if (obj.itemID == splitItem[loopCounter]) { - itemNum = obj.itemID; - itemImager = obj.itemImage; - itemNamer = obj.itemName; - TimeSplitColorTint(); + for (int i = 0; i < splitItem.size(); i++) { + for (const auto& obj : splitObjects) { + if (obj.itemID == splitItem[i]) { + itemNum = obj.itemID; + itemImager = obj.itemImage; + itemNamer = obj.itemName; + TimeSplitColorTint(); + } + } + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.75f, 0.0f, 0.0f, 1.0f)); + if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), + ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { + splitItem.erase(splitItem.begin() + i); + splitTime.erase(splitTime.begin() + i); + splitPreviousBest.erase(splitPreviousBest.begin() + i); + splitBest.erase(splitBest.begin() + i); + splitStatus.erase(splitStatus.begin() + i); + } + ImGui::PopStyleColor(); + ImGui::TableNextColumn(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f * uiScale)); + ImGui::AlignTextToFramePadding(); + if (itemNum == ITEM_SKULL_TOKEN) { + std::string skullText = itemNamer.c_str(); + skullText += " ("; + skullText += std::to_string(splitTokens).c_str(); + skullText += ")"; + ImGui::TextWrapped(skullText.c_str()); + } else { + ImGui::TextWrapped(itemNamer.c_str()); } + ImGui::PopStyleVar(); + ImGui::TableNextColumn(); } - if (splitStatus[buttonID] == 2) { - ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); + ImGui::EndTable(); + } else { + totalPreviousBest = 0; + for (int i = 0; i < splitItem.size(); i++) { + totalPreviousBest += splitPreviousBest[i]; } - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), - ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); - ImGui::PopStyleColor(); - if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { - ImGui::SetDragDropPayload("DragMove", &buttonID, sizeof(uint32_t)); + ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); + ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (27.0f * uiScale)); + ImGui::TableSetupColumn("Item Name"); + ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); + ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, (80.0f * uiScale)); + ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); + ImGui::TableHeadersRow(); - ImGui::Text("Move %s", itemNamer.c_str()); - ImGui::EndDragDropSource(); - } - if (ImGui::BeginDragDropTarget()) { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DragMove")) { - IM_ASSERT(payload->DataSize == sizeof(uint32_t)); - int nextIndex = *(const int*)payload->Data; - uint32_t draggedItem = splitItem[nextIndex]; - uint32_t draggedTime = splitTime[nextIndex]; - uint32_t draggedBest = splitBest[nextIndex]; - uint32_t draggedPreviousBest = splitPreviousBest[nextIndex]; - uint32_t draggedStatus = splitStatus[nextIndex]; - if (loopCounter < nextIndex) { - int v = 0; - int o = nextIndex - v - 1; - for (int i = loopCounter + 1; i < nextIndex + 1; ++i) { - splitItem[nextIndex - v] = splitItem[o]; - splitTime[nextIndex - v] = splitTime[o]; - splitBest[nextIndex - v] = splitBest[o]; - splitPreviousBest[nextIndex - v] = splitPreviousBest[o]; - splitStatus[nextIndex - v] = splitStatus[o]; - v++; - o--; - } - } else { - int v = 0; - int o = nextIndex + v + 1; - for (int i = loopCounter - 1; i > nextIndex - 1; i--) { - splitItem[nextIndex + v] = splitItem[o]; - splitTime[nextIndex + v] = splitTime[o]; - splitBest[nextIndex + v] = splitBest[o]; - splitPreviousBest[nextIndex + v] = splitPreviousBest[o]; - splitStatus[nextIndex + v] = splitStatus[o]; - v++; - o++; - } + for (auto& str : splitItem) { + ImGui::TableNextColumn(); + for (const auto& obj : splitObjects) { + if (obj.itemID == splitItem[loopCounter]) { + itemNum = obj.itemID; + itemImager = obj.itemImage; + itemNamer = obj.itemName; + TimeSplitColorTint(); } - splitItem[loopCounter] = draggedItem; - splitTime[loopCounter] = draggedTime; - splitBest[loopCounter] = draggedBest; - splitPreviousBest[loopCounter] = draggedPreviousBest; - splitStatus[loopCounter] = draggedStatus; } - ImGui::EndDragDropTarget(); - } - ImGui::TableNextColumn(); - // Item Name - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f * uiScale)); - ImGui::AlignTextToFramePadding(); - if (itemNum == ITEM_SKULL_TOKEN) { - std::string skullText = itemNamer.c_str(); - skullText += " ("; - skullText += std::to_string(splitTokens).c_str(); - skullText += ")"; - ImGui::TextWrapped(skullText.c_str()); - } else { - ImGui::TextWrapped(itemNamer.c_str()); - } - ImGui::TableNextColumn(); - // Current Time - if (splitTime[loopCounter] == 0) { - ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else { - ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); - } - ImGui::TableNextColumn(); - // +/- - if (splitStatus[loopCounter] != 1) { - if (splitPreviousBest[loopCounter] == 0) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else { - if (GAMEPLAYSTAT_TOTAL_TIME < splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_LIGHT_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else if (GAMEPLAYSTAT_TOTAL_TIME == splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); - } else if (GAMEPLAYSTAT_TOTAL_TIME > splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_LIGHT_RED, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME - splitPreviousBest[loopCounter]).c_str()); + // Item Image + if (splitStatus[buttonID] == 2) { + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); + } + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); + ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), + ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); + ImGui::PopStyleColor(); + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { + ImGui::SetDragDropPayload("DragMove", &buttonID, sizeof(uint32_t)); + + ImGui::Text("Move %s", itemNamer.c_str()); + ImGui::EndDragDropSource(); + } + if (ImGui::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DragMove")) { + IM_ASSERT(payload->DataSize == sizeof(uint32_t)); + int nextIndex = *(const int*)payload->Data; + uint32_t draggedItem = splitItem[nextIndex]; + uint32_t draggedTime = splitTime[nextIndex]; + uint32_t draggedBest = splitBest[nextIndex]; + uint32_t draggedPreviousBest = splitPreviousBest[nextIndex]; + uint32_t draggedStatus = splitStatus[nextIndex]; + if (loopCounter < nextIndex) { + int v = 0; + int o = nextIndex - v - 1; + for (int i = loopCounter + 1; i < nextIndex + 1; ++i) { + splitItem[nextIndex - v] = splitItem[o]; + splitTime[nextIndex - v] = splitTime[o]; + splitBest[nextIndex - v] = splitBest[o]; + splitPreviousBest[nextIndex - v] = splitPreviousBest[o]; + splitStatus[nextIndex - v] = splitStatus[o]; + v++; + o--; + } + } else { + int v = 0; + int o = nextIndex + v + 1; + for (int i = loopCounter - 1; i > nextIndex - 1; i--) { + splitItem[nextIndex + v] = splitItem[o]; + splitTime[nextIndex + v] = splitTime[o]; + splitBest[nextIndex + v] = splitBest[o]; + splitPreviousBest[nextIndex + v] = splitPreviousBest[o]; + splitStatus[nextIndex + v] = splitStatus[o]; + v++; + o++; + } + } + splitItem[loopCounter] = draggedItem; + splitTime[loopCounter] = draggedTime; + splitBest[loopCounter] = draggedBest; + splitPreviousBest[loopCounter] = draggedPreviousBest; + splitStatus[loopCounter] = draggedStatus; } + ImGui::EndDragDropTarget(); } - } else { - if (splitPreviousBest[loopCounter] == 0) { - ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); + ImGui::TableNextColumn(); + // Item Name + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f * uiScale)); + ImGui::AlignTextToFramePadding(); + if (itemNum == ITEM_SKULL_TOKEN) { + std::string skullText = itemNamer.c_str(); + skullText += " ("; + skullText += std::to_string(splitTokens).c_str(); + skullText += ")"; + ImGui::TextWrapped(skullText.c_str()); } else { - if (splitTime[loopCounter] < splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - splitTime[loopCounter]).c_str()); - } else if (splitTime[loopCounter] == splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); - } else if (splitTime[loopCounter] > splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_RED, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + ImGui::TextWrapped(itemNamer.c_str()); + } + ImGui::TableNextColumn(); + if (splitStatus[loopCounter] == 2) { + // Current Time (Active) + if (splitTime[loopCounter] == 0) { + ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else { + ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); + } + ImGui::TableNextColumn(); + // +/- (active) + if (splitPreviousBest[loopCounter] == 0) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else { + if (GAMEPLAYSTAT_TOTAL_TIME < splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_LIGHT_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - GAMEPLAYSTAT_TOTAL_TIME).c_str()); + } else if (GAMEPLAYSTAT_TOTAL_TIME == splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + } else if (GAMEPLAYSTAT_TOTAL_TIME > splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_LIGHT_RED, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME - splitPreviousBest[loopCounter]).c_str()); + } + } + ImGui::TableNextColumn(); + // Previous Best (Active) + ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + } else if (splitStatus[loopCounter] == 1) { + // Current (Collected) + ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); + ImGui::TableNextColumn(); + // +/- (Collected) + if (splitPreviousBest[loopCounter] == 0) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); + } else { + if (splitTime[loopCounter] < splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - splitTime[loopCounter]).c_str()); + } else if (splitTime[loopCounter] == splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + } else if (splitTime[loopCounter] > splitPreviousBest[loopCounter]) { + ImGui::TextColored(COLOR_RED, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + } } + ImGui::TableNextColumn(); + // Previous Best (Collected) + ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + } else { + // Current Time (Inactive) + ImGui::Text("-:--:--.-"); + ImGui::TableNextColumn(); + // +/- (Inactive) + ImGui::Text("-:--:--.-"); + ImGui::TableNextColumn(); + // Previous Best (Inactive) + ImGui::Text("-:--:--.-"); } + ImGui::PopStyleVar(); + loopCounter++; + buttonID++; } - ImGui::TableNextColumn(); - // Previous Best - ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); + ImGui::EndTable(); ImGui::PopStyleVar(); - loopCounter++; - buttonID++; - } - ImGui::EndTable(); - ImGui::PopStyleVar(1); - UIWidgets::PaddedSeparator(); - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - - ImGui::CalcTextSize(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()).x - - ImGui::CalcTextSize(formatTimestampTimeSplit(totalPreviousBest).c_str()).x - (60 * uiScale)); - ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - ImGui::SameLine(); - ImGui::Text(" / "); - ImGui::SameLine(); - if (splitItem.size() > 0) { - uint32_t lastIndex = splitItem.size() - 1; - ImGui::Text(formatTimestampTimeSplit(splitTime[lastIndex]).c_str()); - } else { - ImGui::Text(formatTimestampTimeSplit(totalPreviousBest).c_str()); + UIWidgets::PaddedSeparator(); + ImGui::SetCursorPosX(ImGui::GetWindowWidth() - + ImGui::CalcTextSize(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()).x - + ImGui::CalcTextSize(formatTimestampTimeSplit(totalPreviousBest).c_str()).x - (60 * uiScale)); + ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); + ImGui::SameLine(); + ImGui::Text(" / "); + ImGui::SameLine(); + if (splitItem.size() > 0) { + uint32_t lastIndex = splitItem.size() - 1; + ImGui::Text(formatTimestampTimeSplit(splitTime[lastIndex]).c_str()); + } else { + ImGui::Text(formatTimestampTimeSplit(totalPreviousBest).c_str()); + } } } @@ -1217,7 +1281,7 @@ void TimeSplitWindow::DrawElement() { } ImGui::EndTabBar(); ImGui::End(); - ImGui::PopStyleColor(1); + ImGui::PopStyleColor(); } void TimeSplitWindow::InitElement() { From 86554c19641678b54b097c9b88456a5f766efbcd Mon Sep 17 00:00:00 2001 From: Caladius Date: Sun, 10 Mar 2024 12:43:09 -0400 Subject: [PATCH 26/40] Bug Fixes: Entrances, Reordering splits with already split statuses, removing entries that are active splits. New: Clear out individual current and previous bests. --- .../Enhancements/timesplits/TimeSplits.cpp | 80 +++++++++++++++++-- 1 file changed, 73 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 36067fcbca6..429af01807a 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -328,7 +328,15 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; splitStatus[loopCounter] = 1; if (loopCounter < (splitItem.size() - 1)) { - splitStatus[loopCounter + 1] = 2; + for (int i = loopCounter; i < splitItem.size(); i++) { + if (splitStatus[i] == 0) { + splitStatus[i] = 2; + i = splitItem.size() - 1; + } + if (splitStatus[splitItem.size() - 1] == 1) { + TimeSplitCompleteSplits(); + } + } } if (splitTime[loopCounter] < splitBest[loopCounter]) { splitBest[loopCounter] = splitTime[loopCounter]; @@ -348,7 +356,7 @@ void TimeSplitSceneSplitHandler(uint32_t entrance) { return; } if (entrance != ESCAPE_LOST_WOODS && entrance != ESCAPE_KOKIRI_FOREST) { - entrance += 667; + entrance = gPlayState->sceneNum + ENTER_DEKU_TREE; } for (auto& str : splitItem) { if (entrance == splitItem[loopCounter]) { @@ -356,7 +364,15 @@ void TimeSplitSceneSplitHandler(uint32_t entrance) { splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; splitStatus[loopCounter] = 1; if (loopCounter < (splitItem.size() - 1)) { - splitStatus[loopCounter + 1] = 2; + for (int i = loopCounter; i < splitItem.size(); i++) { + if (splitStatus[i] == 0) { + splitStatus[i] = 2; + i = splitItem.size() - 1; + } + if (splitStatus[splitItem.size() - 1] == 1) { + TimeSplitCompleteSplits(); + } + } } if (splitTime[loopCounter] < splitBest[loopCounter]) { splitBest[loopCounter] = splitTime[loopCounter]; @@ -390,7 +406,15 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; splitStatus[loopCounter] = 1; if (loopCounter < (splitItem.size() - 1)) { - splitStatus[loopCounter + 1] = 2; + for (int i = loopCounter; i < splitItem.size(); i++) { + if (splitStatus[i] == 0) { + splitStatus[i] = 2; + i = splitItem.size() - 1; + } + if (splitStatus[splitItem.size() - 1] == 1) { + TimeSplitCompleteSplits(); + } + } } if (splitTime[loopCounter] < splitBest[loopCounter]) { splitBest[loopCounter] = splitTime[loopCounter]; @@ -606,9 +630,11 @@ void DrawTimeSplitSplits(){ } //List Removals if (CVarGetInteger("gTimeSplit.EnableEdits", 0)) { - ImGui::BeginTable("Remove Entries", 2); + ImGui::BeginTable("Remove Entries", 4); ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (28.0f * uiScale)); ImGui::TableSetupColumn("Item Name"); + ImGui::TableSetupColumn("Current Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); + ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); ImGui::TableHeadersRow(); ImGui::TableNextColumn(); for (int i = 0; i < splitItem.size(); i++) { @@ -621,16 +647,19 @@ void DrawTimeSplitSplits(){ } } ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.75f, 0.0f, 0.0f, 1.0f)); + // Item Image (Removal) if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { + uint32_t currentStatus = splitStatus[i]; splitItem.erase(splitItem.begin() + i); splitTime.erase(splitTime.begin() + i); splitPreviousBest.erase(splitPreviousBest.begin() + i); splitBest.erase(splitBest.begin() + i); splitStatus.erase(splitStatus.begin() + i); + splitStatus[i] = currentStatus; } - ImGui::PopStyleColor(); ImGui::TableNextColumn(); + // Item Name (Removal) ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f * uiScale)); ImGui::AlignTextToFramePadding(); if (itemNum == ITEM_SKULL_TOKEN) { @@ -642,6 +671,25 @@ void DrawTimeSplitSplits(){ } else { ImGui::TextWrapped(itemNamer.c_str()); } + ImGui::TableNextColumn(); + if (splitBest[i] != 100000) { + if (ImGui::Button(std::string(formatTimestampTimeSplit(splitBest[i])).c_str(), + ImVec2(85.0f, 30.0f))) { + splitBest[i] = 100000; + } + } else { + ImGui::TextColored(COLOR_RED, "No Data"); + } + ImGui::TableNextColumn(); + // Previous Best (Removal) + if (splitPreviousBest[i] != 0) { + if (ImGui::Button(std::string(formatTimestampTimeSplit(splitPreviousBest[i])).c_str(), ImVec2(85.0f, 30.0f))) { + splitPreviousBest[i] = 0; + } + } else { + ImGui::TextColored(COLOR_RED, "No Data"); + } + ImGui::PopStyleColor(); ImGui::PopStyleVar(); ImGui::TableNextColumn(); } @@ -706,6 +754,7 @@ void DrawTimeSplitSplits(){ v++; o--; } + splitStatus[loopCounter] = 3; } else { int v = 0; int o = nextIndex + v + 1; @@ -718,12 +767,24 @@ void DrawTimeSplitSplits(){ v++; o++; } + splitStatus[loopCounter] = 0; } splitItem[loopCounter] = draggedItem; splitTime[loopCounter] = draggedTime; splitBest[loopCounter] = draggedBest; splitPreviousBest[loopCounter] = draggedPreviousBest; splitStatus[loopCounter] = draggedStatus; + for (int i = 0; i < splitItem.size(); i++) { + if (splitStatus[i] != 1) { + splitStatus[i] = 2; + for (int v = i + 1; v < splitItem.size(); v++) { + if (splitStatus[v] != 1){ + splitStatus[v] = 0; + } + } + i = splitItem.size() - 1; + } + } } ImGui::EndDragDropTarget(); } @@ -1259,7 +1320,12 @@ void TimeSplitWindow::DrawElement() { initialized = true; } - uiScale = CVarGetInteger("gImGuiScale", 0); + if (CVarGetInteger("gImGuiScale", 0)) { + uiScale = 1; + } else { + uiScale = CVarGetInteger("gImGuiScale", 0); + } + ImGui::PushStyleColor(ImGuiCol_WindowBg, colorChoice); if (!ImGui::Begin("Time Splitter Window", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { ImGui::End(); From 9d8103d67a1f45332cf80c3fac4f62bec65107e6 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 11 Mar 2024 18:31:19 -0400 Subject: [PATCH 27/40] Update Enable Removals button to Edit Splits and fixed scenarios where Best and Previous Best could be identical. --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 429af01807a..e9667dfbb1c 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -579,7 +579,7 @@ void DrawTimeSplitOptions() { status = "List has been reset"; statusColor = COLOR_RED; } - UIWidgets::EnhancementCheckbox("Enable Removals", "gTimeSplit.EnableEdits", false); + UIWidgets::EnhancementCheckbox("Edit Splits", "gTimeSplit.EnableEdits", false); ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } @@ -672,11 +672,16 @@ void DrawTimeSplitSplits(){ ImGui::TextWrapped(itemNamer.c_str()); } ImGui::TableNextColumn(); + // Current Best (Removal) - needs work if (splitBest[i] != 100000) { - if (ImGui::Button(std::string(formatTimestampTimeSplit(splitBest[i])).c_str(), - ImVec2(85.0f, 30.0f))) { + if (splitBest[i] != splitPreviousBest[i]) { + if (ImGui::Button(std::string(formatTimestampTimeSplit(splitBest[i])).c_str(), ImVec2(85.0f, 30.0f))) { splitBest[i] = 100000; + } + } else { + ImGui::TextColored(COLOR_WHITE, "No Change"); } + } else { ImGui::TextColored(COLOR_RED, "No Data"); } From 7a7b2fa11ef107b44ada03bc20680097381930f0 Mon Sep 17 00:00:00 2001 From: Caladius Date: Tue, 12 Mar 2024 19:09:38 -0400 Subject: [PATCH 28/40] Split List preview in Manage List tab for quick reference. (Thanks aMannus for the suggestion) --- .../Enhancements/timesplits/TimeSplits.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index e9667dfbb1c..5482a1a402c 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -922,6 +922,37 @@ void TimeSplitAddToSplits(uint32_t itemToAdd) { } void DrawTimeSplitListManager() { + if (splitItem.size() == 0) { + ImGui::BeginTable("Current List", 1); + } else { + ImGui::BeginTable("Current List", splitItem.size(), 0, ImVec2(2400.0f, 0.0f)); + for (int i = 0; i < splitItem.size(); i++) { + if (i < 8) { + ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (35.0f * uiScale)); + } + } + ImGui::TableNextColumn(); + } + for (int i = 0; i < splitItem.size(); i++) { + for (auto& obj : splitObjects) { + if (splitItem[i] == obj.itemID) { + ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); + } + } + + if (i != 0 && (i + 1) % 8 == 0) { + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + + //ImGui::TableNextColumn(); + } else { + ImGui::TableNextColumn(); + } + } + ImGui::EndTable(); + UIWidgets::PaddedSeparator(); + ImGui::BeginChild("AddtoList"); if (ImGui::CollapsingHeader("Equipment & Quest Status")) { ImGui::BeginTable("Equipment", 3); for (int i = 0; i < 3; i++) { @@ -1317,6 +1348,7 @@ void DrawTimeSplitListManager() { ImGui::EndTable(); } } + ImGui::EndChild(); } void TimeSplitWindow::DrawElement() { From c5f688b115d447deb27ea0cb80a27af70bcad98b Mon Sep 17 00:00:00 2001 From: Caladius Date: Tue, 12 Mar 2024 19:21:01 -0400 Subject: [PATCH 29/40] cleanup --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 5482a1a402c..87d06f81b0f 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -944,8 +944,6 @@ void DrawTimeSplitListManager() { if (i != 0 && (i + 1) % 8 == 0) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - - //ImGui::TableNextColumn(); } else { ImGui::TableNextColumn(); } From c3510835918519fde70633c10d48d9cad78b7ff1 Mon Sep 17 00:00:00 2001 From: Caladius Date: Wed, 13 Mar 2024 18:32:40 -0400 Subject: [PATCH 30/40] Fix Magic splits --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 87d06f81b0f..5c064f1bc40 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -166,8 +166,8 @@ std::vector splitObjects = { { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, - { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, - { ITEM_MAGIC_LARGE, "Double Magic", "ITEM_MAGIC_LARGE"}, + { ITEM_SINGLE_MAGIC, "Magic Meter", "ITEM_MAGIC_SMALL"}, + { ITEM_DOUBLE_MAGIC, "Double Magic", "ITEM_MAGIC_LARGE"}, { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, { ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK"}, { ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, @@ -257,7 +257,7 @@ std::vector inventoryObjects = { { ITEM_BOMB, "Bombs", "ITEM_BOMB"}, { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, - { ITEM_MAGIC_SMALL, "Magic Meter", "ITEM_MAGIC_SMALL"}, + { ITEM_SINGLE_MAGIC, "Magic Meter", "ITEM_MAGIC_SMALL"}, { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, @@ -1065,7 +1065,7 @@ void DrawTimeSplitListManager() { ImGui::OpenPopup("Hookshot"); } else if (inventoryObjects[i].itemID == ITEM_BOTTLE) { ImGui::OpenPopup("Bottles"); - } else if (inventoryObjects[i].itemID == ITEM_MAGIC_SMALL) { + } else if (inventoryObjects[i].itemID == ITEM_SINGLE_MAGIC) { ImGui::OpenPopup("Magic"); } else if (inventoryObjects[i].itemID == ITEM_WALLET_ADULT) { ImGui::OpenPopup("Wallet"); @@ -1213,7 +1213,7 @@ void DrawTimeSplitListManager() { ImGui::EndPopup(); } if (ImGui::BeginPopupContextItem("Magic")) { - for (int i = ITEM_MAGIC_SMALL; i <= ITEM_MAGIC_LARGE; i++) { + for (int i = ITEM_SINGLE_MAGIC; i <= ITEM_DOUBLE_MAGIC; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), From c8aeabe6b25bec4ace710aba1de323c9b3b2d35b Mon Sep 17 00:00:00 2001 From: Caladius Date: Wed, 13 Mar 2024 21:21:06 -0400 Subject: [PATCH 31/40] Fix Current Time not counting up --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 5c064f1bc40..c1ac460acd5 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -809,7 +809,7 @@ void DrawTimeSplitSplits(){ ImGui::TableNextColumn(); if (splitStatus[loopCounter] == 2) { // Current Time (Active) - if (splitTime[loopCounter] == 0) { + if (splitTime[loopCounter] != 1) { ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); } else { ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); From aece6578a62a8cd5bd956d3aa0e6b784a183e936 Mon Sep 17 00:00:00 2001 From: Caladius Date: Thu, 14 Mar 2024 19:24:41 -0400 Subject: [PATCH 32/40] Fixed initialization of splitdata file; added Text to List Preview area; Added Hide Tabs checkbox to make UI cleaner for running; Made Collapsible Header color with the window + alpha. --- .../Enhancements/timesplits/TimeSplits.cpp | 68 ++++++++++++------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index c1ac460acd5..94b1d1a1c69 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -466,6 +466,9 @@ void DrawTimeSplitOptions() { for (auto& entry : comboList.items()) { keys.push_back(entry.key()); } + if (keys.size() == 0) { + keys.push_back("No Saved Lists"); + } static uint32_t selectedItem = 0; static std::string listItem = keys[0]; ImGui::PushItemWidth(151.0f); @@ -525,7 +528,23 @@ void DrawTimeSplitOptions() { status = "List does not exist in Save Data"; statusColor = COLOR_RED; } - + } + ImGui::SameLine(); + if (ImGui::Button("Delete List")) { + std::ifstream file("splitdata.json"); + json j; + + if (file.is_open()) { + file >> j; + file.close(); + } + j.erase(listItem); + + std::ofstream newFile("splitdata.json"); + newFile << j.dump(4); + newFile.close(); + status = "List has been deleted"; + statusColor = COLOR_RED; } UIWidgets::Spacer(0); ImGui::Text("Background Color"); @@ -580,6 +599,8 @@ void DrawTimeSplitOptions() { statusColor = COLOR_RED; } UIWidgets::EnhancementCheckbox("Edit Splits", "gTimeSplit.EnableEdits", false); + ImGui::SameLine(); + UIWidgets::EnhancementCheckbox("Hide Tabs", "gTimeSplit.EnableTabs", false); ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } @@ -625,9 +646,11 @@ void TimeSplitColorTint() { void DrawTimeSplitSplits(){ uint32_t loopCounter = 0; uint32_t buttonID = 0; - if (ImGui::CollapsingHeader("Time Splitter")) { + ImGui::PushStyleColor(ImGuiCol_Header, colorChoice); + if (ImGui::CollapsingHeader("Time Split Options")) { DrawTimeSplitOptions(); } + ImGui::PopStyleColor(); //List Removals if (CVarGetInteger("gTimeSplit.EnableEdits", 0)) { ImGui::BeginTable("Remove Entries", 4); @@ -885,14 +908,6 @@ void DrawTimeSplitSplits(){ void InitializeSplitFile() { if (!std::filesystem::exists("splitdata.json")) { json j; - j["splitItem"] = splitItem; - j["splitTokens"] = splitTokens; - j["splitTime"] = splitTime; - j["splitPreviousBest"] = splitPreviousBest; - j["backgroundColor.r"] = colorChoice.x; - j["backgroundColor.g"] = colorChoice.y; - j["backgroundColor.b"] = colorChoice.z; - j["backgroundColor.a"] = colorChoice.w; std::ofstream file("splitdata.json"); file << j.dump(4); file.close(); @@ -922,6 +937,7 @@ void TimeSplitAddToSplits(uint32_t itemToAdd) { } void DrawTimeSplitListManager() { + ImGui::Text("List Preview"); if (splitItem.size() == 0) { ImGui::BeginTable("Current List", 1); } else { @@ -936,8 +952,10 @@ void DrawTimeSplitListManager() { for (int i = 0; i < splitItem.size(); i++) { for (auto& obj : splitObjects) { if (splitItem[i] == obj.itemID) { + itemNum = obj.itemID; + TimeSplitColorTint(); ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); + ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); } } @@ -1367,20 +1385,24 @@ void TimeSplitWindow::DrawElement() { ImGui::PopStyleColor(1); return; } - ImGui::BeginTabBar("Split Tabs"); - if (ImGui::BeginTabItem("Splits")) { + if (CVarGetInteger("gTimeSplit.EnableTabs", 0)) { DrawTimeSplitSplits(); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Manage List")) { - ImGui::TextColored(statusColor, status.c_str()); - UIWidgets::PaddedSeparator(); - ImGui::BeginChild("Add Items"); - DrawTimeSplitListManager(); - ImGui::EndChild(); - ImGui::EndTabItem(); + } else { + ImGui::BeginTabBar("Split Tabs"); + if (ImGui::BeginTabItem("Splits")) { + DrawTimeSplitSplits(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Manage List")) { + ImGui::TextColored(statusColor, status.c_str()); + UIWidgets::PaddedSeparator(); + ImGui::BeginChild("Add Items"); + DrawTimeSplitListManager(); + ImGui::EndChild(); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); } - ImGui::EndTabBar(); ImGui::End(); ImGui::PopStyleColor(); } From 0787d3c6876f708ada59d44f555f1754e16b5d22 Mon Sep 17 00:00:00 2001 From: Caladius Date: Fri, 15 Mar 2024 10:10:55 -0400 Subject: [PATCH 33/40] Added in Active Tracking for the currently active split. --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 94b1d1a1c69..fb7de17a1b3 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -601,6 +601,9 @@ void DrawTimeSplitOptions() { UIWidgets::EnhancementCheckbox("Edit Splits", "gTimeSplit.EnableEdits", false); ImGui::SameLine(); UIWidgets::EnhancementCheckbox("Hide Tabs", "gTimeSplit.EnableTabs", false); + ImGui::SameLine(); + UIWidgets::EnhancementCheckbox("Active Tracking", "gTimeSplit.EnableTracking", false); + UIWidgets::Tooltip("Keeps Active Split in view for longer lists."); ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); } @@ -728,6 +731,7 @@ void DrawTimeSplitSplits(){ totalPreviousBest += splitPreviousBest[i]; } ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); + ImGui::BeginChild("SplitTable", ImVec2(0.0f, ImGui::GetWindowHeight() - 128.0f)); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (27.0f * uiScale)); @@ -750,6 +754,9 @@ void DrawTimeSplitSplits(){ // Item Image if (splitStatus[buttonID] == 2) { ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); + if (CVarGetInteger("gTimeSplit.EnableTracking", 0)) { + ImGui::SetScrollHereY(loopCounter * 0.01f); + } } ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), @@ -888,6 +895,7 @@ void DrawTimeSplitSplits(){ } ImGui::EndTable(); ImGui::PopStyleVar(); + ImGui::EndChild(); UIWidgets::PaddedSeparator(); ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ImGui::CalcTextSize(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()).x - From e5cdce697837e0348d7e1664e10e2cbb4971bae9 Mon Sep 17 00:00:00 2001 From: Caladius Date: Fri, 15 Mar 2024 11:13:38 -0400 Subject: [PATCH 34/40] Set new item entries Best to 0 and updated code to reflect it. added Skipping Splits by clicking the item image. --- .../Enhancements/timesplits/TimeSplits.cpp | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index fb7de17a1b3..2035e4d1ae4 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -320,6 +320,16 @@ void TimeSplitCompleteSplits() { gSaveContext.sohStats.gameComplete = true; } +void TimeSplitSkipSplit(uint32_t splitID) { + splitStatus[splitID] = 3; + if (splitID + 1 == splitItem.size()) { + TimeSplitCompleteSplits(); + } else { + splitStatus[splitID + 1] = 2; + } + +} + void TimeSplitSplitsHandlerS(uint32_t itemID) { uint32_t loopCounter = 0; for (auto& str : splitItem) { @@ -338,7 +348,7 @@ void TimeSplitSplitsHandlerS(uint32_t itemID) { } } } - if (splitTime[loopCounter] < splitBest[loopCounter]) { + if (splitTime[loopCounter] < splitBest[loopCounter] || splitBest[loopCounter] == 0) { splitBest[loopCounter] = splitTime[loopCounter]; } if (loopCounter == (splitItem.size() - 1)) { @@ -374,7 +384,7 @@ void TimeSplitSceneSplitHandler(uint32_t entrance) { } } } - if (splitTime[loopCounter] < splitBest[loopCounter]) { + if (splitTime[loopCounter] < splitBest[loopCounter] || splitBest[loopCounter] == 0) { splitBest[loopCounter] = splitTime[loopCounter]; } if (loopCounter == (splitItem.size() - 1)) { @@ -416,7 +426,7 @@ void TimeSplitSplitsHandler(GetItemEntry itemEntry) { } } } - if (splitTime[loopCounter] < splitBest[loopCounter]) { + if (splitTime[loopCounter] < splitBest[loopCounter] || splitBest[loopCounter] == 0) { splitBest[loopCounter] = splitTime[loopCounter]; } if (loopCounter == (splitItem.size() - 1)) { @@ -506,7 +516,7 @@ void DrawTimeSplitOptions() { splitItem.push_back(0); splitTime.push_back(0); splitPreviousBest.push_back(0); - splitBest.push_back(100000); + splitBest.push_back(0); if (i == 0) { splitStatus.push_back(2); } else { @@ -579,7 +589,7 @@ void DrawTimeSplitOptions() { ImGui::SameLine(); if (ImGui::Button("Update Splits")) { for (int i = 0; i < splitItem.size(); i++) { - if (splitPreviousBest[i] == 0) { + if (splitPreviousBest[i] == 0 || splitBest[i] == 0) { splitPreviousBest[i] = splitBest[i]; } else if (splitPreviousBest[i] > splitBest[i]) { splitPreviousBest[i] = splitBest[i]; @@ -759,8 +769,12 @@ void DrawTimeSplitSplits(){ } } ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), - ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); + if (ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), + ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { + if (splitStatus[loopCounter] == 2) { + TimeSplitSkipSplit(loopCounter); + } + } ImGui::PopStyleColor(); if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { ImGui::SetDragDropPayload("DragMove", &buttonID, sizeof(uint32_t)); @@ -934,7 +948,7 @@ void TimeSplitAddToSplits(uint32_t itemToAdd) { splitItem.push_back(itemToAdd); splitTime.push_back(0); splitPreviousBest.push_back(0); - splitBest.push_back(100000); + splitBest.push_back(0); if (splitItem.size() == 1) { splitStatus.push_back(2); } else { From b433be4107a7c0998277ee3701f41c7b43bd9db3 Mon Sep 17 00:00:00 2001 From: Caladius Date: Fri, 15 Mar 2024 12:17:53 -0400 Subject: [PATCH 35/40] Added in JOTWAD Death Trigger. --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 9 +++++++-- soh/soh/Enhancements/timesplits/TimeSplits.h | 4 +++- soh/src/overlays/actors/ovl_player_actor/z_player.c | 7 +++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 2035e4d1ae4..6d4b6589fe4 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -201,6 +201,7 @@ std::vector splitObjects = { { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE"}, { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE"}, { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE"}, + { WATCHTOWER_DEATH, "Watchtower Death", "SPECIAL_SPLIT_ENTRANCE"}, }; std::vector equipmentObjects = { @@ -304,6 +305,7 @@ std::vector sceneObjects = { { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE"}, { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE"}, { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE"}, + { WATCHTOWER_DEATH, "Watchtower Death", "SPECIAL_SPLIT_ENTRANCE"}, }; std::string formatTimestampTimeSplit(uint32_t value) { @@ -365,9 +367,12 @@ void TimeSplitSceneSplitHandler(uint32_t entrance) { if (entrance == ESCAPE_KOKIRI_FOREST && gSaveContext.cutsceneIndex != 0xfff0) { return; } - if (entrance != ESCAPE_LOST_WOODS && entrance != ESCAPE_KOKIRI_FOREST) { + if (entrance != ESCAPE_LOST_WOODS && entrance != ESCAPE_KOKIRI_FOREST && entrance != WATCHTOWER_DEATH) { entrance = gPlayState->sceneNum + ENTER_DEKU_TREE; } + if (entrance == WATCHTOWER_DEATH && gSaveContext.health != 0) { + return; + } for (auto& str : splitItem) { if (entrance == splitItem[loopCounter]) { if (splitStatus[loopCounter] == 2) { @@ -1370,7 +1375,7 @@ void DrawTimeSplitListManager() { ImGui::BeginTable("Overworld", 1); ImGui::TableSetupColumn("Overworld1", ImGuiTableColumnFlags_WidthFixed, (220.0f * uiScale)); ImGui::TableNextColumn(); - for (int i = 16; i <= 17; i++) { + for (int i = 16; i <= 18; i++) { //itemNum = obj.itemID; //TimeSplitColorTint(); if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index 88e91615607..d1a5df97542 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -9,6 +9,7 @@ extern "C" { #endif void TimeSplitSplitsHandlerS(uint32_t itemID); +void TimeSplitSceneSplitHandler(uint32_t entrance); #ifdef __cplusplus } @@ -66,5 +67,6 @@ typedef enum { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, ESCAPE_KOKIRI_FOREST = 286, - ESCAPE_LOST_WOODS = 477 + ESCAPE_LOST_WOODS = 477, + WATCHTOWER_DEATH = 513 }; \ No newline at end of file diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index d1c2240880c..aad3e641a2a 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -30,6 +30,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/timesplits/TimeSplits.h" #include #include @@ -9023,7 +9024,7 @@ s32 func_80843E64(PlayState* play, Player* this) { Player_RequestRumble(this, impactInfo->rumbleStrength, impactInfo->rumbleDuration, impactInfo->rumbleDecreaseRate, 0); Player_PlaySfx(this, NA_SE_PL_BODY_HIT); func_80832698(this, impactInfo->sfxId); - + return impactIndex + 1; } @@ -11449,6 +11450,8 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { : (this->bodyShockTimer != 0) ? &gPlayerAnim_link_normal_electric_shock_end : &gPlayerAnim_link_derth_rebirth); } + TimeSplitSceneSplitHandler(gSaveContext.entranceIndex); + } else { if ((this->actor.parent == NULL) && ((play->transitionTrigger == TRANS_TRIGGER_START) || (this->unk_A87 != 0) || !func_808382DC(this, play))) { @@ -15978,7 +15981,7 @@ s32 Player_InflictDamageModified(PlayState* play, s32 damage, u8 modified) { this->stateFlags2 &= ~PLAYER_STATE2_GRABBED_BY_ENEMY; return 1; } - + return 0; } From e861a1261de5dd1049dff079e813ee56dd1bc6ee Mon Sep 17 00:00:00 2001 From: Caladius Date: Sat, 20 Apr 2024 11:55:18 -0400 Subject: [PATCH 36/40] Fix Scaling --- soh/soh/Enhancements/timesplits/TimeSplits.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 6d4b6589fe4..16eb2fc88d9 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -1401,9 +1401,9 @@ void TimeSplitWindow::DrawElement() { } if (CVarGetInteger("gImGuiScale", 0)) { - uiScale = 1; - } else { uiScale = CVarGetInteger("gImGuiScale", 0); + } else { + uiScale = 1; } ImGui::PushStyleColor(ImGuiCol_WindowBg, colorChoice); From f843da8bb2339d15c4617baf93d47164a82cd857 Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 22 Apr 2024 18:49:24 -0400 Subject: [PATCH 37/40] Pulled in @malkierian CVar updates and updated TimeSplit CVars to match. --- soh/build.c | 9 +++++++++ .../Enhancements/timesplits/TimeSplits.cpp | 20 ++++++++++--------- soh/soh/SohGui.cpp | 2 +- soh/soh/SohMenuBar.cpp | 2 +- 4 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 soh/build.c diff --git a/soh/build.c b/soh/build.c new file mode 100644 index 00000000000..8ca4a9692e4 --- /dev/null +++ b/soh/build.c @@ -0,0 +1,9 @@ +#include + +const char gBuildVersion[] = "Sulu Bravo (8.0.5)"; +const u16 gBuildVersionMajor = 8; +const u16 gBuildVersionMinor = 0; +const u16 gBuildVersionPatch = 5; +const char gBuildTeam[] = "github.com/harbourmasters"; +const char gBuildDate[] = __DATE__ " " __TIME__; +const char gBuildMakeOption[] = ""; diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 16eb2fc88d9..082abdce841 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -600,7 +600,7 @@ void DrawTimeSplitOptions() { splitPreviousBest[i] = splitBest[i]; } } - status = "Splits updated"; + status = "Splits updated locally, click Save List to write to disk."; statusColor = COLOR_GREEN; } ImGui::SameLine(); @@ -613,11 +613,13 @@ void DrawTimeSplitOptions() { status = "List has been reset"; statusColor = COLOR_RED; } - UIWidgets::EnhancementCheckbox("Edit Splits", "gTimeSplit.EnableEdits", false); + UIWidgets::EnhancementCheckbox("Edit Splits", CVAR_ENHANCEMENT("TimeSplit.EnableEdits"), false); + UIWidgets::Tooltip("Allows removing items and clearing split data."); ImGui::SameLine(); - UIWidgets::EnhancementCheckbox("Hide Tabs", "gTimeSplit.EnableTabs", false); + UIWidgets::EnhancementCheckbox("Hide Tabs", CVAR_ENHANCEMENT("TimeSplit.EnableTabs"), false); + UIWidgets::Tooltip("Toggles he display of the Tabs at the top of the window."); ImGui::SameLine(); - UIWidgets::EnhancementCheckbox("Active Tracking", "gTimeSplit.EnableTracking", false); + UIWidgets::EnhancementCheckbox("Active Tracking", CVAR_ENHANCEMENT("TimeSplit.EnableTracking"), false); UIWidgets::Tooltip("Keeps Active Split in view for longer lists."); ImGui::TextColored(statusColor, status.c_str()); UIWidgets::PaddedSeparator(); @@ -670,7 +672,7 @@ void DrawTimeSplitSplits(){ } ImGui::PopStyleColor(); //List Removals - if (CVarGetInteger("gTimeSplit.EnableEdits", 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.EnableEdits"), 0)) { ImGui::BeginTable("Remove Entries", 4); ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (28.0f * uiScale)); ImGui::TableSetupColumn("Item Name"); @@ -769,7 +771,7 @@ void DrawTimeSplitSplits(){ // Item Image if (splitStatus[buttonID] == 2) { ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); - if (CVarGetInteger("gTimeSplit.EnableTracking", 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.EnableTracking"), 0)) { ImGui::SetScrollHereY(loopCounter * 0.01f); } } @@ -1069,9 +1071,9 @@ void DrawTimeSplitListManager() { } } if (ImGui::BeginPopupContextItem("Skull Count")) { - UIWidgets::PaddedEnhancementSliderInt("Skulltula Count: %d Tokens", "##splitToken", "gTimeSplit.SkullTokens", 0, 100, "", 0, true, true, false); + UIWidgets::PaddedEnhancementSliderInt("Skulltula Count: %d Tokens", "##splitToken", CVAR_ENHANCEMENT("TimeSplit.SkullTokens"), 0, 100, "", 0, true, true, false); if (ImGui::Button("Set", ImVec2(30.0f, 20.0f))) { - splitTokens = CVarGetInteger("gTimeSplit.SkullTokens", 0); + splitTokens = CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.SkullTokens"), 0); TimeSplitAddToSplits(ITEM_SKULL_TOKEN); ImGui::CloseCurrentPopup(); } @@ -1412,7 +1414,7 @@ void TimeSplitWindow::DrawElement() { ImGui::PopStyleColor(1); return; } - if (CVarGetInteger("gTimeSplit.EnableTabs", 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.EnableTabs"), 0)) { DrawTimeSplitSplits(); } else { ImGui::BeginTabBar("Split Tabs"); diff --git a/soh/soh/SohGui.cpp b/soh/soh/SohGui.cpp index acc020e5afe..a585250cc44 100644 --- a/soh/soh/SohGui.cpp +++ b/soh/soh/SohGui.cpp @@ -202,7 +202,7 @@ namespace SohGui { gui->AddGuiWindow(mRandomizerSettingsWindow); mAdvancedResolutionSettingsWindow = std::make_shared(CVAR_WINDOW("AdvancedResolutionEditor"), "Advanced Resolution Settings"); gui->AddGuiWindow(mAdvancedResolutionSettingsWindow); - mTimeSplitWindow = std::make_shared("gTimeSplitEnabled", "Time Splits"); + mTimeSplitWindow = std::make_shared(CVAR_WINDOW("TimeSplitEnabled"), "Time Splits"); gui->AddGuiWindow(mTimeSplitWindow); mModalWindow = std::make_shared("gOpenWindows.modalWindowEnabled", "Modal Window"); gui->AddGuiWindow(mModalWindow); diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 12dc1c70041..6dbfe61ca82 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -1416,7 +1416,7 @@ void DrawEnhancementsMenu() { } if (mTimeSplitWindow) { - if (ImGui::Button(GetWindowButtonText("Time Splits", CVarGetInteger("gTimeSplitEnabled", 0)).c_str(), ImVec2(-1.0f, 0.0f))) { + if (ImGui::Button(GetWindowButtonText("Time Splits", CVarGetInteger(CVAR_WINDOW("gTimeSplitEnabled"), 0)).c_str(), ImVec2(-1.0f, 0.0f))) { mTimeSplitWindow->ToggleVisibility(); } } From 61cd36155866d9f9646f88e53c38ee27527620cd Mon Sep 17 00:00:00 2001 From: Caladius Date: Mon, 14 Oct 2024 20:20:47 -0400 Subject: [PATCH 38/40] Fix Includes and replace LUS with Ship --- .../Enhancements/timesplits/TimeSplits.cpp | 52 +++++++++---------- soh/soh/Enhancements/timesplits/TimeSplits.h | 2 +- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 082abdce841..f7303d0030f 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -1,13 +1,11 @@ #include "TimeSplits.h" #include "soh/UIWidgets.hpp" -#include "soh/Enhancements/randomizer/3drando/item_list.hpp" #include "soh/Enhancements/gameplaystats.h" #include "soh/SaveManager.h" #include "soh/util.h" #include #include "include/z64item.h" -#include "nlohmann-json/include/nlohmann/json.hpp" #include #include @@ -691,7 +689,7 @@ void DrawTimeSplitSplits(){ } ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.75f, 0.0f, 0.0f, 1.0f)); // Item Image (Removal) - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { uint32_t currentStatus = splitStatus[i]; splitItem.erase(splitItem.begin() + i); @@ -776,7 +774,7 @@ void DrawTimeSplitSplits(){ } } ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - if (ImGui::ImageButton(std::to_string(buttonID).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), + if (ImGui::ImageButton(std::to_string(buttonID).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { if (splitStatus[loopCounter] == 2) { TimeSplitSkipSplit(loopCounter); @@ -983,7 +981,7 @@ void DrawTimeSplitListManager() { if (splitItem[i] == obj.itemID) { itemNum = obj.itemID; TimeSplitColorTint(); - ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); } } @@ -1008,7 +1006,7 @@ void DrawTimeSplitListManager() { if (i == 4 || i == 8) { ImGui::TableNextColumn(); } - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(equipmentObjects[i].itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(equipmentObjects[i].itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { if (equipmentObjects[i].itemID == ITEM_BRACELET) { ImGui::OpenPopup("Strength"); @@ -1023,7 +1021,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_BRACELET; i <= ITEM_GAUNTLETS_GOLD; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1038,7 +1036,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_SCALE_SILVER; i <= ITEM_SCALE_GOLDEN; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1061,7 +1059,7 @@ void DrawTimeSplitListManager() { if (i == 4 || i == 8 || i == 12 || i == 16 || i == 20) { ImGui::TableNextColumn(); } - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(questObjects[i].itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(questObjects[i].itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { if (questObjects[i].itemID == ITEM_SKULL_TOKEN) { ImGui::OpenPopup("Skull Count"); @@ -1092,7 +1090,7 @@ void DrawTimeSplitListManager() { ImGui::TableNextColumn(); } if (ImGui::ImageButton(std::to_string(i).c_str(), - LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(inventoryObjects[i].itemImage), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(inventoryObjects[i].itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { if (inventoryObjects[i].itemID == ITEM_STICK) { //ImGui::OpenPopup("Stick"); @@ -1129,7 +1127,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_STICK; i <= ITEM_STICK_UPGRADE_30; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1147,7 +1145,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_SLINGSHOT; i <= ITEM_BULLET_BAG_50; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1165,7 +1163,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_NUT; i <= ITEM_NUT_UPGRADE_40; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1183,7 +1181,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_OCARINA_FAIRY; i <= ITEM_OCARINA_TIME; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1198,7 +1196,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_BOMB_BAG_20; i <= ITEM_BOMB_BAG_40; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1213,7 +1211,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_BOW; i <= ITEM_QUIVER_50; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1231,7 +1229,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_HOOKSHOT; i <= ITEM_LONGSHOT; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1246,7 +1244,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_BOTTLE; i <= ITEM_POE; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1263,7 +1261,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_SINGLE_MAGIC; i <= ITEM_DOUBLE_MAGIC; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1278,7 +1276,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_WALLET_ADULT; i <= ITEM_WALLET_GIANT; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1293,7 +1291,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1310,7 +1308,7 @@ void DrawTimeSplitListManager() { for (int i = ITEM_WEIRD_EGG; i <= ITEM_MASK_TRUTH; i++) { for (auto& obj : splitObjects) { if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(i); ImGui::CloseCurrentPopup(); @@ -1337,7 +1335,7 @@ void DrawTimeSplitListManager() { } itemNum = bossObjects[i].itemID; TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(bossObjects[i].itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(bossObjects[i].itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { TimeSplitAddToSplits(bossObjects[i].itemID); } @@ -1361,7 +1359,7 @@ void DrawTimeSplitListManager() { } //itemNum = sceneObjects[i].itemID; //TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(sceneObjects[i].itemID); } @@ -1380,7 +1378,7 @@ void DrawTimeSplitListManager() { for (int i = 16; i <= 18; i++) { //itemNum = obj.itemID; //TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(i).c_str(), LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), + if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { TimeSplitAddToSplits(sceneObjects[i].itemID); } @@ -1437,8 +1435,8 @@ void TimeSplitWindow::DrawElement() { } void TimeSplitWindow::InitElement() { - LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); - LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_SPLIT_ENTRANCE", gSplitEntranceTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_SPLIT_ENTRANCE", gSplitEntranceTex, ImVec4(1, 1, 1, 1)); GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { TimeSplitSplitsHandler(itemEntry); }); diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index d1a5df97542..4085878cb99 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -20,7 +20,7 @@ void TimeSplitSceneSplitHandler(uint32_t entrance); #include #ifdef __cplusplus -class TimeSplitWindow : public LUS::GuiWindow { +class TimeSplitWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; From 330ebd5ddcc16a34b09e969c25acde08d8b1d9b3 Mon Sep 17 00:00:00 2001 From: Caladius Date: Thu, 17 Oct 2024 19:28:46 -0400 Subject: [PATCH 39/40] Full Overhaul, new Hooks, less Src manip. --- .../GameInteractor_HookTable.h | 2 + .../game-interactor/GameInteractor_Hooks.cpp | 8 + .../game-interactor/GameInteractor_Hooks.h | 2 + .../Enhancements/timesplits/TimeSplits.cpp | 1890 ++++++----------- soh/soh/Enhancements/timesplits/TimeSplits.h | 68 +- soh/src/code/z_parameter.c | 8 +- .../ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 8 - .../actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c | 3 - .../actors/ovl_player_actor/z_player.c | 3 - 9 files changed, 641 insertions(+), 1351 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 46f306a3c83..62c74d8a1bf 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -25,7 +25,9 @@ DEFINE_HOOK(OnActorUpdate, (void* actor)); DEFINE_HOOK(OnActorKill, (void* actor)); DEFINE_HOOK(OnEnemyDefeat, (void* actor)); DEFINE_HOOK(OnBossDefeat, (void* actor)); +DEFINE_HOOK(OnTimestamp, (u8 item)); DEFINE_HOOK(OnPlayerBonk, ()); +DEFINE_HOOK(OnPlayerHealthChange, (int16_t amount)); DEFINE_HOOK(OnPlayDestroy, ()); DEFINE_HOOK(OnPlayDrawEnd, ()); DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list originalArgs)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 24efb40c151..7a6362f1e82 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -107,10 +107,18 @@ void GameInteractor_ExecuteOnBossDefeat(void* actor) { GameInteractor::Instance->ExecuteHooksForFilter(actor); } +void GameInteractor_ExecuteOnTimestamp (u8 item) { + GameInteractor::Instance->ExecuteHooks(item); +} + void GameInteractor_ExecuteOnPlayerBonk() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnPlayerHealthChange(int16_t amount) { + GameInteractor::Instance->ExecuteHooks(amount); +} + void GameInteractor_ExecuteOnPlayDestroy() { GameInteractor::Instance->ExecuteHooks(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index dccc9930ae2..30b5d10d6f3 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -24,7 +24,9 @@ void GameInteractor_ExecuteOnActorUpdate(void* actor); void GameInteractor_ExecuteOnActorKill(void* actor); void GameInteractor_ExecuteOnEnemyDefeat(void* actor); void GameInteractor_ExecuteOnBossDefeat(void* actor); +void GameInteractor_ExecuteOnTimestamp (u8 item); void GameInteractor_ExecuteOnPlayerBonk(); +void GameInteractor_ExecuteOnPlayerHealthChange(int16_t amount); void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price); void GameInteractor_ExecuteOnPlayDestroy(); diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index f7303d0030f..a4bedb68d8c 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -33,278 +33,189 @@ extern "C" { #define COLOR_LIGHT_BLUE ImVec4(0.00f, 0.88f, 1.00f, 1.00f) #define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f) -static std::vector splitItem; -static std::vector splitTime; -static std::vector splitBest; -static std::vector splitPreviousBest; -static std::vector splitStatus; -static uint32_t splitTokens; -static std::string status; -static ImVec4 statusColor = COLOR_WHITE; -static uint32_t splitCurNum = 1; -std::string splitAttempt = "Attempt #: 1"; -static std::string splitNumDisp = "Attempt #: "; -static ImVec4 colorChoice = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); -static const char* backgroundColor; -static uint32_t itemNum; -static std::string itemImager; -static std::string itemNamer; -static uint32_t splitCounter; -static uint32_t totalPreviousBest; -char textBuffer[25]; -static ImVec4 pieceTint; -static uint32_t uiScale; - using json = nlohmann::json; -std::vector splitObjects = { - // ID, Item Name Image Name - { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, - { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, - { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, - { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, - { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, - { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, - { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, - { ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME"}, - { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, - { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, - { ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT"}, - { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, - { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, - { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, - { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, - { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, - { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, - { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, - { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, - { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, - { ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED"}, - { ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN"}, - { ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE"}, - { ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY"}, - { ITEM_FISH, "Fish", "ITEM_FISH"}, - { ITEM_MILK_BOTTLE, "Milk", "ITEM_MILK_BOTTLE"}, - { ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO"}, - { ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE"}, - { ITEM_BUG, "Bug", "ITEM_BUG"}, - { ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE"}, - { ITEM_POE, "Poe", "ITEM_POE"}, - { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, - { ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN"}, - { ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA"}, - { ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON"}, - { ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL"}, - { ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY"}, - { ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY"}, - { ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON"}, - { ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA"}, - { ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO"}, - { ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH"}, - { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, - { ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO"}, - { ITEM_COJIRO, "Cojiro", "ITEM_COJIRO"}, - { ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM"}, - { ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION"}, - { ITEM_SAW, "Poacher's Saw", "ITEM_SAW"}, - { ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN"}, - { ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION"}, - { ITEM_FROG, "Eyeball Frog", "ITEM_FROG"}, - { ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS"}, - { ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK"}, - { ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, - { ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, - { ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, - { ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, - { ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, - { ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, - { ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, - { ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, - { ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, - { ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, - { ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30"}, - { ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40"}, - { ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50"}, - { ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30"}, - { ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40"}, - { ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50"}, - { ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20"}, - { ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30"}, - { ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40"}, - { ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, - { ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER"}, - { ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD"}, - { ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, - { ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN"}, - { ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE"}, - { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, - { ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT"}, - { ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE"}, - { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, - { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, - { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, - { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, - { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, - { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, - { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, - { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, - { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, - { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, - { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, - { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, - { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, - { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, - { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, - { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, - { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, - { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, - { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, - { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, - { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, - { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, - { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, - { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, - { ITEM_SINGLE_MAGIC, "Magic Meter", "ITEM_MAGIC_SMALL"}, - { ITEM_DOUBLE_MAGIC, "Double Magic", "ITEM_MAGIC_LARGE"}, - { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, - { ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK"}, - { ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK"}, - { ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT"}, - { ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT"}, - { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE"}, - { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE"}, - { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE"}, - { WATCHTOWER_DEATH, "Watchtower Death", "SPECIAL_SPLIT_ENTRANCE"}, -}; - -std::vector equipmentObjects = { - { ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI"}, - { ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU"}, - { ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET"}, - { ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER"}, - { ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER"}, - { ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN"}, - { ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON"}, - { ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON"}, - { ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS"}, - { ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR"}, - { ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA"}, - { ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER"}, -}; - -std::vector questObjects = { - { ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY"}, - { ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT"}, - { ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY"}, - { ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET"}, - { ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD"}, - { ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST"}, - { ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA"}, - { ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO"}, - { ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN"}, - { ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE"}, - { ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA"}, - { ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE"}, - { ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD"}, - { ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER"}, - { ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN"}, - { ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM"}, - { ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY"}, - { ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT"}, - { ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME"}, - { ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE"}, - { ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE"}, - { ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW"}, - { ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS"}, - { ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE"}, -}; - -std::vector inventoryObjects = { - { ITEM_STICK, "Deku Stick", "ITEM_STICK"}, - { ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT"}, - { ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG"}, - { ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE"}, - { ITEM_NUT, "Deku Nut", "ITEM_NUT"}, - { ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY"}, - { ITEM_LENS, "Lens of Truth", "ITEM_LENS"}, - { ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER"}, - { ITEM_BOMB, "Bombs", "ITEM_BOMB"}, - { ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU"}, - { ITEM_BEAN, "Magic Bean", "ITEM_BEAN"}, - { ITEM_SINGLE_MAGIC, "Magic Meter", "ITEM_MAGIC_SMALL"}, - { ITEM_BOW, "Fairy Bow", "ITEM_BOW"}, - { ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT"}, - { ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER"}, - { ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT"}, - { ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE"}, - { ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE"}, - { ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT"}, - { ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG"}, - { ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE"}, - { ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND"}, - { ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE"}, - { ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG"}, +// NEW START +static uint32_t splitBestTimeDisplay; +static uint32_t popupID = 0; + +static ImVec4 windowColor = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); +static ImVec4 splitStatusColor = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); +static ImVec4 splitTimeColor = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); + +std::vector keys; + +char listNameBuf[25]; +const char* lastLoadedlistName; +bool displayPopup = false; + +std::vector splitList; +std::vector emptyList; + +std::vector splitObjectList = { + { SPLIT_ITEM, ITEM_STICK, "Deku Stick", "ITEM_STICK", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_NUT, "Deku Nut", "ITEM_NUT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOW, "Fairy Bow", "ITEM_BOW", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_LENS, "Lens of Truth", "ITEM_LENS", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BEAN, "Magic Bean", "ITEM_BEAN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_FISH, "Fish", "ITEM_FISH", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MILK_BOTTLE, "Milk", "ITEM_MILK_BOTTLE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BUG, "Bug", "ITEM_BUG", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_POE, "Poe", "ITEM_POE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_COJIRO, "Cojiro", "ITEM_COJIRO", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SAW, "Poacher's Saw", "ITEM_SAW", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_FROG, "Eyeball Frog", "ITEM_FROG", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_SINGLE_MAGIC, "Magic Meter", "ITEM_MAGIC_SMALL", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_DOUBLE_MAGIC, "Double Magic", "ITEM_MAGIC_LARGE", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT", COLOR_WHITE }, + { SPLIT_ITEM, ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT", COLOR_WHITE }, + { SPLIT_BOSS, ACTOR_BOSS_GOMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_GREEN }, + { SPLIT_BOSS, ACTOR_BOSS_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_RED }, + { SPLIT_BOSS, ACTOR_BOSS_VA, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_BLUE }, + { SPLIT_BOSS, ACTOR_BOSS_GANONDROF, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_GREEN }, + { SPLIT_BOSS, ACTOR_BOSS_FD2, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_RED }, + { SPLIT_BOSS, ACTOR_BOSS_MO, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_BLUE }, + { SPLIT_BOSS, ACTOR_BOSS_SST, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_PURPLE }, + { SPLIT_BOSS, ACTOR_BOSS_TW, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_ORANGE }, + { SPLIT_BOSS, ACTOR_BOSS_GANON, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_GREY }, + { SPLIT_BOSS, ACTOR_BOSS_GANON2, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_YELLOW }, + { SPLIT_ENTRANCE, SCENE_DEKU_TREE, "Enter Deku Tree", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_ENTRANCE, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_MISC, SCENE_ZORAS_RIVER, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_MISC, SCENE_LOST_WOODS, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_MISC, SCENE_KAKARIKO_VILLAGE, "Watchtower Death", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, }; -std::vector bossObjects = { - { BOSS_QUEEN_GOHMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_KING_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BARINADE, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_PHANTOM_GANON, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_VOLVAGIA, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_MORPHA, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_BONGO_BONGO, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_TWINROVA, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANONDORF, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE"}, - { BOSS_GANON, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE"}, +std::map> popupList = { + // { ITEM_STICK, { ITEM_STICK, ITEM_STICK_UPGRADE_20, ITEM_STICK_UPGRADE_30, ITEM_STICK } }, + // { ITEM_NUT, { ITEM_NUT, ITEM_NUT_UPGRADE_30, ITEM_NUT_UPGRADE_40 } }, + // { ITEM_BOMB, { ITEM_BOMB_BAG_20, ITEM_BOMB_BAG_30, ITEM_BOMB_BAG_40 } }, + { ITEM_BOW, { ITEM_QUIVER_30, ITEM_QUIVER_40, ITEM_QUIVER_50 } }, + { ITEM_SLINGSHOT, { ITEM_BULLET_BAG_30, ITEM_BULLET_BAG_40, ITEM_BULLET_BAG_50 } }, + { ITEM_OCARINA_FAIRY, { ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME } }, + { ITEM_HOOKSHOT, { ITEM_HOOKSHOT, ITEM_LONGSHOT } }, + // { ITEM_BOTTLE, { } }, + { ITEM_WEIRD_EGG, { ITEM_WEIRD_EGG, ITEM_CHICKEN, ITEM_LETTER_ZELDA, ITEM_MASK_KEATON, + ITEM_MASK_SKULL, ITEM_MASK_SPOOKY, ITEM_MASK_BUNNY, ITEM_MASK_GORON, + ITEM_MASK_ZORA, ITEM_MASK_GERUDO, ITEM_MASK_TRUTH } }, + { ITEM_POCKET_EGG, { ITEM_POCKET_EGG, ITEM_POCKET_CUCCO, ITEM_COJIRO, ITEM_ODD_MUSHROOM, + ITEM_ODD_POTION, ITEM_SAW, ITEM_SWORD_BROKEN, ITEM_PRESCRIPTION, + ITEM_FROG, ITEM_EYEDROPS, ITEM_CLAIM_CHECK } }, + { ITEM_BRACELET, { ITEM_BRACELET, ITEM_GAUNTLETS_SILVER, ITEM_GAUNTLETS_GOLD } }, + { ITEM_SCALE_SILVER, { ITEM_SCALE_SILVER, ITEM_SCALE_GOLDEN } }, }; -std::vector sceneObjects = { - { ENTER_DEKU_TREE, "Enter Deku Tree", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_SPLIT_ENTRANCE"}, - { ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE"}, - { ESCAPE_LOST_WOODS, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE"}, - { ESCAPE_KOKIRI_FOREST, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE"}, - { WATCHTOWER_DEATH, "Watchtower Death", "SPECIAL_SPLIT_ENTRANCE"}, -}; +// NEW END std::string formatTimestampTimeSplit(uint32_t value) { uint32_t sec = value / 10; @@ -320,1116 +231,492 @@ void TimeSplitCompleteSplits() { gSaveContext.sohStats.gameComplete = true; } -void TimeSplitSkipSplit(uint32_t splitID) { - splitStatus[splitID] = 3; - if (splitID + 1 == splitItem.size()) { - TimeSplitCompleteSplits(); - } else { - splitStatus[splitID + 1] = 2; - } - +//void TimeSplitSkipSplit(uint32_t splitID) { +// splitStatus[splitID] = 3; +// if (splitID + 1 == splitItem.size()) { +// TimeSplitCompleteSplits(); +// } else { +// splitStatus[splitID + 1] = 2; +// } +// +//} + +// NEW START +nlohmann::json ImVec4_to_json(const ImVec4& vec) { + return nlohmann::json{ + {"x", vec.x}, + {"y", vec.y}, + {"z", vec.z}, + {"w", vec.w} + }; } -void TimeSplitSplitsHandlerS(uint32_t itemID) { - uint32_t loopCounter = 0; - for (auto& str : splitItem) { - if (itemID == splitItem[loopCounter]) { - if (splitStatus[loopCounter] == 2) { - splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; - splitStatus[loopCounter] = 1; - if (loopCounter < (splitItem.size() - 1)) { - for (int i = loopCounter; i < splitItem.size(); i++) { - if (splitStatus[i] == 0) { - splitStatus[i] = 2; - i = splitItem.size() - 1; - } - if (splitStatus[splitItem.size() - 1] == 1) { - TimeSplitCompleteSplits(); - } - } - } - if (splitTime[loopCounter] < splitBest[loopCounter] || splitBest[loopCounter] == 0) { - splitBest[loopCounter] = splitTime[loopCounter]; - } - if (loopCounter == (splitItem.size() - 1)) { - TimeSplitCompleteSplits(); - } - } - } - loopCounter++; - } +ImVec4 json_to_ImVec4(const nlohmann::json& jsonVec) { + return ImVec4(jsonVec["x"], jsonVec["y"], jsonVec["z"], jsonVec["w"]); } -void TimeSplitSceneSplitHandler(uint32_t entrance) { - uint32_t loopCounter = 0; - if (entrance == ESCAPE_KOKIRI_FOREST && gSaveContext.cutsceneIndex != 0xfff0) { - return; - } - if (entrance != ESCAPE_LOST_WOODS && entrance != ESCAPE_KOKIRI_FOREST && entrance != WATCHTOWER_DEATH) { - entrance = gPlayState->sceneNum + ENTER_DEKU_TREE; - } - if (entrance == WATCHTOWER_DEATH && gSaveContext.health != 0) { - return; - } - for (auto& str : splitItem) { - if (entrance == splitItem[loopCounter]) { - if (splitStatus[loopCounter] == 2) { - splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; - splitStatus[loopCounter] = 1; - if (loopCounter < (splitItem.size() - 1)) { - for (int i = loopCounter; i < splitItem.size(); i++) { - if (splitStatus[i] == 0) { - splitStatus[i] = 2; - i = splitItem.size() - 1; - } - if (splitStatus[splitItem.size() - 1] == 1) { - TimeSplitCompleteSplits(); - } - } - } - if (splitTime[loopCounter] < splitBest[loopCounter] || splitBest[loopCounter] == 0) { - splitBest[loopCounter] = splitTime[loopCounter]; - } - if (loopCounter == (splitItem.size() - 1)) { - TimeSplitCompleteSplits(); - } - } - } - loopCounter++; - } +nlohmann::json SplitObject_to_json(const SplitObject& split) { + return nlohmann::json{ + {"splitType", split.splitType}, + {"splitID", split.splitID}, + {"splitName", split.splitName}, + {"splitImage", split.splitImage}, + {"splitTint", ImVec4_to_json(split.splitTint)}, + {"splitTimeCurrent", split.splitTimeCurrent}, + {"splitTimeBest", split.splitTimeBest}, + {"splitTimePreviousBest", split.splitTimePreviousBest}, + {"splitTimeStatus", split.splitTimeStatus}, + {"splitSkullTokencount", split.splitSkullTokenCount} + }; } -void TimeSplitSplitsHandler(GetItemEntry itemEntry) { - if (itemEntry.modIndex != 0) { - return; - } - uint32_t loopCounter = 0; - for (auto& str : splitItem) { - if (itemEntry.itemId == ITEM_NUTS_5 || itemEntry.itemId == ITEM_NUTS_10) { - itemEntry.itemId = ITEM_NUT; - } else if (itemEntry.itemId == ITEM_STICKS_5 || itemEntry.itemId == ITEM_STICKS_10) { - itemEntry.itemId == ITEM_STICK; - } else if (itemEntry.itemId == ITEM_SKULL_TOKEN) { - if (gSaveContext.inventory.gsTokens != splitTokens) { - return; - } - } - if (itemEntry.itemId == splitItem[loopCounter]) { - if (splitStatus[loopCounter] == 2) { - splitTime[loopCounter] = GAMEPLAYSTAT_TOTAL_TIME; - splitStatus[loopCounter] = 1; - if (loopCounter < (splitItem.size() - 1)) { - for (int i = loopCounter; i < splitItem.size(); i++) { - if (splitStatus[i] == 0) { - splitStatus[i] = 2; - i = splitItem.size() - 1; - } - if (splitStatus[splitItem.size() - 1] == 1) { - TimeSplitCompleteSplits(); - } - } - } - if (splitTime[loopCounter] < splitBest[loopCounter] || splitBest[loopCounter] == 0) { - splitBest[loopCounter] = splitTime[loopCounter]; - } - if (loopCounter == (splitItem.size() - 1)) { - TimeSplitCompleteSplits(); - } - } - } - loopCounter++; - } +SplitObject json_to_SplitObject(const nlohmann::json& jsonSplit) { + SplitObject split; + split.splitType = jsonSplit["splitType"]; + split.splitID = jsonSplit["splitID"]; + split.splitName = jsonSplit["splitName"].get(); + split.splitImage = jsonSplit["splitImage"].get(); + split.splitTint = json_to_ImVec4(jsonSplit["splitTint"]); + split.splitTimeCurrent = jsonSplit["splitTimeCurrent"]; + split.splitTimeBest = jsonSplit["splitTimeBest"]; + split.splitTimePreviousBest = jsonSplit["splitTimePreviousBest"]; + split.splitTimeStatus = jsonSplit["splitTimeStatus"]; + split.splitSkullTokenCount = jsonSplit["splitSkullTokenCount"]; + return split; } -void DrawTimeSplitOptions() { - ImGui::Text("List Name"); - ImGui::SameLine(0); - ImGui::PushItemWidth(165.0f); - ImGui::InputText("##List Name", textBuffer, sizeof(textBuffer)); - ImGui::PopItemWidth(); - ImGui::SameLine(); - if (ImGui::Button("Save List")) { - std::ifstream existingFile("splitdata.json"); - json existingData; - existingFile >> existingData; - existingFile.close(); - - existingData[textBuffer]["splitItem"] = splitItem; - existingData[textBuffer]["splitTime"] = splitTime; - existingData[textBuffer]["splitTokens"] = splitTokens; - existingData[textBuffer]["splitPreviousBest"] = splitPreviousBest; - existingData[textBuffer]["backgroundColor.r"] = colorChoice.x; - existingData[textBuffer]["backgroundColor.g"] = colorChoice.y; - existingData[textBuffer]["backgroundColor.b"] = colorChoice.z; - existingData[textBuffer]["backgroundColor.a"] = colorChoice.w; +void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vector listData) { + std::string filename = "timesplitdata.json"; + json saveFile; + json listArray = nlohmann::json::array(); - std::ofstream newFile("splitdata.json"); - newFile << existingData.dump(4); - newFile.close(); - status = "List has been saved to disk"; - statusColor = COLOR_LIGHT_BLUE; - } - UIWidgets::Spacer(0); - ImGui::Text("Saved Lists"); - ImGui::SameLine(); - std::ifstream lists("splitdata.json"); - json comboList; - lists >> comboList; - std::vector keys; - for (auto& entry : comboList.items()) { - keys.push_back(entry.key()); - } - if (keys.size() == 0) { - keys.push_back("No Saved Lists"); - } - static uint32_t selectedItem = 0; - static std::string listItem = keys[0]; - ImGui::PushItemWidth(151.0f); - if (ImGui::BeginCombo("##lists", keys[selectedItem].c_str())) { - for (int i = 0; i < keys.size(); i++) { - bool isSelected = (selectedItem == i); - if (ImGui::Selectable(keys[i].c_str(), isSelected)) { - selectedItem = i; - listItem = keys[i].c_str(); - } - if (isSelected) { - ImGui::SetItemDefaultFocus(); - } - } - ImGui::EndCombo(); + std::ifstream inputFile(filename); + if (inputFile.is_open()) { + inputFile >> saveFile; + inputFile.close(); } - ImGui::PopItemWidth(); - ImGui::SameLine(); - if (ImGui::Button("Load List")) { - std::ifstream file("splitdata.json"); - json j; - if (file.is_open()) { - file >> j; - file.close(); + if (action == ACTION_SAVE) { + for (auto& data : listData) { + listArray.push_back(SplitObject_to_json(data)); } - if (j[listItem]["splitItem"].size() > 0) { - splitItem.clear(); - splitTime.clear(); - splitPreviousBest.clear(); - splitBest.clear(); - splitStatus.clear(); + saveFile[listEntry] = listArray; - for (int i = 0; i < j[listItem]["splitItem"].size(); i++) { - splitItem.push_back(0); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(0); - if (i == 0) { - splitStatus.push_back(2); - } else { - splitStatus.push_back(0); - } - } - splitItem = j[listItem]["splitItem"].get>(); - splitTime = j[listItem]["splitTime"].get>(); - splitTokens = j[listItem]["splitTokens"]; - splitPreviousBest = j[listItem]["splitPreviousBest"].get>(); - colorChoice.x = j[listItem]["backgroundColor.r"]; - colorChoice.y = j[listItem]["backgroundColor.g"]; - colorChoice.z = j[listItem]["backgroundColor.b"]; - colorChoice.w = j[listItem]["backgroundColor.a"]; - file.close(); - status = "List has been loaded from Save Data"; - statusColor = COLOR_LIGHT_BLUE; - } else { - status = "List does not exist in Save Data"; - statusColor = COLOR_RED; + // Update Save File on Disk + std::ofstream outputFile(filename); + if (outputFile.is_open()) { + outputFile << saveFile.dump(4); + outputFile.close(); } } - ImGui::SameLine(); - if (ImGui::Button("Delete List")) { - std::ifstream file("splitdata.json"); - json j; - if (file.is_open()) { - file >> j; - file.close(); - } - j.erase(listItem); + if (action == ACTION_LOAD) { + if (saveFile.contains(listEntry)) { + listArray = saveFile[listEntry]; + splitList.clear(); - std::ofstream newFile("splitdata.json"); - newFile << j.dump(4); - newFile.close(); - status = "List has been deleted"; - statusColor = COLOR_RED; - } - UIWidgets::Spacer(0); - ImGui::Text("Background Color"); - if (ImGui::ColorEdit4("Background Color", (float*)&colorChoice, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { - Color_RGBA8 color; - color.r = colorChoice.x; - color.g = colorChoice.y; - color.b = colorChoice.z; - color.a = colorChoice.w; - } - ImGui::SameLine(); - if (ImGui::Button("Reset")) { - colorChoice = { 0.0f, 0.0f, 0.0f, 1.0f }; - } - UIWidgets::Spacer(0); - if (ImGui::Button("New Attempt")) { - splitStatus.clear(); - splitTime.clear(); - for (int i = 0; i < splitItem.size(); i++) { - if (i == 0) { - splitStatus.push_back(2); - } else { - splitStatus.push_back(0); + for (auto& data : listArray) { + splitList.push_back(json_to_SplitObject(data)); } - splitTime.push_back(0); } - splitCurNum++; - std::stringstream ss; - ss << splitCurNum; - splitAttempt = (splitNumDisp).c_str() + ss.str(); } - ImGui::SameLine(); - if (ImGui::Button("Update Splits")) { - for (int i = 0; i < splitItem.size(); i++) { - if (splitPreviousBest[i] == 0 || splitBest[i] == 0) { - splitPreviousBest[i] = splitBest[i]; - } else if (splitPreviousBest[i] > splitBest[i]) { - splitPreviousBest[i] = splitBest[i]; + + if (action == ACTION_UPDATE) { + for (auto& update : listData) { + if (update.splitTimeBest < update.splitTimePreviousBest) { + update.splitTimePreviousBest = update.splitTimeBest; } } - status = "Splits updated locally, click Save List to write to disk."; - statusColor = COLOR_GREEN; - } - ImGui::SameLine(); - if (ImGui::Button("Reset List")) { - splitItem.clear(); - splitTime.clear(); - splitTokens = 0; - splitStatus.clear(); - splitPreviousBest.clear(); - status = "List has been reset"; - statusColor = COLOR_RED; } - UIWidgets::EnhancementCheckbox("Edit Splits", CVAR_ENHANCEMENT("TimeSplit.EnableEdits"), false); - UIWidgets::Tooltip("Allows removing items and clearing split data."); - ImGui::SameLine(); - UIWidgets::EnhancementCheckbox("Hide Tabs", CVAR_ENHANCEMENT("TimeSplit.EnableTabs"), false); - UIWidgets::Tooltip("Toggles he display of the Tabs at the top of the window."); - ImGui::SameLine(); - UIWidgets::EnhancementCheckbox("Active Tracking", CVAR_ENHANCEMENT("TimeSplit.EnableTracking"), false); - UIWidgets::Tooltip("Keeps Active Split in view for longer lists."); - ImGui::TextColored(statusColor, status.c_str()); - UIWidgets::PaddedSeparator(); -} -void TimeSplitColorTint() { - switch (itemNum) { - case BOSS_QUEEN_GOHMA: - pieceTint = COLOR_LIGHT_GREEN; - break; - case BOSS_KING_DODONGO: - pieceTint = COLOR_LIGHT_RED; - break; - case BOSS_BARINADE: - pieceTint = COLOR_LIGHT_BLUE; - break; - case BOSS_PHANTOM_GANON: - pieceTint = COLOR_GREEN; - break; - case BOSS_VOLVAGIA: - pieceTint = COLOR_RED; - break; - case BOSS_MORPHA: - pieceTint = COLOR_BLUE; - break; - case BOSS_BONGO_BONGO: - pieceTint = COLOR_PURPLE; - break; - case BOSS_TWINROVA: - pieceTint = COLOR_ORANGE; - break; - case BOSS_GANONDORF: - pieceTint = COLOR_GREY; - break; - case BOSS_GANON: - pieceTint = COLOR_YELLOW; - break; - default: - pieceTint = COLOR_WHITE; - break; - } -} - -void DrawTimeSplitSplits(){ - uint32_t loopCounter = 0; - uint32_t buttonID = 0; - ImGui::PushStyleColor(ImGuiCol_Header, colorChoice); - if (ImGui::CollapsingHeader("Time Split Options")) { - DrawTimeSplitOptions(); - } - ImGui::PopStyleColor(); - //List Removals - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.EnableEdits"), 0)) { - ImGui::BeginTable("Remove Entries", 4); - ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (28.0f * uiScale)); - ImGui::TableSetupColumn("Item Name"); - ImGui::TableSetupColumn("Current Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); - ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); - ImGui::TableHeadersRow(); - ImGui::TableNextColumn(); - for (int i = 0; i < splitItem.size(); i++) { - for (const auto& obj : splitObjects) { - if (obj.itemID == splitItem[i]) { - itemNum = obj.itemID; - itemImager = obj.itemImage; - itemNamer = obj.itemName; - TimeSplitColorTint(); - } - } - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.75f, 0.0f, 0.0f, 1.0f)); - // Item Image (Removal) - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), - ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { - uint32_t currentStatus = splitStatus[i]; - splitItem.erase(splitItem.begin() + i); - splitTime.erase(splitTime.begin() + i); - splitPreviousBest.erase(splitPreviousBest.begin() + i); - splitBest.erase(splitBest.begin() + i); - splitStatus.erase(splitStatus.begin() + i); - splitStatus[i] = currentStatus; - } - ImGui::TableNextColumn(); - // Item Name (Removal) - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f * uiScale)); - ImGui::AlignTextToFramePadding(); - if (itemNum == ITEM_SKULL_TOKEN) { - std::string skullText = itemNamer.c_str(); - skullText += " ("; - skullText += std::to_string(splitTokens).c_str(); - skullText += ")"; - ImGui::TextWrapped(skullText.c_str()); - } else { - ImGui::TextWrapped(itemNamer.c_str()); - } - ImGui::TableNextColumn(); - // Current Best (Removal) - needs work - if (splitBest[i] != 100000) { - if (splitBest[i] != splitPreviousBest[i]) { - if (ImGui::Button(std::string(formatTimestampTimeSplit(splitBest[i])).c_str(), ImVec2(85.0f, 30.0f))) { - splitBest[i] = 100000; - } - } else { - ImGui::TextColored(COLOR_WHITE, "No Change"); - } - - } else { - ImGui::TextColored(COLOR_RED, "No Data"); - } - ImGui::TableNextColumn(); - // Previous Best (Removal) - if (splitPreviousBest[i] != 0) { - if (ImGui::Button(std::string(formatTimestampTimeSplit(splitPreviousBest[i])).c_str(), ImVec2(85.0f, 30.0f))) { - splitPreviousBest[i] = 0; - } - } else { - ImGui::TextColored(COLOR_RED, "No Data"); - } - ImGui::PopStyleColor(); - ImGui::PopStyleVar(); - ImGui::TableNextColumn(); + if (action == ACTION_COLLECT) { + keys.clear(); + for (auto& data : saveFile.items()) { + keys.push_back(data.key()); } - ImGui::EndTable(); - } else { - totalPreviousBest = 0; - for (int i = 0; i < splitItem.size(); i++) { - totalPreviousBest += splitPreviousBest[i]; + if (keys.size() == 0) { + keys.push_back("No Saved Lists"); } - ImGui::TextColored(COLOR_YELLOW, (splitAttempt).c_str()); - ImGui::BeginChild("SplitTable", ImVec2(0.0f, ImGui::GetWindowHeight() - 128.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); - ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); - ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (27.0f * uiScale)); - ImGui::TableSetupColumn("Item Name"); - ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); - ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, (80.0f * uiScale)); - ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, (90.0f * uiScale)); - ImGui::TableHeadersRow(); - - for (auto& str : splitItem) { - ImGui::TableNextColumn(); - for (const auto& obj : splitObjects) { - if (obj.itemID == splitItem[loopCounter]) { - itemNum = obj.itemID; - itemImager = obj.itemImage; - itemNamer = obj.itemName; - TimeSplitColorTint(); - } - } - // Item Image - if (splitStatus[buttonID] == 2) { - ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.EnableTracking"), 0)) { - ImGui::SetScrollHereY(loopCounter * 0.01f); - } - } - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); - if (ImGui::ImageButton(std::to_string(buttonID).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemImager), - ImVec2(26.0f * uiScale, 26.0f *uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { - if (splitStatus[loopCounter] == 2) { - TimeSplitSkipSplit(loopCounter); - } - } - ImGui::PopStyleColor(); - if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { - ImGui::SetDragDropPayload("DragMove", &buttonID, sizeof(uint32_t)); + } +} - ImGui::Text("Move %s", itemNamer.c_str()); - ImGui::EndDragDropSource(); - } - if (ImGui::BeginDragDropTarget()) { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DragMove")) { - IM_ASSERT(payload->DataSize == sizeof(uint32_t)); - int nextIndex = *(const int*)payload->Data; - uint32_t draggedItem = splitItem[nextIndex]; - uint32_t draggedTime = splitTime[nextIndex]; - uint32_t draggedBest = splitBest[nextIndex]; - uint32_t draggedPreviousBest = splitPreviousBest[nextIndex]; - uint32_t draggedStatus = splitStatus[nextIndex]; - if (loopCounter < nextIndex) { - int v = 0; - int o = nextIndex - v - 1; - for (int i = loopCounter + 1; i < nextIndex + 1; ++i) { - splitItem[nextIndex - v] = splitItem[o]; - splitTime[nextIndex - v] = splitTime[o]; - splitBest[nextIndex - v] = splitBest[o]; - splitPreviousBest[nextIndex - v] = splitPreviousBest[o]; - splitStatus[nextIndex - v] = splitStatus[o]; - v++; - o--; - } - splitStatus[loopCounter] = 3; - } else { - int v = 0; - int o = nextIndex + v + 1; - for (int i = loopCounter - 1; i > nextIndex - 1; i--) { - splitItem[nextIndex + v] = splitItem[o]; - splitTime[nextIndex + v] = splitTime[o]; - splitBest[nextIndex + v] = splitBest[o]; - splitPreviousBest[nextIndex + v] = splitPreviousBest[o]; - splitStatus[nextIndex + v] = splitStatus[o]; - v++; - o++; +void TimeSplitsPopUpContext(uint32_t itemClicked) { + uint32_t rowIndex = 0; + ImGui::OpenPopup(std::to_string(itemClicked).c_str()); + auto it = popupList.find(itemClicked); + if (it != popupList.end()) { + if (ImGui::BeginPopup(std::to_string(itemClicked).c_str())) { + for (auto& popupID : it->second) { + auto findID = std::find_if(splitObjectList.begin(), splitObjectList.end(), + [popupID](const SplitObject& obj) { + return obj.splitID == popupID; + }); + + if (findID != splitObjectList.end()) { + SplitObject& popupObject = *findID; + if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(popupObject.splitImage), + ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0), popupObject.splitTint)) { + splitList.push_back(popupObject); + if (splitList.size() == 1) { + splitList[0].splitTimeStatus = SPLIT_ACTIVE; + } else { + splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; } - splitStatus[loopCounter] = 0; + ImGui::CloseCurrentPopup(); + displayPopup = false; } - splitItem[loopCounter] = draggedItem; - splitTime[loopCounter] = draggedTime; - splitBest[loopCounter] = draggedBest; - splitPreviousBest[loopCounter] = draggedPreviousBest; - splitStatus[loopCounter] = draggedStatus; - for (int i = 0; i < splitItem.size(); i++) { - if (splitStatus[i] != 1) { - splitStatus[i] = 2; - for (int v = i + 1; v < splitItem.size(); v++) { - if (splitStatus[v] != 1){ - splitStatus[v] = 0; - } - } - i = splitItem.size() - 1; - } - } - } - ImGui::EndDragDropTarget(); - } - ImGui::TableNextColumn(); - // Item Name - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f * uiScale)); - ImGui::AlignTextToFramePadding(); - if (itemNum == ITEM_SKULL_TOKEN) { - std::string skullText = itemNamer.c_str(); - skullText += " ("; - skullText += std::to_string(splitTokens).c_str(); - skullText += ")"; - ImGui::TextWrapped(skullText.c_str()); - } else { - ImGui::TextWrapped(itemNamer.c_str()); - } - ImGui::TableNextColumn(); - if (splitStatus[loopCounter] == 2) { - // Current Time (Active) - if (splitTime[loopCounter] != 1) { - ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else { - ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); - } - ImGui::TableNextColumn(); - // +/- (active) - if (splitPreviousBest[loopCounter] == 0) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else { - if (GAMEPLAYSTAT_TOTAL_TIME < splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_LIGHT_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - GAMEPLAYSTAT_TOTAL_TIME).c_str()); - } else if (GAMEPLAYSTAT_TOTAL_TIME == splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); - } else if (GAMEPLAYSTAT_TOTAL_TIME > splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_LIGHT_RED, formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME - splitPreviousBest[loopCounter]).c_str()); - } - } - ImGui::TableNextColumn(); - // Previous Best (Active) - ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); - } else if (splitStatus[loopCounter] == 1) { - // Current (Collected) - ImGui::Text(formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); - ImGui::TableNextColumn(); - // +/- (Collected) - if (splitPreviousBest[loopCounter] == 0) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter]).c_str()); - } else { - if (splitTime[loopCounter] < splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_GREEN, formatTimestampTimeSplit(splitPreviousBest[loopCounter] - splitTime[loopCounter]).c_str()); - } else if (splitTime[loopCounter] == splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_WHITE, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); - } else if (splitTime[loopCounter] > splitPreviousBest[loopCounter]) { - ImGui::TextColored(COLOR_RED, formatTimestampTimeSplit(splitTime[loopCounter] - splitPreviousBest[loopCounter]).c_str()); + if (rowIndex != 5) { + ImGui::SameLine(); } + rowIndex++; } - ImGui::TableNextColumn(); - // Previous Best (Collected) - ImGui::Text(formatTimestampTimeSplit(splitPreviousBest[loopCounter]).c_str()); - } else { - // Current Time (Inactive) - ImGui::Text("-:--:--.-"); - ImGui::TableNextColumn(); - // +/- (Inactive) - ImGui::Text("-:--:--.-"); - ImGui::TableNextColumn(); - // Previous Best (Inactive) - ImGui::Text("-:--:--.-"); } - ImGui::PopStyleVar(); - loopCounter++; - buttonID++; + ImGui::EndPopup(); } - ImGui::EndTable(); - ImGui::PopStyleVar(); - ImGui::EndChild(); - UIWidgets::PaddedSeparator(); - ImGui::SetCursorPosX(ImGui::GetWindowWidth() - - ImGui::CalcTextSize(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()).x - - ImGui::CalcTextSize(formatTimestampTimeSplit(totalPreviousBest).c_str()).x - (60 * uiScale)); - ImGui::Text(formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str()); - ImGui::SameLine(); - ImGui::Text(" / "); - ImGui::SameLine(); - if (splitItem.size() > 0) { - uint32_t lastIndex = splitItem.size() - 1; - ImGui::Text(formatTimestampTimeSplit(splitTime[lastIndex]).c_str()); + } else { + auto findID = std::find_if(splitObjectList.begin(), splitObjectList.end(), + [itemClicked](const SplitObject& obj) { + return obj.splitID == popupID; + }); + SplitObject& popupObject = *findID; + splitList.push_back(popupObject); + if (splitList.size() == 1) { + splitList[0].splitTimeStatus = SPLIT_ACTIVE; } else { - ImGui::Text(formatTimestampTimeSplit(totalPreviousBest).c_str()); + splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; } + displayPopup = false; } } -void InitializeSplitFile() { - if (!std::filesystem::exists("splitdata.json")) { - json j; - std::ofstream file("splitdata.json"); - file << j.dump(4); - file.close(); - } -} - -static bool initialized = false; - -void TimeSplitAddToSplits(uint32_t itemToAdd) { - std::string itemStatus; - for (const auto& obj : splitObjects) { - if (obj.itemID == itemToAdd) { - itemStatus = obj.itemName; - } - } - splitItem.push_back(itemToAdd); - splitTime.push_back(0); - splitPreviousBest.push_back(0); - splitBest.push_back(0); - if (splitItem.size() == 1) { - splitStatus.push_back(2); - } else { - splitStatus.push_back(0); - } - statusColor = COLOR_GREEN; - status = itemStatus + std::string(" added to list"); -} - -void DrawTimeSplitListManager() { - ImGui::Text("List Preview"); - if (splitItem.size() == 0) { - ImGui::BeginTable("Current List", 1); - } else { - ImGui::BeginTable("Current List", splitItem.size(), 0, ImVec2(2400.0f, 0.0f)); - for (int i = 0; i < splitItem.size(); i++) { - if (i < 8) { - ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, (35.0f * uiScale)); - } - } - ImGui::TableNextColumn(); - } - for (int i = 0; i < splitItem.size(); i++) { - for (auto& obj : splitObjects) { - if (splitItem[i] == obj.itemID) { - itemNum = obj.itemID; - TimeSplitColorTint(); - ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint); - } - } - - if (i != 0 && (i + 1) % 8 == 0) { - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); - } else { - ImGui::TableNextColumn(); - } - } - ImGui::EndTable(); - UIWidgets::PaddedSeparator(); - ImGui::BeginChild("AddtoList"); - if (ImGui::CollapsingHeader("Equipment & Quest Status")) { - ImGui::BeginTable("Equipment", 3); - for (int i = 0; i < 3; i++) { - ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - } - ImGui::TableNextColumn(); - for (int i = 0; i < 12; i++) { - if (i == 4 || i == 8) { - ImGui::TableNextColumn(); - } - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(equipmentObjects[i].itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (equipmentObjects[i].itemID == ITEM_BRACELET) { - ImGui::OpenPopup("Strength"); - } else if (equipmentObjects[i].itemID == ITEM_SCALE_SILVER) { - ImGui::OpenPopup("Scale"); - } else { - TimeSplitAddToSplits(equipmentObjects[i].itemID); - } - } - } - if (ImGui::BeginPopupContextItem("Strength")) { - for (int i = ITEM_BRACELET; i <= ITEM_GAUNTLETS_GOLD; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); +void TimeSplitsItemSplitEvent(u8 item) { + uint32_t index = 0; + if (item == ITEM_NUTS_5 || item == ITEM_NUTS_10) { + item = ITEM_NUT; + } else if (item == ITEM_STICKS_5 || item == ITEM_STICKS_10) { + item = ITEM_STICK; + } + if (item == ITEM_SKULL_TOKEN) { + auto it = std::find_if(splitList.begin(), splitList.end(), [item](const SplitObject& split) { + if (split.splitSkullTokenCount == gSaveContext.inventory.gsTokens + 1) { + return split.splitID == item; + } + }); + if (it == splitList.end()) { + return; + } + } + + for (auto& split : splitList) { + if (split.splitType == SPLIT_ITEM) { + if (item == split.splitID) { + if (split.splitTimeStatus == SPLIT_ACTIVE) { + split.splitTimeCurrent = GAMEPLAYSTAT_TOTAL_TIME; + split.splitTimeStatus = SPLIT_COLLECTED; + if (split.splitTimeBest > GAMEPLAYSTAT_TOTAL_TIME || split.splitTimeBest == 0) { + split.splitTimeBest = GAMEPLAYSTAT_TOTAL_TIME; } - } - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Scale")) { - for (int i = ITEM_SCALE_SILVER; i <= ITEM_SCALE_GOLDEN; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); + if (split.splitTimePreviousBest == 0) { + split.splitTimePreviousBest = GAMEPLAYSTAT_TOTAL_TIME; + } + if (index == splitList.size() - 1) { + // Completed List + TimeSplitCompleteSplits(); + } else { + splitList[index + 1].splitTimeStatus = SPLIT_ACTIVE; } } } - ImGui::EndPopup(); - } - ImGui::EndTable(); - ImGui::SameLine(129.0f * uiScale); - - ImGui::BeginTable("Quest", 6); - for (int i = 0; i < 6; i++) { - ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - } - ImGui::TableNextColumn(); - for (int i = 0; i < 24; i++) { - if (i == 4 || i == 8 || i == 12 || i == 16 || i == 20) { - ImGui::TableNextColumn(); - } - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(questObjects[i].itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (questObjects[i].itemID == ITEM_SKULL_TOKEN) { - ImGui::OpenPopup("Skull Count"); - } else { - TimeSplitAddToSplits(questObjects[i].itemID); - } - } - } - if (ImGui::BeginPopupContextItem("Skull Count")) { - UIWidgets::PaddedEnhancementSliderInt("Skulltula Count: %d Tokens", "##splitToken", CVAR_ENHANCEMENT("TimeSplit.SkullTokens"), 0, 100, "", 0, true, true, false); - if (ImGui::Button("Set", ImVec2(30.0f, 20.0f))) { - splitTokens = CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.SkullTokens"), 0); - TimeSplitAddToSplits(ITEM_SKULL_TOKEN); - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); } - ImGui::EndTable(); + index++; } - if (ImGui::CollapsingHeader("Inventory")) { - ImGui::BeginTable("Inventory", 6); - for (int i = 0; i < 6; i++) { - ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed, (35.0f * uiScale)); - } - ImGui::TableNextColumn(); - for (int i = 0; i < 24; i++) { - if (i == 4 || i == 8 || i == 12 || i == 16 || i == 20) { - ImGui::TableNextColumn(); - } - if (ImGui::ImageButton(std::to_string(i).c_str(), - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(inventoryObjects[i].itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - if (inventoryObjects[i].itemID == ITEM_STICK) { - //ImGui::OpenPopup("Stick"); - TimeSplitAddToSplits(inventoryObjects[i].itemID); - } else if (inventoryObjects[i].itemID == ITEM_SLINGSHOT) { - ImGui::OpenPopup("Slingshot"); - } else if (inventoryObjects[i].itemID == ITEM_NUT) { - //ImGui::OpenPopup("Nut"); - TimeSplitAddToSplits(inventoryObjects[i].itemID); - } else if (inventoryObjects[i].itemID == ITEM_OCARINA_FAIRY) { - ImGui::OpenPopup("Ocarina"); - } else if (inventoryObjects[i].itemID == ITEM_BOMB) { - ImGui::OpenPopup("Bomb"); - } else if (inventoryObjects[i].itemID == ITEM_BOW) { - ImGui::OpenPopup("Bow"); - } else if (inventoryObjects[i].itemID == ITEM_HOOKSHOT) { - ImGui::OpenPopup("Hookshot"); - } else if (inventoryObjects[i].itemID == ITEM_BOTTLE) { - ImGui::OpenPopup("Bottles"); - } else if (inventoryObjects[i].itemID == ITEM_SINGLE_MAGIC) { - ImGui::OpenPopup("Magic"); - } else if (inventoryObjects[i].itemID == ITEM_WALLET_ADULT) { - ImGui::OpenPopup("Wallet"); - } else if (inventoryObjects[i].itemID == ITEM_POCKET_EGG) { - ImGui::OpenPopup("AdultTrade"); - } else if (inventoryObjects[i].itemID == ITEM_WEIRD_EGG) { - ImGui::OpenPopup("ChildTrade"); - } else { - TimeSplitAddToSplits(inventoryObjects[i].itemID); - } - } - } - if (ImGui::BeginPopupContextItem("Stick")) { - for (int i = ITEM_STICK; i <= ITEM_STICK_UPGRADE_30; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); +} + +void TimeSplitsBossSplitEvent(Actor* actor) { + uint32_t index = 0; + for (auto& split : splitList) { + if (split.splitType == SPLIT_BOSS) { + if (actor->id == split.splitID) { + if (split.splitTimeStatus == SPLIT_ACTIVE) { + split.splitTimeCurrent = GAMEPLAYSTAT_TOTAL_TIME; + split.splitTimeStatus = SPLIT_COLLECTED; + if (split.splitTimeBest > GAMEPLAYSTAT_TOTAL_TIME || split.splitTimeBest == 0) { + split.splitTimeBest = GAMEPLAYSTAT_TOTAL_TIME; } - } - if (i == ITEM_STICK) { - i = (ITEM_STICK_UPGRADE_20 - 1); - } - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Slingshot")) { - for (int i = ITEM_SLINGSHOT; i <= ITEM_BULLET_BAG_50; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); + if (split.splitTimePreviousBest == 0) { + split.splitTimePreviousBest = GAMEPLAYSTAT_TOTAL_TIME; } - } - if (i == ITEM_SLINGSHOT) { - i = (ITEM_BULLET_BAG_40 - 1); - } - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Nut")) { - for (int i = ITEM_NUT; i <= ITEM_NUT_UPGRADE_40; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); + if (index == splitList.size() - 1) { + // Completed List + TimeSplitCompleteSplits(); + } else { + splitList[index + 1].splitTimeStatus = SPLIT_ACTIVE; } } - if (i == ITEM_NUT) { - i = (ITEM_NUT_UPGRADE_30 - 1); - } } - ImGui::EndPopup(); } - if (ImGui::BeginPopupContextItem("Ocarina")) { - for (int i = ITEM_OCARINA_FAIRY; i <= ITEM_OCARINA_TIME; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); + index++; + } +} + +void TimeSplitsSceneSplitEvent(int16_t scene) { + uint32_t setType = SPLIT_ENTRANCE; + + if ((scene == SCENE_ZORAS_RIVER && gSaveContext.entranceIndex == ENTR_ZORAS_RIVER_4) || + (scene == SCENE_LOST_WOODS && (gSaveContext.entranceIndex == ENTR_LOST_WOODS_9 || + gSaveContext.entranceIndex == ENTR_LOST_WOODS_0)) || scene == SCENE_KAKARIKO_VILLAGE) { + setType = SPLIT_MISC; + } + + uint32_t index = 0; + for (auto& split : splitList) { + if (split.splitType == setType) { + if (scene == split.splitID) { + if (split.splitTimeStatus == SPLIT_ACTIVE) { + split.splitTimeCurrent = GAMEPLAYSTAT_TOTAL_TIME; + split.splitTimeStatus = SPLIT_COLLECTED; + if (split.splitTimeBest > GAMEPLAYSTAT_TOTAL_TIME || split.splitTimeBest == 0) { + split.splitTimeBest = GAMEPLAYSTAT_TOTAL_TIME; } - } - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Bomb")) { - for (int i = ITEM_BOMB_BAG_20; i <= ITEM_BOMB_BAG_40; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); + if (split.splitTimePreviousBest == 0) { + split.splitTimePreviousBest = GAMEPLAYSTAT_TOTAL_TIME; } - } - } - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextItem("Bow")) { - for (int i = ITEM_BOW; i <= ITEM_QUIVER_50; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); + if (index == splitList.size() - 1) { + // Completed List + TimeSplitCompleteSplits(); + } else { + splitList[index + 1].splitTimeStatus = SPLIT_ACTIVE; } } - if (i == ITEM_BOW) { - i = (ITEM_QUIVER_40 - 1); - } } - ImGui::EndPopup(); } - if (ImGui::BeginPopupContextItem("Hookshot")) { - for (int i = ITEM_HOOKSHOT; i <= ITEM_LONGSHOT; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - } - } - } - ImGui::EndPopup(); + index++; + } +} + +void TimeSplitsSplitBestTimeDisplay(uint32_t status, uint32_t currentBestTime, uint32_t previousBestTime) { + if (status == SPLIT_ACTIVE) { + if (GAMEPLAYSTAT_TOTAL_TIME > previousBestTime) { + splitTimeColor = COLOR_RED; + splitBestTimeDisplay = (GAMEPLAYSTAT_TOTAL_TIME - previousBestTime); } - if (ImGui::BeginPopupContextItem("Bottles")) { - for (int i = ITEM_BOTTLE; i <= ITEM_POE; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - if (i != ITEM_FISH) { - ImGui::SameLine(); - } - } - } - } - ImGui::EndPopup(); + if (GAMEPLAYSTAT_TOTAL_TIME == previousBestTime) { + splitTimeColor = COLOR_WHITE; + splitBestTimeDisplay = GAMEPLAYSTAT_TOTAL_TIME; } - if (ImGui::BeginPopupContextItem("Magic")) { - for (int i = ITEM_SINGLE_MAGIC; i <= ITEM_DOUBLE_MAGIC; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - } - } - } - ImGui::EndPopup(); + if (GAMEPLAYSTAT_TOTAL_TIME < previousBestTime) { + splitTimeColor = COLOR_GREEN; + splitBestTimeDisplay = (previousBestTime - GAMEPLAYSTAT_TOTAL_TIME); } - if (ImGui::BeginPopupContextItem("Wallet")) { - for (int i = ITEM_WALLET_ADULT; i <= ITEM_WALLET_GIANT; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - } - } - } - ImGui::EndPopup(); + } + if (status == SPLIT_INACTIVE) { + splitTimeColor = COLOR_WHITE; + splitBestTimeDisplay = currentBestTime; + } + if (status == SPLIT_COLLECTED) { + if (currentBestTime > previousBestTime) { + splitTimeColor = COLOR_RED; } - if (ImGui::BeginPopupContextItem("AdultTrade")) { - for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - if (i != ITEM_SAW) { - ImGui::SameLine(); - } - } - } - } - ImGui::EndPopup(); + if (currentBestTime == previousBestTime) { + splitTimeColor = COLOR_WHITE; } - if (ImGui::BeginPopupContextItem("ChildTrade")) { - for (int i = ITEM_WEIRD_EGG; i <= ITEM_MASK_TRUTH; i++) { - for (auto& obj : splitObjects) { - if (obj.itemID == i) { - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(obj.itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(i); - ImGui::CloseCurrentPopup(); - } - if (i != ITEM_MASK_SPOOKY) { - ImGui::SameLine(); - } - } - } - } - ImGui::EndPopup(); + if (currentBestTime < previousBestTime) { + splitTimeColor = COLOR_GREEN; } - ImGui::EndTable(); + splitBestTimeDisplay = currentBestTime; } - // SPACE SAVE FOR MISC ITEMS (12 SLOTS/3 COLUMNS x4) - if (ImGui::CollapsingHeader("Bosses")) { - ImGui::BeginTable("Bosses", 2); - ImGui::TableSetupColumn("Boss1", ImGuiTableColumnFlags_WidthFixed, (150.0f * uiScale)); - ImGui::TableSetupColumn("Boss2", ImGuiTableColumnFlags_WidthFixed, (150.0f * uiScale)); +} + +void TimeSplitsDrawSplitsList() { + ImGui::BeginChild("SplitTable", ImVec2(0.0f, ImGui::GetWindowHeight() - 128.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 0)); + ImGui::BeginTable("Splits", 5, ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 27.0f); + ImGui::TableSetupColumn("Item Name"); + ImGui::TableSetupColumn("Current Time", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableSetupColumn("+/-", ImGuiTableColumnFlags_WidthFixed, 80.0f); + ImGui::TableSetupColumn("Prev. Best", ImGuiTableColumnFlags_WidthFixed, 90.0f); + ImGui::TableHeadersRow(); + + for (auto& split : splitList) { ImGui::TableNextColumn(); - for (int i = 0; i < 10; i++) { - if (i == 5) { - ImGui::TableNextColumn(); - } - itemNum = bossObjects[i].itemID; - TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(bossObjects[i].itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), pieceTint)) { - TimeSplitAddToSplits(bossObjects[i].itemID); + ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(split.splitImage), + ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0), split.splitTint); + ImGui::TableNextColumn(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 7.0f)); + ImGui::AlignTextToFramePadding(); + ImGui::Text(split.splitName.c_str()); + ImGui::TableNextColumn(); + // Current Time + ImGui::Text((split.splitTimeStatus == SPLIT_ACTIVE) + ? formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str() : (split.splitTimeStatus == SPLIT_COLLECTED) + ? formatTimestampTimeSplit(split.splitTimeCurrent).c_str() : "--:--:-"); + ImGui::TableNextColumn(); + // +/- Difference + TimeSplitsSplitBestTimeDisplay(split.splitTimeStatus, split.splitTimeBest, split.splitTimePreviousBest); + ImGui::TextColored(splitTimeColor, formatTimestampTimeSplit(splitBestTimeDisplay).c_str()); + ImGui::TableNextColumn(); + // Previous Best + ImGui::Text((split.splitTimePreviousBest != 0) ? formatTimestampTimeSplit(split.splitTimePreviousBest).c_str() : "--:--:-"); + ImGui::PopStyleVar(1); + } + ImGui::PopStyleVar(); + ImGui::EndTable(); + ImGui::EndChild(); +} + +void TimeSplitsDrawItemList(uint32_t type) { + ImGui::BeginChild("Item Child"); + ImGui::BeginTable("Item List", 2); + ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 27.0f); + ImGui::TableSetupColumn("Item Name"); + + for (auto& split : splitObjectList) { + if (split.splitType == type) { + ImGui::TableNextColumn(); + ImGui::PushID(split.splitID); + if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(split.splitImage), + ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0), split.splitTint)) { + popupID = split.splitID; + displayPopup = true; } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); + ImGui::PopID(); + ImGui::TableNextColumn(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 7.0f)); ImGui::AlignTextToFramePadding(); - ImGui::Text(bossObjects[i].itemName); + ImGui::Text(split.splitName.c_str()); ImGui::PopStyleVar(1); } - ImGui::EndTable(); } - if (ImGui::CollapsingHeader("Scenes")) { - if (ImGui::CollapsingHeader("Dungeon Entrances")) { - ImGui::BeginTable("Dungeons", 2); - ImGui::TableSetupColumn("Dungeon1", ImGuiTableColumnFlags_WidthFixed, (220.0f * uiScale)); - ImGui::TableSetupColumn("Dungeon2", ImGuiTableColumnFlags_WidthFixed, (220.0f * uiScale)); - ImGui::TableNextColumn(); - for (int i = 0; i < 16; i++) { - if (i == 8) { - ImGui::TableNextColumn(); - } - //itemNum = sceneObjects[i].itemID; - //TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(sceneObjects[i].itemID); - } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); - ImGui::AlignTextToFramePadding(); - ImGui::TextWrapped(sceneObjects[i].itemName); - ImGui::PopStyleVar(1); + ImGui::EndTable(); + ImGui::EndChild(); +} + +void TimeSplitsDrawOptionsMenu() { + ImGui::SeparatorText("Background Color"); + if (ImGui::ColorEdit4("Background Color", (float*)&windowColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { + Color_RGBA8 color; + color.r = windowColor.x; + color.g = windowColor.y; + color.b = windowColor.z; + color.a = windowColor.w; + } + ImGui::SameLine(); + if (ImGui::Button("Reset")) { + windowColor = { 0.0f, 0.0f, 0.0f, 1.0f }; + } + //UIWidgets::PaddedEnhancementCheckbox("Set Last Split as Goal", CVAR_SETTING("TimesplitGoal")); + + ImGui::SeparatorText("Split List Management"); + ImGui::Text("New List Name: "); + ImGui::PushItemWidth(100.0f); + ImGui::InputText("##listName", listNameBuf, 25); + ImGui::PopItemWidth(); + ImGui::SameLine(); + if (ImGui::Button("Create List")) { + TimeSplitsFileManagement(ACTION_SAVE, listNameBuf, splitList); + } + UIWidgets::PaddedSeparator(); + + TimeSplitsFileManagement(ACTION_COLLECT, "", emptyList); + static uint32_t selectedItem = 0; + static std::string listItem = keys[0]; + ImGui::Text("Select List to Load: "); + ImGui::PushItemWidth(150.0f); + if (ImGui::BeginCombo("##listEntries", keys[selectedItem].c_str())) { + for (int i = 0; i < keys.size(); i++) { + bool isSelected = (selectedItem == i); + if (ImGui::Selectable(keys[i].c_str(), isSelected)) { + selectedItem = i; + listItem = keys[i].c_str(); } - ImGui::EndTable(); - } - if (ImGui::CollapsingHeader("Overworld Entrances")) { - ImGui::BeginTable("Overworld", 1); - ImGui::TableSetupColumn("Overworld1", ImGuiTableColumnFlags_WidthFixed, (220.0f * uiScale)); - ImGui::TableNextColumn(); - for (int i = 16; i <= 18; i++) { - //itemNum = obj.itemID; - //TimeSplitColorTint(); - if (ImGui::ImageButton(std::to_string(i).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(sceneObjects[i].itemImage), - ImVec2(32.0f * uiScale, 32.0f * uiScale), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { - TimeSplitAddToSplits(sceneObjects[i].itemID); - } - ImGui::SameLine(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); - ImGui::AlignTextToFramePadding(); - ImGui::TextWrapped(sceneObjects[i].itemName); - ImGui::PopStyleVar(1); + if (isSelected) { + ImGui::SetItemDefaultFocus(); } - ImGui::EndTable(); } + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); + ImGui::SameLine(); + if (ImGui::Button("Load List")) { + TimeSplitsFileManagement(ACTION_LOAD, keys[selectedItem].c_str(), emptyList); + lastLoadedlistName = keys[selectedItem].c_str(); + } + UIWidgets::PaddedSeparator(); + + if (ImGui::Button("Update Splits")) { + TimeSplitsFileManagement(ACTION_UPDATE, lastLoadedlistName, splitList); + } + ImGui::SameLine(); + if (ImGui::Button("Save List")) { + TimeSplitsFileManagement(ACTION_SAVE, lastLoadedlistName, splitList); + } +} + +void TimeSplitsDrawManageList() { + ImGui::BeginTabBar("List Options"); + if (ImGui::BeginTabItem("Inventory")) { + TimeSplitsDrawItemList(SPLIT_ITEM); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Entrances")) { + TimeSplitsDrawItemList(SPLIT_ENTRANCE); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Bosses")) { + TimeSplitsDrawItemList(SPLIT_BOSS); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Miscellaneous")) { + TimeSplitsDrawItemList(SPLIT_MISC); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); +} + +// NEW END + +void InitializeSplitDataFile() { + if (!std::filesystem::exists("timesplitdata.json")) { + json j; + std::ofstream file("timesplitdata.json"); + file << j.dump(4); + file.close(); } - ImGui::EndChild(); } +static bool initialized = false; + void TimeSplitWindow::DrawElement() { if (!initialized) { - InitializeSplitFile(); + InitializeSplitDataFile(); initialized = true; } - if (CVarGetInteger("gImGuiScale", 0)) { - uiScale = CVarGetInteger("gImGuiScale", 0); - } else { - uiScale = 1; + if (displayPopup) { + TimeSplitsPopUpContext(popupID); } - - ImGui::PushStyleColor(ImGuiCol_WindowBg, colorChoice); + + ImGui::PushStyleColor(ImGuiCol_WindowBg, windowColor); if (!ImGui::Begin("Time Splitter Window", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { ImGui::End(); ImGui::PopStyleColor(1); return; } - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSplit.EnableTabs"), 0)) { - DrawTimeSplitSplits(); - } else { - ImGui::BeginTabBar("Split Tabs"); - if (ImGui::BeginTabItem("Splits")) { - DrawTimeSplitSplits(); - ImGui::EndTabItem(); - } - if (ImGui::BeginTabItem("Manage List")) { - ImGui::TextColored(statusColor, status.c_str()); - UIWidgets::PaddedSeparator(); - ImGui::BeginChild("Add Items"); - DrawTimeSplitListManager(); - ImGui::EndChild(); - ImGui::EndTabItem(); - } - ImGui::EndTabBar(); + ImGui::BeginTabBar("Split Tabs"); + if (ImGui::BeginTabItem("Splits")) { + TimeSplitsDrawSplitsList(); + ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("Manage List")) { + TimeSplitsDrawManageList(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Options")) { + TimeSplitsDrawOptionsMenu(); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); ImGui::End(); ImGui::PopStyleColor(); } @@ -1437,10 +724,27 @@ void TimeSplitWindow::DrawElement() { void TimeSplitWindow::InitElement() { Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_TRIFORCE_PIECE_WHITE", gWTriforcePieceTex, ImVec4(1, 1, 1, 1)); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("SPECIAL_SPLIT_ENTRANCE", gSplitEntranceTex, ImVec4(1, 1, 1, 1)); - GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { - TimeSplitSplitsHandler(itemEntry); + + GameInteractor::Instance->RegisterGameHook([](u8 item) { + TimeSplitsItemSplitEvent(item); }); - GameInteractor::Instance->RegisterGameHook([]() { - TimeSplitSceneSplitHandler(gSaveContext.entranceIndex); + + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + TimeSplitsBossSplitEvent((Actor*)refActor); + }); + + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + if (gPlayState->sceneNum != SCENE_KAKARIKO_VILLAGE) { + TimeSplitsSceneSplitEvent(sceneNum); + } + }); + + GameInteractor::Instance->RegisterGameHook([](int16_t amount) { + if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE) { + Player* player = GET_PLAYER(gPlayState); + if (player->fallDistance > 500 && gSaveContext.health <= 0) { + TimeSplitsSceneSplitEvent(gPlayState->sceneNum); + } + } }); } \ No newline at end of file diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index 4085878cb99..c208b4c3eae 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -8,9 +8,6 @@ extern "C" { #endif -void TimeSplitSplitsHandlerS(uint32_t itemID); -void TimeSplitSceneSplitHandler(uint32_t entrance); - #ifdef __cplusplus } #endif @@ -28,45 +25,38 @@ class TimeSplitWindow : public Ship::GuiWindow { void DrawElement() override; void UpdateElement() override{}; }; -#endif -typedef struct { - uint32_t itemID; - const char* itemName; - const char* itemImage; -} TimeSplitObject; +typedef enum { + ACTION_SAVE, + ACTION_LOAD, + ACTION_UPDATE, + ACTION_COLLECT +}; typedef enum { - BOSS_QUEEN_GOHMA = 657, - BOSS_KING_DODONGO, - BOSS_BARINADE, - BOSS_PHANTOM_GANON, - BOSS_VOLVAGIA, - BOSS_MORPHA, - BOSS_TWINROVA, - BOSS_BONGO_BONGO, - BOSS_GANONDORF, - BOSS_GANON + SPLIT_ACTIVE, + SPLIT_INACTIVE, + SPLIT_COLLECTED }; typedef enum { - ENTER_DEKU_TREE = 667, - ENTER_DODONGOS_CAVERN, - ENTER_JABU_JABU, - ENTER_FOREST_TEMPLE, - ENTER_FIRE_TEMPLE, - ENTER_WATER_TEMPLE, - ENTER_SPIRIT_TEMPLE, - ENTER_SHADOW_TEMPLE, - ENTER_BOTTOM_OF_THE_WELL, - ENTER_ICE_CAVERN, - ENTER_GANONS_TOWER, - ENTER_GERUDO_TRAINING_GROUND, - ENTER_THIEVES_HIDEOUT, - ENTER_INSIDE_GANONS_CASTLE, - ENTER_GANONS_TOWER_COLLAPSE_INTERIOR, - ENTER_INSIDE_GANONS_CASTLE_COLLAPSE, - ESCAPE_KOKIRI_FOREST = 286, - ESCAPE_LOST_WOODS = 477, - WATCHTOWER_DEATH = 513 -}; \ No newline at end of file + SPLIT_ITEM, + SPLIT_BOSS, + SPLIT_ENTRANCE, + SPLIT_MISC +}; + +typedef struct { + uint32_t splitType; + uint32_t splitID; + std::string splitName; + std::string splitImage; + ImVec4 splitTint; + uint32_t splitTimeCurrent; + uint32_t splitTimeBest; + uint32_t splitTimePreviousBest; + uint32_t splitTimeStatus; + uint32_t splitSkullTokenCount; +} SplitObject; + +#endif diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 0bb6ef5fdb2..dabefdffc7f 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -22,8 +22,6 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" -#include "soh/Enhancements/timesplits/TimeSplits.h" - #define DO_ACTION_TEX_WIDTH() 48 #define DO_ACTION_TEX_HEIGHT() 16 #define DO_ACTION_TEX_SIZE() ((DO_ACTION_TEX_WIDTH() * DO_ACTION_TEX_HEIGHT()) / 2) @@ -1846,6 +1844,7 @@ void GameplayStats_SetTimestamp(PlayState* play, u8 item) { } gSaveContext.sohStats.itemTimestamp[item] = time; + GameInteractor_ExecuteOnTimestamp(item); } // Gameplay stat tracking: Update time the item was acquired @@ -3116,9 +3115,6 @@ void Inventory_UpdateBottleItem(PlayState* play, u8 item, u8 button) { play->pauseCtx.cursorItem[PAUSE_ITEM] = item; gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(button)] = BTN_ENABLED; - if (item != ITEM_BOTTLE) { - TimeSplitSplitsHandlerS(item); - } } s32 Inventory_ConsumeFairy(PlayState* play) { @@ -3323,6 +3319,8 @@ s32 Health_ChangeBy(PlayState* play, s16 healthChange) { } } + GameInteractor_ExecuteOnPlayerHealthChange(healthChange); + // "Life=%d *** %d ******" osSyncPrintf(" ライフ=%d *** %d ******\n", gSaveContext.health, healthLevel); diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index 60568312501..799a46c62a4 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -13,8 +13,6 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/Enhancements/timesplits/TimeSplits.h" - #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) typedef enum { @@ -222,19 +220,16 @@ void BgDyYoseizo_ChooseType(BgDyYoseizo* this, PlayState* play) { switch (this->fountainType) { case FAIRY_SPELL_FARORES_WIND: if (!Flags_GetItemGetInf(ITEMGETINF_18)) { - TimeSplitSplitsHandlerS(ITEM_FARORES_WIND); givingReward = true; } break; case FAIRY_SPELL_DINS_FIRE: if (!Flags_GetItemGetInf(ITEMGETINF_19)) { - TimeSplitSplitsHandlerS(ITEM_DINS_FIRE); givingReward = true; } break; case FAIRY_SPELL_NAYRUS_LOVE: if (!Flags_GetItemGetInf(ITEMGETINF_1A)) { - TimeSplitSplitsHandlerS(ITEM_NAYRUS_LOVE); givingReward = true; } break; @@ -729,7 +724,6 @@ void BgDyYoseizo_Give_Reward(BgDyYoseizo* this, PlayState* play) { case FAIRY_UPGRADE_MAGIC: gSaveContext.isMagicAcquired = true; gSaveContext.magicFillTarget = MAGIC_NORMAL_METER; - TimeSplitSplitsHandlerS(ITEM_SINGLE_MAGIC); Interface_ChangeAlpha(9); break; case FAIRY_UPGRADE_DOUBLE_MAGIC: @@ -739,12 +733,10 @@ void BgDyYoseizo_Give_Reward(BgDyYoseizo* this, PlayState* play) { gSaveContext.isDoubleMagicAcquired = true; gSaveContext.magicFillTarget = MAGIC_DOUBLE_METER; gSaveContext.magicLevel = 0; - TimeSplitSplitsHandlerS(ITEM_DOUBLE_MAGIC); Interface_ChangeAlpha(9); break; case FAIRY_UPGRADE_HALF_DAMAGE: gSaveContext.isDoubleDefenseAcquired = true; - TimeSplitSplitsHandlerS(ITEM_DOUBLE_DEFENSE); Interface_ChangeAlpha(9); break; } diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c index 9a3c9acc7e7..621ed0e7fa3 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c @@ -8,8 +8,6 @@ #include "objects/object_toki_objects/object_toki_objects.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/Enhancements/timesplits/TimeSplits.h" - #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED void BgTokiSwd_Init(Actor* thisx, PlayState* play); @@ -130,7 +128,6 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) { if (!LINK_IS_ADULT) { if (GameInteractor_Should(VB_GIVE_ITEM_MASTER_SWORD, true)) { Item_Give(play, ITEM_SWORD_MASTER); - TimeSplitSplitsHandlerS(ITEM_SWORD_MASTER); } play->csCtx.segment = D_808BB2F0; } else { diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 85275ac6d11..66109ab44aa 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -31,7 +31,6 @@ #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/Enhancements/timesplits/TimeSplits.h" #include #include @@ -11433,8 +11432,6 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { : (this->bodyShockTimer != 0) ? &gPlayerAnim_link_normal_electric_shock_end : &gPlayerAnim_link_derth_rebirth); } - TimeSplitSceneSplitHandler(gSaveContext.entranceIndex); - } else { if ((this->actor.parent == NULL) && ((play->transitionTrigger == TRANS_TRIGGER_START) || (this->unk_A87 != 0) || !func_808382DC(this, play))) { From 1564540e7f2bcb8298ac25d9ea546596c20f0e05 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 17 Oct 2024 19:37:40 -0500 Subject: [PATCH 40/40] Working popup --- .../Enhancements/timesplits/TimeSplits.cpp | 87 ++++++++----------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index a4bedb68d8c..7c0fe935485 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -340,52 +340,33 @@ void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vecto } } -void TimeSplitsPopUpContext(uint32_t itemClicked) { - uint32_t rowIndex = 0; - ImGui::OpenPopup(std::to_string(itemClicked).c_str()); - auto it = popupList.find(itemClicked); - if (it != popupList.end()) { - if (ImGui::BeginPopup(std::to_string(itemClicked).c_str())) { - for (auto& popupID : it->second) { - auto findID = std::find_if(splitObjectList.begin(), splitObjectList.end(), - [popupID](const SplitObject& obj) { - return obj.splitID == popupID; - }); - - if (findID != splitObjectList.end()) { - SplitObject& popupObject = *findID; - if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(popupObject.splitImage), - ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0), popupObject.splitTint)) { - splitList.push_back(popupObject); - if (splitList.size() == 1) { - splitList[0].splitTimeStatus = SPLIT_ACTIVE; - } else { - splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; - } - ImGui::CloseCurrentPopup(); - displayPopup = false; - } - if (rowIndex != 5) { - ImGui::SameLine(); - } - rowIndex++; +void TimeSplitsPopUpContext() { + int rowIndex = 0; + if (ImGui::BeginPopup("TimeSplitsPopUp") && popupID) { + for (auto item : popupList[popupID]) { + auto findID = std::find_if(splitObjectList.begin(), splitObjectList.end(), [&](const SplitObject& obj) { return obj.splitID == item; }); + if (findID == splitObjectList.end()) { + continue; + } + + SplitObject& popupObject = *findID; + if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(popupObject.splitImage), + ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0), popupObject.splitTint)) { + splitList.push_back(popupObject); + if (splitList.size() == 1) { + splitList[0].splitTimeStatus = SPLIT_ACTIVE; + } else { + splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; } + ImGui::CloseCurrentPopup(); + displayPopup = false; } - ImGui::EndPopup(); - } - } else { - auto findID = std::find_if(splitObjectList.begin(), splitObjectList.end(), - [itemClicked](const SplitObject& obj) { - return obj.splitID == popupID; - }); - SplitObject& popupObject = *findID; - splitList.push_back(popupObject); - if (splitList.size() == 1) { - splitList[0].splitTimeStatus = SPLIT_ACTIVE; - } else { - splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; + if (rowIndex != 5) { + ImGui::SameLine(); + } + rowIndex++; } - displayPopup = false; + ImGui::EndPopup(); } } @@ -577,9 +558,21 @@ void TimeSplitsDrawItemList(uint32_t type) { ImGui::PushID(split.splitID); if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(split.splitImage), ImVec2(26.0f, 26.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0), split.splitTint)) { - popupID = split.splitID; - displayPopup = true; + + if (popupList.contains(split.splitID)) { + popupID = split.splitID; + ImGui::OpenPopup("TimeSplitsPopUp"); + } else { + splitList.push_back(split); + if (splitList.size() == 1) { + splitList[0].splitTimeStatus = SPLIT_ACTIVE; + } else { + splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; + } + } } + + TimeSplitsPopUpContext(); ImGui::PopID(); ImGui::TableNextColumn(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 7.0f)); @@ -693,10 +686,6 @@ void TimeSplitWindow::DrawElement() { initialized = true; } - if (displayPopup) { - TimeSplitsPopUpContext(popupID); - } - ImGui::PushStyleColor(ImGuiCol_WindowBg, windowColor); if (!ImGui::Begin("Time Splitter Window", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { ImGui::End();