summaryrefslogtreecommitdiff
path: root/src/d/d_linkage.cpp
diff options
context:
space:
mode:
authorElijah Thomas <42302100+elijah-thomas774@users.noreply.github.com>2025-05-25 15:51:35 -0400
committerGitHub <noreply@github.com>2025-05-25 15:51:35 -0400
commitfd7d30d32283d03a412e8c401d04418351cf686a (patch)
treee88bed25f474f06552cd7a7ea7067a0beead4414 /src/d/d_linkage.cpp
parent018ef1971cd53aa8e78154789bcf6cac2f19b603 (diff)
d_linkage is largely done (#176)
Diffstat (limited to 'src/d/d_linkage.cpp')
-rw-r--r--src/d/d_linkage.cpp251
1 files changed, 251 insertions, 0 deletions
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);
+}