add in hooks

This commit is contained in:
TakaRikka
2026-08-07 07:46:43 -07:00
parent 48cf860467
commit 769f83db25
3 changed files with 571 additions and 3 deletions
+1 -1
-1
View File
@@ -101,7 +101,6 @@ file(GLOB_RECURSE RANDOMIZER_DATA RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
# to both the mod and the standalone generator
add_library(randomizer_embeds OBJECT)
b_embed(randomizer_embeds "res/shadow_crystal.bti")
foreach (RANDOMIZER_FILE IN LISTS RANDOMIZER_DATA)
if (RANDOMIZER_FILE MATCHES "^generator/data/tests")
continue()
+570 -1
View File
@@ -2,15 +2,58 @@
#include "session.hpp"
#include "randomizer_context.hpp"
#include "ui/rando_config.hpp"
#include "flags.h"
#include "stages.h"
#include "tools.h"
#include "item_ids.h"
#include <mods/svc/hook.hpp>
#include <mods/svc/log.hpp>
#include "d/actor/d_a_alink.h"
#include "d/d_file_select.h"
#include "d/d_meter2_info.h"
#include "d/d_save.h"
#include "d/d_shop_system.h"
DEFINE_HOOK(&dFile_select_c::selectDataNameMove, dFile_select_c__selectDataNameMove);
DEFINE_HOOK(&dFile_select_c::dataSelect, dFile_select_c__dataSelect);
DEFINE_HOOK(&dSv_event_c::isEventBit, dSv_event_c__isEventBit);
DEFINE_HOOK(&dSv_event_c::onEventBit, dSv_event_c__onEventBit);
DEFINE_HOOK(&dSv_memBit_c::isSwitch, dSv_memBit_c__isSwitch);
DEFINE_HOOK(&dSv_memBit_c::onSwitch, dSv_memBit_c__onSwitch);
DEFINE_HOOK(&dSv_memBit_c::onDungeonItem, dSv_memBit_c__onDungeonItem);
DEFINE_HOOK(&dSv_memBit_c::offDungeonItem, dSv_memBit_c__offDungeonItem);
DEFINE_HOOK(&dSv_memBit_c::isDungeonItem, dSv_memBit_c__isDungeonItem);
DEFINE_HOOK(&dSv_player_status_b_c::isDarkClearLV, dSv_player_status_b_c__isDarkClearLV);
DEFINE_HOOK(&dSv_player_item_c::checkEmptyBottle, dSv_player_item_c__checkEmptyBottle);
DEFINE_HOOK(&dSv_player_item_c::setLineUpItem, dSv_player_item_c__setLineUpItem);
DEFINE_HOOK(&dSv_info_c::onSwitch, dSv_info_c__onSwitch);
DEFINE_HOOK(&dMsgFlow_c::query001, dMsgFlow_c__query001);
DEFINE_HOOK(&dMsgFlow_c::query022, dMsgFlow_c__query022);
DEFINE_HOOK(&dMsgFlow_c::query025, dMsgFlow_c__query025);
DEFINE_HOOK(&dMsgFlow_c::query049, dMsgFlow_c__query049);
DEFINE_HOOK(&dMsgFlow_c::event035, dMsgFlow_c__event035);
/*DEFINE_HOOK_SYMBOL("__Z21dComIfGp_setNextStagePKcsaafjiasii",
void(char const*, s16, s8, s8, f32, u32, int, s8, s16, int, int), setNextStage);*/
DEFINE_HOOK_SYMBOL("daObj_Gb_Create", int(fopAc_ac_c*), ObjGb_Create);
DEFINE_HOOK(&dMeter2Info_readItemTexture, readItemTexture);
DEFINE_HOOK(&dShopSystem_c::seq_decide_yes, dShopSystem_c__seq_decide_yes);
DEFINE_HOOK(&CheckFieldItemCreateHeap, dItemData_CheckFieldItemCreateHeap);
DEFINE_HOOK(&dEvt_control_c::talkEnd, dEvt_control_c__talkEnd);
namespace randomizer::ui {
dialogSelectModeState g_dialogSelectModeState = SelectReady;
}
@@ -18,7 +61,6 @@ dialogSelectModeState g_dialogSelectModeState = SelectReady;
namespace randomizer::hooks {
namespace {
UiDialogHandle playModeDialog{0};
HookAction hookPreDataSelect(ModContext*, void* args, void* retval, void* userdata) {
ui::g_dialogSelectModeState = ui::SelectReady;
ui::g_file_select_window_ctx.is_proceed = false;
@@ -94,6 +136,493 @@ HookAction hookPreSelectDataNameMove(ModContext*, void* args, void* retval, void
return HOOK_SKIP_ORIGINAL;
}
HookAction hookPreIsEventBit(ModContext*, void* args, void* retval, void*) {
const u16 i_no = mods::arg<u16>(args, 1);
auto& out = *static_cast<BOOL*>(retval);
switch (i_no) {
case BO_TALKED_TO_YOU_AFTER_OPENING_IRON_BOOTS_CHEST: {
if (daAlink_c::checkStageName(allStages[Ordon_Village_Interiors])) {
out = dComIfGs_isEventBit(HEARD_BO_TEXT_AFTER_SUMO_FIGHT) ? TRUE : FALSE;
return HOOK_SKIP_ORIGINAL;
}
break;
}
case GAVE_ILIA_HER_CHARM: // Gave Ilia the charm
case CITY_OOCCOO_CS_WATCHED: // CiTS Intro CS watched
{
if (daAlink_c::checkStageName(allStages[Hidden_Village])) {
if (!dComIfGs_isEventBit(GOT_ILIAS_CHARM)) {
// If we haven't gotten the item from Impaz then we need to return false or it
// will break her dialogue.
out = FALSE;
return HOOK_SKIP_ORIGINAL;
}
}
break;
}
case GORON_MINES_CLEARED: {
if (daAlink_c::checkStageName(allStages[Goron_Mines]) ||
daAlink_c::checkStageName(allStages[Death_Mountain_Interiors])) {
out = FALSE; // The gorons will not act properly if the flag is set.
return HOOK_SKIP_ORIGINAL;
}
break;
}
case ZORA_ESCORT_CLEARED: {
if (daAlink_c::checkStageName(allStages[Castle_Town])) {
// If the flag isn't set the player will be thrown into escort when they open the door
out = TRUE;
return HOOK_SKIP_ORIGINAL;
}
if (playerIsInRoomStage(0, allStages[Kakariko_Village_Interiors])) {
out = TRUE; // Return true to prevent Renado/Ilia crash after ToT
return HOOK_SKIP_ORIGINAL;
}
break;
}
case CITY_IN_THE_SKY_CLEARED: // Would like to find where this is checked and patch it there.
{
if (!dComIfGs_isEventBit(FIXED_THE_MIRROR_OF_TWILIGHT)) {
if (randomizer_GetContext().mSettings[RandomizerContext::PALACE_OF_TWILIGHT_REQUIREMENTS] !=
RandomizerContext::VANILLA) {
out = FALSE;
return HOOK_SKIP_ORIGINAL;
}
}
break;
}
case HOWLED_AT_SNOWPEAK_STONE: {
if (daAlink_c::checkStageName(allStages[Snowpeak])) {
// return false so the player can howl at the stone multiple times to remove map glitch
out = FALSE;
return HOOK_SKIP_ORIGINAL;
}
break;
}
case WATCHED_CUTSCENE_AFTER_GOATS_2: {
if (playerIsInRoomStage(1, allStages[Ordon_Village_Interiors])) {
// false -> Sera gives the milk item once they help the cat;
// true -> the shop is always usable even if the cat is not returned.
out = dComIfGs_isEventBit(SERAS_CAT_RETURNED_TO_SHOP) ? FALSE : TRUE;
return HOOK_SKIP_ORIGINAL;
}
break;
}
case FIXED_THE_MIRROR_OF_TWILIGHT: {
if (daAlink_c::checkStageName(allStages[Palace_of_Twilight])) {
out = TRUE; // If the flag is not set, the player cannot leave PoT from the inside.
return HOOK_SKIP_ORIGINAL;
}
break;
}
default:
break;
}
return HOOK_CONTINUE;
}
HookAction hookPreOnEventBit(ModContext*, void* args, void*, void*) {
const u16 i_no = mods:: arg<u16>(args, 1);
switch (i_no) {
// Wolf <-> Human crash patches/bug fixes: some cutscenes/events either crash or act
// weird if Link is in the wrong form and the game no longer auto-transforms once the
// Shadow Crystal has been obtained.
case ENTERED_ORDON_SPRING_DAY_3:
if (dComIfGs_isEventBit(TRANSFORMING_UNLOCKED)) {
dComIfGs_setTransformStatus(0);
}
break;
case WATCHED_CUTSCENE_AFTER_BEING_CAPTURED_IN_FARON_TWILIGHT:
if (dComIfGs_isEventBit(TRANSFORMING_UNLOCKED)) {
dComIfGs_setTransformStatus(1);
}
break;
case MIDNAS_DESPERATE_HOUR_COMPLETED:
dComIfGs_onDarkClearLV(3);
break;
case CLEARED_FARON_TWILIGHT:
// If we've already cleared Eldin Twilight, Lanayru Twilight, and MDH
if (dComIfGs_isEventBit(MIDNAS_DESPERATE_HOUR_COMPLETED)) {
if (dComIfGs_isDarkClearLV(2) && dComIfGs_isDarkClearLV(3)) {
// Set the flag for the last transformed twilight; also puts Midna on the
// player's back
dComIfGs_onTransformLV(3);
dComIfGs_onDarkClearLV(3);
}
}
break;
case CLEARED_ELDIN_TWILIGHT:
dComIfGs_onEventBit(MAP_WARPING_UNLOCKED); // in glitched logic, you can skip the gorge bridge
if (dComIfGs_isEventBit(MIDNAS_DESPERATE_HOUR_COMPLETED)) {
if (dComIfGs_isDarkClearLV(1) && dComIfGs_isDarkClearLV(3)) {
dComIfGs_onTransformLV(3);
dComIfGs_onDarkClearLV(3);
}
}
// Set flag for the bridge between Castle Town and Eldin field if skip bridge
// donation is on and both Eldin and Lanayru twilight are cleared
if (dComIfGs_isEventBit(CLEARED_LANAYRU_TWILIGHT) &&
randomizer_GetContext().mSettings[RandomizerContext::SKIP_BRIDGE_DONATION] ==
RandomizerContext::ON)
{
dComIfGs_onEventBit(BRIDGE_REPAIR_FUNDRAISING_COMPLETED);
dComIfGs_onStageSwitch(6, 0x1B); // Bridge exists
}
break;
case CLEARED_LANAYRU_TWILIGHT:
if (dComIfGs_isEventBit(MIDNAS_DESPERATE_HOUR_COMPLETED)) {
if (dComIfGs_isDarkClearLV(1) && dComIfGs_isDarkClearLV(2)) {
dComIfGs_onTransformLV(3);
dComIfGs_onDarkClearLV(3);
}
}
if (dComIfGs_isEventBit(CLEARED_ELDIN_TWILIGHT) &&
randomizer_GetContext().mSettings[RandomizerContext::SKIP_BRIDGE_DONATION] ==
RandomizerContext::ON)
{
dComIfGs_onEventBit(BRIDGE_REPAIR_FUNDRAISING_COMPLETED);
dComIfGs_onStageSwitch(6, 0x1B); // Bridge exists
}
break;
case REMOVE_SWORD_SHIELD_FROM_WOLF_BACK:
if (!dComIfGs_isEventBit(CLEARED_FARON_TWILIGHT)) {
dComIfGs_onTransformLV(0); // Set the last transformed twilight to include Faron
}
break;
case GAVE_TELMA_RENADOS_LETTER:
offWarashibeItem(dItemNo_Randomizer_LETTER_e);
break;
default:
break;
}
return HOOK_CONTINUE;
}
HookAction hookPreMembitIsSwitch(ModContext*, void* args, void* retval, void*) {
if (getStageID() == Hidden_Village_Interiors) {
if (mods::arg<int>(args, 1) == 0x61) { // Is Impaz in her house
*static_cast<BOOL*>(retval) = TRUE;
return HOOK_SKIP_ORIGINAL;
}
}
return HOOK_CONTINUE;
}
// kinda hacky check to see if this membit object is the temp memory area in save info
inline bool isTempMemBit(dSv_memBit_c* i_this) {
return i_this == &dComIfGs_getSaveInfo()->getMemory().getBit();
}
HookAction hookPreMembitOnSwitch(ModContext*, void* args, void*, void*) {
auto* i_this = mods::arg<dSv_memBit_c*>(args, 0);
const int i_no = mods::arg<int>(args, 1);
if (isTempMemBit(i_this)) {
if (getStageID() == Arbiters_Grounds) {
// Poe flame CS trigger
if (i_no == 0x26) {
i_this->offSwitch(0x45); // Open the Poe gate
return HOOK_SKIP_ORIGINAL;
}
} else if (getStageID() == Lake_Hylia) {
// Lanayru Twilight End CS trigger
if (i_no == 0xD) {
if (dComIfGs_isEventBit(TRANSFORMING_UNLOCKED)) {
// Set player to Human as the game will not do so if Shadow Crystal has
// been obtained.
dComIfGs_setTransformStatus(0);
}
}
} else if (getStageID() == Kakariko_Village) {
// Hawkeye is for sale
if (i_no == 0x3E) {
i_this->offSwitch(0xB); // Remove the coming soon sign so the hawkeye can be bought
}
} else if (getStageID() == Hyrule_Field) {
// Destroyed North Eldin rocks barrier
if (i_no == 0x11) {
// Unlock Eldin Province on the map. Done manually rather than via
// `onRegionBit`, which would see the rocks unbroken and skip the region.
dComIfGs_getSaveData()->getPlayer().getPlayerFieldLastStayInfo().mRegion |= 0x08;
}
}
}
return HOOK_CONTINUE;
}
HookAction hookPreOnDungeonItem(ModContext*, void* args, void*, void*) {
int i_no = mods::arg<int>(args, 1);
// Don't use the stage life collection flag for rando
if (i_no == dSv_memBit_c::STAGE_LIFE) {
return HOOK_SKIP_ORIGINAL;
}
// Don't turn Ooccoo into the note when defeating a boss
else if (dComIfGs_isStageBossEnemy() && i_no == dSv_memBit_c::OOCCOO_NOTE) {
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
}
HookAction hookPreOffDungeonItem(ModContext*, void* args, void*, void*) {
if (mods::arg<int>(args, 1) == dSv_memBit_c::STAGE_LIFE) {
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
}
HookAction hookPreIsDungeonItem(ModContext*, void* args, void* retval, void*) {
const int i_no = mods::arg<int>(args, 1);
auto& out = *static_cast<BOOL*>(retval);
switch (i_no) {
case dSv_memBit_c::STAGE_LIFE:
out = FALSE;
return HOOK_SKIP_ORIGINAL;
case dSv_memBit_c::STAGE_BOSS_ENEMY: {
// If we are in a dungeon or fighting a midboss, we don't want the boss being
// defeated to affect the gameplay.
std::string stageName = dComIfGp_getStartStageName();
if (stageName.starts_with("D_MN")) {
out = FALSE;
return HOOK_SKIP_ORIGINAL;
}
break;
}
case dSv_memBit_c::STAGE_BOSS_ENEMY_2: {
// If we are in the early rooms of FT, we don't want Ook being defeated to affect
// gameplay
if (daAlink_c::checkStageName("D_MN05") && dComIfGp_roomControl_getStayNo() < 4) {
out = FALSE;
return HOOK_SKIP_ORIGINAL;
}
break;
}
default:
break;
}
return HOOK_CONTINUE;
}
HookAction hookPreIsDarkClearLV(ModContext*, void* args, void* retval, void*) {
if (mods::arg<int>(args, 1) == 0 &&
playerIsInRoomStage(1, allStages[Ordon_Village_Interiors]))
{
// Return false so Sera will give us the bottle if we have rescued the cat.
*static_cast<BOOL*>(retval) = FALSE;
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
}
HookAction hookPreCheckEmptyBottle(ModContext*, void*, void* retval, void*) {
if (getStageID() == Cave_of_Ordeals) {
// Return 1 to allow the player to collect the floor 50 reward, as this makes the
// game think the player has an empty bottle.
*static_cast<u8*>(retval) = 1;
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
}
void hookPostSetLineUpItem(ModContext*, void* args, void*, void*) {
// Allow rando to use all item slots. Checks the loaded hash rather than
// randomizer_IsActive() because this runs on file select.
if (randomizer_GetContext().mHash.empty()) {
return;
}
auto* i_this = mods::arg<dSv_player_item_c*>(args, 0);
if (i_this->mItems[7] == dItemNo_NONE_e) {
return;
}
// append slot 7 after the vanilla lineup, unless already present
int slot_idx = 0;
for (; slot_idx < 24; slot_idx++) {
const u8 lineup = i_this->mItemSlots[slot_idx];
if (lineup == 7) {
return;
}
if (lineup == 0xFF) {
break;
}
}
if (slot_idx < 24) {
i_this->mItemSlots[slot_idx] = 7;
}
}
HookAction hookPreSaveInfoOnSwitch(ModContext*, void* args, void*, void*) {
// Set custom flag for the Temple of Time pedestal strike
if (getStageID() == Sacred_Grove && mods::arg<int>(args, 1) == 0xEE) {
mods::arg<dSv_info_c*>(args, 0)->onSwitch(0x63, mods::arg<int>(args, 2));
}
return HOOK_CONTINUE;
}
HookAction hookPreQuery001(ModContext*, void* args, void* retval, void*) {
auto* node = mods::arg<mesg_flow_node_branch*>(args, 1);
if (node->param == 0xFA) { // MDH Completed
// Return 0 to be able to turn souls into Jovani pre MDH
if (playerIsInRoomStage(5, allStages[Castle_Town_Shops])) {
*static_cast<u16*>(retval) = 0;
return HOOK_SKIP_ORIGINAL;
}
}
return HOOK_CONTINUE;
}
HookAction hookPreQuery022(ModContext*, void* args, void* retval, void*) {
if (daAlink_c::checkStageName(allStages[Ordon_Village_Interiors])) {
auto* node = mods::arg<mesg_flow_node_branch*>(args, 1);
if ((node->param & 0xFF) == dItemNo_Randomizer_HVY_BOOTS_e) {
// Return false so that the door in Bo's house can be opened without the Iron Boots
*static_cast<u16*>(retval) = 0;
return HOOK_SKIP_ORIGINAL;
}
}
return HOOK_CONTINUE;
}
HookAction hookPreQuery025(ModContext*, void* args, void* retval, void*) {
// 0x4461 is the key for the red potion shop item
if (playerIsInRoomStage(3, allStages[Kakariko_Village_Interiors]) &&
randomizer_GetContext().mShopOverrides.contains(0x4461)) {
// Return 0 so the player can buy the red potion item from the shop.
*static_cast<u16*>(retval) = 0;
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
}
void hookPostQuery049(ModContext*, void*, void* retval, void*) {
// Split up getting both rewards from Jovani in randomizer
auto& out = *static_cast<u16*>(retval);
if (out == 4 && !dComIfGs_isEventBit(GOT_BOTTLE_FROM_JOVANI)) {
out = 3;
}
}
HookAction hookPreEvent035(ModContext*, void* args, void* retval, void*) {
auto* node = mods::arg<mesg_flow_node_event*>(args, 1);
const u8* p = node->params;
const int prm0 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
if (prm0 == dItemNo_TOMATO_PUREE_e || prm0 == dItemNo_TASTE_e) {
dComIfGs_offItemFirstBit(prm0);
} else if (prm0 == dItemNo_RAFRELS_MEMO_e || prm0 == dItemNo_ASHS_SCRIBBLING_e) {
// rando: keep SLOT_19 (the items are randomized)
} else if (prm0 == dItemNo_LETTER_e || prm0 == dItemNo_BILL_e ||
prm0 == dItemNo_WOOD_STATUE_e || prm0 == dItemNo_IRIAS_PENDANT_e) {
offWarashibeItem(prm0);
}
*static_cast<int*>(retval) = 1;
return HOOK_SKIP_ORIGINAL;
}
// TODO: item service
/* HookAction hookPreExecItemGet(ModContext*, void* args, void*, void*) {
if (randomizer_IsActive()) {
const u8 item = mods::arg<u8>(args, 0);
item_funcs::exec_item_get(item);
dusk::mods::item_granted(item, mods::arg<u32>(args, 1), mods::arg<fopAc_ac_c*>(args, 2));
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
} */
/* HookAction hookPreCheckItemGet(ModContext*, void* args, void* retval, void*) {
if (randomizer_IsActive()) {
*static_cast<int*>(retval) = item_funcs::check_item_get(mods::arg<u8>(args, 0), mods::arg<int>(args, 1));
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
} */
HookAction hookPreSetNextStage(ModContext*, void* args, void*, void*) {
randomizer_checkAndOverrideEntranceData(
mods::arg_ref<char const*>(args, 0),
mods::arg_ref<s8>(args, 2),
mods::arg_ref<s16>(args, 1),
mods::arg_ref<s8>(args, 3)
);
return HOOK_CONTINUE;
}
HookAction hookPreObjGbCreate(ModContext*, void* args, void* retval, void*) {
if (getStageID() == StageIDs::Mirror_Chamber && !randomizer_mirrorChamberWallShouldExist()) {
*static_cast<int*>(retval) = cPhs_ERROR_e;
return HOOK_SKIP_ORIGINAL;
}
return HOOK_CONTINUE;
}
void hookPostReadItemTexture(ModContext*, void* args, void*, void*) {
const u8 item_no = mods::arg<u8>(args, 1);
void* tex_buf1 = mods::arg<void*>(args, 2);
if (tex_buf1 == nullptr || item_no != dItemNo_Randomizer_MAGIC_LV1_e) {
return;
}
ResourceBuffer bti = RESOURCE_BUFFER_INIT;
if (session::svc_mng.resource->load(session::svc_mng.mod_ctx, "shadow_crystal.bti", &bti) == MOD_OK) {
std::memcpy(tex_buf1, bti.data, bti.size < 0xC00 ? bti.size : 0xC00);
session::svc_mng.resource->free(session::svc_mng.mod_ctx, &bti);
}
}
HookAction hookPreShopSeqDecideYes(ModContext*, void* args, void*, void*) {
auto* i_this = mods::arg<dShopSystem_c*>(args, 0);
int item_no = 0;
if (i_this->mFlow.getEventId(&item_no) == 1 && playerIsInRoomStage(3, "R_SP109")) {
const u16 key = static_cast<u16>((getStageID() << 8) | (item_no & 0xFF));
if (randomizer_GetContext().mShopOverrides.contains(key)) {
i_this->setSoldOutFlag();
}
}
return HOOK_CONTINUE;
}
HookAction hookPreCheckFieldItemCreateHeap(ModContext*, void* args, void* retval, void*) {
auto* i_this = mods::arg<fopAc_ac_c*>(args, 0);
switch (static_cast<daItemBase_c*>(i_this)->getItemNo()) {
case dItemNo_Randomizer_EMPTY_BOTTLE_e:
case dItemNo_Randomizer_HALF_MILK_BOTTLE_e:
case dItemNo_Randomizer_OIL_BOTTLE3_e:
case dItemNo_Randomizer_DROP_BOTTLE_e:
case dItemNo_Randomizer_LINKS_SAVINGS_e:
case dItemNo_Randomizer_POU_SPIRIT_e:
*static_cast<int*>(retval) = CheckItemCreateHeap(i_this);
return HOOK_SKIP_ORIGINAL;
default:
return HOOK_CONTINUE;
}
}
void hookPostTalkEnd(ModContext*, void*, void*, void*) {
if (g_randomizerState.getHasPendingToDChange()) {
g_randomizerState.setHasPendingToDChange(false);
g_randomizerState.handleTimeOfDayChange();
}
}
}
ModResult initialize() {
@@ -103,9 +632,49 @@ ModResult initialize() {
return MOD_ERROR; \
}
#define ADD_HOOK_POST(originalFn, hookFn) \
if (mods::hook::add_post<originalFn>(hookFn) != MOD_OK) { \
mods::log::error("Failed to add post-hook for " #originalFn); \
return MOD_ERROR; \
}
ADD_HOOK_PRE(dFile_select_c__selectDataNameMove, hookPreSelectDataNameMove);
ADD_HOOK_PRE(dFile_select_c__dataSelect, hookPreDataSelect);
ADD_HOOK_PRE(dSv_event_c__isEventBit, hookPreIsEventBit);
ADD_HOOK_PRE(dSv_event_c__onEventBit, hookPreOnEventBit);
ADD_HOOK_PRE(dSv_memBit_c__isSwitch, hookPreMembitIsSwitch);
ADD_HOOK_PRE(dSv_memBit_c__onSwitch, hookPreMembitOnSwitch);
ADD_HOOK_PRE(dSv_memBit_c__onDungeonItem, hookPreOnDungeonItem);
ADD_HOOK_PRE(dSv_memBit_c__offDungeonItem, hookPreOffDungeonItem);
ADD_HOOK_PRE(dSv_memBit_c__isDungeonItem, hookPreIsDungeonItem);
ADD_HOOK_PRE(dSv_player_status_b_c__isDarkClearLV, hookPreIsDarkClearLV);
ADD_HOOK_PRE(dSv_player_item_c__checkEmptyBottle, hookPreCheckEmptyBottle);
ADD_HOOK_POST(dSv_player_item_c__setLineUpItem, hookPostSetLineUpItem);
ADD_HOOK_PRE(dSv_info_c__onSwitch, hookPreSaveInfoOnSwitch);
ADD_HOOK_PRE(dMsgFlow_c__query001, hookPreQuery001);
ADD_HOOK_PRE(dMsgFlow_c__query022, hookPreQuery022);
ADD_HOOK_PRE(dMsgFlow_c__query025, hookPreQuery025);
ADD_HOOK_POST(dMsgFlow_c__query049, hookPostQuery049);
ADD_HOOK_PRE(dMsgFlow_c__event035, hookPreEvent035);
//ADD_HOOK_PRE(setNextStage, hookPreSetNextStage);
ADD_HOOK_PRE(ObjGb_Create, hookPreObjGbCreate);
ADD_HOOK_POST(readItemTexture, hookPostReadItemTexture);
ADD_HOOK_PRE(dShopSystem_c__seq_decide_yes, hookPreShopSeqDecideYes);
ADD_HOOK_PRE(dItemData_CheckFieldItemCreateHeap, hookPreCheckFieldItemCreateHeap);
ADD_HOOK_POST(dEvt_control_c__talkEnd, hookPostTalkEnd);
return MOD_OK;
}
}