diff options
| author | Elijah Thomas <42302100+elijah-thomas774@users.noreply.github.com> | 2025-05-25 15:51:35 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-25 15:51:35 -0400 |
| commit | fd7d30d32283d03a412e8c401d04418351cf686a (patch) | |
| tree | e88bed25f474f06552cd7a7ea7067a0beead4414 /src | |
| parent | 018ef1971cd53aa8e78154789bcf6cac2f19b603 (diff) | |
d_linkage is largely done (#176)
Diffstat (limited to 'src')
| -rw-r--r-- | src/REL/d/a/e/d_a_e_sm.cpp | 3 | ||||
| -rw-r--r-- | src/REL/d/a/obj/d_a_obj_ring.cpp | 14 | ||||
| -rw-r--r-- | src/REL/d/a/obj/d_a_obj_tubo.cpp | 48 | ||||
| -rw-r--r-- | src/d/a/obj/d_a_obj_arrow.cpp | 5 | ||||
| -rw-r--r-- | src/d/a/obj/d_a_obj_boomerang.cpp | 95 | ||||
| -rw-r--r-- | src/d/a/obj/d_a_obj_switch.cpp | 34 | ||||
| -rw-r--r-- | src/d/d_carry.cpp | 12 | ||||
| -rw-r--r-- | src/d/d_linkage.cpp | 251 | ||||
| -rw-r--r-- | src/m/m_mtx.cpp | 48 |
9 files changed, 443 insertions, 67 deletions
diff --git a/src/REL/d/a/e/d_a_e_sm.cpp b/src/REL/d/a/e/d_a_e_sm.cpp index fe3c7514..dae7f886 100644 --- a/src/REL/d/a/e/d_a_e_sm.cpp +++ b/src/REL/d/a/e/d_a_e_sm.cpp @@ -16,6 +16,7 @@ #include "d/col/cc/d_cc_s.h" #include "d/d_camera.h" #include "d/d_jnt_col.h" +#include "d/d_linkage.h" #include "d/d_sc_game.h" #include "d/flag/sceneflag_manager.h" #include "d/flag/storyflag_manager.h" @@ -629,7 +630,7 @@ int dAcEsm_c::actorExecute() { dAcBomb_c *bomb = getBombWithinRadius(lookRadius); if (bomb != nullptr && std::abs(bomb->GetPosition().y - mHomePos1.y) < 0.7f * lookRadius) { - if (bomb->mActorCarryInfo.tryAttachWithRef(bomb, this, &mBombRef, 1, false)) { + if (bomb->GetLinkage().tryAttach(bomb, this, &mBombRef, dLinkage_c::CONNECTION_1, false)) { mTimer_0xBAE = 160; playSound(SE_ESm_BRING_IN); clearActorProperty(1); diff --git a/src/REL/d/a/obj/d_a_obj_ring.cpp b/src/REL/d/a/obj/d_a_obj_ring.cpp index 554a9d35..7d52f2bb 100644 --- a/src/REL/d/a/obj/d_a_obj_ring.cpp +++ b/src/REL/d/a/obj/d_a_obj_ring.cpp @@ -1,6 +1,8 @@ #include "d/a/obj/d_a_obj_ring.h" #include "d/a/d_a_player.h" +#include "d/d_linkage.h" +#include "m/m_angle.h" #include "nw4r/g3d/res/g3d_resfile.h" SPECIAL_ACTOR_PROFILE(OBJ_RING, dAcOring_c, fProfile::OBJ_RING, 0x00f2, 0, 0x103); @@ -10,7 +12,6 @@ STATE_DEFINE(dAcOring_c, Move); bool dAcOring_c::createHeap() { nw4r::g3d::ResFile f(getOarcResFile("PRing")); nw4r::g3d::ResMdl mdl = f.GetResMdl("PeehatRing"); - // This matches but in a really weird way. Maybe an inline function? TRY_CREATE(mModel.create(mdl, &heap_allocator, 0x20, 1, nullptr)); return true; } @@ -52,18 +53,11 @@ int dAcOring_c::draw() { void dAcOring_c::initializeState_Move() {} -u32 dAcOring_c::ROT_PER_TICK = 0x1000; - void dAcOring_c::executeState_Move() { - bool isCarried = false; - if (mActorCarryInfo.isCarried == 1 && mActorCarryInfo.carryType == 7) { - isCarried = true; - } - - if (isCarried) { + if (GetLinkage().checkConnection(dLinkage_c::CONNECTION_7)) { return; } - rotation.x.mVal += ROT_PER_TICK; + rotation.addX(0x1000); if (field_0x38C >= position.y) { deleteRequest(); } diff --git a/src/REL/d/a/obj/d_a_obj_tubo.cpp b/src/REL/d/a/obj/d_a_obj_tubo.cpp index 2c6d42ec..bfcb4ba7 100644 --- a/src/REL/d/a/obj/d_a_obj_tubo.cpp +++ b/src/REL/d/a/obj/d_a_obj_tubo.cpp @@ -17,6 +17,7 @@ #include "d/col/c/c_cc_d.h" #include "d/col/c/c_m3d_g_pla.h" #include "d/col/cc/d_cc_s.h" +#include "d/d_linkage.h" #include "d/flag/dungeonflag_manager.h" #include "d/flag/sceneflag_manager.h" #include "egg/math/eggMath.h" @@ -104,11 +105,11 @@ int dAcOtubo_c::actorCreate() { mStateMgr.changeState(StateID_Wait); boundingBox.Set(mVec3_c(-100.f, -40.f, -100.f), mVec3_c(100.f, 80.f, 100.f)); - mActorCarryInfo.set(0xC8A0, 28.f, 50.f, 28.f, nullptr); // TODO (ActorCarry Flags) - mActorCarryInfo.field_0x8C = 26.f; - mActorCarryInfo.field_0x90 = 46.f; - mActorCarryInfo.field_0x94 = 28.f; - mActorCarryInfo.field_0x98 = 0.f; + GetLinkage().set(0xC8A0, 28.f, 50.f, 28.f, nullptr); // TODO (ActorCarry Flags) + GetLinkage().field_0x8C = 26.f; + GetLinkage().field_0x90 = 46.f; + GetLinkage().field_0x94 = 28.f; + GetLinkage().field_0x98 = 0.f; return SUCCEEDED; } @@ -166,7 +167,7 @@ int dAcOtubo_c::actorExecute() { mField_0x9DC += position.y - mOldPosition.y; adjustRoll(); } - mActorCarryInfo.bushTpFunc(mObjAcch); + GetLinkage().bushTpFunc(mObjAcch); } if (mStateMgr.isState(StateID_Wait) || mStateMgr.isState(StateID_Slope)) { @@ -175,7 +176,7 @@ int dAcOtubo_c::actorExecute() { mSph.SetC(getCenter()); dCcS::GetInstance()->Set(&mSph); - mActorCarryInfo.fn_800511E0(this); + GetLinkage().fn_800511E0(this); mField_0x8F0.modifyMtx(); calcRoll(); @@ -283,28 +284,23 @@ void dAcOtubo_c::executeState_Grab() { dAcNpcCeLady_c *lady = mCeLady.get(); dAcNpcCeFriend_c *ceFriend = mCeFriend.get(); if (ceFriend && ceFriend->fn_11_17C0(this)) { - mActorCarryInfo.fn_80050EA0(this); + GetLinkage().fn_80050EA0(this); } else if (lady && lady->fn_12_1C20(this)) { - mActorCarryInfo.fn_80050EA0(this); + GetLinkage().fn_80050EA0(this); } } - if (mActorCarryInfo.checkCarryType(5) && sLib::calcTimer(&mTimer_0x9F5) == 0 && + if (GetLinkage().checkConnection(dLinkage_c::CONNECTION_5) && sLib::calcTimer(&mTimer_0x9F5) == 0 && (mObjAcch.ChkGndHit() || mObjAcch.ChkWallHit(nullptr) || mObjAcch.ChkRoofHit())) { destroy(); - } else if (dAcPy_c::LINK->getCurrentAction() == 66 /* Put Down Medium */) { // TODO (Link Action ID) + } else if (dAcPy_c::GetLink()->getCurrentAction() == 66 /* Put Down Medium */) { // TODO (Link Action ID) mStateMgr.changeState(StateID_Put); } else { - if (mActorCarryInfo.isCarried != 4) { - bool isCarried = false; - if (mActorCarryInfo.isCarried == 1 && mActorCarryInfo.carryType == 5) { - isCarried = true; - } - - if (isCarried) { - mField_0x9F6 = 0; + if (!GetLinkage().checkState(dLinkage_c::STATE_DELETE)) { + if (GetLinkage().checkConnection(dLinkage_c::CONNECTION_5)) { + mField_0x9F6 = dLinkage_c::STATE_0; } else { - mField_0x9F6 = mActorCarryInfo.isCarried; + mField_0x9F6 = GetLinkage().getState(); } } @@ -320,7 +316,7 @@ void dAcOtubo_c::finalizeState_Grab() { } mField_0x9D4 = cM::rndF(40.f); mSph.ClrCo_0x400(); - if ((u8)mActorCarryInfo.isCarried == 2) { + if ((u8)GetLinkage().mState == 2) { mSph.OnAtSet(); } mObjAcch.ClrRoofNone(); @@ -407,7 +403,7 @@ void dAcOtubo_c::initializeState_Rebirth() { mSph.ClrCoSet(); mSph.ClrTgSet(); setObjectProperty(0x200); - mActorCarryInfo.fn_80050EA0(this); + GetLinkage().fn_80050EA0(this); int item_drop_table = getParams2UpperByte(); switch (item_drop_table) { @@ -456,7 +452,7 @@ void dAcOtubo_c::destroy() { return; } fn_80022BE0(BlurAndPaletteManager::GetPInstance(), position); - mActorCarryInfo.fn_80050EA0(this); + GetLinkage().fn_80050EA0(this); dEmitterBase_c *fx_thing = dJEffManager_c::spawnEffect( PARTICLE_RESOURCE_ID_MAPPING_211_, poscopy2, nullptr, nullptr, nullptr, nullptr, 0, 0 @@ -651,7 +647,7 @@ void dAcOtubo_c::attemptDestroy() { mField_0x9DC = 0.f; } if (!mObjAcch.ChkGndHit() && mSph.ChkCoHit()) { - if (mActorCarryInfo.isCarried != 1 && forwardSpeed > 0.f) { + if (GetLinkage().mState != 1 && forwardSpeed > 0.f) { if (mSph.GetCoActor()->unkByteTargetFiRelated == 4) { destroy(); return; @@ -807,7 +803,9 @@ bool dAcOtubo_c::checkOnLava() { } bool dAcOtubo_c::checkCarryType() const { - return mActorCarryInfo.checkCarryType(1) || mActorCarryInfo.checkCarryType(7) || mActorCarryInfo.checkCarryType(5); + const dLinkage_c &linkage = GetLinkage(); + return linkage.checkConnection(dLinkage_c::CONNECTION_1) || linkage.checkConnection(dLinkage_c::CONNECTION_7) || + linkage.checkConnection(dLinkage_c::CONNECTION_5); } bool dAcOtubo_c::checkSubmerged() { diff --git a/src/d/a/obj/d_a_obj_arrow.cpp b/src/d/a/obj/d_a_obj_arrow.cpp index 42e1965d..2b9bbb57 100644 --- a/src/d/a/obj/d_a_obj_arrow.cpp +++ b/src/d/a/obj/d_a_obj_arrow.cpp @@ -1,7 +1,6 @@ #include "d/a/obj/d_a_obj_arrow.h" #include "c/c_math.h" -#include "d/a/d_a_player.h" #include "d/col/c/c_cc_d.h" #include "nw4r/types_nw4r.h" @@ -38,7 +37,7 @@ const dCcD_SrcSph dAcArrow_c::sCc2 = { // clang-format on -bool hitCallback(dAcObjBase_c *i_actorA, cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, cCcD_Obj *i_objInfB) { +bool dAcArrow_atHitCallback(dAcObjBase_c *i_actorA, cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, cCcD_Obj *i_objInfB) { static_cast<dAcArrow_c *>(i_actorA)->hitCallback(i_objInfA, i_actorB, i_objInfB); return true; } @@ -70,7 +69,7 @@ int dAcArrow_c::create() { mCcCps.Set(sCc1); mCcCps.SetStts(mStts); mCcCps.SetAtFlag(0x2000); - mCcCps.SetAtCallback(::hitCallback); + mCcCps.SetAtCallback(dAcArrow_atHitCallback); mCcSph.Set(sCc2); mCcSph.SetStts(mStts); diff --git a/src/d/a/obj/d_a_obj_boomerang.cpp b/src/d/a/obj/d_a_obj_boomerang.cpp new file mode 100644 index 00000000..1f908925 --- /dev/null +++ b/src/d/a/obj/d_a_obj_boomerang.cpp @@ -0,0 +1,95 @@ +#include "d/a/obj/d_a_obj_boomerang.h" + +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "f/f_profile_name.h" +#include "m/m3d/m_fanm.h" +#include "nw4r/g3d/g3d_anmchr.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "s/s_State.hpp" + +SPECIAL_ACTOR_PROFILE(BOOMERANG, dAcBoomerang_c, fProfile::BOOMERANG, 0x125, 0, 0x4); + +STATE_DEFINE(dAcBoomerang_c, Wait); +STATE_DEFINE(dAcBoomerang_c, Move); +STATE_DEFINE(dAcBoomerang_c, MoveCancelWait); +STATE_DEFINE(dAcBoomerang_c, ReturnWait); +STATE_DEFINE(dAcBoomerang_c, EventReturnWait); + +const dAcBoomerang_c::ChrAnimation_t dAcBoomerang_c::sChrAnims[dAcBoomerang_c::RB_MAX] = { + { "RB_Set", 0.f}, + {"RB_Default", 3.f}, + { "RB_Cut", 3.f}, + { "RB_Hold", 3.f}, + {"RB_Hold_ed", 3.f}, + { "RB_Back", 3.f}, +}; + +void areaCallback(dAcObjBase_c *param0, mVec3_c *param1, u32 param2) { + if (param2 != 0) { + return; + } +} + +void dAcBoomerang_c::atHitCallback(cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, cCcD_Obj *i_objInfB) { + if (i_actorB != nullptr && GetLinkage().checkFlag(0x80)) { + if (dAcPy_c::getCurrentBeetleType() > 2) { + if (i_actorB == mGrabbedActor.get()) { + return; + } + + if (!mStateMgr.isState(StateID_Move)) { + return; + } + + if (tryGrabObject(i_actorB)) { + setChrAnimation(RB_HOLD); + mAnmChr[0].setRate(0.f); + mAnmChr[0].setFrameOnly(i_actorB->GetLinkage().field_0x24); + } + } + } +} + +bool dAcBoomerang_atHitCallback( + dAcObjBase_c *i_actorA, cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, cCcD_Obj *i_objInfB +) { + static_cast<dAcBoomerang_c *>(i_actorA)->atHitCallback(i_objInfA, i_actorB, i_objInfB); + return true; +} + +// ... + +bool dAcBoomerang_c::tryGrabObject(dAcObjBase_c *pObj) { + dAcPy_c *player = dAcPy_c::GetLink2(); + if (checkField_0x8CC(0x1000) && GetLinkage().checkFlag(0x80)) {} +} + +// ... + +void dAcBoomerang_c::setChrAnimation(dAcBoomerang_c::ChrAnimation_e requestedAnimation) { + // Do not set anim if there is no change, or the request is to cut from hold + if (requestedAnimation == mCurrentAnimation || (mCurrentAnimation == RB_HOLD && requestedAnimation == RB_CUT)) { + return; + } + + mAnmChr[0].setAnm(mMdl, mResFile.GetResAnmChr(sChrAnims[requestedAnimation].mName), m3d::PLAY_MODE_4); + nw4r::g3d::AnmObjChr *pAnmObj = static_cast<nw4r::g3d::AnmObjChr *>(mAnmChr[0].getAnimObj()); + + pAnmObj->Release(); + + nw4r::g3d::ResMdl mdl = mMdl.getResMdl(); + for (int i = 0; i < mWindNodeID; ++i) { + pAnmObj->Bind(mdl, i, nw4r::g3d::AnmObjChr::BIND_ONE); + } + + if (requestedAnimation == RB_SET) { + pAnmObj->Bind(mdl, mLeftWingNodeID, nw4r::g3d::AnmObjChr::BIND_ONE); + pAnmObj->Bind(mdl, mRightWingNodeID, nw4r::g3d::AnmObjChr::BIND_ONE); + } + + mCurrentAnimation = requestedAnimation; + + mMdl.setAnm(mAnmChrBlend, sChrAnims[requestedAnimation].mRate); +} diff --git a/src/d/a/obj/d_a_obj_switch.cpp b/src/d/a/obj/d_a_obj_switch.cpp index ffc58d74..fd5cd444 100644 --- a/src/d/a/obj/d_a_obj_switch.cpp +++ b/src/d/a/obj/d_a_obj_switch.cpp @@ -3,6 +3,7 @@ #include "d/a/d_a_player.h" #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_w.h" +#include "d/d_linkage.h" #include "d/flag/sceneflag_manager.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_Math.h" @@ -42,26 +43,29 @@ void dAcOsw_c::rideCallback(dBgW *unknown, dAcObjBase_c *actor, dAcObjBase_c *in dAcPy_c *link = interactor->isActorPlayer() ? static_cast<dAcPy_c *>(interactor) : nullptr; dAcOsw_c *sw = static_cast<dAcOsw_c *>(actor); - // halp - if (!(link == nullptr || (!link->checkActionFlags(dAcPy_c::FLG0_IN_WATER) && - ((!link->checkFlags0x340(0x800000) || - ((link->getCurrentCarriedActor() != nullptr && - link->getCurrentCarriedActor()->mActorCarryInfo.testCarryFlag(0x04)))))))) { + if (link != nullptr) { + if (link->checkActionFlags(dAcPy_c::FLG0_IN_WATER)) { + return; + } + if (link->checkFlags0x340(0x800000) && + !(link->getCurrentCarriedActor() && link->getCurrentCarriedActor()->GetLinkage().checkFlag(0x04))) { + return; + } + } + + if (interactor->GetLinkage().checkState(dLinkage_c::STATE_ACTIVE)) { return; } - if (interactor->mActorCarryInfo.isCarried != 1) { - if (link == nullptr || (link->checkActionFlags(0xC70852)) == 0) { - if (!sw->someInteractCheck(link != nullptr)) { - bool needsOnFlag = sw->mOnSceneFlag < 0xFF && - !SceneflagManager::sInstance->checkBoolFlag(sw->roomid, sw->mOnSceneFlag); - if (!needsOnFlag && sw->mObjRef.get() == nullptr && link != nullptr && sw->field_0x5F1 == 0 && - sw->mStateMgr.isState(StateID_On)) { - link->onFlags_0x360(0x8000); - } + + if (!(link && link->checkActionFlags(0xC70852))) { + if (!sw->someInteractCheck(link != nullptr)) { + if (!sw->checkOnFlag() && sw->mObjRef.get() == nullptr && link != nullptr && sw->field_0x5F1 == 0 && + sw->mStateMgr.isState(StateID_On)) { + link->onFlags_0x360(0x8000); } } - interactor->setObjectProperty(0x40); } + interactor->setObjectProperty(0x40); } bool dAcOsw_c::createHeap() { diff --git a/src/d/d_carry.cpp b/src/d/d_carry.cpp deleted file mode 100644 index ce473dd4..00000000 --- a/src/d/d_carry.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "d/a/obj/d_a_obj_base.h" -#include "m/m_mtx.h" - -ActorCarryStruct::ActorCarryStruct() - : actorLink(nullptr), carriedActor(nullptr), carryFlags(0), carryType(0), field_0x18(0), - field_0x1C(0.0f, 0.0f, 0.0f), carryTransMtx(mMtx_c::Identity), field_0x58(mMtx_c::Identity), isCarried(0), - field_0x8C(0.0f), field_0x90(0.0f), field_0x94(0.0f), field_0x98(0.0f) {} - -ActorCarryStruct::~ActorCarryStruct() { - fn_80051190(nullptr); - fn_80050EB0(nullptr); -} diff --git a/src/d/d_linkage.cpp b/src/d/d_linkage.cpp new file mode 100644 index 00000000..c37f6118 --- /dev/null +++ b/src/d/d_linkage.cpp @@ -0,0 +1,251 @@ +#include "d/d_linkage.h" + +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/bg/d_bg_s_acch.h" +#include "f/f_profile_name.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" +#include "rvl/MTX/mtx.h" + +dLinkage_c::dLinkage_c() + : mControllingActor(nullptr), + pLinkedActor(nullptr), + carryFlags(0), + mType(CONNECTION_0), + field_0x18(0), + field_0x1C(0.0f), + field_0x20(0.f), + field_0x24(0.f), + carryTransMtx(mMtx_c::Identity), + field_0x58(mMtx_c::Identity), + mState(STATE_0), + field_0x8C(0.0f), + field_0x90(0.0f), + field_0x94(0.0f), + field_0x98(0.0f) {} + +dLinkage_c::~dLinkage_c() { + fn_80051190(nullptr); + fn_80050EB0(nullptr); +} + +// Ignore the parameter names. I am unsure what they are +void dLinkage_c::set(u32 flags, f32 x, f32 y, f32 z, void *) { + onFlag(0x8000000 | flags); + field_0x1C = x; + field_0x20 = y; + field_0x24 = z; + + if (flags & 2) { + field_0x8C = 28.f; + field_0x90 = 36.f; + field_0x94 = 28.f; + field_0x98 = 0.f; + } else if (flags & 4) { + field_0x8C = 18.f; + field_0x90 = 25.f; + field_0x94 = 18.f; + field_0x98 = 0.f; + } else if (flags & 8) { + field_0x8C = 16.7f; + field_0x90 = 25.f; + field_0x94 = 16.7f; + field_0x98 = 0.f; + } else { + field_0x8C = 18.f; + field_0x90 = 30.f; + field_0x94 = 18.f; + field_0x98 = 0.f; + } +} + +bool dLinkage_c::tryAttach( + dAcObjBase_c *pActor, dAcObjBase_c *pSrc, dAcRefBase_c *pRef, dLinkage_c::ConnectionType_e type, bool replace +) { + if (checkState(STATE_ACTIVE)) { + if (replace) { + fn_80050EB0(pActor); + } else { + return false; + } + } + pActor->clearObjectProperty(0x1000); + pActor->clearObjectProperty(0x4); + mControllingActor.link(pSrc); + mState = STATE_ACTIVE; + mType = type; + + if (type == CONNECTION_4) { + pActor->setObjectProperty(0x4); + } else if (type == CONNECTION_7) { + pActor->setObjectProperty(0x1000); + field_0x1A = 4; + } + MTXIdentity(carryTransMtx); + pLinkedActor = pRef; + pRef->link(pActor); + if ((pSrc == dAcPy_c::GetLink2() || type == CONNECTION_5) && + pActor->getConnectParent()->profile_name == fProfile::ROOM) { + pActor->addActorToRoom(-1); + onFlag(0x20000000); + pActor->setActorProperty(0x2000000); + pActor->changeLoadedEntitiesWithSet(); + } + pActor->clearActorProperty(0x1); + return true; +} + +void dLinkage_c::fn_80050DC0(dAcObjBase_c *pActor, const f32 speed, const f32 velocityY, mAng rot) { + mState = STATE_2; + fn_80050E40(pActor, speed, velocityY, rot); +} + +void dLinkage_c::fn_80050E00(dAcObjBase_c *pActor, const f32 speed, const f32 velocityY, mAng rot) { + mState = STATE_3; + fn_80050E40(pActor, speed, velocityY, rot); +} + +void dLinkage_c::fn_80050E40(dAcObjBase_c *pActor, const f32 speed, const f32 velocityY, mAng rot) { + fn_80050EB0(pActor); + pActor->forwardSpeed = speed; + pActor->velocity.y = velocityY; + pActor->angle.y = rot; +} + +void dLinkage_c::fn_80050EA0(dAcObjBase_c *pActor) { + mState = STATE_DELETE; + fn_80050EB0(pActor); +} + +void dLinkage_c::fn_80050EB0(dAcObjBase_c *pActor) { + mControllingActor.unlink(); + if (pLinkedActor) { + pLinkedActor->unlink(); + pLinkedActor = nullptr; + } + + if (checkType_1_3_5_6_9()) { + MTXConcat(carryTransMtx, field_0x58, field_0x58); + field_0x58.fn_802F1C40(2, 0); + field_0x18 = 5; + MTXIdentity(carryTransMtx); + } else if (mType == CONNECTION_4) { + if (pActor) { + pActor->clearObjectProperty(0x4); + } + } else if (mType == CONNECTION_7) { + if (pActor) { + pActor->clearObjectProperty(0x1000); + } + } + + if (pActor && checkFlag(0x20000000)) { + pActor->addActorToRoom(pActor->getRoomId()); + offFlag(0x20000000); + } + + field_0x1A = 4; + mType = CONNECTION_0; + offFlag(0x10000000); +} + +void dLinkage_c::bushTpFunc(dBgS_Acch &acch) { + mVec3_c *pos = acch.GetPos(); + mVec3_c origPos = *pos; + + if (field_0x1A != 0) { + if (field_0x1A == 4 && !acch.ChkLineCheck()) { + acch.OnLineCheck(); + onFlag(0x4000000); + } + + if (--field_0x1A == 0 && checkFlag(0x4000000)) { + acch.OffLineCheck(); + offFlag(0x4000000); + } + } + + acch.CrrPos(*dBgS::GetInstance()); + if (mState == STATE_ACTIVE) { + dAcPy_c *player = dAcPy_c::GetLink2(); + if (mType == CONNECTION_1 && mControllingActor.p_owner == player) { + player->fn_80202E00(nullptr, pos->x - origPos.x, pos->z - origPos.z); + } + + if (mType == CONNECTION_7 && mControllingActor.p_owner == player) { + if (!checkFlag(0x10000)) { + if (acch.ChkWallHit(nullptr)) { + fn_80050EA0(player->getWhippedItem()); + return; + } + field_0x1A = 3; + } + } + + *pos = origPos; + } +} + +void dLinkage_c::fn_80051190(dAcObjBase_c *pActor) { + // If not active, return + if (!checkState(STATE_ACTIVE)) { + return; + } + + // If currently Linked + if (mControllingActor.p_owner) { + // if the actor being linked to is empty, no need to delink + if (pLinkedActor == nullptr) { + return; + } + + // If the Actor is linked to itself, return? + dAcObjBase_c *pLinked = static_cast<dAcObjBase_c *>(pLinkedActor->p_owner); + if (pLinked && &pLinked->GetLinkage() == this) { + return; + } + } + pLinkedActor = nullptr; + + fn_80050EA0(pActor); +} + +void dLinkage_c::fn_800511E0(dAcObjBase_c *pActor) { + bool b = checkType_1_3_5_6_9(); + + if (!(checkFlag(0x200) || b || field_0x18 == 0)) { + field_0x58.slerpTo(mMtx_c::Identity, field_0x58, 1.f / field_0x18); + field_0x58.fn_802F1C40(2, 0); + field_0x18--; + } + mMtx_c &mtx = pActor->mWorldMtx; + f32 y = field_0x1C * pActor->mScale.y; + mtx.transS(pActor->GetPosition().x, pActor->GetPosition().y + pActor->GetYOffset(), pActor->GetPosition().z); + if (mType == CONNECTION_1) { + MTXConcat(mtx, carryTransMtx, mtx); + } + mMtx_c m1; + MTXTrans(m1, 0.f, y, 0.f); + MTXConcat(mtx, m1, mtx); + + if (b && mType != CONNECTION_1) { + MTXConcat(mtx, carryTransMtx, mtx); + } + mMtx_c m2; + MTXConcat(mtx, field_0x58, mtx); + MTXTrans(m2, 0.f, -y, 0.f); + MTXConcat(mtx, m2, mtx); + + mtx.ZXYrotM(pActor->rotation); + if (mControllingActor.p_owner) { + pActor->roomid = static_cast<dAcObjBase_c *>(mControllingActor.p_owner)->roomid; + } +} + +bool dLinkage_c::fn_800513C0() const { + return (mState == STATE_ACTIVE && (mType == CONNECTION_1 || mType == CONNECTION_6)) && + !(mControllingActor.p_owner && mControllingActor.p_owner->profile_name == fProfile::E_GEROCK); +} diff --git a/src/m/m_mtx.cpp b/src/m/m_mtx.cpp index 712d612c..521cbb7a 100644 --- a/src/m/m_mtx.cpp +++ b/src/m/m_mtx.cpp @@ -1,6 +1,8 @@ +#include "m/m_mtx.h" + #include "c/c_math.h" #include "m/m_math.h" -#include "nw4r/math.h" +#include "m/m_vec.h" void mMtx_c::toRot(mAng3_c &out) const { f32 t1 = 0.0f; @@ -10,3 +12,47 @@ void mMtx_c::toRot(mAng3_c &out) const { } s16 anglex = cM::atan2s(-m[1][2], t1); } + +void mMtx_c::fn_802F1C40(s32 i, s32 j) { + f32 *pJ = &arr[j]; + f32 *pI = &arr[i]; + + mVec3_c v0(pI[0], pI[4], pI[8]); + mVec3_c v1(pJ[0], pJ[4], pJ[8]); + + mVec3_c v2; + v0.normalize(); + + f32 z, y, x; + if (j - i == 1 || j - i == -2) { + z = (v0.x * v1.y) - (v0.y * v1.x); + y = (v0.z * v1.x) - (v0.x * v1.z); + x = (v0.y * v1.z) - (v0.z * v1.y); + v2 = mVec3_c(x, y, z); + + z = (v2.x * v0.y) - (v2.y * v0.x); + y = (v2.z * v0.x) - (v2.x * v0.z); + x = (v2.y * v0.z) - (v2.z * v0.y); + v1 = mVec3_c(x, y, z); + } else { + z = (v1.x * v0.y) - (v1.y * v0.x); + y = (v1.z * v0.x) - (v1.x * v0.z); + x = (v1.y * v0.z) - (v1.z * v0.y); + v2 = mVec3_c(x, y, z); + + z = (v0.x * v2.y) - (v0.y * v2.x); + y = (v0.z * v2.x) - (v0.x * v2.z); + x = (v0.y * v2.z) - (v0.z * v2.y); + v1 = mVec3_c(x, y, z); + } + v2.normalize(); + v1.normalize(); + + f32 *pK = &arr[((3 - i) - j)]; + + // clang-format off + pI[0] = v0.x; pI[4] = v0.y; pI[8] = v0.z; + pJ[0] = v1.x; pJ[4] = v1.y; pJ[8] = v1.z; + pK[0] = v2.x; pK[4] = v2.y; pK[8] = v2.z; + // clang-format on +} |
