From 57b335614c25c8d6973259bc708506c2478fecbb Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 25 May 2025 15:29:47 +0000 Subject: [PATCH] mechanism --- .../vanilla-behavior/GIVanillaBehavior.h | 8 +++++++ .../3drando/hint_list/hint_list_item.cpp | 2 ++ .../randomizer/3drando/item_pool.cpp | 4 ++++ .../Enhancements/randomizer/ShuffleSpeak.cpp | 21 +++++++++++++++++++ soh/soh/Enhancements/randomizer/item_list.cpp | 2 ++ soh/soh/Enhancements/randomizer/logic.cpp | 3 +++ .../randomizer/option_descriptions.cpp | 1 + .../Enhancements/randomizer/randomizer.cpp | 4 +++- .../Enhancements/randomizer/randomizerTypes.h | 3 +++ .../Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 4 ++++ soh/soh/Enhancements/randomizer/settings.cpp | 3 +++ .../actors/ovl_player_actor/z_player.c | 2 +- 13 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 186307aed..c6ef9c16b 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2049,6 +2049,14 @@ typedef enum { // - `*ShotSun` VB_SPAWN_SONG_FAIRY, + // #### `result` + // ```c + // (talkOfferActor != NULL) || (cUpTalkActor != NULL) + // ``` + // #### `args` + // - None + VB_SPEAK, + // #### `result` // ```c // varies, never set should to true diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index f5195c91d..5db03bac1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2100,6 +2100,8 @@ void StaticData::HintTable_Init_Item() { { CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") }); // /*spanish*/un desbloqueador maestro + hintTextTable[RHT_SPEAK] = HintText(CustomMessage("the ability to speak", /*german*/"!!!", /*french*/"!!!")); + //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 3e6588646..73e6761cd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -591,6 +591,10 @@ void GenerateItemPool() { AddItemToMainPool(RG_PROGRESSIVE_SCALE); } + if (ctx->GetOption(RSK_SHUFFLE_SPEAK)) { + AddItemToMainPool(RG_SPEAK); + } + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23); diff --git a/soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp b/soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp new file mode 100644 index 000000000..b04504d47 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleSpeak.cpp @@ -0,0 +1,21 @@ +#include +extern "C" { +extern PlayState* gPlayState; +#include "variables.h" +#include "functions.h" +} + +void RegisterShuffleSpeak() { + bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_SPEAK).Get(); + + COND_VB_SHOULD(VB_SPEAK, shouldRegister, { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_SPEAK)) { + Actor* talkActor = GET_PLAYER(gPlayState)->talkActor; + if (talkActor != NULL && talkActor->category == ACTORCAT_NPC) { + *should = false; + } + } + }); +} + +static RegisterShipInitFunc initFunc(RegisterShuffleSpeak, { "IS_RANDO" }); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 7f22fe83f..563803ab6 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -352,6 +352,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_SPEAK] = Item(RG_SPEAK, Text{ "Speak", "Parler", "" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_SPEAK, RG_SPEAK, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index eea79e92d..a30375560 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -127,6 +127,7 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_ZELDAS_LETTER: case RG_WEIRD_EGG: case RG_GREG_RUPEE: + case RG_SPEAK: // Ocarina Buttons case RG_OCARINA_A_BUTTON: case RG_OCARINA_C_LEFT_BUTTON: @@ -1472,6 +1473,7 @@ std::map Logic::RandoGetToRandInf = { { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, { RG_GREG_RUPEE, RAND_INF_GREG_FOUND }, + { RG_SPEAK, RAND_INF_CAN_SPEAK }, { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, { RG_GUARD_HOUSE_KEY, RAND_INF_GUARD_HOUSE_KEY_OBTAINED }, { RG_MARKET_BAZAAR_KEY, RAND_INF_MARKET_BAZAAR_KEY_OBTAINED }, @@ -1837,6 +1839,7 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_OCARINA_C_LEFT_BUTTON: case RG_OCARINA_C_RIGHT_BUTTON: case RG_GREG_RUPEE: + case RG_SPEAK: case RG_FISHING_POLE: case RG_GUARD_HOUSE_KEY: case RG_MARKET_BAZAAR_KEY: diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 50d11d9b2..8f988bf6b 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -251,6 +251,7 @@ void Settings::CreateOptionDescriptions() { "\n" "If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n" "If you void out in Water Temple you will immediately be kicked out to prevent a softlock."; + mOptionDescriptions[RSK_SHUFFLE_SPEAK] = "Shuffle the ability to speak to NPCs."; mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling " "\"Skip Child Zelda\" disables this feature.\n" "\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 5f9027d82..e2c3de191 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5391,7 +5391,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = { { + const std::array getItemMessages = { { GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", @@ -5715,6 +5715,7 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), + GIMESSAGE(RG_SPEAK, ITEM_SCALE_SILVER, "You got the %rAbility to Speak%w!&Use your words!", "!!!", "!!!"), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), @@ -5827,6 +5828,7 @@ extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); std::map randomizerGetToRandInf = { { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_SPEAK, RAND_INF_CAN_SPEAK }, { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..c494ff335 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4008,6 +4008,7 @@ typedef enum { RG_HINT, RG_TYCOON_WALLET, RG_BRONZE_SCALE, + RG_SPEAK, RG_CHILD_WALLET, RG_BOMBCHU_BAG, RG_QUIVER_INF, @@ -5205,6 +5206,7 @@ typedef enum { RHT_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RHT_BRONZE_SCALE, + RHT_SPEAK, RHT_FISHING_POLE, RHT_SKELETON_KEY, RHT_EPONA, @@ -5773,6 +5775,7 @@ typedef enum { RSK_SHUFFLE_OCARINA, RSK_SHUFFLE_OCARINA_BUTTONS, RSK_SHUFFLE_SWIM, + RSK_SHUFFLE_SPEAK, RSK_STARTING_DEKU_SHIELD, RSK_STARTING_KOKIRI_SWORD, RSK_STARTING_MASTER_SWORD, diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index d42e14cb1..39db7a9ae 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1001,6 +1001,7 @@ DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE) DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) DEFINE_RAND_INF(RAND_INF_CAN_SWIM) +DEFINE_RAND_INF(RAND_INF_CAN_SPEAK) DEFINE_RAND_INF(RAND_INF_HAS_WALLET) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 51101f6fa..a7c952781 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -258,6 +258,10 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetRandomizerInf(RAND_INF_CAN_SWIM); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_SPEAK) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_SPEAK); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); } diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5f8c60ac0..ea38fe46c 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -212,6 +212,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_OCARINA, "Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]); OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]); OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); + OPT_BOOL(RSK_SHUFFLE_SPEAK, "Shuffle Speak", CVAR_RANDOMIZER_SETTING("ShuffleSpeak"), mOptionDescriptions[RSK_SHUFFLE_SPEAK]); OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]); OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WidgetType::Combobox, RO_SHUFFLE_POTS_OFF); @@ -1241,6 +1242,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_SPEAK], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_FISHING_POLE], @@ -1519,6 +1521,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_SPEAK], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_MERCHANTS], diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 3571ca135..65a56b0c9 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6167,7 +6167,7 @@ s32 Player_ActionHandler_Talk(Player* this, PlayState* play) { } } - if ((talkOfferActor != NULL) || (cUpTalkActor != NULL)) { + if (GameInteractor_Should(VB_SPEAK, (talkOfferActor != NULL) || (cUpTalkActor != NULL))) { if ((lockOnActor == NULL) || (lockOnActor == talkOfferActor) || (lockOnActor == cUpTalkActor)) { if (!(this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) || ((this->heldActor != NULL) &&