From baf7691fbde9b27a328a7e9b5a9ffb4c244d22ca Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 13 May 2024 12:29:34 -0500 Subject: [PATCH] Fix weirdness with item gets from chests (#4146) --- .../game-interactor/GameInteractor.h | 2 ++ .../Enhancements/randomizer/hook_handlers.cpp | 26 ++++++++++++++++--- .../Enhancements/timesaver_hook_handlers.cpp | 11 ++++++++ .../actors/ovl_player_actor/z_player.c | 15 +++++------ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 956384e5d..57f1d1e5c 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -260,6 +260,8 @@ typedef enum { // Opt: *EnOkarinaTag VB_PLAY_DOOR_OF_TIME_CS, VB_PLAY_RAINBOW_BRIDGE_CS, + // Opt: *EnBox + VB_PLAY_SLOW_CHEST_CS, /*** Give Items ***/ diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 3f15ce4c8..e164eae16 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -37,6 +37,9 @@ extern "C" { extern SaveContext gSaveContext; extern PlayState* gPlayState; +extern void func_8084DFAC(PlayState* play, Player* player); +extern void func_80835DAC(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 flags); +extern s32 func_80836898(PlayState* play, Player* player, PlayerFuncA74 func); } #define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() @@ -555,8 +558,26 @@ void RandomizerSetChestGameRandomizerInf(RandomizerCheck rc) { } } +void Player_Action_8084E6D4_override(Player* player, PlayState* play) { + if (LinkAnimation_Update(play, &player->skelAnime)) { + func_8084DFAC(play, player); + } +} + +void func_8083A434_override(PlayState* play, Player* player) { + func_80835DAC(play, player, Player_Action_8084E6D4_override, 0); + player->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_IN_CUTSCENE; +} + void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) { switch (id) { + case VB_PLAY_SLOW_CHEST_CS: { + // We force fast chests if SkipGetItemAnimation is enabled because the camera in the CS looks pretty wonky otherwise + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_DISABLED)) { + *should = false; + } + break; + } case VB_GIVE_ITEM_FROM_CHEST: { EnBox* chest = static_cast(optionalArg); RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(chest->dyna.actor.id, gPlayState->sceneNum, chest->dyna.actor.params); @@ -565,9 +586,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void RandomizerSetChestGameRandomizerInf(rc); Player* player = GET_PLAYER(gPlayState); - player->av2.actionVar2 = 1; - player->getItemId = GI_NONE; - player->getItemEntry = GetItemEntry(GET_ITEM_NONE); + func_80836898(gPlayState, player, func_8083A434_override); + *should = false; break; } diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 28518ae14..81c7d7727 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -3,6 +3,7 @@ #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/enhancementTypes.h" extern "C" { #include "src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.h" @@ -14,6 +15,7 @@ extern "C" { #include "src/overlays/actors/ovl_En_Ko/z_en_ko.h" #include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h" #include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h" +#include "src/overlays/actors/ovl_En_Box/z_en_box.h" #include "src/overlays/actors/ovl_Demo_Im/z_demo_im.h" #include "src/overlays/actors/ovl_En_Sa/z_en_sa.h" #include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h" @@ -625,6 +627,15 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* } break; } + case VB_PLAY_SLOW_CHEST_CS: { + if (CVarGetInteger(CVAR_ENHANCEMENT("FastChests"), 0)) { + *should = false; + } else if (CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED) && *should) { + EnBox* enBox = static_cast(opt); + *should = enBox->dyna.actor.scale.x != 0.005f; + } + break; + } } } 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 8cadd404b..3dfb2dbeb 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6853,10 +6853,6 @@ s32 Player_ActionChange_2(Player* this, PlayState* play) { giEntry = this->getItemEntry; } EnBox* chest = (EnBox*)interactedActor; - if (CVarGetInteger(CVAR_ENHANCEMENT("FastChests"), 0) != 0) { - giEntry.gi = -1 * abs(giEntry.gi); - } - if (giEntry.itemId != ITEM_NONE) { if (((Item_CheckObtainability(giEntry.itemId) == ITEM_NONE) && (giEntry.field & 0x40)) || ((Item_CheckObtainability(giEntry.itemId) != ITEM_NONE) && (giEntry.field & 0x20))) { @@ -6865,11 +6861,12 @@ s32 Player_ActionChange_2(Player* this, PlayState* play) { } } - func_80836898(play, this, func_8083A434); if (GameInteractor_Should(VB_GIVE_ITEM_FROM_CHEST, true, chest)) { + func_80836898(play, this, func_8083A434); + } this->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD | PLAYER_STATE1_IN_CUTSCENE; func_8083AE40(this, giEntry.objectId); - } + this->actor.world.pos.x = chest->dyna.actor.world.pos.x - (Math_SinS(chest->dyna.actor.shape.rot.y) * 29.4343f); this->actor.world.pos.z = @@ -6877,8 +6874,10 @@ s32 Player_ActionChange_2(Player* this, PlayState* play) { this->yaw = this->actor.shape.rot.y = chest->dyna.actor.shape.rot.y; func_80832224(this); - if ((giEntry.itemId != ITEM_NONE) && (giEntry.gi >= 0) && - (Item_CheckObtainability(giEntry.itemId) == ITEM_NONE)) { + bool vanillaPlaySlowChestCS = (giEntry.itemId != ITEM_NONE) && (giEntry.gi >= 0) && + (Item_CheckObtainability(giEntry.itemId) == ITEM_NONE); + + if (GameInteractor_Should(VB_PLAY_SLOW_CHEST_CS, vanillaPlaySlowChestCS, chest)) { Player_AnimPlayOnceAdjusted(play, this, this->ageProperties->unk_98); Player_AnimReplaceApplyFlags(play, this, 0x28F); chest->unk_1F4 = 1;