From fe9c996dc41781a900af068ed76e9272969facf3 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Thu, 28 May 2026 22:49:50 +0100 Subject: [PATCH 1/7] MapObjBall initial commit --- include/MoveBG/MapObjBall.hpp | 48 +- include/MoveBG/MapObjBase.hpp | 1 + include/MoveBG/MapObjGeneral.hpp | 2 +- src/MoveBG/MapObjBall.cpp | 1720 ++++++++++++++++++++++++++++++ 4 files changed, 1763 insertions(+), 8 deletions(-) diff --git a/include/MoveBG/MapObjBall.hpp b/include/MoveBG/MapObjBall.hpp index 5f71e97b..ea5989d9 100644 --- a/include/MoveBG/MapObjBall.hpp +++ b/include/MoveBG/MapObjBall.hpp @@ -2,6 +2,7 @@ #define MOVE_BG_MAP_OBJ_BALL_HPP #include +#include class TMapObjBall : public TMapObjGeneral { public: @@ -28,6 +29,27 @@ class TMapObjBall : public TMapObjGeneral { virtual void calcCurrentMtx(); void boundByActor(THitActor*); + + /* 0x148 */ f32 unk148; + /* 0x14C */ f32 unk14C; + /* 0x150 */ f32 unk150; + /* 0x154 */ f32 unk154; + /* 0x158 */ f32 unk158; + /* 0x15C */ f32 unk15C; + /* 0x160 */ f32 unk160; + /* 0x164 */ f32 unk164; + /* 0x168 */ f32 unk168; + /* 0x16C */ f32 unk16C; + /* 0x170 */ f32 unk170; + /* 0x174 */ f32 unk174; + /* 0x178 */ f32 unk178; + /* 0x17C */ f32 unk17C; + /* 0x180 */ f32 unk180; + /* 0x184 */ f32 unk184; + /* 0x188 */ f32 unk188; + /* 0x18C */ f32 unk18C; + /* 0x190 */ f32 unk190; + /* 0x194 */ s32 unk194; }; class TResetFruit : public TMapObjBall { @@ -61,18 +83,26 @@ class TResetFruit : public TMapObjBall { void makeObjLiving(); void makeObjWaitingToAppear(); - u32 mFruitLivingTime; - u32 mScaleUpSpeed; - u32 mRottingScaleSpeed; - u32 mBreakingScaleSpeed; - u32 mFruitWaitTimeToAppear; - u32 mRottenColor; + void touchKillSurface(); + + inline void hideTouchActor(THitActor*); + + static u32 mFruitWaitTimeToAppear; + static f32 mScaleUpSpeed; + static u32 mFruitLivingTime; + static f32 mBreakingScaleSpeed; + + f32 unk198; + GXColorS10 mRottenColor; + u8 unk1A4; }; class TRandomFruit : public TResetFruit { public: TRandomFruit(const char* name = "ランダムフルーツ"); virtual void initMapObj(); + + char mFruitName[0x20]; }; class TCoverFruit : public TMapObjBase { @@ -90,7 +120,7 @@ class TBigWatermelon : public TMapObjBall { virtual void loadAfter(); virtual BOOL receiveMessage(THitActor* sender, u32 message); - virtual void control() { } + virtual void control(); virtual void kill(); virtual void initMapObj(); virtual void touchActor(THitActor*); @@ -102,6 +132,10 @@ class TBigWatermelon : public TMapObjBall { virtual void touchWaterSurface(); void startEvent(); + + TWaterEmitInfo* unk198; + s32 unk19C; + f32 unk1A0; }; #endif diff --git a/include/MoveBG/MapObjBase.hpp b/include/MoveBG/MapObjBase.hpp index 0347ed54..5505b645 100644 --- a/include/MoveBG/MapObjBase.hpp +++ b/include/MoveBG/MapObjBase.hpp @@ -58,6 +58,7 @@ struct TMapObjCollisionInfo { // fabricated struct TMapObjSoundData { /* 0x0 */ u32 unk0[10]; + /* 0x40 */ u32 unk40; }; // fabricated diff --git a/include/MoveBG/MapObjGeneral.hpp b/include/MoveBG/MapObjGeneral.hpp index 80629057..106b7a30 100644 --- a/include/MoveBG/MapObjGeneral.hpp +++ b/include/MoveBG/MapObjGeneral.hpp @@ -65,7 +65,7 @@ class TMapObjGeneral : public TMapObjBase { static f32 mNormalThrowSpeedRate; public: - /* 0x138 */ const TBGCheckData* unk138; // TODO: maybe not const + /* 0x138 */ TBGCheckData* unk138; /* 0x13C */ const TBGCheckData* unk13C; /* 0x140 */ f32 unk140; /* 0x144 */ f32 unk144; diff --git a/src/MoveBG/MapObjBall.cpp b/src/MoveBG/MapObjBall.cpp index 8b137891..62439e1e 100644 --- a/src/MoveBG/MapObjBall.cpp +++ b/src/MoveBG/MapObjBall.cpp @@ -1 +1,1721 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// rogue includes needed for matching sinit & bss +#include +#include + +extern float SMS_GetSandRiseUpRatio(const TLiveActor* actor); +extern bool gParticleFlagLoaded[0x201]; +extern JPAResourceManager* gpResourceManager; + +static const char* const unusedString1 = "\0\0\0\0\0\0\0\0\0\0\0"; +static const char* const unusedString2 = "メモリが足りません\n"; +static const char* const unusedString3 + = "MActorMtxCalcType_Basic クラシックスケールON"; +static const char* const unusedString4 + = "MActorMtxCalcType_Softimage クラシックスケールOFF"; +static const char* const unusedString5 + = "MActorMtxCalcType_MotionBlend モーションブレンド"; +static const char* const unusedString6 = "MActorMtxCalcType_User ユーザー定義"; + +u32 TResetFruit::mFruitLivingTime = 14400; +f32 TResetFruit::mScaleUpSpeed = 1.05f; +f32 TResetFruit::mBreakingScaleSpeed = 0.96f; +u32 TResetFruit::mFruitWaitTimeToAppear = 360; + +void TMapObjBall::touchRoof(JGeometry::TVec3* param1) +{ + if (param1->y > unk140) { + param1->y = unk140; + } + + calcReflectingVelocity(unk13C, mMapObjData->mPhysical->unk4->unk4, + &mVelocity); +} + +inline f32 vecLength(JGeometry::TVec3 vec) { return vec.length(); } + +void TMapObjBall::touchWall(JGeometry::TVec3* param1, + TBGWallCheckRecord* param2) +{ + if (!checkLiveFlag2(0x80) && !isActorType(0x400000d0)) { + f32 velMag = vecLength(mVelocity); + mVelocity.y += unk184 * velMag; + } + + for (s32 iVar1 = 0, iVar3 = 0; iVar1 < param2->mResultWallsNum; + ++iVar1, ++iVar3) { + TBGCheckData* pVar1 = param2->mResultWalls[iVar3]; + JGeometry::TVec3 velCopy = mVelocity; + f32 fVar4 = velCopy.dot(pVar1->mNormal); + if (fVar4 < 0.0f) { + f32 fVar5 = param1->dot(pVar1->mNormal) + pVar1->mPlaneDistance; + param1->x += (mBodyRadius - fVar5) * pVar1->mNormal.x; + param1->z += (mBodyRadius - fVar5) * pVar1->mNormal.z; + f32 fVar6 = fVar4 * -(-1.0f + mMapObjData->mPhysical->unk4->unk8); + mVelocity.x += fVar6 * pVar1->mNormal.x; + mVelocity.z += fVar6 * pVar1->mNormal.z; + if (isActorType(0x400000d0)) { + if (mScaling.y >= 5.0f) { + f32 fVar6 = abs(vecLength(mVelocity)); + if (gpMSound->gateCheck(0x308a) != 0) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x308a, &mPosition, nullptr, fVar6, 0, 0, nullptr, + 0, 0x4); + } + } else { + f32 fVar6 = abs(vecLength(mVelocity)); + if (gpMSound->gateCheck(0x308b) != 0) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x308b, &mPosition, nullptr, fVar6, 0, 0, nullptr, + 0, 0x4); + } + } + } else { + u32 uVar1 = mMapObjData->mSound->unk4->unk0[4]; + if (gpMSound->gateCheck(uVar1) != 0) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + uVar1, &mPosition, &mVelocity, 0.0f, 0, 0, nullptr, 0, + 0x4); + } + } + } + } +} + +void TMapObjBall::touchPollution() { kill(); } + +void TMapObjBall::touchWaterSurface() { kill(); } + +void TMapObjBall::rebound(JGeometry::TVec3* wall) +{ + calcReflectingVelocity(mGroundPlane, mMapObjData->mPhysical->unk4->unk4, + &mVelocity); + wall->y = mGroundHeight; + onLiveFlag(LIVE_FLAG_AIRBORNE); + + if (isActorType(0x400000d0)) { + f32 soundY; + if (mScaling.y >= 5.0f) { + soundY = abs(mGroundPlane->mNormal.y); + if (gpMSound->gateCheck(0x3889)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x3889, &mPosition, nullptr, soundY, 0, 0, nullptr, 0, 4); + } + } else { + soundY = abs(mGroundPlane->mNormal.y); + if (gpMSound->gateCheck(0x388C)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x388C, &mPosition, nullptr, soundY, 0, 0, nullptr, 0, 4); + } + } + } else { + u32 soundID = mMapObjData->mSound->unk4->unk0[4]; + if (gpMSound->gateCheck(soundID)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + soundID, &mPosition, &mVelocity, 0.0f, 0, 0, nullptr, 0, 4); + } + } +} + +void TMapObjBall::touchGround(JGeometry::TVec3* ground) +{ + f32 fVar1 = abs(vecLength(mVelocity)); + if (fVar1 > 0.05f && isActorType(0x400000d0)) { + if (mScaling.y >= 5.0f) { + if (gpMSound->gateCheck(0x308a)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x308a, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, 4); + } + } else { + if (gpMSound->gateCheck(0x308b)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x308b, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, 4); + } + } + } + + if (mGroundPlane->isWaterSurface()) { + touchWaterSurface(); + ground->set(mPosition); + } else { + if (gpPollution->isPolluted(ground->x, ground->y, ground->z)) { + touchPollution(); + ground->set(mPosition); + } else { + if (mVelocity.y > -unk188) { + offLiveFlag(LIVE_FLAG_AIRBORNE); + mVelocity.y = 0.0f; + ground->y = mGroundHeight; + } else { + rebound(ground); + } + + if (!checkLiveFlag2(0x80)) { + mVelocity.x += unk180 * mGroundPlane->mNormal.x; + mVelocity.z += unk180 * mGroundPlane->mNormal.z; + } + + mVelocity.x *= mMapObjData->mPhysical->unk4->unk10; + mVelocity.z *= mMapObjData->mPhysical->unk4->unk10; + + f32 unkC = mMapObjData->mPhysical->unk4->unkC; + if (isActorType(0x400000d0) + && (abs(mVelocity.x) > mMapObjData->mPhysical->unk4->unkC + || abs(mVelocity.z) > mMapObjData->mPhysical->unk4->unkC)) { + if (gpMSound->gateCheck(0x1009)) { + MSoundSESystem::MSoundSE::startSoundActor( + 0x1009, &mPosition, nullptr, nullptr, 0, 4); + } + } + } + } +} + +void TMapObjBall::put() +{ + TMapObjGeneral::put(); + calcCurrentMtx(); +} + +void TMapObjBall::hold(TTakeActor* holder) +{ + if (vecLength(mVelocity) > 10.0f) { + return; + } + + TMapObjGeneral::hold(holder); + mVelocity.zero(); +} + +void TMapObjBall::kicked() +{ + JGeometry::TVec3 velCopy = mVelocity; + JGeometry::TVec3 velCopy2 = velCopy; + if (velCopy2.y > 0.0f) { + return; + } + + JGeometry::TVec3 velCopy3 = velCopy; + + if (velCopy3.y == 0.0f) { + mVelocity.y = unk178; + } else { + JGeometry::TVec3 velCopy4 = velCopy; + mVelocity.y = unk174 * *gpMarioSpeedY - unk160 * velCopy4.y; + } + + mVelocity.x += unk170 * *gpMarioSpeedX; + mVelocity.z += unk170 * *gpMarioSpeedZ; + + f32 unkC = mMapObjData->mPhysical->unk4->unkC; + if (abs(mVelocity.x) < unkC && abs(mVelocity.z) < unkC) { + mVelocity.x = MsRandF() * 2.0f - 1.0f; + mVelocity.z = MsRandF() * 2.0f - 1.0f; + } + + unk194 = 10; + offLiveFlag(LIVE_FLAG_UNK10); + onLiveFlag(LIVE_FLAG_AIRBORNE); + + THitActor* marHitActor = SMS_GetMarioHitActor(); + marHitActor->receiveMessage(this, 14); + if (!isActorType(0x400000d0)) { + gpMSound->startSoundActor(0x194f, &mPosition, nullptr, nullptr, 0, 4); + } +} + +u32 TMapObjBall::touchWater(THitActor* water) +{ + if (!isState(6)) { + if (isState(2)) { + return 1; + } + + JGeometry::TVec3 velCopy = mVelocity; + const JGeometry::TVec3& waterSpeed + = TMapObjBase::getWaterSpeed(water); + + velCopy.x = waterSpeed.x * unk17C + velCopy.x; + velCopy.y = waterSpeed.y * unk17C + velCopy.y; + velCopy.z = waterSpeed.z * unk17C + velCopy.z; + mVelocity = velCopy; + offLiveFlag(LIVE_FLAG_UNK10); + } + + return 1; +} + +void TMapObjBall::boundByActor(THitActor* actor) +{ + JGeometry::TVec3 offsetToActor; + offsetToActor.x = actor->mPosition.x - mPosition.x; + offsetToActor.z = actor->mPosition.z - mPosition.z; + offsetToActor.y = 0.0f; + + f32 fVar1 = isActorType(0x400000d0) ? mAttackRadius + actor->mDamageRadius + : mDamageRadius; + + if (!(offsetToActor.x * offsetToActor.x + offsetToActor.z * offsetToActor.z + < fVar1 * fVar1)) { + if (offsetToActor.x != 0.0f && offsetToActor.z != 0.0f) { + MsVECNormalize(offsetToActor, offsetToActor); + } + if (actor->isActorType(0x80000001)) { + if (!checkMapObjFlag(0x2000000)) { + f32 unkC = mMapObjData->mPhysical->unk4->unkC; + if (abs(*gpMarioSpeedX) > unkC || abs(*gpMarioSpeedZ) > unkC) { + mVelocity.y += unk150; + if (!isActorType(0x400000d0)) { + gpMSound->startSoundActor(0x194f, &mPosition, nullptr, + nullptr, 0, 4); + } + } else { + mVelocity.y += unk154; + } + + mVelocity.x + += unk148 * *gpMarioSpeedX - offsetToActor.x * unk14C; + mVelocity.z + += unk148 * *gpMarioSpeedZ - offsetToActor.z * unk14C; + actor->receiveMessage(this, 14); + } + } else { + f32 fVar2 = mVelocity.z * offsetToActor.z + + mVelocity.x * offsetToActor.x + + mVelocity.y * offsetToActor.y; + if ((fVar2 >= 0.0f) + && (abs(mVelocity.x) > mMapObjData->mPhysical->unk4->unkC) + && (abs(mVelocity.z) > mMapObjData->mPhysical->unk4->unkC)) { + mVelocity.x -= (unk16C + 1.0f) * offsetToActor.x * fVar2; + mVelocity.y += unk168; + mVelocity.z -= (unk16C + 1.0f) * offsetToActor.z * fVar2; + actor->receiveMessage(this, 16); + if (!isActorType(0x400000d0) && gpMSound->gateCheck(0x3862)) { + MSoundSESystem::MSoundSE::startSoundActor( + 0x3862, &mPosition, nullptr, nullptr, 0, 4); + } + } else { + mVelocity.x -= (offsetToActor.x * unk164); + mVelocity.y += unk168; + mVelocity.z -= (offsetToActor.z * unk164); + } + } + if (actor->isActorType(0x80000001) && !checkMapObjFlag(0x2000000) + && mVelocity.y < 0.0f + && gpMarioPos->y + 130.0f < mPosition.y + mBodyRadius) { + JGeometry::TVec3 vec; + mVelocity.y = (-unk160) * mVelocity.y; + mVelocity.x += unk158 * *gpMarioSpeedX; + mVelocity.y += unk15C * *gpMarioSpeedY; + mVelocity.z += unk158 * *gpMarioSpeedZ; + + if (!isActorType(0x400000d0) && gpMSound->gateCheck(0x194f)) { + MSoundSESystem::MSoundSE::startSoundActor( + 0x194f, mPosition, nullptr, nullptr, 0, 4); + } + } + unk194 = 10; + offLiveFlag(LIVE_FLAG_UNK10); + onLiveFlag(LIVE_FLAG_AIRBORNE); + } +} + +inline void gekkoCopy(void* dst, void* src) +{ + JGeometry::gekko_ps_copy12(dst, src); +} + +void TMapObjBall::touchActor(THitActor* actor) +{ + if ((!unk194 == 0 || isState(6)) || TMapObjBase::isHideObj(actor) + || actor->isActorType(0x8000083) || actor->isActorType(0x400000ca) + || actor->isActorType(0x400000cc)) { + return; + } else { + if (actor->isActorType(0x80000001) && !isActorType(0x400000d0) + && *gpMarioSpeedY != 0.0f) { + kicked(); + } else { + boundByActor(actor); + } + } +} + +void TMapObjBall::calcCurrentMtx() +{ + Mtx local48; + local48[2][3] = 0.0f; + local48[1][3] = 0.0f; + local48[0][3] = 0.0f; + local48[1][2] = 0.0f; + local48[0][2] = 0.0f; + local48[2][1] = 0.0f; + local48[0][1] = 0.0f; + local48[2][0] = 0.0f; + local48[1][0] = 0.0f; + local48[2][2] = 1.0f; + local48[1][1] = 1.0f; + local48[0][0] = 1.0f; + JGeometry::TVec3 vec = mVelocity; + if (abs(mVelocity.x) < mMapObjData->mPhysical->unk4->unkC) { + JGeometry::TVec3 vec2 = mVelocity; + if (abs(mVelocity.z) < mMapObjData->mPhysical->unk4->unkC + && mGroundPlane->mNormal.y == 1.0f) { + mVelocity.x = 0.0f; + mVelocity.z = 0.0f; + } + } + + JGeometry::TVec3 vec3 = mVelocity; + if (!(abs(mVelocity.x) > mMapObjData->mPhysical->unk4->unkC)) { + JGeometry::TVec3 vec4 = mVelocity; + if (!(abs(mVelocity.z) > mMapObjData->mPhysical->unk4->unkC)) { + goto todo; + } + } + + JGeometry::TVec3 vec5 = mVelocity; + JGeometry::TVec3 vec6 = vec5; + TMapObjBase::getVerticalVecToTargetXZ(mPosition.x + mVelocity.x, + mPosition.z + mVelocity.z, &vec); + JGeometry::TVec3 vec7 = mVelocity; + JGeometry::TVec3 vec8 = vec7; + f32 fVar1 = mVelocity.x; + f32 fVar2 = mVelocity.z; + fVar1 = fVar1 * fVar1 + fVar2 * fVar2; + if (fVar1 < 0.0f) { + fVar2 = JGeometry::TUtil::inv_sqrt(fVar1); + fVar1 = fVar1 * (fVar2 / 2.0f) * -(fVar1 * fVar2 * fVar2 - 3.0f); + } + f32 dVar8 = 1.0f; + f32 dVar7 = (fVar1 / mBodyRadius) * 2.0f; + f32 dVar3 = vec.dot(vec); + JGeometry::TVec3 local124; + if (dVar3 <= 3.814697265625e-06f) { + local124.z = 0.0f; + local124.y = 0.0f; + local124.x = 0.0f; + } else { + dVar3 = JGeometry::TUtil::inv_sqrt(dVar3); + local124.scale(dVar8 * dVar3, vec); + } + + f32 fVar9 = sinf(dVar7); + dVar3 = fVar9; + fVar9 = cosf(dVar7); + dVar7 = fVar9; + f32 dVar6 = local124.x; + f32 dVar5 = 1.0f - dVar7; + dVar8 = local124.y; + f32 dVar4 = local124.z; + local48[0][0] = dVar5 * (dVar6 * dVar6) + dVar7; + fVar9 = dVar8 * (dVar5 * dVar6); + fVar1 = dVar4 * (dVar5 * dVar6); + local48[0][1] = fVar9 - (dVar3 * dVar4); + local48[0][2] = fVar1 + (dVar3 * dVar8); + local48[1][0] = fVar9 + (dVar3 * dVar4); + fVar9 = dVar4 * (dVar5 * dVar8); + local48[1][1] = dVar5 * (dVar8 * dVar8) + dVar7; + local48[1][2] = fVar9 - (dVar3 * dVar6); + local48[2][0] = fVar1 - (dVar3 * dVar8); + local48[2][1] = fVar9 + (dVar3 * dVar6); + local48[2][2] = dVar5 * (dVar4 * dVar4) + dVar7; +todo: + Mtx afStack94; + gekkoCopy(afStack94, *(getModel()->getAnmMtx(0))); + JGeometry::TVec3 vec9(0.0f); + PSMTXConcat(local48, afStack94, local48); + local48[0][3] = mPosition.x; + local48[1][3] = mPosition.y + mBodyRadius; + local48[2][3] = mPosition.z; + if (isActorType(0x40000394) && local48[1][1] > 0.0f) { + local48[1][3] = -(local48[1][1] * 50.0f - local48[1][3]); + } + if (isActorType(0x40000392)) { + local48[1][3] = -((1.0f - local48[1][1]) * 10.0f - local48[1][3]); + } + + J3DModel* model = getModel(); + PSMTXCopy(local48, model->getAnmMtx(0)); +} + +void TMapObjBall::checkWallCollision(JGeometry::TVec3* wall) +{ + TBGWallCheckRecord wallRecord; + wallRecord.mCenter.x = wall->x; + wallRecord.mCenter.y = mBodyRadius + wall->y; + wallRecord.mCenter.z = wall->z; + wallRecord.mRadius = mBodyRadius; + wallRecord.mFlags = mMapObjData->mPhysical->mWallCheckFlags; + wallRecord.mMaxResults = 4; + if (gpMap->isTouchedWallsAndMoveXZ(&wallRecord)) { + unk138 = wallRecord.mResultWalls[0]; + wall->x = wallRecord.mCenter.x; + wall->z = wallRecord.mCenter.z; + touchWall(wall, &wallRecord); + } else { + unk138 = nullptr; + } +} + +void TMapObjBall::makeObjDefault() +{ + TMapObjBase::makeObjDefault(); + J3DModel* model = TLiveActor::getModel(); + MtxPtr nodeMatrix = model->getAnmMtx(0); + nodeMatrix[0][3] = mPosition.x; + nodeMatrix[1][3] = mPosition.y + mBodyRadius; + nodeMatrix[1][3] = mPosition.z; +} + +void TMapObjBall::makeObjAppeared() +{ + TMapObjBase::makeObjAppeared(); + calcCurrentMtx(); + J3DModel* model = TLiveActor::getModel(); + MtxPtr nodeMatrix = model->getAnmMtx(0); + nodeMatrix[0][3] = mPosition.x; + nodeMatrix[1][3] = mPosition.y + mBodyRadius; + nodeMatrix[2][3] = mPosition.z; + + if (isActorType(0x40000394)) { + if (nodeMatrix[1][1] > 0.0f) { + nodeMatrix[1][3] -= 50.0f * nodeMatrix[1][1]; + } + } + + if (isActorType(0x40000392)) { + nodeMatrix[1][3] -= 10.0f * (1.0f - nodeMatrix[1][1]); + } + + unkE8 = 0; +} + +void TMapObjBall::control() +{ + TMapObjGeneral::control(); + if (unk194 != 0) { + unk194 -= 1; + } + + if (isState(6)) { + TTakeActor* holder = mHolder; + MtxPtr takingMtx = holder->getTakingMtx(); + Mtx takingMtxCopy; + PSMTXCopy(takingMtx, takingMtxCopy); + f32 mtxEntry = takingMtxCopy[2][2]; + mtxEntry += unk190; + J3DModel* model = TLiveActor::getModel(); + PSMTXCopy(takingMtxCopy, model->getAnmMtx(0)); + } else { + if (!(mVelocity.squared() <= 3.8146973e-6f) + || mGroundPlane->mActor != nullptr) { + calcCurrentMtx(); + } + } +} + +BOOL TMapObjBall::receiveMessage(THitActor* actor, u32 msg) +{ + if (TMapObjGeneral::receiveMessage(actor, msg) != 0) { + return TRUE; + } + + if (msg == 4) { + if (checkMapObjFlag(0x100000)) { + hold(static_cast(actor)); + return TRUE; + } + } + + if (actor->isActorType(0x80000001) && !isActorType(0x400000d0)) { + if (msg != 4) { + kicked(); + return TRUE; + } + } + + return FALSE; +} + +void TMapObjBall::initMapObj() +{ + TMapObjGeneral::initMapObj(); + mInitialScaling.set(mScaling); + switch (mActorType) { + case 0x400000d0: { + unk14C = 4.0f; + unk150 = 0.0f; + unk154 = 0.0f; + unk158 = 0.15f; + unk15C = 0.0f; + unk160 = 0.9f; + unk164 = 0.06f; + unk168 = 1.5f; + unk16C = 0.5f; + unk170 = 0.5f; + unk174 = 0.2f; + unk178 = 2.5f; + unk17C = 0.001f; + unk180 = 0.3f; + unk184 = 1.5f; + unk188 = 1.5f; + mBodyRadius = 50.0f * mScaling.y; + unk18C = mBodyRadius / 3.0f; + break; + } + case 0x40000064: { + unk148 = 0.6f; + unk14C = 2.0f; + unk150 = 0.02f; + unk154 = 0.0f; + unk158 = 0.055f; + unk15C = 0.02f; + unk160 = 0.83f; + unk170 = 0.9f; + unk174 = 0.13f; + unk178 = 20.0f; + unk164 = 0.5f; + unk168 = 0.02f; + unk16C = 0.5f; + unk17C = 1.2f; + unk180 = 0.8f; + unk184 = 1.0f; + unk188 = 1.5f; + mBodyRadius = 50.0f * mScaling.y; + unk18C = mBodyRadius / 3.0f; + break; + } + case 0x40000393: { + unk148 = 0.6f; + unk14C = 0.2f; + unk150 = 1.3f; + unk154 = 15.0f; + unk158 = 0.5f; + unk15C = 1.3f; + unk160 = 1.0f; + unk170 = 0.9f; + unk174 = 0.13f; + unk178 = 20.0f; + unk164 = 2.0f; + unk168 = 0.02f; + unk16C = 0.3f; + unk17C = 0.05f; + unk180 = 0.5f; + unk184 = 1.0f; + unk188 = 1.5f; + mBodyRadius = 50.0f * mScaling.y; + unk18C = 50.0f; + break; + } + case 0x40000390: + case 0x40000391: + case 0x40000392: { + unk148 = 0.4f; + unk14C = 0.2f; + unk150 = 1.3f; + unk154 = 0.0f; + unk158 = 1.2f; + unk15C = 0.8f; + unk160 = 0.5f; + unk170 = 0.9f; + unk174 = 0.13f; + unk178 = 20.0f; + unk164 = 2.0f; + unk168 = 0.02f; + unk16C = 0.3f; + unk17C = 0.05f; + unk180 = 0.5f; + unk184 = 1.0f; + unk188 = 1.5f; + mBodyRadius = 50.0f * mScaling.y; + unk18C = 50.0f; + break; + } + case 0x40000394: { + unk148 = 0.2f; + unk14C = 0.0f; + unk150 = 0.0f; + unk154 = 0.0f; + unk158 = 0.0f; + unk15C = 0.0f; + unk160 = 0.0f; + unk170 = 0.0f; + unk174 = 0.0f; + unk178 = 0.0f; + unk164 = 0.0f; + unk168 = 0.0f; + unk16C = 0.0f; + unk17C = 0.05f; + unk180 = 0.5f; + unk184 = 1.0f; + unk188 = 1.5f; + mBodyRadius = 50.0f * mScaling.y; + unk18C = 50.0f; + break; + } + case 0x40000395: { + unk148 = 0.4f; + unk14C = 0.2f; + unk150 = 1.3f; + unk154 = 0.0f; + unk158 = 1.2f; + unk15C = 0.8f; + unk160 = 0.5f; + unk170 = 0.9f; + unk174 = 0.13f; + unk178 = 20.0f; + unk164 = 2.0f; + unk168 = 0.02f; + unk16C = 0.3f; + unk17C = 0.05f; + unk180 = 0.5f; + unk184 = 1.0f; + unk188 = 1.5f; + mBodyRadius = 50.0f * mScaling.y; + unk18C = 50.0f; + break; + } + } + + if (isActorType(0x40000393)) { + mBodyRadius = mScaling.y * 45.0f; + unk190 = mBodyRadius; + } + if (isActorType(0x40000390)) { + mBodyRadius = mScaling.y * 40.0f; + unk190 = 20.0f; + } + if (isActorType(0x40000391)) { + mBodyRadius = mScaling.y * 40.0f; + unk190 = 20.0f; + } + if (isActorType(0x40000392)) { + unk190 = 10.0f; + } +} + +TMapObjBall::TMapObjBall(const char* name) + : TMapObjGeneral(name) +{ + unk148 = 0.f; + unk14C = 0.f; + unk150 = 0.f; + unk154 = 0.f; + unk158 = 0.f; + unk15C = 0.f; + unk160 = 0.f; + unk164 = 0.f; + unk168 = 0.f; + unk16C = 0.f; + unk170 = 0.f; + unk174 = 0.f; + unk178 = 0.f; + unk17C = 0.0f; + unk180 = 0.0f; + unk184 = 0.0f; + unk188 = 0.0f; + unk18C = 0.0f; + unk190 = 0.0f; + unk194 = 0; + mInitialScaling.z = 0.0f; + mInitialScaling.y = 0.0f; + mInitialScaling.x = 0.0f; +} + +void TResetFruit::checkGroundCollision(JGeometry::TVec3* ground) +{ + if (gpMarDirector->mMap != 7 && gpMarDirector->mMap != 4) { + TMapObjGeneral::checkGroundCollision(ground); + } else if (gpMarDirector->mMap == 4) { + mGroundHeight = gpMap->checkGround(ground->x, ground->y + 200.0f, + ground->z, &mGroundPlane); + mGroundHeight += 1.0f; + if (ground->y <= mGroundHeight) { + touchGround(ground); + } else { + onLiveFlag(0x80); + } + } else { + mGroundHeight = gpMap->checkGround(ground->x, ground->y + mHeadHeight, + ground->z, &mGroundPlane); + + bool bVar1; + if (mGroundPlane->mBGType + == BG_TYPE_EVERYTHING_BUT_MAP_OBJECTS_PHASE_THROUGH + || mGroundPlane->mBGType == BG_TYPE_MAP_CHANGE_PHASE_THROUGH) { + bVar1 = true; + } else { + bVar1 = false; + } + + if (bVar1) { + mGroundHeight = gpMap->checkGroundExactY( + ground->x, mGroundHeight - 200.0f, ground->z, &mGroundPlane); + } + + mGroundHeight += 1.0f; + if (ground->y <= mGroundHeight) { + touchGround(ground); + } else { + onLiveFlag(0x80); + } + } +} + +void TResetFruit::waitingToAppear() +{ + if (gpMarDirector->mMap == 3 && unk1A4 != 0) { + makeObjDead(); + } + + if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear() && mColCount == 0) { + onMapObjFlag(0x40000); + makeObjAppeared(); + Mtx scaleMat; + PSMTXScale(scaleMat, 0.2f, 0.2f, 0.2f); + MtxPtr nodeMats = getModel()->getAnmMtx(0); + TMapObjBase::concatOnlyRotFromLeft(scaleMat, getModel()->getAnmMtx(0), + nodeMats); + + mScaling.y = 0.2f; + onHitFlag(HIT_FLAG_NO_COLLISION); + mState = 2; + gpMSound->startSoundActor(0x3802, &mPosition, nullptr, nullptr, 0, 4); + } +} + +void TResetFruit::makeObjWaitingToAppear() +{ + mState = 11; + makeObjDefault(); + makeObjDead(); + calcRootMatrix(); + J3DModel* model = TLiveActor::getModel(); + model->calc(); + mTimeTilAppear = mFruitWaitTimeToAppear; + offMapObjFlag(0x40000); + mState = 10; + if (gpMarDirector->mMap == 3) { + if (unk1A4 != 0) { + makeObjDead(); + } + } +} + +void TResetFruit::thrown() +{ + TMapObjGeneral::thrown(); + mState = 11; +} + +void TResetFruit::hold(TTakeActor* actor) +{ + if (!(vecLength(mVelocity) > 10.0f)) { + TMapObjGeneral::hold(actor); + mVelocity.zero(); + } + + mVelocity.zero(); + onLiveFlag(0x10); + if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear()) { + onMapObjFlag(0x40000); + mTimeTilAppear = getLivingTime(); + } +} + +void TResetFruit::touchKillSurface() +{ + makeObjDefault(); + mState = 11; + makeObjDefault(); + makeObjDead(); + calcRootMatrix(); + getModel()->calc(); + mTimeTilAppear = mFruitWaitTimeToAppear; + offMapObjFlag(0x40000); + mState = 10; + if (gpMarDirector->getCurrentMap() == 3 && unk1A4 != 0) { + makeObjDead(); + } +} + +void TResetFruit::touchPollution() +{ + gpMarioParticleManager->emitAndBindToPosPtr(0x8b, &mPosition, 0, nullptr); + gpMSound->startSoundActor(0x3881, &mPosition, nullptr, nullptr, 0, 4); + + touchKillSurface(); +} + +void TResetFruit::touchWaterSurface() +{ + TMapObjBase::emitColumnWater(); + gpMSound->startSoundActor(0x3875, &mPosition, nullptr, nullptr, 0, 4); + + touchKillSurface(); +} + +u32 TResetFruit::touchWater(THitActor* water) +{ + if (!isState(6) && !isState(2)) { + JGeometry::TVec3 velCopy = mVelocity; + const JGeometry::TVec3& waterSpeed + = TMapObjBase::getWaterSpeed(water); + + mVelocity.x = waterSpeed.x * unk17C + velCopy.x; + mVelocity.y = waterSpeed.y * unk17C + velCopy.y; + mVelocity.z = waterSpeed.z * unk17C + velCopy.z; + offLiveFlag(0x10); + } + + if (!isWaitingToAppear()) { + onMapObjFlag(0x40000); + mTimeTilAppear = getLivingTime(); + } + + offLiveFlag(0x10); + mState = 11; + + return 1; +} + +void TResetFruit::hideTouchActor(THitActor* actor) +{ + TMapObjBall::touchActor(actor); +} + +void TResetFruit::touchActor(THitActor* actor) +{ + if (!isState(2) && !isState(3) && !isState(12) && !isState(10)) { + hideTouchActor(actor); + if (!checkMapObjFlag(0x4000000) && isState(1) && !checkLiveFlag(0x10)) { + if (!isWaitingToAppear()) { + onMapObjFlag(0x40000); + mTimeTilAppear = getLivingTime(); + } + offLiveFlag(0x10); + mState = 11; + } + } +} + +void TResetFruit::touchGround(JGeometry::TVec3* ground) +{ + if (getGroundPlane()->isDeathPlane()) { + mState = 11; + makeObjDefault(); + makeObjDead(); + calcRootMatrix(); + J3DModel* model = TLiveActor::getModel(); + model->calc(); + mTimeTilAppear = mFruitWaitTimeToAppear; + offMapObjFlag(0x40000); + mState = 10; + if (gpMarDirector->getCurrentMap() == 3) { + if (unk1A4 != 0) { + makeObjDead(); + } + } + + ground->set(getPosition()); + } else { + TMapObjBall::touchGround(ground); + } +} + +void TResetFruit::makeObjLiving() +{ + if (!isWaitingToAppear()) { + onMapObjFlag(0x40000); + mTimeTilAppear = getLivingTime(); + } + + offLiveFlag(0x10); + mState = 11; +} + +void TResetFruit::kicked() +{ + if (!checkMapObjFlag(0x2000000) && !isState(6)) { + if (*gpMarioSpeedY < 0.0f) { + return; + } else { + if (mVelocity.y <= 0.0f && checkLiveFlag2(0x80) + && mVelocity.x * gpMarioPos->x - mPosition.x + + mVelocity.z * gpMarioPos->z - mPosition.z + + mVelocity.y * 0.0f + > 0.0f) { + if (mVelocity.y == 0.0f) { + mVelocity.y = unk178; + } else { + mVelocity.y + = unk174 * *gpMarioSpeedY - unk160 * mVelocity.y; + } + + mVelocity.x += unk170 * *gpMarioSpeedX; + mVelocity.z += unk170 * *gpMarioSpeedZ; + + f32 unkC = mMapObjData->mPhysical->unk4->unkC; + if (abs(mVelocity.x) < unkC && abs(mVelocity.z) < unkC) { + mVelocity.x = MsRandF() * 2.0f - 1.0f; + mVelocity.z = MsRandF() * 2.0f - 1.0f; + } + + unk194 = 10; + offLiveFlag(0x10); + SMS_GetMarioHitActor()->receiveMessage(this, 14); + gpMSound->startSoundActor(0x194f, &mPosition, nullptr, nullptr, + 0, 4); + } + } + } +} + +void TResetFruit::breaking() +{ + Mtx scaleMtx; + PSMTXScale(scaleMtx, 1.0f, mBreakingScaleSpeed, 1.0f); + J3DModel* model = getModel(); + MtxPtr nodeMat = model->getAnmMtx(0); + TMapObjBase::concatOnlyRotFromLeft(scaleMtx, nodeMat, nodeMat); + mScaling.y *= mBreakingScaleSpeed; + nodeMat[1][3] = mBodyRadius * mScaling.y + mPosition.y; + if (mScaling.y < 0.2f) { + mPosition.y += mBodyRadius / 2.0f; + mScaling.set(mInitialScaling); + emitAndScale(229, 0, &mPosition); + + gpMSound->startSoundActor(0x387d, &mPosition, nullptr, nullptr, 0, 4); + mTimeTilAppear = 240; + sleep(); + mState = 13; + } +} + +void TResetFruit::appearing() +{ + MtxPtr scaleMatCopy; + Mtx scaleMat; + PSMTXScale(scaleMat, mScaleUpSpeed, mScaleUpSpeed, mScaleUpSpeed); + J3DModel* model2 = TLiveActor::getModel(); + scaleMatCopy = model2->getAnmMtx(0); + TMapObjBase::concatOnlyRotFromLeft(scaleMat, scaleMatCopy, scaleMatCopy); + mScaling.y = mScaling.y * mScaleUpSpeed; + mScaledBodyRadius = mBodyRadius * mScaling.y; + scaleMatCopy[1][3] = mBodyRadius * mScaling.y + mPosition.y; + if (mScaling.y >= mInitialScaling.y) { + mScaling.set(mInitialScaling); + J3DModel* model = TLiveActor::getModel(); + model->calc(); + unk64 &= ~0x1; + makeObjAppeared(); + mState = 1; + } +} + +void TResetFruit::control() +{ + f32 unused4C; + switch (mState) { + case 1: { + unk64 &= ~0x1; + for (s32 iVar6 = 0, iVar5 = 0; iVar6 < mColCount; ++iVar6, ++iVar5) { + THitActor* hitActor = mCollisions[iVar5]; + if (!isState(2) && !isState(3) && !isState(12) && !isState(10)) { + hideTouchActor(hitActor); + if (!checkMapObjFlag(0x4000000) && isState(1) + && !checkLiveFlag(0x10)) { + if (!isWaitingToAppear()) { + onMapObjFlag(0x40000); + mTimeTilAppear = getLivingTime(); + } + offLiveFlag(0x10); + mState = 11; + } + } + } + + if (mGroundPlane->mActor != nullptr) { + calcCurrentMtx(); + } + break; + } + case 11: { + unk64 &= ~0x1; + if (gpMarDirector->mMap == 4 && checkLiveFlag(0x10)) { + offLiveFlag(0x10); + } + + if (mGroundPlane->mActor != nullptr) { + if (checkLiveFlag(0x10)) { + offLiveFlag(0x10); + } + + const TLiveActor* actor = mGroundPlane->mActor; + if (mPosition.y < mGroundHeight + 200.0f + && !actor->isActorType(0x400000cd)) { + if (actor->isActorType(0x400000cd)) { + f32 prevUnk198 = unk198; + unk198 = SMS_GetSandRiseUpRatio(actor); + if (unk198 > 0.05f && unk198 > prevUnk198) { + mVelocity.y += 20.0f; + } + } + } + } else { + unk198 = 0.0f; + } + + TMapObjBall::control(); + if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear()) { + if (mHolder != nullptr) { + mHolder->receiveMessage(this, 8); + mHolder->mHeldObject = nullptr; + mHolder = nullptr; + } + + mVelocity.setAll(0.0f); + mState = 12; + } + break; + } + case 6: { + TMapObjBall::control(); + if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear()) { + if (mHolder != nullptr) { + mHolder->receiveMessage(this, 8); + mHolder->mHeldObject = nullptr; + mHolder = nullptr; + } + + mVelocity.setAll(0.0f); + mState = 12; + } + break; + } + case 2: + case 3: { + TMapObjGeneral::control(); + if (unk194 != 0) { + unk194 -= 1; + } + + if (isState(6)) { + Mtx takingMtx; + PSMTXCopy(mHolder->getTakingMtx(), takingMtx); + unused4C += unk190; + PSMTXCopy(takingMtx, getModel()->getAnmMtx(0)); + } else { + if (!(3.8146973e-06f <= mVelocity.squared()) + || mGroundPlane->mActor != nullptr) { + calcCurrentMtx(); + } + } + break; + } + case 12: { + mPosition.y += mBodyRadius / 2.0f; + mScaling.set(mInitialScaling); + emitAndScale(229, 0, &mPosition); + if (gpMSound->gateCheck(0x387d)) { + MSoundSESystem::MSoundSE::startSoundActor(0x387d, &mPosition, + nullptr, nullptr, 0, 4); + } + + mTimeTilAppear = 240; + sleep(); + mState = 13; + break; + } + case 13: { + if (!isWaitingToAppear()) { + mRottenColor.r = 0xff; + mRottenColor.g = 0xff; + mRottenColor.b = 0xff; + awake(); + mState = 11; + makeObjDefault(); + makeObjDead(); + calcRootMatrix(); + getModel()->calc(); + mTimeTilAppear = mFruitWaitTimeToAppear; + offMapObjFlag(0x40000); + mState = 10; + if (gpMarDirector->mMap == 3 && unk1A4 != 0) { + makeObjDead(); + } + } + break; + } + } +} + +inline f32 squaredVec(JGeometry::TVec3 vec) +{ + return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z; +} + +void TResetFruit::perform(u32 param1, JDrama::TGraphics* graphics) +{ + if (gpMarDirector->mMap == 7) { + if (isState(6) || !(squaredVec(mVelocity) <= 3.8146973e-6f)) { + if (checkLiveFlag(0x200)) { + offLiveFlag(0x200); + } + } else { + if (!gpCubeArea->isInAreaCube(mPosition) && isState(11)) { + if (mPosition.x != mInitialPosition.x + || mPosition.z != mInitialPosition.z) { + makeObjWaitingToAppear(); + return; + } + } + } + } + + TMapObjGeneral::perform(param1, graphics); +} + +void TResetFruit::killByTimer(int timer) +{ + mTimeTilAppear = timer; + onMapObjFlag(0x40000); + mState = 11; +} + +void TResetFruit::makeObjAppeared() +{ + if (checkMapObjFlag(0x4000000)) { + makeObjDefault(); + } + + TMapObjBase::makeObjAppeared(); + calcCurrentMtx(); + J3DModel* model = getModel(); + MtxPtr nodeMat = model->getAnmMtx(0); + nodeMat[0][3] = mPosition.x; + nodeMat[1][3] = mPosition.y + mBodyRadius; + nodeMat[2][3] = mPosition.z; + if (isActorType(0x40000394) && nodeMat[1][1] > 0.0f) { + nodeMat[1][3] -= 50.0f * nodeMat[1][1]; + } + + if (isActorType(0x40000392)) { + nodeMat[1][3] -= 10.0f * (1.0f - nodeMat[1][1]); + } + + unkE8 = 0; + if (checkMapObjFlag(0x4000000)) { + mState = 11; + } +} + +u32 TResetFruit::getLivingTime() const { return mFruitLivingTime; } + +BOOL TResetFruit::receiveMessage(THitActor* actor, u32 msg) +{ + BOOL res; + if (msg == 11) { + if (isState(1) || isState(6) || isState(11)) { + makeObjWaitingToAppear(); + res = TRUE; + } else { + res = FALSE; + } + } else if (msg == 13) { + kill(); + res = TRUE; + } else { + if (isState(1) || isState(6) || isState(11)) { + if (!isState(2) && !isState(3) && !isState(12) && !isState(10)) { + hideTouchActor(actor); + if (!checkMapObjFlag(0x4000000) && isState(1) + && !checkLiveFlag(0x10)) { + if (!isWaitingToAppear()) { + onMapObjFlag(0x40000); + mTimeTilAppear = getLivingTime(); + } + offLiveFlag(0x10); + mState = 11; + } + } + + if (TMapObjGeneral::receiveMessage(actor, msg) != 0) { + res = TRUE; + } else { + if (msg == 4 && checkMapObjFlag(0x100000)) { + hold(static_cast(actor)); + res = TRUE; + } else if (actor->isActorType(0x80000001) + && !isActorType(0x400000d0) && msg != 4) { + kicked(); + res = TRUE; + } else { + res = FALSE; + } + } + + if (msg == 6 && isState(1)) { + mState = 11; + } + } else { + res = FALSE; + } + } + + return res; +} + +void TResetFruit::initMapObj() +{ + TMapObjBall::initMapObj(); + + J3DModel* model = TLiveActor::getModel(); + SMS_InitPacket_OneTevColor(model, 0, GX_TEVREG0, &mRottenColor); +} + +TResetFruit::TResetFruit(const char* name) + : TMapObjBall(name) +{ + unk198 = 0.0f; + unk1A4 = 0; + mRottenColor.r = 0xff; + mRottenColor.g = 0xff; + mRottenColor.b = 0xff; + mRottenColor.a = 0xff; +} + +void TRandomFruit::initMapObj() +{ + s32 fruitNum = MsRandF() * 5.0f; + switch (fruitNum) { + case 0: { + snprintf(mFruitName, sizeof(mFruitName), "FruitCoconut"); + break; + } + case 1: { + snprintf(mFruitName, sizeof(mFruitName), "FruitDurian"); + break; + } + case 2: { + snprintf(mFruitName, sizeof(mFruitName), "FruitPapaya"); + break; + } + case 3: { + snprintf(mFruitName, sizeof(mFruitName), "FruitPine"); + break; + } + default: { + snprintf(mFruitName, sizeof(mFruitName), "FruitPine"); + break; + } + } + + unkF4 = mFruitName; + TMapObjBall::initMapObj(); + SMS_InitPacket_OneTevColor(getModel(), 0, GX_TEVREG0, &mRottenColor); +} + +TRandomFruit::TRandomFruit(const char* name) + : TResetFruit(name) +{ + memset((void*)&mFruitName, 0, sizeof(mFruitName)); +} + +void TCoverFruit::calcRootMatrix() +{ + if (mHolder != nullptr) { + MtxPtr takingMtx = mHolder->getTakingMtx(); + J3DModel* model = getModel(); + PSMTXCopy(takingMtx, model->unk20); + mPosition.set(takingMtx[0][3], takingMtx[1][3], takingMtx[2][3]); + } else { + f32 fVar1 = mRotation.z; + f32 fVar2 = (mPosition.y - mYOffset); + f32 fVar3 = mRotation.y; + f32 fVar4 = mRotation.x; + f32 fVar5 = mPosition.z; + f32 fVar6 = mPosition.x; + MsMtxSetXYZRPH(getModel()->unk20, fVar6, fVar5, fVar4, fVar3, fVar2, + fVar1); + } + + J3DModel* model = getModel(); + model->unk14 = mScaling; +} + +BOOL TCoverFruit::receiveMessage(THitActor* actor, u32 msg) +{ + if (actor->isActorType(0x8000083) && msg == 4) { + onHitFlag(HIT_FLAG_NO_COLLISION); + mHolder = static_cast(actor); + return TRUE; + } else if (msg == 11) { + kill(); + TFlagManager::smInstance->setBool(true, 0x1038b); + return TRUE; + } else { + return FALSE; + } +} + +void TCoverFruit::loadAfter() +{ + TMapObjBase::loadAfter(); + if (TFlagManager::smInstance->getBool(0x1038b)) { + makeObjDead(); + } +} + +void TBigWatermelon::touchWaterSurface() +{ + TMapObjBase::emitColumnWater(); + gpMSound->startSoundActor(0x3875, &mPosition, nullptr, nullptr, 0, 4); + kill(); +} + +void TBigWatermelon::touchWall(JGeometry::TVec3* wall, + TBGWallCheckRecord* record) +{ + TMapObjBall::touchWall(wall, record); +} + +void TBigWatermelon::rebound(JGeometry::TVec3* surface) +{ + if (isState(12)) { + kill(); + (*surface) = mPosition; + } else { + TMapObjBase::calcReflectingVelocity( + mGroundPlane, mMapObjData->mPhysical->unk4->unk4, &mVelocity); + surface->y = mGroundHeight; + onLiveFlag(0x80); + if (isActorType(0x400000d0)) { + f32 fVar1; + if (mScaling.y >= 5.0f) { + fVar1 = abs(mGroundPlane->mNormal.y); + if (gpMSound->gateCheck(0x3889)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x3889, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, + 4); + } + } else { + fVar1 = abs(mGroundPlane->mNormal.y); + if (gpMSound->gateCheck(0x388c)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + 0x388c, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, + 4); + } + } + } else { + u32 soundID = mMapObjData->mSound->unk4->unk0[4]; + if (gpMSound->gateCheck(soundID)) { + MSoundSESystem::MSoundSE::startSoundActorWithInfo( + soundID, &mPosition, &mVelocity, 0.0f, 0, 0, nullptr, 0, 4); + } + } + if (isState(11)) { + mState = 12; + } + } +} + +void TBigWatermelon::touchGround(JGeometry::TVec3* ground) +{ + TMapObjBall::touchGround(ground); +} + +// This inline probably lives on a class higher up the inheritance chain +inline bool isFalling(JGeometry::TVec3& vel) +{ + JGeometry::TVec3 velCopy(vel); + return velCopy.y < 0.0f; +} + +void TBigWatermelon::touchActor(THitActor* actor) +{ + if (!isState(2)) { + if (isState(1) || isFalling(mVelocity)) { + kill(); + } else { + if (actor->isActorType(0x80000001)) { + f32 fVar1 = mPosition.x - actor->mPosition.x; + f32 fVar2 = mPosition.y - actor->mPosition.y; + f32 fVar3 = mPosition.z - actor->mPosition.z; + f32 fVar4 = fVar2 * fVar2; + fVar4 += fVar3 * fVar3 + fVar1 * fVar1; + if (fVar4 <= 0.0f) { + fVar2 = __frsqrte(fVar4); + fVar4 = fVar4 * fVar2 / 2.0f + * -(fVar4 * fVar2 * fVar2 - 3.0f); + } + if (fVar4 < mBodyRadius * 0.6f) { + kill(); + return; + } + } + + if (actor->isActorType(0x10000015)) { + if (static_cast(actor)->isMoving()) { + if (!(abs(mVelocity.y) + < mMapObjData->mPhysical->unk4->unkC)) { + return; + } + + mVelocity.y += 30.0f; + mState = 11; + return; + } + } + + if (unk194 == 0 && !isState(6)) { + if (!TMapObjBase::isHideObj(actor) + && !actor->isActorType(0x8000083) + && !actor->isActorType(0x400000ca) + && !actor->isActorType(0x400000cc)) { + if (actor->isActorType(0x80000001) + && !isActorType(0x400000d0) && *gpMarioSpeedY != 0.0f) { + kicked(); + } else { + TMapObjBall::boundByActor(actor); + } + } + } + } + } +} + +void TBigWatermelon::kill() +{ + TMapObjBase::emitAndScale(0x5d, 0, &mPosition); + TMapObjBase::emitAndScale(0x5e, 0, &mPosition); + TMapObjBase::emitAndScale(0x5f, 0, &mPosition); + JGeometry::TVec3 vec(1.0f, 1.0f, 1.0f); + TMapObjBase::emitAndScale(0x6b, 0, &mPosition, vec); + TMapObjBase::emitAndScale(0x6c, 0, &mPosition, vec); + TWaterEmitInfo* emitInfo = unk198; + emitInfo->mPos.value = mPosition; + gpModelWaterManager->emitRequest(*unk198); + gpMSound->startSoundActor(0x38a3, &mPosition, nullptr, nullptr, 0, 4); + + if (unk19C < 10) { + TMapObjBase* mapObj = gpItemManager->makeObjAppear( + mPosition.x, mPosition.y, mPosition.z, 0x2000000e, true); + + if (mapObj != nullptr) { + mapObj->mVelocity.set(0.0f, 25.0f, 0.0f); + mapObj->offLiveFlag(0x10); + ++unk19C; + } + } + TMapObjGeneral::kill(); +} + +void TBigWatermelon::appearing() +{ + TMapObjGeneral::appearing(); + MtxPtr nodeMats = getModel()->getAnmMtx(0); + calcRootMatrix(); + J3DModel* model = getModel(); + model->calc(); + nodeMats[1][3] + = mBodyRadius * (mScaling.y / mInitialScaling.y) + mPosition.y; + mScaledBodyRadius = mScaling.x * 50.0f; + mDamageRadius = mScaling.x * 50.0f; + calcEntryRadius(); + if (isState(1)) { + mActorType = 0x400000d0; + mAttackRadius = mScaling.x * 50.0f; + calcEntryRadius(); + } else { + mActorType = 0x400000db; + mAttackRadius = 0.0f; + calcEntryRadius(); + } +} + +void TBigWatermelon::control() +{ + TMapObjGeneral::control(); + if (unk194 != 0) { + unk194 -= 1; + } + + f32 local3C; + if (isState(6)) { + TTakeActor* holder = mHolder; + MtxPtr takingMtx = holder->getTakingMtx(); + Mtx takingMtxCopy; + PSMTXCopy(takingMtx, takingMtxCopy); + local3C += unk190; + J3DModel* model = TLiveActor::getModel(); + PSMTXCopy(takingMtxCopy, model->getAnmMtx(0)); + } else { + if (!(squaredVec(mVelocity) <= 3.8146973e-06f) + || mGroundPlane->mActor != nullptr) { + calcCurrentMtx(); + } + } + + switch (mState) { + case 1: { + if (checkLiveFlag(LIVE_FLAG_UNK10)) { + offLiveFlag(0x10); + } + const TLiveActor* groundPlaneActor = mGroundPlane->mActor; + if (mPosition.y < mGroundHeight + 200.0f + && groundPlaneActor != nullptr) { + if (mGroundPlane->mActor->isActorType(0x400000cd) + || mGroundPlane->mActor->isActorType(0x400000cd)) { + f32 prevUnk1A0 = unk1A0; + unk1A0 = SMS_GetSandRiseUpRatio(mGroundPlane->mActor); + if (unk1A0 > 0.05f && unk1A0 > prevUnk1A0) { + mVelocity.y += 20.0f; + } + } + } + } break; + case 2: + case 10: + case 11: + case 12: + break; + case 13: { + if (!isWaitingToAppear()) { + JGeometry::TVec3 vec(1.0f, 1.0f, 1.0f); + TMapObjBase::emitAndScale(0x6b, 0, &mPosition, vec); + TMapObjBase::emitAndScale(0x6c, 0, &mPosition, vec); + mTimeTilAppear = 30; + } + if (TMapObjBase::animIsFinished()) { + makeObjDead(); + } + break; + } + } +} + +void TBigWatermelon::startEvent() +{ + if (strcmp(getName(), "スイカ(大)") == 0) { + mPosition.set(-4660.0f, 1300.0f, 13600.0f); + offMapObjFlag(0x100); + onLiveFlag(LIVE_FLAG_UNK10); + mVelocity.zero(); + onLiveFlag(LIVE_FLAG_UNK10); + TMapObjBase::startAnim(7); + // getter? + TMarDirector* director = gpMarDirector; + director->fireStartDemoCamera("スイカゴールカメラ", &mPosition, -1, + 0.0f, true, nullptr, 0, nullptr, 0); + gpItemManager->makeShineAppearWithDemoOffset( + "シャイン(お化けスイカ用)", "スイカシャインカメラ", 0.0f, 0.0f, + 0.0f); + mTimeTilAppear = 380; + mState = 13; + } else { + for (s32 i = 0; i < 10; ++i) { + TItem* item = static_cast(gpItemManager->makeObjAppear( + gpMarioPos->x, gpMarioPos->y, gpMarioPos->z, 0x2000000e, true)); + if (item != nullptr) { + f32 randZ = 20.0f * (MsRandF() - 0.5f); + f32 randY = 20.0f * MsRandF() + 20.0f; + item->mVelocity.x = 20.0f * (MsRandF() - 0.5f); + item->mVelocity.y = randY; + item->mVelocity.z = randZ; + item->offLiveFlag(LIVE_FLAG_UNK10); + item->unk14C = 960; + } + } + makeObjDead(); + } +} + +void TBigWatermelon::checkWallCollision(JGeometry::TVec3* wall) +{ + TMapObjGeneral::checkWallCollision(wall); +} + +BOOL TBigWatermelon::receiveMessage(THitActor* actor, u32 msg) +{ + if (actor->isActorType(0x80000001)) { + TMapObjBall::boundByActor(actor); + return TRUE; + } + + if (TMapObjGeneral::receiveMessage(actor, msg)) { + return TRUE; + } else { + if (msg == 4 && checkMapObjFlag(0x100000)) { + hold(static_cast(actor)); + return TRUE; + } else if (actor->isActorType(0x80000001) && !isActorType(0x400000d0) + && msg != 4) { + kicked(); + return TRUE; + } else { + return FALSE; + } + } +} + +void TBigWatermelon::loadAfter() +{ + TMapObjGeneral::loadAfter(); + TLiveActor* foo + = JDrama::TNameRefGen::search("シャイン(お化けスイカ用)"); + foo->mPosition.set(-4659.0f, 460.0f, 13620.0f); +} + +inline void loadParticle(u32 flagIdx, const char* resPath) +{ + if (gParticleFlagLoaded[flagIdx] == 0) { + gpResourceManager->load(resPath, flagIdx); + gParticleFlagLoaded[flagIdx] = 1; + } +} + +void TBigWatermelon::initMapObj() +{ + TMapObjBall::initMapObj(); + loadParticle(0x5d, "/scene/mapObj/watermelon_bomb.jpa"); + loadParticle(0x5e, "/scene/mapObj/watermelon_bomb_a.jpa"); + loadParticle(0x5f, "/scene/mapObj/watermelon_bomb_b.jpa"); + loadParticle(0x6b, "/scene/mapObj/watermelon_shrink_a.jpa"); + loadParticle(0x6c, "/scene/mapObj/watermelon_shrink_b.jpa"); + + TWaterEmitInfo* emitInfo = new TWaterEmitInfo("/watermelon.prm"); + unk198 = emitInfo; +} + +TBigWatermelon::TBigWatermelon(const char* name) + : TMapObjBall(name) +{ + unk198 = nullptr; + unk19C = 0; + unk1A0 = 0; +} From 544558c45e6a0ac9639622a9a53720383bf934e0 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Fri, 29 May 2026 00:24:11 +0100 Subject: [PATCH 2/7] General cleanup Moved defintion of TMapObjGeneral::getLivingTime to MapObjGeneral.cpp as the definition in the header was masking the overwrite in MapObjBall --- include/MoveBG/MapObjBall.hpp | 4 +- include/MoveBG/MapObjGeneral.hpp | 2 +- src/MoveBG/MapObjBall.cpp | 281 +++++++++++-------------------- src/MoveBG/MapObjGeneral.cpp | 4 +- 4 files changed, 110 insertions(+), 181 deletions(-) diff --git a/include/MoveBG/MapObjBall.hpp b/include/MoveBG/MapObjBall.hpp index ea5989d9..8c0795e1 100644 --- a/include/MoveBG/MapObjBall.hpp +++ b/include/MoveBG/MapObjBall.hpp @@ -30,6 +30,8 @@ class TMapObjBall : public TMapObjGeneral { void boundByActor(THitActor*); + inline void kick(); + /* 0x148 */ f32 unk148; /* 0x14C */ f32 unk14C; /* 0x150 */ f32 unk150; @@ -93,7 +95,7 @@ class TResetFruit : public TMapObjBall { static f32 mBreakingScaleSpeed; f32 unk198; - GXColorS10 mRottenColor; + GXColorS10 mFruitColor; u8 unk1A4; }; diff --git a/include/MoveBG/MapObjGeneral.hpp b/include/MoveBG/MapObjGeneral.hpp index 106b7a30..23e6722e 100644 --- a/include/MoveBG/MapObjGeneral.hpp +++ b/include/MoveBG/MapObjGeneral.hpp @@ -24,7 +24,7 @@ class TMapObjGeneral : public TMapObjBase { virtual void checkIllegalAttr() const { } virtual void touchPlayer(THitActor*); virtual u32 touchWater(THitActor*); - virtual u32 getLivingTime() const { return mNormalLivingTime; } + virtual u32 getLivingTime() const; virtual int getFlushTime() const { } virtual bool isPollutedGround(const JGeometry::TVec3&) const; virtual void work(); diff --git a/src/MoveBG/MapObjBall.cpp b/src/MoveBG/MapObjBall.cpp index 62439e1e..9cc923ae 100644 --- a/src/MoveBG/MapObjBall.cpp +++ b/src/MoveBG/MapObjBall.cpp @@ -30,6 +30,7 @@ extern float SMS_GetSandRiseUpRatio(const TLiveActor* actor); extern bool gParticleFlagLoaded[0x201]; extern JPAResourceManager* gpResourceManager; +// These strings exist in the .rodata but aren't used from what I can tell static const char* const unusedString1 = "\0\0\0\0\0\0\0\0\0\0\0"; static const char* const unusedString2 = "メモリが足りません\n"; static const char* const unusedString3 @@ -45,6 +46,16 @@ f32 TResetFruit::mScaleUpSpeed = 1.05f; f32 TResetFruit::mBreakingScaleSpeed = 0.96f; u32 TResetFruit::mFruitWaitTimeToAppear = 360; +inline f32 squaredVec(JGeometry::TVec3 vec) +{ + return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z; +} + +inline bool objIsNotMoving(JGeometry::TVec3& vel) +{ + return squaredVec(vel) <= 1 / 262144.0f; +} + void TMapObjBall::touchRoof(JGeometry::TVec3* param1) { if (param1->y > unk140) { @@ -80,26 +91,19 @@ void TMapObjBall::touchWall(JGeometry::TVec3* param1, if (isActorType(0x400000d0)) { if (mScaling.y >= 5.0f) { f32 fVar6 = abs(vecLength(mVelocity)); - if (gpMSound->gateCheck(0x308a) != 0) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x308a, &mPosition, nullptr, fVar6, 0, 0, nullptr, - 0, 0x4); - } + gpMSound->startSoundActorWithInfo(0x308a, &mPosition, + nullptr, fVar6, 0, 0, + nullptr, 0, 0x4); } else { f32 fVar6 = abs(vecLength(mVelocity)); - if (gpMSound->gateCheck(0x308b) != 0) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x308b, &mPosition, nullptr, fVar6, 0, 0, nullptr, - 0, 0x4); - } + gpMSound->startSoundActorWithInfo(0x308b, &mPosition, + nullptr, fVar6, 0, 0, + nullptr, 0, 0x4); } } else { u32 uVar1 = mMapObjData->mSound->unk4->unk0[4]; - if (gpMSound->gateCheck(uVar1) != 0) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - uVar1, &mPosition, &mVelocity, 0.0f, 0, 0, nullptr, 0, - 0x4); - } + gpMSound->startSoundActorWithInfo(uVar1, &mPosition, &mVelocity, + 0.0f, 0, 0, nullptr, 0, 0x4); } } } @@ -120,23 +124,17 @@ void TMapObjBall::rebound(JGeometry::TVec3* wall) f32 soundY; if (mScaling.y >= 5.0f) { soundY = abs(mGroundPlane->mNormal.y); - if (gpMSound->gateCheck(0x3889)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x3889, &mPosition, nullptr, soundY, 0, 0, nullptr, 0, 4); - } + gpMSound->startSoundActorWithInfo(0x3889, &mPosition, nullptr, + soundY, 0, 0, nullptr, 0, 4); } else { soundY = abs(mGroundPlane->mNormal.y); - if (gpMSound->gateCheck(0x388C)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x388C, &mPosition, nullptr, soundY, 0, 0, nullptr, 0, 4); - } + gpMSound->startSoundActorWithInfo(0x388C, &mPosition, nullptr, + soundY, 0, 0, nullptr, 0, 4); } } else { u32 soundID = mMapObjData->mSound->unk4->unk0[4]; - if (gpMSound->gateCheck(soundID)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - soundID, &mPosition, &mVelocity, 0.0f, 0, 0, nullptr, 0, 4); - } + gpMSound->startSoundActorWithInfo(soundID, &mPosition, &mVelocity, 0.0f, + 0, 0, nullptr, 0, 4); } } @@ -145,15 +143,11 @@ void TMapObjBall::touchGround(JGeometry::TVec3* ground) f32 fVar1 = abs(vecLength(mVelocity)); if (fVar1 > 0.05f && isActorType(0x400000d0)) { if (mScaling.y >= 5.0f) { - if (gpMSound->gateCheck(0x308a)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x308a, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, 4); - } + gpMSound->startSoundActorWithInfo(0x308a, &mPosition, nullptr, + fVar1, 0, 0, nullptr, 0, 4); } else { - if (gpMSound->gateCheck(0x308b)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x308b, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, 4); - } + gpMSound->startSoundActorWithInfo(0x308b, &mPosition, nullptr, + fVar1, 0, 0, nullptr, 0, 4); } } @@ -185,10 +179,8 @@ void TMapObjBall::touchGround(JGeometry::TVec3* ground) if (isActorType(0x400000d0) && (abs(mVelocity.x) > mMapObjData->mPhysical->unk4->unkC || abs(mVelocity.z) > mMapObjData->mPhysical->unk4->unkC)) { - if (gpMSound->gateCheck(0x1009)) { - MSoundSESystem::MSoundSE::startSoundActor( - 0x1009, &mPosition, nullptr, nullptr, 0, 4); - } + gpMSound->startSoundActor(0x1009, &mPosition, nullptr, nullptr, + 0, 4); } } } @@ -218,26 +210,7 @@ void TMapObjBall::kicked() return; } - JGeometry::TVec3 velCopy3 = velCopy; - - if (velCopy3.y == 0.0f) { - mVelocity.y = unk178; - } else { - JGeometry::TVec3 velCopy4 = velCopy; - mVelocity.y = unk174 * *gpMarioSpeedY - unk160 * velCopy4.y; - } - - mVelocity.x += unk170 * *gpMarioSpeedX; - mVelocity.z += unk170 * *gpMarioSpeedZ; - - f32 unkC = mMapObjData->mPhysical->unk4->unkC; - if (abs(mVelocity.x) < unkC && abs(mVelocity.z) < unkC) { - mVelocity.x = MsRandF() * 2.0f - 1.0f; - mVelocity.z = MsRandF() * 2.0f - 1.0f; - } - - unk194 = 10; - offLiveFlag(LIVE_FLAG_UNK10); + kick(); onLiveFlag(LIVE_FLAG_AIRBORNE); THitActor* marHitActor = SMS_GetMarioHitActor(); @@ -313,9 +286,9 @@ void TMapObjBall::boundByActor(THitActor* actor) mVelocity.y += unk168; mVelocity.z -= (unk16C + 1.0f) * offsetToActor.z * fVar2; actor->receiveMessage(this, 16); - if (!isActorType(0x400000d0) && gpMSound->gateCheck(0x3862)) { - MSoundSESystem::MSoundSE::startSoundActor( - 0x3862, &mPosition, nullptr, nullptr, 0, 4); + if (!isActorType(0x400000d0)) { + gpMSound->startSoundActor(0x3862, &mPosition, nullptr, + nullptr, 0, 4); } } else { mVelocity.x -= (offsetToActor.x * unk164); @@ -414,7 +387,7 @@ void TMapObjBall::calcCurrentMtx() f32 dVar7 = (fVar1 / mBodyRadius) * 2.0f; f32 dVar3 = vec.dot(vec); JGeometry::TVec3 local124; - if (dVar3 <= 3.814697265625e-06f) { + if (dVar3 <= 1 / 262144.0f) { local124.z = 0.0f; local124.y = 0.0f; local124.x = 0.0f; @@ -526,13 +499,11 @@ void TMapObjBall::control() MtxPtr takingMtx = holder->getTakingMtx(); Mtx takingMtxCopy; PSMTXCopy(takingMtx, takingMtxCopy); - f32 mtxEntry = takingMtxCopy[2][2]; - mtxEntry += unk190; + takingMtxCopy[2][2] += unk190; J3DModel* model = TLiveActor::getModel(); PSMTXCopy(takingMtxCopy, model->getAnmMtx(0)); } else { - if (!(mVelocity.squared() <= 3.8146973e-6f) - || mGroundPlane->mActor != nullptr) { + if (!objIsNotMoving(mVelocity) || mGroundPlane->mActor != nullptr) { calcCurrentMtx(); } } @@ -746,6 +717,27 @@ TMapObjBall::TMapObjBall(const char* name) mInitialScaling.x = 0.0f; } +inline void TMapObjBall::kick() +{ + if (mVelocity.y == 0.0f) { + mVelocity.y = unk178; + } else { + mVelocity.y = unk174 * *gpMarioSpeedY - unk160 * mVelocity.y; + } + + mVelocity.x += unk170 * *gpMarioSpeedX; + mVelocity.z += unk170 * *gpMarioSpeedZ; + + f32 unkC = mMapObjData->mPhysical->unk4->unkC; + if (abs(mVelocity.x) < unkC && abs(mVelocity.z) < unkC) { + mVelocity.x = MsRandF() * 2.0f - 1.0f; + mVelocity.z = MsRandF() * 2.0f - 1.0f; + } + + unk194 = 10; + offLiveFlag(LIVE_FLAG_UNK10); +} + void TResetFruit::checkGroundCollision(JGeometry::TVec3* ground) { if (gpMarDirector->mMap != 7 && gpMarDirector->mMap != 4) { @@ -757,7 +749,7 @@ void TResetFruit::checkGroundCollision(JGeometry::TVec3* ground) if (ground->y <= mGroundHeight) { touchGround(ground); } else { - onLiveFlag(0x80); + onLiveFlag(LIVE_FLAG_AIRBORNE); } } else { mGroundHeight = gpMap->checkGround(ground->x, ground->y + mHeadHeight, @@ -781,7 +773,7 @@ void TResetFruit::checkGroundCollision(JGeometry::TVec3* ground) if (ground->y <= mGroundHeight) { touchGround(ground); } else { - onLiveFlag(0x80); + onLiveFlag(LIVE_FLAG_AIRBORNE); } } } @@ -840,7 +832,7 @@ void TResetFruit::hold(TTakeActor* actor) } mVelocity.zero(); - onLiveFlag(0x10); + onLiveFlag(LIVE_FLAG_UNK10); if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear()) { onMapObjFlag(0x40000); mTimeTilAppear = getLivingTime(); @@ -879,7 +871,7 @@ void TResetFruit::touchWaterSurface() touchKillSurface(); } -u32 TResetFruit::touchWater(THitActor* water) +inline u32 TResetFruit::touchWater(THitActor* water) { if (!isState(6) && !isState(2)) { JGeometry::TVec3 velCopy = mVelocity; @@ -889,16 +881,10 @@ u32 TResetFruit::touchWater(THitActor* water) mVelocity.x = waterSpeed.x * unk17C + velCopy.x; mVelocity.y = waterSpeed.y * unk17C + velCopy.y; mVelocity.z = waterSpeed.z * unk17C + velCopy.z; - offLiveFlag(0x10); + offLiveFlag(LIVE_FLAG_UNK10); } - if (!isWaitingToAppear()) { - onMapObjFlag(0x40000); - mTimeTilAppear = getLivingTime(); - } - - offLiveFlag(0x10); - mState = 11; + makeObjLiving(); return 1; } @@ -912,13 +898,9 @@ void TResetFruit::touchActor(THitActor* actor) { if (!isState(2) && !isState(3) && !isState(12) && !isState(10)) { hideTouchActor(actor); - if (!checkMapObjFlag(0x4000000) && isState(1) && !checkLiveFlag(0x10)) { - if (!isWaitingToAppear()) { - onMapObjFlag(0x40000); - mTimeTilAppear = getLivingTime(); - } - offLiveFlag(0x10); - mState = 11; + if (!checkMapObjFlag(0x4000000) && isState(1) + && !checkLiveFlag(LIVE_FLAG_UNK10)) { + makeObjLiving(); } } } @@ -954,39 +936,22 @@ void TResetFruit::makeObjLiving() mTimeTilAppear = getLivingTime(); } - offLiveFlag(0x10); + offLiveFlag(LIVE_FLAG_UNK10); mState = 11; } void TResetFruit::kicked() { - if (!checkMapObjFlag(0x2000000) && !isState(6)) { + if (!checkMapObjFlag(LIVE_FLAG_UNK2000000) && !isState(6)) { if (*gpMarioSpeedY < 0.0f) { return; } else { - if (mVelocity.y <= 0.0f && checkLiveFlag2(0x80) + if (mVelocity.y <= 0.0f && checkLiveFlag2(LIVE_FLAG_AIRBORNE) && mVelocity.x * gpMarioPos->x - mPosition.x + mVelocity.z * gpMarioPos->z - mPosition.z + mVelocity.y * 0.0f > 0.0f) { - if (mVelocity.y == 0.0f) { - mVelocity.y = unk178; - } else { - mVelocity.y - = unk174 * *gpMarioSpeedY - unk160 * mVelocity.y; - } - - mVelocity.x += unk170 * *gpMarioSpeedX; - mVelocity.z += unk170 * *gpMarioSpeedZ; - - f32 unkC = mMapObjData->mPhysical->unk4->unkC; - if (abs(mVelocity.x) < unkC && abs(mVelocity.z) < unkC) { - mVelocity.x = MsRandF() * 2.0f - 1.0f; - mVelocity.z = MsRandF() * 2.0f - 1.0f; - } - - unk194 = 10; - offLiveFlag(0x10); + kick(); SMS_GetMarioHitActor()->receiveMessage(this, 14); gpMSound->startSoundActor(0x194f, &mPosition, nullptr, nullptr, 0, 4); @@ -1045,18 +1010,7 @@ void TResetFruit::control() unk64 &= ~0x1; for (s32 iVar6 = 0, iVar5 = 0; iVar6 < mColCount; ++iVar6, ++iVar5) { THitActor* hitActor = mCollisions[iVar5]; - if (!isState(2) && !isState(3) && !isState(12) && !isState(10)) { - hideTouchActor(hitActor); - if (!checkMapObjFlag(0x4000000) && isState(1) - && !checkLiveFlag(0x10)) { - if (!isWaitingToAppear()) { - onMapObjFlag(0x40000); - mTimeTilAppear = getLivingTime(); - } - offLiveFlag(0x10); - mState = 11; - } - } + TResetFruit::touchActor(hitActor); } if (mGroundPlane->mActor != nullptr) { @@ -1066,13 +1020,13 @@ void TResetFruit::control() } case 11: { unk64 &= ~0x1; - if (gpMarDirector->mMap == 4 && checkLiveFlag(0x10)) { - offLiveFlag(0x10); + if (gpMarDirector->mMap == 4 && checkLiveFlag(LIVE_FLAG_UNK10)) { + offLiveFlag(LIVE_FLAG_UNK10); } if (mGroundPlane->mActor != nullptr) { - if (checkLiveFlag(0x10)) { - offLiveFlag(0x10); + if (checkLiveFlag(LIVE_FLAG_UNK10)) { + offLiveFlag(LIVE_FLAG_UNK10); } const TLiveActor* actor = mGroundPlane->mActor; @@ -1141,10 +1095,7 @@ void TResetFruit::control() mPosition.y += mBodyRadius / 2.0f; mScaling.set(mInitialScaling); emitAndScale(229, 0, &mPosition); - if (gpMSound->gateCheck(0x387d)) { - MSoundSESystem::MSoundSE::startSoundActor(0x387d, &mPosition, - nullptr, nullptr, 0, 4); - } + gpMSound->startSoundActor(0x387d, &mPosition, nullptr, nullptr, 0, 4); mTimeTilAppear = 240; sleep(); @@ -1153,9 +1104,9 @@ void TResetFruit::control() } case 13: { if (!isWaitingToAppear()) { - mRottenColor.r = 0xff; - mRottenColor.g = 0xff; - mRottenColor.b = 0xff; + mFruitColor.r = 0xff; + mFruitColor.g = 0xff; + mFruitColor.b = 0xff; awake(); mState = 11; makeObjDefault(); @@ -1174,17 +1125,12 @@ void TResetFruit::control() } } -inline f32 squaredVec(JGeometry::TVec3 vec) -{ - return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z; -} - void TResetFruit::perform(u32 param1, JDrama::TGraphics* graphics) { if (gpMarDirector->mMap == 7) { - if (isState(6) || !(squaredVec(mVelocity) <= 3.8146973e-6f)) { - if (checkLiveFlag(0x200)) { - offLiveFlag(0x200); + if (isState(6) || !objIsNotMoving(mVelocity)) { + if (checkLiveFlag(LIVE_FLAG_UNK200)) { + offLiveFlag(LIVE_FLAG_UNK200); } } else { if (!gpCubeArea->isInAreaCube(mPosition) && isState(11)) { @@ -1234,7 +1180,7 @@ void TResetFruit::makeObjAppeared() } } -u32 TResetFruit::getLivingTime() const { return mFruitLivingTime; } +u32 TResetFruit::getLivingTime() const { return TResetFruit::mFruitLivingTime; } BOOL TResetFruit::receiveMessage(THitActor* actor, u32 msg) { @@ -1251,19 +1197,7 @@ BOOL TResetFruit::receiveMessage(THitActor* actor, u32 msg) res = TRUE; } else { if (isState(1) || isState(6) || isState(11)) { - if (!isState(2) && !isState(3) && !isState(12) && !isState(10)) { - hideTouchActor(actor); - if (!checkMapObjFlag(0x4000000) && isState(1) - && !checkLiveFlag(0x10)) { - if (!isWaitingToAppear()) { - onMapObjFlag(0x40000); - mTimeTilAppear = getLivingTime(); - } - offLiveFlag(0x10); - mState = 11; - } - } - + TResetFruit::touchActor(actor); if (TMapObjGeneral::receiveMessage(actor, msg) != 0) { res = TRUE; } else { @@ -1295,18 +1229,18 @@ void TResetFruit::initMapObj() TMapObjBall::initMapObj(); J3DModel* model = TLiveActor::getModel(); - SMS_InitPacket_OneTevColor(model, 0, GX_TEVREG0, &mRottenColor); + SMS_InitPacket_OneTevColor(model, 0, GX_TEVREG0, &mFruitColor); } TResetFruit::TResetFruit(const char* name) : TMapObjBall(name) { - unk198 = 0.0f; - unk1A4 = 0; - mRottenColor.r = 0xff; - mRottenColor.g = 0xff; - mRottenColor.b = 0xff; - mRottenColor.a = 0xff; + unk198 = 0.0f; + unk1A4 = 0; + mFruitColor.r = 0xff; + mFruitColor.g = 0xff; + mFruitColor.b = 0xff; + mFruitColor.a = 0xff; } void TRandomFruit::initMapObj() @@ -1337,7 +1271,7 @@ void TRandomFruit::initMapObj() unkF4 = mFruitName; TMapObjBall::initMapObj(); - SMS_InitPacket_OneTevColor(getModel(), 0, GX_TEVREG0, &mRottenColor); + SMS_InitPacket_OneTevColor(getModel(), 0, GX_TEVREG0, &mFruitColor); } TRandomFruit::TRandomFruit(const char* name) @@ -1413,30 +1347,22 @@ void TBigWatermelon::rebound(JGeometry::TVec3* surface) TMapObjBase::calcReflectingVelocity( mGroundPlane, mMapObjData->mPhysical->unk4->unk4, &mVelocity); surface->y = mGroundHeight; - onLiveFlag(0x80); + onLiveFlag(LIVE_FLAG_AIRBORNE); if (isActorType(0x400000d0)) { f32 fVar1; if (mScaling.y >= 5.0f) { fVar1 = abs(mGroundPlane->mNormal.y); - if (gpMSound->gateCheck(0x3889)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x3889, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, - 4); - } + gpMSound->startSoundActorWithInfo(0x3889, &mPosition, nullptr, + fVar1, 0, 0, nullptr, 0, 4); } else { fVar1 = abs(mGroundPlane->mNormal.y); - if (gpMSound->gateCheck(0x388c)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - 0x388c, &mPosition, nullptr, fVar1, 0, 0, nullptr, 0, - 4); - } + gpMSound->startSoundActorWithInfo(0x388c, &mPosition, nullptr, + fVar1, 0, 0, nullptr, 0, 4); } } else { u32 soundID = mMapObjData->mSound->unk4->unk0[4]; - if (gpMSound->gateCheck(soundID)) { - MSoundSESystem::MSoundSE::startSoundActorWithInfo( - soundID, &mPosition, &mVelocity, 0.0f, 0, 0, nullptr, 0, 4); - } + gpMSound->startSoundActorWithInfo(soundID, &mPosition, &mVelocity, + 0.0f, 0, 0, nullptr, 0, 4); } if (isState(11)) { mState = 12; @@ -1528,7 +1454,7 @@ void TBigWatermelon::kill() if (mapObj != nullptr) { mapObj->mVelocity.set(0.0f, 25.0f, 0.0f); - mapObj->offLiveFlag(0x10); + mapObj->offLiveFlag(LIVE_FLAG_UNK10); ++unk19C; } } @@ -1575,8 +1501,7 @@ void TBigWatermelon::control() J3DModel* model = TLiveActor::getModel(); PSMTXCopy(takingMtxCopy, model->getAnmMtx(0)); } else { - if (!(squaredVec(mVelocity) <= 3.8146973e-06f) - || mGroundPlane->mActor != nullptr) { + if (!objIsNotMoving(mVelocity) || mGroundPlane->mActor != nullptr) { calcCurrentMtx(); } } diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index fc47a3c4..9af43712 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -95,7 +95,7 @@ void TMapObjGeneral::put() s32 preservedTimeTilAppear = getTimeTilAppear(); makeObjAppeared(); mTimeTilAppear = preservedTimeTilAppear; - mPosition.x = JMASSin(*gpMarioAngleY) + mPosition.x = JMASSin(*gpMarioAngleY) * (getDamageRadius() + SMS_GetMarioDamageRadius() + 10.0f) + SMS_GetMarioPos().x; mPosition.y = SMS_GetMarioPos().y; @@ -333,6 +333,8 @@ void TMapObjGeneral::kill() breaking(); } +u32 TMapObjGeneral::getLivingTime() const { return mNormalLivingTime; } + void TMapObjGeneral::appear() { makeObjAppeared(); From 0a492fceeab372c6f507705b26f100c160896de2 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Fri, 29 May 2026 01:01:17 +0100 Subject: [PATCH 3/7] More code cleanup --- include/MoveBG/MapObjBall.hpp | 3 +- src/MoveBG/MapObjBall.cpp | 58 +++++++++++++++-------------------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/include/MoveBG/MapObjBall.hpp b/include/MoveBG/MapObjBall.hpp index 8c0795e1..7b4fe543 100644 --- a/include/MoveBG/MapObjBall.hpp +++ b/include/MoveBG/MapObjBall.hpp @@ -65,7 +65,7 @@ class TResetFruit : public TMapObjBall { virtual void initMapObj(); virtual void touchActor(THitActor*); virtual u32 touchWater(THitActor*); - virtual u32 getLivingTime() const; + virtual u32 getLivingTime() const { return mFruitLivingTime; }; virtual void appearing(); virtual void breaking(); virtual void waitingToAppear(); @@ -88,6 +88,7 @@ class TResetFruit : public TMapObjBall { void touchKillSurface(); inline void hideTouchActor(THitActor*); + inline void unknownInline(); static u32 mFruitWaitTimeToAppear; static f32 mScaleUpSpeed; diff --git a/src/MoveBG/MapObjBall.cpp b/src/MoveBG/MapObjBall.cpp index 9cc923ae..aa8cb02b 100644 --- a/src/MoveBG/MapObjBall.cpp +++ b/src/MoveBG/MapObjBall.cpp @@ -71,7 +71,7 @@ inline f32 vecLength(JGeometry::TVec3 vec) { return vec.length(); } void TMapObjBall::touchWall(JGeometry::TVec3* param1, TBGWallCheckRecord* param2) { - if (!checkLiveFlag2(0x80) && !isActorType(0x400000d0)) { + if (!checkLiveFlag2(LIVE_FLAG_AIRBORNE) && !isActorType(0x400000d0)) { f32 velMag = vecLength(mVelocity); mVelocity.y += unk184 * velMag; } @@ -167,7 +167,7 @@ void TMapObjBall::touchGround(JGeometry::TVec3* ground) rebound(ground); } - if (!checkLiveFlag2(0x80)) { + if (!checkLiveFlag2(LIVE_FLAG_AIRBORNE)) { mVelocity.x += unk180 * mGroundPlane->mNormal.x; mVelocity.z += unk180 * mGroundPlane->mNormal.z; } @@ -826,6 +826,7 @@ void TResetFruit::thrown() void TResetFruit::hold(TTakeActor* actor) { + // Most likely a call to TMapObjBall::hold, but calling it doesn't match if (!(vecLength(mVelocity) > 10.0f)) { TMapObjGeneral::hold(actor); mVelocity.zero(); @@ -841,7 +842,6 @@ void TResetFruit::hold(TTakeActor* actor) void TResetFruit::touchKillSurface() { - makeObjDefault(); mState = 11; makeObjDefault(); makeObjDead(); @@ -860,6 +860,7 @@ void TResetFruit::touchPollution() gpMarioParticleManager->emitAndBindToPosPtr(0x8b, &mPosition, 0, nullptr); gpMSound->startSoundActor(0x3881, &mPosition, nullptr, nullptr, 0, 4); + makeObjDefault(); touchKillSurface(); } @@ -867,7 +868,6 @@ void TResetFruit::touchWaterSurface() { TMapObjBase::emitColumnWater(); gpMSound->startSoundActor(0x3875, &mPosition, nullptr, nullptr, 0, 4); - touchKillSurface(); } @@ -1002,9 +1002,23 @@ void TResetFruit::appearing() } } +void TResetFruit::unknownInline() +{ + TMapObjBall::control(); + if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear()) { + if (mHolder != nullptr) { + mHolder->receiveMessage(this, 8); + mHolder->mHeldObject = nullptr; + mHolder = nullptr; + } + + mVelocity.setAll(0.0f); + mState = 12; + } +} + void TResetFruit::control() { - f32 unused4C; switch (mState) { case 1: { unk64 &= ~0x1; @@ -1044,31 +1058,11 @@ void TResetFruit::control() unk198 = 0.0f; } - TMapObjBall::control(); - if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear()) { - if (mHolder != nullptr) { - mHolder->receiveMessage(this, 8); - mHolder->mHeldObject = nullptr; - mHolder = nullptr; - } - - mVelocity.setAll(0.0f); - mState = 12; - } + unknownInline(); break; } case 6: { - TMapObjBall::control(); - if (!checkMapObjFlag(0x4000000) && !isWaitingToAppear()) { - if (mHolder != nullptr) { - mHolder->receiveMessage(this, 8); - mHolder->mHeldObject = nullptr; - mHolder = nullptr; - } - - mVelocity.setAll(0.0f); - mState = 12; - } + unknownInline(); break; } case 2: @@ -1081,11 +1075,10 @@ void TResetFruit::control() if (isState(6)) { Mtx takingMtx; PSMTXCopy(mHolder->getTakingMtx(), takingMtx); - unused4C += unk190; + takingMtx[2][2] += unk190; PSMTXCopy(takingMtx, getModel()->getAnmMtx(0)); } else { - if (!(3.8146973e-06f <= mVelocity.squared()) - || mGroundPlane->mActor != nullptr) { + if (!objIsNotMoving(mVelocity) || mGroundPlane->mActor != nullptr) { calcCurrentMtx(); } } @@ -1180,8 +1173,6 @@ void TResetFruit::makeObjAppeared() } } -u32 TResetFruit::getLivingTime() const { return TResetFruit::mFruitLivingTime; } - BOOL TResetFruit::receiveMessage(THitActor* actor, u32 msg) { BOOL res; @@ -1491,13 +1482,12 @@ void TBigWatermelon::control() unk194 -= 1; } - f32 local3C; if (isState(6)) { TTakeActor* holder = mHolder; MtxPtr takingMtx = holder->getTakingMtx(); Mtx takingMtxCopy; PSMTXCopy(takingMtx, takingMtxCopy); - local3C += unk190; + takingMtxCopy[2][2] += unk190; J3DModel* model = TLiveActor::getModel(); PSMTXCopy(takingMtxCopy, model->getAnmMtx(0)); } else { From 5f8281907f71bbd07fbb30d79400fea36dde27c7 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Fri, 29 May 2026 01:13:56 +0100 Subject: [PATCH 4/7] Revert moving TMapObjGeneral::getLivingTime as it regressed WoodBarrel. Added comment isntead --- include/MoveBG/MapObjBall.hpp | 4 +++- include/MoveBG/MapObjGeneral.hpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/MoveBG/MapObjBall.hpp b/include/MoveBG/MapObjBall.hpp index 7b4fe543..b648f7fb 100644 --- a/include/MoveBG/MapObjBall.hpp +++ b/include/MoveBG/MapObjBall.hpp @@ -65,7 +65,9 @@ class TResetFruit : public TMapObjBall { virtual void initMapObj(); virtual void touchActor(THitActor*); virtual u32 touchWater(THitActor*); - virtual u32 getLivingTime() const { return mFruitLivingTime; }; + // This definition is being occluded by TMapObjGeneral::getLivingTime for + // some reason + virtual u32 getLivingTime() const { return mFruitLivingTime; } virtual void appearing(); virtual void breaking(); virtual void waitingToAppear(); diff --git a/include/MoveBG/MapObjGeneral.hpp b/include/MoveBG/MapObjGeneral.hpp index 23e6722e..106b7a30 100644 --- a/include/MoveBG/MapObjGeneral.hpp +++ b/include/MoveBG/MapObjGeneral.hpp @@ -24,7 +24,7 @@ class TMapObjGeneral : public TMapObjBase { virtual void checkIllegalAttr() const { } virtual void touchPlayer(THitActor*); virtual u32 touchWater(THitActor*); - virtual u32 getLivingTime() const; + virtual u32 getLivingTime() const { return mNormalLivingTime; } virtual int getFlushTime() const { } virtual bool isPollutedGround(const JGeometry::TVec3&) const; virtual void work(); From 6a2397e374ae53a5650588c806db40e48d86bbc1 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Fri, 29 May 2026 01:15:55 +0100 Subject: [PATCH 5/7] Fix redefinition error --- src/MoveBG/MapObjGeneral.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index 9af43712..d5958586 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -333,8 +333,6 @@ void TMapObjGeneral::kill() breaking(); } -u32 TMapObjGeneral::getLivingTime() const { return mNormalLivingTime; } - void TMapObjGeneral::appear() { makeObjAppeared(); From 10ea256d5ce31fb529ea775f09a49cb3c9263cf9 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Sat, 30 May 2026 18:02:56 +0100 Subject: [PATCH 6/7] Removed some fake matching Added a comment indicating fabricated inlines --- include/MoveBG/MapObjBall.hpp | 1 + src/MoveBG/MapObjBall.cpp | 29 +++++++++++------------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/include/MoveBG/MapObjBall.hpp b/include/MoveBG/MapObjBall.hpp index b648f7fb..333e0738 100644 --- a/include/MoveBG/MapObjBall.hpp +++ b/include/MoveBG/MapObjBall.hpp @@ -89,6 +89,7 @@ class TResetFruit : public TMapObjBall { void touchKillSurface(); + // fabricated inline void hideTouchActor(THitActor*); inline void unknownInline(); diff --git a/src/MoveBG/MapObjBall.cpp b/src/MoveBG/MapObjBall.cpp index aa8cb02b..ae62ed86 100644 --- a/src/MoveBG/MapObjBall.cpp +++ b/src/MoveBG/MapObjBall.cpp @@ -202,11 +202,16 @@ void TMapObjBall::hold(TTakeActor* holder) mVelocity.zero(); } +// This inline probably lives on a class higher up the inheritance chain +inline bool isFalling(JGeometry::TVec3& vel) +{ + JGeometry::TVec3 velCopy(vel); + return velCopy.y < 0.0f; +} + void TMapObjBall::kicked() { - JGeometry::TVec3 velCopy = mVelocity; - JGeometry::TVec3 velCopy2 = velCopy; - if (velCopy2.y > 0.0f) { + if (!isFalling(mVelocity)) { return; } @@ -339,6 +344,7 @@ void TMapObjBall::touchActor(THitActor* actor) void TMapObjBall::calcCurrentMtx() { + Mtx local48; local48[2][3] = 0.0f; local48[1][3] = 0.0f; @@ -1279,14 +1285,8 @@ void TCoverFruit::calcRootMatrix() PSMTXCopy(takingMtx, model->unk20); mPosition.set(takingMtx[0][3], takingMtx[1][3], takingMtx[2][3]); } else { - f32 fVar1 = mRotation.z; - f32 fVar2 = (mPosition.y - mYOffset); - f32 fVar3 = mRotation.y; - f32 fVar4 = mRotation.x; - f32 fVar5 = mPosition.z; - f32 fVar6 = mPosition.x; - MsMtxSetXYZRPH(getModel()->unk20, fVar6, fVar5, fVar4, fVar3, fVar2, - fVar1); + MsMtxSetXYZRPH(getModel()->unk20, mPosition.x, mPosition.z, mRotation.x, + mRotation.y, mPosition.y - mYOffset, mRotation.z); } J3DModel* model = getModel(); @@ -1366,13 +1366,6 @@ void TBigWatermelon::touchGround(JGeometry::TVec3* ground) TMapObjBall::touchGround(ground); } -// This inline probably lives on a class higher up the inheritance chain -inline bool isFalling(JGeometry::TVec3& vel) -{ - JGeometry::TVec3 velCopy(vel); - return velCopy.y < 0.0f; -} - void TBigWatermelon::touchActor(THitActor* actor) { if (!isState(2)) { From 70eb9f4db116c35b8eeb151de0f50b1d206a2531 Mon Sep 17 00:00:00 2001 From: Nicholas Stearns Date: Sat, 30 May 2026 18:27:50 +0100 Subject: [PATCH 7/7] Update clang-format version --- src/MoveBG/MapObjGeneral.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MoveBG/MapObjGeneral.cpp b/src/MoveBG/MapObjGeneral.cpp index d5958586..fc47a3c4 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -95,7 +95,7 @@ void TMapObjGeneral::put() s32 preservedTimeTilAppear = getTimeTilAppear(); makeObjAppeared(); mTimeTilAppear = preservedTimeTilAppear; - mPosition.x = JMASSin(*gpMarioAngleY) + mPosition.x = JMASSin(*gpMarioAngleY) * (getDamageRadius() + SMS_GetMarioDamageRadius() + 10.0f) + SMS_GetMarioPos().x; mPosition.y = SMS_GetMarioPos().y;