diff --git a/config/SOUE01/rels/d_a_obj_warp_holeNP/symbols.txt b/config/SOUE01/rels/d_a_obj_warp_holeNP/symbols.txt index 60e8abc3..a60ea418 100644 --- a/config/SOUE01/rels/d_a_obj_warp_holeNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_warp_holeNP/symbols.txt @@ -2,21 +2,21 @@ _prolog = .text:0x00000000; // type:function size:0x2C scope:global _epilog = .text:0x00000030; // type:function size:0x2C scope:global _unresolved = .text:0x00000060; // type:function size:0x4 scope:global dAcOwarpHole_c_classInit__Fv = .text:0x00000070; // type:function size:0x6C -fn_619_E0 = .text:0x000000E0; // type:function size:0x8 -AcOwarpHole__init = .text:0x000000F0; // type:function size:0xF8 -fn_619_1F0 = .text:0x000001F0; // type:function size:0x8 -AcOwarpHole__update = .text:0x00000200; // type:function size:0xDC -AcOwarpHole__updateInEvent = .text:0x000002E0; // type:function size:0x350 -fn_619_630 = .text:0x00000630; // type:function size:0x8 +createHeap__14dAcOwarpHole_cFv = .text:0x000000E0; // type:function size:0x8 +create__14dAcOwarpHole_cFv = .text:0x000000F0; // type:function size:0xF8 +doDelete__14dAcOwarpHole_cFv = .text:0x000001F0; // type:function size:0x8 +actorExecute__14dAcOwarpHole_cFv = .text:0x00000200; // type:function size:0xDC +actorExecuteInEvent__14dAcOwarpHole_cFv = .text:0x000002E0; // type:function size:0x350 +draw__14dAcOwarpHole_cFv = .text:0x00000630; // type:function size:0x8 __dt__14dAcOwarpHole_cFv = .text:0x00000640; // type:function size:0x80 _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global -lbl_619_rodata_0 = .rodata:0x00000000; // type:object size:0x4 data:float -lbl_619_rodata_4 = .rodata:0x00000004; // type:object size:0x4 align:4 data:float -lbl_619_rodata_8 = .rodata:0x00000008; // type:object size:0x10 align:4 data:float +dummy600__14dAcOwarpHole_c = .rodata:0x00000000; // type:object size:0x4 data:float +@24817 = .rodata:0x00000004; // type:object size:0x4 scope:local align:4 data:float +@24840 = .rodata:0x00000008; // type:object size:0x10 scope:local align:4 data:float g_profile_OBJ_WARP_HOLE = .data:0x00000000; // type:object size:0x10 -lbl_619_data_10 = .data:0x00000010; // type:object size:0x30 -lbl_619_data_40 = .data:0x00000040; // type:object size:0x1C data:string -lbl_619_data_5C = .data:0x0000005C; // type:object size:0x1C -lbl_619_data_78 = .data:0x00000078; // type:object size:0x20 -AcOwarpHole__vtable = .data:0x00000098; // type:object size:0x80 +sCylSrc__14dAcOwarpHole_c = .data:0x00000010; // type:object size:0x30 +@24816 = .data:0x00000040; // type:object size:0x1C scope:local data:string +@24841 = .data:0x0000005C; // type:object size:0x19 scope:local align:4 data:string +@24908 = .data:0x00000078; // type:object size:0x1C scope:local align:8 data:string +__vt__14dAcOwarpHole_c = .data:0x00000098; // type:object size:0x80 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index ff5d9b53..f1ea4879 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -1290,7 +1290,7 @@ ActorLink__setObjActorFlags0x200 = .text:0x800346B0; // type:function size:0x14 ActorLink__unsetObjActorFlags0x200 = .text:0x800346D0; // type:function size:0x14 fn_800346F0 = .text:0x800346F0; // type:function size:0xDC vt_0x2AC__17daPlayerActBase_cFv = .text:0x800347D0; // type:function size:0x4 -triggerMoveEventMaybe__17daPlayerActBase_cFv = .text:0x800347E0; // type:function size:0x4 +triggerMoveEventMaybe__17daPlayerActBase_cFUlUlUlR7mVec3_cRC4mAngUlUl = .text:0x800347E0; // type:function size:0x4 vt_0x2C4__17daPlayerActBase_cFv = .text:0x800347F0; // type:function size:0x8 fn_80034800 = .text:0x80034800; // type:function size:0x170 fn_80034970 = .text:0x80034970; // type:function size:0xFC diff --git a/configure.py b/configure.py index 4c8acef2..20c59ade 100644 --- a/configure.py +++ b/configure.py @@ -2825,7 +2825,7 @@ config.libs = [ Rel(NonMatching, "d_a_obj_vent_fan", "REL/d/a/obj/d_a_obj_vent_fan.cpp"), Rel(NonMatching, "d_a_obj_vortex", "REL/d/a/obj/d_a_obj_vortex.cpp"), Rel(NonMatching, "d_a_obj_warp", "REL/d/a/obj/d_a_obj_warp.cpp"), - Rel(NonMatching, "d_a_obj_warp_hole", "REL/d/a/obj/d_a_obj_warp_hole.cpp"), + Rel(Matching, "d_a_obj_warp_hole", "REL/d/a/obj/d_a_obj_warp_hole.cpp"), Rel( NonMatching, "d_a_obj_waterfall_D100", "REL/d/a/obj/d_a_obj_waterfall_D100.cpp" ), diff --git a/include/d/a/npc/d_a_npc_kensei.h b/include/d/a/npc/d_a_npc_kensei.h index 2d2c77eb..292f8e31 100644 --- a/include/d/a/npc/d_a_npc_kensei.h +++ b/include/d/a/npc/d_a_npc_kensei.h @@ -10,8 +10,16 @@ public: dAcNpcKensei_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcNpcKensei_c() {} + static dAcNpcKensei_c* GetInstance() { + return sInstance; + } + private: + static dAcNpcKensei_c *sInstance; + /* 0x??? */ STATE_MGR_DECLARE(dAcNpcKensei_c); }; + + #endif diff --git a/include/d/a/obj/d_a_obj_warp_hole.h b/include/d/a/obj/d_a_obj_warp_hole.h index 1df439af..4defe361 100644 --- a/include/d/a/obj/d_a_obj_warp_hole.h +++ b/include/d/a/obj/d_a_obj_warp_hole.h @@ -2,13 +2,33 @@ #define D_A_OBJ_WARP_HOLE_H #include "d/a/obj/d_a_obj_base.h" +#include "d/col/cc/d_cc_d.h" +#include "toBeSorted/actor_event.h" +#include "toBeSorted/d_emitter.h" class dAcOwarpHole_c : public dAcObjBase_c { public: - dAcOwarpHole_c() {} + dAcOwarpHole_c() : mEvent(*this, nullptr) {} virtual ~dAcOwarpHole_c() {} + virtual bool createHeap() override; + virtual int create() override; + + virtual int doDelete() override; + virtual int actorExecute() override; + virtual int actorExecuteInEvent() override; + virtual int draw() override; + private: + /* 0x330 */ dCcD_Cyl mCcCyl; + /* 0x480 */ EffectsStruct mEff; + /* 0x4B4 */ ActorEventRelated mEvent; + /* 0x504 */ mVec3_c mLinkPos; + /* 0x510 */ u8 mExitListIdx; + /* 0x511 */ u8 mWalkFramesMaybe; + + static dCcD_SrcCyl sCylSrc; + static const float dummy600; }; #endif diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index b06ba8fa..c5096561 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -412,7 +412,7 @@ public: /* vt 0x2A8 */ virtual void lookTowardItem() {} /* vt 0x2AC */ virtual void vt_0x2AC() {} /* vt 0x2B0 */ virtual void vt_0x2B0() {} - /* vt 0x2B4 */ virtual void triggerMoveEventMaybe() {} + /* vt 0x2B4 */ virtual void triggerMoveEventMaybe(u32, u32, u32, mVec3_c &, const mAng&, u32, u32) {} /* vt 0x2B8 */ virtual void setActorRef9() {} /* vt 0x2BC */ virtual void unlinkActorRef9() {} /* vt 0x2C0 */ virtual bool vt_0x2C0() { diff --git a/src/REL/d/a/obj/d_a_obj_warp_hole.cpp b/src/REL/d/a/obj/d_a_obj_warp_hole.cpp index 958f7d87..5babbb42 100644 --- a/src/REL/d/a/obj/d_a_obj_warp_hole.cpp +++ b/src/REL/d/a/obj/d_a_obj_warp_hole.cpp @@ -1,3 +1,127 @@ #include "d/a/obj/d_a_obj_warp_hole.h" +#include "c/c_lib.h" +#include "d/a/d_a_player.h" +#include "d/a/npc/d_a_npc_talk_kensei.h" +#include "d/col/cc/d_cc_s.h" +#include "d/d_sc_game.h" +#include "d/snd/d_snd_wzsound.h" +#include "toBeSorted/event_manager.h" + SPECIAL_ACTOR_PROFILE(OBJ_WARP_HOLE, dAcOwarpHole_c, fProfile::OBJ_WARP_HOLE, 0x25C, 0, 0); + +dCcD_SrcCyl dAcOwarpHole_c::sCylSrc = { + /* mObjInf */ + {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ + {~(AT_TYPE_BUGNET | AT_TYPE_0x80000 | AT_TYPE_BEETLE | AT_TYPE_WIND | AT_TYPE_0x8000), 0x111, {0, 0, 0x407}, 0, 0}, + /* mObjCo */ {0x29}}, + /* mCylInf */ + {320.f, 300.f} +}; + +// Unused(?) 600.0f float at start of rodata +const float dAcOwarpHole_c::dummy600 = 600.0f; + +bool dAcOwarpHole_c::createHeap() { + return true; +} + +int dAcOwarpHole_c::create() { + mExitListIdx = mParams; + CREATE_ALLOCATOR(dAcOwarpHole_c); + mStts.SetRank(0xD); + mCcCyl.Set(sCylSrc); + mCcCyl.SetStts(mStts); + dCcS::GetInstance()->Set(&mCcCyl); + mCcCyl.OnCoSet(); + mCcCyl.ClrTgSet(); + mLinkPos = dAcPy_c::GetLink()->mPosition; + mEff.init(this); + mWalkFramesMaybe = 0; + mPositionCopy2.set(mPosition.x, mPosition.y + 170.0f, mPosition.z); + mPositionCopy3 = mPositionCopy2; + + return SUCCEEDED; +} + +int dAcOwarpHole_c::doDelete() { + return SUCCEEDED; +} + +int dAcOwarpHole_c::actorExecute() { + if (!dAcPy_c::GetLink()->checkObjectProperty(0x200) && getDistanceTo(dAcPy_c::GetLinkM()->mPosition) < 600.0f) { + Event ev = Event("BeforeLastBossBattleTalk", 100, 0x100001, nullptr, nullptr); + EventManager::alsoSetAsCurrentEvent(dAcNpcTalkKensei_c::GetInstance(), &ev, nullptr); + } + + dCcS::GetInstance()->Set(&mCcCyl); + updateMatrix(); + mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_914_, mWorldMtx, nullptr, nullptr); + holdSound(SE_WarpH_Wait); + + return SUCCEEDED; +} + +// copy from d_a_obj_fairy - TODO move it to a shared file +inline static void vecCylCalc(mVec3_c &target, const mAng &rot, f32 factor) { + target.x += factor * rot.sin(); + target.z += factor * rot.cos(); +} + +int dAcOwarpHole_c::actorExecuteInEvent() { + mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_914_, mWorldMtx, nullptr, nullptr); + holdSound(SE_WarpH_Wait); + int retVal = NOT_READY; + bool advance = mEvent.isAdvance(); + mPositionCopy2.set(mPosition.x, mPosition.y + 170.0f, mPosition.z); + + switch (mEvent.getCurrentEventCommand()) { + case 'none': + mEvent.advanceNext(); + retVal = SUCCEEDED; + break; + case 'plwk': + if (advance) { + dAcPy_c *link = dAcPy_c::GetLinkM(); + mLinkPos = link->mPosition; + vecCylCalc(mLinkPos,cLib::targetAngleY(mPosition, link->mPosition), 330.0f); + } + if (EventManager::isInEvent()) { + if (EventManager::isCurrentEvent("BeforeLastBossBattleChicken")) { + dAcPy_c* player = dAcPy_c::GetLinkM(); + player->vt_0x2AC(); + player->triggerMoveEventMaybe(2, 0, 0, mLinkPos, 0, 0, 0); + } + } + if (dAcPy_c::GetLinkM()->mPosition.absXZTo(mLinkPos) < 10.0f) { + mEvent.advanceNext(); + } + retVal = SUCCEEDED; + break; + case 'warp': + if (advance) { + dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_916_, mWorldMtx, nullptr, nullptr, 0, 0); + mWalkFramesMaybe = 80; + } + if (mWalkFramesMaybe != 0) { + mWalkFramesMaybe -= 1; + } + if (mWalkFramesMaybe == 77) { + dAcPy_c::GetLinkM()->setObjectProperty(OBJ_PROP_0x200); + } + if (mWalkFramesMaybe == 20) { + dScGame_c::GetInstance()->triggerExit(mRoomID, mExitListIdx); + } + if (mWalkFramesMaybe == 0) { + mEvent.advanceNext(); + } + retVal = SUCCEEDED; + } + + return retVal; +} + +int dAcOwarpHole_c::draw() { + return SUCCEEDED; +}