diff --git a/include/Kawano/driver.h b/include/Kawano/driver.h index 14f3a791..809ac9cc 100644 --- a/include/Kawano/driver.h +++ b/include/Kawano/driver.h @@ -136,6 +136,8 @@ class DriverModel : public ExModel int IsChange(); int IsChangeBack(); int IsChangeFront(); + int IsSit(); + int IsStand(); public: u8 _8c[0xfc - 0x8c]; diff --git a/include/Sato/GeographyObj.h b/include/Sato/GeographyObj.h index d564d6ef..16717ba0 100644 --- a/include/Sato/GeographyObj.h +++ b/include/Sato/GeographyObj.h @@ -289,14 +289,14 @@ class ExGeographyObj : public GeographyObj { ~ExGeographyObj() {} // TODO: check return types - virtual bool Search_Bound(const JGeometry::TVec3f &) { return false; } - virtual bool Search_BoundRadius(const JGeometry::TVec3f &, f32) { return false; } - virtual void Search(const JGeometry::TVec3f &, const JGeometry::TVec3f &) {} - virtual void AddVel(const JGeometry::TVec3f &, const JGeometry::TVec3f &) {} - virtual void Search_Wall(const JGeometry::TVec3f &, f32) { } - virtual void draw(Mtx) {} - virtual f32 getMaxHeight() const { return 0.0f; } - virtual void lockDisplayList() {} + virtual bool Search_Bound(const JGeometry::TVec3f &) { return false; } // 80 + virtual bool Search_BoundRadius(const JGeometry::TVec3f &, f32) { return false; } // 84 + virtual void Search(const JGeometry::TVec3f &, const JGeometry::TVec3f &) {} // 88 + virtual void AddVel(const JGeometry::TVec3f &, const JGeometry::TVec3f &) {} // 8C + virtual void Search_Wall(const JGeometry::TVec3f &, f32) { } // 90 + virtual void draw(Mtx) {} // 94 + virtual f32 getMaxHeight() const { return 0.0f; } // 98 + virtual void lockDisplayList() {} // 9C template static T *ExNew(CrsData::SObject &object) { return new T(object); } diff --git a/include/Sato/JPEffectPerformer.h b/include/Sato/JPEffectPerformer.h index 089fe5b3..af0e7c01 100644 --- a/include/Sato/JPEffectPerformer.h +++ b/include/Sato/JPEffectPerformer.h @@ -16,6 +16,8 @@ class JPEffectPerformer Effect_Unknown6 = 0x6, // Something reflection related...? Effect_Unknown12 = 0x12, // Star react. Effect_Burn = 0x13, + Effect_Unknown1b = 0x1b, // something slide related + Effect_Unknown1A = 0x1A, Effect_Star = 0x1c }; @@ -102,4 +104,4 @@ class JPEffectPerformer // void JPStartFootSmokeEmitterCallBack::draw(JPABaseEmitter *); // void PermissionCounterObserver::reset(); // void PermissionCounterObserver::calc(); -#endif // JPEFFECTPERFORMER_H \ No newline at end of file +#endif // JPEFFECTPERFORMER_H diff --git a/include/Yamamoto/KartGame.h b/include/Yamamoto/KartGame.h index 2220031d..88c34f33 100644 --- a/include/Yamamoto/KartGame.h +++ b/include/Yamamoto/KartGame.h @@ -11,7 +11,7 @@ class KartGame { public: // In kartCtrlStrat.cpp - void Init(int); + bool Init(int kartNo); void GetGorundTireNum(); void WatchEffectAcceleration(); void WatchAcceleration(); @@ -22,7 +22,7 @@ class KartGame void DoDriftTurboSterr(); void SetDriftTurboSterr(); void CheckDriftTurbo(); - void DoWarmUpRoll(); + f32 DoWarmUpRoll(); void DoRollAnim(); void DoDriftClear(); void DoRoll(); @@ -30,9 +30,9 @@ class KartGame void DoLiftTurbo(); void DoTurbo(); void DoRollThrow(); - void DoRollOver(); + int DoRollOver(); void DoWanWan(); - void DoPushStart(); + bool DoPushStart(); void DoBalance(f32 *, f32); void MakeClear(); void MakeBoardDash(); @@ -54,7 +54,7 @@ class KartGame bool CheckBalloon(); void SetRank(); void RankWatchMan(); - void ItemWatchMan(ItemObj *); + void ItemWatchMan(ItemObj *incomingItem); void AfterItemWatchMan(); void DoFlagCtrl(); void KeepWatch(); @@ -89,13 +89,21 @@ class KartGame // void FrameWorkL(f32, f32, KartSus *); // void DoTurboPower(); // void CheckBalloonPlayer(); - KartBody *mBody; - u8 _4[0x12 - 004]; - u16 mCountDownDuration; - u8 _14[0x20 - 0x14]; + KartBody *mBody; // 00 + u32 _4; + u8 _8; // probably a bitmask + u8 _9; + u8 _A; + u8 mTimeToChange; + u8 _C[0x2]; + u16 _E; + u16 _10; + u16 mCountDownDuration; // 12 + ItemObj *mIncomingItem; // 14, the item that's about to collide with the kart + float _18[2]; JGeometry::TVec3f _20; JGeometry::TVec3f _2C; - JGeometry::TVec3f _34; + JGeometry::TVec3f _38; }; #endif KARTGAME_H diff --git a/include/Yamamoto/KartRescue.h b/include/Yamamoto/KartRescue.h index e4f2eab2..8cd9db1c 100644 --- a/include/Yamamoto/KartRescue.h +++ b/include/Yamamoto/KartRescue.h @@ -31,12 +31,14 @@ class KartRescue // Inline/Unused // void DoHang(); -// private: u8 _0[0xc]; // CrsGround mGround; // c u8 _6c[0x74 - 0x6c]; // padding up to offset 0x74 - u8 mFlags; // 74 - u8 _75[0x8c - 0x75]; // remaining padding + u8 mFlags; // 74 0x20: in rescue animation + u8 _75; + u8 mState; // 0: no rescue 2: got out of course 3: lakitu holds us 4: lakitu lets us down + u8 _77; // seems to be some kind of frame counter when getting rescued + u8 _78[0x8c - 0x78]; // remaining padding JGeometry::TVec3f _8c; // JGeometry::TVec3f _98; // JGeometry::TVec3f _a4; // diff --git a/include/Yamamoto/kartBody.h b/include/Yamamoto/kartBody.h index a32c0d6d..1d1e84c0 100644 --- a/include/Yamamoto/kartBody.h +++ b/include/Yamamoto/kartBody.h @@ -32,6 +32,33 @@ class KartBody { public: + // TODO: move in KartGame + enum GameStatus { + HasCoDriver = 1<<0, + GsUnknown3 = 1<<3, + }; + + enum CarStatus { + DriftLeft = 1<<0, + DriftRight = 1<<1, + DoesSlide = 1<<2, + CsUnknown3 = 1<<3, + CsUnknown5 = 1<<5, + InDriverChange = 1<<7, + CsUnknown8 = 1<<8, + CsUnknown9 = 1<<9, + CsUnknown10 = 1<<10, + CsUnknown11 = 1<<11, + CsUnknown12 = 1<<12, + CsUnknown15 = 1<<15, + CsUnknown18 = 1<<18, + CsUnknown20 = 1<<20, + CsUnknown22 = 1<<22, + CsUnknown25 = 1<<25, + CsUnknown26 = 1<<26, + CsUnknown27 = 1<<27, + }; + KartBody() {} void DegubBody(u32); @@ -102,7 +129,7 @@ class KartBody KartSus *mKartSus[4]; ExModel *mBodyModel; DriverModel *mDriverModels[2]; - ExModel *mExModels[2]; + DriverModel *mExModels[2]; KartShadowModel *mShadowModel; CrsGround mBodyGround; CrsArea mShadowArea; @@ -285,7 +312,7 @@ class KartBody f32 _564; f32 _568; u8 _56c[4]; // padding? - u64 mCarStatus; // 570, 574 + u64 mCarStatus; // 570, 574 | 0x400000: could be off track u32 mGameStatus; // 578 u32 _57c; u32 _580; @@ -311,7 +338,7 @@ class KartBody u8 mMynum; u8 _5b4; u8 _5b5; // also some timer - u8 _5b6; // dash timer? + u8 mSlideTimer; // dash timer? u8 mCameraNum; u8 _5b8[8]; u8 _5c0; diff --git a/include/Yamamoto/kartCtrl.h b/include/Yamamoto/kartCtrl.h index 04e63b06..936d6c77 100644 --- a/include/Yamamoto/kartCtrl.h +++ b/include/Yamamoto/kartCtrl.h @@ -97,7 +97,7 @@ class KartCtrl : public KartMat // WHAT THE HELL ARE YOU DOING double GetTireRadius(int); bool IsBurn(int); bool IsWallReact(int); - u32 HaveBalloon(int); + bool HaveBalloon(int); int GetDriftCnt(int); bool IsMiniGame(); bool IsMiniGameEnd(); diff --git a/include/Yamamoto/kartSus.h b/include/Yamamoto/kartSus.h index e20646b7..c99285f9 100644 --- a/include/Yamamoto/kartSus.h +++ b/include/Yamamoto/kartSus.h @@ -54,7 +54,7 @@ class KartSus f32 _10c; f32 _110; u8 _114[0x124 - 0x114]; - u32 _124; + u32 _124; // bitmask? 0: on ground? Mtx _128; Mtx _158; Mtx _188; diff --git a/src/Yamamoto/kartBody.cpp b/src/Yamamoto/kartBody.cpp index 606ee270..a2b23db5 100644 --- a/src/Yamamoto/kartBody.cpp +++ b/src/Yamamoto/kartBody.cpp @@ -1926,7 +1926,7 @@ void KartBody::Init(int index) { _5b0 = 0; _5b1 = 0; mDriver = 0; - _5b6 = 0; + mSlideTimer = 0; mMynum = 0; _5c5 = 0; _592 = 0; diff --git a/src/Yamamoto/kartCtrlStrat.cpp b/src/Yamamoto/kartCtrlStrat.cpp index 8cef9586..35cf2869 100644 --- a/src/Yamamoto/kartCtrlStrat.cpp +++ b/src/Yamamoto/kartCtrlStrat.cpp @@ -1,63 +1,752 @@ +#include "JSystem/JGeometry/Vec.h" +#include "Kaneshige/RaceMgr.h" +#include "Osako/kartPad.h" +#include "Sato/ItemObjMgr.h" +#include "Sato/JPEffectPerformer.h" #include "Yamamoto/KartGame.h" +#include "Yamamoto/kartBody.h" +#include "Yamamoto/kartCtrl.h" #include "JSystem/JAudio/JASFakeMatch2.h" +#include "dolphin/mtx.h" // comments inside functions are inline functions being called in that function -void KartGame::Init(int) {} +bool KartGame::Init(int kartNo) { + mBody = GetKartCtrl()->getKartBody(kartNo); + _8 = 0; + _9 = 0; + _38.zero(); + _4 = 0; + _18[0] = 0.f; + _18[1] = 0.f; + _E = 0; + _10 = 0; + mCountDownDuration = 0; -void KartGame::GetGorundTireNum() {} + _A = 0; + mTimeToChange = 0; + _C[0] = 0; -void KartGame::WatchEffectAcceleration() {} + bool isRight = RaceMgr::getCurrentManager()->getStartPoint(&_20, &_2C, kartNo); -void KartGame::WatchAcceleration() {} + _20.y += 300.f; -void KartGame::DoItmCancel() {} + return isRight; +} + +void KartGame::GetGorundTireNum() { + u8 num = mBody->mMynum; + + KartBody *body = mBody; + body->mTouchNum = 0; + + KartSus *sus[4]; + int idx = num; + sus[0] = GetKartCtrl()->getKartSus(idx * 4 + 0); + sus[1] = GetKartCtrl()->getKartSus(idx * 4 + 1); + sus[2] = GetKartCtrl()->getKartSus(idx * 4 + 2); + sus[3] = GetKartCtrl()->getKartSus(idx * 4 + 3); + + if (sus[0]->_124 & 1) + ++body->mTouchNum; + + if (sus[1]->_124 & 1) + ++body->mTouchNum; + + if (sus[2]->_124 & 1) + ++body->mTouchNum; + + if (sus[3]->_124 & 1) + ++body->mTouchNum; + + GetKartCtrl()->getKartSound(num)->DoSlipSound(num); + + // TODO: what kind of vectors are this? + JGeometry::TVec3f _vec0; + _vec0.set(body->mPlayerPosMtx[0][3], body->mPlayerPosMtx[1][3], body->mPlayerPosMtx[2][3]); + + body->mShadowArea.searchShadow(_vec0); + + if (body->mTouchNum != 0 && body->_58c == 7) { + // TODO: is getObject return type wrong or is the cast here ok? + // first one probably + ExGeographyObj *exGeo = static_cast(body->mBodyGround.getObject()); -void KartGame::DoStopItm() {} + JGeometry::TVec3f _vec2; + _vec2.set(0.f, -3.5f, 0.f); + + exGeo->AddVel(_vec0, _vec2); + } +} + +void KartGame::WatchEffectAcceleration() { + KartBody *body = mBody; + int num = body->mMynum; + + const KartGamePad *gamePad = GetKartCtrl()->GetDriveCont(num); + const KartPad *pad = GetKartCtrl()->getKartPad(num); + + if (gamePad->testButton(pad->mAccelBtn)) { + body->mKartRPM = GetKartCtrl()->fcnvge(body->mKartRPM, 1.f, 0.050000001f, 0.050000001f); + } else { + body->mKartRPM = GetKartCtrl()->fcnvge(body->mKartRPM, 0.f, 0.050000001f, 0.050000001f); + } +} + +void KartGame::WatchAcceleration() { + KartBody *body = mBody; + int num = body->mMynum; + + const KartGamePad *gamePad = GetKartCtrl()->GetDriveCont(num); + if ((body->mCarStatus & 0x400000) && (body->getRescue()->mState >= 3)) { + KartPad *pad = GetKartCtrl()->getKartPad(num); + if (gamePad->testButton(pad->mAccelBtn)) { + body->_3c8 = GetKartCtrl()->fcnvge(body->_3c8, body->_3d0, 1.f, 1.f); + _8 |= 2; + } else { + GetKartCtrl()->ChaseFnumber(&body->_3c8, 0.f, 1.f); + _8 &= ~2; + } + } +} + +void KartGame::DoItmCancel() { + KartBody *body = mBody; + + body->mCarStatus |= 0x80000000; + GetItemObjMgr()->abortItemShuffle(body->mMynum); +} -void KartGame::DoChange() {} +void KartGame::DoStopItm() { + KartBody *body = mBody; + u8 num = body->mMynum; -void KartGame::DoSlide() {} + body->mCarStatus |= 0x80000000; + GetItemObjMgr()->abortItemShuffle(body->mMynum); -void KartGame::DoDriftTurboSterr() {} + ItemObjMgr *itemMgr = GetItemObjMgr(); + ItemObj *item = itemMgr->getKartEquipItem(num, 0); + itemMgr->deleteHeartItem(num); -void KartGame::SetDriftTurboSterr() {} + if (item != nullptr) { + item->IsSuccessionItem() ? item->setChildStateForceDisappear() + : item->setStateForceDisappear(); + } -void KartGame::CheckDriftTurbo() { - // void JUTGamePad::getMainStickX() const {} + item = itemMgr->getKartEquipItem(num, 1); + if (item != nullptr) { + item->IsSuccessionItem() ? item->setChildStateForceDisappear() + : item->setStateForceDisappear(); + } } -void KartGame::DoWarmUpRoll() {} +void KartGame::DoChange() { + KartBody *body = mBody; + int num = body->mMynum; + + const KartGamePad *gpDriver = GetKartCtrl()->GetDriveCont(num); + const KartGamePad *gpCoDriv = GetKartCtrl()->GetCoDriveCont(num); + + bool change = false; + const bool possible = GetKartCtrl()->MakeChangePossible(num); + + if (body->getChecker()->CheckCheange(num)) { + mTimeToChange = 0; + return; + } + + if (mTimeToChange) + mTimeToChange--; + + // single player kart + if ((body->mGameStatus & KartBody::HasCoDriver) == false) { + if (gpDriver->testTrigger(GetKartCtrl()->getKartPad(num)->mTrigZ)) + mTimeToChange = 20; + + if (body->mCarStatus & KartBody::InDriverChange) { + if (!(body->mExModels[0])->IsChange() && !(body->mExModels[1])->IsChange()) + body->mCarStatus &= ~KartBody::InDriverChange; + + } else if ((gpDriver->testTrigger(GetKartCtrl()->getKartPad(num)->mTrigZ) || possible || + mTimeToChange != 0)) { + change = true; + mTimeToChange = 0; + } + // with co-driver, but already in change + } else if (body->mCarStatus & KartBody::InDriverChange) { + if (gpDriver->testButton(GetKartCtrl()->getKartPad(num)->mTrigZ) && + gpCoDriv->testButton(GetKartCtrl()->getKartPad(num)->mTrigZ)) { + mTimeToChange = 20; + } + + if (!(body->mExModels[0])->IsChange() && !(body->mExModels[1])->IsChange()) { + body->mCarStatus &= ~KartBody::InDriverChange; + } + // with co-driver and ready to change + } else if ((gpDriver->testButton(GetKartCtrl()->getKartPad(num)->mTrigZ) && + gpCoDriv->testButton(GetKartCtrl()->getKartPad(num)->mTrigZ)) || + mTimeToChange != 0) { + change = true; + mTimeToChange = 0; + } + + if (!change) + return; + + body->mCarStatus &= ~(1ull << 38); + body->mCarStatus |= KartBody::InDriverChange; + + GetKartCtrl()->getKartAnime(num)->mFlags |= 1; + GetKartCtrl()->getKartSound(num)->DoChangeVoice(); + GetKartCtrl()->getKartSound(num)->DoChangeStarSound(); +} + +void KartGame::DoSlide() { + const int num = mBody->mMynum; + KartBody *body = mBody; + + if (body->getChecker()->CheckPartsClearKey(num) || + !(body->mGameStatus & KartBody::HasCoDriver)) { + return; + } + + if (body->mSlideTimer != 0) { + body->mSlideTimer--; + } + + if (body->mSlideTimer == 0) { + body->mCarStatus &= ~KartBody::DoesSlide; + } + + if ((body->mCarStatus & KartBody::DoesSlide)) { + if (body->mSlideTimer >= 29) { + body->_2cc.x += body->_2f0.x * body->_528; + body->_2cc.y += body->_2f0.y * body->_528; + body->_2cc.z += body->_2f0.z * body->_528; + } + + return; + } + + KartGamePad *gpCoDriv = GetKartCtrl()->GetCoDriveCont(num); + if (body->getTouchNum() == 0 || (GetKartCtrl()->GetCarSpeed(num) <= 50.f)) { + return; + } + + if (!gpCoDriv->testTrigger(JUTGamePad::L) && !gpCoDriv->testTrigger(JUTGamePad::R)) { + return; + } + + body->mSlideTimer = 35; + + if (RaceMgr::getCurrentManager()->isMirror()) { + if (gpCoDriv->testTrigger(JUTGamePad::L)) { + body->_528 = -50.f * body->_3a4; + GetKartCtrl()->getKartAnime(num)->mFlags |= 0x10; + JPEffectPerformer::setEffect(JPEffectPerformer::Effect_Unknown1b, num, body->mPos, 1); + } else if (gpCoDriv->testTrigger(JUTGamePad::R)) { + body->_528 = 50.f * body->_3a4; + GetKartCtrl()->getKartAnime(num)->mFlags |= 0x20; + JPEffectPerformer::setEffect(JPEffectPerformer::Effect_Unknown1b, num, body->mPos, 0); + } + } else { + if (gpCoDriv->testTrigger(JUTGamePad::R)) { + body->_528 = -50.f * body->_3a4; + GetKartCtrl()->getKartAnime(num)->mFlags |= 0x10; + JPEffectPerformer::setEffect(JPEffectPerformer::Effect_Unknown1b, num, body->mPos, 1); + } else if (gpCoDriv->testTrigger(JUTGamePad::L)) { + body->_528 = 50.f * body->_3a4; + GetKartCtrl()->getKartAnime(num)->mFlags |= 0x20; + JPEffectPerformer::setEffect(JPEffectPerformer::Effect_Unknown1b, num, body->mPos, 0); + } + } + + body->_2cc.x += body->_2f0.x * body->_528; + body->_2cc.y += body->_2f0.y * body->_528; + body->_2cc.z += body->_2f0.z * body->_528; + + body->mCarStatus |= KartBody::DoesSlide; + GetKartCtrl()->getKartSound(num)->DoStrikeSound(); + GetKartCtrl()->getKartSound(num)->DoTandemVoice(2); +} + +void KartGame::DoDriftTurboSterr() { + KartBody *body = mBody; + + if (body->mDriftSterr != 0 && body->mDriftSterr < 0x1E) + body->mDriftSterr++; +} + +void KartGame::SetDriftTurboSterr() { + KartBody *body = mBody; + const int num = mBody->mMynum; + + const int threshold = (body->mGameStatus & KartBody::HasCoDriver) ? 2 : 6; + if ((body->mDriftSterr) < threshold) + return; + + body->mMTState++; + + if (body->mMTState == 1) + GetKartCtrl()->getKartSound(num)->DoKartsetSeSound(0x100C9); + else if (body->mMTState == 2) + GetKartCtrl()->getKartSound(num)->DoKartsetSeSound(0x100CA); + + if (body->mMTState >= 2) + body->mMTState = 2; + + body->mDriftSterr = 0; +} + +void KartGame::CheckDriftTurbo(void) { + KartBody *body = mBody; + int num = body->mMynum; + + if (GetKartCtrl()->GetCarSpeed(num) <= 50.f) { + body->mCarStatus &= ~(1ull << 41); + body->mMTBoost = 0; + body->mDriftSterr = 0; + body->mMTState = 0; + return; + } + + if (body->mGameStatus & KartBody::GsUnknown3) + return; + + bool didDriftSterr = false; + KartGamePad *gpCoDriv = GetKartCtrl()->GetCoDriveCont(num); + + if (body->mCarStatus & KartBody::DriftLeft) { + if (body->mGameStatus & KartBody::HasCoDriver) { + if (gpCoDriv->getMainStickX() < 0.5f) { + didDriftSterr = true; + DoDriftTurboSterr(); + } + } else if (body->mFrame >= -0.5f) { + didDriftSterr = true; + DoDriftTurboSterr(); + } + + if (!didDriftSterr) { + SetDriftTurboSterr(); + body->mDriftSterr = 1; + } + } else { + if ((body->mCarStatus & KartBody::DriftRight) != 0) { + if (body->mGameStatus & KartBody::HasCoDriver) { + if (gpCoDriv->getMainStickX() > -0.30000001f) { + didDriftSterr = true; + DoDriftTurboSterr(); + } + } else { + if (body->mFrame <= 0.5f) { + didDriftSterr = true; + DoDriftTurboSterr(); + } + } + + if (!didDriftSterr) { + SetDriftTurboSterr(); + body->mDriftSterr = 1; + } + } else { + body->mMTState = 0; + body->mDriftSterr = 0; + } + } + + body->mCarStatus &= ~(1ull << 41); + body->mMTBoost = 0; +} + +f32 KartGame::DoWarmUpRoll() { + int kartNo = mBody->mMynum; + KartBody *body = mBody; + + KartGamePad *gpDriver = GetKartCtrl()->GetDriveCont(kartNo); + if (body->mCarStatus & KartBody::DoesSlide) { + body->mCarStatus &= + ~(KartBody::DriftLeft | KartBody::DriftRight | 1ull << 41 | 1ull << 47 | 1ull << 48); + body->_4d8 = 0.f; + body->_4d4 = 0.f; + body->_4c4 = 0.f; + body->_394 = 0.f; + body->mLiftframe = 0.f; + body->_39c = 0.f; + body->_398 = 0.f; + body->mMTBoost = 0; + body->mDriftSterr = 0; + body->mMTState = 0; + body->mSterrNorm = 0.f; + } + + if (body->mCarStatus & (KartBody::DriftLeft | KartBody::DriftRight) && + gpDriver->testTrigger(GetKartCtrl()->getKartPad(kartNo)->mTrigL | + GetKartCtrl()->getKartPad(kartNo)->mTrigR)) { + DoDriftClear(); + return 0.f; + } + + float ret; + if (gpDriver->testButton(GetKartCtrl()->getKartPad(kartNo)->mTrigL | + GetKartCtrl()->getKartPad(kartNo)->mTrigR)) { + if (body->mCarStatus & KartBody::DriftLeft) { + body->mCarStatus |= (KartBody::DriftLeft | 1ull << 47); + body->mCarStatus &= ~(KartBody::DriftRight | 1ull << 48); + ret = 150.f; + CheckDriftTurbo(); + } else if (body->mCarStatus & KartBody::DriftRight) { + body->mCarStatus |= (KartBody::DriftRight | 1ull << 48); + body->mCarStatus &= ~(KartBody::DriftLeft | 1ull << 47); + ret = -150.f; + CheckDriftTurbo(); + } else { + ret = 0.f; + if (body->mFrame < -0.8f) { + ret = 150.f; + body->_4d4 = 0.f; + body->mCarStatus |= (KartBody::DriftLeft | 1ull << 47); + body->mCarStatus &= ~(KartBody::DriftRight | 1ull << 48); + body->mSterrNorm = 0.043611001f; + if (body->mFrame < -0.90000004f) { + body->mSterrNorm = 0.1133888f; + } + } else if (body->mFrame > 0.8f) { + ret = -150.f; + body->_4d4 = 0.f; + body->mCarStatus |= (KartBody::DriftRight | 1ull << 48); + body->mCarStatus &= ~(KartBody::DriftLeft | 1ull << 47); + body->mSterrNorm = 0.043611001f; + if (body->mFrame < 0.90000004f) { + body->mSterrNorm = 0.1133888f; + } + } else { + body->mMTBoost = 0; + body->mDriftSterr = 0; + body->mMTState = 0; + body->mCarStatus &= ~(1ull << 41); + body->mCarStatus &= + ~(KartBody::DriftLeft | KartBody::DriftRight | 1ull << 47 | 1ull << 48); + } + } + + KartAnime *anime = GetKartCtrl()->getKartAnime(kartNo); + if (!anime->IsProhibition(kartNo) && !body->mDriverModels[0]->IsSit() && + !body->getChecker()->CheckOnlyTandemPartsClearKey(kartNo) && + !(body->mCarStatus & (KartBody::DriftLeft | KartBody::DriftRight))) { + GetKartCtrl()->getKartAnime(kartNo)->mFlags |= 0x200u; + } + } else { + if (!(body->mCarStatus & KartBody::CsUnknown15) && body->mDriverModels[0]->IsSit() && + !body->mDriverModels[0]->IsStand() && + !body->getChecker()->CheckOnlyTandemPartsClearKey(kartNo)) { + GetKartCtrl()->getKartAnime(kartNo)->mFlags |= 0x400u; + } + + if (body->mMTState >= 2u) { + body->mCarStatus |= 1ull << 41; + body->mMTBoost = body->mMTBoostMax; + JPEffectPerformer::setEffect(JPEffectPerformer::Effect_Unknown1A, kartNo, body->mPos, + 0); + GetKartCtrl()->getKartSound(body->mMynum)->DoKartMiniTuroboSound(); + GetKartCtrl()->getKartSound(body->mMynum)->DoTandemVoice(0); + body->getStrat()->DoMotor(MotorManager::MotorType_6); + } + + body->mDriftSterr = 0; + body->mMTState = 0; + body->mCarStatus &= + ~(KartBody::DriftLeft | KartBody::DriftRight | 1ull << 47 | 1ull << 48); + ret = 0.f; + } + + return ret; +} + +void KartGame::DoRollAnim() { + KartBody *body = mBody; + int kartNo = body->mMynum; + + KartGamePad *gpDriver = GetKartCtrl()->GetDriveCont(kartNo); + if (gpDriver->getMainStickX() >= 0.2f) { + body->_394 = -1.0f; + } else if (gpDriver->getMainStickX() <= -0.2f) { + body->_394 = 1.0f; + } else { + body->_394 = .0f; + } + + body->mLiftframe = + GetKartCtrl()->fcnvge(body->mLiftframe, body->_394, 0.050000001f, 0.050000001f); + + if (GetKartCtrl()->getKartAnime(kartNo)->IsDrift(kartNo) == false && + GetKartCtrl()->getKartAnime(kartNo)->IsDriftStart(kartNo) == false) { + + if (gpDriver->getMainStickX() >= 0.2f) { + body->_39c = -1.0f; + } else if (gpDriver->getMainStickX() <= -0.2f) { + body->_39c = 1.0f; + } else { + body->_39c = 0.0f; + } + + body->_398 = GetKartCtrl()->fcnvge(body->_398, body->_39c, 0.050000001f, 0.050000001f); + } + + if (body->mCarStatus & KartBody::DriftLeft) { + body->_394 = -1.0f; + body->mLiftframe = -1.0f; + if (GetKartCtrl()->getKartAnime(kartNo)->IsDriftLeft(kartNo)) { + body->_39c = 1.0f; + body->_398 = 1.0f; + } else { + body->_39c = -1.0f; + body->_398 = -1.0f; + } + + return; + } + + if (body->mCarStatus & KartBody::DriftRight) { + body->_394 = 1.0f; + body->mLiftframe = 1.0f; + if (GetKartCtrl()->getKartAnime(kartNo)->IsDriftRight(kartNo)) { + body->_39c = -1.0f; + body->_398 = -1.0f; + } else { + body->_39c = 1.0f; + body->_398 = 1.0f; + } + } +} + +void KartGame::DoDriftClear() { + KartBody *body = mBody; + + body->mMTBoost = 0; + body->mDriftSterr = 0; + body->mMTState = 0; + body->mCarStatus &= ~(1ull << 41); + body->mCarStatus &= + ~(KartBody::DriftLeft | KartBody::DriftRight | (1ull << 47) | (1ull << 48)); +} -void KartGame::DoRollAnim() {} +void KartGame::DoRoll() { + KartBody *body = mBody; -void KartGame::DoDriftClear() {} + MakeJump(); -void KartGame::DoRoll() {} + f32 warmupRollRet = DoWarmUpRoll(); + + if (GetKartCtrl()->GetCarSpeed(body->mMynum) <= 30.f || + GetKartCtrl()->GetCarSpeed(body->mMynum) <= 40.f && body->_3c8 == 0.f) { + DoDriftClear(); + } + + if (GetKartCtrl()->GetCarSpeed(body->mMynum) < 40.f && body->_510 > 2.44222f) { + DoDriftClear(); + } + + if (GetKartCtrl()->GetCarSpeed(body->mMynum) <= 80.f && body->_3cc != 0.f) { + DoDriftClear(); + } + + if (body->mCarStatus & KartBody::CsUnknown3) { + DoDriftClear(); + } + + if (body->_458 < 2.f) { + body->_4c4 = GetKartCtrl()->fcnvge(body->_4c4, warmupRollRet * 0.0088235298f, 0.1f, 0.1f); + } else { + if (body->_458 < 18.f) { + body->_4c4 = + GetKartCtrl()->fcnvge(body->_4c4, warmupRollRet * 0.0023529413f, 0.1f, 0.1f); + } else { + int touchNum = body->getTouchNum(); + f32 _unk2 = (touchNum == 0) ? 0.023529412f * warmupRollRet + : (body->_4f8 / 170.f) * warmupRollRet; + + GetKartCtrl()->ChaseFnumber(&body->_4c4, _unk2, body->_3b4); + } + } + + if (!(body->mCarStatus & (KartBody::DriftLeft | KartBody::DriftRight))) { + body->_4c4 = 0.f; + } + + DoRollAnim(); +} void KartGame::DoTestPitch() { - // void JUTGamePad::getMainStickY() const {} + KartBody *body = mBody; + + KartGamePad *pad = GetKartCtrl()->GetDriveCont(body->mMynum); + if (body->getTouchNum() != 0) { + body->_4c0 = 0.f; + if (body->mCarStatus & (KartBody::CsUnknown8 | KartBody::CsUnknown9)) { + body->getStrat()->PitchClear(); + } + return; + } + + f32 mainY = pad->getMainStickY(); + if (mainY > 0.f) { + body->mCarStatus |= KartBody::CsUnknown9; + body->mCarStatus &= ~KartBody::CsUnknown8; + } else if (mainY < 0.f) { + body->mCarStatus |= KartBody::CsUnknown8; + body->mCarStatus &= ~KartBody::CsUnknown9; + } + + f32 x; + f32 y = 0.0; + if (mainY < 0.5 && mainY > -0.5f) { + x = 0.0; + } else { + y = 0.2f; + x = 1.5f * mainY; + } + + GetKartCtrl()->ChaseFnumber(&body->_4c0, x, y); + if (body->_4c0 == 0.f) { + body->getStrat()->PitchClear(); + } } -void KartGame::DoLiftTurbo() {} +void KartGame::DoLiftTurbo() { + KartBody *kartBody = mBody; + f32 fVar3; + JGeometry::TVec3f vec3; + JGeometry::TVec3f vec2; + JGeometry::TVec3f vec1; + JGeometry::TVec3f vec0; + + if (!(kartBody->mCarStatus & (KartBody::DriftLeft | KartBody::DriftRight))) { + kartBody->_518 = 0.0f; + } + + if (!(kartBody->mCarStatus & (KartBody::DriftLeft | KartBody::DriftRight)) || + kartBody->getTouchNum() <= 1 || + kartBody->mCarStatus & (KartBody::CsUnknown5 | KartBody::CsUnknown10 | KartBody::CsUnknown26 | KartBody::CsUnknown27) || + kartBody->mBodyGround.getAttribute() == 6 + ) { + kartBody->_564 = 0.0f; + kartBody->_518 = 0.0f; + return; + } + + if (GetKartCtrl()->GetCarSpeed(kartBody->mMynum) <= 30.0f) { + return; + } + + if (GetKartCtrl()->GetCarSpeed(kartBody->mMynum) >= 40.0f && kartBody->_3c8 != 0.0f) { + GetKartCtrl()->DevMatrixByVector(&vec2, &kartBody->mVel, kartBody->_110); + vec2.x *= 1.075f; + vec2.z *= 1.015f; + + if (vec2.z < 0.0f) { + vec2.z *= -1.0f; + } + + PSMTXMultVecSR(kartBody->_110, &vec2, &kartBody->mVel); + } + + kartBody->_518 = kartBody->_514; + + f32 fVar2 = kartBody->_4dc * kartBody->_3c8 * kartBody->_518; + + kartBody->_564 = 0.38f; + + f32 fVar4 = kartBody->_564; + vec3.set(kartBody->_344.x,kartBody->_344.y, kartBody->_344.z); + + fVar3 = fVar2 * fVar4; + fVar4 = 1.0f - fVar4; + vec2.set(kartBody->_3a4 * fVar3, 0.0f, kartBody->_3a4 * (fVar2 * fVar4)); + + if ((kartBody->mCarStatus & 2) != 0) { + vec2.x *= -1.0f; + } + + PSMTXMultVec(kartBody->_110, &vec3, &vec1); + PSMTXMultVecSR(kartBody->_110, &vec2, &vec0); + kartBody->DoForce(&vec1, &vec0); + + vec3.set(kartBody->_344.x, kartBody->_344.y,-(kartBody->_344).z * 0.5f); + vec2.set(kartBody->_3a4 * fVar3, 0.0f, kartBody->_3a4 * (kartBody->_4dc * fVar4)); + + if ((kartBody->mCarStatus & 2) != 0) { + vec2.x *= -1.0f; + } + + PSMTXMultVec(kartBody->_110, &vec3, &vec1); + PSMTXMultVecSR(kartBody->_110, &vec2, &vec0); + kartBody->DoForce(&vec1, &vec0); +} void KartGame::DoTurbo() {} void KartGame::DoRollThrow() {} -void KartGame::DoRollOver() {} +// literally a no-op always returning 0 +int KartGame::DoRollOver() { + KartBody *body = mBody; + + if (body->getTouchNum() == 0 || + body->mCarStatus & (KartBody::CsUnknown12 | KartBody::CsUnknown18) || + body->mGameStatus & (KartBody::GsUnknown3)) { + return 0; + } + + return 0; +} void KartGame::DoWanWan() { // void ItemWanWanObj::getDifVel() const {} // void ItemWanWanObj::getPullVec(JGeometry::TVec3 *) {} } -void KartGame::DoPushStart() {} +bool KartGame::DoPushStart() { + const int timerEnd = 30; + KartBody *body = mBody; + + body->_594++; + body->_3c8 = body->_3d0; + if (body->_594 == timerEnd) { + body->mCarStatus &= ~(KartBody::CsUnknown25); + return true; + } + + return false; +} + +void KartGame::DoBalance(float *a2, float a3) { + KartBody *kartBody = mBody; -void KartGame::DoBalance(float *, float) {} + if ((mBody->mCarStatus & (KartBody::CsUnknown5 | KartBody::CsUnknown10 + | KartBody::CsUnknown26 | KartBody::CsUnknown27))) { + return; + } -void KartGame::MakeClear() {} + f32 v0 = kartBody->_468; + if (v0 > -0.40122193f && v0 < 0.40122193f) { + return; + } + + *a2 *= a3; +} + +void KartGame::MakeClear() { + KartBody *body = mBody; + + body->_3c8 = 0.f; + body->getStrat()->LiftClear(); + body->getStrat()->PitchClear(); + body->getStrat()->AllGravyClear(); + body->getStrat()->DashClear(); + body->getStrat()->OtherClear(); +} void KartGame::MakeBoardDash() {} @@ -93,17 +782,91 @@ void KartGame::DoBodyAction() {} void KartGame::DoElementForce() {} -bool KartGame::CheckBalloon() {} +bool KartGame::CheckBalloon() { + KartBody *kartBody = mBody; + int kartNo = kartBody->mMynum; -void KartGame::SetRank() {} + if (RaceMgr::getCurrentManager()->getRaceMode() != BALLOON_BATTLE) { + return false; + } + + if (GetKartCtrl()->HaveBalloon(kartNo) && + !(kartBody->mCarStatus & KartBody::CsUnknown20) && + !(kartBody->mCarStatus & KartBody::CsUnknown22) && + !(kartBody->getThunder()->mFlags & 0x01) + ) { + return true; + } + + return false; +} + +void KartGame::SetRank() { + KartBody *kartBody = mBody; + + kartBody->mMyRank = RCMGetKartChecker(kartBody->mMynum)->getRank(); + kartBody->_59c = 0; +} void KartGame::RankWatchMan() {} -void KartGame::ItemWatchMan(ItemObj *) {} +void KartGame::ItemWatchMan(ItemObj *incomingItem) { + if (!incomingItem) { + return; + } + + int kartNo = incomingItem->getOwnerNum(); + KartBody *kartBody = GetKartCtrl()->getKartBody(kartNo); + + RCMGetKartChecker(kartNo); + if (kartBody->getGame()->_E) { + return; + } + + if (kartBody->getChecker()->CheckOnlyTandemPartsClearKey(kartNo)) { + return; + } + + if (GetKartCtrl()->CheckTandemItmGet(kartNo)) { + return; + } + + kartBody->getGame()->_E = (0x08 | 0x10 | 0x20 | 0x40); + kartBody->getGame()->mIncomingItem = incomingItem; +} + +void KartGame::AfterItemWatchMan() { + // they probably just copy pasted the typical body myNum intro here + // in the original code, because kartBody gets r31 assigned + KartBody *kartBody; + + GetKartCtrl()->getKartSound(mBody->mMynum)->DoItemAlarm(); + if (_E == (0x01 | 0x02 | 0x04 | 0x10 | 0x20 | 0x40)) { + int kartNo = mIncomingItem->getOwnerNum(); + kartBody = GetKartCtrl()->getKartBody(kartNo); -void KartGame::AfterItemWatchMan() {} + if (mIncomingItem->getState() != ItemObj::StateDivested + && !kartBody->getChecker()->CheckOnlyTandemPartsClearKey(kartNo) + && !GetKartCtrl()->CheckTandemItmGet(kartNo)) { -void KartGame::DoFlagCtrl() {} + GetKartCtrl()->getKartSound(kartNo)->DoItmHitVoice(); + GetKartCtrl()->getKartAnime(kartNo)->mFlags |= (1LL<<34); + } + + _E = 0; + } + + if (_E == (0x02 | 0x04 | 0x10 | 0x20 | 0x40)) { + _E = 0; + } +} + +void KartGame::DoFlagCtrl() { + KartBody *kartBody = mBody; + + kartBody->_590 &= ~(0x04 | 0x08 | 0x10 | 0x40); + kartBody->getDamage()->mFlags &= ~(0x02); +} void KartGame::KeepWatch() {} @@ -112,7 +875,15 @@ void KartGame::DoActionMgr() { // void ItemObjMgr::getKartHitList(int) {} } -void KartGame::DoActionCtrl() {} +void KartGame::DoActionCtrl() { + // peak mwcc doing an extra compare when checking explicit against true + if (mBody->getChecker()->CheckCrash() == true) { + return; + } + + DoSlide(); + DoWanWan(); +} void KartGame::DoStatus() { // void KartCtrl::DoAnime(int) {}