From 9041d6289f713b62aab9a9d7c8b8a889c7f42ca1 Mon Sep 17 00:00:00 2001 From: Huitzi <73550465+marwernerh@users.noreply.github.com> Date: Wed, 28 Jan 2026 17:21:47 -0500 Subject: [PATCH] Various Lakebed Temple/water-related object debug equivalencies (#3070) * d_a_obj_syRock + waterPillar debug equivalent * Implemented HIO genMessage * Added drawCylinder debug drawing * d_a_obj_waterfall debug equivalent * Implemented HIO genMessage * Added unused tri collider and cull box data * Various LV3 d_a_obj_* actors debug equivalent * Added/modified some documentation * Added some widescreen support functions * Added relevant HIO stuff * Noted weak ordering issues in configure.py * Refactoring according to feedback --- configure.py | 20 +- include/d/actor/d_a_obj_bsGate.h | 14 - include/d/actor/d_a_obj_lv3Candle.h | 17 +- include/d/actor/d_a_obj_lv3Water.h | 19 +- include/d/actor/d_a_obj_lv3Water2.h | 26 +- include/d/actor/d_a_obj_syRock.h | 35 +- include/d/actor/d_a_obj_waterPillar.h | 64 ++-- include/d/actor/d_a_obj_waterfall.h | 18 +- src/d/actor/d_a_obj_bsGate.cpp | 81 ++++- src/d/actor/d_a_obj_lv3Candle.cpp | 62 +++- src/d/actor/d_a_obj_lv3Water.cpp | 249 ++++++++------ src/d/actor/d_a_obj_lv3Water2.cpp | 463 +++++++++++++------------ src/d/actor/d_a_obj_lv3WaterB.cpp | 99 +++--- src/d/actor/d_a_obj_lv3saka00.cpp | 53 ++- src/d/actor/d_a_obj_lv3waterEff.cpp | 11 +- src/d/actor/d_a_obj_syRock.cpp | 319 +++++++++++------- src/d/actor/d_a_obj_waterPillar.cpp | 469 ++++++++++++++++---------- src/d/actor/d_a_obj_waterfall.cpp | 383 ++++++++++++--------- 18 files changed, 1450 insertions(+), 952 deletions(-) diff --git a/configure.py b/configure.py index d5ad356688..9242526b8e 100755 --- a/configure.py +++ b/configure.py @@ -2524,7 +2524,7 @@ config.libs = [ ActorRel(MatchingFor(ALL_GCN), "d_a_obj_bombf"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_boumato"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_brg"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_bsGate"), + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_bsGate"), # debug weak func order ActorRel(MatchingFor(ALL_GCN), "d_a_obj_bubblePilar"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_catdoor"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_cb"), @@ -2626,12 +2626,12 @@ config.libs = [ ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lp"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv1Candle00"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv1Candle01"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3Candle"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3Water"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3Water2"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3WaterB"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3saka00"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3waterEff"), + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3Candle"), # debug weak func order + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3Water"), # debug weak func order + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3Water2"), # debug weak func order + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3WaterB"), # debug weak func order + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3saka00"), # debug weak func order + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv3waterEff"), # debug weak func order ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv4CandleDemoTag"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv4CandleTag"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_lv4EdShutter"), @@ -2757,7 +2757,7 @@ config.libs = [ ActorRel(MatchingFor(ALL_GCN), "d_a_obj_swpush2"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_swspinner"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_swturn"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_syRock"), + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_syRock"), # debug weak func order ActorRel(MatchingFor(ALL_GCN), "d_a_obj_szbridge"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_taFence"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_table"), @@ -2789,8 +2789,8 @@ config.libs = [ ActorRel(MatchingFor(ALL_GCN), "d_a_obj_warp_kbrg"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_warp_obrg"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_waterGate"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_waterPillar"), - ActorRel(MatchingFor(ALL_GCN), "d_a_obj_waterfall"), + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_waterPillar"), # debug weak func order + ActorRel(MatchingFor(ALL_GCN), "d_a_obj_waterfall"), # debug weak func order ActorRel(MatchingFor(ALL_GCN), "d_a_obj_wchain"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_wdStick"), ActorRel(MatchingFor(ALL_GCN), "d_a_obj_web0"), diff --git a/include/d/actor/d_a_obj_bsGate.h b/include/d/actor/d_a_obj_bsGate.h index 6ccdb38633..b40c5dcf6d 100644 --- a/include/d/actor/d_a_obj_bsGate.h +++ b/include/d/actor/d_a_obj_bsGate.h @@ -48,18 +48,4 @@ private: STATIC_ASSERT(sizeof(daBsGate_c) == 0x5B8); -class daBsGate_HIO_c : public mDoHIO_entry_c { -public: - daBsGate_HIO_c(); - ~daBsGate_HIO_c() {} - - void genMessage(JORMContext*); - - /* 0x4 */ f32 mOpenSpeed; - /* 0x8 */ f32 mCloseSpeed; - /* 0xC */ u8 mShockStrength; -}; - -STATIC_ASSERT(sizeof(daBsGate_HIO_c) == 0x10); - #endif /* D_A_OBJ_BSGATE_H */ diff --git a/include/d/actor/d_a_obj_lv3Candle.h b/include/d/actor/d_a_obj_lv3Candle.h index 0adca9d812..b82ad0b8c4 100644 --- a/include/d/actor/d_a_obj_lv3Candle.h +++ b/include/d/actor/d_a_obj_lv3Candle.h @@ -3,7 +3,7 @@ #include "d/d_cc_d.h" #include "f_op/f_op_actor_mng.h" -#include "m_Do/m_Do_hostIO.h" +#include "d/d_kankyo.h" /** @@ -26,8 +26,8 @@ public: int Draw(); int Delete(); - u8 getSwBit() { return fopAcM_GetParamBit(this, 0, 8); } - u8 getType() { return fopAcM_GetParamBit(this, 8, 8); } + int getSwBit() { return fopAcM_GetParamBit(this, 0, 8); } + int getType() { return fopAcM_GetParamBit(this, 8, 8); } private: /* 0x568 */ request_of_phase_process_class mPhaseReq; @@ -51,15 +51,4 @@ private: STATIC_ASSERT(sizeof(daLv3Candle_c) == 0x754); -class daLv3Candle_HIO_c : public mDoHIO_entry_c { -public: - daLv3Candle_HIO_c(); - virtual ~daLv3Candle_HIO_c() {} - - void genMessage(JORMContext*); - - /* 0x00 vtable */ - /* 0x04 */ u8 field_0x04; -}; - #endif /* D_A_OBJ_LV3CANDLE_H */ diff --git a/include/d/actor/d_a_obj_lv3Water.h b/include/d/actor/d_a_obj_lv3Water.h index b6084c9928..de4ff03356 100644 --- a/include/d/actor/d_a_obj_lv3Water.h +++ b/include/d/actor/d_a_obj_lv3Water.h @@ -40,10 +40,9 @@ public: virtual ~daLv3Water_c() {} virtual bool eventStart(); - int getParam() { return fpcM_GetParam(this) >> 0xC & 0x0FFF; } - int getParamSw() { return fpcM_GetParam(this) & 0xFF; } + int getParam(int shift, int bit) { return fopAcM_GetParamBit(this, shift, bit); } int getParamEvent() { return shape_angle.x & 0xFF; } - u8 getParamType() { return (shape_angle.x >> 8) & 0xFF; } + int getParamType() { return (shape_angle.x & 0xFF00) >> 8; } u8 getType() { return mType; } private: @@ -54,13 +53,13 @@ private: /* 0x5E0 */ mDoExt_btkAnm mBtk2; /* 0x5F8 */ u8 mMode; /* 0x5F9 */ u8 mType; - /* 0x5FC */ f32 field_0x5fc; - /* 0x600 */ u8 field_0x600; - /* 0x601 */ u8 field_0x601; - /* 0x602 */ u8 mSwitch1; - /* 0x603 */ u8 mSwitch2; - /* 0x604 */ u8 field_0x604; - /* 0x605 */ u8 field_0x605; + /* 0x5FC */ f32 mWaterLv; // Amount that the water's y coodinate should increase + /* 0x600 */ u8 mCurrentWaterLvFrame; // Number of frames that the water level has been changing + /* 0x601 */ u8 mWaterLvFrame; // Number of frames that should be taken for the water level to change + /* 0x602 */ u8 mSwInitialState; + /* 0x603 */ u8 mSwCurrentState; + /* 0x604 */ u8 mLvControlWaitFrames; + /* 0x605 */ u8 mSwStatePostEvent; // Only when true (i.e event initiated water raising instead of lowering) should anything be drawn /* 0x608 */ u32 mEmitterIDs[8]; }; diff --git a/include/d/actor/d_a_obj_lv3Water2.h b/include/d/actor/d_a_obj_lv3Water2.h index 7bfee65c27..be13ef4819 100644 --- a/include/d/actor/d_a_obj_lv3Water2.h +++ b/include/d/actor/d_a_obj_lv3Water2.h @@ -32,21 +32,21 @@ public: private: /* 0x5B8 */ request_of_phase_process_class mPhase; /* 0x5C0 */ J3DModel* mpModel; - /* 0x5C4 */ mDoExt_btkAnm mWaterSurfaceRefractionAnm; + /* 0x5C4 */ mDoExt_btkAnm mRefractionAnm; // Applied to water surface /* 0x5DC */ u8 mMode; - /* 0x5DD */ u8 mResourceIndex; - /* 0x5E0 */ f32 mWaterLv; - /* 0x5E4 */ u8 mCurrentWaterLvFrame; - /* 0x5E5 */ u8 mWaterLvFrame; - /* 0x5E6 */ u8 mFullRatio; - /* 0x5E7 */ u8 mEastSwInitialStatus; // East SW is the lever in the east-most room on 2F, which can only be pulled after raising the water level in that room by pulling the lever in 4F - /* 0x5E8 */ u8 mWestSwInitialStatus; // West SW is the lever in the west-most room on 2F, which can only be pulled after raising the water level in that room by pulling the lever in 4F - /* 0x5E9 */ u8 mEastSwCurrentStatus; - /* 0x5EA */ u8 mWestSwCurrentStatus; - /* 0x5EB */ u8 mLevelControlWaitFrames; + /* 0x5DD */ u8 mResIdx; + /* 0x5E0 */ f32 mWaterLv; // Amount that the water's y coodinate should increase + /* 0x5E4 */ u8 mCurrentWaterLvFrame; // Number of frames that the water level has been changing + /* 0x5E5 */ u8 mWaterLvFrame; // Number of frames that should be taken for the water level to change + /* 0x5E6 */ u8 mEvActivatorSwState; + /* 0x5E7 */ u8 mEastSwInitialState; // East SW is the lever in the east-most room on 2F, which can only be pulled after raising the water level in that room by pulling the lever in 4F + /* 0x5E8 */ u8 mWestSwInitialState; // West SW is the lever in the west-most room on 2F, which can only be pulled after raising the water level in that room by pulling the lever in 4F + /* 0x5E9 */ u8 mEastSwCurrentState; + /* 0x5EA */ u8 mWestSwCurrentState; + /* 0x5EB */ u8 mLvControlWaitFrames; /* 0x5EC */ f32 mBaseYPos; - /* 0x5F0 */ u32 mEastWaterParticles[4]; // If the central staircase isn't rotated to allow water from the east to flow down it, the water falls into the basin; these are the splash particles where the basin water and falling water meet - /* 0x600 */ u32 mWestWaterParticles[4]; // If the central staircase isn't rotated to allow water from the west to flow down it, the water falls into the basin; these are the splash particles where the basin water and falling water meet + /* 0x5F0 */ u32 mEastParticles[4]; // If the central staircase isn't rotated to allow water from the east to flow down it, the water falls into the basin; these are the splash particles where the basin water and falling water meet + /* 0x600 */ u32 mWestParticles[4]; // If the central staircase isn't rotated to allow water from the west to flow down it, the water falls into the basin; these are the splash particles where the basin water and falling water meet enum Mode_e { WAIT, LEVEL_CTRL diff --git a/include/d/actor/d_a_obj_syRock.h b/include/d/actor/d_a_obj_syRock.h index aa662de6bd..0af85cbaa6 100644 --- a/include/d/actor/d_a_obj_syRock.h +++ b/include/d/actor/d_a_obj_syRock.h @@ -1,8 +1,8 @@ #ifndef D_A_OBJ_SYROCK_H #define D_A_OBJ_SYROCK_H -#include "d/actor/d_a_obj_waterPillar.h" #include "d/d_bg_s_movebg_actor.h" +#include "d/actor/d_a_obj_waterPillar.h" /** * @ingroup actors-objects @@ -50,20 +50,20 @@ private: /* 0x5B8 */ request_of_phase_process_class mPhase; /* 0x5C0 */ J3DModel* mpModels[2]; /* 0x5C8 */ u8 mMode; - /* 0x5C9 */ u8 mDropAutomaticallySwitchNo; + /* 0x5C9 */ u8 mAutoDropSwNo; /* 0x5CC */ dCcD_Stts mStts; - /* 0x608 */ dCcD_Cyl mUnbrokenCylinderCollider; // Collider used to check for bomb/bomb arrow for breaking stalactite + /* 0x608 */ dCcD_Cyl mUnbrokenCollider; // Collider used to check for bomb/bomb arrow for breaking stalactite /* 0x744 */ u8 mWaitFrames; - /* 0x748 */ u32 mShakeOscillationAngleStep; - /* 0x74C */ csXyz mShakeXZAngleOffset; + /* 0x748 */ u32 mShakeOscAngStep; + /* 0x74C */ csXyz mShakeAngOffset; // Y component is always 0 /* 0x754 */ f32 mShakeAmplitude; - /* 0x758 */ f32 mShakeXOscillationAngle; - /* 0x75C */ f32 mShakeZOscillationAngle; - /* 0x760 */ f32 mShakeDamping; + /* 0x758 */ f32 mShakeXOscAngQuantum; + /* 0x75C */ f32 mShakeZOscAngQuantum; + /* 0x760 */ f32 mShakeDampingScale; /* 0x764 */ f32 mShakeMaxDecay; /* 0x768 */ f32 mShakeMinDecay; - /* 0x76C */ cXyz mUnderwaterRotatedStalactiteOffset; - /* 0x778 */ bool mInWaterPreviousFrame; + /* 0x76C */ cXyz mUnderwaterOffset; + /* 0x778 */ u8 mInWaterPrevFrame; /* 0x779 */ u8 field_0x779; // Redundant variable, thus left unnamed /* 0x77C */ dBgS_AcchCir mAcchCir; /* 0x7BC */ dBgS_ObjAcch mAcch; @@ -77,31 +77,30 @@ private: } // Switch to determine whether or not the stalactite has been broken - u32 getSwBit1() { + int getSwBit1() { return fopAcM_GetParamBit(this, 0, 8); } // Switch to determine whether or not the stalactite should be broken automatically when player is in range - u32 getSwBit2() { + int getSwBit2() { return fopAcM_GetParamBit(this, 8, 8); } // Event ID for Midna to stop and note the stalactite that fell by itself - s32 getEvetID() { + int getEvetID() { return fopAcM_GetParamBit(this, 16, 8); } enum Mode_e { - MODE_WAIT, - MODE_DROP_INIT, + MODE_WAIT, + MODE_DROP_INIT, MODE_DROP, - MODE_SINK, - MODE_MOVE, + MODE_SINK, + MODE_MOVE, MODE_DROP_END }; }; STATIC_ASSERT(sizeof(daSyRock_c) == 0x9a0); - #endif /* D_A_OBJ_SYROCK_H */ diff --git a/include/d/actor/d_a_obj_waterPillar.h b/include/d/actor/d_a_obj_waterPillar.h index 0a4bba4c04..6bcad283da 100644 --- a/include/d/actor/d_a_obj_waterPillar.h +++ b/include/d/actor/d_a_obj_waterPillar.h @@ -1,11 +1,6 @@ #ifndef D_A_OBJ_WATERPILLAR_H #define D_A_OBJ_WATERPILLAR_H -#include "d/d_bg_s_acch.h" -#include "d/d_cc_d.h" -#include "d/d_event_lib.h" -#include "f_op/f_op_actor_mng.h" - /** * @ingroup actors-objects * @class daWtPillar_c @@ -15,6 +10,13 @@ * */ +#include "d/d_bg_s_acch.h" +#include "d/d_cc_d.h" +#include "d/d_event_lib.h" +#include "f_op/f_op_actor.h" +#include "f_op/f_op_actor_mng.h" +#include "m_Do/m_Do_ext.h" +#include "SSystem/SComponent/c_phase.h" class daWtPillar_c : public fopAc_ac_c, public request_of_phase_process_class, public dEvLib_callback_c { public: daWtPillar_c() : dEvLib_callback_c(this) {} @@ -59,7 +61,7 @@ public: static dCcD_SrcCyl mCcDCyl; void onRockFlag() { - mIsCarryingStalactite = true; + mCarryingStalactite = true; } cXyz getPos() { @@ -67,18 +69,18 @@ public: } u8 isRockYure() { - return mStalactiteShouldStartShaking; + return mStartStalactiteShake; } void clearRockYure() { - mStalactiteShouldStartShaking = false; + mStartStalactiteShake = false; } private: /* 0x584 */ request_of_phase_process_class mPhase; /* 0x58C */ J3DModel* mpModel; - /* 0x590 */ mDoExt_btkAnm mVerticalTextureScrollAnimation; - /* 0x5A8 */ mDoExt_bckAnm mModelRotationAnimation; + /* 0x590 */ mDoExt_btkAnm mVTexScrollAnm; + /* 0x5A8 */ mDoExt_bckAnm mModelRotAnm; /* 0x5C4 */ dBgS_ObjAcch mAcch; /* 0x79C */ dBgS_AcchCir mAcchCir; /* 0x7DC */ dCcD_Stts mStts; @@ -86,34 +88,34 @@ private: /* 0x95C */ dCcD_Cyl mCylinderCollider; /* 0xA98 */ u8 pad0[0x30]; /* 0xAC8 */ cXyz field_0xAC8; // unused. - /* 0xAD4 */ cXyz mScale; // Modified but never read; unused? + /* 0xAD4 */ cXyz mDbgDrawScale; /* 0xAE0 */ f32 mCurrentHeight; /* 0xAE4 */ cM3dGCpsS mCapsuleSource; /* 0xB00 */ u8 mAction; - /* 0xB02 */ u16 mWaitFrameDelay; - /* 0xB04 */ f32 mTargetMaxSpeed; + /* 0xB02 */ u16 mWaitFrames; + /* 0xB04 */ f32 mTargetSpeed; /* 0xB08 */ u8 mSwitchNo; /* 0xB09 */ u8 mType; /* 0xB0A */ u8 pad2[0x6]; - /* 0xB10 */ f32 mFirstTargetHeight; + /* 0xB10 */ f32 mUpFirstTargetHeight; /* 0xB14 */ f32 mMaxHeight; /* 0xB18 */ f32 mTargetHeightStalactiteOffset; /* 0xB1C */ f32 mRelativeWaterHeight; - /* 0xB20 */ u32 mEffectOscillationAngleStep; - /* 0xB24 */ cXyz mEffectOscillationVerticalOffset; - /* 0xB30 */ f32 mEffectOscillationAngle; - /* 0xB34 */ f32 mEffectOscillationAmplitude; - /* 0xB38 */ f32 mEffectOscillationDampingScale; - /* 0xB3C */ f32 mEffectOscillationMaxDecay; - /* 0xB40 */ f32 mEffectOscillationMinDecay; + /* 0xB20 */ u32 mVOscAngleStep; + /* 0xB24 */ cXyz mVOscVOffset; + /* 0xB30 */ f32 mVOscAngleQuantum; + /* 0xB34 */ f32 mVOscAmplitude; + /* 0xB38 */ f32 mVOscDampingScale; + /* 0xB3C */ f32 mVOscMaxDecay; + /* 0xB40 */ f32 mVOscMinDecay; /* 0xB44 */ u8 field_0xB44; // Modified, but never read; unused? - /* 0xB45 */ u8 mStartedRisingOrDoesNotRiseAndFall; - /* 0xB46 */ u8 mPillarIsPreparingToRise; - /* 0xB48 */ u32 mBottomAndTopParticleEmmitters[7]; - /* 0xB64 */ u32 mWaterSurfaceParticleEmitters[2]; + /* 0xB45 */ u8 mIsUpOrStatic; + /* 0xB46 */ u8 mIsUpFirst; + /* 0xB48 */ u32 mBotAndTopEmmitters[7]; + /* 0xB64 */ u32 mWaterSurfaceEmitters[2]; /* 0xB6C */ cXyz mTopPos; - /* 0xB78 */ s8 mStalactiteShouldStartShaking; // Modified by d_a_obj_syRock - /* 0xB79 */ u8 mIsCarryingStalactite; // Modified by d_a_obj_syRock + /* 0xB78 */ u8 mStartStalactiteShake; // Modified by d_a_obj_syRock + /* 0xB79 */ u8 mCarryingStalactite; // Modified by d_a_obj_syRock s32 getEventID() { return shape_angle.x & 0xFF; @@ -124,11 +126,11 @@ private: } enum Action_e { - ACTION_SW_WAIT, - ACTION_WAIT, + ACTION_SW_WAIT, + ACTION_WAIT, ACTION_UP_FIRST, ACTION_UP_FIRST_WAIT, - ACTION_UP, ACTION_UP_WAIT, - ACTION_DOWN, + ACTION_UP, ACTION_UP_WAIT, + ACTION_DOWN, ACTION_ROCK_WAIT, ACTION_ROCK_ON, ACTION_END }; diff --git a/include/d/actor/d_a_obj_waterfall.h b/include/d/actor/d_a_obj_waterfall.h index 031a45d717..e7c143910d 100644 --- a/include/d/actor/d_a_obj_waterfall.h +++ b/include/d/actor/d_a_obj_waterfall.h @@ -8,9 +8,9 @@ /** * @ingroup actors-objects * @class daObjWaterFall_c - * @brief Waterfall With Collision Object + * @brief Waterfall Collision * - * @details Waterfalls that player cannot move through (e.g. those in Zora's Domain) + * @details Collision added to waterfalls that player shouldn't move through (e.g. those in Zora's Domain). Doesn't actually draw the waterfall. */ class daObjWaterFall_c : public fopAc_ac_c { public: @@ -30,23 +30,23 @@ private: /* 0x574 */ dCcD_Stts mCylColliderStts; /* 0x5B0 */ dCcD_Tri mUnusedTriCollider[2]; /* 0x868 */ dCcD_Cyl mCylCollider; - /* 0x9A4 */ cXyz mCylColliderCenterOscillationTargets[2]; - /* 0x9BC */ cXyz mCylColliderCenter; - /* 0x9C8 */ s8 mCylColliderCenterQuantizedOscillation; + /* 0x9A4 */ cXyz mColOscPosTargets[2]; + /* 0x9BC */ cXyz mColCenter; + /* 0x9C8 */ s8 mColOscDir; enum Type_e { ALLOW_ARROWS_e }; BOOL checkFallOut() { - return fopAcM_GetParamBit(this, 10, 4); + return (BOOL) fopAcM_GetParamBit(this, 10, 4) == TRUE; } - Type_e getType() { - return static_cast(fopAcM_GetParamBit(this, 8, 2)); + u8 getType() { + return fopAcM_GetParamBit(this, 8, 2); } - u32 getSwbit() { + u8 getSwbit() { return fopAcM_GetParamBit(this, 0, 8); } }; diff --git a/src/d/actor/d_a_obj_bsGate.cpp b/src/d/actor/d_a_obj_bsGate.cpp index 03edb364f2..3092b78e94 100644 --- a/src/d/actor/d_a_obj_bsGate.cpp +++ b/src/d/actor/d_a_obj_bsGate.cpp @@ -9,12 +9,58 @@ #include "d/d_com_inf_game.h" #include "d/d_procname.h" +class daBsGate_HIO_c : public mDoHIO_entry_c { +public: + daBsGate_HIO_c(); + ~daBsGate_HIO_c() {} + + void genMessage(JORMContext*); + + /* 0x4 */ f32 mOpenSpeed; + /* 0x8 */ f32 mCloseSpeed; + /* 0xC */ u8 mShockStrength; +}; + +STATIC_ASSERT(sizeof(daBsGate_HIO_c) == 0x10); + +static daBsGate_HIO_c l_HIO; + daBsGate_HIO_c::daBsGate_HIO_c() { mOpenSpeed = 2.0f; mCloseSpeed = 12.0f; mShockStrength = 3; } +#if DEBUG +void daBsGate_HIO_c::genMessage(JORMContext* mctx) { + // OPEN speed + mctx->genSlider("OPEN速度", &mOpenSpeed, 0.1f, 100.0f); + // CLOSE speed + mctx->genSlider("CLOSE速度", &mCloseSpeed, 0.1f, 100.0f); + + /* Vibration */ + /* Vibration */ + mctx->startComboBox("振動", &mShockStrength); + // Strength 1 + mctx->genComboBoxItem("強さ1", VIBMODE_S_POWER1); + // Strength 2 + mctx->genComboBoxItem("強さ2", VIBMODE_S_POWER2); + // Strength 3 + mctx->genComboBoxItem("強さ3", VIBMODE_S_POWER3); + // Strength 4 + mctx->genComboBoxItem("強さ4", VIBMODE_S_POWER4); + // Strength 5 + mctx->genComboBoxItem("強さ5", VIBMODE_S_POWER5); + // Strength 6 + mctx->genComboBoxItem("強さ6", VIBMODE_S_POWER6); + // Strength 7 + mctx->genComboBoxItem("強さ7", VIBMODE_S_POWER7); + // Strength 8 + mctx->genComboBoxItem("強さ8", VIBMODE_S_POWER8); + mctx->endComboBox(); +} +#endif + void daBsGate_c::setBaseMtx() { mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z); mDoMtx_stack_c::ZXYrotM(shape_angle.x, shape_angle.y, shape_angle.z); @@ -24,8 +70,11 @@ void daBsGate_c::setBaseMtx() { } int daBsGate_c::CreateHeap() { - J3DModelData* model_data = (J3DModelData*)dComIfG_getObjectRes("S_Zgate", 4); - mpModel = mDoExt_J3DModel__create(model_data, 0x80000, 0x11000084); + J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes("S_Zgate", 4); + + JUT_ASSERT(178, modelData != NULL); + + mpModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084); if (mpModel == NULL) { return 0; } @@ -42,10 +91,14 @@ cPhs_Step daBsGate_c::create() { fopAcM_SetMtx(this, mpModel->getBaseTRMtx()); fopAcM_setCullSizeBox2(this, mpModel->getModelData()); mOpen = fopAcM_isSwitch(this, fopAcM_GetParam(this) & 0xff); - mSide = (fopAcM_GetParam(this) >> 8) & 0xff; + mSide = (fopAcM_GetParam(this) & 0xFF00) >> 8; mTargetDist = -250.0f; if (mSide == 1) { + #if DEBUG + shape_angle.y += static_cast(0x8000); + #else shape_angle.y += 0x8000; + #endif } mOpenDist = 0.0f; if (mOpen) { @@ -53,6 +106,10 @@ cPhs_Step daBsGate_c::create() { } init_modeWait(); setBaseMtx(); + + #if DEBUG + l_HIO.entryHIO("ぶら下がりスイッチゲート"); // "Hanging Switch Gate" / "Pull-Down Switch Gate" + #endif } return step; } @@ -64,11 +121,9 @@ int daBsGate_c::Execute(Mtx** i_mtxP) { return 1; } -static daBsGate_HIO_c l_HIO; - void daBsGate_c::moveGate() { typedef void (daBsGate_c::*daBsGate_modeFunc)(); - static daBsGate_modeFunc mode_proc[3] = { + static const daBsGate_modeFunc mode_proc[3] = { &daBsGate_c::modeWait, &daBsGate_c::modeOpen, &daBsGate_c::modeClose, @@ -102,7 +157,9 @@ void daBsGate_c::modeOpen() { mDoAud_seStartLevel(Z2SE_OBJ_SW_W_DR_OP, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); } - if (cLib_addCalc(&mOpenDist, mTargetDist, 0.2f, l_HIO.mOpenSpeed, 0.5f) == 0.0f) { + + const f32 distanceToOpenPosition = cLib_addCalc(&mOpenDist, mTargetDist, 0.2f, l_HIO.mOpenSpeed, 0.5f); + if (distanceToOpenPosition == 0.0f) { if (mSide == 0) { mDoAud_seStart(Z2SE_OBJ_SW_W_DR_OP_STOP, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); @@ -121,7 +178,9 @@ void daBsGate_c::modeClose() { mDoAud_seStartLevel(Z2SE_OBJ_SW_W_DR_CL, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); } - if (cLib_addCalc(&mOpenDist, 0.0f, 0.4f, l_HIO.mCloseSpeed, 0.5f) == 0.0f) { + + const f32 distanceToClosedPosition = cLib_addCalc(&mOpenDist, 0.0f, 0.4f, l_HIO.mCloseSpeed, 0.5f); + if (distanceToClosedPosition == 0.0f) { if (mSide == 0) { mDoAud_seStart(Z2SE_OBJ_SW_W_DR_CL_STOP, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); @@ -142,6 +201,11 @@ int daBsGate_c::Draw() { int daBsGate_c::Delete() { dComIfG_resDelete(&mPhaseReq, "S_Zgate"); + + #if DEBUG + l_HIO.removeHIO(); + #endif + return 1; } @@ -155,6 +219,7 @@ static int daBsGate_Execute(daBsGate_c* i_this) { } static int daBsGate_Delete(daBsGate_c* i_this) { + fopAcM_RegisterDeleteID(i_this, "daBsGate"); return i_this->MoveBGDelete(); } diff --git a/src/d/actor/d_a_obj_lv3Candle.cpp b/src/d/actor/d_a_obj_lv3Candle.cpp index 079c2e5adc..708ac0045b 100644 --- a/src/d/actor/d_a_obj_lv3Candle.cpp +++ b/src/d/actor/d_a_obj_lv3Candle.cpp @@ -8,13 +8,32 @@ #include "d/actor/d_a_obj_lv3Candle.h" #include "d/d_com_inf_game.h" +#include "d/d_s_play.h" +#include "d/d_cc_uty.h" + +class daLv3Candle_HIO_c : public mDoHIO_entry_c { +public: + daLv3Candle_HIO_c(); + virtual ~daLv3Candle_HIO_c() {} + + void genMessage(JORMContext*); + + /* 0x00 vtable */ + /* 0x04 */ u8 mTimer; // Written to, but never read +}; static daLv3Candle_HIO_c l_HIO; daLv3Candle_HIO_c::daLv3Candle_HIO_c() { - field_0x04 = 0x1e; + mTimer = 0x1e; } +#if DEBUG +void daLv3Candle_HIO_c::genMessage(JORMContext* mctx) { + mctx->genSlider("timer", &mTimer, 0, 0xFF); +} +#endif + dCcD_SrcGObjInf const daLv3Candle_c::mCcDObjInfo = { {0, {{0x200, 0, 0x13}, {0xd8fbfdff, 0x1f}, {0x79}}}, {1, 0, 0, 0, 0}, @@ -36,9 +55,12 @@ void daLv3Candle_c::setBaseMtx() { static u32 const l_bmdIdx[] = {0x03, 0x03}; int daLv3Candle_c::CreateHeap() { - J3DModelData* model_data = + J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(l_resNameIdx[mType], l_bmdIdx[mType]); - mpModel = mDoExt_J3DModel__create(model_data, 0x80000, 0x11000084); + + JUT_ASSERT(226, modelData != NULL); + + mpModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084); if (mpModel == NULL) { return FALSE; @@ -95,7 +117,8 @@ cPhs_Step daLv3Candle_c::create() { } int daLv3Candle_c::createHeapCallBack(fopAc_ac_c* i_this) { - return static_cast(i_this)->CreateHeap(); + daLv3Candle_c* actor = static_cast(i_this); + return actor->CreateHeap(); } void daLv3Candle_c::lightInit() { @@ -116,14 +139,14 @@ void daLv3Candle_c::lightInit() { } void daLv3Candle_c::pointLightProc() { - if (!mIsLit) { - GXColor color = {188, 102, 66, 255}; - cLib_addCalc(&mIntensity, 1.0f, 0.5f, 0.1f, 0.0001f); + if (mIsLit) + return; - if (mIntensity >= 0.000001f) { - dKy_BossLight_set(&mLightPos, &color, mIntensity, 0); - } - } + GXColor color = {188, 102, 66, 255}; + cLib_addCalc(&mIntensity, 1.0f, 0.5f, 0.1f, 0.0001f); + + if (mIntensity >= 0.000001f) + dKy_BossLight_set(&mLightPos, &color, mIntensity, 0); } int daLv3Candle_c::Execute() { @@ -137,8 +160,8 @@ int daLv3Candle_c::Execute() { if (mSph.ChkTgHit()) { cCcD_Obj* obj = mSph.GetTgHitObj(); if (obj != NULL) { - bool play_sound = true; - fopAc_ac_c* actor = obj->GetAc(); + u8 play_sound = true; + fopAc_ac_c* actor = dCc_GetAc(obj->GetAc()); if (fopAcM_GetName(actor) == PROC_ALINK) { dCcD_GObjInf* gobj = mSph.GetTgHitGObj(); if (gobj->GetAtType() & AT_TYPE_NORMAL_SWORD && mTgHit != 0) { @@ -160,11 +183,11 @@ int daLv3Candle_c::Execute() { cXyz pos = current.pos; if (mType == 0) { - mSph.SetR(90.0f); - pos.z += 70.0f; + mSph.SetR(90.0f + oREG_F(0)); + pos.z += 70.0f + oREG_F(1); } else { - mSph.SetR(60.0f); - pos.y -= 200.0f; + mSph.SetR(60.0f + oREG_F(3)); + pos.y -= 200.0f + oREG_F(2); } mSph.SetC(pos); @@ -205,11 +228,14 @@ static int daLv3Candle_Execute(daLv3Candle_c* i_this) { } static int daLv3Candle_Delete(daLv3Candle_c* i_this) { + fopAcM_RegisterDeleteID(i_this, "daLv3Candle"); return static_cast(i_this)->Delete(); } static int daLv3Candle_Create(fopAc_ac_c* i_this) { - return static_cast(i_this)->create(); + daLv3Candle_c* const actor = static_cast(i_this); + fopAcM_RegisterCreateID(i_this, "daLv3Candle"); + return actor->create(); } static actor_method_class l_daLv3Candle_Method = { diff --git a/src/d/actor/d_a_obj_lv3Water.cpp b/src/d/actor/d_a_obj_lv3Water.cpp index 02b5941151..704f35dcf5 100644 --- a/src/d/actor/d_a_obj_lv3Water.cpp +++ b/src/d/actor/d_a_obj_lv3Water.cpp @@ -10,8 +10,15 @@ #include "d/d_bg_w.h" #include "d/d_com_inf_game.h" #include "d/d_procname.h" +#include "f_op/f_op_actor_mng.h" #include "f_op/f_op_msg_mng.h" +#if DEBUG +#include "f_ap/f_ap_game.h" +#include "m_Do/m_Do_graphic.h" +#include "CaptureScreen.h" +#endif + class daLv3Water_HIO_c : public mDoHIO_entry_c { public: daLv3Water_HIO_c(); @@ -20,26 +27,21 @@ public: void genMessage(JORMContext*); /* 0x00 */ /* vtable */ - /* 0x04 */ u8 field_0x04; -}; - -static daLv3Water_HIO_c l_HIO; - -static char* l_resNameIdx[] = { - "Kr10water", "Kr10wat01", "Kr02wat00", "Kr03wat00", "Kr03wat01", "Kr03wat02", "Kr03wat03", - "Kr03wat04", "Kr07wat00", "Kr08wat00", "Kr08wat01", "Kr02wat01", "Kr02wat02", "Kr02wat03", - "Kr11wat00", "Kr12wat00", "Kr13wat00", "Kr13wat01", "Kr13wat02", "Kr03wat05", "Kr03wat06", -}; - -static daLv3Water_c::modeFunc l_mode_func[] = { - &daLv3Water_c::mode_proc_wait, - &daLv3Water_c::mode_proc_levelCtrl, + /* 0x04 */ u8 mLevelControlWaitFrames; }; daLv3Water_HIO_c::daLv3Water_HIO_c() { - field_0x04 = NULL; + mLevelControlWaitFrames = NULL; } +#if DEBUG +void daLv3Water_HIO_c::genMessage(JORMContext* mctx) { + mctx->genSlider("wait time", &mLevelControlWaitFrames, 0, 0xFF); +} +#endif + +static daLv3Water_HIO_c l_HIO; + void daLv3Water_c::setBaseMtx() { if (mpModel2 != NULL) { mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z); @@ -76,23 +78,33 @@ static const int l_btkIdrIdx[] = { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -1, -1, }; +static char* l_resNameIdx[] = { + "Kr10water", "Kr10wat01", "Kr02wat00", "Kr03wat00", "Kr03wat01", "Kr03wat02", "Kr03wat03", + "Kr03wat04", "Kr07wat00", "Kr08wat00", "Kr08wat01", "Kr02wat01", "Kr02wat02", "Kr02wat03", + "Kr11wat00", "Kr12wat00", "Kr13wat00", "Kr13wat01", "Kr13wat02", "Kr03wat05", "Kr03wat06", +}; + int daLv3Water_c::CreateHeap() { J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(l_resNameIdx[mType], l_bmdIdx[mType]); + JUT_ASSERT(384, modelData != NULL); + mpModel1 = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000284); if (mpModel1 == NULL) { return 0; } - J3DAnmTextureSRTKey* btk = - (J3DAnmTextureSRTKey*)dComIfG_getObjectRes(l_resNameIdx[mType], l_btkIdx[mType]); - mBtk1.init(modelData, btk, TRUE, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1); + int res = mBtk1.init(modelData, (J3DAnmTextureSRTKey*)dComIfG_getObjectRes(l_resNameIdx[mType], l_btkIdx[mType]), + TRUE, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1); + + JUT_ASSERT(400, res == 1); if (l_bmdIdrIdx[mType] != -1) { - J3DModelData* modelData = - (J3DModelData*)dComIfG_getObjectRes(l_resNameIdx[mType], l_bmdIdrIdx[mType]); + modelData = (J3DModelData*)dComIfG_getObjectRes(l_resNameIdx[mType], l_bmdIdrIdx[mType]); + + JUT_ASSERT(404, modelData != NULL); mpModel2 = mDoExt_J3DModel__create(modelData, 0x80000, 0x19000284); @@ -100,9 +112,8 @@ int daLv3Water_c::CreateHeap() { return 0; } - J3DAnmTextureSRTKey* btk = - (J3DAnmTextureSRTKey*)dComIfG_getObjectRes(l_resNameIdx[mType], l_btkIdrIdx[mType]); - mBtk2.init(modelData, btk, TRUE, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1); + res = mBtk2.init(modelData, (J3DAnmTextureSRTKey*)dComIfG_getObjectRes(l_resNameIdx[mType], l_btkIdrIdx[mType]), + TRUE, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1); } else { mpModel2 = NULL; } @@ -110,35 +121,31 @@ int daLv3Water_c::CreateHeap() { return 1; } -static u16 const estimateSizeTbl[] = { - 0x1CE0, - 0x4F90, - 0x1C80, - 0x1C30, - 0x1C30, - 0x1C30, - 0x1C30, - 0x8000, - 0x27D0, - 0x2490, - 0x1E60, - 0x1C80, - 0x1C80, - 0x1C80, - 0x4F90, - 0x2880, - 0x29D0, - 0x2B00, - 0x2040, - 0x1360, - 0x1360, - /* padding */ - 0x0000, - 0x0000, - 0x0000, -}; - int daLv3Water_c::create() { + static u16 const estimateSizeTbl[] = { + 0x1CE0, + 0x4F90, + 0x1C80, + 0x1C30, + 0x1C30, + 0x1C30, + 0x1C30, + 0x8000, + 0x27D0, + 0x2490, + 0x1E60, + 0x1C80, + 0x1C80, + 0x1C80, + 0x4F90, + 0x2880, + 0x29D0, + 0x2B00, + 0x2040, + 0x1360, + 0x1360, + }; + fopAcM_ct(this, daLv3Water_c); mType = getParamType(); @@ -146,37 +153,49 @@ int daLv3Water_c::create() { int phase = dComIfG_resLoad(&mPhase, l_resNameIdx[mType]); if (phase == cPhs_COMPLEATE_e) { - if (MoveBGCreate(l_resNameIdx[mType], l_dzbIdx[mType], NULL, estimateSizeTbl[mType], + u32 heapSize = estimateSizeTbl[mType]; + OS_REPORT("l3water: == type:%d [0x%04x:%s] ==\n", mType, heapSize, l_resNameIdx[mType]); + + if (MoveBGCreate(l_resNameIdx[mType], l_dzbIdx[mType], NULL, heapSize, NULL) == cPhs_ERROR_e) { return cPhs_ERROR_e; } - field_0x5fc = getParam(); - mSwitch1 = dComIfGs_isSwitch(getParamSw(), fopAcM_GetHomeRoomNo(this)); - field_0x605 = 1; + mWaterLv = getParam(12, 12); + mSwInitialState = fopAcM_isSwitch(this, getParam(0, 8)); + mSwStatePostEvent = true; if (mType == 1 || mType == 10 || mType == 15 || mType == 17 || mType == 19 || mType == 20) { - if (mSwitch1 == 0) { + if (!mSwInitialState) { if (mpBgW != NULL) { dComIfG_Bgsp().Release(mpBgW); } - field_0x605 = 0; + mSwStatePostEvent = false; // Water is not raised upon creation, ensure it is drawn accordingly } else if (mType == 1) { - current.pos.y = home.pos.y + field_0x5fc; + current.pos.y = home.pos.y + mWaterLv; } - } else if (mSwitch1 != 0) { - current.pos.y = home.pos.y + field_0x5fc; + } else if (mSwInitialState) { + current.pos.y = home.pos.y + mWaterLv; } fopAcM_SetMtx(this, mpModel1->getBaseTRMtx()); setBaseMtx(); mMode = WAIT; + + #if DEBUG + l_HIO.entryHIO("LV3水面"); // "LV3 water surface" + #endif } return phase; } +static daLv3Water_c::modeFunc l_mode_func[] = { + &daLv3Water_c::mode_proc_wait, + &daLv3Water_c::mode_proc_levelCtrl, +}; + int daLv3Water_c::Execute(Mtx** i_mtx) { mBtk1.play(); @@ -185,7 +204,7 @@ int daLv3Water_c::Execute(Mtx** i_mtx) { } eventUpdate(); - mSwitch2 = dComIfGs_isSwitch(getParamSw(), fopAcM_GetHomeRoomNo(this)); + mSwCurrentState = fopAcM_isSwitch(this, getParam(0, 8)); (this->*l_mode_func[mMode])(); effectSet(); *i_mtx = &mpModel1->getBaseTRMtx(); @@ -205,7 +224,7 @@ void daLv3Water_c::effectSet() { } break; case 9: - if (mSwitch1) { + if (mSwInitialState) { mEmitterIDs[0] = dComIfGp_particle_set(mEmitterIDs[0], 0X8AB4, ¤t.pos, NULL, NULL); mEmitterIDs[1] = @@ -243,7 +262,7 @@ void daLv3Water_c::effectSet() { } break; case 17: - if (mSwitch1) { + if (mSwInitialState) { mEmitterIDs[0] = dComIfGp_particle_set(mEmitterIDs[0], 0X8AC4, ¤t.pos, NULL, NULL); mEmitterIDs[1] = @@ -255,7 +274,7 @@ void daLv3Water_c::effectSet() { } break; case 16: - if (mSwitch1) { + if (mSwInitialState) { mEmitterIDs[0] = dComIfGp_particle_set(mEmitterIDs[0], 0X8AC8, ¤t.pos, NULL, NULL); mEmitterIDs[1] = @@ -269,10 +288,10 @@ void daLv3Water_c::effectSet() { } void daLv3Water_c::mode_proc_wait() { - if (mSwitch1 != mSwitch2) { - int event = getParamEvent(); - if (event != 0xFF) { - orderEvent(event, 0xFF, 1); + // Only change the water level when the pull switch is activated (i.e. its initial state differs from its current state) + if (mSwInitialState != mSwCurrentState) { + if (getParamEvent() != 0xFF) { + orderEvent(getParamEvent(), 0xFF, 1); } else { eventStart(); } @@ -280,40 +299,48 @@ void daLv3Water_c::mode_proc_wait() { } void daLv3Water_c::mode_init_levelCtrl() { - field_0x600 = 0; - field_0x604 = l_HIO.field_0x04; + mCurrentWaterLvFrame = 0; + mLvControlWaitFrames = l_HIO.mLevelControlWaitFrames; if (mType == 9) { - fopAcM_seStartCurrent(this, Z2SE_ENV_FILL_UP_LV3WTR3, 0); + mDoAud_seStart(Z2SE_ENV_FILL_UP_LV3WTR3, ¤t.pos, 0, + dComIfGp_getReverb(fopAcM_GetRoomNo(this))); } mMode = LEVEL_CTRL; } void daLv3Water_c::mode_proc_levelCtrl() { - if (field_0x604 != NULL) { - field_0x604 = field_0x604 - 1; - } else { - f32 fVar = fopMsgM_valueIncrease(field_0x601, field_0x600, mSwitch1); + f32 ratioOfWaterLevelFramesAdvancedToTarget; - if (mSwitch1 == 0) { - fVar = 1.0f - fVar; + if (mLvControlWaitFrames != 0) { + mLvControlWaitFrames--; + } else { + ratioOfWaterLevelFramesAdvancedToTarget = fopMsgM_valueIncrease(mWaterLvFrame, mCurrentWaterLvFrame, mSwInitialState); + + if (!mSwInitialState) { + // Water level should lower, invert the ratio so that it goes (1.0f -> 0.0f) + ratioOfWaterLevelFramesAdvancedToTarget = 1.0f - ratioOfWaterLevelFramesAdvancedToTarget; } - field_0x600 = field_0x600 + 1; - if (field_0x600 >= field_0x601) { - fVar = mSwitch1; + mCurrentWaterLvFrame++; + if (mCurrentWaterLvFrame >= mWaterLvFrame) { + ratioOfWaterLevelFramesAdvancedToTarget = mSwInitialState; mMode = WAIT; } - current.pos.y = home.pos.y + field_0x5fc * fVar; + current.pos.y = mWaterLv * ratioOfWaterLevelFramesAdvancedToTarget + home.pos.y; } } int daLv3Water_c::Draw() { - if (field_0x605 == NULL) { + J3DTexMtxInfo* texMtxInfo; + J3DMaterial* material; + J3DModelData* modelData; + + // Only draw if the water is raised + if (!mSwStatePostEvent) return 0; - } g_env_light.settingTevStruct(0x10, ¤t.pos, &tevStr); g_env_light.setLightTevColorType_MAJI(mpModel1, &tevStr); @@ -322,10 +349,12 @@ int daLv3Water_c::Draw() { g_env_light.setLightTevColorType_MAJI(mpModel2, &tevStr); } - mBtk1.entry(mpModel1->getModelData()); + modelData = mpModel1->getModelData(); + mBtk1.entry(modelData); if (mpModel2 != NULL) { - mBtk2.entry(mpModel2->getModelData()); + modelData = mpModel2->getModelData(); + mBtk2.entry(modelData); } dComIfGd_setXluListDarkBG(); @@ -333,20 +362,38 @@ int daLv3Water_c::Draw() { dComIfGd_setList(); if (mpModel2 != NULL) { - J3DModelData* modelData = mpModel2->getModelData(); - J3DMaterial* material = modelData->getMaterialNodePointer(0); + modelData = mpModel2->getModelData(); + material = modelData->getMaterialNodePointer(0); dComIfGd_setListInvisisble(); - J3DTexMtx* texMtx = material->getTexGenBlock()->getTexMtx(0); - if (texMtx != NULL) { - J3DTexMtxInfo* texMtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); + if (material->getTexGenBlock()->getTexMtx(0) != NULL) { + texMtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); if (texMtxInfo != NULL) { Mtx lightProjMtx; C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0.0f); + + #if WIDESCREEN_SUPPORT + mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx); + #endif + + #if DEBUG + if(fapGm_HIO_c::isCaptureScreen()) { + Mtx44 screenCaptureMtx; + MTXCopy(lightProjMtx, screenCaptureMtx); + + screenCaptureMtx[2][3] = -2.0f; + CPerspDivider perspectiveDivider(screenCaptureMtx, fapGm_HIO_c::getCaptureScreenDivH(), fapGm_HIO_c::getCaptureScreenDivV()); + perspectiveDivider.divide(screenCaptureMtx, fapGm_HIO_c::getCaptureScreenNumH(), fapGm_HIO_c::getCaptureScreenNumV()); + screenCaptureMtx[2][3] = 0.0f; + + MTXCopy(screenCaptureMtx, lightProjMtx); + } + #endif + texMtxInfo->setEffectMtx(lightProjMtx); - modelData->simpleCalcMaterial(0, (MtxP)j3dDefaultMtx); + modelData->simpleCalcMaterial((MtxP)j3dDefaultMtx); } } @@ -359,21 +406,26 @@ int daLv3Water_c::Draw() { int daLv3Water_c::Delete() { dComIfG_resDelete(&mPhase, l_resNameIdx[mType]); + + #if DEBUG + l_HIO.removeHIO(); + #endif + return 1; } bool daLv3Water_c::eventStart() { - field_0x601 = fpcM_GetParam(this) >> 0x18; - mSwitch1 = mSwitch2; + mWaterLvFrame = getParam(24, 8); + mSwInitialState = mSwCurrentState; // Ensure the water raise event isn't activated again if (mType == 1 || mType == 10 || mType == 15 || mType == 17 || mType == 19 || mType == 20) { if (mpBgW != NULL) { dComIfG_Bgsp().Regist(mpBgW, this); } if (mType == 1) { - current.pos.y = home.pos.y + field_0x5fc; + current.pos.y = home.pos.y + mWaterLv; } - field_0x605 = mSwitch2; + mSwStatePostEvent = mSwCurrentState; mMode = WAIT; } else { mode_init_levelCtrl(); @@ -383,7 +435,7 @@ bool daLv3Water_c::eventStart() { } static int daLv3Water_Draw(daLv3Water_c* i_this) { - return i_this->Draw(); + return i_this->MoveBGDraw(); } static int daLv3Water_Execute(daLv3Water_c* i_this) { @@ -391,11 +443,14 @@ static int daLv3Water_Execute(daLv3Water_c* i_this) { } static int daLv3Water_Delete(daLv3Water_c* i_this) { + fopAcM_RegisterDeleteID(i_this, "daTreeSh"); //! @note Suggests copy-and-pasting from d_a_obj_treesh return i_this->MoveBGDelete(); } static int daLv3Water_Create(fopAc_ac_c* i_this) { - return static_cast(i_this)->create(); + daLv3Water_c* const actor = static_cast(i_this); + fopAcM_RegisterCreateID(i_this, "daLv3Water"); + return actor->create(); } static actor_method_class l_daLv3Water_Method = { diff --git a/src/d/actor/d_a_obj_lv3Water2.cpp b/src/d/actor/d_a_obj_lv3Water2.cpp index f00fc68485..098b585aa0 100644 --- a/src/d/actor/d_a_obj_lv3Water2.cpp +++ b/src/d/actor/d_a_obj_lv3Water2.cpp @@ -1,12 +1,13 @@ /** * @file d_a_obj_lv3Water2.cpp - * + * */ #include "d/dolzel_rel.h" // IWYU pragma: keep #include "d/actor/d_a_obj_lv3Water2.h" #include "d/d_com_inf_game.h" +#include "f_ap/f_ap_game.h" #include "f_op/f_op_msg_mng.h" #include "m_Do/m_Do_graphic.h" @@ -40,10 +41,249 @@ void daLv3Water2_HIO_c::genMessage(JORMContext* ctx) { static char* l_resNameIdx[] = {"Kr03wat04"}; +void daLv3Water2_c::setBaseMtx() { + mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z); + mDoMtx_stack_c::YrotM(shape_angle.y); + + mpModel->setBaseScale(scale); + mpModel->setBaseTRMtx(mDoMtx_stack_c::get()); +} + +static const int l_bmdIdx[] = {5}; + +static const int l_dzbIdx[] = {13}; + +static const int l_btkIdx[] = {9}; + +int daLv3Water2_c::CreateHeap() { + J3DModelData* modelData = static_cast(dComIfG_getObjectRes(l_resNameIdx[mResIdx], l_bmdIdx[mResIdx])); + JUT_ASSERT(171, modelData != NULL); + mpModel = mDoExt_J3DModel__create(modelData, (1 << 19), 0x19000284); + if(!mpModel) + return 0; + + int res = mRefractionAnm.init(modelData, static_cast(dComIfG_getObjectRes(l_resNameIdx[mResIdx], l_btkIdx[mResIdx])), 1, 2, 1.0f, 0, -1); + JUT_ASSERT(188, res == 1); + + return 1; +} + +cPhs_Step daLv3Water2_c::create() { + fopAcM_ct(this, daLv3Water2_c); + mResIdx = getParam(0, 4); + + cPhs_Step resPhase = static_cast(dComIfG_resLoad(&mPhase, l_resNameIdx[mResIdx])); + if(resPhase == cPhs_COMPLEATE_e) { + if(MoveBGCreate(l_resNameIdx[mResIdx], l_dzbIdx[mResIdx], NULL, 0x2D00, NULL) == cPhs_ERROR_e) + return cPhs_ERROR_e; + + mEastSwInitialState = fopAcM_isSwitch(this, getParamSw1()); + mWestSwInitialState = fopAcM_isSwitch(this, getParamSw2()); + + setBaseMtx(); + fopAcM_SetMtx(this, mpModel->getBaseTRMtx()); + + if(mEastSwInitialState) + current.pos.y = home.pos.y + getParamLevel1() * 5.0f; + + if(mWestSwInitialState) + current.pos.y = home.pos.y + getParamLevel1() * 5.0f + getParamLevel1() * 5.0f; + + mMode = WAIT; + + // "LV3 Water surface (2SW)" + #if DEBUG + l_HIO.entryHIO("LV3水面(2SW)"); + #endif + } + + return resPhase; +} + static actionFunc l_mode_func[] = { - &daLv3Water2_c::mode_proc_wait, &daLv3Water2_c::mode_proc_levelCtrl + &daLv3Water2_c::mode_proc_wait, &daLv3Water2_c::mode_proc_levelCtrl }; +int daLv3Water2_c::Execute(Mtx** i_mtx) { + mRefractionAnm.play(); + + eventUpdate(); + + mEastSwCurrentState = fopAcM_isSwitch(this, getParamSw1()); + mWestSwCurrentState = fopAcM_isSwitch(this, getParamSw2()); + + (this->*l_mode_func[mMode])(); + + if(fopAcM_isSwitch(this, 0xE)) { + mEastParticles[0] = dComIfGp_particle_set(mEastParticles[0], 0x8AAC, ¤t.pos, NULL, NULL); + mEastParticles[1] = dComIfGp_particle_set(mEastParticles[1], 0x8AAD, ¤t.pos, NULL, NULL); + mEastParticles[2] = dComIfGp_particle_set(mEastParticles[2], 0x8AAE, ¤t.pos, NULL, NULL); + mEastParticles[3] = dComIfGp_particle_set(mEastParticles[3], 0x8AAF, ¤t.pos, NULL, NULL); + } + + if(fopAcM_isSwitch(this, 0xF)) { + mWestParticles[0] = dComIfGp_particle_set(mWestParticles[0], 0x8AA8, ¤t.pos, NULL, NULL); + mWestParticles[1] = dComIfGp_particle_set(mWestParticles[1], 0x8AA9, ¤t.pos, NULL, NULL); + mWestParticles[2] = dComIfGp_particle_set(mWestParticles[2], 0x8AAA, ¤t.pos, NULL, NULL); + mWestParticles[3] = dComIfGp_particle_set(mWestParticles[3], 0x8AAB, ¤t.pos, NULL, NULL); + } + + *i_mtx = &mpModel->getBaseTRMtx(); + setBaseMtx(); + + return 1; +} + +void daLv3Water2_c::mode_proc_wait() { + if(mEastSwInitialState != mEastSwCurrentState) { + if(getParamEvent() != 0xFF) + orderEvent(getParamEvent(), 0xFF, 1); + else + eventStart(); + } + else if(mWestSwInitialState != mWestSwCurrentState) { + if(getParamEvent2() != 0xFF) + orderEvent(getParamEvent2(), 0xFF, 1); + else + eventStart(); + } +} + +void daLv3Water2_c::mode_init_levelCtrl() { + mCurrentWaterLvFrame = 0; + mLvControlWaitFrames = l_HIO.mLevelControlWaitFrames; + mBaseYPos = current.pos.y; + mMode = LEVEL_CTRL; +} + +void daLv3Water2_c::mode_proc_levelCtrl() { + if(mLvControlWaitFrames) { + mLvControlWaitFrames--; + return; + } + + f32 ratioOfWaterLevelFramesAdvancedToTarget = fopMsgM_valueIncrease(mWaterLvFrame, mCurrentWaterLvFrame, mEvActivatorSwState); + + if(!mEastSwInitialState) { + // Water level should lower, invert the ratio so that it goes (1.0f -> 0.0f) + ratioOfWaterLevelFramesAdvancedToTarget = 1.0f - ratioOfWaterLevelFramesAdvancedToTarget; + } + + mCurrentWaterLvFrame++; + + if(mCurrentWaterLvFrame >= mWaterLvFrame) { + ratioOfWaterLevelFramesAdvancedToTarget = mEvActivatorSwState; + mMode = WAIT; + } + + current.pos.y = mWaterLv * ratioOfWaterLevelFramesAdvancedToTarget + mBaseYPos; +} + +int daLv3Water2_c::Draw() { + J3DTexMtxInfo* texMtxInfo; + J3DModelData* modelData; + J3DMaterial* btkMaterial; + + g_env_light.settingTevStruct(16, ¤t.pos, &tevStr); + g_env_light.setLightTevColorType_MAJI(mpModel, &tevStr); + + modelData = mpModel->getModelData(); + mRefractionAnm.entry(modelData); + btkMaterial = modelData->getMaterialNodePointer(0); + + dComIfGd_setListInvisisble(); + + if(btkMaterial->getTexGenBlock()->getTexMtx(0)) { + texMtxInfo = &btkMaterial->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); + if(texMtxInfo) { + Mtx lightProjMtx; + C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0); + + #if WIDESCREEN_SUPPORT + mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx); + #endif + + #if DEBUG + if(fapGm_HIO_c::isCaptureScreen()) { + Mtx44 screenCaptureMtx; + MTXCopy(lightProjMtx, screenCaptureMtx); + + screenCaptureMtx[2][3] = -2.0f; + CPerspDivider perspectiveDivider(screenCaptureMtx, fapGm_HIO_c::getCaptureScreenDivH(), fapGm_HIO_c::getCaptureScreenDivV()); + perspectiveDivider.divide(screenCaptureMtx, fapGm_HIO_c::getCaptureScreenNumH(), fapGm_HIO_c::getCaptureScreenNumV()); + screenCaptureMtx[2][3] = 0.0f; + + MTXCopy(screenCaptureMtx, lightProjMtx); + } + #endif + + texMtxInfo->setEffectMtx(lightProjMtx); + modelData->simpleCalcMaterial(const_cast(j3dDefaultMtx)); + } + } + + mDoExt_modelUpdateDL(mpModel); + + dComIfGd_setList(); + + return 1; +} + +int daLv3Water2_c::Delete() { + dComIfG_resDelete(&mPhase, l_resNameIdx[mResIdx]); + + #if DEBUG + l_HIO.removeHIO(); + #endif + + return 1; +} + +bool daLv3Water2_c::eventStart() { + // Check which switch initiated the event + if(mEastSwInitialState != mEastSwCurrentState) { + mWaterLv = getParamLevel1() * 5.0f; + mWaterLvFrame = static_cast(getParamFrame1()); + mEvActivatorSwState = mEastSwCurrentState; + mEastSwInitialState = mEastSwCurrentState; + + mDoAud_seStart(Z2SE_ENV_FILL_UP_LV3WTR1, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); + } + else { + mWaterLv = getParamLevel1() * 5.0f; + mWaterLvFrame = static_cast(getParamFrame2()); + mEvActivatorSwState = mWestSwCurrentState; + mWestSwInitialState = mWestSwCurrentState; + + mDoAud_seStart(Z2SE_ENV_FILL_UP_LV3WTR2, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); + } + + OS_REPORT("== mWaterLv %f mWaterLvFrame %d ==\n", mWaterLv, mWaterLvFrame); + + mode_init_levelCtrl(); + + return true; +} + +static int daLv3Water2_Draw(daLv3Water2_c* i_this) { + return i_this->MoveBGDraw(); +} + +static int daLv3Water2_Execute(daLv3Water2_c* i_this) { + return i_this->MoveBGExecute(); +} + +static int daLv3Water2_Delete(daLv3Water2_c* i_this) { + fopAcM_RegisterDeleteID(i_this, "daLv3Water2"); + return i_this->MoveBGDelete(); +} + +static int daLv3Water2_Create(fopAc_ac_c* i_this) { + daLv3Water2_c* const actor = static_cast(i_this); + fopAcM_RegisterCreateID(i_this, "daLv3Water2"); + return actor->create(); +} + static actor_method_class l_daLv3Water2_Method = { (process_method_func)daLv3Water2_Create, (process_method_func)daLv3Water2_Delete, @@ -68,222 +308,3 @@ actor_process_profile_definition g_profile_Obj_Lv3Water2 = { fopAc_ACTOR_e, // mActorType fopAc_CULLBOX_CUSTOM_e, // cullType }; - -void daLv3Water2_c::setBaseMtx() { - mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z); - mDoMtx_stack_c::YrotM(shape_angle.y); - - mpModel->setBaseScale(scale); - mpModel->setBaseTRMtx(mDoMtx_stack_c::get()); -} - -static const int l_bmdIdx[] = {5}; - -static const int l_dzbIdx[] = {13}; - -static const int l_btkIdx[] = {9}; - -int daLv3Water2_c::CreateHeap() { - J3DModelData* modelData = static_cast(dComIfG_getObjectRes(l_resNameIdx[mResourceIndex], l_bmdIdx[mResourceIndex])); - JUT_ASSERT(171, modelData != NULL); - mpModel = mDoExt_J3DModel__create(modelData, (1 << 19), 0x19000284); - if(!mpModel) - return 0; - - int res = mWaterSurfaceRefractionAnm.init(modelData, static_cast(dComIfG_getObjectRes(l_resNameIdx[mResourceIndex], l_btkIdx[mResourceIndex])), 1, 2, 1.0f, 0, -1); - JUT_ASSERT(188, res == 1); - - return 1; -} - -cPhs_Step daLv3Water2_c::create() { - fopAcM_ct(this, daLv3Water2_c); - mResourceIndex = getParam(0, 4); - - cPhs_Step resPhase = static_cast(dComIfG_resLoad(&mPhase, l_resNameIdx[mResourceIndex])); - if(resPhase == cPhs_COMPLEATE_e) { - if(MoveBGCreate(l_resNameIdx[mResourceIndex], l_dzbIdx[mResourceIndex], NULL, 0x2D00, NULL) == cPhs_ERROR_e) - return cPhs_ERROR_e; - - mEastSwInitialStatus = fopAcM_isSwitch(this, getParamSw1()); - mWestSwInitialStatus = fopAcM_isSwitch(this, getParamSw2()); - - setBaseMtx(); - fopAcM_SetMtx(this, mpModel->getBaseTRMtx()); - - if(mEastSwInitialStatus) - current.pos.y = home.pos.y + getParamLevel1() * 5.0f; - - if(mWestSwInitialStatus) - current.pos.y = home.pos.y + getParamLevel1() * 5.0f + getParamLevel1() * 5.0f; - - mMode = WAIT; - - // "LV3 Water surface (2SW)" - #if DEBUG - l_HIO.entryHIO("LV3水面(2SW)"); - #endif - } - - return resPhase; -} - -int daLv3Water2_c::Execute(Mtx** i_mtx) { - mWaterSurfaceRefractionAnm.play(); - - eventUpdate(); - - mEastSwCurrentStatus = fopAcM_isSwitch(this, getParamSw1()); - mWestSwCurrentStatus = fopAcM_isSwitch(this, getParamSw2()); - - (this->*l_mode_func[mMode])(); - - if(fopAcM_isSwitch(this, 0xE)) { - mEastWaterParticles[0] = dComIfGp_particle_set(mEastWaterParticles[0], 0x8AAC, ¤t.pos, NULL, NULL); - mEastWaterParticles[1] = dComIfGp_particle_set(mEastWaterParticles[1], 0x8AAD, ¤t.pos, NULL, NULL); - mEastWaterParticles[2] = dComIfGp_particle_set(mEastWaterParticles[2], 0x8AAE, ¤t.pos, NULL, NULL); - mEastWaterParticles[3] = dComIfGp_particle_set(mEastWaterParticles[3], 0x8AAF, ¤t.pos, NULL, NULL); - } - - if(fopAcM_isSwitch(this, 0xF)) { - mWestWaterParticles[0] = dComIfGp_particle_set(mWestWaterParticles[0], 0x8AA8, ¤t.pos, NULL, NULL); - mWestWaterParticles[1] = dComIfGp_particle_set(mWestWaterParticles[1], 0x8AA9, ¤t.pos, NULL, NULL); - mWestWaterParticles[2] = dComIfGp_particle_set(mWestWaterParticles[2], 0x8AAA, ¤t.pos, NULL, NULL); - mWestWaterParticles[3] = dComIfGp_particle_set(mWestWaterParticles[3], 0x8AAB, ¤t.pos, NULL, NULL); - } - - *i_mtx = &mpModel->getBaseTRMtx(); - setBaseMtx(); - - return 1; -} - -void daLv3Water2_c::mode_proc_wait() { - if(mEastSwInitialStatus != mEastSwCurrentStatus) { - if(getParamEvent() != 0xFF) - orderEvent(getParamEvent(), 0xFF, 1); - else - eventStart(); - } - else if(mWestSwInitialStatus != mWestSwCurrentStatus) { - if(getParamEvent2() != 0xFF) - orderEvent(getParamEvent2(), 0xFF, 1); - else - eventStart(); - } -} - -void daLv3Water2_c::mode_init_levelCtrl() { - mCurrentWaterLvFrame = 0; - mLevelControlWaitFrames = l_HIO.mLevelControlWaitFrames; - mBaseYPos = current.pos.y; - mMode = LEVEL_CTRL; -} - -void daLv3Water2_c::mode_proc_levelCtrl() { - if(mLevelControlWaitFrames) { - mLevelControlWaitFrames--; - } - else { - f32 currentRatio = fopMsgM_valueIncrease(mWaterLvFrame, mCurrentWaterLvFrame, mFullRatio); - - if(!mEastSwInitialStatus) - currentRatio = 1.0f - currentRatio; - - mCurrentWaterLvFrame++; - - if(mCurrentWaterLvFrame >= mWaterLvFrame) { - currentRatio = mFullRatio; - mMode = WAIT; - } - - current.pos.y = mWaterLv * currentRatio + mBaseYPos; - } -} - -int daLv3Water2_c::Draw() { - g_env_light.settingTevStruct(16, ¤t.pos, &tevStr); - g_env_light.setLightTevColorType_MAJI(mpModel, &tevStr); - - J3DModelData* modelData = mpModel->getModelData(); - mWaterSurfaceRefractionAnm.entry(modelData); - J3DMaterial* const btkMaterial = modelData->getMaterialNodePointer(0); - - dComIfGd_setListInvisisble(); - - if(btkMaterial->getTexGenBlock()->getTexMtx(0)) { - J3DTexMtxInfo* texMtxInfo = &btkMaterial->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo(); - if(texMtxInfo) { - Mtx lightProjMtx; - C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0); - - #if WIDESCREEN_SUPPORT - mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx); - /* TODO: Handle screen capture perspective calculations */ - #endif - - texMtxInfo->setEffectMtx(lightProjMtx); - modelData->simpleCalcMaterial(const_cast(j3dDefaultMtx)); - } - } - - mDoExt_modelUpdateDL(mpModel); - - dComIfGd_setList(); - - return 1; -} - -int daLv3Water2_c::Delete() { - dComIfG_resDelete(&mPhase, l_resNameIdx[mResourceIndex]); - - #if DEBUG - l_HIO.removeHIO(); - #endif - - return 1; -} - -bool daLv3Water2_c::eventStart() { - if(mEastSwInitialStatus != mEastSwCurrentStatus) { - mWaterLv = getParamLevel1() * 5.0f; - mWaterLvFrame = static_cast(getParamFrame1()); - mFullRatio = mEastSwCurrentStatus; - mEastSwInitialStatus = mEastSwCurrentStatus; - - mDoAud_seStart(Z2SE_ENV_FILL_UP_LV3WTR1, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); - } - else { - mWaterLv = getParamLevel1() * 5.0f; - mWaterLvFrame = static_cast(getParamFrame2()); - mFullRatio = mWestSwCurrentStatus; - mWestSwInitialStatus = mWestSwCurrentStatus; - - mDoAud_seStart(Z2SE_ENV_FILL_UP_LV3WTR2, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); - } - - OS_REPORT("== mWaterLv %f mWaterLvFrame %d ==\n", mWaterLv, mWaterLvFrame); - - mode_init_levelCtrl(); - - return true; -} - -static int daLv3Water2_Draw(daLv3Water2_c* i_this) { - return i_this->MoveBGDraw(); -} - -static int daLv3Water2_Execute(daLv3Water2_c* i_this) { - return i_this->MoveBGExecute(); -} - -static int daLv3Water2_Delete(daLv3Water2_c* i_this) { - const fpc_ProcID procID = fopAcM_GetID(i_this); - return i_this->MoveBGDelete(); -} - -static int daLv3Water2_Create(fopAc_ac_c* i_this) { - daLv3Water2_c* const lv3Water2 = static_cast(i_this); - const fpc_ProcID procID = fopAcM_GetID(i_this); - return lv3Water2->create(); -} diff --git a/src/d/actor/d_a_obj_lv3WaterB.cpp b/src/d/actor/d_a_obj_lv3WaterB.cpp index 43a3e3d76f..ab842c6748 100644 --- a/src/d/actor/d_a_obj_lv3WaterB.cpp +++ b/src/d/actor/d_a_obj_lv3WaterB.cpp @@ -9,10 +9,15 @@ #include "JSystem/J3DGraphBase/J3DMaterial.h" #include "d/d_bg_w.h" #include "d/d_com_inf_game.h" +#include "d/d_s_play.h" +#include "f_op/f_op_actor.h" +#include "f_op/f_op_actor_mng.h" static int daObj_Lv3waterB_Draw(obj_lv3WaterB_class* i_this) { - g_env_light.settingTevStruct(0x10, &i_this->current.pos, &i_this->tevStr); - g_env_light.setLightTevColorType_MAJI(i_this->mpBWaterModel, &i_this->tevStr); + fopAc_ac_c* const actor = i_this; + + g_env_light.settingTevStruct(0x10, &actor->current.pos, &actor->tevStr); + g_env_light.setLightTevColorType_MAJI(i_this->mpBWaterModel, &actor->tevStr); i_this->mpBWaterBtk->entry(i_this->mpBWaterModel->getModelData()); @@ -24,15 +29,19 @@ static int daObj_Lv3waterB_Draw(obj_lv3WaterB_class* i_this) { Mtx m; C_MTXLightPerspective(m, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.015f, 0.0f); + #if WIDESCREEN_SUPPORT + mDoGph_gInf_c::setWideZoomLightProjection(m); + #endif + tex_mtx_info->setEffectMtx(m); - i_this->mpBWaterModel->getModelData()->simpleCalcMaterial(0, (MtxP)j3dDefaultMtx); + i_this->mpBWaterModel->getModelData()->simpleCalcMaterial((MtxP)j3dDefaultMtx); } } mDoExt_modelUpdateDL(i_this->mpBWaterModel); if (i_this->mpOctHibiModel != NULL) { - g_env_light.setLightTevColorType_MAJI(i_this->mpOctHibiModel, &i_this->tevStr); + g_env_light.setLightTevColorType_MAJI(i_this->mpOctHibiModel, &actor->tevStr); dComIfGd_setListBG(); mDoExt_modelUpdateDL(i_this->mpOctHibiModel); @@ -43,6 +52,8 @@ static int daObj_Lv3waterB_Draw(obj_lv3WaterB_class* i_this) { } static void action(obj_lv3WaterB_class* i_this) { + fopAc_ac_c* const actor = i_this; + switch (i_this->mAction) { case LV3WATERB_ACT_WAIT: break; @@ -55,16 +66,16 @@ static void action(obj_lv3WaterB_class* i_this) { dKy_custom_colset(4, 4, 0.0f); if (i_this->field_0x586 == 0) { - i_this->current.pos.y = (i_this->home.pos.y - 14450.0f) + 160.0f + 4000.0f; + actor->current.pos.y = (actor->home.pos.y - 14450.0f) + AREG_F(17) + 160.0f + 4000.0f + AREG_F(16); i_this->field_0x586 = 1; } - cLib_addCalc2(&i_this->current.pos.y, (i_this->home.pos.y - 14450.0f) + 160.0f, 0.05f, - 10.0f); + cLib_addCalc2(&actor->current.pos.y, (actor->home.pos.y - 14450.0f) + AREG_F(17) + 160.0f, 0.05f, + 10.0f + AREG_F(19)); break; } - mDoMtx_stack_c::transS(i_this->current.pos.x, i_this->current.pos.y, i_this->current.pos.z); + mDoMtx_stack_c::transS(actor->current.pos.x, actor->current.pos.y, actor->current.pos.z); i_this->mpBWaterModel->setBaseTRMtx(mDoMtx_stack_c::get()); MTXCopy(mDoMtx_stack_c::get(), i_this->mpBWaterMtx); @@ -81,6 +92,8 @@ static void action(obj_lv3WaterB_class* i_this) { } static int daObj_Lv3waterB_Execute(obj_lv3WaterB_class* i_this) { + fopAc_ac_c* const actor = i_this; + action(i_this); return 1; } @@ -90,7 +103,9 @@ static int daObj_Lv3waterB_IsDelete(obj_lv3WaterB_class* i_this) { } static int daObj_Lv3waterB_Delete(obj_lv3WaterB_class* i_this) { - fopAcM_GetID(i_this); + fopAc_ac_c* const actor = i_this; + fopAcM_RegisterDeleteID(i_this, "Obj_Lv3waterB"); + dComIfG_resDelete(&i_this->mBWaterPhase, "L3_bwater"); dComIfG_resDelete(&i_this->mOcthibiPhase, "S_octhibi"); @@ -104,53 +119,53 @@ static int daObj_Lv3waterB_Delete(obj_lv3WaterB_class* i_this) { } static int useHeapInit(fopAc_ac_c* i_this) { - obj_lv3WaterB_class* a_this = static_cast(i_this); + obj_lv3WaterB_class* const actor = static_cast(i_this); J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes("L3_bwater", 5); - JUT_ASSERT(0, modelData != NULL); + JUT_ASSERT(308, modelData != NULL); - a_this->mpBWaterModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000284); - if (a_this->mpBWaterModel == NULL) { + actor->mpBWaterModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000284); + if (actor->mpBWaterModel == NULL) { return 0; } - a_this->mpBWaterBtk = new mDoExt_btkAnm(); - if (a_this->mpBWaterBtk == NULL) { + actor->mpBWaterBtk = new mDoExt_btkAnm(); + if (actor->mpBWaterBtk == NULL) { return 0; } - J3DAnmTextureSRTKey* btk = (J3DAnmTextureSRTKey*)dComIfG_getObjectRes("L3_bwater", 8); - if (!a_this->mpBWaterBtk->init(a_this->mpBWaterModel->getModelData(), btk, TRUE, - J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1)) + if (!actor->mpBWaterBtk->init(actor->mpBWaterModel->getModelData(), + (J3DAnmTextureSRTKey*)dComIfG_getObjectRes("L3_bwater", 8), + TRUE, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1)) { return 0; } - a_this->mpBWaterBgW = new dBgW(); - if (a_this->mpBWaterBgW == NULL) { + actor->mpBWaterBgW = new dBgW(); + if (actor->mpBWaterBgW == NULL) { return 0; } - cBgD_t* dzb = (cBgD_t*)dComIfG_getObjectRes("L3_bwater", 11); - if (a_this->mpBWaterBgW->Set(dzb, dBgW::MOVE_BG_e, &a_this->mpBWaterMtx) == true) { + if (actor->mpBWaterBgW->Set((cBgD_t*)dComIfG_getObjectRes("L3_bwater", 11), + dBgW::MOVE_BG_e, &actor->mpBWaterMtx) == true) { return 0; } modelData = (J3DModelData*)dComIfG_getObjectRes("S_octhibi", 4); - JUT_ASSERT(0, modelData != NULL); + JUT_ASSERT(343, modelData != NULL); - a_this->mpOctHibiModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084); - if (a_this->mpOctHibiModel == NULL) { + actor->mpOctHibiModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084); + if (actor->mpOctHibiModel == NULL) { return 0; } - a_this->mpOctHibiBgW = new dBgW(); - if (a_this->mpOctHibiBgW == NULL) { + actor->mpOctHibiBgW = new dBgW(); + if (actor->mpOctHibiBgW == NULL) { return 0; } - dzb = (cBgD_t*)dComIfG_getObjectRes("S_octhibi", 7); - if (a_this->mpOctHibiBgW->Set(dzb, dBgW::MOVE_BG_e, &a_this->mpOctHibiMtx) == true) { + if (actor->mpOctHibiBgW->Set((cBgD_t*) dComIfG_getObjectRes("S_octhibi", 7), + dBgW::MOVE_BG_e, &actor->mpOctHibiMtx) == true) { return 0; } @@ -158,38 +173,38 @@ static int useHeapInit(fopAc_ac_c* i_this) { } static int daObj_Lv3waterB_Create(fopAc_ac_c* i_this) { - obj_lv3WaterB_class* a_this = static_cast(i_this); - fopAcM_ct(a_this, obj_lv3WaterB_class); + obj_lv3WaterB_class* const actor = static_cast(i_this); + fopAcM_ct(actor, obj_lv3WaterB_class); - int phase_state = dComIfG_resLoad(&a_this->mBWaterPhase, "L3_bwater"); - int octhibi_phase_state = dComIfG_resLoad(&a_this->mOcthibiPhase, "S_octhibi"); + int phase_state = dComIfG_resLoad(&actor->mBWaterPhase, "L3_bwater"); + int octhibi_phase_state = dComIfG_resLoad(&actor->mOcthibiPhase, "S_octhibi"); if (phase_state == cPhs_COMPLEATE_e && octhibi_phase_state == cPhs_COMPLEATE_e) { - OS_REPORT("OBJ_LV3WATERB PARAM %x\n", fopAcM_GetParam(a_this)); + OS_REPORT("OBJ_LV3WATERB PARAM %x\n", fopAcM_GetParam(i_this)); OS_REPORT("OBJ_LV3WATERB//////////////OBJ_LV3WATERB SET 1 !!\n"); - if (!fopAcM_entrySolidHeap(a_this, useHeapInit, 0x4B000)) { + if (!fopAcM_entrySolidHeap(i_this, useHeapInit, 0x4B000)) { OS_REPORT("//////////////OBJ_LV3WATERB SET NON !!\n"); return cPhs_ERROR_e; } OS_REPORT("//////////////OBJ_LV3WATERB SET 2 !!\n"); - if (dComIfG_Bgsp().Regist(a_this->mpBWaterBgW, a_this)) { + if (dComIfG_Bgsp().Regist(actor->mpBWaterBgW, actor)) { return cPhs_ERROR_e; } - if (dComIfG_Bgsp().Regist(a_this->mpOctHibiBgW, a_this)) { + if (dComIfG_Bgsp().Regist(actor->mpOctHibiBgW, actor)) { return cPhs_ERROR_e; } if (dComIfGs_isStageBossEnemy()) { - a_this->current.pos.y = (a_this->home.pos.y - 14450.0f) + 160.0f; - a_this->mAction = LV3WATERB_ACT_END; - a_this->field_0x586 = 1; - a_this->mpOctHibiModel = NULL; + i_this->current.pos.y = (i_this->home.pos.y - 14450.0f) + AREG_F(17) + 160.0f; + actor->mAction = LV3WATERB_ACT_END; + actor->field_0x586 = 1; + actor->mpOctHibiModel = NULL; } - daObj_Lv3waterB_Execute(a_this); + daObj_Lv3waterB_Execute(actor); return phase_state; } else if (phase_state == cPhs_COMPLEATE_e) { return octhibi_phase_state; diff --git a/src/d/actor/d_a_obj_lv3saka00.cpp b/src/d/actor/d_a_obj_lv3saka00.cpp index b6e1a5ce70..0a32b9739d 100644 --- a/src/d/actor/d_a_obj_lv3saka00.cpp +++ b/src/d/actor/d_a_obj_lv3saka00.cpp @@ -9,14 +9,44 @@ #include "d/d_bg_w.h" #include "d/d_com_inf_game.h" #include "d/d_procname.h" +#include "m_Do/m_Do_mtx.h" + +static char* l_arcName[] = {"Obj_saka", "Obj_saka2"}; + +#if DEBUG +class daObjLv3saka_HIO_c : public mDoHIO_entry_c { + public: + daObjLv3saka_HIO_c(); + ~daObjLv3saka_HIO_c() {} + + void genMessage(JORMContext*); + + /* 0x08 */ f32 field_0x08; + /* 0x0C */ u8 field_0x0C; +}; + +static daObjLv3saka_HIO_c l_HIO; + +daObjLv3saka_HIO_c::daObjLv3saka_HIO_c() { + field_0x08 = 0.0f; + field_0x0C = 0; +} + +void daObjLv3saka_HIO_c::genMessage(JORMContext* mctx) { + /* Flowing Water Slippery Surface */ + mctx->genLabel("水が流れると滑る", 0); + mctx->genCheckBox("チェック描画", &field_0x0C, 0x1); +} + +#endif void daObjLv3saka_c::initBaseMtx() { setBaseMtx(); } void daObjLv3saka_c::setBaseMtx() { - MTXTrans(mDoMtx_stack_c::now, current.pos.x, current.pos.y, current.pos.z); - mDoMtx_YrotM(mDoMtx_stack_c::get(), shape_angle.y); + mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z); + mDoMtx_stack_c::YrotM(shape_angle.y); MTXCopy(mDoMtx_stack_c::get(), mBgMtx); } @@ -42,8 +72,6 @@ static int const l_dzbIdx[] = {3, 3}; static int const l_dzbIdx2[] = {4, 4}; -static char* l_arcName[] = {"Obj_saka", "Obj_saka2"}; - int daObjLv3saka_c::CreateHeap() { mpBgW2 = new dBgW(); if (mpBgW2 == NULL || @@ -67,6 +95,10 @@ int daObjLv3saka_c::create1st() { if (phase == cPhs_ERROR_e) { return phase; } + + #if DEBUG + l_HIO.entryHIO("水が流れると滑る"); // "Flowing water slippery surface" + #endif } return phase; } @@ -105,6 +137,14 @@ void daObjLv3saka_c::setWtrDzb() { } int daObjLv3saka_c::Draw() { + #if DEBUG + if(l_HIO.field_0x0C) { + if(mpBgW->ChkUsed()) + mpBgW->DebugDraw(); + else if(mpBgW2->ChkUsed()) + mpBgW2->DebugDraw(); + } + #endif return 1; } @@ -113,6 +153,11 @@ int daObjLv3saka_c::Delete() { dComIfG_Bgsp().Release(mpBgW2); } dComIfG_resDelete(&mPhase, l_arcName[getType()]); + + #if DEBUG + l_HIO.removeHIO(); + #endif + return 1; } diff --git a/src/d/actor/d_a_obj_lv3waterEff.cpp b/src/d/actor/d_a_obj_lv3waterEff.cpp index fd8b50a979..28a43141a6 100644 --- a/src/d/actor/d_a_obj_lv3waterEff.cpp +++ b/src/d/actor/d_a_obj_lv3waterEff.cpp @@ -8,6 +8,7 @@ #include "d/actor/d_a_obj_lv3waterEff.h" #include "d/d_com_inf_game.h" #include "d/d_procname.h" +#include "f_op/f_op_actor_mng.h" static u16 const l_eff_id[] = { 0x86D2, @@ -20,6 +21,11 @@ int daObjWaterEff_c::Create() { for (int i = 0; i < 4; i++) { mParticles[i] = dComIfGp_particle_set(l_eff_id[i], ¤t.pos, NULL, NULL, 0xFF, NULL, -1, NULL, NULL, NULL); + + if(mParticles[i] == NULL) { + // "LV3R09 Water flow effect: Effect <%d> could not be set" + OS_REPORT_ERROR("Lv3R09水流エフェクト:エフェクト<%d>セットできませんでした\n"); + } } mSePositions[0].set(14420.0f, -1100.0f, -4950.0f); @@ -76,11 +82,14 @@ static int daObjWaterEff_Execute(daObjWaterEff_c* i_this) { } static int daObjWaterEff_Delete(daObjWaterEff_c* i_this) { + const fpc_ProcID id = fopAcM_GetID(i_this); return i_this->_delete(); } static int daObjWaterEff_Create(fopAc_ac_c* i_this) { - return static_cast(i_this)->create(); + daObjWaterEff_c* const actor = static_cast(i_this); + const fpc_ProcID id = fopAcM_GetID(i_this); + return actor->create(); } static actor_method_class l_daObjWaterEff_Method = { diff --git a/src/d/actor/d_a_obj_syRock.cpp b/src/d/actor/d_a_obj_syRock.cpp index 60d50e393f..4dbcc13b9f 100644 --- a/src/d/actor/d_a_obj_syRock.cpp +++ b/src/d/actor/d_a_obj_syRock.cpp @@ -1,16 +1,16 @@ /** * @file d_a_obj_syRock.cpp - * + * */ #include "d/dolzel_rel.h" // IWYU pragma: keep #include "d/actor/d_a_obj_syRock.h" #include "d/actor/d_a_obj_eff.h" -#include "d/d_bg_w.h" -#include "d/d_com_inf_game.h" #include "f_op/f_op_kankyo_mng.h" -#include "SSystem/SComponent/c_math.h" +#include "d/d_s_play.h" + +typedef void (daSyRock_c::*actionFunc)(); class daSyRock_HIO_c : public mDoHIO_entry_c { public: @@ -19,56 +19,103 @@ public: void genMessage(JORMContext*); - /* 0x04 */ f32 mShakeAmplitude; // "揺れ強さ" "Shake strength" | Slider - /* 0x08 */ f32 mShakeXOscillationAngle; // "振幅X" "Amplitude X" | Slider - /* 0x0C */ f32 mShakeZOscillationAngle; // "振幅Z" "Amplitude Z" | Slider - /* 0x10 */ f32 mShakeDamping; // "揺れ減衰" "Shake damping" | Slider - /* 0x14 */ f32 mShakeMaxDecay; // "最大減衰量" "Maximum decay" | Slider - /* 0x18 */ f32 mShakeMinDecay; // "最小減衰量" "Minimum decay" | Slider - /* 0x1C */ f32 mFallAcceleration; // "落下速度" "Fall speed" | Slider - /* 0x20 */ f32 mMaxFallSpeed; // "最大落下速度" "Maximum falling speed" | Slider - /* 0x24 */ u8 mWaitFrames; // "wait time" | Slider (unused) - /* 0x25 */ u8 mShockStrength; // "振動" "Vibration" | Combo Box - /* "強さ1" "Strength 1" - "強さ2" "Strength 2" - "強さ3" "Strength 3" - "強さ4" "Strength 4" - "強さ5" "Strength 5" - "強さ6" "Strength 6" - "強さ7" "Strength 7" - "強さ8" "Strength 8" */ - /* 0x28 */ f32 mEffectScale; // "eff scale" | Slider - /* 0x2C */ f32 mFallWaterBouyancy; // "sink speed" | Slider - /* 0x30 */ f32 mMaxWaterPillarRange; // "renge" | "Range" | Slider + /* 0x04 */ f32 mShakeAmplitude; + /* 0x08 */ f32 mShakeXOscAngQuantum; + /* 0x0C */ f32 mShakeZOscAngQuantum; + /* 0x10 */ f32 mShakeDampingScale; + /* 0x14 */ f32 mShakeMaxDecay; + /* 0x18 */ f32 mShakeMinDecay; + /* 0x1C */ f32 mFallAcceleration; + /* 0x20 */ f32 mMaxFallSpeed; + /* 0x24 */ u8 mWaitFrames; + /* 0x25 */ u8 mVibModePower; + /* 0x28 */ f32 mEffScale; + /* 0x2C */ f32 mFallWaterBouyancy; + /* 0x30 */ f32 mRange; // Maximum horizontal distance a d_a_obj_waterPillar instance may be from the current syRock instance in order for the two to be associated }; -typedef void (daSyRock_c::*actionFunc)(); - static daSyRock_HIO_c l_HIO; dCcD_SrcCyl daSyRock_c::mCcDCyl = {mCcDObjInfo}; daSyRock_HIO_c::daSyRock_HIO_c() { mShakeAmplitude = 450.0f; - mShakeXOscillationAngle = 90.0f; - mShakeZOscillationAngle = 45.0f; - mShakeDamping = 1.0f / 20.0f; + mShakeXOscAngQuantum = 90.0f; + mShakeZOscAngQuantum = 45.0f; + mShakeDampingScale = 1.0f / 20.0f; mShakeMaxDecay = 5.0f; mShakeMinDecay = 1.0f / 10.0f; mFallAcceleration = 10.0f; mMaxFallSpeed = 200.0f; mWaitFrames = 30; - mEffectScale = 4.0f; - mShockStrength = 4; + mEffScale = 4.0f; + mVibModePower = VIBMODE_S_POWER4; mFallWaterBouyancy = 3.0f; - mMaxWaterPillarRange = 5.0f; + mRange = 5.0f; } +#if DEBUG +void daSyRock_HIO_c::genMessage(JORMContext* mctx) { + /* ==== Falling ==== */ + mctx->genLabel("\n==== 落下 ====", 0); + // Wait time + mctx->genSlider("wait time", &mWaitFrames, 0, 0xFF); + // Fall speed + mctx->genSlider("落下速度", &mFallAcceleration, 0.0f, 100.0f); + // Maximum fall speed + mctx->genSlider("最大落下速度", &mMaxFallSpeed, 0.1f, 500.0f); + // Effect scale + mctx->genSlider("eff scale", &mEffScale, 0.1f, 20.0f); + + /* ==== Shaking ==== */ + mctx->genLabel("\n==== 揺れ ====", 0); + // Shaking intensity + mctx->genSlider("揺れ強さ", &mShakeAmplitude, 0.0f, 10000.0f); + // Z Amplitude + mctx->genSlider("振幅Z", &mShakeZOscAngQuantum, 0.0f, 180.0f); + // X Amplitude + mctx->genSlider("振幅X", &mShakeXOscAngQuantum, 0.0f, 180.0f); + // Shake damping + mctx->genSlider("揺れ減衰", &mShakeDampingScale, 0.0f, 1.0f); + // Maximum damping amount + mctx->genSlider("最大減衰量", &mShakeMaxDecay, 0.0f, 100.0f); + // Minimum damping amount + mctx->genSlider("最小減衰量", &mShakeMinDecay, 0.0f, 100.0f); + + /* Vibration */ + mctx->startComboBox("振動", &mVibModePower); + // Strength 1 + mctx->genComboBoxItem("強さ1", VIBMODE_S_POWER1); + // Strength 2 + mctx->genComboBoxItem("強さ2", VIBMODE_S_POWER2); + // Strength 3 + mctx->genComboBoxItem("強さ3", VIBMODE_S_POWER3); + // Strength 4 + mctx->genComboBoxItem("強さ4", VIBMODE_S_POWER4); + // Strength 5 + mctx->genComboBoxItem("強さ5", VIBMODE_S_POWER5); + // Strength 6 + mctx->genComboBoxItem("強さ6", VIBMODE_S_POWER6); + // Strength 7 + mctx->genComboBoxItem("強さ7", VIBMODE_S_POWER7); + // Strength 8 + mctx->genComboBoxItem("強さ8", VIBMODE_S_POWER8); + mctx->endComboBox(); + + /* ==== For Testing Purposes ==== */ + mctx->genLabel("\n==== テスト用 ====", 0); + // Range + mctx->genSlider("renge", &mRange, 0.1f, 20.0f); + // Sink speed + mctx->genSlider("sink speed", &mFallWaterBouyancy, 0.1f, 20.0f); +} +#endif + void daSyRock_c::setBaseMtx() { mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z); mDoMtx_stack_c::ZXYrotM(0, shape_angle.y, shape_angle.z); - mDoMtx_stack_c::ZXYrotM(mShakeXZAngleOffset.x, mShakeXZAngleOffset.y, mShakeXZAngleOffset.z); - mDoMtx_stack_c::transM(mUnderwaterRotatedStalactiteOffset.x, mUnderwaterRotatedStalactiteOffset.y, mUnderwaterRotatedStalactiteOffset.z); + mDoMtx_stack_c::ZXYrotM(mShakeAngOffset.x, mShakeAngOffset.y, mShakeAngOffset.z); + mDoMtx_stack_c::transM(mUnderwaterOffset.x, mUnderwaterOffset.y, mUnderwaterOffset.z); mpModels[mIsUnbroken]->setBaseScale(scale); @@ -81,7 +128,7 @@ int daSyRock_c::CreateHeap() { J3DModelData* modelData = static_cast(dComIfG_getObjectRes("syourock", 4)); JUT_ASSERT(271, modelData != NULL); mpModels[0] = mDoExt_J3DModel__create(modelData, 1 << 19, 0x11000084); - + if(!mpModels[0]) return 0; @@ -91,7 +138,7 @@ int daSyRock_c::CreateHeap() { if(!mpModels[1]) return 0; - + mpBrokenCollision = new dBgW; if(!mpBrokenCollision || mpBrokenCollision->Set(static_cast(dComIfG_getObjectRes("syourock", 9)), 1, &mBgMtx)) { @@ -112,8 +159,9 @@ dCcD_SrcGObjInf const daSyRock_c::mCcDObjInfo = { cPhs_Step daSyRock_c::create() { fopAcM_ct(this, daSyRock_c); + // Check if an associated water pillar should be searched for if(getArg0() == TRUE) { - mpWaterPillar = static_cast(fopAcIt_Judge(searchWaterPillar, this)); + mpWaterPillar = static_cast(fopAcM_Search(searchWaterPillar, this)); if(!mpWaterPillar) return cPhs_INIT_e; @@ -126,24 +174,39 @@ cPhs_Step daSyRock_c::create() { return cPhs_ERROR_e; mAcchCir.SetWall(150.0f, 150.0f); - mAcch.Set(¤t.pos, &old.pos, this, 0x1, &mAcchCir, &speed, NULL, NULL); + mAcch.Set(fopAcM_GetPosition_p(this), + fopAcM_GetOldPosition_p(this), + this, 0x1, &mAcchCir, + fopAcM_GetSpeed_p(this), + NULL, NULL); mAcch.SetWaterCheckOffset(10000.0f); - mShakeOscillationAngleStep = 0; - mShakeXZAngleOffset.setall(0); - mShakeXOscillationAngle = mShakeZOscillationAngle = mShakeAmplitude = 0.0f; - mShakeMinDecay = mShakeMaxDecay = mShakeDamping = 0.0f; - mUnderwaterRotatedStalactiteOffset.setall(0.0f); + mShakeOscAngStep = 0; + + mShakeAngOffset.x = 0; + mShakeAngOffset.y = 0; + mShakeAngOffset.z = 0; + + mShakeAmplitude = 0.0f; + mShakeZOscAngQuantum = 0.0f; + mShakeXOscAngQuantum = 0.0f; + + mShakeDampingScale = 0.0f; + mShakeMaxDecay = 0.0f; + mShakeMinDecay = 0.0f; + + mUnderwaterOffset.x = 0.0f; + mUnderwaterOffset.y = 0.0f; + mUnderwaterOffset.z = 0.0f; mStts.Init(0xFF, 0xFF, this); - mUnbrokenCylinderCollider.Set(mCcDCyl); - mUnbrokenCylinderCollider.SetStts(&mStts); - mUnbrokenCylinderCollider.OffAtSetBit(); + mUnbrokenCollider.Set(mCcDCyl); + mUnbrokenCollider.SetStts(&mStts); + mUnbrokenCollider.OffAtSetBit(); - const u32 wasBrokenSwitchNo = getSwBit1(); - if(dComIfGs_isSwitch(wasBrokenSwitchNo, fopAcM_GetHomeRoomNo(this))) { + if(fopAcM_isSwitch(this, getSwBit1())) { mIsUnbroken = false; - mUnbrokenCylinderCollider.OffCoSetBit(); + mUnbrokenCollider.OffCoSetBit(); if(mpBrokenCollision && mpBrokenCollision->ChkUsed()) { dComIfG_Bgsp().Release(mpBrokenCollision); mpBrokenCollision->Move(); @@ -157,13 +220,13 @@ cPhs_Step daSyRock_c::create() { if(mpBgW) dComIfG_Bgsp().Release(mpBgW); - + if(mpBrokenCollision) { dComIfG_Bgsp().Regist(mpBrokenCollision, this); mpBrokenCollision->Move(); } - mDropAutomaticallySwitchNo = getSwBit2(); + mAutoDropSwNo = getSwBit2(); init_modeWait(); } @@ -172,23 +235,31 @@ cPhs_Step daSyRock_c::create() { fopAcM_SetMtx(this, mpModels[mIsUnbroken]->getBaseTRMtx()); fopAcM_setCullSizeBox2(this, mpModels[mIsUnbroken]->getModelData()); setBaseMtx(); + + #if DEBUG + l_HIO.entryHIO("鍾乳石"); // "Stalactite" + #endif } return requestedPhaseProcess; } void daSyRock_c::setFallStat() { - mpWaterPillar = static_cast(fopAcIt_Judge(searchWaterPillar, this)); + mpWaterPillar = static_cast(fopAcM_Search(searchWaterPillar, this)); if(mpWaterPillar) { + OS_REPORT("== 下に水柱あり ==\n"); // "== Water pillar below ==" + mpWaterPillar->onRockFlag(); mMode = MODE_MOVE; } else { + OS_REPORT("== 下に水柱無し ==\n"); // "== No water pillar below ==" + mAcch.CrrPos(dComIfG_Bgsp()); if(mAcch.ChkWaterHit()) { if(mAcch.m_wtr.GetHeight() - mAcch.GetGroundH() >= 200.0f) { - mUnderwaterRotatedStalactiteOffset.x = 150.0f; + mUnderwaterOffset.x = 150.0f; shape_angle.z = 0x4000; } current.pos.y = mAcch.GetGroundH(); @@ -208,37 +279,37 @@ int daSyRock_c::Execute(Mtx** i_mtx) { *i_mtx = &mpModels[mIsUnbroken]->getBaseTRMtx(); - mInWaterPreviousFrame = mAcch.ChkWaterIn(); + mInWaterPrevFrame = mAcch.ChkWaterIn() != false; setBaseMtx(); return 1; } void daSyRock_c::move() { - static actionFunc mode_proc[] = { + static const actionFunc mode_proc[] = { &daSyRock_c::modeWait, &daSyRock_c::modeDropInit, &daSyRock_c::modeDrop, &daSyRock_c::modeSink, &daSyRock_c::modeMove, &daSyRock_c::modeDropEnd }; + (this->*mode_proc[mMode])(); - (this->*mode_proc[mMode])(); - mShakeXZAngleOffset.x = mShakeAmplitude * cM_ssin(mShakeOscillationAngleStep * cM_deg2s(mShakeXOscillationAngle)); - mShakeXZAngleOffset.z = mShakeAmplitude * cM_scos(mShakeOscillationAngleStep * cM_deg2s(mShakeZOscillationAngle)); + mShakeAngOffset.x = mShakeAmplitude * cM_ssin(mShakeOscAngStep * cM_deg2s(mShakeXOscAngQuantum)); + mShakeAngOffset.z = mShakeAmplitude * cM_scos(mShakeOscAngStep * cM_deg2s(mShakeZOscAngQuantum)); - cLib_addCalc(&mShakeAmplitude, 0.0f, mShakeDamping, mShakeMaxDecay, mShakeMinDecay); + cLib_addCalc(&mShakeAmplitude, 0.0f, mShakeDampingScale, mShakeMaxDecay, mShakeMinDecay); - mShakeOscillationAngleStep++; + mShakeOscAngStep++; - mUnbrokenCylinderCollider.SetR(150.0f); - mUnbrokenCylinderCollider.SetH(680.0f); + mUnbrokenCollider.SetR(150.0f + oREG_F(0)); + mUnbrokenCollider.SetH(680.0f + oREG_F(1)); cXyz currentPos = current.pos; - currentPos.y -= 250.0f; + currentPos.y -= 250.0f + oREG_F(2); - mUnbrokenCylinderCollider.SetC(currentPos); + mUnbrokenCollider.SetC(currentPos); - dComIfG_Ccsp()->Set(&mUnbrokenCylinderCollider); + dComIfG_Ccsp()->Set(&mUnbrokenCollider); } void daSyRock_c::init_modeWait() { @@ -246,16 +317,19 @@ void daSyRock_c::init_modeWait() { } void daSyRock_c::modeWait() { - if(mDropAutomaticallySwitchNo != 0xFF && dComIfGs_isSwitch(mDropAutomaticallySwitchNo, fopAcM_GetHomeRoomNo(this))) { + if(mAutoDropSwNo != 0xFF && fopAcM_isSwitch(this, mAutoDropSwNo)) { field_0x779 = 0; - if(getEvetID() != 0xFF){ + if(getEvetID() != 0xFF) { orderEvent(getEvetID(), 0xFF, 1); } else { eventStart(); } + return; } - else if(mUnbrokenCylinderCollider.ChkTgHit()) { - if(mUnbrokenCylinderCollider.GetTgHitGObj()->GetAtType() == AT_TYPE_BOMB) { + + if(mUnbrokenCollider.ChkTgHit()) { + dCcD_GObjInf* tgHitGObj = mUnbrokenCollider.GetTgHitGObj(); + if(tgHitGObj->GetAtType() == AT_TYPE_BOMB) { field_0x779 = 0; if(getEvetID() != 0xFF) orderEvent(getEvetID(), 0xFF, 1); @@ -263,7 +337,7 @@ void daSyRock_c::modeWait() { eventStart(); } } - mUnbrokenCylinderCollider.ClrTgHit(); + mUnbrokenCollider.ClrTgHit(); } } @@ -276,14 +350,15 @@ bool daSyRock_c::eventStart() { } void daSyRock_c::init_modeDropInit() { - fopAcM_seStartCurrent(this, Z2SE_OBJ_STALAC_BREAK, 0); + mDoAud_seStart(Z2SE_OBJ_STALAC_BREAK, ¤t.pos, 0, + dComIfGp_getReverb(fopAcM_GetRoomNo(this))); - mUnbrokenCylinderCollider.OffCoSetBit(); - mUnbrokenCylinderCollider.OffTgSetBit(); + mUnbrokenCollider.OffCoSetBit(); + mUnbrokenCollider.OffTgSetBit(); mWaitFrames = 0; - mpWaterPillar = static_cast(fopAcIt_Judge(searchWaterPillar, this)); + mpWaterPillar = static_cast(fopAcM_Search(searchWaterPillar, this)); mMode = MODE_DROP_INIT; } @@ -300,10 +375,10 @@ void* daSyRock_c::searchWaterPillar(void* i_proc, void* i_this) { daWtPillar_c* const wtPillar = static_cast(i_proc); if(wtPillar && fopAcM_IsActor(wtPillar) && fopAcM_GetProfName(wtPillar) == PROC_Obj_WaterPillar) { - const cXyz vectorToWaterPillar = fopAcM_GetPosition(syRock) - fopAcM_GetPosition(wtPillar); - const f32 horizontalDistanceToWaterPillar = sqrtf(vectorToWaterPillar.getMagXZ()); - - if(horizontalDistanceToWaterPillar <= l_HIO.mMaxWaterPillarRange) + const cXyz vectorFromWaterPillar = syRock->current.pos - wtPillar->current.pos; + const f32 horizontalDistanceToWaterPillar = vectorFromWaterPillar.absXZ(); + + if(horizontalDistanceToWaterPillar <= l_HIO.mRange) return wtPillar; else return NULL; @@ -312,9 +387,9 @@ void* daSyRock_c::searchWaterPillar(void* i_proc, void* i_this) { } void daSyRock_c::init_modeDrop() { - gravity = -l_HIO.mFallAcceleration; - maxFallSpeed = -l_HIO.mMaxFallSpeed; - speedF = 0.0f; + fopAcM_SetGravity(this, -l_HIO.mFallAcceleration); + fopAcM_SetMaxFallSpeed(this, -l_HIO.mMaxFallSpeed); + fopAcM_SetSpeedF(this, 0.0f); if(mpBrokenCollision) { dComIfG_Bgsp().Release(mpBrokenCollision); @@ -327,7 +402,7 @@ void daSyRock_c::init_modeDrop() { const cXyz particlePos = current.pos; dComIfGp_particle_set(0x8616, &particlePos, NULL, NULL); - mUnbrokenCylinderCollider.OnAtSetBit(); + mUnbrokenCollider.OnAtSetBit(); mMode = MODE_DROP; } @@ -338,11 +413,11 @@ void daSyRock_c::modeDrop() { } void daSyRock_c::init_modeSink() { - gravity = -l_HIO.mFallAcceleration + l_HIO.mFallWaterBouyancy; - speed.y = cLib_minMaxLimit(speed.y, -15.0f, 13.0f); + fopAcM_SetGravity(this, -l_HIO.mFallAcceleration + l_HIO.mFallWaterBouyancy); + speed.y = cLib_minMaxLimit(speed.y, -15.0f - oREG_F(7), 13.0f + oREG_F(8)); if(!mpWaterPillar) - mUnderwaterRotatedStalactiteOffset.x = 150.0f; + mUnderwaterOffset.x = 150.0f; mMode = MODE_SINK; } @@ -351,7 +426,7 @@ void daSyRock_c::modeSink() { if(!mpWaterPillar) cLib_addCalcAngleS(&shape_angle.z, 0x4000, 1, 0x444, 1); - speed.y = cLib_minMaxLimit(speed.y, -15.0f, 13.0f); + speed.y = cLib_minMaxLimit(speed.y, -15.0f - oREG_F(7), 13.0f + oREG_F(8)); fopAcM_posMoveF(this, mStts.GetCCMoveP()); mAcch.CrrPos(dComIfG_Bgsp()); @@ -360,7 +435,8 @@ void daSyRock_c::modeSink() { } void daSyRock_c::init_modeMove() { - fopAcM_seStartCurrent(this, Z2SE_OBJ_STALAC_LAND_WATER, 0); + mDoAud_seStart(Z2SE_OBJ_STALAC_LAND_WATER, ¤t.pos, 0, + dComIfGp_getReverb(fopAcM_GetRoomNo(this))); if(mpBgW) dComIfG_Bgsp().Regist(mpBgW, this); @@ -368,16 +444,15 @@ void daSyRock_c::init_modeMove() { mpWaterPillar->onRockFlag(); mShakeAmplitude = l_HIO.mShakeAmplitude; - mShakeZOscillationAngle = l_HIO.mShakeZOscillationAngle; - mShakeXOscillationAngle = l_HIO.mShakeXOscillationAngle; - mShakeDamping = l_HIO.mShakeDamping; + mShakeZOscAngQuantum = l_HIO.mShakeZOscAngQuantum; + mShakeXOscAngQuantum = l_HIO.mShakeXOscAngQuantum; + mShakeDampingScale = l_HIO.mShakeDampingScale; mShakeMaxDecay = l_HIO.mShakeMaxDecay; mShakeMinDecay = l_HIO.mShakeMinDecay; - mUnbrokenCylinderCollider.OffAtSetBit(); + mUnbrokenCollider.OffAtSetBit(); - const u32 swBit = getSwBit1(); - dComIfGs_onSwitch(swBit, fopAcM_GetHomeRoomNo(this)); + fopAcM_onSwitch(this, getSwBit1()); mMode = MODE_MOVE; } @@ -387,12 +462,12 @@ void daSyRock_c::modeMove() { current.pos = mpWaterPillar->getPos(); current.pos.y -= 50.0f; - + if(mpWaterPillar->isRockYure()) { mShakeAmplitude = l_HIO.mShakeAmplitude; - mShakeZOscillationAngle = l_HIO.mShakeZOscillationAngle; - mShakeXOscillationAngle = l_HIO.mShakeXOscillationAngle; - mShakeDamping = l_HIO.mShakeDamping; + mShakeZOscAngQuantum = l_HIO.mShakeZOscAngQuantum; + mShakeXOscAngQuantum = l_HIO.mShakeXOscAngQuantum; + mShakeDampingScale = l_HIO.mShakeDampingScale; mShakeMaxDecay = l_HIO.mShakeMaxDecay; mShakeMinDecay = l_HIO.mShakeMinDecay; @@ -401,35 +476,35 @@ void daSyRock_c::modeMove() { } BOOL daSyRock_c::chkWaterLineIn() { - return mAcch.m_wtr.GetHeight() > current.pos.y + 150.0f; + const f32 waterHeight = mAcch.m_wtr.GetHeight(); + return waterHeight > current.pos.y + 150.0f; } void daSyRock_c::bgCheck() { - // Note stack ordering issues arise if fopAcM_seStartCurrent() is used instead of mDoAud_seStart() - const u32 hitGround = mAcch.ChkGroundHit() ? TRUE : FALSE; - const u32 hitWater = mAcch.ChkWaterHit() ? TRUE : FALSE; - const u32 inWater = mAcch.ChkWaterIn() ? TRUE : FALSE; + const bool hitGround = mAcch.ChkGroundHit(); + const bool hitWater = mAcch.ChkWaterHit(); + const bool inWater = mAcch.ChkWaterIn(); bool inWaterPillar = false; if(mMode == MODE_DROP) { if(mpWaterPillar) { - const f32 waterPillarHeight = mpWaterPillar->getPillarHeight(); - const f32 waterPillarVerticalPos = fopAcM_GetPosition(mpWaterPillar).y; - if(waterPillarVerticalPos + waterPillarHeight - 50.0f >= current.pos.y) + const f32 pillarTop = mpWaterPillar->getPillarHeight() + mpWaterPillar->current.pos.y - 50.0f; + if(pillarTop >= current.pos.y) inWaterPillar = true; } const f32 waterHeight = mAcch.m_wtr.GetHeight(); if(hitWater) { const f32 verticalSpeed = speed.y; - + if(chkWaterLineIn()) init_modeSink(); - if(inWater && !mInWaterPreviousFrame) { - cXyz currentRockPos = current.pos; + if(inWater && !mInWaterPrevFrame) { + cXyz currentRockPos(current.pos); currentRockPos.y = waterHeight; - fopKyM_createWpillar(¤tRockPos, l_HIO.mEffectScale, 3); + + fopKyM_createWpillar(¤tRockPos, l_HIO.mEffScale, 3); if(verticalSpeed < -15.0f) fopAcM_seStart(this, Z2SE_OBJ_FALL_WATER_M, 0); @@ -445,7 +520,7 @@ void daSyRock_c::bgCheck() { if(hitGround) { if(!hitWater && !mpWaterPillar) { mDoAud_seStart(Z2SE_OBJ_STALAC_LAND, ¤t.pos, 0, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); - daObjEff::Act_c::make_land_smoke(¤t.pos, l_HIO.mEffectScale); + daObjEff::Act_c::make_land_smoke(¤t.pos, l_HIO.mEffScale); } if(mpWaterPillar) @@ -457,16 +532,15 @@ void daSyRock_c::bgCheck() { void daSyRock_c::init_modeDropEnd() { if(!mAcch.ChkWaterIn()) { - dComIfGp_getVibration().StartShock(l_HIO.mShockStrength, 0xF, cXyz(0.0f, 1.0f, 0.0f)); + dComIfGp_getVibration().StartShock(l_HIO.mVibModePower, 0xF, cXyz(0.0f, 1.0f, 0.0f)); } if(mpBgW) dComIfG_Bgsp().Regist(mpBgW, this); - mUnbrokenCylinderCollider.OffAtSetBit(); + mUnbrokenCollider.OffAtSetBit(); - const u32 switchBitIndex = getSwBit1(); - dComIfGs_onSwitch(switchBitIndex, fopAcM_GetHomeRoomNo(this)); + fopAcM_onSwitch(this, getSwBit1()); mMode = MODE_DROP_END; } @@ -476,9 +550,9 @@ void daSyRock_c::modeDropEnd() { } int daSyRock_c::Draw() { - g_env_light.settingTevStruct(0x10, fopAcM_GetPosition_p(this), &tevStr); + g_env_light.settingTevStruct(0x10, ¤t.pos, &tevStr); g_env_light.setLightTevColorType_MAJI(mpModels[mIsUnbroken], &tevStr); - + dComIfGd_setListBG(); mDoExt_modelUpdateDL(mpModels[mIsUnbroken]); dComIfGd_setList(); @@ -492,11 +566,15 @@ int daSyRock_c::Delete() { if(mpBrokenCollision && mpBrokenCollision->ChkUsed()) dComIfG_Bgsp().Release(mpBrokenCollision); + #if DEBUG + l_HIO.removeHIO(); + #endif + return 1; } static int daSyRock_Draw(daSyRock_c* i_this) { - return i_this->Draw(); + return i_this->MoveBGDraw(); return 1; } @@ -505,11 +583,14 @@ static int daSyRock_Execute(daSyRock_c* i_this) { } static int daSyRock_Delete(daSyRock_c* i_this) { + fopAcM_RegisterDeleteID(i_this, "daSyRock"); return i_this->MoveBGDelete(); } static int daSyRock_Create(fopAc_ac_c* i_this) { - return static_cast(i_this)->create(); + daSyRock_c* const actor = static_cast(i_this); + fopAcM_RegisterCreateID(i_this, "daSyRock"); + return actor->create(); } static actor_method_class l_daSyRock_Method = { diff --git a/src/d/actor/d_a_obj_waterPillar.cpp b/src/d/actor/d_a_obj_waterPillar.cpp index 65abe22e5c..73099dbf6b 100644 --- a/src/d/actor/d_a_obj_waterPillar.cpp +++ b/src/d/actor/d_a_obj_waterPillar.cpp @@ -1,40 +1,42 @@ /** * @file d_a_obj_waterPillar.cpp - * + * */ + #include "d/dolzel_rel.h" // IWYU pragma: keep #include "d/actor/d_a_obj_waterPillar.h" -#include "d/d_com_inf_game.h" -#include "SSystem/SComponent/c_math.h" +#if DEBUG +#include "d/d_debug_viewer.h" +#endif struct daWtPillar_HIO_c : public mDoHIO_entry_c { daWtPillar_HIO_c(); - virtual ~daWtPillar_HIO_c() {} + ~daWtPillar_HIO_c() {} void genMessage(JORMContext*); - /* 0x04 */ cXyz field_0x04; - /* 0x10 */ csXyz field_0x10; - /* 0x16 */ s8 mForTesting; // "----------- テスト用 ----------" "----------- For Testing ----------" | Checkbox - /* 0x17 */ s8 mDisableDrawing; // "モデル描画OFF" "Model Drawing OFF" | Checkbox - /* 0x18 */ s8 mStopTime; // "停止時間" "Stop time" | Slider - /* 0x19 */ u8 mUpFirstWaitFrames; // "待ち時間" "Waiting time" | Slider - /* 0x1A */ u8 field_0x1A[6]; - /* 0x20 */ f32 field_0x20; // "速度" "Velocity" | Slider - /* 0x24 */ u8 field_0x24[4]; - /* 0x28 */ f32 field_0x28; // mColliderUpdateScaleFactor? - /* 0x2C */ u8 mUpWaitFrames; // "待ち時間" "Waiting time" | Slider - /* 0x2D */ u8 field_0x2D[4]; - /* 0x34 */ f32 field_0x34; // "速度" "Velocity" | Slider - /* 0x38 */ u8 field_0x38[8]; - /* 0x40 */ f32 mDownwardSpeedUnitsPerSecond; // "速度" "Velocity" | Slider - /* 0x44 */ f32 mEffectOscillationAngle; // "振幅Y" "Y Amplitude" | Slider - /* 0x48 */ f32 mEffectOscillationAmplitude; // "移動強さ" "Moving strength" | Slider - /* 0x4C */ f32 mEffectOscillationDampingScale; // "揺れ減衰" "Sway damping" | Slider - /* 0x50 */ f32 mEffectOscillationMaxDecay; // "最大減衰量" "Maximum decay" | Slider - /* 0x54 */ f32 mEffectOscillationMinDecay; // "最小減衰量" "Minimum decay" | Slider + /* 0x04 */ cXyz mDbgDrawScale; + /* 0x10 */ csXyz mDbgDrawAngle; + /* 0x16 */ bool mTesting; + /* 0x17 */ u8 mDbgDrawingOn; + /* 0x18 */ u8 mStopTime; + /* 0x19 */ u8 mUpFirstWaitFrames; + /* 0x1A */ u8 pad_0[6]; + /* 0x20 */ f32 mUpFirstTargetSpeed; // Maximum speed for preliminary upward movement + /* 0x24 */ u8 pad_1[4]; + /* 0x28 */ f32 mColScaleFactor; + /* 0x2C */ u8 mUpWaitFrames; + /* 0x2D */ u8 pad_2[4]; + /* 0x34 */ f32 mUpTargetSpeed; // Maximum speed for final upward movement + /* 0x38 */ u8 pad_3[8]; + /* 0x40 */ f32 mDownTargetSpeed; // In units per second + /* 0x44 */ f32 mVOscAngleQuantum; + /* 0x48 */ f32 mVOscAmplitude; + /* 0x4C */ f32 mVOscDampingScale; + /* 0x50 */ f32 mVOscMaxDecay; + /* 0x54 */ f32 mVOscMinDecay; }; typedef void (daWtPillar_c::*actionFunc)(); @@ -45,58 +47,89 @@ int daWtPillar_Delete(daWtPillar_c* i_this); int daWtPillar_Create(fopAc_ac_c* i_this); daWtPillar_HIO_c::daWtPillar_HIO_c() { - field_0x04.setall(1.0f); - field_0x10.setall(0); - mDisableDrawing = mForTesting = false; + mDbgDrawScale.set(1.0f, 1.0f, 1.0f); + mDbgDrawAngle.set(0, 0, 0); + mTesting = false; + mDbgDrawingOn = false; mStopTime = 30; - field_0x20 = 2000.0f; + mUpFirstTargetSpeed = 2000.0f; mUpFirstWaitFrames = 30; - field_0x34 = 5000.0f; + mUpTargetSpeed = 5000.0f; mUpWaitFrames = 60; - mDownwardSpeedUnitsPerSecond = 1000.0f; - mEffectOscillationAngle = 20.0f; - mEffectOscillationAmplitude = 25.0f; - mEffectOscillationDampingScale = 1.0f / 100.0f; - mEffectOscillationMaxDecay = 1.0f / 20.0f; - mEffectOscillationMinDecay = 1.0f / 100.0f; + mDownTargetSpeed = 1000.0f; + mVOscAngleQuantum = 20.0f; + mVOscAmplitude = 25.0f; + mVOscDampingScale = 1.0f / 100.0f; + mVOscMaxDecay = 1.0f / 20.0f; + mVOscMinDecay = 1.0f / 100.0f; } +#if DEBUG +void daWtPillar_HIO_c::genMessage(JORMContext* mctx) { + /* === During Preparatory Movements === */ + mctx->genLabel("\n=== 予備動作時 ===", 0); + // Waiting time + mctx->genSlider("待ち時間", &mUpFirstWaitFrames, 0, 0xFF); + + /* === During Upward Movements === */ + mctx->genLabel("\n=== 上昇動作時 ===", 0); + // Waiting time + mctx->genSlider("待ち時間", &mUpWaitFrames, 0, 0xFF); + + /* ----------- For Testing ---------- */ + mctx->genCheckBox("----------- テスト用 ----------", (u8*) &mTesting, 0x1); + + /* === When Stopped === */ + mctx->genLabel("\n=== 停止時 ===", 0); + // Stop time + mctx->genSlider("停止時間", &mStopTime, 0, 0xFF); + + /* === During Preparatory Movements === */ + mctx->genLabel("\n=== 予備動作時 ===", 0); + // Velocity + mctx->genSlider("速度", &mUpFirstTargetSpeed, 0.0f, 30000.0f); + + /* === During Upward Movements === */ + mctx->genLabel("\n=== 上昇動作時 ===", 0); + // Velocity + mctx->genSlider("速度", &mUpTargetSpeed, 0.0f, 30000.0f); + + /* === During Descending Movements === */ + mctx->genLabel("\n=== 下降動作時 ===", 0); + // Velocity + mctx->genSlider("速度", &mDownTargetSpeed, 0.0f, 30000.0f); + + /* ====Shaking==== */ + mctx->genLabel("\n====揺れ====", 0); + // Y amplitude + mctx->genSlider("振幅Y", &mVOscAngleQuantum, 0.0f, 180.0f); + // Shake strength + mctx->genSlider("移動強さ", &mVOscAmplitude, 0.0f, 10000.0f); + // Shake damping + mctx->genSlider("揺れ減衰", &mVOscDampingScale, 0.0f, 1.0f); + // Maximum damping amount + mctx->genSlider("最大減衰量", &mVOscMaxDecay, 0.0f, 100.0f); + // Minimum damping amount + mctx->genSlider("最小減衰量", &mVOscMinDecay, 0.0f, 100.0f); + + /* Model Drawing OFF */ // (Actually turns on debug cylinder drawing) + mctx->genCheckBox("モデル描画OFF", &mDbgDrawingOn, 0x1); +} +#endif + void daWtPillar_c::setBaseMtx() { mDoMtx_stack_c::transS(current.pos.x, current.pos.y + mCurrentHeight, current.pos.z); - mDoMtx_stack_c::transM(mEffectOscillationVerticalOffset.x, mEffectOscillationVerticalOffset.y, mEffectOscillationVerticalOffset.z); + mDoMtx_stack_c::transM(mVOscVOffset.x, mVOscVOffset.y, mVOscVOffset.z); mpModel->setBaseScale(scale); mpModel->setBaseTRMtx(mDoMtx_stack_c::get()); } int daWtPillar_c::createHeapCallBack(fopAc_ac_c* i_this) { - return static_cast(i_this)->CreateHeap(); + daWtPillar_c* actor = static_cast(i_this); + return actor->CreateHeap(); } -int daWtPillar_c::CreateHeap() { - J3DModelData* modelData = static_cast(dComIfG_getObjectRes("efWater", 8)); - JUT_ASSERT(369, modelData != NULL); - mpModel = mDoExt_J3DModel__create(modelData, J3DMdlFlag_DifferedDLBuffer, 0x11000284); - - if(!mpModel) - return 0; - - J3DAnmTransform* anmTransform = static_cast(dComIfG_getObjectRes("efWater", 5)); - int res = mModelRotationAnimation.init(anmTransform, 1, 2, 1.0f, 0, -1, false); - JUT_ASSERT(385, res == 1) - - J3DAnmTextureSRTKey* anmSRTKey = static_cast(dComIfG_getObjectRes("efWater", 11)); - res = mVerticalTextureScrollAnimation.init(modelData, anmSRTKey, 1, 2, 1.0f, 0, -1); - JUT_ASSERT(395, res == 1) - - return 1; -} - -cull_box l_cull_box = { - {-30.0f, -10.0f, -30.0f}, - {30.0f, 60.0f, 30.0f} -}; - const dCcD_SrcGObjInf daWtPillar_c::mCcDObjInfo = { {0x0, {{AT_TYPE_100, 0x0, 0x1D}, {AT_TYPE_0, 0x0}, 0x0}}, // mObj {dCcD_SE_SWORD, 0x0, 0x0, dCcD_MTRL_NONE, 0x0}, // mGObjAt @@ -112,6 +145,11 @@ const dCcD_SrcGObjInf daWtPillar_c::mCcDObjCoInfo = { daWtPillar_HIO_c l_HIO; +cull_box l_cull_box = { + {-30.0f, -10.0f, -30.0f}, + {30.0f, 60.0f, 30.0f} +}; + dCcD_SrcCps daWtPillar_c::mCcDCps = { daWtPillar_c::mCcDObjInfo, { { {0.0f, 0.0f, 0.0f}, {0.0f,1100.0f, 0.0f}, 150.0f }} @@ -119,6 +157,26 @@ dCcD_SrcCps daWtPillar_c::mCcDCps = { dCcD_SrcCyl daWtPillar_c::mCcDCyl = {daWtPillar_c::mCcDObjCoInfo}; +int daWtPillar_c::CreateHeap() { + J3DModelData* modelData = static_cast(dComIfG_getObjectRes("efWater", 8)); + JUT_ASSERT(369, modelData != NULL); + mpModel = mDoExt_J3DModel__create(modelData, J3DMdlFlag_DifferedDLBuffer, 0x11000284); + + if(!mpModel) + return 0; + + int res = mModelRotAnm.init(static_cast(dComIfG_getObjectRes("efWater", 5)), + 1, 2, 1.0f, 0, -1, false); + JUT_ASSERT(385, res == 1) + + res = mVTexScrollAnm.init(modelData, + static_cast(dComIfG_getObjectRes("efWater", 11)), + 1, 2, 1.0f, 0, -1); + JUT_ASSERT(394, res == 1) + + return 1; +} + cPhs_Step daWtPillar_c::create() { fopAcM_ct(this, daWtPillar_c); const cPhs_Step phase = static_cast(dComIfG_resLoad(&mPhase, "efWater")); @@ -126,21 +184,24 @@ cPhs_Step daWtPillar_c::create() { if(phase == cPhs_COMPLEATE_e) { if(!fopAcM_entrySolidHeap(this, createHeapCallBack, 0x2000)) return cPhs_ERROR_e; - + mStts.Init(0xFE, 0xFF, this); mCylinderCollider.Set(mCcDCyl); mCylinderCollider.SetStts(&mStts); mCapsuleCollider.Set(mCcDCps); mCapsuleCollider.SetStts(&mStts); - //! @bug maxY is used as maxZ for setting cull size box, making it larger than intended - const f32 minX = l_cull_box.min.x * scale.x; - const f32 minY = l_cull_box.min.y * scale.y; - const f32 minZ = l_cull_box.min.z * scale.x; - const f32 maxX = l_cull_box.max.x * scale.x; - const f32 maxY = l_cull_box.max.y * scale.y; - const f32 maxZ = l_cull_box.max.z * scale.x; - fopAcM_setCullSizeBox(this, minX, minY, minZ, maxX, maxY, maxY); + //! @bug l_cull_box.min is used to set actor cull.box.max, and vice-versa + //! @note Scaling is symmetric with respect to X and Z + cull_box cullBounds; + cullBounds.max.x = l_cull_box.min.x * scale.x; + cullBounds.max.y = l_cull_box.min.y * scale.y; + cullBounds.max.z = l_cull_box.min.z * scale.x; + cullBounds.min.x = l_cull_box.max.x * scale.x; + cullBounds.min.y = l_cull_box.max.y * scale.y; + cullBounds.min.z = l_cull_box.max.z * scale.x; + //! @bug cullBounds.min.y is passed as max Z for setting cull size box, making it larger than intended + fopAcM_setCullSizeBox(this, cullBounds.max.x, cullBounds.max.y, cullBounds.max.z, cullBounds.min.x, cullBounds.min.y, cullBounds.min.y); mAcchCir.SetWall(150.0f, 5.0f); mAcch.Set(fopAcM_GetPosition_p(this), fopAcM_GetOldPosition_p(this), this, 1, &mAcchCir, fopAcM_GetSpeed_p(this), 0, 0); @@ -148,8 +209,8 @@ cPhs_Step daWtPillar_c::create() { mAcch.SetWaterCheckOffset(10000.0f); mAcch.OnLineCheckNone(); - mIsCarryingStalactite = false; - mStalactiteShouldStartShaking = 0; + mCarryingStalactite = false; + mStartStalactiteShake = 0; mSwitchNo = getParam(0, 8); mType = getParam(8, 4); @@ -161,15 +222,15 @@ cPhs_Step daWtPillar_c::create() { mAcch.CrrPos(dComIfG_Bgsp()); - /** + /** * @bug Adjustments to the water pillar's target height are only made when the object * is created, leading to inconsistent behavior if the water height is changed * after the object is created. * - * See the east room in B1 of the Lakebed Temple as an example: + * See the east room in B1 of the Lakebed Temple as an example: * When first entering entering the room after redirecting water towards it, a - * cutscene plays showing the water level rising; - * the bottom of the oscillating water pillar in this room starts above water, + * cutscene plays showing the water level rising; + * the bottom of the oscillating water pillar in this room starts above water, * but ends up below water after the cutscene, resulting in its target height never being modified. * However, exiting and re-entering the room does not result in the cutscene playing again, * so its target height is modified upon subsequent entries to the room @@ -183,17 +244,17 @@ cPhs_Step daWtPillar_c::create() { } field_0xB44 = 0; - mStartedRisingOrDoesNotRiseAndFall = 0; - mPillarIsPreparingToRise = 0; - mEffectOscillationAngleStep = 0; - mEffectOscillationVerticalOffset.x = 0.0f; - mEffectOscillationVerticalOffset.y = 0.0f; - mEffectOscillationVerticalOffset.z = 0.0f; - mEffectOscillationAmplitude = 0.0f; - mEffectOscillationAngle = 0.0f; - mEffectOscillationDampingScale = 0.0f; - mEffectOscillationMaxDecay = 0.0f; - mEffectOscillationMinDecay = 0.0f; + mIsUpOrStatic = 0; + mIsUpFirst = 0; + mVOscAngleStep = 0; + mVOscVOffset.x = 0.0f; + mVOscVOffset.y = 0.0f; + mVOscVOffset.z = 0.0f; + mVOscAmplitude = 0.0f; + mVOscAngleQuantum = 0.0f; + mVOscDampingScale = 0.0f; + mVOscMaxDecay = 0.0f; + mVOscMinDecay = 0.0f; mCurrentHeight = 0.0f; if(mSwitchNo != 0xFF) { @@ -202,7 +263,7 @@ cPhs_Step daWtPillar_c::create() { else if(mType == STATIC) { mCurrentHeight = mMaxHeight; field_0xB44 = true; - mStartedRisingOrDoesNotRiseAndFall = true; + mIsUpOrStatic = true; actionRockWaitInit(); } else { @@ -210,18 +271,19 @@ cPhs_Step daWtPillar_c::create() { } setBaseMtx(); - - // TODO: + + #if DEBUG // "Water column" - // entryHIO(&l_HIO, "水柱"); + l_HIO.entryHIO("水柱"); + #endif } return phase; } int daWtPillar_c::execute() { - mModelRotationAnimation.play(); - mVerticalTextureScrollAnimation.play(); + mModelRotAnm.play(); + mVTexScrollAnm.play(); eventUpdate(); actionMain(); @@ -230,8 +292,8 @@ int daWtPillar_c::execute() { effectSet(); effectSet2(); - mScale.x = scale.x; - mScale.z = scale.z; + mDbgDrawScale.x = scale.x; + mDbgDrawScale.z = scale.z; cXyz currentHeightVector(0.0f, 1.0f, 0.0f); currentHeightVector.y *= mCurrentHeight; @@ -249,9 +311,9 @@ int daWtPillar_c::execute() { mCapsuleSource.mEnd = currentHeightVector + currentPos; mCapsuleSource.mRadius = scale.x * 140.0f; - if(mCurrentHeight / 100.0f > scale.y * l_HIO.field_0x28) { - cM3dGCps& cps = mCapsuleCollider; - cps.Set(mCapsuleSource); + //! @bug l_HIO.mColliderUpdateScaleFactor is read, but never written to after default initialization. This therefore evaluates to mCurrentHeight / 100.0f > 0.0f + if(mCurrentHeight / 100.0f > scale.y * l_HIO.mColScaleFactor) { + mCapsuleCollider.cM3dGCps::Set(mCapsuleSource); dComIfG_Ccsp()->Set(&mCapsuleCollider); } @@ -260,11 +322,11 @@ int daWtPillar_c::execute() { mCylinderCollider.SetC(current.pos); dComIfG_Ccsp()->Set(&mCylinderCollider); - mEffectOscillationVerticalOffset.y = mEffectOscillationAmplitude * cM_ssin(mEffectOscillationAngleStep * cM_deg2s(mEffectOscillationAngle)); + mVOscVOffset.y = mVOscAmplitude * cM_ssin(mVOscAngleStep * cM_deg2s(mVOscAngleQuantum)); - cLib_addCalc(&mEffectOscillationAmplitude, 0.0f, mEffectOscillationDampingScale, mEffectOscillationMaxDecay, mEffectOscillationMinDecay); + cLib_addCalc(&mVOscAmplitude, 0.0f, mVOscDampingScale, mVOscMaxDecay, mVOscMinDecay); - mEffectOscillationAngleStep++; + mVOscAngleStep++; setBaseMtx(); @@ -283,7 +345,8 @@ void daWtPillar_c::actionMain() { (this->*l_func[mAction])(); } -static u16 l_eff[7] = { +void daWtPillar_c::effectSet() { + static u16 l_eff[7] = { 0x86E3, // Smoke-like water foam particles, placed at pillar top 0x86E4, // Large paint splatter-type water foam particles, placed at pillar top 0x86E7, // Small paint splash-type water foam particles, placed at pillar top @@ -291,14 +354,12 @@ static u16 l_eff[7] = { 0x86E5, // Large paint splash-type water foam particles, placed at pillar bottom 0x86EB, // Water splash particles, placed at pillar bottom 0x86EA // Water splash particles, placed at pillar top -}; + }; -void daWtPillar_c::effectSet() { // Create foam particles at the bottom and top of the pillar - cXyz effectOscillationOffset; - effectOscillationOffset.setall(0.0f); + cXyz effectOscillationOffset(0.0f, 0.0f, 0.0f); - mDoMtx_stack_c::transS(mEffectOscillationVerticalOffset.x, mEffectOscillationVerticalOffset.y, mEffectOscillationVerticalOffset.z); + mDoMtx_stack_c::transS(mVOscVOffset.x, mVOscVOffset.y, mVOscVOffset.z); mDoMtx_stack_c::multVec(&effectOscillationOffset, &effectOscillationOffset); cXyz currentPosWithOscillationOffset = current.pos + effectOscillationOffset; @@ -307,45 +368,44 @@ void daWtPillar_c::effectSet() { mTopPos.y += mCurrentHeight; for(int i = 0; i < 3; i++) - mBottomAndTopParticleEmmitters[i] = dComIfGp_particle_set(mBottomAndTopParticleEmmitters[i],l_eff[i], &mTopPos, NULL, NULL); - - if(!mIsCarryingStalactite) - mBottomAndTopParticleEmmitters[3] = dComIfGp_particle_set(mBottomAndTopParticleEmmitters[3],l_eff[3], &mTopPos, NULL, NULL); - - if(mStartedRisingOrDoesNotRiseAndFall) - mBottomAndTopParticleEmmitters[4] = dComIfGp_particle_set(mBottomAndTopParticleEmmitters[4],l_eff[4], ¤t.pos, NULL, NULL); - - if(mPillarIsPreparingToRise) { - mBottomAndTopParticleEmmitters[5] = dComIfGp_particle_set(mBottomAndTopParticleEmmitters[5],l_eff[5], ¤t.pos, NULL, NULL); + mBotAndTopEmmitters[i] = dComIfGp_particle_set(mBotAndTopEmmitters[i],l_eff[i], &mTopPos, NULL, NULL); + + if(!mCarryingStalactite) + mBotAndTopEmmitters[3] = dComIfGp_particle_set(mBotAndTopEmmitters[3],l_eff[3], &mTopPos, NULL, NULL); + + if(mIsUpOrStatic) + mBotAndTopEmmitters[4] = dComIfGp_particle_set(mBotAndTopEmmitters[4],l_eff[4], ¤t.pos, NULL, NULL); + + if(mIsUpFirst) { + mBotAndTopEmmitters[5] = dComIfGp_particle_set(mBotAndTopEmmitters[5],l_eff[5], ¤t.pos, NULL, NULL); } - if(mIsCarryingStalactite) - mBottomAndTopParticleEmmitters[6] = dComIfGp_particle_set(mBottomAndTopParticleEmmitters[6],l_eff[6], &mTopPos, NULL, NULL); + if(mCarryingStalactite) + mBotAndTopEmmitters[6] = dComIfGp_particle_set(mBotAndTopEmmitters[6],l_eff[6], &mTopPos, NULL, NULL); } void daWtPillar_c::effectSet2() { - + /* If the bottom of the pillar is at least 500.0 units underwater and the current height of the pillar makes the top be above water, - create foam particles at the horizontal position of the pillar, but at + create foam particles at the horizontal position of the pillar, but at the water surface */ // Can be observed in Lakebed Temple, when water level is raised in certain rooms - if(mAcch.m_wtr.GetHeight() - current.pos.y >= 500.0f && + if(mAcch.m_wtr.GetHeight() - current.pos.y >= 500.0f && current.pos.y + mCurrentHeight >= mAcch.m_wtr.GetHeight()) { - cXyz effectOscillationOffset; - effectOscillationOffset.setall(0.0f); + cXyz effectOscillationOffset(0.0f, 0.0f, 0.0f); - mDoMtx_stack_c::transS(mEffectOscillationVerticalOffset.x, mEffectOscillationVerticalOffset.y, mEffectOscillationVerticalOffset.z); + mDoMtx_stack_c::transS(mVOscVOffset.x, mVOscVOffset.y, mVOscVOffset.z); mDoMtx_stack_c::multVec(&effectOscillationOffset, &effectOscillationOffset); cXyz currentPosWithVerticalOffset = current.pos + effectOscillationOffset; currentPosWithVerticalOffset.y = mAcch.m_wtr.GetHeight(); - mWaterSurfaceParticleEmitters[0] = dComIfGp_particle_set(mWaterSurfaceParticleEmitters[0], 0x888F, ¤tPosWithVerticalOffset, NULL, NULL); - mWaterSurfaceParticleEmitters[1] = dComIfGp_particle_set(mWaterSurfaceParticleEmitters[1], 0x8890, ¤tPosWithVerticalOffset, NULL, NULL); + mWaterSurfaceEmitters[0] = dComIfGp_particle_set(mWaterSurfaceEmitters[0], 0x888F, ¤tPosWithVerticalOffset, NULL, NULL); + mWaterSurfaceEmitters[1] = dComIfGp_particle_set(mWaterSurfaceEmitters[1], 0x8890, ¤tPosWithVerticalOffset, NULL, NULL); } } @@ -354,7 +414,7 @@ void daWtPillar_c::actionSwWaitInit() { } void daWtPillar_c::actionSwWait() { - if(dComIfGs_isSwitch(mSwitchNo, fopAcM_GetHomeRoomNo(this))) { + if(fopAcM_isSwitch(this, mSwitchNo)) { if(getEventID() != 0xFF) orderEvent(getEventID(), 0xFF, 1); else @@ -368,75 +428,97 @@ bool daWtPillar_c::eventStart() { } void daWtPillar_c::actionWaitInit() { - mWaitFrameDelay = getParam(12, 5) * 0.5f * 30.0f; - mStartedRisingOrDoesNotRiseAndFall = field_0xB44 = false; + mWaitFrames = getParam(12, 5) * 0.5f * 30.0f; - fopAcM_seStartCurrent(this, Z2SE_OBJ_WTR_CLMN_WAIT, 0); + #if DEBUG + if(l_HIO.mTesting) + mWaitFrames = l_HIO.mStopTime; + #endif + + field_0xB44 = false; + mIsUpOrStatic = false; + + mDoAud_seStart(Z2SE_OBJ_WTR_CLMN_WAIT, ¤t.pos, 0, + dComIfGp_getReverb(fopAcM_GetRoomNo(this))); mAction = ACTION_WAIT; } void daWtPillar_c::actionWait() { - if(mWaitFrameDelay) - mWaitFrameDelay--; + if(mWaitFrames) + mWaitFrames--; else actionUpFirstInit(); } void daWtPillar_c::actionUpFirstInit() { - mTargetMaxSpeed = (getParam(17, 5) * 100.0f * 5.0f) / 30.0f; + mTargetSpeed = (getParam(17, 5) * 100.0f * 5.0f) / 30.0f; - if(mIsCarryingStalactite) - mFirstTargetHeight = 50.0f; + #if DEBUG + if(l_HIO.mTesting) + mTargetSpeed = l_HIO.mUpFirstTargetSpeed / 30.0f; + #endif + + if(mCarryingStalactite) + mUpFirstTargetHeight = 50.0f; else - mFirstTargetHeight = 300.0f; + mUpFirstTargetHeight = 300.0f; speedF = 0.0f; - mStalactiteShouldStartShaking = mPillarIsPreparingToRise = field_0xB44 = TRUE; - - fopAcM_seStartCurrent(this, Z2SE_OBJ_WTR_CLMN_READY, 0); + field_0xB44 = true; + mIsUpFirst = true; + mStartStalactiteShake = true; + + mDoAud_seStart(Z2SE_OBJ_WTR_CLMN_READY, ¤t.pos, 0, + dComIfGp_getReverb(fopAcM_GetRoomNo(this))); mAction = ACTION_UP_FIRST; } void daWtPillar_c::actionUpFirst() { - cLib_chaseF(&speedF, mTargetMaxSpeed, mTargetMaxSpeed / 30.0f); + const BOOL maxSpeedReached = cLib_chaseF(&speedF, mTargetSpeed, mTargetSpeed / 30.0f); - const f32 differenceBetweenCurrentAndFirstTargetHeight = cLib_addCalc(&mCurrentHeight, mFirstTargetHeight, 1.0f, speedF, 1.0f / 10.0f); + const f32 differenceBetweenCurrentAndFirstTargetHeight = cLib_addCalc(&mCurrentHeight, mUpFirstTargetHeight, 1.0f, speedF, 1.0f / 10.0f); if(differenceBetweenCurrentAndFirstTargetHeight == 0.0f) actionUpFirstWaitInit(); } void daWtPillar_c::actionUpFirstWaitInit() { - mWaitFrameDelay = l_HIO.mUpFirstWaitFrames; - mEffectOscillationAmplitude = l_HIO.mEffectOscillationAmplitude; - mEffectOscillationAngle = l_HIO.mEffectOscillationAngle; - mEffectOscillationDampingScale = l_HIO.mEffectOscillationDampingScale; - mEffectOscillationMaxDecay = l_HIO.mEffectOscillationMaxDecay; - mEffectOscillationMinDecay = l_HIO.mEffectOscillationMinDecay; + mWaitFrames = l_HIO.mUpFirstWaitFrames; + mVOscAmplitude = l_HIO.mVOscAmplitude; + mVOscAngleQuantum = l_HIO.mVOscAngleQuantum; + mVOscDampingScale = l_HIO.mVOscDampingScale; + mVOscMaxDecay = l_HIO.mVOscMaxDecay; + mVOscMinDecay = l_HIO.mVOscMinDecay; mAction = ACTION_UP_FIRST_WAIT; } void daWtPillar_c::actionUpFirstWait() { - if(mWaitFrameDelay) - mWaitFrameDelay--; + if(mWaitFrames) + mWaitFrames--; else actionUpInit(); } void daWtPillar_c::actionUpInit() { - mTargetMaxSpeed = getParam(22, 5) * 100.0f * 5.0f / 30.0f; + mTargetSpeed = getParam(22, 5) * 100.0f * 5.0f / 30.0f; - if(mIsCarryingStalactite) + #if DEBUG + if(l_HIO.mTesting) + mTargetSpeed = l_HIO.mUpTargetSpeed / 30.0f; + #endif + + if(mCarryingStalactite) mTargetHeightStalactiteOffset = -250.0f; else mTargetHeightStalactiteOffset = 0.0f; - mPillarIsPreparingToRise = false; + mIsUpFirst = false; - mStalactiteShouldStartShaking = mStartedRisingOrDoesNotRiseAndFall = true; + mIsUpOrStatic = true; + mStartStalactiteShake = true; speedF = 0.0f; @@ -444,7 +526,7 @@ void daWtPillar_c::actionUpInit() { } void daWtPillar_c::actionUp() { - cLib_chaseF(&speedF, mTargetMaxSpeed, mTargetMaxSpeed / 30.0f); + const BOOL maxSpeedReached = cLib_chaseF(&speedF, mTargetSpeed, mTargetSpeed / 30.0f); const f32 differenceBetweenCurrentAndMaxHeightWithStalactiteWeight = cLib_addCalc(&mCurrentHeight, mMaxHeight + mTargetHeightStalactiteOffset, 1.0f, speedF, 1.0f / 10.0f); @@ -460,32 +542,32 @@ void daWtPillar_c::actionUp() { } void daWtPillar_c::actionUpWaitInit() { - mWaitFrameDelay = l_HIO.mUpWaitFrames; - mEffectOscillationAmplitude = l_HIO.mEffectOscillationAmplitude; - mEffectOscillationAngle = l_HIO.mEffectOscillationAngle; - mEffectOscillationDampingScale = l_HIO.mEffectOscillationDampingScale; - mEffectOscillationMaxDecay = l_HIO.mEffectOscillationMaxDecay; - mEffectOscillationMinDecay = l_HIO.mEffectOscillationMinDecay; + mWaitFrames = l_HIO.mUpWaitFrames; + mVOscAmplitude = l_HIO.mVOscAmplitude; + mVOscAngleQuantum = l_HIO.mVOscAngleQuantum; + mVOscDampingScale = l_HIO.mVOscDampingScale; + mVOscMaxDecay = l_HIO.mVOscMaxDecay; + mVOscMinDecay = l_HIO.mVOscMinDecay; mAction = ACTION_UP_WAIT; } void daWtPillar_c::actionUpWait() { mDoAud_seStartLevel(Z2SE_OBJ_WTR_CLMN_UP, &mTopPos, mMaxHeight + mTargetHeightStalactiteOffset, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); - if(mWaitFrameDelay) - mWaitFrameDelay--; + if(mWaitFrames) + mWaitFrames--; else actionDownInit(); } void daWtPillar_c::actionDownInit() { speedF = 0.0f; - mStalactiteShouldStartShaking = true; + mStartStalactiteShake = true; mAction = ACTION_DOWN; } void daWtPillar_c::actionDown() { - cLib_chaseF(&speedF, l_HIO.mDownwardSpeedUnitsPerSecond / 30.0f, (l_HIO.mDownwardSpeedUnitsPerSecond / 30.0f) / 30.0f); + const BOOL maxDownwardSpeedReached = cLib_chaseF(&speedF, l_HIO.mDownTargetSpeed / 30.0f, (l_HIO.mDownTargetSpeed / 30.0f) / 30.0f); const f32 diff = cLib_addCalc(&mCurrentHeight, 0.0f, 1.0f, speedF, 0.1f); @@ -502,7 +584,7 @@ void daWtPillar_c::actionRockWaitInit() { void daWtPillar_c::actionRockWait() { mDoAud_seStartLevel(Z2SE_OBJ_WTR_CLMN_UP, &mTopPos, mMaxHeight + mTargetHeightStalactiteOffset, dComIfGp_getReverb(fopAcM_GetRoomNo(this))); - if(mIsCarryingStalactite) + if(mCarryingStalactite) actionRockOnInit(); } @@ -531,23 +613,65 @@ f32 daWtPillar_c::getPillarHeight() { return mCurrentHeight; } +#if DEBUG +void drawCylinder(cXyz* pos, cXyz* scale, csXyz* angle) { + UNUSED(angle); + Mtx finalMtx; + + // fakematch? + GXColor cylinderColor; + GXColor baseColor = {0x00, 0x00, 0xFF, 0xE6}; + GXColor cylinderColorRedundant; + *(u32*) &cylinderColorRedundant = *(u32*) &baseColor; + *(u32*) &cylinderColor = *(u32*) &cylinderColorRedundant; + + mDoMtx_stack_c::transS(pos->x, pos->y, pos->z); + //! @note Scaling is symmetric with respect to X and Z + mDoMtx_stack_c::scaleM(150.0f * scale->x, 50.0f * scale->y, 150.0f * scale->x); + mDoMtx_stack_c::transM(0.0f, 1.0f, 0.0f); + mDoMtx_stack_c::XrotM(0x4000); + MTXCopy(mDoMtx_stack_c::get(), finalMtx); + + dDbVw_drawCylinderMXlu(finalMtx, cylinderColor, 1); +} +#endif + int daWtPillar_c::draw() { g_env_light.settingTevStruct(0x10, ¤t.pos, &tevStr); g_env_light.setLightTevColorType_MAJI(mpModel, &tevStr); - J3DModelData* const modelData = mpModel->getModelData(); - mModelRotationAnimation.entry(modelData); - mVerticalTextureScrollAnimation.entry(modelData); + J3DModelData* const modelData = mpModel->getModelData(); + mModelRotAnm.entry(modelData); + mVTexScrollAnm.entry(modelData); dComIfGd_setListBG(); mDoExt_modelUpdateDL(mpModel); dComIfGd_setList(); - + + + #if DEBUG + u8 draw = false; + if(l_HIO.mTesting) { + current.angle = l_HIO.mDbgDrawAngle; + scale = l_HIO.mDbgDrawScale; + } + + //! @bug mDbgDrawScale is always + if((draw = l_HIO.mDbgDrawingOn)) { + drawCylinder(¤t.pos, &mDbgDrawScale, ¤t.angle); + } + #endif + return 1; } int daWtPillar_c::_delete() { dComIfG_resDelete(&mPhase, "efWater"); + + #if DEBUG + l_HIO.removeHIO(); + #endif + return 1; } @@ -560,11 +684,14 @@ int daWtPillar_Execute(daWtPillar_c* i_this) { } int daWtPillar_Delete(daWtPillar_c* i_this) { + fopAcM_RegisterDeleteID(i_this, "daWtPillar"); return i_this->_delete(); } int daWtPillar_Create(fopAc_ac_c* i_this) { - return static_cast(i_this)->create(); + daWtPillar_c* const actor = static_cast(i_this); + fopAcM_RegisterCreateID(i_this, "daWtPillar"); + return actor->create(); } actor_method_class l_daWtPillar_Method = { diff --git a/src/d/actor/d_a_obj_waterfall.cpp b/src/d/actor/d_a_obj_waterfall.cpp index 1ce008500b..b91a03311e 100644 --- a/src/d/actor/d_a_obj_waterfall.cpp +++ b/src/d/actor/d_a_obj_waterfall.cpp @@ -4,11 +4,18 @@ #include "d/dolzel_rel.h" // IWYU pragma: keep +#if DEBUG +#include "d/d_debug_viewer.h" +#endif + #include "d/actor/d_a_obj_waterfall.h" #include "d/actor/d_a_arrow.h" #include "d/d_com_inf_game.h" #include "d/d_bomb.h" #include "SSystem/SComponent/c_math.h" +#include "f_op/f_op_actor.h" +#include "f_op/f_op_actor_mng.h" +#include "m_Do/m_Do_mtx.h" #define MAX_TARGET_INFO_COUNT 10 @@ -17,18 +24,88 @@ static int daObjWaterFall_Execute(daObjWaterFall_c* i_this); static int daObjWaterFall_Delete(daObjWaterFall_c* i_this); static int daObjWaterFall_Create(fopAc_ac_c* i_this); -static fopAc_ac_c* target_info[MAX_TARGET_INFO_COUNT]; +static fopAc_ac_c* target_info[MAX_TARGET_INFO_COUNT]; // Mutually exclusive list of bomb/arrow actors to be potentially deleted +static int target_info_count; -static s32 target_info_count; +const char* l_arcName = "sample"; + +#if DEBUG +static cull_box l_cull_box = { + {-200.0f, -100.0f, -200.0f}, + {200.0f, 100.0f, 200.0f} +}; + +static dCcD_SrcTri l_tri_src = { + { + {0, {{0, 0, 0}, {0x6002, 0x11}, 0}}, + {dCcD_SE_NONE, 0, 0, 0, {0}}, + {dCcD_SE_NONE, 0, 0, 0, {0x84}}, + {0}, + }, + { + { + {0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f}, + }, + }, +}; +#endif + +static dCcD_SrcCyl l_cyl_src = { + { + {0x0, {{0x0, 0x0, 0x0}, {0x2, 0x10}, 0x119}}, // mObj + {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt + {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x84}, // mGObjTg + {0x2}, // mGObjCo + }, // mObjInf + { + { + {0.0f, 0.0f, 0.0f}, // mCenter + 0.0f, // mRadius + 0.0f // mHeight + } // mCyl + } +}; + +#if DEBUG +class daObjWaterFall_HIO_c : public mDoHIO_entry_c { +public: + daObjWaterFall_HIO_c(); + ~daObjWaterFall_HIO_c() {} + + void genMessage(JORMContext*); + + /* 0x08 */ f32 mPushStrengthHuman; + /* 0x0C */ f32 mPushStrengthWolf; +}; + +static daObjWaterFall_HIO_c l_HIO; + +daObjWaterFall_HIO_c::daObjWaterFall_HIO_c() { + mPushStrengthHuman = 10.0f; + mPushStrengthWolf = 25.0f; +} + +void daObjWaterFall_HIO_c::genMessage(JORMContext* mctx) { + /* Waterfall */ + mctx->genLabel("滝", 0); + // Pushing force ・ human + mctx->genSlider("押す力・人間", &mPushStrengthHuman, 0.0f, 100.0f); + // Pushing force ・ wolf + mctx->genSlider("押す力・狼", &mPushStrengthWolf, 0.0f, 100.0f); +} + +#endif static void* s_b_sub(void* param_0, void* unused) { - if(fopAcM_IsActor(param_0) && fopAcM_GetName(param_0) == PROC_NBOMB) { - dBomb_c* foundBomb = static_cast(param_0); - if(!foundBomb->checkWaterBomb(foundBomb) && fopAcM_GetParam(foundBomb) != dBomb_c::PRM_NORMAL_BOMB_EXPLODE) { - const u32 idx = target_info_count; // Regalloc issues if this isn't done + #define BOMB_ACTOR static_cast(param_0) + UNUSED(unused); + if(fopAcM_IsActor(param_0) && dBomb_c::checkBombActor(BOMB_ACTOR)) { + if(!dBomb_c::checkWaterBomb(BOMB_ACTOR) && !BOMB_ACTOR->checkStateExplode()) { if(target_info_count < MAX_TARGET_INFO_COUNT) { - target_info[idx] = foundBomb; + target_info[target_info_count] = BOMB_ACTOR; target_info_count++; } } @@ -37,12 +114,11 @@ static void* s_b_sub(void* param_0, void* unused) { } static void* s_a_sub(void* param_0, void* unused) { + UNUSED(unused); + if(fopAcM_IsActor(param_0) && fopAcM_GetName(param_0) == PROC_ARROW) { - const u32 idx = target_info_count; // Regalloc issues if this isn't done - if(target_info_count < MAX_TARGET_INFO_COUNT) { - daArrow_c* arrow_0 = static_cast(param_0); - target_info[idx] = arrow_0; + target_info[target_info_count] = static_cast(param_0); target_info_count++; } } @@ -50,10 +126,10 @@ static void* s_a_sub(void* param_0, void* unused) { } void daObjWaterFall_c::search_bomb() { - if(checkFallOut() != TRUE) { + if(!checkFallOut()) { // Get rid of previously found arrow or bomb processes populating target_info target_info_count = 0; - for(u32 i = 0; i < MAX_TARGET_INFO_COUNT; i++) { + for(int i = 0; i < MAX_TARGET_INFO_COUNT; i++) { target_info[i] = NULL; } @@ -75,21 +151,23 @@ void daObjWaterFall_c::search_bomb() { mDoMtx_stack_c::multVec(&vectorToOldBombPos, &vectorToOldBombPos); mDoMtx_stack_c::multVec(&vectorToCurrentBombPos, &vectorToCurrentBombPos); - bool bombPassedZOriginPrevAndCurrentBombPosAreWithinXYBounds = ( - (vectorToOldBombPos.z * vectorToCurrentBombPos.z) < 0.0f && - (vectorToOldBombPos.x > -scale.x * 50.0f && vectorToOldBombPos.x < scale.x * 50.0f) && + // Bomb's Z position passed that of waterfall, and was within X,Y bounds both in the previous frame and current frame + bool multiFrameDeleteCondition = ( + (vectorToOldBombPos.z * vectorToCurrentBombPos.z) < 0.0f && + (vectorToOldBombPos.x > -scale.x * 50.0f && vectorToOldBombPos.x < scale.x * 50.0f) && (vectorToCurrentBombPos.x > -scale.x * 50.0f && vectorToCurrentBombPos.x < scale.x * 50.0f) && (vectorToOldBombPos.y > 0.0f && vectorToOldBombPos.y < scale.y * 100.0f) && (vectorToCurrentBombPos.y > 0.0f && vectorToCurrentBombPos.y < scale.y * 100.0f) ); - bool currentBombPosIsWithinXYZBounds = ( + // Bomb is within X,Y,Z bounds in the current frame + bool currentFrameDeleteCondition = ( (vectorToCurrentBombPos.x > -scale.x * 50.0f && vectorToCurrentBombPos.x < scale.x * 50.0f) && (vectorToCurrentBombPos.y > 0.0f && vectorToCurrentBombPos.y < scale.y * 100.0f) && (vectorToCurrentBombPos.z > -scale.z * 50.0f && vectorToCurrentBombPos.z < scale.z * 50.0f) ); - if(bombPassedZOriginPrevAndCurrentBombPosAreWithinXYBounds || currentBombPosIsWithinXYZBounds) + if(multiFrameDeleteCondition || currentFrameDeleteCondition) fopAcM_delete(bomb); } } @@ -98,12 +176,12 @@ void daObjWaterFall_c::search_bomb() { void daObjWaterFall_c::search_arrow() { // Some waterfalls (e.g. in the Lakebed Temple) allow arrows to fly through them - if(getType() == ALLOW_ARROWS_e || checkFallOut() == TRUE) + if(getType() == ALLOW_ARROWS_e || checkFallOut()) return; // Get rid of previously found arrow or bomb processes populating target_info target_info_count = 0; - for(u32 i = 0; i < MAX_TARGET_INFO_COUNT; i++) { + for(int i = 0; i < MAX_TARGET_INFO_COUNT; i++) { target_info[i] = NULL; } @@ -125,21 +203,23 @@ void daObjWaterFall_c::search_arrow() { mDoMtx_stack_c::multVec(&vectorToOldArrowPos, &vectorToOldArrowPos); mDoMtx_stack_c::multVec(&vectorToCurrentArrowPos, &vectorToCurrentArrowPos); - bool arrowPassedZOriginPrevAndCurrentArrowPosAreWithinXYBounds = ( - (vectorToOldArrowPos.z * vectorToCurrentArrowPos.z) < 0.0f && - (vectorToOldArrowPos.x > -scale.x * 50.0f && vectorToOldArrowPos.x < scale.x * 50.0f) && + // Arrow's Z position passed that of waterfall, and was within X,Y bounds both in the previous frame and current frame + bool multiFrameDeleteCondition = ( + (vectorToOldArrowPos.z * vectorToCurrentArrowPos.z) < 0.0f && + (vectorToOldArrowPos.x > -scale.x * 50.0f && vectorToOldArrowPos.x < scale.x * 50.0f) && (vectorToCurrentArrowPos.x > -scale.x * 50.0f && vectorToCurrentArrowPos.x < scale.x * 50.0f) && (vectorToOldArrowPos.y > 0.0f && vectorToOldArrowPos.y < scale.y * 100.0f) && (vectorToCurrentArrowPos.y > 0.0f && vectorToCurrentArrowPos.y < scale.y * 100.0f) ); - bool currentArrowPosIsWithinXYZBounds = ( + // Arrow is within X,Y,Z bounds in the current frame + bool currentFrameDeleteCondition = ( (vectorToCurrentArrowPos.x > -scale.x * 50.0f && vectorToCurrentArrowPos.x < scale.x * 50.0f) && (vectorToCurrentArrowPos.y > 0.0f && vectorToCurrentArrowPos.y < scale.y * 100.0f) && (vectorToCurrentArrowPos.z > -scale.z * 50.0f && vectorToCurrentArrowPos.z < scale.z * 50.0f) ); - if(arrowPassedZOriginPrevAndCurrentArrowPosAreWithinXYBounds || currentArrowPosIsWithinXYZBounds) + if(multiFrameDeleteCondition || currentFrameDeleteCondition) fopAcM_delete(arrow); } } @@ -150,31 +230,10 @@ void daObjWaterFall_c::initBaseMtx() { } void daObjWaterFall_c::setBaseMtx() { - cXyz* pos = fopAcM_GetPosition_p(this); - PSMTXTrans(mDoMtx_stack_c::get(), pos->x, pos->y, pos->z); - - csXyz* shapeAngle = fopAcM_GetShapeAngle_p(this); - mDoMtx_stack_c::ZXYrotM(shapeAngle->x, shapeAngle->y, shapeAngle->z); + mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z); + mDoMtx_stack_c::ZXYrotM(shape_angle.x, shape_angle.y, shape_angle.z); } -static const char* l_arcName = "sample"; - -static dCcD_SrcCyl l_cyl_src = { - { - {0x0, {{0x0, 0x0, 0x0}, {0x2, 0x10}, 0x119}}, // mObj - {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x0}, // mGObjAt - {dCcD_SE_NONE, 0x0, 0x0, 0x0, 0x84}, // mGObjTg - {0x2}, // mGObjCo - }, // mObjInf - { - { - {0.0f, 0.0f, 0.0f}, // mCenter - 0.0f, // mRadius - 0.0f // mHeight - } // mCyl - } -}; - cPhs_Step daObjWaterFall_c::Create() { initBaseMtx(); @@ -190,35 +249,148 @@ cPhs_Step daObjWaterFall_c::Create() { mCylCollider.OnCoNoCamHit(); - // If a waterfall process is not a circular cylinder (i.e. scale.x != scale.z), the circular cylindrical collider - // is oscillated in order to approximate the elliptical shape of the process. + // If a waterfall process is not a circular cylinder (i.e. scale.x != scale.z), the circular cylindrical collider + // is oscillated in order to approximate an elliptical shape // - // The member variable speedF (inherited from fopAc_ac_c) is used to control the speed of oscillation + // speedF is used to control the speed of oscillation // // This effect can be observed at the largest waterfall in Zora's Domain if(scale.x > scale.z) { - mCylColliderCenterOscillationTargets[0].set((scale.x * -50.0f) + (scale.z * 50.0f), 0.0f,0.0f); - mCylColliderCenterOscillationTargets[1].set((scale.x * 50.0f) - (scale.z * 50.0f), 0.0f,0.0f); + mColOscPosTargets[0].set((scale.x * -50.0f) + (scale.z * 50.0f), 0.0f,0.0f); + mColOscPosTargets[1].set((scale.x * 50.0f) - (scale.z * 50.0f), 0.0f,0.0f); speedF = ((scale.x * 100.0f) - (scale.z * 100.0f)) / 10.0f; } else { - mCylColliderCenterOscillationTargets[0].set(0.0f, 0.0f,(scale.z * -50.0f) + (scale.x * 50.0f)); - mCylColliderCenterOscillationTargets[1].set(0.0f, 0.0f,(scale.z * 50.0f) - (scale.x * 50.0f)); + // Oscillation position targets are <0, 0, 0> if scale.x == scale.z + mColOscPosTargets[0].set(0.0f, 0.0f,(scale.z * -50.0f) + (scale.x * 50.0f)); + mColOscPosTargets[1].set(0.0f, 0.0f,(scale.z * 50.0f) - (scale.x * 50.0f)); speedF = ((scale.z * 100.0f) - (scale.x * 100.0f)) / 10.0f; } mDoMtx_stack_c::transS(home.pos); mDoMtx_stack_c::YrotM(home.angle.y); - PSMTXMultVec(mDoMtx_stack_c::get(), &mCylColliderCenterOscillationTargets[0], &mCylColliderCenterOscillationTargets[0]); - PSMTXMultVec(mDoMtx_stack_c::get(), &mCylColliderCenterOscillationTargets[1], &mCylColliderCenterOscillationTargets[1]); + mDoMtx_stack_c::multVec(&mColOscPosTargets[0], &mColOscPosTargets[0]); + mDoMtx_stack_c::multVec(&mColOscPosTargets[1], &mColOscPosTargets[1]); - mCylColliderCenter = mCylColliderCenterOscillationTargets[0]; - mCylColliderCenterQuantizedOscillation = 1; + mColCenter = mColOscPosTargets[0]; + mColOscDir = 1; // Move collider toward mColOscPosTargets[1] return cPhs_LOADING_e; } +cPhs_Step daObjWaterFall_c::create() { + fopAcM_ct(this, daObjWaterFall_c); + + if(Create() == cPhs_INIT_e) { + return cPhs_ERROR_e; + } + + #if DEBUG + l_HIO.entryHIO("滝"); // "Waterfall" + #endif + + return cPhs_COMPLEATE_e; +} + +int daObjWaterFall_c::execute() { + if(getSwbit() != 0xFF && !fopAcM_isSwitch(this, getSwbit())) + return 1; + + push_player(); + search_bomb(); + search_arrow(); + + if(mColOscDir > 0) { + if(cLib_chasePosXZ(&mColCenter, mColOscPosTargets[1], speedF)) + mColOscDir = -1; // Move collider toward mColOscPosTargets[0] + } + else if(cLib_chasePosXZ(&mColCenter, mColOscPosTargets[0], speedF)) { + mColOscDir = 1; // Move collider toward mColOscPosTargets[1] + } + + mCylCollider.SetC(mColCenter); + dComIfG_Ccsp()->Set(&mCylCollider); + + return 1; +} + +void daObjWaterFall_c::push_player() { + daPy_py_c* const player = daPy_getPlayerActorClass(); + + #if DEBUG + f32 outMagnitude = l_HIO.mPushStrengthHuman; + #else + f32 outMagnitude = 10.0f; + #endif + + if(player->checkNowWolf()) { + #if DEBUG + outMagnitude = l_HIO.mPushStrengthWolf; + #else + outMagnitude = 25.0f; + #endif + } + + if(scale.x == scale.z) { + // Waterfall is a circular cylinder + if(fopAcM_searchPlayerDistanceXZ(this) < scale.x * 50.0f) { + cXyz vectorToPlayer = player->current.pos - current.pos; + player->setOutPower(outMagnitude, cM_atan2s(vectorToPlayer.x, vectorToPlayer.z) , FALSE); + } + } + else { + // Waterfall is an elliptic cylinder + cXyz vectorToPlayer = player->current.pos - current.pos; + + mDoMtx_stack_c::YrotS(-current.angle.y); + mDoMtx_stack_c::multVec(&vectorToPlayer, &vectorToPlayer); + + if((vectorToPlayer.x > -scale.x * 50.0f && vectorToPlayer.x < scale.x * 50.0f) && + vectorToPlayer.y > -10.0f && vectorToPlayer.y < scale.y * 100.0f) { + if(vectorToPlayer.z >= scale.z * 10.0f && vectorToPlayer.z < scale.z * 60.0f) { + player->setOutPower(outMagnitude, current.angle.y, FALSE); + } + else if(vectorToPlayer.z < scale.z * -10.0f && vectorToPlayer.z > scale.z * -60.0f) { + player->setOutPower(outMagnitude, (current.angle.y + (1 << 16)) - 0x8000, FALSE); + } + } + } +} + +int daObjWaterFall_c::draw() { + return 1; +} + +int daObjWaterFall_c::_delete() { + dComIfG_resDelete(&mPhase, l_arcName); + + #if DEBUG + l_HIO.removeHIO(); + #endif + + return 1; +} + +static int daObjWaterFall_Draw(daObjWaterFall_c* i_this) { + return i_this->draw(); +} + +static int daObjWaterFall_Execute(daObjWaterFall_c* i_this) { + return i_this->execute(); +} + +static int daObjWaterFall_Delete(daObjWaterFall_c* i_this) { + fopAcM_RegisterDeleteID(i_this, "WaterFall"); + return i_this->_delete(); +} + +static int daObjWaterFall_Create(fopAc_ac_c* i_this) { + daObjWaterFall_c* const actor = static_cast(i_this); + fopAcM_RegisterCreateID(i_this, "WaterFall"); + return actor->create(); +} + static actor_method_class l_daObjWaterFall_Method = { (process_method_func)daObjWaterFall_Create, (process_method_func)daObjWaterFall_Delete, @@ -243,96 +415,3 @@ actor_process_profile_definition g_profile_Obj_WaterFall = { fopAc_ACTOR_e, // mActorType fopAc_CULLBOX_CUSTOM_e, // cullType }; - -cPhs_Step daObjWaterFall_c::create() { - fopAcM_ct(this, daObjWaterFall_c); - - if(Create() == cPhs_INIT_e) { - return cPhs_ERROR_e; - } - - return cPhs_COMPLEATE_e; -} - -int daObjWaterFall_c::execute() { - if(getSwbit() != 0xFF && !fopAcM_isSwitch(this, getSwbit())) - return 1; - - push_player(); - search_bomb(); - search_arrow(); - - if(mCylColliderCenterQuantizedOscillation > 0) { - if(cLib_chasePosXZ(&mCylColliderCenter, mCylColliderCenterOscillationTargets[1], speedF)) - mCylColliderCenterQuantizedOscillation = -1; - } - else if(cLib_chasePosXZ(&mCylColliderCenter, mCylColliderCenterOscillationTargets[0], speedF)) { - mCylColliderCenterQuantizedOscillation = 1; - } - - mCylCollider.SetC(mCylColliderCenter); - dComIfG_Ccsp()->Set(&mCylCollider); - - return 1; -} - -void daObjWaterFall_c::push_player() { - daPy_py_c* const player = daPy_getPlayerActorClass(); - - f32 outMagnitude = 10.0f; - if(daPy_getLinkPlayerActorClass()->checkWolf()) - outMagnitude = 25.0f; - - if(scale.x == scale.z) { - // Waterfall is a circular cylinder - const f32 distToPlayer = fopAcM_searchPlayerDistanceXZ(this); - - if(distToPlayer < scale.x * 50.0f) { - cXyz vectorToPlayer = player->current.pos - current.pos; - s16 outAngle = cM_atan2s(vectorToPlayer.x, vectorToPlayer.z); - player->setOutPower(outMagnitude,outAngle,FALSE); - } - } - else { - // Waterfall is an elliptic cylinder - cXyz vectorToPlayer = player->current.pos - current.pos; - - mDoMtx_YrotS(mDoMtx_stack_c::get(), -current.angle.y); - PSMTXMultVec(mDoMtx_stack_c::get(), &vectorToPlayer, &vectorToPlayer); - - if((vectorToPlayer.x > -scale.x * 50.0f && vectorToPlayer.x < scale.x * 50.0f) && - vectorToPlayer.y > -10.0f && vectorToPlayer.y < scale.y * 100.0f) { - if(vectorToPlayer.z >= scale.z * 10.0f && vectorToPlayer.z < scale.z * 60.0f) { - player->setOutPower(outMagnitude, current.angle.y, FALSE); - } - else if(vectorToPlayer.z < scale.z * -10.0f && vectorToPlayer.z > scale.z * -60.0f) { - player->setOutPower(outMagnitude, (current.angle.y + (1 << 16)) - 0x8000, FALSE); - } - } - } -} - -int daObjWaterFall_c::draw() { - return 1; -} - -int daObjWaterFall_c::_delete() { - dComIfG_resDelete(&mPhase, l_arcName); - return 1; -} - -static int daObjWaterFall_Draw(daObjWaterFall_c* i_this) { - return i_this->draw(); -} - -static int daObjWaterFall_Execute(daObjWaterFall_c* i_this) { - return i_this->execute(); -} - -static int daObjWaterFall_Delete(daObjWaterFall_c* i_this) { - return i_this->_delete(); -} - -static int daObjWaterFall_Create(fopAc_ac_c* i_this) { - return static_cast(i_this)->create(); -}