diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index a4054f2cb..89d2467c6 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -305,6 +305,8 @@ typedef enum { GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, // Opt: *EnHy GI_VB_GIVE_ITEM_FROM_LOST_DOG, + // Opt: *EnBomBowlPit + GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, GI_VB_GIVE_ITEM_FAIRY_OCARINA, GI_VB_GIVE_ITEM_WEIRD_EGG, diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index f1715c8eb..07f2ecb54 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -30,6 +30,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Skj/z_en_skj.h" #include "src/overlays/actors/ovl_En_Hy/z_en_hy.h" #include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" +#include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h" #include "adult_trade_shuffle.h" extern SaveContext gSaveContext; extern PlayState* gPlayState; @@ -256,6 +257,30 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { } } +void EnExItem_DrawRandomizedItem(EnExItem* enExItem, PlayState* play) { + func_8002ED80(&enExItem->actor, play, 0); + EnItem00_CustomItemsParticles(&enExItem->actor, play, enExItem->sohItemEntry); + GetItemEntry_Draw(play, enExItem->sohItemEntry); +} + +void EnExItem_WaitForObjectRandomized(EnExItem* enExItem, PlayState* play) { + EnExItem_WaitForObject(enExItem, play); + if (Object_IsLoaded(&play->objectCtx, enExItem->objectIdx)) { + enExItem->actor.draw = (ActorFunc)EnExItem_DrawRandomizedItem; + Actor_SetScale(&enExItem->actor, enExItem->scale); + + // for now we're just using this to not have items float + // below the bowling counter, but it would be nice to use + // this to not draw gigantic skull tokens etc. + switch (enExItem->type) { + case EXITEM_BOMB_BAG_COUNTER: { + enExItem->actor.shape.yOffset = -10.0f; + break; + } + } + } +} + void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play) { f32 mtxScale = CVarGetFloat("gTimeSavers.SkipGetItemAnimationScale", 10.0f); Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); @@ -932,6 +957,13 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void *should = false; break; } + case GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING: { + EnBomBowlPit* enBomBowlPit = static_cast(optionalArg); + if (enBomBowlPit->prizeIndex == EXITEM_BOMB_BAG_BOWLING || enBomBowlPit->prizeIndex == EXITEM_HEART_PIECE_BOWLING) { + *should = false; + } + break; + } case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_FROG: @@ -1216,6 +1248,33 @@ void RandomizerOnActorInitHandler(void* actorRef) { objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(gPlayState->sceneNum, (s16)actor->world.pos.x, respawnData); objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait; } + + if (actor->id == ACTOR_EN_EX_ITEM) { + EnExItem* enExItem = static_cast(actorRef); + + RandomizerCheck rc = RC_UNKNOWN_CHECK; + switch (enExItem->type) { + case EXITEM_BOMB_BAG_COUNTER: + case EXITEM_BOMB_BAG_BOWLING: + rc = RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE; + break; + case EXITEM_HEART_PIECE_COUNTER: + case EXITEM_HEART_PIECE_BOWLING: + rc = RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE; + break; + case EXITEM_BOMBCHUS_COUNTER: + case EXITEM_BOMBCHUS_BOWLING: + rc = RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS; + break; + case EXITEM_BULLET_BAG: + rc = RC_LW_TARGET_IN_WOODS; + break; + } + if (rc != RC_UNKNOWN_CHECK) { + enExItem->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + enExItem->actionFunc = (EnExItemActionFunc)EnExItem_WaitForObjectRandomized; + } + } } void RandomizerRegisterHooks() { diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c index 232b096f9..7e5cc3ef1 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c @@ -2,6 +2,7 @@ #include "vt.h" #include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h" #include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -177,56 +178,30 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play) { Player_SetCsActionWithHaltedActors(play, NULL, 7); this->getItemId = sGetItemIds[this->prizeIndex]; - this->getItemEntry = (GetItemEntry)GET_ITEM_NONE; if ((this->getItemId == GI_BOMB_BAG_30) && (CUR_CAPACITY(UPG_BOMB_BAG) == 30)) { this->getItemId = GI_BOMB_BAG_40; } - if (IS_RANDO) { - switch (this->prizeIndex) { - case EXITEM_BOMB_BAG_BOWLING: - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); - this->getItemId = this->getItemEntry.getItemId; - break; - case EXITEM_HEART_PIECE_BOWLING: - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); - this->getItemId = this->getItemEntry.getItemId; - break; - case EXITEM_BOMBCHUS_BOWLING: - this->getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); - this->getItemId = this->getItemEntry.getItemId; - break; - } - } - player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; this->actor.parent = NULL; - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, true, this)) { Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); } player->stateFlags1 |= PLAYER_STATE1_IN_CUTSCENE; this->actionFunc = EnBomBowlPit_WaitTillPrizeGiven; } void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play)) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, true, this)) { this->actionFunc = EnBomBowlPit_Reset; } else { - if (!IS_RANDO || this->getItemEntry.getItemId == GI_NONE) { - Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); - } else { - GiveItemEntryFromActor(&this->actor, play, this->getItemEntry, 2000.0f, 1000.0f); - } + Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f); } } void EnBomBowlPit_Reset(EnBomBowlPit* this, PlayState* play) { - if (((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && - Message_ShouldAdvance(play)) || - (IS_RANDO && this->getItemId == GI_ICE_TRAP)) { + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { // "Normal termination"/"completion" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST); if (this->getItemId == GI_HEART_PIECE) { diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h index 97ff39ac8..48cfbd5c2 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h @@ -33,7 +33,6 @@ typedef struct EnBomBowlPit { /* 0x01D4 */ Vec3f unk_1D4; // camera eye (maxsteps) /* 0x01E0 */ EnExItem* exItem; /* 0x01E4 */ char unk_1E4[0x3520]; - /* */ GetItemEntry getItemEntry; } EnBomBowlPit; // size = 0x3704 #endif diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 3860336ef..28e89036d 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -138,12 +138,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { onCounter = true; case EXITEM_BOMB_BAG_BOWLING: this->unk_17C = func_8002EBCC; - if (IS_RANDO) { - this->giDrawId = - Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20).gid; - } else { - this->giDrawId = GID_BOMB_BAG_30; - } + this->giDrawId = GID_BOMB_BAG_30; this->timer = 65; this->prizeRotateTimer = 35; this->scale = 0.5f; @@ -151,7 +146,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { this->actionFunc = EnExItem_BowlPrize; } else { this->actionFunc = EnExItem_SetupBowlCounter; - this->actor.shape.yOffset = IS_RANDO ? -10.0f : -18.0f; + this->actor.shape.yOffset = -18.0f; } break; case EXITEM_HEART_PIECE_COUNTER: @@ -173,11 +168,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { onCounter = true; case EXITEM_BOMBCHUS_BOWLING: this->unk_17C = func_8002EBCC; - if (IS_RANDO) { - this->giDrawId = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10).gid; - } else { - this->giDrawId = GID_BOMBCHU; - } + this->giDrawId = GID_BOMBCHU; this->timer = 65; this->prizeRotateTimer = 35; this->scale = 0.5f; @@ -496,43 +487,12 @@ void EnExItem_DrawItems(EnExItem* this, PlayState* play) { } if (this) {} func_8002ED80(&this->actor, play, 0); - if (IS_RANDO) { - GetItemEntry randoGetItem = (GetItemEntry)GET_ITEM_NONE; - switch (this->type) { - case EXITEM_BOMB_BAG_BOWLING: - case EXITEM_BOMB_BAG_COUNTER: - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); - break; - case EXITEM_BOMBCHUS_BOWLING: - case EXITEM_BOMBCHUS_COUNTER: - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); - break; - case EXITEM_BULLET_BAG: - randoGetItem = Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); - break; - } - - if (randoGetItem.getItemId != GI_NONE) { - EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem); - GetItemEntry_Draw(play, randoGetItem); - return; - } - } - GetItem_Draw(play, this->giDrawId); } void EnExItem_DrawHeartPiece(EnExItem* this, PlayState* play) { func_8002ED80(&this->actor, play, 0); - - if (IS_RANDO) { - GetItemEntry randoGetItem = - Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); - EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem); - GetItemEntry_Draw(play, randoGetItem); - } else { - GetItem_Draw(play, GID_HEART_PIECE); - } + GetItem_Draw(play, GID_HEART_PIECE); } void EnExItem_DrawMagic(EnExItem* this, PlayState* play, s16 magicIndex) { diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h index d014e19be..090d7028c 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h @@ -27,6 +27,9 @@ typedef struct EnExItem { /* 0x0170 */ Vec3f initPos; // unused /* 0x017C */ EnExItemLightFunc unk_17C; /* 0x0180 */ EnExItemLightFunc unk_180; + // #region SOH [Randomizer] Caching the get item entry for the draw function for performance + /* */ GetItemEntry sohItemEntry; + // #endregion } EnExItem; // size = 0x0184 typedef enum { @@ -52,6 +55,8 @@ typedef enum { /* 19 */ EXITEM_BULLET_BAG } EnExItemType; +void EnExItem_WaitForObject(EnExItem* enExItem, PlayState* play); + #define EXITEM_COUNTER 5 #define EXITEM_CHEST 10 #define EXITEM_MAGIC 16