From b017949c4b37acbfea90fdd5641dbdceaee688a7 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sat, 13 Dec 2025 01:23:37 +0100 Subject: [PATCH 1/5] d_t_mass_obj 99% --- config/SOUE01/splits.txt | 2 +- config/SOUE01/symbols.txt | 116 +-- include/JSystem/JMath/JMath.h | 2 +- include/c/c_counter.h | 15 + include/d/a/d_a_base.h | 12 + include/d/col/c/c_cc_d.h | 16 + include/d/col/cc/d_cc_mass_s.h | 3 + include/d/d_light_env.h | 30 +- include/d/d_player_act.h | 10 +- include/d/t/d_t_mass_obj.h | 301 +++++++ include/egg/math/eggQuat.h | 22 + include/egg/math/eggVector.h | 7 + include/m/m_mtx.h | 10 + include/nw4r/ut/ut_Color.h | 11 + src/d/tg/d_t_mass_object.cpp | 1509 ++++++++++++++++++++++++++++++++ 15 files changed, 2003 insertions(+), 63 deletions(-) create mode 100644 include/c/c_counter.h create mode 100644 src/d/tg/d_t_mass_object.cpp diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 02c56d5e..501527d4 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -1539,7 +1539,7 @@ d/tg/d_t_mass_object.cpp: .rodata start:0x804EE5A8 end:0x804EE6C0 .data start:0x80536478 end:0x80536608 .sbss start:0x80575930 end:0x80575938 - .bss start:0x805B57A8 end:0x805B57C0 + .bss start:0x805B57A8 end:0x805B57BC d/tg/d_t_camera.cpp: .text start:0x8027A0B0 end:0x8027A370 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index e86041fb..95a9bae3 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -14557,56 +14557,56 @@ initializeState__21sFStateID_c<7dTgSw_c>CFR7dTgSw_c = .text:0x80275280; // type: __sinit_\d_t_switch_cpp = .text:0x802752B0; // type:function size:0x338 scope:local __dt__21sFStateID_c<7dTgSw_c>Fv = .text:0x802755F0; // type:function size:0x58 scope:weak isSameName__21sFStateID_c<7dTgSw_c>CFPCc = .text:0x80275650; // type:function size:0x88 scope:weak -TgMassObj__ctor = .text:0x802756E0; // type:function size:0x4C -getCurrentStageGrassSubtype = .text:0x80275730; // type:function size:0x124 -fn_80275860 = .text:0x80275860; // type:function size:0x8 -TgMassObj__init = .text:0x80275870; // type:function size:0x85C -fn_802760D0 = .text:0x802760D0; // type:function size:0x14 -TgMassObj__destroy = .text:0x802760F0; // type:function size:0xB4 -fn_802761B0 = .text:0x802761B0; // type:function size:0x7C -TgMassObj__update = .text:0x80276230; // type:function size:0xEC -TgMassObj__draw = .text:0x80276320; // type:function size:0x74 +dTgMassObj_c_classInit__Fv = .text:0x802756E0; // type:function size:0x4C +getCurrentStageGrassSubtype__12dTgMassObj_cFv = .text:0x80275730; // type:function size:0x124 +actorCreate__12dTgMassObj_cFv = .text:0x80275860; // type:function size:0x8 +actorPostCreate__12dTgMassObj_cFv = .text:0x80275870; // type:function size:0x85C +__ct__29TList<18dTgMassObjInstance,0>Fv = .text:0x802760D0; // type:function size:0x14 +doDelete__12dTgMassObj_cFv = .text:0x802760F0; // type:function size:0xB4 +__dt__10GrassModelFv = .text:0x802761B0; // type:function size:0x7C +actorExecute__12dTgMassObj_cFv = .text:0x80276230; // type:function size:0xEC +draw__12dTgMassObj_cFv = .text:0x80276320; // type:function size:0x74 unloadRoom__12dTgMassObj_cFUs = .text:0x802763A0; // type:function size:0x60 -fn_80276400 = .text:0x80276400; // type:function size:0x250 -fn_80276650 = .text:0x80276650; // type:function size:0x260 -fn_802768B0 = .text:0x802768B0; // type:function size:0xB4 -fn_80276970 = .text:0x80276970; // type:function size:0x60 -fn_802769D0 = .text:0x802769D0; // type:function size:0x40 -fn_80276A10 = .text:0x80276A10; // type:function size:0x40 -fn_80276A50 = .text:0x80276A50; // type:function size:0x3C8 -fn_80276E20 = .text:0x80276E20; // type:function size:0x20 -fn_80276E40 = .text:0x80276E40; // type:function size:0x3C -fn_80276E80 = .text:0x80276E80; // type:function size:0x44 -fn_80276ED0 = .text:0x80276ED0; // type:function size:0x288 -fn_80277160 = .text:0x80277160; // type:function size:0x94 -fn_80277200 = .text:0x80277200; // type:function size:0x58 -fn_80277260 = .text:0x80277260; // type:function size:0x74 -fn_802772E0 = .text:0x802772E0; // type:function size:0xD8 -fn_802773C0 = .text:0x802773C0; // type:function size:0x80 -fn_80277440 = .text:0x80277440; // type:function size:0xE0 -fn_80277520 = .text:0x80277520; // type:function size:0xB4 -fn_802775E0 = .text:0x802775E0; // type:function size:0xA0 -fn_80277680 = .text:0x80277680; // type:function size:0x150 -fn_802777D0 = .text:0x802777D0; // type:function size:0x48 -fn_80277820 = .text:0x80277820; // type:function size:0x28 -fn_80277850 = .text:0x80277850; // type:function size:0x1EC -fn_80277A40 = .text:0x80277A40; // type:function size:0x20C -fn_80277C50 = .text:0x80277C50; // type:function size:0x1014 -fn_80278C70 = .text:0x80278C70; // type:function size:0x5A0 -fn_80279210 = .text:0x80279210; // type:function size:0x394 -fn_802795B0 = .text:0x802795B0; // type:function size:0xBC -fn_80279670 = .text:0x80279670; // type:function size:0xC8 -fn_80279740 = .text:0x80279740; // type:function size:0x84 -fn_802797D0 = .text:0x802797D0; // type:function size:0x48 -fn_80279820 = .text:0x80279820; // type:function size:0xD0 -fn_802798F0 = .text:0x802798F0; // type:function size:0x64 -fn_80279960 = .text:0x80279960; // type:function size:0x60 -fn_802799C0 = .text:0x802799C0; // type:function size:0x64 -fn_80279A30 = .text:0x80279A30; // type:function size:0x1D4 -fn_80279C10 = .text:0x80279C10; // type:function size:0x418 -fn_8027A030 = .text:0x8027A030; // type:function size:0x5C -fn_8027A090 = .text:0x8027A090; // type:function size:0x4 -fn_8027A0A0 = .text:0x8027A0A0; // type:function size:0x4 +initializeCircle__12dTgMassObj_cFP10GrassModelP7mVec3_cP7mVec3_clP6mMtx_clUlUcilUcf = .text:0x80276400; // type:function size:0x250 +initializeBox__12dTgMassObj_cFP10GrassModelP7mVec3_cP7mVec3_ciP6mMtx_ciUlUcilUcf = .text:0x80276650; // type:function size:0x260 +remove__10GrassModelFv = .text:0x802768B0; // type:function size:0xB4 +__dt__14GrassModelDataFv = .text:0x80276970; // type:function size:0x60 +__dt__18dTgMassObjInstanceFv = .text:0x802769D0; // type:function size:0x40 +__dt__19dTgMassObjTransformFv = .text:0x80276A10; // type:function size:0x40 +setModelInfo__10GrassModelFffilUsUsiUclUlP16mHeapAllocator_c = .text:0x80276A50; // type:function size:0x3C8 +__ct__14GrassModelDataFv = .text:0x80276E20; // type:function size:0x20 +__ct__18dTgMassObjInstanceFv = .text:0x80276E40; // type:function size:0x3C +initResForModel__10GrassModelFlQ34nw4r3g3d6ResMatQ34nw4r3g3d6ResShp = .text:0x80276E80; // type:function size:0x44 +spawnSingleGrass__10GrassModelFiUsP7mVec3_cUsliilUc = .text:0x80276ED0; // type:function size:0x288 +addToRoom__10GrassModelFUllP18dTgMassObjInstance = .text:0x80277160; // type:function size:0x94 +addToFreeInstances__10GrassModelFP18dTgMassObjInstance = .text:0x80277200; // type:function size:0x58 +unloadRoom__10GrassModelFUs = .text:0x80277260; // type:function size:0x74 +update__10GrassModelFv = .text:0x802772E0; // type:function size:0xD8 +draw__10GrassModelFv = .text:0x802773C0; // type:function size:0x80 +aquireTransform__10GrassModelFv = .text:0x80277440; // type:function size:0xE0 +releaseTransform__10GrassModelFP19dTgMassObjTransform = .text:0x80277520; // type:function size:0xB4 +__ct__19dTgMassObjTransformFv = .text:0x802775E0; // type:function size:0xA0 +update__19dTgMassObjTransformFv = .text:0x80277680; // type:function size:0x150 +releaseDynamicTransform__18dTgMassObjInstanceFP10GrassModel = .text:0x802777D0; // type:function size:0x48 +reset__18dTgMassObjInstanceFv = .text:0x80277820; // type:function size:0x28 +getDrawMatrix__18dTgMassObjInstanceFP6mMtx_c = .text:0x80277850; // type:function size:0x1EC +checkForHit__18dTgMassObjInstanceFP10GrassModelP14GrassModelDataUs = .text:0x80277A40; // type:function size:0x20C +checkForHit__18dTgMassObjInstanceFUlR15dCcMassS_HitInfP12dAcObjBase_cP10GrassModelP14GrassModelDataUl = .text:0x80277C50; // type:function size:0x1014 +FUN_80278c70__18dTgMassObjInstanceFUlR15dCcMassS_HitInfP9dAcBase_cP10GrassModel = .text:0x80278C70; // type:function size:0x5A0 +handleLinkSpinAttack__18dTgMassObjInstanceFP10GrassModel = .text:0x80279210; // type:function size:0x394 +isHidden__18dTgMassObjInstanceFff = .text:0x802795B0; // type:function size:0xBC +handleTimeshiftZone__18dTgMassObjInstanceFv = .text:0x80279670; // type:function size:0xC8 +tryCreateLinkedLists__14GrassModelDataFlPQ23EGG4Heap = .text:0x80279740; // type:function size:0x84 +destroyLinkedLists__14GrassModelDataFv = .text:0x802797D0; // type:function size:0x48 +unloadRoom__14GrassModelDataFP10GrassModeli = .text:0x80279820; // type:function size:0xD0 +initRes__14GrassModelDataFQ34nw4r3g3d6ResMatQ34nw4r3g3d6ResShp = .text:0x802798F0; // type:function size:0x64 +addToRoom__14GrassModelDataFlP18dTgMassObjInstance = .text:0x80279960; // type:function size:0x60 +removeFromRoom__14GrassModelDataFlP18dTgMassObjInstance = .text:0x802799C0; // type:function size:0x64 +update__14GrassModelDataFP10GrassModel = .text:0x80279A30; // type:function size:0x1D4 +draw__14GrassModelDataFffPQ34nw4r4math5MTX34 = .text:0x80279C10; // type:function size:0x418 +__dt__12dTgMassObj_cFv = .text:0x8027A030; // type:function size:0x5C +drawXlu__10GrassModelFv = .text:0x8027A090; // type:function size:0x4 +drawOpa__10GrassModelFv = .text:0x8027A0A0; // type:function size:0x4 TgCamera__ctor = .text:0x8027A0B0; // type:function size:0x4C TgCamera__init = .text:0x8027A100; // type:function size:0x54 fn_8027A160 = .text:0x8027A160; // type:function size:0x68 @@ -28649,8 +28649,10 @@ lbl_804EE3B8 = .rodata:0x804EE3B8; // type:object size:0xC0 data:4byte @LOCAL@checkIsClear__9dAcTbox_cCFv@fsIdxes@0 = .rodata:0x804EE478; // type:object size:0xD0 data:4byte lbl_804EE548 = .rodata:0x804EE548; // type:object size:0x30 lbl_804EE578 = .rodata:0x804EE578; // type:object size:0x30 align:4 data:float -TgMassObj__GRASS_A_TYPES = .rodata:0x804EE5A8; // type:object size:0xF8 data:4byte -lbl_804EE6A0 = .rodata:0x804EE6A0; // type:object size:0x20 +GRASS_A_TYPES = .rodata:0x804EE5A8; // type:object size:0x8C data:4byte +GRASS_MODEL_NAMES = .rodata:0x804EE634; // type:object size:0x3C data:4byte +GRASS_VECS = .rodata:0x804EE670; // type:object size:0x30 data:4byte +@LOCAL@FUN_80279c10__14GrassModelDataFffP6mMtx_c@fifoMtx = .rodata:0x804EE6A0; // type:object size:0x20 lbl_804EE6C0 = .rodata:0x804EE6C0; // type:object size:0x40 data:4byte lbl_804EE700 = .rodata:0x804EE700; // type:object size:0x28 data:4byte lbl_804EE728 = .rodata:0x804EE728; // type:object size:0x28 @@ -36451,9 +36453,9 @@ lbl_80536500 = .data:0x80536500; // type:object size:0xA data:string lbl_8053650C = .data:0x8053650C; // type:object size:0xA data:string lbl_80536518 = .data:0x80536518; // type:object size:0x1A data:string jumptable_80536534 = .data:0x80536534; // type:object size:0x28 scope:local -TgMassObj__vtable = .data:0x8053655C; // type:object size:0x74 -lbl_805365D0 = .data:0x805365D0; // type:object size:0x2C -lbl_805365FC = .data:0x805365FC; // type:object size:0xC +__vt__12dTgMassObj_c = .data:0x8053655C; // type:object size:0x74 +__vt__10GrassModel = .data:0x805365D0; // type:object size:0x2C +__vt__14GrassModelData = .data:0x805365FC; // type:object size:0xC g_profile_CAMERA_TAG = .data:0x80536608; // type:object size:0x10 TgCamera__vtable = .data:0x80536618; // type:object size:0x10 lbl_80536628 = .data:0x80536628; // type:object size:0x68 @@ -42566,7 +42568,7 @@ sCurrentObtainingItemOarcName = .sbss:0x80575918; // type:object size:0x4 data:4 @GUARD@checkIsClear__9dAcTbox_cCFv@offsets = .sbss:0x80575927; // type:object size:0x1 data:byte lbl_80575928 = .sbss:0x80575928; // type:object size:0x8 data:byte sInstance__12dTgMassObj_c = .sbss:0x80575930; // type:object size:0x4 data:4byte -lbl_80575934 = .sbss:0x80575934; // type:object size:0x4 data:4byte +sAllocator__12dTgMassObj_c = .sbss:0x80575934; // type:object size:0x4 data:4byte sDisp00ArrowRotation__14dLytPauseMgr_c = .sbss:0x80575938; // type:object size:0x4 align:4 data:float sDisp00ArrowLength__14dLytPauseMgr_c = .sbss:0x8057593C; // type:object size:0x4 align:4 data:float sInstance__14dLytPauseMgr_c = .sbss:0x80575940; // type:object size:0x4 data:4byte @@ -42636,7 +42638,7 @@ Udchuff = .sbss:0x80575B40; // type:object size:0x20 data:4byte Ydchuff = .sbss:0x80575B60; // type:object size:0x8 data:4byte sm_numberMemo__10sStateID_c = .sbss:0x80575B68; // type:object size:0x4 data:4byte sAssertCallback__7sAssert = .sbss:0x80575B70; // type:object size:0x4 data:4byte -cCounter_c__m_gameFrame = .sbss:0x80575B78; // type:object size:0x4 data:4byte +m_gameFrame__10cCounter_c = .sbss:0x80575B78; // type:object size:0x4 data:4byte lbl_80575B7C = .sbss:0x80575B7C; // type:object size:0x4 data:4byte mFirst__24DynamicModuleControlBase = .sbss:0x80575B80; // type:object size:0x4 data:4byte mLast__24DynamicModuleControlBase = .sbss:0x80575B84; // type:object size:0x4 data:4byte @@ -52391,7 +52393,7 @@ StateID_On__7dTgSw_c = .bss:0x805B56F8; // type:object size:0x30 data:4byte StateID_OffWait__7dTgSw_c = .bss:0x805B5738; // type:object size:0x30 data:4byte @5126 = .bss:0x805B5768; // type:object size:0xC scope:local StateID_Off__7dTgSw_c = .bss:0x805B5778; // type:object size:0x30 data:4byte -lbl_805B57A8 = .bss:0x805B57A8; // type:object size:0x18 data:4byte +sGrassModels__12dTgMassObj_c = .bss:0x805B57A8; // type:object size:0x14 data:4byte lbl_805B57C0 = .bss:0x805B57C0; // type:object size:0x10 TgTkEvnt__STATE_WAIT = .bss:0x805B57D0; // type:object size:0x30 data:4byte lbl_805B5800 = .bss:0x805B5800; // type:object size:0x10 diff --git a/include/JSystem/JMath/JMath.h b/include/JSystem/JMath/JMath.h index 343571b8..08e15fb9 100644 --- a/include/JSystem/JMath/JMath.h +++ b/include/JSystem/JMath/JMath.h @@ -214,8 +214,8 @@ namespace JMathInlineVEC { } inline f32 C_VECSquareMag(register const Vec* v) { - register f32 x_y; register f32 z; + register f32 x_y; register f32 res; #ifdef __MWERKS__ asm { diff --git a/include/c/c_counter.h b/include/c/c_counter.h new file mode 100644 index 00000000..5f3590e4 --- /dev/null +++ b/include/c/c_counter.h @@ -0,0 +1,15 @@ +#ifndef C_COUNTER_H +#define C_COUNTER_H + +#include "common.h" + +class cCounter_c { +public: + static s32 GetGameFrame() { + return m_gameFrame; + } +private: + static s32 m_gameFrame; +}; + +#endif diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index ee2350c6..f6823dae 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -158,6 +158,9 @@ public: mVec3_c &getPosition() { return mPosition; } + mVec3_c const &getPosition() const { + return mPosition; + } mAng3_c &getRotation() { return mRotation; } @@ -166,6 +169,11 @@ public: return mPosition - other.mPosition; } + void getPostionDifferenceOut(const mVec3_c &other, mVec3_c& result) const { + mVec3_c diff = (other - mPosition); + result = diff; + } + f32 getHeightDifference(const dAcBase_c &b) const { return mPosition.y - b.mPosition.y; } @@ -194,6 +202,10 @@ public: return mRoomID == room; } + void setRoomId(u32 room) { + mRoomID = room; + } + void unsetActorProperty(u32 property) { mActorProperties &= ~property; } diff --git a/include/d/col/c/c_cc_d.h b/include/d/col/c/c_cc_d.h index b4f7f4f2..58bf05e9 100644 --- a/include/d/col/c/c_cc_d.h +++ b/include/d/col/c/c_cc_d.h @@ -751,6 +751,13 @@ public: const mVec3_c &GetAtHitPos() const; mVec3_c &GetAtHitPos(); + const mVec3_c &GetAtHitPosInline() const { + return mAt.mHitPos; + } + + mVec3_c &GetAtHitPosInline() { + return mAt.mHitPos; + } bool GetAtFlag0x2() const; bool GetAtFlag0x4() const; bool GetAtFlag0x8() const; @@ -773,6 +780,9 @@ public: bool ChkTgAtHitType(u32) const; u32 GetTgAtHitType() const; + bool ChkAtType(u32 mask) const { + return mAt.MskType(mask); + } bool ChkTgBit14() const; u8 GetTgDamage() const; u16 GetTgDamageFlags() const; @@ -1051,6 +1061,12 @@ public: u32 ChkCo_0x40000000() { return mCo.MskSPrm(0x40000000); } + u32 ChkCo_0x10() { + return mCo.MskSPrm(0x10); + } + u32 ChkCo_0x2() { + return mCo.MskSPrm(0x2); + } /** * SET HIT diff --git a/include/d/col/cc/d_cc_mass_s.h b/include/d/col/cc/d_cc_mass_s.h index 056ec3cf..581120ea 100644 --- a/include/d/col/cc/d_cc_mass_s.h +++ b/include/d/col/cc/d_cc_mass_s.h @@ -63,6 +63,9 @@ public: cCcD_Obj *GetAtHitObj() const { return mpAtObj; } + cCcD_Obj *GetCoHitObj() const { + return mpCoObj; + } }; class dCcMassS_Mng { diff --git a/include/d/d_light_env.h b/include/d/d_light_env.h index 5e48e39e..a2267a02 100644 --- a/include/d/d_light_env.h +++ b/include/d/d_light_env.h @@ -434,6 +434,30 @@ public: return field_0x2F1C; } + bool getfield_0x38B0() const { + return field_0x38B0; + } + + void setfield_0x38B0(bool val) { + field_0x38B0 = val; + } + + f32 getfield_0x38C0() const { + return field_0x38C0; + } + + const mVec3_c& getfield_0x38B4() const { + return field_0x38B4; + } + + mVec3_c& getfield_0x38C8() { + return field_0x38C8; + } + + void setfield_0x38C4(s32 val) { + field_0x38C4 = val; + } + s32 getField_0x38DC() const { return field_0x38DC; } @@ -442,6 +466,10 @@ public: field_0x38DC = v; } + f32 getfield_0x5D44() const { + return field_0x5D44; + } + void setField_0x5D48(f32 val) { field_0x5D48 = val; } @@ -503,7 +531,7 @@ private: /* 0x48E4 */ Bpm4 field_0x48E4; /* 0x5CE4 */ PaletteDefaultMCF field_0x5CE4; /* 0x5D04 */ TwoPaletteDefaultMCF field_0x5D04; - /* 0x5D44 */ u8 field_0x5D44[0x5D48 - 0x5D44]; + /* 0x5D44 */ f32 field_0x5D44; /* 0x5D48 */ f32 field_0x5D48; /* 0x5D4C */ u8 field_0x5D4C[0x5D59 - 0x5D4C]; /* 0x5D59 */ struct { // Anonymous until more is known diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 4d3b9dc2..b8c465dd 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -61,8 +61,8 @@ public: /* vt 0x0C0 */ virtual bool isUsingWhip() const { return false; } - /* vt 0x0C4 */ virtual bool anotherThingWithWhip() { - return false; + /* vt 0x0C4 */ virtual const mVec3_c* anotherThingWithWhip() { + return nullptr; } /* vt 0x0C8 */ virtual bool somethingWithWHip() { return false; @@ -642,7 +642,7 @@ public: return mAttackDirection == ATTACK_JUMP_SLASH; } - u16 getSpecificAttackDirection() const { + s32 getSpecificAttackDirection() const { return mSpecificAttackDirection; } @@ -650,6 +650,10 @@ public: return vt_0x1C0() != nullptr; } + static s32 getCurrentSwordTypeInline() { + return sCurrentSword; + } + static bool isInEvent(); bool isAttackingLeft() const; bool isAttackingRight() const; diff --git a/include/d/t/d_t_mass_obj.h b/include/d/t/d_t_mass_obj.h index bfb7166a..98a34f69 100644 --- a/include/d/t/d_t_mass_obj.h +++ b/include/d/t/d_t_mass_obj.h @@ -1,7 +1,255 @@ #ifndef D_T_MASS_OBJ_H #define D_T_MASS_OBJ_H +#include "c/c_math.h" +#include "common.h" +#include "d/d_heap.h" #include "d/t/d_tg.h" +#include "egg/core/eggHeap.h" +#include "egg/math/eggMatrix.h" +#include "egg/math/eggQuat.h" +#include "m/m3d/m_proc.h" +#include "m/m3d/m_scnleaf.h" +#include "m/m_angle.h" +#include "m/m_color.h" +#include "m/m_heap.h" +#include "m/m_mtx.h" +#include "m/m_quat.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resshp.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTypes.h" +#include "s/s_Math.h" +#include "toBeSorted/tlist.h" + +class dTgMassObjInstance; +class dTgMassObjTransform; +class GrassModel; +class GrassModelData; +class dCcMassS_HitInf; +class dAcObjBase_c; + +typedef TList dTgMassObjInstanceList; +typedef TList dTgMassObjTransformList; + +// a single piece of grass +// dTgMassObjInstance +// size: 0x34 +class dTgMassObjInstance { +public: + enum Flags { + TG_MASS_UNK2_IS_HIDDEN = 1, + TG_MASS_UNK2_IS_CUT = 2, + TG_MASS_UNK2_TIMESHIFT_RELATED = 4, + }; + dTgMassObjInstance(){ + reset(); + } + ~dTgMassObjInstance() {} + void reset(); + void releaseDynamicTransform(GrassModel *param_2); + s32 checkForHit(GrassModel *param2,GrassModelData *param3,u16 roomid); + undefined4 checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, + GrassModel *param_5,GrassModelData* param_6,undefined4 roomid); + undefined4 FUN_80278c70(u32 param_2,dCcMassS_HitInf & param_3,dAcBase_c *param_4, + GrassModel *param_5); + undefined4 handleLinkSpinAttack(GrassModel *param_2); + s32 handleTimeshiftZone(); + void getDrawMatrix(mMtx_c *pOut); + bool isHidden(f32 param2, f32 param3); + bool isItemDrop10() const { + return mSpecialItemDropId == 10; + } + +// private: + /* 0x00 */ TListNode mLink; + /* 0x08 */ GXColorS10 mTevColor; + /* 0x10 */ mVec3_c mGroundHeight; + /* 0x1C */ dTgMassObjTransform *mInitPosTransform; + /* 0x20 */ dTgMassObjTransform *mDynamicTransform; + /* 0x24 */ f32 field_0x24; // unused? + /* 0x28 */ f32 mScale; + /* 0x2C */ u16 mGrassFlags; + /* 0x2E */ u16 yRotation; + /* 0x30 */ u8 mSpecialItemDropId; + /* 0x31 */ u8 mLightingCode; + /* 0x32 */ u8 mMassObjSubtype; + /* 0x33 */ bool mActiveInPresent; +}; + +// a transform for a single piece of grass +// size: 0x50 +class dTgMassObjTransform { +public: + + dTgMassObjTransform(); + ~dTgMassObjTransform() {} + void update(); + const mMtx_c& getMtx() const { + return mMtx; + } + + void setQuat(const mQuat_c& quat) { + mQuat.set(quat); + } + + void setMtxFromQuat(const mQuat_c& quat) { + mMtx.fromQuat(quat); + } + + /* 0x00 */ s32 field_0x00; + /* 0x04 */ s32 field_0x04; + /* 0x08 */ mMtx_c mMtx; + /* 0x38 */ mAng mRotY; + /* 0x3A */ mAng mRotX; + /* 0x3C */ s16 mRotXSpeed; + /* 0x40 */ EGG::Quatf mQuat; +}; + +class GrassModelData { +public: + GrassModelData() : mLinkedLists(nullptr) {} + virtual ~GrassModelData() { + destroyLinkedLists(); + } + void initRes(nw4r::g3d::ResMat pResMat, nw4r::g3d::ResShp pResShp); + void addToRoom(s32 room, dTgMassObjInstance* p3); + void removeFromRoom(s32 room, dTgMassObjInstance* p3); + void update(GrassModel*); + bool tryCreateLinkedLists(s32 entrycount, EGG::Heap* heap); + void destroyLinkedLists(); + void unloadRoom(GrassModel *param_2,int roomid); + void draw(f32 param_1,f32 param_2, + nw4r::math::MTX34 *param_4); +private: + /* 0x04 */ nw4r::g3d::ResMat mResMat; + /* 0x08 */ nw4r::g3d::ResShp mResShp; + /* 0x0C */ dTgMassObjInstanceList* mLinkedLists; + /* 0x10 */ u16 mLinkedListsCount; +}; + +struct GrassModelInfo { + /* 0x00 */ char* mArcName; + /* 0x04 */ char* mModelName; + /* 0x08 */ char* mCutModelName; + /* 0x0C */ u32 field_0x0C; + /* 0x10 */ u16 mRadius; + /* 0x12 */ u16 field_0x12; + /* 0x14 */ u16 mInstanceCount; + /* 0x16 */ u16 mStaticTransformCount; + /* 0x18 */ u16 mDynamicTransformCount; + /* 0x1A */ u8 field_0x1A; + /* 0x1B */ u8 field_0x1B; // might be padding +}; + + +struct GrassModelNames { + /* 0x00 */ char* mArcName; + /* 0x04 */ char* mModelName; + /* 0x08 */ char* mCutModelName; +}; + +class GrassModel : public m3d::proc_c { +public: + GrassModel() : mpModelData(nullptr), mInstanceList(nullptr), mStaticTransformationList(nullptr), mDynamicTransformationList(nullptr), mCutCounter(0) {} + /* vt 0x08 */ virtual ~GrassModel() { + remove(); + } + undefined4 + setModelInfo(f32 radius,f32 param_2,int param_4, + s32 roomCount,u16 instanceListLength,u16 staticTransformationListLength,int dynamicTransformationListLength, + undefined1 param_9,s32 opaDrawPrio,u32 xluDrawPrio,mHeapAllocator_c *allocator); + undefined4 + spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHeight, + u16 yRotation,s32 specialItemDropId,int affectedByTimeshift,int activeInPresent, + s32 massObjSubtype,u8 lightingCode); + void addToFreeInstances(dTgMassObjInstance *param_2); + s32 addToRoom(u32 param2, s32 roomid, dTgMassObjInstance* param4); + void unloadRoom(u16 roomid); + void initResForModel(s32 param_2,nw4r::g3d::ResMat pResMat,nw4r::g3d::ResShp pResShp); + dTgMassObjTransform* aquireTransform(); + void update(); + void releaseTransform(dTgMassObjTransform*); + void setModelInfo(const GrassModelInfo* modelInfo, mHeapAllocator_c * heap) { + setModelInfo( + modelInfo->mRadius, modelInfo->field_0x0C, + modelInfo->field_0x12, 0x3F, + modelInfo->mInstanceCount, modelInfo->mStaticTransformCount, + modelInfo->mDynamicTransformCount, (f32)modelInfo->field_0x1A, + 0x7F, 0xFFFFFFFF, heap + ); + } + + void setRadius(f32 r) { + mRadius = r; + mRadiusSquared = r * r; + } + + void setInstanceLength(s32 len) { + mInstanceListLength = len; + } + + s32 getInstanceListLength() const { + return mInstanceListLength; + } + + s32 getDynamicTransformListLength() const { + return mDynamicTransformationListLength; + } + + dTgMassObjInstanceList& getFree() { + return mFreeInstances; + } + + bool testSpecialItemtype(s32 itemtype) { + return itemtype == 10; + } + + /* vt 0x10 */ virtual void remove() override; + // /* vt 0x14 */ virtual int entry(); + /* vt 0x18 */ virtual void drawOpa() override { + draw(); + } + /* vt 0x1C */ virtual void drawXlu() override { + draw(); + } + void draw(); + + void calcCutCounter() { + mCutCounter = (mCutCounter != 0) ? mCutCounter-1 : mCutCounter; + } + + dTgMassObjTransformList& GetUnk3Too() { + return mAquiredTransforms; + } + + dTgMassObjTransformList& GetUnk3() { + return mAvailableTransforms; + } + +// private: + /* 0x18 */ GrassModelData* mpModelData; + /* 0x1C */ dTgMassObjInstance* mInstanceList; + /* 0x20 */ dTgMassObjTransform* mStaticTransformationList; + /* 0x24 */ dTgMassObjTransform* mDynamicTransformationList; + /* 0x28 */ dTgMassObjInstanceList mFreeInstances; + /* 0x34 */ dTgMassObjTransformList mAquiredTransforms; + /* 0x40 */ dTgMassObjTransformList mAvailableTransforms; + /* 0x4C */ f32 mRadius; + /* 0x50 */ f32 mRadiusSquared; + /* 0x54 */ f32 field_0x54; + /* 0x58 */ u16 field_0x58; + /* 0x5A */ u16 mRoomCount; + /* 0x5C */ u16 mInstanceListLength; + /* 0x5E */ u16 mStaticTransformationListLength; + /* 0x60 */ u16 mDynamicTransformationListLength; + /* 0x62 */ u8 field_0x62; + /* 0x63 */ u8 field_0x63; + /* 0x64 */ s16 mCutCounter; + /* 0x66 */ u8 field_0x66; + /* 0x67 */ u8 field_0x67; +}; class dTgMassObj_c : public dTg_c { public: @@ -12,10 +260,63 @@ public: return sInstance; } + static u8 getCurrentStageGrassSubtype(); + void unloadRoom(u16 roomid); + int initializeCircle(GrassModel *grassModel, mVec3_c *bbStart, mVec3_c *bbEnd,s32 xzDisplacement,mMtx_c *param_7,s32 specialItemDropId, + undefined4 affectedByTimeshift,u8 activeInPresent,int randInt,s32 massObjSubtype, + u8 lightingCode, f32 fParam); + + int initializeBox(GrassModel *grassModel,mVec3_c *minVec, + mVec3_c *maxVec,int xzDisplacement,mMtx_c *boundsMtx,int specialItemDropId,undefined4 affectedByTimeshift, + u8 activeInPresent,int randInt,s32 massObjSubtype,u8 lightingCode, f32 fParam); + + virtual int actorExecute() override; + virtual int actorCreate() override; + virtual int actorPostCreate() override; + virtual int draw() override; + virtual int doDelete() override; + + mMtx_c getPreparedMtx() const { + mMtx_c mtx; + mtx.transS(mPosition); + mtx.YrotM(mRotation.y); + mtx.scaleM(mScale); + mMtx_c mtx2 = mtx; + mtx2.inverse(); + return mtx2; + } + + GrassModel* getGrassModel(s32 i) { + return sGrassModels[i]; + } + + void toGlobalRoom() { + s8 roomid = getRoomId(); + addActorToRoom(-1); + mRoomID = roomid; + } + + s32 getGrassTypeFromParams() { + return getFromParams(0, 7); + } + + mMtx_c makeBoundsMtx() { + mMtx_c mtx; + mtx.transS(mPosition); + mtx.YrotM(mRotation.y); + mtx.scaleM(mScale); + return mtx; + } + private: static dTgMassObj_c *sInstance; + static mHeapAllocator_c *sAllocator; + static GrassModel *sGrassModels[5]; + + /* 0x0FC */ s32 mMassSubtype; + /* 0x100 */ u8 field_0xFC[0x104 - 0x100]; }; #endif diff --git a/include/egg/math/eggQuat.h b/include/egg/math/eggQuat.h index a752b229..96808c56 100644 --- a/include/egg/math/eggQuat.h +++ b/include/egg/math/eggQuat.h @@ -44,10 +44,26 @@ struct Quatf { Vector3f rotateVector(const Vector3f &); Vector3f rotateVectorInv(const Vector3f &); // not in SS void slerpTo(const Quatf &, f32, Quatf &out) const; + void slerpTo2(f32 fparam,const Quatf & param1, Quatf &out ) const { + const Quatf & tmp = param1; + slerpTo(tmp, fparam, out); + } void limitSlerpTo(const Quatf &, f32, f32, Quatf &out) const; void makeVectorRotationLimit(Vector3f &, Vector3f &, f32); // not in SS void makeVectorRotation(const Vector3f &, const Vector3f &); + // not sure about the name + f32 dot(const Quatf& other) const { + f32 ret = v.dot(other.v); + ret += w * other.w; + return ret; + } + + void set(const Quatf& other) { + v.set(other.v); + w = other.w; + } + void multScalar(f32 s) { w *= s; v.x *= s; @@ -58,6 +74,12 @@ struct Quatf { set(1.0f, 0.0f, 0.0f, 0.0f); } + void makeWPositive() { + if (w < 0.f) { + multScalar(-1.f); + } + } + Vector3f v; f32 w; }; diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index abcf1176..8886a45a 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -1,11 +1,14 @@ #ifndef EGG_VECTOR_H #define EGG_VECTOR_H +#include "JSystem/JMath/JMath.h" #include "common.h" #include "egg/math/eggMath.h" +#include "nw4r/math/math_arithmetic.h" #include "nw4r/math/math_triangular.h" #include "nw4r/math.h" +#include namespace EGG { @@ -132,6 +135,10 @@ struct Vector3f : public nw4r::math::VEC3 { return squaredLength() <= Math::epsilon(); } + bool isZero2() const { + return fabsf(JMathInlineVEC::C_VECSquareMag(*this)) <= Math::epsilon(); + } + void setZero() { x = y = z = 0.0f; } diff --git a/include/m/m_mtx.h b/include/m/m_mtx.h index ac131169..3cdb56bb 100644 --- a/include/m/m_mtx.h +++ b/include/m/m_mtx.h @@ -87,6 +87,11 @@ public: void inverse() { MTXInverse(*this, *this); } + mMtx_c copyInverse() { + mMtx_c ret = *this; + ret.inverse(); + return ret; + } void multVecZero(nw4r::math::VEC3 &out) const; ///< Converts the matrix to a vector. void zero(); ///< Zeroes out the matrix. @@ -142,6 +147,11 @@ public: MTXMultVec(*this, ret, ret); return ret; } + mVec3_c multVec2(const mVec3_c &v) const { + mVec3_c ret; + MTXMultVec(*this, v, ret); + return ret; + } void multVecSR(const mVec3_c &in, mVec3_c &out) const { MTXMultVecSR(*this, in, out); diff --git a/include/nw4r/ut/ut_Color.h b/include/nw4r/ut/ut_Color.h index e94ba43a..95ecc926 100644 --- a/include/nw4r/ut/ut_Color.h +++ b/include/nw4r/ut/ut_Color.h @@ -2,6 +2,7 @@ #define NW4R_UT_COLOR_H #include "nw4r/types_nw4r.h" +#include "rvl/GX/GXTypes.h" #include "rvl/GX.h" // IWYU pragma: export namespace nw4r { @@ -61,6 +62,16 @@ public: operator u32() const { return ToU32ref(); } + + operator GXColorS10() const { + GXColorS10 c; + c.r = r; + c.g = g; + c.b = b; + c.a = a; + return c; + } + // clang-format off static const u32 RED = 0xFF0000FF; static const u32 GREEN = 0x00FF00FF; diff --git a/src/d/tg/d_t_mass_object.cpp b/src/d/tg/d_t_mass_object.cpp new file mode 100644 index 00000000..a6cae7f3 --- /dev/null +++ b/src/d/tg/d_t_mass_object.cpp @@ -0,0 +1,1509 @@ +#include "c/c_counter.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_gnd_chk.h" +#include "d/col/c/c_cc_d.h" +#include "d/col/cc/d_cc_mass_s.h" +#include "d/col/cc/d_cc_s.h" +#include "d/d_camera.h" +#include "d/d_heap.h" +#include "d/d_light_env.h" +#include "d/d_player_act.h" +#include "d/d_sc_game.h" +#include "d/d_stage.h" +#include "d/d_stage_mgr.h" +#include "d/snd/d_snd_small_effect_mgr.h" +#include "d/t/d_t_mass_obj.h" +#include "d/d_heap_alloc.h" +#include "egg/core/eggHeap.h" +#include "egg/math/eggQuat.h" +#include "f/f_base.h" +#include "m/m3d/m3d.h" +#include "m/m3d/m_scnleaf.h" +#include "m/m_allocator.h" +#include "m/m_angle.h" +#include "m/m_color.h" +#include "m/m_heap.h" +#include "m/m_mtx.h" +#include "m/m_quat.h" +#include "m/m_vec.h" +#include "nw4r/g3d/g3d_draw1mat1shp.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/g3d/g3d_state.h" +#include "nw4r/g3d/platform/g3d_gpu.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resshp.h" +#include "nw4r/math/math_geometry.h" +#include "nw4r/math/math_types.h" +#include "rvl/GX/GXTev.h" +#include "rvl/GX/GXTransform.h" +#include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtx.h" +#include "s/s_Math.h" +#include "toBeSorted/d_emitter.h" +#include "toBeSorted/special_item_drop_mgr.h" +#include "toBeSorted/time_area_mgr.h" +#include + + +SPECIAL_ACTOR_PROFILE(MASS_OBJ_TAG, dTgMassObj_c, fProfile::MASS_OBJ_TAG, 0x28A, 0, 4); + +GrassModel* dTgMassObj_c::sGrassModels[5] = {}; +dTgMassObj_c* dTgMassObj_c::sInstance = nullptr; +mHeapAllocator_c* dTgMassObj_c::sAllocator = nullptr; + +u8 dTgMassObj_c::getCurrentStageGrassSubtype() { + u8 ret = 0; + if (dStageMgr_c::GetInstance()->isSTIFAreaFaron()) { + if (dScGame_c::isCurrentStage("D100") ||dScGame_c::isCurrentStage("B100")) { + ret = 4; + } else { + ret = 3; + } + } else if(dStageMgr_c::GetInstance()->isSTIFAreaEldin()) { + ret = 2; + } else if(dStageMgr_c::GetInstance()->isSTIFAreaLanayru()) { + ret = 1; + } + if (dScGame_c::isCurrentStage("D003")) { + ret = 0; + } else if (dScGame_c::isCurrentStage("D003_1") || dScGame_c::isCurrentStage("D003_2")) { + ret = 2; + } else if (dScGame_c::isCurrentStage("D003_3") || dScGame_c::isCurrentStage("D003_4")) { + ret = 1; + } else if (dScGame_c::isCurrentStage("D003_5") || dScGame_c::isCurrentStage("D003_6")) { + ret = 3; + } + return ret; +} + +int dTgMassObj_c::actorCreate() { + return SUCCEEDED; +} + +static const GrassModelInfo GRASS_A_TYPES[5] = { + { + "GrassA", + "GrassA", + "GrassACut", + 0x1770, + 0x64, + 0x2, + 0x7D0, + 0x8, + 0x80, + 0, + 0, + }, + { + "GrassA", + "GrassA", + "GrassACut", + 0x1770, + 0x64, + 0x2, + 0x3E8, + 0x8, + 0x80, + 0, + 0, + }, + { + "FlowerA00", + "FlowerA00", + "FlowerA00Cut", + 0x1770, + 0x64, + 0x2, + 0x12C, + 0x8, + 0x20, + 0x2, + 0, + }, + { + "FlowerB00", + "FlowerB00", + "FlowerB00Cut", + 0x1770, + 0x64, + 0x2, + 0x12C, + 0x8, + 0x20, + 0x2, + 0, + }, + { + "FlowerB01", + "FlowerB01", + "FlowerB01Cut", + 0x1770, + 0x64, + 0x2, + 0x12C, + 0x8, + 0x20, + 0x2, + 0, + }, +}; + +static const GrassModelNames GRASS_MODEL_NAMES[5] = { + { + "GrassA", + "GrassA", + "GrassACut", + }, + { + "GrassB", + "GrassB", + "GrassBCut", + }, + { + "GrassC", + "GrassC", + "GrassCCut", + }, + { + "GrassD", + "GrassD", + "GrassDCut", + }, + { + "GrassE", + "GrassE", + "GrassECut", + }, +}; + +static const f32 GRASS_VECS[4][3] = { + { + -0.5f, + 0.5f, + -0.5f, + }, + { + 0.5f, + 0.5f, + -0.5f, + }, + { + 0.5f, + -0.5f, + 0.5f, + }, + { + -0.5f, + -0.5f, + 0.5f, + }, +}; + +int dTgMassObj_c::actorPostCreate() { + s32 grassModelIndex = getGrassTypeFromParams(); + s32 retVar = SUCCEEDED; + if (sInstance == nullptr) { + sInstance = this; + toGlobalRoom(); + sAllocator = new (dHeap::work1Heap.heap) mHeapAllocator_c(); + for (s32 i = 0; i < 5; i++) { + sGrassModels[i] = new(dHeap::work1Heap.heap) GrassModel(); + } + if (sAllocator->createFrmHeap(0xFFFFFFFF, dHeap::work1Heap.heap, "dTgMassObj_c::m_allocator", 0x20, mHeap::OPT_NONE) == 0) { + return FAILED; + } + u8 grassSubtype = getCurrentStageGrassSubtype(); + for (s32 i = 0; i < 5; i++) { + const GrassModelInfo* modelInfo; + modelInfo = &GRASS_A_TYPES[i]; + sGrassModels[i]->setModelInfo(modelInfo, sAllocator); + if (i == 0) { + void* file = dAcObjBase_c::getOarcResFile(GRASS_MODEL_NAMES[grassSubtype].mArcName); + nw4r::g3d::ResFile res(file); + nw4r::g3d::ResMdl mdl = res.GetResMdl(GRASS_MODEL_NAMES[grassSubtype].mModelName); + sGrassModels[i]->initResForModel(0, mdl.GetResMat(0), mdl.GetResShp(0)); + mdl = res.GetResMdl(GRASS_MODEL_NAMES[grassSubtype].mCutModelName); + sGrassModels[i]->initResForModel(1, mdl.GetResMat(0), mdl.GetResShp(0)); + } else { + void* file = dAcObjBase_c::getOarcResFile(modelInfo->mArcName); + nw4r::g3d::ResFile res(file); + nw4r::g3d::ResMdl mdl = res.GetResMdl(modelInfo->mModelName); + sGrassModels[i]->initResForModel(0, mdl.GetResMat(0), mdl.GetResShp(0)); + mdl = res.GetResMdl(modelInfo->mCutModelName); + sGrassModels[i]->initResForModel(1, mdl.GetResMat(0), mdl.GetResShp(0)); + } + } + sAllocator->adjustFrmHeap(); + } else { + retVar = 2; + } + if (grassModelIndex == 0) { + grassModelIndex = 0; + mMassSubtype = getCurrentStageGrassSubtype(); + if (getFromParams(3, 1) != 0) { + if (getFromParams(0x12, 1) != 0) { + mMassSubtype = 1; + grassModelIndex = 0; + } else { + mMassSubtype = 0; + grassModelIndex = 1; + } + } + } else if (grassModelIndex == 1) { + mMassSubtype = 9; + grassModelIndex = 4; + } else if (grassModelIndex == 2) { + mMassSubtype = 7; + grassModelIndex = 2; + } else if (grassModelIndex == 3) { + if (s32(mParams >> 0x19) == 1) { + mMassSubtype = 9; + grassModelIndex = 4; + } else { + mMassSubtype = 8; + grassModelIndex = 3; + } + } + + s32 fromParam4 = getFromParams(4, 0x7F); + s32 fromParamB = getFromParams(0xB, 0x7F); + s32 affectedByTimeshift = getFromParams(3, 1); + s32 activeInPresent = getFromParams(0x12, 1); + s32 uVar6 = fromParam4 * 10; + f32 xzStep = uVar6; + s32 xzDisplacement = xzStep * (fromParamB / 100.f); + GrassModel** tmpGrassModel = &sGrassModels[grassModelIndex]; + + mMtx_c mtx; + mtx.transS(mPosition); + mtx.YrotM(mRotation.y); + mtx.scaleM(mScale); + mMtx_c boundsMtx = mtx.copyInverse(); + mVec3_c minVec(FLOAT_MAX, FLOAT_MAX, FLOAT_MAX); + mVec3_c maxVec(FLOAT_MIN, FLOAT_MIN, FLOAT_MIN); + + const f32 (*loop)[3] = &GRASS_VECS[0]; + for (s32 i = 0; i < ARRAY_LENGTH(GRASS_VECS); i++) { + mVec3_c mult = mtx.multVec2(mVec3_c(*(loop++))); + if (mult.x < minVec.x) { + minVec.x = mult.x; + } + if (mult.x > maxVec.x) { + maxVec.x = mult.x; + } + if (mult.y < minVec.y) { + minVec.y = mult.y; + } + if (mult.y > maxVec.y) { + maxVec.y = mult.y; + } + if (mult.z < minVec.z) { + minVec.z = mult.z; + } + if (mult.z > maxVec.z) { + maxVec.z = mult.z; + } + } + minVec.x += uVar6 - ((s32)minVec.x % uVar6); + minVec.z += uVar6 - ((s32)minVec.z % uVar6); + maxVec.x -= (s32)maxVec.x % uVar6; + maxVec.z -= (s32)maxVec.z % uVar6; + s32 specialItemDropId = getParams2UpperByte(); + fillUpperParams2Byte(); + mVec3_c groundCheckPos = mPosition; + groundCheckPos.y += 200; + u8 lightingCode = dBgS::GetInstance()->GetLightingCode(&groundCheckPos); + s32 rnd = 0; + // special item drop for farore's tear, unused + if (specialItemDropId == 10) { + if (getFromParams(0x15, 0xF) == 0) { + s32 tmp = initializeCircle(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, -1, mMassSubtype, lightingCode, xzStep); + rnd = cM::rndInt(tmp); + } else { + s32 tmp = initializeBox(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, -1, mMassSubtype, lightingCode, xzStep); + rnd = cM::rndInt(tmp); + } + } + if (getFromParams(0x15, 0xF) == 0) { + initializeCircle(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, rnd, mMassSubtype, lightingCode, xzStep); + } else { + initializeBox(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, rnd, mMassSubtype, lightingCode, xzStep); + } + return retVar; +} + +int dTgMassObj_c::doDelete() { + if (sInstance == this) { + GrassModel** modelP = sGrassModels; + for (s32 i = 0; i < 5; i++, modelP++) { + delete *modelP; + *modelP = nullptr; + } + delete sAllocator; + sAllocator = nullptr; + sInstance = nullptr; + } + return SUCCEEDED; +} + +int dTgMassObj_c::actorExecute() { + dLightEnv_c& lightEnv = dLightEnv_c::GetInstance(); + if (sInstance == nullptr) { + return NOT_READY; + } else { + dCcS::GetInstance()->GetMassMng().Prepare(); + GrassModel** modelP = sGrassModels; + for (s32 i = 0; i < 5; i++) { + if ((cCounter_c::GetGameFrame() & 1) == 0) { + (*modelP)->calcCutCounter(); + } + if (lightEnv.getfield_0x5D44() > 0.f) { + (*modelP)->setPriorityDraw(0x1C, 0); + } else { + (*modelP)->setPriorityDraw(0x7F, 0); + } + (*modelP++)->update(); + } + return SUCCEEDED; + } +} + +int dTgMassObj_c::draw() { + if (sInstance == nullptr) { + return NOT_READY; + } else { + GrassModel** modelP = sGrassModels; + for (s32 i = 0; i < 5; i++) { + (*modelP++)->entry(); + } + return SUCCEEDED; + } +} + +void dTgMassObj_c::unloadRoom(u16 roomid) { + GrassModel** modelP = sGrassModels; + for (s32 i = 0; i < 5; i++) { + (*modelP++)->unloadRoom(roomid); + } +} + +int dTgMassObj_c::initializeCircle(GrassModel *grassModel, mVec3_c *bbStart, mVec3_c *bbEnd,s32 xzDisplacement,mMtx_c *param_7,s32 specialItemDropIdParam, + undefined4 affectedByTimeshift,u8 activeInPresent,int randInt,s32 massObjSubtype, + u8 lightingCode, f32 fParam) +{ + f32 p4z = bbStart->z; + s32 iVar3 = 0; + while(p4z < bbEnd->z) { + f32 p4x = bbStart->x; + while (p4x < bbEnd->x) { + mVec3_c position( + p4x + cM::rndFX(xzDisplacement), + bbEnd->y, + p4z + cM::rndFX(xzDisplacement) + ); + mVec3_c multiplied; + param_7->multVec(position, multiplied); + mVec3_c nul(0,0,0); + multiplied.y = 0.f; + f32 length = multiplied.distance(nul); + if (length < 0.5f && dBgS_ObjGndChk::CheckPos(position) && + dBgS_ObjGndChk::GetGroundHeight() >= (bbStart->y - 100.f)) { + if (randInt >= 0) { + position.y = dBgS_ObjGndChk::GetGroundHeight(); + s32 specialItemDropId = specialItemDropIdParam; + if (specialItemDropId == 10) { + if (randInt == iVar3) { + specialItemDropIdParam = 0xFF; + } else { + specialItemDropId = 0xFF; + } + } + if (!grassModel->spawnSingleGrass(0, getRoomId(), &position, 0, specialItemDropId, affectedByTimeshift, activeInPresent, massObjSubtype, lightingCode)) { + return 0; + } + } + iVar3++; + } + + p4x += fParam; + + } + p4z += fParam; + } + return iVar3; +} + +int dTgMassObj_c::initializeBox(GrassModel *grassModel,mVec3_c *minVec, + mVec3_c *maxVec,int xzDisplacement,mMtx_c *boundsMtx,int specialItemDropIdParam,undefined4 affectedByTimeshift, + u8 activeInPresent,int randInt,s32 massObjSubtype,u8 lightingCode, f32 fParam) { + + f32 p4z = minVec->z; + s32 iVar3 = 0; + while(p4z < maxVec->z) { + f32 p4x = minVec->x; + while (p4x < maxVec->x) { + mVec3_c position( + p4x + cM::rndFX(xzDisplacement), + maxVec->y, + p4z + cM::rndFX(xzDisplacement) + ); + mVec3_c multiplied; + boundsMtx->multVec(position, multiplied); + if (-0.5f <= multiplied.x && multiplied.x <= 0.5f + && -0.5f <= multiplied.z && multiplied.z <= 0.5f && dBgS_ObjGndChk::CheckPos(position)) { + if (dBgS_ObjGndChk::GetGroundHeight() >= (minVec->y - 100.f)) { + if (randInt >= 0) { + position.y = dBgS_ObjGndChk::GetGroundHeight(); + s32 specialItemDropId = specialItemDropIdParam; + if (specialItemDropId == 10) { + if (randInt == iVar3) { + specialItemDropIdParam = 0xFF; + } else { + specialItemDropId = 0xFF; + } + } + if (!grassModel->spawnSingleGrass(0, getRoomId(), &position, 0, specialItemDropId, affectedByTimeshift, activeInPresent, massObjSubtype, lightingCode)) { + return 0; + } + } + } + iVar3++; + } + + p4x += fParam; + + } + p4z += fParam; + } + return iVar3; +} + + +void GrassModel::remove() { + if (mpModelData != nullptr) { + delete[] mpModelData; + mpModelData = nullptr; + } + if (mInstanceList != nullptr) { + delete[] mInstanceList; + mInstanceList = nullptr; + } + if (mStaticTransformationList != nullptr) { + delete[] mStaticTransformationList; + mStaticTransformationList = nullptr; + } + if (mDynamicTransformationList != nullptr) { + delete[] mDynamicTransformationList; + mDynamicTransformationList = nullptr; + } + m3d::scnLeaf_c::remove(); +} + +undefined4 GrassModel::setModelInfo(f32 radius,f32 param_2,int param_4, + s32 roomCount,u16 instanceListLength,u16 staticTransformationListLength,int dynamicTransformationListLength, + undefined1 param_9,s32 opaDrawPrio,u32 xluDrawPrio,mHeapAllocator_c *allocator) { + if (!create(allocator, nullptr)) { + return 0; + } + EGG::Heap* heap = allocator->mHeap; + mpModelData = new (heap, 4) GrassModelData[param_4]; + if (!mpModelData) { + remove(); + return 0; + } + GrassModelData* modelData = &mpModelData[0]; + for (s32 i = 0; i < param_4; i++) { + if (!(modelData++)->tryCreateLinkedLists(roomCount, heap)) { + remove(); + return 0; + } + } + mInstanceList = new (heap, 4) dTgMassObjInstance[instanceListLength]; + if (!mInstanceList) { + remove(); + return 0; + } + mStaticTransformationList = new (heap, 4) dTgMassObjTransform[staticTransformationListLength]; + if (!mStaticTransformationList) { + remove(); + return 0; + } + mDynamicTransformationList = new (heap, 4) dTgMassObjTransform[dynamicTransformationListLength]; + if (!mDynamicTransformationList) { + remove(); + return 0; + } + field_0x58 = param_4; + mRoomCount = roomCount; + mInstanceListLength = instanceListLength; + mStaticTransformationListLength = staticTransformationListLength; + mDynamicTransformationListLength = dynamicTransformationListLength; + mRadius = radius; + mRadiusSquared = radius * radius; + field_0x54 = param_2; + field_0x62 = param_9; + { + dTgMassObjInstance *itr1 = mInstanceList; + s32 i = 0; + if (getInstanceListLength() > 0) { + for (; i < getInstanceListLength(); i++) { + // regswap + mFreeInstances.append(itr1++); + } + } + } + { + dTgMassObjTransform *itr2 = mDynamicTransformationList; + s32 i = 0; + if (getDynamicTransformListLength() > 0) { + for (; i < getDynamicTransformListLength(); i++) { + // regswap + mAvailableTransforms.append(itr2++); + } + } + } + if (opaDrawPrio >= 0) { + setPriorityDraw(opaDrawPrio, 0); + setOption(nw4r::g3d::ScnObj::OPTION_DISABLE_DRAW_XLU, 1); + } else { + setPriorityDraw(0, xluDrawPrio); + setOption(nw4r::g3d::ScnObj::OPTION_DISABLE_DRAW_OPA, 1); + } + return 1; +} + +void GrassModel::initResForModel(s32 room,nw4r::g3d::ResMat pResMat,nw4r::g3d::ResShp pResShp) { + mpModelData[room].initRes(pResMat, pResShp); +} + +undefined4 GrassModel::spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHeight, + u16 yRotation,s32 specialItemDropId,int affectedByTimeshift,int activeInPresent, + s32 massObjSubtype,u8 lightingCode) { + const dLightEnv_c& lightEnv = dLightEnv_c::GetInstance(); + if (mFreeInstances.mCount == 0) { + return 0; + } + // almost + dTgMassObjInstance* first = &*mFreeInstances.GetBeginIter(); + mFreeInstances.remove(first); + first->reset(); + first->mGroundHeight.set(*groundHeight); + first->yRotation = yRotation; + first->mSpecialItemDropId = specialItemDropId; + first->mDynamicTransform = nullptr; + s32 chosen = cM::rndInt(mStaticTransformationListLength); + first->mInitPosTransform = &mStaticTransformationList[chosen]; + first->field_0x24 = cM::rndFX(0.2f) + 1.f; + first->mMassObjSubtype = massObjSubtype; + first->mLightingCode = lightingCode; + first->mTevColor = lightEnv.GetCurrentSpf().mActorPalette.field_0x02C; + if (first->mLightingCode == 0) { + first->mTevColor.r = 0.7f * first->mTevColor.r; + first->mTevColor.r &= 0xFF; + first->mTevColor.g = 0.6f * first->mTevColor.g; + first->mTevColor.g &= 0xFF; + first->mTevColor.b = 0.7f * first->mTevColor.b; + first->mTevColor.b &= 0xFF; + } + if (affectedByTimeshift) { + first->mGrassFlags |= dTgMassObjInstance::TG_MASS_UNK2_TIMESHIFT_RELATED; + if (activeInPresent) { + first->mActiveInPresent = true; + } else { + first->mScale = 0.f; + } + } + mpModelData[modelSubtype].addToRoom(roomid, first); + return 1; +} + +s32 GrassModel::addToRoom(u32 modelSubtype, s32 roomid, dTgMassObjInstance* pInstance) { + mpModelData[modelSubtype].addToRoom(roomid, pInstance); + if (modelSubtype == 1) { + SpecialItemDropMgr::GetInstance()->giveSpecialDropItem(pInstance->mSpecialItemDropId, roomid, &pInstance->mGroundHeight, 0, 0, -1); + pInstance->mSpecialItemDropId = 0xFF; + } + return 1; +} + +void GrassModel::addToFreeInstances(dTgMassObjInstance *param_2) { + mFreeInstances.append(param_2); +} + +void GrassModel::unloadRoom(u16 roomid) { + GrassModelData* modelData = mpModelData; + for (s32 i = 0; i < field_0x58; i++) { + (modelData++)->unloadRoom(this, roomid); + } +} + +inline void SetMassMngAttr(f32 radius, f32 height, u8 param_2, u8 param_3) { + dCcS::GetInstance()->GetMassMng().SetAttr(radius, height, param_2, param_3); +} + +void GrassModel::update() { + dTgMassObjTransform* obj = mStaticTransformationList; + for (s32 i = 0; i < mStaticTransformationListLength; obj++, i++ ) { + obj->update(); + } + SetMassMngAttr(mRadius, mRadius * 2, 0xB, field_0x62); + GrassModelData* modelData = mpModelData; + for (s32 i = 0; i < field_0x58; i++) { + (modelData++)->update(this); + } +} + +void GrassModel::draw() { + nw4r::math::MTX34 cameraMtx; + m3d::getCurrentCamera().GetCameraMtx(&cameraMtx); + GrassModelData* data = mpModelData; + for (s32 i = 0; i < field_0x58; data++, i++) { + data->draw(mRadius, field_0x54, &cameraMtx); + } +} + +dTgMassObjTransform* GrassModel::aquireTransform() { + if (mAvailableTransforms.mCount == 0) { + return nullptr; + } + // not exactly, this produces an additional instruction + dTgMassObjTransform * first = &*(mAvailableTransforms.GetBeginIter()); + mAvailableTransforms.remove(first); + mAquiredTransforms.append(first); + return first; +} + +// regalloc, should be equivalent +void GrassModel::releaseTransform(dTgMassObjTransform* param2) { + mAquiredTransforms.remove(param2); + mAvailableTransforms.append(param2); +} + +static s32 lbl_80573AF0 = 0x1000; + +dTgMassObjTransform::dTgMassObjTransform() { + field_0x00 = 0; + field_0x04 = 0; + mRotXSpeed = 0; + mRotY = cM::rndInt(0x10000); + mRotX = lbl_80573AF0; + mQuat.setUnit(); + s32 rnd = cM::rndInt(100); + for (s32 i = 0; i < rnd; i++) { + update(); + } +} + +#define CLAMP2(low, high, x) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x))) + +// matches besides data +void dTgMassObjTransform::update() { + mRotXSpeed -= (s16)(mRotX * 0.005f); + mRotXSpeed = CLAMP2(-0x4B, 0x4B, mRotXSpeed); + mRotX += mRotXSpeed; + mVec3_c tmp1(0, 1, 0); + mVec3_c tmp2(0, 1, 0); + tmp2.rotX(mRotX); + tmp2.rotY(mRotY); + EGG::Quatf quat; + quat.makeVectorRotation(tmp1, tmp2); + mQuat.slerpTo(quat, 0.5f, mQuat); + mQuat.normalise(); + mQuat.makeWPositive(); + mMtx.fromQuat(mQuat); +} + +void dTgMassObjInstance::releaseDynamicTransform(GrassModel *param_2) { + if (mDynamicTransform != nullptr) { + param_2->releaseTransform(mDynamicTransform); + mDynamicTransform = nullptr; + } +} + +void dTgMassObjInstance::reset() { + mGrassFlags = 0; + mTevColor.a = 0; + mTevColor.b = 0; + mTevColor.g = 0; + mTevColor.r = 0; + mActiveInPresent = false; + mScale = 1; +} + +// matches besides data +void dTgMassObjInstance::getDrawMatrix(mMtx_c *pOut) { + if (mDynamicTransform != nullptr) { + *pOut = mDynamicTransform->getMtx(); + } else if (mInitPosTransform != nullptr) { + *pOut = mInitPosTransform->getMtx(); + } else { + pOut->YrotS(yRotation); + } + pOut->setBase(3, mGroundHeight); + pOut->scaleM(mScale, mScale, mScale); + s32 sure = ((s16)mGroundHeight.x >> 1) & 7; + pOut->scaleM( + sure * 0.015f + 1.f, + sure * 0.015f + 1.f, + sure * 0.015f + 1.f + ); +} + +// matches besides data +s32 dTgMassObjInstance::checkForHit(GrassModel *param_2, + GrassModelData *param_3,u16 roomid) { + dCcMassS_HitInf massHitInf; + dAcObjBase_c* actor; + u32 chk = dCcS::GetInstance()->GetMassMng().Chk(&mGroundHeight, &actor, &massHitInf); + s32 iVar5 = checkForHit(chk, massHitInf, actor, param_2, param_3, roomid); + if (iVar5 == 0 + && FUN_80278c70(chk, massHitInf, actor, param_2) == 0 + && handleLinkSpinAttack(param_2) == 0) { + if (mDynamicTransform != nullptr) { + EGG::Quatf& dynQuat = mDynamicTransform->mQuat; + f32 fVar2 = (mInitPosTransform->mQuat.dot(dynQuat)); + fVar2 *= 0.1f; + if (fVar2 < 0.1f) { + fVar2 = 0.1f; + } + dynQuat.slerpTo(mInitPosTransform->mQuat, fVar2, dynQuat); + mDynamicTransform->mQuat.normalise(); + mDynamicTransform->mQuat.makeWPositive(); + mDynamicTransform->mMtx.fromQuat(mDynamicTransform->mQuat); + if (mInitPosTransform->mQuat.dot(mDynamicTransform->mQuat) >= 1.f) { + param_2->releaseTransform(mDynamicTransform); + mDynamicTransform = nullptr; + } + } + return 0; + } else { + return 1; + } +} + +// matches besides data +undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, + GrassModel *param_5,GrassModelData* param_6,undefined4 roomid) { + dAcPy_c * link = dAcPy_c::GetLinkM(); + if (link == nullptr) { + return 0; + } + if ((param_2 & 1) == 0 || param_4 == nullptr) { + return 0; + } + f32 impactDistanceFactor; + f32 impactFactor; + f32 maybeMaxImpactDistance = 0.f; + f32 distance; + s32 isNotCut; + f32 fVar20; + f32 fVar5; + f32 fVar4; + f32 fVar2; + f32 fVar21; + mVec3_c localB4(0.f,1.f,0.f); + cCcD_Obj * hitObj = param_3.GetAtHitObj(); + if (hitObj != nullptr) { + mVec3_c& p4Pos = param_4->getPosition(); + mVec3_c hitPosition = param_4->mPosition; + s32 needsLightingRelated = 0; + impactFactor = 0.f; + if (hitObj->ChkAtType(AT_TYPE_BELLOWS)) { + hitPosition = link->mPosition; + needsLightingRelated = 1; + maybeMaxImpactDistance = 1000.f; + impactFactor = cM::rndF(0.5f) + 0.5f; + isNotCut = 1; + } else if (hitObj->ChkAtType(AT_TYPE_SLINGSHOT)) { + maybeMaxImpactDistance = 120.f; + impactFactor = cM::rndF(0.06f) + 0.6f; + isNotCut = 1; + } else if (hitObj->ChkAtType(AT_TYPE_0x200000) || hitObj->ChkAtType(AT_TYPE_BUGNET)) { + maybeMaxImpactDistance = 1000.f; + impactFactor = cM::rndF(0.2f) + 0.6f; + isNotCut = 1; + } else if (hitObj->ChkAtType(AT_TYPE_0x40)) { + mVec3_c localCC = mGroundHeight; + isNotCut = 1; + if (std::fabsf(localCC.y - param_4->mPosition.y) < 60.f) { + localCC.y = param_4->mPosition.y; + f32 dist = localCC.distance(p4Pos); + if (dist < 160.f) { + isNotCut = 0; + } + } + if (isNotCut == 1) { + maybeMaxImpactDistance = 600.f; + impactFactor = cM::rndF(0.3f) + 0.3f; + } + needsLightingRelated = 1; + + } else if (hitObj->ChkAtType(AT_TYPE_BEETLE)) { + mVec3_c localD8 = mGroundHeight; + isNotCut = 1; + if (std::fabsf(localD8.y - param_4->mPosition.y) < 80.f) { + localD8.y = param_4->mPosition.y; + f32 dist = localD8.distance(param_4->mPosition); + if (dist < 160.f) { + isNotCut = 0; + } + } + if (isNotCut == 1) { + maybeMaxImpactDistance = 800.f; + impactFactor = cM::rndF(0.2f) + 0.5f; + } + + } else if (hitObj->ChkAtType(AT_TYPE_WHIP)) { + mVec3_c localE4 = mGroundHeight; + hitPosition = *link->anotherThingWithWhip(); + if (localE4.distance(hitPosition) < 120.f) { + isNotCut = 0; + } else { + maybeMaxImpactDistance = 300.f; + impactFactor = cM::rndF(0.05f) + 0.5f; + isNotCut = 1; + } + } else if (hitObj->ChkAtType(AT_TYPE_0x800000)) { + isNotCut = 0; + } else if (hitObj->ChkAtType(AT_TYPE_ARROW)) { + mVec3_c localE4 = mGroundHeight; + if (localE4.distance(param_4->mPosition) < 80.f) { + isNotCut = 0; + } else { + maybeMaxImpactDistance = 200.f; + impactFactor = cM::rndF(0.04f) + 0.4f; + isNotCut = 1; + } + } else if (hitObj->ChkAtType(AT_TYPE_BOMB)) { + mVec3_c localE4 = mGroundHeight; + if (localE4.distance(param_4->mPosition) < 300.f) { + isNotCut = 0; + } else { + maybeMaxImpactDistance = 5000.f; + impactFactor = cM::rndF(0.09f) + 0.9f; + isNotCut = 1; + } + } else if (hitObj->ChkAtType(AT_TYPE_SWORD)) { + s32 currentSword = daPlayerActBase_c::getCurrentSwordTypeInline(); + fVar20 = 120.f; + fVar21 = 260.f; + fVar5 = 430.f; + fVar4 = 305.f; + fVar2 = 1000.f; + if (currentSword == 0) { + fVar5 = 200.f; + fVar21 = 150.f; + fVar2 = 180.f; + fVar4 = 200.f; + } else if (currentSword == 1) { + fVar21 = 170.f; + fVar5 = 400.f; + fVar4 = 250.f; + fVar2 = 200.f; + } else if (currentSword == 2 || currentSword == 3) { + fVar20 = 130.f; + fVar21 = 200.f; + fVar5 = 420.f; + fVar4 = 290.f; + fVar2 = 250.f; + } + hitPosition = link->mPosition; + distance = mGroundHeight.distance(hitPosition); + if (link->getSpecificAttackDirection() == 1 + || link->getSpecificAttackDirection() == 0x10 + || link->getSpecificAttackDirection() == 0x100) { + if (distance < fVar20) { + isNotCut = 0; + } else { + maybeMaxImpactDistance = 300.f; + impactFactor = cM::rndF(0.05f) + 0.5f; + isNotCut = 1; + if (distance >= fVar20 + 60.f) { + return 1; + } + } + } else { + if (mMassObjSubtype == 8 || mMassObjSubtype == 9) { + fVar21 = fVar20 * 0.8f; + hitPosition = dAcPy_c::GetLink()->getSwordPos(); + + distance = mGroundHeight.distance(hitPosition); + if (link->getSpecificAttackDirection() != 2 && link->getSpecificAttackDirection() != 0x80) { + return 1; + } + if (distance >= fVar21) { + return 1; + } + } + if (link->isAttackingSpin()) { + if (link->checkSwordAndMoreStates(daPlayerActBase_c::SKYWARD_STRIKE_ACTIVE)) { + fVar21 = fVar5; + } else { + fVar21 = fVar4; + } + } + if (distance < fVar21) { + isNotCut = 0; + } else if (distance < fVar2) { + maybeMaxImpactDistance = 5000.f; + impactFactor = cM::rndF(0.5f) + 0.5f; + isNotCut = 1; + } else { + return 1; + } + } + } else { + isNotCut = 0; + } + if (isNotCut == 1) { + // grass is not cut, just move + f32 fVar20 = cM::rndFX(0.025f) + 0.05f; + if (!hitObj->ChkAtType(AT_TYPE_WHIP) && !hitObj->ChkAtType(AT_TYPE_BELLOWS)) { + if ((!link->isAttackingSpin())) { + hitPosition = param_4->mPosition; + } + } + f32 tempDistance = mGroundHeight.distance(hitPosition); + if (tempDistance > maybeMaxImpactDistance) { + tempDistance = maybeMaxImpactDistance; + } + // check this for regalloc + impactDistanceFactor = (1.f - (tempDistance / maybeMaxImpactDistance) * (tempDistance / maybeMaxImpactDistance)); + if (mDynamicTransform == nullptr) { + mDynamicTransform = param_5->aquireTransform(); + if (mDynamicTransform == nullptr) { + return 0; + } + mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); + mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); + } + if (param_4 == nullptr) { + return 0; + } + mVec3_c local108 = mGroundHeight - hitPosition; + local108.rotY(0x4000); + local108.normalize(); + mVec3_c local114 = hitObj->mAt.mVec; + mVec3_c local120 = local114; + if (needsLightingRelated) { + fVar20 = cM::rndF(0.5f) + 0.15f; + hitPosition.y += 50.f; + dLightEnv_c::GetPInstance()->get_vectle_calc(&hitPosition, &mGroundHeight, &local120); + if (!local120.normalizeRS()) { + local120.x = 1.f; + local120.z = 0.f; + } + if (!local120.normalizeRS()) { + local120 = localB4; + } + } else if (local114.isZero2()) { + local120 = mGroundHeight - hitPosition; + if (!local120.normalizeRS()) { + local120.x = 1.f; + local120.z = 0.f; + } + local120.y = 0.5f; + if (!local120.normalizeRS()) { + local120 = localB4; + } + fVar20 = cM::rndF(0.5f) + 0.5f; + } else { + local114.y = 0.f; + local114.normalize(); + f32 fVar2 = local108.inprodXZ(local114); + if (fVar2 != 0.f) { + local120.y = 2.f / fVar2; + } + if (local108.inprodXZ(local114) >= 0.f) { + local120.rotY(-0x4000); + } else { + local120.rotY(0x4000); + } + if (!local120.normalizeRS()) { + local120 = localB4; + } + } + mQuat_c local130; + local130.makeVectorRotation(localB4, local120); + local130.slerpTo(mInitPosTransform->mQuat, 1.f - impactFactor * impactDistanceFactor, local130); + local130.normalise(); + local130.makeWPositive(); + mQuat_c local140; + mDynamicTransform->mMtx.toQuat(local140); + local140.slerpTo(local130, fVar20, local140); + local140.normalise(); + local140.makeWPositive(); + mDynamicTransform->mQuat.set(local130); + mDynamicTransform->mMtx.fromQuat(local140); + } else if (hitObj->ChkAtType(AT_TYPE_WIND)) { + if (mDynamicTransform == nullptr) { + mDynamicTransform = param_5->aquireTransform(); + if (mDynamicTransform == nullptr) { + return 0; + } + mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); + mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); + } + if (param_4 == nullptr) { + return 0; + } + mVec3_c local150 = mGroundHeight - param_4->mPosition; + mQuat_c local160; + local150.y = 0.f; + local150.x *= (cM::rndFX(0.5f) + 0.5f); + local150.z *= (cM::rndFX(0.5f) + 0.5f); + if (!local150.normalizeRS()) { + local150 = localB4; + } + local160.makeVectorRotation(localB4, local150); + // float regalloc + f32 fVar2 = (local160.dot(mDynamicTransform->mQuat)); + fVar2 *= 0.1f; + if (fVar2 < 0.1f) { + fVar2 = 0.1f; + } + local160.slerpTo2(cM::rndF(0.4f) + 0.3f, mInitPosTransform->mQuat, local160); + local160.normalise(); + local160.makeWPositive(); + mDynamicTransform->mQuat.slerpTo(local160, fVar2, mDynamicTransform->mQuat); + mDynamicTransform->mQuat.normalise(); + if (mDynamicTransform->mQuat.w < 0) { + mDynamicTransform->mQuat.multScalar(-1); + } + mDynamicTransform->mMtx.fromQuat(mDynamicTransform->mQuat); + } else { + // grass is cut + param_6->removeFromRoom(roomid, this); + param_5->addToRoom(1, roomid, this); + mGrassFlags |= TG_MASS_UNK2_IS_CUT; + if (mDynamicTransform != nullptr) { + // this is wrong... + yRotation = *(u16*)mDynamicTransform->mRotY.ref(); + param_5->releaseTransform(mDynamicTransform); + mDynamicTransform = nullptr; + } + yRotation = *(u16*)mInitPosTransform->mRotY.ref(); + mInitPosTransform = nullptr; + if (param_5->mCutCounter < 0x19) { + param_5->mCutCounter++; + mVec3_c local16C(mGroundHeight.x, mGroundHeight.y, mGroundHeight.z); + mColor local17C = 0xFFFFFFFF; + f32 camField2A8 = dScGame_c::getCamera()->getField_0x2A8(); + local17C.r = mTevColor.r; + local17C.g = mTevColor.g; + local17C.b = mTevColor.b; + local17C.a = mTevColor.a; + if (local16C.y + 100.f < camField2A8 && mMassObjSubtype <= 5) { + if (dScGame_c::isCurrentStage("D100")) { + mMassObjSubtype = 6; + } else { + mMassObjSubtype = 5; + } + } + dEmitterBase_c * ret; + switch (mMassObjSubtype) { + case 0: + dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_120_, local16C, nullptr, &local17C); + break; + case 1: + dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_121_, local16C, nullptr, &local17C); + break; + case 2: + dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_122_, local16C, nullptr, &local17C); + break; + case 3: + dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_123_, local16C, nullptr, &local17C); + break; + case 4: + dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_124_, local16C, nullptr, &local17C); + break; + case 5: + dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_687_, local16C, nullptr, &local17C); + break; + case 6: + dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_800_, local16C, nullptr, &local17C); + break; + case 7: + ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_838_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + if (ret != nullptr) { + ret->bindShpEmitter(0x24, true); + } + ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_839_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + if (ret != nullptr) { + ret->bindShpEmitter(0x25, true); + } + break; + case 8: + ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_840_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + if (ret != nullptr) { + ret->bindShpEmitter(0x26, true); + } + break; + case 9: + ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_841_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + if (ret != nullptr) { + ret->bindShpEmitter(0x27, true); + } + break; + } + dSndSmallEffectMgr_c::GetInstance()->playSoundAtPosition(SE_O_GRASS_CUT, mGroundHeight); + } + } + } + return 1; +} + +// non matching +undefined4 dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3, dAcBase_c *param_4, + GrassModel *param_5) { + mVec3_c local54 = mGroundHeight; + f32 fVar12 = 1000.f; + s32 iVar11 = 0; + f32 fVar1 = 0.55f; + if ((param_2 & 2) == 0) { + return 0; + } + if (param_4 == nullptr) { + param_4 = dAcPy_c::GetLinkM(); + } + if (param_3.GetCoHitObj()->ChkCo_0x10() && dAcPy_c::GetLink() != nullptr) { + mVec3_c local60 = mGroundHeight; + mVec3_c local6C; + if (dAcPy_c::GetLink()->isUsingBugnet()) { + local6C = dAcPy_c::GetLink()->getBugNetPos(); + } else { + local6C = dAcPy_c::GetLink()->vt_0x278(); + local6C += (dAcPy_c::GetLink()->getSwordPos() - dAcPy_c::GetLink()->vt_0x278()) * 0.5f; + } + local60.y += 60.f; + local54 = local60 - local6C; + fVar12 = local60.distance(local6C); + if (fVar12 > 40.f) { + iVar11 = 1; + } else { + fVar12 = 1 - fVar12 / 250.f; + } + } else { + iVar11 = param_3.GetCoHitObj()->ChkCo_0x2() ? 1 : 2; + } + if (iVar11 != 0) { + // TODO here + f32 fVar12_2 = 100.f; + if (iVar11 == 2) { + fVar12_2 = 200.f; + fVar1 = 0.8f; + } + local54 = mGroundHeight - param_4->getPosition(); + if (param_5->mRadiusSquared < local54.squareMagXZ()) { + return 0; + } + f32 distance = mGroundHeight.distance(param_4->getPosition()); + f32 fVar13; + if (distance > fVar12_2) { + fVar13 = fVar12_2; + } else { + fVar13 = distance; + if (iVar11 == 1) { + param_4->getSoundSource()->holdSound(SE_L_GRASS_RUSTLE_LV); + } + } + fVar12 = 1 - fVar13 / fVar12_2; + } + mVec3_c local78(0.f, 1.f, 0.f); + if (mDynamicTransform == nullptr) { + mDynamicTransform = param_5->aquireTransform(); + if (mDynamicTransform == nullptr) { + return 0; + } + mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); + mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); + } + if (local54.isZero2()) { + local54.set(1.f, 0.5f, 0.f); + } + mQuat_c local88; + mVec3_c local98 = local54; + if (!local98.normalizeRS()) { + local98.x = 1.f; + local98.z = 0.f; + } + local98.y = 0.5f; + if (!local98.normalizeRS()) { + local98 = local78; + } + local88.makeVectorRotation(local78, local98); + local88.slerpTo(mInitPosTransform->mQuat, 1 - fVar1 * fVar12, local88); + local88.normalise(); + local88.makeWPositive(); + mQuat_c localA8; + mDynamicTransform->mMtx.toQuat(localA8); + localA8.slerpTo(local88, cM::rndF(0.2f) + 0.2f, localA8); + localA8.normalise(); + localA8.makeWPositive(); + mDynamicTransform->setQuat(local88); + mDynamicTransform->setMtxFromQuat(localA8); + return 1; +} + +// matches besides data +undefined4 dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { + const dAcPy_c* link = dAcPy_c::GetLink(); + if (link == nullptr) { + return 0; + } + if (!link->isAttackingSpin()) { + return 0; + } else { + mVec3_c local3C; + dAcPy_c::GetLink()->getPostionDifferenceOut(mGroundHeight, local3C); + f32 dist = mGroundHeight.distance(dAcPy_c::GetLinkM()->getPosition()); + f32 comparison = 350.f; + if (link->isAttackingDown()) { + comparison = 150.f; + } else if (link->checkSwordAndMoreStates(daPlayerActBase_c::SKYWARD_STRIKE_ACTIVE)) { + comparison = 450.f; + } + if (dist > comparison) { + return 0; + } + mVec3_c local48(0.f, 1.f, 0.f); + if (mDynamicTransform == nullptr) { + mDynamicTransform = param_2->aquireTransform(); + if (mDynamicTransform == nullptr) { + return 0; + } + mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); + mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); + } + if (local3C.isZero2()) { + local3C.set(1.f, 0.5f, 0.f); + } + mQuat_c local58; + mVec3_c local68 = local3C; + if (!local68.normalizeRS()) { + local68.x = 1.f; + local68.z = 0.f; + } + local68.y = 0.5f; + if (!local68.normalizeRS()) { + local68 = local48; + } + local58.makeVectorRotation(local48, local68); + local58.slerpTo2(cM::rndF(0.5f), mInitPosTransform->mQuat, local58); + local58.normalise(); + local58.makeWPositive(); + mQuat_c local78; + mDynamicTransform->mMtx.toQuat(local78); + local78.slerpTo(local58, cM::rndF(0.3f) + 0.5f, local78); + local78.normalise(); + local78.makeWPositive(); + mDynamicTransform->mQuat.set(local58); + mDynamicTransform->setMtxFromQuat(local78); + return 1; + } +} + +extern "C" bool fn_801BB700(EGG::Quatf*,f32); + +// matches besides data +bool dTgMassObjInstance::isHidden(f32 param2, f32 param3) { + bool uVar1 = mSpecialItemDropId != 10; + if (uVar1) { + mVec3_c tmp2(mGroundHeight.x, mGroundHeight.y + param2, mGroundHeight.z); + EGG::Quatf tmp(param2 + 700.f, tmp2); + uVar1 = fn_801BB700(&tmp, param3); + } + if (uVar1) { + mGrassFlags |= dTgMassObjInstance::TG_MASS_UNK2_IS_HIDDEN; + return true; + } else { + mGrassFlags &= ~dTgMassObjInstance::TG_MASS_UNK2_IS_HIDDEN; + return false; + } +} + +// matches besides data +s32 dTgMassObjInstance::handleTimeshiftZone() { + s32 uVar1 = 1; + f32 fVar2 = dTimeAreaMgr_c::GetInstance()->checkPositionIsInPastState(-1, mGroundHeight, nullptr, 8.f); + if (mActiveInPresent == false) { + sLib::addCalc(&mScale, fVar2, 0.5f, 0.2f, 0.01f); + if (mScale <= 0) { + uVar1 = 0; + } + } else if (mActiveInPresent == true) { + sLib::addCalc(&mScale, 1.f - fVar2, 0.5f, 0.2f, 0.01f); + if (mScale <= 0) { + uVar1 = 0; + } + } + return uVar1; +} + +bool GrassModelData::tryCreateLinkedLists(s32 entrycount, EGG::Heap* heap) { + mLinkedLists = new (heap, 4) dTgMassObjInstanceList[entrycount]; + if (mLinkedLists == nullptr) { + destroyLinkedLists(); + return false; + } else { + mLinkedListsCount = entrycount; + return true; + } +} + +void GrassModelData::destroyLinkedLists() { + if (mLinkedLists != nullptr) { + delete [] mLinkedLists; + mLinkedLists = nullptr; + } +} + +void GrassModelData::unloadRoom(GrassModel *param_2,int roomid) { + dTgMassObjInstanceList& gll = mLinkedLists[roomid]; + dTgMassObjInstanceList::Iterator it = gll.GetBeginIter(); + while (it != gll.GetEndIter()) { + dTgMassObjInstance* lst = (&*(it)); + ++it; + lst->releaseDynamicTransform(param_2); + gll.remove(lst); + param_2->addToFreeInstances(lst); + } +} + +void GrassModelData::initRes(nw4r::g3d::ResMat pResMat, nw4r::g3d::ResShp pResShp) { + mResMat = pResMat; + mResShp = pResShp; + nw4r::g3d::ResMatChan chan = mResMat.GetResMatChan(); + chan.GXSetChanAmbColor(GX_COLOR0, mColor(0xFF, 0xFF, 0xFF, 0xFF)); +} + +void GrassModelData::addToRoom(s32 room, dTgMassObjInstance* p3) { + mLinkedLists[room].append(p3); +} + +// regalloc +void GrassModelData::removeFromRoom(s32 room, dTgMassObjInstance* p3) { + mLinkedLists[room].remove(p3); +} + +// matches besides data +void GrassModelData::update(GrassModel* param2) { + mVec3_c groundHeight(999999.f, 999999.f, 999999.f); + dLightEnv_c& lightEnv = dLightEnv_c::GetInstance(); + bool bVar1 = false; + s32 count = 0; + f32 minDist = lightEnv.getfield_0x38C0(); + dTgMassObjInstanceList* grassList = mLinkedLists; + for (s32 roomid = 0; roomid < mLinkedListsCount; roomid++, grassList++ ) { + if (grassList->mCount == 0 || dStage_c::GetInstance()->getRoom(roomid)->checkFlag(4)) { + continue; + } + dTgMassObjInstanceList::Iterator it = grassList->GetBeginIter(); + while (it != grassList->GetEndIter()) { + dTgMassObjInstance& lst = *it; + ++it; + if ((lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_TIMESHIFT_RELATED) && !lst.handleTimeshiftZone()) { + lst.mGrassFlags |= dTgMassObjInstance::TG_MASS_UNK2_IS_HIDDEN; + } else { + if ((lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_IS_HIDDEN) == 0 && (lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_IS_CUT) == 0) { + lst.checkForHit(param2, this, roomid); + } + if (lightEnv.getfield_0x38B0() == 1) { + if (lightEnv.getfield_0x38B4().distance(lst.mGroundHeight) < minDist) { + minDist = lightEnv.getfield_0x38B4().distance(lst.mGroundHeight); + groundHeight = lst.mGroundHeight; + } + if (lightEnv.getfield_0x38B4().distance(lst.mGroundHeight) < lightEnv.getfield_0x38C0()) { + bVar1 = true; + count++; + } + } + } + } + } + if (lightEnv.getfield_0x38B0() == 1) { + lightEnv.setfield_0x38B0(0); + if (bVar1) { + lightEnv.getfield_0x38C8() = groundHeight; + } + lightEnv.setfield_0x38C4(count); + } +} + +extern void LoadMaterial(nw4r::g3d::ResMat mat, u32 ctrl, nw4r::g3d::Draw1Mat1ShpSwap *pSwap, nw4r::g3d::G3DState::IndMtxOp *pIndMtxOp, bool bIgnoreMaterial); + +// matches besides data +void GrassModelData::draw(f32 param_1,f32 param_2, + nw4r::math::MTX34 *pMtx) { + mVec3_c cameraPosition = dScGame_c::getCamera()->getPositionMaybe(); + bool isInFaronWoods = dScGame_c::isCurrentStage("F100"); + nw4r::g3d::ResMatMisc miscData(mResMat.GetResMatMisc()); + miscData.SetLightSetIdx(1); + miscData.SetFogIdx(0); + LoadMaterial(mResMat, 0, nullptr, nullptr, false); + nw4r::g3d::G3DState::LoadResShpPrePrimitive(mResShp); + const static u32 fifoMtx[8] = { + 0x3C, + 0x3C, + 0x3C, + 0x3C, + 0x3C, + 0x3C, + 0x3C, + 0x3C, + }; + nw4r::g3d::fifo::GDSetCurrentMtx(fifoMtx); + GXSetCurrentMtx(0); + dTgMassObjInstanceList* grassList = mLinkedLists; + for (s32 roomid = 0; roomid < mLinkedListsCount; roomid++, grassList++ ) { + if (grassList->mCount == 0 || dStage_c::GetInstance()->getRoom(roomid)->checkFlag(4)) { + continue; + } + dTgMassObjInstanceList::Iterator it = grassList->GetBeginIter(); + for (;it != grassList->GetEndIter();++it) { + dTgMassObjInstance* lst = (&*it); + if (!lst->isHidden(param_1, param_2)) { + mMtx_c local160; + lst->getDrawMatrix(&local160); + f32 cameraDist = lst->mGroundHeight.distance(cameraPosition); + f32 fVar6 = param_2 * 0.6f; + if (cameraDist > fVar6) { + f32 fVar7 = (cameraDist - fVar6) / (param_2 - fVar6); + if (fVar7 > 1.f) { + fVar7 = 1.f; + } + if (fVar7 < 0.f) { + fVar7 = 0.f; + continue; + } else { + f32 scale = 1. - fVar7; // double + local160.scaleM(scale, scale, scale); + } + } + if (isInFaronWoods + && lst->mGroundHeight.x <= -5200.f + && lst->mGroundHeight.x >= -5500.f + && lst->mGroundHeight.z <= -5900.f + && lst->mGroundHeight.z >= -6100.f) { + local160.scaleM(1.f, 1.5f, 1.f); + } + f32 fVar7 = ((s32)(lst->mGroundHeight.x + lst->mGroundHeight.z) & 0x1F) / 31.f; + f32 scale = fVar7 * 0.1f + 1.f; + local160.scaleM(scale, scale, scale); + local160.YrotM(fVar7 * 65535.f); + MTXConcat(*pMtx, local160, local160); + GXLoadPosMtxImm(local160, 0); + GXLoadNrmMtxImm(local160, 0); + GXSetTevColorS10(GX_TEVREG1, lst->mTevColor); + mResShp.CallPrimitiveDisplayList(false); + } + } + } +} From ab4b5ef9156320a2d58cacf9e6b0ac2c431070b3 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:27:23 +0100 Subject: [PATCH 2/5] review --- include/JSystem/JMath/JMath.h | 2 +- include/d/t/d_t_mass_obj.h | 23 +-- include/egg/math/eggVector.h | 4 - include/m/m_mtx.h | 5 - src/d/tg/d_t_mass_object.cpp | 308 +++++++++++++++++----------------- 5 files changed, 159 insertions(+), 183 deletions(-) diff --git a/include/JSystem/JMath/JMath.h b/include/JSystem/JMath/JMath.h index 08e15fb9..343571b8 100644 --- a/include/JSystem/JMath/JMath.h +++ b/include/JSystem/JMath/JMath.h @@ -214,8 +214,8 @@ namespace JMathInlineVEC { } inline f32 C_VECSquareMag(register const Vec* v) { - register f32 z; register f32 x_y; + register f32 z; register f32 res; #ifdef __MWERKS__ asm { diff --git a/include/d/t/d_t_mass_obj.h b/include/d/t/d_t_mass_obj.h index 98a34f69..308ac075 100644 --- a/include/d/t/d_t_mass_obj.h +++ b/include/d/t/d_t_mass_obj.h @@ -1,18 +1,12 @@ #ifndef D_T_MASS_OBJ_H #define D_T_MASS_OBJ_H -#include "c/c_math.h" #include "common.h" -#include "d/d_heap.h" #include "d/t/d_tg.h" #include "egg/core/eggHeap.h" -#include "egg/math/eggMatrix.h" #include "egg/math/eggQuat.h" #include "m/m3d/m_proc.h" -#include "m/m3d/m_scnleaf.h" #include "m/m_angle.h" -#include "m/m_color.h" -#include "m/m_heap.h" #include "m/m_mtx.h" #include "m/m_quat.h" #include "m/m_vec.h" @@ -20,7 +14,6 @@ #include "nw4r/g3d/res/g3d_resshp.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXTypes.h" -#include "s/s_Math.h" #include "toBeSorted/tlist.h" class dTgMassObjInstance; @@ -49,13 +42,13 @@ public: ~dTgMassObjInstance() {} void reset(); void releaseDynamicTransform(GrassModel *param_2); - s32 checkForHit(GrassModel *param2,GrassModelData *param3,u16 roomid); - undefined4 checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, + bool checkForHit(GrassModel *param2,GrassModelData *param3,u16 roomid); + bool checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, GrassModel *param_5,GrassModelData* param_6,undefined4 roomid); - undefined4 FUN_80278c70(u32 param_2,dCcMassS_HitInf & param_3,dAcBase_c *param_4, + bool FUN_80278c70(u32 param_2,dCcMassS_HitInf & param_3,dAcBase_c *param_4, GrassModel *param_5); - undefined4 handleLinkSpinAttack(GrassModel *param_2); - s32 handleTimeshiftZone(); + bool handleLinkSpinAttack(GrassModel *param_2); + bool handleTimeshiftZone(); void getDrawMatrix(mMtx_c *pOut); bool isHidden(f32 param2, f32 param3); bool isItemDrop10() const { @@ -156,16 +149,16 @@ public: /* vt 0x08 */ virtual ~GrassModel() { remove(); } - undefined4 + bool setModelInfo(f32 radius,f32 param_2,int param_4, s32 roomCount,u16 instanceListLength,u16 staticTransformationListLength,int dynamicTransformationListLength, undefined1 param_9,s32 opaDrawPrio,u32 xluDrawPrio,mHeapAllocator_c *allocator); - undefined4 + bool spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHeight, u16 yRotation,s32 specialItemDropId,int affectedByTimeshift,int activeInPresent, s32 massObjSubtype,u8 lightingCode); void addToFreeInstances(dTgMassObjInstance *param_2); - s32 addToRoom(u32 param2, s32 roomid, dTgMassObjInstance* param4); + bool addToRoom(u32 param2, s32 roomid, dTgMassObjInstance* param4); void unloadRoom(u16 roomid); void initResForModel(s32 param_2,nw4r::g3d::ResMat pResMat,nw4r::g3d::ResShp pResShp); dTgMassObjTransform* aquireTransform(); diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index 8886a45a..515b3e5a 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -135,10 +135,6 @@ struct Vector3f : public nw4r::math::VEC3 { return squaredLength() <= Math::epsilon(); } - bool isZero2() const { - return fabsf(JMathInlineVEC::C_VECSquareMag(*this)) <= Math::epsilon(); - } - void setZero() { x = y = z = 0.0f; } diff --git a/include/m/m_mtx.h b/include/m/m_mtx.h index 3cdb56bb..fb18660f 100644 --- a/include/m/m_mtx.h +++ b/include/m/m_mtx.h @@ -147,11 +147,6 @@ public: MTXMultVec(*this, ret, ret); return ret; } - mVec3_c multVec2(const mVec3_c &v) const { - mVec3_c ret; - MTXMultVec(*this, v, ret); - return ret; - } void multVecSR(const mVec3_c &in, mVec3_c &out) const { MTXMultVecSR(*this, in, out); diff --git a/src/d/tg/d_t_mass_object.cpp b/src/d/tg/d_t_mass_object.cpp index a6cae7f3..ca696107 100644 --- a/src/d/tg/d_t_mass_object.cpp +++ b/src/d/tg/d_t_mass_object.cpp @@ -39,7 +39,6 @@ #include "nw4r/g3d/res/g3d_resmat.h" #include "nw4r/g3d/res/g3d_resmdl.h" #include "nw4r/g3d/res/g3d_resshp.h" -#include "nw4r/math/math_geometry.h" #include "nw4r/math/math_types.h" #include "rvl/GX/GXTev.h" #include "rvl/GX/GXTransform.h" @@ -49,7 +48,6 @@ #include "toBeSorted/d_emitter.h" #include "toBeSorted/special_item_drop_mgr.h" #include "toBeSorted/time_area_mgr.h" -#include SPECIAL_ACTOR_PROFILE(MASS_OBJ_TAG, dTgMassObj_c, fProfile::MASS_OBJ_TAG, 0x28A, 0, 4); @@ -183,7 +181,7 @@ static const GrassModelNames GRASS_MODEL_NAMES[5] = { }, }; -static const f32 GRASS_VECS[4][3] = { +static const Vec GRASS_VECS[4] = { { -0.5f, 0.5f, @@ -289,9 +287,9 @@ int dTgMassObj_c::actorPostCreate() { mVec3_c minVec(FLOAT_MAX, FLOAT_MAX, FLOAT_MAX); mVec3_c maxVec(FLOAT_MIN, FLOAT_MIN, FLOAT_MIN); - const f32 (*loop)[3] = &GRASS_VECS[0]; + const Vec* loop = &GRASS_VECS[0]; for (s32 i = 0; i < ARRAY_LENGTH(GRASS_VECS); i++) { - mVec3_c mult = mtx.multVec2(mVec3_c(*(loop++))); + mVec3_c mult = mtx * *(loop++); if (mult.x < minVec.x) { minVec.x = mult.x; } @@ -506,39 +504,39 @@ void GrassModel::remove() { m3d::scnLeaf_c::remove(); } -undefined4 GrassModel::setModelInfo(f32 radius,f32 param_2,int param_4, +bool GrassModel::setModelInfo(f32 radius,f32 param_2,int param_4, s32 roomCount,u16 instanceListLength,u16 staticTransformationListLength,int dynamicTransformationListLength, undefined1 param_9,s32 opaDrawPrio,u32 xluDrawPrio,mHeapAllocator_c *allocator) { if (!create(allocator, nullptr)) { - return 0; + return false; } EGG::Heap* heap = allocator->mHeap; mpModelData = new (heap, 4) GrassModelData[param_4]; if (!mpModelData) { remove(); - return 0; + return false; } GrassModelData* modelData = &mpModelData[0]; for (s32 i = 0; i < param_4; i++) { if (!(modelData++)->tryCreateLinkedLists(roomCount, heap)) { remove(); - return 0; + return false; } } mInstanceList = new (heap, 4) dTgMassObjInstance[instanceListLength]; if (!mInstanceList) { remove(); - return 0; + return false; } mStaticTransformationList = new (heap, 4) dTgMassObjTransform[staticTransformationListLength]; if (!mStaticTransformationList) { remove(); - return 0; + return false; } mDynamicTransformationList = new (heap, 4) dTgMassObjTransform[dynamicTransformationListLength]; if (!mDynamicTransformationList) { remove(); - return 0; + return false; } field_0x58 = param_4; mRoomCount = roomCount; @@ -576,61 +574,61 @@ undefined4 GrassModel::setModelInfo(f32 radius,f32 param_2,int param_4, setPriorityDraw(0, xluDrawPrio); setOption(nw4r::g3d::ScnObj::OPTION_DISABLE_DRAW_OPA, 1); } - return 1; + return true; } void GrassModel::initResForModel(s32 room,nw4r::g3d::ResMat pResMat,nw4r::g3d::ResShp pResShp) { mpModelData[room].initRes(pResMat, pResShp); } -undefined4 GrassModel::spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHeight, +bool GrassModel::spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHeight, u16 yRotation,s32 specialItemDropId,int affectedByTimeshift,int activeInPresent, s32 massObjSubtype,u8 lightingCode) { const dLightEnv_c& lightEnv = dLightEnv_c::GetInstance(); if (mFreeInstances.mCount == 0) { - return 0; + return false; } // almost - dTgMassObjInstance* first = &*mFreeInstances.GetBeginIter(); - mFreeInstances.remove(first); - first->reset(); - first->mGroundHeight.set(*groundHeight); - first->yRotation = yRotation; - first->mSpecialItemDropId = specialItemDropId; - first->mDynamicTransform = nullptr; + dTgMassObjInstance& first = *mFreeInstances.GetBeginIter(); + mFreeInstances.remove(&first); + first.reset(); + first.mGroundHeight.set(*groundHeight); + first.yRotation = yRotation; + first.mSpecialItemDropId = specialItemDropId; + first.mDynamicTransform = nullptr; s32 chosen = cM::rndInt(mStaticTransformationListLength); - first->mInitPosTransform = &mStaticTransformationList[chosen]; - first->field_0x24 = cM::rndFX(0.2f) + 1.f; - first->mMassObjSubtype = massObjSubtype; - first->mLightingCode = lightingCode; - first->mTevColor = lightEnv.GetCurrentSpf().mActorPalette.field_0x02C; - if (first->mLightingCode == 0) { - first->mTevColor.r = 0.7f * first->mTevColor.r; - first->mTevColor.r &= 0xFF; - first->mTevColor.g = 0.6f * first->mTevColor.g; - first->mTevColor.g &= 0xFF; - first->mTevColor.b = 0.7f * first->mTevColor.b; - first->mTevColor.b &= 0xFF; + first.mInitPosTransform = &mStaticTransformationList[chosen]; + first.field_0x24 = cM::rndFX(0.2f) + 1.f; + first.mMassObjSubtype = massObjSubtype; + first.mLightingCode = lightingCode; + first.mTevColor = lightEnv.GetCurrentSpf().mActorPalette.field_0x02C; + if (first.mLightingCode == 0) { + first.mTevColor.r = 0.7f * first.mTevColor.r; + first.mTevColor.r &= 0xFF; + first.mTevColor.g = 0.6f * first.mTevColor.g; + first.mTevColor.g &= 0xFF; + first.mTevColor.b = 0.7f * first.mTevColor.b; + first.mTevColor.b &= 0xFF; } if (affectedByTimeshift) { - first->mGrassFlags |= dTgMassObjInstance::TG_MASS_UNK2_TIMESHIFT_RELATED; + first.mGrassFlags |= dTgMassObjInstance::TG_MASS_UNK2_TIMESHIFT_RELATED; if (activeInPresent) { - first->mActiveInPresent = true; + first.mActiveInPresent = true; } else { - first->mScale = 0.f; + first.mScale = 0.f; } } - mpModelData[modelSubtype].addToRoom(roomid, first); - return 1; + mpModelData[modelSubtype].addToRoom(roomid, &first); + return true; } -s32 GrassModel::addToRoom(u32 modelSubtype, s32 roomid, dTgMassObjInstance* pInstance) { +bool GrassModel::addToRoom(u32 modelSubtype, s32 roomid, dTgMassObjInstance* pInstance) { mpModelData[modelSubtype].addToRoom(roomid, pInstance); if (modelSubtype == 1) { SpecialItemDropMgr::GetInstance()->giveSpecialDropItem(pInstance->mSpecialItemDropId, roomid, &pInstance->mGroundHeight, 0, 0, -1); pInstance->mSpecialItemDropId = 0xFF; } - return 1; + return true; } void GrassModel::addToFreeInstances(dTgMassObjInstance *param_2) { @@ -674,10 +672,10 @@ dTgMassObjTransform* GrassModel::aquireTransform() { return nullptr; } // not exactly, this produces an additional instruction - dTgMassObjTransform * first = &*(mAvailableTransforms.GetBeginIter()); - mAvailableTransforms.remove(first); - mAquiredTransforms.append(first); - return first; + dTgMassObjTransform& first = *mAvailableTransforms.GetBeginIter(); + mAvailableTransforms.remove(&first); + mAquiredTransforms.append(&first); + return &first; } // regalloc, should be equivalent @@ -686,14 +684,12 @@ void GrassModel::releaseTransform(dTgMassObjTransform* param2) { mAvailableTransforms.append(param2); } -static s32 lbl_80573AF0 = 0x1000; - dTgMassObjTransform::dTgMassObjTransform() { field_0x00 = 0; field_0x04 = 0; mRotXSpeed = 0; mRotY = cM::rndInt(0x10000); - mRotX = lbl_80573AF0; + mRotX = 0x1000; mQuat.setUnit(); s32 rnd = cM::rndInt(100); for (s32 i = 0; i < rnd; i++) { @@ -701,12 +697,10 @@ dTgMassObjTransform::dTgMassObjTransform() { } } -#define CLAMP2(low, high, x) ((x) < (low) ? (low) : ((x) > (high) ? (high) : (x))) - // matches besides data void dTgMassObjTransform::update() { mRotXSpeed -= (s16)(mRotX * 0.005f); - mRotXSpeed = CLAMP2(-0x4B, 0x4B, mRotXSpeed); + mRotXSpeed = cM::minMaxLimit(mRotXSpeed, -0x4B, 0x4B); mRotX += mRotXSpeed; mVec3_c tmp1(0, 1, 0); mVec3_c tmp2(0, 1, 0); @@ -757,15 +751,14 @@ void dTgMassObjInstance::getDrawMatrix(mMtx_c *pOut) { } // matches besides data -s32 dTgMassObjInstance::checkForHit(GrassModel *param_2, +bool dTgMassObjInstance::checkForHit(GrassModel *param_2, GrassModelData *param_3,u16 roomid) { dCcMassS_HitInf massHitInf; dAcObjBase_c* actor; u32 chk = dCcS::GetInstance()->GetMassMng().Chk(&mGroundHeight, &actor, &massHitInf); - s32 iVar5 = checkForHit(chk, massHitInf, actor, param_2, param_3, roomid); - if (iVar5 == 0 - && FUN_80278c70(chk, massHitInf, actor, param_2) == 0 - && handleLinkSpinAttack(param_2) == 0) { + if (!checkForHit(chk, massHitInf, actor, param_2, param_3, roomid) + && !FUN_80278c70(chk, massHitInf, actor, param_2) + && !handleLinkSpinAttack(param_2)) { if (mDynamicTransform != nullptr) { EGG::Quatf& dynQuat = mDynamicTransform->mQuat; f32 fVar2 = (mInitPosTransform->mQuat.dot(dynQuat)); @@ -782,21 +775,21 @@ s32 dTgMassObjInstance::checkForHit(GrassModel *param_2, mDynamicTransform = nullptr; } } - return 0; + return false; } else { - return 1; + return true; } } // matches besides data -undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, +bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, GrassModel *param_5,GrassModelData* param_6,undefined4 roomid) { dAcPy_c * link = dAcPy_c::GetLinkM(); if (link == nullptr) { - return 0; + return false; } if ((param_2 & 1) == 0 || param_4 == nullptr) { - return 0; + return false; } f32 impactDistanceFactor; f32 impactFactor; @@ -926,7 +919,7 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, impactFactor = cM::rndF(0.05f) + 0.5f; isNotCut = 1; if (distance >= fVar20 + 60.f) { - return 1; + return true; } } } else { @@ -936,10 +929,10 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, distance = mGroundHeight.distance(hitPosition); if (link->getSpecificAttackDirection() != 2 && link->getSpecificAttackDirection() != 0x80) { - return 1; + return true; } if (distance >= fVar21) { - return 1; + return true; } } if (link->isAttackingSpin()) { @@ -956,7 +949,7 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, impactFactor = cM::rndF(0.5f) + 0.5f; isNotCut = 1; } else { - return 1; + return true; } } } else { @@ -979,13 +972,13 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, if (mDynamicTransform == nullptr) { mDynamicTransform = param_5->aquireTransform(); if (mDynamicTransform == nullptr) { - return 0; + return false; } mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); } if (param_4 == nullptr) { - return 0; + return false; } mVec3_c local108 = mGroundHeight - hitPosition; local108.rotY(0x4000); @@ -1003,7 +996,7 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, if (!local120.normalizeRS()) { local120 = localB4; } - } else if (local114.isZero2()) { + } else if (cM::isZero(local114.getSquareMag())) { local120 = mGroundHeight - hitPosition; if (!local120.normalizeRS()) { local120.x = 1.f; @@ -1046,13 +1039,13 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, if (mDynamicTransform == nullptr) { mDynamicTransform = param_5->aquireTransform(); if (mDynamicTransform == nullptr) { - return 0; + return false; } mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); } if (param_4 == nullptr) { - return 0; + return false; } mVec3_c local150 = mGroundHeight - param_4->mPosition; mQuat_c local160; @@ -1133,23 +1126,23 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, case 7: ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_838_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); if (ret != nullptr) { - ret->bindShpEmitter(0x24, true); + ret->bindShpEmitter(dJEffManager_c::FlowerA00F, true); } ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_839_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); if (ret != nullptr) { - ret->bindShpEmitter(0x25, true); + ret->bindShpEmitter(dJEffManager_c::FlowerA00L, true); } break; case 8: ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_840_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); if (ret != nullptr) { - ret->bindShpEmitter(0x26, true); + ret->bindShpEmitter(dJEffManager_c::FlowerB00, true); } break; case 9: ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_841_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); if (ret != nullptr) { - ret->bindShpEmitter(0x27, true); + ret->bindShpEmitter(dJEffManager_c::FlowerB01, true); } break; } @@ -1157,18 +1150,18 @@ undefined4 dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3, } } } - return 1; + return true; } // non matching -undefined4 dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3, dAcBase_c *param_4, +bool dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3, dAcBase_c *param_4, GrassModel *param_5) { mVec3_c local54 = mGroundHeight; f32 fVar12 = 1000.f; s32 iVar11 = 0; f32 fVar1 = 0.55f; if ((param_2 & 2) == 0) { - return 0; + return false; } if (param_4 == nullptr) { param_4 = dAcPy_c::GetLinkM(); @@ -1202,7 +1195,7 @@ undefined4 dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3 } local54 = mGroundHeight - param_4->getPosition(); if (param_5->mRadiusSquared < local54.squareMagXZ()) { - return 0; + return false; } f32 distance = mGroundHeight.distance(param_4->getPosition()); f32 fVar13; @@ -1220,12 +1213,12 @@ undefined4 dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3 if (mDynamicTransform == nullptr) { mDynamicTransform = param_5->aquireTransform(); if (mDynamicTransform == nullptr) { - return 0; + return false; } mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); } - if (local54.isZero2()) { + if (cM::isZero(local54.getSquareMag())) { local54.set(1.f, 0.5f, 0.f); } mQuat_c local88; @@ -1249,65 +1242,64 @@ undefined4 dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3 localA8.makeWPositive(); mDynamicTransform->setQuat(local88); mDynamicTransform->setMtxFromQuat(localA8); - return 1; + return true; } // matches besides data -undefined4 dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { +bool dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { const dAcPy_c* link = dAcPy_c::GetLink(); if (link == nullptr) { - return 0; + return false; } if (!link->isAttackingSpin()) { - return 0; - } else { - mVec3_c local3C; - dAcPy_c::GetLink()->getPostionDifferenceOut(mGroundHeight, local3C); - f32 dist = mGroundHeight.distance(dAcPy_c::GetLinkM()->getPosition()); - f32 comparison = 350.f; - if (link->isAttackingDown()) { - comparison = 150.f; - } else if (link->checkSwordAndMoreStates(daPlayerActBase_c::SKYWARD_STRIKE_ACTIVE)) { - comparison = 450.f; - } - if (dist > comparison) { - return 0; - } - mVec3_c local48(0.f, 1.f, 0.f); - if (mDynamicTransform == nullptr) { - mDynamicTransform = param_2->aquireTransform(); - if (mDynamicTransform == nullptr) { - return 0; - } - mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); - mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); - } - if (local3C.isZero2()) { - local3C.set(1.f, 0.5f, 0.f); - } - mQuat_c local58; - mVec3_c local68 = local3C; - if (!local68.normalizeRS()) { - local68.x = 1.f; - local68.z = 0.f; - } - local68.y = 0.5f; - if (!local68.normalizeRS()) { - local68 = local48; - } - local58.makeVectorRotation(local48, local68); - local58.slerpTo2(cM::rndF(0.5f), mInitPosTransform->mQuat, local58); - local58.normalise(); - local58.makeWPositive(); - mQuat_c local78; - mDynamicTransform->mMtx.toQuat(local78); - local78.slerpTo(local58, cM::rndF(0.3f) + 0.5f, local78); - local78.normalise(); - local78.makeWPositive(); - mDynamicTransform->mQuat.set(local58); - mDynamicTransform->setMtxFromQuat(local78); - return 1; + return false; } + mVec3_c local3C; + dAcPy_c::GetLink()->getPostionDifferenceOut(mGroundHeight, local3C); + f32 dist = mGroundHeight.distance(dAcPy_c::GetLinkM()->getPosition()); + f32 comparison = 350.f; + if (link->isAttackingDown()) { + comparison = 150.f; + } else if (link->checkSwordAndMoreStates(daPlayerActBase_c::SKYWARD_STRIKE_ACTIVE)) { + comparison = 450.f; + } + if (dist > comparison) { + return false; + } + mVec3_c local48(0.f, 1.f, 0.f); + if (mDynamicTransform == nullptr) { + mDynamicTransform = param_2->aquireTransform(); + if (mDynamicTransform == nullptr) { + return false; + } + mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); + mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); + } + if (cM::isZero(local3C.getSquareMag())) { + local3C.set(1.f, 0.5f, 0.f); + } + mQuat_c local58; + mVec3_c local68 = local3C; + if (!local68.normalizeRS()) { + local68.x = 1.f; + local68.z = 0.f; + } + local68.y = 0.5f; + if (!local68.normalizeRS()) { + local68 = local48; + } + local58.makeVectorRotation(local48, local68); + local58.slerpTo2(cM::rndF(0.5f), mInitPosTransform->mQuat, local58); + local58.normalise(); + local58.makeWPositive(); + mQuat_c local78; + mDynamicTransform->mMtx.toQuat(local78); + local78.slerpTo(local58, cM::rndF(0.3f) + 0.5f, local78); + local78.normalise(); + local78.makeWPositive(); + mDynamicTransform->mQuat.set(local58); + mDynamicTransform->setMtxFromQuat(local78); + return true; } extern "C" bool fn_801BB700(EGG::Quatf*,f32); @@ -1330,21 +1322,21 @@ bool dTgMassObjInstance::isHidden(f32 param2, f32 param3) { } // matches besides data -s32 dTgMassObjInstance::handleTimeshiftZone() { - s32 uVar1 = 1; +bool dTgMassObjInstance::handleTimeshiftZone() { + bool ret = true; f32 fVar2 = dTimeAreaMgr_c::GetInstance()->checkPositionIsInPastState(-1, mGroundHeight, nullptr, 8.f); if (mActiveInPresent == false) { sLib::addCalc(&mScale, fVar2, 0.5f, 0.2f, 0.01f); if (mScale <= 0) { - uVar1 = 0; + ret = false; } } else if (mActiveInPresent == true) { sLib::addCalc(&mScale, 1.f - fVar2, 0.5f, 0.2f, 0.01f); if (mScale <= 0) { - uVar1 = 0; + ret = false; } } - return uVar1; + return ret; } bool GrassModelData::tryCreateLinkedLists(s32 entrycount, EGG::Heap* heap) { @@ -1369,11 +1361,11 @@ void GrassModelData::unloadRoom(GrassModel *param_2,int roomid) { dTgMassObjInstanceList& gll = mLinkedLists[roomid]; dTgMassObjInstanceList::Iterator it = gll.GetBeginIter(); while (it != gll.GetEndIter()) { - dTgMassObjInstance* lst = (&*(it)); + dTgMassObjInstance& lst = *it; ++it; - lst->releaseDynamicTransform(param_2); - gll.remove(lst); - param_2->addToFreeInstances(lst); + lst.releaseDynamicTransform(param_2); + gll.remove(&lst); + param_2->addToFreeInstances(&lst); } } @@ -1450,14 +1442,14 @@ void GrassModelData::draw(f32 param_1,f32 param_2, LoadMaterial(mResMat, 0, nullptr, nullptr, false); nw4r::g3d::G3DState::LoadResShpPrePrimitive(mResShp); const static u32 fifoMtx[8] = { - 0x3C, - 0x3C, - 0x3C, - 0x3C, - 0x3C, - 0x3C, - 0x3C, - 0x3C, + GX_IDENTITY, + GX_IDENTITY, + GX_IDENTITY, + GX_IDENTITY, + GX_IDENTITY, + GX_IDENTITY, + GX_IDENTITY, + GX_IDENTITY, }; nw4r::g3d::fifo::GDSetCurrentMtx(fifoMtx); GXSetCurrentMtx(0); @@ -1468,11 +1460,11 @@ void GrassModelData::draw(f32 param_1,f32 param_2, } dTgMassObjInstanceList::Iterator it = grassList->GetBeginIter(); for (;it != grassList->GetEndIter();++it) { - dTgMassObjInstance* lst = (&*it); - if (!lst->isHidden(param_1, param_2)) { + dTgMassObjInstance& lst = *it; + if (!lst.isHidden(param_1, param_2)) { mMtx_c local160; - lst->getDrawMatrix(&local160); - f32 cameraDist = lst->mGroundHeight.distance(cameraPosition); + lst.getDrawMatrix(&local160); + f32 cameraDist = lst.mGroundHeight.distance(cameraPosition); f32 fVar6 = param_2 * 0.6f; if (cameraDist > fVar6) { f32 fVar7 = (cameraDist - fVar6) / (param_2 - fVar6); @@ -1488,20 +1480,20 @@ void GrassModelData::draw(f32 param_1,f32 param_2, } } if (isInFaronWoods - && lst->mGroundHeight.x <= -5200.f - && lst->mGroundHeight.x >= -5500.f - && lst->mGroundHeight.z <= -5900.f - && lst->mGroundHeight.z >= -6100.f) { + && lst.mGroundHeight.x <= -5200.f + && lst.mGroundHeight.x >= -5500.f + && lst.mGroundHeight.z <= -5900.f + && lst.mGroundHeight.z >= -6100.f) { local160.scaleM(1.f, 1.5f, 1.f); } - f32 fVar7 = ((s32)(lst->mGroundHeight.x + lst->mGroundHeight.z) & 0x1F) / 31.f; + f32 fVar7 = ((s32)(lst.mGroundHeight.x + lst.mGroundHeight.z) & 0x1F) / 31.f; f32 scale = fVar7 * 0.1f + 1.f; local160.scaleM(scale, scale, scale); local160.YrotM(fVar7 * 65535.f); MTXConcat(*pMtx, local160, local160); GXLoadPosMtxImm(local160, 0); GXLoadNrmMtxImm(local160, 0); - GXSetTevColorS10(GX_TEVREG1, lst->mTevColor); + GXSetTevColorS10(GX_TEVREG1, lst.mTevColor); mResShp.CallPrimitiveDisplayList(false); } } From 066967c146c2ae3b4ec5cfa871748bb50e826aaa Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sun, 1 Feb 2026 17:36:32 +0100 Subject: [PATCH 3/5] format --- include/c/c_counter.h | 1 + include/d/a/d_a_base.h | 2 +- include/d/d_light_env.h | 4 +- include/d/d_player_act.h | 2 +- include/d/t/d_t_mass_obj.h | 135 ++++---- include/egg/math/eggQuat.h | 8 +- include/egg/math/eggVector.h | 1 + include/nw4r/ut/ut_Color.h | 1 + src/d/tg/d_t_mass_object.cpp | 574 +++++++++++++++++------------------ 9 files changed, 359 insertions(+), 369 deletions(-) diff --git a/include/c/c_counter.h b/include/c/c_counter.h index 5f3590e4..8efe5f26 100644 --- a/include/c/c_counter.h +++ b/include/c/c_counter.h @@ -8,6 +8,7 @@ public: static s32 GetGameFrame() { return m_gameFrame; } + private: static s32 m_gameFrame; }; diff --git a/include/d/a/d_a_base.h b/include/d/a/d_a_base.h index f6823dae..360397b2 100644 --- a/include/d/a/d_a_base.h +++ b/include/d/a/d_a_base.h @@ -169,7 +169,7 @@ public: return mPosition - other.mPosition; } - void getPostionDifferenceOut(const mVec3_c &other, mVec3_c& result) const { + void getPostionDifferenceOut(const mVec3_c &other, mVec3_c &result) const { mVec3_c diff = (other - mPosition); result = diff; } diff --git a/include/d/d_light_env.h b/include/d/d_light_env.h index a2267a02..350a7d9f 100644 --- a/include/d/d_light_env.h +++ b/include/d/d_light_env.h @@ -446,11 +446,11 @@ public: return field_0x38C0; } - const mVec3_c& getfield_0x38B4() const { + const mVec3_c &getfield_0x38B4() const { return field_0x38B4; } - mVec3_c& getfield_0x38C8() { + mVec3_c &getfield_0x38C8() { return field_0x38C8; } diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index b8c465dd..4dadb99f 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -61,7 +61,7 @@ public: /* vt 0x0C0 */ virtual bool isUsingWhip() const { return false; } - /* vt 0x0C4 */ virtual const mVec3_c* anotherThingWithWhip() { + /* vt 0x0C4 */ virtual const mVec3_c *anotherThingWithWhip() { return nullptr; } /* vt 0x0C8 */ virtual bool somethingWithWHip() { diff --git a/include/d/t/d_t_mass_obj.h b/include/d/t/d_t_mass_obj.h index 308ac075..db751857 100644 --- a/include/d/t/d_t_mass_obj.h +++ b/include/d/t/d_t_mass_obj.h @@ -36,17 +36,18 @@ public: TG_MASS_UNK2_IS_CUT = 2, TG_MASS_UNK2_TIMESHIFT_RELATED = 4, }; - dTgMassObjInstance(){ + dTgMassObjInstance() { reset(); } ~dTgMassObjInstance() {} void reset(); void releaseDynamicTransform(GrassModel *param_2); - bool checkForHit(GrassModel *param2,GrassModelData *param3,u16 roomid); - bool checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, - GrassModel *param_5,GrassModelData* param_6,undefined4 roomid); - bool FUN_80278c70(u32 param_2,dCcMassS_HitInf & param_3,dAcBase_c *param_4, - GrassModel *param_5); + bool checkForHit(GrassModel *param2, GrassModelData *param3, u16 roomid); + bool checkForHit( + u32 param_2, dCcMassS_HitInf ¶m_3, dAcObjBase_c *param_4, GrassModel *param_5, GrassModelData *param_6, + undefined4 roomid + ); + bool FUN_80278c70(u32 param_2, dCcMassS_HitInf ¶m_3, dAcBase_c *param_4, GrassModel *param_5); bool handleLinkSpinAttack(GrassModel *param_2); bool handleTimeshiftZone(); void getDrawMatrix(mMtx_c *pOut); @@ -55,7 +56,7 @@ public: return mSpecialItemDropId == 10; } -// private: + // private: /* 0x00 */ TListNode mLink; /* 0x08 */ GXColorS10 mTevColor; /* 0x10 */ mVec3_c mGroundHeight; @@ -75,19 +76,18 @@ public: // size: 0x50 class dTgMassObjTransform { public: - dTgMassObjTransform(); ~dTgMassObjTransform() {} void update(); - const mMtx_c& getMtx() const { + const mMtx_c &getMtx() const { return mMtx; } - void setQuat(const mQuat_c& quat) { + void setQuat(const mQuat_c &quat) { mQuat.set(quat); } - - void setMtxFromQuat(const mQuat_c& quat) { + + void setMtxFromQuat(const mQuat_c &quat) { mMtx.fromQuat(quat); } @@ -107,25 +107,25 @@ public: destroyLinkedLists(); } void initRes(nw4r::g3d::ResMat pResMat, nw4r::g3d::ResShp pResShp); - void addToRoom(s32 room, dTgMassObjInstance* p3); - void removeFromRoom(s32 room, dTgMassObjInstance* p3); - void update(GrassModel*); - bool tryCreateLinkedLists(s32 entrycount, EGG::Heap* heap); + void addToRoom(s32 room, dTgMassObjInstance *p3); + void removeFromRoom(s32 room, dTgMassObjInstance *p3); + void update(GrassModel *); + bool tryCreateLinkedLists(s32 entrycount, EGG::Heap *heap); void destroyLinkedLists(); - void unloadRoom(GrassModel *param_2,int roomid); - void draw(f32 param_1,f32 param_2, - nw4r::math::MTX34 *param_4); + void unloadRoom(GrassModel *param_2, int roomid); + void draw(f32 param_1, f32 param_2, nw4r::math::MTX34 *param_4); + private: /* 0x04 */ nw4r::g3d::ResMat mResMat; /* 0x08 */ nw4r::g3d::ResShp mResShp; - /* 0x0C */ dTgMassObjInstanceList* mLinkedLists; + /* 0x0C */ dTgMassObjInstanceList *mLinkedLists; /* 0x10 */ u16 mLinkedListsCount; }; struct GrassModelInfo { - /* 0x00 */ char* mArcName; - /* 0x04 */ char* mModelName; - /* 0x08 */ char* mCutModelName; + /* 0x00 */ char *mArcName; + /* 0x04 */ char *mModelName; + /* 0x08 */ char *mCutModelName; /* 0x0C */ u32 field_0x0C; /* 0x10 */ u16 mRadius; /* 0x12 */ u16 field_0x12; @@ -136,42 +136,45 @@ struct GrassModelInfo { /* 0x1B */ u8 field_0x1B; // might be padding }; - struct GrassModelNames { - /* 0x00 */ char* mArcName; - /* 0x04 */ char* mModelName; - /* 0x08 */ char* mCutModelName; + /* 0x00 */ char *mArcName; + /* 0x04 */ char *mModelName; + /* 0x08 */ char *mCutModelName; }; class GrassModel : public m3d::proc_c { public: - GrassModel() : mpModelData(nullptr), mInstanceList(nullptr), mStaticTransformationList(nullptr), mDynamicTransformationList(nullptr), mCutCounter(0) {} + GrassModel() + : mpModelData(nullptr), + mInstanceList(nullptr), + mStaticTransformationList(nullptr), + mDynamicTransformationList(nullptr), + mCutCounter(0) {} /* vt 0x08 */ virtual ~GrassModel() { remove(); } - bool - setModelInfo(f32 radius,f32 param_2,int param_4, - s32 roomCount,u16 instanceListLength,u16 staticTransformationListLength,int dynamicTransformationListLength, - undefined1 param_9,s32 opaDrawPrio,u32 xluDrawPrio,mHeapAllocator_c *allocator); - bool - spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHeight, - u16 yRotation,s32 specialItemDropId,int affectedByTimeshift,int activeInPresent, - s32 massObjSubtype,u8 lightingCode); + bool setModelInfo( + f32 radius, f32 param_2, int param_4, s32 roomCount, u16 instanceListLength, u16 staticTransformationListLength, + int dynamicTransformationListLength, undefined1 param_9, s32 opaDrawPrio, u32 xluDrawPrio, + mHeapAllocator_c *allocator + ); + bool spawnSingleGrass( + int modelSubtype, u16 roomid, mVec3_c *groundHeight, u16 yRotation, s32 specialItemDropId, + int affectedByTimeshift, int activeInPresent, s32 massObjSubtype, u8 lightingCode + ); void addToFreeInstances(dTgMassObjInstance *param_2); - bool addToRoom(u32 param2, s32 roomid, dTgMassObjInstance* param4); + bool addToRoom(u32 param2, s32 roomid, dTgMassObjInstance *param4); void unloadRoom(u16 roomid); - void initResForModel(s32 param_2,nw4r::g3d::ResMat pResMat,nw4r::g3d::ResShp pResShp); - dTgMassObjTransform* aquireTransform(); + void initResForModel(s32 param_2, nw4r::g3d::ResMat pResMat, nw4r::g3d::ResShp pResShp); + dTgMassObjTransform *aquireTransform(); void update(); - void releaseTransform(dTgMassObjTransform*); - void setModelInfo(const GrassModelInfo* modelInfo, mHeapAllocator_c * heap) { + void releaseTransform(dTgMassObjTransform *); + void setModelInfo(const GrassModelInfo *modelInfo, mHeapAllocator_c *heap) { setModelInfo( - modelInfo->mRadius, modelInfo->field_0x0C, - modelInfo->field_0x12, 0x3F, - modelInfo->mInstanceCount, modelInfo->mStaticTransformCount, - modelInfo->mDynamicTransformCount, (f32)modelInfo->field_0x1A, - 0x7F, 0xFFFFFFFF, heap - ); + modelInfo->mRadius, modelInfo->field_0x0C, modelInfo->field_0x12, 0x3F, modelInfo->mInstanceCount, + modelInfo->mStaticTransformCount, modelInfo->mDynamicTransformCount, (f32)modelInfo->field_0x1A, 0x7F, + 0xFFFFFFFF, heap + ); } void setRadius(f32 r) { @@ -191,14 +194,14 @@ public: return mDynamicTransformationListLength; } - dTgMassObjInstanceList& getFree() { + dTgMassObjInstanceList &getFree() { return mFreeInstances; } bool testSpecialItemtype(s32 itemtype) { return itemtype == 10; } - + /* vt 0x10 */ virtual void remove() override; // /* vt 0x14 */ virtual int entry(); /* vt 0x18 */ virtual void drawOpa() override { @@ -210,22 +213,22 @@ public: void draw(); void calcCutCounter() { - mCutCounter = (mCutCounter != 0) ? mCutCounter-1 : mCutCounter; + mCutCounter = (mCutCounter != 0) ? mCutCounter - 1 : mCutCounter; } - dTgMassObjTransformList& GetUnk3Too() { + dTgMassObjTransformList &GetUnk3Too() { return mAquiredTransforms; } - dTgMassObjTransformList& GetUnk3() { + dTgMassObjTransformList &GetUnk3() { return mAvailableTransforms; } -// private: - /* 0x18 */ GrassModelData* mpModelData; - /* 0x1C */ dTgMassObjInstance* mInstanceList; - /* 0x20 */ dTgMassObjTransform* mStaticTransformationList; - /* 0x24 */ dTgMassObjTransform* mDynamicTransformationList; + // private: + /* 0x18 */ GrassModelData *mpModelData; + /* 0x1C */ dTgMassObjInstance *mInstanceList; + /* 0x20 */ dTgMassObjTransform *mStaticTransformationList; + /* 0x24 */ dTgMassObjTransform *mDynamicTransformationList; /* 0x28 */ dTgMassObjInstanceList mFreeInstances; /* 0x34 */ dTgMassObjTransformList mAquiredTransforms; /* 0x40 */ dTgMassObjTransformList mAvailableTransforms; @@ -257,13 +260,17 @@ public: void unloadRoom(u16 roomid); - int initializeCircle(GrassModel *grassModel, mVec3_c *bbStart, mVec3_c *bbEnd,s32 xzDisplacement,mMtx_c *param_7,s32 specialItemDropId, - undefined4 affectedByTimeshift,u8 activeInPresent,int randInt,s32 massObjSubtype, - u8 lightingCode, f32 fParam); + int initializeCircle( + GrassModel *grassModel, mVec3_c *bbStart, mVec3_c *bbEnd, s32 xzDisplacement, mMtx_c *param_7, + s32 specialItemDropId, undefined4 affectedByTimeshift, u8 activeInPresent, int randInt, s32 massObjSubtype, + u8 lightingCode, f32 fParam + ); - int initializeBox(GrassModel *grassModel,mVec3_c *minVec, - mVec3_c *maxVec,int xzDisplacement,mMtx_c *boundsMtx,int specialItemDropId,undefined4 affectedByTimeshift, - u8 activeInPresent,int randInt,s32 massObjSubtype,u8 lightingCode, f32 fParam); + int initializeBox( + GrassModel *grassModel, mVec3_c *minVec, mVec3_c *maxVec, int xzDisplacement, mMtx_c *boundsMtx, + int specialItemDropId, undefined4 affectedByTimeshift, u8 activeInPresent, int randInt, s32 massObjSubtype, + u8 lightingCode, f32 fParam + ); virtual int actorExecute() override; virtual int actorCreate() override; @@ -281,7 +288,7 @@ public: return mtx2; } - GrassModel* getGrassModel(s32 i) { + GrassModel *getGrassModel(s32 i) { return sGrassModels[i]; } diff --git a/include/egg/math/eggQuat.h b/include/egg/math/eggQuat.h index 96808c56..aa33b73b 100644 --- a/include/egg/math/eggQuat.h +++ b/include/egg/math/eggQuat.h @@ -44,8 +44,8 @@ struct Quatf { Vector3f rotateVector(const Vector3f &); Vector3f rotateVectorInv(const Vector3f &); // not in SS void slerpTo(const Quatf &, f32, Quatf &out) const; - void slerpTo2(f32 fparam,const Quatf & param1, Quatf &out ) const { - const Quatf & tmp = param1; + void slerpTo2(f32 fparam, const Quatf ¶m1, Quatf &out) const { + const Quatf &tmp = param1; slerpTo(tmp, fparam, out); } void limitSlerpTo(const Quatf &, f32, f32, Quatf &out) const; @@ -53,13 +53,13 @@ struct Quatf { void makeVectorRotation(const Vector3f &, const Vector3f &); // not sure about the name - f32 dot(const Quatf& other) const { + f32 dot(const Quatf &other) const { f32 ret = v.dot(other.v); ret += w * other.w; return ret; } - void set(const Quatf& other) { + void set(const Quatf &other) { v.set(other.v); w = other.w; } diff --git a/include/egg/math/eggVector.h b/include/egg/math/eggVector.h index 515b3e5a..e69f0649 100644 --- a/include/egg/math/eggVector.h +++ b/include/egg/math/eggVector.h @@ -8,6 +8,7 @@ #include "nw4r/math/math_triangular.h" #include "nw4r/math.h" + #include namespace EGG { diff --git a/include/nw4r/ut/ut_Color.h b/include/nw4r/ut/ut_Color.h index 95ecc926..494d0b89 100644 --- a/include/nw4r/ut/ut_Color.h +++ b/include/nw4r/ut/ut_Color.h @@ -3,6 +3,7 @@ #include "nw4r/types_nw4r.h" #include "rvl/GX/GXTypes.h" + #include "rvl/GX.h" // IWYU pragma: export namespace nw4r { diff --git a/src/d/tg/d_t_mass_object.cpp b/src/d/tg/d_t_mass_object.cpp index ca696107..58ba9137 100644 --- a/src/d/tg/d_t_mass_object.cpp +++ b/src/d/tg/d_t_mass_object.cpp @@ -11,6 +11,7 @@ #include "d/col/cc/d_cc_s.h" #include "d/d_camera.h" #include "d/d_heap.h" +#include "d/d_heap_alloc.h" #include "d/d_light_env.h" #include "d/d_player_act.h" #include "d/d_sc_game.h" @@ -18,7 +19,6 @@ #include "d/d_stage_mgr.h" #include "d/snd/d_snd_small_effect_mgr.h" #include "d/t/d_t_mass_obj.h" -#include "d/d_heap_alloc.h" #include "egg/core/eggHeap.h" #include "egg/math/eggQuat.h" #include "f/f_base.h" @@ -49,24 +49,23 @@ #include "toBeSorted/special_item_drop_mgr.h" #include "toBeSorted/time_area_mgr.h" - SPECIAL_ACTOR_PROFILE(MASS_OBJ_TAG, dTgMassObj_c, fProfile::MASS_OBJ_TAG, 0x28A, 0, 4); -GrassModel* dTgMassObj_c::sGrassModels[5] = {}; -dTgMassObj_c* dTgMassObj_c::sInstance = nullptr; -mHeapAllocator_c* dTgMassObj_c::sAllocator = nullptr; +GrassModel *dTgMassObj_c::sGrassModels[5] = {}; +dTgMassObj_c *dTgMassObj_c::sInstance = nullptr; +mHeapAllocator_c *dTgMassObj_c::sAllocator = nullptr; u8 dTgMassObj_c::getCurrentStageGrassSubtype() { u8 ret = 0; if (dStageMgr_c::GetInstance()->isSTIFAreaFaron()) { - if (dScGame_c::isCurrentStage("D100") ||dScGame_c::isCurrentStage("B100")) { + if (dScGame_c::isCurrentStage("D100") || dScGame_c::isCurrentStage("B100")) { ret = 4; } else { ret = 3; } - } else if(dStageMgr_c::GetInstance()->isSTIFAreaEldin()) { + } else if (dStageMgr_c::GetInstance()->isSTIFAreaEldin()) { ret = 2; - } else if(dStageMgr_c::GetInstance()->isSTIFAreaLanayru()) { + } else if (dStageMgr_c::GetInstance()->isSTIFAreaLanayru()) { ret = 1; } if (dScGame_c::isCurrentStage("D003")) { @@ -87,121 +86,76 @@ int dTgMassObj_c::actorCreate() { static const GrassModelInfo GRASS_A_TYPES[5] = { { - "GrassA", - "GrassA", - "GrassACut", - 0x1770, - 0x64, - 0x2, - 0x7D0, - 0x8, - 0x80, - 0, - 0, - }, + "GrassA", "GrassA", + "GrassACut", 0x1770, + 0x64, 0x2, + 0x7D0, 0x8, + 0x80, 0, + 0, }, { - "GrassA", - "GrassA", - "GrassACut", - 0x1770, - 0x64, - 0x2, - 0x3E8, - 0x8, - 0x80, - 0, - 0, - }, + "GrassA", "GrassA", + "GrassACut", 0x1770, + 0x64, 0x2, + 0x3E8, 0x8, + 0x80, 0, + 0, }, { - "FlowerA00", - "FlowerA00", - "FlowerA00Cut", - 0x1770, - 0x64, - 0x2, - 0x12C, - 0x8, - 0x20, - 0x2, - 0, - }, + "FlowerA00", "FlowerA00", + "FlowerA00Cut", 0x1770, + 0x64, 0x2, + 0x12C, 0x8, + 0x20, 0x2, + 0, }, { - "FlowerB00", - "FlowerB00", - "FlowerB00Cut", - 0x1770, - 0x64, - 0x2, - 0x12C, - 0x8, - 0x20, - 0x2, - 0, - }, + "FlowerB00", "FlowerB00", + "FlowerB00Cut", 0x1770, + 0x64, 0x2, + 0x12C, 0x8, + 0x20, 0x2, + 0, }, { - "FlowerB01", - "FlowerB01", - "FlowerB01Cut", - 0x1770, - 0x64, - 0x2, - 0x12C, - 0x8, - 0x20, - 0x2, - 0, - }, + "FlowerB01", "FlowerB01", + "FlowerB01Cut", 0x1770, + 0x64, 0x2, + 0x12C, 0x8, + 0x20, 0x2, + 0, }, }; static const GrassModelNames GRASS_MODEL_NAMES[5] = { { - "GrassA", - "GrassA", - "GrassACut", - }, + "GrassA", "GrassA", + "GrassACut", }, { - "GrassB", - "GrassB", - "GrassBCut", - }, + "GrassB", "GrassB", + "GrassBCut", }, { - "GrassC", - "GrassC", - "GrassCCut", - }, + "GrassC", "GrassC", + "GrassCCut", }, { - "GrassD", - "GrassD", - "GrassDCut", - }, + "GrassD", "GrassD", + "GrassDCut", }, { - "GrassE", - "GrassE", - "GrassECut", - }, + "GrassE", "GrassE", + "GrassECut", }, }; static const Vec GRASS_VECS[4] = { { - -0.5f, - 0.5f, - -0.5f, - }, + -0.5f, + 0.5f,-0.5f, + }, { - 0.5f, - 0.5f, - -0.5f, - }, + 0.5f, 0.5f, + -0.5f, + }, { - 0.5f, - -0.5f, - 0.5f, - }, + 0.5f, -0.5f, + 0.5f, }, { - -0.5f, - -0.5f, - 0.5f, - }, + -0.5f, + -0.5f, + 0.5f, }, }; int dTgMassObj_c::actorPostCreate() { @@ -212,25 +166,27 @@ int dTgMassObj_c::actorPostCreate() { toGlobalRoom(); sAllocator = new (dHeap::work1Heap.heap) mHeapAllocator_c(); for (s32 i = 0; i < 5; i++) { - sGrassModels[i] = new(dHeap::work1Heap.heap) GrassModel(); + sGrassModels[i] = new (dHeap::work1Heap.heap) GrassModel(); } - if (sAllocator->createFrmHeap(0xFFFFFFFF, dHeap::work1Heap.heap, "dTgMassObj_c::m_allocator", 0x20, mHeap::OPT_NONE) == 0) { + if (!sAllocator->createFrmHeap( + 0xFFFFFFFF, dHeap::work1Heap.heap, "dTgMassObj_c::m_allocator", 0x20, mHeap::OPT_NONE + )) { return FAILED; } u8 grassSubtype = getCurrentStageGrassSubtype(); for (s32 i = 0; i < 5; i++) { - const GrassModelInfo* modelInfo; + const GrassModelInfo *modelInfo; modelInfo = &GRASS_A_TYPES[i]; sGrassModels[i]->setModelInfo(modelInfo, sAllocator); if (i == 0) { - void* file = dAcObjBase_c::getOarcResFile(GRASS_MODEL_NAMES[grassSubtype].mArcName); + void *file = dAcObjBase_c::getOarcResFile(GRASS_MODEL_NAMES[grassSubtype].mArcName); nw4r::g3d::ResFile res(file); nw4r::g3d::ResMdl mdl = res.GetResMdl(GRASS_MODEL_NAMES[grassSubtype].mModelName); sGrassModels[i]->initResForModel(0, mdl.GetResMat(0), mdl.GetResShp(0)); mdl = res.GetResMdl(GRASS_MODEL_NAMES[grassSubtype].mCutModelName); sGrassModels[i]->initResForModel(1, mdl.GetResMat(0), mdl.GetResShp(0)); } else { - void* file = dAcObjBase_c::getOarcResFile(modelInfo->mArcName); + void *file = dAcObjBase_c::getOarcResFile(modelInfo->mArcName); nw4r::g3d::ResFile res(file); nw4r::g3d::ResMdl mdl = res.GetResMdl(modelInfo->mModelName); sGrassModels[i]->initResForModel(0, mdl.GetResMat(0), mdl.GetResShp(0)); @@ -277,7 +233,7 @@ int dTgMassObj_c::actorPostCreate() { s32 uVar6 = fromParam4 * 10; f32 xzStep = uVar6; s32 xzDisplacement = xzStep * (fromParamB / 100.f); - GrassModel** tmpGrassModel = &sGrassModels[grassModelIndex]; + GrassModel **tmpGrassModel = &sGrassModels[grassModelIndex]; mMtx_c mtx; mtx.transS(mPosition); @@ -287,7 +243,7 @@ int dTgMassObj_c::actorPostCreate() { mVec3_c minVec(FLOAT_MAX, FLOAT_MAX, FLOAT_MAX); mVec3_c maxVec(FLOAT_MIN, FLOAT_MIN, FLOAT_MIN); - const Vec* loop = &GRASS_VECS[0]; + const Vec *loop = &GRASS_VECS[0]; for (s32 i = 0; i < ARRAY_LENGTH(GRASS_VECS); i++) { mVec3_c mult = mtx * *(loop++); if (mult.x < minVec.x) { @@ -322,24 +278,36 @@ int dTgMassObj_c::actorPostCreate() { // special item drop for farore's tear, unused if (specialItemDropId == 10) { if (getFromParams(0x15, 0xF) == 0) { - s32 tmp = initializeCircle(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, -1, mMassSubtype, lightingCode, xzStep); + s32 tmp = initializeCircle( + *tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, + activeInPresent, -1, mMassSubtype, lightingCode, xzStep + ); rnd = cM::rndInt(tmp); } else { - s32 tmp = initializeBox(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, -1, mMassSubtype, lightingCode, xzStep); + s32 tmp = initializeBox( + *tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, + activeInPresent, -1, mMassSubtype, lightingCode, xzStep + ); rnd = cM::rndInt(tmp); } } if (getFromParams(0x15, 0xF) == 0) { - initializeCircle(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, rnd, mMassSubtype, lightingCode, xzStep); + initializeCircle( + *tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, + activeInPresent, rnd, mMassSubtype, lightingCode, xzStep + ); } else { - initializeBox(*tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, activeInPresent, rnd, mMassSubtype, lightingCode, xzStep); + initializeBox( + *tmpGrassModel, &minVec, &maxVec, xzDisplacement, &boundsMtx, specialItemDropId, affectedByTimeshift, + activeInPresent, rnd, mMassSubtype, lightingCode, xzStep + ); } return retVar; } int dTgMassObj_c::doDelete() { if (sInstance == this) { - GrassModel** modelP = sGrassModels; + GrassModel **modelP = sGrassModels; for (s32 i = 0; i < 5; i++, modelP++) { delete *modelP; *modelP = nullptr; @@ -352,12 +320,12 @@ int dTgMassObj_c::doDelete() { } int dTgMassObj_c::actorExecute() { - dLightEnv_c& lightEnv = dLightEnv_c::GetInstance(); + dLightEnv_c &lightEnv = dLightEnv_c::GetInstance(); if (sInstance == nullptr) { return NOT_READY; } else { dCcS::GetInstance()->GetMassMng().Prepare(); - GrassModel** modelP = sGrassModels; + GrassModel **modelP = sGrassModels; for (s32 i = 0; i < 5; i++) { if ((cCounter_c::GetGameFrame() & 1) == 0) { (*modelP)->calcCutCounter(); @@ -377,7 +345,7 @@ int dTgMassObj_c::draw() { if (sInstance == nullptr) { return NOT_READY; } else { - GrassModel** modelP = sGrassModels; + GrassModel **modelP = sGrassModels; for (s32 i = 0; i < 5; i++) { (*modelP++)->entry(); } @@ -386,33 +354,30 @@ int dTgMassObj_c::draw() { } void dTgMassObj_c::unloadRoom(u16 roomid) { - GrassModel** modelP = sGrassModels; + GrassModel **modelP = sGrassModels; for (s32 i = 0; i < 5; i++) { (*modelP++)->unloadRoom(roomid); } } -int dTgMassObj_c::initializeCircle(GrassModel *grassModel, mVec3_c *bbStart, mVec3_c *bbEnd,s32 xzDisplacement,mMtx_c *param_7,s32 specialItemDropIdParam, - undefined4 affectedByTimeshift,u8 activeInPresent,int randInt,s32 massObjSubtype, - u8 lightingCode, f32 fParam) -{ +int dTgMassObj_c::initializeCircle( + GrassModel *grassModel, mVec3_c *bbStart, mVec3_c *bbEnd, s32 xzDisplacement, mMtx_c *param_7, + s32 specialItemDropIdParam, undefined4 affectedByTimeshift, u8 activeInPresent, int randInt, s32 massObjSubtype, + u8 lightingCode, f32 fParam +) { f32 p4z = bbStart->z; s32 iVar3 = 0; - while(p4z < bbEnd->z) { + while (p4z < bbEnd->z) { f32 p4x = bbStart->x; while (p4x < bbEnd->x) { - mVec3_c position( - p4x + cM::rndFX(xzDisplacement), - bbEnd->y, - p4z + cM::rndFX(xzDisplacement) - ); + mVec3_c position(p4x + cM::rndFX(xzDisplacement), bbEnd->y, p4z + cM::rndFX(xzDisplacement)); mVec3_c multiplied; param_7->multVec(position, multiplied); - mVec3_c nul(0,0,0); + mVec3_c nul(0, 0, 0); multiplied.y = 0.f; f32 length = multiplied.distance(nul); - if (length < 0.5f && dBgS_ObjGndChk::CheckPos(position) && - dBgS_ObjGndChk::GetGroundHeight() >= (bbStart->y - 100.f)) { + if (length < 0.5f && dBgS_ObjGndChk::CheckPos(position) && + dBgS_ObjGndChk::GetGroundHeight() >= (bbStart->y - 100.f)) { if (randInt >= 0) { position.y = dBgS_ObjGndChk::GetGroundHeight(); s32 specialItemDropId = specialItemDropIdParam; @@ -423,7 +388,10 @@ int dTgMassObj_c::initializeCircle(GrassModel *grassModel, mVec3_c *bbStart, mVe specialItemDropId = 0xFF; } } - if (!grassModel->spawnSingleGrass(0, getRoomId(), &position, 0, specialItemDropId, affectedByTimeshift, activeInPresent, massObjSubtype, lightingCode)) { + if (!grassModel->spawnSingleGrass( + 0, getRoomId(), &position, 0, specialItemDropId, affectedByTimeshift, activeInPresent, + massObjSubtype, lightingCode + )) { return 0; } } @@ -431,31 +399,27 @@ int dTgMassObj_c::initializeCircle(GrassModel *grassModel, mVec3_c *bbStart, mVe } p4x += fParam; - } p4z += fParam; } return iVar3; } -int dTgMassObj_c::initializeBox(GrassModel *grassModel,mVec3_c *minVec, - mVec3_c *maxVec,int xzDisplacement,mMtx_c *boundsMtx,int specialItemDropIdParam,undefined4 affectedByTimeshift, - u8 activeInPresent,int randInt,s32 massObjSubtype,u8 lightingCode, f32 fParam) { - +int dTgMassObj_c::initializeBox( + GrassModel *grassModel, mVec3_c *minVec, mVec3_c *maxVec, int xzDisplacement, mMtx_c *boundsMtx, + int specialItemDropIdParam, undefined4 affectedByTimeshift, u8 activeInPresent, int randInt, s32 massObjSubtype, + u8 lightingCode, f32 fParam +) { f32 p4z = minVec->z; s32 iVar3 = 0; - while(p4z < maxVec->z) { + while (p4z < maxVec->z) { f32 p4x = minVec->x; while (p4x < maxVec->x) { - mVec3_c position( - p4x + cM::rndFX(xzDisplacement), - maxVec->y, - p4z + cM::rndFX(xzDisplacement) - ); + mVec3_c position(p4x + cM::rndFX(xzDisplacement), maxVec->y, p4z + cM::rndFX(xzDisplacement)); mVec3_c multiplied; boundsMtx->multVec(position, multiplied); - if (-0.5f <= multiplied.x && multiplied.x <= 0.5f - && -0.5f <= multiplied.z && multiplied.z <= 0.5f && dBgS_ObjGndChk::CheckPos(position)) { + if (-0.5f <= multiplied.x && multiplied.x <= 0.5f && -0.5f <= multiplied.z && multiplied.z <= 0.5f && + dBgS_ObjGndChk::CheckPos(position)) { if (dBgS_ObjGndChk::GetGroundHeight() >= (minVec->y - 100.f)) { if (randInt >= 0) { position.y = dBgS_ObjGndChk::GetGroundHeight(); @@ -467,7 +431,10 @@ int dTgMassObj_c::initializeBox(GrassModel *grassModel,mVec3_c *minVec, specialItemDropId = 0xFF; } } - if (!grassModel->spawnSingleGrass(0, getRoomId(), &position, 0, specialItemDropId, affectedByTimeshift, activeInPresent, massObjSubtype, lightingCode)) { + if (!grassModel->spawnSingleGrass( + 0, getRoomId(), &position, 0, specialItemDropId, affectedByTimeshift, activeInPresent, + massObjSubtype, lightingCode + )) { return 0; } } @@ -476,14 +443,12 @@ int dTgMassObj_c::initializeBox(GrassModel *grassModel,mVec3_c *minVec, } p4x += fParam; - } p4z += fParam; } return iVar3; } - void GrassModel::remove() { if (mpModelData != nullptr) { delete[] mpModelData; @@ -504,19 +469,21 @@ void GrassModel::remove() { m3d::scnLeaf_c::remove(); } -bool GrassModel::setModelInfo(f32 radius,f32 param_2,int param_4, - s32 roomCount,u16 instanceListLength,u16 staticTransformationListLength,int dynamicTransformationListLength, - undefined1 param_9,s32 opaDrawPrio,u32 xluDrawPrio,mHeapAllocator_c *allocator) { +bool GrassModel::setModelInfo( + f32 radius, f32 param_2, int param_4, s32 roomCount, u16 instanceListLength, u16 staticTransformationListLength, + int dynamicTransformationListLength, undefined1 param_9, s32 opaDrawPrio, u32 xluDrawPrio, + mHeapAllocator_c *allocator +) { if (!create(allocator, nullptr)) { return false; } - EGG::Heap* heap = allocator->mHeap; + EGG::Heap *heap = allocator->mHeap; mpModelData = new (heap, 4) GrassModelData[param_4]; if (!mpModelData) { remove(); return false; } - GrassModelData* modelData = &mpModelData[0]; + GrassModelData *modelData = &mpModelData[0]; for (s32 i = 0; i < param_4; i++) { if (!(modelData++)->tryCreateLinkedLists(roomCount, heap)) { remove(); @@ -577,19 +544,20 @@ bool GrassModel::setModelInfo(f32 radius,f32 param_2,int param_4, return true; } -void GrassModel::initResForModel(s32 room,nw4r::g3d::ResMat pResMat,nw4r::g3d::ResShp pResShp) { +void GrassModel::initResForModel(s32 room, nw4r::g3d::ResMat pResMat, nw4r::g3d::ResShp pResShp) { mpModelData[room].initRes(pResMat, pResShp); } -bool GrassModel::spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHeight, - u16 yRotation,s32 specialItemDropId,int affectedByTimeshift,int activeInPresent, - s32 massObjSubtype,u8 lightingCode) { - const dLightEnv_c& lightEnv = dLightEnv_c::GetInstance(); +bool GrassModel::spawnSingleGrass( + int modelSubtype, u16 roomid, mVec3_c *groundHeight, u16 yRotation, s32 specialItemDropId, int affectedByTimeshift, + int activeInPresent, s32 massObjSubtype, u8 lightingCode +) { + const dLightEnv_c &lightEnv = dLightEnv_c::GetInstance(); if (mFreeInstances.mCount == 0) { return false; } // almost - dTgMassObjInstance& first = *mFreeInstances.GetBeginIter(); + dTgMassObjInstance &first = *mFreeInstances.GetBeginIter(); mFreeInstances.remove(&first); first.reset(); first.mGroundHeight.set(*groundHeight); @@ -622,10 +590,12 @@ bool GrassModel::spawnSingleGrass(int modelSubtype,u16 roomid,mVec3_c *groundHei return true; } -bool GrassModel::addToRoom(u32 modelSubtype, s32 roomid, dTgMassObjInstance* pInstance) { +bool GrassModel::addToRoom(u32 modelSubtype, s32 roomid, dTgMassObjInstance *pInstance) { mpModelData[modelSubtype].addToRoom(roomid, pInstance); if (modelSubtype == 1) { - SpecialItemDropMgr::GetInstance()->giveSpecialDropItem(pInstance->mSpecialItemDropId, roomid, &pInstance->mGroundHeight, 0, 0, -1); + SpecialItemDropMgr::GetInstance()->giveSpecialDropItem( + pInstance->mSpecialItemDropId, roomid, &pInstance->mGroundHeight, 0, 0, -1 + ); pInstance->mSpecialItemDropId = 0xFF; } return true; @@ -636,7 +606,7 @@ void GrassModel::addToFreeInstances(dTgMassObjInstance *param_2) { } void GrassModel::unloadRoom(u16 roomid) { - GrassModelData* modelData = mpModelData; + GrassModelData *modelData = mpModelData; for (s32 i = 0; i < field_0x58; i++) { (modelData++)->unloadRoom(this, roomid); } @@ -647,12 +617,12 @@ inline void SetMassMngAttr(f32 radius, f32 height, u8 param_2, u8 param_3) { } void GrassModel::update() { - dTgMassObjTransform* obj = mStaticTransformationList; - for (s32 i = 0; i < mStaticTransformationListLength; obj++, i++ ) { + dTgMassObjTransform *obj = mStaticTransformationList; + for (s32 i = 0; i < mStaticTransformationListLength; obj++, i++) { obj->update(); } SetMassMngAttr(mRadius, mRadius * 2, 0xB, field_0x62); - GrassModelData* modelData = mpModelData; + GrassModelData *modelData = mpModelData; for (s32 i = 0; i < field_0x58; i++) { (modelData++)->update(this); } @@ -661,25 +631,25 @@ void GrassModel::update() { void GrassModel::draw() { nw4r::math::MTX34 cameraMtx; m3d::getCurrentCamera().GetCameraMtx(&cameraMtx); - GrassModelData* data = mpModelData; + GrassModelData *data = mpModelData; for (s32 i = 0; i < field_0x58; data++, i++) { data->draw(mRadius, field_0x54, &cameraMtx); } } -dTgMassObjTransform* GrassModel::aquireTransform() { +dTgMassObjTransform *GrassModel::aquireTransform() { if (mAvailableTransforms.mCount == 0) { return nullptr; } // not exactly, this produces an additional instruction - dTgMassObjTransform& first = *mAvailableTransforms.GetBeginIter(); + dTgMassObjTransform &first = *mAvailableTransforms.GetBeginIter(); mAvailableTransforms.remove(&first); mAquiredTransforms.append(&first); return &first; } // regalloc, should be equivalent -void GrassModel::releaseTransform(dTgMassObjTransform* param2) { +void GrassModel::releaseTransform(dTgMassObjTransform *param2) { mAquiredTransforms.remove(param2); mAvailableTransforms.append(param2); } @@ -743,48 +713,44 @@ void dTgMassObjInstance::getDrawMatrix(mMtx_c *pOut) { pOut->setBase(3, mGroundHeight); pOut->scaleM(mScale, mScale, mScale); s32 sure = ((s16)mGroundHeight.x >> 1) & 7; - pOut->scaleM( - sure * 0.015f + 1.f, - sure * 0.015f + 1.f, - sure * 0.015f + 1.f - ); + pOut->scaleM(sure * 0.015f + 1.f, sure * 0.015f + 1.f, sure * 0.015f + 1.f); } // matches besides data -bool dTgMassObjInstance::checkForHit(GrassModel *param_2, - GrassModelData *param_3,u16 roomid) { +bool dTgMassObjInstance::checkForHit(GrassModel *param_2, GrassModelData *param_3, u16 roomid) { dCcMassS_HitInf massHitInf; - dAcObjBase_c* actor; + dAcObjBase_c *actor; u32 chk = dCcS::GetInstance()->GetMassMng().Chk(&mGroundHeight, &actor, &massHitInf); - if (!checkForHit(chk, massHitInf, actor, param_2, param_3, roomid) - && !FUN_80278c70(chk, massHitInf, actor, param_2) - && !handleLinkSpinAttack(param_2)) { - if (mDynamicTransform != nullptr) { - EGG::Quatf& dynQuat = mDynamicTransform->mQuat; - f32 fVar2 = (mInitPosTransform->mQuat.dot(dynQuat)); - fVar2 *= 0.1f; - if (fVar2 < 0.1f) { - fVar2 = 0.1f; - } - dynQuat.slerpTo(mInitPosTransform->mQuat, fVar2, dynQuat); - mDynamicTransform->mQuat.normalise(); - mDynamicTransform->mQuat.makeWPositive(); - mDynamicTransform->mMtx.fromQuat(mDynamicTransform->mQuat); - if (mInitPosTransform->mQuat.dot(mDynamicTransform->mQuat) >= 1.f) { - param_2->releaseTransform(mDynamicTransform); - mDynamicTransform = nullptr; - } + if (!checkForHit(chk, massHitInf, actor, param_2, param_3, roomid) && + !FUN_80278c70(chk, massHitInf, actor, param_2) && !handleLinkSpinAttack(param_2)) { + if (mDynamicTransform != nullptr) { + EGG::Quatf &dynQuat = mDynamicTransform->mQuat; + f32 fVar2 = (mInitPosTransform->mQuat.dot(dynQuat)); + fVar2 *= 0.1f; + if (fVar2 < 0.1f) { + fVar2 = 0.1f; + } + dynQuat.slerpTo(mInitPosTransform->mQuat, fVar2, dynQuat); + mDynamicTransform->mQuat.normalise(); + mDynamicTransform->mQuat.makeWPositive(); + mDynamicTransform->mMtx.fromQuat(mDynamicTransform->mQuat); + if (mInitPosTransform->mQuat.dot(mDynamicTransform->mQuat) >= 1.f) { + param_2->releaseTransform(mDynamicTransform); + mDynamicTransform = nullptr; } - return false; - } else { - return true; } + return false; + } else { + return true; + } } // matches besides data -bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObjBase_c* param_4, - GrassModel *param_5,GrassModelData* param_6,undefined4 roomid) { - dAcPy_c * link = dAcPy_c::GetLinkM(); +bool dTgMassObjInstance::checkForHit( + u32 param_2, dCcMassS_HitInf ¶m_3, dAcObjBase_c *param_4, GrassModel *param_5, GrassModelData *param_6, + undefined4 roomid +) { + dAcPy_c *link = dAcPy_c::GetLinkM(); if (link == nullptr) { return false; } @@ -801,10 +767,10 @@ bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObj f32 fVar4; f32 fVar2; f32 fVar21; - mVec3_c localB4(0.f,1.f,0.f); - cCcD_Obj * hitObj = param_3.GetAtHitObj(); + mVec3_c localB4(0.f, 1.f, 0.f); + cCcD_Obj *hitObj = param_3.GetAtHitObj(); if (hitObj != nullptr) { - mVec3_c& p4Pos = param_4->getPosition(); + mVec3_c &p4Pos = param_4->getPosition(); mVec3_c hitPosition = param_4->mPosition; s32 needsLightingRelated = 0; impactFactor = 0.f; @@ -909,49 +875,48 @@ bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObj } hitPosition = link->mPosition; distance = mGroundHeight.distance(hitPosition); - if (link->getSpecificAttackDirection() == 1 - || link->getSpecificAttackDirection() == 0x10 - || link->getSpecificAttackDirection() == 0x100) { - if (distance < fVar20) { - isNotCut = 0; - } else { - maybeMaxImpactDistance = 300.f; - impactFactor = cM::rndF(0.05f) + 0.5f; - isNotCut = 1; - if (distance >= fVar20 + 60.f) { - return true; - } - } + if (link->getSpecificAttackDirection() == 1 || link->getSpecificAttackDirection() == 0x10 || + link->getSpecificAttackDirection() == 0x100) { + if (distance < fVar20) { + isNotCut = 0; } else { - if (mMassObjSubtype == 8 || mMassObjSubtype == 9) { - fVar21 = fVar20 * 0.8f; - hitPosition = dAcPy_c::GetLink()->getSwordPos(); - - distance = mGroundHeight.distance(hitPosition); - if (link->getSpecificAttackDirection() != 2 && link->getSpecificAttackDirection() != 0x80) { - return true; - } - if (distance >= fVar21) { - return true; - } - } - if (link->isAttackingSpin()) { - if (link->checkSwordAndMoreStates(daPlayerActBase_c::SKYWARD_STRIKE_ACTIVE)) { - fVar21 = fVar5; - } else { - fVar21 = fVar4; - } - } - if (distance < fVar21) { - isNotCut = 0; - } else if (distance < fVar2) { - maybeMaxImpactDistance = 5000.f; - impactFactor = cM::rndF(0.5f) + 0.5f; - isNotCut = 1; - } else { + maybeMaxImpactDistance = 300.f; + impactFactor = cM::rndF(0.05f) + 0.5f; + isNotCut = 1; + if (distance >= fVar20 + 60.f) { return true; } } + } else { + if (mMassObjSubtype == 8 || mMassObjSubtype == 9) { + fVar21 = fVar20 * 0.8f; + hitPosition = dAcPy_c::GetLink()->getSwordPos(); + + distance = mGroundHeight.distance(hitPosition); + if (link->getSpecificAttackDirection() != 2 && link->getSpecificAttackDirection() != 0x80) { + return true; + } + if (distance >= fVar21) { + return true; + } + } + if (link->isAttackingSpin()) { + if (link->checkSwordAndMoreStates(daPlayerActBase_c::SKYWARD_STRIKE_ACTIVE)) { + fVar21 = fVar5; + } else { + fVar21 = fVar4; + } + } + if (distance < fVar21) { + isNotCut = 0; + } else if (distance < fVar2) { + maybeMaxImpactDistance = 5000.f; + impactFactor = cM::rndF(0.5f) + 0.5f; + isNotCut = 1; + } else { + return true; + } + } } else { isNotCut = 0; } @@ -968,7 +933,8 @@ bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObj tempDistance = maybeMaxImpactDistance; } // check this for regalloc - impactDistanceFactor = (1.f - (tempDistance / maybeMaxImpactDistance) * (tempDistance / maybeMaxImpactDistance)); + impactDistanceFactor = + (1.f - (tempDistance / maybeMaxImpactDistance) * (tempDistance / maybeMaxImpactDistance)); if (mDynamicTransform == nullptr) { mDynamicTransform = param_5->aquireTransform(); if (mDynamicTransform == nullptr) { @@ -1078,11 +1044,11 @@ bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObj mGrassFlags |= TG_MASS_UNK2_IS_CUT; if (mDynamicTransform != nullptr) { // this is wrong... - yRotation = *(u16*)mDynamicTransform->mRotY.ref(); + yRotation = *(u16 *)mDynamicTransform->mRotY.ref(); param_5->releaseTransform(mDynamicTransform); mDynamicTransform = nullptr; } - yRotation = *(u16*)mInitPosTransform->mRotY.ref(); + yRotation = *(u16 *)mInitPosTransform->mRotY.ref(); mInitPosTransform = nullptr; if (param_5->mCutCounter < 0x19) { param_5->mCutCounter++; @@ -1100,47 +1066,69 @@ bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObj mMassObjSubtype = 5; } } - dEmitterBase_c * ret; + dEmitterBase_c *ret; switch (mMassObjSubtype) { case 0: - dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_120_, local16C, nullptr, &local17C); + dJEffManager_c::createMassObjEffect( + PARTICLE_RESOURCE_ID_MAPPING_120_, local16C, nullptr, &local17C + ); break; case 1: - dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_121_, local16C, nullptr, &local17C); + dJEffManager_c::createMassObjEffect( + PARTICLE_RESOURCE_ID_MAPPING_121_, local16C, nullptr, &local17C + ); break; case 2: - dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_122_, local16C, nullptr, &local17C); + dJEffManager_c::createMassObjEffect( + PARTICLE_RESOURCE_ID_MAPPING_122_, local16C, nullptr, &local17C + ); break; case 3: - dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_123_, local16C, nullptr, &local17C); + dJEffManager_c::createMassObjEffect( + PARTICLE_RESOURCE_ID_MAPPING_123_, local16C, nullptr, &local17C + ); break; case 4: - dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_124_, local16C, nullptr, &local17C); + dJEffManager_c::createMassObjEffect( + PARTICLE_RESOURCE_ID_MAPPING_124_, local16C, nullptr, &local17C + ); break; case 5: - dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_687_, local16C, nullptr, &local17C); + dJEffManager_c::createMassObjEffect( + PARTICLE_RESOURCE_ID_MAPPING_687_, local16C, nullptr, &local17C + ); break; case 6: - dJEffManager_c::createMassObjEffect(PARTICLE_RESOURCE_ID_MAPPING_800_, local16C, nullptr, &local17C); + dJEffManager_c::createMassObjEffect( + PARTICLE_RESOURCE_ID_MAPPING_800_, local16C, nullptr, &local17C + ); break; case 7: - ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_838_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + ret = dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_838_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0 + ); if (ret != nullptr) { ret->bindShpEmitter(dJEffManager_c::FlowerA00F, true); } - ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_839_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + ret = dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_839_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0 + ); if (ret != nullptr) { ret->bindShpEmitter(dJEffManager_c::FlowerA00L, true); } break; case 8: - ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_840_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + ret = dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_840_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0 + ); if (ret != nullptr) { ret->bindShpEmitter(dJEffManager_c::FlowerB00, true); } break; case 9: - ret = dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_841_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0); + ret = dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_841_, local16C, nullptr, nullptr, &local17C, nullptr, 0, 0 + ); if (ret != nullptr) { ret->bindShpEmitter(dJEffManager_c::FlowerB01, true); } @@ -1154,8 +1142,7 @@ bool dTgMassObjInstance::checkForHit(u32 param_2,dCcMassS_HitInf& param_3,dAcObj } // non matching -bool dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3, dAcBase_c *param_4, - GrassModel *param_5) { +bool dTgMassObjInstance::FUN_80278c70(u32 param_2, dCcMassS_HitInf ¶m_3, dAcBase_c *param_4, GrassModel *param_5) { mVec3_c local54 = mGroundHeight; f32 fVar12 = 1000.f; s32 iVar11 = 0; @@ -1247,7 +1234,7 @@ bool dTgMassObjInstance::FUN_80278c70(u32 param_2,dCcMassS_HitInf ¶m_3, dAcB // matches besides data bool dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { - const dAcPy_c* link = dAcPy_c::GetLink(); + const dAcPy_c *link = dAcPy_c::GetLink(); if (link == nullptr) { return false; } @@ -1302,7 +1289,7 @@ bool dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { return true; } -extern "C" bool fn_801BB700(EGG::Quatf*,f32); +extern "C" bool fn_801BB700(EGG::Quatf *, f32); // matches besides data bool dTgMassObjInstance::isHidden(f32 param2, f32 param3) { @@ -1339,7 +1326,7 @@ bool dTgMassObjInstance::handleTimeshiftZone() { return ret; } -bool GrassModelData::tryCreateLinkedLists(s32 entrycount, EGG::Heap* heap) { +bool GrassModelData::tryCreateLinkedLists(s32 entrycount, EGG::Heap *heap) { mLinkedLists = new (heap, 4) dTgMassObjInstanceList[entrycount]; if (mLinkedLists == nullptr) { destroyLinkedLists(); @@ -1352,16 +1339,16 @@ bool GrassModelData::tryCreateLinkedLists(s32 entrycount, EGG::Heap* heap) { void GrassModelData::destroyLinkedLists() { if (mLinkedLists != nullptr) { - delete [] mLinkedLists; + delete[] mLinkedLists; mLinkedLists = nullptr; } } -void GrassModelData::unloadRoom(GrassModel *param_2,int roomid) { - dTgMassObjInstanceList& gll = mLinkedLists[roomid]; +void GrassModelData::unloadRoom(GrassModel *param_2, int roomid) { + dTgMassObjInstanceList &gll = mLinkedLists[roomid]; dTgMassObjInstanceList::Iterator it = gll.GetBeginIter(); while (it != gll.GetEndIter()) { - dTgMassObjInstance& lst = *it; + dTgMassObjInstance &lst = *it; ++it; lst.releaseDynamicTransform(param_2); gll.remove(&lst); @@ -1376,35 +1363,36 @@ void GrassModelData::initRes(nw4r::g3d::ResMat pResMat, nw4r::g3d::ResShp pResSh chan.GXSetChanAmbColor(GX_COLOR0, mColor(0xFF, 0xFF, 0xFF, 0xFF)); } -void GrassModelData::addToRoom(s32 room, dTgMassObjInstance* p3) { +void GrassModelData::addToRoom(s32 room, dTgMassObjInstance *p3) { mLinkedLists[room].append(p3); } // regalloc -void GrassModelData::removeFromRoom(s32 room, dTgMassObjInstance* p3) { +void GrassModelData::removeFromRoom(s32 room, dTgMassObjInstance *p3) { mLinkedLists[room].remove(p3); } // matches besides data -void GrassModelData::update(GrassModel* param2) { +void GrassModelData::update(GrassModel *param2) { mVec3_c groundHeight(999999.f, 999999.f, 999999.f); - dLightEnv_c& lightEnv = dLightEnv_c::GetInstance(); + dLightEnv_c &lightEnv = dLightEnv_c::GetInstance(); bool bVar1 = false; s32 count = 0; f32 minDist = lightEnv.getfield_0x38C0(); - dTgMassObjInstanceList* grassList = mLinkedLists; - for (s32 roomid = 0; roomid < mLinkedListsCount; roomid++, grassList++ ) { + dTgMassObjInstanceList *grassList = mLinkedLists; + for (s32 roomid = 0; roomid < mLinkedListsCount; roomid++, grassList++) { if (grassList->mCount == 0 || dStage_c::GetInstance()->getRoom(roomid)->checkFlag(4)) { continue; } dTgMassObjInstanceList::Iterator it = grassList->GetBeginIter(); while (it != grassList->GetEndIter()) { - dTgMassObjInstance& lst = *it; + dTgMassObjInstance &lst = *it; ++it; if ((lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_TIMESHIFT_RELATED) && !lst.handleTimeshiftZone()) { lst.mGrassFlags |= dTgMassObjInstance::TG_MASS_UNK2_IS_HIDDEN; } else { - if ((lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_IS_HIDDEN) == 0 && (lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_IS_CUT) == 0) { + if ((lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_IS_HIDDEN) == 0 && + (lst.mGrassFlags & dTgMassObjInstance::TG_MASS_UNK2_IS_CUT) == 0) { lst.checkForHit(param2, this, roomid); } if (lightEnv.getfield_0x38B0() == 1) { @@ -1429,11 +1417,13 @@ void GrassModelData::update(GrassModel* param2) { } } -extern void LoadMaterial(nw4r::g3d::ResMat mat, u32 ctrl, nw4r::g3d::Draw1Mat1ShpSwap *pSwap, nw4r::g3d::G3DState::IndMtxOp *pIndMtxOp, bool bIgnoreMaterial); +extern void LoadMaterial( + nw4r::g3d::ResMat mat, u32 ctrl, nw4r::g3d::Draw1Mat1ShpSwap *pSwap, nw4r::g3d::G3DState::IndMtxOp *pIndMtxOp, + bool bIgnoreMaterial +); // matches besides data -void GrassModelData::draw(f32 param_1,f32 param_2, - nw4r::math::MTX34 *pMtx) { +void GrassModelData::draw(f32 param_1, f32 param_2, nw4r::math::MTX34 *pMtx) { mVec3_c cameraPosition = dScGame_c::getCamera()->getPositionMaybe(); bool isInFaronWoods = dScGame_c::isCurrentStage("F100"); nw4r::g3d::ResMatMisc miscData(mResMat.GetResMatMisc()); @@ -1442,25 +1432,18 @@ void GrassModelData::draw(f32 param_1,f32 param_2, LoadMaterial(mResMat, 0, nullptr, nullptr, false); nw4r::g3d::G3DState::LoadResShpPrePrimitive(mResShp); const static u32 fifoMtx[8] = { - GX_IDENTITY, - GX_IDENTITY, - GX_IDENTITY, - GX_IDENTITY, - GX_IDENTITY, - GX_IDENTITY, - GX_IDENTITY, - GX_IDENTITY, + GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, GX_IDENTITY, }; nw4r::g3d::fifo::GDSetCurrentMtx(fifoMtx); GXSetCurrentMtx(0); - dTgMassObjInstanceList* grassList = mLinkedLists; - for (s32 roomid = 0; roomid < mLinkedListsCount; roomid++, grassList++ ) { + dTgMassObjInstanceList *grassList = mLinkedLists; + for (s32 roomid = 0; roomid < mLinkedListsCount; roomid++, grassList++) { if (grassList->mCount == 0 || dStage_c::GetInstance()->getRoom(roomid)->checkFlag(4)) { continue; } dTgMassObjInstanceList::Iterator it = grassList->GetBeginIter(); - for (;it != grassList->GetEndIter();++it) { - dTgMassObjInstance& lst = *it; + for (; it != grassList->GetEndIter(); ++it) { + dTgMassObjInstance &lst = *it; if (!lst.isHidden(param_1, param_2)) { mMtx_c local160; lst.getDrawMatrix(&local160); @@ -1479,11 +1462,8 @@ void GrassModelData::draw(f32 param_1,f32 param_2, local160.scaleM(scale, scale, scale); } } - if (isInFaronWoods - && lst.mGroundHeight.x <= -5200.f - && lst.mGroundHeight.x >= -5500.f - && lst.mGroundHeight.z <= -5900.f - && lst.mGroundHeight.z >= -6100.f) { + if (isInFaronWoods && lst.mGroundHeight.x <= -5200.f && lst.mGroundHeight.x >= -5500.f && + lst.mGroundHeight.z <= -5900.f && lst.mGroundHeight.z >= -6100.f) { local160.scaleM(1.f, 1.5f, 1.f); } f32 fVar7 = ((s32)(lst.mGroundHeight.x + lst.mGroundHeight.z) & 0x1F) / 31.f; From bbccc82fd768853dd1adcef8a661f7a2c1e5a76e Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:08:59 +0100 Subject: [PATCH 4/5] improve FUN_80278c70, non matching comments --- src/d/tg/d_t_mass_object.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/d/tg/d_t_mass_object.cpp b/src/d/tg/d_t_mass_object.cpp index 58ba9137..2d590a49 100644 --- a/src/d/tg/d_t_mass_object.cpp +++ b/src/d/tg/d_t_mass_object.cpp @@ -548,6 +548,7 @@ void GrassModel::initResForModel(s32 room, nw4r::g3d::ResMat pResMat, nw4r::g3d: mpModelData[room].initRes(pResMat, pResShp); } +// non matching bool GrassModel::spawnSingleGrass( int modelSubtype, u16 roomid, mVec3_c *groundHeight, u16 yRotation, s32 specialItemDropId, int affectedByTimeshift, int activeInPresent, s32 massObjSubtype, u8 lightingCode @@ -637,6 +638,7 @@ void GrassModel::draw() { } } +// non matching dTgMassObjTransform *GrassModel::aquireTransform() { if (mAvailableTransforms.mCount == 0) { return nullptr; @@ -667,7 +669,6 @@ dTgMassObjTransform::dTgMassObjTransform() { } } -// matches besides data void dTgMassObjTransform::update() { mRotXSpeed -= (s16)(mRotX * 0.005f); mRotXSpeed = cM::minMaxLimit(mRotXSpeed, -0x4B, 0x4B); @@ -716,7 +717,6 @@ void dTgMassObjInstance::getDrawMatrix(mMtx_c *pOut) { pOut->scaleM(sure * 0.015f + 1.f, sure * 0.015f + 1.f, sure * 0.015f + 1.f); } -// matches besides data bool dTgMassObjInstance::checkForHit(GrassModel *param_2, GrassModelData *param_3, u16 roomid) { dCcMassS_HitInf massHitInf; dAcObjBase_c *actor; @@ -745,7 +745,6 @@ bool dTgMassObjInstance::checkForHit(GrassModel *param_2, GrassModelData *param_ } } -// matches besides data bool dTgMassObjInstance::checkForHit( u32 param_2, dCcMassS_HitInf ¶m_3, dAcObjBase_c *param_4, GrassModel *param_5, GrassModelData *param_6, undefined4 roomid @@ -962,6 +961,7 @@ bool dTgMassObjInstance::checkForHit( if (!local120.normalizeRS()) { local120 = localB4; } + // regalloc } else if (cM::isZero(local114.getSquareMag())) { local120 = mGroundHeight - hitPosition; if (!local120.normalizeRS()) { @@ -1174,22 +1174,22 @@ bool dTgMassObjInstance::FUN_80278c70(u32 param_2, dCcMassS_HitInf ¶m_3, dAc iVar11 = param_3.GetCoHitObj()->ChkCo_0x2() ? 1 : 2; } if (iVar11 != 0) { - // TODO here + f32 fVar13; f32 fVar12_2 = 100.f; if (iVar11 == 2) { fVar12_2 = 200.f; fVar1 = 0.8f; } - local54 = mGroundHeight - param_4->getPosition(); - if (param_5->mRadiusSquared < local54.squareMagXZ()) { + f32 radSq = param_5->mRadiusSquared; + local54 = mGroundHeight - param_4->mPosition; + if (local54.squareMagXZ() > radSq) { return false; } f32 distance = mGroundHeight.distance(param_4->getPosition()); - f32 fVar13; + fVar13 = distance; if (distance > fVar12_2) { fVar13 = fVar12_2; } else { - fVar13 = distance; if (iVar11 == 1) { param_4->getSoundSource()->holdSound(SE_L_GRASS_RUSTLE_LV); } @@ -1205,6 +1205,7 @@ bool dTgMassObjInstance::FUN_80278c70(u32 param_2, dCcMassS_HitInf ¶m_3, dAc mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); } + // regalloc if (cM::isZero(local54.getSquareMag())) { local54.set(1.f, 0.5f, 0.f); } @@ -1232,7 +1233,7 @@ bool dTgMassObjInstance::FUN_80278c70(u32 param_2, dCcMassS_HitInf ¶m_3, dAc return true; } -// matches besides data +// non matching bool dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { const dAcPy_c *link = dAcPy_c::GetLink(); if (link == nullptr) { @@ -1262,6 +1263,7 @@ bool dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { mDynamicTransform->mQuat.set(mInitPosTransform->mQuat); mDynamicTransform->mMtx.fromQuat(mInitPosTransform->mQuat); } + // regalloc if (cM::isZero(local3C.getSquareMag())) { local3C.set(1.f, 0.5f, 0.f); } @@ -1291,7 +1293,6 @@ bool dTgMassObjInstance::handleLinkSpinAttack(GrassModel *param_2) { extern "C" bool fn_801BB700(EGG::Quatf *, f32); -// matches besides data bool dTgMassObjInstance::isHidden(f32 param2, f32 param3) { bool uVar1 = mSpecialItemDropId != 10; if (uVar1) { @@ -1308,7 +1309,6 @@ bool dTgMassObjInstance::isHidden(f32 param2, f32 param3) { } } -// matches besides data bool dTgMassObjInstance::handleTimeshiftZone() { bool ret = true; f32 fVar2 = dTimeAreaMgr_c::GetInstance()->checkPositionIsInPastState(-1, mGroundHeight, nullptr, 8.f); @@ -1372,7 +1372,6 @@ void GrassModelData::removeFromRoom(s32 room, dTgMassObjInstance *p3) { mLinkedLists[room].remove(p3); } -// matches besides data void GrassModelData::update(GrassModel *param2) { mVec3_c groundHeight(999999.f, 999999.f, 999999.f); dLightEnv_c &lightEnv = dLightEnv_c::GetInstance(); @@ -1422,7 +1421,6 @@ extern void LoadMaterial( bool bIgnoreMaterial ); -// matches besides data void GrassModelData::draw(f32 param_1, f32 param_2, nw4r::math::MTX34 *pMtx) { mVec3_c cameraPosition = dScGame_c::getCamera()->getPositionMaybe(); bool isInFaronWoods = dScGame_c::isCurrentStage("F100"); From 3c3585efeb19390cd83883b8e2d8043bee52c6c0 Mon Sep 17 00:00:00 2001 From: lepelog <25211966+lepelog@users.noreply.github.com> Date: Sun, 1 Feb 2026 18:49:27 +0100 Subject: [PATCH 5/5] rebase fixes --- include/d/d_player_act.h | 2 +- src/d/tg/d_t_mass_object.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 4dadb99f..c8deccaa 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -642,7 +642,7 @@ public: return mAttackDirection == ATTACK_JUMP_SLASH; } - s32 getSpecificAttackDirection() const { + u16 getSpecificAttackDirection() const { return mSpecificAttackDirection; } diff --git a/src/d/tg/d_t_mass_object.cpp b/src/d/tg/d_t_mass_object.cpp index 2d590a49..15cc73b2 100644 --- a/src/d/tg/d_t_mass_object.cpp +++ b/src/d/tg/d_t_mass_object.cpp @@ -874,8 +874,9 @@ bool dTgMassObjInstance::checkForHit( } hitPosition = link->mPosition; distance = mGroundHeight.distance(hitPosition); - if (link->getSpecificAttackDirection() == 1 || link->getSpecificAttackDirection() == 0x10 || - link->getSpecificAttackDirection() == 0x100) { + if ((s32)link->getSpecificAttackDirection() == dAcPy_c::ATTACK_DIRECTION_DOWN || + (s32)link->getSpecificAttackDirection() == dAcPy_c::ATTACK_DIRECTION_UP || + (s32)link->getSpecificAttackDirection() == dAcPy_c::ATTACK_DIRECTION_STAB) { if (distance < fVar20) { isNotCut = 0; } else { @@ -892,7 +893,8 @@ bool dTgMassObjInstance::checkForHit( hitPosition = dAcPy_c::GetLink()->getSwordPos(); distance = mGroundHeight.distance(hitPosition); - if (link->getSpecificAttackDirection() != 2 && link->getSpecificAttackDirection() != 0x80) { + if ((s32)link->getSpecificAttackDirection() != dAcPy_c::ATTACK_DIRECTION_DOWNRIGHT && + (s32)link->getSpecificAttackDirection() != dAcPy_c::ATTACK_DIRECTION_DOWNLEFT) { return true; } if (distance >= fVar21) {