summaryrefslogtreecommitdiff
path: root/src/d/a/obj/d_a_obj_tbox.cpp
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2024-11-17 21:19:50 +0100
committerrobojumper <robojumper@gmail.com>2024-11-17 21:19:50 +0100
commit451566ac23a71223e00f3f4de9cd7fc1574b46fd (patch)
tree8de244cbc7815f981547cea297987c86a2909d84 /src/d/a/obj/d_a_obj_tbox.cpp
parent8240b23a86a76727ce4865acb43940dc3fe0790b (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.cpp253
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;
}