mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-02 09:39:48 -04:00
477 lines
14 KiB
C++
477 lines
14 KiB
C++
/**
|
|
* @file d_a_obj_lv3Water.cpp
|
|
*
|
|
*/
|
|
|
|
#include "d/dolzel_rel.h" // IWYU pragma: keep
|
|
|
|
#include "d/actor/d_a_obj_lv3Water.h"
|
|
#include "JSystem/J3DGraphBase/J3DMaterial.h"
|
|
#include "d/d_bg_w.h"
|
|
#include "d/d_com_inf_game.h"
|
|
#include "f_pc/f_pc_name.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();
|
|
virtual ~daLv3Water_HIO_c() {}
|
|
|
|
void genMessage(JORMContext*);
|
|
|
|
/* 0x00 */ /* vtable */
|
|
/* 0x04 */ u8 mLevelControlWaitFrames;
|
|
};
|
|
|
|
daLv3Water_HIO_c::daLv3Water_HIO_c() {
|
|
mLevelControlWaitFrames = 0;
|
|
}
|
|
|
|
#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);
|
|
mDoMtx_stack_c::YrotM(shape_angle.y);
|
|
|
|
mpModel2->setBaseScale(scale);
|
|
mpModel2->setBaseTRMtx(mDoMtx_stack_c::get());
|
|
}
|
|
|
|
mDoMtx_stack_c::transS(current.pos.x, current.pos.y, current.pos.z);
|
|
mDoMtx_stack_c::YrotM(shape_angle.y);
|
|
|
|
mpModel1->setBaseScale(scale);
|
|
mpModel1->setBaseTRMtx(mDoMtx_stack_c::get());
|
|
}
|
|
|
|
static const int l_bmdIdx[] = {
|
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
|
};
|
|
|
|
static const int l_dzbIdx[] = {
|
|
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11,
|
|
};
|
|
|
|
static const int l_btkIdx[] = {
|
|
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
|
|
};
|
|
|
|
static const int l_bmdIdrIdx[] = {
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -1, -1,
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
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) {
|
|
modelData = (J3DModelData*)dComIfG_getObjectRes(l_resNameIdx[mType], l_bmdIdrIdx[mType]);
|
|
|
|
JUT_ASSERT(404, modelData != NULL);
|
|
|
|
mpModel2 = mDoExt_J3DModel__create(modelData, 0x80000, 0x19000284);
|
|
|
|
if (mpModel2 == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
res = mBtk2.init(modelData, (J3DAnmTextureSRTKey*)dComIfG_getObjectRes(l_resNameIdx[mType], l_btkIdrIdx[mType]),
|
|
TRUE, J3DFrameCtrl::EMode_LOOP, 1.0f, 0, -1);
|
|
} else {
|
|
mpModel2 = NULL;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
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();
|
|
|
|
int phase = dComIfG_resLoad(&mPhase, l_resNameIdx[mType]);
|
|
|
|
if (phase == cPhs_COMPLEATE_e) {
|
|
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;
|
|
}
|
|
|
|
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 (!mSwInitialState) {
|
|
if (mpBgW != NULL) {
|
|
dComIfG_Bgsp().Release(mpBgW);
|
|
}
|
|
mSwStatePostEvent = false; // Water is not raised upon creation, ensure it is drawn accordingly
|
|
} else if (mType == 1) {
|
|
current.pos.y = home.pos.y + mWaterLv;
|
|
}
|
|
} 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();
|
|
|
|
if (mpModel2 != NULL) {
|
|
mBtk2.play();
|
|
}
|
|
|
|
eventUpdate();
|
|
mSwCurrentState = fopAcM_isSwitch(this, getParam(0, 8));
|
|
(this->*l_mode_func[mMode])();
|
|
effectSet();
|
|
*i_mtx = &mpModel1->getBaseTRMtx();
|
|
setBaseMtx();
|
|
|
|
return 1;
|
|
}
|
|
|
|
void daLv3Water_c::effectSet() {
|
|
switch (mType) {
|
|
case 8:
|
|
if (fopAcM_isSwitch(this, 8)) {
|
|
mEmitterIDs[0] =
|
|
dComIfGp_particle_set(mEmitterIDs[0], 0X8AB2, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[1] =
|
|
dComIfGp_particle_set(mEmitterIDs[1], 0X8AB3, ¤t.pos, NULL, NULL);
|
|
}
|
|
break;
|
|
case 9:
|
|
if (mSwInitialState) {
|
|
mEmitterIDs[0] =
|
|
dComIfGp_particle_set(mEmitterIDs[0], 0X8AB4, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[1] =
|
|
dComIfGp_particle_set(mEmitterIDs[1], 0X8AB5, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[2] =
|
|
dComIfGp_particle_set(mEmitterIDs[2], 0X8AB6, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[3] =
|
|
dComIfGp_particle_set(mEmitterIDs[3], 0X8AB7, ¤t.pos, NULL, NULL);
|
|
}
|
|
break;
|
|
case 1:
|
|
if (fopAcM_isSwitch(this, 8)) {
|
|
mEmitterIDs[0] =
|
|
dComIfGp_particle_set(mEmitterIDs[0], 0x8AB9, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[1] =
|
|
dComIfGp_particle_set(mEmitterIDs[1], 0x8ABA, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[2] =
|
|
dComIfGp_particle_set(mEmitterIDs[2], 0x8ABB, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[3] =
|
|
dComIfGp_particle_set(mEmitterIDs[3], 0x8ABC, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[4] =
|
|
dComIfGp_particle_set(mEmitterIDs[4], 0x8AB8, ¤t.pos, NULL, NULL);
|
|
}
|
|
break;
|
|
case 14:
|
|
if (fopAcM_isSwitch(this, 9)) {
|
|
mEmitterIDs[0] =
|
|
dComIfGp_particle_set(mEmitterIDs[0], 0X8ABF, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[1] =
|
|
dComIfGp_particle_set(mEmitterIDs[1], 0X8AC0, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[2] =
|
|
dComIfGp_particle_set(mEmitterIDs[2], 0X8AC1, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[3] =
|
|
dComIfGp_particle_set(mEmitterIDs[3], 0X8AC2, ¤t.pos, NULL, NULL);
|
|
}
|
|
break;
|
|
case 17:
|
|
if (mSwInitialState) {
|
|
mEmitterIDs[0] =
|
|
dComIfGp_particle_set(mEmitterIDs[0], 0X8AC4, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[1] =
|
|
dComIfGp_particle_set(mEmitterIDs[1], 0X8AC5, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[2] =
|
|
dComIfGp_particle_set(mEmitterIDs[2], 0X8AC6, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[3] =
|
|
dComIfGp_particle_set(mEmitterIDs[3], 0X8AC7, ¤t.pos, NULL, NULL);
|
|
}
|
|
break;
|
|
case 16:
|
|
if (mSwInitialState) {
|
|
mEmitterIDs[0] =
|
|
dComIfGp_particle_set(mEmitterIDs[0], 0X8AC8, ¤t.pos, NULL, NULL);
|
|
mEmitterIDs[1] =
|
|
dComIfGp_particle_set(mEmitterIDs[1], 0X8AC9, ¤t.pos, NULL, NULL);
|
|
}
|
|
if (fopAcM_isSwitch(this, 9)) {
|
|
mEmitterIDs[2] =
|
|
dComIfGp_particle_set(mEmitterIDs[2], 0x8AC3, ¤t.pos, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void daLv3Water_c::mode_proc_wait() {
|
|
// 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();
|
|
}
|
|
}
|
|
}
|
|
|
|
void daLv3Water_c::mode_init_levelCtrl() {
|
|
mCurrentWaterLvFrame = 0;
|
|
mLvControlWaitFrames = l_HIO.mLevelControlWaitFrames;
|
|
|
|
if (mType == 9) {
|
|
mDoAud_seStart(Z2SE_ENV_FILL_UP_LV3WTR3, ¤t.pos, 0,
|
|
dComIfGp_getReverb(fopAcM_GetRoomNo(this)));
|
|
}
|
|
|
|
mMode = LEVEL_CTRL;
|
|
}
|
|
|
|
void daLv3Water_c::mode_proc_levelCtrl() {
|
|
f32 ratioOfWaterLevelFramesAdvancedToTarget;
|
|
|
|
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;
|
|
}
|
|
|
|
mCurrentWaterLvFrame++;
|
|
if (mCurrentWaterLvFrame >= mWaterLvFrame) {
|
|
ratioOfWaterLevelFramesAdvancedToTarget = mSwInitialState;
|
|
mMode = WAIT;
|
|
}
|
|
|
|
current.pos.y = mWaterLv * ratioOfWaterLevelFramesAdvancedToTarget + home.pos.y;
|
|
}
|
|
}
|
|
|
|
int daLv3Water_c::Draw() {
|
|
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);
|
|
|
|
if (mpModel2 != NULL) {
|
|
g_env_light.setLightTevColorType_MAJI(mpModel2, &tevStr);
|
|
}
|
|
|
|
modelData = mpModel1->getModelData();
|
|
mBtk1.entry(modelData);
|
|
|
|
if (mpModel2 != NULL) {
|
|
modelData = mpModel2->getModelData();
|
|
mBtk2.entry(modelData);
|
|
}
|
|
|
|
dComIfGd_setXluListDarkBG();
|
|
mDoExt_modelUpdateDL(mpModel1);
|
|
dComIfGd_setList();
|
|
|
|
if (mpModel2 != NULL) {
|
|
modelData = mpModel2->getModelData();
|
|
material = modelData->getMaterialNodePointer(0);
|
|
|
|
dComIfGd_setListInvisisble();
|
|
|
|
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((MtxP)j3dDefaultMtx);
|
|
}
|
|
}
|
|
|
|
mDoExt_modelUpdateDL(mpModel2);
|
|
dComIfGd_setList();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int daLv3Water_c::Delete() {
|
|
dComIfG_resDelete(&mPhase, l_resNameIdx[mType]);
|
|
|
|
#if DEBUG
|
|
l_HIO.removeHIO();
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
bool daLv3Water_c::eventStart() {
|
|
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 + mWaterLv;
|
|
}
|
|
mSwStatePostEvent = mSwCurrentState;
|
|
mMode = WAIT;
|
|
} else {
|
|
mode_init_levelCtrl();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static int daLv3Water_Draw(daLv3Water_c* i_this) {
|
|
return i_this->MoveBGDraw();
|
|
}
|
|
|
|
static int daLv3Water_Execute(daLv3Water_c* i_this) {
|
|
return i_this->MoveBGExecute();
|
|
}
|
|
|
|
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) {
|
|
daLv3Water_c* const actor = static_cast<daLv3Water_c*>(i_this);
|
|
fopAcM_RegisterCreateID(i_this, "daLv3Water");
|
|
return actor->create();
|
|
}
|
|
|
|
static actor_method_class l_daLv3Water_Method = {
|
|
(process_method_func)daLv3Water_Create, (process_method_func)daLv3Water_Delete,
|
|
(process_method_func)daLv3Water_Execute, 0,
|
|
(process_method_func)daLv3Water_Draw,
|
|
};
|
|
|
|
actor_process_profile_definition g_profile_Obj_Lv3Water = {
|
|
/* Layer ID */ fpcLy_CURRENT_e,
|
|
/* List ID */ 3,
|
|
/* List Prio */ fpcPi_CURRENT_e,
|
|
/* Proc Name */ fpcNm_Obj_Lv3Water_e,
|
|
/* Proc SubMtd */ &g_fpcLf_Method.base,
|
|
/* Size */ sizeof(daLv3Water_c),
|
|
/* Size Other */ 0,
|
|
/* Parameters */ 0,
|
|
/* Leaf SubMtd */ &g_fopAc_Method.base,
|
|
/* Draw Prio */ fpcDwPi_Obj_Lv3Water_e,
|
|
/* Actor SubMtd */ &l_daLv3Water_Method,
|
|
/* Status */ fopAcStts_UNK_0x40000_e | fopAcStts_UNK_0x4000_e,
|
|
/* Group */ fopAc_ACTOR_e,
|
|
/* Cull Type */ fopAc_CULLBOX_CUSTOM_e,
|
|
};
|