diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index aae9a997..dd364038 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -14105,19 +14105,20 @@ __dt__27sFState_c<14dAcBoomerang_c>Fv = .text:0x80260F70; // type:function size: __dt__30sFStateFct_c<14dAcBoomerang_c>Fv = .text:0x80260FD0; // type:function size:0x6C __dt__83sStateMgr_c<14dAcBoomerang_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80261040; // type:function size:0xA0 __dt__53sFStateMgr_c<14dAcBoomerang_c,20sStateMethodUsr_FI_c>Fv = .text:0x802610E0; // type:function size:0xA4 -areaCallback__FP12dAcObjBase_cP7mVec3_cUl = .text:0x80261190; // type:function size:0x18 +dAcBoomerang_areaCallback__FP12dAcObjBase_cP7mVec3_cUl = .text:0x80261190; // type:function size:0x10 +areaCallback__14dAcBoomerang_cFP7mVec3_cUl = .text:0x802611A0; // type:function size:0x8 atHitCallback__14dAcBoomerang_cFP8cCcD_ObjP12dAcObjBase_cP8cCcD_Obj = .text:0x802611B0; // type:function size:0x290 -fn_80261440 = .text:0x80261440; // type:function size:0x10 +changeState__83sStateMgr_c<14dAcBoomerang_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x80261440; // type:function size:0x10 dAcBoomerang_atHitCallback__FP12dAcObjBase_cP8cCcD_ObjP12dAcObjBase_cP8cCcD_Obj = .text:0x80261450; // type:function size:0x24 -AcBoomerang__assignBeetleModel = .text:0x80261480; // type:function size:0x5C -AcBoomerang__initModels = .text:0x802614E0; // type:function size:0x310 -AcBoomerang__init = .text:0x802617F0; // type:function size:0x208 -AcBoomerang__dtor = .text:0x80261A00; // type:function size:0x1AC -fn_80261BB0 = .text:0x80261BB0; // type:function size:0x70 -fn_80261C20 = .text:0x80261C20; // type:function size:0x88 -fn_80261CB0 = .text:0x80261CB0; // type:function size:0x8 -fn_80261CC0 = .text:0x80261CC0; // type:function size:0x68 -fn_80261D30 = .text:0x80261D30; // type:function size:0xDC +hideModel__14dAcBoomerang_cFQ214dAcBoomerang_c11ModelType_e = .text:0x80261480; // type:function size:0x5C +createHeap__14dAcBoomerang_cFv = .text:0x802614E0; // type:function size:0x310 +create__14dAcBoomerang_cFv = .text:0x802617F0; // type:function size:0x208 +__dt__14dAcBoomerang_cFv = .text:0x80261A00; // type:function size:0x1AC +deleteReady__14dAcBoomerang_cFv = .text:0x80261BB0; // type:function size:0x70 +retrieve__14dAcBoomerang_cFv = .text:0x80261C20; // type:function size:0x88 +doDelete__14dAcBoomerang_cFv = .text:0x80261CB0; // type:function size:0x8 +setRoomId__14dAcBoomerang_cFv = .text:0x80261CC0; // type:function size:0x68 +placeOnArm__14dAcBoomerang_cFv = .text:0x80261D30; // type:function size:0xDC fn_80261E10 = .text:0x80261E10; // type:function size:0x338 fn_80262150 = .text:0x80262150; // type:function size:0x54 calcBeetleVelocity_y = .text:0x802621B0; // type:function size:0x12C @@ -14128,7 +14129,7 @@ fn_80262890 = .text:0x80262890; // type:function size:0x22C fn_80262AC0 = .text:0x80262AC0; // type:function size:0x120 fn_80262BE0 = .text:0x80262BE0; // type:function size:0x1E0 fn_80262DC0 = .text:0x80262DC0; // type:function size:0x13C -fn_80262F00 = .text:0x80262F00; // type:function size:0x2C +bonk__14dAcBoomerang_cFv = .text:0x80262F00; // type:function size:0x2C setChrAnimation__14dAcBoomerang_cFQ214dAcBoomerang_c14ChrAnimation_e = .text:0x80262F30; // type:function size:0x154 fn_80263090 = .text:0x80263090; // type:function size:0xE4 fn_80263180 = .text:0x80263180; // type:function size:0x50 @@ -14152,7 +14153,7 @@ fn_80264860 = .text:0x80264860; // type:function size:0x4 AcBoomerang__update = .text:0x80264870; // type:function size:0x45C fn_80264CD0 = .text:0x80264CD0; // type:function size:0x10 AcBoomerang__draw = .text:0x80264CE0; // type:function size:0x160 -fn_80264E40 = .text:0x80264E40; // type:function size:0x88 +create__18dAcBoomerangProc_cFPQ23m3d5mdl_c6mColoriP12mAllocator_c = .text:0x80264E40; // type:function size:0x88 fn_80264ED0 = .text:0x80264ED0; // type:function size:0x80 fn_80264F50 = .text:0x80264F50; // type:function size:0x60 fn_80264FB0 = .text:0x80264FB0; // type:function size:0xC @@ -18943,7 +18944,7 @@ AdjustHitPos__10cCcD_ObjTgFff = .text:0x8032BB00; // type:function size:0x34 __ct__10cCcD_ObjCoFv = .text:0x8032BB40; // type:function size:0x48 __dt__10cCcD_ObjCoFv = .text:0x8032BB90; // type:function size:0x58 Set__10cCcD_ObjCoFRC14cCcD_SrcGObjCo = .text:0x8032BBF0; // type:function size:0x18 -SetCoFlag__10cCcD_ObjCoFUl = .text:0x8032BC10; // type:function size:0x1C +SetGrp__10cCcD_ObjCoFUl = .text:0x8032BC10; // type:function size:0x1C AdjustHitPos__10cCcD_ObjCoFff = .text:0x8032BC30; // type:function size:0x4 __sinit_\c_cc_d_cpp = .text:0x8032BC40; // type:function size:0x2C scope:local @44@__dt__12cCcD_UnkAttrFv = .text:0x8032BC70; // type:function size:0x8 diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index e293b927..550adccb 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -31,7 +31,7 @@ struct SoundSource { SOUNDSOURCE_VIRTUAL(0x34); SOUNDSOURCE_VIRTUAL(0x38); SOUNDSOURCE_VIRTUAL(0x3C); - SOUNDSOURCE_VIRTUAL(0x40); + virtual void vt_0x40(s32); SOUNDSOURCE_VIRTUAL(0x44); virtual bool shutdown(); // 0x48 SOUNDSOURCE_VIRTUAL(0x4C); diff --git a/include/d/a/d_a_player.h b/include/d/a/d_a_player.h index 324e27bf..fd753989 100644 --- a/include/d/a/d_a_player.h +++ b/include/d/a/d_a_player.h @@ -5,6 +5,7 @@ #include "d/a/d_a_item.h" #include "d/col/c/c_bg_s_poly_info.h" #include "d/d_player_mdl.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/file_manager.h" #include "toBeSorted/minigame_mgr.h" @@ -29,9 +30,15 @@ public: /* vt 0x318 */ virtual void vt_0x318(); protected: - /* 0x137C */ u8 _0x137C[0x4564 - 0x137C]; + /* 0x137C */ u8 _0x137C[0x16F0 - 0x137C]; + /* 0x16F0 */ nw4r::g3d::ResFile mHeldResFile; + /* 0x16F4 */ u8 _0x16F4[0x4564 - 0x16F4]; /* 0x4564 */ f32 field_0x4564; +public: + // Beetle Functions [0x8021AA70 - 0x8021BE20] + f32 getBeetleRadius(); + public: f32 getField_0x4564() const { return field_0x4564; @@ -44,6 +51,9 @@ public: nw4r::g3d::ResFile getSwordResFile() const { return mSwordRes; } + nw4r::g3d::ResFile getHeldResFile() const { + return mHeldResFile; + } inline bool hasvt_0x1C0() const { return vt_0x1C0() != nullptr; diff --git a/include/d/a/obj/d_a_obj_boomerang.h b/include/d/a/obj/d_a_obj_boomerang.h index 3b2a6261..0b3ad479 100644 --- a/include/d/a/obj/d_a_obj_boomerang.h +++ b/include/d/a/obj/d_a_obj_boomerang.h @@ -5,30 +5,35 @@ #include "d/a/d_a_base.h" #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_s_acch.h" +#include "d/col/bg/d_bg_s_lin_chk.h" #include "d/col/cc/d_cc_d.h" #include "d/d_shadow.h" #include "d/lyt/d_lyt_fader.h" #include "m/m3d/m_anmchr.h" #include "m/m3d/m_anmchrblend.h" #include "m/m3d/m_mdl.h" -#include "m/m3d/m_proc.h" #include "m/m_color.h" +#include "m/m_fader.h" +#include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" +#include "rvl/GX/GXTypes.h" #include "s/s_State.hpp" #include "toBeSorted/actor_event.h" #include "toBeSorted/d_emitter.h" -class dAcBoomerangProcBase_c : public m3d::proc_c { -public: - ~dAcBoomerangProcBase_c() {} -}; -class dAcBoomerangProc_c : public dAcBoomerangProcBase_c { +class dAcBoomerangProc_c : public d3d::UnkProc { public: dAcBoomerangProc_c() : mColor0(0), mColor1(0xFFFFFFFF) {} ~dAcBoomerangProc_c() {} + bool create(m3d::mdl_c *mdl, mColor clr, int prioOpa, mAllocator_c *alloc); + bool create2(m3d::mdl_c *mdl, mColor clr, int prioOpa, mAllocator_c *alloc) { + return create(mdl, clr, prioOpa, alloc); + } + virtual void drawOpa() override; +private: mColor mColor0; mColor mColor1; }; @@ -60,6 +65,14 @@ public: STATE_FUNC_DECLARE(dAcBoomerang_c, EventReturnWait); public: // TYPES + enum Variant_e { + NONE, + BEETLE, + HOOK_BEETLE, + QUICK_BEETLE, + TOUGH_BEETLE, + }; + struct ChrAnimation_t { const char *mName; f32 mRate; @@ -75,22 +88,66 @@ public: // TYPES }; static const ChrAnimation_t sChrAnims[RB_MAX]; + enum ModelType_e { + MDL_WINGS_BASIC = 0, + MDL_BODY_BASIC = 1, + MDL_MOUTH_BASIC = 2, + MDL_MOUTH_HOOK = 3, + MDL_MOTTH_ADV = MDL_MOUTH_HOOK, // Just for naming :P + MDL_BODY_ADV = 4, + MDL_WINGS_ADV = 5, + }; + + // Macros until enum is solidified +#define FLAG_BOOMERANG_CANCEL (0x3) +#define FLAG_BOOMERANG_RUMBLE_ACTIVE (0x4000) + public: // INLINES - bool checkField_0x8CC(u32 mask) { + bool checkField_0x8CC(u32 mask) const { return field_0x8CC & mask; } + void onField_0x8CC(u32 mask) { + field_0x8CC |= mask; + } + bool isMoving() { + return mStateMgr.isState(StateID_Move); + } public: // FUNCTIONS + void areaCallback(mVec3_c *param1, u32 param2); void atHitCallback(cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, cCcD_Obj *i_objInfB); + /** hides the given shape within the resfile. Ref Brawlcrate's 'polygon#' in the mdl0/Object folder */ + void hideModel(ModelType_e type); + + /** ?? */ + void deleteCheck(); + + /** ?? Retrieve Beetle */ + void retrieve(); + + /** Attempts to grab ahold of the object upon collision. Called from atHitCallback if type > Hook beetle */ bool tryGrabObject(dAcObjBase_c *pObject); + + /** Sets the room id of the beetle. Sets to links room id or the room id of the collision its around */ + void setRoomId(); + + /** Updates the position based on where links wrist is */ + void placeOnArm(); + + /** Sets the assuming bonk flag and plays the rumble feedback */ + void bonk(); + + /** Applies the selected animation to the beetle */ void setChrAnimation(ChrAnimation_e requestedAnimation); private: /* 0x0330 */ nw4r::g3d::ResFile mResFile; /* 0x0334 */ m3d::mdl_c mMdl; /* 0x0358 */ m3d::anmChrBlend_c mAnmChrBlend; - /* 0x0380 */ m3d::anmChr_c mAnmChr[2]; +#define BOOMERANG_ANIM_PINCERS (0) +#define BOOMERANG_ANIM_WINGS (1) + /* 0x0380 */ m3d::anmChr_c mAnmChr[2]; /* 0 - Pincers, 1 - Wings*/ /* 0x03F0 */ dAcBoomerangProc_c mProc; /* 0x0410 */ dShadowCircle_c mShadow; /* 0x0418 */ dAcRef_c mGrabbedActor; @@ -105,7 +162,9 @@ private: /* 0x08B7 */ u8 mRightWingNodeID; /* 0x08B8 */ u8 _0x8B8[0x8CC - 0x8B8]; /* 0x08B8 */ u32 field_0x8CC; - /* 0x08D0 */ u8 _0x8D0[0x8FC - 0x8D0]; + /* 0x08D0 */ u8 _0x8D0[0x8D8 - 0x8D0]; + /* 0x08D8 */ mVec3_c field_0x8D8; + /* 0x08E4 */ u8 _0x8E4[0x8FC - 0x8E4]; /* 0x08FC */ dCcD_Sph mSph0; /* 0x0A4C */ dCcD_Sph mSph1; /* 0x0B9C */ EffectsStruct mEff0; @@ -113,8 +172,13 @@ private: /* 0x0C04 */ EffectsStruct mEff2; /* 0x0C38 */ EffectsStruct mEff3; /* 0x0C6C */ dLytFader_c mLytFader; - /* 0x114C */ u8 _0x114C[0x115C - 0x114C]; + /* 0x114C */ mFader_c mFader; + /* 0x1150 */ u8 _0x1150[0x115C - 0x1150]; /* 0x115C */ STATE_MGR_DECLARE(dAcBoomerang_c); + + static dCcD_SrcSph sSphSrc; + static dBgS_BeetleLinChk sLinChk; + static const u32 sSrcAtType; }; #endif diff --git a/include/d/col/bg/d_bg_s_acch.h b/include/d/col/bg/d_bg_s_acch.h index 6682fac3..ef546f23 100644 --- a/include/d/col/bg/d_bg_s_acch.h +++ b/include/d/col/bg/d_bg_s_acch.h @@ -146,6 +146,7 @@ public: /* 0x 0800 0000 */ ACCH_FLAG_0x8000000 = (1 << 27), /* 0x 1000 0000 */ ACCH_FLAG_0x10000000 = (1 << 28), /* 0x 2000 0000 */ ACCH_FLAG_0x20000000 = (1 << 29), + /* 0x 4000 0000 */ ACCH_FLAG_0x40000000 = (1 << 30), /* 0x 8000 0000 */ ACCH_FLAG_0x80000000 = (1 << 31), }; @@ -314,6 +315,12 @@ public: return mFlags & ACCH_FLAG_0x10000000; } + void ClrLineDown() { + mFlags &= ~LINE_DOWN; + } + void SetLineDown() { + mFlags |= LINE_DOWN; + } void Clr_0x20000() { mFlags &= ~ACCH_FLAG_0x20000; } @@ -323,6 +330,15 @@ public: bool Chk_0x20000() { return mFlags & ACCH_FLAG_0x20000; } + void Clr_0x40000000() { + mFlags &= ~ACCH_FLAG_0x40000000; + } + void Set_0x40000000() { + mFlags |= ACCH_FLAG_0x40000000; + } + bool Chk_0x40000000() { + return mFlags & ACCH_FLAG_0x40000000; + } void Clr_0x80000000() { mFlags &= ~ACCH_FLAG_0x80000000; } @@ -506,6 +522,14 @@ public: return mGnd; } + dBgS_RoofChk &GetRoof() { + return mRoof; + } + + void SetField_0xD4(f32 v) { + mField_0x0D4 = v; + } + public: /* 0x040 */ u32 mFlags; /* 0x044 */ mVec3_c *mpPos; diff --git a/include/d/col/bg/d_bg_s_roof_chk.h b/include/d/col/bg/d_bg_s_roof_chk.h index 214cef0b..0e012dd1 100644 --- a/include/d/col/bg/d_bg_s_roof_chk.h +++ b/include/d/col/bg/d_bg_s_roof_chk.h @@ -23,6 +23,10 @@ public: void SetPos(mVec3_c const *); + void SetField_0x7C(u8 param0) { + mField_0x7C = param0; + } + void SetNowY(f32 y) { mNowY = y; } diff --git a/include/d/col/c/c_bg_s_lin_chk.h b/include/d/col/c/c_bg_s_lin_chk.h index 4d5e8141..e3cafb41 100644 --- a/include/d/col/c/c_bg_s_lin_chk.h +++ b/include/d/col/c/c_bg_s_lin_chk.h @@ -50,6 +50,9 @@ public: bool GetPreGroundChk() const { return mPreGroundChk; } + void SetPreRoofChk(bool b) { + mPreRoofChk = b; + } bool GetPreRoofChk() const { return mPreRoofChk; } diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index d3a0cf5a..975c2b36 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -338,7 +338,7 @@ enum dCcD_ObjAtType { /* 0x 0000 0008 */ AT_TYPE_PHYSICS = (1 << 3), /* 0x 0000 0010 */ AT_TYPE_0x10 = (1 << 4), /* 0x 0000 0020 */ AT_TYPE_BOMB = (1 << 5), - /* 0x 0000 0040 */ AT_TYPE_0x40 = (1 << 6), + /* 0x 0000 0040 */ AT_TYPE_0x40 = (1 << 6), // Used in Beetle /* 0x 0000 0080 */ AT_TYPE_SLINGSHOT = (1 << 7), /* 0x 0000 0100 */ AT_TYPE_0x100 = (1 << 8), /* 0x 0000 0200 */ AT_TYPE_WIND = (1 << 9), @@ -686,7 +686,7 @@ public: cCcD_ObjCo(); virtual ~cCcD_ObjCo(); void Set(const cCcD_SrcGObjCo &); - void SetCoFlag(u32); + void SetGrp(u32); void AdjustHitPos(f32, f32); void ClrSet() { @@ -815,6 +815,9 @@ public: mCo.OnSPrm(f); } + void SetAtType(u32 type) { + mAt.SetType(type); + } void SetTgType(u32 type) { mTg.SetType(type); } @@ -932,6 +935,11 @@ public: void OnAt_0x40() { mAt.OnSPrm(0x40); } + // Related to Beetle (no hook) + void OnAt_0x4000() { + mAt.OnSPrm(0x4000); + } + void SetAtDamage(u8 amount) { @@ -967,6 +975,9 @@ public: void ClrTgElectric() { return mTg.OffSPrm(0x40000); } + u32 ChkTgBonk() const { + return mTg.MskSPrm(0x200000); + } void OnTg_0x200000() { mTg.OnSPrm(0x200000); @@ -990,6 +1001,9 @@ public: // Co + void SetCoGrp(u32 grp) { + mCo.SetGrp(grp << 4); + } void OnCoSet() { mCo.OnSPrm(1); } diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index a490da69..6214a749 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -584,6 +584,13 @@ public: return mCurrentAction == 0xAD || mCurrentAction == 0xAE; } + void onModelUpdateFlag(u32 mask) { + mModelUpdateFlags |= mask; + } + void offModelUpdateFlag(u32 mask) { + mModelUpdateFlags &= ~mask; + } + inline bool checkActionFlags(u32 mask) const { return (mActionFlags & mask) != 0; } diff --git a/include/m/m3d/m_anmchr.h b/include/m/m3d/m_anmchr.h index 2ff01dd7..02bef1ca 100644 --- a/include/m/m3d/m_anmchr.h +++ b/include/m/m3d/m_anmchr.h @@ -4,6 +4,7 @@ #include "common.h" #include "m/m3d/m_bmdl.h" #include "m/m3d/m_fanm.h" +#include "nw4r/g3d/g3d_anmchr.h" #include "nw4r/g3d/res/g3d_resanmchr.h" namespace m3d { diff --git a/include/m/m3d/m_mdl.h b/include/m/m3d/m_mdl.h index a0833038..90ec1ea2 100644 --- a/include/m/m3d/m_mdl.h +++ b/include/m/m3d/m_mdl.h @@ -1,6 +1,7 @@ #ifndef M3D_M_MDL_H #define M3D_M_MDL_H +#include "common.h" #include "m/m3d/m_banm.h" #include "m/m3d/m_calc_ratio.h" #include "m/m3d/m_smdl.h" @@ -59,6 +60,9 @@ public: virtual ~mdl_c(); bool create(nw4r::g3d::ResMdl, mAllocator_c *, u32, int, u32 *); + bool create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u32 flag, int num) { + return create(mdl, alloc, flag, num, nullptr); + } bool create(nw4r::g3d::ResMdl, mdlCallback_c *cb, mAllocator_c *, u32, int, u32 *); virtual void remove() override; diff --git a/include/m/m_fader.h b/include/m/m_fader.h index 2d8c1189..afa508d7 100644 --- a/include/m/m_fader.h +++ b/include/m/m_fader.h @@ -28,9 +28,16 @@ public: mpFader->setStatus(status); } + void fadeIn() { + mpFader->fadeIn(); + } bool calc() { return mpFader->calc(); } + void setFrame(u16 frame) { + mpFader->setFrame(frame); + } + protected: mFaderBase_c *mpFader; }; diff --git a/include/m/m_vec.h b/include/m/m_vec.h index 0fb52aea..0a8cf706 100644 --- a/include/m/m_vec.h +++ b/include/m/m_vec.h @@ -216,7 +216,7 @@ public: return x != v.x || y != v.y || z != v.z; } - void normalize(); + f32 normalize(); bool normalizeRS(); static mVec3_c createProjectionXZ(const mAng3_c &ang, f32 scalar); diff --git a/src/d/a/obj/d_a_obj_boomerang.cpp b/src/d/a/obj/d_a_obj_boomerang.cpp index 23d8e695..5ceb5ff8 100644 --- a/src/d/a/obj/d_a_obj_boomerang.cpp +++ b/src/d/a/obj/d_a_obj_boomerang.cpp @@ -1,13 +1,25 @@ #include "d/a/obj/d_a_obj_boomerang.h" +#include "c/c_math.h" #include "common.h" #include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/col/c/c_cc_d.h" +#include "d/d_rumble.h" +#include "f/f_base.h" #include "f/f_profile_name.h" +#include "m/m3d/m_anmchr.h" #include "m/m3d/m_fanm.h" +#include "m/m_color.h" +#include "m/m_fader_base.h" +#include "m/m_mtx.h" #include "nw4r/g3d/g3d_anmchr.h" +#include "nw4r/g3d/res/g3d_resanmchr.h" #include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resshp.h" #include "s/s_State.hpp" +#include "toBeSorted/small_sound_mgr.h" SPECIAL_ACTOR_PROFILE(BOOMERANG, dAcBoomerang_c, fProfile::BOOMERANG, 0x125, 0, 0x4); @@ -17,36 +29,30 @@ STATE_DEFINE(dAcBoomerang_c, MoveCancelWait); STATE_DEFINE(dAcBoomerang_c, ReturnWait); STATE_DEFINE(dAcBoomerang_c, EventReturnWait); -const dAcBoomerang_c::ChrAnimation_t dAcBoomerang_c::sChrAnims[dAcBoomerang_c::RB_MAX] = { - { "RB_Set", 0.f}, - {"RB_Default", 3.f}, - { "RB_Cut", 3.f}, - { "RB_Hold", 3.f}, - {"RB_Hold_ed", 3.f}, - { "RB_Back", 3.f}, -}; - -void areaCallback(dAcObjBase_c *param0, mVec3_c *param1, u32 param2) { - if (param2 != 0) { - return; +void dAcBoomerang_areaCallback(dAcObjBase_c *param0, mVec3_c *param1, u32 param2) { + if (param2 == 0) { + static_cast(param0)->areaCallback(param1, param2); } + return; +} +// This function is odd. only called by the areaCallback +void dAcBoomerang_c::areaCallback(mVec3_c *param1, u32 param2) { + setChrAnimation(dAcBoomerang_c::RB_CUT); } - void dAcBoomerang_c::atHitCallback(cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, cCcD_Obj *i_objInfB) { - if (i_actorB != nullptr && GetLinkage().checkFlag(0x80)) { - if (dAcPy_c::getCurrentBeetleType() > 2) { - if (i_actorB == mGrabbedActor.get()) { - return; - } - - if (!mStateMgr.isState(StateID_Move)) { + if (i_actorB != nullptr && i_actorB->GetLinkage().checkFlag(0x80)) { + // Check if beetle can grab things + if ((s32)(dAcPy_c::getCurrentBeetleType() >= HOOK_BEETLE) != FALSE) { + // If beetle is already holding the object or is stationary + if (i_actorB == mGrabbedActor.get() || !mStateMgr.isState(StateID_Move)) { return; } + // Try grabbing the object if (tryGrabObject(i_actorB)) { setChrAnimation(RB_HOLD); - mAnmChr[0].setRate(0.f); - mAnmChr[0].setFrameOnly(i_actorB->GetLinkage().field_0x24); + mAnmChr[BOOMERANG_ANIM_PINCERS].setRate(0.f); + mAnmChr[BOOMERANG_ANIM_PINCERS].setFrameOnly(i_actorB->GetLinkage().field_0x24); return; } } @@ -56,8 +62,26 @@ void dAcBoomerang_c::atHitCallback(cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, return; } - if (i_objInfB->ChkTgBit23()) { + if (!i_objInfB->ChkTgBonk()) { + field_0x8D8 = position - i_actorB->position; + field_0x8D8.y = 0.f; + + if (cM::isZero(field_0x8D8.normalize())) { + field_0x8D8.set(-angle.y.sin(), 0.f, -angle.y.cos()); + } + field_0x8D8 *= velocity.absXZ(); + field_0x8D8.y = -velocity.y; + + field_0x8D8.normalize(); + + onField_0x8CC(FLAG_BOOMERANG_CANCEL); + mStateMgr.changeState(StateID_MoveCancelWait); + } else { + // Play the animation to move the pincers setChrAnimation(RB_CUT); + + // I think this plays the vibration and drops the object + bonk(); } } @@ -68,6 +92,183 @@ bool dAcBoomerang_atHitCallback( return true; } +void dAcBoomerang_c::hideModel(dAcBoomerang_c::ModelType_e type) { + // Implicity ModelType_e -> int conversion + nw4r::g3d::ResShp obj(mMdl.getResMdl().GetResShp(type)); + obj.SetVisibility(false); + obj.DCStore(false); +} + +bool dAcBoomerang_c::createHeap() { + mResFile = dAcPy_c::GetLink2()->getHeldResFile(); + nw4r::g3d::ResMdl mdl = mResFile.GetResMdl("EquipBeetle"); + + TRY_CREATE(mMdl.create(mdl, &heap_allocator, 0x120, 1)); + + // Decide the Pincers + if ((s32)(dAcPy_c::getCurrentBeetleType() >= HOOK_BEETLE) != FALSE) { + hideModel(MDL_MOUTH_BASIC); + } else { + hideModel(MDL_MOUTH_HOOK); + } + + // Decide the Body + if ((s32)(dAcPy_c::getCurrentBeetleType() >= TOUGH_BEETLE) != FALSE) { + hideModel(MDL_BODY_BASIC); + } else { + hideModel(MDL_BODY_ADV); + } + + // Decide the Wings + if ((s32)(dAcPy_c::getCurrentBeetleType() >= QUICK_BEETLE) != FALSE) { + hideModel(MDL_WINGS_BASIC); + } else { + hideModel(MDL_WINGS_ADV); + } + + mLeftWingNodeID = mdl.GetResNode("wing_L").GetID(); + mRightWingNodeID = mdl.GetResNode("wing_R").GetID(); + + if (mLeftWingNodeID > mRightWingNodeID) { + mWindNodeID = mRightWingNodeID; + } else { + mWindNodeID = mLeftWingNodeID; + } + + TRY_CREATE(mAnmChrBlend.create(mdl, 2, &heap_allocator)); + + m3d::anmChr_c *pAnmChr = mAnmChr; + nw4r::g3d::AnmObjChr *pAnimChr; + nw4r::g3d::ResAnmChr resAnmChr = mResFile.GetResAnmChr("RB_Set"); + for (s32 i = 0; i < 2; ++i, ++pAnmChr) { + TRY_CREATE(pAnmChr->create2(mdl, resAnmChr, &heap_allocator)); + + pAnmChr->setAnm(mMdl, resAnmChr, m3d::PLAY_MODE_0); + if (i == BOOMERANG_ANIM_WINGS) { + pAnimChr = static_cast(pAnmChr->getAnimObj()); + pAnimChr->Release(); + pAnimChr->Bind(mdl, mLeftWingNodeID, nw4r::g3d::AnmObjChr::BIND_PARTIAL); + pAnimChr->Bind(mdl, mRightWingNodeID, nw4r::g3d::AnmObjChr::BIND_PARTIAL); + } + mAnmChrBlend.attach(i, pAnmChr, 1.f); + } + mMdl.setAnm(mAnmChrBlend); + TRY_CREATE(mProc.create2(&mMdl, mColor(0x00, 0x10, 0x14, 0xFF), 0x27, &heap_allocator)); + if (mLytFader.init()) { + return true; + } + return false; +} + +int dAcBoomerang_c::create() { + CREATE_ALLOCATOR(dAcBoomerang_c); + + mAcch.Set(this, 1, &mAcchCir); + mAcch.SetGroundUpY(20.f); + mAcch.SetField_0xD4(30.f); + mAcch.ClrRoofNone(); + mAcch.SetBeetle(); + mAcch.OnWaterGrp(); + mAcch.OnLineCheck(); + mAcch.GetRoof().SetField_0x7C(1); + mAcch.Set_0x2000000(); + mAcch.Set_0x40000000(); + mAcch.SetLineDown(); + + mAcchCir.SetWall(0.f, dAcPy_c::GetLink2()->getBeetleRadius()); + + mCurrentAnimation = RB_MAX; + mStateMgr.changeState(StateID_Wait); + + placeOnArm(); + + mStts.SetRank(3); + + mSph0.Set(sSphSrc); + mSph0.SetStts(mStts); + mSph0.SetAtCallback(dAcBoomerang_atHitCallback); + mSph0.ClrTgSet(); + + mSph1.Set(sSphSrc); + mSph1.SetStts(mStts); + mSph1.SetAtCallback(dAcBoomerang_atHitCallback); + mSph1.SetR(dAcPy_c::GetLink2()->getBeetleRadius()); + mSph1.ClrCoSet(); + mSph1.SetAtType(AT_TYPE_0x40); + + mSph1.SetCoGrp(0xE); + + if ((s32)(dAcPy_c::getCurrentBeetleType() >= HOOK_BEETLE) == FALSE) { + mSph0.OnAt_0x4000(); + mSph1.OnAt_0x4000(); + } + + sLinChk.SetPreRoofChk(false); + mAcch.CrrPos(*dBgS::GetInstance()); + setRoomId(); + mLytFader.setStatus(mFaderBase_c::FADED_IN); + mFader.setFader(&mLytFader); + + return SUCCEEDED; +} + +dAcBoomerang_c::~dAcBoomerang_c() { + deleteCheck(); +} + +void dAcBoomerang_c::deleteReady() { + deleteCheck(); + + if (getSoundSource()) { + getSoundSource()->vt_0x40(5); + } + + if (dAcPy_c::GetLink2()) { + dAcPy_c::GetLink2()->onModelUpdateFlag(0x10000000); + } +} + +void dAcBoomerang_c::retrieve() { + if (mFader.isStatus(mFaderBase_c::FADED_OUT)) { + mFader.setFrame(5); + mFader.fadeIn(); + playSound(SE_BE_COME_BACK); + } + mFader.calc(); +} + +int dAcBoomerang_c::doDelete() { + return SUCCEEDED; +} + +void dAcBoomerang_c::setRoomId() { + if (mAcch.GetGroundH() != 1e-9f) { + roomid = dBgS::GetInstance()->GetRoomId(mAcch.GetGnd()); + } else if (roomid == -1) { + roomid = dAcPy_c::GetLink2()->roomid; + } +} + +void dAcBoomerang_c::placeOnArm() { + dAcPy_c::GetLink2()->getBodyMtx(&mWorldMtx, dAcPy_c::PLAYER_MAIN_NODE_ARM_R2); + mMtx_c m; + m.transS(18.5f, 0.f, 14.5f); + mWorldMtx += m; + mWorldMtx.ZYXrotM(mAng::fromDeg(90.f), 0, mAng::fromDeg(90.f)); + mMdl.setLocalMtx(mWorldMtx); + mWorldMtx.getTranslation(position); + mWorldMtx.getTranslation(mOldPosition); +} + +const dAcBoomerang_c::ChrAnimation_t dAcBoomerang_c::sChrAnims[dAcBoomerang_c::RB_MAX] = { + { "RB_Set", 0.f}, + {"RB_Default", 3.f}, + { "RB_Cut", 3.f}, + { "RB_Hold", 3.f}, + {"RB_Hold_ed", 3.f}, + { "RB_Back", 3.f}, +}; + // ... bool dAcBoomerang_c::tryGrabObject(dAcObjBase_c *pObj) { @@ -77,19 +278,29 @@ bool dAcBoomerang_c::tryGrabObject(dAcObjBase_c *pObj) { // ... +void dAcBoomerang_c::bonk() { + if (checkField_0x8CC(FLAG_BOOMERANG_RUMBLE_ACTIVE)) { + return; + } + onField_0x8CC(FLAG_BOOMERANG_RUMBLE_ACTIVE); + dRumble_c::start(dRumble_c::sRumblePreset1, 1); +} + void dAcBoomerang_c::setChrAnimation(dAcBoomerang_c::ChrAnimation_e requestedAnimation) { // Do not set anim if there is no change, or the request is to cut from hold if (requestedAnimation == mCurrentAnimation || (mCurrentAnimation == RB_HOLD && requestedAnimation == RB_CUT)) { return; } - mAnmChr[0].setAnm(mMdl, mResFile.GetResAnmChr(sChrAnims[requestedAnimation].mName), m3d::PLAY_MODE_4); - nw4r::g3d::AnmObjChr *pAnmObj = static_cast(mAnmChr[0].getAnimObj()); + mAnmChr[BOOMERANG_ANIM_PINCERS].setAnm( + mMdl, mResFile.GetResAnmChr(sChrAnims[requestedAnimation].mName), m3d::PLAY_MODE_4 + ); + nw4r::g3d::AnmObjChr *pAnmObj = static_cast(mAnmChr[BOOMERANG_ANIM_PINCERS].getAnimObj()); pAnmObj->Release(); nw4r::g3d::ResMdl mdl = mMdl.getResMdl(); - for (int i = 0; i < mWindNodeID; ++i) { + for (s32 i = 0; i < mWindNodeID; ++i) { pAnmObj->Bind(mdl, i, nw4r::g3d::AnmObjChr::BIND_ONE); } @@ -102,3 +313,7 @@ void dAcBoomerang_c::setChrAnimation(dAcBoomerang_c::ChrAnimation_e requestedAni mMdl.setAnm(mAnmChrBlend, sChrAnims[requestedAnimation].mRate); } + +// ... + +bool dAcBoomerangProc_c::create(m3d::mdl_c *mdl, mColor clr, int prioOpa, mAllocator_c *alloc) {} diff --git a/src/d/col/c/c_cc_d.cpp b/src/d/col/c/c_cc_d.cpp index f8669ee6..e6f58d49 100644 --- a/src/d/col/c/c_cc_d.cpp +++ b/src/d/col/c/c_cc_d.cpp @@ -14,9 +14,10 @@ #include "m/m_mtx.h" #include "m/m_vec.h" #include "nw4r/types_nw4r.h" -#include "rvl/MTX.h" // IWYU pragma: export #include "s/s_Math.h" +#include "rvl/MTX.h" // IWYU pragma: export + static inline void MtxTransMinusXYZ(mMtx_c &mtx, f32 x, f32 y, f32 z) { PSMTXTrans(mtx, -x, -y, -z); } @@ -1448,8 +1449,14 @@ void cCcD_ObjAt::AdjustHitPos(f32 x, f32 z) { } cCcD_ObjTg::cCcD_ObjTg() - : mShieldFrontRangeYAngle(nullptr), mField_0x4A(0), mField_0x4B(0), mField_0x4C(0), mField_0x50(0), mField_0x54(0), - mField_0x6C(0.f, 0.f, 0.f), mField_0x78(0) {} + : mShieldFrontRangeYAngle(nullptr), + mField_0x4A(0), + mField_0x4B(0), + mField_0x4C(0), + mField_0x50(0), + mField_0x54(0), + mField_0x6C(0.f, 0.f, 0.f), + mField_0x78(0) {} cCcD_ObjTg::~cCcD_ObjTg() {} @@ -1480,10 +1487,10 @@ cCcD_ObjCo::~cCcD_ObjCo() {} void cCcD_ObjCo::Set(const cCcD_SrcGObjCo &src) { mEffCounter = 0; mSrc = src; - SetCoFlag(mSrc.mSPrm & 0x1e0); + SetGrp(mSrc.mSPrm & 0x1e0); } -void cCcD_ObjCo::SetCoFlag(u32 flag) { +void cCcD_ObjCo::SetGrp(u32 flag) { mSrc.mSPrm = mSrc.mSPrm & ~0x1E0 | flag; mGrp = (mSrc.mSPrm & 0x1E0) >> 4; }