#include "d/a/obj/d_a_obj_block_underground.h" #include "c/c_list.h" #include "common.h" #include "d/a/d_a_player.h" #include "d/a/obj/d_a_obj_base.h" #include "d/col/bg/d_bg_s.h" #include "d/col/cc/d_cc_d.h" #include "d/col/cc/d_cc_s.h" #include "d/flag/sceneflag_manager.h" #include "d/snd/d_snd_small_effect_mgr.h" #include "f/f_base.h" #include "f/f_list_nd.h" #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/g3d/res/g3d_resmdl.h" #include "toBeSorted/d_emitter.h" SPECIAL_ACTOR_PROFILE(OBJ_BLOCK_UNDERGROUND, dAcOBlockUnderground, fProfile::OBJ_BLOCK_UNDERGROUND, 0x13F, 0, 3); const dAcOBlockUnderground::SubtypeData dAcOBlockUnderground::sSubtypeData[4] = { {0, 0, 0}, {1, 1, 1}, {2, 2, 2}, {3, 1, 1}, }; const char *const dAcOBlockUnderground::sOarcName = "MoleBlock"; const char *const dAcOBlockUnderground::sMdlNames[4] = { "MoleBlock", "MoleBlockBomb", "MoleBlockBreak", "MoleBlockBreak", }; const char *const dAcOBlockUnderground::sDzbPlcNames[4] = { "MoleBlock_rock", "MoleBlock_rock", "MoleBlock_tuti", "MoleBlock_tuti", }; const dCcD_SrcCyl dAcOBlockUnderground::sCylSrc = { /* mObjInf */ {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, /* mObjTg */ {AT_TYPE_BOMB, 0x11, {0, 8, 0x407}, 0x0, 0x0}, /* mObjCo */ {0}}, /* mCylInf */ {50.f, 100.f} }; u32 dAcOBlockUnderground::getCylTgType() { return AT_TYPE_0x20000 | AT_TYPE_BOMB; } const char *dAcOBlockUnderground::getOarcName() { return sOarcName; } extern "C" cListMg_c *fn_8018B840(); // d_underground dAcOBlockUnderground::dAcOBlockUnderground() : mRef(this), mUndergroundRef(nullptr) { fn_8018B840()->append(&mRef); } dAcOBlockUnderground::~dAcOBlockUnderground() { fn_8018B840()->remove(&mRef); delete mCyl; } bool dAcOBlockUnderground::createHeap() { const char *oarcName = getOarcName(); void *data = getOarcResFile(oarcName); if (data == nullptr) { return false; } nw4r::g3d::ResFile resFile(data); if (!resFile.IsValid()) { return false; } const char *mdlName = getMdlName(); nw4r::g3d::ResMdl mdl = resFile.GetResMdl(mdlName); if (!mdl.IsValid()) { return false; } if (!mMdl.create(mdl, &mAllocator, 0x120, 1, nullptr)) { return false; } void *dzb = getOarcDZB(getOarcName(), sDzbPlcNames[getMdlDzbPlcIdx()]); if (dzb == nullptr) { return false; } void *plc = getOarcPLC(getOarcName(), sDzbPlcNames[getMdlDzbPlcIdx()]); if (plc == nullptr) { return false; } bool result = !mBgW.Set((cBgD_t *)dzb, (PLC *)plc, cBgW::MOVE_BG_e, &mWorldMtx, &mScale); if (!result) { return false; } if (hasCyl()) { mCyl = new dCcD_Cyl(); if (mCyl == nullptr) { return false; } } return true; } int dAcOBlockUnderground::actorCreate() { u8 sceneFlag = getSecondSceneFlag(); if (sceneFlag < 0xFF && SceneflagManager::sInstance->checkBoolFlag(mRoomID, sceneFlag)) { return FAILED; } bool success = false; s32 newSubtype = 0; u8 subtype = getSubtype(); const SubtypeData *subtypeData = &sSubtypeData[0]; while ((!success && newSubtype <= 3)) { if (subtype == subtypeData->mSubtype) { success = true; } else { subtypeData++; newSubtype++; } } if (success) { setSubtype(newSubtype); } else { return FAILED; } updateMatrix(); CREATE_ALLOCATOR(dAcOBlockUnderground); mMdl.setLocalMtx(mWorldMtx); mMdl.setPriorityDraw(0x82, 0x7F); if (hasCyl()) { mStts.SetRank(0xD); mCyl->Set(sCylSrc); mCyl->SetStts(mStts); if (shouldSetCylTgType()) { mCyl->mTg.mSrc.mType = getCylTgType(); } mCyl->SetC(mPosition); } mBgW.Move(); mVec3_c min, max; mMdl.getBounds(&min, &max); mBoundingBox.Set(min, max); return SUCCEEDED; } int dAcOBlockUnderground::actorPostCreate() { if (mBgW.ChkUsed()) { mBgW.Lock(); return SUCCEEDED; } registBg(); return NOT_READY; } int dAcOBlockUnderground::actorExecute() { if (hasCyl()) { if (mCyl->ChkTgHit()) { if (mUndergroundRef.p_owner != nullptr) { mUndergroundRef.get()->fn_458_9D0(field_0x57C, field_0x57E); } if (getSubtype() == 1) { spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_461_); dSndSmallEffectMgr_c::GetInstance()->playSoundAtPosition(SE_BlockUg_BROKEN_BOMB, mPosition); } else { spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_462_); dSndSmallEffectMgr_c::GetInstance()->playSoundAtPosition(SE_BlockUg_BROKEN_CLAW, mPosition); } u8 firstSceneFlag = getFirstSceneFlag(); if (firstSceneFlag < 0xFF) { SceneflagManager::sInstance->setFlag(mRoomID, firstSceneFlag); } u8 secondSceneFlag = getSecondSceneFlag(); if (secondSceneFlag < 0xFF) { SceneflagManager::sInstance->setFlag(mRoomID, secondSceneFlag); } deleteRequest(); } else if (dAcPy_c::GetLink()->checkActionFlagsCont(0x400000)) { dCcS::GetInstance()->Set(mCyl); } } return SUCCEEDED; } int dAcOBlockUnderground::draw() { if (dAcPy_c::GetLink()->checkActionFlagsCont(0x400000)) { drawModelType1(&mMdl); } return SUCCEEDED; } void dAcOBlockUnderground::setUndergroundRef(dAcOUnderground_c *underground) { mUndergroundRef.link(underground); } bool dAcOBlockUnderground::undergroundRefEquals(dAcOUnderground_c *underground) { return underground == mUndergroundRef.p_owner; } void dAcOBlockUnderground::setBlockUndergroundPosition(mVec3_c *pos) { setPosition(*pos); updateMatrix(); mMdl.setLocalMtx(mWorldMtx); if (hasCyl()) { mCyl->SetC(*pos); } mBgW.Move(); } void dAcOBlockUnderground::fn_459_840(u16 _field_0x57C, u16 _field_0x57E) { field_0x57C = _field_0x57C; field_0x57E = _field_0x57E; } u16 dAcOBlockUnderground::getField_0x57C() { return field_0x57C; } u16 dAcOBlockUnderground::getField_0x57E() { return field_0x57E; } void dAcOBlockUnderground::registBg() { dBgS::GetInstance()->Regist(&mBgW, this); } void dAcOBlockUnderground::releaseBg() { dBgS::GetInstance()->Release(&mBgW); } void dAcOBlockUnderground::setSubtype(u32 subtype) { mSubtype = subtype; } u8 dAcOBlockUnderground::getSubtype() { return getFromParams(0, 0xFF); } u8 dAcOBlockUnderground::getFirstSceneFlag() { return getFromParams(8, 0xFF); } u8 dAcOBlockUnderground::getSecondSceneFlag() { return getFromParams(16, 0xFF); } u32 dAcOBlockUnderground::getSubtypeCylVariant() { return sSubtypeData[mSubtype].mCylVariant; } u32 dAcOBlockUnderground::getMdlDzbPlcIdx() { return sSubtypeData[mSubtype].mMdlDzbPlcIdx; } bool dAcOBlockUnderground::noCyl() { return getSubtypeCylVariant() == 0; } bool dAcOBlockUnderground::shouldSetCylTgType() { return getSubtypeCylVariant() == 2; } const char *dAcOBlockUnderground::getMdlName() { return sMdlNames[getMdlDzbPlcIdx()]; } bool dAcOBlockUnderground::hasCyl() { return !noCyl(); } void dAcOBlockUnderground::spawnEffect(u16 effectResourceId) const { mVec3_c pos(mPosition.x, mPosition.y + 50.f, mPosition.z); dJEffManager_c::spawnEffect(effectResourceId, pos, nullptr, nullptr, nullptr, nullptr, 0, 0); }