diff --git a/configure.py b/configure.py index 3afc183d..24be3e6e 100755 --- a/configure.py +++ b/configure.py @@ -1356,7 +1356,7 @@ def MatchingFor(*versions): Object(NonMatching, "Shiraiwa/JugemGoal.cpp"), Object(NonMatching, "Shiraiwa/JugemFlag.cpp"), Object(NonMatching, "Shiraiwa/MapObjWanwan.cpp"), - Object(NonMatching, "Shiraiwa/MapObjWanwanChain.cpp"), + Object(Matching, "Shiraiwa/MapObjWanwanChain.cpp"), Object(Matching, "Shiraiwa/AnmPlayer.cpp"), Object(NonMatching, "Shiraiwa/MapObjSkyShip.cpp"), Object(NonMatching, "Shiraiwa/MapObjDonkyRockGen.cpp"), diff --git a/include/JSystem/JAudio/JAUAudience.h b/include/JSystem/JAudio/JAUAudience.h index 3212e605..a0e0d80e 100644 --- a/include/JSystem/JAudio/JAUAudience.h +++ b/include/JSystem/JAudio/JAUAudience.h @@ -152,7 +152,7 @@ class JAUAudience_withSetting_doppler : public JAUAudience_withSetting { class JAUAudienceState { public: JAUAudienceState() {} - //~JAUDopplerAudienceState() {} + //~JAUAudienceState() {} void init() { Mtx m; @@ -163,7 +163,7 @@ class JAUAudienceState { JGeometry::TPos3f m; mMtx.set(in); m.setPositionFromLookAt(mMtx); - m.getTransInline(_3c); + m.getTrans(_3c); _48.set(_3c); _30.zero(); @@ -190,7 +190,7 @@ class JAUDopplerAudienceState { JGeometry::TPos3f m; mMtx.set(in); m.setPositionFromLookAt(mMtx); - m.getTransInline(_3c); + m.getTrans(_3c); _48.set(_3c); _30.zero(); } diff --git a/include/JSystem/JGeometry/Matrix.h b/include/JSystem/JGeometry/Matrix.h index 42b0f6a6..6f15d80a 100644 --- a/include/JSystem/JGeometry/Matrix.h +++ b/include/JSystem/JGeometry/Matrix.h @@ -13,7 +13,9 @@ namespace JGeometry { { public: SMatrix34C() {} - void set(const SMatrix34C &rSrc); + void set(const SMatrix34C &rSrc) { + JMath::gekko_ps_copy12(this, rSrc); + } void set(T rxx, T ryx, T rzx, T tx, T rxy, T ryy, T rzy, T ty, T rxz, T ryz, T rzz, T tz); void scale(T); @@ -23,6 +25,8 @@ namespace JGeometry { JMath::gekko_ps_copy12(this, pSrc); } + f32 at(u32 i, u32 j) const { return mMtx[i][j]; } + T &ref(u32 i, u32 j) { return mMtx[i][j]; } inline Mtx *toMtx() @@ -82,26 +86,16 @@ namespace JGeometry { TRotation3() {} void identity33(); - // TODO: seems fakematch to me but that's a problem for later i guess inline void getXDir(TVec3f &rDest) const { - f32 z = this->mMtx[2][0]; - f32 y = this->mMtx[1][0]; - f32 x = this->mMtx[0][0]; - rDest.set(x, y, z); + rDest.set(this->at(0, 0), this->at(1, 0), this->at(2, 0)); } inline void getYDir(TVec3f &rDest) const { - f32 z = this->mMtx[2][1]; - f32 y = this->mMtx[1][1]; - f32 x = this->mMtx[0][1]; - rDest.set(x, y, z); + rDest.set(this->at(0,1), this->at(1, 1), this->at(2, 1)); } inline void getZDir(TVec3f &rDest) const { - f32 z = this->mMtx[2][2]; - f32 y = this->mMtx[1][2]; - f32 x = this->mMtx[0][2]; - rDest.set(x, y, z); + rDest.set(this->at(0, 2), this->at(1, 2), this->at(2, 2)); } void getXYZDir(TVec3f &rDestX, TVec3f &rDestY, TVec3f &rDestZ) const; @@ -209,9 +203,12 @@ namespace JGeometry { { public: TPosition3() {} + + void getTrans(TVec3f &rDest) const { - rDest.set(this->mMtx[0][3], this->mMtx[1][3], this->mMtx[2][3]); + rDest.set(this->at(0, 3), this->at(1, 3), this->at(2, 3)); } + void setTrans(const TVec3f &rSrc); void setTrans(f32 x, f32 y, f32 z); void zeroTrans() @@ -245,14 +242,6 @@ namespace JGeometry { this->ref(2, 3) = (rLookAt[0][3] * this->mMtx[2][0]) - (rLookAt[1][3] * this->mMtx[2][1]) + rLookAt[0][3] * this->mMtx[2][2]; } void setQT(const TQuat4f &rSrcQuat, const TVec3f &rSrcTrans); - - inline void getTransInline(TVec3f &rDest) const - { - f32 z = this->mMtx[2][3]; - f32 y = this->mMtx[1][3]; - f32 x = this->mMtx[0][3]; - rDest.set(x, y, z); - } }; typedef TMatrix34 TMtx34f; diff --git a/include/JSystem/JGeometry/Vec.h b/include/JSystem/JGeometry/Vec.h index a5ff0517..d19370f3 100644 --- a/include/JSystem/JGeometry/Vec.h +++ b/include/JSystem/JGeometry/Vec.h @@ -261,13 +261,20 @@ namespace JGeometry { return *this; } - /*TVec3 operator+(const TVec3 &operand) + TVec3 operator-(const TVec3 &operand) + { + TVec3 tmp(*this); + tmp -= operand; + return tmp; + } + + TVec3 operator+(const TVec3 &operand) { TVec3 tmp(*this); tmp += operand; return tmp; } -*/ + TVec3 operator*(f32 scalar) const { TVec3 scaled(*this); @@ -348,7 +355,18 @@ namespace JGeometry { return 0.0f; f32 invsqrt = TUtilf::inv_sqrt(this_squared); - scale(invsqrt); + this->scale(invsqrt); + return invsqrt * this_squared; + } + + f32 normalize(f32 scalar) // fabricated + { + f32 this_squared = squared(); + if (this_squared <= TUtilf::epsilon()) + return 0.0f; + + f32 invsqrt = TUtilf::inv_sqrt(this_squared); + this->scale(invsqrt * scalar); return invsqrt * this_squared; } @@ -356,12 +374,12 @@ namespace JGeometry { { f32 sq = other.squared(); if (sq <= TUtilf::epsilon()) { - zero(); + this->zero(); return 0.0f; } f32 invsqrt = TUtilf::inv_sqrt(sq); - scale(invsqrt, other); + this->scale(invsqrt, other); return invsqrt * sq; } }; diff --git a/include/Kaneshige/Course/CrsGround.h b/include/Kaneshige/Course/CrsGround.h index c37b7684..b00b4871 100644 --- a/include/Kaneshige/Course/CrsGround.h +++ b/include/Kaneshige/Course/CrsGround.h @@ -43,6 +43,7 @@ class CrsGround enum EMat { // TODO + Mat_1 = 1, Mat_255 = 0xff, }; diff --git a/include/Sato/GeographyObj.h b/include/Sato/GeographyObj.h index b58f5462..a5756a49 100644 --- a/include/Sato/GeographyObj.h +++ b/include/Sato/GeographyObj.h @@ -229,7 +229,7 @@ class GeographyObj virtual u32 getJ3DModelDataTevStageNum() const { return 0x20000; } // 50 virtual void createColModel(J3DModelData *); // 54 virtual void createBoundsSphere(J3DModelData *); // 58 - virtual GeoAnmTableEntry *getAnmTbl() { return nullptr; } // 5C + virtual GeoAnmTableEntry *getAnmTbl() { return nullptr; } // 5C virtual u16 getSizeAnmTbl() { return 0; } // 60 virtual GeoObjSupervisor *getSupervisor() { return nullptr; } // 64 virtual void getItemThrowDirPow(JGeometry::TVec3f *, f32 *, const ItemObj &); // 68 @@ -314,7 +314,7 @@ class TMapObjHioNode : public GeographyObj public: TMapObjHioNode(u32 id) : GeographyObj(id) {} TMapObjHioNode(const CrsData::SObject &rObj) : GeographyObj(rObj) {} - virtual ~TMapObjHioNode(); + virtual ~TMapObjHioNode() {} }; #endif diff --git a/include/Sato/ItemObj.h b/include/Sato/ItemObj.h index ce3e8f90..564efc14 100644 --- a/include/Sato/ItemObj.h +++ b/include/Sato/ItemObj.h @@ -289,6 +289,7 @@ class ItemObj int get_1fc() const { return _1fc; } const JGeometry::TVec3f &getPos() const { return mPos; } + const JGeometry::TVec3f &getVel() const { return mVel; } const JGeometry::TVec3f getColPos() const { return mColPos; } ItemObjSuc *getSuccessionParent() const { return mSuccessionParent; } diff --git a/include/Sato/J3DAnmObject.h b/include/Sato/J3DAnmObject.h index 43bd5213..38ceeddd 100644 --- a/include/Sato/J3DAnmObject.h +++ b/include/Sato/J3DAnmObject.h @@ -2,13 +2,16 @@ #define SATO_J3DANMOBJECT_H #include "JSystem/J3D/J3DAnmBase.h" +#include "JSystem/J3D/J3DAnmCluster.h" #include "JSystem/J3D/J3DAnmColor.h" #include "JSystem/J3D/J3DAnmTransform.h" #include "JSystem/J3D/J3DFrameCtrl.h" #include "JSystem/J3D/J3DModel.h" #include "JSystem/J3D/J3DMtxCalc.h" +#include "JSystem/J3D/J3DSkinDeform.h" #include "JSystem/JUtility/JUTAssert.h" #include "Kaneshige/ExModel.h" +#include "types.h" class J3DAnmObjBase { @@ -19,15 +22,15 @@ class J3DAnmObjBase void frameProc() { mFrameCtrl.update(); } void update() { mFrameCtrl.update(); } void resetFrame() { mFrameCtrl.reset(); } - - void initFrameCtrl() { - initFrameCtrl(mAnmBase); - } J3DFrameCtrl *getFrameCtrl() { return &mFrameCtrl; } + f32 getFrame() const { return mFrameCtrl.getFrame(); } + f32 getRate() const { return mFrameCtrl.getRate(); } + void setExModel(ExModel *model) { mModel = model; } void setRate(const float &rate) { mFrameCtrl.setRate(rate); } void setFrame(float frame) { mFrameCtrl.setFrame(frame); } + void stop() { mFrameCtrl.stop(); } J3DModelData *getModelData() { return mModel->getModelData(); } @@ -36,9 +39,40 @@ class J3DAnmObjBase ExModel *mModel; // 04 J3DFrameCtrl mFrameCtrl; // 08 + + // TODO: does this belong here or in J3DAnmObjMaterial? it doesn't make much sense to be here but it does fix offsets for all classes that inherit J3DAnmObjBase J3DAnmBase *mAnmBase; // 1c }; // Size: 0x20 +class J3DAnmObjCluster : public J3DAnmObjBase { +public: + J3DAnmObjCluster() { + mDeformData = nullptr; + } + virtual ~J3DAnmObjCluster() {} + virtual void anmFrameProc(); + + void attach(J3DAnmCluster *); + + static void loadClusterAnmData(J3DAnmCluster **, void *); + static void loadClusterData(J3DDeformData * *, void *); + static void setDeformData(ExModel *, J3DDeformData *, bool); + + void setExModel(ExModel *mdl, J3DDeformData *deformData) { + mModel = mdl; + mDeformData = deformData; + } + + void update() { + mDeformData->setAnm((J3DAnmCluster*)mAnmBase); + mFrameCtrl.update(); + anmFrameProc(); + } + +private: + J3DDeformData *mDeformData; +}; + class J3DAnmObjMaterial : public J3DAnmObjBase { public: @@ -54,7 +88,7 @@ class J3DAnmObjMaterial : public J3DAnmObjBase template void attach(T *anm) { mAnmBase = anm; - initFrameCtrl(mAnmBase); + J3DAnmObjBase::initFrameCtrl(mAnmBase); } J3DAnmBase *getAnmBase() { return mAnmBase; } diff --git a/include/Sato/ObjCollision.h b/include/Sato/ObjCollision.h index 5aa34b27..33580740 100644 --- a/include/Sato/ObjCollision.h +++ b/include/Sato/ObjCollision.h @@ -33,7 +33,8 @@ class ObjColBase u8 IsHitBoundPos(JGeometry::TVec3f, JGeometry::TVec3f); - void setRadius(f32 rad) { mRadius = rad; } + void setRadius(const f32 rad) { mRadius = rad; } + void scaleRadius(const f32 scale) { mRadius = scale * mRadius; } void setScale(f32 scale) { mScale = scale; } f32 getRadius() const { return mRadius; } diff --git a/include/Shiraiwa/Coord3D.h b/include/Shiraiwa/Coord3D.h index 79abcff0..0205eead 100644 --- a/include/Shiraiwa/Coord3D.h +++ b/include/Shiraiwa/Coord3D.h @@ -6,8 +6,10 @@ #include "JSystem/JGeometry/Quat.h" #include "JSystem/JGeometry/Vec.h" #include "Kaneshige/Course/CrsData.h" +#include "macros.h" class TFreeMove { +public: TFreeMove(); virtual ~TFreeMove() {} void init(JGeometry::TVec3f *, JGeometry::TVec3f *, f32); @@ -24,6 +26,23 @@ class TFreeMove { void initStart(); void setTargetPosUniform(const JGeometry::TVec3f &, int); void fixCurPosition(); + + bool hasTarget() const { + return _18; + } + + void releaseTarget() { // not sure what to name this + _18 = false; + } + +private: + JGeometry::TVec3f mTagret; + JGeometry::TVec3f *mpPos; + JGeometry::TVec3f *mpVel; + bool _18; + f32 _1c; + f32 _20; + f32 _24; }; class TPathMove { @@ -46,12 +65,14 @@ class TPathMove { void getNodeDir(u16, JGeometry::TVec3f *); protected: - const CrsData::SObject *mpObj; // 04 - short _8; // + s16 _8; // JGeometry::TVec3f *mpPos; // 0c JGeometry::TVec3f *mpVel; // 10 - + f32 _14; + f32 _18; + bool _1c; + PLACEHOLDER_BYTES(0x1d, 0x24); }; // Size: 0x24 class TFreeRotate { diff --git a/include/Shiraiwa/MapObjAntLion.h b/include/Shiraiwa/Objects/MapObjAntLion.h similarity index 100% rename from include/Shiraiwa/MapObjAntLion.h rename to include/Shiraiwa/Objects/MapObjAntLion.h diff --git a/include/Shiraiwa/MapObjAward.h b/include/Shiraiwa/Objects/MapObjAward.h similarity index 98% rename from include/Shiraiwa/MapObjAward.h rename to include/Shiraiwa/Objects/MapObjAward.h index f673d983..5db3e7aa 100644 --- a/include/Shiraiwa/MapObjAward.h +++ b/include/Shiraiwa/Objects/MapObjAward.h @@ -4,7 +4,7 @@ #include "Sato/GeographyObj.h" #include "Sato/StateObserver.h" #include "Sato/Objects/GeoItemBox.h" -#include "Shiraiwa/MapObjDemoObj.h" +#include "Shiraiwa/Objects/MapObjDemoObj.h" // Inline/Unused //void JSULink::~JSULink(); diff --git a/include/Shiraiwa/MapObjDemoObj.h b/include/Shiraiwa/Objects/MapObjDemoObj.h similarity index 100% rename from include/Shiraiwa/MapObjDemoObj.h rename to include/Shiraiwa/Objects/MapObjDemoObj.h diff --git a/include/Shiraiwa/MapObjHanabi.h b/include/Shiraiwa/Objects/MapObjHanabi.h similarity index 100% rename from include/Shiraiwa/MapObjHanabi.h rename to include/Shiraiwa/Objects/MapObjHanabi.h diff --git a/include/Shiraiwa/MapObjPool.h b/include/Shiraiwa/Objects/MapObjPool.h similarity index 100% rename from include/Shiraiwa/MapObjPool.h rename to include/Shiraiwa/Objects/MapObjPool.h diff --git a/include/Shiraiwa/Objects/MapObjWanwan.h b/include/Shiraiwa/Objects/MapObjWanwan.h new file mode 100644 index 00000000..6b06abda --- /dev/null +++ b/include/Shiraiwa/Objects/MapObjWanwan.h @@ -0,0 +1,166 @@ +#ifndef MAPOBJWANWAN_H +#define MAPOBJWANWAN_H + +#include "Bando/EngineSound.h" +#include "JSystem/JGeometry/Vec.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "Kaneshige/Course/CrsGround.h" +#include "Sato/GeographyObj.h" +#include "Sato/J3DAnmObject.h" +#include "Sato/StateObserver.h" +#include "Sato/StringObj.h" +#include "Shiraiwa/Coord3D.h" +#include "macros.h" +#include "types.h" + +class TMapObjWanwan; + +class TMapObjWanwanPile : public GeographyObj { +public: + TMapObjWanwanPile(); + virtual ~TMapObjWanwanPile(); + virtual void doKartColCallBack(int); + virtual void reset(); + virtual void createColModel(J3DModelData *); + virtual const char *getBmdFileName(); + virtual void calc() {} // 0x80297c18 + + void setPosition(const JGeometry::TVec3f &pos) { + mPos.set(pos); + } +private: + friend class TMapObjWanwan; +}; + +class TMapObjWanwanChain : public GeographyObj { +public: + TMapObjWanwanChain(); // 0x802978d4 + virtual ~TMapObjWanwanChain(); // 0x80297948 + virtual void reset(); // 0x802979c8 + virtual void createColModel(J3DModelData *); // 0x80297a18 + virtual const char *getBmdFileName(); // 0x80297a1c + virtual void setCurrentViewNo(u32); // 0x80297a44 + + // Inline + virtual void calc() {} // 0x80297c1c + + static f32 sChainOneLength; // 0x80415190 + + void setPosition(const JGeometry::TVec3f &pos) { + mPos.set(pos); + } + + void setPile(TMapObjWanwanPile *pile) { + mpPile = pile; + } + +private: + friend class TMapObjWanwan; + TMapObjWanwanPile *mpPile; +}; + +class TMapObjWanwan : public TMapObjHioNode, StateObserver { // Autogenerated +public: + TMapObjWanwan(const CrsData::SObject &); // 0x80294db8 + virtual ~TMapObjWanwan(); // 0x80294f34 + void makeChain(int); // 0x80295054 + void reset(); // 0x80295118 + void getParameters(); // 0x80295230 + void resetPosition(int); // 0x802952e0 + void loadAnimation(); // 0x8029534c + const char *getShadowBmdFileName(); // 0x802953cc + void createColModel(J3DModelData *); // 0x802953f4 + void createModel(JKRSolidHeap *, u32); // 0x80295444 + const char *getBmdFileName(); // 0x802955dc + void doKartColCallBack(int); // 0x80295604 + void setCurrentViewNo(u32); // 0x80295668 + void initFunc_Wait(); // 0x802956c8 + void doFunc_Wait(); // 0x802956cc + void initFunc_Jump(); // 0x80295738 + void doFunc_Jump(); // 0x802957e0 + void initFunc_Attack(); // 0x802958b0 + void initFunc_Attacked(); // 0x80295ac8 + void doFunc_Attacked(); // 0x80295acc + void initFunc_Jumped(); // 0x80295b60 + void doFunc_Jumped(); // 0x80295b64 + void setRotate(f32); // 0x80295c1c + void doFunc_Attack(); // 0x80295d60 + void turnDown(bool); // 0x80295e04 + void initFunc_Walk(); // 0x80295e4c + void doFunc_Walk(); // 0x80295ec4 + void initFunc_Back(); // 0x80295f54 + void doFunc_Back(); // 0x80295fb8 + void fallDown(s32, bool); // 0x80296054 + void turnTo(); // 0x8029614c + void jumpStart(JGeometry::TVec3f &, f32); // 0x80296338 + bool isTouchGround(); // 0x80296408 + f32 getCourseHeight(JGeometry::TVec3f &); // 0x8029645c + f32 getAngleToRand(); // 0x80296494 + f32 getRandRadius(u8, u8); // 0x802965c0 + void getWanwanBackPos(JGeometry::TVec3f *); // 0x80296658 + f32 getAngleToAttack(JGeometry::TVec3f &); // 0x802966c0 + + int searchTargetKart(); // 0x8029678c + void calc(); // 0x802967bc + void update(); // 0x80296a2c + void chainCorrect(); // 0x80296ae8 + bool checkWanwanHitting(); // 0x80296eb8 + void fixChain(); // 0x80296efc + void setChainPosition(TMapObjWanwanChain *, JGeometry::TVec3f &, JGeometry::TVec3f &, f32); // 0x802971a0 + void createEmitterOnGround(JPABaseEmitter **, const char *); // 0x802974bc + + virtual void MoveExec(); // 0x80297450 + virtual void InitExec(); // 0x80296720 + + static StateFuncSet sTable[7]; // 0x803a4400 + static f32 sOffsetHeight; // 0x80415168 + static f32 sJumpHeight; // 0x8041516c + static f32 sChainBackInside; // 0x80415170 + static s16 sDefaultRingNodeNo; // 0x80415174 + static f32 sAirFriction; // 0x80415178 + static f32 sGravity; // 0x8041517c + static f32 sItemHitVelScale; // 0x80415180 + static f32 sKartHitVelScale; // 0x80415184 + static f32 sJumpVelY; // 0x80415188 + static s16 sJumpTopFrame; // 0x8041518c + static J3DAnmTransform *sWanwanBckAnmTrans; // 0x80416de0 + static J3DMtxCalc *sWanwanBckMtxCalc; // 0x80416de4 + static J3DDeformData *sWanwanBlsAnmData; // 0x80416de8 + static J3DAnmCluster *sWanwanBlkAnmData; // 0x80416dec + static int sChainJointNo; // 0x80416df0 + // Inline/Unused + //void fixPosition(); + //void fixWall(JGeometry::TVec3f &, JGeometry::TVec3f &); + //void changeState_Wall(u32); + //void getAngleToKart(); + static int sWanwanChainNum; + static f32 scChainHalfLength; + // Inline + virtual u32 getMotorType() const { return 3; }; // 0x802975cc + +private: + TMapObjWanwanChain *mpaChain[30]; + TMapObjWanwanPile *mpPile; + f32 mChainLength; + int mKartNo; + bool _1dc; + TFreeMove mFreeMove; + CrsGround *mpGround; + f32 _20c; + s16 mWalkTimer; + s16 mTimesAttacked; + s16 mWalkDuration; + u8 mNumChains; + f32 _218; + f32 mAttackAngle; // 21c + f32 mRotate; + f32 _224; + f32 mHeightOffset; + f32 _22c; + f32 _230; + s16 mRingNodeNo; + ExStringNodeManager *mpStringNodeMgr; + J3DAnmObjCluster mAnmObjCluster; + JPABaseEmitter *mpEmitter; +}; // class MapObjWanwan +#endif // MAPOBJWANWAN_H diff --git a/include/Yamamoto/KartAnt.h b/include/Yamamoto/KartAnt.h index a442347e..aa5602a7 100644 --- a/include/Yamamoto/KartAnt.h +++ b/include/Yamamoto/KartAnt.h @@ -3,7 +3,7 @@ #include -#include "Shiraiwa/MapObjAntLion.h" +#include "Shiraiwa/Objects/MapObjAntLion.h" #include "types.h" diff --git a/src/Kaneshige/Course/CrsGround.cpp b/src/Kaneshige/Course/CrsGround.cpp index 5b0cd6ec..1f25909c 100644 --- a/src/Kaneshige/Course/CrsGround.cpp +++ b/src/Kaneshige/Course/CrsGround.cpp @@ -7,7 +7,7 @@ #include "Kaneshige/Objects/GeoPuller.h" #include "Kaneshige/Objects/GeoSplash.h" #include "Kaneshige/Objects/GeoWater.h" -#include "Shiraiwa/MapObjPool.h" +#include "Shiraiwa/Objects/MapObjPool.h" #include "mathHelper.h" diff --git a/src/Kaneshige/DemoTimeKeeper.cpp b/src/Kaneshige/DemoTimeKeeper.cpp index 9e9e8085..09d35828 100644 --- a/src/Kaneshige/DemoTimeKeeper.cpp +++ b/src/Kaneshige/DemoTimeKeeper.cpp @@ -12,8 +12,8 @@ #include "Sato/JPEffectMgr.h" #include "Sato/EffectScreen.h" #include "Sato/RivalSpeedCtrl.h" -#include "Shiraiwa/MapObjAward.h" -#include "Shiraiwa/MapObjHanabi.h" +#include "Shiraiwa/Objects/MapObjAward.h" +#include "Shiraiwa/Objects/MapObjHanabi.h" #include "kartEnums.h" s32 StaffRollTimeKeeper::sStartTitleCreditTime; diff --git a/src/Kaneshige/RaceDirector.cpp b/src/Kaneshige/RaceDirector.cpp index 9ee7a580..d8e917ef 100644 --- a/src/Kaneshige/RaceDirector.cpp +++ b/src/Kaneshige/RaceDirector.cpp @@ -10,7 +10,7 @@ #include "Osako/system.h" #include "Sato/GeographyObjMgr.h" #include "Sato/JPEffectMgr.h" -#include "Shiraiwa/MapObjHanabi.h" +#include "Shiraiwa/Objects/MapObjHanabi.h" #include "kartEnums.h" #include "JSystem/JAudio/JASFakeMatch2.h" diff --git a/src/Kaneshige/RaceDrawer.cpp b/src/Kaneshige/RaceDrawer.cpp index 1e4bfc2d..2bbf44ec 100644 --- a/src/Kaneshige/RaceDrawer.cpp +++ b/src/Kaneshige/RaceDrawer.cpp @@ -23,7 +23,7 @@ #include "Sato/stEffectMgr.h" #include "Shiraiwa/Balloon.h" #include "Shiraiwa/LensFlare.h" -#include "Shiraiwa/MapObjAward.h" +#include "Shiraiwa/Objects/MapObjAward.h" #include "Shiraiwa/ZCaptureMgr.h" #include "dolphin/gx/GXEnum.h" #include "dolphin/gx/GXPixel.h" diff --git a/src/Sato/ItemYoshiEgg.cpp b/src/Sato/ItemYoshiEgg.cpp index 134d1f15..bb509810 100644 --- a/src/Sato/ItemYoshiEgg.cpp +++ b/src/Sato/ItemYoshiEgg.cpp @@ -78,8 +78,7 @@ void ItemYoshiEgg::loadAnmData(J3DModelData *mdlData) { void ItemYoshiEgg::createModel(JKRSolidHeap *heap, u32 p2, u32 p3) { mModel.createDifferedModel(heap, p2, p3 | (0x1000000 | 0x20000), false); mMat.setExModel(&mModel); - mMat.setAnmBase(sTexPattern); - mMat.initFrameCtrl(); + mMat.attach(sTexPattern); } void ItemYoshiEgg::update() { @@ -337,7 +336,7 @@ void ItemYoshiEgg::calcCreateItem(u32 *outKinds) { } //-------------------------------------------------------------- - // 4?d. Next round will draw from the three “common” entries + // 4?d. Next round will draw from the three "Common" entries // plus whatever we have just appended (0?2 entries) //-------------------------------------------------------------- listSize = appended + 3; // 3 mandatory + newly added diff --git a/src/Sato/StringObj.cpp b/src/Sato/StringObj.cpp index e8fb5bbc..7e1457dd 100644 --- a/src/Sato/StringObj.cpp +++ b/src/Sato/StringObj.cpp @@ -319,7 +319,7 @@ void StringObj::calc() { ExModel *exModel = mExModel; JSUListIterator it(mStringNodeMgr->mStrNodeList.getFirst()); - JGeometry::TRot3f m; + JGeometry::TRot3f m; // making this a matrix causes instruction swaps PSMTXCopy(_14, m); f32 scale = 0.0001f; @@ -334,8 +334,7 @@ void StringObj::calc() { for (u32 i = 0; i < mStringNodeMgr->mStrNodeList.getNumLinks() - 1; i++) { if (i < mStringNodeMgr->mStrNodeList.getNumLinks() - 1) { JGeometry::TVec3f cp, ang, vel, pos, pos2; - - m.getYDir(ang); + ang.set(m[0][1], m[1][1], m[2][1]); mStringNodeMgr->getNodePos(i, &pos); mStringNodeMgr->getNodePos(i + 1, &pos2); diff --git a/src/Shiraiwa/MapObjWanwan.cpp b/src/Shiraiwa/MapObjWanwan.cpp index e69de29b..f9097940 100644 --- a/src/Shiraiwa/MapObjWanwan.cpp +++ b/src/Shiraiwa/MapObjWanwan.cpp @@ -0,0 +1,759 @@ +#include "Shiraiwa/Objects/MapObjWanwan.h" +#include "JSystem/J3D/J3DFrameCtrl.h" +#include "JSystem/J3D/J3DModel.h" +#include "JSystem/JGeometry/Matrix.h" +#include "JSystem/JGeometry/Util.h" +#include "JSystem/JGeometry/Vec.h" +#include "Kaneshige/Course/CrsGround.h" +#include "Kaneshige/RaceMgr.h" +#include "Sato/GeographyObj.h" +#include "Sato/GeographyObjMgr.h" +#include "Sato/J3DAnmObject.h" +#include "Sato/JPEffectMgr.h" +#include "Sato/ObjUtility.h" +#include "Sato/StateObserver.h" +#include "Shiraiwa/SiUtil.h" +#include "Yamamoto/kartCtrl.h" +#include "dolphin/mtx.h" +#include "kartEnums.h" +#include "types.h" +#include "mathHelper.h" +#include "std/math.h" +#include +#include + +J3DAnmTransform *TMapObjWanwan::sWanwanBckAnmTrans; +J3DMtxCalc *TMapObjWanwan::sWanwanBckMtxCalc; +J3DDeformData *TMapObjWanwan::sWanwanBlsAnmData; +J3DAnmCluster *TMapObjWanwan::sWanwanBlkAnmData; +int TMapObjWanwan::sChainJointNo; + +f32 TMapObjWanwan::sOffsetHeight = 300.0f; +f32 TMapObjWanwan::sJumpHeight = 8.0f; +f32 TMapObjWanwan::sChainBackInside = 30.0f; +s16 TMapObjWanwan::sDefaultRingNodeNo = 9; +f32 TMapObjWanwan::sAirFriction = 0.9999f; +f32 TMapObjWanwan::sGravity = 15.0f; +f32 TMapObjWanwan::sItemHitVelScale = 1.0f; +f32 TMapObjWanwan::sKartHitVelScale = 1.0f; +f32 TMapObjWanwan::sJumpVelY = 350.0f; +s16 TMapObjWanwan::sJumpTopFrame = 15; + +StateObserver::StateFuncSet TMapObjWanwan::sTable[7] = { + {0, &TMapObjWanwan::initFunc_Wait, &TMapObjWanwan::doFunc_Wait}, + {1, &TMapObjWanwan::initFunc_Attack, &TMapObjWanwan::doFunc_Attack}, + {2, &TMapObjWanwan::initFunc_Walk, &TMapObjWanwan::doFunc_Walk}, + {3, &TMapObjWanwan::initFunc_Back, &TMapObjWanwan::doFunc_Back}, + {4, &TMapObjWanwan::initFunc_Jump, &TMapObjWanwan::doFunc_Jump}, + {5, &TMapObjWanwan::initFunc_Attacked, &TMapObjWanwan::doFunc_Attacked}, + {6, &TMapObjWanwan::initFunc_Jumped, &TMapObjWanwan::doFunc_Jumped}, +}; + +TMapObjWanwan::TMapObjWanwan(const CrsData::SObject &obj) : TMapObjHioNode(obj), mpPile(nullptr), mpEmitter(nullptr) { + GeographyObj::NewAnmCtrl(); + GeographyObj::createSoundMgr(); + mpGround = new CrsGround(RCMGetCourse()); + getParameters(); + makeChain(mNumChains); + mFreeMove.init(&mPos, &mVel, 100.0f); + mpStringNodeMgr = new ExStringNodeManager(mNumChains, 30.0f, true, false, 0); + mpStringNodeMgr->set_3c(0x40000); +} + +TMapObjWanwan::~TMapObjWanwan() { + delete mpStringNodeMgr; + delete mpGround; +} + +void TMapObjWanwan::makeChain(int count) { + mpPile = (TMapObjWanwanPile *)GetGeoObjMgr()->createSubObj(0xe7a); + + count = MIN(count, 30); + + for (u8 i = 0; i < count; i++) { + mpaChain[i] = (TMapObjWanwanChain *)GetGeoObjMgr()->createSubObj(0xe79); + mpaChain[i]->setPile(mpPile); + } + mChainLength = (count - 1) * TMapObjWanwanChain::sChainOneLength; + mpaChain[0]->setObjFlagHidding(); +} + +void TMapObjWanwan::reset() { + GeographyObj::resetObject(); + GeographyObj::setObjFlagCheckItemHitting(); + _58 = 0xb; + mReaction.setFlg(7, 0); + StateObserver::ResetState(); + mAnmCtrl->Reset(); + mWalkTimer = 0; + mTimesAttacked = 0; + _20c = -10.0f; + _218 = -100.0f; + _22c = 0.05f; + mRotate = 0.0f; + mKartNo = -1; + mRingNodeNo = sDefaultRingNodeNo; + mAttackAngle = 0.0f; + _230 = 0.0f; + _1dc = true; + mpEmitter = nullptr; + mAnmObjCluster.resetFrame(); + mFreeMove.reset(); + setRotate(mAttackAngle); + resetPosition(mNumChains); + mpStringNodeMgr->resetNodeAll(nullptr); + mpStringNodeMgr->setNodeLengthAll(TMapObjWanwanChain::sChainOneLength); +} + +void TMapObjWanwan::getParameters() { + if (mObjData->mParam1 < 2) { + mNumChains = 21; + } + else { + mNumChains = mObjData->mParam1 + 1; + } + + u8 clamped = mNumChains; + if (clamped > 30) { + clamped = 30; + } + else if (clamped < 2) { + clamped = 2; + } + + mNumChains = clamped; + + if (mObjData->mParam2 == 0) { + mWalkDuration = 120; + } + else { + mWalkDuration = mObjData->mParam2; + } + + if (mObjData->mParam3 == 0) { + _224 = 20.0f; + } + else { + _224 = mObjData->mParam3; + } +} + +void TMapObjWanwan::resetPosition(int count) { + for (u8 i = 0; i < count; i++) { + if (mpaChain[i]) { + mpaChain[i]->setPosition(mPos); + } + } + + if (mpPile) { + mpPile->setPosition(mPos); + } +} + +void TMapObjWanwan::loadAnimation() { + J3DModelData *mdlData = mModel.getModelData(); + void *bca = ObjUtility::getPtrCourseArc("/Objects/Wanwan1.bca"); + J3DAnmObjTrans::setupTransAnmData(&sWanwanBckAnmTrans, &sWanwanBckMtxCalc, mdlData, bca); + + void *bls = ObjUtility::getPtrCourseArc("/Objects/Wanwan1.bls"); + J3DAnmObjCluster::loadClusterData(&sWanwanBlsAnmData, bls); + + void *bla = ObjUtility::getPtrCourseArc("/Objects/Wanwan1.bla"); + J3DAnmObjCluster::loadClusterAnmData(&sWanwanBlkAnmData, bla); +} + +const char *TMapObjWanwan::getShadowBmdFileName() { + static const char *cShadowBmdName = "/Objects/Wanwan1Shadow.bmd"; + return cShadowBmdName; +} + +void TMapObjWanwan::createColModel(J3DModelData *mdlData) { + createBoundsSphere(mdlData); + mBounds[0]->scaleRadius(0.8f); +} + +void TMapObjWanwan::createModel(JKRSolidHeap *heap, u32 viewNo) { + mModel.createDifferedModel(heap, viewNo, 0x200, true); + GeographyObj::getAnmCtrl()->InitRegistration(1, &mModel); + GeographyObj::getAnmCtrl()->RegisterTrans(0, sWanwanBckAnmTrans, sWanwanBckMtxCalc); + GeographyObj::getAnmCtrl()->getFrameCtrl(0)->setAttribute(2); + + J3DAnmObjCluster::setDeformData(&mModel, sWanwanBlsAnmData, false); + mAnmObjCluster.setExModel(&mModel, sWanwanBlsAnmData); + mAnmObjCluster.attach(sWanwanBlkAnmData); + mAnmObjCluster.getFrameCtrl()->setAttribute(2); + sChainJointNo = mModel.getModelData()->getJointName()->getIndex("pos_chn"); + mHeightOffset = sOffsetHeight * mScale.y; +} + +const char *TMapObjWanwan::getBmdFileName() { + static const char *cBmdName = "/Objects/Wanwan1.bmd"; + return cBmdName; +} + +void TMapObjWanwan::doKartColCallBack(int kartNo) { + if (!(GetKartCtrl()->GetKartStatus(kartNo) & 0x40000)) return; + + mKartNo = kartNo; + StateObserver::setState(4); +} + +void TMapObjWanwan::setCurrentViewNo(u32 viewNo) { + mModel.setCurrentViewNo(viewNo); + + Mtx m; + ObjUtility::getCamDependLightMtx(viewNo, mPos, m); + mModel.setEffectMtx(m, 0); +} + +void TMapObjWanwan::initFunc_Wait() {} + +void TMapObjWanwan::doFunc_Wait() { + if (StateObserver::getStateCount() > 10) { + StateObserver::setState(2); + } + else if (mWalkTimer > 0) { + mWalkTimer--; + } +createEmitterOnGround(&mpEmitter, "mk_wanSmoke_a"); +} + +void TMapObjWanwan::initFunc_Jump() { + if (GeographyObj::tstItemHitting()) { + mVel.scale(sItemHitVelScale, GeographyObj::getColItemObj()->getVel()); + } + else { + ObjUtility::getKartVel(mKartNo, &mVel); + mVel.scale(sKartHitVelScale); + } + mVel.y += sJumpVelY; + mAnmObjCluster.stop(); +} + +void TMapObjWanwan::doFunc_Jump() { + mVel.scale(sAirFriction); + mVel.y -= sGravity; + mPos.add(mVel); + + JGeometry::TVec3f posdiff, backPos; + getWanwanBackPos(&backPos); + + posdiff.sub(backPos, mObjData->position); + + if (posdiff.length() > mChainLength) { + mVel.zero(); + StateObserver::setState(6); + } +} + +void TMapObjWanwan::initFunc_Attack() { + JGeometry::TVec3f pos; + ObjUtility::getKartPos(mKartNo, &pos); + pos.sub(mPos); + pos.scale(2.0f); + pos.add(mPos); + + JGeometry::TVec3f kartVel; + ObjUtility::getKartVel(mKartNo, &kartVel); + kartVel.y = 0.0f; + kartVel.normalize(); + + f32 velScale = GetKartCtrl()->GetCarSpeed(mKartNo); + velScale = velScale * velScale * (mScale.y * 0.2f + 0.7f); + kartVel.scale(velScale); + pos.add(kartVel); + + pos.y = mHeightOffset + getCourseHeight(pos); + pos.y = mPos.y; + mFreeMove.setTargetPos(pos, 6.0f, 70.0f); + mVel.zero(); + pos.sub(mPos); + mAttackAngle = getAngleToAttack(pos); +} + +void TMapObjWanwan::initFunc_Attacked() {} + +void TMapObjWanwan::doFunc_Attacked() { + if (isTouchGround() && StateObserver::getStateCount() > 50) { + StateObserver::setState(3); + } + else { + if (mAnmObjCluster.getFrame() == 0.0f) { + mAnmObjCluster.setFrame(0.0f); + } + fallDown(-1, true); + } + + mTimesAttacked++; + createEmitterOnGround(&mpEmitter, "mk_wanSmoke_a"); +} + +void TMapObjWanwan::initFunc_Jumped() {} + +void TMapObjWanwan::doFunc_Jumped() { + if (StateObserver::getStateCount() setRate(1.0f); + StateObserver::setState(2); + return; + } + + mVel.scale(sAirFriction); + mVel.y -= sGravity; + mPos.add(mVel); +} + +void TMapObjWanwan::setRotate(f32 rotate) { + mRotate = rotate; + + // might be mRotMtx.setEulerXYZ? + const f32 x = 0; + const f32 y = mRotate; + const f32 z = _230; + f32 cr = cos(x); // f26 + f32 cp = cos(y); // f31 + f32 cy = cos(z); // f30 + f32 sr = sin(x); // f29 + f32 sp = sin(y); // f28 + f32 sy = sin(z); // f7 + + // ??? + f32 tmp = sy * sp; + f32 cpy = (cy * cp); + f32 spy = sp * sy; + + mRotMtx[0][0] = ((tmp) * sr + (cp * cr)); + mRotMtx[1][0] = (sr * cy); + mRotMtx[2][0] = -(sp * cr) + (sy * cp * sr); + + mRotMtx[0][1] = ((-sr * cp) + (spy) * cr); + mRotMtx[1][1] = (cy * cr); + mRotMtx[2][1] = (sp * sr + sy * (cp * cr)); + + mRotMtx[0][2] = (cy * sp); + mRotMtx[1][2] = (-sy); + mRotMtx[2][2] = (cpy); +} + +void TMapObjWanwan::doFunc_Attack() { + if (mAnmObjCluster.getRate() != 0.0f && mAnmObjCluster.getFrame() == 5.0f) { + mAnmObjCluster.stop(); + } + + if (!mFreeMove.hasTarget()) { + mWalkTimer = mWalkDuration; + mTimesAttacked = 0; + mVel.zero(); + mAnmObjCluster.getFrameCtrl()->setRate(1.0f); + StateObserver::setState(5); + return; + } + + turnDown(true); + turnTo(); +} + +void TMapObjWanwan::turnDown(bool p1) { + if (p1) { + if (_230 < 0.75f) { + _230 += 0.03f; + } + } + else { + if (_230 > 0.0f) { + _230 -= 0.05f; + } + } +} + +void TMapObjWanwan::initFunc_Walk() { + if (!isTouchGround()) return; + + if (mRotate == mAttackAngle) { + mAttackAngle = getAngleToRand(); + } + + JGeometry::TVec3f t; + mRotMtx.getZDir(t); + jumpStart(t, 12.0f); +} + +void TMapObjWanwan::doFunc_Walk() { + fallDown(0, false); + if (RCMGetManager()->getRaceMode() == TIME_ATTACK) return; + + if (mWalkTimer <= 0) { + int targetKart = -1; + if (!(StateObserver::getStateCount() & 0x1f)) { + targetKart = searchTargetKart(); + } + if (targetKart != -1) { + mKartNo = targetKart; + StateObserver::setState(1); + } + return; + } + mWalkTimer--; +} + +void TMapObjWanwan::initFunc_Back() { + mAnmObjCluster.getFrameCtrl()->setRate(1.0f); + if (!isTouchGround()) return; + + JGeometry::TVec3f t; + mRotMtx.getZDir(t); + jumpStart(t, 12.0f); +} + +void TMapObjWanwan::doFunc_Back() { + fallDown(3, (mWalkDuration - mWalkTimer < 30)); + if (mWalkTimer < 0) { + mAnmObjCluster.getFrameCtrl()->setRate(1.0f); + StateObserver::setState(2); + return; + } + + if (mWalkDuration - mWalkTimer == 30) { + mAnmObjCluster.getFrameCtrl()->setRate(1.0f); + } + mWalkTimer--; +} + +void TMapObjWanwan::fallDown(s32 nextState, bool p2) { + mPos.add(mVel); + + if (isTouchGround()) { + if (nextState != -1) { + StateObserver::setState(nextState); + } + } + else { + turnDown(p2); + turnTo(); + mVel.y += _20c; + if (mVel.y < _218) { + mVel.y = _218; + } + } + createEmitterOnGround(&mpEmitter, "mk_wanSmoke_a"); +} + +// Nonmatching +// https://decomp.me/scratch/N6GWY +void TMapObjWanwan::turnTo() { + f32 targetAngle = mAttackAngle; + f32 rotate = mRotate; + + f32 minAngle = targetAngle - 3.141593f; + f32 maxAngle = targetAngle + 3.141593f; + + if (minAngle <= maxAngle) + { + f32 range = maxAngle - minAngle; // 2pi + + while (rotate < minAngle) + { + rotate += range; + } + + while (rotate >= maxAngle) + { + rotate -= range; + } + } + + rotate = _22c; + if (StateObserver::getState() == 1) { + rotate *= 2.0f; + } + + if (-rotate < targetAngle - minAngle) { + mRotate -= rotate; + } + else if (rotate > targetAngle - minAngle) { + mRotate += rotate; + } + else { + mRotate = targetAngle; + } + + setRotate(mRotate); +} + +void TMapObjWanwan::jumpStart(JGeometry::TVec3f &vel, f32 s) { + vel.y = 0.0f; + + f32 scale = MAX(mScale.x, mScale.z); + vel.normalize(s * scale); + + vel.y = sJumpHeight * mScale.y; + mVel.set(vel); +} + +bool TMapObjWanwan::isTouchGround() { + return (mPos.y - mHeightOffset) <= getCourseHeight(mPos) ? true : false; +} + +f32 TMapObjWanwan::getCourseHeight(JGeometry::TVec3f &pos) { + mpGround->search(pos); + return mpGround->getHeight(); +} + +f32 TMapObjWanwan::getAngleToRand() { + JGeometry::TVec3f posDiff, backPos; + posDiff.sub(mObjData->position, mPos); + f32 angle = mAttackAngle; + + getWanwanBackPos(&backPos); + backPos.sub(mObjData->position); + + JGeometry::TVec3f zDir; + mRotMtx.getZDir(zDir); + + if ((zDir.dotZX(posDiff) < 0.0f) + && (backPos.length() > mChainLength * 0.8f)) + { + f32 a = std::atan2f(posDiff.x, posDiff.z); + a += getRandRadius(90, 20); + angle = a; + for (; angle < -F_PI; angle += F_TAU); + for (; angle >= F_PI; angle -= F_TAU); + + } + return angle; +} + +f32 TMapObjWanwan::getRandRadius(u8 max, u8 min) { + u32 range = max - min; + u32 rand = GeographyObj::getGeoRnd()->get(); + int deg = (rand % range) * 2 - range; + if (deg < 0) { + deg -= min; + } + else { + deg += min; + } + return MTXDegToRad(deg); +} + +void TMapObjWanwan::getWanwanBackPos(JGeometry::TVec3f *out) { + if (_1dc) { + f32 x = mPos.x; + f32 y = mPos.y + mHeightOffset; + f32 z = mPos.z; + out->set(x, y, z); + return; + } + + Mtx &bumpMtx = mModel.getModel()->getAnmMtx(sChainJointNo); + out->set(bumpMtx[0][3], bumpMtx[1][3], bumpMtx[2][3]); +} + +f32 TMapObjWanwan::getAngleToAttack(JGeometry::TVec3f &v) { + f32 a = std::atan2f(v.x, v.z); + for (; a < -F_PI; a += F_TAU); + for (; a >= F_PI; a -= F_TAU); + + return a; +} + +void TMapObjWanwan::InitExec() { + Observer_FindAndInit(TMapObjWanwan, 7); +} + +int TMapObjWanwan::searchTargetKart() { + return SiUtil::searchNearKartBall(mObjData->position, _224); +} + +void TMapObjWanwan::calc() { + JGeometry::TVec3f pos(mPos); + StateObserver::ExecuteState(); + if (StateObserver::getState() == 1) { + mFreeMove.update(); + } + chainCorrect(); + + if (isTouchGround()) { + mpGround->search(mPos); + mPos.y = mHeightOffset + mpGround->getHeight() - 0.1f; + mVel.y = 0.0f; + } + + bool isWall = false; + mpGround->search(mPos, pos); + if (mpGround->getAttribute() == CrsGround::Attr_2) { + JGeometry::TVec3f wall; + + f32 wallNorm = mpGround->getWallNormal(&wall, nullptr) + 20.0f; + isWall = true; + + wall.scale(wallNorm); + mPos.add(wall); + mVel.set(wall); + } + + if (isWall) { + switch (StateObserver::getState()) { + case 2: { + mAttackAngle = std::atan2f(mVel.x, mVel.z); + mAttackAngle += getRandRadius(90, 20); + + f32 a = mAttackAngle; + for (; a < -F_PI; a += F_TAU); + for (; a >= F_PI; a -= F_TAU); + mAttackAngle = a; + } + } + } + + if (checkWanwanHitting()) { + StateObserver::setState(4); + } + GeographyObj::moveShadowModel(); + if (_1dc) { + _1dc = false; + } +} + +void TMapObjWanwan::update() { + mAnmObjCluster.update(); + + if (mAnmObjCluster.getFrameCtrl()->getFrame() == 0.0f && mAnmObjCluster.getFrameCtrl()->getRate() != 0.0f) { + mSoundMgr->setSe(0x40021); + } + mSoundMgr->frameWork(); + setModelMatrixAndScale(); + mModel.update(0); +} + +void TMapObjWanwan::chainCorrect() { + JGeometry::TVec3f chainPos, objPos, chainOffset, zDir, vel, posDiff; + if (_1dc) { + objPos.set(mPos.x, mPos.y + mHeightOffset, mPos.z); + } + else { + const Mtx &anm_mtx = mModel.getModel()->getAnmMtx(sChainJointNo); + objPos.set(anm_mtx[0][3], anm_mtx[1][3], anm_mtx[2][3]); + } + + chainPos.sub(objPos, mObjData->position); + if (chainPos.length() > mChainLength) { + if (mFreeMove.hasTarget() && chainPos.dot(mVel) > 0.0f) { + mFreeMove.releaseTarget(); + + } + chainOffset.sub(mPos, objPos); + chainPos.normalize(mChainLength); + chainPos.add(chainOffset); + mPos.add(mObjData->position, chainPos); + } + + mpStringNodeMgr->calc(); + + mRotMtx.getZDir(zDir); + zDir.scale(sChainBackInside * mScale.z); + objPos.add(zDir); + mpStringNodeMgr->setNodePos(0, objPos); + + posDiff.sub(mPos, mObjData->position); + posDiff.normalize(); + posDiff.scaleAdd(50.0f, posDiff, mObjData->position); + posDiff.y += 50.0f; + mpStringNodeMgr->setNodePos(mNumChains - 1, posDiff); + + + vel.zero(); + mpStringNodeMgr->setNodeVel(mNumChains - 1, vel); + fixChain(); +} + +bool TMapObjWanwan::checkWanwanHitting() { + bool ret = false; + + if (StateObserver::getState() != 4 && GeographyObj::tstItemHitting() ) { + u32 itemKind = mColItemObj->getKind(); + if (itemKind == 7 || itemKind == 8 || itemKind == 1) { + ret = true; + } + } + return ret; +} + +void TMapObjWanwan::fixChain() { + static f32 addf = F_HALF_PI; + + f32 f = (mNumChains & 1) ? 0.0f : addf; + + JGeometry::TVec3f pos, nextPos, posDiff; + for (u32 i = 0; i < mNumChains - 1; i++) { + mpStringNodeMgr->getNodePos(i, &pos); + mpStringNodeMgr->getNodePos(i + 1, &nextPos); + + posDiff.sub(pos, nextPos); + posDiff.normalize(); + + setChainPosition(mpaChain[i], pos, posDiff, f); + f += addf; + } + + mpStringNodeMgr->getNodePos(mNumChains - 1, &pos); + posDiff.sub(mPos, mObjData->position); + posDiff.y = 0.0f; + posDiff.normalize(); + setChainPosition(mpaChain[mNumChains - 1], pos, posDiff, f); +} + +void TMapObjWanwan::setChainPosition(TMapObjWanwanChain *pChain, JGeometry::TVec3f &rPos, JGeometry::TVec3f &rPosDiff, f32 f) { + + JGeometry::TVec3f cp, yDir; + mRotMtx.getYDir(yDir); + pChain->setPosition(rPos); + + cp.cross(rPosDiff, yDir); + cp.normalize(); + yDir.cross(cp, rPosDiff); + yDir.normalize(); + + JGeometry::TPos3f r_m, b; + r_m.setXYZDir(cp, yDir, rPosDiff); + PSMTXIdentity(b); + + // might be setRotate? + f32 s = sin(f); + f32 c = cos(f); + + b[0][0] = c; + b[0][1] = -s; + b[1][0] = s; + b[1][1] = c; + b[2][2] = 1.0f; + b[2][1] = 0.0f; + b[1][2] = 0.0f; + b[2][0] = 0.0f; + b[0][2] = 0.0f; + + PSMTXConcat(r_m, b, r_m); + pChain->mRotMtx.set( r_m ); +} + +void TMapObjWanwan::MoveExec() { + Observer_FindAndExec(TMapObjWanwan, 7); +} + +void TMapObjWanwan::createEmitterOnGround(JPABaseEmitter **paEmitter, const char *pName) { + J3DFrameCtrl *ctrl = mAnmCtrl->getFrameCtrl(0); + if (ctrl->getFrame() != 4.0f) return; + + CrsGround ground(RCMGetCourse()); + ground.search(mPos); + if (ground.getMaterial() != CrsGround::Mat_1) return; + + *paEmitter = GetJPAMgr()->createEmt(pName, mPos); + if (*paEmitter) { + JGeometry::TVec3f scale(mScale); + (*paEmitter)->setGlobalScale(scale); + } +} + +#include "JSystem/JAudio/JASFakeMatch2.h" diff --git a/src/Shiraiwa/MapObjWanwanChain.cpp b/src/Shiraiwa/MapObjWanwanChain.cpp index e69de29b..4db5deba 100644 --- a/src/Shiraiwa/MapObjWanwanChain.cpp +++ b/src/Shiraiwa/MapObjWanwanChain.cpp @@ -0,0 +1,60 @@ +#include "Sato/GeographyObj.h" +#include "Sato/ObjUtility.h" +#include "Shiraiwa/Objects/MapObjWanwan.h" + +#include "JSystem/JAudio/JASFakeMatch2.h" + +f32 TMapObjWanwanChain::sChainOneLength = 120.0f; + +TMapObjWanwanChain::TMapObjWanwanChain() : GeographyObj(0xe79) { + GeographyObj::setObjFlagSimpleDraw(); + GeographyObj::NewAnmCtrl(); +} + +TMapObjWanwanChain::~TMapObjWanwanChain() {} + +void TMapObjWanwanChain::reset() { + GeographyObj::resetObject(); + GeographyObj::clrObjFlagCheckGeoHitting(); + GeographyObj::clrObjFlagCheckItemHitting(); + GeographyObj::clrAllCheckKartHitFlag(); + _58 = 0; +} + +void TMapObjWanwanChain::createColModel(J3DModelData *) {} + +const char *TMapObjWanwanChain::getBmdFileName() { + static const char *cBmdName = "/Item/wanwan_chn.bmd"; + return cBmdName; +} + +void TMapObjWanwanChain::setCurrentViewNo(u32 viewNo) { + mModel.setCurrentViewNo(viewNo); + Mtx m; + ObjUtility::getCamDependLightMtx(viewNo, mPos, m); + mModel.setEffectMtx(m, 0); +} + +TMapObjWanwanPile::TMapObjWanwanPile() : GeographyObj(0xe7a) { + GeographyObj::setObjFlagSimpleDraw(); + GeographyObj::NewAnmCtrl(); +} + +TMapObjWanwanPile::~TMapObjWanwanPile() {} + +void TMapObjWanwanPile::doKartColCallBack(int) {} + +void TMapObjWanwanPile::reset() { + GeographyObj::resetObject(); + GeographyObj::clrObjFlagCheckGeoHitting(); + GeographyObj::clrObjFlagCheckItemHitting(); + GeographyObj::clrAllCheckKartHitFlag(); + _58 = 0; +} + +void TMapObjWanwanPile::createColModel(J3DModelData *) {} + +const char *TMapObjWanwanPile::getBmdFileName() { + static const char *cBmdName = "/Objects/Wanwan1Pile.bmd"; + return cBmdName; +}