From 039ab22ecc1d1a2ced7de099368ee1a0668154b2 Mon Sep 17 00:00:00 2001 From: inspectredc Date: Thu, 28 Aug 2025 13:04:21 +0100 Subject: [PATCH 01/11] implement shuffle isg --- .../game-interactor/GameInteractor_HookTable.h | 1 + .../game-interactor/GameInteractor_Hooks.cpp | 4 ++++ .../game-interactor/GameInteractor_Hooks.h | 1 + .../randomizer/3drando/item_pool.cpp | 4 ++++ .../Enhancements/randomizer/hook_handlers.cpp | 17 +++++++++++++++++ soh/soh/Enhancements/randomizer/item_list.cpp | 3 +++ soh/soh/Enhancements/randomizer/logic.cpp | 8 ++++++++ .../randomizer/option_descriptions.cpp | 3 +++ soh/soh/Enhancements/randomizer/randomizer.cpp | 6 ++++++ .../Enhancements/randomizer/randomizerTypes.h | 8 ++++++++ .../Enhancements/randomizer/randomizer_inf.h | 2 ++ soh/soh/Enhancements/randomizer/savefile.cpp | 4 ++++ soh/soh/Enhancements/randomizer/settings.cpp | 3 +++ soh/src/code/z_skelanime.c | 1 + 14 files changed, 65 insertions(+) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 3ac408e78ef..c5844346d84 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -47,6 +47,7 @@ DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list or DEFINE_HOOK(OnSaveFile, (int32_t fileNum)); DEFINE_HOOK(OnLoadFile, (int32_t fileNum)); DEFINE_HOOK(OnDeleteFile, (int32_t fileNum)); +DEFINE_HOOK(OnLinkAnimEnd, (SkelAnime* skelAnime)); DEFINE_HOOK(OnDialogMessage, ()); DEFINE_HOOK(OnPresentTitleCard, ()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index f69cc29af53..cb591a536d6 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -97,6 +97,10 @@ void GameInteractor_ExecuteOnCuccoOrChickenHatch() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime) { + GameInteractor::Instance->ExecuteHooks(skelAnime); +} + void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) { GameInteractor::Instance->ExecuteHooks(cursorIndex, price); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index a6f1563f23e..396c1896044 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -28,6 +28,7 @@ void GameInteractor_ExecuteOnPlayerUpdate(); void GameInteractor_ExecuteOnSetDoAction(uint16_t action); void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnCuccoOrChickenHatch(); +void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime); void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorSpawn(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 3e658864601..0ce28552fc1 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_ISG)) { + AddItemToMainPool(RG_ABILITY_ISG); + } + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index bf2722f8091..8a2f5899349 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -69,6 +69,7 @@ extern void EnGe1_Wait_Archery(EnGe1* enGe1, PlayState* play); extern void EnGe1_SetAnimationIdle(EnGe1* enGe1); extern void EnGe1_SetAnimationIdle(EnGe1* enGe1); extern void EnGe2_SetupCapturePlayer(EnGe2* enGe2, PlayState* play); +extern void func_80832318(Player* player); } bool LocMatchesQuest(Rando::Location loc) { @@ -2343,6 +2344,17 @@ void RandomizerOnCuccoOrChickenHatch() { } } +void RandomizerOnLinkAnimEnd(SkelAnime* skelAnime) { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_ISG)) { + Player* player = GET_PLAYER(gPlayState); + + // Make sure we are only checking for the end of link's animation + if (skelAnime == &player->skelAnime) { + func_80832318(player); + } + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -2362,6 +2374,7 @@ void RandomizerRegisterHooks() { static uint32_t onExitGameHook = 0; static uint32_t onKaleidoUpdateHook = 0; static uint32_t onCuccoOrChickenHatchHook = 0; + static uint32_t onLinkAnimEndHook = 0; static uint32_t fishsanityOnActorInitHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0; @@ -2394,6 +2407,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onExitGameHook); GameInteractor::Instance->UnregisterGameHook(onKaleidoUpdateHook); GameInteractor::Instance->UnregisterGameHook(onCuccoOrChickenHatchHook); + GameInteractor::Instance->UnregisterGameHook(onLinkAnimEndHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); @@ -2420,6 +2434,7 @@ void RandomizerRegisterHooks() { onExitGameHook = 0; onKaleidoUpdateHook = 0; onCuccoOrChickenHatchHook = 0; + onLinkAnimEndHook = 0; fishsanityOnActorInitHook = 0; fishsanityOnActorUpdateHook = 0; @@ -2475,6 +2490,8 @@ void RandomizerRegisterHooks() { RandomizerOnKaleidoscopeUpdateHandler); onCuccoOrChickenHatchHook = GameInteractor::Instance->RegisterGameHook( RandomizerOnCuccoOrChickenHatch); + onLinkAnimEndHook = GameInteractor::Instance->RegisterGameHook( + [](SkelAnime* skelAnime) { RandomizerOnLinkAnimEnd(skelAnime); }); if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 7f22fe83f55..71d512d3706 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -352,6 +352,9 @@ 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_ABILITY_ISG] = Item(RG_ABILITY_ISG, Text{ "ISG", "ISG", "ISG" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_ISG, RG_ABILITY_ISG, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_ISG].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + 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 fa275480df6..6d83113c180 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1803,6 +1803,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_BOMBCHU_20: SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); break; + case RG_ABILITY_ISG: + SetRandoInf(RAND_INF_CAN_ISG, state); + break; default: break; } @@ -2326,6 +2329,11 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_CAN_SWIM, true); } + // If we're not shuffling glitch abilites, we start with them + if (ctx->GetOption(RSK_SHUFFLE_ISG).Is(false)) { + SetRandoInf(RAND_INF_CAN_ISG, true); + } + // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { SetRandoInf(RAND_INF_HAS_WALLET, true); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 50d11d9b2ab..c164b1058a1 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -760,5 +760,8 @@ void Settings::CreateOptionDescriptions() { "Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its " "respective soul." "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; + + mOptionDescriptions[RSK_SHUFFLE_ISG] = + "Shuffles the ability to use the glitch ISG into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index bbab5ebb30a..040d042bda3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5718,6 +5718,11 @@ 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_ABILITY_ISG, ITEM_SINGLE_MAGIC, "You got %rISG%w!", + "Du hast %rISG%w&erhalten!", + "Vous obtenez %rISG%w!"), + 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!"), @@ -5911,6 +5916,7 @@ std::map randomizerGetToRandInf = { { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_ABILITY_ISG, RAND_INF_CAN_ISG }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 806488a616d..68daef89283 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4054,6 +4054,10 @@ typedef enum { RG_BACK_TOWER_KEY, RG_HYLIA_LAB_KEY, RG_FISHING_HOLE_KEY, + + // Glitch abilities + RG_ABILITY_ISG, + // Logic Only RG_DISTANT_SCARECROW, RG_STICKS, @@ -5649,6 +5653,8 @@ typedef enum { RHT_DODONGOS_CAVERN_GRASS, RHT_BOTTOM_OF_THE_WELL_GRASS, RHT_JABU_JABUS_BELLY_GRASS, + // Glitch Abilities + RHT_ABILITY_ISG, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5942,6 +5948,8 @@ typedef enum { RSK_SHUFFLE_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, + + RSK_SHUFFLE_ISG, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index d42e14cb101..38a46b44be0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1004,6 +1004,8 @@ DEFINE_RAND_INF(RAND_INF_CAN_SWIM) DEFINE_RAND_INF(RAND_INF_HAS_WALLET) +DEFINE_RAND_INF(RAND_INF_CAN_ISG) + DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 51101f6fa59..fa16bbcf163 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_ISG) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_ISG); + } + 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 d94905ae170..e2119d95751 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -214,6 +214,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); 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_BOOL(RSK_SHUFFLE_ISG, "Shuffle ISG", CVAR_RANDOMIZER_SETTING("ShuffleISG"), mOptionDescriptions[RSK_SHUFFLE_ISG]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1247,6 +1248,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], + &mOptions[RSK_SHUFFLE_ISG], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1541,6 +1543,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_FAIRIES], + &mOptions[RSK_SHUFFLE_ISG], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c index a7e93e8c356..6518dee1359 100644 --- a/soh/src/code/z_skelanime.c +++ b/soh/src/code/z_skelanime.c @@ -1225,6 +1225,7 @@ s32 LinkAnimation_Once(PlayState* play, SkelAnime* skelAnime) { if (skelAnime->curFrame == skelAnime->endFrame) { LinkAnimation_AnimateFrame(play, skelAnime); + GameInteractor_ExecuteOnLinkAnimEnd(skelAnime); return 1; } skelAnime->curFrame += skelAnime->playSpeed * updateRate; From 0fba74fb7d5952b7c77e060994686324702ac8dc Mon Sep 17 00:00:00 2001 From: inspectredc Date: Fri, 29 Aug 2025 11:49:04 +0100 Subject: [PATCH 02/11] ocarina items --- .../vanilla-behavior/GIVanillaBehavior.h | 8 ++++++++ .../3drando/hint_list/hint_list_item.cpp | 18 ++++++++++++++++++ .../randomizer/3drando/item_pool.cpp | 3 +++ .../Enhancements/randomizer/hook_handlers.cpp | 19 +++++++++++++++++++ soh/soh/Enhancements/randomizer/item_list.cpp | 4 +++- soh/soh/Enhancements/randomizer/logic.cpp | 6 ++++++ .../randomizer/option_descriptions.cpp | 2 ++ .../Enhancements/randomizer/randomizer.cpp | 6 +++++- .../Enhancements/randomizer/randomizerTypes.h | 5 ++++- .../Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 3 +++ soh/soh/Enhancements/randomizer/settings.cpp | 3 +++ .../actors/ovl_player_actor/z_player.c | 3 +++ 13 files changed, 78 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 7e517155b07..2ecfe3056ff 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2253,6 +2253,14 @@ typedef enum { // #### `args` // - `*DoorShutter` VB_BE_NEAR_DOOR_SHUTTER, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_SKIP_FORCE_PLAY_OCARINA, } GIVanillaBehavior; #endif 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 f5195c91d2b..1156015615e 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 @@ -2132,6 +2132,24 @@ void StaticData::HintTable_Init_Item() { CustomMessage("a four legged friend", /*german*/"ein vierbeiniger Freund", /*french*/"un puissant animal")}); // /*spanish*/una amiga cuadrúpeda + hintTextTable[RHT_ABILITY_ISG] = HintText(CustomMessage("ISG", /*german*/"ISG", /*french*/"ISG"), + // /*spanish*/ISG + { + CustomMessage("a flashy weapon", /*german*/"ISG", /*french*/"ISG") + // /*spanish*/ISG + }, { + CustomMessage("a permanent hitbox", /*german*/"ISG", /*french*/"ISG")}); + // /*spanish*/ISG + + hintTextTable[RHT_ABILITY_OI] = HintText(CustomMessage("OI", /*german*/"OI", /*french*/"OI"), + // /*spanish*/OI + { + CustomMessage("a musical bottle", /*german*/"OI", /*french*/"OI") + // /*spanish*/OI + }, { + CustomMessage("a potato of any color", /*german*/"OI", /*french*/"OI")}); + // /*spanish*/OI + //What is this used for? hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); // /*spanish*/algo misterioso diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 0ce28552fc1..63595321a76 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -594,6 +594,9 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_ISG)) { AddItemToMainPool(RG_ABILITY_ISG); } + if (ctx->GetOption(RSK_SHUFFLE_OI)) { + AddItemToMainPool(RG_ABILITY_OI); + } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 8a2f5899349..a42cf6994b0 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -70,6 +70,8 @@ extern void EnGe1_SetAnimationIdle(EnGe1* enGe1); extern void EnGe1_SetAnimationIdle(EnGe1* enGe1); extern void EnGe2_SetupCapturePlayer(EnGe2* enGe2, PlayState* play); extern void func_80832318(Player* player); +extern void Player_SetupActionPreserveItemAction(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 flags); +extern void Player_Action_Idle(Player* player, PlayState* play); } bool LocMatchesQuest(Rando::Location loc) { @@ -2235,6 +2237,21 @@ std::map swimSpecialRespawnInfo = { f32 triforcePieceScale; +void RandomizerShouldSkipForcePlayOcarina(bool* should) { + + if (!Flags_GetRandomizerInf(RAND_INF_CAN_OI)) { + Player* player = GET_PLAYER(gPlayState); + + if (player->itemAction != PLAYER_IA_OCARINA_FAIRY && player->itemAction != PLAYER_IA_OCARINA_OF_TIME) { + player->unk_6AD = 0; + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); + Player_SetupActionPreserveItemAction(gPlayState, player, Player_Action_Idle, 0); + player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; + *should = true; + } + } +} + void RandomizerOnPlayerUpdateHandler() { if ((GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_WATER) && !Flags_GetRandomizerInf(RAND_INF_CAN_SWIM) && CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) != EQUIP_VALUE_BOOTS_IRON) { @@ -2493,6 +2510,8 @@ void RandomizerRegisterHooks() { onLinkAnimEndHook = GameInteractor::Instance->RegisterGameHook( [](SkelAnime* skelAnime) { RandomizerOnLinkAnimEnd(skelAnime); }); + COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); }); + if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 71d512d3706..26ee877d1bc 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -352,8 +352,10 @@ 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_ABILITY_ISG] = Item(RG_ABILITY_ISG, Text{ "ISG", "ISG", "ISG" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_ISG, RG_ABILITY_ISG, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_ISG] = Item(RG_ABILITY_ISG, Text{ "ISG", "ISG", "ISG" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_ISG, RG_ABILITY_ISG, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_ISG].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_OI] = Item(RG_ABILITY_OI, Text{ "OI", "OI", "OI" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_OI, RG_ABILITY_OI, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_OI].SetCustomDrawFunc(Randomizer_DrawMysteryItem); 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 6d83113c180..de873bda52d 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1806,6 +1806,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_ABILITY_ISG: SetRandoInf(RAND_INF_CAN_ISG, state); break; + case RG_ABILITY_OI: + SetRandoInf(RAND_INF_CAN_OI, state); + break; default: break; } @@ -2333,6 +2336,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_ISG).Is(false)) { SetRandoInf(RAND_INF_CAN_ISG, true); } + if (ctx->GetOption(RSK_SHUFFLE_OI).Is(false)) { + SetRandoInf(RAND_INF_CAN_OI, true); + } // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index c164b1058a1..210064252bb 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -763,5 +763,7 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SHUFFLE_ISG] = "Shuffles the ability to use the glitch ISG into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_OI] = + "Shuffles the ability to use the glitch Ocarina Items into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 040d042bda3..50528e4fc77 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5394,7 +5394,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!", @@ -5722,6 +5722,9 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_ABILITY_ISG, ITEM_SINGLE_MAGIC, "You got %rISG%w!", "Du hast %rISG%w&erhalten!", "Vous obtenez %rISG%w!"), + GIMESSAGE(RG_ABILITY_OI, ITEM_OCARINA_TIME, "You got %rOI%w!", + "Du hast %rOI%w&erhalten!", + "Vous obtenez %rOI%w!"), 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!", @@ -5917,6 +5920,7 @@ std::map randomizerGetToRandInf = { { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, { RG_ABILITY_ISG, RAND_INF_CAN_ISG }, + { RG_ABILITY_OI, RAND_INF_CAN_OI }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 68daef89283..0e71413803c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4057,6 +4057,7 @@ typedef enum { // Glitch abilities RG_ABILITY_ISG, + RG_ABILITY_OI, // Logic Only RG_DISTANT_SCARECROW, @@ -5655,6 +5656,7 @@ typedef enum { RHT_JABU_JABUS_BELLY_GRASS, // Glitch Abilities RHT_ABILITY_ISG, + RHT_ABILITY_OI, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5948,8 +5950,9 @@ typedef enum { RSK_SHUFFLE_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, - + // Glitch shuffles RSK_SHUFFLE_ISG, + RSK_SHUFFLE_OI, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 38a46b44be0..0fb69f3efde 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1005,6 +1005,7 @@ DEFINE_RAND_INF(RAND_INF_CAN_SWIM) DEFINE_RAND_INF(RAND_INF_HAS_WALLET) DEFINE_RAND_INF(RAND_INF_CAN_ISG) +DEFINE_RAND_INF(RAND_INF_CAN_OI) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index fa16bbcf163..12a39bb4b95 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -261,6 +261,9 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_ISG) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_ISG); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OI) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_OI); + } 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 e2119d95751..0c8011a4653 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -215,6 +215,7 @@ void Settings::CreateOptions() { 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_BOOL(RSK_SHUFFLE_ISG, "Shuffle ISG", CVAR_RANDOMIZER_SETTING("ShuffleISG"), mOptionDescriptions[RSK_SHUFFLE_ISG]); + OPT_BOOL(RSK_SHUFFLE_OI, "Shuffle OI", CVAR_RANDOMIZER_SETTING("ShuffleOI"), mOptionDescriptions[RSK_SHUFFLE_OI]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1249,6 +1250,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_ISG], + &mOptions[RSK_SHUFFLE_OI], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1544,6 +1546,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_FAIRIES], &mOptions[RSK_SHUFFLE_ISG], + &mOptions[RSK_SHUFFLE_OI], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { 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 3571ca1352e..cbc8e19205f 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6100,6 +6100,9 @@ s32 Player_ActionHandler_13(Player* this, PlayState* play) { func_80835EA4(play, 2); } } else { + if (GameInteractor_Should(VB_SKIP_FORCE_PLAY_OCARINA, false, NULL)) { + return 0; + } Player_SetupActionPreserveItemAction(play, this, Player_Action_8084E3C4, 0); Player_AnimPlayOnceAdjusted(play, this, &gPlayerAnim_link_normal_okarina_start); this->stateFlags2 |= PLAYER_STATE2_OCARINA_PLAYING; From a16323a902d898ccb17fcc5c01a29e2b1f164be9 Mon Sep 17 00:00:00 2001 From: inspectredc Date: Fri, 29 Aug 2025 14:20:13 +0100 Subject: [PATCH 03/11] qpa (untested) --- .../GameInteractor_HookTable.h | 1 + .../game-interactor/GameInteractor_Hooks.cpp | 4 ++ .../game-interactor/GameInteractor_Hooks.h | 1 + .../3drando/hint_list/hint_list_item.cpp | 8 ++++ .../randomizer/3drando/item_pool.cpp | 3 ++ .../Enhancements/randomizer/hook_handlers.cpp | 43 ++++++++++++------- soh/soh/Enhancements/randomizer/item_list.cpp | 2 + soh/soh/Enhancements/randomizer/logic.cpp | 6 +++ .../randomizer/option_descriptions.cpp | 2 + .../Enhancements/randomizer/randomizer.cpp | 6 ++- .../Enhancements/randomizer/randomizerTypes.h | 3 ++ .../Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 3 ++ soh/soh/Enhancements/randomizer/settings.cpp | 3 ++ .../actors/ovl_player_actor/z_player.c | 3 +- 15 files changed, 71 insertions(+), 18 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index c5844346d84..68cf4cf093f 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -48,6 +48,7 @@ DEFINE_HOOK(OnSaveFile, (int32_t fileNum)); DEFINE_HOOK(OnLoadFile, (int32_t fileNum)); DEFINE_HOOK(OnDeleteFile, (int32_t fileNum)); DEFINE_HOOK(OnLinkAnimEnd, (SkelAnime* skelAnime)); +DEFINE_HOOK(OnQPADamage, (uint32_t* dmgFlags)); DEFINE_HOOK(OnDialogMessage, ()); DEFINE_HOOK(OnPresentTitleCard, ()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index cb591a536d6..ec7d2c6de0e 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -101,6 +101,10 @@ void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime) { GameInteractor::Instance->ExecuteHooks(skelAnime); } +void GameInteractor_ExecuteOnQPADamage(uint32_t* dmgFlags) { + GameInteractor::Instance->ExecuteHooks(dmgFlags); +} + void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) { GameInteractor::Instance->ExecuteHooks(cursorIndex, price); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 396c1896044..efe752225db 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -29,6 +29,7 @@ void GameInteractor_ExecuteOnSetDoAction(uint16_t action); void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnCuccoOrChickenHatch(); void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime); +void GameInteractor_ExecuteOnQPADamage(uint32_t* dmgFlags); void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorSpawn(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor); 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 1156015615e..f041d7b2d77 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 @@ -2149,6 +2149,14 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("a potato of any color", /*german*/"OI", /*french*/"OI")}); // /*spanish*/OI + hintTextTable[RHT_ABILITY_QPA] = HintText(CustomMessage("QPA", /*german*/"QPA", /*french*/"QPA"), + // /*spanish*/QPA + { + CustomMessage("some funky damage", /*german*/"QPA", /*french*/"QPA") + // /*spanish*/QPA + }, { + CustomMessage("some fast hands", /*german*/"QPA", /*french*/"QPA")}); + // /*spanish*/QPA //What is this used for? hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 63595321a76..daac40a9e08 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -597,6 +597,9 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_OI)) { AddItemToMainPool(RG_ABILITY_OI); } + if (ctx->GetOption(RSK_SHUFFLE_QPA)) { + AddItemToMainPool(RG_ABILITY_QPA); + } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index a42cf6994b0..1384d14a5ba 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -2237,21 +2237,6 @@ std::map swimSpecialRespawnInfo = { f32 triforcePieceScale; -void RandomizerShouldSkipForcePlayOcarina(bool* should) { - - if (!Flags_GetRandomizerInf(RAND_INF_CAN_OI)) { - Player* player = GET_PLAYER(gPlayState); - - if (player->itemAction != PLAYER_IA_OCARINA_FAIRY && player->itemAction != PLAYER_IA_OCARINA_OF_TIME) { - player->unk_6AD = 0; - Sfx_PlaySfxCentered(NA_SE_SY_ERROR); - Player_SetupActionPreserveItemAction(gPlayState, player, Player_Action_Idle, 0); - player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; - *should = true; - } - } -} - void RandomizerOnPlayerUpdateHandler() { if ((GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_WATER) && !Flags_GetRandomizerInf(RAND_INF_CAN_SWIM) && CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) != EQUIP_VALUE_BOOTS_IRON) { @@ -2366,12 +2351,34 @@ void RandomizerOnLinkAnimEnd(SkelAnime* skelAnime) { Player* player = GET_PLAYER(gPlayState); // Make sure we are only checking for the end of link's animation - if (skelAnime == &player->skelAnime) { + // TODO: Use gPlayerAnim_link_normal_defense_kiru? + if (skelAnime == &player->skelAnime && player->meleeWeaponAnimation == PLAYER_MWA_STAB_1H) { func_80832318(player); } } } +void RandomizerShouldSkipForcePlayOcarina(bool* should) { + + if (!Flags_GetRandomizerInf(RAND_INF_CAN_OI)) { + Player* player = GET_PLAYER(gPlayState); + + if (player->itemAction != PLAYER_IA_OCARINA_FAIRY && player->itemAction != PLAYER_IA_OCARINA_OF_TIME) { + player->unk_6AD = 0; + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); + Player_SetupActionPreserveItemAction(gPlayState, player, Player_Action_Idle, 0); + player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; + *should = true; + } + } +} + +void RandomizerOnQPADamage(uint32_t* dmgFlags) { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_QPA)) { + *dmgFlags = 0; + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -2392,6 +2399,7 @@ void RandomizerRegisterHooks() { static uint32_t onKaleidoUpdateHook = 0; static uint32_t onCuccoOrChickenHatchHook = 0; static uint32_t onLinkAnimEndHook = 0; + static uint32_t onQPADamageHook = 0; static uint32_t fishsanityOnActorInitHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0; @@ -2425,6 +2433,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onKaleidoUpdateHook); GameInteractor::Instance->UnregisterGameHook(onCuccoOrChickenHatchHook); GameInteractor::Instance->UnregisterGameHook(onLinkAnimEndHook); + GameInteractor::Instance->UnregisterGameHook(onQPADamageHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); @@ -2509,6 +2518,8 @@ void RandomizerRegisterHooks() { RandomizerOnCuccoOrChickenHatch); onLinkAnimEndHook = GameInteractor::Instance->RegisterGameHook( [](SkelAnime* skelAnime) { RandomizerOnLinkAnimEnd(skelAnime); }); + onQPADamageHook = GameInteractor::Instance->RegisterGameHook( + [](uint32_t* dmgFlags) { RandomizerOnQPADamage(dmgFlags); }); COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); }); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 26ee877d1bc..6de360cb578 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -356,6 +356,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ABILITY_ISG].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_OI] = Item(RG_ABILITY_OI, Text{ "OI", "OI", "OI" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_OI, RG_ABILITY_OI, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_OI].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_QPA] = Item(RG_ABILITY_QPA, Text{ "QPA", "QPA", "QPA" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_QPA, RG_ABILITY_QPA, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_QPA].SetCustomDrawFunc(Randomizer_DrawMysteryItem); 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 de873bda52d..ca93932b9ce 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1809,6 +1809,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_ABILITY_OI: SetRandoInf(RAND_INF_CAN_OI, state); break; + case RG_ABILITY_QPA: + SetRandoInf(RAND_INF_CAN_QPA, state); + break; default: break; } @@ -2339,6 +2342,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_OI).Is(false)) { SetRandoInf(RAND_INF_CAN_OI, true); } + if (ctx->GetOption(RSK_SHUFFLE_QPA).Is(false)) { + SetRandoInf(RAND_INF_CAN_QPA, true); + } // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 210064252bb..e8ebdfd40be 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -765,5 +765,7 @@ void Settings::CreateOptionDescriptions() { "Shuffles the ability to use the glitch ISG into the item pool."; mOptionDescriptions[RSK_SHUFFLE_OI] = "Shuffles the ability to use the glitch Ocarina Items into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_QPA] = + "Shuffles the ability to use Quick Putaway Glitched Damage into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 50528e4fc77..105eae5902a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5719,12 +5719,15 @@ void Randomizer::CreateCustomMessages() { "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_ABILITY_ISG, ITEM_SINGLE_MAGIC, "You got %rISG%w!", + GIMESSAGE(RG_ABILITY_ISG, ITEM_SWORD_MASTER, "You got %rISG%w!", "Du hast %rISG%w&erhalten!", "Vous obtenez %rISG%w!"), GIMESSAGE(RG_ABILITY_OI, ITEM_OCARINA_TIME, "You got %rOI%w!", "Du hast %rOI%w&erhalten!", "Vous obtenez %rOI%w!"), + GIMESSAGE(RG_ABILITY_QPA, ITEM_BLUE_FIRE, "You got %rQPA%w!", + "Du hast %rQPA%w&erhalten!", + "Vous obtenez %rQPA%w!"), 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!", @@ -5921,6 +5924,7 @@ std::map randomizerGetToRandInf = { { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, { RG_ABILITY_ISG, RAND_INF_CAN_ISG }, { RG_ABILITY_OI, RAND_INF_CAN_OI }, + { RG_ABILITY_QPA, RAND_INF_CAN_QPA }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 0e71413803c..a65fb88148f 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4058,6 +4058,7 @@ typedef enum { // Glitch abilities RG_ABILITY_ISG, RG_ABILITY_OI, + RG_ABILITY_QPA, // Logic Only RG_DISTANT_SCARECROW, @@ -5657,6 +5658,7 @@ typedef enum { // Glitch Abilities RHT_ABILITY_ISG, RHT_ABILITY_OI, + RHT_ABILITY_QPA, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5953,6 +5955,7 @@ typedef enum { // Glitch shuffles RSK_SHUFFLE_ISG, RSK_SHUFFLE_OI, + RSK_SHUFFLE_QPA, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 0fb69f3efde..94fc5e80995 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1006,6 +1006,7 @@ DEFINE_RAND_INF(RAND_INF_HAS_WALLET) DEFINE_RAND_INF(RAND_INF_CAN_ISG) DEFINE_RAND_INF(RAND_INF_CAN_OI) +DEFINE_RAND_INF(RAND_INF_CAN_QPA) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 12a39bb4b95..eadc215480f 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -264,6 +264,9 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_OI) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_OI); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_QPA) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_QPA); + } 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 0c8011a4653..57707734877 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -216,6 +216,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); OPT_BOOL(RSK_SHUFFLE_ISG, "Shuffle ISG", CVAR_RANDOMIZER_SETTING("ShuffleISG"), mOptionDescriptions[RSK_SHUFFLE_ISG]); OPT_BOOL(RSK_SHUFFLE_OI, "Shuffle OI", CVAR_RANDOMIZER_SETTING("ShuffleOI"), mOptionDescriptions[RSK_SHUFFLE_OI]); + OPT_BOOL(RSK_SHUFFLE_QPA, "Shuffle QPA", CVAR_RANDOMIZER_SETTING("ShuffleQPA"), mOptionDescriptions[RSK_SHUFFLE_QPA]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1251,6 +1252,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_ISG], &mOptions[RSK_SHUFFLE_OI], + &mOptions[RSK_SHUFFLE_QPA], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1547,6 +1549,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FAIRIES], &mOptions[RSK_SHUFFLE_ISG], &mOptions[RSK_SHUFFLE_OI], + &mOptions[RSK_SHUFFLE_QPA], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { 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 cbc8e19205f..99b93f837bc 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -4450,6 +4450,7 @@ void func_80837948(PlayState* play, Player* this, s32 arg2) { if ((arg2 >= PLAYER_MWA_FLIPSLASH_START) && (arg2 <= PLAYER_MWA_JUMPSLASH_FINISH)) { if (CVarGetInteger(CVAR_GENERAL("RestoreQPA"), 1) && temp == -1) { dmgFlags = 0x16171617; + GameInteractor_ExecuteOnQPADamage(&dmgFlags); } else { dmgFlags = D_80854488[temp][1]; } @@ -6100,7 +6101,7 @@ s32 Player_ActionHandler_13(Player* this, PlayState* play) { func_80835EA4(play, 2); } } else { - if (GameInteractor_Should(VB_SKIP_FORCE_PLAY_OCARINA, false, NULL)) { + if (GameInteractor_Should(VB_SKIP_FORCE_PLAY_OCARINA, false)) { return 0; } Player_SetupActionPreserveItemAction(play, this, Player_Action_8084E3C4, 0); From 665376e84aed57b9f2769fca7e04fa16cc518eb5 Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Fri, 29 Aug 2025 19:15:26 +0100 Subject: [PATCH 04/11] Shuffle hess and superslide --- .../GameInteractor_HookTable.h | 2 ++ .../game-interactor/GameInteractor_Hooks.cpp | 8 ++++++++ .../game-interactor/GameInteractor_Hooks.h | 2 ++ .../3drando/hint_list/hint_list_item.cpp | 16 ++++++++++++++++ .../randomizer/3drando/item_pool.cpp | 6 ++++++ .../Enhancements/randomizer/hook_handlers.cpp | 19 +++++++++++++++++++ soh/soh/Enhancements/randomizer/item_list.cpp | 6 +++++- soh/soh/Enhancements/randomizer/logic.cpp | 12 ++++++++++++ .../randomizer/option_descriptions.cpp | 4 ++++ .../Enhancements/randomizer/randomizer.cpp | 10 +++++++++- .../Enhancements/randomizer/randomizerTypes.h | 6 ++++++ .../Enhancements/randomizer/randomizer_inf.h | 2 ++ soh/soh/Enhancements/randomizer/savefile.cpp | 6 ++++++ soh/soh/Enhancements/randomizer/settings.cpp | 6 ++++++ .../actors/ovl_player_actor/z_player.c | 4 ++++ 15 files changed, 107 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 68cf4cf093f..4049cd1bdd9 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -49,6 +49,8 @@ DEFINE_HOOK(OnLoadFile, (int32_t fileNum)); DEFINE_HOOK(OnDeleteFile, (int32_t fileNum)); DEFINE_HOOK(OnLinkAnimEnd, (SkelAnime* skelAnime)); DEFINE_HOOK(OnQPADamage, (uint32_t* dmgFlags)); +DEFINE_HOOK(OnESS, ()); +DEFINE_HOOK(OnWaitForPutaway, ()); DEFINE_HOOK(OnDialogMessage, ()); DEFINE_HOOK(OnPresentTitleCard, ()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index ec7d2c6de0e..44a49cdea68 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -105,6 +105,14 @@ void GameInteractor_ExecuteOnQPADamage(uint32_t* dmgFlags) { GameInteractor::Instance->ExecuteHooks(dmgFlags); } +void GameInteractor_ExecuteOnESS() { + GameInteractor::Instance->ExecuteHooks(); +} + +void GameInteractor_ExecuteOnWaitForPutaway() { + GameInteractor::Instance->ExecuteHooks(); +} + void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) { GameInteractor::Instance->ExecuteHooks(cursorIndex, price); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index efe752225db..b26a7ed26d8 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -30,6 +30,8 @@ void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnCuccoOrChickenHatch(); void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime); void GameInteractor_ExecuteOnQPADamage(uint32_t* dmgFlags); +void GameInteractor_ExecuteOnESS(); +void GameInteractor_ExecuteOnWaitForPutaway(); void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorSpawn(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor); 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 f041d7b2d77..20befed140d 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 @@ -2157,6 +2157,22 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("some fast hands", /*german*/"QPA", /*french*/"QPA")}); // /*spanish*/QPA + hintTextTable[RHT_ABILITY_HESS] = HintText(CustomMessage("HESS", /*german*/"HESS", /*french*/"HESS"), + // /*spanish*/HESS + { + CustomMessage("some explosive speed", /*german*/"HESS", /*french*/"HESS") + // /*spanish*/HESS + }, { + CustomMessage("some slick feet", /*german*/"HESS", /*french*/"HESS")}); + // /*spanish*/HESS + hintTextTable[RHT_ABILITY_SUPERSLIDE] = HintText(CustomMessage("Superslide", /*german*/"Superslide", /*french*/"Superslide"), + // /*spanish*/Superslide + { + CustomMessage("some straight line speed", /*german*/"Superslide", /*french*/"Superslide") + // /*spanish*/Superslide + }, { + CustomMessage("some shield power", /*german*/"Superslide", /*french*/"Superslide")}); + // /*spanish*/Superslide //What is this used for? hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index daac40a9e08..f186d40b4d0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -600,6 +600,12 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_QPA)) { AddItemToMainPool(RG_ABILITY_QPA); } + if (ctx->GetOption(RSK_SHUFFLE_HESS)) { + AddItemToMainPool(RG_ABILITY_HESS); + } + if (ctx->GetOption(RSK_SHUFFLE_SUPERSLIDE)) { + AddItemToMainPool(RG_ABILITY_SUPERSLIDE); + } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 1384d14a5ba..b9f7897ebd3 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -72,6 +72,7 @@ extern void EnGe2_SetupCapturePlayer(EnGe2* enGe2, PlayState* play); extern void func_80832318(Player* player); extern void Player_SetupActionPreserveItemAction(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 flags); extern void Player_Action_Idle(Player* player, PlayState* play); +extern s32 Player_DecelerateToZero(Player* player); } bool LocMatchesQuest(Rando::Location loc) { @@ -2379,6 +2380,18 @@ void RandomizerOnQPADamage(uint32_t* dmgFlags) { } } +void RandomizerOnESS() { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_HESS)) { + Player_DecelerateToZero(GET_PLAYER(gPlayState)); + } +} + +void RandomizerOnWaitForPutaway() { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_SUPERSLIDE)) { + Player_DecelerateToZero(GET_PLAYER(gPlayState)); + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -2400,6 +2413,8 @@ void RandomizerRegisterHooks() { static uint32_t onCuccoOrChickenHatchHook = 0; static uint32_t onLinkAnimEndHook = 0; static uint32_t onQPADamageHook = 0; + static uint32_t onESSHook = 0; + static uint32_t onWaitForPutawayHook = 0; static uint32_t fishsanityOnActorInitHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0; @@ -2434,6 +2449,8 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onCuccoOrChickenHatchHook); GameInteractor::Instance->UnregisterGameHook(onLinkAnimEndHook); GameInteractor::Instance->UnregisterGameHook(onQPADamageHook); + GameInteractor::Instance->UnregisterGameHook(onESSHook); + GameInteractor::Instance->UnregisterGameHook(onWaitForPutawayHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); @@ -2520,6 +2537,8 @@ void RandomizerRegisterHooks() { [](SkelAnime* skelAnime) { RandomizerOnLinkAnimEnd(skelAnime); }); onQPADamageHook = GameInteractor::Instance->RegisterGameHook( [](uint32_t* dmgFlags) { RandomizerOnQPADamage(dmgFlags); }); + onESSHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnESS); + onWaitForPutawayHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnWaitForPutaway); COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); }); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 6de360cb578..13046fdf502 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -356,8 +356,12 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ABILITY_ISG].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_OI] = Item(RG_ABILITY_OI, Text{ "OI", "OI", "OI" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_OI, RG_ABILITY_OI, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_OI].SetCustomDrawFunc(Randomizer_DrawMysteryItem); - itemTable[RG_ABILITY_QPA] = Item(RG_ABILITY_QPA, Text{ "QPA", "QPA", "QPA" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_QPA, RG_ABILITY_QPA, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_QPA] = Item(RG_ABILITY_QPA, Text{ "QPA", "QPA", "QPA" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_QPA, RG_ABILITY_QPA, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_QPA].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_HESS] = Item(RG_ABILITY_HESS, Text{ "HESS", "HESS", "HESS" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HESS, RG_ABILITY_HESS, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_HESS].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_SUPERSLIDE] = Item(RG_ABILITY_SUPERSLIDE, Text{ "SUPERSLIDE", "SUPERSLIDE", "SUPERSLIDE" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_SUPERSLIDE, RG_ABILITY_SUPERSLIDE, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_SUPERSLIDE].SetCustomDrawFunc(Randomizer_DrawMysteryItem); 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 ca93932b9ce..72de0b5bfc4 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1812,6 +1812,12 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_ABILITY_QPA: SetRandoInf(RAND_INF_CAN_QPA, state); break; + case RG_ABILITY_HESS: + SetRandoInf(RAND_INF_CAN_HESS, state); + break; + case RG_ABILITY_SUPERSLIDE: + SetRandoInf(RAND_INF_CAN_SUPERSLIDE, state); + break; default: break; } @@ -2345,6 +2351,12 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_QPA).Is(false)) { SetRandoInf(RAND_INF_CAN_QPA, true); } + if (ctx->GetOption(RSK_SHUFFLE_HESS).Is(false)) { + SetRandoInf(RAND_INF_CAN_HESS, true); + } + if (ctx->GetOption(RSK_SHUFFLE_SUPERSLIDE).Is(false)) { + SetRandoInf(RAND_INF_CAN_SUPERSLIDE, true); + } // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index e8ebdfd40be..1cf2a424377 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -767,5 +767,9 @@ void Settings::CreateOptionDescriptions() { "Shuffles the ability to use the glitch Ocarina Items into the item pool."; mOptionDescriptions[RSK_SHUFFLE_QPA] = "Shuffles the ability to use Quick Putaway Glitched Damage into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_HESS] = + "Shuffles the ability to HESS into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE] = + "Shuffles the ability to superslide into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 105eae5902a..357e2040e7c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5394,7 +5394,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!", @@ -5728,6 +5728,12 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_ABILITY_QPA, ITEM_BLUE_FIRE, "You got %rQPA%w!", "Du hast %rQPA%w&erhalten!", "Vous obtenez %rQPA%w!"), + GIMESSAGE(RG_ABILITY_HESS, ITEM_BOOTS_HOVER, "You got %rHESS%w!", + "Du hast %rHESS%w&erhalten!", + "Vous obtenez %rHESS%w!"), + GIMESSAGE(RG_ABILITY_SUPERSLIDE, ITEM_BOOTS_HOVER, "You got %rSuperslide%w!", + "Du hast %rSuperslide%w&erhalten!", + "Vous obtenez %rSuperslide%w!"), 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!", @@ -5925,6 +5931,8 @@ std::map randomizerGetToRandInf = { { RG_ABILITY_ISG, RAND_INF_CAN_ISG }, { RG_ABILITY_OI, RAND_INF_CAN_OI }, { RG_ABILITY_QPA, RAND_INF_CAN_QPA }, + { RG_ABILITY_HESS, RAND_INF_CAN_HESS }, + { RG_ABILITY_SUPERSLIDE, RAND_INF_CAN_SUPERSLIDE }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index a65fb88148f..7a34001a879 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4059,6 +4059,8 @@ typedef enum { RG_ABILITY_ISG, RG_ABILITY_OI, RG_ABILITY_QPA, + RG_ABILITY_HESS, + RG_ABILITY_SUPERSLIDE, // Logic Only RG_DISTANT_SCARECROW, @@ -5659,6 +5661,8 @@ typedef enum { RHT_ABILITY_ISG, RHT_ABILITY_OI, RHT_ABILITY_QPA, + RHT_ABILITY_HESS, + RHT_ABILITY_SUPERSLIDE, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5956,6 +5960,8 @@ typedef enum { RSK_SHUFFLE_ISG, RSK_SHUFFLE_OI, RSK_SHUFFLE_QPA, + RSK_SHUFFLE_HESS, + RSK_SHUFFLE_SUPERSLIDE, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 94fc5e80995..f1a62590181 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1007,6 +1007,8 @@ DEFINE_RAND_INF(RAND_INF_HAS_WALLET) DEFINE_RAND_INF(RAND_INF_CAN_ISG) DEFINE_RAND_INF(RAND_INF_CAN_OI) DEFINE_RAND_INF(RAND_INF_CAN_QPA) +DEFINE_RAND_INF(RAND_INF_CAN_HESS) +DEFINE_RAND_INF(RAND_INF_CAN_SUPERSLIDE) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index eadc215480f..91fe3ca66c0 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -267,6 +267,12 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_QPA) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_QPA); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_HESS) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_HESS); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_SUPERSLIDE) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_SUPERSLIDE); + } 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 57707734877..38ee3b20106 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -217,6 +217,8 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_ISG, "Shuffle ISG", CVAR_RANDOMIZER_SETTING("ShuffleISG"), mOptionDescriptions[RSK_SHUFFLE_ISG]); OPT_BOOL(RSK_SHUFFLE_OI, "Shuffle OI", CVAR_RANDOMIZER_SETTING("ShuffleOI"), mOptionDescriptions[RSK_SHUFFLE_OI]); OPT_BOOL(RSK_SHUFFLE_QPA, "Shuffle QPA", CVAR_RANDOMIZER_SETTING("ShuffleQPA"), mOptionDescriptions[RSK_SHUFFLE_QPA]); + OPT_BOOL(RSK_SHUFFLE_HESS, "Shuffle HESS", CVAR_RANDOMIZER_SETTING("ShuffleHESS"), mOptionDescriptions[RSK_SHUFFLE_HESS]); + OPT_BOOL(RSK_SHUFFLE_SUPERSLIDE, "Shuffle Superslide", CVAR_RANDOMIZER_SETTING("ShuffleSUPERSLIDE"), mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1253,6 +1255,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ISG], &mOptions[RSK_SHUFFLE_OI], &mOptions[RSK_SHUFFLE_QPA], + &mOptions[RSK_SHUFFLE_HESS], + &mOptions[RSK_SHUFFLE_SUPERSLIDE], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1550,6 +1554,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ISG], &mOptions[RSK_SHUFFLE_OI], &mOptions[RSK_SHUFFLE_QPA], + &mOptions[RSK_SHUFFLE_HESS], + &mOptions[RSK_SHUFFLE_SUPERSLIDE], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { 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 99b93f837bc..bc26e19977a 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -8733,6 +8733,8 @@ void Player_Action_TurnInPlace(Player* this, PlayState* play) { this->skelAnime.morphTable, sUpperBodyLimbCopyMap); } + GameInteractor_ExecuteOnESS(); + Player_GetMovementSpeedAndYaw(this, &speedTarget, &yawTarget, SPEED_MODE_CURVED, play); //! @bug This action does not handle xzSpeed in any capacity. @@ -10226,6 +10228,8 @@ void Player_Action_WaitForPutAway(Player* this, PlayState* play) { this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_Z_TARGET | PLAYER_STATE2_DISABLE_ROTATION_ALWAYS; LinkAnimation_Update(play, &this->skelAnime); + GameInteractor_ExecuteOnWaitForPutaway(); + // Wait for the held item put away process to complete. // Determining if the put away process is complete is a bit complicated: // `Player_UpdateUpperBody` will only return false if the current UpperAction returns false. From 87831bba95d771951cff4f69c3738c8a14f0f0f6 Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Fri, 29 Aug 2025 21:22:04 +0100 Subject: [PATCH 05/11] Hovering (may break smth but not sure what) --- .../vanilla-behavior/GIVanillaBehavior.h | 10 +++++++++- .../randomizer/3drando/hint_list/hint_list_item.cpp | 8 ++++++++ soh/soh/Enhancements/randomizer/3drando/item_pool.cpp | 3 +++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 8 ++++++++ soh/soh/Enhancements/randomizer/item_list.cpp | 4 +++- soh/soh/Enhancements/randomizer/logic.cpp | 6 ++++++ .../Enhancements/randomizer/option_descriptions.cpp | 2 ++ soh/soh/Enhancements/randomizer/randomizer.cpp | 6 +++++- soh/soh/Enhancements/randomizer/randomizerTypes.h | 3 +++ soh/soh/Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 3 +++ soh/soh/Enhancements/randomizer/settings.cpp | 5 ++++- soh/src/overlays/actors/ovl_player_actor/z_player.c | 2 +- 13 files changed, 56 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 2ecfe3056ff..4a965cd6e9b 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2256,11 +2256,19 @@ typedef enum { // #### `result` // ```c - // true + // false // ``` // #### `args` // - None VB_SKIP_FORCE_PLAY_OCARINA, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_HOVER_WITH_ISG, } GIVanillaBehavior; #endif 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 20befed140d..d6fe2b32f47 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 @@ -2173,6 +2173,14 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("some shield power", /*german*/"Superslide", /*french*/"Superslide")}); // /*spanish*/Superslide + hintTextTable[RHT_ABILITY_HOVER] = HintText(CustomMessage("Hover", /*german*/"Hover", /*french*/"Hover"), + // /*spanish*/Hover + { + CustomMessage("a weightless trick", /*german*/"Hover", /*french*/"Hover") + // /*spanish*/Hover + }, { + CustomMessage("gravityn't", /*german*/"Hover", /*french*/"Hover")}); + // /*spanish*/Hover //What is this used for? hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index f186d40b4d0..16f7d97085c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -606,6 +606,9 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_SUPERSLIDE)) { AddItemToMainPool(RG_ABILITY_SUPERSLIDE); } + if (ctx->GetOption(RSK_SHUFFLE_HOVER)) { + AddItemToMainPool(RG_ABILITY_HOVER); + } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index b9f7897ebd3..97936be0457 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -2392,6 +2392,12 @@ void RandomizerOnWaitForPutaway() { } } +void RandomizerShouldHover(bool* should) { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_HOVER)) { + *should = false; + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -2542,6 +2548,8 @@ void RandomizerRegisterHooks() { COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); }); + COND_VB_SHOULD(VB_HOVER_WITH_ISG, true, { RandomizerShouldHover(should); }); + if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 13046fdf502..643f3366f87 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -360,8 +360,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ABILITY_QPA].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_HESS] = Item(RG_ABILITY_HESS, Text{ "HESS", "HESS", "HESS" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HESS, RG_ABILITY_HESS, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_HESS].SetCustomDrawFunc(Randomizer_DrawMysteryItem); - itemTable[RG_ABILITY_SUPERSLIDE] = Item(RG_ABILITY_SUPERSLIDE, Text{ "SUPERSLIDE", "SUPERSLIDE", "SUPERSLIDE" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_SUPERSLIDE, RG_ABILITY_SUPERSLIDE, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_SUPERSLIDE] = Item(RG_ABILITY_SUPERSLIDE, Text{ "Superslide", "Superslide", "Superslide" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_SUPERSLIDE, RG_ABILITY_SUPERSLIDE, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_SUPERSLIDE].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_HOVER] = Item(RG_ABILITY_HOVER, Text{ "Hover", "Hover", "Hover" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HOVER, RG_ABILITY_HOVER, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_HOVER].SetCustomDrawFunc(Randomizer_DrawMysteryItem); 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 72de0b5bfc4..248127d1f81 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1818,6 +1818,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_ABILITY_SUPERSLIDE: SetRandoInf(RAND_INF_CAN_SUPERSLIDE, state); break; + case RG_ABILITY_HOVER: + SetRandoInf(RAND_INF_CAN_HOVER, state); + break; default: break; } @@ -2357,6 +2360,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_SUPERSLIDE).Is(false)) { SetRandoInf(RAND_INF_CAN_SUPERSLIDE, true); } + if (ctx->GetOption(RSK_SHUFFLE_HOVER).Is(false)) { + SetRandoInf(RAND_INF_CAN_HOVER, true); + } // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 1cf2a424377..8e6ff51125c 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -771,5 +771,7 @@ void Settings::CreateOptionDescriptions() { "Shuffles the ability to HESS into the item pool."; mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE] = "Shuffles the ability to superslide into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_HOVER] = + "Shuffles the ability to hover into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 357e2040e7c..8bc8aaf1628 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5394,7 +5394,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!", @@ -5734,6 +5734,9 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_ABILITY_SUPERSLIDE, ITEM_BOOTS_HOVER, "You got %rSuperslide%w!", "Du hast %rSuperslide%w&erhalten!", "Vous obtenez %rSuperslide%w!"), + GIMESSAGE(RG_ABILITY_HOVER, ITEM_BOOTS_HOVER, "You got %rHover%w!", + "Du hast %rHover%w&erhalten!", + "Vous obtenez %rHover%w!"), 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!", @@ -5933,6 +5936,7 @@ std::map randomizerGetToRandInf = { { RG_ABILITY_QPA, RAND_INF_CAN_QPA }, { RG_ABILITY_HESS, RAND_INF_CAN_HESS }, { RG_ABILITY_SUPERSLIDE, RAND_INF_CAN_SUPERSLIDE }, + { RG_ABILITY_HOVER, RAND_INF_CAN_HOVER }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 7a34001a879..98f57b775c3 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4061,6 +4061,7 @@ typedef enum { RG_ABILITY_QPA, RG_ABILITY_HESS, RG_ABILITY_SUPERSLIDE, + RG_ABILITY_HOVER, // Logic Only RG_DISTANT_SCARECROW, @@ -5663,6 +5664,7 @@ typedef enum { RHT_ABILITY_QPA, RHT_ABILITY_HESS, RHT_ABILITY_SUPERSLIDE, + RHT_ABILITY_HOVER, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5962,6 +5964,7 @@ typedef enum { RSK_SHUFFLE_QPA, RSK_SHUFFLE_HESS, RSK_SHUFFLE_SUPERSLIDE, + RSK_SHUFFLE_HOVER, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index f1a62590181..111e8bd462d 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1009,6 +1009,7 @@ DEFINE_RAND_INF(RAND_INF_CAN_OI) DEFINE_RAND_INF(RAND_INF_CAN_QPA) DEFINE_RAND_INF(RAND_INF_CAN_HESS) DEFINE_RAND_INF(RAND_INF_CAN_SUPERSLIDE) +DEFINE_RAND_INF(RAND_INF_CAN_HOVER) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 91fe3ca66c0..cba0d722392 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -273,6 +273,9 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_SUPERSLIDE) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_SUPERSLIDE); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_HOVER) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_HOVER); + } 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 38ee3b20106..43a98b8ab83 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -218,7 +218,8 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_OI, "Shuffle OI", CVAR_RANDOMIZER_SETTING("ShuffleOI"), mOptionDescriptions[RSK_SHUFFLE_OI]); OPT_BOOL(RSK_SHUFFLE_QPA, "Shuffle QPA", CVAR_RANDOMIZER_SETTING("ShuffleQPA"), mOptionDescriptions[RSK_SHUFFLE_QPA]); OPT_BOOL(RSK_SHUFFLE_HESS, "Shuffle HESS", CVAR_RANDOMIZER_SETTING("ShuffleHESS"), mOptionDescriptions[RSK_SHUFFLE_HESS]); - OPT_BOOL(RSK_SHUFFLE_SUPERSLIDE, "Shuffle Superslide", CVAR_RANDOMIZER_SETTING("ShuffleSUPERSLIDE"), mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE]); + OPT_BOOL(RSK_SHUFFLE_SUPERSLIDE, "Shuffle Superslide", CVAR_RANDOMIZER_SETTING("ShuffleSuperslide"), mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE]); + OPT_BOOL(RSK_SHUFFLE_HOVER, "Shuffle Hover", CVAR_RANDOMIZER_SETTING("ShuffleHover"), mOptionDescriptions[RSK_SHUFFLE_HOVER]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1257,6 +1258,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_QPA], &mOptions[RSK_SHUFFLE_HESS], &mOptions[RSK_SHUFFLE_SUPERSLIDE], + &mOptions[RSK_SHUFFLE_HOVER], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1556,6 +1558,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_QPA], &mOptions[RSK_SHUFFLE_HESS], &mOptions[RSK_SHUFFLE_SUPERSLIDE], + &mOptions[RSK_SHUFFLE_HOVER], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { 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 bc26e19977a..cfb72d69bfe 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -5789,7 +5789,7 @@ void func_8083AA10(Player* this, PlayState* play) { if (!(this->stateFlags3 & PLAYER_STATE3_MIDAIR) && !(this->skelAnime.movementFlags & 0x80) && (Player_Action_8084411C != this->actionFunc) && (Player_Action_80844A44 != this->actionFunc)) { - if ((sPrevFloorProperty == 7) || (this->meleeWeaponState != 0)) { + if ((sPrevFloorProperty == 7) || (GameInteractor_Should(VB_HOVER_WITH_ISG, true) && (this->meleeWeaponState != 0))) { Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); Player_ZeroSpeedXZ(this); return; From a6c3f2fa0d50065fda9e6fe216f65796f6674f5d Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Fri, 29 Aug 2025 23:25:47 +0100 Subject: [PATCH 06/11] equip swap --- .../game-interactor/GameInteractor_HookTable.h | 1 + .../game-interactor/GameInteractor_Hooks.cpp | 4 ++++ .../game-interactor/GameInteractor_Hooks.h | 1 + .../3drando/hint_list/hint_list_item.cpp | 8 ++++++++ .../randomizer/3drando/item_pool.cpp | 3 +++ .../Enhancements/randomizer/hook_handlers.cpp | 16 ++++++++++++++-- soh/soh/Enhancements/randomizer/item_list.cpp | 2 ++ soh/soh/Enhancements/randomizer/logic.cpp | 6 ++++++ .../randomizer/option_descriptions.cpp | 2 ++ soh/soh/Enhancements/randomizer/randomizer.cpp | 6 +++++- .../Enhancements/randomizer/randomizerTypes.h | 3 +++ soh/soh/Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 3 +++ soh/soh/Enhancements/randomizer/settings.cpp | 5 ++++- .../misc/ovl_kaleido_scope/z_kaleido_item.c | 2 ++ 15 files changed, 59 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 4049cd1bdd9..8f257af2213 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -78,3 +78,4 @@ DEFINE_HOOK(OnSetGameLanguage, ()); DEFINE_HOOK(OnFileDropped, (std::string filePath)); DEFINE_HOOK(OnAssetAltChange, ()); DEFINE_HOOK(OnKaleidoUpdate, ()); +DEFINE_HOOK(OnKaleidoMoveCursorFromSpecialPos, (PauseContext* pauseCtx, uint16_t* cursorItem)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 44a49cdea68..9f6bd21fdf1 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -339,3 +339,7 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) { void GameInteractor_ExecuteOnKaleidoUpdate() { GameInteractor::Instance->ExecuteHooks(); } + +void GameInteractor_ExecuteOnKaleidoMoveCursorFromSpecialPos(PauseContext* pauseCtx, uint16_t* cursorItem) { + GameInteractor::Instance->ExecuteHooks(pauseCtx, cursorItem); +} diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index b26a7ed26d8..241c672a5a2 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -88,6 +88,7 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)); // Mark: - Pause Menu void GameInteractor_ExecuteOnKaleidoUpdate(); +void GameInteractor_ExecuteOnKaleidoMoveCursorFromSpecialPos(PauseContext* pauseCtx, uint16_t* cursorItem); #ifdef __cplusplus } 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 d6fe2b32f47..992ee52a56c 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 @@ -2181,6 +2181,14 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("gravityn't", /*german*/"Hover", /*french*/"Hover")}); // /*spanish*/Hover + hintTextTable[RHT_ABILITY_EQUIP_SWAP] = HintText(CustomMessage("Equip Swap", /*german*/"Equip Swap", /*french*/"Equip Swap"), + // /*spanish*/Equip Swap + { + CustomMessage("an unbufferable ability", /*german*/"Equip Swap", /*french*/"Equip Swap") + // /*spanish*/Equip Swap + }, { + CustomMessage("a timeless talent", /*german*/"Equip Swap", /*french*/"Equip Swap")}); + // /*spanish*/Equip Swap //What is this used for? hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 16f7d97085c..d71a0b88909 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -609,6 +609,9 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_HOVER)) { AddItemToMainPool(RG_ABILITY_HOVER); } + if (ctx->GetOption(RSK_SHUFFLE_EQUIP_SWAP)) { + AddItemToMainPool(RG_ABILITY_EQUIP_SWAP); + } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 97936be0457..5a95eac36a6 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -2398,6 +2398,14 @@ void RandomizerShouldHover(bool* should) { } } +void RandomizerOnKaleidoMoveCursorFromSpecialPos(PauseContext* pauseCtx, uint16_t* cursorItem) { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_EQUIP_SWAP)) { + *cursorItem = PAUSE_ITEM_NONE; + // PAUSE_ITEM_NONE feels more accurate to intended behaviour, but alternative here also works + // *cursorItem = gSaveContext.inventory.items[pauseCtx->cursorPoint[PAUSE_ITEM]]; + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -2421,6 +2429,7 @@ void RandomizerRegisterHooks() { static uint32_t onQPADamageHook = 0; static uint32_t onESSHook = 0; static uint32_t onWaitForPutawayHook = 0; + static uint32_t onKaleidoMoveCursorFromSpecialPosHook = 0; static uint32_t fishsanityOnActorInitHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0; @@ -2457,6 +2466,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onQPADamageHook); GameInteractor::Instance->UnregisterGameHook(onESSHook); GameInteractor::Instance->UnregisterGameHook(onWaitForPutawayHook); + GameInteractor::Instance->UnregisterGameHook(onKaleidoMoveCursorFromSpecialPosHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); @@ -2543,8 +2553,10 @@ void RandomizerRegisterHooks() { [](SkelAnime* skelAnime) { RandomizerOnLinkAnimEnd(skelAnime); }); onQPADamageHook = GameInteractor::Instance->RegisterGameHook( [](uint32_t* dmgFlags) { RandomizerOnQPADamage(dmgFlags); }); - onESSHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnESS); - onWaitForPutawayHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnWaitForPutaway); + onESSHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnESS); + onWaitForPutawayHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnWaitForPutaway); + onKaleidoMoveCursorFromSpecialPosHook = GameInteractor::Instance->RegisterGameHook( + [](PauseContext* pauseCtx, uint16_t* cursorItem) { RandomizerOnKaleidoMoveCursorFromSpecialPos(pauseCtx, cursorItem); }); COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); }); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 643f3366f87..2c0c2302fc2 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -364,6 +364,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ABILITY_SUPERSLIDE].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_HOVER] = Item(RG_ABILITY_HOVER, Text{ "Hover", "Hover", "Hover" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HOVER, RG_ABILITY_HOVER, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_HOVER].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_EQUIP_SWAP] = Item(RG_ABILITY_EQUIP_SWAP, Text{ "Equip Swap", "Equip Swap", "Equip Swap" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_EQUIP_SWAP, RG_ABILITY_EQUIP_SWAP, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_EQUIP_SWAP].SetCustomDrawFunc(Randomizer_DrawMysteryItem); 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 248127d1f81..0719036f099 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1821,6 +1821,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_ABILITY_HOVER: SetRandoInf(RAND_INF_CAN_HOVER, state); break; + case RG_ABILITY_EQUIP_SWAP: + SetRandoInf(RAND_INF_CAN_EQUIP_SWAP, state); + break; default: break; } @@ -2363,6 +2366,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_HOVER).Is(false)) { SetRandoInf(RAND_INF_CAN_HOVER, true); } + if (ctx->GetOption(RSK_SHUFFLE_EQUIP_SWAP).Is(false)) { + SetRandoInf(RAND_INF_CAN_EQUIP_SWAP, true); + } // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 8e6ff51125c..29d0d42b8f5 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -773,5 +773,7 @@ void Settings::CreateOptionDescriptions() { "Shuffles the ability to superslide into the item pool."; mOptionDescriptions[RSK_SHUFFLE_HOVER] = "Shuffles the ability to hover into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP] = + "Shuffles the ability to equip swap into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 8bc8aaf1628..4b01083b58c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5394,7 +5394,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!", @@ -5737,6 +5737,9 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_ABILITY_HOVER, ITEM_BOOTS_HOVER, "You got %rHover%w!", "Du hast %rHover%w&erhalten!", "Vous obtenez %rHover%w!"), + GIMESSAGE(RG_ABILITY_EQUIP_SWAP, ITEM_DINS_FIRE, "You got %rEquip Swap%w!", + "Du hast %rEquip Swap%w&erhalten!", + "Vous obtenez %rEquip Swap%w!"), 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!", @@ -5937,6 +5940,7 @@ std::map randomizerGetToRandInf = { { RG_ABILITY_HESS, RAND_INF_CAN_HESS }, { RG_ABILITY_SUPERSLIDE, RAND_INF_CAN_SUPERSLIDE }, { RG_ABILITY_HOVER, RAND_INF_CAN_HOVER }, + { RG_ABILITY_EQUIP_SWAP, RAND_INF_CAN_EQUIP_SWAP }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 98f57b775c3..ca6d1438d6e 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4062,6 +4062,7 @@ typedef enum { RG_ABILITY_HESS, RG_ABILITY_SUPERSLIDE, RG_ABILITY_HOVER, + RG_ABILITY_EQUIP_SWAP, // Logic Only RG_DISTANT_SCARECROW, @@ -5665,6 +5666,7 @@ typedef enum { RHT_ABILITY_HESS, RHT_ABILITY_SUPERSLIDE, RHT_ABILITY_HOVER, + RHT_ABILITY_EQUIP_SWAP, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5965,6 +5967,7 @@ typedef enum { RSK_SHUFFLE_HESS, RSK_SHUFFLE_SUPERSLIDE, RSK_SHUFFLE_HOVER, + RSK_SHUFFLE_EQUIP_SWAP, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 111e8bd462d..2dd9e5ada75 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1010,6 +1010,7 @@ DEFINE_RAND_INF(RAND_INF_CAN_QPA) DEFINE_RAND_INF(RAND_INF_CAN_HESS) DEFINE_RAND_INF(RAND_INF_CAN_SUPERSLIDE) DEFINE_RAND_INF(RAND_INF_CAN_HOVER) +DEFINE_RAND_INF(RAND_INF_CAN_EQUIP_SWAP) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index cba0d722392..c588c05b453 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -276,6 +276,9 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_HOVER) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_HOVER); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_EQUIP_SWAP) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_EQUIP_SWAP); + } 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 43a98b8ab83..53358c439e8 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -219,7 +219,8 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_QPA, "Shuffle QPA", CVAR_RANDOMIZER_SETTING("ShuffleQPA"), mOptionDescriptions[RSK_SHUFFLE_QPA]); OPT_BOOL(RSK_SHUFFLE_HESS, "Shuffle HESS", CVAR_RANDOMIZER_SETTING("ShuffleHESS"), mOptionDescriptions[RSK_SHUFFLE_HESS]); OPT_BOOL(RSK_SHUFFLE_SUPERSLIDE, "Shuffle Superslide", CVAR_RANDOMIZER_SETTING("ShuffleSuperslide"), mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE]); - OPT_BOOL(RSK_SHUFFLE_HOVER, "Shuffle Hover", CVAR_RANDOMIZER_SETTING("ShuffleHover"), mOptionDescriptions[RSK_SHUFFLE_HOVER]); + OPT_BOOL(RSK_SHUFFLE_HOVER, "Shuffle Hovering", CVAR_RANDOMIZER_SETTING("ShuffleHover"), mOptionDescriptions[RSK_SHUFFLE_HOVER]); + OPT_BOOL(RSK_SHUFFLE_EQUIP_SWAP, "Shuffle Equip Swap", CVAR_RANDOMIZER_SETTING("ShuffleEquipSwap"), mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1259,6 +1260,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_HESS], &mOptions[RSK_SHUFFLE_SUPERSLIDE], &mOptions[RSK_SHUFFLE_HOVER], + &mOptions[RSK_SHUFFLE_EQUIP_SWAP], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1559,6 +1561,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_HESS], &mOptions[RSK_SHUFFLE_SUPERSLIDE], &mOptions[RSK_SHUFFLE_HOVER], + &mOptions[RSK_SHUFFLE_EQUIP_SWAP], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index beef301c411..2e13781e966 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -553,6 +553,7 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { pauseCtx->cursorX[PAUSE_ITEM] = cursorX; pauseCtx->cursorY[PAUSE_ITEM] = cursorY; moveCursorResult = 1; + GameInteractor_ExecuteOnKaleidoMoveCursorFromSpecialPos(pauseCtx, &cursorItem); break; } @@ -589,6 +590,7 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { pauseCtx->cursorX[PAUSE_ITEM] = cursorX; pauseCtx->cursorY[PAUSE_ITEM] = cursorY; moveCursorResult = 1; + GameInteractor_ExecuteOnKaleidoMoveCursorFromSpecialPos(pauseCtx, &cursorItem); break; } From 0c5622e50a48c88b3ec0d5e5012e261aaf33d2d7 Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Sat, 30 Aug 2025 15:03:44 +0100 Subject: [PATCH 07/11] Ground jump --- .../randomizer/3drando/hint_list/hint_list_item.cpp | 8 ++++++++ soh/soh/Enhancements/randomizer/3drando/item_pool.cpp | 3 +++ soh/soh/Enhancements/randomizer/hook_handlers.cpp | 9 +++++++++ soh/soh/Enhancements/randomizer/item_list.cpp | 2 ++ soh/soh/Enhancements/randomizer/logic.cpp | 6 ++++++ soh/soh/Enhancements/randomizer/option_descriptions.cpp | 2 ++ soh/soh/Enhancements/randomizer/randomizer.cpp | 4 ++++ soh/soh/Enhancements/randomizer/randomizerTypes.h | 3 +++ soh/soh/Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 3 +++ soh/soh/Enhancements/randomizer/settings.cpp | 3 +++ 11 files changed, 44 insertions(+) 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 992ee52a56c..0c93bd7003a 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 @@ -2189,6 +2189,14 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("a timeless talent", /*german*/"Equip Swap", /*french*/"Equip Swap")}); // /*spanish*/Equip Swap + hintTextTable[RHT_ABILITY_GROUND_JUMP] = HintText(CustomMessage("Ground Jump", /*german*/"Ground Jump", /*french*/"Ground Jump"), + // /*spanish*/Ground Jump + { + CustomMessage("a little leap", /*german*/"Ground Jump", /*french*/"Ground Jump") + // /*spanish*/Ground Jump + }, { + CustomMessage("a beginner's trick", /*german*/"Ground Jump", /*french*/"Ground Jump")}); + // /*spanish*/Ground Jump //What is this used for? hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index d71a0b88909..c868f2433bd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -612,6 +612,9 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_EQUIP_SWAP)) { AddItemToMainPool(RG_ABILITY_EQUIP_SWAP); } + if (ctx->GetOption(RSK_SHUFFLE_GROUND_JUMP)) { + AddItemToMainPool(RG_ABILITY_GROUND_JUMP); + } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 5a95eac36a6..bb573fac6a3 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -73,6 +73,7 @@ extern void func_80832318(Player* player); extern void Player_SetupActionPreserveItemAction(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 flags); extern void Player_Action_Idle(Player* player, PlayState* play); extern s32 Player_DecelerateToZero(Player* player); +extern s32 func_80834BD4(Player* player, PlayState* play); } bool LocMatchesQuest(Rando::Location loc) { @@ -2286,6 +2287,14 @@ void RandomizerOnPlayerUpdateHandler() { GameInteractor::State::TriforceHuntPieceGiven = 0; } } + + if (!Flags_GetRandomizerInf(RAND_INF_CAN_GROUND_JUMP)) { + if (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR && GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_SHIELDING) { + if (GET_PLAYER(gPlayState)->upperActionFunc == func_80834BD4 && GET_PLAYER(gPlayState)->heldActor == NULL) { + GET_PLAYER(gPlayState)->stateFlags1 &= ~PLAYER_STATE1_CARRYING_ACTOR; + } + } + } } void RandomizerOnSceneSpawnActorsHandler() { diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 2c0c2302fc2..8d0259eff51 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -366,6 +366,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ABILITY_HOVER].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_EQUIP_SWAP] = Item(RG_ABILITY_EQUIP_SWAP, Text{ "Equip Swap", "Equip Swap", "Equip Swap" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_EQUIP_SWAP, RG_ABILITY_EQUIP_SWAP, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_EQUIP_SWAP].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_GROUND_JUMP] = Item(RG_ABILITY_GROUND_JUMP, Text{ "Ground Jump", "Ground Jump", "Ground Jump" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_GROUND_JUMP, RG_ABILITY_GROUND_JUMP, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_GROUND_JUMP].SetCustomDrawFunc(Randomizer_DrawMysteryItem); 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 0719036f099..594c9728fb6 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1824,6 +1824,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_ABILITY_EQUIP_SWAP: SetRandoInf(RAND_INF_CAN_EQUIP_SWAP, state); break; + case RG_ABILITY_GROUND_JUMP: + SetRandoInf(RAND_INF_CAN_GROUND_JUMP, state); + break; default: break; } @@ -2369,6 +2372,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_EQUIP_SWAP).Is(false)) { SetRandoInf(RAND_INF_CAN_EQUIP_SWAP, true); } + if (ctx->GetOption(RSK_SHUFFLE_GROUND_JUMP).Is(false)) { + SetRandoInf(RAND_INF_CAN_GROUND_JUMP, true); + } // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 29d0d42b8f5..a2edc699459 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -775,5 +775,7 @@ void Settings::CreateOptionDescriptions() { "Shuffles the ability to hover into the item pool."; mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP] = "Shuffles the ability to equip swap into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP] = + "Shuffles the ability to ground jump into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 4b01083b58c..40a9ccd72a4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5740,6 +5740,9 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_ABILITY_EQUIP_SWAP, ITEM_DINS_FIRE, "You got %rEquip Swap%w!", "Du hast %rEquip Swap%w&erhalten!", "Vous obtenez %rEquip Swap%w!"), + GIMESSAGE(RG_ABILITY_GROUND_JUMP, ITEM_DINS_FIRE, "You got %rGround Jump%w!", + "Du hast %rGround Jump%w&erhalten!", + "Vous obtenez %rGround Jump%w!"), 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!", @@ -5941,6 +5944,7 @@ std::map randomizerGetToRandInf = { { RG_ABILITY_SUPERSLIDE, RAND_INF_CAN_SUPERSLIDE }, { RG_ABILITY_HOVER, RAND_INF_CAN_HOVER }, { RG_ABILITY_EQUIP_SWAP, RAND_INF_CAN_EQUIP_SWAP }, + { RG_ABILITY_GROUND_JUMP, RAND_INF_CAN_GROUND_JUMP }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index ca6d1438d6e..be4f9f4e439 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4063,6 +4063,7 @@ typedef enum { RG_ABILITY_SUPERSLIDE, RG_ABILITY_HOVER, RG_ABILITY_EQUIP_SWAP, + RG_ABILITY_GROUND_JUMP, // Logic Only RG_DISTANT_SCARECROW, @@ -5667,6 +5668,7 @@ typedef enum { RHT_ABILITY_SUPERSLIDE, RHT_ABILITY_HOVER, RHT_ABILITY_EQUIP_SWAP, + RHT_ABILITY_GROUND_JUMP, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5968,6 +5970,7 @@ typedef enum { RSK_SHUFFLE_SUPERSLIDE, RSK_SHUFFLE_HOVER, RSK_SHUFFLE_EQUIP_SWAP, + RSK_SHUFFLE_GROUND_JUMP, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 2dd9e5ada75..c8f88c2c169 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1011,6 +1011,7 @@ DEFINE_RAND_INF(RAND_INF_CAN_HESS) DEFINE_RAND_INF(RAND_INF_CAN_SUPERSLIDE) DEFINE_RAND_INF(RAND_INF_CAN_HOVER) DEFINE_RAND_INF(RAND_INF_CAN_EQUIP_SWAP) +DEFINE_RAND_INF(RAND_INF_CAN_GROUND_JUMP) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index c588c05b453..bdf1875f26a 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -279,6 +279,9 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_EQUIP_SWAP) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_EQUIP_SWAP); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROUND_JUMP) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_GROUND_JUMP); + } 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 53358c439e8..c656e598664 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -221,6 +221,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_SUPERSLIDE, "Shuffle Superslide", CVAR_RANDOMIZER_SETTING("ShuffleSuperslide"), mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE]); OPT_BOOL(RSK_SHUFFLE_HOVER, "Shuffle Hovering", CVAR_RANDOMIZER_SETTING("ShuffleHover"), mOptionDescriptions[RSK_SHUFFLE_HOVER]); OPT_BOOL(RSK_SHUFFLE_EQUIP_SWAP, "Shuffle Equip Swap", CVAR_RANDOMIZER_SETTING("ShuffleEquipSwap"), mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP]); + OPT_BOOL(RSK_SHUFFLE_GROUND_JUMP, "Shuffle Ground Jump", CVAR_RANDOMIZER_SETTING("ShuffleGroundJump"), mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1261,6 +1262,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_SUPERSLIDE], &mOptions[RSK_SHUFFLE_HOVER], &mOptions[RSK_SHUFFLE_EQUIP_SWAP], + &mOptions[RSK_SHUFFLE_GROUND_JUMP], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1562,6 +1564,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_SUPERSLIDE], &mOptions[RSK_SHUFFLE_HOVER], &mOptions[RSK_SHUFFLE_EQUIP_SWAP], + &mOptions[RSK_SHUFFLE_GROUND_JUMP], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { From 2cb76a13dbca3fbd60db09bc6562ac855902d3cd Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Sat, 30 Aug 2025 15:39:43 +0100 Subject: [PATCH 08/11] weirdshot --- .../GameInteractor_HookTable.h | 1 + .../game-interactor/GameInteractor_Hooks.cpp | 4 ++++ .../game-interactor/GameInteractor_Hooks.h | 1 + .../3drando/hint_list/hint_list_item.cpp | 8 +++++++ .../randomizer/3drando/item_pool.cpp | 3 +++ .../Enhancements/randomizer/hook_handlers.cpp | 22 +++++++++++++++++++ soh/soh/Enhancements/randomizer/item_list.cpp | 4 +++- soh/soh/Enhancements/randomizer/logic.cpp | 6 +++++ .../randomizer/option_descriptions.cpp | 2 ++ .../Enhancements/randomizer/randomizer.cpp | 8 +++++-- .../Enhancements/randomizer/randomizerTypes.h | 3 +++ .../Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 3 +++ soh/soh/Enhancements/randomizer/settings.cpp | 3 +++ soh/src/code/z_skelanime.c | 2 ++ 15 files changed, 68 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 8f257af2213..65dce6817c5 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -51,6 +51,7 @@ DEFINE_HOOK(OnLinkAnimEnd, (SkelAnime* skelAnime)); DEFINE_HOOK(OnQPADamage, (uint32_t* dmgFlags)); DEFINE_HOOK(OnESS, ()); DEFINE_HOOK(OnWaitForPutaway, ()); +DEFINE_HOOK(OnAnimationSetLoadFrame, (LinkAnimationHeader* animation, int32_t* frame)); DEFINE_HOOK(OnDialogMessage, ()); DEFINE_HOOK(OnPresentTitleCard, ()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 9f6bd21fdf1..18872ee7d11 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -113,6 +113,10 @@ void GameInteractor_ExecuteOnWaitForPutaway() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnAnimationSetLoadFrame(LinkAnimationHeader* animation, int32_t* frame) { + GameInteractor::Instance->ExecuteHooks(animation, frame); +} + void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) { GameInteractor::Instance->ExecuteHooks(cursorIndex, price); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 241c672a5a2..d64d0a7fc9c 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -32,6 +32,7 @@ void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime); void GameInteractor_ExecuteOnQPADamage(uint32_t* dmgFlags); void GameInteractor_ExecuteOnESS(); void GameInteractor_ExecuteOnWaitForPutaway(); +void GameInteractor_ExecuteOnAnimationSetLoadFrame(LinkAnimationHeader* animation, int32_t* frame); void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorSpawn(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor); 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 0c93bd7003a..ce4ebfc4f57 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 @@ -2197,6 +2197,14 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("a beginner's trick", /*german*/"Ground Jump", /*french*/"Ground Jump")}); // /*spanish*/Ground Jump + hintTextTable[RHT_ABILITY_WEIRDSHOT] = HintText(CustomMessage("Weirdshot", /*german*/"Weirdshot", /*french*/"Weirdshot"), + // /*spanish*/Weirdshot + { + CustomMessage("a weird shot", /*german*/"Weirdshot", /*french*/"Weirdshot") + // /*spanish*/Weirdshot + }, { + CustomMessage("a mangled animation", /*german*/"Weirdshot", /*french*/"Weirdshot")}); + // /*spanish*/Weirdshot //What is this used for? hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index c868f2433bd..979136d3660 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -615,6 +615,9 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_GROUND_JUMP)) { AddItemToMainPool(RG_ABILITY_GROUND_JUMP); } + if (ctx->GetOption(RSK_SHUFFLE_WEIRDSHOT)) { + AddItemToMainPool(RG_ABILITY_WEIRDSHOT); + } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index bb573fac6a3..124d051b16f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -2415,6 +2415,24 @@ void RandomizerOnKaleidoMoveCursorFromSpecialPos(PauseContext* pauseCtx, uint16_ } } +void RandomizerOnAnimationSetLoadFrame(LinkAnimationHeader* animation, int32_t* frame) { + if (!Flags_GetRandomizerInf(RAND_INF_CAN_WEIRDSHOT)) { + std::optional animationName; + + if (ResourceMgr_OTRSigCheck(reinterpret_cast(animation)) != 0) { + animationName = reinterpret_cast(animation); + animation = reinterpret_cast(ResourceMgr_LoadAnimByName(*animationName)); + } + + const auto playerAnimHeader = + static_cast(SEGMENTED_TO_VIRTUAL(static_cast(animation))); + + if (*frame < 0 || *frame >= playerAnimHeader->common.frameCount) { + *frame = 0; + } + } +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; @@ -2439,6 +2457,7 @@ void RandomizerRegisterHooks() { static uint32_t onESSHook = 0; static uint32_t onWaitForPutawayHook = 0; static uint32_t onKaleidoMoveCursorFromSpecialPosHook = 0; + static uint32_t onAnimationSetLoadFrameHook = 0; static uint32_t fishsanityOnActorInitHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0; @@ -2476,6 +2495,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onESSHook); GameInteractor::Instance->UnregisterGameHook(onWaitForPutawayHook); GameInteractor::Instance->UnregisterGameHook(onKaleidoMoveCursorFromSpecialPosHook); + GameInteractor::Instance->UnregisterGameHook(onAnimationSetLoadFrameHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); @@ -2566,6 +2586,8 @@ void RandomizerRegisterHooks() { onWaitForPutawayHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnWaitForPutaway); onKaleidoMoveCursorFromSpecialPosHook = GameInteractor::Instance->RegisterGameHook( [](PauseContext* pauseCtx, uint16_t* cursorItem) { RandomizerOnKaleidoMoveCursorFromSpecialPos(pauseCtx, cursorItem); }); + onAnimationSetLoadFrameHook = GameInteractor::Instance->RegisterGameHook( + [](LinkAnimationHeader* animation, int32_t* frame) { RandomizerOnAnimationSetLoadFrame(animation, frame); }); COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); }); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 8d0259eff51..774499e02b6 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -366,8 +366,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ABILITY_HOVER].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_EQUIP_SWAP] = Item(RG_ABILITY_EQUIP_SWAP, Text{ "Equip Swap", "Equip Swap", "Equip Swap" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_EQUIP_SWAP, RG_ABILITY_EQUIP_SWAP, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_EQUIP_SWAP].SetCustomDrawFunc(Randomizer_DrawMysteryItem); - itemTable[RG_ABILITY_GROUND_JUMP] = Item(RG_ABILITY_GROUND_JUMP, Text{ "Ground Jump", "Ground Jump", "Ground Jump" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_GROUND_JUMP, RG_ABILITY_GROUND_JUMP, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_GROUND_JUMP] = Item(RG_ABILITY_GROUND_JUMP, Text{ "Ground Jump", "Ground Jump", "Ground Jump" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_GROUND_JUMP, RG_ABILITY_GROUND_JUMP, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_GROUND_JUMP].SetCustomDrawFunc(Randomizer_DrawMysteryItem); + itemTable[RG_ABILITY_WEIRDSHOT] = Item(RG_ABILITY_WEIRDSHOT, Text{ "Weirdshot", "Weirdshot", "Weirdshot" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_WEIRDSHOT, RG_ABILITY_WEIRDSHOT, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_WEIRDSHOT].SetCustomDrawFunc(Randomizer_DrawMysteryItem); 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 594c9728fb6..97471c64876 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1827,6 +1827,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_ABILITY_GROUND_JUMP: SetRandoInf(RAND_INF_CAN_GROUND_JUMP, state); break; + case RG_ABILITY_WEIRDSHOT: + SetRandoInf(RAND_INF_CAN_WEIRDSHOT, state); + break; default: break; } @@ -2375,6 +2378,9 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_GROUND_JUMP).Is(false)) { SetRandoInf(RAND_INF_CAN_GROUND_JUMP, true); } + if (ctx->GetOption(RSK_SHUFFLE_WEIRDSHOT).Is(false)) { + SetRandoInf(RAND_INF_CAN_WEIRDSHOT, true); + } // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index a2edc699459..386f091c2cd 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -777,5 +777,7 @@ void Settings::CreateOptionDescriptions() { "Shuffles the ability to equip swap into the item pool."; mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP] = "Shuffles the ability to ground jump into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_WEIRDSHOT] = + "Shuffles the ability to weirdshot into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 40a9ccd72a4..7e2553492ca 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5394,7 +5394,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!", @@ -5740,9 +5740,12 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_ABILITY_EQUIP_SWAP, ITEM_DINS_FIRE, "You got %rEquip Swap%w!", "Du hast %rEquip Swap%w&erhalten!", "Vous obtenez %rEquip Swap%w!"), - GIMESSAGE(RG_ABILITY_GROUND_JUMP, ITEM_DINS_FIRE, "You got %rGround Jump%w!", + GIMESSAGE(RG_ABILITY_GROUND_JUMP, ITEM_SHIELD_HYLIAN, "You got %rGround Jump%w!", "Du hast %rGround Jump%w&erhalten!", "Vous obtenez %rGround Jump%w!"), + GIMESSAGE(RG_ABILITY_WEIRDSHOT, ITEM_HOOKSHOT, "You got %rWeirdshot%w!", + "Du hast %rWeirdshot%w&erhalten!", + "Vous obtenez %rWeirdshot%w!"), 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!", @@ -5945,6 +5948,7 @@ std::map randomizerGetToRandInf = { { RG_ABILITY_HOVER, RAND_INF_CAN_HOVER }, { RG_ABILITY_EQUIP_SWAP, RAND_INF_CAN_EQUIP_SWAP }, { RG_ABILITY_GROUND_JUMP, RAND_INF_CAN_GROUND_JUMP }, + { RG_ABILITY_WEIRDSHOT, RAND_INF_CAN_WEIRDSHOT }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index be4f9f4e439..ef61a11cb62 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4064,6 +4064,7 @@ typedef enum { RG_ABILITY_HOVER, RG_ABILITY_EQUIP_SWAP, RG_ABILITY_GROUND_JUMP, + RG_ABILITY_WEIRDSHOT, // Logic Only RG_DISTANT_SCARECROW, @@ -5669,6 +5670,7 @@ typedef enum { RHT_ABILITY_HOVER, RHT_ABILITY_EQUIP_SWAP, RHT_ABILITY_GROUND_JUMP, + RHT_ABILITY_WEIRDSHOT, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -5971,6 +5973,7 @@ typedef enum { RSK_SHUFFLE_HOVER, RSK_SHUFFLE_EQUIP_SWAP, RSK_SHUFFLE_GROUND_JUMP, + RSK_SHUFFLE_WEIRDSHOT, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index c8f88c2c169..be967faab0b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1012,6 +1012,7 @@ DEFINE_RAND_INF(RAND_INF_CAN_SUPERSLIDE) DEFINE_RAND_INF(RAND_INF_CAN_HOVER) DEFINE_RAND_INF(RAND_INF_CAN_EQUIP_SWAP) DEFINE_RAND_INF(RAND_INF_CAN_GROUND_JUMP) +DEFINE_RAND_INF(RAND_INF_CAN_WEIRDSHOT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT) DEFINE_RAND_INF(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index bdf1875f26a..a1928dc144d 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -282,6 +282,9 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROUND_JUMP) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_GROUND_JUMP); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_WEIRDSHOT) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_WEIRDSHOT); + } 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 c656e598664..027452fdc5b 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -222,6 +222,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_HOVER, "Shuffle Hovering", CVAR_RANDOMIZER_SETTING("ShuffleHover"), mOptionDescriptions[RSK_SHUFFLE_HOVER]); OPT_BOOL(RSK_SHUFFLE_EQUIP_SWAP, "Shuffle Equip Swap", CVAR_RANDOMIZER_SETTING("ShuffleEquipSwap"), mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP]); OPT_BOOL(RSK_SHUFFLE_GROUND_JUMP, "Shuffle Ground Jump", CVAR_RANDOMIZER_SETTING("ShuffleGroundJump"), mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP]); + OPT_BOOL(RSK_SHUFFLE_WEIRDSHOT, "Shuffle Weirdshot", CVAR_RANDOMIZER_SETTING("ShuffleWeirdshot"), mOptionDescriptions[RSK_SHUFFLE_WEIRDSHOT]); 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); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); @@ -1263,6 +1264,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_HOVER], &mOptions[RSK_SHUFFLE_EQUIP_SWAP], &mOptions[RSK_SHUFFLE_GROUND_JUMP], + &mOptions[RSK_SHUFFLE_WEIRDSHOT], }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = @@ -1565,6 +1567,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_HOVER], &mOptions[RSK_SHUFFLE_EQUIP_SWAP], &mOptions[RSK_SHUFFLE_GROUND_JUMP], + &mOptions[RSK_SHUFFLE_WEIRDSHOT], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c index 6518dee1359..fcb20a342ea 100644 --- a/soh/src/code/z_skelanime.c +++ b/soh/src/code/z_skelanime.c @@ -889,6 +889,8 @@ void AnimationContext_SetLoadFrame(PlayState* play, LinkAnimationHeader* animati Vec3s* frameTable) { AnimationEntry* entry = AnimationContext_AddEntry(&play->animationCtx, ANIMENTRY_LOADFRAME); + GameInteractor_ExecuteOnAnimationSetLoadFrame(animation, &frame); + if (GameInteractor_Should(VB_LOAD_PLAYER_ANIMATION_FRAME, entry != NULL, entry, animation, frame, limbCount, frameTable)) { if (ResourceMgr_OTRSigCheck(animation) != 0) From dff9dd5a764dc9b11be33747556fdfc7bab3bc98 Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Sat, 30 Aug 2025 15:50:42 +0100 Subject: [PATCH 09/11] format --- .../GameInteractor_HookTable.h | 8 ++--- .../Enhancements/randomizer/hook_handlers.cpp | 33 ++++++++++++------- .../randomizer/option_descriptions.cpp | 24 +++++--------- .../Enhancements/randomizer/randomizer.cpp | 29 ++++++---------- .../actors/ovl_player_actor/z_player.c | 3 +- 5 files changed, 46 insertions(+), 51 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 65dce6817c5..78fe45df8c0 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -47,11 +47,11 @@ DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list or DEFINE_HOOK(OnSaveFile, (int32_t fileNum)); DEFINE_HOOK(OnLoadFile, (int32_t fileNum)); DEFINE_HOOK(OnDeleteFile, (int32_t fileNum)); -DEFINE_HOOK(OnLinkAnimEnd, (SkelAnime* skelAnime)); -DEFINE_HOOK(OnQPADamage, (uint32_t* dmgFlags)); +DEFINE_HOOK(OnLinkAnimEnd, (SkelAnime * skelAnime)); +DEFINE_HOOK(OnQPADamage, (uint32_t * dmgFlags)); DEFINE_HOOK(OnESS, ()); DEFINE_HOOK(OnWaitForPutaway, ()); -DEFINE_HOOK(OnAnimationSetLoadFrame, (LinkAnimationHeader* animation, int32_t* frame)); +DEFINE_HOOK(OnAnimationSetLoadFrame, (LinkAnimationHeader * animation, int32_t* frame)); DEFINE_HOOK(OnDialogMessage, ()); DEFINE_HOOK(OnPresentTitleCard, ()); @@ -79,4 +79,4 @@ DEFINE_HOOK(OnSetGameLanguage, ()); DEFINE_HOOK(OnFileDropped, (std::string filePath)); DEFINE_HOOK(OnAssetAltChange, ()); DEFINE_HOOK(OnKaleidoUpdate, ()); -DEFINE_HOOK(OnKaleidoMoveCursorFromSpecialPos, (PauseContext* pauseCtx, uint16_t* cursorItem)); +DEFINE_HOOK(OnKaleidoMoveCursorFromSpecialPos, (PauseContext * pauseCtx, uint16_t* cursorItem)); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 124d051b16f..7665753e4ad 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -70,7 +70,8 @@ extern void EnGe1_SetAnimationIdle(EnGe1* enGe1); extern void EnGe1_SetAnimationIdle(EnGe1* enGe1); extern void EnGe2_SetupCapturePlayer(EnGe2* enGe2, PlayState* play); extern void func_80832318(Player* player); -extern void Player_SetupActionPreserveItemAction(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 flags); +extern void Player_SetupActionPreserveItemAction(PlayState* play, Player* player, PlayerActionFunc actionFunc, + s32 flags); extern void Player_Action_Idle(Player* player, PlayState* play); extern s32 Player_DecelerateToZero(Player* player); extern s32 func_80834BD4(Player* player, PlayState* play); @@ -2289,7 +2290,8 @@ void RandomizerOnPlayerUpdateHandler() { } if (!Flags_GetRandomizerInf(RAND_INF_CAN_GROUND_JUMP)) { - if (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR && GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_SHIELDING) { + if (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR && + GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_SHIELDING) { if (GET_PLAYER(gPlayState)->upperActionFunc == func_80834BD4 && GET_PLAYER(gPlayState)->heldActor == NULL) { GET_PLAYER(gPlayState)->stateFlags1 &= ~PLAYER_STATE1_CARRYING_ACTOR; } @@ -2369,7 +2371,7 @@ void RandomizerOnLinkAnimEnd(SkelAnime* skelAnime) { } void RandomizerShouldSkipForcePlayOcarina(bool* should) { - + if (!Flags_GetRandomizerInf(RAND_INF_CAN_OI)) { Player* player = GET_PLAYER(gPlayState); @@ -2494,8 +2496,10 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onQPADamageHook); GameInteractor::Instance->UnregisterGameHook(onESSHook); GameInteractor::Instance->UnregisterGameHook(onWaitForPutawayHook); - GameInteractor::Instance->UnregisterGameHook(onKaleidoMoveCursorFromSpecialPosHook); - GameInteractor::Instance->UnregisterGameHook(onAnimationSetLoadFrameHook); + GameInteractor::Instance->UnregisterGameHook( + onKaleidoMoveCursorFromSpecialPosHook); + GameInteractor::Instance->UnregisterGameHook( + onAnimationSetLoadFrameHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); @@ -2582,12 +2586,19 @@ void RandomizerRegisterHooks() { [](SkelAnime* skelAnime) { RandomizerOnLinkAnimEnd(skelAnime); }); onQPADamageHook = GameInteractor::Instance->RegisterGameHook( [](uint32_t* dmgFlags) { RandomizerOnQPADamage(dmgFlags); }); - onESSHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnESS); - onWaitForPutawayHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnWaitForPutaway); - onKaleidoMoveCursorFromSpecialPosHook = GameInteractor::Instance->RegisterGameHook( - [](PauseContext* pauseCtx, uint16_t* cursorItem) { RandomizerOnKaleidoMoveCursorFromSpecialPos(pauseCtx, cursorItem); }); - onAnimationSetLoadFrameHook = GameInteractor::Instance->RegisterGameHook( - [](LinkAnimationHeader* animation, int32_t* frame) { RandomizerOnAnimationSetLoadFrame(animation, frame); }); + onESSHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnESS); + onWaitForPutawayHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnWaitForPutaway); + onKaleidoMoveCursorFromSpecialPosHook = + GameInteractor::Instance->RegisterGameHook( + [](PauseContext* pauseCtx, uint16_t* cursorItem) { + RandomizerOnKaleidoMoveCursorFromSpecialPos(pauseCtx, cursorItem); + }); + onAnimationSetLoadFrameHook = + GameInteractor::Instance->RegisterGameHook( + [](LinkAnimationHeader* animation, int32_t* frame) { + RandomizerOnAnimationSetLoadFrame(animation, frame); + }); COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); }); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 386f091c2cd..29fb543e414 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -761,23 +761,15 @@ void Settings::CreateOptionDescriptions() { "respective soul." "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; - mOptionDescriptions[RSK_SHUFFLE_ISG] = - "Shuffles the ability to use the glitch ISG into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_OI] = - "Shuffles the ability to use the glitch Ocarina Items into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_ISG] = "Shuffles the ability to use the glitch ISG into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_OI] = "Shuffles the ability to use the glitch Ocarina Items into the item pool."; mOptionDescriptions[RSK_SHUFFLE_QPA] = "Shuffles the ability to use Quick Putaway Glitched Damage into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_HESS] = - "Shuffles the ability to HESS into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE] = - "Shuffles the ability to superslide into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_HOVER] = - "Shuffles the ability to hover into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP] = - "Shuffles the ability to equip swap into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP] = - "Shuffles the ability to ground jump into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_WEIRDSHOT] = - "Shuffles the ability to weirdshot into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_HESS] = "Shuffles the ability to HESS into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE] = "Shuffles the ability to superslide into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_HOVER] = "Shuffles the ability to hover into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP] = "Shuffles the ability to equip swap into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP] = "Shuffles the ability to ground jump into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_WEIRDSHOT] = "Shuffles the ability to weirdshot into the item pool."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 7e2553492ca..720726db736 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5719,34 +5719,25 @@ void Randomizer::CreateCustomMessages() { "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_ABILITY_ISG, ITEM_SWORD_MASTER, "You got %rISG%w!", - "Du hast %rISG%w&erhalten!", + GIMESSAGE(RG_ABILITY_ISG, ITEM_SWORD_MASTER, "You got %rISG%w!", "Du hast %rISG%w&erhalten!", "Vous obtenez %rISG%w!"), - GIMESSAGE(RG_ABILITY_OI, ITEM_OCARINA_TIME, "You got %rOI%w!", - "Du hast %rOI%w&erhalten!", + GIMESSAGE(RG_ABILITY_OI, ITEM_OCARINA_TIME, "You got %rOI%w!", "Du hast %rOI%w&erhalten!", "Vous obtenez %rOI%w!"), - GIMESSAGE(RG_ABILITY_QPA, ITEM_BLUE_FIRE, "You got %rQPA%w!", - "Du hast %rQPA%w&erhalten!", + GIMESSAGE(RG_ABILITY_QPA, ITEM_BLUE_FIRE, "You got %rQPA%w!", "Du hast %rQPA%w&erhalten!", "Vous obtenez %rQPA%w!"), - GIMESSAGE(RG_ABILITY_HESS, ITEM_BOOTS_HOVER, "You got %rHESS%w!", - "Du hast %rHESS%w&erhalten!", + GIMESSAGE(RG_ABILITY_HESS, ITEM_BOOTS_HOVER, "You got %rHESS%w!", "Du hast %rHESS%w&erhalten!", "Vous obtenez %rHESS%w!"), GIMESSAGE(RG_ABILITY_SUPERSLIDE, ITEM_BOOTS_HOVER, "You got %rSuperslide%w!", - "Du hast %rSuperslide%w&erhalten!", - "Vous obtenez %rSuperslide%w!"), - GIMESSAGE(RG_ABILITY_HOVER, ITEM_BOOTS_HOVER, "You got %rHover%w!", - "Du hast %rHover%w&erhalten!", + "Du hast %rSuperslide%w&erhalten!", "Vous obtenez %rSuperslide%w!"), + GIMESSAGE(RG_ABILITY_HOVER, ITEM_BOOTS_HOVER, "You got %rHover%w!", "Du hast %rHover%w&erhalten!", "Vous obtenez %rHover%w!"), - GIMESSAGE(RG_ABILITY_EQUIP_SWAP, ITEM_DINS_FIRE, "You got %rEquip Swap%w!", - "Du hast %rEquip Swap%w&erhalten!", + GIMESSAGE(RG_ABILITY_EQUIP_SWAP, ITEM_DINS_FIRE, "You got %rEquip Swap%w!", "Du hast %rEquip Swap%w&erhalten!", "Vous obtenez %rEquip Swap%w!"), GIMESSAGE(RG_ABILITY_GROUND_JUMP, ITEM_SHIELD_HYLIAN, "You got %rGround Jump%w!", - "Du hast %rGround Jump%w&erhalten!", - "Vous obtenez %rGround Jump%w!"), - GIMESSAGE(RG_ABILITY_WEIRDSHOT, ITEM_HOOKSHOT, "You got %rWeirdshot%w!", - "Du hast %rWeirdshot%w&erhalten!", + "Du hast %rGround Jump%w&erhalten!", "Vous obtenez %rGround Jump%w!"), + GIMESSAGE(RG_ABILITY_WEIRDSHOT, ITEM_HOOKSHOT, "You got %rWeirdshot%w!", "Du hast %rWeirdshot%w&erhalten!", "Vous obtenez %rWeirdshot%w!"), - + 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!"), 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 cfb72d69bfe..8bf20178658 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -5789,7 +5789,8 @@ void func_8083AA10(Player* this, PlayState* play) { if (!(this->stateFlags3 & PLAYER_STATE3_MIDAIR) && !(this->skelAnime.movementFlags & 0x80) && (Player_Action_8084411C != this->actionFunc) && (Player_Action_80844A44 != this->actionFunc)) { - if ((sPrevFloorProperty == 7) || (GameInteractor_Should(VB_HOVER_WITH_ISG, true) && (this->meleeWeaponState != 0))) { + if ((sPrevFloorProperty == 7) || + (GameInteractor_Should(VB_HOVER_WITH_ISG, true) && (this->meleeWeaponState != 0))) { Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); Player_ZeroSpeedXZ(this); return; From e0759e894748b243ec581d92ca7dde2e4bc45a5c Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Sat, 30 Aug 2025 15:50:49 +0100 Subject: [PATCH 10/11] format2 --- soh/src/code/z_skelanime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c index fcb20a342ea..74ba737de44 100644 --- a/soh/src/code/z_skelanime.c +++ b/soh/src/code/z_skelanime.c @@ -890,7 +890,7 @@ void AnimationContext_SetLoadFrame(PlayState* play, LinkAnimationHeader* animati AnimationEntry* entry = AnimationContext_AddEntry(&play->animationCtx, ANIMENTRY_LOADFRAME); GameInteractor_ExecuteOnAnimationSetLoadFrame(animation, &frame); - + if (GameInteractor_Should(VB_LOAD_PLAYER_ANIMATION_FRAME, entry != NULL, entry, animation, frame, limbCount, frameTable)) { if (ResourceMgr_OTRSigCheck(animation) != 0) From 91990475adb0701bac48a4b16b951a10e2cb770c Mon Sep 17 00:00:00 2001 From: inspectredc <78732756+inspectredc@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:56:10 +0100 Subject: [PATCH 11/11] Update some namings --- .../3drando/hint_list/hint_list_item.cpp | 24 +++++++++---------- soh/soh/Enhancements/randomizer/item_list.cpp | 4 ++-- .../randomizer/option_descriptions.cpp | 16 +++++++------ 3 files changed, 23 insertions(+), 21 deletions(-) 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 ce4ebfc4f57..9c237c73fa7 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 @@ -2157,14 +2157,14 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("some fast hands", /*german*/"QPA", /*french*/"QPA")}); // /*spanish*/QPA - hintTextTable[RHT_ABILITY_HESS] = HintText(CustomMessage("HESS", /*german*/"HESS", /*french*/"HESS"), - // /*spanish*/HESS + hintTextTable[RHT_ABILITY_HESS] = HintText(CustomMessage("Extended Superslide", /*german*/"Extended Superslide", /*french*/"Extended Superslide"), + // /*spanish*/Extended Superslide { - CustomMessage("some explosive speed", /*german*/"HESS", /*french*/"HESS") - // /*spanish*/HESS + CustomMessage("some explosive speed", /*german*/"Extended Superslide", /*french*/"Extended Superslide") + // /*spanish*/Extended Superslide }, { - CustomMessage("some slick feet", /*german*/"HESS", /*french*/"HESS")}); - // /*spanish*/HESS + CustomMessage("some slick feet", /*german*/"Extended Superslide", /*french*/"Extended Superslide")}); + // /*spanish*/Extended Superslide hintTextTable[RHT_ABILITY_SUPERSLIDE] = HintText(CustomMessage("Superslide", /*german*/"Superslide", /*french*/"Superslide"), // /*spanish*/Superslide { @@ -2173,14 +2173,14 @@ void StaticData::HintTable_Init_Item() { }, { CustomMessage("some shield power", /*german*/"Superslide", /*french*/"Superslide")}); // /*spanish*/Superslide - hintTextTable[RHT_ABILITY_HOVER] = HintText(CustomMessage("Hover", /*german*/"Hover", /*french*/"Hover"), - // /*spanish*/Hover + hintTextTable[RHT_ABILITY_HOVER] = HintText(CustomMessage("Hovering", /*german*/"Hovering", /*french*/"Hovering"), + // /*spanish*/Hovering { - CustomMessage("a weightless trick", /*german*/"Hover", /*french*/"Hover") - // /*spanish*/Hover + CustomMessage("a weightless trick", /*german*/"Hovering", /*french*/"Hovering") + // /*spanish*/Hovering }, { - CustomMessage("gravityn't", /*german*/"Hover", /*french*/"Hover")}); - // /*spanish*/Hover + CustomMessage("gravityn't", /*german*/"Hovering", /*french*/"Hovering")}); + // /*spanish*/Hovering hintTextTable[RHT_ABILITY_EQUIP_SWAP] = HintText(CustomMessage("Equip Swap", /*german*/"Equip Swap", /*french*/"Equip Swap"), // /*spanish*/Equip Swap { diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 774499e02b6..3f429064d58 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -358,11 +358,11 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ABILITY_OI].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_QPA] = Item(RG_ABILITY_QPA, Text{ "QPA", "QPA", "QPA" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_QPA, RG_ABILITY_QPA, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_QPA].SetCustomDrawFunc(Randomizer_DrawMysteryItem); - itemTable[RG_ABILITY_HESS] = Item(RG_ABILITY_HESS, Text{ "HESS", "HESS", "HESS" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HESS, RG_ABILITY_HESS, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_HESS] = Item(RG_ABILITY_HESS, Text{ "Extended Superslide", "Extended Superslide", "Extended Superslide" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HESS, RG_ABILITY_HESS, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_HESS].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_SUPERSLIDE] = Item(RG_ABILITY_SUPERSLIDE, Text{ "Superslide", "Superslide", "Superslide" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_SUPERSLIDE, RG_ABILITY_SUPERSLIDE, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_SUPERSLIDE].SetCustomDrawFunc(Randomizer_DrawMysteryItem); - itemTable[RG_ABILITY_HOVER] = Item(RG_ABILITY_HOVER, Text{ "Hover", "Hover", "Hover" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HOVER, RG_ABILITY_HOVER, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ABILITY_HOVER] = Item(RG_ABILITY_HOVER, Text{ "Hovering", "Hovering", "Hovering" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_HOVER, RG_ABILITY_HOVER, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_HOVER].SetCustomDrawFunc(Randomizer_DrawMysteryItem); itemTable[RG_ABILITY_EQUIP_SWAP] = Item(RG_ABILITY_EQUIP_SWAP, Text{ "Equip Swap", "Equip Swap", "Equip Swap" }, ITEMTYPE_ITEM, GI_NONE, true, LOGIC_NONE, RHT_ABILITY_EQUIP_SWAP, RG_ABILITY_EQUIP_SWAP, OBJECT_GI_COIN, GID_NCOIN_YELLOW, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ABILITY_EQUIP_SWAP].SetCustomDrawFunc(Randomizer_DrawMysteryItem); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 29fb543e414..5fe157a9a60 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -761,15 +761,17 @@ void Settings::CreateOptionDescriptions() { "respective soul." "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; - mOptionDescriptions[RSK_SHUFFLE_ISG] = "Shuffles the ability to use the glitch ISG into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_ISG] = + "Shuffles the ability to use the Infinite Sword Glitch (ISG) into the item pool."; mOptionDescriptions[RSK_SHUFFLE_OI] = "Shuffles the ability to use the glitch Ocarina Items into the item pool."; mOptionDescriptions[RSK_SHUFFLE_QPA] = "Shuffles the ability to use Quick Putaway Glitched Damage into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_HESS] = "Shuffles the ability to HESS into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE] = "Shuffles the ability to superslide into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_HOVER] = "Shuffles the ability to hover into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP] = "Shuffles the ability to equip swap into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP] = "Shuffles the ability to ground jump into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_WEIRDSHOT] = "Shuffles the ability to weirdshot into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_HESS] = + "Shuffles the ability to perform an Extended Superslide into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_SUPERSLIDE] = "Shuffles the ability to Superslide into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_HOVER] = "Shuffles the ability to Hover into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_EQUIP_SWAP] = "Shuffles the ability to Equip Swap into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_GROUND_JUMP] = "Shuffles the ability to Ground Jump into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_WEIRDSHOT] = "Shuffles the ability to Weirdshot into the item pool."; } } // namespace Rando