From d586e445e7ec5a1fad1182c4243958b76fe81219 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Mon, 9 Jun 2025 22:48:21 -0400 Subject: [PATCH] Beetle Progress --- config/SOUE01/splits.txt | 3 + config/SOUE01/symbols.txt | 118 ++++++------- include/d/a/d_a_player.h | 21 ++- include/d/a/obj/d_a_obj_boomerang.h | 65 +++++-- include/d/d_player_act.h | 5 + include/m/m_vec.h | 4 + include/toBeSorted/actor_event.h | 1 + src/d/a/obj/d_a_obj_boomerang.cpp | 251 +++++++++++++++++++++++++++- 8 files changed, 392 insertions(+), 76 deletions(-) diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index e66d16a4..b8538c4c 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -1359,7 +1359,10 @@ d/a/obj/d_a_obj_boomerang.cpp: .ctors start:0x804DB834 end:0x804DB838 .rodata start:0x804ED380 end:0x804ED3B0 .data start:0x80534AD0 end:0x80534E78 + .sdata start:0x805739D8 end:0x80573A30 .sbss start:0x80575900 end:0x80575908 + .sdata2 start:0x8057C0F8 end:0x8057C180 + .bss start:0x805B4BF0 end:0x805B4DD8 d/a/obj/d_a_obj_fairy.cpp: .text start:0x80265620 end:0x80268598 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 752563db..cddf981e 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -12739,46 +12739,46 @@ ActorLink__equipBeetle = .text:0x8021AA70; // type:function size:0x270 fn_8021ACE0 = .text:0x8021ACE0; // type:function size:0x2D8 ActorLink__equipSpawnBeetle = .text:0x8021AFC0; // type:function size:0x80 fn_8021B040 = .text:0x8021B040; // type:function size:0x20 -fn_8021B060 = .text:0x8021B060; // type:function size:0x1C -fn_8021B080 = .text:0x8021B080; // type:function size:0x8 +getBeetleHeldActor = .text:0x8021B060; // type:function size:0x1C +getBeetleActor = .text:0x8021B080; // type:function size:0x8 getBeetleFlightTime = .text:0x8021B090; // type:function size:0x50 -fn_8021B0E0 = .text:0x8021B0E0; // type:function size:0x28 -fn_8021B110 = .text:0x8021B110; // type:function size:0x28 -fn_8021B140 = .text:0x8021B140; // type:function size:0x8 -fn_8021B150 = .text:0x8021B150; // type:function size:0x8 -getNormalBeetleSpeed = .text:0x8021B160; // type:function size:0x8 -getSpeedBeetleSpeed = .text:0x8021B170; // type:function size:0x8 -fn_8021B180 = .text:0x8021B180; // type:function size:0x8 -fn_8021B190 = .text:0x8021B190; // type:function size:0x8 -getVal35.0 = .text:0x8021B1A0; // type:function size:0x8 -fn_8021B1B0 = .text:0x8021B1B0; // type:function size:0x8 -fn_8021B1C0 = .text:0x8021B1C0; // type:function size:0x28 -fn_8021B1F0 = .text:0x8021B1F0; // type:function size:0x28 -fn_8021B220 = .text:0x8021B220; // type:function size:0x28 -fn_8021B250 = .text:0x8021B250; // type:function size:0x28 +getBettleAngle0 = .text:0x8021B0E0; // type:function size:0x28 +getBettleAngle1 = .text:0x8021B110; // type:function size:0x28 +getBeetleWingAngleActive = .text:0x8021B140; // type:function size:0x8 +getBeetleWingAngleInactive = .text:0x8021B150; // type:function size:0x8 +getBeetleNormalSpeed = .text:0x8021B160; // type:function size:0x8 +getBeetleQuickSpeed = .text:0x8021B170; // type:function size:0x8 +getBeetleMaxRange = .text:0x8021B180; // type:function size:0x8 +getBeetleLargeRadius = .text:0x8021B190; // type:function size:0x8 +getBeetleSmallRadius = .text:0x8021B1A0; // type:function size:0x8 +getBeetleMaxHeightOffset = .text:0x8021B1B0; // type:function size:0x8 +getBeetleSmallAngle0 = .text:0x8021B1C0; // type:function size:0x28 +getBeetleSmallAngle1 = .text:0x8021B1F0; // type:function size:0x28 +getBeetleBonkRecoilAngle = .text:0x8021B220; // type:function size:0x28 +getBeetleSmallAngle2 = .text:0x8021B250; // type:function size:0x28 fn_8021B280 = .text:0x8021B280; // type:function size:0x8 fn_8021B290 = .text:0x8021B290; // type:function size:0x8 fn_8021B2A0 = .text:0x8021B2A0; // type:function size:0x8 -fn_8021B2B0 = .text:0x8021B2B0; // type:function size:0x8 +getBeetleWarningTimeLeft__7dAcPy_cFv = .text:0x8021B2B0; // type:function size:0x8 fn_8021B2C0 = .text:0x8021B2C0; // type:function size:0x8 -fn_8021B2D0 = .text:0x8021B2D0; // type:function size:0xAC -fn_8021B380 = .text:0x8021B380; // type:function size:0x48 -fn_8021B3D0 = .text:0x8021B3D0; // type:function size:0x48 -fn_8021B420 = .text:0x8021B420; // type:function size:0x38 -fn_8021B460 = .text:0x8021B460; // type:function size:0x7C -fn_8021B4E0 = .text:0x8021B4E0; // type:function size:0x4 -ActorLink__isUsingBeetle = .text:0x8021B4F0; // type:function size:0x50 -fn_8021B540 = .text:0x8021B540; // type:function size:0x10 -fn_8021B550 = .text:0x8021B550; // type:function size:0xA0 -fn_8021B5F0 = .text:0x8021B5F0; // type:function size:0x90 -ActorLink__shootBeetleMaybe = .text:0x8021B680; // type:function size:0x2B8 -ActorLink__useBeetleMaybe = .text:0x8021B940; // type:function size:0x44 -ActorLink__usingRocketBeetleRelated = .text:0x8021B990; // type:function size:0x114 -fn_8021BAB0 = .text:0x8021BAB0; // type:function size:0x68 +checkBeetleItemRetrieve = .text:0x8021B2D0; // type:function size:0xAC +setBeetleFlashClr__7dAcPy_cFRC6mColor = .text:0x8021B380; // type:function size:0x48 +setBeetleBackAnim__7dAcPy_cFv = .text:0x8021B3D0; // type:function size:0x48 +setBeetleReleasedObject = .text:0x8021B420; // type:function size:0x38 +getBeetleActorPtr = .text:0x8021B460; // type:function size:0x7C +strippedBeetleFunction = .text:0x8021B4E0; // type:function size:0x4 +checkUsingBeetleAnim = .text:0x8021B4F0; // type:function size:0x50 +startUseBeetle = .text:0x8021B540; // type:function size:0x10 +setBeetleMove = .text:0x8021B550; // type:function size:0xA0 +retrieveBeetle = .text:0x8021B5F0; // type:function size:0x90 +shootBeetle = .text:0x8021B680; // type:function size:0x2B8 +useBeetle = .text:0x8021B940; // type:function size:0x44 +updateBeetle = .text:0x8021B990; // type:function size:0x114 +lookAtBeetle = .text:0x8021BAB0; // type:function size:0x68 fn_8021BB20 = .text:0x8021BB20; // type:function size:0x80 fn_8021BBA0 = .text:0x8021BBA0; // type:function size:0x38 -ActorLink__doUseBeetle = .text:0x8021BBE0; // type:function size:0x74 -ActorLink__HoldBeetle = .text:0x8021BC60; // type:function size:0x1C0 +setUseBeetleAction = .text:0x8021BBE0; // type:function size:0x74 +performBeeltleAction = .text:0x8021BC60; // type:function size:0x1C0 fn_8021BE20 = .text:0x8021BE20; // type:function size:0x100 fn_8021BF20 = .text:0x8021BF20; // type:function size:0x9C fn_8021BFC0 = .text:0x8021BFC0; // type:function size:0x8 @@ -14131,28 +14131,28 @@ fn_80262BE0 = .text:0x80262BE0; // type:function size:0x1E0 fn_80262DC0 = .text:0x80262DC0; // type:function size:0x13C 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 -fn_802631D0 = .text:0x802631D0; // type:function size:0x8C -fn_80263260 = .text:0x80263260; // type:function size:0x5C -fn_802632C0 = .text:0x802632C0; // type:function size:0x4 -fn_802632D0 = .text:0x802632D0; // type:function size:0x70 -fn_80263340 = .text:0x80263340; // type:function size:0x7C -fn_802633C0 = .text:0x802633C0; // type:function size:0x18 -fn_802633E0 = .text:0x802633E0; // type:function size:0x210 -AcBoomerang__stateWaitUpdate = .text:0x802635F0; // type:function size:0xA84 -fn_80264080 = .text:0x80264080; // type:function size:0x4 -fn_80264090 = .text:0x80264090; // type:function size:0x198 -fn_80264230 = .text:0x80264230; // type:function size:0x3E4 -fn_80264620 = .text:0x80264620; // type:function size:0x4 -fn_80264630 = .text:0x80264630; // type:function size:0x5C -fn_80264690 = .text:0x80264690; // type:function size:0x30 -fn_802646C0 = .text:0x802646C0; // type:function size:0x4 -fn_802646D0 = .text:0x802646D0; // type:function size:0x188 -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 +setFlyChrAnimation__14dAcBoomerang_cFQ214dAcBoomerang_c14FlyAnimation_e = .text:0x80263090; // type:function size:0xE4 +setRemainingFlightTime__14dAcBoomerang_cFs = .text:0x80263180; // type:function size:0x50 +initializeState_Wait__14dAcBoomerang_cFv = .text:0x802631D0; // type:function size:0x8C +executeState_Wait__14dAcBoomerang_cFv = .text:0x80263260; // type:function size:0x5C +finalizeState_Wait__14dAcBoomerang_cFv = .text:0x802632C0; // type:function size:0x4 +initializeState_ReturnWait__14dAcBoomerang_cFv = .text:0x802632D0; // type:function size:0x70 +executeState_ReturnWait__14dAcBoomerang_cFv = .text:0x80263340; // type:function size:0x7C +finalizeState_ReturnWait__14dAcBoomerang_cFv = .text:0x802633C0; // type:function size:0x18 +initializeState_Move__14dAcBoomerang_cFv = .text:0x802633E0; // type:function size:0x210 +executeState_Move__14dAcBoomerang_cFv = .text:0x802635F0; // type:function size:0xA84 +finalizeState_Move__14dAcBoomerang_cFv = .text:0x80264080; // type:function size:0x4 +initializeState_MoveCancelWait__14dAcBoomerang_cFv = .text:0x80264090; // type:function size:0x198 +executeState_MoveCancelWait__14dAcBoomerang_cFv = .text:0x80264230; // type:function size:0x3E4 +finalizeState_MoveCancelWait__14dAcBoomerang_cFv = .text:0x80264620; // type:function size:0x4 +initializeState_EventReturnWait__14dAcBoomerang_cFv = .text:0x80264630; // type:function size:0x5C +executeState_EventReturnWait__14dAcBoomerang_cFv = .text:0x80264690; // type:function size:0x30 +finalizeState_EventReturnWait__14dAcBoomerang_cFv = .text:0x802646C0; // type:function size:0x4 +executeTimeWarning__14dAcBoomerang_cFv = .text:0x802646D0; // type:function size:0x188 +registerInEvent__14dAcBoomerang_cFv = .text:0x80264860; // type:function size:0x4 +actorExecute__14dAcBoomerang_cFv = .text:0x80264870; // type:function size:0x45C +executeState__83sStateMgr_c<14dAcBoomerang_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80264CD0; // type:function size:0x10 +draw__14dAcBoomerang_cFv = .text:0x80264CE0; // type:function size:0x160 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 @@ -51407,9 +51407,11 @@ AcArrow__STATE_BOUND = .bss:0x805B4BA0; // type:object size:0x30 data:4byte lbl_805B4BD0 = .bss:0x805B4BD0; // type:object size:0x10 align:4 data:float lbl_805B4BE0 = .bss:0x805B4BE0; // type:object size:0x10 lbl_805B4BF0 = .bss:0x805B4BF0; // type:object size:0xA8 -AcBoomerang__STATE_WAIT = .bss:0x805B4C98; // type:object size:0x40 data:4byte -AcBoomerang__STATE_MOVE = .bss:0x805B4CD8; // type:object size:0x40 data:4byte -AcBoomerang__STATE_CANCEL_WAIT = .bss:0x805B4D18; // type:object size:0xC0 data:4byte +StateID_Wait__14dAcBoomerang_c = .bss:0x805B4C98; // type:object size:0x40 data:4byte +StateID_Move__14dAcBoomerang_c = .bss:0x805B4CD8; // type:object size:0x40 data:4byte +StateID_MoveCancelWait__14dAcBoomerang_c = .bss:0x805B4D18; // type:object size:0x40 data:4byte +StateID_ReturnWait__14dAcBoomerang_c = .bss:0x805B4D58; // type:object size:0x40 data:4byte +StateID_EventReturnWait__14dAcBoomerang_c = .bss:0x805B4D98; // type:object size:0x40 data:4byte lbl_805B4DD8 = .bss:0x805B4DD8; // type:object size:0x10 AcFairy__STATE_WAIT = .bss:0x805B4DE8; // type:object size:0x40 data:4byte AcFairy__STATE_AVOID = .bss:0x805B4E28; // type:object size:0x40 data:4byte diff --git a/include/d/a/d_a_player.h b/include/d/a/d_a_player.h index fd753989..e3b4a1cf 100644 --- a/include/d/a/d_a_player.h +++ b/include/d/a/d_a_player.h @@ -5,6 +5,8 @@ #include "d/a/d_a_item.h" #include "d/col/c/c_bg_s_poly_info.h" #include "d/d_player_mdl.h" +#include "m/m_angle.h" +#include "m/m_color.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "toBeSorted/file_manager.h" #include "toBeSorted/minigame_mgr.h" @@ -37,7 +39,24 @@ protected: public: // Beetle Functions [0x8021AA70 - 0x8021BE20] - f32 getBeetleRadius(); + s16 getBeetleFlightTime(); + mAng getBeetleAngle0(); + mAng getBeetleAngle1(); + f32 getBeetleWingAngleActive(); + f32 getBeetleWingAngleInactive(); + f32 getBeetleNormalSpeed(); + f32 getBeetleQuickSpeed(); + f32 getBeetleMaxRange(); + f32 getBeetleLargeRadius(); + f32 getBeetleSmallRadius(); + f32 getBeetleMaxHeightOffset(); + mAng getBeetleSmallAngle0(); + mAng getBeetleSmallAngle1(); + mAng getBeetleBonkRecoilAngle(); + mAng getBeetleSmallAngle2(); + void setBeetleFlashClr(const mColor &); + void setBeetleBackAnim(); + s32 getBeetleWarningTimeLeft(); public: f32 getField_0x4564() const { diff --git a/include/d/a/obj/d_a_obj_boomerang.h b/include/d/a/obj/d_a_obj_boomerang.h index 0b3ad479..20dd7c9b 100644 --- a/include/d/a/obj/d_a_obj_boomerang.h +++ b/include/d/a/obj/d_a_obj_boomerang.h @@ -16,14 +16,13 @@ #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 dAcBoomerangProc_c : public d3d::UnkProc { public: - dAcBoomerangProc_c() : mColor0(0), mColor1(0xFFFFFFFF) {} + dAcBoomerangProc_c() : mpMdl(nullptr), mClr(0xFFFFFFFF) {} ~dAcBoomerangProc_c() {} bool create(m3d::mdl_c *mdl, mColor clr, int prioOpa, mAllocator_c *alloc); @@ -34,8 +33,8 @@ public: virtual void drawOpa() override; private: - mColor mColor0; - mColor mColor1; + m3d::mdl_c *mpMdl; + mColor mClr; }; class dAcBoomerang_c : public dAcObjBase_c { @@ -98,17 +97,44 @@ public: // TYPES MDL_WINGS_ADV = 5, }; - // Macros until enum is solidified + 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]; +// Macros until enum is solidified (0x8CC) #define FLAG_BOOMERANG_CANCEL (0x3) +#define FLAG_BOOMERANG_RELEASE_ITEM (0x4) +#define FLAG_BOOMERANG_0x8 (0x8) +#define FLAG_BOOMERANG_0x10 (0x10) +#define FLAG_BOOMERANG_0x20 (0x20) +#define FLAG_BOOMERANG_0x40 (0x40) +#define FLAG_BOOMERANG_0x80 (0x80) +#define FLAG_BOOMERANG_STOP_TIMER_ACTIVE (0x100) +#define FLAG_BOOMERANG_DROP_ITEM (0x200) // related to 0x400 +#define FLAG_BOOMERANG_REQUEST_0x400 (0x400) // related to 0x200 +#define FLAG_BOOMERANG_REQUEST_MOVE (0x800) +#define FLAG_BOOMERANG_CONTROLLABLE (0x1000) +#define FLAG_BOOMERANG_0x2000 (0x2000) #define FLAG_BOOMERANG_RUMBLE_ACTIVE (0x4000) +#define FLAG_BOOMERANG_WING_EFFECT_ACTIVE (0x8000) +#define FLAG_BOOMERANG_0x10000 (0x10000) +#define FLAG_BOOMERANG_0x40000 (0x40000) public: // INLINES bool checkField_0x8CC(u32 mask) const { return field_0x8CC & mask; } - void onField_0x8CC(u32 mask) { + void setField_0x8CC(u32 mask) { field_0x8CC |= mask; } + void unsetField_0x8CC(u32 mask) { + field_0x8CC &= ~mask; + } bool isMoving() { return mStateMgr.isState(StateID_Move); } @@ -141,6 +167,15 @@ public: // FUNCTIONS /** 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; @@ -156,15 +191,22 @@ private: /* 0x0804 */ dBgS_AcchCir mAcchCir; /* 0x0860 */ ActorEventRelated mEventRelated; /* 0x08B0 */ u8 mCurrentAnimation; - /* 0x08B1 */ u8 _0x8B1[0x8B5 - 0x8B1]; + /* 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 */ u8 _0x8B8[0x8CC - 0x8B8]; - /* 0x08B8 */ u32 field_0x8CC; - /* 0x08D0 */ u8 _0x8D0[0x8D8 - 0x8D0]; + /* 0x08B8 */ u8 _0x8B8[0x8C8 - 0x8B8]; + /* 0x08CA */ u16 field_0x8C8; + /* 0x08CA */ u16 mRemainingFlightTime; + /* 0x08CC */ u32 field_0x8CC; + /* 0x08D0 */ f32 field_0x8D0; + /* 0x08D4 */ f32 field_0x8D4; /* 0x08D8 */ mVec3_c field_0x8D8; - /* 0x08E4 */ u8 _0x8E4[0x8FC - 0x8E4]; + /* 0x08E4 */ mVec3_c field_0x8E4; + /* 0x08F0 */ u8 _0x8E4[0x8FC - 0x8F0]; /* 0x08FC */ dCcD_Sph mSph0; /* 0x0A4C */ dCcD_Sph mSph1; /* 0x0B9C */ EffectsStruct mEff0; @@ -176,6 +218,7 @@ private: /* 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; diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 6214a749..0631bfdc 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -464,6 +464,8 @@ public: enum ModelUpdateFlags_e { UPDATE_MODEL_SWORD = 0x20, UPDATE_MODEL_SHIELD = 0x40, + + UPDATE_MODEL_BEETLE = 0x10000000, }; enum SwordAndMoreStates_e { @@ -590,6 +592,9 @@ public: void offModelUpdateFlag(u32 mask) { mModelUpdateFlags &= ~mask; } + bool checkModelUpdateFlag(u32 mask) const { + return mModelUpdateFlags & mask; + } inline bool checkActionFlags(u32 mask) const { return (mActionFlags & mask) != 0; diff --git a/include/m/m_vec.h b/include/m/m_vec.h index 0a8cf706..24339d74 100644 --- a/include/m/m_vec.h +++ b/include/m/m_vec.h @@ -265,6 +265,10 @@ public: return cM::atan2s(-y, absXZ()); } + f32 angle(const mVec3_c &other) const { + return EGG::Vector3f::angle(other); + } + static mVec3_c Zero; static mVec3_c Ex; static mVec3_c Ey; diff --git a/include/toBeSorted/actor_event.h b/include/toBeSorted/actor_event.h index 5a691f53..8cb6df43 100644 --- a/include/toBeSorted/actor_event.h +++ b/include/toBeSorted/actor_event.h @@ -16,6 +16,7 @@ public: u32 getCurrentEventCommand() const; void advanceNext(); bool isAdvance(); + int getSomeEventRelatedNumber(); int getSingleFloatData(f32 *result, u32 code, u32); int getSingleVecData(mVec3_c *result, u32 code, u32); diff --git a/src/d/a/obj/d_a_obj_boomerang.cpp b/src/d/a/obj/d_a_obj_boomerang.cpp index 6a7affbe..48264a84 100644 --- a/src/d/a/obj/d_a_obj_boomerang.cpp +++ b/src/d/a/obj/d_a_obj_boomerang.cpp @@ -5,6 +5,7 @@ #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/bg/d_bg_s_lin_chk.h" #include "d/col/c/c_cc_d.h" #include "d/d_rumble.h" #include "d/snd/d_snd_wzsound.h" @@ -15,11 +16,27 @@ #include "m/m_color.h" #include "m/m_fader_base.h" #include "m/m_mtx.h" +#include "m/m_quat.h" +#include "m/m_vec.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 "rvl/GX/GXTypes.h" +#include "s/s_Math.h" #include "s/s_State.hpp" +#include "toBeSorted/d_emitter.h" +#include "toBeSorted/event_manager.h" + +dBgS_BeetleLinChk dAcBoomerang_c::sLinChk; +dCcD_SrcSph dAcBoomerang_c::sSphSrc = { + {{AT_TYPE_BEETLE, BoomerangAtFlags, {4, 0, 0}, 0, 1, 0, 0, 0}, + {~AT_TYPE_COMMON0, 0x291, {0, 0, 0x407}, 0, 0}, + {0x28}}, + {15.f} +}; +const u32 dAcBoomerang_c::BoomerangAtFlags = 0x209B; +; SPECIAL_ACTOR_PROFILE(BOOMERANG, dAcBoomerang_c, fProfile::BOOMERANG, 0x125, 0, 0x4); @@ -74,7 +91,7 @@ void dAcBoomerang_c::atHitCallback(cCcD_Obj *i_objInfA, dAcObjBase_c *i_actorB, field_0x8D8.normalize(); - onField_0x8CC(FLAG_BOOMERANG_CANCEL); + setField_0x8CC(FLAG_BOOMERANG_CANCEL); mStateMgr.changeState(StateID_MoveCancelWait); } else { // Play the animation to move the pincers @@ -175,7 +192,7 @@ int dAcBoomerang_c::create() { mAcch.Set_0x40000000(); mAcch.SetLineDown(); - mAcchCir.SetWall(0.f, dAcPy_c::GetLink2()->getBeetleRadius()); + mAcchCir.SetWall(0.f, dAcPy_c::GetLink2()->getBeetleSmallRadius()); mCurrentAnimation = RB_MAX; mStateMgr.changeState(StateID_Wait); @@ -192,7 +209,7 @@ int dAcBoomerang_c::create() { mSph1.Set(sSphSrc); mSph1.SetStts(mStts); mSph1.SetAtCallback(dAcBoomerang_atHitCallback); - mSph1.SetR(dAcPy_c::GetLink2()->getBeetleRadius()); + mSph1.SetR(dAcPy_c::GetLink2()->getBeetleSmallRadius()); mSph1.ClrCoSet(); mSph1.SetAtType(AT_TYPE_0x40); @@ -282,7 +299,7 @@ void dAcBoomerang_c::bonk() { if (checkField_0x8CC(FLAG_BOOMERANG_RUMBLE_ACTIVE)) { return; } - onField_0x8CC(FLAG_BOOMERANG_RUMBLE_ACTIVE); + setField_0x8CC(FLAG_BOOMERANG_RUMBLE_ACTIVE); dRumble_c::start(dRumble_c::sRumblePreset1, 1); } @@ -314,6 +331,228 @@ void dAcBoomerang_c::setChrAnimation(dAcBoomerang_c::ChrAnimation_e requestedAni mMdl.setAnm(mAnmChrBlend, sChrAnims[requestedAnimation].mRate); } -// ... +// HELP: I need this to be const to fix the load, but I cant do that without ruining sdata +const char *dAcBoomerang_c::sFlyChrAnims[RB_FLY_MAX] = {"RB_Fly", "RB_FlyFast"}; +void dAcBoomerang_c::setFlyChrAnimation(FlyAnimation_e requestedAnimation) { + nw4r::g3d::ResAnmChr resAnmChr = mResFile.GetResAnmChr(sFlyChrAnims[requestedAnimation]); + mAnmChr[BOOMERANG_ANIM_WINGS].setAnm(mMdl, resAnmChr, m3d::PLAY_MODE_4); + nw4r::g3d::AnmObjChr *pAnmObj = static_cast(mAnmChr[BOOMERANG_ANIM_WINGS].getAnimObj()); + pAnmObj->Release(); + pAnmObj->Bind(mMdl.getResMdl(), mLeftWingNodeID, nw4r::g3d::AnmObjChr::BIND_PARTIAL); + pAnmObj->Bind(mMdl.getResMdl(), mRightWingNodeID, nw4r::g3d::AnmObjChr::BIND_PARTIAL); -bool dAcBoomerangProc_c::create(m3d::mdl_c *mdl, mColor clr, int prioOpa, mAllocator_c *alloc) {} + mMdl.setAnm(mAnmChrBlend); +} + +void dAcBoomerang_c::setRemainingFlightTime(s16 time) { + if (time < 0) { + time = dAcPy_c::GetLink2()->getBeetleWarningTimeLeft(); + } + if (mRemainingFlightTime > time) { + mRemainingFlightTime = time; + mFlashTimer = time; + } +} + +void dAcBoomerang_c::initializeState_Wait() { + setChrAnimation(RB_SET); + mAnmChrBlend.setWeight(1, 0.f); + mSph0.ClrAtHit(); + mSph1.ClrTgHit(); + mSph1.ClrAtHit(); + unsetField_0x8CC( + FLAG_BOOMERANG_0x10000 | FLAG_BOOMERANG_WING_EFFECT_ACTIVE | FLAG_BOOMERANG_0x2000 | + FLAG_BOOMERANG_STOP_TIMER_ACTIVE | FLAG_BOOMERANG_0x10 | FLAG_BOOMERANG_RELEASE_ITEM | FLAG_BOOMERANG_CANCEL + ); + + placeOnArm(); + field_0x8D0 = 0.f; + + dAcPy_c::GetLink2()->onModelUpdateFlag(dAcPy_c::UPDATE_MODEL_BEETLE); +} +void dAcBoomerang_c::executeState_Wait() { + forwardSpeed = 0.f; + placeOnArm(); + if (checkField_0x8CC(FLAG_BOOMERANG_REQUEST_MOVE)) { + mStateMgr.changeState(StateID_Move); + } +} +void dAcBoomerang_c::finalizeState_Wait() {} + +void dAcBoomerang_c::initializeState_ReturnWait() { + setChrAnimation(RB_BACK); + setFlyChrAnimation(RB_FLY_FAST); + mSph0.ClrAtHit(); + mSph1.ClrTgHit(); + mSph1.ClrAtHit(); + unsetField_0x8CC( + FLAG_BOOMERANG_0x10000 | FLAG_BOOMERANG_WING_EFFECT_ACTIVE | FLAG_BOOMERANG_0x2000 | + FLAG_BOOMERANG_STOP_TIMER_ACTIVE | FLAG_BOOMERANG_0x10 | FLAG_BOOMERANG_RELEASE_ITEM | FLAG_BOOMERANG_CANCEL + ); + placeOnArm(); +} +void dAcBoomerang_c::executeState_ReturnWait() { + forwardSpeed = 0.f; + placeOnArm(); + if (mAnmChr[BOOMERANG_ANIM_PINCERS].isStop() || !dAcPy_c::GetLink2()->checkActionFlagsCont(0x10)) { + playSound(SE_BE_CATCH); + mStateMgr.changeState(StateID_Wait); + } +} +void dAcBoomerang_c::finalizeState_ReturnWait() { + if (dAcPy_c::GetLink2()->checkActionFlagsCont(0x10)) { + dAcPy_c::GetLink2()->setBeetleBackAnim(); + } +} + +void dAcBoomerang_c::initializeState_Move() { + setChrAnimation(RB_DEFAULT); + mAnmChrBlend.setWeight(1, 1.f); + setFlyChrAnimation(RB_FLY); + field_0x8B1 = 45; // 1.5 seconds if that means anything + field_0x8C8 = 0; + forwardSpeed = dAcPy_c::GetLink2()->getBeetleSmallRadius(); +} +void dAcBoomerang_c::executeState_Move() {} +void dAcBoomerang_c::finalizeState_Move() {} + +void dAcBoomerang_c::initializeState_MoveCancelWait() {} +void dAcBoomerang_c::executeState_MoveCancelWait() {} +void dAcBoomerang_c::finalizeState_MoveCancelWait() {} + +void dAcBoomerang_c::initializeState_EventReturnWait() { + mSph0.ClrCoHit(); + mSph0.ClrAtHit(); + mSph1.ClrTgHit(); + mSph1.ClrAtHit(); + + unsetField_0x8CC( + FLAG_BOOMERANG_0x10000 | FLAG_BOOMERANG_WING_EFFECT_ACTIVE | FLAG_BOOMERANG_0x2000 | + FLAG_BOOMERANG_STOP_TIMER_ACTIVE | FLAG_BOOMERANG_0x10 | FLAG_BOOMERANG_RELEASE_ITEM | FLAG_BOOMERANG_CANCEL + ); +} +void dAcBoomerang_c::executeState_EventReturnWait() {} +void dAcBoomerang_c::finalizeState_EventReturnWait() {} + +void dAcBoomerang_c::executeTimeWarning() { + s16 timeLimit = dAcPy_c::GetLink2()->getBeetleWarningTimeLeft(); + mColor flashClr(0, 0, 0, 0xFF); + + if (mRemainingFlightTime <= timeLimit) { + setField_0x8CC(FLAG_BOOMERANG_STOP_TIMER_ACTIVE); + + if (mFlashTimer != 0) { + mFlashTimer--; + } + + s32 r; + if (mFlashTimer > 75) { + r = 37; + } else if (mFlashTimer > 37) { + r = 18; + } else { + r = 9; + } + + flashClr.r = (1.f / (r - 6)) * MAX(0, (mFlashTimer % r) - 5) * 255.f; + if (flashClr.r == 0xFF && !mStateMgr.isState(StateID_MoveCancelWait)) { + playSound(SE_BE_WARNING); + } + } + + mMdl.setTevKColorAll(GX_KCOLOR3, flashClr, false); + dAcPy_c::GetLink2()->setBeetleFlashClr(flashClr); +} + +void dAcBoomerang_c::registerInEvent() { + return; +} + +int dAcBoomerang_c::actorExecute() { + dAcPy_c *player = dAcPy_c::GetLink2(); + + if (checkField_0x8CC(FLAG_BOOMERANG_REQUEST_0x400)) { + unsetField_0x8CC(FLAG_BOOMERANG_REQUEST_0x400); + } + + if (dAcPy_c::GetLink2()->checkModelUpdateFlag(0x10000 | 0x80)) { + deleteRequest(); + unsetField_0x8CC(FLAG_BOOMERANG_REQUEST_0x400); + return SUCCEEDED; + } + + if (EventManager::isInEvent() && mEventRelated.getSomeEventRelatedNumber() != -1) { + setField_0x8CC(FLAG_BOOMERANG_0x40); + mEventRelated.advanceNext(); + } + + unsetField_0x8CC(FLAG_BOOMERANG_0x40000 | FLAG_BOOMERANG_RUMBLE_ACTIVE); + + for (int i = 0; i < 2; ++i) { + mAnmChr[i].play(); + } + mMdl.play(); + mStateMgr.executeState(); + + sLib::chase(&field_0x8D4, 0.f, 0.05f); + mAcch.CrrPos(*dBgS::GetInstance()); + + setRoomId(); + + mMdl.calc(false); + mMdl.getNodeWorldMtxMultVecZero(0, poscopy2); + poscopy3 = poscopy2; + + if (checkField_0x8CC(FLAG_BOOMERANG_WING_EFFECT_ACTIVE)) { + mEff0.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_6_, mWorldMtx, nullptr, nullptr); + mEff1.setTransform(mWorldMtx); + + f32 ang = field_0x8E4.angle(velocity); + ang = 10.f - mAng::fromRad(ang) * (7.f / 256.f); + ang = nw4r::ut::Max(ang, 3.f); + mEff1.setAwayFromCenterSpeed(ang); + } else { + mEff0.remove(true); + } + + if (field_0x8B1 == 0 && (mStateMgr.isState(StateID_Move) || mStateMgr.isState(StateID_MoveCancelWait))) { + mEff2.createContinuousEffect( + PARTICLE_RESOURCE_ID_MAPPING_5_, player->GetPosition(), nullptr, nullptr, nullptr, nullptr + ); + } else { + mEff2.remove(true); + } + + if (checkField_0x8CC(FLAG_BOOMERANG_0x20) && !checkField_0x8CC(FLAG_BOOMERANG_CANCEL)) { + if (mStateMgr.isState(StateID_Move) || mStateMgr.isState(StateID_MoveCancelWait)) { + mEff3.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_7_, mWorldMtx, nullptr, nullptr); + playSoundEffect1(SE_BE_HIT_LEAVES_LV); + } + } + + unsetField_0x8CC(FLAG_BOOMERANG_0x20 | FLAG_BOOMERANG_0x40 | FLAG_BOOMERANG_0x80 | FLAG_BOOMERANG_DROP_ITEM); + retrieve(); + return SUCCEEDED; +} + +int dAcBoomerang_c::draw() { + if (mStateMgr.isState(StateID_EventReturnWait) || dAcPy_c::GetLink2()->checkModelUpdateFlag(0x10000 | 0x80)) { + return SUCCEEDED; + } + drawModelType1(&mMdl); + if (!mStateMgr.isState(StateID_Wait)) { + mProc.entry(); + static mQuat_c shadow(mVec3_c::Zero, 50.f); + drawShadow(mShadow, nullptr, mWorldMtx, &shadow, -1, -1, -1, -1, -1, position.y - mAcch.GetGroundH()); + } + return SUCCEEDED; +} + +bool dAcBoomerangProc_c::create(m3d::mdl_c *mdl, mColor clr, int prioOpa, mAllocator_c *alloc) { + if (!d3d::UnkProc::create(prioOpa, -1, alloc)) { + return false; + } + mpMdl = mdl; + mClr = clr; + return true; +}