mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
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>
This commit is contained in:
committed by
Garrett Cox
co-authored by
Archez
Garrett Cox
parent
5fe3e350fa
commit
db223d8d95
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user