From c65b8a42b86a945937d087388454a9d8be37a098 Mon Sep 17 00:00:00 2001 From: TakaRikka Date: Thu, 13 Aug 2026 14:50:39 -0700 Subject: [PATCH] add handful of missing hooks --- include/d/actor/d_a_door_shutter.h | 2 +- mods/randomizer/src/hooks.cpp | 142 ++++++++++++++++++++++++++++- 2 files changed, 142 insertions(+), 2 deletions(-) diff --git a/include/d/actor/d_a_door_shutter.h b/include/d/actor/d_a_door_shutter.h index a8e99f1295..34ea7f7fc9 100644 --- a/include/d/actor/d_a_door_shutter.h +++ b/include/d/actor/d_a_door_shutter.h @@ -123,7 +123,7 @@ public: bool checkFlag(u16 flag) { return field_0x68e & flag; } void setAction(u8 action) { mAction = action; } -private: +// private: /* 0x56C */ request_of_phase_process_class mPhase1; /* 0x574 */ request_of_phase_process_class mPhase2; /* 0x57C */ J3DModel* mModel1; diff --git a/mods/randomizer/src/hooks.cpp b/mods/randomizer/src/hooks.cpp index e8e0c3a2ac..32d9157d90 100644 --- a/mods/randomizer/src/hooks.cpp +++ b/mods/randomizer/src/hooks.cpp @@ -12,11 +12,17 @@ #include #include "d/actor/d_a_alink.h" -#include "d/d_file_select.h" +#include "d/actor/d_a_b_bq.h" +#include "d/actor/d_a_door_shutter.h" +#include "d/actor/d_a_tag_kmsg.h" +#include "d/d_door_param2.h" #include "d/d_file_sel_info.h" +#include "d/d_file_select.h" #include "d/d_meter2_info.h" +#include "d/d_msg_object.h" #include "d/d_save.h" #include "d/d_shop_system.h" +#include "d/actor/d_a_e_mk.h" DEFINE_HOOK(&dFile_select_c::selectDataNameMove, dFile_select_c__selectDataNameMove); DEFINE_HOOK(&dFile_select_c::dataSelect, dFile_select_c__dataSelect); @@ -61,6 +67,16 @@ DEFINE_HOOK(&getItemFunc, dItem_getItemFunc); extern int checkItemGet(u8 i_itemNo, int i_default); DEFINE_HOOK(&checkItemGet, dItem_checkItemGet); +DEFINE_HOOK(&daAlink_c::decideDoStatus, daAlink_c__decideDoStatus); +DEFINE_HOOK_SYMBOL("daAlink_searchBouDoor", void*(fopAc_ac_c*, void*), searchBouDoor); +DEFINE_HOOK(&daAlink_c::checkGroundSpecialMode, daAlink_c__checkGroundSpecialMode); + +DEFINE_HOOK_SYMBOL("b_bq_end", void(b_bq_class*), bq_end); + +DEFINE_HOOK(&daDoor20_c::checkOpenMsgDoor, daDoor20_c__checkOpenMsgDoor); + +DEFINE_HOOK_SYMBOL("demo_camera_end", void(e_mk_class*), e_mk_demo_camera_end); + namespace randomizer::ui { dialogSelectModeState g_dialogSelectModeState = SelectReady; } @@ -1204,6 +1220,110 @@ HookAction hookPreOnStageSwitch(ModContext*, void* args, void* retval, void*) { return HOOK_CONTINUE; } +HookAction hookPreDecideDoStatus(ModContext*, void* args, void* retval, void*) { + daAlink_c* i_this = mods::arg(args, 0); + bool set_status = false; + + if (i_this->mAttList != NULL) { + s16 actor_name = fopAcM_GetName(i_this->field_0x27f4); + if (actor_name == fpcNm_Tag_Lv6Gate_e || + (actor_name == fpcNm_TAG_KMSG_e && static_cast(i_this->field_0x27f4)->getType() == 3)) + { + // Separate check for striking sword into the pedestal for randomizer + if (!i_this->checkEquipAnime() && randomizer_checkTempleOfTimeRequirement()) { + i_this->setDoStatus(BUTTON_STATUS_STRIKE); + set_status = true; + } + } + } + + if (set_status) { + i_this->decideCommonDoStatus(); + return HOOK_SKIP_ORIGINAL; + } + + return HOOK_CONTINUE; +} + +HookAction hookPreSearchBouDoor(ModContext*, void* args, void* retval, void*) { + // In randomizer, we don't want Bo preventing us from entering his house on Day 2 + if (daAlink_c::checkStageName("F_SP103")) + { + *static_cast(retval) = nullptr; + return HOOK_SKIP_ORIGINAL; + } + + return HOOK_CONTINUE; +} + +HookAction hookPreCheckGroundSpecialMode(ModContext*, void* args, void* retval, void*) { + daAlink_c* i_this = mods::arg(args, 0); + + if (i_this->mLinkAcch.ChkGroundHit() + && !i_this->checkModeFlg(daAlink_c::MODE_PLAYER_FLY) + && !i_this->checkMagneBootsOn() + && i_this->checkEndResetFlg0(daAlink_c::ERFLG0_FORCE_WOLF_CHANGE)) + { + u8 stage = getStageID(); + // In rando, don't transform in twilight fog unless we have shadow crystal + if (!dComIfGs_isEventBit(TRANSFORMING_UNLOCKED) && + (stage == Palace_of_Twilight || stage == Phantom_Zant_1 || stage == Phantom_Zant_2)) + { + *static_cast(retval) = FALSE; + return HOOK_SKIP_ORIGINAL; + } + *static_cast(retval) = i_this->procCoMetamorphoseInit(); + return HOOK_SKIP_ORIGINAL; + } + + return HOOK_CONTINUE; +} + +void hookPostBqEnd(ModContext*, void* args, void* retval, void*) { + // If the player is wolf, they will softlock after the defeat cutscene is completed. + checkTransformFromWolf(); +} + +HookAction hookPreCheckOpenMsgDoor(ModContext*, void* args, void* retval, void*) { + daDoor20_c* i_this = mods::arg(args, 0); + int* param_1 = mods::arg(args, 1); + + if (!door_param2_c::isMsgDoor(i_this)) { + *static_cast(retval) = 1; + return HOOK_SKIP_ORIGINAL; + } + + int msgNo = door_param2_c::getMsgNo(i_this); + if (msgNo == 0xffff) { + *param_1 = 0; + *static_cast(retval) = 1; + return HOOK_SKIP_ORIGINAL; + } + + i_this->field_0x624.init(NULL, msgNo, 0, NULL); + int rv = 1; + // If we are in SPR, we don't want Yeta's msg flow to prevent us from opening the door if we haven't talked to her. + if (!daAlink_c::checkStageName("D_MN11")) { + rv = i_this->field_0x624.checkOpenDoor(i_this, param_1); + } + dMsgObject_endFlowGroup(); + *static_cast(retval) = rv; + return HOOK_SKIP_ORIGINAL; +} + +void hookPostEmkDemoCameraEnd(ModContext*, void* args, void* retval, void*) { + e_mk_class* i_this = mods::arg(args, 0); + + switch (i_this->demoSubMode) { + case 6: + if (i_this->demoCamCounter == 180) { + // If the player is wolf, they will void and lose the boomerang check. + checkTransformFromWolf(); + } + break; + } +} + } ModResult initialize() { @@ -1259,6 +1379,16 @@ ModResult initialize() { ADD_HOOK_PRE(onStageSwitch, hookPreOnStageSwitch); + ADD_HOOK_PRE(daAlink_c__decideDoStatus, hookPreDecideDoStatus); + ADD_HOOK_PRE(searchBouDoor, hookPreSearchBouDoor); + ADD_HOOK_PRE(daAlink_c__checkGroundSpecialMode, hookPreCheckGroundSpecialMode); + + ADD_HOOK_POST(bq_end, hookPostBqEnd); + + ADD_HOOK_PRE(daDoor20_c__checkOpenMsgDoor, hookPreCheckOpenMsgDoor); + + ADD_HOOK_POST(e_mk_demo_camera_end, hookPostEmkDemoCameraEnd); + return MOD_OK; } @@ -1303,6 +1433,16 @@ ModResult uninstall() { mods::hook::uninstall(svc_hook); + mods::hook::uninstall(svc_hook); + mods::hook::uninstall(svc_hook); + mods::hook::uninstall(svc_hook); + + mods::hook::uninstall(svc_hook); + + mods::hook::uninstall(svc_hook); + + mods::hook::uninstall(svc_hook); + return MOD_OK; } } \ No newline at end of file