diff options
| author | robojumper <robojumper@gmail.com> | 2026-05-07 19:52:36 +0200 |
|---|---|---|
| committer | robojumper <robojumper@gmail.com> | 2026-05-14 14:40:32 +0200 |
| commit | 48fbe8d1da7a82412a73746620291af93354364a (patch) | |
| tree | aa7cb0631f3970e41aa4266ca51657237d6917fa /src/d | |
| parent | 02bab6f41fc616ca7d9aa77f4a81782d65b16200 (diff) | |
Progress
Diffstat (limited to 'src/d')
| -rw-r--r-- | src/d/a/d_a_item.cpp | 374 | ||||
| -rw-r--r-- | src/d/a/obj/d_a_obj_tbox.cpp | 2 |
2 files changed, 337 insertions, 39 deletions
diff --git a/src/d/a/d_a_item.cpp b/src/d/a/d_a_item.cpp index 5781c44c..f467afc7 100644 --- a/src/d/a/d_a_item.cpp +++ b/src/d/a/d_a_item.cpp @@ -10,6 +10,7 @@ #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/d_angle.h" #include "d/d_camera.h" #include "d/d_linkage.h" #include "d/d_player.h" @@ -24,6 +25,7 @@ #include "d/t/d_t_force_get_flag.h" #include "d/t/d_t_minigame_insect_capture.h" #include "d/t/d_t_siren.h" +#include "m/m_angle.h" #include "m/m_vec.h" #include "toBeSorted/event_manager.h" #include "toBeSorted/file_manager.h" @@ -325,6 +327,25 @@ bool dAcItemBase_c::setDungeonFlagForTear(int tearNum) { return true; } +static bool isDefaultDeleteGround(s32 specialCode) { + // Lava, Cursed Water + return specialCode == 7 || specialCode == 17; +} + +static bool isDefaultSwimGround(s32 specialCode) { + // Deep Sand (Knee Deep), Very Deep Sand (Void, Instant), Very Deep Sand (Void, Slow) + return specialCode == 10 || specialCode == 11 || specialCode == 16; +} + +static bool isHeartDeleteGround(s32 specialCode) { + // Lava + return specialCode == 7; +} + +static bool isHeartSwimGround(s32 specialCode) { + return false; +} + // This might be a cM::calcTimer thing... bool increment(u32 *value) { if (*value < UINT32_MAX) { @@ -358,10 +379,10 @@ u16 getIndex(u16 itemId) { // } static const char *const sResNodeName = "Set"; -/* static */ extern const char *const sDefaultGetItem = "DefaultGetItem"; -/* static */ extern const char *const sItemGetGorgeous = "ItemGetGorgeous"; -/* static */ extern const char *const sItemGetDefaultTbox = "ItemGetDefaultTBox"; -/* static */ extern const char *const sItemGetGorgeousTbox = "ItemGetGorgeousTBox"; +static const char *const sDefaultGetItem = "DefaultGetItem"; +static const char *const sItemGetGorgeous = "ItemGetGorgeous"; +static const char *const sItemGetDefaultTbox = "ItemGetDefaultTBox"; +static const char *const sItemGetGorgeousTbox = "ItemGetGorgeousTBox"; /* static */ extern const char *const sItemGetBird = "ItemGetBird"; const mVec3_c dAcItem_c::sFreestandingDowsingOffset(0.0f, 25.0f, 0.0f); @@ -369,17 +390,17 @@ const mVec3_c dAcItem_c::sScale1Maybe(1.0f, 1.0f, 1.0f); const mVec3_c dAcItem_c::sScale2Maybe(1.75f, 1.75f, 1.75f); struct TearIdIdx { - s32 idx; + dAcItem_c::Tear_e idx; u16 itemId; mColor color1; mColor color2; }; -/* static */ extern "C" TearIdIdx sTearIdxes[] = { - {0, ITEM_FARORE_TEAR, mColor(0x00, 0x80, 0x30, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, - {1, ITEM_DIN_TEAR, mColor(0xFF, 0x64, 0x80, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, - {2, ITEM_NAYRU_TEAR, mColor(0x80, 0x80, 0x00, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, - {3, ITEM_SACRED_TEAR, mColor(0x00, 0x64, 0xC8, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, +static TearIdIdx sTearIdxes[] = { + { dAcItem_c::TEAR_FARON, ITEM_FARORE_TEAR, mColor(0x00, 0x80, 0x30, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, + { dAcItem_c::TEAR_ELDIN, ITEM_DIN_TEAR, mColor(0xFF, 0x64, 0x80, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, + {dAcItem_c::TEAR_LANAYRU, ITEM_NAYRU_TEAR, mColor(0x80, 0x80, 0x00, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, + {dAcItem_c::TEAR_GODDESS, ITEM_SACRED_TEAR, mColor(0x00, 0x64, 0xC8, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, }; struct TearEffectColorThing { @@ -405,15 +426,32 @@ extern "C" TearEffectColorThing sTearEffectColors[] = { mColor(0x40, 0xA0, 0xFF, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, }; +struct UnkFloat { + f32 f; + UnkFloat(f32 f_) : f(f_) {} +}; + +const mVec3_c dAcItem_c::sUnkOffset1(0.0f, 28.0f, 0.0f); +const mVec3_c dAcItem_c::sUnkOffset2(0.0f, 0.0f, 0.0f); +const mVec3_c dAcItem_c::sUnkOffset3(0.0f, 28.0f, 0.0f); +const mVec3_c dAcItem_c::sUnkOffset4(0.0f, 0.0f, 0.0f); +const mVec3_c dAcItem_c::sUnkOffset5(0.0f, 25.0f, 0.0f); +const mVec3_c dAcItem_c::sUnkOffset6(0.0f, 25.0f, 0.0f); +extern const UnkFloat f1(0.25f); +extern const UnkFloat f2(1.0f); + /* static */ extern const char *const sGetFairyBody = "GetFairy_body"; /* static */ extern const char *const sBottleFairy_body = "BottleFairy_body"; SPECIAL_ACTOR_PROFILE(ITEM, dAcItem_c, fProfile::ITEM, 0x2B, 0, 2); -const dAcItem_c::sStaticPtmf dAcItem_c::sStaticPtmfs[] = { +const dAcItem_c::sStaticPtmf dAcItem_c::sStaticPtmfs1[] = { &dAcItem_c::fn_80248020, nullptr, &dAcItem_c::fn_80248010, nullptr, &dAcItem_c::fn_80255B30, &dAcItem_c::fn_80255BA0, +}; + +const dAcItem_c::sStaticPtmf dAcItem_c::sStaticPtmfs2[] = { &dAcItem_c::fn_80248040, nullptr, &dAcItem_c::fn_80248030, nullptr, &dAcItem_c::fn_80255BD0, &dAcItem_c::fn_80255C40, @@ -422,6 +460,7 @@ const dAcItem_c::sStaticPtmf dAcItem_c::sStaticPtmfs[] = { fLiMgBa_c dAcItem_c::sItemList; dAcRef_c<dAcObjBase_c> dAcItem_c::sItemListHead; dAcRef_c<dAcObjBase_c> dAcItem_c::sItemListTail; +fLiMgBa_c dAcItem_c::sUnusedList; dAcItem_c::dAcItem_c() : mStateMgr(*this), @@ -474,6 +513,23 @@ dAcItem_c::~dAcItem_c() { mDowsingTarget.doUnregister(); } +dAcItem_c::Tear_e dAcItem_c::getTearSubtype(u32 id) { + // If only this could be written in a simpler way... + bool found = false; + int i = 0; + while (!found && i <= (int)ARRAY_LENGTH(sTearIdxes) - 1) { + if (id == sTearIdxes[i].itemId) { + found = true; + } else { + i++; + } + } + if (found) { + return sTearIdxes[i].idx; + } + return TEAR_MAX; +} + bool dAcItem_c::createHeap() { if (dItemMdlPut_c::isMdlForItemId(mRealItemId)) { mpMdl = new dItemMdlPut_c(); @@ -966,9 +1022,9 @@ int dAcItem_c::create() { } if (isHeartV()) { - mFn_0xCB4 = &dAcItem_c::fn_802577C0; + mFnGetSinkSpeed = &dAcItem_c::getSinkSpeedHeart; } else { - mFn_0xCB4 = &dAcItem_c::fn_802577D0; + mFnGetSinkSpeed = &dAcItem_c::getSinkSpeedDefault; } if (mbNoDespawn) { @@ -986,7 +1042,7 @@ int dAcItem_c::create() { } if (isAnyTear()) { - s32 type = getTearSubtype((ITEM_ID)mId); + s32 type = getTearSubtype(mId); if (type == TEAR_MAX) { type = TEAR_FARON; } @@ -1219,8 +1275,7 @@ int dAcItem_c::actorExecute() { applyBoundingBox(); - bool tmp = 0.0f < field_0xD04; - if (tmp || mStateMgr.isState(StateID_WaitGetDemo) || mStateMgr.isState(StateID_Get) || + if (isField_0xD04GtZero() || mStateMgr.isState(StateID_WaitGetDemo) || mStateMgr.isState(StateID_Get) || mStateMgr.isState(StateID_GetBeetle)) { setActorProperty(AC_PROP_0x4); } else { @@ -1307,7 +1362,7 @@ void dAcItem_c::initializeState_Wait() { mObjAcch.SetMoveBGOnly(); } mMdlScaleType = 0; - field_0xD00 = 0.0f; + mSinkOffset = 0.0f; mYOffset = 0.0f; } @@ -1587,20 +1642,20 @@ void dAcItem_c::executeState_Wait() { if (mObjAcch.ChkGndHit() && mVelocity.y <= 0.0f) { u32 specialCode = dBgS::GetInstance()->GetSpecialCode(mObjAcch.GetGnd()); - if (fn_80255C50(specialCode)) { - if (sLib::chase(&field_0xD00, -100.0f, (this->*mFn_0xCB4)())) { + if (isItemDeleteGround(specialCode)) { + if (sLib::chase(&mSinkOffset, -100.0f, (this->*mFnGetSinkSpeed)())) { deleteRequest(); } - } else if (fn_80255CA0(specialCode)) { - sLib::chase(&field_0xD00, -30.0f, (this->*mFn_0xCB4)()); + } else if (isItemSwimGround(specialCode)) { + sLib::chase(&mSinkOffset, -30.0f, (this->*mFnGetSinkSpeed)()); } else { - sLib::chase(&field_0xD00, 0.0f, 6.0f); + sLib::chase(&mSinkOffset, 0.0f, 6.0f); } } else { - field_0xD00 = 0.0f; + mSinkOffset = 0.0f; } - mYOffset = field_0xD00; + mYOffset = mSinkOffset; if (isAnyTear() && mObjAcch.ChkGroundLanding()) { startSoundWithFloatParam(SE_Item_A43_FALL, mVelocity.y); } @@ -1653,9 +1708,7 @@ void dAcItem_c::executeState_Wait() { } dir *= -40.0f; mVec3_c efPos = offsetPos + dir; - mEff_0x928.holdEffect( - PARTICLE_RESOURCE_ID_MAPPING_821_, efPos, nullptr, &scale, nullptr, nullptr - ); + mEff_0x928.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_821_, efPos, nullptr, &scale, nullptr, nullptr); } makeLinkLookTowardItem(); if (!mbNoDespawn && !isItemSmallKeyOrHeartPieceOrStaminaFruit()) { @@ -1668,7 +1721,7 @@ void dAcItem_c::finalizeState_Wait() { unsetActorProperty(AC_PROP_0x1); mObjAcch.SetRoofNone(); mObjAcch.Clr_0x2000000(); - field_0xD00 = 0.0f; + mSinkOffset = 0.0f; mYOffset = 0.0f; if (isTriforce() && mEff_0x928.hasEmitters()) { mEff_0x928.remove(true); @@ -1716,7 +1769,7 @@ void dAcItem_c::executeState_Carry() { mStateMgr.changeState(StateID_Wait); } else if (mLinkage.checkConnection(dLinkage_c::CONNECTION_9) && mCyl.ChkTgHit() && !mCyl.ChkTgAtHitType(AT_TYPE_WHIP)) { - mLinkage.fn_80050EA0(this); + mLinkage.forceRemove(this); mStateMgr.changeState(StateID_Wait); } else { fn_80256E80(); @@ -1782,7 +1835,7 @@ void dAcItem_c::executeState_GetBeetle() { v.rotY(+beetlePtr->mRotation.y); mPosition = beetlePtr->mPosition + v; mPosition.y += field_0xD0C; - fn_80255E80(); + rotateTowardsCamera(); sLib::addCalcScaledDiff(&field_0xD0C, 37.6f, 0.1f, 10000.0f); } } @@ -1969,9 +2022,9 @@ void dAcItem_c::initializeState_GetDemo() { setObjectProperty(OBJ_PROP_0x200); mMdlScaleType = 2; if (isBirdStatuette()) { - mFn_0xC9C = &dAcItem_c::fn_80255F40; + mFn_0xC9C = &dAcItem_c::rotateFixedBirdStatuette; } else { - mFn_0xC9C = &dAcItem_c::fn_80255E80; + mFn_0xC9C = &dAcItem_c::rotateTowardsCamera; } } @@ -1984,7 +2037,9 @@ void dAcItem_c::executeState_GetDemo() { fn_80254590(efPos); mVec3_c diff = dScGame_c::getCamera()->getPosition() - mPosition; // TODO close but an extsh is missing - mAng3_c rot((s32)-diff.atan2sY_XZ(), (s32)diff.atan2sX_Z(), 0); + // Same pattern as in rotateTowardsCamera + mAng3_c rot; + setRotXYVec(rot, diff); u32 alpha = 0xFF; if (dScGame_c::currentSpawnInfo.getTrial() == SpawnInfo::TRIAL) { alpha = 0x80; @@ -2042,7 +2097,7 @@ void dAcItem_c::initializeState_WaitTBoxGetDemo() { void dAcItem_c::executeState_WaitTBoxGetDemo() { const char *name; - getItemGetEventName(getItemId(), &name); + getItemGetTboxEventName(getItemId(), &name); Event ev(name, 1, 0x100001, (void *)itemGetEventStart, (void *)itemGetEventEnd); EventManager::alsoSetAsCurrentEvent(this, &ev, nullptr); } @@ -2091,7 +2146,7 @@ void dAcItem_c::initializeState_WaitTurnOff() { } void dAcItem_c::executeState_WaitTurnOff() { - if (field_0xD04 <= 0.0f) { + if (!isField_0xD04GtZero()) { deleteRequest(); } } @@ -2131,9 +2186,111 @@ STATE_DEFINE(dAcItem_c, ResurgeWait); STATE_DEFINE(dAcItem_c, WaitTurnOff); STATE_DEFINE(dAcItem_c, WaitSacredDewGetEffect); +void dAcItem_c::getItemFromBWheelItem() { + if (mStateMgr.isState(StateID_Get) || mStateMgr.isState(StateID_WaitGetDemo)) { + return; + } + if (!mStateMgr.isState(StateID_ResurgeWait)) { + onTouchLink(); + } +} + +void dAcItem_c::setItemPosition(const mVec3_c &pos) { + mPosition = pos; + field_0xD51 = 1; + if (!field_0xD5E) { + return; + } + field_0xD5F = 1; + mItemPosCopy = pos; +} + +void dAcItem_c::setItemVelocity(f32 f) { + mVelocity.y = f; + field_0xD51 = 0; + if (!field_0xD5E) { + return; + } + field_0xD60 = 0; + if (!field_0xD61) { + return; + } + field_0xD5F = 0; + field_0xD08 = 1.0f; +} + +bool dAcItem_c::isStateWait() const { + return mStateMgr.isState(StateID_Wait); +} + +void dAcItem_c::stopCarryAndGet() { + mLinkage.forceRemove(this); + mStateMgr.changeState(StateID_Get); +} + +bool dAcItem_c::getEventNameForAnim(u32 anim, const char **outName) { + if (outName == nullptr) { + return false; + } + switch (anim) { + default: return false; + case ANIM_DEFAULT: *outName = sDefaultGetItem; break; + case ANIM_GORGEOUS: *outName = sItemGetGorgeous; break; + case ANIM_FROWN: *outName = sDefaultGetItem; break; + case ANIM_SMALL: *outName = sDefaultGetItem; break; + } + return true; +} + +bool dAcItem_c::getTboxEventNameForAnim(u32 anim, const char **outName) { + if (outName == nullptr) { + return false; + } + switch (anim) { + default: return false; + case ANIM_DEFAULT: *outName = sItemGetDefaultTbox; break; + case ANIM_GORGEOUS: *outName = sItemGetGorgeousTbox; break; + case ANIM_FROWN: *outName = sItemGetDefaultTbox; break; + case ANIM_SMALL: *outName = sItemGetDefaultTbox; break; + } + return true; +} + +bool dAcItem_c::getItemGetEventName(u16 item, const char **outName) { + u32 anim; + if (getItemAnimType(item, &anim) == false) { + return false; + } + return getEventNameForAnim(anim, outName); +} + +bool dAcItem_c::getItemGetTboxEventName(u16 item, const char **outName) { + u32 anim; + if (getItemAnimType(item, &anim) == false) { + return false; + } + return getTboxEventNameForAnim(anim, outName); +} + +bool dAcItem_c::playHeartStemCutSound() { + dSoundSourceIf_c *src = getSoundSource(); + if (src == nullptr) { + return false; + } + return src->startSoundAtPosition(SE_O_HEART_STEM_CUT, mPosition); +} + +void dAcItem_c::getOffsetPosition(mVec3_c &position) const { + position.set(mPosition.x, mPosition.y + getYOffset(), mPosition.z); +} + +f32 dAcItem_c::scaleBy(f32 f) const { + return f * mBaseScale; +} + void dAcItem_c::itemGetEventStart(dAcBase_c *arg) { // TODO - dAcItem_c *item = static_cast<dAcItem_c*>(arg); + dAcItem_c *item = static_cast<dAcItem_c *>(arg); item->mStateMgr.changeState(StateID_GetDemo); item->setObtainedItemId(item->getItemId(), true); if (item->mId == ITEM_DUNGEON_MAP_FI && ItemflagManager::sInstance->getItemCounterOrFlag(0x32) == 0) { @@ -2250,9 +2407,9 @@ void dAcItem_c::performCollectionPart1() { default: { if (isTriforce()) { doFullHeal(); - } else if (isGratitudeCrystal()) { + } else if (isGratitudeCrystalV()) { increaseGratitudeCrystalCounter(1); - } else if (is5GratitudeCrystals()) { + } else if (is5GratitudeCrystalsV()) { increaseGratitudeCrystalCounter(5); } else if (id == ITEM_EXTRA_WALLET) { increaseExtraWalletCounter(1); @@ -2403,3 +2560,144 @@ void dAcItem_c::performCollectionPart2() { dTgMinigameInsectCapture_c::GetInstance()->recordCollectedInsect(mId, mItemQuantity != 0 ? mItemQuantity : 1); } } + +bool dAcItem_c::isItemDeleteGround(s32 specialCode) const { + if (isHeartV()) { + return isHeartDeleteGround(specialCode); + } else { + return isDefaultDeleteGround(specialCode); + } +} + +bool dAcItem_c::isItemSwimGround(s32 specialCode) const { + if (isHeartV()) { + return isHeartSwimGround(specialCode); + } else { + return isDefaultSwimGround(specialCode); + } +} + +void dAcItem_c::rotateTowardsCamera() { + dCamera_c *cam = dScGame_c::getCamera(); + if (cam == nullptr) { + return; + } + mVec3_c diff = cam->getPosition() - mPosition; + // TODO close but an extsh is missing + // Same pattern as in executeState_GetDemo + setRotXYVec(mRotation, diff); +} + +void dAcItem_c::rotateFixedBirdStatuette() { + mRotation.x.mVal = 1237; + mRotation.y.mVal = 20330; + mRotation.z.mVal = 0; +} + +void dAcItem_0xB34_1::vt_0x0C() { + // no-op +} + +bool dAcItem_0xB34_1::vt_0x10(dAcItem_c *item) { + return false; +} + +void dAcItem_0xB34_2::vt_0x0C() { + // TODO weird double load + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link != nullptr) { + mHighestRelativeHeadHeight = link->getHeadTranslation().y - link->getPosition().y; + } + mNumFrames = 0; +} + +bool dAcItem_0xB34_2::vt_0x10(dAcItem_c *item) { + if (mNumFrames >= 22) { + return false; + } + + // TODO weird double load + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link == nullptr) { + return false; + } + + mVec3_c linkPos = link->getPosition(); + mVec3_c headPos = link->getHeadTranslation(); + f32 diff = headPos.y - linkPos.y; + if (mHighestRelativeHeadHeight < diff) { + mHighestRelativeHeadHeight = diff; + } + + item->mPosition.set(headPos.x, linkPos.y + mHighestRelativeHeadHeight, headPos.z); + + f32 f = 12.0f; + if (mNumFrames != 0) { + f = (f32)mNumFrames * 0.5f * ((mNumFrames - 1) * -0.3f + 12.0f) + 12.0f; + } + item->mPosition.y += f; + item->rotateTowardsCamera(); + mNumFrames++; + return true; +} + +void dAcItem_0xB3C::fn_802579D0() { + fn_80257A80(); + vt_0x10(); +} + +bool dAcItem_0xB3C::fn_80257A10(dAcItem_c *item) { + if (item->getSquareDistToPlayer() < 40000.0f) { + return false; + } + return vt_0x14(item); +} + +void dAcItem_0xB3C::fn_80257A80() { + field_0x04 = vt_0x18(); +} + +void dAcItem_0xB3C::fn_80257AC0() { + if (field_0x04 == 0) { + return; + } + if (!EventManager::isInEvent()) { + field_0x04--; + } +} + +bool dAcItem_0xB3C::fn_80257B10() const { + return field_0x04 == 0; +} + +void dAcItem_0xB3C_1::vt_0x0C(u16 arg) { + // no-op +} + +void dAcItem_0xB3C_1::vt_0x10() { + // no-op +} + +bool dAcItem_0xB3C_1::vt_0x14(dAcItem_c *) { + return false; +} + +UNKWORD dAcItem_0xB3C_1::vt_0x18() { + return 0; +} + +void dAcItem_0xB3C_2::vt_0x0C(u16 arg) { + field_0x20 = arg; +} + +void dAcItem_0xB3C_2::vt_0x10() { + // no-op +} + +bool dAcItem_0xB3C_2::vt_0x14(dAcItem_c *) { + return (this->*mCb2)(); +} + +UNKWORD dAcItem_0xB3C_2::vt_0x18() { + return field_0x20; +} diff --git a/src/d/a/obj/d_a_obj_tbox.cpp b/src/d/a/obj/d_a_obj_tbox.cpp index bcacf40d..7f219bc4 100644 --- a/src/d/a/obj/d_a_obj_tbox.cpp +++ b/src/d/a/obj/d_a_obj_tbox.cpp @@ -1962,7 +1962,7 @@ void dAcTbox_c::initializeState_Open() { if (item != nullptr) { mItemRef.link(item); const char *evName; - if (dAcItem_c::getItemGetEventName(itemId, &evName)) { + if (dAcItem_c::getItemGetTboxEventName(itemId, &evName)) { Event ev(evName, 300, 4, (void *)dAcItem_c::itemGetEventStart, (void *)dAcItem_c::itemGetEventEnd); EventManager::changeOwnEvent(this, item, &ev, 0); } |
