diff --git a/source/game/field/obj/ObjectBasabasa.cc b/source/game/field/obj/ObjectBasabasa.cc index 03a98b58..3a9647f7 100644 --- a/source/game/field/obj/ObjectBasabasa.cc +++ b/source/game/field/obj/ObjectBasabasa.cc @@ -75,13 +75,13 @@ void ObjectBasabasaDummy::calcState0() { ObjectBasabasa::ObjectBasabasa(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), m_initialTimer(params.setting(1)), m_batsPerGroup(params.setting(2)), m_startFrame(params.setting(6)), - m_batSpacing(static_cast(static_cast(params.setting(5)) / + m_batSpacing(static_cast(static_cast(params.setting(5)) / static_cast(params.setting(0)) / static_cast(m_batsPerGroup))) { f32 railLen = RailManager::Instance()->rail(params.pathId())->getPathLength(); u32 groupCount = static_cast(railLen / static_cast(params.setting(0)) / static_cast(m_initialTimer)) + 1; - u32 batCount = groupCount * m_batsPerGroup; + u32 batCount = groupCount * static_cast(m_batsPerGroup); m_bats = std::span(new ObjectBasabasaDummy *[batCount], batCount); @@ -90,8 +90,8 @@ ObjectBasabasa::ObjectBasabasa(const System::MapdataGeoObj ¶ms) bat->load(); } - s_initialX = params.setting(3); - s_initialY = params.setting(4); + s_initialX = static_cast(params.setting(3)); + s_initialY = static_cast(params.setting(4)); } /// @addr{0x806B72F4} @@ -114,7 +114,7 @@ void ObjectBasabasa::init() { /// @addr{0x806B74C4} void ObjectBasabasa::calc() { - if (System::RaceManager::Instance()->timer() <= m_startFrame) { + if (System::RaceManager::Instance()->timer() <= static_cast(m_startFrame)) { return; } diff --git a/source/game/field/obj/ObjectBasabasa.hh b/source/game/field/obj/ObjectBasabasa.hh index 76676d2e..22751548 100644 --- a/source/game/field/obj/ObjectBasabasa.hh +++ b/source/game/field/obj/ObjectBasabasa.hh @@ -89,12 +89,12 @@ public: private: std::span m_bats; ///< The array of individual bats - const u32 m_initialTimer; ///< The m_cycleTimer starts and resets to this value - const u32 m_batsPerGroup; ///< Number of bats that will spawn before resetting the m_cycleTimer - const u32 m_startFrame; ///< Initial delay before the spawner will start calculating - const u32 m_batSpacing; ///< How many frames in between bat spawns - u32 m_cycleTimer; ///< Used to determine when to spawn next bat - u32 m_batsActive; ///< The number of bats currently spawned + const s32 m_initialTimer; ///< The m_cycleTimer starts and resets to this value + const s32 m_batsPerGroup; ///< Number of bats that will spawn before resetting the m_cycleTimer + const s32 m_startFrame; ///< Initial delay before the spawner will start calculating + const s32 m_batSpacing; ///< How many frames in between bat spawns + s32 m_cycleTimer; ///< Used to determine when to spawn next bat + s32 m_batsActive; ///< The number of bats currently spawned }; } // namespace Field diff --git a/source/game/field/obj/ObjectBelt.cc b/source/game/field/obj/ObjectBelt.cc index 69ac3043..9f329fe2 100644 --- a/source/game/field/obj/ObjectBelt.cc +++ b/source/game/field/obj/ObjectBelt.cc @@ -33,7 +33,7 @@ bool ObjectBelt::calcCollision(const EGG::Vector3f &v0, const EGG::Vector3f & /* if (entry->dist > info->movingFloorDist) { info->movingFloorDist = entry->dist; info->roadVelocity = calcRoadVelocity(entry->variant(), v0, - System::RaceManager::Instance()->timer() - timeOffset); + static_cast(System::RaceManager::Instance()->timer() - timeOffset)); } return true; diff --git a/source/game/field/obj/ObjectBelt.hh b/source/game/field/obj/ObjectBelt.hh index 780882b2..858895cd 100644 --- a/source/game/field/obj/ObjectBelt.hh +++ b/source/game/field/obj/ObjectBelt.hh @@ -142,7 +142,7 @@ public: } [[nodiscard]] virtual EGG::Vector3f calcRoadVelocity(u32 variant, const EGG::Vector3f &pos, - u32 timeOffset) const = 0; + s32 timeOffset) const = 0; [[nodiscard]] virtual bool isMoving(u32 variant, const EGG::Vector3f &pos) const = 0; diff --git a/source/game/field/obj/ObjectBeltCrossing.cc b/source/game/field/obj/ObjectBeltCrossing.cc index c1a5ba3b..2b6cf239 100644 --- a/source/game/field/obj/ObjectBeltCrossing.cc +++ b/source/game/field/obj/ObjectBeltCrossing.cc @@ -12,7 +12,7 @@ ObjectBeltCrossing::~ObjectBeltCrossing() = default; /// @addr{0x807FC7D8} EGG::Vector3f ObjectBeltCrossing::calcRoadVelocity(u32 variant, const EGG::Vector3f & /*pos*/, - u32 /*timeOffset*/) const { + s32 /*timeOffset*/) const { switch (variant) { case 0: return -EGG::Vector3f::ex * m_roadVel; diff --git a/source/game/field/obj/ObjectBeltCrossing.hh b/source/game/field/obj/ObjectBeltCrossing.hh index 7cf1c129..9754ce71 100644 --- a/source/game/field/obj/ObjectBeltCrossing.hh +++ b/source/game/field/obj/ObjectBeltCrossing.hh @@ -11,7 +11,7 @@ public: ~ObjectBeltCrossing() override; [[nodiscard]] EGG::Vector3f calcRoadVelocity(u32 variant, const EGG::Vector3f &pos, - u32 timeOffset) const override; + s32 timeOffset) const override; [[nodiscard]] bool isMoving(u32 variant, const EGG::Vector3f &pos) const override; }; diff --git a/source/game/field/obj/ObjectBeltCurveA.cc b/source/game/field/obj/ObjectBeltCurveA.cc index 6cc4a6d4..b037060a 100644 --- a/source/game/field/obj/ObjectBeltCurveA.cc +++ b/source/game/field/obj/ObjectBeltCurveA.cc @@ -17,7 +17,7 @@ ObjectBeltCurveA::~ObjectBeltCurveA() = default; /// @addr{0x807FC9D4} EGG::Vector3f ObjectBeltCurveA::calcRoadVelocity(u32 variant, const EGG::Vector3f &pos, - u32 timeOffset) const { + s32 timeOffset) const { EGG::Vector3f posDelta = pos - m_pos; posDelta.y = 0.0f; diff --git a/source/game/field/obj/ObjectBeltCurveA.hh b/source/game/field/obj/ObjectBeltCurveA.hh index 2ce646db..cd291785 100644 --- a/source/game/field/obj/ObjectBeltCurveA.hh +++ b/source/game/field/obj/ObjectBeltCurveA.hh @@ -12,7 +12,7 @@ public: ~ObjectBeltCurveA() override; [[nodiscard]] EGG::Vector3f calcRoadVelocity(u32 variant, const EGG::Vector3f &pos, - u32 timeOffset) const override; + s32 timeOffset) const override; /// @addr{0x807FCCA4} [[nodiscard]] bool isMoving(u32 variant, const EGG::Vector3f & /*pos*/) const override { @@ -23,8 +23,8 @@ private: [[nodiscard]] f32 calcDirSwitchVelocity(u32 t) const; bool m_startForward; - u16 m_dirChange1Frame; - u16 m_dirChange2Frame; + s32 m_dirChange1Frame; + s32 m_dirChange2Frame; EGG::Matrix34f m_initMat; }; diff --git a/source/game/field/obj/ObjectBeltEasy.cc b/source/game/field/obj/ObjectBeltEasy.cc index db714270..c31d9dbf 100644 --- a/source/game/field/obj/ObjectBeltEasy.cc +++ b/source/game/field/obj/ObjectBeltEasy.cc @@ -12,7 +12,7 @@ ObjectBeltEasy::~ObjectBeltEasy() = default; /// @addr{0x807FC62C} EGG::Vector3f ObjectBeltEasy::calcRoadVelocity(u32 variant, const EGG::Vector3f & /*pos*/, - u32 /*timeOffset*/) const { + s32 /*timeOffset*/) const { switch (variant) { case 2: return EGG::Vector3f::ex * m_roadVel; diff --git a/source/game/field/obj/ObjectBeltEasy.hh b/source/game/field/obj/ObjectBeltEasy.hh index 3fbfa69b..fc10f852 100644 --- a/source/game/field/obj/ObjectBeltEasy.hh +++ b/source/game/field/obj/ObjectBeltEasy.hh @@ -12,7 +12,7 @@ public: private: [[nodiscard]] EGG::Vector3f calcRoadVelocity(u32 variant, const EGG::Vector3f &pos, - u32 timeOffset) const override; + s32 timeOffset) const override; /// @addr{0x807FC6C8} [[nodiscard]] bool isMoving(u32 variant, const EGG::Vector3f & /*pos*/) const override { diff --git a/source/game/field/obj/ObjectBird.cc b/source/game/field/obj/ObjectBird.cc index c5139882..d9162879 100644 --- a/source/game/field/obj/ObjectBird.cc +++ b/source/game/field/obj/ObjectBird.cc @@ -11,7 +11,7 @@ ObjectBird::ObjectBird(const System::MapdataGeoObj ¶ms) : ObjectCollidable(p m_leader = new ObjectBirdLeader(params, this); m_leader->load(); - u32 count = params.setting(1); + u32 count = static_cast(params.setting(1)); if (count == 0) { count = 5; } @@ -73,6 +73,7 @@ void ObjectBirdLeader::init() { m_railInterpolator->calc(); m_pos = m_railInterpolator->curPos(); m_flags.setBit(eFlags::Position); + ASSERT(m_mapObj); m_railInterpolator->setCurrVel(static_cast(m_mapObj->setting(0))); } @@ -117,6 +118,7 @@ void ObjectBirdFollower::init() { f32 rate = rand.getF32(static_cast(frameCount)); anmMgr->playAnim(rate, 1.0f, 0); + ASSERT(m_mapObj); m_baseSpeed = static_cast(m_mapObj->setting(0)); m_velocity = EGG::Vector3f::ez * m_baseSpeed; diff --git a/source/game/field/obj/ObjectBulldozer.cc b/source/game/field/obj/ObjectBulldozer.cc index 288740e0..06d50449 100644 --- a/source/game/field/obj/ObjectBulldozer.cc +++ b/source/game/field/obj/ObjectBulldozer.cc @@ -8,16 +8,11 @@ namespace Field { /// @addr{0x807FD938} ObjectBulldozer::ObjectBulldozer(const System::MapdataGeoObj ¶ms) - : ObjectKCL(params), m_initialPos(m_pos), m_initialRot(m_rot) { - m_timeOffset = params.setting(3) * 2; - m_periodDenom = std::max(2, params.setting(2)); - m_restFrames = params.setting(4); - m_amplitude = params.setting(1); - m_left = (strcmp(getName(), "bulldozer_left") == 0); - m_fullPeriod = m_periodDenom + m_restFrames * 2; - m_halfPeriod = m_fullPeriod / 2; - m_period = F_TAU / static_cast(m_periodDenom); -} + : ObjectKCL(params), m_initialPos(m_pos), m_initialRot(m_rot), + m_timeOffset(params.setting(3) * 2), m_periodDenom(std::max(2, params.setting(2))), + m_restFrames(params.setting(4)), m_fullPeriod(m_periodDenom + m_restFrames * 2), + m_amplitude(params.setting(1)), m_left(strcmp(getName(), "bulldozer_left") == 0), + m_period(F_TAU / static_cast(m_periodDenom)), m_halfPeriod(m_fullPeriod / 2) {} /// @addr{0x807FE5F0} ObjectBulldozer::~ObjectBulldozer() = default; diff --git a/source/game/field/obj/ObjectBulldozer.hh b/source/game/field/obj/ObjectBulldozer.hh index fedf75f9..03fb05c6 100644 --- a/source/game/field/obj/ObjectBulldozer.hh +++ b/source/game/field/obj/ObjectBulldozer.hh @@ -38,14 +38,14 @@ public: const EGG::Vector3f m_initialPos; const EGG::Vector3f m_initialRot; - u16 m_timeOffset; - u16 m_periodDenom; - u16 m_restFrames; ///< How long bulldozers stop moving for - u16 m_fullPeriod; ///< m_periodDenom + 2 * m_restFrames - u16 m_amplitude; - bool m_left; ///< Flips the sin wave direction. - f32 m_period; - u16 m_halfPeriod; + const s16 m_timeOffset; + const s16 m_periodDenom; + const s16 m_restFrames; ///< How long bulldozers stop moving for + const s16 m_fullPeriod; ///< m_periodDenom + 2 * m_restFrames + const s16 m_amplitude; + const bool m_left; ///< Flips the sin wave direction. + const f32 m_period; + const s16 m_halfPeriod; EGG::Matrix34f m_rtMat; ///< Exists solely so getUpdatedMatrix can return a reference. }; diff --git a/source/game/field/obj/ObjectCarA.cc b/source/game/field/obj/ObjectCarA.cc index ccc56d0c..1487860a 100644 --- a/source/game/field/obj/ObjectCarA.cc +++ b/source/game/field/obj/ObjectCarA.cc @@ -11,8 +11,7 @@ namespace Field { ObjectCarA::ObjectCarA(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), m_finalVel(static_cast(params.setting(0))), - m_accel(static_cast(params.setting(1)) / 10.0f), - m_stopTime(static_cast(params.setting(2))) {} + m_accel(static_cast(params.setting(1)) / 10.0f), m_stopTime(params.setting(2)) {} /// @addr{0x806B78CC} ObjectCarA::~ObjectCarA() = default; @@ -96,7 +95,7 @@ void ObjectCarA::enterCruising() { /// @addr{0x806B8588} void ObjectCarA::calcStop() { - if (m_currentFrame > m_stopTime) { + if (m_currentFrame > static_cast(m_stopTime)) { m_motionState = MotionState::Accelerating; m_currentStateId = 1; } diff --git a/source/game/field/obj/ObjectCarA.hh b/source/game/field/obj/ObjectCarA.hh index 9ef348f1..f1c4efc9 100644 --- a/source/game/field/obj/ObjectCarA.hh +++ b/source/game/field/obj/ObjectCarA.hh @@ -44,7 +44,7 @@ private: const f32 m_finalVel; const f32 m_accel; - const u32 m_stopTime; + const s32 m_stopTime; f32 m_cruiseTime; ///< How long to spend at cruising speed before decelerating. EGG::Vector3f m_currTangent; ///< It's @ref EGG::Vector3f::ey unless it flies up in the air. EGG::Vector3f m_currUp; ///< It's @ref EGG::Vector3f::ey unless it flies up in the air. diff --git a/source/game/field/obj/ObjectCarTGE.cc b/source/game/field/obj/ObjectCarTGE.cc index 0ef591fe..4d64ead0 100644 --- a/source/game/field/obj/ObjectCarTGE.cc +++ b/source/game/field/obj/ObjectCarTGE.cc @@ -14,18 +14,15 @@ namespace Field { /// @addr{0x806D5EE4} ObjectCarTGE::ObjectCarTGE(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), m_auxCollision(nullptr), - m_carName{}, m_mdlName{}, m_carType(CarType::Normal), m_dummyId(ObjectId::None), + m_highwayVel(static_cast(params.setting(2))), + m_localVel(static_cast(params.setting(1))), m_carName{}, m_mdlName{}, + m_carType(CarType::Normal), m_dummyId(ObjectId::None), m_scaledTangentDir(EGG::Vector3f::zero), m_currSpeed(0.0f), m_up(EGG::Vector3f::zero), m_tangent(EGG::Vector3f::zero) { - u32 carVariant = static_cast(params.setting(3)); - m_highwayVel = static_cast(params.setting(2)); - m_localVel = static_cast(params.setting(1)); - - s16 pathId = params.pathId(); - // The base game returns before the StateManager sets its state entries. // Since we handle this in the template specialization's constructor in Kinoko, // we need to reset the StateManager parameters back to their default values before returning. + s16 pathId = params.pathId(); if (pathId == -1) { m_nextStateId = -1; m_currentStateId = 0; @@ -50,6 +47,7 @@ ObjectCarTGE::ObjectCarTGE(const System::MapdataGeoObj ¶ms) } const auto *resourceName = getResources(); + s32 carVariant = params.setting(3); switch (carVariant) { case 0: { @@ -111,7 +109,7 @@ void ObjectCarTGE::init() { return; } - u16 idx = m_mapObj->setting(0); + u16 idx = static_cast(m_mapObj->setting(0)); m_railInterpolator->init(0.0f, idx); auto *rail = RailManager::Instance()->rail(m_mapObj->pathId()); diff --git a/source/game/field/obj/ObjectCarTGE.hh b/source/game/field/obj/ObjectCarTGE.hh index d7ec35be..9f9e2c99 100644 --- a/source/game/field/obj/ObjectCarTGE.hh +++ b/source/game/field/obj/ObjectCarTGE.hh @@ -71,8 +71,8 @@ private: const ObjectHighwayManager *m_highwayMgr; ObjectCollisionBase *m_auxCollision; - f32 m_highwayVel; ///< Speed while on the highway - f32 m_localVel; ///< Speed while off the highway + const f32 m_highwayVel; ///< Speed while on the highway + const f32 m_localVel; ///< Speed while off the highway char m_carName[32]; char m_mdlName[32]; CarType m_carType; ///< Car, truck, or bomb car diff --git a/source/game/field/obj/ObjectChoropu.cc b/source/game/field/obj/ObjectChoropu.cc index 41218895..3a157b91 100644 --- a/source/game/field/obj/ObjectChoropu.cc +++ b/source/game/field/obj/ObjectChoropu.cc @@ -9,13 +9,11 @@ namespace Field { /// @addr{0x806B96A0} ObjectChoropu::ObjectChoropu(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), StateManager(this, STATE_ENTRIES) { + : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), + m_startFrameOffset(params.setting(1)), m_idleDuration(params.setting(0)), + m_isStationary(strcmp(getName(), "choropu") != 0) { constexpr f32 MAX_SPEED = 20.0f; - m_startFrameOffset = static_cast(params.setting(1)); - m_idleDuration = params.setting(0); - m_isStationary = strcmp(getName(), "choropu") != 0; - s16 railIdx = params.pathId(); if (railIdx != -1) { auto *rail = RailManager::Instance()->rail(railIdx); @@ -172,7 +170,7 @@ void ObjectChoropu::calcStateStub() {} /// @addr{0x806BA7FC} void ObjectChoropu::calcDigging() { if (m_isStationary) { - if (m_currentFrame > m_idleDuration) { + if (m_currentFrame > static_cast(m_idleDuration)) { m_nextStateId = 1; } diff --git a/source/game/field/obj/ObjectChoropu.hh b/source/game/field/obj/ObjectChoropu.hh index 2c48731d..42dc00d9 100644 --- a/source/game/field/obj/ObjectChoropu.hh +++ b/source/game/field/obj/ObjectChoropu.hh @@ -48,10 +48,10 @@ private: std::span m_groundObjs; ObjectChoropuHoll *m_objHoll; - s16 m_startFrameOffset; - u16 m_idleDuration; + const s16 m_startFrameOffset; + const s16 m_idleDuration; f32 m_groundHeight; - bool m_isStationary; ///< rPG moles don't move while MMM moles do + const bool m_isStationary; ///< rPG moles don't move while MMM moles do EGG::Matrix34f m_transMat; EGG::Matrix34f m_railMat; f32 m_groundLength; diff --git a/source/game/field/obj/ObjectCow.cc b/source/game/field/obj/ObjectCow.cc index b2475286..23b6c309 100644 --- a/source/game/field/obj/ObjectCow.cc +++ b/source/game/field/obj/ObjectCow.cc @@ -12,9 +12,8 @@ namespace Field { /// @addr{0x806BBEC0} -ObjectCow::ObjectCow(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params) { - m_startFrame = params.setting(2); -} +ObjectCow::ObjectCow(const System::MapdataGeoObj ¶ms) + : ObjectCollidable(params), m_startFrame(params.setting(2)) {} /// @addr{0x806BBF24} ObjectCow::~ObjectCow() = default; @@ -114,6 +113,7 @@ void ObjectCowLeader::init() { setTarget(m_pos + m_railInterpolator->curTangentDir() * 10.0f); + ASSERT(m_mapObj); m_railInterpolator->setCurrVel(static_cast(m_mapObj->setting(1))); m_railSpeed = 0.0f; @@ -128,7 +128,7 @@ void ObjectCowLeader::init() { void ObjectCowLeader::calc() { u32 t = System::RaceManager::Instance()->timer(); - if (t >= m_startFrame) { + if (t >= static_cast(m_startFrame)) { StateManager::calc(); } @@ -283,7 +283,7 @@ void ObjectCowFollower::init() { void ObjectCowFollower::calc() { u32 t = System::RaceManager::Instance()->timer(); - if (t < m_startFrame) { + if (t < static_cast(m_startFrame)) { if (m_currentFrame > m_waitFrames) { m_nextStateId = 1; } @@ -432,11 +432,10 @@ void ObjectCowFollower::calcFollowLeader() { ObjectCowHerd::ObjectCowHerd(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params) { constexpr f32 FOLLOWER_SPACING = 600.0f; - u8 followerCount = params.setting(0); - m_leader = new ObjectCowLeader(params); m_leader->load(); + u8 followerCount = static_cast(params.setting(0)); m_followers = std::span(new ObjectCowFollower *[followerCount], followerCount); diff --git a/source/game/field/obj/ObjectCow.hh b/source/game/field/obj/ObjectCow.hh index 76100a8f..74fbe16b 100644 --- a/source/game/field/obj/ObjectCow.hh +++ b/source/game/field/obj/ObjectCow.hh @@ -29,7 +29,7 @@ protected: return v0 + (v1 - v0) * t; } - u32 m_startFrame; ///< The frame the cow will start moving + const s32 m_startFrame; ///< The frame the cow will start moving EGG::Vector3f m_tangent; EGG::Vector3f m_prevTangent; EGG::Vector3f m_up; diff --git a/source/game/field/obj/ObjectCrab.cc b/source/game/field/obj/ObjectCrab.cc index 86ac5f23..1ad40ac1 100644 --- a/source/game/field/obj/ObjectCrab.cc +++ b/source/game/field/obj/ObjectCrab.cc @@ -9,7 +9,7 @@ namespace Field { /// @addr{0x8088344C} ObjectCrab::ObjectCrab(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), m_vel(static_cast(static_cast(params.setting(0)))), + : ObjectCollidable(params), m_vel(static_cast(params.setting(0))), m_backwards(!!params.setting(1)), m_introCalc(false) {} /// @addr{0x808837B8} diff --git a/source/game/field/obj/ObjectCrane.cc b/source/game/field/obj/ObjectCrane.cc index 4320873f..4c4ab035 100644 --- a/source/game/field/obj/ObjectCrane.cc +++ b/source/game/field/obj/ObjectCrane.cc @@ -4,16 +4,12 @@ namespace Field { /// @addr{0x807FE658} ObjectCrane::ObjectCrane(const System::MapdataGeoObj ¶ms) - : ObjectKCL(params), m_startPos(m_pos) { + : ObjectKCL(params), m_startPos(m_pos), m_xPeriod(std::max(2, params.setting(1))), + m_yPeriod(std::max(2, params.setting(4))), m_xAmplitude(params.setting(2)), + m_yAmplitude(params.setting(5)), m_xFreq(2.0f * F_PI / static_cast(m_xPeriod)), + m_yFreq(2.0f * F_PI / static_cast(m_yPeriod)) { m_xt = params.setting(3); m_yt = 0; - m_xPeriod = std::max(static_cast(2), params.setting(1)); - m_yPeriod = std::max(static_cast(2), params.setting(4)); - m_xAmplitude = params.setting(2); - m_yAmplitude = params.setting(5); - - m_xFreq = 2.0f * F_PI / static_cast(m_xPeriod); - m_yFreq = 2.0f * F_PI / static_cast(m_yPeriod); } /// @addr{0x807FEB28} diff --git a/source/game/field/obj/ObjectCrane.hh b/source/game/field/obj/ObjectCrane.hh index af64bf67..9c28923f 100644 --- a/source/game/field/obj/ObjectCrane.hh +++ b/source/game/field/obj/ObjectCrane.hh @@ -26,14 +26,14 @@ public: private: const EGG::Vector3f m_startPos; ///< Initial starting position - u16 m_xt; ///< Current time along the x-axis period - u16 m_yt; ///< Current time along the y-axis period - u16 m_xPeriod; ///< Framecount of a full oscillation on x-axis - u16 m_yPeriod; ///< Framecount of a full oscillation on y-axis - u16 m_xAmplitude; ///< Max x-position delta from starting position - u16 m_yAmplitude; ///< Max y-position delta from starting position - f32 m_xFreq; ///< 2pi / m_xPeriod - f32 m_yFreq; ///< 2pi / m_yPeriod + s16 m_xt; ///< Current time along the x-axis period + s16 m_yt; ///< Current time along the y-axis period + const s16 m_xPeriod; ///< Framecount of a full oscillation on x-axis + const s16 m_yPeriod; ///< Framecount of a full oscillation on y-axis + const s16 m_xAmplitude; ///< Max x-position delta from starting position + const s16 m_yAmplitude; ///< Max y-position delta from starting position + const f32 m_xFreq; ///< 2pi / m_xPeriod + const f32 m_yFreq; ///< 2pi / m_yPeriod }; } // namespace Field diff --git a/source/game/field/obj/ObjectDossun.cc b/source/game/field/obj/ObjectDossun.cc index 9c4c05af..273b5d36 100644 --- a/source/game/field/obj/ObjectDossun.cc +++ b/source/game/field/obj/ObjectDossun.cc @@ -115,9 +115,10 @@ Kart::Reaction ObjectDossun::onCollision(Kart::KartObject *kartObj, Kart::Reacti /// @addr{0x8075F21C} void ObjectDossun::initState() { - m_stillTimer = static_cast(m_mapObj->setting(2)); + ASSERT(m_mapObj); + m_stillTimer = static_cast(m_mapObj->setting(2)); if (m_stillTimer == 0) { - m_stillTimer = static_cast(m_mapObj->setting(3)); + m_stillTimer = static_cast(m_mapObj->setting(3)); } m_groundedTimer = 0; diff --git a/source/game/field/obj/ObjectDossunNormal.cc b/source/game/field/obj/ObjectDossunNormal.cc index bfa0b07e..ee8604c2 100644 --- a/source/game/field/obj/ObjectDossunNormal.cc +++ b/source/game/field/obj/ObjectDossunNormal.cc @@ -45,6 +45,7 @@ void ObjectDossunNormal::startStill() { m_flags.setBit(eFlags::Rotation); m_rot.y = m_currRot; m_stompState = StompState::Inactive; + ASSERT(m_mapObj); m_stillTimer = static_cast(m_mapObj->setting(3)); } diff --git a/source/game/field/obj/ObjectDossunTsuibiHolder.cc b/source/game/field/obj/ObjectDossunTsuibiHolder.cc index 7f70651c..8dc60d1d 100644 --- a/source/game/field/obj/ObjectDossunTsuibiHolder.cc +++ b/source/game/field/obj/ObjectDossunTsuibiHolder.cc @@ -6,9 +6,8 @@ namespace Field { /// @addr{0x807614D0} ObjectDossunTsuibiHolder::ObjectDossunTsuibiHolder(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), m_stillTimer(static_cast(params.setting(2))), - m_facingBackwards(false), m_forwardVel(static_cast(m_mapObj->setting(0))), - m_stillDuration(static_cast(m_mapObj->setting(3))) { + : ObjectCollidable(params), m_stillTimer(params.setting(2)), m_facingBackwards(false), + m_forwardVel(static_cast(params.setting(0))), m_stillDuration(params.setting(3)) { for (auto *&dossun : m_dossuns) { dossun = new ObjectDossunTsuibi(params, this); dossun->load(); diff --git a/source/game/field/obj/ObjectDossunTsuibiHolder.hh b/source/game/field/obj/ObjectDossunTsuibiHolder.hh index 4176744b..8e92bb15 100644 --- a/source/game/field/obj/ObjectDossunTsuibiHolder.hh +++ b/source/game/field/obj/ObjectDossunTsuibiHolder.hh @@ -74,7 +74,7 @@ private: std::array m_dossuns; State m_state; EGG::Vector3f m_initPos; - u32 m_stillTimer; + s32 m_stillTimer; bool m_movingForward; u32 m_forwardTimer; bool m_movingSideways; ///< Whether the Thwomps should move along the z-axis @@ -91,7 +91,7 @@ private: // These members are not in the base game but we add them to prevent dereferencing m_mapObj. const f32 m_forwardVel; ///< Rail velocity - const u32 m_stillDuration; ///< How long Thwomps remain at their home for + const s32 m_stillDuration; ///< How long Thwomps remain at their home for /// How long Thwomps take to reset after returning to home static constexpr u32 HOME_RESET_FRAMES = 36; diff --git a/source/game/field/obj/ObjectEscalator.cc b/source/game/field/obj/ObjectEscalator.cc index 12dfe945..5035713f 100644 --- a/source/game/field/obj/ObjectEscalator.cc +++ b/source/game/field/obj/ObjectEscalator.cc @@ -12,14 +12,10 @@ namespace Field { /// @addr{0x807FFB20} ObjectEscalator::ObjectEscalator(const System::MapdataGeoObj ¶ms, bool reverse /* = false */) : ObjectKCL(params), m_initialPos(m_pos), m_initialRot(m_rot), - m_stillFrames( - {static_cast(params.setting(2)) * 60, static_cast(params.setting(4)) * 60}), - m_speed({(reverse ? -1.0f : 1.0f) * - (0.15f * static_cast(static_cast(params.setting(1))) / 100.0f), - (reverse ? -1.0f : 1.0f) * - (0.15f * static_cast(static_cast(params.setting(3))) / 100.0f), - (reverse ? -1.0f : 1.0f) * - (0.15f * static_cast(static_cast(params.setting(5))) / 100.0f)}), + m_stillFrames({params.setting(2) * 60, params.setting(4) * 60}), + m_speed({(reverse ? -1.0f : 1.0f) * (0.15f * static_cast(params.setting(1)) / 100.0f), + (reverse ? -1.0f : 1.0f) * (0.15f * static_cast(params.setting(3)) / 100.0f), + (reverse ? -1.0f : 1.0f) * (0.15f * static_cast(params.setting(5)) / 100.0f)}), m_checkColYPosMax(m_initialPos.y + MAX_HEIGHT_OFFSET), m_checkColYPosMin(m_initialPos.y + MIN_HEIGHT_OFFSET), m_stopFrames({static_cast(m_stillFrames[0]) - REVERSE_FRAMES_F32, diff --git a/source/game/field/obj/ObjectFireRing.cc b/source/game/field/obj/ObjectFireRing.cc index bb116f41..b0ffa639 100644 --- a/source/game/field/obj/ObjectFireRing.cc +++ b/source/game/field/obj/ObjectFireRing.cc @@ -4,17 +4,18 @@ namespace Field { /// @addr{0x80767FF4} ObjectFireRing::ObjectFireRing(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), m_phase(0.0f) { - size_t fireballCount = std::max(1, params.setting(0)); - m_angSpeed = static_cast(static_cast(params.setting(1))); + : ObjectCollidable(params), m_angSpeed(static_cast(params.setting(1))), m_phase(0.0f) { + s32 fireballCount = std::max(1, static_cast(params.setting(0))); m_fireballs = std::span(new ObjectFireball *[fireballCount], fireballCount); + f32 distance = 100.0f * static_cast(params.setting(3)); + f32 phase = 360.0f / static_cast(fireballCount); - for (size_t i = 0; i < fireballCount; ++i) { + for (s32 i = 0; i < fireballCount; ++i) { m_fireballs[i] = new ObjectFireball(params); m_fireballs[i]->load(); m_fireballs[i]->setDistance(distance); - m_fireballs[i]->setAngle(static_cast(i) * (360.0f / fireballCount)); + m_fireballs[i]->setAngle(static_cast(i) * phase); } EGG::Matrix34f mat; diff --git a/source/game/field/obj/ObjectFireRing.hh b/source/game/field/obj/ObjectFireRing.hh index d58855f7..4f05e6f5 100644 --- a/source/game/field/obj/ObjectFireRing.hh +++ b/source/game/field/obj/ObjectFireRing.hh @@ -23,7 +23,7 @@ public: private: std::span m_fireballs; - f32 m_angSpeed; + const f32 m_angSpeed; f32 m_degAngle; EGG::Vector3f m_axis; EGG::Vector3f m_initDir; diff --git a/source/game/field/obj/ObjectFireSnake.cc b/source/game/field/obj/ObjectFireSnake.cc index f4e9f480..2cb864f7 100644 --- a/source/game/field/obj/ObjectFireSnake.cc +++ b/source/game/field/obj/ObjectFireSnake.cc @@ -17,7 +17,7 @@ ObjectFireSnakeKid::~ObjectFireSnakeKid() = default; /// @addr{0x806C0F30} ObjectFireSnake::ObjectFireSnake(const System::MapdataGeoObj ¶ms) : StateManager(this, STATE_ENTRIES), ObjectProjectile(params), m_initialPos(params.pos()), - m_maxAge(static_cast(params.setting(1))) { + m_maxAge(params.setting(1)) { if (ObjectDirector::Instance()->managedObjects().size() > 0) { registerManagedObject(); } @@ -53,7 +53,7 @@ void ObjectFireSnake::calc() { StateManager::calc(); if (isCollisionEnabled()) { - if (++m_age >= m_maxAge && m_currentStateId == 3) { + if (++m_age >= static_cast(m_maxAge) && m_currentStateId == 3) { m_nextStateId = 0; } } diff --git a/source/game/field/obj/ObjectFireSnake.hh b/source/game/field/obj/ObjectFireSnake.hh index c94f8081..e640589f 100644 --- a/source/game/field/obj/ObjectFireSnake.hh +++ b/source/game/field/obj/ObjectFireSnake.hh @@ -62,7 +62,7 @@ protected: EGG::Vector3f m_visualPos; EGG::Vector3f m_bounceDir; u16 m_age; ///< How long the firesnake has been spawned - u16 m_delayFrame; + s16 m_delayFrame; private: void calcBounce(f32 initialVel); diff --git a/source/game/field/obj/ObjectFireSnakeV.cc b/source/game/field/obj/ObjectFireSnakeV.cc index ed8f3bef..eab71bdf 100644 --- a/source/game/field/obj/ObjectFireSnakeV.cc +++ b/source/game/field/obj/ObjectFireSnakeV.cc @@ -34,7 +34,7 @@ void ObjectFireSnakeV::init() { /// @addr{0x806C2D54} void ObjectFireSnakeV::calc() { - if (System::RaceManager::Instance()->timer() >= m_delayFrame) { + if (System::RaceManager::Instance()->timer() >= static_cast(m_delayFrame)) { calcSub(); } } @@ -43,8 +43,8 @@ void ObjectFireSnakeV::calc() { void ObjectFireSnakeV::calcSub() { StateManager::calc(); - u32 frame = System::RaceManager::Instance()->timer() - m_delayFrame; - if (frame % m_cycleDuration == 0) { + u32 frame = System::RaceManager::Instance()->timer() - static_cast(m_delayFrame); + if (frame % static_cast(m_cycleDuration) == 0) { m_nextStateId = 1; } diff --git a/source/game/field/obj/ObjectFireSnakeV.hh b/source/game/field/obj/ObjectFireSnakeV.hh index 7a60de0c..8a030090 100644 --- a/source/game/field/obj/ObjectFireSnakeV.hh +++ b/source/game/field/obj/ObjectFireSnakeV.hh @@ -70,7 +70,7 @@ private: &ObjectFireSnakeV::calcDespawning>(5)}, }}; - const u16 m_cycleDuration; + const s16 m_cycleDuration; const f32 m_distFromPipe; f32 m_fallSpeed; diff --git a/source/game/field/obj/ObjectFirebar.cc b/source/game/field/obj/ObjectFirebar.cc index 717a9de0..afa7844c 100644 --- a/source/game/field/obj/ObjectFirebar.cc +++ b/source/game/field/obj/ObjectFirebar.cc @@ -3,21 +3,22 @@ namespace Field { /// @addr{0x807678F4} -ObjectFirebar::ObjectFirebar(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params) { - m_spokes = std::max(1, params.setting(3)); - size_t fireballCount = std::max(1, params.setting(0) * m_spokes); - m_angSpeed = static_cast(static_cast(params.setting(1))); - +ObjectFirebar::ObjectFirebar(const System::MapdataGeoObj ¶ms) + : ObjectCollidable(params), m_angSpeed(static_cast(params.setting(1))) { + s32 spokes = std::max(1, params.setting(3)); + s32 fireballCount = std::max(1, params.setting(0) * spokes); m_fireballs = std::span(new ObjectFireball *[fireballCount], fireballCount); - for (size_t i = 0; i < fireballCount; ++i) { + f32 distScalar = 100.0f * static_cast(params.setting(2)); + f32 phase = 360.0f / spokes; + + for (s32 i = 0; i < fireballCount; ++i) { m_fireballs[i] = new ObjectFireball(params); m_fireballs[i]->load(); - f32 ring = 1.0f + static_cast(i / m_spokes); - m_fireballs[i]->setDistance( - ring * (100.0f * static_cast(static_cast(params.setting(2))))); - m_fireballs[i]->setAngle((360.0f / m_spokes) * (i % m_spokes)); + f32 ring = 1.0f + static_cast(i / spokes); + m_fireballs[i]->setDistance(ring * distScalar); + m_fireballs[i]->setAngle(phase * (i % spokes)); } EGG::Matrix34f mat; diff --git a/source/game/field/obj/ObjectFirebar.hh b/source/game/field/obj/ObjectFirebar.hh index 89abdbb2..3e1c0a26 100644 --- a/source/game/field/obj/ObjectFirebar.hh +++ b/source/game/field/obj/ObjectFirebar.hh @@ -25,8 +25,7 @@ public: private: std::span m_fireballs; - u32 m_spokes; // The number of fireball "segments" - f32 m_angSpeed; + const f32 m_angSpeed; f32 m_degAngle; EGG::Vector3f m_axis; EGG::Vector3f m_initDir; diff --git a/source/game/field/obj/ObjectFlamePoleFoot.cc b/source/game/field/obj/ObjectFlamePoleFoot.cc index f199aeb8..0ff9dd10 100644 --- a/source/game/field/obj/ObjectFlamePoleFoot.cc +++ b/source/game/field/obj/ObjectFlamePoleFoot.cc @@ -10,13 +10,11 @@ namespace Field { /// @addr{0x8067E6F4} ObjectFlamePoleFoot::ObjectFlamePoleFoot(const System::MapdataGeoObj ¶ms) - : ObjectKCL(params), StateManager(this, STATE_ENTRIES) { - m_extraCycleFrames = params.setting(0); - m_initDelay = params.setting(1); - m_poleScale = static_cast(params.setting(2)); - + : ObjectKCL(params), StateManager(this, STATE_ENTRIES), m_extraCycleFrames(params.setting(0)), + m_initDelay(params.setting(1)) { ++FLAMEPOLE_COUNT; + m_poleScale = static_cast(params.setting(2)); if (m_poleScale == 0.0f) { m_poleScale = 3.0f + static_cast(FLAMEPOLE_COUNT % 3); } @@ -59,7 +57,7 @@ void ObjectFlamePoleFoot::init() { /// @addr{0x8067EF70} void ObjectFlamePoleFoot::calc() { - if (System::RaceManager::Instance()->timer() < m_initDelay) { + if (System::RaceManager::Instance()->timer() < static_cast(m_initDelay)) { return; } @@ -79,7 +77,8 @@ void ObjectFlamePoleFoot::calc() { /// @addr{0x8067F6B8} void ObjectFlamePoleFoot::calcStates() { - u32 frame = static_cast(System::RaceManager::Instance()->timer() - m_initDelay); + u32 frame = static_cast( + System::RaceManager::Instance()->timer() - static_cast(m_initDelay)); m_cycleFrame = frame % (m_extraCycleFrames + CYCLE_FRAMES); // Access the array of state timers to see which state corresponds with the current frame. @@ -98,7 +97,7 @@ void ObjectFlamePoleFoot::calcStates() { } f32 ObjectFlamePoleFoot::getScaleY(u32 timeOffset) const { - u32 frame = System::RaceManager::Instance()->timer() - timeOffset; + s32 frame = System::RaceManager::Instance()->timer() - timeOffset; if (frame < m_initDelay) { return 1.0f; } diff --git a/source/game/field/obj/ObjectFlamePoleFoot.hh b/source/game/field/obj/ObjectFlamePoleFoot.hh index 1f193721..48672d8e 100644 --- a/source/game/field/obj/ObjectFlamePoleFoot.hh +++ b/source/game/field/obj/ObjectFlamePoleFoot.hh @@ -24,6 +24,7 @@ public: /// @addr{0x806814C4} [[nodiscard]] f32 getCollisionRadius() const override { + ASSERT(m_mapObj); return 245.0f * static_cast(m_mapObj->setting(2)); } @@ -91,8 +92,9 @@ private: EGG::Matrix34f m_workMatrix; ObjectFlamePole *m_pole; - u32 m_extraCycleFrames; ///< Used to increase the animation cycle beyond the typical 540 frames - u32 m_initDelay; + const s32 m_extraCycleFrames; ///< Used to increase the animation cycle beyond the typical 540 + ///< frames + const s32 m_initDelay; f32 m_poleScale; s32 m_eruptUpDuration; s32 m_eruptDownDuration; @@ -123,7 +125,7 @@ private: &ObjectFlamePoleFoot::calcState5>(5)}, }}; - static constexpr u32 CYCLE_FRAMES = 540; + static constexpr s32 CYCLE_FRAMES = 540; }; } // namespace Field diff --git a/source/game/field/obj/ObjectFlamePoleV.cc b/source/game/field/obj/ObjectFlamePoleV.cc index 12e09f2b..8f8558bd 100644 --- a/source/game/field/obj/ObjectFlamePoleV.cc +++ b/source/game/field/obj/ObjectFlamePoleV.cc @@ -6,10 +6,8 @@ namespace Field { /// @addr{0x806C3AA4} ObjectFlamePoleV::ObjectFlamePoleV(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), - m_initDelay(static_cast(params.setting(1))), - m_cycleDuration(static_cast(params.setting(0))), - m_dormantFrames(static_cast(params.setting(3)) + 200), + : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), m_initDelay(params.setting(1)), + m_cycleDuration(params.setting(0)), m_dormantFrames(params.setting(3) + 200), m_scaleFactor(params.setting(2) == 0 ? 5.0f : static_cast(params.setting(2))), m_initPosY(m_pos.y), m_isBig(strcmp(getName(), "FlamePole_v_big") == 0) { constexpr f32 M_D8 = 384.0f; @@ -50,7 +48,7 @@ void ObjectFlamePoleV::init() { /// @addr{0x806C3FCC} void ObjectFlamePoleV::calc() { - if (System::RaceManager::Instance()->timer() <= m_initDelay) { + if (System::RaceManager::Instance()->timer() <= static_cast(m_initDelay)) { return; } diff --git a/source/game/field/obj/ObjectFlamePoleV.hh b/source/game/field/obj/ObjectFlamePoleV.hh index c7ed0645..52f73179 100644 --- a/source/game/field/obj/ObjectFlamePoleV.hh +++ b/source/game/field/obj/ObjectFlamePoleV.hh @@ -89,7 +89,7 @@ private: accel = initVel * initVel / doublePeak; } - const u32 m_initDelay; + const s32 m_initDelay; const s32 m_cycleDuration; const s32 m_dormantFrames; const f32 m_scaleFactor; diff --git a/source/game/field/obj/ObjectHanachan.cc b/source/game/field/obj/ObjectHanachan.cc index ece93984..8bf9dd64 100644 --- a/source/game/field/obj/ObjectHanachan.cc +++ b/source/game/field/obj/ObjectHanachan.cc @@ -119,7 +119,7 @@ void ObjectHanachanBody::calcCollisionTransform() { /// @addr{0x806C8A5C} ObjectHanachan::ObjectHanachan(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), m_chain(BODY_PART_DISTANCES), - m_movingVel(static_cast(static_cast(params.setting(0)))) { + m_movingVel(static_cast(params.setting(0))) { constexpr f32 SCALE = 3.0f; constexpr EGG::Vector3f SCALE_VEC = EGG::Vector3f(SCALE, SCALE, SCALE); diff --git a/source/game/field/obj/ObjectHeyho.cc b/source/game/field/obj/ObjectHeyho.cc index e1466ecc..1b4e853b 100644 --- a/source/game/field/obj/ObjectHeyho.cc +++ b/source/game/field/obj/ObjectHeyho.cc @@ -21,7 +21,7 @@ ObjectHeyho::ObjectHeyho(const System::MapdataGeoObj ¶ms) // We form an acceleration constant so multiplying with (pos - center) gives v^2 // This way, we can inversely correlate height difference with speed ASSERT(m_apex - m_midpoint.y > std::numeric_limits::epsilon()); - f32 maxVel = static_cast(static_cast(params.setting(0))); + f32 maxVel = static_cast(params.setting(0)); m_maxVelSq = maxVel * maxVel; m_accel = m_maxVelSq / (m_apex - m_midpoint.y); } diff --git a/source/game/field/obj/ObjectHeyhoShip.cc b/source/game/field/obj/ObjectHeyhoShip.cc index 00b7b0cc..5a9ac930 100644 --- a/source/game/field/obj/ObjectHeyhoShip.cc +++ b/source/game/field/obj/ObjectHeyhoShip.cc @@ -4,8 +4,8 @@ namespace Field { /// @addr{0x806D18FC} ObjectHeyhoShip::ObjectHeyhoShip(const System::MapdataGeoObj ¶ms) - : ObjectProjectileLauncher(params), - m_yAmplitude(static_cast(static_cast(params.setting(1)))), m_frame(0) { + : ObjectProjectileLauncher(params), m_yAmplitude(static_cast(params.setting(1))), + m_frame(0) { registerManagedObject(); } diff --git a/source/game/field/obj/ObjectItemboxLine.cc b/source/game/field/obj/ObjectItemboxLine.cc index d9d0f41f..c7bdef25 100644 --- a/source/game/field/obj/ObjectItemboxLine.cc +++ b/source/game/field/obj/ObjectItemboxLine.cc @@ -7,17 +7,13 @@ namespace Field { /// @addr{0x8076D044} ObjectItemboxLine::ObjectItemboxLine(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params) { + : ObjectCollidable(params), m_cooldownDuration(params.setting(5)) { constexpr u32 DEFAULT_PRESS_COUNT = 5; auto *senko = new ObjectPressSenko(params); senko->load(); - u32 pressCount = params.setting(6); - if (pressCount == 0) { - pressCount = DEFAULT_PRESS_COUNT; - } - + s32 pressCount = (params.setting(6) == 0) ? DEFAULT_PRESS_COUNT : params.setting(6); m_press = std::span(new ObjectItemboxPress *[pressCount], pressCount); for (auto *&press : m_press) { @@ -36,10 +32,9 @@ ObjectItemboxLine::~ObjectItemboxLine() { /// @addr{0x8076D604} void ObjectItemboxLine::init() { ASSERT(m_mapObj); - u32 timer = static_cast(m_mapObj->setting(4)); - + s32 timer = static_cast(m_mapObj->setting(4)); if (timer == 0) { - timer = static_cast(m_mapObj->setting(5)); + timer = m_cooldownDuration; } m_stompCooldown = timer; @@ -52,8 +47,7 @@ void ObjectItemboxLine::calc() { return; } - m_stompCooldown = static_cast(m_mapObj->setting(5)); - + m_stompCooldown = m_cooldownDuration; m_press[m_curPressIdx]->startPress(); m_curPressIdx = (m_curPressIdx + 1) % m_press.size(); } diff --git a/source/game/field/obj/ObjectItemboxLine.hh b/source/game/field/obj/ObjectItemboxLine.hh index 9bce70d7..011fe181 100644 --- a/source/game/field/obj/ObjectItemboxLine.hh +++ b/source/game/field/obj/ObjectItemboxLine.hh @@ -23,8 +23,9 @@ public: private: std::span m_press; - u32 m_stompCooldown; ///< Number of frames in between stomps + s32 m_stompCooldown; ///< Number of frames in between stomps u32 m_curPressIdx; + const s32 m_cooldownDuration; }; } // namespace Field diff --git a/source/game/field/obj/ObjectKinoko.cc b/source/game/field/obj/ObjectKinoko.cc index e256182f..b5fe1cb9 100644 --- a/source/game/field/obj/ObjectKinoko.cc +++ b/source/game/field/obj/ObjectKinoko.cc @@ -49,7 +49,7 @@ ObjectKinokoUd::ObjectKinokoUd(const System::MapdataGeoObj ¶ms) : ObjectKino m_oscFrame = params.setting(3); m_waitDuration = params.setting(4); m_amplitude = params.setting(1); - m_period = std::max(params.setting(2), 2); + m_period = std::max(params.setting(2), 2); m_angFreq = F_TAU / static_cast(m_period); } @@ -81,7 +81,7 @@ void ObjectKinokoUd::calcOscillation() { ObjectKinokoBend::ObjectKinokoBend(const System::MapdataGeoObj ¶ms) : ObjectKinoko(params) { m_currentFrame = params.setting(3); m_amplitude = static_cast(params.setting(1)) * DEG2RAD; - m_period = std::max(params.setting(2), 2); + m_period = std::max(params.setting(2), 2); m_angFreq = F_TAU / static_cast(m_period); } diff --git a/source/game/field/obj/ObjectKinoko.hh b/source/game/field/obj/ObjectKinoko.hh index 34b1edf2..e93daebe 100644 --- a/source/game/field/obj/ObjectKinoko.hh +++ b/source/game/field/obj/ObjectKinoko.hh @@ -4,7 +4,7 @@ namespace Field { -enum class KinokoType : u16 { +enum class KinokoType : s16 { Light = 0, Dark = 1, }; @@ -35,7 +35,7 @@ protected: s16 m_pulseFrame; s16 m_restFrame; s16 m_pulseFalloff; - u16 m_oscFrame; + s16 m_oscFrame; }; /// @brief Mushrooms which oscillate up and down. The stem does not move. diff --git a/source/game/field/obj/ObjectKoopaFigure64.cc b/source/game/field/obj/ObjectKoopaFigure64.cc index a02e7316..7e7539bc 100644 --- a/source/game/field/obj/ObjectKoopaFigure64.cc +++ b/source/game/field/obj/ObjectKoopaFigure64.cc @@ -9,7 +9,7 @@ namespace Field { /// @addr{0x806DA914} ObjectKoopaFigure64::ObjectKoopaFigure64(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), m_isBigStatue(params.setting(1) == 1), - m_startDelay(static_cast(params.setting(2))) {} + m_startDelay(params.setting(2)) {} /// @addr{0x806DB114} ObjectKoopaFigure64::~ObjectKoopaFigure64() = default; @@ -36,7 +36,7 @@ void ObjectKoopaFigure64::init() { /// @addr{0x806DAB5C} void ObjectKoopaFigure64::calc() { u32 timer = System::RaceManager::Instance()->timer(); - if (timer < m_startDelay) { + if (timer < static_cast(m_startDelay)) { return; } diff --git a/source/game/field/obj/ObjectKoopaFigure64.hh b/source/game/field/obj/ObjectKoopaFigure64.hh index a0f6d5c0..0aaff54c 100644 --- a/source/game/field/obj/ObjectKoopaFigure64.hh +++ b/source/game/field/obj/ObjectKoopaFigure64.hh @@ -38,7 +38,7 @@ public: private: const bool m_isBigStatue; ///< Differentiates the first rBC turn statue from tiny statues - const u32 m_startDelay; + const s32 m_startDelay; u32 m_cycleFrame; static constexpr u32 FIRE_DURATION = 300; ///< How long the statue shoots fire for in a cycle diff --git a/source/game/field/obj/ObjectKuribo.cc b/source/game/field/obj/ObjectKuribo.cc index 4ec7d477..1a0f435c 100644 --- a/source/game/field/obj/ObjectKuribo.cc +++ b/source/game/field/obj/ObjectKuribo.cc @@ -9,9 +9,8 @@ namespace Field { /// @addr{0x806DB184} ObjectKuribo::ObjectKuribo(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), StateManager(this, STATE_ENTRIES) { - ASSERT(m_mapObj); - m_animStep = static_cast(m_mapObj->setting(2)) / 100.0f; - m_speedStep = static_cast(m_mapObj->setting(1)) / 100.0f; + m_animStep = static_cast(params.setting(2)) / 100.0f; + m_speedStep = static_cast(params.setting(1)) / 100.0f; } /// @addr{0x806DB3A0} diff --git a/source/game/field/obj/ObjectObakeBlock.cc b/source/game/field/obj/ObjectObakeBlock.cc index bede504c..c23bd25d 100644 --- a/source/game/field/obj/ObjectObakeBlock.cc +++ b/source/game/field/obj/ObjectObakeBlock.cc @@ -4,7 +4,8 @@ namespace Field { /// @addr{0x8080AD20} ObjectObakeBlock::ObjectObakeBlock(const System::MapdataGeoObj ¶ms) - : ObjectBase(params), m_initialPos(params.pos()), m_fallState(FallState::Rest) { + : ObjectBase(params), m_initialPos(params.pos()), m_fallState(FallState::Rest), + m_fallFrame(params.setting(2) + params.setting(1) * 60) { constexpr f32 SI_WIDTH = 162.5f; // Half-width of block in the spatial index constexpr f32 FALL_LINEAR_SPEED = 1.0f; constexpr f32 FALL_ANGULAR_SPEED = 0.02f; @@ -12,8 +13,6 @@ ObjectObakeBlock::ObjectObakeBlock(const System::MapdataGeoObj ¶ms) m_framesFallen = 0; m_fallVel.setZero(); m_fallAngVel.setZero(); - m_fallFrame = static_cast( - static_cast(params.setting(2)) + static_cast(params.setting(1)) * 60); f32 yRot = params.rot().y; diff --git a/source/game/field/obj/ObjectObakeBlock.hh b/source/game/field/obj/ObjectObakeBlock.hh index 916145c6..361ac63c 100644 --- a/source/game/field/obj/ObjectObakeBlock.hh +++ b/source/game/field/obj/ObjectObakeBlock.hh @@ -51,7 +51,7 @@ private: EGG::Vector3f m_fallVel; EGG::Vector3f m_fallAngVel; EGG::BoundBox3f m_bbox; - s32 m_fallFrame; ///< Frame the block starts falling, or 0 if it never falls. + const s32 m_fallFrame; ///< Frame the block starts falling, or 0 if it never falls. }; } // namespace Field diff --git a/source/game/field/obj/ObjectPakkunF.cc b/source/game/field/obj/ObjectPakkunF.cc index b073628e..b498ba19 100644 --- a/source/game/field/obj/ObjectPakkunF.cc +++ b/source/game/field/obj/ObjectPakkunF.cc @@ -5,7 +5,7 @@ namespace Field { /// @addr{0x807743A4} ObjectPakkunF::ObjectPakkunF(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), m_attackFrames(0), m_currAttackFrame(0), - m_waitDuration(static_cast(m_mapObj->setting(0))) {} + m_waitDuration(params.setting(0)) {} /// @addr{0x807754FC} ObjectPakkunF::~ObjectPakkunF() = default; diff --git a/source/game/field/obj/ObjectPakkunF.hh b/source/game/field/obj/ObjectPakkunF.hh index 6bce42d9..6b1136e5 100644 --- a/source/game/field/obj/ObjectPakkunF.hh +++ b/source/game/field/obj/ObjectPakkunF.hh @@ -44,7 +44,7 @@ private: /// Total time the piranha will be idle for. Not in the base game, but this prevents /// having to dereference m_mapObj multiple times. - const u32 m_waitDuration; + const s32 m_waitDuration; }; } // namespace Field diff --git a/source/game/field/obj/ObjectPillar.cc b/source/game/field/obj/ObjectPillar.cc index da74befc..e7900146 100644 --- a/source/game/field/obj/ObjectPillar.cc +++ b/source/game/field/obj/ObjectPillar.cc @@ -13,7 +13,7 @@ ObjectPillarBase::~ObjectPillarBase() = default; /// @addr{0x807FEB68} ObjectPillarC::ObjectPillarC(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), m_fallStart(static_cast(params.setting(0))) {} + : ObjectCollidable(params), m_fallStart(params.setting(0)) {} /// @addr{0x807FFAE0} ObjectPillarC::~ObjectPillarC() = default; @@ -37,7 +37,7 @@ void ObjectPillarC::calcCollisionTransform() { /// @addr{0x807FED80} ObjectPillar::ObjectPillar(const System::MapdataGeoObj ¶ms) - : ObjectKCL(params), m_state(State::Upright), m_fallStart(static_cast(params.setting(0))), + : ObjectKCL(params), m_state(State::Upright), m_fallStart(params.setting(0)), m_targetRotation(F_PI * static_cast(params.setting(1)) / 180.0f), m_initRot(m_rot.x), m_setupRot(EGG::Vector3f::zero) { m_base = new ObjectPillarBase(params); @@ -63,7 +63,7 @@ void ObjectPillar::init() { /// @addr{0x807FF17C} void ObjectPillar::calc() { - u32 time = System::RaceManager::Instance()->timer(); + s32 time = System::RaceManager::Instance()->timer(); if (m_state == State::Upright && time < m_fallStart) { m_collidable->enableCollision(); @@ -71,7 +71,7 @@ void ObjectPillar::calc() { // The pillar has now started to fall. m_state = State::Break; } else if (m_state == State::Break) { - f32 rot = calcRot(static_cast(time)); + f32 rot = calcRot(time); if (rot < m_targetRotation) { m_transform = getUpdatedMatrix(0); m_pos = m_transform.base(3); diff --git a/source/game/field/obj/ObjectPillar.hh b/source/game/field/obj/ObjectPillar.hh index 20acbca5..dc5343f4 100644 --- a/source/game/field/obj/ObjectPillar.hh +++ b/source/game/field/obj/ObjectPillar.hh @@ -51,11 +51,12 @@ public: Kart::Reaction onCollision(Kart::KartObject * /*kartObj*/, Kart::Reaction reactionOnKart, Kart::Reaction /*reactionOnObj*/, EGG::Vector3f & /*hitDepth*/) override { auto *raceMgr = System::RaceManager::Instance(); - return raceMgr->timer() < m_fallStart ? Kart::Reaction::WallAllSpeed : reactionOnKart; + return raceMgr->timer() < static_cast(m_fallStart) ? Kart::Reaction::WallAllSpeed : + reactionOnKart; } private: - const u32 m_fallStart; ///< The number of frames before the pillar will start to fall. + const s32 m_fallStart; ///< The number of frames before the pillar will start to fall. }; /// @brief Represents the entirety of a pillar that falls on Dry Dry Ruins. @@ -91,7 +92,7 @@ private: [[nodiscard]] f32 calcRot(s32 frame) const; State m_state; ///< 0 when upright, 1 when falling, and 2 afterwards. - const u32 m_fallStart; ///< The number of frames before the pillar will start to fall. + const s32 m_fallStart; ///< The number of frames before the pillar will start to fall. const f32 m_targetRotation; ///< How much the pillar rotates during the fall, in radians. const f32 m_initRot; EGG::Vector3f m_setupRot; ///< Initial rotation of the pillar. diff --git a/source/game/field/obj/ObjectPress.cc b/source/game/field/obj/ObjectPress.cc index e3b38d29..1bb41244 100644 --- a/source/game/field/obj/ObjectPress.cc +++ b/source/game/field/obj/ObjectPress.cc @@ -9,7 +9,7 @@ namespace Field { /// @addr{0x80777564} ObjectPress::ObjectPress(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), m_loweringVelocity(0.0f) {} + : ObjectCollidable(params), m_loweringVelocity(0.0f), m_raisedDuration(params.setting(2)) {} /// @addr{0x807775FC} ObjectPress::~ObjectPress() = default; @@ -24,7 +24,7 @@ void ObjectPress::init() { m_startingRise = false; m_anmDuration = 0; ASSERT(m_mapObj); - m_raisedTimer = static_cast(m_mapObj->setting(1)); + m_raisedTimer = static_cast(m_mapObj->setting(1)); m_windUpTimer = 0; m_raisedHeight = m_pos.y; @@ -191,8 +191,7 @@ void ObjectPress::calcRaising() { } else { m_pos.y = m_raisedHeight; m_state = State::Raised; - ASSERT(m_mapObj); - m_raisedTimer = static_cast(m_mapObj->setting(2)); + m_raisedTimer = m_raisedDuration; } m_flags.setBit(eFlags::Position); diff --git a/source/game/field/obj/ObjectPress.hh b/source/game/field/obj/ObjectPress.hh index db2ed142..c26fd00f 100644 --- a/source/game/field/obj/ObjectPress.hh +++ b/source/game/field/obj/ObjectPress.hh @@ -51,13 +51,15 @@ private: void calcRaising(); bool m_startingRise; ///< Used to delay state change by 1 frame - u32 m_raisedTimer; ///< Number of frames remaining in raised state + s32 m_raisedTimer; ///< Number of frames remaining in raised state u32 m_anmDuration; f32 m_loweringVelocity; f32 m_raisedHeight; f32 m_loweredHeight; bool m_startedLowered; ///< Used to induce crush effect even if it hit floor this frame + const s32 m_raisedDuration; + static constexpr f32 ANM_RATE = 2.0f; }; diff --git a/source/game/field/obj/ObjectRock.cc b/source/game/field/obj/ObjectRock.cc index 81ceb8af..ec3ee31f 100644 --- a/source/game/field/obj/ObjectRock.cc +++ b/source/game/field/obj/ObjectRock.cc @@ -7,7 +7,10 @@ namespace Field { /// @addr {0x8076F2E0} -ObjectRock::ObjectRock(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params) {} +ObjectRock::ObjectRock(const System::MapdataGeoObj ¶ms) + : ObjectCollidable(params), m_cooldownDuration(params.setting(1)), + m_vel(static_cast(params.setting(2))), + m_intangibleHeight(static_cast(params.setting(3))) {} /// @addr{0x8076F344} ObjectRock::~ObjectRock() = default; @@ -15,7 +18,7 @@ ObjectRock::~ObjectRock() = default; /// @addr{0x8076F384} void ObjectRock::init() { m_railInterpolator->init(0.0f, 0); - m_railInterpolator->setCurrVel(static_cast(m_mapObj->setting(2))); + m_railInterpolator->setCurrVel(m_vel); m_railInterpolator->calc(); m_state = State::Tangible; @@ -30,7 +33,7 @@ void ObjectRock::init() { m_angSpd = INITIAL_ANGULAR_SPEED; m_cooldownTimer = m_mapObj->setting(0); m_colTranslate.x = 0.0f; - m_colTranslate.y = static_cast(m_mapObj->setting(3)); + m_colTranslate.y = m_intangibleHeight; m_colTranslate.z = 0.0f; calcTransform(); } @@ -78,8 +81,8 @@ void ObjectRock::calcIntangible() { if (m_cooldownTimer < 0) { m_state = State::Tangible; m_angSpd = INITIAL_ANGULAR_SPEED; - m_colTranslate.y = static_cast(m_mapObj->setting(3)); - m_cooldownTimer = m_mapObj->setting(1); + m_colTranslate.y = m_intangibleHeight; + m_cooldownTimer = m_cooldownDuration; enableCollision(); } } @@ -110,9 +113,7 @@ void ObjectRock::checkSphereFull() { if (CollisionDirector::Instance()->checkSphereFull(50.0f, pos, EGG::Vector3f::inf, KCL_TYPE_FLOOR, &info, nullptr, 0)) { m_colTranslate.y *= -0.3f; - m_angSpd = std::max(360.0f * static_cast(m_mapObj->setting(2)) / - (480.0f * m_scale.x * F_PI), - m_angSpd + 1.0f); + m_angSpd = std::max(360.0f * m_vel / (480.0f * m_scale.x * F_PI), m_angSpd + 1.0f); m_flags.setBit(eFlags::Position); m_pos += info.tangentOff; } @@ -122,7 +123,7 @@ void ObjectRock::checkSphereFull() { void ObjectRock::breakRock() { m_state = State::Intangible; m_railInterpolator->init(0.0f, 0); - m_railInterpolator->setCurrVel(static_cast(m_mapObj->setting(2))); + m_railInterpolator->setCurrVel(m_vel); m_flags.setBit(eFlags::Position); m_pos.y = m_startYPos; diff --git a/source/game/field/obj/ObjectRock.hh b/source/game/field/obj/ObjectRock.hh index fd892263..c83696b3 100644 --- a/source/game/field/obj/ObjectRock.hh +++ b/source/game/field/obj/ObjectRock.hh @@ -47,6 +47,10 @@ private: int m_cooldownTimer; f32 m_angRad; + const s32 m_cooldownDuration; + const f32 m_vel; + const f32 m_intangibleHeight; + static constexpr f32 INITIAL_ANGULAR_SPEED = 3.0f; }; diff --git a/source/game/field/obj/ObjectSandcone.cc b/source/game/field/obj/ObjectSandcone.cc index 23a57e7e..ddc26d09 100644 --- a/source/game/field/obj/ObjectSandcone.cc +++ b/source/game/field/obj/ObjectSandcone.cc @@ -5,10 +5,9 @@ namespace Field { /// @addr{0x80686F84} -ObjectSandcone::ObjectSandcone(const System::MapdataGeoObj ¶ms) : ObjectKCL(params) { - m_flowRate = static_cast(params.setting(0)) / 100.0f; - m_finalHeightDelta = static_cast(params.setting(1)); - m_startFrame = params.setting(2); +ObjectSandcone::ObjectSandcone(const System::MapdataGeoObj ¶ms) + : ObjectKCL(params), m_flowRate(static_cast(params.setting(0)) / 100.0f), + m_finalHeightDelta(static_cast(params.setting(1))), m_startFrame(params.setting(2)) { m_baseMtx.makeRT(m_rot, m_pos); } @@ -17,7 +16,7 @@ ObjectSandcone::~ObjectSandcone() = default; /// @addr{0x806872A0} void ObjectSandcone::init() { - m_duration = m_finalHeightDelta / m_flowRate; + m_duration = static_cast(m_finalHeightDelta / m_flowRate); m_currentMtx = m_baseMtx; // Moved from getUpdatedMatrix to init b/c this only needs to be computed once per object. @@ -35,14 +34,15 @@ void ObjectSandcone::calc() { const EGG::Matrix34f &ObjectSandcone::getUpdatedMatrix(u32 timeOffset) { m_currentMtx = m_baseMtx; - u32 t = System::RaceManager::Instance()->timer() - timeOffset; + s32 t = static_cast(System::RaceManager::Instance()->timer() - timeOffset); + s32 startFrame = static_cast(m_startFrame); - if (t > m_startFrame + m_duration) { + if (t > startFrame + static_cast(m_duration)) { // The sandcone has finished "flowing", so just return the final position. // For Kinoko, we introduce a slight performance improvement by caching the m_finalPos. m_currentMtx.setBase(3, m_finalPos); - } else if (t > m_startFrame) { - EGG::Vector3f deltaPos = EGG::Vector3f::ey * ((t - m_startFrame) * m_flowRate); + } else if (t > startFrame) { + EGG::Vector3f deltaPos = EGG::Vector3f::ey * ((t - startFrame) * m_flowRate); m_currentMtx.setBase(3, m_baseMtx.base(3) + deltaPos); } diff --git a/source/game/field/obj/ObjectSandcone.hh b/source/game/field/obj/ObjectSandcone.hh index 27b332d4..fbb1bb84 100644 --- a/source/game/field/obj/ObjectSandcone.hh +++ b/source/game/field/obj/ObjectSandcone.hh @@ -26,9 +26,9 @@ public: KCLTypeMask *maskOut, u32 timeOffset) override; private: - f32 m_flowRate; - f32 m_finalHeightDelta; - u16 m_startFrame; + const f32 m_flowRate; + const f32 m_finalHeightDelta; + const s16 m_startFrame; u16 m_duration; EGG::Matrix34f m_baseMtx; EGG::Matrix34f m_currentMtx; diff --git a/source/game/field/obj/ObjectSunDS.cc b/source/game/field/obj/ObjectSunDS.cc index 447444fe..244f2366 100644 --- a/source/game/field/obj/ObjectSunDS.cc +++ b/source/game/field/obj/ObjectSunDS.cc @@ -7,8 +7,7 @@ namespace Field { /// @addr{0x806DDDD8} ObjectSunDS::ObjectSunDS(const System::MapdataGeoObj ¶ms) : ObjectProjectileLauncher(params), StateManager(this, STATE_ENTRIES), - m_revolutionSpeed(static_cast(params.setting(0))), - m_startFrame(static_cast(params.setting(1))) {} + m_revolutionSpeed(params.setting(0)), m_startFrame(params.setting(1)) {} /// @addr{0x806DDF68} ObjectSunDS::~ObjectSunDS() = default; diff --git a/source/game/field/obj/ObjectTownBridge.cc b/source/game/field/obj/ObjectTownBridge.cc index 2cff3788..1fde3760 100644 --- a/source/game/field/obj/ObjectTownBridge.cc +++ b/source/game/field/obj/ObjectTownBridge.cc @@ -7,13 +7,11 @@ namespace Field { /// @addr{0x80809448} -ObjectTownBridge::ObjectTownBridge(const System::MapdataGeoObj ¶ms) : ObjectKCL(params) { - m_rotateUpwards = m_rot.y < 0.0f; - m_angVel = static_cast(params.setting(0)); - m_pivotFrames = static_cast(params.setting(1)); - m_raisedFrames = static_cast(params.setting(2)); - m_loweredFrames = static_cast(params.setting(3)); - m_fullAnimFrames = m_pivotFrames * 2 + (m_loweredFrames + m_raisedFrames); +ObjectTownBridge::ObjectTownBridge(const System::MapdataGeoObj ¶ms) + : ObjectKCL(params), m_rotateUpwards(m_rot.y < 0.0f), + m_angVel(static_cast(params.setting(0))), m_pivotFrames(params.setting(1)), + m_raisedFrames(params.setting(2)), m_loweredFrames(params.setting(3)), + m_fullAnimFrames(m_pivotFrames * 2 + (m_loweredFrames + m_raisedFrames)) { m_state = State::Raising; } @@ -36,7 +34,7 @@ ObjectTownBridge::~ObjectTownBridge() { /// @addr{0x80809774} void ObjectTownBridge::calc() { - u32 t = System::RaceManager::Instance()->timer(); + s32 t = System::RaceManager::Instance()->timer(); f32 angle = calcBridgeAngle(t); // Set the object collision based off the angle of the bridge. @@ -75,7 +73,7 @@ void ObjectTownBridge::createCollision() { } /// @addr{0x80809CDC} -f32 ObjectTownBridge::calcBridgeAngle(u32 t) const { +f32 ObjectTownBridge::calcBridgeAngle(s32 t) const { u32 animFrame = t % m_fullAnimFrames; State state = calcState(animFrame); @@ -104,7 +102,7 @@ f32 ObjectTownBridge::calcBridgeAngle(u32 t) const { } /// @brief Helper function which determines the current state of the bridge based on t. -ObjectTownBridge::State ObjectTownBridge::calcState(u32 t) const { +ObjectTownBridge::State ObjectTownBridge::calcState(s32 t) const { if (t < m_pivotFrames) { return State::Raising; } diff --git a/source/game/field/obj/ObjectTownBridge.hh b/source/game/field/obj/ObjectTownBridge.hh index 17eba0f6..ab6b440e 100644 --- a/source/game/field/obj/ObjectTownBridge.hh +++ b/source/game/field/obj/ObjectTownBridge.hh @@ -29,15 +29,15 @@ public: } private: - [[nodiscard]] f32 calcBridgeAngle(u32 t) const; - [[nodiscard]] State calcState(u32 t) const; - - bool m_rotateUpwards; ///< Normally 1, otherwise the bridge will open downwards. - f32 m_angVel; ///< Speed of the bridge's movement. - u32 m_pivotFrames; ///< # of frames the bridge pivots up or down. - u32 m_raisedFrames; ///< # of frames the bridge remains raised. - u32 m_loweredFrames; ///< # of frames the bridge remains lowered. - u32 m_fullAnimFrames; ///< The full duration of a bridge raise/lower loop. + [[nodiscard]] f32 calcBridgeAngle(s32 t) const; + [[nodiscard]] State calcState(s32 t) const; + + const bool m_rotateUpwards; ///< Normally 1, otherwise the bridge will open downwards. + const f32 m_angVel; ///< Speed of the bridge's movement. + const s32 m_pivotFrames; ///< # of frames the bridge pivots up or down. + const s32 m_raisedFrames; ///< # of frames the bridge remains raised. + const s32 m_loweredFrames; ///< # of frames the bridge remains lowered. + const s32 m_fullAnimFrames; ///< The full duration of a bridge raise/lower loop. State m_state; ObjColMgr *m_raisedColMgr; ObjColMgr *m_midColMgr; diff --git a/source/game/field/obj/ObjectTruckWagon.cc b/source/game/field/obj/ObjectTruckWagon.cc index 646f4601..e3355ebf 100644 --- a/source/game/field/obj/ObjectTruckWagon.cc +++ b/source/game/field/obj/ObjectTruckWagon.cc @@ -202,8 +202,8 @@ void ObjectTruckWagonCart::reset(u32 idx) { /// @addr{0x806E206C} ObjectTruckWagon::ObjectTruckWagon(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), m_spawn2Frame(static_cast(params.setting(1))), - m_cycleDuration(static_cast(params.setting(2))) { + : ObjectCollidable(params), m_spawn2Frame(params.setting(1)), + m_cycleDuration(params.setting(2)) { constexpr u32 CART_COUNT = 12; // For now, we don't care about low LOD minecarts since they don't have collision. diff --git a/source/game/field/obj/ObjectVolcanoBall.hh b/source/game/field/obj/ObjectVolcanoBall.hh index 06e52eb9..cd669d29 100644 --- a/source/game/field/obj/ObjectVolcanoBall.hh +++ b/source/game/field/obj/ObjectVolcanoBall.hh @@ -53,12 +53,12 @@ private: /// @addr{0x806E3324} void calcBurning() { - if (m_currentFrame >= m_burnDuration) { + if (m_currentFrame >= static_cast(m_burnDuration)) { m_nextStateId = 0; } } - const u16 m_burnDuration; ///< How long the ball burns for before disappearing + const s16 m_burnDuration; ///< How long the ball burns for before disappearing const f32 m_accel; const f32 m_finalVel; ///< Velocity of the ball at the moment of impact const f32 m_endPosY; ///< Height of the ball at the end of its rail diff --git a/source/game/field/obj/ObjectVolcanoBallLauncher.cc b/source/game/field/obj/ObjectVolcanoBallLauncher.cc index a7fb4354..c8001648 100644 --- a/source/game/field/obj/ObjectVolcanoBallLauncher.cc +++ b/source/game/field/obj/ObjectVolcanoBallLauncher.cc @@ -9,8 +9,8 @@ namespace Field { /// @addr{0x806E3458} ObjectVolcanoBallLauncher::ObjectVolcanoBallLauncher(const System::MapdataGeoObj ¶ms) - : ObjectCollidable(params), m_initDelay(static_cast(static_cast(params.setting(1)))), - m_cycleDuration(static_cast(static_cast(params.setting(2)))) { + : ObjectCollidable(params), m_initDelay(static_cast(params.setting(1))), + m_cycleDuration(static_cast(params.setting(2))) { const auto *rail = RailManager::Instance()->rail(params.pathId()); ASSERT(rail); const auto &points = rail->points(); @@ -26,7 +26,7 @@ ObjectVolcanoBallLauncher::ObjectVolcanoBallLauncher(const System::MapdataGeoObj EGG::Vector3f dir = points[1].pos - points[0].pos; dir.normalise2(); - EGG::Vector3f vel = dir * static_cast(static_cast(params.setting(0))); + EGG::Vector3f vel = dir * static_cast(params.setting(0)); f32 accel = vel.y * vel.y / (2.0f * (pos - points[0].pos.y)); f32 endPosY = points.back().pos.y; @@ -38,8 +38,8 @@ ObjectVolcanoBallLauncher::ObjectVolcanoBallLauncher(const System::MapdataGeoObj f32 fallTime = (t2 > 0.0f) ? t2 : (t1 > 0.0f) ? t1 : -1.0f; f32 finalVel = 2.0f * accel * (pos - endPosY); - f32 burnDuration = static_cast(static_cast(params.setting(3))); - u32 ballCount = static_cast((fallTime + burnDuration) / m_cycleDuration) + 2; + f32 burnDuration = static_cast(params.setting(3)); + s32 ballCount = static_cast((fallTime + burnDuration) / m_cycleDuration) + 2; m_balls = std::span(new ObjectVolcanoBall *[ballCount], ballCount); diff --git a/source/game/field/obj/ObjectVolcanoPiece.cc b/source/game/field/obj/ObjectVolcanoPiece.cc index 8a9070d0..b55e59ae 100644 --- a/source/game/field/obj/ObjectVolcanoPiece.cc +++ b/source/game/field/obj/ObjectVolcanoPiece.cc @@ -11,8 +11,8 @@ ObjectVolcanoPiece::ObjectVolcanoPiece(const System::MapdataGeoObj ¶ms) m_shakeDuration(m_restDuration + params.setting(2) * 60), m_quakeDuration(m_shakeDuration + params.setting(7) + 1), m_colMgrB(nullptr), m_colMgrC(nullptr) { - snprintf(m_modelName, sizeof(m_modelName), "VolcanoPiece%hd", - static_cast(params.setting(0))); + snprintf(m_modelName, sizeof(m_modelName), "VolcanoPiece%d", + static_cast(params.setting(0))); } /// @addr{0x80803DA8} @@ -23,7 +23,7 @@ ObjectVolcanoPiece::~ObjectVolcanoPiece() { /// @addr{0x80819400} void ObjectVolcanoPiece::calc() { - u32 timer = System::RaceManager::Instance()->timer(); + s32 timer = static_cast(static_cast(System::RaceManager::Instance()->timer())); if (calcState(timer) == State::Fall && FALL_DURATION - 1 == calcT(timer)) { update(0); } @@ -187,7 +187,8 @@ void ObjectVolcanoPiece::update(u32 timeOffset) { /// @addr{0x80818674} void ObjectVolcanoPiece::calcScale(u32 timeOffset) { - State state = calcState(System::RaceManager::Instance()->timer() - timeOffset); + State state = calcState(static_cast( + static_cast(System::RaceManager::Instance()->timer() - timeOffset))); if (state == State::Rest || state == State::Gone) { return; @@ -272,7 +273,7 @@ const EGG::Matrix34f &ObjectVolcanoPiece::calcShakeAndFall(EGG::Vector3f *vel, u } /// @addr{0x80818FCC} -ObjectVolcanoPiece::State ObjectVolcanoPiece::calcState(u32 frame) const { +ObjectVolcanoPiece::State ObjectVolcanoPiece::calcState(s32 frame) const { if (frame < m_restDuration) { return State::Rest; } @@ -293,7 +294,7 @@ ObjectVolcanoPiece::State ObjectVolcanoPiece::calcState(u32 frame) const { } /// @addr{0x80819028} -f32 ObjectVolcanoPiece::calcT(u32 frame) const { +f32 ObjectVolcanoPiece::calcT(s32 frame) const { if (frame < m_restDuration) { return static_cast(frame); } diff --git a/source/game/field/obj/ObjectVolcanoPiece.hh b/source/game/field/obj/ObjectVolcanoPiece.hh index cef2512d..2b1b77f8 100644 --- a/source/game/field/obj/ObjectVolcanoPiece.hh +++ b/source/game/field/obj/ObjectVolcanoPiece.hh @@ -205,20 +205,20 @@ private: }; const EGG::Matrix34f &calcShakeAndFall(EGG::Vector3f *vel, u32 timeOffset); - State calcState(u32 frame) const; - f32 calcT(u32 frame) const; + State calcState(s32 frame) const; + f32 calcT(s32 frame) const; char m_modelName[16]; const EGG::Vector3f m_initialPos; const EGG::Vector3f m_initialRot; - const u32 m_restDuration; - const u32 m_shakeDuration; - const u32 m_quakeDuration; + const s32 m_restDuration; + const s32 m_shakeDuration; + const s32 m_quakeDuration; EGG::Matrix34f m_rtMat; ObjColMgr *m_colMgrB; ObjColMgr *m_colMgrC; - static constexpr u32 FALL_DURATION = 900; + static constexpr s32 FALL_DURATION = 900; }; } // namespace Field diff --git a/source/game/field/obj/ObjectVolcanoRock.cc b/source/game/field/obj/ObjectVolcanoRock.cc index d841cc2c..c83ba754 100644 --- a/source/game/field/obj/ObjectVolcanoRock.cc +++ b/source/game/field/obj/ObjectVolcanoRock.cc @@ -4,12 +4,11 @@ namespace Field { /// @addr{0x8081A198} ObjectVolcanoRock::ObjectVolcanoRock(const System::MapdataGeoObj ¶ms) - : ObjectKCL(params), m_initialPos(m_pos), m_initialRot(m_rot), - m_phaseShift(static_cast(params.setting(3))), - m_zPeriod(std::max(static_cast(params.setting(1)), 2)), - m_yPeriod(std::max(static_cast(params.setting(4)), 2)), - m_zAmplitude(static_cast(static_cast(params.setting(2)))), - m_yAmplitude(static_cast(static_cast(params.setting(5)))), + : ObjectKCL(params), m_initialPos(m_pos), m_initialRot(m_rot), m_phaseShift(params.setting(3)), + m_zPeriod(std::max(params.setting(1), 2)), + m_yPeriod(std::max(params.setting(4), 2)), + m_zAmplitude(static_cast(params.setting(2))), + m_yAmplitude(static_cast(params.setting(5))), m_zAngVel(6.2831855f / static_cast(m_zPeriod)), m_yAngVel(6.2831855f / static_cast(m_yPeriod)), m_variant(!!params.setting(0)) { m_pos = calcPos(0); @@ -22,13 +21,13 @@ ObjectVolcanoRock::~ObjectVolcanoRock() = default; /// @addr{0x8081A370} void ObjectVolcanoRock::calc() { EGG::Vector3f prevPos = m_pos; - m_pos = calcPos(System::RaceManager::Instance()->timer()); + m_pos = calcPos(static_cast(System::RaceManager::Instance()->timer())); m_flags.setBit(eFlags::Position); setMovingObjVel(m_pos - prevPos); } /// @addr{0x8081A414} -EGG::Vector3f ObjectVolcanoRock::calcPos(u32 frame) { +EGG::Vector3f ObjectVolcanoRock::calcPos(s32 frame) { f32 tz = static_cast((frame + m_phaseShift) % m_zPeriod); f32 ty = static_cast(frame % m_yPeriod); diff --git a/source/game/field/obj/ObjectVolcanoRock.hh b/source/game/field/obj/ObjectVolcanoRock.hh index cccdad48..4bf9dcfd 100644 --- a/source/game/field/obj/ObjectVolcanoRock.hh +++ b/source/game/field/obj/ObjectVolcanoRock.hh @@ -37,7 +37,7 @@ public: } private: - EGG::Vector3f calcPos(u32 frame); + EGG::Vector3f calcPos(s32 frame); const EGG::Vector3f m_initialPos; const EGG::Vector3f m_initialRot; diff --git a/source/game/field/obj/ObjectWLWallGC.cc b/source/game/field/obj/ObjectWLWallGC.cc index 62f6c4fc..d61e452f 100644 --- a/source/game/field/obj/ObjectWLWallGC.cc +++ b/source/game/field/obj/ObjectWLWallGC.cc @@ -5,23 +5,23 @@ namespace Field { /// @addr{0x8086BC1C} -ObjectWLWallGC::ObjectWLWallGC(const System::MapdataGeoObj ¶ms) : ObjectKCL(params) { - m_extendedDuration = params.setting(1); - m_startFrame = params.setting(4); - u32 rate = params.setting(2); - u16 distance = params.setting(3); +ObjectWLWallGC::ObjectWLWallGC(const System::MapdataGeoObj ¶ms) + : ObjectKCL(params), m_startFrame(params.setting(4)) { + f32 extendedDuration = params.setting(1); + s16 rate = params.setting(2); + s16 distance = params.setting(3); if (rate == 0) { - m_moveDuration = -1; + m_moveDuration = std::numeric_limits::max(); m_hiddenDuration = -1; m_extendedFrame = -1; m_retractingFrame = -1; m_cycleDuration = -1; } else { - m_moveDuration = distance / rate; + m_moveDuration = static_cast(distance) / static_cast(rate); m_hiddenDuration = params.setting(0); m_extendedFrame = m_hiddenDuration + m_moveDuration; - m_retractingFrame = m_extendedFrame + m_extendedDuration; + m_retractingFrame = m_extendedFrame + extendedDuration; m_cycleDuration = m_retractingFrame + m_moveDuration; } @@ -60,17 +60,20 @@ void ObjectWLWallGC::calc() { /// @addr{0x8086BF30} const EGG::Matrix34f &ObjectWLWallGC::getUpdatedMatrix(u32 timeOffset) { - s32 time = cycleFrame(System::RaceManager::Instance()->timer() - timeOffset); + u32 time = cycleFrame(System::RaceManager::Instance()->timer() - timeOffset); f32 t; - if (time < m_hiddenDuration) { + if (time < static_cast(m_hiddenDuration)) { t = 0.0f; - } else if (time < m_extendedFrame) { - t = static_cast(time - m_hiddenDuration) / static_cast(m_moveDuration); - } else if (time < m_retractingFrame) { + } else if (time < static_cast(m_extendedFrame)) { + t = static_cast(time - static_cast(m_hiddenDuration)) / + static_cast(m_moveDuration); + } else if (time < static_cast(m_retractingFrame)) { t = 1.0f; } else { - t = 1.0f - static_cast(time - m_retractingFrame) / static_cast(m_moveDuration); + t = 1.0f - + static_cast(time - static_cast(m_retractingFrame)) / + static_cast(m_moveDuration); } m_currTransform.setBase(3, Interpolate(t, m_initialPos, m_targetPos)); diff --git a/source/game/field/obj/ObjectWLWallGC.hh b/source/game/field/obj/ObjectWLWallGC.hh index 0016e202..0a5da545 100644 --- a/source/game/field/obj/ObjectWLWallGC.hh +++ b/source/game/field/obj/ObjectWLWallGC.hh @@ -38,9 +38,8 @@ private: return time % m_cycleDuration; } - s32 m_extendedDuration; u32 m_moveDuration; - s32 m_startFrame; + const s32 m_startFrame; s32 m_hiddenDuration; s32 m_extendedFrame; s32 m_retractingFrame; diff --git a/source/game/field/obj/ObjectWanwan.cc b/source/game/field/obj/ObjectWanwan.cc index 51bd97aa..52cf69d0 100644 --- a/source/game/field/obj/ObjectWanwan.cc +++ b/source/game/field/obj/ObjectWanwan.cc @@ -16,8 +16,8 @@ ObjectWanwan::ObjectWanwan(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), m_pitch(0.0f), m_chainLength(static_cast(params.setting(0))), m_attackDistance(4800.0f + static_cast(params.setting(2))), - m_attackArcTargetX(10.0f * static_cast(static_cast(params.setting(3)))), - m_attackArcTargetZ(10.0f * static_cast(static_cast(params.setting(4)))), + m_attackArcTargetX(10.0f * static_cast(params.setting(3))), + m_attackArcTargetZ(10.0f * static_cast(params.setting(4))), m_chainAttachMat(EGG::Matrix34f::ident) { constexpr EGG::Vector3f ANCHOR_OFFSET = EGG::Vector3f(0.0f, 20.0f, 0.0f); constexpr EGG::Vector3f POS_OFFSET_MCWII = EGG::Vector3f(14500.0f, 1300.0f, 44850.0f); diff --git a/source/game/field/obj/ObjectWoodboxW.cc b/source/game/field/obj/ObjectWoodboxW.cc index 790bad19..d7e6c600 100644 --- a/source/game/field/obj/ObjectWoodboxW.cc +++ b/source/game/field/obj/ObjectWoodboxW.cc @@ -5,17 +5,13 @@ namespace Field { /// @addr{0x8077DF24} -ObjectWoodboxW::ObjectWoodboxW(const System::MapdataGeoObj ¶ms) : ObjectCollidable(params) { +ObjectWoodboxW::ObjectWoodboxW(const System::MapdataGeoObj ¶ms) + : ObjectCollidable(params), m_cooldownDuration(params.setting(5)) { constexpr u16 DEFAULT_BOX_COUNT = 5; ObjectCollidable::init(); - u16 boxCount = params.setting(6); - - if (boxCount == 0) { - boxCount = DEFAULT_BOX_COUNT; - } - + s16 boxCount = (params.setting(6) == 0) ? DEFAULT_BOX_COUNT : params.setting(6); m_boxes = std::span(new ObjectWoodboxWSub *[boxCount], boxCount); for (auto *&box : m_boxes) { @@ -32,9 +28,9 @@ ObjectWoodboxW::~ObjectWoodboxW() { /// @addr{0x8077E1A0} void ObjectWoodboxW::init() { ASSERT(m_mapObj); - u32 frames = m_mapObj->setting(4); + s32 frames = static_cast(m_mapObj->setting(4)); if (frames == 0) { - frames = m_mapObj->setting(5); + frames = m_cooldownDuration; } m_framesUntilSpawn = frames; @@ -47,8 +43,7 @@ void ObjectWoodboxW::calc() { return; } - ASSERT(m_mapObj); - m_framesUntilSpawn = m_mapObj->setting(5); + m_framesUntilSpawn = m_cooldownDuration; m_boxes[m_nextBoxIdx]->enableCollision(); m_nextBoxIdx = (m_nextBoxIdx + 1) % m_boxes.size(); } diff --git a/source/game/field/obj/ObjectWoodboxW.hh b/source/game/field/obj/ObjectWoodboxW.hh index 286b7e9f..5df4d778 100644 --- a/source/game/field/obj/ObjectWoodboxW.hh +++ b/source/game/field/obj/ObjectWoodboxW.hh @@ -26,6 +26,8 @@ private: std::span m_boxes; s32 m_framesUntilSpawn; u32 m_nextBoxIdx; + + const s32 m_cooldownDuration; }; } // namespace Field diff --git a/source/game/system/map/MapdataGeoObj.cc b/source/game/system/map/MapdataGeoObj.cc index 465a46c9..9f32f788 100644 --- a/source/game/system/map/MapdataGeoObj.cc +++ b/source/game/system/map/MapdataGeoObj.cc @@ -16,7 +16,7 @@ void MapdataGeoObj::read(EGG::Stream &stream) { m_pathId = stream.read_s16(); for (auto &setting : m_settings) { - setting = stream.read_u16(); + setting = stream.read_s16(); } m_presenceFlag = stream.read_u16(); diff --git a/source/game/system/map/MapdataGeoObj.hh b/source/game/system/map/MapdataGeoObj.hh index 103adcad..8539bb49 100644 --- a/source/game/system/map/MapdataGeoObj.hh +++ b/source/game/system/map/MapdataGeoObj.hh @@ -42,7 +42,7 @@ public: return m_pathId; } - [[nodiscard]] u16 setting(size_t idx) const { + [[nodiscard]] s16 setting(size_t idx) const { ASSERT(idx < m_settings.size()); return m_settings[idx]; } @@ -59,7 +59,7 @@ private: EGG::Vector3f m_rot; EGG::Vector3f m_scale; s16 m_pathId; - std::array m_settings; + std::array m_settings; u16 m_presenceFlag; };