From 206079e0f609821b8efac29e4d1772af30844e5f Mon Sep 17 00:00:00 2001 From: swekka Date: Sat, 20 Dec 2025 18:20:36 +0100 Subject: [PATCH 1/4] d_a_obj_rope_igaiga OK --- .../rels/d_a_obj_ivy_ropeNP/symbols.txt | 2 +- .../rels/d_a_obj_rope_igaigaNP/symbols.txt | 86 +- configure.py | 2 +- include/d/a/d_a_base.h | 8 +- include/d/a/obj/d_a_obj_ivy_rope.h | 30 +- include/d/a/obj/d_a_obj_rope_igaiga.h | 76 +- include/d/col/c/c_cc_d.h | 7 +- include/d/d_player_act.h | 8 + src/REL/d/a/obj/d_a_obj_ivy_rope.cpp | 2 + src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp | 782 +++++++++++++++++- 10 files changed, 936 insertions(+), 67 deletions(-) diff --git a/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt b/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt index 0035787f..8c232f32 100644 --- a/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt @@ -161,7 +161,7 @@ _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global lbl_256_rodata_0 = .rodata:0x00000000; // type:object size:0x40 data:float -lbl_256_rodata_40 = .rodata:0x00000040; // type:object size:0x60 +lbl_256_rodata_40__13dAcOivyRope_c = .rodata:0x00000040; // type:object size:0x60 lbl_256_rodata_A0 = .rodata:0x000000A0; // type:object size:0x10 lbl_256_rodata_B0 = .rodata:0x000000B0; // type:object size:0x10 align:4 data:float lbl_256_rodata_C0 = .rodata:0x000000C0; // type:object size:0x8 align:8 data:double diff --git a/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt b/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt index 019eeffb..22beb64c 100644 --- a/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt @@ -8,13 +8,13 @@ __dt__29sFState_c<16dAcOropeIgaiga_c>Fv = .text:0x000001E0; // type:function siz __dt__32sFStateFct_c<16dAcOropeIgaiga_c>Fv = .text:0x00000240; // type:function size:0x6C __dt__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000002B0; // type:function size:0xA0 __dt__55sFStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c>Fv = .text:0x00000350; // type:function size:0xA4 -fn_257_400 = .text:0x00000400; // type:function size:0x90 -fn_257_490 = .text:0x00000490; // type:function size:0x1A4 +createHeap__16dAcOropeIgaiga_cFv = .text:0x00000400; // type:function size:0x90 +create__16dAcOropeIgaiga_cFv = .text:0x00000490; // type:function size:0x1A4 changeState__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000640; // type:function size:0x10 -fn_257_650 = .text:0x00000650; // type:function size:0x8 -fn_257_660 = .text:0x00000660; // type:function size:0x170 +doDelete__16dAcOropeIgaiga_cFv = .text:0x00000650; // type:function size:0x8 +actorExecute__16dAcOropeIgaiga_cFv = .text:0x00000660; // type:function size:0x170 executeState__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000007D0; // type:function size:0x10 -fn_257_7E0 = .text:0x000007E0; // type:function size:0x28 +draw__16dAcOropeIgaiga_cFv = .text:0x000007E0; // type:function size:0x28 initializeState_Init__16dAcOropeIgaiga_cFv = .text:0x00000810; // type:function size:0x4 executeState_Init__16dAcOropeIgaiga_cFv = .text:0x00000820; // type:function size:0x268 finalizeState_Init__16dAcOropeIgaiga_cFv = .text:0x00000A90; // type:function size:0x10 @@ -34,18 +34,18 @@ finalizeState_Stick__16dAcOropeIgaiga_cFv = .text:0x00001990; // type:function s initializeState_Water__16dAcOropeIgaiga_cFv = .text:0x000019C0; // type:function size:0x34 executeState_Water__16dAcOropeIgaiga_cFv = .text:0x00001A00; // type:function size:0x28C finalizeState_Water__16dAcOropeIgaiga_cFv = .text:0x00001C90; // type:function size:0x10 -fn_257_1CA0 = .text:0x00001CA0; // type:function size:0x7C -fn_257_1D20 = .text:0x00001D20; // type:function size:0xD0 -fn_257_1DF0 = .text:0x00001DF0; // type:function size:0x128 -fn_257_1F20 = .text:0x00001F20; // type:function size:0x98 +fn_257_1CA0__16dAcOropeIgaiga_cFv = .text:0x00001CA0; // type:function size:0x7C +fn_257_1D20__16dAcOropeIgaiga_cFv = .text:0x00001D20; // type:function size:0xD0 +fn_257_1DF0__16dAcOropeIgaiga_cFv = .text:0x00001DF0; // type:function size:0x128 +fn_257_1F20__16dAcOropeIgaiga_cFv = .text:0x00001F20; // type:function size:0x98 getStateID__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00001FC0; // type:function size:0x10 -fn_257_1FD0 = .text:0x00001FD0; // type:function size:0x18 -fn_257_1FF0 = .text:0x00001FF0; // type:function size:0xF8 -fn_257_20F0 = .text:0x000020F0; // type:function size:0xB0 -fn_257_21A0 = .text:0x000021A0; // type:function size:0x28 -fn_257_21D0 = .text:0x000021D0; // type:function size:0x13C -fn_257_2310 = .text:0x00002310; // type:function size:0x408 -fn_257_2720 = .text:0x00002720; // type:function size:0xE0 +fn_257_1FD0__16dAcOropeIgaiga_cFv = .text:0x00001FD0; // type:function size:0x18 +fn_257_1FF0__16dAcOropeIgaiga_cFPfb = .text:0x00001FF0; // type:function size:0xF8 +fn_257_20F0__16dAcOropeIgaiga_cFff = .text:0x000020F0; // type:function size:0xB0 +fn_257_21A0__16dAcOropeIgaiga_cFv = .text:0x000021A0; // type:function size:0x28 +fn_257_21D0__16dAcOropeIgaiga_cFv = .text:0x000021D0; // type:function size:0x13C +fn_257_2310__16dAcOropeIgaiga_cFs = .text:0x00002310; // type:function size:0x408 +fn_257_2720__16dAcOropeIgaiga_cFv = .text:0x00002720; // type:function size:0xE0 __dt__16dAcOropeIgaiga_cFv = .text:0x00002800; // type:function size:0x100 build__32sFStateFct_c<16dAcOropeIgaiga_c>FRC12sStateIDIf_c = .text:0x00002900; // type:function size:0x60 dispose__32sFStateFct_c<16dAcOropeIgaiga_c>FRP10sStateIf_c = .text:0x00002960; // type:function size:0xC @@ -66,32 +66,32 @@ isSameName__31sFStateID_c<16dAcOropeIgaiga_c>CFPCc = .text:0x00002FC0; // type:f _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global -lbl_257_rodata_0 = .rodata:0x00000000; // type:object size:0x28 data:float -lbl_257_rodata_28 = .rodata:0x00000028; // type:object size:0x4 align:4 data:float -lbl_257_rodata_2C = .rodata:0x0000002C; // type:object size:0xC align:4 data:float -lbl_257_rodata_38 = .rodata:0x00000038; // type:object size:0x14 align:4 data:float -lbl_257_rodata_4C = .rodata:0x0000004C; // type:object size:0x8 align:4 data:float -lbl_257_rodata_54 = .rodata:0x00000054; // type:object size:0xC align:4 data:float -lbl_257_rodata_60 = .rodata:0x00000060; // type:object size:0xC align:4 data:float -lbl_257_rodata_6C = .rodata:0x0000006C; // type:object size:0x34 align:4 data:float -lbl_257_rodata_A0 = .rodata:0x000000A0; // type:object size:0x4 align:4 data:float -lbl_257_rodata_A4 = .rodata:0x000000A4; // type:object size:0x34 align:4 data:float -lbl_257_rodata_D8 = .rodata:0x000000D8; // type:object size:0x8 align:4 data:float +lbl_257_rodata_0 = .rodata:0x00000000; // type:object size:0x28 scope:local data:float +lbl_257_rodata_28 = .rodata:0x00000028; // type:object size:0x4 scope:local align:4 data:float +lbl_257_rodata_2C = .rodata:0x0000002C; // type:object size:0xC scope:local align:4 data:float +lbl_257_rodata_38 = .rodata:0x00000038; // type:object size:0x14 scope:local align:4 data:float +lbl_257_rodata_4C = .rodata:0x0000004C; // type:object size:0x8 scope:local align:4 data:float +lbl_257_rodata_54 = .rodata:0x00000054; // type:object size:0xC scope:local align:4 data:float +lbl_257_rodata_60 = .rodata:0x00000060; // type:object size:0xC scope:local align:4 data:float +lbl_257_rodata_6C = .rodata:0x0000006C; // type:object size:0x34 scope:local align:4 data:float +lbl_257_rodata_A0 = .rodata:0x000000A0; // type:object size:0x4 scope:local align:4 data:float +lbl_257_rodata_A4 = .rodata:0x000000A4; // type:object size:0x34 scope:local align:4 data:float +lbl_257_rodata_D8 = .rodata:0x000000D8; // type:object size:0x8 scope:local align:4 data:float g_profile_OBJ_ROPE_IGAIGA = .data:0x00000000; // type:object size:0x10 data:4byte -lbl_257_data_10 = .data:0x00000010; // type:object size:0x2C -lbl_257_data_3C = .data:0x0000003C; // type:object size:0xB data:string -lbl_257_data_48 = .data:0x00000048; // type:object size:0x1E data:string -lbl_257_data_68 = .data:0x00000068; // type:object size:0x80 -lbl_257_data_E8 = .data:0x000000E8; // type:object size:0x30 -lbl_257_data_118 = .data:0x00000118; // type:object size:0x30 -lbl_257_data_148 = .data:0x00000148; // type:object size:0x18 -lbl_257_data_160 = .data:0x00000160; // type:object size:0x1B8 -lbl_257_data_318 = .data:0x00000318; // type:object size:0x34 +lbl_257_data_10 = .data:0x00000010; // type:object size:0x2C scope:local +lbl_257_data_3C = .data:0x0000003C; // type:object size:0xB scope:local data:string +lbl_257_data_48 = .data:0x00000048; // type:object size:0x1E scope:local data:string +__vt__16dAcOropeIgaiga_c = .data:0x00000068; // type:object size:0x80 +__vt__55sFStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c> = .data:0x000000E8; // type:object size:0x30 +__vt__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x00000118; // type:object size:0x30 +lbl_257_data_148 = .data:0x00000148; // type:object size:0x18 scope:local +lbl_257_data_160 = .data:0x00000160; // type:object size:0x1B8 scope:local +__vt__31sFStateID_c<16dAcOropeIgaiga_c> = .data:0x00000318; // type:object size:0x34 scope:local __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global -lbl_257_bss_8 = .bss:0x00000008; // type:object size:0x10 data:4byte -lbl_257_bss_18 = .bss:0x00000018; // type:object size:0x40 data:4byte -lbl_257_bss_58 = .bss:0x00000058; // type:object size:0x40 data:4byte -lbl_257_bss_98 = .bss:0x00000098; // type:object size:0x40 data:4byte -lbl_257_bss_D8 = .bss:0x000000D8; // type:object size:0x40 data:4byte -lbl_257_bss_118 = .bss:0x00000118; // type:object size:0x40 data:4byte -lbl_257_bss_158 = .bss:0x00000158; // type:object size:0x30 data:4byte +lbl_257_bss_8 = .bss:0x00000008; // type:object size:0x10 scope:local data:4byte +lbl_257_bss_18 = .bss:0x00000018; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_58 = .bss:0x00000058; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_98 = .bss:0x00000098; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_D8 = .bss:0x000000D8; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_118 = .bss:0x00000118; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_158 = .bss:0x00000158; // type:object size:0x30 scope:local data:4byte diff --git a/configure.py b/configure.py index 03e61e06..2b05c81e 100644 --- a/configure.py +++ b/configure.py @@ -2617,7 +2617,7 @@ config.libs = [ Rel(NonMatching, "d_a_obj_roll_pillar", "REL/d/a/obj/d_a_obj_roll_pillar.cpp"), Rel(NonMatching, "d_a_obj_roll_rock", "REL/d/a/obj/d_a_obj_roll_rock.cpp"), Rel(Matching, "d_a_obj_rope_base", "REL/d/a/obj/d_a_obj_rope_base.cpp"), - Rel(NonMatching, "d_a_obj_rope_igaiga", "REL/d/a/obj/d_a_obj_rope_igaiga.cpp"), + Rel(Matching, "d_a_obj_rope_igaiga", "REL/d/a/obj/d_a_obj_rope_igaiga.cpp"), Rel( NonMatching, "d_a_obj_rotation_light", "REL/d/a/obj/d_a_obj_rotation_light.cpp" ), diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index 6df2237e..e746985a 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -189,6 +189,10 @@ public: return mRoomID; } + bool isRoomID(s8 room) const { + return mRoomID == room; + } + void unsetActorProperty(u32 property) { mActorProperties &= ~property; } @@ -199,8 +203,8 @@ public: return mActorProperties & property; } - dAcBase_c* searchNextActor(dAcBase_c* parent) { - return static_cast(fManager_c::searchBaseByGroupType(dAcBase_c::ACTOR, parent)); + dAcBase_c *searchNextActor(dAcBase_c *parent) { + return static_cast(fManager_c::searchBaseByGroupType(dAcBase_c::ACTOR, parent)); } public: diff --git a/include/d/a/obj/d_a_obj_ivy_rope.h b/include/d/a/obj/d_a_obj_ivy_rope.h index 3cbb6a31..09038c43 100644 --- a/include/d/a/obj/d_a_obj_ivy_rope.h +++ b/include/d/a/obj/d_a_obj_ivy_rope.h @@ -15,7 +15,6 @@ #include "toBeSorted/attention.h" #include "toBeSorted/d_path.h" - class dAcOivyRope_c : public dAcObjBase_c { public: dAcOivyRope_c() : field_0x330(0), mStateMgr(*this, sStateID::null), mStts2(this), mEvent(*this, nullptr) {} @@ -140,6 +139,28 @@ public: return mSubtype == sub; } + mVec3_c *getPnts2() { + return mPnts2; + } + + mVec3_c &getTightRopeEnd() { + return mTightropeEnd; + } + + mVec3_c &getTightRopeStart() { + return mTightropeStart; + } + + bool getField_0x1002() { + return field_0x1002; + } + + bool getField_0x1087() { + return field_0x1087; + } + + static const f32 lbl_256_rodata_40; + private: /* 0x 330 */ UNKWORD field_0x330; /* 0x 334 */ m3d::smdl_c mMdlArr[2]; @@ -204,7 +225,9 @@ private: /* 0x FF6 */ u8 field_0xFF6; /* 0x FF7 */ u8 field_0xFF7; /* 0x FF8 */ u8 field_0xFF8; - /* 0x FF9 */ u8 _FF9[0x1005 - 0xFF9]; + /* 0x FF9 */ u8 _FF9[0x1002 - 0xFF9]; + /* 0x1002 */ bool field_0x1002; + /* 0x1003 */ u8 _1003[0x1005 - 0x1003]; /* 0x1005 */ u8 field_0x1005; /* 0x1006 */ u8 _1006[0x1010 - 0x1006]; /* 0x1010 */ mVec3_c field_0x1010; @@ -235,7 +258,8 @@ private: /* 0x106C */ f32 field_0x106C; /* 0x1070 */ u8 _1070[0x1083 - 0x1070]; /* 0x1083 */ u8 field_0x1083; - /* 0x1084 */ u8 _1084[0x1088 - 0x1084]; + /* 0x1084 */ u8 _1084[0x1087 - 0x1084]; + /* 0x1087 */ bool field_0x1087; /* 0x1088 */ dCcD_Cps mCpsArr2[16]; /* 0x2788 */ mVec3_c *mPnts1; /* 0x278C */ mVec3_c *mPnts2; diff --git a/include/d/a/obj/d_a_obj_rope_igaiga.h b/include/d/a/obj/d_a_obj_rope_igaiga.h index 1b64f23f..ee41bb10 100644 --- a/include/d/a/obj/d_a_obj_rope_igaiga.h +++ b/include/d/a/obj/d_a_obj_rope_igaiga.h @@ -1,7 +1,14 @@ #ifndef D_A_OBJ_ROPE_IGAIGA_H #define D_A_OBJ_ROPE_IGAIGA_H +#include "d/a/d_a_base.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/a/obj/d_a_obj_ivy_rope.h" +#include "d/col/bg/d_bg_s_acch.h" +#include "d/col/cc/d_cc_d.h" +#include "m/m3d/m_smdl.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" @@ -10,6 +17,24 @@ public: dAcOropeIgaiga_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcOropeIgaiga_c() {} + virtual bool createHeap() override; + virtual int create() override; + virtual int doDelete() override; + virtual int actorExecute() override; + virtual int draw() override; + + u32 fn_257_1CA0(); + s32 fn_257_1D20(); + void fn_257_1DF0(); + void fn_257_1F20(); + void fn_257_1FD0(); + bool fn_257_1FF0(f32 *, bool); + void fn_257_20F0(f32, f32); + void fn_257_21A0(); + bool fn_257_21D0(); + bool fn_257_2310(s16 rotationOffset); + bool fn_257_2720(); + STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Init); STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Rope); STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Ground); @@ -18,7 +43,56 @@ public: STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Water); private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOropeIgaiga_c); + /* 0x330 */ nw4r::g3d::ResFile mResFile; + /* 0x334 */ m3d ::smdl_c mMdl; + /* 0x350 */ dCcD_Sph mCollider; + /* 0x4A0 */ dBgS_AcchCir mAcchCir; + /* 0x4FC */ dBgS_ObjAcch mObjAcch; + /* 0x8AC */ STATE_MGR_DECLARE(dAcOropeIgaiga_c); + /* 0x8E8 */ dAcRef_c ivyRopeRef; + /* 0x8F4 */ mVec3_c mPositionOffset; + /* 0x900 */ mVec3_c mPositionRelated; + /* 0x90C */ mVec3_c mLinkPosDiff; + /* 0x918 */ u16 mRopeTimer; + /* 0x91A */ u16 field_0x91A; + /* 0x91C */ s16 mRotationYOffset; + /* 0x91E */ s16 field_0x91E; + /* 0x920 */ s16 mRotationXOffset; + /* 0x922 */ u8 field_0x922; + /* 0x923 */ u8 mPnts2Idx; + /* 0x924 */ u8 mInitTimer; + /* 0x925 */ u8 mStartStateTree; + /* 0x926 */ u8 mSceneflag; + /* 0x927 */ u8 mStickTimer; + /* 0x928 */ u8 field_0x928; + /* 0x929 */ u8 mGroundTimer; + /* 0x92A */ s8 mVelocityYRelated; + /* 0x92C */ f32 mLinkSpeedRelated; + /* 0x930 */ f32 mPositionYRelated; + /* 0x934 */ f32 mVecCylCalcFactor; + /* 0x938 */ bool field_0x938; + /* 0x939 */ bool mLinkShieldBash; + /* 0x93A */ bool mLinkHigher; + /* 0x93B */ bool mIdleOnVinesNoStamina; + /* 0x93C */ bool mSoundPlayed; + + static dCcD_SrcSph sSphSrc; + static const s16 sRopeTimerMin1; + static const s16 sRopeTimerMin2; + static const f32 lbl_257_rodata_4[3]; + static const s16 lbl_257_rodata_10; + static const s16 lbl_257_rodata_12; + static const s16 lbl_257_rodata_14; + static const s16 lbl_257_rodata_16; + static const s16 lbl_257_rodata_18; + static const s16 lbl_257_rodata_1A; + static const s16 lbl_257_rodata_1C; + static const s16 lbl_257_rodata_1E; + static const s16 lbl_257_rodata_20; + static const f32 lbl_257_rodata_28; + static const s16 lbl_257_rodata_90; + static const f32 sSquareXZDistanceThreshold; + static const f32 sFloats2[6]; }; #endif diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index 73be114a..0fe8de42 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -878,7 +878,7 @@ public: return mTg.ChkSet(); } - + bool ChkAtEffCounter() { return mAt.ChkEffCounter(); } bool ChkTgEffCounter() { return mTg.ChkEffCounter(); } void ClrAtEffCounter() { mAt.ClrEffCounter(); } @@ -905,7 +905,7 @@ public: return mAt.MskSPrm(0x40); } u32 ChkCoNoCoHitInfSet() const { - return mCo.MskSPrm(0x800); + return mCo.MskSPrm(0x800); } // At @@ -1012,6 +1012,9 @@ public: void OnCoSet() { mCo.OnSPrm(1); } + void OffCoSet() { + mCo.OffSPrm(1); + } u32 ChkCoSet2() const { return mCo.MskSPrm(0x800); } diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index f3eab389..2a948aa8 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -545,6 +545,10 @@ public: return (someFlags_0x350 & mask) != 0; } + inline bool checkFlags0x354(u32 mask) const { + return (someFlags_0x354 & mask) != 0; + } + inline void onFlags_0x358(u32 mask) { someFlags_0x358 |= mask; } @@ -592,6 +596,10 @@ public: return mCurrentAction == 0xAD || mCurrentAction == 0xAE; } + bool checkSwordAndMoreStates(u32 mask) { + return mSwordAndMoreStates & mask; + } + void onModelUpdateFlag(u32 mask) { mModelUpdateFlags |= mask; } diff --git a/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp b/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp index bd426433..b6115020 100644 --- a/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp +++ b/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp @@ -79,6 +79,8 @@ dCcD_SrcCyl dAcOivyRope_c::sCylSrc = { {10.f, 750.f} }; +const f32 dAcOivyRope_c::lbl_256_rodata_40 = 0.04f; + dAcOivyRope_c::~dAcOivyRope_c() { if (mPnts1) { delete[] mPnts1; diff --git a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp index 1d80fc4a..6f056264 100644 --- a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp +++ b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp @@ -1,5 +1,28 @@ #include "d/a/obj/d_a_obj_rope_igaiga.h" +#include "c/c_lib.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_base.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/bg/d_bg_s_wtr_chk.h" +#include "d/col/c/c_cc_d.h" +#include "d/col/cc/d_cc_s.h" +#include "d/flag/sceneflag_manager.h" +#include "d/snd/d_snd_wzsound.h" +#include "f/f_base.h" +#include "f/f_profile_name.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/math/math_arithmetic.h" +#include "nw4r/ut/ut_Color.h" +#include "rvl/GX/GXTypes.h" +#include "s/s_Math.h" +#include "toBeSorted/d_emitter.h" + SPECIAL_ACTOR_PROFILE(OBJ_ROPE_IGAIGA, dAcOropeIgaiga_c, fProfile::OBJ_ROPE_IGAIGA, 0x265, 0, 2); STATE_DEFINE(dAcOropeIgaiga_c, Init); @@ -9,21 +32,752 @@ STATE_DEFINE(dAcOropeIgaiga_c, Tree); STATE_DEFINE(dAcOropeIgaiga_c, Stick); STATE_DEFINE(dAcOropeIgaiga_c, Water); +dCcD_SrcSph dAcOropeIgaiga_c::sSphSrc = { + /* mObjInf */ + {/* mObjAt */ {0x400, 0x1F, {0, 0, 0}, 1, 0, 0, 0, 0, 0}, + /* mObjTg */ {0xFEB77DFF, 0x311, {0, 0, 0x407}, 0, 0}, + /* mObjCo */ {0xA9}}, + /* mSphInf */ + {20.f}, +}; + +const s16 dAcOropeIgaiga_c::sRopeTimerMin1 = 0x2D; +const s16 dAcOropeIgaiga_c::sRopeTimerMin2 = 0x3C; +const f32 dAcOropeIgaiga_c::lbl_257_rodata_4[3] = {500.f, 250.f, 50.f}; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_10 = 0x96; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_12 = 0x64; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_14 = 0x41; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_16 = 0x41; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_18 = 0x64; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_1A = 0x64; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_1C = 0x4; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_1E = 0x41; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_20 = 0x64; +const f32 dAcOropeIgaiga_c::lbl_257_rodata_28 = 20.f; + +// copy from d_a_obj_fairy - TODO move it to a shared file +inline static void vecCylCalc(mVec3_c &target, const mAng &rot, f32 factor) { + target.x += factor * rot.sin(); + target.z += factor * rot.cos(); +} + +bool dAcOropeIgaiga_c::createHeap() { + void *data = getOarcResFile("NeedleBall"); + if (data == nullptr) { + return false; + } + mResFile = nw4r::g3d::ResFile(data); + nw4r::g3d::ResMdl mdl = mResFile.GetResMdl("NeedleBall"); + TRY_CREATE(mMdl.create(mdl, &mAllocator, 0x120, 1, nullptr)); + return true; +} + +int dAcOropeIgaiga_c::create() { + mStartStateTree = getFromParams(0, 0xF); + if (mStartStateTree >= 2) { + mStartStateTree = 0; + } + mSceneflag = getFromParams(4, 0xFF); + CREATE_ALLOCATOR(dAcOropeIgaiga_c); + mObjAcch.Set(&mPosition, &mOldPosition, this, 1, &mAcchCir, &mVelocity, nullptr, nullptr); + mAcchCir.SetWall(20.0f, 20.0f); + mStts.mRank = 0; + mCollider.Set(sSphSrc); + mCollider.SetStts(mStts); + mCollider.ClrAtSet(); + mAcceleration = 0.0f; + mMaxSpeed = -100.0f; + mInitTimer = 5; + mPnts2Idx = 0xff; + field_0x91E = -1; + field_0x928 = 0xff; + if (mStartStateTree == 1) { + mStateMgr.changeState(StateID_Tree); + } else { + mStateMgr.changeState(StateID_Init); + } + mBoundingBox.Set(mVec3_c(-50.0f, -50.0f, -50.0f), mVec3_c(50.0f, 50.0f, 50.0f)); + return SUCCEEDED; +} + +int dAcOropeIgaiga_c::doDelete() { + return SUCCEEDED; +} + +int dAcOropeIgaiga_c::actorExecute() { + mStateMgr.executeState(); + if (field_0x91E >= 0) { + u8 red = 0; + if (field_0x91E < 0x3C) { + if ((field_0x91E / 3 & 1) == 0) { + red = 0xff; + if (!mSoundPlayed) { + startSound(SE_RopeIga_COUNT); + mSoundPlayed = true; + } + } else { + mSoundPlayed = false; + } + } else if ((field_0x91E & 4) != 0) { + red = 0xff; + if (!mSoundPlayed) { + startSound(SE_RopeIga_COUNT); + mSoundPlayed = true; + } + } else { + mSoundPlayed = false; + } + + mMdl.setTevKColorAll(GX_KCOLOR3, mColor(red, 0, 0, 0xff), false); + } + f32 prevYPosition = mPosition.y; + mPosition.y += 20.0f; + mCollider.SetC(mPosition); + dCcS::GetInstance()->Set(&mCollider); + updateMatrix(); + mMdl.setLocalMtx(mWorldMtx); + mPosition.y = prevYPosition; + return SUCCEEDED; +} + +int dAcOropeIgaiga_c::draw() { + drawModelType1(&mMdl); + return SUCCEEDED; +} + void dAcOropeIgaiga_c::initializeState_Init() {} -void dAcOropeIgaiga_c::executeState_Init() {} -void dAcOropeIgaiga_c::finalizeState_Init() {} -void dAcOropeIgaiga_c::initializeState_Rope() {} -void dAcOropeIgaiga_c::executeState_Rope() {} + +void dAcOropeIgaiga_c::executeState_Init() { + if (mInitTimer != 0) { + mInitTimer--; + if (mCollider.ChkCoHit()) { + dAcOivyRope_c *rope = (dAcOivyRope_c *)mCollider.GetCoActor(); + if (rope != NULL && (rope->mProfileName == fProfile::OBJ_IVY_ROPE) && rope->checkSubtype(1)) { + ivyRopeRef.link(rope); + mInitTimer = 0; + mPnts2Idx = 0.5f + mPosition.distance(rope->mPosition) * rope->lbl_256_rodata_40; + mPosition = rope->getPnts2()[mPnts2Idx]; + f32 vecCylCalcFactor = cM::rndF(5.f) + 15.f; + mPositionOffset.x = 0.f; + mPositionOffset.y = 0.f; + mPositionOffset.z = 0.f; + s16 ang1 = cLib::targetAngleY(rope->getTightRopeEnd(), rope->getTightRopeStart()); + s16 ang2 = cM::rndInt(100) & 1 ? -1 : 1; + vecCylCalc(mPositionOffset, ang1 + ang2 * 0x4000, vecCylCalcFactor); + f32 positionYOffset = cM::rndFX(15.f); + mPositionOffset.y += positionYOffset; + mPosition += mPositionOffset; + mPositionRelated = mPosition; + } + } + } else if (mPnts2Idx == 255) { + mStateMgr.changeState(StateID_Ground); + mVelocityYRelated = 1; + } else { + mStateMgr.changeState(StateID_Rope); + } +} + +void dAcOropeIgaiga_c::finalizeState_Init() { + mCollider.mCo.SetGrp(mCollider.mCo.mSrc.mSPrm & 0x160); +} + +void dAcOropeIgaiga_c::initializeState_Rope() { + mAcceleration = -3.0f; +} + +void dAcOropeIgaiga_c::executeState_Rope() { + if (mRopeTimer != 0) { + mRopeTimer--; + } else { + field_0x922 = 0; + } + mVec3_c pos = mPosition; + bool rope0x1087 = false; + bool rope0x1002 = false; + dAcOivyRope_c *rope = ivyRopeRef.get(); + if (rope != nullptr) { + rope0x1002 = rope->getField_0x1002(); + rope0x1087 = rope->getField_0x1087(); + if (rope0x1002) { + pos.y = rope->getPnts2()[mPnts2Idx].y; + pos.y += mPositionOffset.y; + } else { + pos = rope->getPnts2()[mPnts2Idx]; + pos += mPositionOffset; + } + pos.y -= 20.f; + } + if (rope0x1087) { + s32 val = fn_257_1CA0(); + if (val > 0) { + u32 ropeTimerMin = sRopeTimerMin1; + field_0x922 += val; + if (val == 2) { + ropeTimerMin = sRopeTimerMin2; + } + if (ropeTimerMin > mRopeTimer) { + mRopeTimer = ropeTimerMin; + } + + if (mVelocityYRelated == 0) { + mVelocityYRelated = val + 1; + mVelocity.y = 5.f * mVelocityYRelated; + fn_257_1F20(); + } + } + } + if (mVelocityYRelated > 0) { + mRotation.x += mRotationXOffset; + calcVelocity(); + mPosition += mVelocity; + if (mPosition.y < pos.y) { + mPosition.y = pos.y; + mVelocityYRelated -= 1; + if (mVelocityYRelated != 0) { + mVelocity.y = 7.f * mVelocityYRelated; + } + } + } + if (mVelocityYRelated == 0) { + if (rope0x1002) { + sLib::addCalc(&mPosition.y, pos.y, 0.5f, 20.f, 3.f); + } else { + cLib::addCalcPos(&mPosition, pos, 0.5f, 20.f, 3.f); + } + } + s32 val = fn_257_1D20(); + fn_257_1DF0(); + if (val == 1) { + mStateMgr.changeState(StateID_Stick); + } else if (val == 3) { + mStateMgr.changeState(StateID_Ground); + } else if (field_0x922 >= 3) { + mAngle.y = cM::rndInt(0xFFFF); + mSpeed = 5.f; + mVelocity.y = 20.f; + mStateMgr.changeState(StateID_Ground); + } +} + void dAcOropeIgaiga_c::finalizeState_Rope() {} -void dAcOropeIgaiga_c::initializeState_Ground() {} -void dAcOropeIgaiga_c::executeState_Ground() {} + +void dAcOropeIgaiga_c::initializeState_Ground() { + mVelocityYRelated = -1; + mAcceleration = -4.f; + mStts.SetRank(0); + fn_257_1F20(); + mGroundTimer = 0x1e; +} + +void dAcOropeIgaiga_c::executeState_Ground() { + if (mGroundTimer != 0) { + mGroundTimer--; + } + s32 a = fn_257_1D20(); + fn_257_1DF0(); + calcVelocity(); + mPosition += mVelocity; + if (a != 0) { + if (mVelocityYRelated == 0) { + fn_257_20F0(5.f, 10.f); + } + } + if (mVelocityYRelated != 0) { + mObjAcch.CrrPos(*dBgS::GetInstance()); + if (mObjAcch.ChkGndHit()) { + if (mVelocityYRelated == -1) { + mVelocityYRelated = 3; + mSpeed = 3.f; + s16 angleYOffset = cM::rndInt(0x2aab); + if (angleYOffset & 1) { + angleYOffset = -angleYOffset; + } + mAngle.y += angleYOffset; + if (field_0x922 >= 3 || *mStateMgr.getOldStateID() == StateID_Tree) { + fn_257_1FD0(); + } + startSound(SE_RopeIga_GROUND); + } else if (mVelocityYRelated > 0) { + mVelocityYRelated--; + sLib::chase(&mSpeed, 0.f, 1.f); + } + if (mVelocityYRelated > 0) { + mVelocity.y = 7.f * mVelocityYRelated; + } else if (mVelocityYRelated == 0) { + mAcceleration = 0.f; + mSpeed = 0.f; + } + } + } else if (field_0x91E > 0) { + mAcceleration = -4.f; + mObjAcch.CrrPos(*dBgS::GetInstance()); + } + if (mVelocityYRelated != 0 && !mObjAcch.ChkGndHit()) { + mRotation.x += mRotationXOffset; + } + if (a == 1 && mGroundTimer == 0) { + mStateMgr.changeState(StateID_Stick); + } + if (field_0x91E >= 0) { + f32 posY = mPosition.y; + if (fn_257_1FF0(&posY, false)) { + mPositionRelated = mPosition; + mPositionRelated.y = posY - 20.f; + mStateMgr.changeState(StateID_Water); + } + } +} + void dAcOropeIgaiga_c::finalizeState_Ground() {} -void dAcOropeIgaiga_c::initializeState_Tree() {} -void dAcOropeIgaiga_c::executeState_Tree() {} + +void dAcOropeIgaiga_c::initializeState_Tree() { + mAcceleration = 0.0f; +} + +void dAcOropeIgaiga_c::executeState_Tree() { + s32 tmp = fn_257_1D20(); + if (tmp == 1) { + mStateMgr.changeState(StateID_Stick); + } else if (tmp == 3 || SceneflagManager::sInstance->checkBoolFlag(mRoomID, mSceneflag)) { + mStateMgr.changeState(StateID_Ground); + f32 random = cM::rndF(2.f); + mGroundTimer = 0; + mAcceleration = -(3.f + random); + } + fn_257_1DF0(); +} + void dAcOropeIgaiga_c::finalizeState_Tree() {} -void dAcOropeIgaiga_c::initializeState_Stick() {} -void dAcOropeIgaiga_c::executeState_Stick() {} -void dAcOropeIgaiga_c::finalizeState_Stick() {} -void dAcOropeIgaiga_c::initializeState_Water() {} -void dAcOropeIgaiga_c::executeState_Water() {} -void dAcOropeIgaiga_c::finalizeState_Water() {} + +void dAcOropeIgaiga_c::initializeState_Stick() { + mStts.SetRank(0); + mStickTimer = 10; + mVelocity.y = 17.f; + mAcceleration = -3.f; + if (dAcPy_c::GetLink()->getCenterTranslation().y > mPosition.y) { + mLinkHigher = true; + } else { + mLinkHigher = false; + } + u32 random; + if (mLinkHigher) { + random = cM::rndInt(400) + 200; + } else { + random = cM::rndInt(600); + } + field_0x928 = random / 100; + if (field_0x928 > 5) { + field_0x928 = 5; + } + field_0x91A = 0; + mCollider.ClrTgSet(); + f32 rnd = cM::rndF(10.f); + mVelocity.y = rnd + 3.f; + if (dAcPy_c::GetLink()->checkActionFlags(0x10000)) { + s16 rotationYOffset = cM::rndInt(0x31C7) + 0x38e4; + f32 f1 = (rotationYOffset - 0x38E4) / 12743.f; + if (f1 > 1.f) { + f1 = 1.f; + } else if (f1 < 0.f) { + f1 = 0.f; + } + f32 f2 = cM::rndF(3.f) + 15.f; + mVecCylCalcFactor = 15.f * f1 + f2; + if ((field_0x928 & 1) == 0) { + rotationYOffset = -rotationYOffset; + } + mRotationYOffset = rotationYOffset; + } else { + if (field_0x928 >= 4) { + mVecCylCalcFactor = cM::rndF(10.f); + } else { + mVecCylCalcFactor = cM::rndF(35.f); + } + s16 rotationYOffset = cM::rndInt(0x1555) + 0x2aab; + if ((field_0x928 & 1) == 0) { + rotationYOffset = -rotationYOffset; + } + if (field_0x928 >= 4) { + rotationYOffset += cM::rndInt(0x1555) + 0x2aab; + } + mRotationYOffset = rotationYOffset; + } + mLinkPosDiff = mPosition - dAcPy_c::GetLink()->getCenterTranslation(); + if (dAcPy_c::GetLink()->getCurrentAction() == 0x25 /* (IDL_ON_VINES|NO_STAMINA) */) { + mIdleOnVinesNoStamina = true; + } else { + mIdleOnVinesNoStamina = false; + } +} + +void dAcOropeIgaiga_c::executeState_Stick() { + const dAcPy_c *link = dAcPy_c::GetLink(); + f32 posY = mPosition.y; + if (fn_257_1FF0(&posY, false)) { + mPositionRelated = mPosition; + mPositionRelated.y = posY - 20.f; + mStateMgr.changeState(StateID_Water); + } else if (link->checkActionFlags(0x40000) || !link->checkFlags0x340(0x100)) { + fn_257_1FF0(&posY, true); + mPositionRelated = mPosition; + mPositionRelated.y = posY - 20.f; + mPosition.y = posY - 20.f; + mStateMgr.changeState(StateID_Water); + fn_257_21A0(); + } else if (fn_257_2310(mRotationYOffset)) { + fn_257_1DF0(); + mVec3_c linkPos = dAcPy_c::GetLink()->getCenterTranslation(); + + f32 linkPosDiffAbsXZ = mLinkPosDiff.absXZ(); + if (mIdleOnVinesNoStamina) { + linkPosDiffAbsXZ *= 0.3f; + } + if (!dAcPy_c::GetLinkM()->isRoomID(mRoomID)) { + mAngle.y = cM::rndInt(0x7fff); + mSpeed = 13.f; + mVelocity.y = 20.f; + mStateMgr.changeState(StateID_Ground); + } else { + vecCylCalc(linkPos, dAcPy_c::GetLink()->mRotation.y + mRotationYOffset, linkPosDiffAbsXZ); + linkPos.y += mLinkPosDiff.y; + mRotation.y = cLib::targetAngleY(linkPos, dAcPy_c::GetLink()->mPosition); + mPosition.x = linkPos.x; + mPosition.z = linkPos.z; + if (mVelocityYRelated > 0) { + mAcceleration = -3.5f; + mRotation.x += mRotationXOffset; + calcVelocity(); + mPosition += mVelocity; + if (mPosition.y < linkPos.y) { + mPosition.y = linkPos.y; + mVelocityYRelated--; + if (mVelocityYRelated != 0) { + mVelocity.y = 3.f * mLinkSpeedRelated * mVelocityYRelated; + } + } + } else { + mPosition.y = linkPos.y; + f32 linkSpeedRelated = dAcPy_c::GetLink()->mSpeed / 20.f; + if (linkSpeedRelated > 1.f) { + linkSpeedRelated = 1.f; + } + if (dAcPy_c::GetLinkM()->checkActionFlags(0xc70852)) { + field_0x938 = true; + } else if (field_0x938) { + field_0x938 = false; + linkSpeedRelated = 1.f; + } + mLinkSpeedRelated = linkSpeedRelated; + if (linkSpeedRelated < 0.3f) { + mVelocityYRelated = 0; + } else { + mVelocityYRelated = 3; + mLinkSpeedRelated += cM::rndFX(0.15f); + } + mRotationXOffset = mLinkSpeedRelated * 910.f; + } + if (fn_257_21D0()) { + mAngle.y = cM::rndInt(0x7fff); + mSpeed = 13.f; + mVelocity.y = 20.f; + mStateMgr.changeState(StateID_Ground); + } + } + } +} + +void dAcOropeIgaiga_c::finalizeState_Stick() { + field_0x928 = 0xff; + mCollider.OnTgSet(); + mCollider.OnCoSet(); +} + +void dAcOropeIgaiga_c::initializeState_Water() { + mStts.SetRank(5); + mRotationXOffset = 100; + mPositionYRelated = mPositionRelated.y - 2.0f; + fn_257_20F0(3.f, 10.f); +} + +const s16 dAcOropeIgaiga_c::lbl_257_rodata_90 = 0x2d8; + +void dAcOropeIgaiga_c::executeState_Water() { + fn_257_1D20(); + fn_257_1DF0(); + if (mVelocityYRelated != 0) { + calcVelocity(); + mPosition += mVelocity; + mPosition += mStts.mCcMove; + } + + if (mVelocityYRelated != 0) { + if (fn_257_1FF0(nullptr, 0) != 0) { + mVelocityYRelated--; + if (mVelocityYRelated > 0) { + sLib::chase(&mSpeed, 0, 1.f); + mVelocity.y = 7.f * mVelocityYRelated; + } else { + fn_257_21A0(); + } + } + } else { + f32 f1 = 0.1f; + if (fn_257_1D20() == 1) { + mSpeed = 8.5f; + mAngle.y = cLib::targetAngleY(dAcPy_c::GetLink()->mPosition, mPosition); + } + sLib::chase(&mSpeed, 0, 1.f); + + if (!cM::isZero(mSpeed)) { + calcVelocity(); + mPosition += mVelocity; + mPosition += mStts.mCcMove; + mRotation.x += mAng(0x2d8); + f1 = 2.f; + } + if (sLib::chase(&mPosition.y, mPositionYRelated, f1) != 0) { + if (mPositionYRelated > mPositionRelated.y) { + mPositionYRelated = mPositionRelated.y - 2.f; + } else { + mPositionYRelated = mPositionRelated.y + 1.f; + } + } + } + if (mObjAcch.ChkGndHit()) { + mStateMgr.changeState(StateID_Ground); + mVelocityYRelated = 0; + } + mObjAcch.CrrPos(*dBgS::GetInstance()); +} + +void dAcOropeIgaiga_c::finalizeState_Water() { + mVelocityYRelated = 0; + mStts.SetRank(0); + fn_257_21A0(); +} + +u32 dAcOropeIgaiga_c::fn_257_1CA0() { + f32 distThresh1 = 62500.0f; + f32 distThresh2 = 250000.0f; + f32 squareMagXZ = dAcPy_c::GetLink()->mPosition.squareDistanceToXZ(mPosition); + if (squareMagXZ < distThresh1) { + return 2; + } + return squareMagXZ < distThresh2; +} + +s32 dAcOropeIgaiga_c::fn_257_1D20() { + if (fn_257_2720()) { + fn_257_1FD0(); + return 1; + } + if (mCollider.ChkTgHit()) { + fn_257_1FD0(); + if (mCollider.ChkTgAtHitType(2)) { + startSound(SE_SW_HIT_RopeIga); + } + dAcObjBase_c *tgActor = mCollider.GetTgActor(); + if (tgActor != nullptr && tgActor->mProfileName == fProfile::OBJ_ROPE_IGAIGA) { + return 2; + } + return 3; + } + return 0; +} + +void dAcOropeIgaiga_c::fn_257_1DF0() { + if (field_0x91E > 0) { + field_0x91E--; + if (field_0x91E == 3) { + mCollider.OnAtSet(); + mCollider.SetR(50.f); + mCollider.mCo.OffSPrm(1); + mVec3_c pos = mPosition; + pos.y += 20.f; + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_498_, pos, nullptr, nullptr, nullptr, nullptr, 0, 0 + ); + startSound(SE_RopeIga_EXPLODE); + } else if (field_0x91E == 0) { + deleteRequest(); + } + if ((u16)(field_0x91E - 1) <= 1) { + if (mCollider.ChkAtHit()) { + deleteRequest(); + } + } + } +} + +void dAcOropeIgaiga_c::fn_257_1F20() { + s16 ang = mStateMgr.isState(StateID_Rope) ? 0xb6 : 0x4fa; + s16 random = cM::rndInt(0x222); + s32 ang2 = ang + random; + if (ang2 & 1) { + ang2 = (s16)-ang2; + } + mRotationXOffset = ang2; +} + +void dAcOropeIgaiga_c::fn_257_1FD0() { + if (field_0x91E != -1) { + return; + } + field_0x91E = 0x99; +} + +bool dAcOropeIgaiga_c::fn_257_1FF0(f32 *posY, bool p2) { + if (p2 || mVelocity.y < 0.f) { + mVec3_c _pos = mPosition; + f32 f1 = p2 ? 200.f : 50.f; + f32 f2 = p2 ? -200.f : -30.f; + if (dBgS_WtrChk::CheckPos(&mPosition, true, f1, f2)) { + f32 waterHeight = dBgS_WtrChk::GetWaterHeight(); + if (p2 || mPosition.y < waterHeight - 20.f) { + if (posY != nullptr) { + *posY = waterHeight; + } + return true; + } + } + } + return false; +} + +void dAcOropeIgaiga_c::fn_257_20F0(f32 speed, f32 velocityY) { + fn_257_1F20(); + mVelocityYRelated = 3; + mSpeed = speed; + mAngle.y = cLib::targetAngleY(dAcPy_c::GetLink()->mPosition, mPosition); + s16 angleOffset = cM::rndInt(0x2aab); + if (angleOffset & 1) { + angleOffset = -angleOffset; + } + mAngle.y += angleOffset; + mVelocity.y = velocityY; + mAcceleration = -4.f; +} + +void dAcOropeIgaiga_c::fn_257_21A0() { + mVelocityYRelated = 0; + mVelocity.y = 0.f; + mAcceleration = 0.f; + mSpeed = 0.f; + mRotationXOffset = 100; +} + +bool dAcOropeIgaiga_c::fn_257_21D0() { + if (field_0x91A != 0) { + field_0x91A--; + } + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link->getCurrentAction() == 0x49 /* SHIELD_BASH */) { + if (!mLinkShieldBash) { + field_0x91A += lbl_257_rodata_1E; + } + mLinkShieldBash = true; + } else { + mLinkShieldBash = false; + if (link->checkFlags0x354(0x2000)) { + field_0x91A += lbl_257_rodata_14; + } else if (link->checkFlags0x354(0x4)) { + field_0x91A += lbl_257_rodata_16; + } else if (link->getCurrentAction() == 0xC /* ROLL */) { + field_0x91A += lbl_257_rodata_18; + } else if (link->getCurrentAction() == 0x27 /* START_VINE_LEAP */) { + field_0x91A += lbl_257_rodata_1A; + } else if (link->checkSwordAndMoreStates(0x40) /* SPRINTING */) { + field_0x91A += lbl_257_rodata_1C; + } + } + if (mIdleOnVinesNoStamina) { + if (dAcPy_c::GetLink()->getCurrentAction() != 0x25 /* (IDL_ON_VINES|NO_STAMINA) */) { + field_0x91A += lbl_257_rodata_20; + } + } else if (dAcPy_c::GetLink()->getCurrentAction() == 0x25) { + mIdleOnVinesNoStamina = true; + } + if ((s32)field_0x91A >= 100) { + return true; + } + return false; +} + +const f32 dAcOropeIgaiga_c::sFloats2[6] = {20.f, 30.f, -55.f, -65.f, -25.f, -35.f}; + +bool dAcOropeIgaiga_c::fn_257_2310(s16 rotationYOffset) { + if (mStickTimer != 0) { + mVec3_c translation = dAcPy_c::GetLink()->getCenterTranslation(); + vecCylCalc(translation, dAcPy_c::GetLink()->mRotation.y + rotationYOffset, mVecCylCalcFactor); + translation.y += sFloats2[field_0x928]; + if (mStickTimer == 10 && field_0x928 < 4) { + mVec3_c pos = dAcPy_c::GetLink()->mPosition; + s16 ang1 = cLib::targetAngleY(pos, mPosition); + s16 ang2 = cLib::targetAngleY(pos, translation); + if (sLib::absDiff(ang1, ang2) > 0x471C) { + if (field_0x928 & 1) { + field_0x928--; + } else { + field_0x928++; + } + if (field_0x928 > 5) { + field_0x928 = 5; + } + } + } + mStickTimer--; + mRotation.y = cLib::targetAngleY(mPosition, dAcPy_c::GetLink()->mPosition); + mRotation.x += mRotationXOffset; + cLib::addCalcPosXZ(&mPosition, translation, 0.3f, 10.f, 1.f); + calcVelocity(); + if (mLinkHigher) { + if (mVelocity.y < -5.f) { + mVelocity.y = 10.f; + } + if (mPosition.y > translation.y) { + mVelocity.y = 0.f; + if (mStickTimer > 10) { + mStickTimer = 0; + } + } else { + mPosition.y += mVelocity.y; + } + } else { + if (mVelocity.y < -15.f) { + mVelocity.y = 0.f; + } + mPosition.y += mVelocity.y; + if (mPosition.y < translation.y) { + mVelocity.y = 10.f; + if (mStickTimer > 10) { + mStickTimer = 0; + } + } + } + if (fn_257_2720()) { + mLinkPosDiff = mPosition - dAcPy_c::GetLink()->getCenterTranslation(); + } else { + if (dAcPy_c::GetLinkM()->checkActionFlags(0xc70852) == 0) { + translation = (translation + mPosition) * 0.5f; + } + mLinkPosDiff = translation - dAcPy_c::GetLink()->getCenterTranslation(); + mStickTimer = 0; + } + return false; + } + mCollider.OffCoSet(); + return true; +} + +bool dAcOropeIgaiga_c::fn_257_2720() { + if (mCollider.ChkCoHit()) { + if (mCollider.GetCoActor()->isPlayer() && + dAcPy_c::GetLink()->getCenterTranslation().squareDistanceToXZ(mPosition) < 1600.f) { + return true; + } + } + return false; +} + +const f32 dAcOropeIgaiga_c::sSquareXZDistanceThreshold = 1600.f; From 0c7bef64fe850a76827e91495db4c0a797175a8a Mon Sep 17 00:00:00 2001 From: swekka Date: Sat, 20 Dec 2025 18:20:36 +0100 Subject: [PATCH 2/4] d_a_obj_rope_igaiga OK --- .../rels/d_a_obj_ivy_ropeNP/symbols.txt | 2 +- .../rels/d_a_obj_rope_igaigaNP/symbols.txt | 86 +- configure.py | 2 +- include/d/a/d_a_base.h | 8 +- include/d/a/obj/d_a_obj_ivy_rope.h | 30 +- include/d/a/obj/d_a_obj_rope_igaiga.h | 76 +- include/d/col/c/c_cc_d.h | 7 +- include/d/d_player_act.h | 8 + src/REL/d/a/obj/d_a_obj_ivy_rope.cpp | 2 + src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp | 782 +++++++++++++++++- 10 files changed, 936 insertions(+), 67 deletions(-) diff --git a/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt b/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt index 0035787f..8c232f32 100644 --- a/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_ivy_ropeNP/symbols.txt @@ -161,7 +161,7 @@ _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global lbl_256_rodata_0 = .rodata:0x00000000; // type:object size:0x40 data:float -lbl_256_rodata_40 = .rodata:0x00000040; // type:object size:0x60 +lbl_256_rodata_40__13dAcOivyRope_c = .rodata:0x00000040; // type:object size:0x60 lbl_256_rodata_A0 = .rodata:0x000000A0; // type:object size:0x10 lbl_256_rodata_B0 = .rodata:0x000000B0; // type:object size:0x10 align:4 data:float lbl_256_rodata_C0 = .rodata:0x000000C0; // type:object size:0x8 align:8 data:double diff --git a/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt b/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt index 019eeffb..22beb64c 100644 --- a/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_rope_igaigaNP/symbols.txt @@ -8,13 +8,13 @@ __dt__29sFState_c<16dAcOropeIgaiga_c>Fv = .text:0x000001E0; // type:function siz __dt__32sFStateFct_c<16dAcOropeIgaiga_c>Fv = .text:0x00000240; // type:function size:0x6C __dt__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000002B0; // type:function size:0xA0 __dt__55sFStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c>Fv = .text:0x00000350; // type:function size:0xA4 -fn_257_400 = .text:0x00000400; // type:function size:0x90 -fn_257_490 = .text:0x00000490; // type:function size:0x1A4 +createHeap__16dAcOropeIgaiga_cFv = .text:0x00000400; // type:function size:0x90 +create__16dAcOropeIgaiga_cFv = .text:0x00000490; // type:function size:0x1A4 changeState__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000640; // type:function size:0x10 -fn_257_650 = .text:0x00000650; // type:function size:0x8 -fn_257_660 = .text:0x00000660; // type:function size:0x170 +doDelete__16dAcOropeIgaiga_cFv = .text:0x00000650; // type:function size:0x8 +actorExecute__16dAcOropeIgaiga_cFv = .text:0x00000660; // type:function size:0x170 executeState__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000007D0; // type:function size:0x10 -fn_257_7E0 = .text:0x000007E0; // type:function size:0x28 +draw__16dAcOropeIgaiga_cFv = .text:0x000007E0; // type:function size:0x28 initializeState_Init__16dAcOropeIgaiga_cFv = .text:0x00000810; // type:function size:0x4 executeState_Init__16dAcOropeIgaiga_cFv = .text:0x00000820; // type:function size:0x268 finalizeState_Init__16dAcOropeIgaiga_cFv = .text:0x00000A90; // type:function size:0x10 @@ -34,18 +34,18 @@ finalizeState_Stick__16dAcOropeIgaiga_cFv = .text:0x00001990; // type:function s initializeState_Water__16dAcOropeIgaiga_cFv = .text:0x000019C0; // type:function size:0x34 executeState_Water__16dAcOropeIgaiga_cFv = .text:0x00001A00; // type:function size:0x28C finalizeState_Water__16dAcOropeIgaiga_cFv = .text:0x00001C90; // type:function size:0x10 -fn_257_1CA0 = .text:0x00001CA0; // type:function size:0x7C -fn_257_1D20 = .text:0x00001D20; // type:function size:0xD0 -fn_257_1DF0 = .text:0x00001DF0; // type:function size:0x128 -fn_257_1F20 = .text:0x00001F20; // type:function size:0x98 +fn_257_1CA0__16dAcOropeIgaiga_cFv = .text:0x00001CA0; // type:function size:0x7C +fn_257_1D20__16dAcOropeIgaiga_cFv = .text:0x00001D20; // type:function size:0xD0 +fn_257_1DF0__16dAcOropeIgaiga_cFv = .text:0x00001DF0; // type:function size:0x128 +fn_257_1F20__16dAcOropeIgaiga_cFv = .text:0x00001F20; // type:function size:0x98 getStateID__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00001FC0; // type:function size:0x10 -fn_257_1FD0 = .text:0x00001FD0; // type:function size:0x18 -fn_257_1FF0 = .text:0x00001FF0; // type:function size:0xF8 -fn_257_20F0 = .text:0x000020F0; // type:function size:0xB0 -fn_257_21A0 = .text:0x000021A0; // type:function size:0x28 -fn_257_21D0 = .text:0x000021D0; // type:function size:0x13C -fn_257_2310 = .text:0x00002310; // type:function size:0x408 -fn_257_2720 = .text:0x00002720; // type:function size:0xE0 +fn_257_1FD0__16dAcOropeIgaiga_cFv = .text:0x00001FD0; // type:function size:0x18 +fn_257_1FF0__16dAcOropeIgaiga_cFPfb = .text:0x00001FF0; // type:function size:0xF8 +fn_257_20F0__16dAcOropeIgaiga_cFff = .text:0x000020F0; // type:function size:0xB0 +fn_257_21A0__16dAcOropeIgaiga_cFv = .text:0x000021A0; // type:function size:0x28 +fn_257_21D0__16dAcOropeIgaiga_cFv = .text:0x000021D0; // type:function size:0x13C +fn_257_2310__16dAcOropeIgaiga_cFs = .text:0x00002310; // type:function size:0x408 +fn_257_2720__16dAcOropeIgaiga_cFv = .text:0x00002720; // type:function size:0xE0 __dt__16dAcOropeIgaiga_cFv = .text:0x00002800; // type:function size:0x100 build__32sFStateFct_c<16dAcOropeIgaiga_c>FRC12sStateIDIf_c = .text:0x00002900; // type:function size:0x60 dispose__32sFStateFct_c<16dAcOropeIgaiga_c>FRP10sStateIf_c = .text:0x00002960; // type:function size:0xC @@ -66,32 +66,32 @@ isSameName__31sFStateID_c<16dAcOropeIgaiga_c>CFPCc = .text:0x00002FC0; // type:f _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global -lbl_257_rodata_0 = .rodata:0x00000000; // type:object size:0x28 data:float -lbl_257_rodata_28 = .rodata:0x00000028; // type:object size:0x4 align:4 data:float -lbl_257_rodata_2C = .rodata:0x0000002C; // type:object size:0xC align:4 data:float -lbl_257_rodata_38 = .rodata:0x00000038; // type:object size:0x14 align:4 data:float -lbl_257_rodata_4C = .rodata:0x0000004C; // type:object size:0x8 align:4 data:float -lbl_257_rodata_54 = .rodata:0x00000054; // type:object size:0xC align:4 data:float -lbl_257_rodata_60 = .rodata:0x00000060; // type:object size:0xC align:4 data:float -lbl_257_rodata_6C = .rodata:0x0000006C; // type:object size:0x34 align:4 data:float -lbl_257_rodata_A0 = .rodata:0x000000A0; // type:object size:0x4 align:4 data:float -lbl_257_rodata_A4 = .rodata:0x000000A4; // type:object size:0x34 align:4 data:float -lbl_257_rodata_D8 = .rodata:0x000000D8; // type:object size:0x8 align:4 data:float +lbl_257_rodata_0 = .rodata:0x00000000; // type:object size:0x28 scope:local data:float +lbl_257_rodata_28 = .rodata:0x00000028; // type:object size:0x4 scope:local align:4 data:float +lbl_257_rodata_2C = .rodata:0x0000002C; // type:object size:0xC scope:local align:4 data:float +lbl_257_rodata_38 = .rodata:0x00000038; // type:object size:0x14 scope:local align:4 data:float +lbl_257_rodata_4C = .rodata:0x0000004C; // type:object size:0x8 scope:local align:4 data:float +lbl_257_rodata_54 = .rodata:0x00000054; // type:object size:0xC scope:local align:4 data:float +lbl_257_rodata_60 = .rodata:0x00000060; // type:object size:0xC scope:local align:4 data:float +lbl_257_rodata_6C = .rodata:0x0000006C; // type:object size:0x34 scope:local align:4 data:float +lbl_257_rodata_A0 = .rodata:0x000000A0; // type:object size:0x4 scope:local align:4 data:float +lbl_257_rodata_A4 = .rodata:0x000000A4; // type:object size:0x34 scope:local align:4 data:float +lbl_257_rodata_D8 = .rodata:0x000000D8; // type:object size:0x8 scope:local align:4 data:float g_profile_OBJ_ROPE_IGAIGA = .data:0x00000000; // type:object size:0x10 data:4byte -lbl_257_data_10 = .data:0x00000010; // type:object size:0x2C -lbl_257_data_3C = .data:0x0000003C; // type:object size:0xB data:string -lbl_257_data_48 = .data:0x00000048; // type:object size:0x1E data:string -lbl_257_data_68 = .data:0x00000068; // type:object size:0x80 -lbl_257_data_E8 = .data:0x000000E8; // type:object size:0x30 -lbl_257_data_118 = .data:0x00000118; // type:object size:0x30 -lbl_257_data_148 = .data:0x00000148; // type:object size:0x18 -lbl_257_data_160 = .data:0x00000160; // type:object size:0x1B8 -lbl_257_data_318 = .data:0x00000318; // type:object size:0x34 +lbl_257_data_10 = .data:0x00000010; // type:object size:0x2C scope:local +lbl_257_data_3C = .data:0x0000003C; // type:object size:0xB scope:local data:string +lbl_257_data_48 = .data:0x00000048; // type:object size:0x1E scope:local data:string +__vt__16dAcOropeIgaiga_c = .data:0x00000068; // type:object size:0x80 +__vt__55sFStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c> = .data:0x000000E8; // type:object size:0x30 +__vt__85sStateMgr_c<16dAcOropeIgaiga_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x00000118; // type:object size:0x30 +lbl_257_data_148 = .data:0x00000148; // type:object size:0x18 scope:local +lbl_257_data_160 = .data:0x00000160; // type:object size:0x1B8 scope:local +__vt__31sFStateID_c<16dAcOropeIgaiga_c> = .data:0x00000318; // type:object size:0x34 scope:local __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global -lbl_257_bss_8 = .bss:0x00000008; // type:object size:0x10 data:4byte -lbl_257_bss_18 = .bss:0x00000018; // type:object size:0x40 data:4byte -lbl_257_bss_58 = .bss:0x00000058; // type:object size:0x40 data:4byte -lbl_257_bss_98 = .bss:0x00000098; // type:object size:0x40 data:4byte -lbl_257_bss_D8 = .bss:0x000000D8; // type:object size:0x40 data:4byte -lbl_257_bss_118 = .bss:0x00000118; // type:object size:0x40 data:4byte -lbl_257_bss_158 = .bss:0x00000158; // type:object size:0x30 data:4byte +lbl_257_bss_8 = .bss:0x00000008; // type:object size:0x10 scope:local data:4byte +lbl_257_bss_18 = .bss:0x00000018; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_58 = .bss:0x00000058; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_98 = .bss:0x00000098; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_D8 = .bss:0x000000D8; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_118 = .bss:0x00000118; // type:object size:0x40 scope:local data:4byte +lbl_257_bss_158 = .bss:0x00000158; // type:object size:0x30 scope:local data:4byte diff --git a/configure.py b/configure.py index a0133566..ffb57fe5 100644 --- a/configure.py +++ b/configure.py @@ -2619,7 +2619,7 @@ config.libs = [ Rel(NonMatching, "d_a_obj_roll_pillar", "REL/d/a/obj/d_a_obj_roll_pillar.cpp"), Rel(NonMatching, "d_a_obj_roll_rock", "REL/d/a/obj/d_a_obj_roll_rock.cpp"), Rel(Matching, "d_a_obj_rope_base", "REL/d/a/obj/d_a_obj_rope_base.cpp"), - Rel(NonMatching, "d_a_obj_rope_igaiga", "REL/d/a/obj/d_a_obj_rope_igaiga.cpp"), + Rel(Matching, "d_a_obj_rope_igaiga", "REL/d/a/obj/d_a_obj_rope_igaiga.cpp"), Rel( NonMatching, "d_a_obj_rotation_light", "REL/d/a/obj/d_a_obj_rotation_light.cpp" ), diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index 6df2237e..e746985a 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -189,6 +189,10 @@ public: return mRoomID; } + bool isRoomID(s8 room) const { + return mRoomID == room; + } + void unsetActorProperty(u32 property) { mActorProperties &= ~property; } @@ -199,8 +203,8 @@ public: return mActorProperties & property; } - dAcBase_c* searchNextActor(dAcBase_c* parent) { - return static_cast(fManager_c::searchBaseByGroupType(dAcBase_c::ACTOR, parent)); + dAcBase_c *searchNextActor(dAcBase_c *parent) { + return static_cast(fManager_c::searchBaseByGroupType(dAcBase_c::ACTOR, parent)); } public: diff --git a/include/d/a/obj/d_a_obj_ivy_rope.h b/include/d/a/obj/d_a_obj_ivy_rope.h index 3cbb6a31..09038c43 100644 --- a/include/d/a/obj/d_a_obj_ivy_rope.h +++ b/include/d/a/obj/d_a_obj_ivy_rope.h @@ -15,7 +15,6 @@ #include "toBeSorted/attention.h" #include "toBeSorted/d_path.h" - class dAcOivyRope_c : public dAcObjBase_c { public: dAcOivyRope_c() : field_0x330(0), mStateMgr(*this, sStateID::null), mStts2(this), mEvent(*this, nullptr) {} @@ -140,6 +139,28 @@ public: return mSubtype == sub; } + mVec3_c *getPnts2() { + return mPnts2; + } + + mVec3_c &getTightRopeEnd() { + return mTightropeEnd; + } + + mVec3_c &getTightRopeStart() { + return mTightropeStart; + } + + bool getField_0x1002() { + return field_0x1002; + } + + bool getField_0x1087() { + return field_0x1087; + } + + static const f32 lbl_256_rodata_40; + private: /* 0x 330 */ UNKWORD field_0x330; /* 0x 334 */ m3d::smdl_c mMdlArr[2]; @@ -204,7 +225,9 @@ private: /* 0x FF6 */ u8 field_0xFF6; /* 0x FF7 */ u8 field_0xFF7; /* 0x FF8 */ u8 field_0xFF8; - /* 0x FF9 */ u8 _FF9[0x1005 - 0xFF9]; + /* 0x FF9 */ u8 _FF9[0x1002 - 0xFF9]; + /* 0x1002 */ bool field_0x1002; + /* 0x1003 */ u8 _1003[0x1005 - 0x1003]; /* 0x1005 */ u8 field_0x1005; /* 0x1006 */ u8 _1006[0x1010 - 0x1006]; /* 0x1010 */ mVec3_c field_0x1010; @@ -235,7 +258,8 @@ private: /* 0x106C */ f32 field_0x106C; /* 0x1070 */ u8 _1070[0x1083 - 0x1070]; /* 0x1083 */ u8 field_0x1083; - /* 0x1084 */ u8 _1084[0x1088 - 0x1084]; + /* 0x1084 */ u8 _1084[0x1087 - 0x1084]; + /* 0x1087 */ bool field_0x1087; /* 0x1088 */ dCcD_Cps mCpsArr2[16]; /* 0x2788 */ mVec3_c *mPnts1; /* 0x278C */ mVec3_c *mPnts2; diff --git a/include/d/a/obj/d_a_obj_rope_igaiga.h b/include/d/a/obj/d_a_obj_rope_igaiga.h index 1b64f23f..ee41bb10 100644 --- a/include/d/a/obj/d_a_obj_rope_igaiga.h +++ b/include/d/a/obj/d_a_obj_rope_igaiga.h @@ -1,7 +1,14 @@ #ifndef D_A_OBJ_ROPE_IGAIGA_H #define D_A_OBJ_ROPE_IGAIGA_H +#include "d/a/d_a_base.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/a/obj/d_a_obj_ivy_rope.h" +#include "d/col/bg/d_bg_s_acch.h" +#include "d/col/cc/d_cc_d.h" +#include "m/m3d/m_smdl.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" @@ -10,6 +17,24 @@ public: dAcOropeIgaiga_c() : mStateMgr(*this, sStateID::null) {} virtual ~dAcOropeIgaiga_c() {} + virtual bool createHeap() override; + virtual int create() override; + virtual int doDelete() override; + virtual int actorExecute() override; + virtual int draw() override; + + u32 fn_257_1CA0(); + s32 fn_257_1D20(); + void fn_257_1DF0(); + void fn_257_1F20(); + void fn_257_1FD0(); + bool fn_257_1FF0(f32 *, bool); + void fn_257_20F0(f32, f32); + void fn_257_21A0(); + bool fn_257_21D0(); + bool fn_257_2310(s16 rotationOffset); + bool fn_257_2720(); + STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Init); STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Rope); STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Ground); @@ -18,7 +43,56 @@ public: STATE_FUNC_DECLARE(dAcOropeIgaiga_c, Water); private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOropeIgaiga_c); + /* 0x330 */ nw4r::g3d::ResFile mResFile; + /* 0x334 */ m3d ::smdl_c mMdl; + /* 0x350 */ dCcD_Sph mCollider; + /* 0x4A0 */ dBgS_AcchCir mAcchCir; + /* 0x4FC */ dBgS_ObjAcch mObjAcch; + /* 0x8AC */ STATE_MGR_DECLARE(dAcOropeIgaiga_c); + /* 0x8E8 */ dAcRef_c ivyRopeRef; + /* 0x8F4 */ mVec3_c mPositionOffset; + /* 0x900 */ mVec3_c mPositionRelated; + /* 0x90C */ mVec3_c mLinkPosDiff; + /* 0x918 */ u16 mRopeTimer; + /* 0x91A */ u16 field_0x91A; + /* 0x91C */ s16 mRotationYOffset; + /* 0x91E */ s16 field_0x91E; + /* 0x920 */ s16 mRotationXOffset; + /* 0x922 */ u8 field_0x922; + /* 0x923 */ u8 mPnts2Idx; + /* 0x924 */ u8 mInitTimer; + /* 0x925 */ u8 mStartStateTree; + /* 0x926 */ u8 mSceneflag; + /* 0x927 */ u8 mStickTimer; + /* 0x928 */ u8 field_0x928; + /* 0x929 */ u8 mGroundTimer; + /* 0x92A */ s8 mVelocityYRelated; + /* 0x92C */ f32 mLinkSpeedRelated; + /* 0x930 */ f32 mPositionYRelated; + /* 0x934 */ f32 mVecCylCalcFactor; + /* 0x938 */ bool field_0x938; + /* 0x939 */ bool mLinkShieldBash; + /* 0x93A */ bool mLinkHigher; + /* 0x93B */ bool mIdleOnVinesNoStamina; + /* 0x93C */ bool mSoundPlayed; + + static dCcD_SrcSph sSphSrc; + static const s16 sRopeTimerMin1; + static const s16 sRopeTimerMin2; + static const f32 lbl_257_rodata_4[3]; + static const s16 lbl_257_rodata_10; + static const s16 lbl_257_rodata_12; + static const s16 lbl_257_rodata_14; + static const s16 lbl_257_rodata_16; + static const s16 lbl_257_rodata_18; + static const s16 lbl_257_rodata_1A; + static const s16 lbl_257_rodata_1C; + static const s16 lbl_257_rodata_1E; + static const s16 lbl_257_rodata_20; + static const f32 lbl_257_rodata_28; + static const s16 lbl_257_rodata_90; + static const f32 sSquareXZDistanceThreshold; + static const f32 sFloats2[6]; }; #endif diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index 73be114a..0fe8de42 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -878,7 +878,7 @@ public: return mTg.ChkSet(); } - + bool ChkAtEffCounter() { return mAt.ChkEffCounter(); } bool ChkTgEffCounter() { return mTg.ChkEffCounter(); } void ClrAtEffCounter() { mAt.ClrEffCounter(); } @@ -905,7 +905,7 @@ public: return mAt.MskSPrm(0x40); } u32 ChkCoNoCoHitInfSet() const { - return mCo.MskSPrm(0x800); + return mCo.MskSPrm(0x800); } // At @@ -1012,6 +1012,9 @@ public: void OnCoSet() { mCo.OnSPrm(1); } + void OffCoSet() { + mCo.OffSPrm(1); + } u32 ChkCoSet2() const { return mCo.MskSPrm(0x800); } diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index f3eab389..2a948aa8 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -545,6 +545,10 @@ public: return (someFlags_0x350 & mask) != 0; } + inline bool checkFlags0x354(u32 mask) const { + return (someFlags_0x354 & mask) != 0; + } + inline void onFlags_0x358(u32 mask) { someFlags_0x358 |= mask; } @@ -592,6 +596,10 @@ public: return mCurrentAction == 0xAD || mCurrentAction == 0xAE; } + bool checkSwordAndMoreStates(u32 mask) { + return mSwordAndMoreStates & mask; + } + void onModelUpdateFlag(u32 mask) { mModelUpdateFlags |= mask; } diff --git a/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp b/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp index ecc294ed..ebf95f33 100644 --- a/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp +++ b/src/REL/d/a/obj/d_a_obj_ivy_rope.cpp @@ -74,6 +74,8 @@ dCcD_SrcCyl dAcOivyRope_c::sCylSrc = { {10.f, 750.f} }; +const f32 dAcOivyRope_c::lbl_256_rodata_40 = 0.04f; + dAcOivyRope_c::~dAcOivyRope_c() { if (mPnts1) { delete[] mPnts1; diff --git a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp index 1d80fc4a..6f056264 100644 --- a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp +++ b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp @@ -1,5 +1,28 @@ #include "d/a/obj/d_a_obj_rope_igaiga.h" +#include "c/c_lib.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_base.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/bg/d_bg_s_wtr_chk.h" +#include "d/col/c/c_cc_d.h" +#include "d/col/cc/d_cc_s.h" +#include "d/flag/sceneflag_manager.h" +#include "d/snd/d_snd_wzsound.h" +#include "f/f_base.h" +#include "f/f_profile_name.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/math/math_arithmetic.h" +#include "nw4r/ut/ut_Color.h" +#include "rvl/GX/GXTypes.h" +#include "s/s_Math.h" +#include "toBeSorted/d_emitter.h" + SPECIAL_ACTOR_PROFILE(OBJ_ROPE_IGAIGA, dAcOropeIgaiga_c, fProfile::OBJ_ROPE_IGAIGA, 0x265, 0, 2); STATE_DEFINE(dAcOropeIgaiga_c, Init); @@ -9,21 +32,752 @@ STATE_DEFINE(dAcOropeIgaiga_c, Tree); STATE_DEFINE(dAcOropeIgaiga_c, Stick); STATE_DEFINE(dAcOropeIgaiga_c, Water); +dCcD_SrcSph dAcOropeIgaiga_c::sSphSrc = { + /* mObjInf */ + {/* mObjAt */ {0x400, 0x1F, {0, 0, 0}, 1, 0, 0, 0, 0, 0}, + /* mObjTg */ {0xFEB77DFF, 0x311, {0, 0, 0x407}, 0, 0}, + /* mObjCo */ {0xA9}}, + /* mSphInf */ + {20.f}, +}; + +const s16 dAcOropeIgaiga_c::sRopeTimerMin1 = 0x2D; +const s16 dAcOropeIgaiga_c::sRopeTimerMin2 = 0x3C; +const f32 dAcOropeIgaiga_c::lbl_257_rodata_4[3] = {500.f, 250.f, 50.f}; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_10 = 0x96; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_12 = 0x64; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_14 = 0x41; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_16 = 0x41; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_18 = 0x64; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_1A = 0x64; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_1C = 0x4; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_1E = 0x41; +const s16 dAcOropeIgaiga_c::lbl_257_rodata_20 = 0x64; +const f32 dAcOropeIgaiga_c::lbl_257_rodata_28 = 20.f; + +// copy from d_a_obj_fairy - TODO move it to a shared file +inline static void vecCylCalc(mVec3_c &target, const mAng &rot, f32 factor) { + target.x += factor * rot.sin(); + target.z += factor * rot.cos(); +} + +bool dAcOropeIgaiga_c::createHeap() { + void *data = getOarcResFile("NeedleBall"); + if (data == nullptr) { + return false; + } + mResFile = nw4r::g3d::ResFile(data); + nw4r::g3d::ResMdl mdl = mResFile.GetResMdl("NeedleBall"); + TRY_CREATE(mMdl.create(mdl, &mAllocator, 0x120, 1, nullptr)); + return true; +} + +int dAcOropeIgaiga_c::create() { + mStartStateTree = getFromParams(0, 0xF); + if (mStartStateTree >= 2) { + mStartStateTree = 0; + } + mSceneflag = getFromParams(4, 0xFF); + CREATE_ALLOCATOR(dAcOropeIgaiga_c); + mObjAcch.Set(&mPosition, &mOldPosition, this, 1, &mAcchCir, &mVelocity, nullptr, nullptr); + mAcchCir.SetWall(20.0f, 20.0f); + mStts.mRank = 0; + mCollider.Set(sSphSrc); + mCollider.SetStts(mStts); + mCollider.ClrAtSet(); + mAcceleration = 0.0f; + mMaxSpeed = -100.0f; + mInitTimer = 5; + mPnts2Idx = 0xff; + field_0x91E = -1; + field_0x928 = 0xff; + if (mStartStateTree == 1) { + mStateMgr.changeState(StateID_Tree); + } else { + mStateMgr.changeState(StateID_Init); + } + mBoundingBox.Set(mVec3_c(-50.0f, -50.0f, -50.0f), mVec3_c(50.0f, 50.0f, 50.0f)); + return SUCCEEDED; +} + +int dAcOropeIgaiga_c::doDelete() { + return SUCCEEDED; +} + +int dAcOropeIgaiga_c::actorExecute() { + mStateMgr.executeState(); + if (field_0x91E >= 0) { + u8 red = 0; + if (field_0x91E < 0x3C) { + if ((field_0x91E / 3 & 1) == 0) { + red = 0xff; + if (!mSoundPlayed) { + startSound(SE_RopeIga_COUNT); + mSoundPlayed = true; + } + } else { + mSoundPlayed = false; + } + } else if ((field_0x91E & 4) != 0) { + red = 0xff; + if (!mSoundPlayed) { + startSound(SE_RopeIga_COUNT); + mSoundPlayed = true; + } + } else { + mSoundPlayed = false; + } + + mMdl.setTevKColorAll(GX_KCOLOR3, mColor(red, 0, 0, 0xff), false); + } + f32 prevYPosition = mPosition.y; + mPosition.y += 20.0f; + mCollider.SetC(mPosition); + dCcS::GetInstance()->Set(&mCollider); + updateMatrix(); + mMdl.setLocalMtx(mWorldMtx); + mPosition.y = prevYPosition; + return SUCCEEDED; +} + +int dAcOropeIgaiga_c::draw() { + drawModelType1(&mMdl); + return SUCCEEDED; +} + void dAcOropeIgaiga_c::initializeState_Init() {} -void dAcOropeIgaiga_c::executeState_Init() {} -void dAcOropeIgaiga_c::finalizeState_Init() {} -void dAcOropeIgaiga_c::initializeState_Rope() {} -void dAcOropeIgaiga_c::executeState_Rope() {} + +void dAcOropeIgaiga_c::executeState_Init() { + if (mInitTimer != 0) { + mInitTimer--; + if (mCollider.ChkCoHit()) { + dAcOivyRope_c *rope = (dAcOivyRope_c *)mCollider.GetCoActor(); + if (rope != NULL && (rope->mProfileName == fProfile::OBJ_IVY_ROPE) && rope->checkSubtype(1)) { + ivyRopeRef.link(rope); + mInitTimer = 0; + mPnts2Idx = 0.5f + mPosition.distance(rope->mPosition) * rope->lbl_256_rodata_40; + mPosition = rope->getPnts2()[mPnts2Idx]; + f32 vecCylCalcFactor = cM::rndF(5.f) + 15.f; + mPositionOffset.x = 0.f; + mPositionOffset.y = 0.f; + mPositionOffset.z = 0.f; + s16 ang1 = cLib::targetAngleY(rope->getTightRopeEnd(), rope->getTightRopeStart()); + s16 ang2 = cM::rndInt(100) & 1 ? -1 : 1; + vecCylCalc(mPositionOffset, ang1 + ang2 * 0x4000, vecCylCalcFactor); + f32 positionYOffset = cM::rndFX(15.f); + mPositionOffset.y += positionYOffset; + mPosition += mPositionOffset; + mPositionRelated = mPosition; + } + } + } else if (mPnts2Idx == 255) { + mStateMgr.changeState(StateID_Ground); + mVelocityYRelated = 1; + } else { + mStateMgr.changeState(StateID_Rope); + } +} + +void dAcOropeIgaiga_c::finalizeState_Init() { + mCollider.mCo.SetGrp(mCollider.mCo.mSrc.mSPrm & 0x160); +} + +void dAcOropeIgaiga_c::initializeState_Rope() { + mAcceleration = -3.0f; +} + +void dAcOropeIgaiga_c::executeState_Rope() { + if (mRopeTimer != 0) { + mRopeTimer--; + } else { + field_0x922 = 0; + } + mVec3_c pos = mPosition; + bool rope0x1087 = false; + bool rope0x1002 = false; + dAcOivyRope_c *rope = ivyRopeRef.get(); + if (rope != nullptr) { + rope0x1002 = rope->getField_0x1002(); + rope0x1087 = rope->getField_0x1087(); + if (rope0x1002) { + pos.y = rope->getPnts2()[mPnts2Idx].y; + pos.y += mPositionOffset.y; + } else { + pos = rope->getPnts2()[mPnts2Idx]; + pos += mPositionOffset; + } + pos.y -= 20.f; + } + if (rope0x1087) { + s32 val = fn_257_1CA0(); + if (val > 0) { + u32 ropeTimerMin = sRopeTimerMin1; + field_0x922 += val; + if (val == 2) { + ropeTimerMin = sRopeTimerMin2; + } + if (ropeTimerMin > mRopeTimer) { + mRopeTimer = ropeTimerMin; + } + + if (mVelocityYRelated == 0) { + mVelocityYRelated = val + 1; + mVelocity.y = 5.f * mVelocityYRelated; + fn_257_1F20(); + } + } + } + if (mVelocityYRelated > 0) { + mRotation.x += mRotationXOffset; + calcVelocity(); + mPosition += mVelocity; + if (mPosition.y < pos.y) { + mPosition.y = pos.y; + mVelocityYRelated -= 1; + if (mVelocityYRelated != 0) { + mVelocity.y = 7.f * mVelocityYRelated; + } + } + } + if (mVelocityYRelated == 0) { + if (rope0x1002) { + sLib::addCalc(&mPosition.y, pos.y, 0.5f, 20.f, 3.f); + } else { + cLib::addCalcPos(&mPosition, pos, 0.5f, 20.f, 3.f); + } + } + s32 val = fn_257_1D20(); + fn_257_1DF0(); + if (val == 1) { + mStateMgr.changeState(StateID_Stick); + } else if (val == 3) { + mStateMgr.changeState(StateID_Ground); + } else if (field_0x922 >= 3) { + mAngle.y = cM::rndInt(0xFFFF); + mSpeed = 5.f; + mVelocity.y = 20.f; + mStateMgr.changeState(StateID_Ground); + } +} + void dAcOropeIgaiga_c::finalizeState_Rope() {} -void dAcOropeIgaiga_c::initializeState_Ground() {} -void dAcOropeIgaiga_c::executeState_Ground() {} + +void dAcOropeIgaiga_c::initializeState_Ground() { + mVelocityYRelated = -1; + mAcceleration = -4.f; + mStts.SetRank(0); + fn_257_1F20(); + mGroundTimer = 0x1e; +} + +void dAcOropeIgaiga_c::executeState_Ground() { + if (mGroundTimer != 0) { + mGroundTimer--; + } + s32 a = fn_257_1D20(); + fn_257_1DF0(); + calcVelocity(); + mPosition += mVelocity; + if (a != 0) { + if (mVelocityYRelated == 0) { + fn_257_20F0(5.f, 10.f); + } + } + if (mVelocityYRelated != 0) { + mObjAcch.CrrPos(*dBgS::GetInstance()); + if (mObjAcch.ChkGndHit()) { + if (mVelocityYRelated == -1) { + mVelocityYRelated = 3; + mSpeed = 3.f; + s16 angleYOffset = cM::rndInt(0x2aab); + if (angleYOffset & 1) { + angleYOffset = -angleYOffset; + } + mAngle.y += angleYOffset; + if (field_0x922 >= 3 || *mStateMgr.getOldStateID() == StateID_Tree) { + fn_257_1FD0(); + } + startSound(SE_RopeIga_GROUND); + } else if (mVelocityYRelated > 0) { + mVelocityYRelated--; + sLib::chase(&mSpeed, 0.f, 1.f); + } + if (mVelocityYRelated > 0) { + mVelocity.y = 7.f * mVelocityYRelated; + } else if (mVelocityYRelated == 0) { + mAcceleration = 0.f; + mSpeed = 0.f; + } + } + } else if (field_0x91E > 0) { + mAcceleration = -4.f; + mObjAcch.CrrPos(*dBgS::GetInstance()); + } + if (mVelocityYRelated != 0 && !mObjAcch.ChkGndHit()) { + mRotation.x += mRotationXOffset; + } + if (a == 1 && mGroundTimer == 0) { + mStateMgr.changeState(StateID_Stick); + } + if (field_0x91E >= 0) { + f32 posY = mPosition.y; + if (fn_257_1FF0(&posY, false)) { + mPositionRelated = mPosition; + mPositionRelated.y = posY - 20.f; + mStateMgr.changeState(StateID_Water); + } + } +} + void dAcOropeIgaiga_c::finalizeState_Ground() {} -void dAcOropeIgaiga_c::initializeState_Tree() {} -void dAcOropeIgaiga_c::executeState_Tree() {} + +void dAcOropeIgaiga_c::initializeState_Tree() { + mAcceleration = 0.0f; +} + +void dAcOropeIgaiga_c::executeState_Tree() { + s32 tmp = fn_257_1D20(); + if (tmp == 1) { + mStateMgr.changeState(StateID_Stick); + } else if (tmp == 3 || SceneflagManager::sInstance->checkBoolFlag(mRoomID, mSceneflag)) { + mStateMgr.changeState(StateID_Ground); + f32 random = cM::rndF(2.f); + mGroundTimer = 0; + mAcceleration = -(3.f + random); + } + fn_257_1DF0(); +} + void dAcOropeIgaiga_c::finalizeState_Tree() {} -void dAcOropeIgaiga_c::initializeState_Stick() {} -void dAcOropeIgaiga_c::executeState_Stick() {} -void dAcOropeIgaiga_c::finalizeState_Stick() {} -void dAcOropeIgaiga_c::initializeState_Water() {} -void dAcOropeIgaiga_c::executeState_Water() {} -void dAcOropeIgaiga_c::finalizeState_Water() {} + +void dAcOropeIgaiga_c::initializeState_Stick() { + mStts.SetRank(0); + mStickTimer = 10; + mVelocity.y = 17.f; + mAcceleration = -3.f; + if (dAcPy_c::GetLink()->getCenterTranslation().y > mPosition.y) { + mLinkHigher = true; + } else { + mLinkHigher = false; + } + u32 random; + if (mLinkHigher) { + random = cM::rndInt(400) + 200; + } else { + random = cM::rndInt(600); + } + field_0x928 = random / 100; + if (field_0x928 > 5) { + field_0x928 = 5; + } + field_0x91A = 0; + mCollider.ClrTgSet(); + f32 rnd = cM::rndF(10.f); + mVelocity.y = rnd + 3.f; + if (dAcPy_c::GetLink()->checkActionFlags(0x10000)) { + s16 rotationYOffset = cM::rndInt(0x31C7) + 0x38e4; + f32 f1 = (rotationYOffset - 0x38E4) / 12743.f; + if (f1 > 1.f) { + f1 = 1.f; + } else if (f1 < 0.f) { + f1 = 0.f; + } + f32 f2 = cM::rndF(3.f) + 15.f; + mVecCylCalcFactor = 15.f * f1 + f2; + if ((field_0x928 & 1) == 0) { + rotationYOffset = -rotationYOffset; + } + mRotationYOffset = rotationYOffset; + } else { + if (field_0x928 >= 4) { + mVecCylCalcFactor = cM::rndF(10.f); + } else { + mVecCylCalcFactor = cM::rndF(35.f); + } + s16 rotationYOffset = cM::rndInt(0x1555) + 0x2aab; + if ((field_0x928 & 1) == 0) { + rotationYOffset = -rotationYOffset; + } + if (field_0x928 >= 4) { + rotationYOffset += cM::rndInt(0x1555) + 0x2aab; + } + mRotationYOffset = rotationYOffset; + } + mLinkPosDiff = mPosition - dAcPy_c::GetLink()->getCenterTranslation(); + if (dAcPy_c::GetLink()->getCurrentAction() == 0x25 /* (IDL_ON_VINES|NO_STAMINA) */) { + mIdleOnVinesNoStamina = true; + } else { + mIdleOnVinesNoStamina = false; + } +} + +void dAcOropeIgaiga_c::executeState_Stick() { + const dAcPy_c *link = dAcPy_c::GetLink(); + f32 posY = mPosition.y; + if (fn_257_1FF0(&posY, false)) { + mPositionRelated = mPosition; + mPositionRelated.y = posY - 20.f; + mStateMgr.changeState(StateID_Water); + } else if (link->checkActionFlags(0x40000) || !link->checkFlags0x340(0x100)) { + fn_257_1FF0(&posY, true); + mPositionRelated = mPosition; + mPositionRelated.y = posY - 20.f; + mPosition.y = posY - 20.f; + mStateMgr.changeState(StateID_Water); + fn_257_21A0(); + } else if (fn_257_2310(mRotationYOffset)) { + fn_257_1DF0(); + mVec3_c linkPos = dAcPy_c::GetLink()->getCenterTranslation(); + + f32 linkPosDiffAbsXZ = mLinkPosDiff.absXZ(); + if (mIdleOnVinesNoStamina) { + linkPosDiffAbsXZ *= 0.3f; + } + if (!dAcPy_c::GetLinkM()->isRoomID(mRoomID)) { + mAngle.y = cM::rndInt(0x7fff); + mSpeed = 13.f; + mVelocity.y = 20.f; + mStateMgr.changeState(StateID_Ground); + } else { + vecCylCalc(linkPos, dAcPy_c::GetLink()->mRotation.y + mRotationYOffset, linkPosDiffAbsXZ); + linkPos.y += mLinkPosDiff.y; + mRotation.y = cLib::targetAngleY(linkPos, dAcPy_c::GetLink()->mPosition); + mPosition.x = linkPos.x; + mPosition.z = linkPos.z; + if (mVelocityYRelated > 0) { + mAcceleration = -3.5f; + mRotation.x += mRotationXOffset; + calcVelocity(); + mPosition += mVelocity; + if (mPosition.y < linkPos.y) { + mPosition.y = linkPos.y; + mVelocityYRelated--; + if (mVelocityYRelated != 0) { + mVelocity.y = 3.f * mLinkSpeedRelated * mVelocityYRelated; + } + } + } else { + mPosition.y = linkPos.y; + f32 linkSpeedRelated = dAcPy_c::GetLink()->mSpeed / 20.f; + if (linkSpeedRelated > 1.f) { + linkSpeedRelated = 1.f; + } + if (dAcPy_c::GetLinkM()->checkActionFlags(0xc70852)) { + field_0x938 = true; + } else if (field_0x938) { + field_0x938 = false; + linkSpeedRelated = 1.f; + } + mLinkSpeedRelated = linkSpeedRelated; + if (linkSpeedRelated < 0.3f) { + mVelocityYRelated = 0; + } else { + mVelocityYRelated = 3; + mLinkSpeedRelated += cM::rndFX(0.15f); + } + mRotationXOffset = mLinkSpeedRelated * 910.f; + } + if (fn_257_21D0()) { + mAngle.y = cM::rndInt(0x7fff); + mSpeed = 13.f; + mVelocity.y = 20.f; + mStateMgr.changeState(StateID_Ground); + } + } + } +} + +void dAcOropeIgaiga_c::finalizeState_Stick() { + field_0x928 = 0xff; + mCollider.OnTgSet(); + mCollider.OnCoSet(); +} + +void dAcOropeIgaiga_c::initializeState_Water() { + mStts.SetRank(5); + mRotationXOffset = 100; + mPositionYRelated = mPositionRelated.y - 2.0f; + fn_257_20F0(3.f, 10.f); +} + +const s16 dAcOropeIgaiga_c::lbl_257_rodata_90 = 0x2d8; + +void dAcOropeIgaiga_c::executeState_Water() { + fn_257_1D20(); + fn_257_1DF0(); + if (mVelocityYRelated != 0) { + calcVelocity(); + mPosition += mVelocity; + mPosition += mStts.mCcMove; + } + + if (mVelocityYRelated != 0) { + if (fn_257_1FF0(nullptr, 0) != 0) { + mVelocityYRelated--; + if (mVelocityYRelated > 0) { + sLib::chase(&mSpeed, 0, 1.f); + mVelocity.y = 7.f * mVelocityYRelated; + } else { + fn_257_21A0(); + } + } + } else { + f32 f1 = 0.1f; + if (fn_257_1D20() == 1) { + mSpeed = 8.5f; + mAngle.y = cLib::targetAngleY(dAcPy_c::GetLink()->mPosition, mPosition); + } + sLib::chase(&mSpeed, 0, 1.f); + + if (!cM::isZero(mSpeed)) { + calcVelocity(); + mPosition += mVelocity; + mPosition += mStts.mCcMove; + mRotation.x += mAng(0x2d8); + f1 = 2.f; + } + if (sLib::chase(&mPosition.y, mPositionYRelated, f1) != 0) { + if (mPositionYRelated > mPositionRelated.y) { + mPositionYRelated = mPositionRelated.y - 2.f; + } else { + mPositionYRelated = mPositionRelated.y + 1.f; + } + } + } + if (mObjAcch.ChkGndHit()) { + mStateMgr.changeState(StateID_Ground); + mVelocityYRelated = 0; + } + mObjAcch.CrrPos(*dBgS::GetInstance()); +} + +void dAcOropeIgaiga_c::finalizeState_Water() { + mVelocityYRelated = 0; + mStts.SetRank(0); + fn_257_21A0(); +} + +u32 dAcOropeIgaiga_c::fn_257_1CA0() { + f32 distThresh1 = 62500.0f; + f32 distThresh2 = 250000.0f; + f32 squareMagXZ = dAcPy_c::GetLink()->mPosition.squareDistanceToXZ(mPosition); + if (squareMagXZ < distThresh1) { + return 2; + } + return squareMagXZ < distThresh2; +} + +s32 dAcOropeIgaiga_c::fn_257_1D20() { + if (fn_257_2720()) { + fn_257_1FD0(); + return 1; + } + if (mCollider.ChkTgHit()) { + fn_257_1FD0(); + if (mCollider.ChkTgAtHitType(2)) { + startSound(SE_SW_HIT_RopeIga); + } + dAcObjBase_c *tgActor = mCollider.GetTgActor(); + if (tgActor != nullptr && tgActor->mProfileName == fProfile::OBJ_ROPE_IGAIGA) { + return 2; + } + return 3; + } + return 0; +} + +void dAcOropeIgaiga_c::fn_257_1DF0() { + if (field_0x91E > 0) { + field_0x91E--; + if (field_0x91E == 3) { + mCollider.OnAtSet(); + mCollider.SetR(50.f); + mCollider.mCo.OffSPrm(1); + mVec3_c pos = mPosition; + pos.y += 20.f; + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_498_, pos, nullptr, nullptr, nullptr, nullptr, 0, 0 + ); + startSound(SE_RopeIga_EXPLODE); + } else if (field_0x91E == 0) { + deleteRequest(); + } + if ((u16)(field_0x91E - 1) <= 1) { + if (mCollider.ChkAtHit()) { + deleteRequest(); + } + } + } +} + +void dAcOropeIgaiga_c::fn_257_1F20() { + s16 ang = mStateMgr.isState(StateID_Rope) ? 0xb6 : 0x4fa; + s16 random = cM::rndInt(0x222); + s32 ang2 = ang + random; + if (ang2 & 1) { + ang2 = (s16)-ang2; + } + mRotationXOffset = ang2; +} + +void dAcOropeIgaiga_c::fn_257_1FD0() { + if (field_0x91E != -1) { + return; + } + field_0x91E = 0x99; +} + +bool dAcOropeIgaiga_c::fn_257_1FF0(f32 *posY, bool p2) { + if (p2 || mVelocity.y < 0.f) { + mVec3_c _pos = mPosition; + f32 f1 = p2 ? 200.f : 50.f; + f32 f2 = p2 ? -200.f : -30.f; + if (dBgS_WtrChk::CheckPos(&mPosition, true, f1, f2)) { + f32 waterHeight = dBgS_WtrChk::GetWaterHeight(); + if (p2 || mPosition.y < waterHeight - 20.f) { + if (posY != nullptr) { + *posY = waterHeight; + } + return true; + } + } + } + return false; +} + +void dAcOropeIgaiga_c::fn_257_20F0(f32 speed, f32 velocityY) { + fn_257_1F20(); + mVelocityYRelated = 3; + mSpeed = speed; + mAngle.y = cLib::targetAngleY(dAcPy_c::GetLink()->mPosition, mPosition); + s16 angleOffset = cM::rndInt(0x2aab); + if (angleOffset & 1) { + angleOffset = -angleOffset; + } + mAngle.y += angleOffset; + mVelocity.y = velocityY; + mAcceleration = -4.f; +} + +void dAcOropeIgaiga_c::fn_257_21A0() { + mVelocityYRelated = 0; + mVelocity.y = 0.f; + mAcceleration = 0.f; + mSpeed = 0.f; + mRotationXOffset = 100; +} + +bool dAcOropeIgaiga_c::fn_257_21D0() { + if (field_0x91A != 0) { + field_0x91A--; + } + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link->getCurrentAction() == 0x49 /* SHIELD_BASH */) { + if (!mLinkShieldBash) { + field_0x91A += lbl_257_rodata_1E; + } + mLinkShieldBash = true; + } else { + mLinkShieldBash = false; + if (link->checkFlags0x354(0x2000)) { + field_0x91A += lbl_257_rodata_14; + } else if (link->checkFlags0x354(0x4)) { + field_0x91A += lbl_257_rodata_16; + } else if (link->getCurrentAction() == 0xC /* ROLL */) { + field_0x91A += lbl_257_rodata_18; + } else if (link->getCurrentAction() == 0x27 /* START_VINE_LEAP */) { + field_0x91A += lbl_257_rodata_1A; + } else if (link->checkSwordAndMoreStates(0x40) /* SPRINTING */) { + field_0x91A += lbl_257_rodata_1C; + } + } + if (mIdleOnVinesNoStamina) { + if (dAcPy_c::GetLink()->getCurrentAction() != 0x25 /* (IDL_ON_VINES|NO_STAMINA) */) { + field_0x91A += lbl_257_rodata_20; + } + } else if (dAcPy_c::GetLink()->getCurrentAction() == 0x25) { + mIdleOnVinesNoStamina = true; + } + if ((s32)field_0x91A >= 100) { + return true; + } + return false; +} + +const f32 dAcOropeIgaiga_c::sFloats2[6] = {20.f, 30.f, -55.f, -65.f, -25.f, -35.f}; + +bool dAcOropeIgaiga_c::fn_257_2310(s16 rotationYOffset) { + if (mStickTimer != 0) { + mVec3_c translation = dAcPy_c::GetLink()->getCenterTranslation(); + vecCylCalc(translation, dAcPy_c::GetLink()->mRotation.y + rotationYOffset, mVecCylCalcFactor); + translation.y += sFloats2[field_0x928]; + if (mStickTimer == 10 && field_0x928 < 4) { + mVec3_c pos = dAcPy_c::GetLink()->mPosition; + s16 ang1 = cLib::targetAngleY(pos, mPosition); + s16 ang2 = cLib::targetAngleY(pos, translation); + if (sLib::absDiff(ang1, ang2) > 0x471C) { + if (field_0x928 & 1) { + field_0x928--; + } else { + field_0x928++; + } + if (field_0x928 > 5) { + field_0x928 = 5; + } + } + } + mStickTimer--; + mRotation.y = cLib::targetAngleY(mPosition, dAcPy_c::GetLink()->mPosition); + mRotation.x += mRotationXOffset; + cLib::addCalcPosXZ(&mPosition, translation, 0.3f, 10.f, 1.f); + calcVelocity(); + if (mLinkHigher) { + if (mVelocity.y < -5.f) { + mVelocity.y = 10.f; + } + if (mPosition.y > translation.y) { + mVelocity.y = 0.f; + if (mStickTimer > 10) { + mStickTimer = 0; + } + } else { + mPosition.y += mVelocity.y; + } + } else { + if (mVelocity.y < -15.f) { + mVelocity.y = 0.f; + } + mPosition.y += mVelocity.y; + if (mPosition.y < translation.y) { + mVelocity.y = 10.f; + if (mStickTimer > 10) { + mStickTimer = 0; + } + } + } + if (fn_257_2720()) { + mLinkPosDiff = mPosition - dAcPy_c::GetLink()->getCenterTranslation(); + } else { + if (dAcPy_c::GetLinkM()->checkActionFlags(0xc70852) == 0) { + translation = (translation + mPosition) * 0.5f; + } + mLinkPosDiff = translation - dAcPy_c::GetLink()->getCenterTranslation(); + mStickTimer = 0; + } + return false; + } + mCollider.OffCoSet(); + return true; +} + +bool dAcOropeIgaiga_c::fn_257_2720() { + if (mCollider.ChkCoHit()) { + if (mCollider.GetCoActor()->isPlayer() && + dAcPy_c::GetLink()->getCenterTranslation().squareDistanceToXZ(mPosition) < 1600.f) { + return true; + } + } + return false; +} + +const f32 dAcOropeIgaiga_c::sSquareXZDistanceThreshold = 1600.f; From afa584eafcda2e9359a623c51a0c80131210aaeb Mon Sep 17 00:00:00 2001 From: swekka Date: Mon, 29 Dec 2025 13:27:01 +0100 Subject: [PATCH 3/4] review --- include/d/a/obj/d_a_obj_rope_igaiga.h | 13 +-- include/d/col/c/c_cc_d.h | 3 - src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp | 111 ++++++++++++------------ 3 files changed, 62 insertions(+), 65 deletions(-) diff --git a/include/d/a/obj/d_a_obj_rope_igaiga.h b/include/d/a/obj/d_a_obj_rope_igaiga.h index ee41bb10..99de30bf 100644 --- a/include/d/a/obj/d_a_obj_rope_igaiga.h +++ b/include/d/a/obj/d_a_obj_rope_igaiga.h @@ -3,7 +3,6 @@ #include "d/a/d_a_base.h" #include "d/a/obj/d_a_obj_base.h" -#include "d/a/obj/d_a_obj_ivy_rope.h" #include "d/col/bg/d_bg_s_acch.h" #include "d/col/cc/d_cc_d.h" #include "m/m3d/m_smdl.h" @@ -12,6 +11,8 @@ #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" +class dAcOivyRope_c; + class dAcOropeIgaiga_c : public dAcObjBase_c { public: dAcOropeIgaiga_c() : mStateMgr(*this, sStateID::null) {} @@ -49,7 +50,7 @@ private: /* 0x4A0 */ dBgS_AcchCir mAcchCir; /* 0x4FC */ dBgS_ObjAcch mObjAcch; /* 0x8AC */ STATE_MGR_DECLARE(dAcOropeIgaiga_c); - /* 0x8E8 */ dAcRef_c ivyRopeRef; + /* 0x8E8 */ dAcRef_c mIvyRopeRef; /* 0x8F4 */ mVec3_c mPositionOffset; /* 0x900 */ mVec3_c mPositionRelated; /* 0x90C */ mVec3_c mLinkPosDiff; @@ -64,16 +65,16 @@ private: /* 0x925 */ u8 mStartStateTree; /* 0x926 */ u8 mSceneflag; /* 0x927 */ u8 mStickTimer; - /* 0x928 */ u8 field_0x928; + /* 0x928 */ u8 mYOffsetIdx; /* 0x929 */ u8 mGroundTimer; /* 0x92A */ s8 mVelocityYRelated; /* 0x92C */ f32 mLinkSpeedRelated; /* 0x930 */ f32 mPositionYRelated; - /* 0x934 */ f32 mVecCylCalcFactor; + /* 0x934 */ f32 mXZCirclePointFactor; /* 0x938 */ bool field_0x938; /* 0x939 */ bool mLinkShieldBash; /* 0x93A */ bool mLinkHigher; - /* 0x93B */ bool mIdleOnVinesNoStamina; + /* 0x93B */ bool field_0x93B; /* 0x93C */ bool mSoundPlayed; static dCcD_SrcSph sSphSrc; @@ -92,7 +93,7 @@ private: static const f32 lbl_257_rodata_28; static const s16 lbl_257_rodata_90; static const f32 sSquareXZDistanceThreshold; - static const f32 sFloats2[6]; + static const f32 sLinkCenterTranslationYOffset[6]; }; #endif diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index 0fe8de42..7e51421a 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -1012,9 +1012,6 @@ public: void OnCoSet() { mCo.OnSPrm(1); } - void OffCoSet() { - mCo.OffSPrm(1); - } u32 ChkCoSet2() const { return mCo.MskSPrm(0x800); } diff --git a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp index 6f056264..9ca19b9c 100644 --- a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp +++ b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp @@ -6,10 +6,12 @@ #include "d/a/d_a_base.h" #include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/a/obj/d_a_obj_ivy_rope.h" #include "d/col/bg/d_bg_s.h" #include "d/col/bg/d_bg_s_wtr_chk.h" #include "d/col/c/c_cc_d.h" #include "d/col/cc/d_cc_s.h" +#include "d/d_vec.h" #include "d/flag/sceneflag_manager.h" #include "d/snd/d_snd_wzsound.h" #include "f/f_base.h" @@ -34,8 +36,9 @@ STATE_DEFINE(dAcOropeIgaiga_c, Water); dCcD_SrcSph dAcOropeIgaiga_c::sSphSrc = { /* mObjInf */ - {/* mObjAt */ {0x400, 0x1F, {0, 0, 0}, 1, 0, 0, 0, 0, 0}, - /* mObjTg */ {0xFEB77DFF, 0x311, {0, 0, 0x407}, 0, 0}, + {/* mObjAt */ {AT_TYPE_DAMAGE, 0x1F, {0, 0, 0}, 1, 0, 0, 0, 0, 0}, + /* mObjTg */ + {~(AT_TYPE_WIND | AT_TYPE_0x8000 | AT_TYPE_0x80000 | AT_TYPE_BEETLE | AT_TYPE_BUGNET), 0x311, {0, 0, 0x407}, 0, 0}, /* mObjCo */ {0xA9}}, /* mSphInf */ {20.f}, @@ -55,12 +58,6 @@ const s16 dAcOropeIgaiga_c::lbl_257_rodata_1E = 0x41; const s16 dAcOropeIgaiga_c::lbl_257_rodata_20 = 0x64; const f32 dAcOropeIgaiga_c::lbl_257_rodata_28 = 20.f; -// copy from d_a_obj_fairy - TODO move it to a shared file -inline static void vecCylCalc(mVec3_c &target, const mAng &rot, f32 factor) { - target.x += factor * rot.sin(); - target.z += factor * rot.cos(); -} - bool dAcOropeIgaiga_c::createHeap() { void *data = getOarcResFile("NeedleBall"); if (data == nullptr) { @@ -90,7 +87,7 @@ int dAcOropeIgaiga_c::create() { mInitTimer = 5; mPnts2Idx = 0xff; field_0x91E = -1; - field_0x928 = 0xff; + mYOffsetIdx = 0xff; if (mStartStateTree == 1) { mStateMgr.changeState(StateID_Tree); } else { @@ -153,17 +150,17 @@ void dAcOropeIgaiga_c::executeState_Init() { if (mCollider.ChkCoHit()) { dAcOivyRope_c *rope = (dAcOivyRope_c *)mCollider.GetCoActor(); if (rope != NULL && (rope->mProfileName == fProfile::OBJ_IVY_ROPE) && rope->checkSubtype(1)) { - ivyRopeRef.link(rope); + mIvyRopeRef.link(rope); mInitTimer = 0; mPnts2Idx = 0.5f + mPosition.distance(rope->mPosition) * rope->lbl_256_rodata_40; mPosition = rope->getPnts2()[mPnts2Idx]; - f32 vecCylCalcFactor = cM::rndF(5.f) + 15.f; + f32 xzCirclePointFactor = cM::rndF(5.f) + 15.f; mPositionOffset.x = 0.f; mPositionOffset.y = 0.f; mPositionOffset.z = 0.f; s16 ang1 = cLib::targetAngleY(rope->getTightRopeEnd(), rope->getTightRopeStart()); s16 ang2 = cM::rndInt(100) & 1 ? -1 : 1; - vecCylCalc(mPositionOffset, ang1 + ang2 * 0x4000, vecCylCalcFactor); + getXZCirclePoint(mPositionOffset, ang1 + ang2 * 0x4000, xzCirclePointFactor); f32 positionYOffset = cM::rndFX(15.f); mPositionOffset.y += positionYOffset; mPosition += mPositionOffset; @@ -195,7 +192,7 @@ void dAcOropeIgaiga_c::executeState_Rope() { mVec3_c pos = mPosition; bool rope0x1087 = false; bool rope0x1002 = false; - dAcOivyRope_c *rope = ivyRopeRef.get(); + dAcOivyRope_c *rope = mIvyRopeRef.get(); if (rope != nullptr) { rope0x1002 = rope->getField_0x1002(); rope0x1087 = rope->getField_0x1087(); @@ -366,9 +363,9 @@ void dAcOropeIgaiga_c::initializeState_Stick() { } else { random = cM::rndInt(600); } - field_0x928 = random / 100; - if (field_0x928 > 5) { - field_0x928 = 5; + mYOffsetIdx = random / 100; + if (mYOffsetIdx > 5) { + mYOffsetIdx = 5; } field_0x91A = 0; mCollider.ClrTgSet(); @@ -383,31 +380,31 @@ void dAcOropeIgaiga_c::initializeState_Stick() { f1 = 0.f; } f32 f2 = cM::rndF(3.f) + 15.f; - mVecCylCalcFactor = 15.f * f1 + f2; - if ((field_0x928 & 1) == 0) { + mXZCirclePointFactor = 15.f * f1 + f2; + if ((mYOffsetIdx & 1) == 0) { rotationYOffset = -rotationYOffset; } mRotationYOffset = rotationYOffset; } else { - if (field_0x928 >= 4) { - mVecCylCalcFactor = cM::rndF(10.f); + if (mYOffsetIdx >= 4) { + mXZCirclePointFactor = cM::rndF(10.f); } else { - mVecCylCalcFactor = cM::rndF(35.f); + mXZCirclePointFactor = cM::rndF(35.f); } s16 rotationYOffset = cM::rndInt(0x1555) + 0x2aab; - if ((field_0x928 & 1) == 0) { + if ((mYOffsetIdx & 1) == 0) { rotationYOffset = -rotationYOffset; } - if (field_0x928 >= 4) { + if (mYOffsetIdx >= 4) { rotationYOffset += cM::rndInt(0x1555) + 0x2aab; } mRotationYOffset = rotationYOffset; } mLinkPosDiff = mPosition - dAcPy_c::GetLink()->getCenterTranslation(); - if (dAcPy_c::GetLink()->getCurrentAction() == 0x25 /* (IDL_ON_VINES|NO_STAMINA) */) { - mIdleOnVinesNoStamina = true; + if (dAcPy_c::GetLink()->getCurrentAction() == 0x25) { + field_0x93B = true; } else { - mIdleOnVinesNoStamina = false; + field_0x93B = false; } } @@ -430,7 +427,7 @@ void dAcOropeIgaiga_c::executeState_Stick() { mVec3_c linkPos = dAcPy_c::GetLink()->getCenterTranslation(); f32 linkPosDiffAbsXZ = mLinkPosDiff.absXZ(); - if (mIdleOnVinesNoStamina) { + if (field_0x93B) { linkPosDiffAbsXZ *= 0.3f; } if (!dAcPy_c::GetLinkM()->isRoomID(mRoomID)) { @@ -439,7 +436,7 @@ void dAcOropeIgaiga_c::executeState_Stick() { mVelocity.y = 20.f; mStateMgr.changeState(StateID_Ground); } else { - vecCylCalc(linkPos, dAcPy_c::GetLink()->mRotation.y + mRotationYOffset, linkPosDiffAbsXZ); + getXZCirclePoint(linkPos, dAcPy_c::GetLink()->mRotation.y + mRotationYOffset, linkPosDiffAbsXZ); linkPos.y += mLinkPosDiff.y; mRotation.y = cLib::targetAngleY(linkPos, dAcPy_c::GetLink()->mPosition); mPosition.x = linkPos.x; @@ -488,7 +485,7 @@ void dAcOropeIgaiga_c::executeState_Stick() { } void dAcOropeIgaiga_c::finalizeState_Stick() { - field_0x928 = 0xff; + mYOffsetIdx = 0xff; mCollider.OnTgSet(); mCollider.OnCoSet(); } @@ -602,7 +599,7 @@ void dAcOropeIgaiga_c::fn_257_1DF0() { } else if (field_0x91E == 0) { deleteRequest(); } - if ((u16)(field_0x91E - 1) <= 1) { + if (field_0x91E > 0 && field_0x91E < 3) { if (mCollider.ChkAtHit()) { deleteRequest(); } @@ -672,7 +669,7 @@ bool dAcOropeIgaiga_c::fn_257_21D0() { field_0x91A--; } dAcPy_c *link = dAcPy_c::GetLinkM(); - if (link->getCurrentAction() == 0x49 /* SHIELD_BASH */) { + if (link->getCurrentAction() == 0x49) { if (!mLinkShieldBash) { field_0x91A += lbl_257_rodata_1E; } @@ -683,20 +680,20 @@ bool dAcOropeIgaiga_c::fn_257_21D0() { field_0x91A += lbl_257_rodata_14; } else if (link->checkFlags0x354(0x4)) { field_0x91A += lbl_257_rodata_16; - } else if (link->getCurrentAction() == 0xC /* ROLL */) { + } else if (link->getCurrentAction() == 0xC) { field_0x91A += lbl_257_rodata_18; - } else if (link->getCurrentAction() == 0x27 /* START_VINE_LEAP */) { + } else if (link->getCurrentAction() == 0x27) { field_0x91A += lbl_257_rodata_1A; - } else if (link->checkSwordAndMoreStates(0x40) /* SPRINTING */) { + } else if (link->checkSwordAndMoreStates(0x40)) { field_0x91A += lbl_257_rodata_1C; } } - if (mIdleOnVinesNoStamina) { - if (dAcPy_c::GetLink()->getCurrentAction() != 0x25 /* (IDL_ON_VINES|NO_STAMINA) */) { + if (field_0x93B) { + if (dAcPy_c::GetLink()->getCurrentAction() != 0x25) { field_0x91A += lbl_257_rodata_20; } } else if (dAcPy_c::GetLink()->getCurrentAction() == 0x25) { - mIdleOnVinesNoStamina = true; + field_0x93B = true; } if ((s32)field_0x91A >= 100) { return true; @@ -704,38 +701,40 @@ bool dAcOropeIgaiga_c::fn_257_21D0() { return false; } -const f32 dAcOropeIgaiga_c::sFloats2[6] = {20.f, 30.f, -55.f, -65.f, -25.f, -35.f}; +const f32 dAcOropeIgaiga_c::sLinkCenterTranslationYOffset[6] = {20.f, 30.f, -55.f, -65.f, -25.f, -35.f}; bool dAcOropeIgaiga_c::fn_257_2310(s16 rotationYOffset) { if (mStickTimer != 0) { - mVec3_c translation = dAcPy_c::GetLink()->getCenterTranslation(); - vecCylCalc(translation, dAcPy_c::GetLink()->mRotation.y + rotationYOffset, mVecCylCalcFactor); - translation.y += sFloats2[field_0x928]; - if (mStickTimer == 10 && field_0x928 < 4) { - mVec3_c pos = dAcPy_c::GetLink()->mPosition; - s16 ang1 = cLib::targetAngleY(pos, mPosition); - s16 ang2 = cLib::targetAngleY(pos, translation); + mVec3_c linkCenterTranslation = dAcPy_c::GetLink()->getCenterTranslation(); + getXZCirclePoint( + linkCenterTranslation, dAcPy_c::GetLink()->mRotation.y + rotationYOffset, mXZCirclePointFactor + ); + linkCenterTranslation.y += sLinkCenterTranslationYOffset[mYOffsetIdx]; + if (mStickTimer == 10 && mYOffsetIdx < 4) { + mVec3_c linkPos = dAcPy_c::GetLink()->mPosition; + s16 ang1 = cLib::targetAngleY(linkPos, mPosition); + s16 ang2 = cLib::targetAngleY(linkPos, linkCenterTranslation); if (sLib::absDiff(ang1, ang2) > 0x471C) { - if (field_0x928 & 1) { - field_0x928--; + if (mYOffsetIdx & 1) { + mYOffsetIdx--; } else { - field_0x928++; + mYOffsetIdx++; } - if (field_0x928 > 5) { - field_0x928 = 5; + if (mYOffsetIdx > 5) { + mYOffsetIdx = 5; } } } mStickTimer--; mRotation.y = cLib::targetAngleY(mPosition, dAcPy_c::GetLink()->mPosition); mRotation.x += mRotationXOffset; - cLib::addCalcPosXZ(&mPosition, translation, 0.3f, 10.f, 1.f); + cLib::addCalcPosXZ(&mPosition, linkCenterTranslation, 0.3f, 10.f, 1.f); calcVelocity(); if (mLinkHigher) { if (mVelocity.y < -5.f) { mVelocity.y = 10.f; } - if (mPosition.y > translation.y) { + if (mPosition.y > linkCenterTranslation.y) { mVelocity.y = 0.f; if (mStickTimer > 10) { mStickTimer = 0; @@ -748,7 +747,7 @@ bool dAcOropeIgaiga_c::fn_257_2310(s16 rotationYOffset) { mVelocity.y = 0.f; } mPosition.y += mVelocity.y; - if (mPosition.y < translation.y) { + if (mPosition.y < linkCenterTranslation.y) { mVelocity.y = 10.f; if (mStickTimer > 10) { mStickTimer = 0; @@ -759,14 +758,14 @@ bool dAcOropeIgaiga_c::fn_257_2310(s16 rotationYOffset) { mLinkPosDiff = mPosition - dAcPy_c::GetLink()->getCenterTranslation(); } else { if (dAcPy_c::GetLinkM()->checkActionFlags(0xc70852) == 0) { - translation = (translation + mPosition) * 0.5f; + linkCenterTranslation = (linkCenterTranslation + mPosition) * 0.5f; } - mLinkPosDiff = translation - dAcPy_c::GetLink()->getCenterTranslation(); + mLinkPosDiff = linkCenterTranslation - dAcPy_c::GetLink()->getCenterTranslation(); mStickTimer = 0; } return false; } - mCollider.OffCoSet(); + mCollider.ClrCoSet(); return true; } From 3bbca854eb6cb3de40346dfae7e694000fd8a2df Mon Sep 17 00:00:00 2001 From: swekka Date: Mon, 29 Dec 2025 15:55:25 +0100 Subject: [PATCH 4/4] cleanup --- include/d/a/obj/d_a_obj_rope_igaiga.h | 6 ++--- src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp | 30 ++++++++++++------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/include/d/a/obj/d_a_obj_rope_igaiga.h b/include/d/a/obj/d_a_obj_rope_igaiga.h index 99de30bf..25178c0f 100644 --- a/include/d/a/obj/d_a_obj_rope_igaiga.h +++ b/include/d/a/obj/d_a_obj_rope_igaiga.h @@ -29,8 +29,8 @@ public: void fn_257_1DF0(); void fn_257_1F20(); void fn_257_1FD0(); - bool fn_257_1FF0(f32 *, bool); - void fn_257_20F0(f32, f32); + bool fn_257_1FF0(f32 *posY, bool p2); + void fn_257_20F0(f32 speed, f32 velocityY); void fn_257_21A0(); bool fn_257_21D0(); bool fn_257_2310(s16 rotationOffset); @@ -70,7 +70,7 @@ private: /* 0x92A */ s8 mVelocityYRelated; /* 0x92C */ f32 mLinkSpeedRelated; /* 0x930 */ f32 mPositionYRelated; - /* 0x934 */ f32 mXZCirclePointFactor; + /* 0x934 */ f32 mRadius; /* 0x938 */ bool field_0x938; /* 0x939 */ bool mLinkShieldBash; /* 0x93A */ bool mLinkHigher; diff --git a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp index 9ca19b9c..76423a7e 100644 --- a/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp +++ b/src/REL/d/a/obj/d_a_obj_rope_igaiga.cpp @@ -372,7 +372,7 @@ void dAcOropeIgaiga_c::initializeState_Stick() { f32 rnd = cM::rndF(10.f); mVelocity.y = rnd + 3.f; if (dAcPy_c::GetLink()->checkActionFlags(0x10000)) { - s16 rotationYOffset = cM::rndInt(0x31C7) + 0x38e4; + s16 rotationYOffset = cM::rndInt(0x31C7) + 0x38E4; f32 f1 = (rotationYOffset - 0x38E4) / 12743.f; if (f1 > 1.f) { f1 = 1.f; @@ -380,16 +380,16 @@ void dAcOropeIgaiga_c::initializeState_Stick() { f1 = 0.f; } f32 f2 = cM::rndF(3.f) + 15.f; - mXZCirclePointFactor = 15.f * f1 + f2; + mRadius = 15.f * f1 + f2; if ((mYOffsetIdx & 1) == 0) { rotationYOffset = -rotationYOffset; } mRotationYOffset = rotationYOffset; } else { if (mYOffsetIdx >= 4) { - mXZCirclePointFactor = cM::rndF(10.f); + mRadius = cM::rndF(10.f); } else { - mXZCirclePointFactor = cM::rndF(35.f); + mRadius = cM::rndF(35.f); } s16 rotationYOffset = cM::rndInt(0x1555) + 0x2aab; if ((mYOffsetIdx & 1) == 0) { @@ -571,7 +571,7 @@ s32 dAcOropeIgaiga_c::fn_257_1D20() { } if (mCollider.ChkTgHit()) { fn_257_1FD0(); - if (mCollider.ChkTgAtHitType(2)) { + if (mCollider.ChkTgAtHitType(AT_TYPE_SWORD)) { startSound(SE_SW_HIT_RopeIga); } dAcObjBase_c *tgActor = mCollider.GetTgActor(); @@ -589,11 +589,11 @@ void dAcOropeIgaiga_c::fn_257_1DF0() { if (field_0x91E == 3) { mCollider.OnAtSet(); mCollider.SetR(50.f); - mCollider.mCo.OffSPrm(1); - mVec3_c pos = mPosition; - pos.y += 20.f; + mCollider.ClrCoSet(); + mVec3_c particlePosition = mPosition; + particlePosition.y += 20.f; dJEffManager_c::spawnEffect( - PARTICLE_RESOURCE_ID_MAPPING_498_, pos, nullptr, nullptr, nullptr, nullptr, 0, 0 + PARTICLE_RESOURCE_ID_MAPPING_498_, particlePosition, nullptr, nullptr, nullptr, nullptr, 0, 0 ); startSound(SE_RopeIga_EXPLODE); } else if (field_0x91E == 0) { @@ -610,11 +610,11 @@ void dAcOropeIgaiga_c::fn_257_1DF0() { void dAcOropeIgaiga_c::fn_257_1F20() { s16 ang = mStateMgr.isState(StateID_Rope) ? 0xb6 : 0x4fa; s16 random = cM::rndInt(0x222); - s32 ang2 = ang + random; - if (ang2 & 1) { - ang2 = (s16)-ang2; + s32 rotationXOffset = ang + random; + if (rotationXOffset & 1) { + rotationXOffset = (s16)-rotationXOffset; } - mRotationXOffset = ang2; + mRotationXOffset = rotationXOffset; } void dAcOropeIgaiga_c::fn_257_1FD0() { @@ -706,9 +706,7 @@ const f32 dAcOropeIgaiga_c::sLinkCenterTranslationYOffset[6] = {20.f, 30.f, -55. bool dAcOropeIgaiga_c::fn_257_2310(s16 rotationYOffset) { if (mStickTimer != 0) { mVec3_c linkCenterTranslation = dAcPy_c::GetLink()->getCenterTranslation(); - getXZCirclePoint( - linkCenterTranslation, dAcPy_c::GetLink()->mRotation.y + rotationYOffset, mXZCirclePointFactor - ); + getXZCirclePoint(linkCenterTranslation, dAcPy_c::GetLink()->mRotation.y + rotationYOffset, mRadius); linkCenterTranslation.y += sLinkCenterTranslationYOffset[mYOffsetIdx]; if (mStickTimer == 10 && mYOffsetIdx < 4) { mVec3_c linkPos = dAcPy_c::GetLink()->mPosition;