From 0389c8084c8bce08311e5beaa125548a38c8f492 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 25 Oct 2022 20:24:48 -0500 Subject: [PATCH] Cleanup some of our uses of custom messages (#1847) * Cleanup some of our uses of custom messages * Fix some string escape warnings --- .../custom-message/CustomMessageManager.cpp | 20 +++ .../custom-message/CustomMessageManager.h | 6 + .../custom-message/CustomMessageTypes.h | 2 + .../Enhancements/randomizer/randomizer.cpp | 153 +++++++++--------- soh/soh/Enhancements/randomizer/randomizer.h | 3 +- soh/soh/OTRGlobals.cpp | 68 +++----- soh/soh/z_message_OTR.cpp | 14 +- soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c | 8 +- 8 files changed, 138 insertions(+), 136 deletions(-) diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp index 00c7153ea..222a6c556 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp @@ -47,6 +47,26 @@ void CustomMessageManager::ReplaceColors(std::string& string) { } } +void ReplaceString(std::string& source, std::string textToReplace, std::string value) { + size_t pos = source.find(textToReplace); + if (pos != std::string::npos) { + source.replace(pos, textToReplace.length(), value); + } + CustomMessageManager::Instance->FormatCustomMessage(source); +} + +void CustomMessageManager::ReplaceStringInMessage(CustomMessageEntry& messageEntry, std::string textToReplace, std::string value) { + ReplaceString(messageEntry.english, textToReplace, value); + ReplaceString(messageEntry.german, textToReplace, value); + ReplaceString(messageEntry.french, textToReplace, value); +} + +void CustomMessageManager::ReplaceStringInMessage(CustomMessageEntry& messageEntry, std::string textToReplace, std::string englishValue, std::string germanValue, std::string frenchValue) { + ReplaceString(messageEntry.english, textToReplace, englishValue); + ReplaceString(messageEntry.german, textToReplace, germanValue); + ReplaceString(messageEntry.french, textToReplace, frenchValue); +} + void CustomMessageManager::FormatCustomMessage(std::string& message, ItemID iid) { message.insert(0, ITEM_OBTAINED(iid)); size_t start_pos = 0; diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index 6ae7f6a38..eedb06f9a 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -57,6 +57,12 @@ class CustomMessageManager { public: static CustomMessageManager* Instance; + /* + Replaces the specified string in a CustomMessageEntry with the provided value + */ + static void ReplaceStringInMessage(CustomMessageEntry& messageEntry, std::string textToReplace, std::string value); + static void ReplaceStringInMessage(CustomMessageEntry& messageEntry, std::string textToReplace, std::string englishValue, std::string germanValue, std::string frenchValue); + CustomMessageManager(); ~CustomMessageManager(); diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 4c9de90a5..d00178757 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -20,7 +20,9 @@ typedef enum { TEXT_HUGE_RUPEE = 0xF2, TEXT_BEAN_SALESMAN = 0x405E, TEXT_SCRUB_RANDOM = 0x9000, + TEXT_SCRUB_RANDOM_FREE = 0x9001, TEXT_SHOP_ITEM_RANDOM = 0x9100, + TEXT_SHOP_ITEM_RANDOM_CONFIRM = 0x9101, } TextIDs; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 8445a1591..26393d73b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -12,6 +12,7 @@ #include #include #include "3drando/rando_main.hpp" +#include "3drando/random.hpp" #include "../../UIWidgets.hpp" #include #include "../custom-message/CustomMessageTypes.h" @@ -426,26 +427,19 @@ void Randomizer::LoadMerchantMessages(const char* spoilerFileName) { CustomMessageManager::Instance->ClearMessageTable(Randomizer::merchantMessageTableID); CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::merchantMessageTableID); - // Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so manually adding a "free" variation here + // Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so adding a "free" variation here + CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE, + { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM, + "\x12\x38\x82" "All right! You win! In return for&sparing me, I will give you a&%g{{item}}%w!&Please, take it!\x07\x10\xA3", + "\x12\x38\x82" "In Ordnung! Du gewinnst! Im Austausch&dafür, dass du mich verschont hast,&werde ich dir einen &%g{{item}}%w geben!\x07\x10\xA3", + "\x12\x38\x82" "J'me rends! Laisse-moi partir et en&échange, je te donne un &%g{{item}}%w! Vas-y prends le!\x07\x10\xA3", + }); CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM, { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM, - "\x12\x38\x82\All right! You win! In return for&sparing me, I will give you a&%gmysterious item%w!&Please, take it!\x07\x10\xA3", - "\x12\x38\x82\In Ordnung! Du gewinnst! Im Austausch&dafür, dass du mich verschont hast,&werde ich dir einen %gmysteriösen&Gegenstand%w geben! Bitte nimm ihn!\x07\x10\xA3", - "\x12\x38\x82\J'me rends! Laisse-moi partir et en&échange, je te donne un %gobjet &mystérieux%w! Vas-y prends le!\x07\x10\xA3", + "\x12\x38\x82" "All right! You win! In return for&sparing me, I will sell you a&%g{{item}}%w!&%r{{price}} Rupees%w it is!\x07\x10\xA3", + "\x12\x38\x82" "Aufgeben! Ich verkaufe dir einen&%g{{item}}%w&für %r{{price}} Rubine%w!\x07\x10\xA3", + "\x12\x38\x82" "J'abandonne! Tu veux bien m'acheter&un %g{{item}}%w?&Ça fera %r{{price}} Rubis%w!\x07\x10\xA3" }); - // Currently a scrub message is created for each price between 5-95, identified by the price itself. Soon we'll migrate this - // to be more consistent with shop items, where they are identified by randomizer_inf and only generated where necessary - for (u32 price = 5; price <= 95; price += 5) { - CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM + price, - { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM, - "\x12\x38\x82\All right! You win! In return for&sparing me, I will sell you a&%gmysterious item%w!&%r" + - std::to_string(price) + " Rupees%w it is!\x07\x10\xA3", - "\x12\x38\x82\Aufgeben! Ich verkaufe dir einen&%ggeheimnisvollen Gegenstand%w&für %r" + - std::to_string(price) + " Rubine%w!\x07\x10\xA3", - "\x12\x38\x82J'abandonne! Tu veux bien m'acheter&un %gobjet mystérieux%w?&Ça fera %r" + - std::to_string(price) + " Rubis%w!\x07\x10\xA3" - }); - } CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN, { @@ -459,37 +453,20 @@ void Randomizer::LoadMerchantMessages(const char* spoilerFileName) { "%gobjet mystérieux%w pour 60 Rubis?\x1B&%gOui&Non%w", }); - for (int index = 0; index < NUM_SHOP_ITEMS; index++) { - RandomizerCheck shopItemCheck = shopItemRandomizerChecks[index]; - RandomizerGet shopItemGet = this->itemLocations[shopItemCheck].rgID; - std::vector shopItemName; - // TODO: This should eventually be replaced with a full fledged trick model & trick name system - if (shopItemGet == RG_ICE_TRAP) { - shopItemGet = this->itemLocations[shopItemCheck].fakeRgID; - shopItemName = { - std::string(this->itemLocations[shopItemCheck].trickName), - std::string(this->itemLocations[shopItemCheck].trickName), - std::string(this->itemLocations[shopItemCheck].trickName) - }; - } else { - shopItemName = EnumToSpoilerfileGetName[shopItemGet]; - } - u16 shopItemPrice = merchantPrices[shopItemCheck]; - // Each shop item has two messages, one for when the cursor is over it, and one for when you select it and are - // prompted buy/don't buy, so we're adding the first at {index}, and the second at {index + NUM_SHOP_ITEMS} - CustomMessageManager::Instance->CreateMessage( - Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM + index, { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_VARIABLE, - "\x08%r" + shopItemName[0] + ": " + std::to_string(shopItemPrice) + " Rupees&%wSpecial deal! ONE LEFT!&Get it while it lasts!\x0A\x02", - "\x08%r" + shopItemName[1] + ": " + std::to_string(shopItemPrice) + " Rubine&%wSonderangebot! NUR NOCH EINES VERFÜGBAR!&Beeilen Sie sich!\x0A\x02", - "\x08%r" + shopItemName[2] + ": " + std::to_string(shopItemPrice) + " Rubis&%wOffre spéciale! DERNIER EN STOCK!&Faites vite!\x0A\x02", + // Each shop item has two messages, one for when the cursor is over it, and one for when you select it and are + // prompted buy/don't buy + CustomMessageManager::Instance->CreateMessage( + Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM, { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_VARIABLE, + "\x08%r{{item}}: {{price}} Rupees&%wSpecial deal! ONE LEFT!&Get it while it lasts!\x0A\x02", + "\x08%r{{item}}: {{price}} Rubine&%wSonderangebot! NUR NOCH EINES VERFÜGBAR!&Beeilen Sie sich!\x0A\x02", + "\x08%r{{item}}: {{price}} Rubis&%wOffre spéciale! DERNIER EN STOCK!&Faites vite!\x0A\x02", }); - CustomMessageManager::Instance->CreateMessage( - Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM + index + NUM_SHOP_ITEMS, { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_VARIABLE, - "\x08" + shopItemName[0] + ": " + std::to_string(shopItemPrice) + " Rupees\x09&&\x1B%gBuy&Don't buy%w\x09\x02", - "\x08" + shopItemName[1] + ": " + std::to_string(shopItemPrice) + " Rubine\x09&&\x1B%gKaufen&Nicht kaufen%w\x09\x02", - "\x08" + shopItemName[2] + ": " + std::to_string(shopItemPrice) + " Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02", + CustomMessageManager::Instance->CreateMessage( + Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM_CONFIRM, { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_VARIABLE, + "\x08{{item}}: {{price}} Rupees\x09&&\x1B%gBuy&Don't buy%w\x09\x02", + "\x08{{item}}: {{price}} Rubine\x09&&\x1B%gKaufen&Nicht kaufen%w\x09\x02", + "\x08{{item}}: {{price}} Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02", }); - } } void Randomizer::LoadItemLocations(const char* spoilerFileName, bool silent) { @@ -2399,6 +2376,14 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 actorId, s16 sceneNum, s16 act return GetCheckObjectFromActor(actorId, sceneNum, actorParams).rc; } +RandomizerCheck Randomizer::GetCheckFromRandomizerInf(RandomizerInf randomizerInf) { + for (auto const& [key, value] : rcToRandomizerInf) { + if (value == randomizerInf) return key; + } + + return RC_UNKNOWN_CHECK; +} + std::thread randoThread; void GenerateRandomizerImgui() { @@ -3740,6 +3725,39 @@ void DrawRandoEditor(bool& open) { ImGui::End(); } +CustomMessageEntry Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious) { + CustomMessageEntry messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId); + RandomizerCheck rc = GetCheckFromRandomizerInf(randomizerInf); + RandomizerGet shopItemGet = this->itemLocations[rc].rgID; + std::vector shopItemName; + if (mysterious) { + shopItemName = { + "mysterious item", + "mysteriösen Gegenstand", + "objet mystérieux" + }; + // TODO: This should eventually be replaced with a full fledged trick model & trick name system + } else if (shopItemGet == RG_ICE_TRAP) { + shopItemGet = this->itemLocations[rc].fakeRgID; + shopItemName = { + std::string(this->itemLocations[rc].trickName), + std::string(this->itemLocations[rc].trickName), + std::string(this->itemLocations[rc].trickName) + }; + } else { + shopItemName = EnumToSpoilerfileGetName[shopItemGet]; + } + u16 shopItemPrice = merchantPrices[rc]; + + if (textId == TEXT_SCRUB_RANDOM && shopItemPrice == 0) { + messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE); + } + + CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{item}}", shopItemName[0], shopItemName[1], shopItemName[2]); + CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{price}}", std::to_string(shopItemPrice)); + return messageEntry; +} + void CreateGetItemMessages(std::vector messageEntries) { CustomMessageManager* customMessageManager = CustomMessageManager::Instance; customMessageManager->AddCustomMessageTable(Randomizer::getItemMessageTableID); @@ -3758,16 +3776,16 @@ void CreateRupeeMessages() { for (u8 rupee : rupees) { switch (rupee) { case TEXT_BLUE_RUPEE: - rupeeText = "\x05\x03 5 #RUPEE#\x05\x00"; + rupeeText = "\x05\x03 5 {{rupee}}\x05\x00"; break; case TEXT_RED_RUPEE: - rupeeText = "\x05\x01 20 #RUPEE#\x05\x00"; + rupeeText = "\x05\x01 20 {{rupee}}\x05\x00"; break; case TEXT_PURPLE_RUPEE: - rupeeText = "\x05\x05 50 #RUPEE#\x05\x00"; + rupeeText = "\x05\x05 50 {{rupee}}\x05\x00"; break; case TEXT_HUGE_RUPEE: - rupeeText = "\x05\x06 200 #RUPEE#\x05\x00"; + rupeeText = "\x05\x06 200 {{rupee}}\x05\x00"; break; } customMessageManager->CreateMessage(Randomizer::rupeeMessageTableID, rupee, @@ -3779,37 +3797,12 @@ void CreateRupeeMessages() { } } -std::string Randomizer::RandomizeRupeeName(std::string message, int language) { - int randomIndex; - std::string replaceWith; - switch (language) { - case LANGUAGE_ENG: - randomIndex = rand() % (sizeof(englishRupeeNames) / sizeof(englishRupeeNames[0])); - replaceWith = englishRupeeNames[randomIndex]; - break; - case LANGUAGE_GER: - randomIndex = rand() % (sizeof(germanRupeeNames) / sizeof(germanRupeeNames[0])); - replaceWith = germanRupeeNames[randomIndex]; - break; - case LANGUAGE_FRA: - randomIndex = rand() % (sizeof(frenchRupeeNames) / sizeof(frenchRupeeNames[0])); - replaceWith = frenchRupeeNames[randomIndex]; - break; - } - std::string replaceString = "#RUPEE#"; - size_t pos = message.find(replaceString); - size_t len = replaceString.length(); - message.replace(pos, len, replaceWith); - CustomMessageManager::Instance->FormatCustomMessage(message); - return message; -} - CustomMessageEntry Randomizer::GetRupeeMessage(u16 rupeeTextId) { - CustomMessageEntry messageEntry = - CustomMessageManager::Instance->RetrieveMessage(Randomizer::rupeeMessageTableID, rupeeTextId); - messageEntry.english = Randomizer::RandomizeRupeeName(messageEntry.english, LANGUAGE_ENG); - messageEntry.german = Randomizer::RandomizeRupeeName(messageEntry.german, LANGUAGE_GER); - messageEntry.french = Randomizer::RandomizeRupeeName(messageEntry.french, LANGUAGE_FRA); + CustomMessageEntry messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::rupeeMessageTableID, rupeeTextId); + std::string englishName = RandomElement(englishRupeeNames); + std::string germanName = RandomElement(germanRupeeNames); + std::string frenchName = RandomElement(frenchRupeeNames); + CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{rupee}}", englishName, germanName, frenchName); return messageEntry; } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 578d7cb6b..1a72dd9ca 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -60,6 +60,7 @@ class Randomizer { bool IsTrialRequired(RandomizerInf trial); u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams); + RandomizerCheck GetCheckFromRandomizerInf(RandomizerInf randomizerInf); RandomizerGetData GetRandomizerGetDataFromActor(s16 actorId, s16 sceneNum, s16 actorParams); RandomizerGetData GetRandomizerGetDataFromKnownCheck(RandomizerCheck randomizerCheck); std::string GetChildAltarText() const; @@ -75,8 +76,8 @@ class Randomizer { GetItemID GetItemIdFromRandomizerGet(RandomizerGet randoGet, GetItemID ogItemId); ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck); ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck); + CustomMessageEntry GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false); static void CreateCustomMessages(); - static std::string RandomizeRupeeName(std::string message, int language); static CustomMessageEntry GetRupeeMessage(u16 rupeeTextId); bool CheckContainsVanillaItem(RandomizerCheck randoCheck); }; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 85f971d5e..6dbcc9031 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -37,6 +37,7 @@ #include "Enhancements/debugger/debugger.h" #include "Enhancements/randomizer/randomizer.h" #include "Enhancements/randomizer/randomizer_item_tracker.h" +#include "Enhancements/randomizer/3drando/random.hpp" #include "Enhancements/n64_weird_frame_data.inc" #include "frame_interpolation.h" #include "variables.h" @@ -1855,37 +1856,6 @@ extern "C" CowIdentity Randomizer_IdentifyCow(s32 sceneNum, s32 posX, s32 posZ) return OTRGlobals::Instance->gRandomizer->IdentifyCow(sceneNum, posX, posZ); } -extern "C" CustomMessageEntry Randomizer_GetNaviMessage() { - u16 naviTextId = rand() % NUM_NAVI_MESSAGES; - return CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID, naviTextId); -} - -extern "C" CustomMessageEntry Randomizer_GetIceTrapMessage() { - u16 iceTrapTextId = rand() % NUM_ICE_TRAP_MESSAGES; - return CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, iceTrapTextId); -} - -extern "C" CustomMessageEntry Randomizer_GetAltarMessage() { - return (LINK_IS_ADULT) - ? CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_ADULT) - : CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_CHILD); -} - -extern "C" CustomMessageEntry Randomizer_GetGanonText() { - return CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF_NOHINT); -} - -extern "C" CustomMessageEntry Randomizer_GetGanonHintText() { - return CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF); -} - -extern "C" CustomMessageEntry Randomizer_GetHintFromCheck(RandomizerCheck check) { - // we don't want to make a copy of the std::string returned from GetHintFromCheck - // so we're just going to let RVO take care of it - const CustomMessageEntry hintText = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, check); - return hintText; -} - extern "C" GetItemEntry ItemTable_Retrieve(int16_t getItemID) { GetItemEntry giEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_NONE, getItemID); return giEntry; @@ -1937,7 +1907,8 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) { Player* player = GET_PLAYER(globalCtx); if (player->getItemEntry.getItemId == RG_ICE_TRAP) { - messageEntry = Randomizer_GetIceTrapMessage(); + u16 iceTrapTextId = Random(0, NUM_ICE_TRAP_MESSAGES); + messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, iceTrapTextId); } else { messageEntry = Randomizer_GetCustomGetItemMessage(player); } @@ -1968,29 +1939,41 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { RandomizerCheck hintCheck = Randomizer_GetCheckFromActor(msgCtx->talkActor->id, globalCtx->sceneNum, actorParams); - messageEntry = Randomizer_GetHintFromCheck(hintCheck); + messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, hintCheck); } else if (textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT) { // rando hints at altar - messageEntry = Randomizer_GetAltarMessage(); + messageEntry = (LINK_IS_ADULT) + ? CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_ADULT) + : CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_ALTAR_CHILD); } else if (textId == TEXT_GANONDORF) { if (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) { - messageEntry = Randomizer_GetGanonText(); + messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF_NOHINT); } else { - messageEntry = Randomizer_GetGanonHintText(); + messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_GANONDORF); } - // Business Scrub textID is TEXT_SCRUB_RANDOM + their price, anywhere from 0-95 - } else if (textId >= TEXT_SCRUB_RANDOM && textId <= TEXT_SCRUB_RANDOM + 95) { - messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId); - // Shop items each have two message entries + // textId: TEXT_SCRUB_RANDOM + (randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT) + } else if (textId >= TEXT_SCRUB_RANDOM && textId <= TEXT_SCRUB_RANDOM + NUM_SCRUBS) { + RandomizerInf randoInf = (RandomizerInf)((textId - TEXT_SCRUB_RANDOM) + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); + messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, TEXT_SCRUB_RANDOM, Player_GetMask(globalCtx) != PLAYER_MASK_TRUTH); + // Shop items each have two message entries, second one offset by NUM_SHOP_ITEMS + // textId: TEXT_SHOP_ITEM_RANDOM + (randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + // textId: TEXT_SHOP_ITEM_RANDOM + ((randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + NUM_SHOP_ITEMS) } else if (textId >= TEXT_SHOP_ITEM_RANDOM && textId <= TEXT_SHOP_ITEM_RANDOM + (NUM_SHOP_ITEMS * 2)) { - messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId); + if (textId < TEXT_SHOP_ITEM_RANDOM + NUM_SHOP_ITEMS) { + RandomizerInf randoInf = (RandomizerInf)((textId - TEXT_SHOP_ITEM_RANDOM) + RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1); + messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, TEXT_SHOP_ITEM_RANDOM); + } else { + RandomizerInf randoInf = (RandomizerInf)((textId - (TEXT_SHOP_ITEM_RANDOM + NUM_SHOP_ITEMS)) + RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1); + messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, TEXT_SHOP_ITEM_RANDOM_CONFIRM); + } } else if (CVar_GetS32("gRandomizeRupeeNames", 0) && (textId == TEXT_BLUE_RUPEE || textId == TEXT_RED_RUPEE || textId == TEXT_PURPLE_RUPEE || textId == TEXT_HUGE_RUPEE)) { messageEntry = Randomizer::GetRupeeMessage(textId); // In rando, replace Navi's general overworld hints with rando-related gameplay tips } else if (CVar_GetS32("gRandoRelevantNavi", 1) && textId >= 0x0140 && textId <= 0x015F) { - messageEntry = Randomizer_GetNaviMessage(); + u16 naviTextId = Random(0, NUM_NAVI_MESSAGES); + messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID, naviTextId); } else if (Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS) && textId == TEXT_BEAN_SALESMAN) { messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN); } else if (Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) && @@ -2014,6 +1997,7 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { textId = TEXT_GS_FREEZE; } messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId); + CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{gsCount}}", std::to_string(gSaveContext.inventory.gsTokens + 1)); } } if (messageEntry.textBoxType != -1) { diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index 96cb0f016..c5794a94f 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -100,18 +100,18 @@ extern "C" void OTRMessage_Init() customMessageTableID, (GetItemID)TEXT_GS_NO_FREEZE, ITEM_SKULL_TOKEN, { TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM, - "You got a %rGold Skulltula Token%w!&You've collected %r\x19%w tokens&in total!\x0E\x3C", - "Du erhälst ein %rGoldene&Skulltula-Symbol%w! Du hast&insgesamt %r\x19%w symbol gesammelt!\x0E\x3C", - "Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r\x19\%w symboles en tout!\x0E\x3C" + "You got a %rGold Skulltula Token%w!&You've collected %r{{gsCount}}%w tokens&in total!\x0E\x3C", + "Du erhälst ein %rGoldene&Skulltula-Symbol%w! Du hast&insgesamt %r{{gsCount}}%w symbol gesammelt!\x0E\x3C", + "Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r{{gsCount}}%w symboles en tout!\x0E\x3C" } ); CustomMessageManager::Instance->CreateGetItemMessage( customMessageTableID, (GetItemID)TEXT_GS_FREEZE, ITEM_SKULL_TOKEN, { TEXTBOX_TYPE_BLUE, TEXTBOX_POS_BOTTOM, - "You got a %rGold Skulltula Token%w!&You've collected %r\x19%w tokens&in total!", - "Du erhälst ein %rGoldene&Skulltula-Symbol%w! Du hast&insgesamt %r\x19%w symbol gesammelt!", - "Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r\x19\%w symboles en tout!" + "You got a %rGold Skulltula Token%w!&You've collected %r{{gsCount}}%w tokens&in total!", + "Du erhälst ein %rGoldene&Skulltula-Symbol%w! Du hast&insgesamt %r{{gsCount}}%w symbol gesammelt!", + "Vous obtenez un %rSymbole de&Skulltula d'or%w! Vous avez&collecté %r{{gsCount}}%w symboles en tout!" } ); CustomMessageManager::Instance->CreateMessage( @@ -127,7 +127,7 @@ extern "C" void OTRMessage_Init() customMessageTableID, TEXT_BUY_BOMBCHU_10_PROMPT, { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM, - "\x08\Bombchu 10 pieces 99 Rupees\x09&&\x1B%gBuy&Don't buy%w", + "\x08" "Bombchu 10 pieces 99 Rupees\x09&&\x1B%gBuy&Don't buy%w", "\x08Krabbelmine 10 Stück 99 Rubine\x09&&\x1B%gKaufen!&Nicht kaufen!%w", "\x08Missiles 10 unités 99 Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w", } diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 419e443d0..865da6807 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -181,9 +181,7 @@ void EnDns_Init(Actor* thisx, GlobalContext* globalCtx) { this->dnsItemEntry->purchaseableCheck = EnDns_RandomizerPurchaseableCheck; this->dnsItemEntry->setRupeesAndFlags = EnDns_RandomizerPurchase; this->dnsItemEntry->itemAmount = 1; - // Currently the textID is simply identified by the item price since that is the only thing - // unique to it, later on this will change to identifying by scrubIdentity.randomizerInf - this->actor.textId = 0x9000 + this->dnsItemEntry->itemPrice; + this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); } } this->actionFunc = EnDns_SetupWait; @@ -516,9 +514,7 @@ void EnDns_Update(Actor* thisx, GlobalContext* globalCtx) { this->dustTimer++; this->actor.textId = D_809F040C[this->actor.params]; if (gSaveContext.n64ddFlag && this->scrubIdentity.isShuffled) { - // Currently the textID is simply identified by the item price since that is the only thing - // unique to it, later on this will change to identifying by scrubIdentity.randomizerInf - this->actor.textId = 0x9000 + this->dnsItemEntry->itemPrice; + this->actor.textId = 0x9000 + (this->scrubIdentity.randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT); } Actor_SetFocus(&this->actor, 60.0f); Actor_SetScale(&this->actor, 0.01f);