mirror of
https://github.com/zeldaret/ss
synced 2026-06-11 13:10:11 -04:00
653 lines
18 KiB
C++
653 lines
18 KiB
C++
#include "d/d_room.h"
|
|
|
|
#include "common.h"
|
|
#include "d/a/d_a_base.h"
|
|
#include "d/a/d_a_item.h"
|
|
#include "d/a/obj/d_a_obj_base.h"
|
|
#include "d/col/bg/d_bg_s.h"
|
|
#include "d/col/bg/d_bg_w_base.h"
|
|
#include "d/col/bg/d_bg_w_kcol.h"
|
|
#include "d/d_sc_game.h"
|
|
#include "d/flag/sceneflag_manager.h"
|
|
#include "d/flag/storyflag_manager.h"
|
|
#include "d/t/d_t_mass_obj.h"
|
|
#include "egg/math/eggMath.h"
|
|
#include "f/f_base.h"
|
|
#include "m/m3d/m_anmmatclr.h"
|
|
#include "m/m3d/m_anmtexpat.h"
|
|
#include "m/m3d/m_anmtexsrt.h"
|
|
#include "m/m3d/m_anmvis.h"
|
|
#include "m/m3d/m_fanm.h"
|
|
#include "m/m3d/m_smdl.h"
|
|
#include "m/m_mtx.h"
|
|
#include "m/m_vec.h"
|
|
#include "nw4r/g3d/g3d_scnmdl.h"
|
|
#include "nw4r/g3d/g3d_scnobj.h"
|
|
#include "nw4r/g3d/res/g3d_resanmclr.h"
|
|
#include "nw4r/g3d/res/g3d_resanmtexpat.h"
|
|
#include "nw4r/g3d/res/g3d_resanmtexsrt.h"
|
|
#include "nw4r/g3d/res/g3d_resanmvis.h"
|
|
#include "nw4r/g3d/res/g3d_resfile.h"
|
|
#include "nw4r/g3d/res/g3d_resmat.h"
|
|
#include "nw4r/g3d/res/g3d_resmdl.h"
|
|
#include "nw4r/g3d/res/g3d_resnode.h"
|
|
#include "nw4r/math/math_geometry.h"
|
|
#include "nw4r/math/math_types.h"
|
|
#include "sized_string.h"
|
|
#include "toBeSorted/arc_managers/current_stage_arc_manager.h"
|
|
#include "toBeSorted/room_manager.h"
|
|
#include "toBeSorted/stage_manager.h"
|
|
#include "toBeSorted/time_area_mgr.h"
|
|
#include "toBeSorted/unk_with_water.h"
|
|
|
|
SPECIAL_BASE_PROFILE(ROOM, dRoom_c, fProfile::ROOM, 0x9, 96);
|
|
|
|
STATE_DEFINE(dRoom_c, Active);
|
|
STATE_DEFINE(dRoom_c, NonActive);
|
|
|
|
extern "C" void parseRoomBzs(int roomid, void *bzs);
|
|
|
|
int dRoom_c::create() {
|
|
roomid = params & 0x3F;
|
|
field_0x573 = dStageMgr_c::GetInstance()->getSTIFunk1() == 0 &&
|
|
!(dScGame_c::isCurrentStage("D301") && roomid == 12) &&
|
|
!(dScGame_c::isCurrentStage("D303") && roomid == 12) &&
|
|
!(dScGame_c::isCurrentStage("D300") && (roomid == 0 || roomid == 1 || roomid == 4)) &&
|
|
!(dScGame_c::isCurrentStage("D300_1") && (roomid == 7 || roomid == 9));
|
|
if (!mAllocator.createNewTempFrmHeap(
|
|
-1, CurrentStageArcManager::sInstance->getHeap(roomid), "dRoom_c::m_allocator", 0x20, 0
|
|
)) {
|
|
return FAILED;
|
|
}
|
|
|
|
bool anyError = false;
|
|
|
|
mRoomRes = nw4r::g3d::ResFile(CurrentStageArcManager::sInstance->loadFromRoomArc(roomid, "g3d/room.brres"));
|
|
RoomManager::bindStageResToFile(&mRoomRes);
|
|
RoomManager::bindSkyCmnToResFile(&mRoomRes);
|
|
|
|
for (s32 i = 0; i < 8; i++) {
|
|
model_c *mdl = &mModels[i];
|
|
if (i != 2 || roomid != 1 || dScGame_c::currentSpawnInfo.layer != 14 || !dScGame_c::isCurrentStage("F406")) {
|
|
if (!mdl->create(mRoomRes, mAllocator, i, &mWaterThing)) {
|
|
anyError = true;
|
|
break;
|
|
}
|
|
if (mdl->mpAnmPat) {
|
|
mHasAnmTexPat = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!anyError) {
|
|
if (mWaterThing.hasLinks()) {
|
|
u32 val = 0;
|
|
dStageMgr_c *stageMr = dStageMgr_c::GetInstance();
|
|
if (stageMr->checkFlag0x88A0(2)) {
|
|
val = 3;
|
|
}
|
|
stageMr->initUnkWithWater(val, &mWaterThing);
|
|
}
|
|
anyError = setupBg();
|
|
}
|
|
mAllocator.adjustFrmHeapRestoreCurrent();
|
|
|
|
if (anyError) {
|
|
return FAILED;
|
|
}
|
|
|
|
RoomManager::m_Instance->setRoom(roomid, this);
|
|
BZS = CurrentStageArcManager::sInstance->loadFromRoomArc(roomid, "dat/room.bzs");
|
|
parseRoomBzs(roomid, BZS);
|
|
mDidAlreadyInit = (params >> 6) & 1;
|
|
mStateMgr.changeState(StateID_Active);
|
|
if (roomid != dScGame_c::currentSpawnInfo.room) {
|
|
mFlags |= 2;
|
|
deactivateUpdates();
|
|
}
|
|
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dRoom_c::doDelete() {
|
|
destroyModels();
|
|
if (mWaterThing.hasLinks()) {
|
|
u32 val = 0;
|
|
dStageMgr_c *stageMr = dStageMgr_c::GetInstance();
|
|
if (stageMr->checkFlag0x88A0(2)) {
|
|
val = 3;
|
|
}
|
|
stageMr->destroyUnkWithWater(val, &mWaterThing);
|
|
}
|
|
|
|
RoomManager::m_Instance->setRoom(roomid, nullptr);
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dRoom_c::execute() {
|
|
mStateMgr.executeState();
|
|
f32 val = 0.0f;
|
|
if (field_0x573) {
|
|
val = dTimeAreaMgr_c::sInstance->checkPositionIsInPastState(roomid, mVec3_c::Zero, nullptr, 1000000.0f);
|
|
field_0x576 = !mHasAnmTexPat && (!dTimeAreaMgr_c::sInstance->isInLanayruMiningFacility() || val > 0.0f) &&
|
|
dTimeAreaMgr_c::sInstance->isField0x78();
|
|
} else {
|
|
field_0x576 = false;
|
|
}
|
|
|
|
if ((mFlags & 2) != 0 || field_0x576) {
|
|
releaseBg();
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
executeBg();
|
|
for (s32 i = 0; i < 8; i++) {
|
|
mModels[i].execute(i, field_0x573, val);
|
|
}
|
|
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dRoom_c::draw() {
|
|
if ((mFlags & 2) != 0 || field_0x576) {
|
|
return SUCCEEDED;
|
|
}
|
|
for (s32 i = 0; i < 8; i++) {
|
|
mModels[i].draw(roomid);
|
|
}
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
void deactivateUpdatesCb(dAcBase_c *ac) {
|
|
if (!ac->checkActorProperty(0x400)) {
|
|
return;
|
|
}
|
|
ac->callunkVirtFunc_0x60();
|
|
}
|
|
|
|
void dRoom_c::deactivateUpdates() {
|
|
if (!field_0x572) {
|
|
foreachObject(deactivateUpdatesCb);
|
|
setProcControlFlag(ROOT_DISABLE_EXECUTE | ROOT_DISABLE_DRAW);
|
|
field_0x572 = true;
|
|
}
|
|
}
|
|
|
|
void activateUpdatesCb(dAcBase_c *ac) {
|
|
if (!ac->checkActorProperty(0x400)) {
|
|
return;
|
|
}
|
|
ac->callrestorePosRotFromCopy();
|
|
}
|
|
|
|
void dRoom_c::activateUpdates() {
|
|
if (field_0x572) {
|
|
foreachObject(activateUpdatesCb);
|
|
clearProcControlFlag(ROOT_DISABLE_EXECUTE);
|
|
clearProcControlFlag(ROOT_DISABLE_DRAW);
|
|
field_0x572 = false;
|
|
}
|
|
}
|
|
|
|
s32 dRoom_c::foreachObject(foreachObjCallback cb) {
|
|
s32 count = 0;
|
|
|
|
fBase_c *start = getConnectBrNext();
|
|
if (start == nullptr) {
|
|
start = getConnectParent();
|
|
}
|
|
|
|
for (fBase_c *base = getConnectChild(); base != nullptr && base != start; base = getConnectTreeNext(base)) {
|
|
if (base->group_type == ACTOR || base->group_type == STAGE) {
|
|
cb(static_cast<dAcBase_c *>(base));
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
struct BgData {
|
|
const char *kcl;
|
|
const char *plc;
|
|
};
|
|
|
|
static const BgData sRoomBg[] = {
|
|
{ "kcl/room.kcl", "dat/room.plc"},
|
|
{"kcl/room_n.kcl", "dat/room_n.plc"},
|
|
};
|
|
|
|
bool dRoom_c::setupBg() {
|
|
for (int i = 0; i < 2; i++) {
|
|
dBgWKCol *bg = &mBg[i];
|
|
void *kcl = CurrentStageArcManager::sInstance->getDataFromRoomArc(roomid, sRoomBg[i].kcl);
|
|
if (kcl != nullptr) {
|
|
void *plc = CurrentStageArcManager::sInstance->loadFromRoomArc(roomid, sRoomBg[i].plc);
|
|
bg->Set(kcl, plc);
|
|
bg->SetRoomId(roomid);
|
|
bg->SetPriority(dBgW_Base::PRIORITY_0);
|
|
bool ok = (BOOL)bg->InitMapStuff(&mAllocator);
|
|
if (!ok) {
|
|
return true;
|
|
}
|
|
|
|
if (field_0x573 && !mHasAnmTexPat) {
|
|
bg->SetUnkBase();
|
|
}
|
|
// ???
|
|
dBgS::GetInstance()->Regist(bg, (dAcObjBase_c *)nullptr);
|
|
dBgS::GetInstance()->RegistBg(bg, nullptr);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void dRoom_c::executeBg() {
|
|
for (int i = 0; i < 2; i++) {
|
|
if (!mBg[i].ChkNotReady()) {
|
|
dBgS::GetInstance()->Regist(&mBg[i], (dAcObjBase_c *)nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void dRoom_c::releaseBg() {
|
|
for (int i = 0; i < 2; i++) {
|
|
if (!mBg[i].ChkNotReady()) {
|
|
dBgS::GetInstance()->Release(&mBg[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void dRoom_c::drawOnMapIfVisible(mMtx_c *mtx, int param) {
|
|
bool drawFully = true;
|
|
if (dStageMgr_c::GetInstance()->isAreaTypeDungeonOrBoss()) {
|
|
drawFully = RoomManager::m_Instance->hasVisitedRoomId(roomid);
|
|
if (!drawFully && !dAcItem_c::checkFlag(/* DUNGEON_MAP_FI */ 0x32)) {
|
|
return;
|
|
}
|
|
} else {
|
|
// "new map part in lake floria"
|
|
if (dStageMgr_c::GetInstance()->isAreaTypeOverworldOrSkyloft() && dScGame_c::isCurrentStage("F102") &&
|
|
!StoryflagManager::sInstance->getCounterOrFlag(115) && roomid >= 3 && roomid < 5) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
dBgS::GetInstance()->DrawMap(roomid, mtx, drawFully, param);
|
|
}
|
|
|
|
void dRoom_c::getBounds(mVec3_c *min, mVec3_c *max) const {
|
|
for (int i = 0; i < 8; i++) {
|
|
mVec3_c tMin, tMax;
|
|
mModels[i].getBounds(&tMin, &tMax);
|
|
if (i == 0) {
|
|
*min = tMin;
|
|
*max = tMax;
|
|
} else {
|
|
nw4r::math::VEC3Minimize(min, min, tMin);
|
|
nw4r::math::VEC3Maximize(max, max, tMax);
|
|
}
|
|
}
|
|
}
|
|
|
|
void dRoom_c::formatObj(int obj, SizedString<8> &str) {
|
|
str.sprintf("obj%d", obj);
|
|
}
|
|
|
|
void dRoom_c::updateObjNodeInEachRoom(int obj, bool visible) {
|
|
SizedString<8> objName;
|
|
formatObj(obj, objName);
|
|
for (int i = 0; i < 8; i++) {
|
|
mModels[i].updateObjNode(objName, visible);
|
|
}
|
|
}
|
|
|
|
void dRoom_c::destroyModels() {
|
|
for (int i = 0; i < 8; i++) {
|
|
mModels[i].destroy();
|
|
}
|
|
}
|
|
|
|
// Called from d_a_lastboss
|
|
void dRoom_c::someLastBossThing(bool arg) {
|
|
const char *name = "model0";
|
|
if (!arg) {
|
|
name = "model_obj0";
|
|
}
|
|
nw4r::g3d::ResAnmTexSrt anmSrt = mRoomRes.GetResAnmTexSrt(name);
|
|
if (anmSrt.IsValid()) {
|
|
mModels[0].mpAnmSrt->setAnm(mModels[0].mMdl, anmSrt, 0, m3d::PLAY_MODE_4);
|
|
mModels[0].mMdl.setAnm(*mModels[0].mpAnmSrt);
|
|
}
|
|
}
|
|
|
|
f32 dRoom_c::getFrame() const {
|
|
return mModels[0].getFrame();
|
|
}
|
|
|
|
extern "C" void fn_800641D0(int roomid, void *roomBzs);
|
|
extern "C" void fn_80064160(int roomid, void *roomBzs);
|
|
|
|
void dRoom_c::initializeState_Active() {
|
|
SceneflagManager::sInstance->unsetZoneflagsForRoom(roomid);
|
|
executeBg();
|
|
fn_800641D0(roomid, BZS);
|
|
if (mDidAlreadyInit) {
|
|
fn_80064160(roomid, BZS);
|
|
} else {
|
|
mFlags |= 8 | 2;
|
|
mDidAlreadyInit = true;
|
|
}
|
|
}
|
|
|
|
void dRoom_c::executeState_Active() {
|
|
u8 flags = mFlags;
|
|
field_0x571 = (flags & (4 | 2)) != 0;
|
|
if (field_0x571) {
|
|
if ((flags & 8) != 0) {
|
|
mStateMgr.changeState(StateID_NonActive);
|
|
} else {
|
|
deactivateUpdates();
|
|
}
|
|
return;
|
|
}
|
|
|
|
activateUpdates();
|
|
}
|
|
|
|
void dRoom_c::finalizeState_Active() {}
|
|
|
|
void deleteActor(dAcBase_c *ac) {
|
|
ac->setActorProperty(0x800);
|
|
ac->deleteRequest();
|
|
}
|
|
|
|
void dRoom_c::initializeState_NonActive() {
|
|
foreachObject(deleteActor);
|
|
if (dTgMassObj_c::GetInstance() != nullptr) {
|
|
dTgMassObj_c::GetInstance()->unloadRoom(roomid);
|
|
}
|
|
}
|
|
|
|
void dRoom_c::executeState_NonActive() {
|
|
if ((mFlags & 8) != 0) {
|
|
return;
|
|
}
|
|
mStateMgr.changeState(StateID_Active);
|
|
}
|
|
|
|
void dRoom_c::finalizeState_NonActive() {
|
|
mFlags = mFlags & ~8;
|
|
destroyModels();
|
|
}
|
|
|
|
void dRoom_c::mdl_c::remove() {
|
|
if (mpAabb != nullptr) {
|
|
delete[] mpAabb;
|
|
mpAabb = nullptr;
|
|
doSomethingWithVis(true);
|
|
}
|
|
}
|
|
|
|
bool dRoom_c::mdl_c::create(nw4r::g3d::ResMdl resMdl, mAllocator_c &alloc) {
|
|
if (!m3d::smdl_c::create(resMdl, &alloc, 0x40)) {
|
|
return false;
|
|
}
|
|
calc(false);
|
|
u32 numEntries = resMdl.GetResNodeNumEntries();
|
|
mpAabb = new nw4r::math::AABB[numEntries];
|
|
;
|
|
if (mpAabb == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
nw4r::math::AABB *buf = mpAabb;
|
|
u32 id = 0;
|
|
if (numEntries != 0) {
|
|
for (; id < numEntries; id++) {
|
|
mMtx_c mtx;
|
|
getNodeWorldMtx(id, mtx);
|
|
nw4r::g3d::ResNode resNd = resMdl.GetResNode(id);
|
|
// TODO Vec problems
|
|
nw4r::math::VEC3 min, max;
|
|
min = resNd.GetBoundsMin();
|
|
max = resNd.GetBoundsMax();
|
|
nw4r::math::AABB bb(min, max);
|
|
buf->Set(&bb, mtx);
|
|
buf++;
|
|
}
|
|
}
|
|
|
|
doSomethingWithVis(false);
|
|
return true;
|
|
}
|
|
|
|
extern "C" bool fn_801BB750(nw4r::math::AABB *aabb, f32 f);
|
|
|
|
void dRoom_c::mdl_c::configureSomething() {
|
|
nw4r::g3d::ResMdl mdl = getResMdl();
|
|
u32 numNodes = mdl.GetResNodeNumEntries();
|
|
|
|
nw4r::math::AABB *aabbs = mpAabb;
|
|
for (u32 i = 0; i < numNodes; i++) {
|
|
nw4r::g3d::ResNode nd = mdl.GetResNode(i);
|
|
if (nd.IsVisible() && (nd.ref().flags & nw4r::g3d::ResNodeData::FLAG_GEOMETRY) &&
|
|
nd.GetBillboardMode() == nw4r::g3d::ResNodeDataTypedef::BILLBOARD_OFF) {
|
|
somethingVisibility(i, !fn_801BB750(&aabbs[i], EGG::Math<f32>::maxNumber()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void dRoom_c::mdl_c::somethingVisibility(u32 id, bool visible) {
|
|
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::ScnObj::DynamicCast<nw4r::g3d::ScnMdl>(getG3dObject());
|
|
nw4r::g3d::ScnMdl::CopiedVisAccess v(mdl, id);
|
|
v.SetVisibility(visible);
|
|
}
|
|
|
|
void dRoom_c::mdl_c::doSomethingWithVis(bool arg) {
|
|
nw4r::g3d::ResMdl mdl = getResMdl();
|
|
const char *mdlName = mdl.GetName();
|
|
if (strequals(mdlName, "model0_s") && dScGame_c::isStageSkyloftLayer20()) {
|
|
nw4r::g3d::ResMat mat = mdl.GetResMat("MA03_C_Door_Kasan");
|
|
setMatVisible(mat.GetID(), arg);
|
|
}
|
|
}
|
|
|
|
bool dRoom_c::model_c::create(nw4r::g3d::ResFile resFile, mAllocator_c &alloc, s32 idx, UnkWithWater *waterThing) {
|
|
SizedString<16> mdlName;
|
|
mdlName.sprintf("model%d", idx >> 1);
|
|
if ((idx & 1) != 0) {
|
|
mdlName += "_s";
|
|
}
|
|
|
|
nw4r::g3d::ResMdl mdl = resFile.GetResMdl(mdlName);
|
|
if (!mdl.IsValid()) {
|
|
return true;
|
|
}
|
|
|
|
bool linkResult = UnkWithWater::linkMdl(mdl, waterThing);
|
|
if (!mMdl.create(mdl, alloc)) {
|
|
return false;
|
|
}
|
|
|
|
const DrawPriorityConfig *cfg = getDrawPriority(idx);
|
|
u8 xlu = linkResult != 0 ? dStageMgr_c::GetInstance()->checkFlag0x88A0(0x2) ? cfg->pDrawXlu : 0x84 : cfg->pDrawXlu;
|
|
mMdl.setPriorityDraw(cfg->pDrawOpa1, xlu);
|
|
bool anyAnims = false;
|
|
nw4r::g3d::ResAnmClr anmClr = resFile.GetResAnmClr(mdlName);
|
|
if (anmClr.IsValid()) {
|
|
mpAnmClr = new m3d::anmMatClr_c();
|
|
if (!mpAnmClr) {
|
|
return false;
|
|
}
|
|
if (!mpAnmClr->create(mdl, anmClr, &alloc, nullptr, 1)) {
|
|
return false;
|
|
}
|
|
mMdl.setAnm(*mpAnmClr);
|
|
anyAnims = true;
|
|
}
|
|
|
|
nw4r::g3d::ResAnmTexPat anmPat = resFile.GetResAnmTexPat(mdlName);
|
|
if (anmPat.IsValid()) {
|
|
mpAnmPat = new m3d::anmTexPat_c();
|
|
if (!mpAnmPat) {
|
|
return false;
|
|
}
|
|
if (!mpAnmPat->create(mdl, anmPat, &alloc, nullptr, 1)) {
|
|
return false;
|
|
}
|
|
mMdl.setAnm(*mpAnmPat);
|
|
anyAnims = true;
|
|
}
|
|
|
|
nw4r::g3d::ResAnmTexSrt anmSrt = resFile.GetResAnmTexSrt(mdlName);
|
|
if (!anmSrt.IsValid()) {
|
|
RoomManager::getMA0IndirectSrt(&anmSrt, mdl);
|
|
}
|
|
if (anmSrt.IsValid()) {
|
|
mpAnmSrt = new m3d::anmTexSrt_c();
|
|
if (!mpAnmSrt) {
|
|
return false;
|
|
}
|
|
if (!mpAnmSrt->create(mdl, anmSrt, &alloc, nullptr, 1)) {
|
|
return false;
|
|
}
|
|
mMdl.setAnm(*mpAnmSrt);
|
|
anyAnims = true;
|
|
}
|
|
|
|
nw4r::g3d::ResAnmVis anmVis = resFile.GetResAnmVis(mdlName);
|
|
if (anmVis.IsValid()) {
|
|
mpAnmVis = new m3d::anmVis_c();
|
|
if (!mpAnmVis) {
|
|
return false;
|
|
}
|
|
if (!mpAnmVis->create(mdl, anmVis, &alloc, nullptr)) {
|
|
return false;
|
|
}
|
|
mMdl.setAnm(*mpAnmVis);
|
|
anyAnims = true;
|
|
}
|
|
|
|
if (anyAnims) {
|
|
mMdl.setOption(nw4r::g3d::ScnObj::OPTION_DISABLE_CALC_WORLD, false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void dRoom_c::model_c::execute(s32 idx, bool roomfield_0x573, f32 pastState) {
|
|
if (!mMdl.hasModel()) {
|
|
return;
|
|
}
|
|
|
|
if (mpAnmClr) {
|
|
mpAnmClr->play();
|
|
}
|
|
|
|
if (mpAnmSrt) {
|
|
mpAnmSrt->play();
|
|
}
|
|
|
|
if (mpAnmVis) {
|
|
mpAnmVis->play();
|
|
}
|
|
|
|
if (roomfield_0x573 && !(idx >= 6)) {
|
|
if (mpAnmPat) {
|
|
int frame = (pastState > 0.0f);
|
|
mpAnmPat->setFrame(frame, 0);
|
|
} else {
|
|
const DrawPriorityConfig *cfg = getDrawPriority(idx);
|
|
if (pastState > 0.0f) {
|
|
mMdl.setPriorityDraw(cfg->pDrawOpa2, cfg->pDrawXlu);
|
|
} else {
|
|
mMdl.setPriorityDraw(cfg->pDrawOpa1, cfg->pDrawXlu);
|
|
}
|
|
}
|
|
} else {
|
|
if (mpAnmPat) {
|
|
mpAnmPat->play();
|
|
}
|
|
}
|
|
}
|
|
|
|
void dRoom_c::model_c::draw(int roomid) {
|
|
if (!mMdl.hasModel()) {
|
|
return;
|
|
}
|
|
mMdl.configureSomething();
|
|
configureSomething(roomid, &mMdl);
|
|
mMdl.entry();
|
|
}
|
|
|
|
extern "C" void fn_80017B10(nw4r::g3d::ResMdl &mdl, bool, bool);
|
|
|
|
void dRoom_c::model_c::configureSomething(int roomid, mdl_c *mdl) {
|
|
nw4r::g3d::ResMdl resMdl = mdl->getResMdl();
|
|
fn_80017B10(resMdl, true, false);
|
|
}
|
|
|
|
const DrawPriorityConfig cfg[] = {
|
|
{0x18, 0x5, 0x7},
|
|
{0x1E, 0x5, 0x9},
|
|
{0x19, 0x6, 0x7},
|
|
{0x1F, 0x6, 0x9},
|
|
{0x1A, 0x7, 0x7},
|
|
{0x20, 0x7, 0x9},
|
|
{0x1B, 0x8, 0x7},
|
|
{0x21, 0x8, 0x9},
|
|
};
|
|
|
|
const DrawPriorityConfig *dRoom_c::model_c::getDrawPriority(s32 idx) {
|
|
return &cfg[idx];
|
|
}
|
|
|
|
bool dRoom_c::model_c::getBounds(mVec3_c *min, mVec3_c *max) const {
|
|
return mMdl.getBounds(min, max);
|
|
}
|
|
|
|
nw4r::g3d::ResNode dRoom_c::model_c::getResNode(const char *nodeName) {
|
|
return mMdl.getResMdl().GetResNode(nodeName);
|
|
}
|
|
|
|
void dRoom_c::model_c::updateObjNode(const char *node, bool visible) {
|
|
if (!mMdl.hasModel()) {
|
|
return;
|
|
}
|
|
|
|
nw4r::g3d::ResNode nd = getResNode(node);
|
|
if (!nd.IsValid()) {
|
|
return;
|
|
}
|
|
|
|
nd.SetVisibility(visible);
|
|
mMdl.somethingVisibility(nd.GetID(), visible);
|
|
if (visible) {
|
|
dTimeAreaMgr_c::sInstance->setField0x7A(true);
|
|
} else {
|
|
dTimeAreaMgr_c::sInstance->setField0x7A(false);
|
|
}
|
|
}
|
|
|
|
void dRoom_c::model_c::destroy() {
|
|
if (!mMdl.hasModel()) {
|
|
return;
|
|
}
|
|
|
|
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::ScnObj::DynamicCast<nw4r::g3d::ScnMdl>(mMdl.getG3dObject());
|
|
nw4r::g3d::ResMdl resMdl = mMdl.getResMdl();
|
|
for (u32 i = 0; i < resMdl.GetResNodeNumEntries(); i++) {
|
|
nw4r::g3d::ResNode nd = resMdl.GetResNode(i);
|
|
nd.SetVisibility(true);
|
|
nw4r::g3d::ScnMdl::CopiedVisAccess v(mdl, i);
|
|
v.SetVisibility(true);
|
|
}
|
|
}
|
|
|
|
f32 dRoom_c::model_c::getFrame() const {
|
|
if (!mMdl.hasModel() || !mpAnmSrt) {
|
|
return 0.0f;
|
|
}
|
|
return mpAnmSrt->getFrame(0);
|
|
}
|