From 3e115f57ffc0cf43de037bd6229f0cfb4ca7747b Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Tue, 10 Mar 2026 01:22:42 +0000 Subject: [PATCH 1/6] Partial match on TMapObjGeneral::put Renamed TMapObjBase::unk104 to mTimeTilAppear. It has several uses referring to time and waiting to appear. --- include/MoveBG/MapObjBase.hpp | 6 +++--- src/MoveBG/MapObjGeneral.cpp | 36 +++++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/MoveBG/MapObjBase.hpp b/include/MoveBG/MapObjBase.hpp index 61fc3e21..f4ae81e6 100644 --- a/include/MoveBG/MapObjBase.hpp +++ b/include/MoveBG/MapObjBase.hpp @@ -329,8 +329,8 @@ class TMapObjBase : public TLiveActor { void offMapObjFlag(u32 flag) { unkF8 &= ~flag; } TMapObjData* getMapObjData() { return mMapObjData; } bool isState(u32 v) { return mState == v ? true : false; } - bool isUnk104Positive() { return unk104 > 0 ? true : false; } - int getUnk104() { return unk104; } + bool isReadyToAppear() { return mTimeTilAppear > 0 ? true : false; } + int getTimeTilAppear() { return mTimeTilAppear; } u32 getUnk134() { return unk134; } void setUnk134(u32 v) { unk134 = v; } const char* getUnkF4() { return unkF4; } @@ -342,7 +342,7 @@ class TMapObjBase : public TLiveActor { /* 0xFE */ u16 unkFE; /* 0x100 */ u16 unk100; /* 0x102 */ u16 unk102; - /* 0x104 */ int unk104; + /* 0x104 */ int mTimeTilAppear; /* 0x108 */ f32 mYOffset; // TODO: offset from what to what? /* 0x10C */ JGeometry::TVec3 mInitialPosition; /* 0x118 */ JGeometry::TVec3 mInitialRotation; diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index c88c2c36..c0f6e6cf 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -44,7 +44,7 @@ inline f32 distToMario(const JGeometry::TVec3& v) void TMapObjGeneral::waitingToAppear() { - if (unk104 > 0 ? true : false) + if (mTimeTilAppear > 0 ? true : false) return; if (isActorType(0x4000005a)) { @@ -64,12 +64,12 @@ void TMapObjGeneral::waitingToRecover() recover(); } -void TMapObjGeneral::waitToAppear(s32 param_1) +void TMapObjGeneral::waitToAppear(s32 waitTime) { - if (param_1 == 0) - unk104 = mNormalWaitToAppearTime; + if (waitTime == 0) + mTimeTilAppear = mNormalWaitToAppearTime; else - unk104 = param_1; + mTimeTilAppear = waitTime; mState = 10; } @@ -83,7 +83,19 @@ void TMapObjGeneral::sink() startSound(6); } -void TMapObjGeneral::put() { } +void TMapObjGeneral::put() +{ + mHolder = nullptr; + mHolder = nullptr; + s32 preservedTimeTilAppear = getTimeTilAppear(); + makeObjAppeared(); + mTimeTilAppear = preservedTimeTilAppear; + mPosition.x = JMASSin(*gpMarioAngleY) * (getDamageRadius() + SMS_GetMarioDamageRadius() + 10.0f) + SMS_GetMarioPos().x; + mPosition.y = SMS_GetMarioPos().y; + mPosition.z = JMASCos(*gpMarioAngleY) * (getDamageRadius() + SMS_GetMarioDamageRadius() + 10.0f) + SMS_GetMarioPos().z; + offLiveFlag(LIVE_FLAG_UNK10); + mGroundHeight = gpMap->checkGround(mPosition, &mGroundPlane); +} void TMapObjGeneral::thrown() { } @@ -190,7 +202,7 @@ void TMapObjGeneral::appearing() void TMapObjGeneral::appeared() { - if (checkMapObjFlag(0x40000) && !(unk104 > 0 ? true : false)) + if (checkMapObjFlag(0x40000) && !(mTimeTilAppear > 0 ? true : false)) makeObjDead(); } @@ -279,7 +291,7 @@ void TMapObjGeneral::kill() unk64 |= 1; removeMapCollision(); onLiveFlag(LIVE_FLAG_UNK10 | LIVE_FLAG_UNK8); - unk104 = 0xffffffff; + mTimeTilAppear = 0xffffffff; startAnim(2); mState = 3; startSound(2); @@ -303,7 +315,7 @@ void TMapObjGeneral::appear() appearing(); if (checkMapObjFlag(0x40000)) - unk104 = getLivingTime(); + mTimeTilAppear = getLivingTime(); mState = 2; } @@ -474,9 +486,9 @@ void TMapObjGeneral::perform(u32 param_1, JDrama::TGraphics* param_2) waitingToAppear(); } } else { - if (checkMapObjFlag(0x40000) && isUnk104Positive() - && getUnk104() < getFlushTime() - && ((getUnk104() / mNormalFlushInterval) & 1) != 0) { + if (checkMapObjFlag(0x40000) && isReadyToAppear() + && getTimeTilAppear() < getFlushTime() + && ((getTimeTilAppear() / mNormalFlushInterval) & 1) != 0) { return; } } From ce06abfaaf550a05b76d0dff6c635e1b8eae7a42 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Tue, 10 Mar 2026 01:40:08 +0000 Subject: [PATCH 2/6] Better matching on TMapObjGeneral::waitingToAppear --- src/MoveBG/MapObjGeneral.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index c0f6e6cf..abdf8eb9 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -37,22 +37,25 @@ bool TMapObjGeneral::isPollutedGround(const JGeometry::TVec3& v) const inline f32 distToMario(const JGeometry::TVec3& v) { - JGeometry::TVec3 r; - r.sub(v, *gpMarioPos); - return r.length(); + f32 l = (v.x - gpMarioPos->x) * (v.x - gpMarioPos->x) + + (v.y - gpMarioPos->y) * (v.y - gpMarioPos->y) + + (v.z - gpMarioPos->z) * (v.z - gpMarioPos->z); + return JGeometry::TUtil::sqrt(l); } void TMapObjGeneral::waitingToAppear() { - if (mTimeTilAppear > 0 ? true : false) + if (isReadyToAppear()) return; if (isActorType(0x4000005a)) { - if (SMS_GetMarioDamageRadius() + mDamageRadius + 100.0f + f32 damageRadius = getDamageRadius(); + if (SMS_GetMarioDamageRadius() + damageRadius + 100.0f > distToMario(mInitialPosition)) appear(); } else { - if (SMS_GetMarioDamageRadius() + mDamageRadius + f32 damageRadius = getDamageRadius(); + if (SMS_GetMarioDamageRadius() + damageRadius > distToMario(mInitialPosition)) appear(); } From c3acafe4a8c88b4c46eff2e7292b94c390295c3a Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Tue, 10 Mar 2026 19:42:51 +0000 Subject: [PATCH 3/6] Initial implementation of TMapObjGeneral::thrown Tried to get this closer, but the calculation of initialVelX and initialVelZ is very out of order. Needs more investigation --- src/MoveBG/MapObjGeneral.cpp | 40 +++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index abdf8eb9..24b9b65b 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -100,7 +100,45 @@ void TMapObjGeneral::put() mGroundHeight = gpMap->checkGround(mPosition, &mGroundPlane); } -void TMapObjGeneral::thrown() { } +void TMapObjGeneral::thrown() +{ + f32 posX = gpMarioPos->x; + f32 posY = gpMarioPos->y; + f32 posZ = gpMarioPos->z; + mPosition.x = posX; + mPosition.y = posY; + mPosition.z = posZ; + + s16 angX = *gpMarioAngleX; + s16 angY = *gpMarioAngleY; + s16 angZ = *gpMarioAngleZ; + mRotation.x = angX; + mRotation.y = angY; + mRotation.z = angZ; + + mGroundHeight = gpMap->checkGround(mPosition, &mGroundPlane); + unk138 = 0; + mHolder = nullptr; + + f32 initialVelX = JMASSin((s32)*gpMarioAngleY) * *gpMarioThrowPower * mMapObjData->mPhysical->unk4->unk2C + (mNormalThrowSpeedRate * *gpMarioSpeedX); + f32 initialVelY = mMapObjData->mPhysical->unk4->unk30; + f32 initialVelZ = JMASCos((s32)*gpMarioAngleY) * *gpMarioThrowPower * mMapObjData->mPhysical->unk4->unk2C + (mNormalThrowSpeedRate * *gpMarioSpeedZ); + mVelocity.x = initialVelX; + mVelocity.y = initialVelY; + mVelocity.z = initialVelZ; + + offLiveFlag(LIVE_FLAG_UNK10); + JGeometry::TVec3 vel = mVelocity; + mPosition.x += vel.x; + mPosition.y += vel.y; + mPosition.z += vel.z; + onLiveFlag(LIVE_FLAG_AIRBORNE); + removeMapCollision(); + offLiveFlag(LIVE_FLAG_DEAD); + startAnim(5); + startSound(5); + mState = 1; + } void TMapObjGeneral::touchingWater() { From 60c73c3f9bf7fcc4a0a06b416a534d00edd29789 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Tue, 10 Mar 2026 20:55:28 +0000 Subject: [PATCH 4/6] Partial match on TMapObjGeneral::calcVelocity --- src/MoveBG/MapObjGeneral.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index 24b9b65b..942bceba 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -476,7 +477,35 @@ void TMapObjGeneral::checkGroundCollision(JGeometry::TVec3* param_1) onLiveFlag(LIVE_FLAG_AIRBORNE); } -void TMapObjGeneral::calcVelocity() { } +void TMapObjGeneral::calcVelocity() +{ + if (checkLiveFlag2(LIVE_FLAG_AIRBORNE)) { + f32 dVar5 = getGravityY(); + mVelocity.y -= dVar5; + + f32 cappedVelY = MsClamp(mVelocity.y, -mBodyRadius, mBodyRadius); + mVelocity.y = cappedVelY; + } + + const TMapObjPhysicalInfo* piVar4 = mMapObjData->mPhysical; + if (piVar4 ? (u8)1 : (u8)0) { + mVelocity.x *= mMapObjData->mPhysical->unk4->unk18; + mVelocity.z *= mMapObjData->mPhysical->unk4->unk18; + + f32 cappedVelX = MsClamp(mVelocity.x, -mBodyRadius, mBodyRadius); + mVelocity.x = cappedVelX; + + f32 cappedVelZ = MsClamp(mVelocity.z, -mBodyRadius, mBodyRadius); + mVelocity.z = cappedVelZ; + + if (mGroundPlane->mNormal.y == 1.0f) { + if (abs(mVelocity.x) < mMapObjData->mPhysical->unk4->unkC) + mVelocity.x = 0.0f; + if (abs(mVelocity.z) < mMapObjData->mPhysical->unk4->unkC) + mVelocity.z = 0.0f; + } + } +} void TMapObjGeneral::bind() { } From c435b00d75471de1470689f89b7648547d689ef0 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Wed, 11 Mar 2026 00:11:24 +0000 Subject: [PATCH 5/6] Partial match on TMapObjGeneral::bind --- include/Strategic/LiveActor.hpp | 2 +- src/MoveBG/MapObjGeneral.cpp | 62 ++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/include/Strategic/LiveActor.hpp b/include/Strategic/LiveActor.hpp index 5ec8c76b..bc2c427d 100644 --- a/include/Strategic/LiveActor.hpp +++ b/include/Strategic/LiveActor.hpp @@ -22,7 +22,7 @@ enum TLiveFlagBits { LIVE_FLAG_HIDDEN = 0x2, LIVE_FLAG_CLIPPED_OUT = 0x4, LIVE_FLAG_UNK8 = 0x8, - LIVE_FLAG_UNK10 = 0x10, + LIVE_FLAG_NOT_MOVING = 0x10, LIVE_FLAG_UNK40 = 0x40, LIVE_FLAG_AIRBORNE = 0x80, LIVE_FLAG_UNK100 = 0x100, diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index 942bceba..930fc8b4 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,7 @@ void TMapObjGeneral::waitToAppear(s32 waitTime) void TMapObjGeneral::sink() { mVelocity.x = mVelocity.y = mVelocity.z = 0.0f; - onLiveFlag(LIVE_FLAG_UNK10); + onLiveFlag(LIVE_FLAG_NOT_MOVING); mState = 7; unk144 = mPosition.y; setUpMapCollision(1); @@ -97,7 +98,7 @@ void TMapObjGeneral::put() mPosition.x = JMASSin(*gpMarioAngleY) * (getDamageRadius() + SMS_GetMarioDamageRadius() + 10.0f) + SMS_GetMarioPos().x; mPosition.y = SMS_GetMarioPos().y; mPosition.z = JMASCos(*gpMarioAngleY) * (getDamageRadius() + SMS_GetMarioDamageRadius() + 10.0f) + SMS_GetMarioPos().z; - offLiveFlag(LIVE_FLAG_UNK10); + offLiveFlag(LIVE_FLAG_NOT_MOVING); mGroundHeight = gpMap->checkGround(mPosition, &mGroundPlane); } @@ -128,7 +129,7 @@ void TMapObjGeneral::thrown() mVelocity.y = initialVelY; mVelocity.z = initialVelZ; - offLiveFlag(LIVE_FLAG_UNK10); + offLiveFlag(LIVE_FLAG_NOT_MOVING); JGeometry::TVec3 vel = mVelocity; mPosition.x += vel.x; mPosition.y += vel.y; @@ -236,7 +237,7 @@ void TMapObjGeneral::appearing() } uuuh: - if (!checkLiveFlag(LIVE_FLAG_UNK10)) + if (!checkLiveFlag(LIVE_FLAG_NOT_MOVING)) return; makeObjAppeared(); @@ -324,7 +325,7 @@ void TMapObjGeneral::ensureTakeSituation() TMapObjBase::ensureTakeSituation(); if (isState(6) && mHolder == nullptr) { mState = 1; - offLiveFlag(LIVE_FLAG_UNK10); + offLiveFlag(LIVE_FLAG_NOT_MOVING); } } @@ -332,7 +333,7 @@ void TMapObjGeneral::kill() { unk64 |= 1; removeMapCollision(); - onLiveFlag(LIVE_FLAG_UNK10 | LIVE_FLAG_UNK8); + onLiveFlag(LIVE_FLAG_NOT_MOVING | LIVE_FLAG_UNK8); mTimeTilAppear = 0xffffffff; startAnim(2); mState = 3; @@ -461,7 +462,7 @@ void TMapObjGeneral::touchGround(JGeometry::TVec3* param_1) } else { offLiveFlag(LIVE_FLAG_AIRBORNE); mVelocity.x = mVelocity.y = mVelocity.z = 0.0f; - onLiveFlag(LIVE_FLAG_UNK10); + onLiveFlag(LIVE_FLAG_NOT_MOVING); param_1->y = mGroundHeight; } } @@ -507,7 +508,52 @@ void TMapObjGeneral::calcVelocity() } } -void TMapObjGeneral::bind() { } +void TMapObjGeneral::bind() +{ + if (checkLiveFlag(LIVE_FLAG_NOT_MOVING) == 0) { + if (mBinder != nullptr) { + mBinder->bind(this); + } else { + calcVelocity(); + JGeometry::TVec3 vec = getPosition(); + vec.x += mLinearVelocity.x; + vec.y += mLinearVelocity.y; + vec.z += mLinearVelocity.z; + vec.x += mVelocity.x; + vec.y += mVelocity.y; + vec.z += mVelocity.z; + checkGroundCollision(&vec); + if (checkMapObjFlag(0x10000) != 0) { + checkWallCollision(&vec); + } + if (checkMapObjFlag(0x20000) != 0) { + JGeometry::TVec3 vel = mVelocity; + if (vel.y > 0.0f) { + checkRoofCollision(&vec); + } + } + if (mGroundPlane->checkFlag(0x10)) { + kill(); + } else { + if (!checkLiveFlag2(LIVE_FLAG_AIRBORNE)) { + JGeometry::TVec3 vel = mVelocity; + JGeometry::TVec3 velCopy = vel; + if (velCopy.x == 0.0f) { + JGeometry::TVec3 velCopy2 = vel; + if (velCopy2.y == 0.0f) { + JGeometry::TVec3 velCopy3 = vel; + if (velCopy3.z == 0.0f) { + onLiveFlag(LIVE_FLAG_NOT_MOVING); + } + } + } + } + + mLinearVelocity = vec - mLinearVelocity; + } + } + } +} void TMapObjGeneral::control() { From 9204cc7daad696e9f0f57a46f28ae39ef87a7ad9 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Wed, 11 Mar 2026 12:57:12 +0000 Subject: [PATCH 6/6] Better matching in TMapObjGeneral::touchGround --- src/MoveBG/MapObjGeneral.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index 930fc8b4..9ce08ab2 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -437,6 +437,15 @@ void TMapObjGeneral::checkRoofCollision(JGeometry::TVec3* param_1) touchRoof(param_1); } +inline void playCoinSound(const JGeometry::TVec3& pos, const JGeometry::TVec3& vel) +{ + f32 a = abs(JGeometry::TVec3(vel).y); + if (gpMSound->gateCheck(0x4842)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x4842, pos, nullptr, a, 0, 0, nullptr, 0, 4); + } +} + void TMapObjGeneral::touchGround(JGeometry::TVec3* param_1) { if (mMapObjData->mPhysical ? true : false) { @@ -445,17 +454,12 @@ void TMapObjGeneral::touchGround(JGeometry::TVec3* param_1) } if ((mMapObjData->mPhysical ? true : false) - && std::abs(JGeometry::TVec3(mVelocity).y) + && abs(JGeometry::TVec3(mVelocity).y) > mMapObjData->mPhysical->unk4->unkC) { param_1->y -= JGeometry::TVec3(mVelocity).y; mVelocity.y *= -mMapObjData->mPhysical->unk4->unk4; if (isCoin(this)) { - // TODO: this is an inline 100% - f32 a = std::fabsf(JGeometry::TVec3(mVelocity).y); - if (gpMSound->gateCheck(0x4842)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x4842, mPosition, nullptr, a, 0, 0, nullptr, 0, 4); - } + playCoinSound(mPosition, mVelocity); } else { startSound(4); }