zeldaret/tww#385 d_a_obj_drift (#1100)

* zeldaret/tww#385 d_a_obj_drift

* configure changes

* GZLJ01

* D44J01

* Not matching D44J01

* demo support

* variable cleanup

* revert new helper

* revert again

* Attempt 2

* Try to fix non-deterministic issue

* Revert tide fix

* debug mapping

* more map fixes

* Update src/d/actor/d_a_obj_drift.cpp

Co-authored-by: LagoLunatic <LagoLunatic@users.noreply.github.com>

* review comments

---------

Co-authored-by: LagoLunatic <LagoLunatic@users.noreply.github.com>
This commit is contained in:
Teddy Heidmann
2026-07-30 19:46:56 -07:00
committed by GitHub
parent 2bebe68302
commit 5063d3433c
3 changed files with 396 additions and 27 deletions
+1 -1
View File
@@ -1720,7 +1720,7 @@ config.libs = [
ActorRel(Matching, "d_a_obj_correct"),
ActorRel(Matching, "d_a_obj_dmgroom"),
ActorRel(Matching, "d_a_obj_dragonhead"),
ActorRel(NonMatching, "d_a_obj_drift"),
ActorRel(Matching, "d_a_obj_drift"),
ActorRel(Matching, "d_a_obj_eayogn"),
ActorRel(Matching, "d_a_obj_ebomzo"),
ActorRel(NonMatching, "d_a_obj_ekskz"),
+49 -3
View File
@@ -1,14 +1,28 @@
#ifndef D_A_OBJ_DRIFT_H
#define D_A_OBJ_DRIFT_H
#include "SSystem/SComponent/c_xyz.h"
#include "d/d_bg_s_movebg_actor.h"
#include "dolphin/types.h"
#include "f_op/f_op_actor.h"
#include "d/d_bg_w.h"
namespace daObjDrift {
class Act_c : public dBgS_MoveBgActor {
public:
void prm_get_type() const {}
enum Mode {
MODE_WAIT = 0x0,
MODE_ROT = 0x1,
};
enum Prm_e {
PRM_TYPE_W = 3,
PRM_TYPE_S = 0,
};
int prm_get_type() const {
return daObj::PrmAbstract(this, PRM_TYPE_W, PRM_TYPE_S);
}
virtual BOOL CreateHeap();
virtual BOOL Create();
@@ -24,13 +38,45 @@ namespace daObjDrift {
void mode_rot();
void set_mtx();
void init_mtx();
void rideCB(dBgW*, fopAc_ac_c*, fopAc_ac_c*);
static void rideCB(dBgW*, fopAc_ac_c*, fopAc_ac_c*);
void set_current();
virtual BOOL Execute(Mtx**);
virtual BOOL Draw();
static const char M_arcname[];
static const dCcD_SrcCyl M_cyl_src;
public:
/* Place member variables here */
/* 0x2C8 */ request_of_phase_process_class mPhase;
/* 0x2D0 */ J3DModel* mModel;
/* 0x2D4 */ dCcD_Stts mStts;
/* 0x310 */ dCcD_Cyl mCyl;
/* 0x440 */ int mType;
/* 0x444 */ Mtx mMtx;
/* 0x474 */ fpc_ProcID mFlowerPid;
/* 0x478 */ s32 mMode;
/* 0x47C */ f32 mRideYOff;
/* 0x480 */ f32 mTiltTargetZ;
/* 0x484 */ f32 mTiltTargetX;
/* 0x488 */ f32 mTiltVelZ;
/* 0x48C */ f32 mTiltVelX;
/* 0x490 */ f32 mTiltZ;
/* 0x494 */ f32 mTiltX;
/* 0x498 */ s16 mWavePhaseX;
/* 0x49A */ s16 mWavePhaseY;
/* 0x49C */ s16 mWavePhaseZ;
/* 0x49E */ bool mRideFlag;
/* 0x49F */ u8 field_0x49F;
/* 0x4A0 */ s16 mTargetAngleY;
/* 0x4A2 */ s16 mAngleChaseY;
/* 0x4A4 */ cXyz mHitDir;
/* 0x4B0 */ cXyz field_0x4B0;
/* 0x4BC */ cXyz mPrevPos;
/* 0x4C8 */ f32 field_0x4C8;
/* 0x4CC */ f32 field_0x4CC;
/* 0x4D0 */ f32 field_0x4D0;
/* 0x4D4 */ f32 field_0x4D4;
/* 0x4D8 */ f32 mRotTimer;
};
};
+346 -23
View File
@@ -5,95 +5,418 @@
#include "d/dolzel_rel.h" // IWYU pragma: keep
#include "d/actor/d_a_obj_drift.h"
#include "d/actor/d_a_player.h"
#include "res/Object/Kryu.h"
namespace daObjDrift {
namespace {
struct Attr_c {
/* 0x00 */ f32 mWaveHeight;
/* 0x04 */ f32 mWaveSpeed;
/* 0x08 */ f32 mWavePhase;
/* 0x0C */ f32 mWaveAmplitude;
/* 0x10 */ f32 mRideYOff;
/* 0x14 */ s16 mWavePhaseXStep;
/* 0x16 */ s16 field_0x16;
/* 0x18 */ f32 mWaveSinScale;
/* 0x1C */ f32 field_0x1C;
/* 0x20 */ f32 mTiltChaseWait;
/* 0x24 */ f32 mTiltChaseRot;
/* 0x28 */ f32 mPosMoveDamp;
/* 0x2C */ s16 mWavePhaseYStep;
/* 0x2E */ s16 mWavePhaseZStep;
/* 0x30 */ f32 mTiltSinScale;
/* 0x34 */ f32 field_0x34;
/* 0x38 */ s16 field_0x38;
/* 0x3A */ s16 field_0x3A;
/* 0x3C */ s16 mRotTimerMax;
/* 0x3E */ s16 field_0x3E;
};
static const Attr_c L_attr = {
/* mWaveHeight */ 500.0f,
/* mWaveSpeed */ 0.04f,
/* mWavePhase */ 0.01f,
/* mWaveAmplitude */ 0.02f,
/* mRideYOff */ -20.0f,
/* mWavePhaseXStep */ 400,
/* field_0x16 */ 0,
/* mWaveSinScale */ 0.3f,
/* field_0x1C */ 0.12f,
/* mTiltChaseWait */ 0.8f,
/* mTiltChaseRot */ 0.5f,
/* mPosMoveDamp */ 0.07f,
/* mWavePhaseYStep */ 1000,
/* mWavePhaseZStep */ 1111,
/* mTiltSinScale */ 0.01f,
/* field_0x34 */ 0.5f,
/* field_0x38 */ 30,
/* field_0x3A */ 30,
/* mRotTimerMax */ 10,
/* field_0x3E */ 0,
};
inline const Attr_c& attr() { return L_attr; }
} // namespace
} // namespace daObjDrift
const char daObjDrift::Act_c::M_arcname[] = "Kryu"; /* 0x40 */
const dCcD_SrcCyl daObjDrift::Act_c::M_cyl_src = { /* 0x48 */
{
/* Flags */ 0,
/* SrcObjAt Type */ 0,
/* SrcObjAt Atp */ 0,
/* SrcObjAt SPrm */ 0,
/* SrcObjTg Type */ AT_TYPE_WIND,
/* SrcObjTg SPrm */ cCcD_TgSPrm_Set_e | cCcD_TgSPrm_IsOther_e,
/* SrcObjCo SPrm */ 0,
/* SrcGObjAt Se */ 0,
/* SrcGObjAt HitMark */ 0,
/* SrcGObjAt Spl */ 0,
/* SrcGObjAt Mtrl */ 0,
/* SrcGObjAt SPrm */ 0,
/* SrcGObjTg Se */ 0,
/* SrcGObjTg HitMark */ 0,
/* SrcGObjTg Spl */ 0,
/* SrcGObjTg Mtrl */ 0,
/* SrcGObjTg SPrm */ 0,
/* SrcGObjCo SPrm */ 0,
},
{{
/* Center */ {0.0f, 0.0f, 0.0f},
/* Radius */ 300.0f,
/* Height */ 600.0f,
}},
};
/* 000000EC-000001A0 .text CreateHeap__Q210daObjDrift5Act_cFv */
BOOL daObjDrift::Act_c::CreateHeap() {
/* Nonmatching */
J3DModelData* model_data = (J3DModelData*)dComIfG_getObjectRes(M_arcname, dRes_INDEX_KRYU_BDL_RYU_00_e);
JUT_ASSERT(0x13A, model_data != NULL);
mModel = mDoExt_J3DModel__create(model_data, 0x80000, 0x11000022);
return mModel != NULL;
}
/* 000001A0-00000370 .text Create__Q210daObjDrift5Act_cFv */
BOOL daObjDrift::Act_c::Create() {
/* Nonmatching */
f32 L_waterY[2];
fopAcM_SetMtx(this, mModel->getBaseTRMtx());
init_mtx();
fopAcM_setCullSizeBox(this, -550.0f, -180.0f, -550.0f, 550.0f, 605.0f, 550.0f);
mStts.Init(0xFF, 0xFF, this);
mCyl.Set(M_cyl_src);
mCyl.SetStts(&mStts);
mCyl.SetTgVec((cXyz&)cXyz::Zero);
mCyl.OnTgNoHitMark();
make_flower();
mpBgW->SetRideCallback(rideCB);
mode_wait_init();
if (fopAcM_getWaterY(&home.pos, L_waterY)) {
eyePos.y = L_waterY[0];
}
mRideYOff = 0.0f;
mTiltTargetZ = 0.0f;
mTiltTargetX = 0.0f;
mTiltVelZ = 0.0f;
mTiltVelX = 0.0f;
mTiltZ = 0.0f;
mTiltX = 0.0f;
mWavePhaseX = cM_rndFX(32768.0f);
mWavePhaseY = cM_rndFX(32768.0f);
mWavePhaseZ = cM_rndFX(32768.0f);
mRideFlag = FALSE;
mTargetAngleY = 0;
mAngleChaseY = 0;
mHitDir.set((cXyz&)cXyz::Zero);
field_0x4B0.setall(5.0f);
mPrevPos.set(current.pos);
f32 prevY = mPrevPos.y;
field_0x4C8 = prevY;
field_0x4CC = prevY;
// f32 endZero = 0.0f;
field_0x4D0 = 0.0f;
field_0x4D4 = 0.0f;
return TRUE;
}
/* 00000370-0000050C .text Mthd_Create__Q210daObjDrift5Act_cFv */
cPhs_State daObjDrift::Act_c::Mthd_Create() {
/* Nonmatching */
fopAcM_ct(this, Act_c);
cPhs_State phase_state = dComIfG_resLoad(&mPhase, M_arcname);
if (phase_state == cPhs_COMPLEATE_e) {
mType = prm_get_type();
phase_state = MoveBGCreate(
M_arcname,
dRes_INDEX_KRYU_DZB_RYU_00_e,
dBgS_MoveBGProc_TypicalRotY,
DEMO_SELECT(0x8000, 0x1B80)
);
JUT_ASSERT(0x19B, (phase_state == cPhs_COMPLEATE_e) || (phase_state == cPhs_ERROR_e));
}
return phase_state;
}
/* 0000075C-000007EC .text make_flower__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::make_flower() {
/* Nonmatching */
if (mType >= 0 && mType <= 1) {
cXyz pos;
csXyz angle;
calc_flower_param(&pos, &angle);
static const s16 pf_name[2] = {fpcNm_JBO_e, fpcNm_BO_e};
mFlowerPid = fopAcM_create(
pf_name[mType],
0,
&pos,
fopAcM_GetHomeRoomNo(this),
&angle,
NULL,
-1,
NULL);
} else {
mFlowerPid = fpcM_ERROR_PROCESS_ID_e;
}
}
/* 000007EC-00000890 .text calc_flower_param__Q210daObjDrift5Act_cFP4cXyzP5csXyz */
void daObjDrift::Act_c::calc_flower_param(cXyz*, csXyz*) {
/* Nonmatching */
void daObjDrift::Act_c::calc_flower_param(cXyz* i_pos, csXyz* i_angle) {
static cXyz offset_vec(-489.35f, 600.0f, 0.0f);
mDoMtx_multVec(mMtx, &offset_vec, i_pos);
mDoMtx_MtxToRot(mMtx, i_angle);
}
/* 00000890-00000954 .text set_flower_current__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::set_flower_current() {
/* Nonmatching */
if (mFlowerPid == fpcM_ERROR_PROCESS_ID_e) {
return;
}
fopAc_ac_c* flower = fopAcM_SearchByID(mFlowerPid);
if (flower != NULL) {
cXyz pos;
csXyz angle;
calc_flower_param(&pos, &angle);
flower->current.pos = pos;
if (mType == 0) {
flower->shape_angle = angle;
} else {
flower->current.angle = angle;
}
}
}
/* 00000954-0000095C .text Delete__Q210daObjDrift5Act_cFv */
BOOL daObjDrift::Act_c::Delete() {
/* Nonmatching */
return TRUE;
}
/* 0000095C-000009A8 .text Mthd_Delete__Q210daObjDrift5Act_cFv */
BOOL daObjDrift::Act_c::Mthd_Delete() {
/* Nonmatching */
s32 ret = MoveBGDelete();
dComIfG_resDeleteDemo(&mPhase, M_arcname);
return ret;
}
/* 000009A8-000009C0 .text mode_wait_init__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::mode_wait_init() {
/* Nonmatching */
fopAcM_OnStatus(this, fopAcStts_NOCULLEXEC_e);
mMode = MODE_WAIT;
}
/* 000009C0-00000A80 .text mode_wait__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::mode_wait() {
/* Nonmatching */
if (mCyl.ChkTgHit()) {
mCyl.ClrTgHit();
if (fopAcM_searchPlayerDistanceXZ2(this) > 302500.0f) {
cXyz* l_tgrVec = mCyl.GetTgRVecP();
mHitDir.set(*l_tgrVec);
mHitDir.normalizeZP();
mode_rot_init();
}
} else {
mCyl.MoveCAtTg(current.pos);
dComIfG_Ccsp()->Set(&mCyl);
}
}
/* 00000A80-00000B38 .text mode_rot_init__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::mode_rot_init() {
/* Nonmatching */
fopAcM_OffStatus(this, fopAcStts_NOCULLEXEC_e);
mTargetAngleY = shape_angle.y + 0x8000;
mAngleChaseY = 0;
shape_angle.y += 10;
mRotTimer = 0.0f;
mMode = MODE_ROT;
fopAcM_seStart(this, JA_SE_OBJ_RYUBOKU_MOVE, 0);
}
/* 00000B38-00000C3C .text mode_rot__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::mode_rot() {
/* Nonmatching */
s16 yDiff = mTargetAngleY - shape_angle.y;
if (yDiff <= 0) {
shape_angle.y = mTargetAngleY;
mHitDir.set(cXyz::Zero);
mode_wait_init();
} else {
if (yDiff < 0x2000) {
cLib_chaseS(&mAngleChaseY, 0x14, 0xA);
} else {
cLib_chaseS(&mAngleChaseY, 0x190, 0x14);
}
shape_angle.y += mAngleChaseY;
}
if (mRotTimer >= attr().mRotTimerMax) {
mRotTimer = 0.0f;
field_0x4D0 = 1.0f;
} else {
mRotTimer += 1.0f;
}
}
/* 00000C3C-00000D18 .text set_mtx__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::set_mtx() {
/* Nonmatching */
mDoMtx_stack_c::transS(current.pos);
Quaternion quat;
cXyz axis(mTiltX, 1.0f, mTiltZ);
daObj::quat_rotBaseY2(&quat, axis);
mDoMtx_stack_c::quatM(&quat);
mDoMtx_stack_c::ZXYrotM(shape_angle);
mModel->setBaseTRMtx(mDoMtx_stack_c::get());
cMtx_copy(mDoMtx_stack_c::get(), mMtx);
field_0x4CC = field_0x4C8;
field_0x4C8 = mPrevPos.y;
mDoMtx_multVecZero(mDoMtx_stack_c::get(), &mPrevPos);
}
/* 00000D18-00000D54 .text init_mtx__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::init_mtx() {
/* Nonmatching */
mModel->setBaseScale(scale);
set_mtx();
}
/* 00000D54-00000EC4 .text rideCB__Q210daObjDrift5Act_cFP4dBgWP10fopAc_ac_cP10fopAc_ac_c */
void daObjDrift::Act_c::rideCB(dBgW*, fopAc_ac_c*, fopAc_ac_c*) {
/* Nonmatching */
void daObjDrift::Act_c::rideCB(dBgW*, fopAc_ac_c* i_this, fopAc_ac_c* i_ride) {
Act_c* drift = (Act_c*)i_this;
daPy_py_c* player = (daPy_py_c*)i_ride;
if (fopAcM_GetProfName(player) != fpcNm_PLAYER_e) {
return;
}
f32 ratio = 1.0f / attr().mWaveHeight;
drift->mRideYOff = attr().mRideYOff;
cXyz delta;
cXyz localDelta;
Mtx invMtx;
delta = player->current.pos - drift->current.pos;
if (PSMTXInverse(drift->mMtx, invMtx) &&
!dComIfGp_checkPlayerStatus0(0, daPyStts0_HANG_e)) {
mDoMtx_multVecSR(invMtx, &delta, &localDelta);
f32 sqMag = localDelta.abs2XZ();
if (localDelta.y < 400.0f) {
if (sqMag < 129600.0f) {
drift->mRideFlag = TRUE;
}
} else if (localDelta.y < 550.0f) {
if (sqMag < 48400.0f) {
drift->mRideFlag = TRUE;
}
}
} else {
drift->mRideFlag = TRUE;
}
if (drift->mRideFlag == FALSE) {
drift->mTiltTargetZ = delta.z * (ratio * attr().field_0x1C);
drift->mTiltTargetX = delta.x * (ratio * attr().field_0x1C);
}
}
/* 00000EC4-00001104 .text set_current__Q210daObjDrift5Act_cFv */
void daObjDrift::Act_c::set_current() {
/* Nonmatching */
f32 y = mRideYOff + home.pos.y;
mWavePhaseX += attr().mWavePhaseXStep;
f32 sinVal = cM_ssin(mWavePhaseX);
f32 yDelta = y - current.pos.y;
gravity = yDelta * attr().mWaveAmplitude
+ sinVal * attr().mWaveSinScale;
daObj::posMoveF_stream(this, NULL, &cXyz::Zero, attr().mWaveSpeed, attr().mWavePhase);
#if VERSION == VERSION_DEMO
f32 rotFactor;
f32 chaseFactor;
#else
f32 chaseFactor;
f32 rotFactor;
#endif
if (mRideFlag != 0) {
rotFactor = 0.2f;
} else {
rotFactor = 1.0f;
}
if (mMode == MODE_ROT) {
chaseFactor = attr().mTiltChaseRot;
} else {
chaseFactor = attr().mTiltChaseWait;
}
mHitDir *= 0.95f;
mWavePhaseY += attr().mWavePhaseYStep;
mWavePhaseZ += attr().mWavePhaseZStep;
f32 diffZ = mTiltZ - mTiltTargetZ;
f32 diffX = mTiltX - mTiltTargetX;
f32 sinY = cM_ssin(mWavePhaseY);
f32 z_val = mHitDir.z * attr().field_0x34
+ (rotFactor * (sinY * attr().mTiltSinScale)
- diffZ * chaseFactor);
f32 sinZ = cM_ssin(mWavePhaseZ);
f32 x_val = mHitDir.x * attr().field_0x34
+ (rotFactor * (sinZ * attr().mTiltSinScale)
- diffX * chaseFactor);
mTiltVelZ += z_val;
mTiltVelX += x_val;
mTiltVelZ *= attr().mPosMoveDamp;
mTiltVelX *= attr().mPosMoveDamp;
mTiltZ += mTiltVelZ;
mTiltX += mTiltVelX;
mRideYOff = 0.0f;
mTiltTargetZ = 0.0f;
mTiltTargetX = 0.0f;
mRideFlag = FALSE;
}
/* 00001104-000011D0 .text Execute__Q210daObjDrift5Act_cFPPA3_A4_f */
BOOL daObjDrift::Act_c::Execute(Mtx**) {
/* Nonmatching */
BOOL daObjDrift::Act_c::Execute(Mtx** mtx) {
typedef void (daObjDrift::Act_c::*procFunc)();
static procFunc mode_proc[] = {
&daObjDrift::Act_c::mode_wait,
&daObjDrift::Act_c::mode_rot,
};
(this->*mode_proc[mMode])();
set_current();
set_mtx();
*mtx = &mMtx;
set_flower_current();
return TRUE;
}
/* 000011D0-00001270 .text Draw__Q210daObjDrift5Act_cFv */
BOOL daObjDrift::Act_c::Draw() {
/* Nonmatching */
g_env_light.settingTevStruct(TEV_TYPE_BG0, &current.pos, &tevStr);
g_env_light.setLightTevColorType(mModel, &tevStr);
dComIfGd_setListBG();
mDoExt_modelUpdateDL(mModel);
dComIfGd_setList();
return TRUE;
}
namespace daObjDrift {
@@ -115,12 +438,12 @@ BOOL Mthd_Execute(void* i_this) {
/* 000012D0-000012FC .text Mthd_Draw__Q210daObjDrift27@unnamed@d_a_obj_drift_cpp@FPv */
BOOL Mthd_Draw(void* i_this) {
return ((daObjDrift::Act_c*)i_this)->Draw();
return ((daObjDrift::Act_c*)i_this)->MoveBGDraw();
}
/* 000012FC-00001328 .text Mthd_IsDelete__Q210daObjDrift27@unnamed@d_a_obj_drift_cpp@FPv */
BOOL Mthd_IsDelete(void* i_this) {
return ((daObjDrift::Act_c*)i_this)->IsDelete();
return ((daObjDrift::Act_c*)i_this)->MoveBGIsDelete();
}
static actor_method_class Mthd_Table = {