mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-20 05:16:24 -04:00
Merge with origin/rando-mod
This commit is contained in:
@@ -296,7 +296,7 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[18];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[18];
|
||||
private:
|
||||
// private:
|
||||
/* 0x0E40 */ NPC_FAIRY_HIO_CLASS* mHIO;
|
||||
/* 0x0E44 */ dCcD_Cyl mCyl;
|
||||
/* 0x0F80 */ u8 mType;
|
||||
|
||||
@@ -287,7 +287,7 @@ public:
|
||||
|
||||
static DUSK_GAME_DATA char DUSK_CONST* DUSK_CONST mCutNameList[10];
|
||||
static DUSK_GAME_DATA cutFunc DUSK_CONST mCutList[10];
|
||||
private:
|
||||
// private:
|
||||
/* 0x0E40 */ mDoExt_McaMorfSO* mFishModelMorf;
|
||||
/* 0x0E44 */ mDoExt_McaMorfSO* mLeafModelMorf;
|
||||
/* 0x0E48 */ NPC_YKM_HIO_CLASS* mpHIO;
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
static DUSK_GAME_DATA daObjMasterSword_Attr_c const mAttr;
|
||||
static DUSK_GAME_DATA actionFunc ActionTable[];
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x568 */ J3DModel* mpModel;
|
||||
/* 0x56C */ request_of_phase_process_class mPhase;
|
||||
/* 0x574 */ mDoExt_btkAnm mBtk;
|
||||
|
||||
@@ -14,7 +14,18 @@
|
||||
#include "d/actor/d_a_alink.h"
|
||||
#include "d/actor/d_a_b_bq.h"
|
||||
#include "d/actor/d_a_door_shutter.h"
|
||||
#include "d/actor/d_a_e_md.h"
|
||||
#include "d/actor/d_a_e_mk.h"
|
||||
#include "d/actor/d_a_kytag08.h"
|
||||
#include "d/actor/d_a_npc4.h"
|
||||
#include "d/actor/d_a_npc_bans.h"
|
||||
#include "d/actor/d_a_tag_kmsg.h"
|
||||
#include "d/actor/d_a_npc_fairy.h"
|
||||
#include "d/actor/d_a_obj_master_sword.h"
|
||||
#include "d/actor/d_a_npc_shad.h"
|
||||
#include "d/actor/d_a_npc_yelia.h"
|
||||
#include "d/actor/d_a_npc_ykm.h"
|
||||
#include "d/actor/d_a_npc_ykw.h"
|
||||
#include "d/d_door_param2.h"
|
||||
#include "d/d_file_sel_info.h"
|
||||
#include "d/d_file_select.h"
|
||||
@@ -22,7 +33,7 @@
|
||||
#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"
|
||||
#include "c/c_damagereaction.h"
|
||||
|
||||
DEFINE_HOOK(&dFile_select_c::selectDataNameMove, dFile_select_c__selectDataNameMove);
|
||||
DEFINE_HOOK(&dFile_select_c::dataSelect, dFile_select_c__dataSelect);
|
||||
@@ -84,6 +95,30 @@ DEFINE_HOOK_SYMBOL("demo_camera_end", void(e_mk_class*), e_mk_demo_camera_end);
|
||||
DEFINE_HOOK(&dStage_changeScene4Event, changeScene4Event);
|
||||
DEFINE_HOOK_SYMBOL("dStage_playerInit", int(dStage_dt_c*, void*, int, void*), stage_playerInit);
|
||||
|
||||
DEFINE_HOOK_SYMBOL("daKytag08_Execute", int(kytag08_class*), Kytag08_Execute);
|
||||
|
||||
DEFINE_HOOK(&daNpcT_chkEvtBit, NpcT_chkEvtBit);
|
||||
DEFINE_HOOK(&daNpcF_chkEvtBit, NpcF_chkEvtBit);
|
||||
DEFINE_HOOK(&daNpcF_c::orderEvent, daNpcF_c__orderEvent);
|
||||
|
||||
DEFINE_HOOK(&daNpc_Bans_c::isDelete, daNpc_Bans_c__isDelete);
|
||||
|
||||
DEFINE_HOOK(&daNpc_Fairy_c::AppearDemoCall, daNpc_Fairy_c__AppearDemoCall);
|
||||
|
||||
DEFINE_HOOK(&daNpcShad_c::Create, daNpcShad_c__Create);
|
||||
DEFINE_HOOK(&daNpcShad_c::wait_type1, daNpcShad_c__wait_type1);
|
||||
|
||||
DEFINE_HOOK(&daNpc_Yelia_c::cutTakeWoodStatue, daNpc_Yelia_c__cutTakeWoodStatue);
|
||||
DEFINE_HOOK(&dSv_player_item_c::setWarashibeItem, dSv_player_item_c__setWarashibeItem);
|
||||
|
||||
DEFINE_HOOK(&daNpc_ykM_c::isDelete, daNpc_ykM_c__isDelete);
|
||||
DEFINE_HOOK(&daNpc_ykW_c::isDelete, daNpc_ykW_c__isDelete);
|
||||
|
||||
DEFINE_HOOK_SYMBOL("daE_MD_Create", int(fopAc_ac_c*), daE_MD_c__create);
|
||||
|
||||
DEFINE_HOOK(&daObjMasterSword_c::executeWait, daObjMasterSword_c__executeWait);
|
||||
DEFINE_HOOK_SYMBOL("daObjMasterSword_Execute", int(daObjMasterSword_c*), daObjMasterSword_c__execute);
|
||||
|
||||
namespace randomizer::ui {
|
||||
dialogSelectModeState g_dialogSelectModeState = SelectReady;
|
||||
}
|
||||
@@ -1401,6 +1436,268 @@ HookAction hookPreStagePlayerInit(ModContext*, void* args, void* retval, void*)
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
void hookPostKytag08Execute(ModContext*, void* args, void* retval, void*) {
|
||||
kytag08_class* i_this = mods::arg<kytag08_class*>(args, 0);
|
||||
|
||||
if (i_this->mSizeTimer < 100 || dComIfGs_BossLife_public_Get() == 1) {
|
||||
dComIfGs_BossLife_public_Set(0);
|
||||
i_this->mTargetAvoidPos = i_this->current.pos;
|
||||
i_this->mSizeTimer = 180;
|
||||
mDoAud_startFogWipeTrigger(&i_this->current.pos);
|
||||
}
|
||||
}
|
||||
|
||||
HookAction hookPreNpcTChkEvtBit(ModContext*, void* args, void* retval, void*) {
|
||||
u32 i_no = mods::arg<u32>(args, 0);
|
||||
|
||||
switch (i_no) {
|
||||
case 0x153: // Checking if the player has Ending Blow
|
||||
if (getStageID() == Hidden_Skill) {
|
||||
*static_cast<BOOL*>(retval) = TRUE;
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
}
|
||||
break;
|
||||
case 0x40: // Checking if the player has completed Goron Mines
|
||||
if (getStageID() == Kakariko_Village_Interiors) {
|
||||
// Return true so Barnes will sell bombs no matter what
|
||||
*static_cast<BOOL*>(retval) = TRUE;
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
HookAction hookPreNpcFChkEvtBit(ModContext*, void* args, void* retval, void*) {
|
||||
u32 i_no = mods::arg<u32>(args, 0);
|
||||
|
||||
// shad handling
|
||||
if (std::strcmp(dComIfGp_getStartStageName(), "R_SP209") == 0) {
|
||||
switch (i_no) {
|
||||
case 0x10B:
|
||||
// spawn even if vanilla city requirements aren't met
|
||||
*static_cast<BOOL*>(retval) = TRUE;
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
case 0x12E:
|
||||
case 0x12F:
|
||||
// skip vanilla cannon spawn failure and move checks
|
||||
*static_cast<BOOL*>(retval) = FALSE;
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
case 0x311:
|
||||
// despawn after custom flag is set
|
||||
*static_cast<BOOL*>(retval) = dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[0x333]);
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (i_no) {
|
||||
case 0x169: // Checking if Raised Mirror in Mirror Chamber
|
||||
// Only let Auru despawn in randomizer if we already collected his item
|
||||
if (getStageID() == Lake_Hylia) {
|
||||
*static_cast<BOOL*>(retval) = dComIfGs_isEventBit(GOT_AURUS_MEMO);
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
HookAction hookPreNpcBansIsDelete(ModContext*, void* args, void* retval, void*) {
|
||||
daNpc_Bans_c* i_this = mods::arg<daNpc_Bans_c*>(args, 0);
|
||||
|
||||
switch (i_this->mType) {
|
||||
case 3: // MAKING_BOMBS
|
||||
*static_cast<BOOL*>(retval) = TRUE;
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
case 4: // SHOP
|
||||
*static_cast<BOOL*>(retval) = FALSE;
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
HookAction hookPreNpcFOrderEvent(ModContext*, void* args, void* retval, void*) {
|
||||
daNpcF_c* i_this = mods::arg<daNpcF_c*>(args, 0);
|
||||
int& i_forceSpeak = mods::arg_ref<int>(args, 1);
|
||||
u16 i_priority = mods::arg<u16>(args, 4);
|
||||
|
||||
// kinda hacky way to check for the state where Bo is trying to talk after getting Iron Boots
|
||||
const std::string arcName = i_this->eventInfo.getArchiveName();
|
||||
if (arcName == "Bou4" && i_priority == 40) {
|
||||
i_forceSpeak = FALSE;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
void hookPostFairyAppearDemoCall(ModContext*, void* args, void* retval, void*) {
|
||||
daNpc_Fairy_c* i_this = mods::arg<daNpc_Fairy_c*>(args, 0);
|
||||
|
||||
// randomizer overrides EVT_APPEAR_50F_04 set to always be EVT_APPEAR_50F_01
|
||||
if (i_this->field_0xff4 == 12) {
|
||||
i_this->field_0xff4 = 9;
|
||||
}
|
||||
}
|
||||
|
||||
void hookPostYkMIsDelete(ModContext*, void* args, void* retval, void*) {
|
||||
daNpc_ykM_c* i_this = mods::arg<daNpc_ykM_c*>(args, 0);
|
||||
|
||||
if (i_this->mType == daNpc_ykM_c::TYPE_COOK) {
|
||||
// We don't want cooking Yeto to leave the dungeon, even if the BK is obtained.
|
||||
*static_cast<BOOL*>(retval) = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void hookPostYkWIsDelete(ModContext*, void* args, void* retval, void*) {
|
||||
daNpc_ykW_c* i_this = mods::arg<daNpc_ykW_c*>(args, 0);
|
||||
|
||||
if (i_this->field_0xf80 == 1) {
|
||||
// We don't want Yeta to leave the dungeon, even if the BK is obtained.
|
||||
*static_cast<BOOL*>(retval) = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
u8 hookNpcShadWaitType1_patchItemNo = dItemNo_NONE_e;
|
||||
bool hookNpcShadWaitType1_isPatchItemNo = false;
|
||||
HookAction hookPreNpcShadWaitType1(ModContext*, void* args, void* retval, void*) {
|
||||
dEvt_control_c* event = dComIfGp_getEvent();
|
||||
hookNpcShadWaitType1_isPatchItemNo = false;
|
||||
|
||||
if (event->mPreItemNo >= dItemNo_Randomizer_ANCIENT_DOCUMENT_e) {
|
||||
// backup original item no so we can restore it in post hook
|
||||
hookNpcShadWaitType1_patchItemNo = event->mPreItemNo;
|
||||
|
||||
// force item no so that the dominion rod check is forced regardless
|
||||
// of which skybook you have
|
||||
event->mPreItemNo = dItemNo_Randomizer_ANCIENT_DOCUMENT_e;
|
||||
|
||||
hookNpcShadWaitType1_isPatchItemNo = true;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
void hookPostNpcShadWaitType1(ModContext*, void* args, void* retval, void*) {
|
||||
if (hookNpcShadWaitType1_isPatchItemNo) {
|
||||
dComIfGp_getEvent()->mPreItemNo = hookNpcShadWaitType1_patchItemNo;
|
||||
hookNpcShadWaitType1_isPatchItemNo = false;
|
||||
}
|
||||
}
|
||||
|
||||
// kinda ugly way to handle the wood statue. using a flag here to tell when its the right time
|
||||
// to be overriding the setWarashibeItem call with offWarashibeItem instead. maybe look into
|
||||
// a better solution later
|
||||
bool hookYeliaTakeWoodStatue_isOffWarashibeItem = false;
|
||||
HookAction hookPreNpcYeliaCutTakeWoodStatue(ModContext*, void* args, void*, void*) {
|
||||
hookYeliaTakeWoodStatue_isOffWarashibeItem = false;
|
||||
|
||||
auto* i_this = mods::arg<daNpc_Yelia_c*>(args, 0);
|
||||
const int i_staffId = mods::arg<int>(args, 1);
|
||||
const int yeliaStaffId = dComIfGp_evmng_getMyStaffId("Yelia", i_this, -1);
|
||||
if (i_staffId != yeliaStaffId || !dComIfGp_getEventManager().getIsAddvance(i_staffId)) {
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
int* prm = dComIfGp_evmng_getMyIntegerP(i_staffId, "prm");
|
||||
if (prm != nullptr && *prm == 99) {
|
||||
hookYeliaTakeWoodStatue_isOffWarashibeItem = true;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
void hookPostNpcYeliaCutTakeWoodStatue(ModContext*, void*, void*, void*) {
|
||||
hookYeliaTakeWoodStatue_isOffWarashibeItem = false;
|
||||
}
|
||||
|
||||
HookAction hookPreSetWarashibeItem(ModContext*, void* args, void*, void*) {
|
||||
if (!hookYeliaTakeWoodStatue_isOffWarashibeItem) {
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
const u8 itemNo = mods::arg<u8>(args, 1);
|
||||
if (itemNo == dItemNo_NONE_e) {
|
||||
offWarashibeItem(dItemNo_Randomizer_WOOD_STATUE_e);
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
// kinda hacky, force the SkipInfo check to always fail so that the armor always gets created,
|
||||
// then restore the original SkipInfo afterward. needed to make the ball and chain check respawn
|
||||
// if the player leaves the room without grabbing it
|
||||
daE_MD_c* hookEMdCreate_skipActor = nullptr;
|
||||
u8 hookEMdCreate_prevSkipInfo = 0;
|
||||
HookAction hookPreEMdCreate(ModContext*, void* args, void*, void*) {
|
||||
auto* i_this = mods::arg<daE_MD_c*>(args, 0);
|
||||
if (cDmr_SkipInfo == 0 || i_this->current.pos.z <= -1500.0f) {
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
hookEMdCreate_skipActor = i_this;
|
||||
hookEMdCreate_prevSkipInfo = cDmr_SkipInfo;
|
||||
cDmr_SkipInfo = 0;
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
void hookPostEMdCreate(ModContext*, void* args, void*, void*) {
|
||||
auto* i_this = mods::arg<daE_MD_c*>(args, 0);
|
||||
if (hookEMdCreate_skipActor != i_this) {
|
||||
return;
|
||||
}
|
||||
|
||||
cDmr_SkipInfo = hookEMdCreate_prevSkipInfo;
|
||||
hookEMdCreate_skipActor = nullptr;
|
||||
hookEMdCreate_prevSkipInfo = 0;
|
||||
}
|
||||
|
||||
// functions are simple enough that replacing isn't too bad
|
||||
// todo: item service needs to be properly hooked up to this check i think instead of
|
||||
// using "randomizer_getItemAtLocation"
|
||||
void hookReplaceMasterSwordExecuteWait(ModContext*, void* args, void*, void*) {
|
||||
auto* i_this = mods::arg<daObjMasterSword_c*>(args, 0);
|
||||
|
||||
if (daPy_getPlayerActorClass()->checkPriActorOwn(i_this)) {
|
||||
for (int i = 0; i < dComIfGp_getAttention()->GetActionCount(); i++) {
|
||||
if (dComIfGp_getAttention()->ActionTarget(i) == i_this) {
|
||||
if (dComIfGp_getAttention()->getActionBtnB() != NULL &&
|
||||
dComIfGp_getAttention()->getActionBtnB()->mType == fopAc_attn_CARRY_e)
|
||||
{
|
||||
dComIfGp_setDoStatusForce(8, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fopAcM_checkCarryNow(i_this)) {
|
||||
u8 itemToGive = randomizer_getItemAtLocation("Sacred Grove Pedestal Master Sword");
|
||||
g_randomizerState.addItemToEventQueue(itemToGive);
|
||||
|
||||
itemToGive = randomizer_getItemAtLocation("Sacred Grove Pedestal Shadow Crystal");
|
||||
g_randomizerState.addItemToEventQueue(itemToGive);
|
||||
|
||||
dComIfGs_onTmpBit(0x820);
|
||||
dComIfGs_onEventBit(0x2120);
|
||||
}
|
||||
}
|
||||
|
||||
HookAction hookPreMasterSwordExecute(ModContext*, void* args, void* retval, void*) {
|
||||
auto* i_this = mods::arg<daObjMasterSword_c*>(args, 0);
|
||||
|
||||
if (dComIfGs_isTmpBit(dSv_event_tmp_flag_c::tempBitLabels[73])) {
|
||||
// Don't automatically give the master sword in randomizer
|
||||
fopAcM_delete(i_this);
|
||||
*static_cast<int*>(retval) = 1;
|
||||
return HOOK_SKIP_ORIGINAL;
|
||||
}
|
||||
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ModResult initialize() {
|
||||
@@ -1416,6 +1713,12 @@ ModResult initialize() {
|
||||
return MOD_ERROR; \
|
||||
}
|
||||
|
||||
#define ADD_HOOK_REPLACE(originalFn, hookFn) \
|
||||
if (mods::hook::replace<originalFn>(hookFn) != MOD_OK) { \
|
||||
mods::log::error("Failed to add replace-hook for " #originalFn); \
|
||||
return MOD_ERROR; \
|
||||
}
|
||||
|
||||
ADD_HOOK_PRE(dFile_select_c__selectDataNameMove, hookPreSelectDataNameMove);
|
||||
ADD_HOOK_PRE(dFile_select_c__dataSelect, hookPreDataSelect);
|
||||
|
||||
@@ -1469,6 +1772,32 @@ ModResult initialize() {
|
||||
ADD_HOOK_POST(changeScene4Event, hookPostChangeScene4Event);
|
||||
ADD_HOOK_PRE(stage_playerInit, hookPreStagePlayerInit);
|
||||
|
||||
ADD_HOOK_POST(Kytag08_Execute, hookPostKytag08Execute);
|
||||
|
||||
ADD_HOOK_PRE(NpcT_chkEvtBit, hookPreNpcTChkEvtBit);
|
||||
ADD_HOOK_PRE(NpcF_chkEvtBit, hookPreNpcFChkEvtBit);
|
||||
ADD_HOOK_PRE(daNpcF_c__orderEvent, hookPreNpcFOrderEvent);
|
||||
|
||||
ADD_HOOK_PRE(daNpc_Bans_c__isDelete, hookPreNpcBansIsDelete);
|
||||
|
||||
ADD_HOOK_POST(daNpc_Fairy_c__AppearDemoCall, hookPostFairyAppearDemoCall);
|
||||
|
||||
ADD_HOOK_PRE(daNpcShad_c__wait_type1, hookPreNpcShadWaitType1);
|
||||
ADD_HOOK_POST(daNpcShad_c__wait_type1, hookPostNpcShadWaitType1);
|
||||
|
||||
ADD_HOOK_PRE(daNpc_Yelia_c__cutTakeWoodStatue, hookPreNpcYeliaCutTakeWoodStatue);
|
||||
ADD_HOOK_POST(daNpc_Yelia_c__cutTakeWoodStatue, hookPostNpcYeliaCutTakeWoodStatue);
|
||||
ADD_HOOK_PRE(dSv_player_item_c__setWarashibeItem, hookPreSetWarashibeItem);
|
||||
|
||||
ADD_HOOK_POST(daNpc_ykM_c__isDelete, hookPostYkMIsDelete);
|
||||
ADD_HOOK_POST(daNpc_ykW_c__isDelete, hookPostYkWIsDelete);
|
||||
|
||||
ADD_HOOK_PRE(daE_MD_c__create, hookPreEMdCreate);
|
||||
ADD_HOOK_POST(daE_MD_c__create, hookPostEMdCreate);
|
||||
|
||||
ADD_HOOK_REPLACE(daObjMasterSword_c__executeWait, hookReplaceMasterSwordExecuteWait);
|
||||
ADD_HOOK_PRE(daObjMasterSword_c__execute, hookPreMasterSwordExecute);
|
||||
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
@@ -1527,6 +1856,30 @@ ModResult uninstall() {
|
||||
mods::hook::uninstall<changeScene4Event>(svc_hook);
|
||||
mods::hook::uninstall<stage_playerInit>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<Kytag08_Execute>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<NpcT_chkEvtBit>(svc_hook);
|
||||
mods::hook::uninstall<NpcF_chkEvtBit>(svc_hook);
|
||||
mods::hook::uninstall<daNpcF_c__orderEvent>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daNpc_Bans_c__isDelete>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daNpc_Fairy_c__AppearDemoCall>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daNpcShad_c__Create>(svc_hook);
|
||||
mods::hook::uninstall<daNpcShad_c__wait_type1>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daNpc_Yelia_c__cutTakeWoodStatue>(svc_hook);
|
||||
mods::hook::uninstall<dSv_player_item_c__setWarashibeItem>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daNpc_ykM_c__isDelete>(svc_hook);
|
||||
mods::hook::uninstall<daNpc_ykW_c__isDelete>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daE_MD_c__create>(svc_hook);
|
||||
|
||||
mods::hook::uninstall<daObjMasterSword_c__executeWait>(svc_hook);
|
||||
mods::hook::uninstall<daObjMasterSword_c__execute>(svc_hook);
|
||||
|
||||
return MOD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user