From 6052e667c632b4b22deffa42130a7022c35c9507 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Tue, 25 Nov 2025 00:37:28 -0500 Subject: [PATCH] updateInEvent --- include/d/a/obj/d_a_obj_door.h | 32 +- include/d/a/obj/d_a_obj_fence.h | 10 +- include/d/a/obj/d_a_obj_lock.h | 11 +- include/d/col/bg/d_bg_s_gnd_chk.h | 3 + include/d/d_player_act.h | 3 +- include/d/d_room.h | 3 + include/d/d_stage.h | 1 + include/f/f_base.h | 2 +- include/toBeSorted/actor_event.h | 1 + src/REL/d/a/obj/d_a_obj_door.cpp | 671 ++++++++++++++++++++++++++++-- 10 files changed, 700 insertions(+), 37 deletions(-) diff --git a/include/d/a/obj/d_a_obj_door.h b/include/d/a/obj/d_a_obj_door.h index 1c3eebca..a76dc4dc 100644 --- a/include/d/a/obj/d_a_obj_door.h +++ b/include/d/a/obj/d_a_obj_door.h @@ -36,7 +36,7 @@ public: }; public: - dAcOdoor_c() : mEventRelated(*this, nullptr), mEmmiter0(this), mEmmiter1(this) {} + dAcOdoor_c() : mEventRelated(*this, nullptr), mEmmiterL(this), mEmmiterR(this) {} virtual ~dAcOdoor_c() {} virtual int doDelete() override; @@ -160,7 +160,7 @@ public: void fn_572_4050(u32 flags); // field_0x5A8 = flags /** fn_572_4060 */ - void fn_572_4060(u8); // field_0x5B3 = in + void fn_572_4060(s8); // field_0x5B3 = in /** fn_572_4070 */ void fn_572_4070(s8); // field_0x5B4 = in @@ -250,27 +250,45 @@ public: void playInteractionLocked() const; public: - // defined in main dol + s32 getType() const { + return getFromParams(0, 0x3F); + } + s32 getField_0x5B4() const { + return field_0x5B4; + } + s32 getField_0x5B5() const { + return field_0x5B5; + } + +public: // Functions in this section defined in main dol bool isConnectedToOtherDoor() const; dAcRef_c &getConnectedDoorRef(); // return mConnectedDoor; + /** fn_80194C70 : Rotates the input by this->mRotation.y and adds this->mPosition */ + void stepTowards(mVec3_c &newPosition) const; + private: /* 0x33C */ m3d::smdl_c mMdl0; /* 0x358 */ m3d::smdl_c mMdl1; /* 0x374 */ m3d::mdlAnmChr mAnmChr; /* 0x3DC */ ActorEventRelated mEventRelated; /* 0x42C */ dFlowMgr_c mFlowMgr; - /* 0x4E8 */ dEmitter_c mEmmiter0; - /* 0x51C */ dEmitter_c mEmmiter1; + /* 0x4E8 */ dEmitter_c mEmmiterL; + /* 0x51C */ dEmitter_c mEmmiterR; /* 0x550 */ dTimeBits mTimeBits; /* 0x554 */ dAcRef_c mConnectedDoor; /* 0x560 */ dAcRef_c mLock; /* 0x56C */ dAcRef_c mObjRef; /* 0x578 */ mMtx_c mMtx; - /* 0x5A8 */ u8 _0x584[0x5B1 - 0x5A8]; + /* 0x5A8 */ u8 _0x5A8[0x5AC - 0x5A8]; + /* 0x5AC */ u32 mRumbleIdx; ///< + /* 0x5B0 */ u8 field_0x5B0; ///< some timer to trigger exit /* 0x5B1 */ u8 field_0x5B1; ///< /* 0x5B2 */ u8 mSceneflag; ///< Used for unlocking the door - /* 0x5B3 */ u8 _0x5B3[0x5B7 - 0x5B3]; + /* 0x5B3 */ u8 field_0x5B3; ///< + /* 0x5B4 */ s8 field_0x5B4; + /* 0x5B5 */ s8 field_0x5B5; + /* 0x5B6 */ s8 field_0x5B6; /* 0x5B7 */ bool field_0x5B7; /* 0x5B8 */ u8 _0x5B8[0x5BB - 0x5B8]; /* 0x5BB */ bool field_0x5BB; diff --git a/include/d/a/obj/d_a_obj_fence.h b/include/d/a/obj/d_a_obj_fence.h index 720c41fa..f2127ee2 100644 --- a/include/d/a/obj/d_a_obj_fence.h +++ b/include/d/a/obj/d_a_obj_fence.h @@ -10,6 +10,13 @@ public: dAcOFence_c(); virtual ~dAcOFence_c(); + bool fn_550_11B0() const; + void fn_550_12C0(); + + void changeToRequestConfineEvent() { + mStateMgr.changeState(StateID_RequestConfineEvent); + } + STATE_FUNC_DECLARE(dAcOFence_c, WaitOpen); STATE_FUNC_DECLARE(dAcOFence_c, Open); STATE_FUNC_DECLARE(dAcOFence_c, OpenPocoAPoco); @@ -21,7 +28,8 @@ public: STATE_FUNC_DECLARE(dAcOFence_c, RequestConfineEvent); private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOFence_c); + /* 0x330 */ u8 _0x330[0x368 - 0x330]; + /* 0x368 */ STATE_MGR_DECLARE(dAcOFence_c); }; #endif diff --git a/include/d/a/obj/d_a_obj_lock.h b/include/d/a/obj/d_a_obj_lock.h index 4da6ba02..e332902c 100644 --- a/include/d/a/obj/d_a_obj_lock.h +++ b/include/d/a/obj/d_a_obj_lock.h @@ -12,8 +12,17 @@ public: STATE_FUNC_DECLARE(dAcOLock_c, Wait); + bool checkField_0x2090() const { + return field_0x2090; + } + void setField_0x2090() { + field_0x2090 = true; + } + private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOLock_c); + /* 0x???? */ STATE_MGR_DECLARE(dAcOLock_c); + /* 0x???? */ u8 _0x36C[0x2090 - 0x36C]; + /* 0x2090 */ bool field_0x2090; }; #endif diff --git a/include/d/col/bg/d_bg_s_gnd_chk.h b/include/d/col/bg/d_bg_s_gnd_chk.h index f304c2a3..6b3e2696 100644 --- a/include/d/col/bg/d_bg_s_gnd_chk.h +++ b/include/d/col/bg/d_bg_s_gnd_chk.h @@ -27,6 +27,9 @@ public: static dBgS_ObjGndChk &GetInstance() { return sInstance; } + static dBgS_ObjGndChk *GetPInstance() { + return &sInstance; + } static f32 GetGroundHeight() { return sGroundHeight; } diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index cf1c9236..f3eab389 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -630,7 +630,7 @@ public: bool isAttackingSpinHorizontal() const; bool isAttackingSpinVertical() const; void setBonkRelatedAnimFlag(bool b); - void setPosYRot(const mVec3_c &pos, mAng rot, bool force, UNKWORD, UNKWORD); + void setPosYRot(const mVec3_c &pos, mAng rot, bool force = false, UNKWORD = 0, UNKWORD = 0); void setTransform(const mMtx_c &mtx, bool force, UNKWORD, UNKWORD); bool someTargetedActorCheck() const; static mAng fn_8005BA90(); @@ -646,7 +646,6 @@ public: static const char *getSwordName(s32); static s32 getCurrentlyEquippedShieldType(); - static const mColor &getEarringsColor(); static mVec3_c sPos1; diff --git a/include/d/d_room.h b/include/d/d_room.h index 287ae7c1..225b0bf1 100644 --- a/include/d/d_room.h +++ b/include/d/d_room.h @@ -111,6 +111,9 @@ public: bool checkFlag(u32 flag) { return mFlags & flag; } + void setFlag(u8 flag) { + mFlags |= flag; + } void drawOnMapIfVisible(mMtx_c *mtx, int param); void getBounds(mVec3_c *min, mVec3_c *max) const; diff --git a/include/d/d_stage.h b/include/d/d_stage.h index b0de4c98..2f5a4770 100644 --- a/include/d/d_stage.h +++ b/include/d/d_stage.h @@ -116,6 +116,7 @@ public: int draw() override; void deleteReady() override; + void fn_801B3C60(int roomId); void drawMap(mMtx_c *mtx, int); dRoom_c *getRoom(s32 idx); void setRoom(int roomid, dRoom_c *room); diff --git a/include/f/f_base.h b/include/f/f_base.h index 8ef5ac43..50a5e367 100644 --- a/include/f/f_base.h +++ b/include/f/f_base.h @@ -89,7 +89,7 @@ public: mGroupType = m_tmpCtData.group_type; } - u32 getFromParams(u8 shift, u32 mask) { + u32 getFromParams(u8 shift, u32 mask) const { return (mParams >> shift) & mask; } diff --git a/include/toBeSorted/actor_event.h b/include/toBeSorted/actor_event.h index 03fd30d6..cbd68422 100644 --- a/include/toBeSorted/actor_event.h +++ b/include/toBeSorted/actor_event.h @@ -18,6 +18,7 @@ public: bool isAdvance(); int getSomeEventRelatedNumber(); + int getSingleShortData(int *result, u32 code, u32); int getSingleIntData(int *result, u32 code, u32); int getSingleFloatData(f32 *result, u32 code, u32); int getSingleVecData(mVec3_c *result, u32 code, u32); diff --git a/src/REL/d/a/obj/d_a_obj_door.cpp b/src/REL/d/a/obj/d_a_obj_door.cpp index 1dfaee77..d1cceaa1 100644 --- a/src/REL/d/a/obj/d_a_obj_door.cpp +++ b/src/REL/d/a/obj/d_a_obj_door.cpp @@ -1,16 +1,21 @@ #include "d/a/obj/d_a_obj_door.h" +#include "c/c_lib.h" #include "common.h" #include "d/a/d_a_base.h" +#include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/a/obj/d_a_obj_fence.h" #include "d/a/obj/d_a_obj_lock.h" #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_s_gnd_chk.h" #include "d/col/c/c_m3d_g_aab.h" #include "d/d_room.h" +#include "d/d_rumble.h" #include "d/d_sc_game.h" #include "d/d_stage.h" #include "d/flag/sceneflag_manager.h" +#include "d/snd/d_snd_wzsound.h" #include "egg/math/eggMath.h" #include "f/f_base.h" #include "f/f_manager.h" @@ -20,7 +25,10 @@ #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/math/math_arithmetic.h" +#include "s/s_Math.h" #include "sized_string.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/event_manager.h" SPECIAL_ACTOR_PROFILE(OBJ_DOOR, dAcOdoor_c, fProfile::OBJ_DOOR, 0x188, 0, 7); @@ -51,6 +59,14 @@ DoorFileMapping sDoorMappings[8] = { {8, "DoorH", "DoorH"}, }; +const char *const DoorF = "DoorF"; +const char *const DoorF_Open = "DoorF_Open"; +const char *const DoorF_Close = "DoorF_Close"; +const char *const DoorPull = "DoorPull"; +const char *const DoorPush = "DoorPush"; +const char *const DoorPullLock = "DoorPullLock"; +const char *const DoorPushLock = "DoorPushLock"; + bool getDoorMapping(u32 type, const DoorFileMapping *&filemap) { bool found = false; int i = 0; @@ -87,8 +103,7 @@ bool getDoorMdlName(u32 type, const char *&name) { return found; } -static u8 sDoorUnknown[2] = {0, 1}; - +static const u8 sDoorUnknown[2] = {0, 1}; bool getDoorUnknown(u8 search, u8 &idx) { bool found = false; int i = 0; @@ -167,7 +182,7 @@ bool isInTimeDoorEvent() { return !found; } -bool checkRoom(u8 roomID, bool &b) { +bool checkRoom(s8 roomID, bool &b) { dRoom_c *pRoom = dStage_c::GetInstance()->getRoom(roomID); if (pRoom == nullptr) { return false; @@ -178,8 +193,6 @@ bool checkRoom(u8 roomID, bool &b) { } } // namespace -const char *const DoorF = "DoorF"; -const char *const DoorF_Open = "DoorF_Open"; const char *const DoorE_N = "DoorE_N"; bool dAcOdoor_c::createHeap() { @@ -226,7 +239,7 @@ bool dAcOdoor_c::createHeap() { } if (fn_572_4430()) { - nw4r::g3d::ResMdl resMdl = resFileMdl.GetResMdl(DoorE_N); + nw4r::g3d::ResMdl resMdl = resFileMdl.GetResMdl("DoorE_N"); if (!resMdl.IsValid()) { return false; } @@ -242,8 +255,8 @@ bool dAcOdoor_c::createHeap() { int dAcOdoor_c::actorCreate() { // NONMATCHING - Regalloc issues - s32 subtype = getFromParams(0, 0x3F); - mSubtype = subtype; + s32 subtype = getType(); + mSubtype = getType(); changeLoadedEntitiesWithSet(); if (subtype == SUBTYPE_5 && !dScGame_c::isCurrentStage("B301") && !dScGame_c::isCurrentStage("D301_1")) { @@ -296,7 +309,7 @@ int dAcOdoor_c::actorCreate() { fn_572_40A0(); } - if ((s32)getFromParams(0, 0x3F) == SUBTYPE_7) { + if (getType() == SUBTYPE_7) { mAnmChr.setAnm(DoorF_Open, m3d::PLAY_MODE_4, 0.f); mAnmChr.setFrame(mAnmChr.getAnm().getStartFrame()); mAnmChr.getModel().setPriorityDraw(0x1C, 0); @@ -324,7 +337,7 @@ extern "C" void fn_80067290(dTimeBits *pBits, s32 roomId, const mVec3_c &pos, f3 int dAcOdoor_c::actorPostCreate() { if (field_0x5B7) { - if (true) { + if (!isConnectedToOtherDoor()) { bool foundPair = false; dAcOdoor_c *pDoor = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_DOOR, nullptr)); @@ -353,10 +366,14 @@ int dAcOdoor_c::actorPostCreate() { fn_572_40B0(); } - bool gndChk = dBgS_ObjGndChk::CheckPos(mPosition + mVec3_c::Ey * 10.f); + mVec3_c pos = mPosition + mVec3_c::Ey * 10.f; + bool gndChk = dBgS_ObjGndChk::CheckPos(pos); + dBgS_ObjGndChk *objGndCheck = dBgS_ObjGndChk::GetPInstance(); if (gndChk) { mLightingInfo.mLightingCode = dBgS_ObjGndChk::GetLightingCode(); - setPolyAttrs(dBgS_ObjGndChk::GetInstance()); + if (objGndCheck != nullptr) { + setPolyAttrs(*objGndCheck); + } } if (isInOuterSandship()) { @@ -365,12 +382,12 @@ int dAcOdoor_c::actorPostCreate() { if (gndChk) { dBgS *pBgS = dBgS::GetInstance(); - if (pBgS != nullptr) { - const dAcObjBase_c *pObj = pBgS->GetActorPointer(dBgS_ObjGndChk::GetInstance()); + if (pBgS != nullptr && objGndCheck != nullptr) { + const dAcObjBase_c *pObj = pBgS->GetActorPointer(*objGndCheck); if (pObj) { mObjRef.link(const_cast(pObj)); - mVec3_c v(mPosition - pObj->mPosition); - v.y = dBgS_ObjGndChk::GetGroundHeight() - pObj->mPosition.y; + mVec3_c v(mPosition.x, dBgS_ObjGndChk::GetGroundHeight(), mPosition.z); + v -= pObj->mPosition; v.rotY(-pObj->mRotation.y); @@ -383,7 +400,7 @@ int dAcOdoor_c::actorPostCreate() { } if (!mObjRef.isLinked()) { - s32 type = getFromParams(0, 0x3F); + s32 type = getType(); updateMatrix(); mAnmChr.getModel().setLocalMtx(mWorldMtx); mAnmChr.getModel().calc(false); @@ -405,27 +422,79 @@ int dAcOdoor_c::actorPostCreate() { mPositionCopy2.set(pLock->mPosition); mPositionCopy3.set(pLock->mPosition); } - mVec3_c max(999999.f, 999999.f, 999999.f); - mVec3_c min(-999999.f, -999999.f, -999999.f); + + mVec3_c min, max; + min.set(999999.f, 999999.f, 999999.f); + max.set(-999999.f, -999999.f, -999999.f); if (type == SUBTYPE_7) { mAnmChr.getModel().getBounds(&min, &max); } else { + mVec3_c min_l, max_l; mMtx_c local; - mMdl0.getBounds(&min, &max); + mMdl0.getBounds(&min_l, &max_l); mMdl0.getLocalMtx(local); mMtx_c world = mWorldMtx; world.inverse(); - mVec3_c minPos = min; + mVec3_c minPos = min_l; local.multVec(minPos, minPos); world.multVec(minPos, minPos); - // ... + // clang-format off + min.set( + nw4r::ut::Min(minPos.x, min.x), + nw4r::ut::Min(minPos.y, min.y), + nw4r::ut::Min(minPos.z, min.z) + ); + max.set( + nw4r::ut::Max(minPos.x, max.x), + nw4r::ut::Max(minPos.y, max.y), + nw4r::ut::Max(minPos.z, max.z) + ); + // clang-format on - mBoundingBox.Set(min, max); + mVec3_c maxPos = max_l; + local.multVec(maxPos, maxPos); + world.multVec(maxPos, maxPos); + // clang-format off + min.set( + nw4r::ut::Min(maxPos.x, min.x), + nw4r::ut::Min(maxPos.y, min.y), + nw4r::ut::Min(maxPos.z, min.z) + ); + max.set( + nw4r::ut::Max(maxPos.x, max.x), + nw4r::ut::Max(maxPos.y, max.y), + nw4r::ut::Max(maxPos.z, max.z) + ); + // clang-format on + + mVec3_c vecs[6] = { + mVec3_c(min_l.x, min_l.y, max_l.z), mVec3_c(min_l.x, max_l.y, min_l.z), + mVec3_c(min_l.x, max_l.y, max_l.z), mVec3_c(max_l.x, min_l.y, min_l.z), + mVec3_c(max_l.x, min_l.y, max_l.z), mVec3_c(max_l.x, max_l.y, min_l.z), + }; + + for (int i = 0, j = 0; i < (int)ARRAY_LENGTH(vecs); i++, j++) { + local.multVec(vecs[i], vecs[j]); + world.multVec(vecs[i], vecs[j]); + // clang-format off + min.set( + nw4r::ut::Min(vecs[j].x, min.x), + nw4r::ut::Min(vecs[j].y, min.y), + nw4r::ut::Min(vecs[j].z, min.z) + ); + max.set( + nw4r::ut::Max(vecs[j].x, max.x), + nw4r::ut::Max(vecs[j].y, max.y), + nw4r::ut::Max(vecs[j].z, max.z) + ); + // clang-format on + } } + mBoundingBox.Set(min, max); } if (fn_572_4430()) { @@ -442,7 +511,559 @@ int dAcOdoor_c::doDelete() { return SUCCEEDED; } -int dAcOdoor_c::actorExecuteInEvent() {} +int dAcOdoor_c::actorExecuteInEvent() { + if (fn_572_4430()) { + fn_80067290(&mTimeBits, mRoomID, mPosition, 200.f); + } + + if (mEventRelated.isAdvance()) { + field_0x5B6 = 0; + } else if (field_0x5B6 < 0xFF) { + field_0x5B6++; + } + + if (fn_572_40E0()) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + + switch (field_0x5B3) { + case 0: { + bool b; + checkRoom(mRoomID, b); + if (b) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + } break; + case 1: { + bool b; + fn_572_4150(b); + if (b) { + setObjectProperty(OBJ_PROP_0x200); + return SUCCEEDED; + } + } break; + } + + unsetObjectProperty(OBJ_PROP_0x200); + s32 type = getType(); + + static mVec3_c v1(0.f, 0.f, 70.f); + static mVec3_c v2(0.f, 0.f, -70.f); + + f32 frame0 = -1.f; + f32 frame1 = -1.f; + + switch (mEventRelated.getCurrentEventCommand()) { + case 'pllB': { + f32 frame = dAcPy_c::GetLink()->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + mAnmChr.setAnm(DoorAnimPull, m3d::PLAY_MODE_4); + mAnmChr.setFrame(frame); + field_0x5B0 = 45; + + frame0 = frame; + if (field_0x5B3 == s8(1)) { + fn_572_4340(); + } + } else { + frame0 = mAnmChr.getAnm().getFrame(); + } + mAnmChr.setFrame(frame); + frame1 = mAnmChr.getAnm().getFrame(); + bool old_time = 0 == field_0x5B0; + bool new_time = 0 == sLib::calcTimer(&field_0x5B0); + switch (field_0x5B3) { + case 0: { + if (!old_time && new_time) { + triggerExit(); + } + } break; + case 1: { + if (new_time) { + mEventRelated.advanceNext(); + } + } break; + } + } break; + case 'pllE': { + bool isStop; + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + f32 frame = pPlayer->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + isStop = false; + switch (field_0x5B3) { + case 0: { + frame0 = frame; + } break; + case 1: { + frame0 = mAnmChr.getAnm().getFrame(); + } break; + } + mAnmChr.setAnm(DoorAnimPull, m3d::PLAY_MODE_4); + mAnmChr.setFrame(frame); + } else { + isStop = mAnmChr.getAnm().isStop(); + frame0 = mAnmChr.getAnm().getFrame(); + + if (!isStop) { + mAnmChr.setFrame(frame); + } + } + bool postStop = mAnmChr.getAnm().isStop(); + frame1 = mAnmChr.getAnm().getFrame(); + if (!isStop && postStop) { + if (field_0x5B3 == 1 && getField_0x5B4() != getField_0x5B5()) { + dRoom_c *pRoom = dStage_c::GetInstance()->getRoom(getField_0x5B4()); + if (pRoom != nullptr) { + pRoom->setFlag(0x4); + dStage_c::GetInstance()->fn_801B3C60(getField_0x5B5()); + } + } + mEventRelated.advanceNext(); + + bool search = true; + dAcOFence_c *pFence = + static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, nullptr)); + while (search && pFence != nullptr) { + if (mAng::abs(pPlayer->mRotation.y - pFence->mRotation.y) < 0x4000) { + const mVec3_c &posFence = pFence->mPosition; + const mVec3_c &position = mPosition; + if (posFence.squareDistanceToXZ(position) < 22500.f && + nw4r::math::FAbs(posFence.y - position.y) < 500.f) { + search = false; + continue; + } + } + pFence = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, pFence)); + } + + if (!search) { + if (pFence->fn_550_11B0()) { + pFence->changeToRequestConfineEvent(); + } + pFence->fn_550_12C0(); + } + + if (mLock.get() != nullptr) { + mLock.get()->deleteRequest(); + } + } + } break; + case 'pshB': { + f32 frame = dAcPy_c::GetLink()->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + if (type == SUBTYPE_7) { + mAnmChr.setAnm(DoorF_Open, m3d::PLAY_MODE_4); + field_0x5B0 = 120; + } else { + mAnmChr.setAnm(DoorAnimPush, m3d::PLAY_MODE_4); + field_0x5B0 = 45; + } + if (field_0x5B3 == s8(1)) { + transitionPushRoomFlags(); + } + frame0 = frame; + } else { + frame0 = mAnmChr.getAnm().getFrame(); + } + mAnmChr.setFrame(frame); + frame1 = mAnmChr.getAnm().getFrame(); + bool old_time = 0 == field_0x5B0; + bool new_time = 0 == sLib::calcTimer(&field_0x5B0); + switch (field_0x5B3) { + case 0: { + if (!old_time && new_time) { + triggerExit(); + } + } break; + case 1: { + if (new_time) { + mEventRelated.advanceNext(); + } + } break; + } + } break; + case 'pshE': { + bool isStop; + f32 frame = dAcPy_c::GetLink()->getCurrentAnimFrame(); + if (mEventRelated.isAdvance()) { + isStop = false; + switch (field_0x5B3) { + case 0: { + frame0 = frame; + } break; + case 1: { + frame0 = mAnmChr.getAnm().getFrame(); + } break; + } + if (type == SUBTYPE_7) { + mAnmChr.setAnm(DoorF_Close, m3d::PLAY_MODE_4); + } else { + mAnmChr.setAnm(DoorAnimPush, m3d::PLAY_MODE_4); + } + mAnmChr.setFrame(frame); + } else { + isStop = mAnmChr.getAnm().isStop(); + frame0 = mAnmChr.getAnm().getFrame(); + if (!isStop) { + mAnmChr.setFrame(frame); + } + } + bool stop = mAnmChr.getAnm().isStop(); + frame1 = mAnmChr.getAnm().getFrame(); + if (!isStop && stop) { + if (field_0x5B3 == 1 && getField_0x5B4() != getField_0x5B5()) { + dRoom_c *pRoom = dStage_c::GetInstance()->getRoom(getField_0x5B5()); + if (pRoom != nullptr) { + pRoom->setFlag(0x1); + dStage_c::GetInstance()->fn_801B3C60(getField_0x5B4()); + } + } + mEventRelated.advanceNext(); + + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + + bool search = true; + dAcOFence_c *pFence = + static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, nullptr)); + while (search && pFence != nullptr) { + if (mAng::abs(pPlayer->mRotation.y - pFence->mRotation.y) < 0x4000) { + const mVec3_c &posFence = pFence->mPosition; + const mVec3_c &position = mPosition; + if (posFence.squareDistanceToXZ(position) < 22500.f && + nw4r::math::FAbs(posFence.y - position.y) < 500.f) { + search = false; + continue; + } + } + pFence = static_cast(fManager_c::searchBaseByProfName(fProfile::OBJ_FENCE, pFence)); + } + + if (!search) { + if (pFence->fn_550_11B0()) { + pFence->changeToRequestConfineEvent(); + } + pFence->fn_550_12C0(); + } + + if (mLock.get() != nullptr) { + mLock.get()->deleteRequest(); + } + + if (type == SUBTYPE_7) { + bool b; + if (frame0 == frame1) { + b = frame0 == 55.f; + } else { + b = frame0 < 55.f && 55.f <= frame1; + } + if (b) { + dRumble_c::start(dRumble_c::sRumblePreset5, dRumble_c::FLAG_SLOT0); + } + } + } + } break; + case 'wait': { + mEventRelated.advanceNext(); + } break; + case 'tktn': { + mEventRelated.advanceNext(); + } break; + case 'tkwt': { + mEventRelated.advanceNext(); + } break; + case 'tked': { + mEventRelated.advanceNext(); + } break; + case 'cAna': { + mVec3_c pos; + int rot; + if (type == SUBTYPE_7) { + pos.set(0.f, 0.f, 85.f); + rot = mRotation.y - 0x8000; + } else { + int dir; + mEventRelated.getSingleShortData(&dir, 'dir ', 0); + if (dir == 0) { + pos.set(v1); + rot = mRotation.y - 0x8000; + } else { + pos.set(v2); + rot = mRotation.y; + } + } + stepTowards(pos); + dAcPy_c *pPlayer = dAcPy_c::GetLinkM(); + + if (field_0x5B6 > 0x1E) { + pPlayer->setPosYRot(pos, rot); + mEventRelated.advanceNext(); + } else { + mVec3_c tmp = pPlayer->mPosition; + cLib::addCalcPos(&tmp, pos, 0.25f, 200.f, 0.f); + + mAng ang = pPlayer->mRotation.y; + sLib::addCalcAngle(ang.ref(), rot, 4, 0x7FFF, 0); + + if (pos.squareDistanceToXZ(tmp) < 25.f && mAng(ang - mAng(rot)).abs() < 182) { + pPlayer->setPosYRot(pos, rot); + mEventRelated.advanceNext(); + } else { + pPlayer->setPosYRot(pos, ang); + } + } + } break; + case 'cDeg': { + mVec3_c pos; + mAng rot; + if (mEventRelated.isAdvance()) { + if (type == SUBTYPE_7) { + pos.set(0.f, 0.f, 90.f); + rot = mRotation.y; + } else { + int dir; + mEventRelated.getSingleShortData(&dir, 'dir ', 0); + if (dir == 0) { + pos.set(v1); + rot = mRotation.y - 0x8000; + } else { + pos.set(v2); + rot = mRotation.y; + } + } + stepTowards(pos); + dAcPy_c *pPlayer = dAcPy_c::GetLinkM(); + pPlayer->setPosYRot(pos, rot); + mEventRelated.advanceNext(); + } + } break; + case 'talk': + case 'lock': { + if (mEventRelated.isAdvance()) { + s32 flow = mLock.get() == nullptr ? mParams >> 16 : 4001; + s32 part2 = flow < 10000U ? 1000 : 100; + s32 truncate = (flow / part2); + + u16 lower = flow - truncate * part2; + + s32 part1 = flow < 10000U ? 1000 : 100; + u16 upper = flow / part1; + mFlowMgr.triggerEntryPoint(upper, lower, 0, 0); + } + if (mFlowMgr.checkFinished()) { + mEventRelated.advanceNext(); + } + } break; + case 'unlk': { + dAcOLock_c *pLock = mLock.get(); + if (pLock == nullptr) { + mEventRelated.advanceNext(); + } else { + if (mEventRelated.isAdvance()) { + pLock->setField_0x2090(); + fn_572_4440(); + } + if (pLock->checkField_0x2090()) { + mEventRelated.advanceNext(); + } + } + } break; + default: { + mEventRelated.advanceNext(); + } + case '????': { + } break; + } + + dAcObjBase_c *pObj = mObjRef.get(); + if (pObj != nullptr) { + mMtx_c m = pObj->mWorldMtx; + m += mWorldMtx; + mWorldMtx = m; + mAnmChr.getModel().setLocalMtx(mWorldMtx); + } + + mAnmChr.getModel().calc(false); + + if (type != SUBTYPE_7) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(1, nodeMtx); + nodeMtx.transM(sVecs[0]); + mMdl0.setLocalMtx(nodeMtx); + if (fn_572_4430()) { + mMdl1.setLocalMtx(nodeMtx); + } + } + + if (pObj != nullptr) { + mVec3_c min, max; + min.set(999999.f, 999999.f, 999999.f); + max.set(-999999.f, -999999.f, -999999.f); + + if (type == SUBTYPE_7) { + mAnmChr.getModel().getBounds(&min, &max); + } else { + mVec3_c min_l, max_l; + mMtx_c local; + mMdl0.getBounds(&min_l, &max_l); + mMdl0.getLocalMtx(local); + + mMtx_c world = mWorldMtx; + world.inverse(); + + mVec3_c minPos = min_l; + local.multVec(minPos, minPos); + world.multVec(minPos, minPos); + + // clang-format off + min.set( + nw4r::ut::Min(minPos.x, min.x), + nw4r::ut::Min(minPos.y, min.y), + nw4r::ut::Min(minPos.z, min.z) + ); + max.set( + nw4r::ut::Max(minPos.x, max.x), + nw4r::ut::Max(minPos.y, max.y), + nw4r::ut::Max(minPos.z, max.z) + ); + // clang-format on + + mVec3_c maxPos = max_l; + local.multVec(maxPos, maxPos); + world.multVec(maxPos, maxPos); + // clang-format off + min.set( + nw4r::ut::Min(maxPos.x, min.x), + nw4r::ut::Min(maxPos.y, min.y), + nw4r::ut::Min(maxPos.z, min.z) + ); + max.set( + nw4r::ut::Max(maxPos.x, max.x), + nw4r::ut::Max(maxPos.y, max.y), + nw4r::ut::Max(maxPos.z, max.z) + ); + // clang-format on + + mVec3_c vecs[6] = { + mVec3_c(min_l.x, min_l.y, max_l.z), mVec3_c(min_l.x, max_l.y, min_l.z), + mVec3_c(min_l.x, max_l.y, max_l.z), mVec3_c(max_l.x, min_l.y, min_l.z), + mVec3_c(max_l.x, min_l.y, max_l.z), mVec3_c(max_l.x, max_l.y, min_l.z), + }; + + for (int i = 0, j = 0; i < (int)ARRAY_LENGTH(vecs); j++, i++) { + local.multVec(vecs[i], vecs[j]); + world.multVec(vecs[i], vecs[j]); + // clang-format off + min.set( + nw4r::ut::Min(vecs[j].x, min.x), + nw4r::ut::Min(vecs[j].y, min.y), + nw4r::ut::Min(vecs[j].z, min.z) + ); + max.set( + nw4r::ut::Max(vecs[j].x, max.x), + nw4r::ut::Max(vecs[j].y, max.y), + nw4r::ut::Max(vecs[j].z, max.z) + ); + // clang-format on + } + } + mBoundingBox.Set(min, max); + } + + if (mEmmiterL.hasEmitters()) { + int node = mAnmChr.getModel().getNodeID("DoorF_L"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterL.setTransform(nodeMtx); + } + } + if (mEmmiterL.hasEmitters()) { + int node = mAnmChr.getModel().getNodeID("DoorF_R"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterR.setTransform(nodeMtx); + } + } + + switch (mEventRelated.getCurrentEventCommand()) { + case 'pshB': { + if (mEventRelated.isAdvance() && type == SUBTYPE_7) { + int node; + node = mAnmChr.getModel().getNodeID("DoorF_L"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterL.startEffect(PARTICLE_RESOURCE_ID_MAPPING_935_, nodeMtx, nullptr, nullptr); + } + node = mAnmChr.getModel().getNodeID("DoorF_R"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterR.startEffect(PARTICLE_RESOURCE_ID_MAPPING_936_, nodeMtx, nullptr, nullptr); + } + } + } break; + case 'pshE': { + if (mEventRelated.isAdvance() && type == SUBTYPE_7) { + int node; + node = mAnmChr.getModel().getNodeID("DoorF_L"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterL.startEffect(PARTICLE_RESOURCE_ID_MAPPING_933_, nodeMtx, nullptr, nullptr); + } + node = mAnmChr.getModel().getNodeID("DoorF_R"); + if (node >= 0) { + mMtx_c nodeMtx; + mAnmChr.getModel().getNodeWorldMtx(node, nodeMtx); + mEmmiterR.startEffect(PARTICLE_RESOURCE_ID_MAPPING_934_, nodeMtx, nullptr, nullptr); + } + } + } break; + } + + if (type != SUBTYPE_7) { + bool b; + if (frame0 == frame1) { + b = frame0 == 16.f; + } else { + b = frame0 < 16.f && 16.f <= frame1; + } + if (b) { + startSound(SE_Door_W_OPEN); + } + } + + if (type != SUBTYPE_7) { + bool b; + if (frame0 == frame1) { + b = frame0 == 60.f; + } else { + b = frame0 < 60.f && 60.f <= frame1; + } + if (b) { + startSound(SE_Door_W_CLOSE); + } + } + + if (mEventRelated.getCurrentEventCommand() == 'pshB' && type == SUBTYPE_7) { + if (frame0 < 50.f && 50.f <= frame1) { + // ?? + if (&dRumble_c::sRumblePreset3) { + mRumbleIdx = + dRumble_c::start(dRumble_c::sRumblePreset3, dRumble_c::FLAG_SLOT0 | dRumble_c::FLAG_INITIALIZE); + } + } + if (frame0 <= 115.f && 115.f < frame0) { + dRumble_c::stop(mRumbleIdx); + } + } + return SUCCEEDED; +} int dAcOdoor_c::actorExecute() {} @@ -568,7 +1189,7 @@ void dAcOdoor_c::setRoomId(s8 roomId) {} // mRoomId = roomId; void dAcOdoor_c::fn_572_4050(u32 flags) {} // field_0x5A8 = flags /** fn_572_4060 */ -void dAcOdoor_c::fn_572_4060(u8) {} // field_0x5B3 = in +void dAcOdoor_c::fn_572_4060(s8) {} // field_0x5B3 = in /** fn_572_4070 */ void dAcOdoor_c::fn_572_4070(s8) {} // field_0x5B4 = in