d_a_boomerang matching (#936)

* Added constructor implementation for `daBoomerang_c`.

* Extend `daBoomerang_sightPacket_c` with `dDlst_base_c` base class.

* Refactor `d_a_boomerang.h`: reorganize class definitions and update member layout in `daBoomerang_c`.

* Extend `daBoomerang_c`: add new arrays, members, and static assertions for structure validation.

* Extend `daBoomerang_c`: add `dBgS_BoomerangLinChk` member and update padding fields.

* Extend `daBoomerang_c`: implement `create` method, add new members, and update function signatures.

* Refactor `daBoomerang_c`: update `createHeap` function to return `BOOL` and adjust related calls.

* Extend `daBoomerang_c`: implement `execute` method logic, update member variables, and adjust structure layout in `d_a_boomerang.h`.

* Extend `daBoomerang_c`: add static blur vector definitions for `l_blur_top` and `l_blur_root`.

* Add fields to `daBoomerang_blur_c`.

* Refactor `daBoomerang_blur_c`: implement `initBlur` logic, add `pos` field, update structure layout in `d_a_boomerang.h`.

* Refactor `daBoomerang_blur_c`: update `initBlur` and `copyBlur` logic, modify array structure to use 2D layout, and adjust declarations in `d_a_boomerang.h`.

* Match `copyBlur`

* Update `config.yml`: add symbol `l_matDL` for `daBoomerang_blur_c`.

* Extend `daBoomerang_blur_c`: implement `draw` method, add vertex description, attribute format lists, and texture handling logic.

* Add fields to `daBoomerang_sightPacket_c`

* Update `play` method in `daBoomerang_sightPacket_c`: implement looping logic for modifying `field_0xF4` values.

* Refactor `setSight` and `play` in `daBoomerang_sightPacket_c`: implement animation logic, replace `field_0xF4` with `arr_0xF4`, add `arr_0xF9`, and update structure in `d_a_boomerang.h`.

* Refactor `daBoomerang_sightPacket_c`: add `setTex` and `setImage` methods; update image data logic in `d_a_boomerang.cpp` and `d_a_boomerang.h`.

* Update `initFrame` and `resetSightOn` in `daBoomerang_sightPacket_c`: initialize `arr_0xF4` and reset `targetFlags`.

* Replace hardcoded array size with `BOOM_TARGET_MAX` in `d_a_boomerang.cpp` and `d_a_boomerang.h`

* Refactor `daBoomerang_sightPacket_c`: rename variables for clarity, update structure fields, and adjust logic in `setSight`, `play`, and related methods.

* Implement `draw` method in `daBoomerang_sightPacket_c`: add vertex descriptor/attribute format lists, texture handling, and sight rendering logic.

* Adjust vertex attribute formats in `d_a_boomerang.cpp`: update position to `GX_S8` and texture to `GX_U8`.

* Reorder includes in `d_a_boomerang.cpp` to resolve dependencies for `l_sightMatDL` and `l_sightDL__d_a_boomerang`

* Update `getFlyMax` in `daBoomerang_c`: add player status and stage name checks to determine maximum flight distance.

* Refactor `procMove` and `execute` in `daBoomerang_c`: improve boomerang targeting logic, rename variables for clarity, update array structures, and adjust control flow.

* Implement enhanced boomerang movement logic in `daBoomerang_c`: calculate angles, update position/rotation, handle water effects, and refine collision detection. Adjust structure fields in `d_a_boomerang.h`.

* Refactor `daBoomerang_c` control flow: reorder player retrieval logic, adjust distance-based normalization, and refine boomerang return handling.

* Change return type of `returnBoomerang` from `int` to `BOOL` in `d_a_player_main.h` and `d_a_player_boomerang.inc`.

* Change `setItemWaterEffect` return type from `u32` to `BOOL` and refactor its parameters and logic for clarity and behavior adjustment.

* Adjust `setItemWaterEffect` call in `d_a_boomerang.cpp` to use explicit `BOOL` comparison for clarity.

* Refactor `daBoomerang_c` control flow and targeting logic: introduce `mTargetRayEnd`, enhance position/angle calculations, integrate player sight checks, and update camera handling. Adjust includes and structure definitions for consistency.

* Match `rockLineCallback`

* Rename `param_1` to `pHitActor` in `rockLineCallback` for clarity.

* Match `setAimActor` in `d_a_boomerang.cpp`.

* Refactor `daBoomerang_c`: update `setLockActor` to use `BOOL` type, modify related logic for clarity, and ensure consistent parameter usage across `d_a_boomerang.cpp`.

* Match `resetLockActor` in `d_a_boomerang.cpp`: initialize target arrays and reset counters for consistency.

* Refactor `daBoomerang_c`: Fix struct offsets, update instance size

* Match `setRoomInfo` in `d_a_boomerang.cpp`: update position handling, ground checks, room ID assignment, and environment override logic.

* Match `create` in `d_a_boomerang.cpp`: update matrix handling, target ID initialization, callback setup, and clean up unused code.

* Match `setKeepMatrix` in `d_a_boomerang.cpp`: update transformation logic to align boomerang with Link's hand.

* Refactor `d_a_player_main` boomerang logic: rename `m36F4` to `mBoomerangCatchPos`, implement `getBoomerangCatchPos` accessor

* Match `setAimPos` in `d_a_boomerang.cpp`: implement target position logic based on current target index and player catch position.

* Match `checkBgHit` in `d_a_boomerang.cpp`: implement background collision logic, position updates, sound effects, and behavior adjustments.

* Continue matching `procWait` in `d_a_boomerang.cpp`

* Refactor `d_a_boomerang.cpp`: rename `field_0xF3A` to `mModelRotY` for clarity, update all associated references, and adjust struct definition in the header file.

* Continue matching `procWait` in `d_a_boomerang.cpp`

* Match `procWait` in `d_a_boomerang.cpp`

* Continue matching `procMove` in `d_a_boomerang.cpp`

* Refactor `d_a_boomerang.cpp`: convert `u8` fields to `bool` for clarity and better type usage, update header and references accordingly.

* Match `draw` in `d_a_boomerang.cpp`: implement drawing logic with model updates, light settings, shadow handling, and target sight management. Update struct definition to include `mGroundY`.

* Refactor `procMove` in `d_a_boomerang.cpp`: simplify angle calculations, update `mInWater` to `u8`, and improve readability by reducing nested logic.

* Fix `at_offset` initialization in `procMove` in `d_a_boomerang.cpp`

* Match `procMove` in `d_a_boomerang.cpp`

* Refine `draw` in `d_a_boomerang.cpp`: inline comments for quads setup, add light yellow trail color definition.

* Refactor `d_a_boomerang.cpp` and header: rename `field_0x14` to `numTrailSegments` for improved clarity and update all related references.

* Refactor `draw` in `d_a_boomerang.cpp`: reorganize quads initialization and alpha blending loops for improved structure and readability.

* Refactor `draw` in `d_a_boomerang.cpp`: combine alpha variable declarations for improved local scope and clarity.

* Refactor `draw` in `d_a_boomerang.cpp`: introduce `QUAD_VERT` macro to streamline quad vertex setup and improve code readability.

* Refactor `draw` in `d_a_boomerang.cpp`: rename `alpha` variables to `uCoord` for improved clarity and consistency with their purpose.

* Refactor `d_a_boomerang.cpp` and header: introduce `SEGMENTS_PER_STEP` constant for improved clarity and consistency, update related loops and data structures.

* Refactor `d_a_boomerang.cpp` and header: rename trail arrays for improved clarity and consistency, update all related references.

* Refactor `d_a_boomerang.cpp` and header: simplify trail vertex array indexing by flattening multidimensional arrays and updating all related code.

* Refactor `d_a_boomerang.cpp`: mark `se_flg` array as `const` for improved immutability and clarity.

* Refactor `d_a_boomerang.cpp`: relocate `l_at_cps_src` definition for improved organization and consistency.

* Refactor `d_a_boomerang.cpp` and header: rename and clarify multiple variables (e.g., `field_0xF2C` to `mIsReturning`) for improved readability and consistency, update all related references and logic.

* Refactor `d_a_boomerang.h`: add destructors to `daBoomerang_blur_c` and `daBoomerang_sightPacket_c` for proper ordering.

* Refactor `daBoomerang_blur_c::draw` in `d_a_boomerang.cpp`: reorder variable initialization, streamline loops, and adjust `QUAD_VERT` macro usage for improved clarity and consistency.

* Add inline geometry utility functions to `GFGeometry.h`

* Refactor `d_a_boomerang.cpp`: simplify geometry rendering by updating `QUAD_VERT` macro implementation and replacing manual vertex management with `GFBegin`/`GFEnd`.

* Refactor `d_a_boomerang.cpp`: simplify trail rendering by streamlining `uCoord` handling, reducing redundant variables, and improving clarity in loops.

* Refactor `d_a_boomerang.cpp`: rename `QUAD_VERT` to `QUAD_VTX` for clarity and update all related references.

* Add `l_matDL$4438` entry to config files for `daBoomerang_blur_c` rendering assets.

* Add version check around `j3dSys.reinitGX()` in `d_a_boomerang.cpp` to limit execution to non-demo builds.

* Refactor `d_a_boomerang.cpp`: replace direct `current.roomNo` usage with `roomNo` variable for improved clarity and consistency.

* Add version-specific asserts in `d_a_boomerang.cpp` for demo and non-demo builds

* Add version-specific asserts and adjust version check logic in `d_a_boomerang.cpp` for Japanese build

* Align `GXVtxDescList` and `GXVtxAttrFmtList` declarations with `ALIGN_DECL(32)` in `d_a_boomerang.cpp` for consistent memory alignment.

* Update `d_a_boomerang` to use `MatchingFor` in configuration

* Remove outdated `FIXME` comment in `d_a_boomerang.cpp`.

* Refactor `d_a_boomerang.cpp`: replace hardcoded rotation constants with `yRotPerStep` variable for clarity and maintainability.

* Update `d_a_boomerang.cpp` configuration to use `Matching` instead of `MatchingFor`.

* Refactor `d_a_boomerang.cpp`: rename `field_0xF2E` to `mJustHit` and `field_0xF2D` to `unused_0xF2D` for improved clarity.

* Replace hardcoded value in `d_a_boomerang.cpp` with `daBoomerang_blur_c::SEGMENTS_PER_STEP` for improved readability and maintainability.

* Refactor `d_a_boomerang.cpp`: replace `fpcM_GetParam` with `fopAcM_GetParam` for consistency with actor parameter retrieval methods.

* Introduce `Mode` enum in `d_a_boomerang` and replace related hardcoded values for improved readability and maintainability.

* Refactor `setAimActor` in `d_a_boomerang.cpp`: rename parameter for improved clarity.

* Replace `fpcM_SetParam` with `fopAcM_SetParam` in `d_a_boomerang.cpp` for consistency with actor parameter setting methods.

* Replace hardcoded `0` with `dEvtMode_NONE_e` in `d_a_boomerang.cpp` for improved readability and maintainability.

* Replace `BOOM_TARGET_MAX` with `BOOMERANG_LOCK_MAX` in `d_a_boomerang` for consistency.

* Refactor `d_a_boomerang.cpp` and `d_a_boomerang.h`: rename target-related variables and methods to lock-related for improved clarity and consistency.

* Refactor `daBoomerang_Draw` and `daBoomerang_Execute` in `d_a_boomerang.cpp` to simplify and remove redundant casts.

* Replace `Mode_0` and `Mode_1` with `Mode_Wait` and `Mode_Throw` in `d_a_boomerang`

* Simplify boolean assignment in boomerang lock condition in `d_a_boomerang.cpp`.

* Rename variable `b` to `isAiming` in `d_a_boomerang.cpp` for improved readability.

* Refactor draw methods in `d_a_boomerang.cpp` to streamline list-setting logic.

* Refactor particle effect in `d_a_boomerang.cpp` to use `dComIfGp_particle_setP1` for improved clarity and maintainability.

* Replace `g_dComIfG_gameInfo` camera getter with `dComIfGp` equivalents in `d_a_boomerang.cpp` for consistency.

* Simplify version-specific `JUT_ASSERT` calls in `d_a_boomerang.cpp` with `VERSION_SELECT` for improved maintainability.

* Replace direct model matrix assignment with `fopAcM_SetMtx` in `d_a_boomerang.cpp` for consistency.

* Update matching logic for `d_a_boomerang.cpp` to use `MatchingFor`.
This commit is contained in:
Briggs Baltzell
2026-03-03 22:44:51 -06:00
committed by GitHub
parent 60b0d94e2a
commit d54d983a4a
12 changed files with 952 additions and 167 deletions
+5
View File
@@ -3197,6 +3197,11 @@ extract:
binary: assets/l_sightDL__d_a_boomerang.bin
header: assets/l_sightDL__d_a_boomerang.h
- symbol: l_matDL$4433
binary: assets/l_matDL__draw__18daBoomerang_blur_cFv.bin
header: assets/l_matDL__draw__18daBoomerang_blur_cFv.h
rename: l_matDL
- symbol: l_sightDL!.data:0x80383e00
binary: assets/l_sightDL__d_a_player_main.bin
header: assets/l_sightDL__d_a_player_main.h
+5
View File
@@ -2775,6 +2775,11 @@ extract:
binary: assets/l_sightDL__d_a_boomerang.bin
header: assets/l_sightDL__d_a_boomerang.h
- symbol: l_matDL$4438
binary: assets/l_matDL__draw__18daBoomerang_blur_cFv.bin
header: assets/l_matDL__draw__18daBoomerang_blur_cFv.h
rename: l_matDL
- symbol: l_sightDL!.data:0x8038fc80
binary: assets/l_sightDL__d_a_player_main.bin
header: assets/l_sightDL__d_a_player_main.h
+5
View File
@@ -2359,6 +2359,11 @@ extract:
binary: assets/l_sightDL__d_a_boomerang.bin
header: assets/l_sightDL__d_a_boomerang.h
- symbol: l_matDL$4438
binary: assets/l_matDL__draw__18daBoomerang_blur_cFv.bin
header: assets/l_matDL__draw__18daBoomerang_blur_cFv.h
rename: l_matDL
- symbol: l_sightDL!.data:0x80383320
binary: assets/l_sightDL__d_a_player_main.bin
header: assets/l_sightDL__d_a_player_main.h
+5
View File
@@ -2371,6 +2371,11 @@ extract:
binary: assets/l_sightDL__d_a_boomerang.bin
header: assets/l_sightDL__d_a_boomerang.h
- symbol: l_matDL$4438
binary: assets/l_matDL__draw__18daBoomerang_blur_cFv.bin
header: assets/l_matDL__draw__18daBoomerang_blur_cFv.h
rename: l_matDL
- symbol: l_sightDL!.data:0x80396960
binary: assets/l_sightDL__d_a_player_main.bin
header: assets/l_sightDL__d_a_player_main.h
+1 -1
View File
@@ -573,7 +573,7 @@ config.libs = [
Object(MatchingFor("GZLJ01", "GZLE01", "GZLP01"), "d/actor/d_a_bg.cpp"),
Object(MatchingFor("GZLJ01", "GZLE01", "GZLP01"), "d/actor/d_a_bomb.cpp"),
Object(MatchingFor("GZLJ01", "GZLE01", "GZLP01"), "d/actor/d_a_bomb2.cpp"),
Object(NonMatching, "d/actor/d_a_boomerang.cpp"),
Object(MatchingFor("GZLJ01", "GZLE01", "GZLP01"), "d/actor/d_a_boomerang.cpp"),
Object(MatchingFor("GZLJ01", "GZLE01", "GZLP01"), "d/actor/d_a_dai_item.cpp"),
Object(NonMatching, "d/actor/d_a_demo00.cpp"),
Object(MatchingFor("GZLJ01", "GZLE01", "GZLP01"), "d/actor/d_a_disappear.cpp"),
+87 -20
View File
@@ -4,8 +4,60 @@
#include "f_op/f_op_actor.h"
#include "d/d_cc_d.h"
#define BOOMERANG_LOCK_MAX 5
class daBoomerang_blur_c : public J3DPacket {
public:
virtual ~daBoomerang_blur_c() {}
void initBlur(MtxP, s16);
void copyBlur(MtxP, s16);
virtual void draw();
static const s32 SEGMENTS_PER_STEP = 5;
public:
/* 0x010 */ void* imageData;
/* 0x014 */ s32 numTrailSegments;
/* 0x018 */ cXyz pos;
/* 0x024 */ cXyz trail0_vtxArr0[12 * SEGMENTS_PER_STEP];
/* 0x2F4 */ cXyz trail0_vtxArr1[12 * SEGMENTS_PER_STEP];
/* 0x5C4 */ cXyz trail1_vtxArr0[12 * SEGMENTS_PER_STEP];
/* 0x894 */ cXyz trail1_vtxArr1[12 * SEGMENTS_PER_STEP];
};
class daBoomerang_sightPacket_c : public dDlst_base_c {
public:
virtual ~daBoomerang_sightPacket_c() {}
virtual void draw();
void setSight(cXyz*, int);
void play(int);
void initFrame(int n) { mFrameArr[n] = 0; }
void resetSightOn() { mSightOnFlg = 0; }
void setImage(ResTIMG* i_img) { mImage = i_img; }
void setTex(void* data) { mTex = data; }
static const s32 ANIM_LENGTH = 26;
static const s32 HALF_ANIM_LENGTH = ANIM_LENGTH / 2;
private:
/* 0x004 */ Mtx mMtxArr[BOOMERANG_LOCK_MAX];
/* 0x0F4 */ u8 mFrameArr[BOOMERANG_LOCK_MAX];
/* 0x0F9 */ u8 mScaleArr[BOOMERANG_LOCK_MAX];
/* 0x100 */ u32 mSightOnFlg;
/* 0x104 */ void* mTex;
/* 0x108 */ ResTIMG* mImage;
};
class daBoomerang_c : public fopAc_ac_c {
public:
typedef BOOL (daBoomerang_c::*daBoomerang_c_ProcFunc)();
enum Mode {
Mode_Wait = 0x0,
Mode_Throw = 0x1,
};
void onCancelFlg() { mCancelFlg = true; }
daBoomerang_c();
@@ -15,34 +67,49 @@ public:
float getFlyMax();
void rockLineCallback(fopAc_ac_c*);
void setAimActor(fopAc_ac_c*);
void setLockActor(fopAc_ac_c*, int);
BOOL setLockActor(fopAc_ac_c* i_actor, BOOL doSoundEffect);
void resetLockActor();
void setRoomInfo();
void setKeepMatrix();
void setAimPos();
void checkBgHit(cXyz*, cXyz*);
void procWait();
void procMove();
void createHeap();
BOOL procWait();
BOOL procMove();
BOOL createHeap();
public:
/* Place member variables here */
/* 0x290 */ u8 m290[0xF34 - 0x290];
/* 0xF34 */ bool mCancelFlg;
/* 0x0290 */ J3DModel* mpModel;
/* 0x0294 */ daBoomerang_sightPacket_c mSightPacket;
/* 0x03A0 */ daBoomerang_blur_c mBlur;
/* 0x0F04 */ fpc_ProcID mLockActorIDs[BOOMERANG_LOCK_MAX];
/* 0x0F18 */ fopAc_ac_c* mLockActors[BOOMERANG_LOCK_MAX];
/* 0x0F2C */ bool mIsReturning;
/* 0x0F2D */ bool unused_0xF2D;
/* 0x0F2E */ bool mJustHit;
/* 0x0F2F */ bool mCatchAndDelete;
/* 0x0F30 */ u8 unused_0xF30;
/* 0x0F31 */ u8 mLockCnt;
/* 0x0F32 */ u8 mCurLockIdx;
/* 0x0F33 */ bool mThirdPerson;
/* 0x0F34 */ bool mCancelFlg;
/* 0x0F35 */ u8 mInWater;
/* 0x0F36 */ bool mFreeFlyOut;
/* 0x0F38 */ s16 mModelRotZ;
/* 0x0F3A */ s16 mModelRotY;
/* 0x0F3C */ f32 mGroundY;
/* 0x0F40 */ cXyz mTargetPos;
/* 0x0F4C */ dCcD_Stts mStts;
/* 0x0F88 */ dCcD_Cps mCps;
/* 0x10C0 */ dBgS_BoomerangLinChk mLinChk;
/* 0x112C */ dBgS_ObjGndChk mGndChk;
/* 0x1180 */ daBoomerang_c_ProcFunc mProcFunc;
};
class daBoomerang_blur_c {
public:
void initBlur(MtxP, s16);
void copyBlur(MtxP, s16);
void draw();
};
class daBoomerang_sightPacket_c {
public:
void draw();
void setSight(cXyz*, int);
void play(int);
};
STATIC_ASSERT(offsetof(daBoomerang_c, mSightPacket) == 0x294);
STATIC_ASSERT(offsetof(daBoomerang_c, mBlur) == 0x3A0);
STATIC_ASSERT(offsetof(daBoomerang_c, mCancelFlg) == 0xF34);
STATIC_ASSERT(offsetof(daBoomerang_c, mStts) == 0xF4C);
STATIC_ASSERT(offsetof(daBoomerang_c, mCps) == 0xF88);
STATIC_ASSERT(sizeof(daBoomerang_c) == 0x118C);
#endif /* D_A_BOOMERANG_H */
+7 -5
View File
@@ -58,6 +58,8 @@ public:
}
}
cXyz getPos() { return mPos; }
private:
/* 0x04 */ bool mDrawFlag;
/* 0x05 */ bool mLockFlag;
@@ -1276,7 +1278,7 @@ public:
void setDamageEmitter();
void endFlameDamageEmitter();
void endDamageEmitter();
static u32 setItemWaterEffect(fopAc_ac_c*, int, int);
static BOOL setItemWaterEffect(fopAc_ac_c* i_actor, BOOL inWater, BOOL triggerOnExit);
fopAc_ac_c* getDemoLookActor();
void setTinkleCeiverModel();
void setTalismanModel();
@@ -1608,7 +1610,7 @@ public:
BOOL procRopeUpHang();
BOOL checkBoomerangAnime() const;
void throwBoomerang();
int returnBoomerang();
BOOL returnBoomerang();
BOOL checkNextActionBoomerangReady();
void checkNextActionBoomerangFly();
BOOL checkNextBoomerangMode();
@@ -1846,8 +1848,8 @@ public:
BOOL checkNoControll() const { return dComIfGp_getPlayer(0) != this; }
void exchangeGrabActor(fopAc_ac_c* actor) { mActorKeepGrab.setData(actor); }
void getDekuLeafWindPos() const {}
void getBoomerangCatchPos() const {}
void getLineTopPos() {}
cXyz getBoomerangCatchPos() const { return mBoomerangCatchPos; }
cXyz getLineTopPos() { return mSightPacket.getPos(); }
cXyz getHookshotRootPos() const { return mHookshotRootPos; }
void getIceParticleBtk() {}
void getIceWaterParticleBtk() {}
@@ -2294,7 +2296,7 @@ public:
/* 0x36D0 */ cXyz m36D0;
/* 0x36DC */ cXyz m36DC;
/* 0x36E8 */ cXyz mHookshotRootPos;
/* 0x36F4 */ cXyz m36F4;
/* 0x36F4 */ cXyz mBoomerangCatchPos;
/* 0x3700 */ cXyz m3700;
/* 0x370C */ cXyz m370C;
/* 0x3718 */ cXyz m3718;
+26
View File
@@ -8,4 +8,30 @@ void GFSetVtxAttrFmtv(GXVtxFmt, GXVtxAttrFmtList*);
void GFSetArray(GXAttr, void*, u8);
void GFSetCullMode(GXCullMode);
inline void GFBegin(GXPrimitive type, GXVtxFmt fmt, u16 vert_num) {
GXFIFO.u8 = fmt | type;
GXFIFO.u16 = vert_num;
}
inline void GFEnd() {}
inline void GFWrite_f32(f32 f) {
GX_WRITE_U32(*reinterpret_cast<u32*>(&f));
}
inline void GFWrite_s16(s16 s) {
GXFIFO.s16 = s;
}
inline void GFPosition3f32(f32 x, f32 y, f32 z) {
GFWrite_f32(x);
GFWrite_f32(y);
GFWrite_f32(z);
}
inline void GFTexCoord2s16(s16 u, s16 v) {
GFWrite_s16(u);
GFWrite_s16(v);
}
#endif /* GFGEOMETRY_H */
+799 -132
View File
@@ -5,13 +5,766 @@
#include "d/dolzel.h" // IWYU pragma: keep
#include "d/actor/d_a_boomerang.h"
#include "d/d_camera.h"
#include "d/d_procname.h"
#include "d/d_priority.h"
#include "d/d_cc_d.h"
#include "d/d_material.h"
#include "d/actor/d_a_player_main.h"
#include "d/res/res_link.h"
#include "dolphin/gf/GF.h"
#include "f_op/f_op_camera.h"
#include "f_op/f_op_camera_mng.h"
#include "m_Do/m_Do_lib.h"
static cXyz l_blur_top(40.0f, 0.0f, 0.0f);
static cXyz l_blur_root(-40.0f, 0.0f, 0.0f);
/* 800E0C08-800E0D44 .text initBlur__18daBoomerang_blur_cFPA4_fs */
void daBoomerang_blur_c::initBlur(MtxP mtx, s16 yRot) {
cMtx_multVec(mtx, &l_blur_top, &trail0_vtxArr0[0]);
cMtx_multVec(mtx, &l_blur_root, &trail0_vtxArr1[0]);
trail0_vtxArr0[1] = trail0_vtxArr0[0];
trail0_vtxArr1[1] = trail0_vtxArr1[0];
numTrailSegments = 0;
pos.x = mtx[0][3];
pos.y = mtx[1][3];
pos.z = mtx[2][3];
mDoMtx_stack_c::copy(mtx);
mDoMtx_stack_c::YrotM(-(yRot * 2));
mDoMtx_stack_c::multVec(&l_blur_top, &trail1_vtxArr0[0]);
mDoMtx_stack_c::multVec(&l_blur_root, &trail1_vtxArr1[0]);
trail1_vtxArr0[1] = trail1_vtxArr0[0];
trail1_vtxArr1[1] = trail1_vtxArr1[0];
}
/* 800E0D44-800E101C .text copyBlur__18daBoomerang_blur_cFPA4_fs */
void daBoomerang_blur_c::copyBlur(MtxP mtx, s16 yRot) {
for (int i = 54; i >= 0; i--) {
trail0_vtxArr0[SEGMENTS_PER_STEP + i] = trail0_vtxArr0[i];
trail0_vtxArr1[SEGMENTS_PER_STEP + i] = trail0_vtxArr1[i];
trail1_vtxArr0[SEGMENTS_PER_STEP + i] = trail1_vtxArr0[i];
trail1_vtxArr1[SEGMENTS_PER_STEP + i] = trail1_vtxArr1[i];
}
float t = 0.0f;
cXyz inPos;
inPos.x = mtx[0][3];
inPos.y = mtx[1][3];
inPos.z = mtx[2][3];
cXyz diff = pos - inPos;
pos = inPos;
mDoMtx_stack_c::push();
s16 yRotPerStep = 0x633;
int i;
for (i = 0; i < SEGMENTS_PER_STEP; i++) {
mDoMtx_stack_c::multVec(&l_blur_top, &trail0_vtxArr0[i]);
mDoMtx_stack_c::multVec(&l_blur_root, &trail0_vtxArr1[i]);
VECAdd(&trail0_vtxArr0[i], &(diff * t), &trail0_vtxArr0[i]);
VECAdd(&trail0_vtxArr1[i], &(diff * t), &trail0_vtxArr1[i]);
t += 1.0f / SEGMENTS_PER_STEP;
mDoMtx_stack_c::YrotM(yRotPerStep);
}
t = 0.0f;
mDoMtx_stack_c::pop();
mDoMtx_stack_c::YrotM(-(yRot * 2));
for (i = 0; i < SEGMENTS_PER_STEP; i++) {
mDoMtx_stack_c::multVec(&l_blur_top, &trail1_vtxArr0[i]);
mDoMtx_stack_c::multVec(&l_blur_root, &trail1_vtxArr1[i]);
VECAdd(&trail1_vtxArr0[i], &(diff * t), &trail1_vtxArr0[i]);
VECAdd(&trail1_vtxArr1[i], &(diff * t), &trail1_vtxArr1[i]);
t += 1.0f / SEGMENTS_PER_STEP;
mDoMtx_stack_c::YrotM(-yRotPerStep);
}
numTrailSegments += SEGMENTS_PER_STEP;
if (numTrailSegments >= 59) {
numTrailSegments = 58;
}
}
/* 800E101C-800E13A4 .text draw__18daBoomerang_blur_cFv */
void daBoomerang_blur_c::draw() {
#include "assets/l_matDL__draw__18daBoomerang_blur_cFv.h"
static GXVtxDescList l_vtxDescList[] ALIGN_DECL(32) = {
{GX_VA_POS, GX_DIRECT},
{GX_VA_TEX0, GX_DIRECT},
{GX_VA_NULL, GX_NONE},
};
static GXVtxAttrFmtList l_vtxAttrFmtList[] ALIGN_DECL(32) = {
{GX_VA_POS, GX_POS_XYZ, GX_F32, 0x00},
{GX_VA_TEX0, GX_TEX_ST, GX_S16, 0x08},
{GX_VA_NULL, GX_POS_XYZ, GX_F32, 0x00},
};
static GXTexObj texObj;
#if VERSION > VERSION_JPN
j3dSys.reinitGX();
GXSetNumIndStages(0);
#endif
GXInitTexObj(&texObj, imageData, 16, 4, GX_TF_I4, GX_CLAMP, GX_CLAMP, FALSE);
GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, FALSE, FALSE, GX_ANISO_1);
GXLoadTexObj(&texObj, GX_TEXMAP0);
GXCallDisplayList(l_matDL, 0x80);
// Light yellow color for the trail.
static GXColor color0 = {0xFF, 0xFF, 0x7B, 0x96};
GFSetTevColor(GX_TEVREG0, color0);
const s32 uCoordStep = 0xFF / ((numTrailSegments >> 1) + 1);
s16 uCoord1 = uCoordStep;
s16 uCoord0 = 0;
GFSetVtxDescv(l_vtxDescList);
GFSetVtxAttrFmtv(GX_VTXFMT0, l_vtxAttrFmtList);
GFLoadPosMtxImm(j3dSys.getViewMtx(), GX_PNMTX0);
#define QUAD_VTX(xyz, u, v) \
GFPosition3f32((xyz).x, (xyz).y, (xyz).z); \
GFTexCoord2s16((u), (v))
{
GFBegin(GX_QUADS, GX_VTXFMT0, numTrailSegments * 4 + 4);
for (int i = numTrailSegments; i >= 0; i--) {
QUAD_VTX(trail0_vtxArr0[i], uCoord1, 0x00);
QUAD_VTX(trail0_vtxArr1[i], uCoord1, 0xFF);
QUAD_VTX(trail0_vtxArr1[i + 1], uCoord0, 0xFF);
QUAD_VTX(trail0_vtxArr0[i + 1], uCoord0, 0x00);
uCoord0 = uCoord1;
uCoord1 += uCoordStep;
}
GFEnd();
}
{
uCoord1 = uCoordStep;
uCoord0 = 0;
GFBegin(GX_QUADS, GX_VTXFMT0, numTrailSegments * 4 + 4);
for (int i = numTrailSegments; i >= 0; i--) {
QUAD_VTX(trail1_vtxArr0[i], uCoord1, 0x00);
QUAD_VTX(trail1_vtxArr1[i], uCoord1, 0xFF);
QUAD_VTX(trail1_vtxArr1[i + 1], uCoord0, 0xFF);
QUAD_VTX(trail1_vtxArr0[i + 1], uCoord0, 0x00);
uCoord0 = uCoord1;
uCoord1 += uCoordStep;
}
GFEnd();
}
#if VERSION > VERSION_JPN
J3DShape::resetVcdVatCache();
#endif
}
#include "assets/l_sightMatDL.h"
#include "assets/l_sightDL__d_a_boomerang.h"
/* 800E13A4-800E14F0 .text draw__25daBoomerang_sightPacket_cFv */
void daBoomerang_sightPacket_c::draw() {
static GXVtxDescList l_vtxDescList[] ALIGN_DECL(32) = {
{GX_VA_POS, GX_DIRECT},
{GX_VA_TEX0, GX_DIRECT},
{GX_VA_NULL, GX_NONE},
};
static GXVtxAttrFmtList l_vtxAttrFmtList[] ALIGN_DECL(32) = {
{GX_VA_POS, GX_POS_XYZ, GX_S8, 0x00},
{GX_VA_TEX0, GX_TEX_ST, GX_U8, 0x00},
{GX_VA_NULL, GX_POS_XYZ, GX_F32, 0x00},
};
GXTexObj texObj;
const GXBool mipmap = mImage->mipmapCount > 1 ? TRUE : FALSE;
GXInitTexObj(&texObj, mTex, mImage->width, mImage->height, GXTexFmt(mImage->format), GXTexWrapMode(mImage->wrapS), GXTexWrapMode(mImage->wrapT), mipmap);
GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, FALSE, FALSE, GX_ANISO_1);
GXLoadTexObj(&texObj, GX_TEXMAP0);
GXCallDisplayList(l_sightMatDL, 0x60);
GFSetVtxDescv(l_vtxDescList);
GFSetVtxAttrFmtv(GX_VTXFMT0, l_vtxAttrFmtList);
GXColor color0 = {0xFF, 0xFF, 0x32, 0xFF};
GXColor color1 = {0xFF, 0xFF, 0x32, 0xFF};
for (int i = 0; i < BOOMERANG_LOCK_MAX; i++) {
if (mSightOnFlg & (1 << i)) {
color0.a = mScaleArr[i];
color1.a = mScaleArr[i];
GFSetTevColor(GX_TEVREG0, color0);
GFSetTevColor(GX_TEVREG1, color1);
GFLoadPosMtxImm(mMtxArr[i], GX_PNMTX0);
GXCallDisplayList(l_sightDL, 0x20);
}
}
}
/* 800E14F0-800E1718 .text setSight__25daBoomerang_sightPacket_cFP4cXyzi */
void daBoomerang_sightPacket_c::setSight(cXyz* pPos, int n) {
if (pPos != NULL) {
s32 animFrame = mFrameArr[n];
f32 pingPongAnim;
f32 imageRot;
if (animFrame < (u32)HALF_ANIM_LENGTH) {
pingPongAnim = 1.0f - animFrame / (f32)HALF_ANIM_LENGTH;
imageRot = -pingPongAnim;
} else {
pingPongAnim = (animFrame - HALF_ANIM_LENGTH) / (f32)HALF_ANIM_LENGTH;
imageRot = pingPongAnim;
}
mScaleArr[n] = pingPongAnim * 30.0f + 150.0f;
f32 scale = (pingPongAnim * 35.0f + 65.0f) * 0.01f;
f32 scaleX = scale * mImage->width;
f32 scaleY = scale * mImage->height;
cXyz proj;
mDoLib_project(pPos, &proj);
mDoMtx_stack_c::transS(proj);
mDoMtx_stack_c::scaleM(scaleX, scaleY, scale);
mDoMtx_stack_c::ZrotM(cM_ssin(imageRot * 16384.0f) * 32768.0f);
MTXCopy(mDoMtx_stack_c::get(), mMtxArr[n]);
mSightOnFlg |= 1 << n;
} else {
mSightOnFlg &= ~(1 << n);
}
}
/* 800E1718-800E1754 .text play__25daBoomerang_sightPacket_cFi */
void daBoomerang_sightPacket_c::play(int n) {
u8* p = &mFrameArr[0];
for (int i = 0; i < n; i++) {
*p = *p + 1;
if (*p == ANIM_LENGTH) {
*p = 0;
}
p++;
}
}
/* 800E1754-800E1998 .text draw__13daBoomerang_cFv */
BOOL daBoomerang_c::draw() {
dComIfGd_setListP1();
if (!mThirdPerson && mLockCnt != 0) {
mSightPacket.resetSightOn();
for (int i = mCurLockIdx; i < mLockCnt; i++) {
fopAc_ac_c* pActor = mLockActors[i];
if (pActor) {
mSightPacket.setSight(&pActor->eyePos, i);
} else {
mSightPacket.setSight(NULL, i);
}
}
dComIfGd_set2DXlu(&mSightPacket);
}
if (mBlur.numTrailSegments > 0) {
dComIfGd_entryZSortXluList(&mBlur, current.pos);
}
if (daPy_getPlayerActorClass()->checkPlayerNoDraw() && fopAcM_GetParam(this) == Mode_Wait) {
dComIfGd_setList();
return TRUE;
}
dKy_getEnvlight().settingTevStruct(TEV_TYPE_ACTOR, &current.pos, &tevStr);
dKy_getEnvlight().setLightTevColorType(mpModel, &tevStr);
if (fopAcM_GetParam(this) == Mode_Wait && daPy_getPlayerLinkActorClass()->checkFreezeState()) {
dMat_control_c::iceUpdateDL(mpModel, -1, NULL);
} else {
mDoExt_modelUpdateDL(mpModel);
}
dComIfGd_setList();
if (mGroundY != -G_CM3D_F_INF && fopAcM_GetParam(this) == Mode_Throw) {
cXyz* pFloorNrm = dComIfG_Bgsp()->GetTriPla(mGndChk)->GetNP();
if (pFloorNrm) {
dComIfGd_setSimpleShadow(&current.pos, mGroundY, 30.0f, pFloorNrm);
}
}
return TRUE;
}
/* 800E1998-800E19B8 .text daBoomerang_Draw__FP13daBoomerang_c */
static BOOL daBoomerang_Draw(daBoomerang_c* i_this) {
return i_this->draw();
}
/* 800E19B8-800E1A14 .text getFlyMax__13daBoomerang_cFv */
float daBoomerang_c::getFlyMax() {
if (dComIfGp_checkPlayerStatus0(0, 0x10000) != 0) {
return 5000.0f;
}
if (strcmp(dComIfGp_getStartStageName(), "GanonK") != 0) {
return 2500.0f;
}
return 5000.0f;
}
/* 800E1A14-800E1AAC .text rockLineCallback__13daBoomerang_cFP10fopAc_ac_c */
void daBoomerang_c::rockLineCallback(fopAc_ac_c* pHitActor) {
if (fopAcM_GetParam(this) == Mode_Wait) {
if (pHitActor) {
setLockActor(pHitActor, TRUE);
}
} else {
for (int i = 0; i < BOOMERANG_LOCK_MAX; i++) {
if (mLockActors[i] == pHitActor) {
mLockActorIDs[i] = -1;
mLockActors[i] = NULL;
if (i == mCurLockIdx) {
mJustHit = true;
mCurLockIdx++;
}
}
}
}
}
/* 800E1AAC-800E1AD0 .text daBoomerang_rockLineCallback__FP10fopAc_ac_cP12dCcD_GObjInfP10fopAc_ac_cP12dCcD_GObjInf */
void daBoomerang_rockLineCallback(fopAc_ac_c* i_actor, dCcD_GObjInf*, fopAc_ac_c* i_hit, dCcD_GObjInf*) {
((daBoomerang_c*)i_actor)->rockLineCallback(i_hit);
}
/* 800E1AD0-800E1B20 .text setAimActor__13daBoomerang_cFP10fopAc_ac_c */
void daBoomerang_c::setAimActor(fopAc_ac_c* i_actor) {
resetLockActor();
mThirdPerson = true;
setLockActor(i_actor, FALSE);
}
/* 800E1B20-800E1C20 .text setLockActor__13daBoomerang_cFP10fopAc_ac_ci */
BOOL daBoomerang_c::setLockActor(fopAc_ac_c* i_actor, BOOL doSoundEffect) {
if (mLockCnt >= BOOMERANG_LOCK_MAX) {
return FALSE;
}
fpc_ProcID id = fopAcM_GetID(i_actor);
for (int i = 0; i < mLockCnt; i++) {
if (mLockActorIDs[i] == id) {
return FALSE;
}
}
mLockActorIDs[mLockCnt] = id;
mLockActors[mLockCnt] = i_actor;
mSightPacket.initFrame(mLockCnt);
if (doSoundEffect) {
static const u32 se_flg[BOOMERANG_LOCK_MAX] = {
JA_SE_BOOM_LOCK_ON_1,
JA_SE_BOOM_LOCK_ON_2,
JA_SE_BOOM_LOCK_ON_3,
JA_SE_BOOM_LOCK_ON_4,
JA_SE_BOOM_LOCK_ON_5,
};
mDoAud_seStart(se_flg[mLockCnt]);
}
mLockCnt++;
return TRUE;
}
/* 800E1C20-800E1C58 .text resetLockActor__13daBoomerang_cFv */
void daBoomerang_c::resetLockActor() {
for (int i = 0; i < BOOMERANG_LOCK_MAX; i++) {
mLockActorIDs[i] = fpcM_ERROR_PROCESS_ID_e;
mLockActors[i] = NULL;
}
mLockCnt = 0;
mCurLockIdx = 0;
}
/* 800E1C58-800E1CFC .text setRoomInfo__13daBoomerang_cFv */
void daBoomerang_c::setRoomInfo() {
mGndChk.SetPos(&current.pos);
f32 groundY = dComIfG_Bgsp()->GroundCross(&mGndChk);
s32 roomNo;
if (groundY != -G_CM3D_F_INF) {
roomNo = dComIfG_Bgsp()->GetRoomId(mGndChk);
tevStr.mEnvrIdxOverride = dComIfG_Bgsp()->GetPolyColor(mGndChk);
} else {
roomNo = dComIfGp_roomControl_getStayNo();
}
tevStr.mRoomNo = roomNo;
mStts.SetRoomId(roomNo);
current.roomNo = roomNo;
}
/* 800E1CFC-800E1DA8 .text setKeepMatrix__13daBoomerang_cFv */
void daBoomerang_c::setKeepMatrix() {
// Transform the boomerang to Link's hand.
mDoMtx_stack_c::copy(daPy_getPlayerActorClass()->getLeftHandMatrix());
mDoMtx_stack_c::transM(10.3f, 36.6f, 1.1f);
mDoMtx_stack_c::XYZrotM(-0x39f4, -0x357, -0x2af3);
MtxP mtx = mDoMtx_stack_c::get();
mpModel->setBaseTRMtx(mtx);
current.pos.set(mtx[0][3], mtx[1][3], mtx[2][3]);
}
/* 800E1DA8-800E1E6C .text setAimPos__13daBoomerang_cFv */
void daBoomerang_c::setAimPos() {
if (mIsReturning) {
mTargetPos = daPy_getPlayerLinkActorClass()->getBoomerangCatchPos();
} else {
for (int i = mCurLockIdx; i < mLockCnt; i++) {
if (mLockActors[i] != NULL) {
mTargetPos = mLockActors[i]->eyePos;
return;
}
mCurLockIdx++;
}
}
}
/* 800E1E6C-800E1F94 .text checkBgHit__13daBoomerang_cFP4cXyzP4cXyz */
void daBoomerang_c::checkBgHit(cXyz* pi_start, cXyz* pi_end) {
mLinChk.Set(pi_start, pi_end, this);
if (dComIfG_Bgsp()->LineCross(&mLinChk)) {
current.pos.set(mLinChk.GetCross());
dComIfGp_particle_setP1(dPa_name::ID_COMMON_PURPLE_HIT, &current.pos);
mIsReturning = true;
current.angle.y += 0x8000;
shape_angle.y = current.angle.y;
resetLockActor();
u32 mtrlSndId = dComIfG_Bgsp()->GetMtrlSndId(mLinChk);
s8 roomNo = current.roomNo;
s8 reverb = dComIfGp_getReverb(roomNo);
mDoAud_seStart(JA_SE_LK_W_WEP_HIT, &eyePos, mtrlSndId, reverb);
}
}
/* 800E1F94-800E239C .text procWait__13daBoomerang_cFv */
BOOL daBoomerang_c::procWait() {
daPy_lk_c* pPlayer = daPy_getPlayerLinkActorClass();
speedF = 0.0f;
setKeepMatrix();
if (mBlur.numTrailSegments > 0) {
mBlur.numTrailSegments -= daBoomerang_blur_c::SEGMENTS_PER_STEP;
}
if (fopAcM_GetParam(this) == Mode_Throw) {
speedF = 60.0f;
mCps.ResetAtHit();
mCps.OffAtNoTgHitInfSet();
mIsReturning = false;
unused_0xF2D = true;
mJustHit = false;
mCurLockIdx = 0;
setAimPos();
if (mCurLockIdx == mLockCnt) {
resetLockActor();
s16 angleY = pPlayer->getBodyAngleY() + pPlayer->shape_angle.y;
s16 angleX = pPlayer->getBodyAngleX();
f32 flyMax = getFlyMax();
mTargetPos.set(
current.pos.x + flyMax * cM_ssin(angleY) * cM_scos(angleX),
current.pos.y - flyMax * cM_ssin(angleX),
current.pos.z + flyMax * cM_scos(angleY) * cM_scos(angleX)
);
}
mModelRotY = 0;
cXyz diff = mTargetPos - current.pos;
s16 angle = cM_atan2s(-diff.y, diff.absXZ());
current.angle.x = angle;
if (mLockCnt == 0) {
current.angle.y = cM_atan2s(diff.x, diff.z) + 0x3000;
if (mThirdPerson) {
mFreeFlyOut = false;
} else {
mFreeFlyOut = true;
}
} else {
current.angle.y = cM_atan2s(diff.x, diff.z);
mFreeFlyOut = false;
}
shape_angle.x = current.angle.x;
shape_angle.y = current.angle.y;
shape_angle.z = 0x2000;
mModelRotZ = 0x2000;
mProcFunc = &daBoomerang_c::procMove;
mCancelFlg = false;
mBlur.initBlur(mpModel->getBaseTRMtx(), mModelRotY);
cXyz bgHitPos(pPlayer->current.pos.x, pPlayer->current.pos.y + 60.0f, pPlayer->current.pos.z);
checkBgHit(&bgHitPos, &current.pos);
procMove();
} else {
if (dCam_getBody()->mCurMode != 0xB) {
resetLockActor();
} else {
bool isAiming = (pPlayer->mCurProc == daPy_lk_c::daPyProc_BOOMERANG_SUBJECT_e || pPlayer->mCurProc == daPy_lk_c::daPyProc_SHIP_BOOMERANG_e) &&
pPlayer->mSightPacket.getDrawFlg();
if (isAiming) {
camera_class* pCamera = dComIfGp_getCamera(dComIfGp_getPlayerCameraID(0));
cXyz eyePos = *fopCamM_GetEye_p(pCamera);
cXyz topPos = pPlayer->getLineTopPos();
mCps.OnAtNoTgHitInfSet();
mCps.cM3dGCps::Set(eyePos, topPos, 3.0f);
mCps.CalcAtVec();
mCps.SetAtHitCallback(&daBoomerang_rockLineCallback);
dComIfG_Ccsp()->Set(&mCps);
}
}
}
return TRUE;
}
/* 800E239C-800E2AF4 .text procMove__13daBoomerang_cFv */
BOOL daBoomerang_c::procMove() {
static cXyz at_offset; // Never used.
if (mCatchAndDelete) {
fopAcM_delete(this);
return TRUE;
}
if (dComIfGp_event_getMode() == dEvtMode_NONE_e) {
daPy_lk_c* pPlayer = daPy_getPlayerLinkActorClass();
s16 s = mModelRotY;
mModelRotY -= 0x1F00;
if (s >= 0 && mModelRotY < 0) {
s8 roomNo = current.roomNo;
mDoAud_seStart(JA_SE_LK_BOOM_FLY, &eyePos, 0, dComIfGp_getReverb(roomNo));
}
setAimPos();
cXyz diff = mTargetPos - current.pos;
f32 dist = diff.abs();
cXyz norm;
if (dist > 0.1f) {
norm = diff / dist;
} else {
norm = diff;
}
s16 angle = cM_atan2s(norm.x, norm.z);
s16 currentAngle = angle - current.angle.y;
if (mJustHit) {
mJustHit = false;
if (s16(angle - current.angle.y) > 0) {
current.angle.y = angle - 0x3000;
} else {
current.angle.y = angle + 0x3000;
}
currentAngle = angle - current.angle.y;
}
if (mIsReturning) {
if (dist < speedF * 2.0f) {
if (pPlayer->returnBoomerang()) {
fopAcM_SetParam(this, Mode_Wait);
mThirdPerson = false;
mProcFunc = &daBoomerang_c::procWait;
mCps.SetAtHitCallback(NULL);
} else {
mCatchAndDelete = true;
}
}
} else {
if (dist < speedF || mCps.ChkAtHit() && mCps.GetAtHitAc() == mLockActors[mCurLockIdx]) {
// Boomerang hit its current target.
mJustHit = true;
mLockActors[mCurLockIdx] = NULL;
mLockActorIDs[mCurLockIdx] = fpcM_ERROR_PROCESS_ID_e;
mCurLockIdx++;
mFreeFlyOut = false;
}
}
if (!mIsReturning && (mCancelFlg || (!mFreeFlyOut && mLockCnt <= mCurLockIdx) || mCps.ChkAtShieldHit())) {
// Boomerang should return. It either was canceled, hit its last target, or hit a shield.
mJustHit = true;
mIsReturning = true;
resetLockActor();
mCancelFlg = false;
mFreeFlyOut = false;
}
if (mJustHit) {
current.angle.y = angle;
} else {
s16 newAngle;
if (!mThirdPerson) {
f32 a = 20.0f - dist * 2.0f / speedF;
if (a < 0.0f) {
a = 0.0f;
} else if (a > 18.0f) {
a = 20.0f + 40.0f * (a - 18.0f);
}
newAngle = a * 256.0f + 1024.0f;
} else {
newAngle = 0x4000;
}
if (currentAngle > newAngle) {
currentAngle = newAngle;
} else if (currentAngle < -newAngle) {
currentAngle = -newAngle;
}
current.angle.y += currentAngle;
}
angle = cM_atan2s(-norm.y, norm.absXZ());
current.angle.x = angle;
current.pos.x += speedF * cM_scos(current.angle.x) * cM_ssin(current.angle.y);
current.pos.y -= speedF * cM_ssin(current.angle.x);
current.pos.z += speedF * cM_scos(current.angle.x) * cM_scos(current.angle.y);
shape_angle.y = current.angle.y;
shape_angle.x = current.angle.x;
if (!mIsReturning) {
checkBgHit(&old.pos, &current.pos);
}
currentAngle = -(currentAngle * 2);
if (currentAngle > 0x100) {
currentAngle = 0x2000;
} else if (currentAngle < -0x100) {
currentAngle = -0x2000;
} else {
currentAngle = mModelRotZ;
}
mModelRotZ = currentAngle;
cLib_addCalcAngleS(&shape_angle.z, currentAngle, 0x10, 0x1000, 0x10);
}
mDoMtx_stack_c::transS(current.pos);
mDoMtx_stack_c::ZXYrotM(shape_angle.x, shape_angle.y, shape_angle.z);
mDoMtx_stack_c::YrotM(mModelRotY);
mpModel->setBaseTRMtx(mDoMtx_stack_c::get());
mCps.cM3dGCps::Set(old.pos, current.pos, 30.0f);
mCps.CalcAtVec();
if (dComIfGp_event_getMode() == dEvtMode_NONE_e) {
mBlur.copyBlur(mDoMtx_stack_c::get(), mModelRotY);
dComIfG_Ccsp()->Set(&mCps);
dComIfG_Ccsp()->SetMass(&mCps, 1);
} else {
mBlur.copyBlur(mDoMtx_stack_c::get(), 0);
mCps.ResetAtHit();
}
mInWater = daPy_lk_c::setItemWaterEffect(this, mInWater, TRUE);
return TRUE;
}
/* 800E2AF4-800E2BD0 .text execute__13daBoomerang_cFv */
BOOL daBoomerang_c::execute() {
for (int i = 0; i < mLockCnt; i++) {
mLockActors[i] = fopAcM_SearchByID(mLockActorIDs[i]);
}
if (mProcFunc) {
(this->*mProcFunc)();
}
attention_info.position = current.pos;
eyePos = current.pos;
setRoomInfo();
mSightPacket.play(mLockCnt);
return TRUE;
}
/* 800E2BD0-800E2BF0 .text daBoomerang_Execute__FP13daBoomerang_c */
static BOOL daBoomerang_Execute(daBoomerang_c* i_this) {
return i_this->execute();
}
/* 800E2BF0-800E2BF8 .text daBoomerang_IsDelete__FP13daBoomerang_c */
static BOOL daBoomerang_IsDelete(daBoomerang_c*) {
return TRUE;
}
/* 800E2BF8-800E2C00 .text daBoomerang_Delete__FP13daBoomerang_c */
static BOOL daBoomerang_Delete(daBoomerang_c*) {
return TRUE;
}
/* 800E2C00-800E2CC8 .text createHeap__13daBoomerang_cFv */
BOOL daBoomerang_c::createHeap() {
J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes("Link", LINK_BDL_BOOMERANG);
JUT_ASSERT(VERSION_SELECT(1543, 1539, 1546, 1546), modelData != NULL);
mpModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x37220202);
if (mpModel == NULL)
return FALSE;
return TRUE;
}
/* 800E2CC8-800E2CE8 .text daBoomerang_createHeap__FP10fopAc_ac_c */
static BOOL daBoomerang_createHeap(fopAc_ac_c* i_this) {
return static_cast<daBoomerang_c*>(i_this)->createHeap();
}
static dCcD_SrcCps l_at_cps_src = {
// dCcD_SrcGObjInf
{
@@ -42,140 +795,54 @@ static dCcD_SrcCps l_at_cps_src = {
}},
};
/* 800E0C08-800E0D44 .text initBlur__18daBoomerang_blur_cFPA4_fs */
void daBoomerang_blur_c::initBlur(MtxP, s16) {
/* Nonmatching */
}
/* 800E0D44-800E101C .text copyBlur__18daBoomerang_blur_cFPA4_fs */
void daBoomerang_blur_c::copyBlur(MtxP, s16) {
/* Nonmatching */
}
/* 800E101C-800E13A4 .text draw__18daBoomerang_blur_cFv */
void daBoomerang_blur_c::draw() {
/* Nonmatching */
}
/* 800E13A4-800E14F0 .text draw__25daBoomerang_sightPacket_cFv */
void daBoomerang_sightPacket_c::draw() {
/* Nonmatching */
}
/* 800E14F0-800E1718 .text setSight__25daBoomerang_sightPacket_cFP4cXyzi */
void daBoomerang_sightPacket_c::setSight(cXyz*, int) {
/* Nonmatching */
}
/* 800E1718-800E1754 .text play__25daBoomerang_sightPacket_cFi */
void daBoomerang_sightPacket_c::play(int) {
/* Nonmatching */
}
/* 800E1754-800E1998 .text draw__13daBoomerang_cFv */
BOOL daBoomerang_c::draw() {
/* Nonmatching */
}
/* 800E1998-800E19B8 .text daBoomerang_Draw__FP13daBoomerang_c */
static BOOL daBoomerang_Draw(daBoomerang_c* i_this) {
return ((daBoomerang_c*)i_this)->draw();
}
/* 800E19B8-800E1A14 .text getFlyMax__13daBoomerang_cFv */
float daBoomerang_c::getFlyMax() {
/* Nonmatching */
}
/* 800E1A14-800E1AAC .text rockLineCallback__13daBoomerang_cFP10fopAc_ac_c */
void daBoomerang_c::rockLineCallback(fopAc_ac_c*) {
/* Nonmatching */
}
/* 800E1AAC-800E1AD0 .text daBoomerang_rockLineCallback__FP10fopAc_ac_cP12dCcD_GObjInfP10fopAc_ac_cP12dCcD_GObjInf */
void daBoomerang_rockLineCallback(fopAc_ac_c*, dCcD_GObjInf*, fopAc_ac_c*, dCcD_GObjInf*) {
/* Nonmatching */
}
/* 800E1AD0-800E1B20 .text setAimActor__13daBoomerang_cFP10fopAc_ac_c */
void daBoomerang_c::setAimActor(fopAc_ac_c*) {
/* Nonmatching */
}
/* 800E1B20-800E1C20 .text setLockActor__13daBoomerang_cFP10fopAc_ac_ci */
void daBoomerang_c::setLockActor(fopAc_ac_c*, int) {
/* Nonmatching */
}
/* 800E1C20-800E1C58 .text resetLockActor__13daBoomerang_cFv */
void daBoomerang_c::resetLockActor() {
/* Nonmatching */
}
/* 800E1C58-800E1CFC .text setRoomInfo__13daBoomerang_cFv */
void daBoomerang_c::setRoomInfo() {
/* Nonmatching */
}
/* 800E1CFC-800E1DA8 .text setKeepMatrix__13daBoomerang_cFv */
void daBoomerang_c::setKeepMatrix() {
/* Nonmatching */
}
/* 800E1DA8-800E1E6C .text setAimPos__13daBoomerang_cFv */
void daBoomerang_c::setAimPos() {
/* Nonmatching */
}
/* 800E1E6C-800E1F94 .text checkBgHit__13daBoomerang_cFP4cXyzP4cXyz */
void daBoomerang_c::checkBgHit(cXyz*, cXyz*) {
/* Nonmatching */
}
/* 800E1F94-800E239C .text procWait__13daBoomerang_cFv */
void daBoomerang_c::procWait() {
/* Nonmatching */
}
/* 800E239C-800E2AF4 .text procMove__13daBoomerang_cFv */
void daBoomerang_c::procMove() {
/* Nonmatching */
}
/* 800E2AF4-800E2BD0 .text execute__13daBoomerang_cFv */
BOOL daBoomerang_c::execute() {
/* Nonmatching */
}
/* 800E2BD0-800E2BF0 .text daBoomerang_Execute__FP13daBoomerang_c */
static BOOL daBoomerang_Execute(daBoomerang_c* i_this) {
return ((daBoomerang_c*)i_this)->execute();
}
/* 800E2BF0-800E2BF8 .text daBoomerang_IsDelete__FP13daBoomerang_c */
static BOOL daBoomerang_IsDelete(daBoomerang_c*) {
return TRUE;
}
/* 800E2BF8-800E2C00 .text daBoomerang_Delete__FP13daBoomerang_c */
static BOOL daBoomerang_Delete(daBoomerang_c*) {
return TRUE;
}
/* 800E2C00-800E2CC8 .text createHeap__13daBoomerang_cFv */
void daBoomerang_c::createHeap() {
/* Nonmatching */
}
/* 800E2CC8-800E2CE8 .text daBoomerang_createHeap__FP10fopAc_ac_c */
static BOOL daBoomerang_createHeap(fopAc_ac_c*) {
/* Nonmatching */
}
/* 800E2CE8-800E2EF0 .text create__13daBoomerang_cFv */
cPhs_State daBoomerang_c::create() {
/* Nonmatching */
fopAcM_SetupActor(this, daBoomerang_c);
if (!fopAcM_entrySolidHeap(this, daBoomerang_createHeap, 0xD40)) {
return cPhs_ERROR_e;
}
setKeepMatrix();
fopAcM_SetMtx(this, mpModel->getBaseTRMtx());
mProcFunc = &daBoomerang_c::procWait;
mStts.Init(0x3C, 0xFF, this);
mCps.Set(l_at_cps_src);
mCps.SetStts(&mStts);
mCps.SetAtHitCallback(&daBoomerang_rockLineCallback);
mLinChk.ClrSttsRoofOff();
for (int i = 0; i < BOOMERANG_LOCK_MAX; i++) {
mLockActorIDs[i] = fpcM_ERROR_PROCESS_ID_e;
}
{
ResTIMG* tmp_img = (ResTIMG*)dComIfG_getObjectRes("Link", LINK_BTI_BLUR);
JUT_ASSERT(VERSION_SELECT(1626, 1622, 1629, 1629), tmp_img != NULL);
mBlur.imageData = (u8*)tmp_img + tmp_img->imageOffset;
}
{
ResTIMG* tmp_img = (ResTIMG*)dComIfG_getObjectRes("Link", LINK_BTI_ROCK_MARK);
JUT_ASSERT(VERSION_SELECT(1634, 1630, 1637, 1637), tmp_img != NULL);
mSightPacket.setTex((u8*)tmp_img + tmp_img->imageOffset);
mSightPacket.setImage(tmp_img);
}
setRoomInfo();
model = mpModel;
return cPhs_COMPLEATE_e;
}
/* 800E2EF0-800E329C .text __ct__13daBoomerang_cFv */
daBoomerang_c::daBoomerang_c() {
}
/* 800E33F0-800E3410 .text daBoomerang_Create__FP10fopAc_ac_c */
+2 -2
View File
@@ -24,7 +24,7 @@ BOOL daPy_lk_c::checkBoomerangAnime() const {
void daPy_lk_c::throwBoomerang() {
daBoomerang_c* boomerang = (daBoomerang_c*)mActorKeepEquip.getActor();
fopAcM_SetParam(boomerang, 1);
fopAcM_SetParam(boomerang, daBoomerang_c::Mode_Throw);
if (mpAttnActorLockOn != NULL) {
boomerang->setAimActor(mpAttnActorLockOn);
}
@@ -47,7 +47,7 @@ void daPy_lk_c::throwBoomerang() {
}
/* 80149698-801497A4 .text returnBoomerang__9daPy_lk_cFv */
int daPy_lk_c::returnBoomerang() {
BOOL daPy_lk_c::returnBoomerang() {
dComIfGp_clearPlayerStatus0(0, daPyStts0_BOOMERANG_WAIT_e);
if (mEquipItem == daPyItem_NONE_e && !checkNoControll() && !dComIfGp_event_runCheck() && mDemo.getDemoType() == 0 &&
+1 -1
View File
@@ -11650,7 +11650,7 @@ BOOL daPy_lk_c::execute() {
checkRoofRestart();
mDoMtx_multVecZero(mpCLModel->getAnmMtx(0x08), &mLeftHandPos);
mDoMtx_multVecZero(mpCLModel->getAnmMtx(0x0C), &mRightHandPos);
cMtx_multVec(mpCLModel->getAnmMtx(0x00), &boomerang_catch, &m36F4);
cMtx_multVec(mpCLModel->getAnmMtx(0x00), &boomerang_catch, &mBoomerangCatchPos);
cMtx_multVec(mpCLModel->getAnmMtx(0x08), &hookshot_root, &mHookshotRootPos);
mpKatsuraModel->setBaseTRMtx(mpCLModel->getAnmMtx(0x0F));
mpKatsuraModel->calc();
+9 -6
View File
@@ -1276,16 +1276,19 @@ void daPy_lk_c::endDamageEmitter() {
}
/* 8012CA44-8012CD60 .text setItemWaterEffect__9daPy_lk_cFP10fopAc_ac_cii */
u32 daPy_lk_c::setItemWaterEffect(fopAc_ac_c* i_actor, int param_1, int param_2) {
BOOL daPy_lk_c::setItemWaterEffect(fopAc_ac_c* i_actor, BOOL inWater, BOOL triggerOnExit) {
static cXyz eff_scale0(0.5f, 0.5f, 0.5f);
static cXyz eff_scale2(0.13f, 0.13f, 0.13f);
static JGeometry::TVec3<f32> direction(0.0f, 1.0f, 0.0f);
f32 waterY;
if (fopAcM_getWaterY(&i_actor->current.pos, &waterY) && ((param_1 != 0 && i_actor->current.pos.y > waterY) || (param_1 == 0 && waterY >= i_actor->current.pos.y))) {
param_1 ^= 1;
if (param_1 == 0 && param_2 == 0) {
return param_1;
if (fopAcM_getWaterY(&i_actor->current.pos, &waterY) &&
((inWater && i_actor->current.pos.y > waterY) || (!inWater && waterY >= i_actor->current.pos.y)))
{
// Item entered or exited the water.
inWater ^= 1;
if (!inWater && !triggerOnExit) {
return inWater;
}
f32 deltaY = std::fabsf(i_actor->old.pos.y - i_actor->current.pos.y);
@@ -1321,5 +1324,5 @@ u32 daPy_lk_c::setItemWaterEffect(fopAc_ac_c* i_actor, int param_1, int param_2)
}
}
return param_1;
return inWater;
}