#ifndef D_A_OBJ_BOOMERANG_H #define D_A_OBJ_BOOMERANG_H #include "common.h" #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/m_color.h" #include "m/m_fader.h" #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "toBeSorted/actor_event.h" #include "toBeSorted/d_emitter.h" class dAcBoomerangProc_c : public d3d::UnkProc { public: dAcBoomerangProc_c() : mpMdl(nullptr), mClr(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: m3d::mdl_c *mpMdl; mColor mClr; }; class dAcBoomerang_c : public dAcObjBase_c { public: dAcBoomerang_c() : mStateMgr(*this), mEventRelated(*this, nullptr), mEff0(this), mEff1(this), mEff2(this), mEff3(this), mLytFader(0, dLytFader_c::FADED_OUT) {} virtual ~dAcBoomerang_c(); virtual int create() override; virtual int doDelete() override; virtual int draw() override; virtual void deleteReady() override; virtual bool createHeap() override; virtual int actorExecute() override; virtual void registerInEvent() override; STATE_FUNC_DECLARE(dAcBoomerang_c, Wait); STATE_FUNC_DECLARE(dAcBoomerang_c, Move); STATE_FUNC_DECLARE(dAcBoomerang_c, MoveCancelWait); STATE_FUNC_DECLARE(dAcBoomerang_c, ReturnWait); 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; }; enum ChrAnimation_e { RB_SET = 0, RB_DEFAULT = 1, RB_CUT = 2, RB_HOLD = 3, RB_HOLD_ED = 4, RB_BACK = 5, RB_MAX, }; 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, }; struct FlyChrAnimation_t { const char *mName; }; enum FlyAnimation_e { RB_FLY = 0, RB_FLY_FAST = 1, RB_FLY_MAX = 2, }; static const char *sFlyChrAnims[RB_FLY_MAX]; enum Flags_e { /* 0x00000001 */ FLAG_CANCEL_1 = 1 << 0, /* 0x00000002 */ FLAG_CANCEL_2 = 1 << 1, /* 0x00000003 */ FLAG_CANCEL = FLAG_CANCEL_1 | FLAG_CANCEL_2, /* 0x00000004 */ FLAG_RELEASE_ITEM = 1 << 2, /* 0x00000008 */ FLAG_0x8 = (0x8), /* 0x00000010 */ FLAG_0x10 = (0x10), /* 0x00000020 */ FLAG_0x20 = (0x20), /* 0x00000040 */ FLAG_0x40 = (0x40), /* 0x00000080 */ FLAG_0x80 = (0x80), /* 0x00000100 */ FLAG_STOP_TIMER_ACTIVE = (0x100), /* 0x00000200 */ FLAG_DROP_ITEM = (0x200), // related to 0x400 /* 0x00000400 */ FLAG_REQUEST_0x400 = (0x400), // related to 0x200 /* 0x00000800 */ FLAG_REQUEST_MOVE = (0x800), /* 0x00001000 */ FLAG_CONTROLLABLE = (0x1000), /* 0x00002000 */ FLAG_0x2000 = (0x2000), /* 0x00004000 */ FLAG_RUMBLE_ACTIVE = (0x4000), /* 0x00008000 */ FLAG_WING_EFFECT_ACTIVE = (0x8000), /* 0x00010000 */ FLAG_0x10000 = (0x10000), /* 0x00020000 */ FLAG_0x20000 = (0x40000), /* 0x00040000 */ FLAG_0x40000 = (0x40000), /* 0x00080000 */ FLAG_0x80000 = (0x80000), /* 0x0001A117 */ FLAG_COMMON_INIT = FLAG_0x10000 | FLAG_WING_EFFECT_ACTIVE | FLAG_0x2000 | FLAG_STOP_TIMER_ACTIVE | FLAG_0x10 | FLAG_RELEASE_ITEM | FLAG_CANCEL, }; public: // INLINES bool checkField_0x8CC(u32 mask) const { return field_0x8CC & mask; } void setField_0x8CC(u32 mask) { field_0x8CC |= mask; } void unsetField_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); /** Applies the selected animation to the beetle */ void setFlyChrAnimation(FlyAnimation_e requestedAnimation); /** Sets the amount of time the beetle can fly. Setting a number less than 0 gives it 5s of time */ void setRemainingFlightTime(s16 time); /** Attempts to flash the beetle red at end of flight */ void executeTimeWarning(); private: /* 0x0330 */ nw4r::g3d::ResFile mResFile; /* 0x0334 */ m3d::mdl_c mMdl; /* 0x0358 */ m3d::anmChrBlend_c mAnmChrBlend; #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; /* 0x0424 */ u8 _0x424[0x454 - 0x424]; /* 0x0454 */ dBgS_Acch mAcch; /* 0x0804 */ dBgS_AcchCir mAcchCir; /* 0x0860 */ ActorEventRelated mEventRelated; /* 0x08B0 */ u8 mCurrentAnimation; /* 0x08B1 */ u8 field_0x8B1; /* 0x08B2 */ u8 field_0x8B2; /* 0x08B3 */ u8 mFlashTimer; /* 0x08B4 */ u8 field_0x8B4; /* 0x08B5 */ u8 mWindNodeID; /* 0x08B6 */ u8 mLeftWingNodeID; /* 0x08B7 */ u8 mRightWingNodeID; /* 0x08B8 */ mAng field_0x8B8; /* 0x08BA */ mAng field_0x8BA; /* 0x08BC */ mAng field_0x8BC; /* 0x08BE */ mAng field_0x8BE; /* 0x08C0 */ u8 _0x8C0[0x8C8 - 0x8C0]; /* 0x08CA */ mAng field_0x8C8; /* 0x08CA */ u16 mRemainingFlightTime; /* 0x08CC */ u32 field_0x8CC; /* 0x08D0 */ f32 field_0x8D0; /* 0x08D4 */ f32 field_0x8D4; /* 0x08D8 */ mVec3_c field_0x8D8; /* 0x08E4 */ mVec3_c field_0x8E4; /* 0x08F0 */ mVec3_c field_0x8F0; /* 0x08FC */ dCcD_Sph mSph0; /* 0x0A4C */ dCcD_Sph mSph1; /* 0x0B9C */ EffectsStruct mEff0; /* 0x0BD0 */ EffectsStruct mEff1; /* 0x0C04 */ EffectsStruct mEff2; /* 0x0C38 */ EffectsStruct mEff3; /* 0x0C6C */ dLytFader_c mLytFader; /* 0x114C */ mFader_c mFader; /* 0x1150 */ u8 _0x1150[0x115C - 0x1150]; /* 0x115C */ STATE_MGR_DECLARE(dAcBoomerang_c); static const u32 BoomerangAtFlags; static dCcD_SrcSph sSphSrc; static dBgS_BeetleLinChk sLinChk; static const u32 sSrcAtType; }; #endif