/** * 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, };