From 9e686ae6f6156919d3e52dc43870dd61265c37ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Thu, 26 Jun 2025 05:00:53 +0000 Subject: [PATCH] Shuffles: use ObjectExtension system for rando object identity (#5603) --- soh/soh/Enhancements/CuccosToReturn.cpp | 1 - .../randomizer/ShuffleBeehives.cpp | 22 +++--- .../Enhancements/randomizer/ShuffleCrates.cpp | 71 ++++++++++++++----- .../Enhancements/randomizer/ShuffleCrates.h | 16 ----- .../randomizer/ShuffleFairies.cpp | 42 +++++++---- .../Enhancements/randomizer/ShuffleGrass.cpp | 43 ++++++----- .../Enhancements/randomizer/ShuffleGrass.h | 15 ---- .../Enhancements/randomizer/ShufflePots.cpp | 29 +++++--- soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h | 3 - .../overlays/actors/ovl_En_Kusa/z_en_kusa.h | 1 - .../overlays/actors/ovl_Obj_Comb/z_obj_comb.h | 1 - .../actors/ovl_Obj_Kibako/z_obj_kibako.h | 1 - .../actors/ovl_Obj_Kibako2/z_obj_kibako2.h | 1 - .../actors/ovl_Obj_Tsubo/z_obj_tsubo.h | 1 - 14 files changed, 142 insertions(+), 105 deletions(-) delete mode 100644 soh/soh/Enhancements/randomizer/ShuffleCrates.h delete mode 100644 soh/soh/Enhancements/randomizer/ShuffleGrass.h diff --git a/soh/soh/Enhancements/CuccosToReturn.cpp b/soh/soh/Enhancements/CuccosToReturn.cpp index 317437216..2de929fd3 100644 --- a/soh/soh/Enhancements/CuccosToReturn.cpp +++ b/soh/soh/Enhancements/CuccosToReturn.cpp @@ -1,6 +1,5 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ShipInit.hpp" -#include "soh/Enhancements/randomizer/context.h" extern "C" { extern PlayState* gPlayState; diff --git a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp index 03f6dfa65..c94c68511 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp @@ -1,5 +1,6 @@ #include #include "static_data.h" +#include "soh/ObjectExtension/ObjectExtension.h" extern "C" { #include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" @@ -10,12 +11,14 @@ extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) { s16 params = objComb->actor.params & 0x1F; + const auto beehiveIdentity = ObjectExtension::GetInstance().Get(&objComb->actor); - if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) { + if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity != nullptr && + !Flags_GetRandomizerInf(beehiveIdentity->randomizerInf)) { EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY); - item00->randoInf = objComb->beehiveIdentity.randomizerInf; + item00->randoInf = beehiveIdentity->randomizerInf; item00->itemEntry = - OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(objComb->beehiveIdentity.randomizerCheck, GI_NONE); + OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(beehiveIdentity->randomizerCheck, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; return; } @@ -37,10 +40,11 @@ void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) { } void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { - s32 dmgFlags; - objComb->unk_1B0 -= 50; - if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) { + + const auto beehiveIdentity = ObjectExtension::GetInstance().Get(&objComb->actor); + if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity == nullptr && + !Flags_GetRandomizerInf(beehiveIdentity->randomizerInf)) { if (objComb->unk_1B0 <= -5000) { objComb->unk_1B0 = 1500; } @@ -50,7 +54,7 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { if ((objComb->collider.base.acFlags & AC_HIT) != 0) { objComb->collider.base.acFlags &= ~AC_HIT; - dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags; + s32 dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags; if (dmgFlags & 0x4001F866) { objComb->unk_1B0 = 1500; } else { @@ -70,8 +74,9 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { void ObjComb_RandomizerInit(void* actor) { ObjComb* objComb = static_cast(actor); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive( + auto beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive( gPlayState->sceneNum, (s16)objComb->actor.world.pos.x, respawnData); + ObjectExtension::GetInstance().Set(actor, std::move(beehiveIdentity)); objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait; } @@ -132,4 +137,5 @@ void Rando::StaticData::RegisterBeehiveLocations() { // clang-format-on } +static ObjectExtension::Register RegisterBeehiveIdentity; static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterBeehiveLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp index c6563688b..53a65df22 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp @@ -1,9 +1,10 @@ -#include "ShuffleCrates.h" +#include #include "soh_assets.h" #include "static_data.h" #include #include "global.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/ObjectExtension/ObjectExtension.h" extern "C" { #include "variables.h" @@ -31,8 +32,14 @@ extern "C" void ObjKibako2_RandomizerDraw(Actor* thisx, PlayState* play) { return; } + const auto crateIdentity = ObjectExtension::GetInstance().Get(thisx); + if (crateIdentity == nullptr) { + Gfx_DrawDListOpa(play, (Gfx*)gLargeRandoCrateDL); + return; + } + GetItemEntry crateItem = - Rando::Context::GetInstance()->GetFinalGIEntry(crateActor->crateIdentity.randomizerCheck, true, GI_NONE); + Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE); getItemCategory = crateItem.getItemCategory; // If they have bombchus, don't consider the bombchu item major @@ -99,8 +106,14 @@ extern "C" void ObjKibako_RandomizerDraw(Actor* thisx, PlayState* play) { return; } - GetItemEntry smallCrateItem = Rando::Context::GetInstance()->GetFinalGIEntry( - smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE); + const auto crateIdentity = ObjectExtension::GetInstance().Get(thisx); + if (crateIdentity == nullptr) { + Gfx_DrawDListOpa(play, (Gfx*)gSmallRandoCrateDL); + return; + } + + GetItemEntry smallCrateItem = + Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE); getItemCategory = smallCrateItem.getItemCategory; // If they have bombchus, don't consider the bombchu item major @@ -154,15 +167,19 @@ extern "C" void ObjKibako_RandomizerDraw(Actor* thisx, PlayState* play) { } uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play) { - RandomizerCheck rc = crateActor->crateIdentity.randomizerCheck; + const auto crateIdentity = ObjectExtension::GetInstance().Get(&crateActor->dyna.actor); + if (crateIdentity == nullptr) { + return false; + } + + RandomizerCheck rc = crateIdentity->randomizerCheck; uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); uint8_t crateSetting = RAND_GET_OPTION(RSK_SHUFFLE_CRATES); // Don't pull randomized item if crate isn't randomized or is already checked if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) || (crateSetting == RO_SHUFFLE_CRATES_DUNGEONS && !isDungeon) || - Flags_GetRandomizerInf(crateActor->crateIdentity.randomizerInf) || - crateActor->crateIdentity.randomizerCheck == RC_UNKNOWN_CHECK) { + Flags_GetRandomizerInf(crateIdentity->randomizerInf) || crateIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { return false; } else { return true; @@ -170,15 +187,19 @@ uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play) } uint8_t ObjKibako_RandomizerHoldsItem(ObjKibako* smallCrateActor, PlayState* play) { - RandomizerCheck rc = smallCrateActor->smallCrateIdentity.randomizerCheck; + const auto crateIdentity = ObjectExtension::GetInstance().Get(&smallCrateActor->actor); + if (crateIdentity == nullptr) { + return false; + } + + RandomizerCheck rc = crateIdentity->randomizerCheck; uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); uint8_t crateSetting = RAND_GET_OPTION(RSK_SHUFFLE_CRATES); // Don't pull randomized item if crate isn't randomized or is already checked if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) || (crateSetting == RO_SHUFFLE_CRATES_DUNGEONS && !isDungeon) || - Flags_GetRandomizerInf(smallCrateActor->smallCrateIdentity.randomizerInf) || - smallCrateActor->smallCrateIdentity.randomizerCheck == RC_UNKNOWN_CHECK) { + Flags_GetRandomizerInf(crateIdentity->randomizerInf) || crateIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { return false; } else { return true; @@ -186,10 +207,14 @@ uint8_t ObjKibako_RandomizerHoldsItem(ObjKibako* smallCrateActor, PlayState* pla } void ObjKibako2_RandomizerSpawnCollectible(ObjKibako2* crateActor, PlayState* play) { + const auto crateIdentity = ObjectExtension::GetInstance().Get(&crateActor->dyna.actor); + if (crateIdentity == nullptr) { + return; + } + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &crateActor->dyna.actor.world.pos, ITEM00_SOH_DUMMY); - item00->randoInf = crateActor->crateIdentity.randomizerInf; - item00->itemEntry = - Rando::Context::GetInstance()->GetFinalGIEntry(crateActor->crateIdentity.randomizerCheck, true, GI_NONE); + item00->randoInf = crateIdentity->randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; item00->actor.velocity.y = 8.0f; item00->actor.speedXZ = 2.0f; @@ -197,10 +222,14 @@ void ObjKibako2_RandomizerSpawnCollectible(ObjKibako2* crateActor, PlayState* pl } void ObjKibako_RandomizerSpawnCollectible(ObjKibako* smallCrateActor, PlayState* play) { + const auto crateIdentity = ObjectExtension::GetInstance().Get(&smallCrateActor->actor); + if (crateIdentity == nullptr) { + return; + } + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &smallCrateActor->actor.world.pos, ITEM00_SOH_DUMMY); - item00->randoInf = smallCrateActor->smallCrateIdentity.randomizerInf; - item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry( - smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE); + item00->randoInf = crateIdentity->randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; item00->actor.velocity.y = 8.0f; item00->actor.speedXZ = 2.0f; @@ -231,8 +260,9 @@ void ObjKibako2_RandomizerInit(void* actorRef) { ObjKibako2* crateActor = static_cast(actorRef); - crateActor->crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCrate( - gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + auto crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCrate(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + ObjectExtension::GetInstance().Set(actor, std::move(crateIdentity)); } void ObjKibako_RandomizerInit(void* actorRef) { @@ -243,8 +273,9 @@ void ObjKibako_RandomizerInit(void* actorRef) { ObjKibako* smallCrateActor = static_cast(actorRef); - smallCrateActor->smallCrateIdentity = OTRGlobals::Instance->gRandomizer->IdentifySmallCrate( + auto crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifySmallCrate( gPlayState->sceneNum, (s16)actor->home.pos.x, (s16)actor->home.pos.z); + ObjectExtension::GetInstance().Set(actor, std::move(crateIdentity)); } void RegisterShuffleCrates() { @@ -564,5 +595,7 @@ void Rando::StaticData::RegisterCrateLocations() { // clang-format on } +static ObjectExtension::Register RegisterCrateIdentity; +static ObjectExtension::Register RegisterSmallCrateIdentity; static RegisterShipInitFunc initFunc(RegisterShuffleCrates, { "IS_RANDO" }); static RegisterShipInitFunc locFunc(Rando::StaticData::RegisterCrateLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.h b/soh/soh/Enhancements/randomizer/ShuffleCrates.h deleted file mode 100644 index eb0325f89..000000000 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef ShuffleCrates_H -#define ShuffleCrates_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -void ObjKibako2_RandomizerInit(void* actorRef); -void ObjKibako_RandomizerInit(void* actorRef); -#ifdef __cplusplus -}; -#endif - -#endif // ShuffleCrates_H diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp index aad3f6327..666ba0a21 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -1,19 +1,28 @@ +#include "soh/OTRGlobals.h" #include "randomizer_grotto.h" #include "draw.h" +#include "soh/cvar_prefixes.h" +#include "static_data.h" +#include "soh/Enhancements/item-tables/ItemTableTypes.h" +#include "soh/ObjectExtension/ObjectExtension.h" + +extern "C" { #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 "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) { + const auto fairyIdentity = ObjectExtension::GetInstance().Get(&enElf->actor); + if (fairyIdentity == nullptr) { + return; + } + GetItemEntry randoGetItem = - Rando::Context::GetInstance()->GetFinalGIEntry(enElf->sohFairyIdentity.randomizerCheck, true, GI_FAIRY); + Rando::Context::GetInstance()->GetFinalGIEntry(fairyIdentity->randomizerCheck, true, GI_FAIRY); if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { randoGetItem = GET_ITEM_MYSTERY; } @@ -33,8 +42,8 @@ bool ShuffleFairies_FairyExists(FairyIdentity fairyIdentity) { if (actor->id != ACTOR_EN_ELF) { actor = actor->next; } else { - EnElf* enElf = (EnElf*)(actor); - if (fairyIdentity.randomizerInf == enElf->sohFairyIdentity.randomizerInf) { + const auto actorFairyIdentity = ObjectExtension::GetInstance().Get(&actor); + if (actorFairyIdentity != nullptr && fairyIdentity.randomizerInf == actorFairyIdentity->randomizerInf) { return true; } actor = actor->next; @@ -70,10 +79,10 @@ FairyIdentity ShuffleFairies_GetFairyIdentity(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, fairyType, true); - fairy->sohFairyIdentity = fairyIdentity; - fairy->actor.draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem; + Actor* fairy = Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0, 0, 0, + fairyType, true); + ObjectExtension::GetInstance().Set(fairy, std::move(fairyIdentity)); + fairy->draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem; return true; } return false; @@ -85,8 +94,14 @@ void RegisterShuffleFairies() { // Grant item when picking up fairy. 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); + + const auto fairyIdentity = ObjectExtension::GetInstance().Get(&enElf->actor); + if (fairyIdentity == nullptr) { + return; + } + + if (fairyIdentity != nullptr && fairyIdentity->randomizerInf && fairyIdentity->randomizerInf != RAND_INF_MAX) { + Flags_SetRandomizerInf(fairyIdentity->randomizerInf); } }); @@ -404,5 +419,6 @@ void Rando::StaticData::RegisterFairyLocations() { // clang-format on } +static ObjectExtension::Register RegisterFairyIdentity; static RegisterShipInitFunc registerShuffleFairies(RegisterShuffleFairies, { "IS_RANDO" }); static RegisterShipInitFunc registerShuffleFairiesLocations(Rando::StaticData::RegisterFairyLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp index 28f06e9d4..27d42a148 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp @@ -1,6 +1,7 @@ -#include "ShuffleGrass.h" +#include #include "soh_assets.h" #include "static_data.h" +#include "soh/ObjectExtension/ObjectExtension.h" #include "soh/Enhancements/enhancementTypes.h" extern "C" { @@ -27,18 +28,20 @@ extern "C" void EnKusa_RandomizerDraw(Actor* thisx, PlayState* play) { static Gfx* dLists[] = { (Gfx*)gRandoBushJunkDL, (Gfx*)gRandoCuttableGrassJunkDL, (Gfx*)gRandoCuttableGrassJunkDL }; auto grassActor = ((EnKusa*)thisx); + const auto grassIdentity = ObjectExtension::GetInstance().Get(thisx); + OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); - if (grassActor->grassIdentity.randomizerCheck != RC_MAX && - Flags_GetRandomizerInf(grassActor->grassIdentity.randomizerInf) == 0) { + if (grassIdentity != nullptr && grassIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(grassIdentity->randomizerInf) == 0) { int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); if ((csmc == CSMC_BOTH || csmc == CSMC_TEXTURE) && (!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { - auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(grassActor->grassIdentity.randomizerCheck, - true, GI_NONE); + auto itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(grassIdentity->randomizerCheck, true, GI_NONE); GetItemCategory getItemCategory = itemEntry.getItemCategory; switch (getItemCategory) { @@ -88,19 +91,19 @@ extern "C" void EnKusa_RandomizerDraw(Actor* thisx, PlayState* play) { } uint8_t EnKusa_RandomizerHoldsItem(EnKusa* grassActor, PlayState* play) { - if (grassActor->grassIdentity.randomizerCheck == RC_MAX) + const auto grassIdentity = ObjectExtension::GetInstance().Get(&grassActor->actor); + + if (grassIdentity == nullptr || grassIdentity->randomizerCheck == RC_MAX) return false; - RandomizerCheck rc = grassActor->grassIdentity.randomizerCheck; - + RandomizerCheck rc = grassIdentity->randomizerCheck; uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); uint8_t grassSetting = RAND_GET_OPTION(RSK_SHUFFLE_GRASS); // Don't pull randomized item if grass isn't randomized or is already checked if (!IS_RANDO || (grassSetting == RO_SHUFFLE_GRASS_OVERWORLD && isDungeon) || (grassSetting == RO_SHUFFLE_GRASS_DUNGEONS && !isDungeon) || - Flags_GetRandomizerInf(grassActor->grassIdentity.randomizerInf) || - grassActor->grassIdentity.randomizerCheck == RC_UNKNOWN_CHECK) { + Flags_GetRandomizerInf(grassIdentity->randomizerInf) || rc == RC_UNKNOWN_CHECK) { return false; } else { return true; @@ -108,10 +111,14 @@ uint8_t EnKusa_RandomizerHoldsItem(EnKusa* grassActor, PlayState* play) { } void EnKusa_RandomizerSpawnCollectible(EnKusa* grassActor, PlayState* play) { + const auto grassIdentity = ObjectExtension::GetInstance().Get(&grassActor->actor); + if (grassIdentity == nullptr) { + return; + } + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &grassActor->actor.world.pos, ITEM00_SOH_DUMMY); - item00->randoInf = grassActor->grassIdentity.randomizerInf; - item00->itemEntry = - Rando::Context::GetInstance()->GetFinalGIEntry(grassActor->grassIdentity.randomizerCheck, true, GI_NONE); + item00->randoInf = grassIdentity->randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(grassIdentity->randomizerCheck, true, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; item00->actor.velocity.y = 8.0f; item00->actor.speedXZ = 2.0f; @@ -127,8 +134,9 @@ void EnKusa_RandomizerInit(void* actorRef) { EnKusa* grassActor = static_cast(actorRef); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - grassActor->grassIdentity = OTRGlobals::Instance->gRandomizer->IdentifyGrass( + auto grassIdentity = OTRGlobals::Instance->gRandomizer->IdentifyGrass( gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, respawnData, gPlayState->linkAgeOnLoad); + ObjectExtension::GetInstance().Set(actor, std::move(grassIdentity)); } void RegisterShuffleGrass() { @@ -150,8 +158,10 @@ void RegisterShuffleGrass() { EnKusa* grassActor = va_arg(args, EnKusa*); if (EnKusa_RandomizerHoldsItem(grassActor, gPlayState)) { EnKusa_RandomizerSpawnCollectible(grassActor, gPlayState); - grassActor->grassIdentity.randomizerCheck = RC_MAX; - grassActor->grassIdentity.randomizerInf = RAND_INF_MAX; + ObjectExtension::GetInstance().Set(&grassActor->actor, std::move(GrassIdentity{ + .randomizerInf = RAND_INF_MAX, + .randomizerCheck = RC_MAX, + })); *should = false; } else { *should = true; @@ -519,5 +529,6 @@ void Rando::StaticData::RegisterGrassLocations() { // clang-format on } +static ObjectExtension::Register RegisterGrassIdentity; static RegisterShipInitFunc registerShuffleGrass(RegisterShuffleGrass, { "IS_RANDO" }); static RegisterShipInitFunc registerShuffleGrassLocations(Rando::StaticData::RegisterGrassLocations); diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.h b/soh/soh/Enhancements/randomizer/ShuffleGrass.h deleted file mode 100644 index bc9a130d4..000000000 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SHUFFLEGRASS_H -#define SHUFFLEGRASS_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -void EnKusa_RandomizerInit(void* actorRef); -#ifdef __cplusplus -}; -#endif - -#endif // SHUFFLEGRASS_H diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.cpp b/soh/soh/Enhancements/randomizer/ShufflePots.cpp index 9dfeb06ae..ad23f9d26 100644 --- a/soh/soh/Enhancements/randomizer/ShufflePots.cpp +++ b/soh/soh/Enhancements/randomizer/ShufflePots.cpp @@ -1,6 +1,7 @@ #include "soh/OTRGlobals.h" #include "soh_assets.h" #include "static_data.h" +#include "soh/ObjectExtension/ObjectExtension.h" extern "C" { #include "variables.h" @@ -25,15 +26,19 @@ extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) { } uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) { - RandomizerCheck rc = potActor->potIdentity.randomizerCheck; + const auto potIdentity = ObjectExtension::GetInstance().Get(&potActor->actor); + if (potIdentity == nullptr) { + return false; + } + + RandomizerCheck rc = potIdentity->randomizerCheck; uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); uint8_t potSetting = RAND_GET_OPTION(RSK_SHUFFLE_POTS); // Don't pull randomized item if pot isn't randomized or is already checked if (!IS_RANDO || (potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) || - (potSetting == RO_SHUFFLE_POTS_DUNGEONS && !isDungeon) || - Flags_GetRandomizerInf(potActor->potIdentity.randomizerInf) || - potActor->potIdentity.randomizerCheck == RC_UNKNOWN_CHECK) { + (potSetting == RO_SHUFFLE_POTS_DUNGEONS && !isDungeon) || Flags_GetRandomizerInf(potIdentity->randomizerInf) || + potIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { return false; } else { return true; @@ -41,10 +46,14 @@ uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) { } void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor, PlayState* play) { + const auto potIdentity = ObjectExtension::GetInstance().Get(&potActor->actor); + if (potIdentity == nullptr) { + return; + } + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &potActor->actor.world.pos, ITEM00_SOH_DUMMY); - item00->randoInf = potActor->potIdentity.randomizerInf; - item00->itemEntry = - Rando::Context::GetInstance()->GetFinalGIEntry(potActor->potIdentity.randomizerCheck, true, GI_NONE); + item00->randoInf = potIdentity->randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(potIdentity->randomizerCheck, true, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; item00->actor.velocity.y = 8.0f; item00->actor.speedXZ = 2.0f; @@ -58,8 +67,9 @@ void RegisterShufflePots() { Actor* actor = static_cast(actorRef); ObjTsubo* potActor = static_cast(actorRef); - potActor->potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot( - gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + auto potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + ObjectExtension::GetInstance().Set(actor, std::move(potIdentity)); }); // Draw custom model for pot to indicate it holding a randomized item. @@ -649,5 +659,6 @@ void Rando::StaticData::RegisterPotLocations() { // clang-format on } +static ObjectExtension::Register RegisterPotIdentity; static RegisterShipInitFunc registerShufflePots(RegisterShufflePots, { "IS_RANDO" }); static RegisterShipInitFunc registerShufflePotLocations(Rando::StaticData::RegisterPotLocations); 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 8a5368768..7f8e4c84e 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 @@ -42,9 +42,6 @@ typedef struct EnElf { /* 0x02C7 */ u8 unk_2C7; /* 0x02C8 */ EnElfUnkFunc func_2C8; /* 0x02CC */ EnElfActionFunc actionFunc; - // #region SOH [Randomizer] - /* */ FairyIdentity sohFairyIdentity; - // #endregion } EnElf; // size = 0x02D0 typedef enum { diff --git a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h index 6db50aa28..f1e9f24d7 100644 --- a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h +++ b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h @@ -20,7 +20,6 @@ typedef struct EnKusa { /* 0x0150 */ ColliderCylinder collider; /* 0x019C */ s16 timer; /* 0x019E */ s8 objBankIndex; - /* */ GrassIdentity grassIdentity; } EnKusa; // size = 0x01A0 #endif diff --git a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h index ded72dfc4..ea4910300 100644 --- a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h +++ b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h @@ -15,7 +15,6 @@ typedef struct ObjComb { /* 0x0170 */ ColliderJntSphElement colliderItems[1]; /* 0x01B0 */ s16 unk_1B0; /* 0x01B2 */ s16 unk_1B2; - /* */ BeehiveIdentity beehiveIdentity; } ObjComb; // size = 0x01B4 void ObjComb_Break(ObjComb* objComb, PlayState* play); diff --git a/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.h b/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.h index 32a35563f..68e871c78 100644 --- a/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.h +++ b/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.h @@ -12,7 +12,6 @@ typedef struct ObjKibako { /* 0x0000 */ Actor actor; /* 0x014C */ ObjKibakoActionFunc actionFunc; /* 0x0150 */ ColliderCylinder collider; - /* */ SmallCrateIdentity smallCrateIdentity; } ObjKibako; // size = 0x019C #endif diff --git a/soh/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h b/soh/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h index 7629e6aa1..48c22154f 100644 --- a/soh/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h +++ b/soh/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h @@ -13,7 +13,6 @@ typedef struct ObjKibako2 { /* 0x0164 */ ColliderCylinder collider; /* 0x01B0 */ ObjKibako2ActionFunc actionFunc; /* 0x01B4 */ s16 collectibleFlag; - /* */ CrateIdentity crateIdentity; } ObjKibako2; // size = 0x01B8 #endif diff --git a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h index 74dbf6ebb..a83d43a47 100644 --- a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h +++ b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h @@ -13,7 +13,6 @@ typedef struct ObjTsubo { /* 0x014C */ ObjTsuboActionFunc actionFunc; /* 0x0150 */ ColliderCylinder collider; /* 0x019C */ s8 objTsuboBankIndex; - /* */ PotIdentity potIdentity; } ObjTsubo; // size = 0x01A0 #endif