diff options
| author | Caladius <Caladius@users.noreply.github.com> | 2024-05-06 17:53:57 -0400 |
|---|---|---|
| committer | Garrett Cox <garrettjcox@gmail.com> | 2024-05-22 09:05:03 -0500 |
| commit | db223d8d9547558fb956ffe82d4c5176c1b7d1e7 (patch) | |
| tree | 15aeaef967c928286cfb71a45eef393708b891c1 /mm/2s2h/DeveloperTools/SaveEditor.cpp | |
| parent | 5fe3e350fa6b72f2b7a16cf807600af3e1ec5e81 (diff) | |
Add Quest Status to Save Editor (#294)
* Quest SaveEditor Progress
* Quest Status tab implementation.
* Updated Bombers Notebook, songs, and tooltips
* Give All and Remove All buttons.
* Fixes from Review
* Bump LUS and use nlohmann json from package manager (#254)
* Handling of FD Link Form for Sword updates.
* Update mm/2s2h/DeveloperTools/SaveEditor.cpp
* Update mm/2s2h/DeveloperTools/SaveEditor.cpp
* Oops, missed comments
* Comments
* Fix some ship references
---------
Co-authored-by: Archez <Archez@users.noreply.github.com>
Co-authored-by: Garrett Cox <garrettjcox@gmail.com>
Diffstat (limited to 'mm/2s2h/DeveloperTools/SaveEditor.cpp')
| -rw-r--r-- | mm/2s2h/DeveloperTools/SaveEditor.cpp | 274 |
1 files changed, 269 insertions, 5 deletions
diff --git a/mm/2s2h/DeveloperTools/SaveEditor.cpp b/mm/2s2h/DeveloperTools/SaveEditor.cpp index daf1d5a03..4eeb95661 100644 --- a/mm/2s2h/DeveloperTools/SaveEditor.cpp +++ b/mm/2s2h/DeveloperTools/SaveEditor.cpp @@ -34,6 +34,8 @@ const char* MAGIC_LEVEL_NAMES[3] = { "No Magic", "Single Magic", "Double Magic" constexpr int8_t MAGIC_LEVEL_MAX = 2; const char* WALLET_LEVEL_NAMES[3] = { "Child Wallet", "Adult Wallet", "Giant Wallet" }; constexpr u8 WALLET_LEVEL_MAX = 2; +ImVec4 colorTint; +const char* songTooltip; InventorySlot selectedInventorySlot = SLOT_NONE; std::vector<ItemId> safeItemsForInventorySlot[SLOT_MASK_FIERCE_DEITY + 1] = {}; @@ -598,6 +600,268 @@ void DrawItemsAndMasksTab() { ImGui::PopStyleVar(2); } +void SongInfo(int32_t itemID) { + switch (itemID) { + case QUEST_SONG_SONATA: + colorTint = ImVec4(0.588f, 1.0f, 0.392f, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Sonata of Awakening"; + break; + case QUEST_SONG_LULLABY: + colorTint = ImVec4(1.0f, 0.313f, 0.156f, (CHECK_QUEST_ITEM(itemID) || CHECK_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO)) ? 1.0f : 0.4f); + songTooltip = (!CHECK_QUEST_ITEM(itemID) && CHECK_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO)) ? "Goron Lullaby Intro" : "Goron Lullaby"; + break; + case QUEST_SONG_BOSSA_NOVA: + colorTint = ImVec4(0.392f, 0.588f, 1.0f, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "New Wave Bossa Nova"; + break; + case QUEST_SONG_ELEGY: + colorTint = ImVec4(1.0f, 0.627f, 0.0f, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Elegy of Emptiness"; + break; + case QUEST_SONG_OATH: + colorTint = ImVec4(1.0f, 0.392f, 1.0f, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Oath to Order"; + break; + case QUEST_SONG_TIME: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Song of Time"; + break; + case QUEST_SONG_HEALING: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Song of Healing"; + break; + case QUEST_SONG_EPONA: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Eponas Song"; + break; + case QUEST_SONG_SOARING: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Song of Soaring"; + break; + case QUEST_SONG_STORMS: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Song of Storms"; + break; + case QUEST_SONG_SARIA: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Saria's Song (Unused?)"; + break; + case QUEST_SONG_SUN: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = "Sun's Song (Not Obtainable)"; + break; + default: + colorTint = ImVec4(1, 1, 1, CHECK_QUEST_ITEM(itemID) ? 1.0f : 0.4f); + songTooltip = " "; + break; + } +} + +std::map<QuestItem, ItemId>questToItemMap = { + { QUEST_REMAINS_ODOLWA, ITEM_REMAINS_ODOLWA }, + { QUEST_REMAINS_GOHT, ITEM_REMAINS_GOHT }, + { QUEST_REMAINS_GYORG, ITEM_REMAINS_GYORG }, + { QUEST_REMAINS_TWINMOLD, ITEM_REMAINS_TWINMOLD }, + { QUEST_SONG_SONATA, ITEM_SONG_SONATA }, + { QUEST_SONG_LULLABY, ITEM_SONG_LULLABY }, + { QUEST_SONG_BOSSA_NOVA, ITEM_SONG_NOVA }, + { QUEST_SONG_ELEGY, ITEM_SONG_ELEGY }, + { QUEST_SONG_OATH, ITEM_SONG_OATH }, + { QUEST_SONG_SARIA, ITEM_SONG_SARIA }, + { QUEST_SONG_TIME, ITEM_SONG_TIME }, + { QUEST_SONG_HEALING, ITEM_SONG_HEALING }, + { QUEST_SONG_EPONA, ITEM_SONG_EPONA }, + { QUEST_SONG_SOARING, ITEM_SONG_SOARING }, + { QUEST_SONG_STORMS, ITEM_SONG_STORMS }, + { QUEST_SONG_SUN, ITEM_SONG_SUN } +}; + +void NextQuestInSlot(QuestItem slot) { + if (!gPlayState) { + return; + } + Player* player = GET_PLAYER(gPlayState); + if (slot == QUEST_SONG_LULLABY || slot == QUEST_SONG_LULLABY_INTRO) { + if (CHECK_QUEST_ITEM(QUEST_SONG_LULLABY)) { + REMOVE_QUEST_ITEM(QUEST_SONG_LULLABY); + REMOVE_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO); + } else if (CHECK_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO)) { + SET_QUEST_ITEM(QUEST_SONG_LULLABY); + } else { + SET_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO); + } + } else if (slot == QUEST_SWORD) { + uint32_t currentSword = GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD); + if (GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) >= EQUIP_VALUE_SWORD_GILDED) { + SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); + } else { + SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, currentSword + 1); + } + BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_B) = ITEM_SWORD_KOKIRI + GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) - EQUIP_VALUE_SWORD_KOKIRI; + if (GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_RAZOR) { + gSaveContext.save.saveInfo.playerData.swordHealth = 100; + } + Interface_LoadItemIconImpl(gPlayState, EQUIP_SLOT_B); + } else if (slot == QUEST_SHIELD) { + uint32_t currentShield = GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD); + if (GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == 1) { + SET_EQUIP_VALUE(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); + } else { + SET_EQUIP_VALUE(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_HERO); + } + Player_SetEquipmentData(gPlayState, player); + } else { + if (CHECK_QUEST_ITEM(slot)) { + REMOVE_QUEST_ITEM(slot); + } else { + SET_QUEST_ITEM(slot); + } + } +} + +void DrawQuestSlot(QuestItem slot) { + int x = slot % 6; + int y = ((int)floor(slot / 6) % 4); + ImGui::PushID(slot); + + ImGui::SetCursorPos(ImVec2(x * INV_GRID_WIDTH + INV_GRID_PADDING, y * INV_GRID_HEIGHT + INV_GRID_TOP_MARGIN + INV_GRID_PADDING)); + + ImTextureID textureId = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName((const char*)gItemIcons[questToItemMap[slot]]); + if (ImGui::ImageButton(std::to_string(slot).c_str(), textureId, ImVec2(INV_GRID_ICON_SIZE, INV_GRID_ICON_SIZE), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, CHECK_QUEST_ITEM(slot) ? 1.0f : 0.4f))) { + NextQuestInSlot(slot); + } + + ImGui::PopID(); +} + +void DrawSong(QuestItem slot) { + SongInfo(slot); + if (ImGui::ImageButton(std::to_string(slot).c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName((const char*)gItemIcons[questToItemMap[(QuestItem)slot]]), + ImVec2(INV_GRID_ICON_SIZE / 1.5f, INV_GRID_ICON_SIZE), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), colorTint)) { + NextQuestInSlot(slot); + } + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text(songTooltip); + ImGui::EndTooltip(); + } + if (slot != QUEST_SONG_SUN) { + ImGui::SameLine(); + } +} + +void DrawQuestStatusTab() { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 3.0f); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8.0f, 8.0f)); + ImGui::BeginChild("questTab", ImVec2(0, 0), true); + + if (UIWidgets::Button("Give All##items", { .color = UIWidgets::Colors::Green, .size = UIWidgets::Sizes::Inline })) { + for (int32_t i = QUEST_REMAINS_ODOLWA; i <= QUEST_BOMBERS_NOTEBOOK; i++) { + if (i != QUEST_SHIELD && i != QUEST_SWORD) { + SET_QUEST_ITEM(i); + } + } + SET_EQUIP_VALUE(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); + if (GET_PLAYER_FORM != PLAYER_FORM_FIERCE_DEITY) { + SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_GILDED); + if (gPlayState) { + Player_SetEquipmentData(gPlayState, GET_PLAYER(gPlayState)); + BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_B) = ITEM_SWORD_KOKIRI + GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) - EQUIP_VALUE_SWORD_KOKIRI; + Interface_LoadItemIconImpl(gPlayState, EQUIP_SLOT_B); + } + } + } + ImGui::SameLine(); + if (UIWidgets::Button("Reset##items", { .color = UIWidgets::Colors::Red, .size = UIWidgets::Sizes::Inline })) { + for (int32_t i = QUEST_REMAINS_ODOLWA; i <= QUEST_BOMBERS_NOTEBOOK; i++) { + if (i != QUEST_SHIELD && i != QUEST_SWORD) { + REMOVE_QUEST_ITEM(i); + } + } + REMOVE_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO); + SET_EQUIP_VALUE(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_HERO); + if (GET_PLAYER_FORM != PLAYER_FORM_FIERCE_DEITY) { + SET_EQUIP_VALUE(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); + if (gPlayState) { + Player_SetEquipmentData(gPlayState, GET_PLAYER(gPlayState)); + BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_B) = ITEM_SWORD_KOKIRI + GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) - EQUIP_VALUE_SWORD_KOKIRI; + Interface_LoadItemIconImpl(gPlayState, EQUIP_SLOT_B); + } + } + + } + + ImGui::BeginChild("remainsBox", ImVec2(INV_GRID_WIDTH * 4 + INV_GRID_PADDING * 2, INV_GRID_HEIGHT * 1 + INV_GRID_PADDING * 2 + INV_GRID_TOP_MARGIN), ImGuiChildFlags_Border); + ImGui::Text("Boss Remains"); + for (int32_t i = QUEST_REMAINS_ODOLWA; i <= QUEST_REMAINS_TWINMOLD; i++) { + QuestItem slot = static_cast<QuestItem>(i); + + DrawQuestSlot(slot); + } + ImGui::EndChild(); + ImGui::BeginChild("songBox", ImVec2((INV_GRID_WIDTH / 1.1f) * 6 + INV_GRID_PADDING * 2, INV_GRID_HEIGHT * 2.15f + INV_GRID_PADDING * 1 + INV_GRID_TOP_MARGIN), ImGuiChildFlags_Border); + ImGui::Text("Songs"); + for (int32_t i = QUEST_SONG_TIME; i <= QUEST_SONG_SUN; i++) { + DrawSong((QuestItem)i); + } + for (int32_t i = QUEST_SONG_SONATA; i <= QUEST_SONG_SARIA; i++) { + DrawSong((QuestItem)i); + } + ImGui::EndChild(); + ImGui::BeginChild("equipBox", ImVec2(INV_GRID_WIDTH * 2.2 + INV_GRID_PADDING * 2, INV_GRID_HEIGHT * 1 + INV_GRID_PADDING * 2 + INV_GRID_TOP_MARGIN), ImGuiChildFlags_Border); + ImGui::Text("Equipment"); + if (GET_PLAYER_FORM == PLAYER_FORM_FIERCE_DEITY) { + ImTextureID swordTextureId = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName((const char*)gItemIcons[ITEM_SWORD_DEITY]); + ImGui::ImageButton(std::to_string(ITEM_SWORD_DEITY).c_str(), swordTextureId, ImVec2(INV_GRID_ICON_SIZE, INV_GRID_ICON_SIZE), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); + } else { + ImTextureID swordTextureId = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName((const char*)gItemIcons[ITEM_SWORD_KOKIRI + GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) - EQUIP_VALUE_SWORD_KOKIRI]); + if (ImGui::ImageButton(std::to_string(ITEM_SWORD_KOKIRI).c_str(), swordTextureId, ImVec2(INV_GRID_ICON_SIZE, INV_GRID_ICON_SIZE), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + NextQuestInSlot(QUEST_SWORD); + } + } + ImGui::SameLine(); + if (GET_CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_HERO) { + ImTextureID shieldTextureId = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName((const char*)gItemIcons[ITEM_SHIELD_HERO]); + if (ImGui::ImageButton(std::to_string(ITEM_SHIELD_HERO).c_str(), shieldTextureId, ImVec2(INV_GRID_ICON_SIZE, INV_GRID_ICON_SIZE), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + NextQuestInSlot(QUEST_SHIELD); + } + } else { + ImTextureID shieldTextureId = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName((const char*)gItemIcons[ITEM_SHIELD_MIRROR]); + if (ImGui::ImageButton(std::to_string(ITEM_SHIELD_MIRROR).c_str(), shieldTextureId, ImVec2(INV_GRID_ICON_SIZE, INV_GRID_ICON_SIZE), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + NextQuestInSlot(QUEST_SHIELD); + } + } + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("notebookBox", ImVec2(INV_GRID_WIDTH * 1 + INV_GRID_PADDING * 2, INV_GRID_HEIGHT * 1 + INV_GRID_PADDING * 2 + INV_GRID_TOP_MARGIN), ImGuiChildFlags_Border); + ImGui::Text("Bombers"); + ImTextureID textureId = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName((const char*)gItemIcons[ITEM_BOMBERS_NOTEBOOK]); + if (ImGui::ImageButton(std::to_string(ITEM_BOMBERS_NOTEBOOK).c_str(), textureId, ImVec2(INV_GRID_ICON_SIZE, INV_GRID_ICON_SIZE), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK) ? 1.0f : 0.4f))) { + NextQuestInSlot(QUEST_BOMBERS_NOTEBOOK); + } + ImGui::EndChild(); + ImGui::BeginChild("heartshapedBox", ImVec2(INV_GRID_WIDTH * 2 + INV_GRID_PADDING * 2, INV_GRID_HEIGHT + INV_GRID_PADDING), ImGuiChildFlags_Border); + ImGui::Text("Heart Pieces"); + int32_t pohCount = (gSaveContext.save.saveInfo.inventory.questItems & 0xF0000000) >> 28; + UIWidgets::PushStyleCombobox(UIWidgets::Colors::Red); + if (ImGui::BeginCombo("##PoHcount", std::to_string(pohCount).c_str())) { + for (int32_t i = 0; i < 4; i++) { + if (ImGui::Selectable(std::to_string(i).c_str(), pohCount == i)) { + gSaveContext.save.saveInfo.inventory.questItems &= ~0xF0000000; + gSaveContext.save.saveInfo.inventory.questItems |= (i << 28); + } + } + ImGui::EndCombo(); + } + UIWidgets::PopStyleCombobox(); + ImGui::EndChild(); + + ImGui::EndChild(); + ImGui::PopStyleVar(2); + ImGui::PopStyleColor(1); +} + const char* regGroupNames[] = { "REG (0)", "SREG (1)", @@ -1100,6 +1364,11 @@ void SaveEditorWindow::DrawElement() { ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("Quest Status")) { + DrawQuestStatusTab(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Reg Editor")) { DrawRegEditorTab(); ImGui::EndTabItem(); @@ -1110,11 +1379,6 @@ void SaveEditorWindow::DrawElement() { // ImGui::EndTabItem(); // } - // if (ImGui::BeginTabItem("Quest Status")) { - // DrawQuestStatusTab(); - // ImGui::EndTabItem(); - // } - if (ImGui::BeginTabItem("Flags")) { DrawFlagsTab(); ImGui::EndTabItem(); |
