diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index bcea7d483..a68b4fc61 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -461,6 +461,7 @@ namespace SohImGui { io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; io->Fonts->AddFontDefault(); statsWindowOpen = CVar_GetS32("gStatsEnabled", 0); + CVar_RegisterS32("gRandomizeRupeeNames", 1); CVar_RegisterS32("gRandoRelevantNavi", 1); #ifdef __SWITCH__ Ship::Switch::SetupFont(io->Fonts); @@ -2002,14 +2003,16 @@ namespace SohImGui { { EnhancementCheckbox("Quest Item Fanfares", "gRandoQuestItemFanfares"); Tooltip( - "Play unique fanfares when obtaining quest items\n" - "(medallions/stones/songs). Note that these fanfares\n" - "are longer than usual." + "Play unique fanfares when obtaining quest items " + "(medallions/stones/songs). Note that these fanfares are longer than usual." ); - EnhancementCheckbox("Rando-Relevant Navi Hints", "gRandoRelevantNavi"); + PaddedEnhancementCheckbox("Random Rupee Names", "gRandomizeRupeeNames", true, false); Tooltip( - "Replace Navi's overworld quest hints with rando-\n" - "related gameplay hints.\n" + "When obtaining rupees, randomize what the rupee is called in the textbox." + ); + PaddedEnhancementCheckbox("Rando-Relevant Navi Hints", "gRandoRelevantNavi", true, false); + Tooltip( + "Replace Navi's overworld quest hints with rando-related gameplay hints." ); ImGui::EndMenu(); } diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 514c607ba..324256900 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -110,6 +110,9 @@ set(Header_Files__include "include/ichain.h" "include/macro.inc" "include/macros.h" + "include/message_data_fmt.h" + "include/message_data_static.h" + "include/message_data_textbox_types.h" #"include/math_n64.h" "include/regs.h" "include/segment_symbols.h" diff --git a/soh/include/message_data_static.h b/soh/include/message_data_static.h index c286771aa..0821f1093 100644 --- a/soh/include/message_data_static.h +++ b/soh/include/message_data_static.h @@ -3,32 +3,12 @@ #include "global.h" #include "message_data_fmt.h" +#include "message_data_textbox_types.h" #ifdef __cplusplus extern "C" { #endif -typedef enum { - /* 0 */ TEXTBOX_TYPE_BLACK, - /* 1 */ TEXTBOX_TYPE_WOODEN, - /* 2 */ TEXTBOX_TYPE_BLUE, - /* 3 */ TEXTBOX_TYPE_OCARINA, - /* 4 */ TEXTBOX_TYPE_NONE_BOTTOM, - /* 5 */ TEXTBOX_TYPE_NONE_NO_SHADOW, - /* 11 */ TEXTBOX_TYPE_CREDITS = 11 -} TextBoxType; - -typedef enum { - /* 0 */ TEXTBOX_BG_CROSS -} TextBoxBackground; - -typedef enum { - /* 0 */ TEXTBOX_POS_VARIABLE, - /* 1 */ TEXTBOX_POS_TOP, - /* 2 */ TEXTBOX_POS_MIDDLE, - /* 3 */ TEXTBOX_POS_BOTTOM -} TextBoxPosition; - typedef struct { u16 textId; u8 typePos; diff --git a/soh/include/message_data_textbox_types.h b/soh/include/message_data_textbox_types.h new file mode 100644 index 000000000..03332182c --- /dev/null +++ b/soh/include/message_data_textbox_types.h @@ -0,0 +1,25 @@ +#ifndef MESSAGE_DATA_TEXTBOX_TYPES_H +#define MESSAGE_DATA_TEXTBOX_TYPES_H + +typedef enum { + /* 0 */ TEXTBOX_TYPE_BLACK, + /* 1 */ TEXTBOX_TYPE_WOODEN, + /* 2 */ TEXTBOX_TYPE_BLUE, + /* 3 */ TEXTBOX_TYPE_OCARINA, + /* 4 */ TEXTBOX_TYPE_NONE_BOTTOM, + /* 5 */ TEXTBOX_TYPE_NONE_NO_SHADOW, + /* 11 */ TEXTBOX_TYPE_CREDITS = 11 +} TextBoxType; + +typedef enum { + /* 0 */ TEXTBOX_BG_CROSS +} TextBoxBackground; + +typedef enum { + /* 0 */ TEXTBOX_POS_VARIABLE, + /* 1 */ TEXTBOX_POS_TOP, + /* 2 */ TEXTBOX_POS_MIDDLE, + /* 3 */ TEXTBOX_POS_BOTTOM +} TextBoxPosition; + +#endif diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index 389457d00..6ae7f6a38 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -2,6 +2,7 @@ #include #include #include "../../../include/z64item.h" +#include "../../../include/message_data_textbox_types.h" #undef MESSAGE_END @@ -14,31 +15,6 @@ #define QM_YELLOW 0x46 #define QM_BLACK 0x47 -#ifndef MESSAGE_DATA_STATIC_H - -typedef enum { - /* 0 */ TEXTBOX_TYPE_BLACK, - /* 1 */ TEXTBOX_TYPE_WOODEN, - /* 2 */ TEXTBOX_TYPE_BLUE, - /* 3 */ TEXTBOX_TYPE_OCARINA, - /* 4 */ TEXTBOX_TYPE_NONE_BOTTOM, - /* 5 */ TEXTBOX_TYPE_NONE_NO_SHADOW, - /* 11 */ TEXTBOX_TYPE_CREDITS = 11 -} TextBoxType; - -typedef enum { - /* 0 */ TEXTBOX_BG_CROSS -} TextBoxBackground; - -typedef enum { - /* 0 */ TEXTBOX_POS_VARIABLE, - /* 1 */ TEXTBOX_POS_TOP, - /* 2 */ TEXTBOX_POS_MIDDLE, - /* 3 */ TEXTBOX_POS_BOTTOM -} TextBoxPosition; - -#endif - typedef struct { TextBoxType textBoxType; TextBoxPosition textBoxPos; diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 39dceea1d..b38b5fc80 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -11,7 +11,11 @@ typedef enum { TEXT_ALTAR_CHILD = 0x7040, TEXT_ALTAR_ADULT = 0x7088, TEXT_GANONDORF = 0x70CC, - TEXT_GANONDORF_NOHINT = 0x70CD + TEXT_GANONDORF_NOHINT = 0x70CD, + TEXT_BLUE_RUPEE = 0xCC, + TEXT_RED_RUPEE = 0xF0, + TEXT_PURPLE_RUPEE = 0xF1, + TEXT_HUGE_RUPEE = 0xF2 } TextIDs; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index c00ebf9f2..d13792714 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -14,7 +14,6 @@ #include "3drando/rando_main.hpp" #include #include "Lib/ImGui/imgui_internal.h" -#include #include #include #include @@ -33,8 +32,30 @@ u8 generated; const std::string Randomizer::getItemMessageTableID = "Randomizer"; const std::string Randomizer::hintMessageTableID = "RandomizerHints"; const std::string Randomizer::scrubMessageTableID = "RandomizerScrubs"; +const std::string Randomizer::rupeeMessageTableID = "RandomizerRupees"; const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi"; +static const char* englishRupeeNames[44] = { + "Rupees", "Bitcoin", "Bananas", "Cornflakes", "Gummybears", "Floopies", "Dollars", "Lemmings", + "Emeralds", "Bucks", "Rubles", "Diamonds", "Moons", "Stars", "Mana", "Doll Hairs", + "Dogecoin", "Mushrooms", "Experience", "Friends", "Coins", "Rings", "Gil", "Pokédollars", + "Bells", "Orbs", "Bottle Caps", "Simoleons", "Pokémon", "Toys", "Smackaroos", "Zorkmids", + "Zenny", "Bones", "Souls", "Studs", "Munny", "Rubies", "Gald", "Gold", + "Shillings", "Pounds", "Glimmer", "Potch" +}; + +static const char* germanRupeeNames[1] = { + "Rubine" +}; + +static const char* frenchRupeeNames[36] = { + "Rubis", "Bitcoin", "Bananes", "Euros", "Dollars", "Émeraudes", "Joyaux", "Diamants", + "Balles", "Pokémon", "Pièces", "Lunes", "Étoiles", "Dogecoin", "Anneaux", "Radis", + "Pokédollars", "Zennies", "Pépètes", "Mailles", "Éthers", "Clochettes", "Capsules", "Gils", + "Champignons", "Blés", "Halos", "Munnies", "Orens", "Florens", "Crédits", "Galds", + "Bling", "Orbes", "Baguettes", "Croissants" +}; + Randomizer::Randomizer() { Sprite bowSprite = { dgFairyBowIconTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 0 }; gSeedTextures[0] = bowSprite; @@ -3715,6 +3736,69 @@ void CreateScrubMessages() { } } +void CreateRupeeMessages() { + CustomMessageManager* customMessageManager = CustomMessageManager::Instance; + customMessageManager->AddCustomMessageTable(Randomizer::rupeeMessageTableID); + const std::vector rupees = { TEXT_BLUE_RUPEE, TEXT_RED_RUPEE, TEXT_PURPLE_RUPEE, TEXT_HUGE_RUPEE }; + std::string rupeeText = " "; + for (u8 rupee : rupees) { + switch (rupee) { + case TEXT_BLUE_RUPEE: + rupeeText = "\x05\x03 5 #RUPEE#\x05\x00"; + break; + case TEXT_RED_RUPEE: + rupeeText = "\x05\x01 20 #RUPEE#\x05\x00"; + break; + case TEXT_PURPLE_RUPEE: + rupeeText = "\x05\x05 50 #RUPEE#\x05\x00"; + break; + case TEXT_HUGE_RUPEE: + rupeeText = "\x05\x06 200 #RUPEE#\x05\x00"; + break; + } + customMessageManager->CreateMessage(Randomizer::rupeeMessageTableID, rupee, + { TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM, + "You found" + rupeeText + " !", + "Du hast" + rupeeText + " gefunden!", + "Vous obtenez" + rupeeText + " !" + }); + } +} + +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); + return messageEntry; +} + CustomMessageMinimal NaviMessages[NUM_NAVI_MESSAGES] = { { "%cMissing a small key in a dungeon?&Maybe the %rboss %chas it!", @@ -3863,6 +3947,7 @@ void Randomizer::CreateCustomMessages() { }; CreateGetItemMessages(getItemMessages); CreateScrubMessages(); + CreateRupeeMessages(); CreateNaviRandoMessages(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index fad56ca13..54b50bcba 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -6,6 +6,7 @@ #include "../../../include/z64item.h" #include #include +#include #define NUM_NAVI_MESSAGES 15 @@ -33,6 +34,7 @@ class Randomizer { static const std::string getItemMessageTableID; static const std::string hintMessageTableID; static const std::string scrubMessageTableID; + static const std::string rupeeMessageTableID; static const std::string NaviRandoMessageTableID; static Sprite* GetSeedTexture(uint8_t index); @@ -51,6 +53,8 @@ class Randomizer { s16 GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); s16 GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); 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 7bd704d99..18d20ee00 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -33,6 +33,7 @@ #include "Enhancements/cosmetics/CosmeticsEditor.h" #include "Enhancements/debugconsole.h" #include "Enhancements/debugger/debugger.h" +#include #include #include "Enhancements/n64_weird_frame_data.inc" #include "soh/frame_interpolation.h" @@ -1719,6 +1720,10 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { } } else if (textId == TEXT_SCRUB_POH || textId == TEXT_SCRUB_STICK_UPGRADE || textId == TEXT_SCRUB_NUT_UPGRADE) { messageEntry = Randomizer_GetScrubMessage(textId); + } 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(); @@ -1751,7 +1756,6 @@ extern "C" int CustomMessage_RetrieveIfExists(GlobalContext* globalCtx) { case LANGUAGE_GER: return msgCtx->msgLength = font->msgLength = CopyStringToCharBuffer(messageEntry.german, buffer, maxBufferSize); - case LANGUAGE_ENG: default: return msgCtx->msgLength = font->msgLength =