mirror of
https://github.com/zeldaret/tww.git
synced 2026-08-18 21:18:23 -04:00
460 lines
14 KiB
C++
460 lines
14 KiB
C++
/**
|
|
* d_a_obj_drift.cpp
|
|
* Object - Floating tree platform
|
|
*/
|
|
|
|
#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";
|
|
|
|
const dCcD_SrcCyl daObjDrift::Act_c::M_cyl_src = {
|
|
{
|
|
/* 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() {
|
|
J3DModelData* model_data = (J3DModelData*)dComIfG_getObjectRes(M_arcname, dRes_INDEX_KRYU_BDL_RYU_00_e);
|
|
JUT_ASSERT(314, 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() {
|
|
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();
|
|
f32 waterY;
|
|
if (fopAcM_getWaterY(&home.pos, &waterY)) {
|
|
eyePos.y = waterY;
|
|
}
|
|
|
|
mRideYOff = 0.0f;
|
|
mTiltTargetZ = 0.0f;
|
|
mTiltTargetX = 0.0f;
|
|
mTiltVelZ = 0.0f;
|
|
mTiltVelX = 0.0f;
|
|
mTiltZ = 0.0f;
|
|
mTiltX = 0.0f;
|
|
|
|
mWavePhaseX = cM_rndFX(0x8000);
|
|
mWavePhaseY = cM_rndFX(0x8000);
|
|
mWavePhaseZ = cM_rndFX(0x8000);
|
|
mRideFlag = FALSE;
|
|
|
|
mTargetAngleY = 0;
|
|
mAngleChaseY = 0;
|
|
|
|
mHitDir.set(cXyz::Zero);
|
|
field_0x4B0.setall(5.0f);
|
|
mPrevPos.set(current.pos);
|
|
f32 prevY = mPrevPos.y;
|
|
field_0x4C8 = prevY;
|
|
field_0x4CC = prevY;
|
|
|
|
field_0x4D0 = 0.0f;
|
|
field_0x4D4 = 0.0f;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* 00000370-0000050C .text Mthd_Create__Q210daObjDrift5Act_cFv */
|
|
cPhs_State daObjDrift::Act_c::Mthd_Create() {
|
|
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(411, (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() {
|
|
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
|
|
);
|
|
} else {
|
|
mFlowerPid = fpcM_ERROR_PROCESS_ID_e;
|
|
}
|
|
}
|
|
|
|
/* 000007EC-00000890 .text calc_flower_param__Q210daObjDrift5Act_cFP4cXyzP5csXyz */
|
|
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() {
|
|
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() {
|
|
return TRUE;
|
|
}
|
|
|
|
/* 0000095C-000009A8 .text Mthd_Delete__Q210daObjDrift5Act_cFv */
|
|
BOOL daObjDrift::Act_c::Mthd_Delete() {
|
|
BOOL ret = MoveBGDelete();
|
|
dComIfG_resDeleteDemo(&mPhase, M_arcname);
|
|
return ret;
|
|
}
|
|
|
|
/* 000009A8-000009C0 .text mode_wait_init__Q210daObjDrift5Act_cFv */
|
|
void daObjDrift::Act_c::mode_wait_init() {
|
|
fopAcM_OnStatus(this, fopAcStts_NOCULLEXEC_e);
|
|
mMode = MODE_WAIT;
|
|
}
|
|
|
|
/* 000009C0-00000A80 .text mode_wait__Q210daObjDrift5Act_cFv */
|
|
void daObjDrift::Act_c::mode_wait() {
|
|
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() {
|
|
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() {
|
|
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() {
|
|
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() {
|
|
mModel->setBaseScale(scale);
|
|
set_mtx();
|
|
}
|
|
|
|
/* 00000D54-00000EC4 .text rideCB__Q210daObjDrift5Act_cFP4dBgWP10fopAc_ac_cP10fopAc_ac_c */
|
|
void daObjDrift::Act_c::rideCB(dBgW*, fopAc_ac_c* i_this, fopAc_ac_c* i_ride) {
|
|
Act_c* drift = (Act_c*)i_this;
|
|
if (fopAcM_GetProfName(i_ride) != fpcNm_PLAYER_e) {
|
|
return;
|
|
}
|
|
daPy_py_c* player = (daPy_py_c*)i_ride;
|
|
|
|
f32 ratio = 1.0f / attr().mWaveHeight;
|
|
drift->mRideYOff = attr().mRideYOff;
|
|
cXyz delta = player->current.pos - drift->current.pos;
|
|
Mtx invMtx;
|
|
if (MTXInverse(drift->mMtx, invMtx) && !dComIfGp_checkPlayerStatus0(0, daPyStts0_HANG_e)) {
|
|
cXyz localDelta;
|
|
mDoMtx_multVecSR(invMtx, &delta, &localDelta);
|
|
f32 sqMag = localDelta.abs2XZ();
|
|
if (localDelta.y < 400.0f) {
|
|
if (sqMag < SQUARE(360.0f)) {
|
|
drift->mRideFlag = TRUE;
|
|
}
|
|
} else if (localDelta.y < 550.0f) {
|
|
if (sqMag < SQUARE(220.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() {
|
|
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);
|
|
f32 rotFactor = mRideFlag != 0 ? 0.2f : 1.0f;
|
|
f32 chaseFactor;
|
|
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** 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() {
|
|
g_env_light.settingTevStruct(TEV_TYPE_BG0, ¤t.pos, &tevStr);
|
|
g_env_light.setLightTevColorType(mModel, &tevStr);
|
|
dComIfGd_setListBG();
|
|
mDoExt_modelUpdateDL(mModel);
|
|
dComIfGd_setList();
|
|
return TRUE;
|
|
}
|
|
|
|
namespace daObjDrift {
|
|
namespace {
|
|
/* 00001270-00001290 .text Mthd_Create__Q210daObjDrift27@unnamed@d_a_obj_drift_cpp@FPv */
|
|
cPhs_State Mthd_Create(void* i_this) {
|
|
return ((daObjDrift::Act_c*)i_this)->Mthd_Create();
|
|
}
|
|
|
|
/* 00001290-000012B0 .text Mthd_Delete__Q210daObjDrift27@unnamed@d_a_obj_drift_cpp@FPv */
|
|
BOOL Mthd_Delete(void* i_this) {
|
|
return ((daObjDrift::Act_c*)i_this)->Mthd_Delete();
|
|
}
|
|
|
|
/* 000012B0-000012D0 .text Mthd_Execute__Q210daObjDrift27@unnamed@d_a_obj_drift_cpp@FPv */
|
|
BOOL Mthd_Execute(void* i_this) {
|
|
return ((daObjDrift::Act_c*)i_this)->MoveBGExecute();
|
|
}
|
|
|
|
/* 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)->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)->MoveBGIsDelete();
|
|
}
|
|
|
|
static actor_method_class Mthd_Table = {
|
|
(process_method_func)Mthd_Create,
|
|
(process_method_func)Mthd_Delete,
|
|
(process_method_func)Mthd_Execute,
|
|
(process_method_func)Mthd_IsDelete,
|
|
(process_method_func)Mthd_Draw,
|
|
};
|
|
}; // namespace
|
|
}; // namespace daObjDrift
|
|
|
|
actor_process_profile_definition g_profile_Obj_Drift = {
|
|
/* Layer ID */ fpcLy_CURRENT_e,
|
|
/* List ID */ 0x0002,
|
|
/* List Prio */ fpcPi_CURRENT_e,
|
|
/* Proc Name */ fpcNm_Obj_Drift_e,
|
|
/* Proc SubMtd */ &g_fpcLf_Method.base,
|
|
/* Size */ sizeof(daObjDrift::Act_c),
|
|
/* Size Other */ 0,
|
|
/* Parameters */ 0,
|
|
/* Leaf SubMtd */ &g_fopAc_Method.base,
|
|
/* Draw Prio */ fpcDwPi_Obj_Drift_e,
|
|
/* Actor SubMtd */ &daObjDrift::Mthd_Table,
|
|
/* Status */ fopAcStts_NOCULLEXEC_e | fopAcStts_CULL_e | fopAcStts_UNK40000_e,
|
|
/* Group */ fopAc_ACTOR_e,
|
|
/* Cull Type */ fopAc_CULLBOX_CUSTOM_e,
|
|
};
|