From db10864e95d993a9f5389f31f61d441fb4ccba0c Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Tue, 26 Sep 2023 08:45:51 -0500 Subject: [PATCH] Add flag set/unset hooks and GI actions (#3065) --- soh/include/z64player.h | 3 +- soh/include/z64save.h | 15 ++- .../game-interactor/GameInteractionEffect.cpp | 49 +++++++ .../game-interactor/GameInteractionEffect.h | 22 +++- .../game-interactor/GameInteractor.h | 8 ++ .../game-interactor/GameInteractor_Hooks.cpp | 16 +++ .../game-interactor/GameInteractor_Hooks.h | 4 + .../GameInteractor_RawAction.cpp | 121 ++++++++++++++++++ soh/src/code/z_actor.c | 16 +++ .../overlays/actors/ovl_En_Daiku/z_en_daiku.c | 2 + soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c | 15 +++ soh/src/overlays/actors/ovl_En_Si/z_en_si.c | 2 + soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c | 18 ++- 13 files changed, 283 insertions(+), 8 deletions(-) diff --git a/soh/include/z64player.h b/soh/include/z64player.h index 094e28eb2..ff30cc170 100644 --- a/soh/include/z64player.h +++ b/soh/include/z64player.h @@ -409,7 +409,8 @@ typedef enum { FLAG_ITEM_GET_INF, FLAG_INF_TABLE, FLAG_EVENT_INF, - FLAG_RANDOMIZER_INF + FLAG_RANDOMIZER_INF, + FLAG_GS_TOKEN, } FlagType; typedef struct { diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 50f9ba44b..3f03c9c76 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -578,11 +578,16 @@ typedef enum { // 0xDA-0xDE #define EVENTCHKINF_SKULLTULA_REWARD_INDEX 13 -#define EVENTCHKINF_SKULLTULA_REWARD_10_MASK (1 << 10) -#define EVENTCHKINF_SKULLTULA_REWARD_20_MASK (1 << 11) -#define EVENTCHKINF_SKULLTULA_REWARD_30_MASK (1 << 12) -#define EVENTCHKINF_SKULLTULA_REWARD_40_MASK (1 << 13) -#define EVENTCHKINF_SKULLTULA_REWARD_50_MASK (1 << 14) +#define EVENTCHKINF_SKULLTULA_REWARD_10_SHIFT 10 +#define EVENTCHKINF_SKULLTULA_REWARD_20_SHIFT 11 +#define EVENTCHKINF_SKULLTULA_REWARD_30_SHIFT 12 +#define EVENTCHKINF_SKULLTULA_REWARD_40_SHIFT 13 +#define EVENTCHKINF_SKULLTULA_REWARD_50_SHIFT 14 +#define EVENTCHKINF_SKULLTULA_REWARD_10_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_10_SHIFT) +#define EVENTCHKINF_SKULLTULA_REWARD_20_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_20_SHIFT) +#define EVENTCHKINF_SKULLTULA_REWARD_30_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_30_SHIFT) +#define EVENTCHKINF_SKULLTULA_REWARD_40_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_40_SHIFT) +#define EVENTCHKINF_SKULLTULA_REWARD_50_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_50_SHIFT) /* diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp index 7b725b487..8a8120e70 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp @@ -47,6 +47,55 @@ GameInteractionEffectQueryResult GameInteractionEffectBase::Remove() { namespace GameInteractionEffect { + // MARK: - Flags + GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + + return GameInteractionEffectQueryResult::Possible; + } + + void SetSceneFlag::_Apply() { + GameInteractor::RawAction::SetSceneFlag(parameters[0], parameters[1], parameters[2]); + } + + GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + + return GameInteractionEffectQueryResult::Possible; + } + + void UnsetSceneFlag::_Apply() { + GameInteractor::RawAction::UnsetSceneFlag(parameters[0], parameters[1], parameters[2]); + } + + GameInteractionEffectQueryResult SetFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + + return GameInteractionEffectQueryResult::Possible; + } + + void SetFlag::_Apply() { + GameInteractor::RawAction::SetFlag(parameters[0], parameters[1]); + } + + GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + + return GameInteractionEffectQueryResult::Possible; + } + + void UnsetFlag::_Apply() { + GameInteractor::RawAction::UnsetFlag(parameters[0], parameters[1]); + } + // MARK: - ModifyHeartContainers GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h index ab8cfb610..c4a7f7eac 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h @@ -18,7 +18,7 @@ public: virtual GameInteractionEffectQueryResult CanBeRemoved(); GameInteractionEffectQueryResult Apply(); GameInteractionEffectQueryResult Remove(); - int32_t parameters[2]; + int32_t parameters[3]; protected: virtual void _Apply() = 0; @@ -26,6 +26,26 @@ public: }; namespace GameInteractionEffect { + class SetSceneFlag: public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + }; + + class UnsetSceneFlag: public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + }; + + class SetFlag: public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + }; + + class UnsetFlag: public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + }; + class ModifyHeartContainers: public GameInteractionEffectBase { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 008cfb53c..04f021983 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -152,6 +152,10 @@ public: DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry)); DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum)); DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum)); + DEFINE_HOOK(OnSceneFlagSet, void(int16_t sceneNum, int16_t flagType, int16_t flag)); + DEFINE_HOOK(OnSceneFlagUnset, void(int16_t sceneNum, int16_t flagType, int16_t flag)); + DEFINE_HOOK(OnFlagSet, void(int16_t flagType, int16_t flag)); + DEFINE_HOOK(OnFlagUnset, void(int16_t flagType, int16_t flag)); DEFINE_HOOK(OnSceneSpawnActors, void()); DEFINE_HOOK(OnPlayerUpdate, void()); DEFINE_HOOK(OnOcarinaSongAction, void()); @@ -196,6 +200,10 @@ public: class RawAction { public: + static void SetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag); + static void UnsetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag); + static void SetFlag(int16_t flagType, int16_t chestNum); + static void UnsetFlag(int16_t flagType, int16_t chestNum); static void AddOrRemoveHealthContainers(int16_t amount); static void AddOrRemoveMagic(int8_t amount); static void HealOrDamagePlayer(int16_t hearts); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index dfd90c084..1cb6f48a8 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -30,6 +30,22 @@ void GameInteractor_ExecuteOnSceneInitHooks(int16_t sceneNum) { GameInteractor::Instance->ExecuteHooks(sceneNum); } +void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag) { + GameInteractor::Instance->ExecuteHooks(sceneNum, flagType, flag); +} + +void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, int16_t flag) { + GameInteractor::Instance->ExecuteHooks(sceneNum, flagType, flag); +} + +void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag) { + GameInteractor::Instance->ExecuteHooks(flagType, flag); +} + +void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag) { + GameInteractor::Instance->ExecuteHooks(flagType, flag); +} + void GameInteractor_ExecuteOnSceneSpawnActors() { GameInteractor::Instance->ExecuteHooks(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index a1d2cbb31..b23b64798 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -11,6 +11,10 @@ void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry); void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry); void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum); void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum); +void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag); +void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, int16_t flag); +void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag); +void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag); void GameInteractor_ExecuteOnSceneSpawnActors(); void GameInteractor_ExecuteOnPlayerUpdate(); void GameInteractor_ExecuteOnOcarinaSongAction(); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp index e78da02e1..864eef427 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp @@ -127,6 +127,127 @@ void GameInteractor::RawAction::KnockbackPlayer(float strength) { func_8002F71C(gPlayState, &player->actor, strength * 5, player->actor.world.rot.y + 0x8000, strength * 5); } +void GameInteractor::RawAction::SetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag) { + switch (flagType) { + case FlagType::FLAG_SCENE_SWITCH: + if (sceneNum == gPlayState->sceneNum) { + if (flag < 0x20) { + gPlayState->actorCtx.flags.swch |= (1 << flag); + } else { + gPlayState->actorCtx.flags.tempSwch |= (1 << (flag - 0x20)); + } + } + if (flag < 0x20) { + gSaveContext.sceneFlags[sceneNum].swch |= (1 << flag); + } + break; + case FlagType::FLAG_SCENE_CLEAR: + if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.clear |= (1 << flag); + gSaveContext.sceneFlags[sceneNum].clear |= (1 << flag); + break; + case FlagType::FLAG_SCENE_TREASURE: + if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.chest |= (1 << flag); + gSaveContext.sceneFlags[sceneNum].chest |= (1 << flag); + break; + case FlagType::FLAG_SCENE_COLLECTIBLE: + if (sceneNum == gPlayState->sceneNum) { + if (flag != 0) { + if (flag < 0x20) { + gPlayState->actorCtx.flags.collect |= (1 << flag); + } else { + gPlayState->actorCtx.flags.tempCollect |= (1 << (flag - 0x20)); + } + } + } + if (flag != 0 && flag < 0x20) { + gSaveContext.sceneFlags[sceneNum].collect |= (1 << flag); + } + break; + } +}; + +void GameInteractor::RawAction::UnsetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag) { + switch (flagType) { + case FlagType::FLAG_SCENE_SWITCH: + if (sceneNum == gPlayState->sceneNum) { + if (flag < 0x20) { + gPlayState->actorCtx.flags.swch &= ~(1 << flag); + } else { + gPlayState->actorCtx.flags.tempSwch &= ~(1 << (flag - 0x20)); + } + } + if (flag < 0x20) { + gSaveContext.sceneFlags[sceneNum].swch &= ~(1 << flag); + } + break; + case FlagType::FLAG_SCENE_CLEAR: + if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.clear &= ~(1 << flag); + gSaveContext.sceneFlags[sceneNum].clear &= ~(1 << flag); + break; + case FlagType::FLAG_SCENE_TREASURE: + if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.chest &= ~(1 << flag); + gSaveContext.sceneFlags[sceneNum].chest &= ~(1 << flag); + break; + case FlagType::FLAG_SCENE_COLLECTIBLE: + if (sceneNum == gPlayState->sceneNum) { + if (flag != 0) { + if (flag < 0x20) { + gPlayState->actorCtx.flags.collect &= ~(1 << flag); + } else { + gPlayState->actorCtx.flags.tempCollect &= ~(1 << (flag - 0x20)); + } + } + } + if (flag != 0 && flag < 0x20) { + gSaveContext.sceneFlags[sceneNum].collect &= ~(1 << flag); + } + break; + } +}; + +void GameInteractor::RawAction::SetFlag(int16_t flagType, int16_t flag) { + switch (flagType) { + case FlagType::FLAG_EVENT_CHECK_INF: + gSaveContext.eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); + break; + case FlagType::FLAG_ITEM_GET_INF: + gSaveContext.itemGetInf[flag >> 4] |= (1 << (flag & 0xF)); + break; + case FlagType::FLAG_INF_TABLE: + gSaveContext.infTable[flag >> 4] |= (1 << (flag & 0xF)); + break; + case FlagType::FLAG_EVENT_INF: + gSaveContext.eventInf[flag >> 4] |= (1 << (flag & 0xF)); + break; + case FlagType::FLAG_RANDOMIZER_INF: + gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); + break; + case FlagType::FLAG_GS_TOKEN: + SET_GS_FLAGS((flag & 0x1F00) >> 8, flag & 0xFF); + break; + } +}; + +void GameInteractor::RawAction::UnsetFlag(int16_t flagType, int16_t flag) { + switch (flagType) { + case FlagType::FLAG_EVENT_CHECK_INF: + gSaveContext.eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); + break; + case FlagType::FLAG_ITEM_GET_INF: + gSaveContext.itemGetInf[flag >> 4] &= ~(1 << (flag & 0xF)); + break; + case FlagType::FLAG_INF_TABLE: + gSaveContext.infTable[flag >> 4] &= ~(1 << (flag & 0xF)); + break; + case FlagType::FLAG_EVENT_INF: + gSaveContext.eventInf[flag >> 4] &= ~(1 << (flag & 0xF)); + break; + case FlagType::FLAG_RANDOMIZER_INF: + gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); + break; + } +}; + void GameInteractor::RawAction::GiveOrTakeShield(int32_t shield) { // When taking a shield, make sure it is unequipped as well. // When giving a shield and the player isn't wearing one yet, diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 750419966..85b9748df 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -668,6 +668,7 @@ void Flags_SetSwitch(PlayState* play, s32 flag) { } else { play->actorCtx.flags.tempSwch |= (1 << (flag - 0x20)); } + GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_SWITCH, flag); } /** @@ -680,6 +681,7 @@ void Flags_UnsetSwitch(PlayState* play, s32 flag) { } else { play->actorCtx.flags.tempSwch &= ~(1 << (flag - 0x20)); } + GameInteractor_ExecuteOnSceneFlagUnset(play->sceneNum, FLAG_SCENE_SWITCH, flag); } /** @@ -728,6 +730,7 @@ s32 Flags_GetTreasure(PlayState* play, s32 flag) { void Flags_SetTreasure(PlayState* play, s32 flag) { lusprintf(__FILE__, __LINE__, 2, "Treasure Flag Set - %#x", flag); play->actorCtx.flags.chest |= (1 << flag); + GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_TREASURE, flag); } /** @@ -742,6 +745,7 @@ s32 Flags_GetClear(PlayState* play, s32 flag) { */ void Flags_SetClear(PlayState* play, s32 flag) { play->actorCtx.flags.clear |= (1 << flag); + GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_CLEAR, flag); } /** @@ -749,6 +753,7 @@ void Flags_SetClear(PlayState* play, s32 flag) { */ void Flags_UnsetClear(PlayState* play, s32 flag) { play->actorCtx.flags.clear &= ~(1 << flag); + GameInteractor_ExecuteOnSceneFlagUnset(play->sceneNum, FLAG_SCENE_CLEAR, flag); } /** @@ -795,6 +800,7 @@ void Flags_SetCollectible(PlayState* play, s32 flag) { play->actorCtx.flags.tempCollect |= (1 << (flag - 0x20)); } } + GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_COLLECTIBLE, flag); } void func_8002CDE4(PlayState* play, TitleCardContext* titleCtx) { @@ -4718,6 +4724,7 @@ s32 Flags_GetEventChkInf(s32 flag) { */ void Flags_SetEventChkInf(s32 flag) { gSaveContext.eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, flag); } /** @@ -4725,6 +4732,7 @@ void Flags_SetEventChkInf(s32 flag) { */ void Flags_UnsetEventChkInf(s32 flag) { gSaveContext.eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagUnset(FLAG_EVENT_CHECK_INF, flag); } /** @@ -4739,6 +4747,7 @@ s32 Flags_GetItemGetInf(s32 flag) { */ void Flags_SetItemGetInf(s32 flag) { gSaveContext.itemGetInf[flag >> 4] |= (1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagSet(FLAG_ITEM_GET_INF, flag); } /** @@ -4746,6 +4755,7 @@ void Flags_SetItemGetInf(s32 flag) { */ void Flags_UnsetItemGetInf(s32 flag) { gSaveContext.itemGetInf[flag >> 4] &= ~(1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagUnset(FLAG_ITEM_GET_INF, flag); } /** @@ -4760,6 +4770,7 @@ s32 Flags_GetInfTable(s32 flag) { */ void Flags_SetInfTable(s32 flag) { gSaveContext.infTable[flag >> 4] |= (1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagSet(FLAG_INF_TABLE, flag); } /** @@ -4767,6 +4778,7 @@ void Flags_SetInfTable(s32 flag) { */ void Flags_UnsetInfTable(s32 flag) { gSaveContext.infTable[flag >> 4] &= ~(1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagUnset(FLAG_INF_TABLE, flag); } /** @@ -4781,6 +4793,7 @@ s32 Flags_GetEventInf(s32 flag) { */ void Flags_SetEventInf(s32 flag) { gSaveContext.eventInf[flag >> 4] |= (1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_INF, flag); } /** @@ -4788,6 +4801,7 @@ void Flags_SetEventInf(s32 flag) { */ void Flags_UnsetEventInf(s32 flag) { gSaveContext.eventInf[flag >> 4] &= ~(1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagUnset(FLAG_EVENT_INF, flag); } /** @@ -4802,6 +4816,7 @@ s32 Flags_GetRandomizerInf(RandomizerInf flag) { */ void Flags_SetRandomizerInf(RandomizerInf flag) { gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagSet(FLAG_RANDOMIZER_INF, flag); } /** @@ -4809,6 +4824,7 @@ void Flags_SetRandomizerInf(RandomizerInf flag) { */ void Flags_UnsetRandomizerInf(RandomizerInf flag) { gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); + GameInteractor_ExecuteOnFlagUnset(FLAG_RANDOMIZER_INF, flag); } u32 func_80035BFC(PlayState* play, s16 arg1) { diff --git a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index a8724f107..8df2f8c0b 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -1,6 +1,7 @@ #include "z_en_daiku.h" #include "overlays/actors/ovl_En_GeldB/z_en_geldb.h" #include "objects/object_daiku/object_daiku.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -403,6 +404,7 @@ void EnDaiku_InitEscape(EnDaiku* this, PlayState* play) { this->stateFlags &= ~(ENDAIKU_STATEFLAG_1 | ENDAIKU_STATEFLAG_2); gSaveContext.eventChkInf[EVENTCHKINF_CARPENTERS_FREE_INDEX] |= EVENTCHKINF_CARPENTERS_FREE_MASK(this->actor.params & 3); + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_CARPENTERS_FREE_INDEX << 4) + (this->actor.params & 3)); this->actor.gravity = -1.0f; this->escapeSubCamTimer = sEscapeSubCamParams[this->actor.params & 3].maxFramesActive; diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index a7aaa2f52..0cad40183 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -3,6 +3,7 @@ #include "vt.h" #include "objects/object_fr/object_fr.h" #include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -103,6 +104,17 @@ static u16 sSongIndex[] = { 0x0002, 0x0004, 0x0010, 0x0008, 0x0020, 0x0040, 0x0001, 0x0000, }; +static u16 sSongIndexShift[] = { + EVENTCHKINF_SONGS_FOR_FROGS_ZL_SHIFT, + EVENTCHKINF_SONGS_FOR_FROGS_EPONA_SHIFT, + EVENTCHKINF_SONGS_FOR_FROGS_SARIA_SHIFT, + EVENTCHKINF_SONGS_FOR_FROGS_SUNS_SHIFT, + EVENTCHKINF_SONGS_FOR_FROGS_SOT_SHIFT, + EVENTCHKINF_SONGS_FOR_FROGS_STORMS_SHIFT, + EVENTCHKINF_SONGS_FOR_FROGS_CHOIR_SHIFT, + 0x0, // FROG_NO_SONG +}; + // Frog to Index for Song Flag (sSongIndex) Mapping static u8 sFrogToSongIndex[] = { FROG_SARIA, FROG_SUNS, FROG_SOT, FROG_ZL, FROG_EPONA, @@ -955,6 +967,7 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if ((songIndex >= FROG_ZL) && (songIndex <= FROG_SOT)) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); if (!gSaveContext.n64ddFlag) { this->reward = GI_RUPEE_PURPLE; } else { @@ -967,6 +980,7 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { } else if (songIndex == FROG_STORMS) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); if (!gSaveContext.n64ddFlag) { this->reward = GI_HEART_PIECE; } else { @@ -979,6 +993,7 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { } else if (songIndex == FROG_CHOIR_SONG) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); if (!gSaveContext.n64ddFlag) { this->reward = GI_HEART_PIECE; } else { diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c index ba9f3ccd2..64f69300a 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c @@ -5,6 +5,7 @@ */ #include "z_en_si.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" extern void func_8083C148(Player*, PlayState*); extern void func_80078884(uint16_t); @@ -183,6 +184,7 @@ void func_80AFB950(EnSi* this, PlayState* play) { player->actor.freezeTimer = 10; } else { SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF); + GameInteractor_ExecuteOnFlagSet(FLAG_GS_TOKEN, this->actor.params); Actor_Kill(&this->actor); if (gSaveContext.pendingIceTrapCount > 0 && player->heldItemId == 11) { player->actor.freezeTimer = 0; diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index 46e3e73a9..3e641ee34 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -9,6 +9,7 @@ #include "objects/object_ahg/object_ahg.h" #include "objects/object_boj/object_boj.h" #include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -81,7 +82,21 @@ static EnSthActionFunc sRewardObtainedWaitActions[6] = { }; static u16 sEventFlags[6] = { - 0, EVENTCHKINF_SKULLTULA_REWARD_10_MASK, EVENTCHKINF_SKULLTULA_REWARD_20_MASK, EVENTCHKINF_SKULLTULA_REWARD_30_MASK, EVENTCHKINF_SKULLTULA_REWARD_40_MASK, EVENTCHKINF_SKULLTULA_REWARD_50_MASK, + 0, + EVENTCHKINF_SKULLTULA_REWARD_10_MASK, + EVENTCHKINF_SKULLTULA_REWARD_20_MASK, + EVENTCHKINF_SKULLTULA_REWARD_30_MASK, + EVENTCHKINF_SKULLTULA_REWARD_40_MASK, + EVENTCHKINF_SKULLTULA_REWARD_50_MASK, +}; + +static u16 sEventFlagsShift[6] = { + 0, + EVENTCHKINF_SKULLTULA_REWARD_10_SHIFT, + EVENTCHKINF_SKULLTULA_REWARD_20_SHIFT, + EVENTCHKINF_SKULLTULA_REWARD_30_SHIFT, + EVENTCHKINF_SKULLTULA_REWARD_40_SHIFT, + EVENTCHKINF_SKULLTULA_REWARD_50_SHIFT, }; static s16 sGetItemIds[6] = { @@ -298,6 +313,7 @@ void EnSth_GiveReward(EnSth* this, PlayState* play) { this->actor.parent = NULL; EnSth_SetupAction(this, EnSth_RewardObtainedTalk); gSaveContext.eventChkInf[EVENTCHKINF_SKULLTULA_REWARD_INDEX] |= this->eventFlag; + GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SKULLTULA_REWARD_INDEX << 4) + sEventFlagsShift[this->actor.params]); } else { EnSth_GivePlayerItem(this, play); }