From fab52d323bb3bf48b64b660d1b84293ab754389d Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 2 Nov 2022 11:03:26 -0500 Subject: [PATCH] Implement hint for dungeon type on Map get item messages (#1852) * Implement hint for dungeon type on Map get item messages * Color dungeon name in item tracker when MQ and map is found * No hint when all dungeons are MQ or non MQ * TWEAK: French hint Co-authored-by: PurpleHato --- .../Enhancements/randomizer/randomizer.cpp | 93 +++++++++++++++---- soh/soh/Enhancements/randomizer/randomizer.h | 1 + .../randomizer/randomizer_item_tracker.cpp | 10 ++ soh/soh/OTRGlobals.cpp | 2 + 4 files changed, 86 insertions(+), 20 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 98e87178f..163068e86 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3793,6 +3793,59 @@ CustomMessageEntry Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u return messageEntry; } +std::vector> mapGetItemHints = { + { " It's ordinary.", " It's masterful!" }, + { " It's ordinary.", " It's masterful!" }, // TODO: German Translation (when map items are also translated) + { "&Elle vous semble %rordinaire%w.", "&Étrange... les mots %r\"Master&Quest\"%w sont gravés dessus." }, +}; + +CustomMessageEntry Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) { + CustomMessageEntry messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::getItemMessageTableID, itemEntry.getItemId); + int sceneNum; + switch (itemEntry.getItemId) { + case RG_DEKU_TREE_MAP: + sceneNum = SCENE_YDAN; + break; + case RG_DODONGOS_CAVERN_MAP: + sceneNum = SCENE_DDAN; + break; + case RG_JABU_JABUS_BELLY_MAP: + sceneNum = SCENE_BDAN; + break; + case RG_FOREST_TEMPLE_MAP: + sceneNum = SCENE_BMORI1; + break; + case RG_FIRE_TEMPLE_MAP: + sceneNum = SCENE_HIDAN; + break; + case RG_WATER_TEMPLE_MAP: + sceneNum = SCENE_MIZUSIN; + break; + case RG_SPIRIT_TEMPLE_MAP: + sceneNum = SCENE_JYASINZOU; + break; + case RG_SHADOW_TEMPLE_MAP: + sceneNum = SCENE_HAKADAN; + break; + case RG_BOTTOM_OF_THE_WELL_MAP: + sceneNum = SCENE_HAKADANCH; + break; + case RG_ICE_CAVERN_MAP: + sceneNum = SCENE_ICE_DOUKUTO; + break; + } + + if (this->masterQuestDungeons.empty() || this->masterQuestDungeons.size() >= 12) { + CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{typeHint}}", ""); + } else if (ResourceMgr_IsSceneMasterQuest(sceneNum)) { + CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{typeHint}}", mapGetItemHints[0][1], mapGetItemHints[1][1], mapGetItemHints[2][1]); + } else { + CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{typeHint}}", mapGetItemHints[0][0], mapGetItemHints[1][0], mapGetItemHints[2][0]); + } + + return messageEntry; +} + void CreateGetItemMessages(std::vector messageEntries) { CustomMessageManager* customMessageManager = CustomMessageManager::Instance; customMessageManager->AddCustomMessageTable(Randomizer::getItemMessageTableID); @@ -4134,26 +4187,26 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE_NO_GERMAN(RG_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rGanon's Castle &%wBoss Key!", "Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"), - GIMESSAGE_NO_GERMAN(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree &%wMap!", - "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!"), - GIMESSAGE_NO_GERMAN(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!", - "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!"), - GIMESSAGE_NO_GERMAN(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!", - "Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!"), - GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!", - "Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!"), - GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!", - "Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!"), - GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!", - "Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!"), - GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!", - "Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!"), - GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!", - "Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!"), - GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!", - "Vous obtenez la %rCarte %wdu &%pPuits%w!"), - GIMESSAGE_NO_GERMAN(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!", - "Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!"), + GIMESSAGE_NO_GERMAN(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%rTemple du Feu%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the &Well %wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wdu &%pPuits%w!{{typeHint}}"), + GIMESSAGE_NO_GERMAN(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern &%wMap!{{typeHint}}", + "Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w!{{typeHint}}"), GIMESSAGE_NO_GERMAN(RG_DEKU_TREE_COMPASS, ITEM_COMPASS, "You found the %gDeku Tree &%wCompass!", "Vous obtenez la %rBoussole %wde&l'%gArbre Mojo%w!"), diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 1a72dd9ca..a4e3873f8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -77,6 +77,7 @@ class Randomizer { ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck); ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck); CustomMessageEntry GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false); + CustomMessageEntry GetMapGetItemMessageWithHint(GetItemEntry itemEntry); static void CreateCustomMessages(); static CustomMessageEntry GetRupeeMessage(u16 rupeeTextId); bool CheckContainsVanillaItem(RandomizerCheck randoCheck); diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index cb55e6ce4..612b56ad6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -338,6 +338,7 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { #define IM_COL_RED IM_COL32(255, 0, 0, 255) #define IM_COL_GREEN IM_COL32(0, 255, 0, 255) #define IM_COL_GRAY IM_COL32(155, 155, 155, 255) +#define IM_COL_PURPLE IM_COL32(180, 90, 200, 255) void DrawItemCount(ItemTrackerItem item) { int iconSize = CVar_GetS32("gItemTrackerIconSize", 36); @@ -500,6 +501,7 @@ void DrawBottle(ItemTrackerItem item) { void DrawDungeonItem(ItemTrackerItem item) { uint32_t itemId = item.id; + ImU32 dungeonColor = IM_COL_WHITE; uint32_t bitMask = 1 << (item.id - ITEM_KEY_BOSS); // Bitset starts at ITEM_KEY_BOSS == 0. the rest are sequential int iconSize = CVar_GetS32("gItemTrackerIconSize", 36); bool hasItem = (bitMask & gSaveContext.inventory.dungeonItems[item.data]) != 0; @@ -514,13 +516,19 @@ void DrawDungeonItem(ItemTrackerItem item) { ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); } + if (ResourceMgr_IsSceneMasterQuest(item.data) && CHECK_DUNGEON_ITEM(DUNGEON_MAP, item.data)) { + dungeonColor = IM_COL_PURPLE; + } + if (itemId == ITEM_KEY_SMALL) { DrawItemCount(item); ImVec2 p = ImGui::GetCursorScreenPos(); std::string dungeonName = itemTrackerDungeonShortNames[item.data]; ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + 16))); + ImGui::PushStyleColor(ImGuiCol_Text, dungeonColor); ImGui::Text(dungeonName.c_str()); + ImGui::PopStyleColor(); } if (itemId == ITEM_DUNGEON_MAP && @@ -529,7 +537,9 @@ void DrawDungeonItem(ItemTrackerItem item) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string dungeonName = itemTrackerDungeonShortNames[item.data]; ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + 13))); + ImGui::PushStyleColor(ImGuiCol_Text, dungeonColor); ImGui::Text(dungeonName.c_str()); + ImGui::PopStyleColor(); } ImGui::EndGroup(); diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 6dbcc9031..e3f12065f 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1909,6 +1909,8 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { if (player->getItemEntry.getItemId == RG_ICE_TRAP) { u16 iceTrapTextId = Random(0, NUM_ICE_TRAP_MESSAGES); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, iceTrapTextId); + } else if (player->getItemEntry.getItemId >= RG_DEKU_TREE_MAP && player->getItemEntry.getItemId <= RG_ICE_CAVERN_MAP) { + messageEntry = OTRGlobals::Instance->gRandomizer->GetMapGetItemMessageWithHint(player->getItemEntry); } else { messageEntry = Randomizer_GetCustomGetItemMessage(player); }