diff options
| author | robojumper <robojumper@gmail.com> | 2024-11-17 21:19:50 +0100 |
|---|---|---|
| committer | robojumper <robojumper@gmail.com> | 2024-11-17 21:19:50 +0100 |
| commit | 451566ac23a71223e00f3f4de9cd7fc1574b46fd (patch) | |
| tree | 8de244cbc7815f981547cea297987c86a2909d84 /src/d/a/obj/d_a_obj_tbox.cpp | |
| parent | 8240b23a86a76727ce4865acb43940dc3fe0790b (diff) | |
dAcTbox_c::create structurally matching
Diffstat (limited to 'src/d/a/obj/d_a_obj_tbox.cpp')
| -rw-r--r-- | src/d/a/obj/d_a_obj_tbox.cpp | 253 |
1 files changed, 247 insertions, 6 deletions
diff --git a/src/d/a/obj/d_a_obj_tbox.cpp b/src/d/a/obj/d_a_obj_tbox.cpp index b73edb3d..11dcd85b 100644 --- a/src/d/a/obj/d_a_obj_tbox.cpp +++ b/src/d/a/obj/d_a_obj_tbox.cpp @@ -1,7 +1,12 @@ #include "d/a/obj/d_a_obj_tbox.h" #include "common.h" +#include "d/a/d_a_item.h" +#include "d/a/d_a_itembase.h" +#include "d/col/cc/d_cc_d.h" +#include "d/flag/sceneflag_manager.h" #include "d/flag/storyflag_manager.h" +#include "m/m3d/m_fanm.h" #include "m/m_mtx.h" #include "m/m_vec.h" #include "nw4r/g3d/g3d_resanmchr.h" @@ -60,6 +65,33 @@ extern "C" char *const sOpenEventNames[] = { "TreasureBoxOpen", }; +// clang-format off +// TODO just copied from somewhere +const cCcD_SrcGObj dAcTbox_c::sColSrc = { + /* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ {~(AT_TYPE_BUGNET | AT_TYPE_BEETLE | AT_TYPE_0x80000 | AT_TYPE_0x8000 | AT_TYPE_WIND), 0x1080111, {6, 0x407}, 0, 0}, + /* mObjCo */ {0x0} +}; +// clang-format on + +// TODO enum, item comments +static const u8 sItemToTBoxVariant[MAX_ITEM_ID + 1] = { + 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + static char *const sMdlNames[] = { "TBoxNormalT", "TBoxSmallT", @@ -90,8 +122,7 @@ static char *const sOpenCcNames[] = { dAcTbox_c::dAcTbox_c() : mStateMgr(*this, sStateID::null), mScnCallback(this), mEvent(*this, nullptr), mTboxListNode(this), - mDowsingTarget1(this, DowsingTarget::SLOT_NONE), mDowsingTarget2(this, DowsingTarget::SLOT_NONE), - field_0x4E8(-1) { + mDowsingTarget1(this, DowsingTarget::SLOT_NONE), mDowsingTarget2(this, DowsingTarget::SLOT_NONE) { sTboxActorList.append(&mTboxListNode); unkByteTargetFiRelated = 2; } @@ -117,7 +148,7 @@ bool dAcTbox_c::createHeap() { return false; } - if (mVariant == 3) { + if (mVariant == GODDESS) { nw4r::g3d::ResFile res = data; if (!res.mFile.IsValid()) { return false; @@ -145,7 +176,7 @@ bool dAcTbox_c::createHeap() { } mMdl1.getModel().setAnm(mAnmGoddessTexSrt); } - } else if (mVariant == 0) { + } else if (mVariant == NORMAL) { nw4r::g3d::ResFile res = data; if (!res.mFile.IsValid()) { return false; @@ -224,13 +255,223 @@ bool dAcTbox_c::createHeap() { return true; } +static u32 sSomeCounters[16] = {}; + +int dAcTbox_c::create() { + if (!isActualVisibleBox()) { + return FAILED; + } + int roomId_tmp = roomid; + if (addActorToRoom(-1)) { + roomid = roomId_tmp; + changeLoadedEntitiesWithSet(); + } + setItemId((ITEM_ID)(rotation.z & 0x1FF)); + if (mItemId > MAX_ITEM_ID) { + return FAILED; + } + mVariant = sItemToTBoxVariant[mItemId]; + if (mVariant == GODDESS) { + setItemId((ITEM_ID)(MAX_ITEM_ID - mItemId)); + } + mSpawnSceneFlag = (params >> 0x14) & 0xFF; + mSetSceneFlag = rotation.x & 0xFF; + setChestFlag(); + field_0x120F = ((rotation.x >> 8) & 1) == 0; + if (!noObstructionCheck()) { + setDoObstructionCheck(); + } + field_0x1208 = (rotation.x >> 0xA) & 0xF; + switch (fn_8026B370()) { + case 0: field_0x120A = 0; break; + case 1: field_0x120A = 1; break; + case 3: field_0x120A = 3; break; + default: field_0x120A = 3; break; + } + rotation.z = 0; + rotation.x = 0; + + // This part of the code checks if there's another chest with similar properties + // and only keeps one of them. + if (fn_80268660(field_0x1208) && !field_0x1210) { + sSomeCounters[field_0x1208]++; + field_0x1210 = true; + } + field_0x120D = 0; + if (fn_8026D670()) { + u32 counterValue = 0; + getSomeCounter(&counterValue); + if (counterValue > 1) { + bool keepGoing = true; + dAcTbox_c *other; + dAcObjBase_c *cursor = nullptr; + do { + cursor = getNextObject(&sTboxActorList, cursor); + other = static_cast<dAcTbox_c *>(cursor); + if (other != nullptr && this != other && !other->field_0x120D && field_0x1208 == other->field_0x1208) { + keepGoing = false; + } + } while (keepGoing && cursor != nullptr); + + bool b; + if (checkTboxFlag()) { + b = true; + } else if (other->checkTboxFlag()) { + b = false; + } else { + b = fn_8026D560(); + } + + if (b) { + other->deleteRequest(); + field_0x120D = true; + } else { + field_0x120D = true; + return FAILED; + } + } + } + + if (checkTboxFlag() || + (mSetSceneFlag < 0xFF && SceneflagManager::sInstance->checkBoolFlag(roomid, mSetSceneFlag))) { + mHasBeenOpened = true; + } else { + mHasBeenOpened = false; + if (isItemRupee()) { + initDowsingTarget(DowsingTarget::SLOT_RUPEE); + } else if (dAcItem_c::isKeyPiece((ITEM_ID)mItemId)) { + initDowsingTarget(DowsingTarget::SLOT_QUEST); + } else if (dAcItem_c::isTreasure((ITEM_ID)mItemId)) { + initDowsingTarget(DowsingTarget::SLOT_TREASURE); + } + + if (mVariant == GODDESS && StoryflagManager::sInstance->getCounterOrFlag(getParams2Lower())) { + initDowsingTargetCube(); + } + } + + if (isItemRupee() || dAcItem_c::isTreasure((ITEM_ID)mItemId)) { + mRegisterDowsingTarget = &dAcTbox_c::registerRupeeOrTreasureDowsing; + mUnregisterDowsingTarget = &dAcTbox_c::unregisterDowsing; + } else if (dAcItem_c::isKeyPiece((ITEM_ID)mItemId)) { + mRegisterDowsingTarget = &dAcTbox_c::registerKeyPieceDowsing; + mUnregisterDowsingTarget = &dAcTbox_c::noUnregisterDowsing; + } else { + mRegisterDowsingTarget = &dAcTbox_c::noRegisterDowsing; + mUnregisterDowsingTarget = &dAcTbox_c::noUnregisterDowsing; + } + + updateMatrix(); + + CREATE_ALLOCATOR(dAcTbox_c); + + mStts.SetRank(0xD); + static const dCcD_SrcUnk s1 = { + sColSrc, + {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}, + }; + mCcD3.Set(s1); + mCcD4.SetStts(mStts); + static const dCcD_SrcCyl s2 = { + sColSrc, + {1.0f, 1.0f}, + }; + mCcD4.Set(s2); + mCcD4.SetStts(mStts); + if (mVariant == SMALL) { + // clang-format off + static const dCcD_SrcUnk s3 = {{ + /* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ {~(AT_TYPE_BUGNET | AT_TYPE_BEETLE | AT_TYPE_0x80000 | AT_TYPE_0x8000 | AT_TYPE_WIND), 0x1080111, {6, 0x407}, 0, 0}, + /* mObjCo */ {0x0}}, + {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}, + }; + // clang-format on + field_0x0D48.addCc(mCcD1, s3); + field_0x0D48.addCc(mCcD2, s3); + } else { + // clang-format off + static const dCcD_SrcUnk s4 = {{ + /* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ {~(AT_TYPE_BUGNET | AT_TYPE_BEETLE | AT_TYPE_0x80000 | AT_TYPE_0x8000 | AT_TYPE_WIND), 0x1080111, {6, 0x407}, 0, 0}, + /* mObjCo */ {0x0}}, + {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}, + }; + // clang-format on + field_0x0D48.addCc(mCcD1, s4); + field_0x0D48.addCc(mCcD2, s4); + } + field_0x0D48.SetStts(mStts); + // TODO figure out the right fields + mCcD1.SetTgType(-1); + mCcD2.SetTgType(-1); + mMdl1.setAnm(sAnmNames[mVariant], m3d::PLAY_MODE_4); + if (mHasBeenOpened == true) { + mMdl1.setFrame(mMdl1.getAnm().getEndFrame()); + } else { + mMdl1.setFrame(mMdl1.getAnm().getStartFrame()); + } + mMdl1.getModel().calc(false); + mMtx_c nodeMtx; + mMdl1.getModel().getNodeWorldMtx(mMdl1.getModel().getNodeID("Cover"), nodeMtx); + + nodeMtx.getTranslation(field_0x11D8); + if (mVariant == GODDESS) { + if (!mHasBeenOpened && StoryflagManager::sInstance->getCounterOrFlag(getParams2Lower())) { + mAnmGoddessPat.setFrame(1.0f, 0); + } else { + mAnmGoddessPat.setFrame(0.0f, 0); + } + } + + field_0x11F0 = 0; + switch (mVariant) { + case NORMAL: { + static mVec3_c bbLo = mVec3_c(-65.0f, 0.0f, -100.0f); + static mVec3_c bbUp = mVec3_c(65.0f, 150.0f, 45.0f); + boundingBox.Set(bbLo, bbUp); + } break; + case SMALL: { + static mVec3_c bbLo = mVec3_c(-38.0f, 0.0f, -70.0f); + static mVec3_c bbUp = mVec3_c(38.0f, 110.0f, 35.0f); + boundingBox.Set(bbLo, bbUp); + } break; + case BOSS: { + static mVec3_c bbLo = mVec3_c(-90.0f, 0.0f, -140.0f); + static mVec3_c bbUp = mVec3_c(90.0f, 170.0f, 60.0f); + boundingBox.Set(bbLo, bbUp); + } break; + case GODDESS: { + static mVec3_c bbLo = mVec3_c(-65.0f, 0.0f, -100.0f); + static mVec3_c bbUp = mVec3_c(65.0f, 150.0f, 50.0f); + boundingBox.Set(bbLo, bbUp); + } break; + } + + field_0x11EC = 1.0f; + field_0x11FC = 0; + + field_0x4E8.r = 0; + field_0x4E8.g = 0; + field_0x4E8.b = 0; + + field_0x4EC = 0.0f; + field_0x4DC = position; + field_0x4DC.y += 100.0f; + + return SUCCEEDED; +} + void dAcTbox_c::initializeState_DugOut() {} void dAcTbox_c::executeState_DugOut() {} void dAcTbox_c::finalizeState_DugOut() {} void dAcTbox_c::initializeState_WaitAppear() {} void dAcTbox_c::executeState_WaitAppear() {} void dAcTbox_c::finalizeState_WaitAppear() {} -void dAcTbox_c::initializeState_DemoAppear() {} +void dAcTbox_c::initializeState_DemoAppear() { + // TODO, just referencing this bit of data + mMdl1.setAnm(sAppearAnmName, m3d::PLAY_MODE_4); +} void dAcTbox_c::executeState_DemoAppear() {} void dAcTbox_c::finalizeState_DemoAppear() {} void dAcTbox_c::initializeState_WaitOpen() {} @@ -265,5 +506,5 @@ void dAcTbox_c::executeState_GoddessWait() {} void dAcTbox_c::finalizeState_GoddessWait() {} bool dAcTbox_c::isNotSmall() const { - return mVariant != 1; + return mVariant != SMALL; } |
