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/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 c88c2c36..9ce08ab2 100644 --- a/src/MoveBG/MapObjGeneral.cpp +++ b/src/MoveBG/MapObjGeneral.cpp @@ -1,9 +1,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -37,22 +39,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 (unk104 > 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(); } @@ -64,28 +69,78 @@ 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; } 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); 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_NOT_MOVING); + 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_NOT_MOVING); + 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() { @@ -182,7 +237,7 @@ void TMapObjGeneral::appearing() } uuuh: - if (!checkLiveFlag(LIVE_FLAG_UNK10)) + if (!checkLiveFlag(LIVE_FLAG_NOT_MOVING)) return; makeObjAppeared(); @@ -190,7 +245,7 @@ void TMapObjGeneral::appearing() void TMapObjGeneral::appeared() { - if (checkMapObjFlag(0x40000) && !(unk104 > 0 ? true : false)) + if (checkMapObjFlag(0x40000) && !(mTimeTilAppear > 0 ? true : false)) makeObjDead(); } @@ -270,7 +325,7 @@ void TMapObjGeneral::ensureTakeSituation() TMapObjBase::ensureTakeSituation(); if (isState(6) && mHolder == nullptr) { mState = 1; - offLiveFlag(LIVE_FLAG_UNK10); + offLiveFlag(LIVE_FLAG_NOT_MOVING); } } @@ -278,8 +333,8 @@ void TMapObjGeneral::kill() { unk64 |= 1; removeMapCollision(); - onLiveFlag(LIVE_FLAG_UNK10 | LIVE_FLAG_UNK8); - unk104 = 0xffffffff; + onLiveFlag(LIVE_FLAG_NOT_MOVING | LIVE_FLAG_UNK8); + mTimeTilAppear = 0xffffffff; startAnim(2); mState = 3; startSound(2); @@ -303,7 +358,7 @@ void TMapObjGeneral::appear() appearing(); if (checkMapObjFlag(0x40000)) - unk104 = getLivingTime(); + mTimeTilAppear = getLivingTime(); mState = 2; } @@ -382,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) { @@ -390,24 +454,19 @@ 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); } } 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; } } @@ -423,9 +482,82 @@ 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; + } -void TMapObjGeneral::bind() { } + 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() +{ + 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() { @@ -474,9 +606,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; } }