diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp index ea34d1414..ffd9a60b4 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -1,18 +1,19 @@ -#include "ShuffleFairies.h" #include "randomizer_grotto.h" #include "draw.h" #include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" #include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h" #include "src/overlays/actors/ovl_En_Gs/z_en_gs.h" #include "src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h" -#include "../../OTRGlobals.h" -#include "../../cvar_prefixes.h" +#include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" +#include "soh/Enhancements/item-tables/ItemTableTypes.h" #include "static_data.h" #define FAIRY_FLAG_TIMED (1 << 8) void ShuffleFairies_DrawRandomizedItem(EnElf* enElf, PlayState* play) { - GetItemEntry randoGetItem = enElf->sohFairyIdentity.itemEntry; + GetItemEntry randoGetItem = + Rando::Context::GetInstance()->GetFinalGIEntry(enElf->sohFairyIdentity.randomizerCheck, true, GI_FAIRY); if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { randoGetItem = GET_ITEM_MYSTERY; } @@ -60,18 +61,17 @@ FairyIdentity ShuffleFairies_GetFairyIdentity(int32_t params) { assert(false); } else { fairyIdentity.randomizerInf = static_cast(location->GetCollectionCheck().flag); - fairyIdentity.itemEntry = - Rando::Context::GetInstance()->GetFinalGIEntry(location->GetRandomizerCheck(), true, GI_FAIRY); + fairyIdentity.randomizerCheck = location->GetRandomizerCheck(); } return fairyIdentity; } -bool ShuffleFairies_SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params) { +static bool SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params, FairyType fairyType) { FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params); if (!Flags_GetRandomizerInf(fairyIdentity.randomizerInf)) { EnElf* fairy = (EnElf*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0, - 0, 0, FAIRY_HEAL, true); + 0, 0, fairyType, true); fairy->sohFairyIdentity = fairyIdentity; fairy->actor.draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem; return true; @@ -79,58 +79,62 @@ bool ShuffleFairies_SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params) { return false; } -void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { - va_list args; - va_copy(args, originalArgs); - - Actor* actor = va_arg(args, Actor*); - - va_end(args); +void RegisterShuffleFairies() { + bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES); // Grant item when picking up fairy. - if (id == VB_FAIRY_HEAL) { - EnElf* enElf = (EnElf*)(actor); + COND_VB_SHOULD(VB_FAIRY_HEAL, shouldRegister, { + EnElf* enElf = va_arg(args, EnElf*); if (enElf->sohFairyIdentity.randomizerInf && enElf->sohFairyIdentity.randomizerInf != RAND_INF_MAX) { Flags_SetRandomizerInf(enElf->sohFairyIdentity.randomizerInf); } - // Spawn fairies in fairy fountains - } else if (id == VB_SPAWN_FOUNTAIN_FAIRIES) { + }); + + // Spawn fairies in fairy fountains + COND_VB_SHOULD(VB_SPAWN_FOUNTAIN_FAIRIES, shouldRegister, { + Actor* actor = va_arg(args, Actor*); bool fairySpawned = false; s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0; for (s16 index = 0; index < 8; index++) { int32_t params = (grottoId << 8) | index; - if (ShuffleFairies_SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, params)) { + if (SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, params, FAIRY_HEAL)) { fairySpawned = true; } } if (fairySpawned) { *should = false; } - // Spawn 3 fairies when playing Song of Storms next to a planted bean - } else if (id == VB_SPAWN_BEAN_STALK_FAIRIES) { - ObjBean* objBean = (ObjBean*)(actor); + }); + + // Spawn 3 fairies when playing Song of Storms next to a planted bean + COND_VB_SHOULD(VB_SPAWN_BEAN_STALK_FAIRIES, shouldRegister, { + ObjBean* objBean = va_arg(args, ObjBean*); bool fairySpawned = false; for (s16 index = 0; index < 3; index++) { int32_t params = ((objBean->dyna.actor.params & 0x3F) << 8) | index; - if (ShuffleFairies_SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y, - objBean->dyna.actor.world.pos.z, params)) { + if (SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y, + objBean->dyna.actor.world.pos.z, params, FAIRY_HEAL)) { fairySpawned = true; } } if (fairySpawned) { *should = false; } - // Spawn a fairy from a ShotSun when playing the right song near it - } else if (id == VB_SPAWN_SONG_FAIRY) { - ShotSun* shotSun = (ShotSun*)(actor); - if (ShuffleFairies_SpawnFairy(shotSun->actor.world.pos.x, shotSun->actor.world.pos.y, - shotSun->actor.world.pos.z, - TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z))) { + }); + + // Spawn a fairy from a ShotSun when playing the right song near it + COND_VB_SHOULD(VB_SPAWN_SONG_FAIRY, shouldRegister, { + ShotSun* shotSun = va_arg(args, ShotSun*); + if (SpawnFairy(shotSun->actor.world.pos.x, shotSun->actor.world.pos.y, shotSun->actor.world.pos.z, + TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z), FAIRY_HEAL_BIG)) { *should = false; } - // Handle playing both misc songs and song of storms in front of a gossip stone. - } else if (id == VB_SPAWN_GOSSIP_STONE_FAIRY) { - EnGs* gossipStone = (EnGs*)(actor); + }); + + // Handle playing both misc songs and song of storms in front of a gossip stone. + COND_VB_SHOULD(VB_SPAWN_GOSSIP_STONE_FAIRY, shouldRegister, { + EnGs* gossipStone = va_arg(args, EnGs*); + FairyType fairyType = FAIRY_HEAL; // Mimic vanilla behaviour, only go into this path if song played is one of the ones normally spawning a fairy. // Otherwise fall back to vanilla behaviour. @@ -144,6 +148,7 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, // Distinguish storms fairies from the normal song fairies if (gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_STORMS) { params |= 0x1000; + fairyType = FAIRY_HEAL_BIG; } // Combine actor + song params with position to get the right randomizer check @@ -156,8 +161,8 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, // collected, the vanilla code will handle that part automatically. FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params); if (!ShuffleFairies_FairyExists(fairyIdentity)) { - if (ShuffleFairies_SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y, - gossipStone->actor.world.pos.z, params)) { + if (SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y, + gossipStone->actor.world.pos.z, params, fairyType)) { Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); // Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well. gossipStone->unk_19D = 0; @@ -167,20 +172,7 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, *should = false; } } - } -} - -uint32_t onVanillaBehaviorHook = 0; - -void ShuffleFairies_RegisterHooks() { - onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook( - ShuffleFairies_OnVanillaBehaviorHandler); -} - -void ShuffleFairies_UnregisterHooks() { - GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); - - onVanillaBehaviorHook = 0; + }); } void Rando::StaticData::RegisterFairyLocations() { @@ -412,4 +404,5 @@ void Rando::StaticData::RegisterFairyLocations() { // clang-format on } -static RegisterShipInitFunc initFunc(Rando::StaticData::RegisterFairyLocations); +static RegisterShipInitFunc registerShuffleFairies(RegisterShuffleFairies, { "IS_RANDO" }); +static RegisterShipInitFunc registerShuffleFairiesLocations(Rando::StaticData::RegisterFairyLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.h b/soh/soh/Enhancements/randomizer/ShuffleFairies.h deleted file mode 100644 index 2b29a6146..000000000 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include "soh/Enhancements/item-tables/ItemTableTypes.h" -#include "randomizerTypes.h" - -typedef struct FairyIdentity { - RandomizerInf randomizerInf; - GetItemEntry itemEntry; -} FairyIdentity; - -void ShuffleFairies_RegisterHooks(); -void ShuffleFairies_UnregisterHooks(); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 508979eaf..7f23f60cc 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -14,7 +14,6 @@ #include "soh/SohGui/ImGuiUtils.h" #include "soh/Notification/Notification.h" #include "soh/SaveManager.h" -#include "soh/Enhancements/randomizer/ShuffleFairies.h" extern "C" { #include "macros.h" @@ -2396,8 +2395,6 @@ void RandomizerRegisterHooks() { shuffleFreestandingOnVanillaBehaviorHook = 0; - ShuffleFairies_UnregisterHooks(); - if (!IS_RANDO) return; @@ -2468,9 +2465,5 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->RegisterGameHook( ShuffleFreestanding_OnVanillaBehaviorHandler); } - - if (RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES)) { - ShuffleFairies_RegisterHooks(); - } }); } diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 5075182b3..c3bda412a 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -6361,6 +6361,11 @@ typedef struct FishIdentity { RandomizerCheck randomizerCheck; } FishIdentity; +typedef struct FairyIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} FairyIdentity; + typedef struct GrassIdentity { RandomizerInf randomizerInf; RandomizerCheck randomizerCheck; diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h index da77ac778..8a5368768 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h @@ -4,7 +4,6 @@ #include #include "global.h" #include "overlays/actors/ovl_Elf_Msg/z_elf_msg.h" -#include "soh/Enhancements/randomizer/ShuffleFairies.h" struct EnElf;