mechanism

This commit is contained in:
Demur Rumed 2025-05-25 15:29:47 +00:00
parent 7514bdc08b
commit 606d4706df
13 changed files with 56 additions and 2 deletions

View file

@ -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

View file

@ -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"));

View file

@ -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);

View file

@ -0,0 +1,21 @@
#include <soh/OTRGlobals.h>
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" });

View file

@ -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);

View file

@ -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:
@ -1470,6 +1471,7 @@ std::map<RandomizerGet, uint32_t> 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 },
@ -1835,6 +1837,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:

View file

@ -249,6 +249,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"

View file

@ -5343,7 +5343,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<GetItemMessage, 112> getItemMessages = { {
const std::array<GetItemMessage, 113> 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!",
@ -5667,6 +5667,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!"),
@ -5779,6 +5780,7 @@ extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem);
std::map<RandomizerGet, RandomizerInf> 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 },

View file

@ -3975,6 +3975,7 @@ typedef enum {
RG_HINT,
RG_TYCOON_WALLET,
RG_BRONZE_SCALE,
RG_SPEAK,
RG_CHILD_WALLET,
RG_BOMBCHU_BAG,
RG_QUIVER_INF,
@ -5172,6 +5173,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,
@ -5719,6 +5721,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,

View file

@ -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)

View file

@ -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);
}

View file

@ -211,6 +211,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);
@ -1221,6 +1222,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],
@ -1498,6 +1500,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],

View file

@ -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) &&