diff options
Diffstat (limited to 'src/d/a/d_a_item.cpp')
| -rw-r--r-- | src/d/a/d_a_item.cpp | 2381 |
1 files changed, 2333 insertions, 48 deletions
diff --git a/src/d/a/d_a_item.cpp b/src/d/a/d_a_item.cpp index 1d4bcee5..47cfabc2 100644 --- a/src/d/a/d_a_item.cpp +++ b/src/d/a/d_a_item.cpp @@ -1,12 +1,41 @@ #include "d/a/d_a_item.h" +#include "c/c_math.h" #include "common.h" #include "d/a/d_a_itembase.h" +#include "d/a/d_a_player.h" +#include "d/a/npc/d_a_npc_talk_kensei.h" +#include "d/a/obj/d_a_obj_boomerang.h" +#include "d/a/obj/d_a_obj_warp.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/d_angle.h" +#include "d/d_camera.h" +#include "d/d_linkage.h" +#include "d/d_player.h" +#include "d/d_pouch.h" +#include "d/d_sc_game.h" #include "d/flag/dungeonflag_manager.h" -#include "d/flag/flag_index.h" -#include "f/f_list_mg.h" -#include "toBeSorted/dowsing_target.h" +#include "d/flag/itemflag_manager.h" +#include "d/flag/sceneflag_manager.h" +#include "d/flag/storyflag_manager.h" +#include "d/snd/d_snd_small_effect_mgr.h" +#include "d/snd/d_snd_wzsound.h" +#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" +#include "toBeSorted/item_mdl.h" +#include "toBeSorted/item_mdl_item.h" +#include "toBeSorted/item_mdl_light_fruit.h" +#include "toBeSorted/item_mdl_misc.h" +#include "toBeSorted/item_mdl_rupee.h" +#include "toBeSorted/item_mdl_stamina_fruit.h" +#include "toBeSorted/minigame_mgr.h" const ItemFlagStruct dAcItemBase_c::sDefaultFlagStruct = {0x28, 0x3C, 0x1E, 0xFF, 0x0000, 0x02, 0x01}; const ItemFlagStruct dAcItemBase_c::sItemFlagStructs[167] = { @@ -219,6 +248,25 @@ const u32 dAcItemBase_c::sItemTypeFlags[MAX_ITEM_ID - 1] = { 0xFFFF, 0x0, 0x0, 0x0, 0x0, 0x0, }; +struct GlitteringSporeRupeeChance { + s32 itemId; + s32 weight; +}; + +static const GlitteringSporeRupeeChance sSporeRupeeChances[] = { + {ITEM_GREEN_RUPEE, 4}, + { ITEM_BLUE_RUPEE, 5}, + { ITEM_RED_RUPEE, 1}, + { ITEM_RUPOOR, 1}, +}; + +static const dCcD_SrcCyl sSrcCyl = { + {{0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + {~(AT_TYPE_BEETLE | AT_TYPE_GLITTERING_SPORES | AT_TYPE_0x8000 | AT_TYPE_WIND), 0x111, {0, 0x08, 0x407}, 0, 0}, + {0xE9}}, + {40.0f, 60.0f} +}; + bool dAcItemBase_c::isValidItemTypeIdx(int itemId) { return itemId < ARRAY_LENGTH(sItemTypeFlags); } @@ -279,7 +327,35 @@ bool dAcItemBase_c::setDungeonFlagForTear(int tearNum) { return true; } -u16 dAcItemBase_c::getItemId() { +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) { + (*value)++; + return true; + } + return false; +} + +u16 dAcItemBase_c::getItemId() const { return mId; } @@ -302,22 +378,89 @@ u16 getIndex(u16 itemId) { // } // } -fLiMgBa_c dAcItem_c::sItemList; +static const char *const sResNodeName = "Set"; +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); +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 { + dAcItem_c::Tear_e idx; + u16 itemId; + mColor color1; + mColor color2; +}; + +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 { + mColor color1; + mColor color2; + mColor color3; + mColor color4; + mColor color5; + mColor color6; +}; + +extern "C" TearEffectColorThing sTearEffectColors[] = { + {mColor(0x80, 0xFF, 0x80, 0xFF), mColor(0x00, 0xFF, 0x40, 0xFF), mColor(0xC8, 0xFF, 0xC8, 0xFF), + mColor(0x40, 0xFF, 0x40, 0xFF), mColor(0x40, 0xFF, 0x60, 0xFF), mColor(0x00, 0xFF, 0x40, 0xFF)}, + + {mColor(0xFF, 0x80, 0xA0, 0xFF), mColor(0xFF, 0x40, 0x80, 0xFF), mColor(0xFF, 0xC8, 0xC8, 0xFF), + mColor(0xFF, 0x40, 0x80, 0xFF), mColor(0xFF, 0x60, 0x80, 0xFF), mColor(0xFF, 0x00, 0x40, 0xFF)}, + + {mColor(0xFF, 0xFF, 0x80, 0xFF), mColor(0xFF, 0xFF, 0x00, 0xFF), mColor(0xFF, 0xFF, 0xC8, 0xFF), + mColor(0xFF, 0xFF, 0x40, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF), mColor(0xFF, 0xFF, 0xFF, 0xFF)}, + + {mColor(0x80, 0xFF, 0xFF, 0xFF), mColor(0x00, 0x80, 0xFF, 0xFF), mColor(0xC8, 0xC8, 0xFF, 0xFF), + 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); -STATE_DEFINE(dAcItem_c, Wait); -STATE_DEFINE(dAcItem_c, Carry); -STATE_DEFINE(dAcItem_c, GetBeetle); -STATE_DEFINE(dAcItem_c, WaitGet); -STATE_DEFINE(dAcItem_c, Get); -STATE_DEFINE(dAcItem_c, WaitGetDemo); -STATE_DEFINE(dAcItem_c, WaitForcedGetDemo); -STATE_DEFINE(dAcItem_c, GetDemo); -STATE_DEFINE(dAcItem_c, WaitTBoxGetDemo); -STATE_DEFINE(dAcItem_c, ResurgeWait); -STATE_DEFINE(dAcItem_c, WaitTurnOff); -STATE_DEFINE(dAcItem_c, WaitSacredDewGetEffect); +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, +}; + +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), @@ -360,58 +503,2200 @@ dAcItem_c::dAcItem_c() sItemList.append(&mNode); mTargetFiRelated = 3; } + dAcItem_c::~dAcItem_c() { - delete field_0xB3C; + delete mpResurgeCtl; for (int i = 0; i < 2; i++) { - delete field_0xB34[i]; + delete mpPickupPositionCtl[i]; } + delete mpMdl; mDowsingTarget.doUnregister(); } -void dAcItem_c::initializeState_Wait() {} -void dAcItem_c::executeState_Wait() {} -void dAcItem_c::finalizeState_Wait() {} +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(); + } else if (dItemMdlShield_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlShield_c(); + } else if (dItemMdlBottle_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlBottle_c(); + } else if (dItemMdlTear_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlTear_c(); + } else if (dItemMdlFirefly_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlFirefly_c(); + } else if (dItemMdlPotion_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlPotion_c(); + } else if (dItemMdlItem_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlItem_c(); + } else if (dItemMdlRupee_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlRupee_c(); + } else if (dItemMdlLightFruit_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlLightFruit_c(); + } else if (dItemMdlStaminaFruit_c::isMdlForItemId(mRealItemId)) { + mpMdl = new dItemMdlStaminaFruit_c(); + } else { + return false; + } + + if (mpMdl == nullptr) { + return false; + } + + if (!mpMdl->init(mRealItemId, this, &mAllocator)) { + return false; + } + + mpPickupPositionCtl[0] = new dAcItemPickupPositionOn_c(); + if (mpPickupPositionCtl[0] == nullptr) { + return false; + } + mpPickupPositionCtl[1] = new dAcItemPickupPositionOff_c(); + if (mpPickupPositionCtl[1] == nullptr) { + return false; + } + + if (getItemInitStruct()->_0x00[6] != 0) { + mpResurgeCtl = new dAcItemResurgeOn_c(getItemInitStruct()->_0x00[4], getItemInitStruct()->_0x00[5]); + if (mId == ITEM_STAMINA_FRUIT) { + mpResurgeCtl->setTimerInitVal(150); + } else if (isLightFruit()) { + mpResurgeCtl->setTimerInitVal(0); + } + } else { + mpResurgeCtl = new dAcItemResurgeOff_c(getItemInitStruct()->_0x00[4], getItemInitStruct()->_0x00[5]); + } + + if (mpResurgeCtl == nullptr) { + return false; + } + + return true; +} + +int dAcItem_c::create() { + u32 flag = getFromParams(0xA, 0xFF); + if (flag < 0xFF && SceneflagManager::sInstance->checkBoolFlag(mRoomID, flag)) { + return FAILED; + } + + u32 paramId = getItemIdFromParams(); + if (paramId == ITEM_NONE) { + return FAILED; + } + + if (isItemDropFromEnemy()) { + mId = determineActualItemIdFromItem(paramId); + } else { + mId = paramId; + } + + if (isGratitudeCrystal()) { + if (!StoryflagManager::sInstance->getCounterOrFlag(STORYFLAG_GRATITUDE_QUEST_STARTED) || + !dScGame_c::currentSpawnInfo.isNight()) { + return FAILED; + } + } else if (isHeart()) { + if (isItemDropFromEnemy() && dScGame_c::isHeroMode()) { + switch (adventurePouchCountItem(ITEM_HEART_MEDAL)) { + case 0: return FAILED; + case 1: + if (cM::rndInt(2) < 1) { + return FAILED; + } + } + } + } + + setItemId(getItemId2()); + + switch (getItemInitStruct()->_0x00[9]) { + case 0: mFn_0xC90 = &dAcItem_c::fn_80254DE0; break; + case 1: mFn_0xC90 = &dAcItem_c::fn_80254DF0; break; + default: return FAILED; + } + + if (isSmallKey()) { + mFnGetFreestandingScale = &dAcItem_c::getSmallKeyFreestandingScale; + } else if (isGreenRupee() || isBlueRupee() || isRedRupee() || isRupoor()) { + mFnGetFreestandingScale = &dAcItem_c::getLowValueRupeeFreestandingScale; + } else if (isSilverRupee() || isGoldRupee()) { + mFnGetFreestandingScale = &dAcItem_c::getHighValueRupeeFreestandingScale; + } else if (isSlingshot()) { + mFnGetFreestandingScale = &dAcItem_c::getSlingshotFreestandingScale; + } else if (isEldinOre()) { + mFnGetFreestandingScale = &dAcItem_c::getEldinOreFreestandingScale; + } else if (isJellyBlob()) { + mFnGetFreestandingScale = &dAcItem_c::getJellyBlobFreestandingScale; + } else if (isUnkTreasureGroup1()) { + mFnGetFreestandingScale = &dAcItem_c::getUnkTreasureGroup1FreestandingScale; + } else if (isHeartPiece()) { + mFnGetFreestandingScale = &dAcItem_c::getHeartPieceFreestandingScale; + } else if (isGratitudeCrystal()) { + mFnGetFreestandingScale = &dAcItem_c::getGratitudeCrystalFreestandingScale; + } else { + mFnGetFreestandingScale = &dAcItem_c::getDefaultFreestandingScale; + } + + if (isTreasure3()) { + mFnGetScale = &dAcItem_c::getTreasure3Scale; + } else if (isInsect()) { + mFnGetScale = &dAcItem_c::getInsectScale; + } else { + mFnGetScale = &dAcItem_c::getDefaultScale; + } + + if (isSilverRupee() || isGoldRupee()) { + mFnGetPickupDemoScale = &dAcItem_c::getHighValueRupeePickupScale; + } else { + mFnGetPickupDemoScale = &dAcItem_c::getDefaultPickupScale; + } + + mFnCallGetFreestandingScale = &dAcItem_c::callGetFreestandingModelScale; + + switch (getItemInitStruct()->_0x00[10]) { + case 0: mFnAction = &dAcItem_c::moveNormal0; break; + case 1: mFnAction = &dAcItem_c::moveNormal1; break; + case 2: mFnAction = &dAcItem_c::moveSpecial; break; + default: return FAILED; + } + + if (isHeartV()) { + mFunc_0xB58 = &dAcItem_c::fn_802555F0; + } else { + mFunc_0xB58 = &dAcItem_c::fn_802555D0; + } + + if (isAnyRupee()) { + mFnBounce = &dAcItem_c::bounceRupee; + } else if (isHeartV()) { + mFnBounce = &dAcItem_c::bounceNone; + } else { + mFnBounce = &dAcItem_c::bounceNormal; + } + + if (isAnyRupee()) { + mFnAction3 = &dAcItem_c::fn_802558F0; + } else if (isAnyTear() || isTriforce() || isHeartPiece()) { + mFnAction3 = &dAcItem_c::fn_80255AE0; + } else { + mFnAction3 = &dAcItem_c::fn_802558E0; + } + + if (getItemInitStruct()->_0x00[8] == 0) { + mFnAction4 = &dAcItem_c::fn_80248060; + } else if (getItemInitStruct()->_0x00[8] == 1) { + mFnAction4 = &dAcItem_c::fn_80248050; + } else if (getItemInitStruct()->_0x00[8] == 2) { + mFnAction4 = &dAcItem_c::fn_80255D50; + } else if (getItemInitStruct()->_0x00[8] == 3) { + mFnAction4 = &dAcItem_c::fn_80255DB0; + } else if (getItemInitStruct()->_0x00[8] == 4) { + mFnAction4 = &dAcItem_c::fn_80248060; + } else { + return FAILED; + } + + mSubtype = mId; + + CREATE_ALLOCATOR(dAcItem_c); + + if (!getFromParams(0x13, 0x1)) { + mpMdl->setPriorityDraw(); + } + mStts.SetRank(1); + mCyl.Set(sSrcCyl); + mCyl.SetStts(mStts); + mCyl.SetR(getItemFlagStruct(mId)->field_0x00); + mCyl.SetH(getItemFlagStruct(mId)->field_0x01); + + setupUnkColliderFlags2(); + + if (isAnyRupee()) { + mCyl.OnTgInfo_0x2(0x8); + mCyl.SetTgSrcField_0x0C(0x8); + } + + u32 unk = getParams2Lower_shift1_0x7(); + if ((mId == ITEM_STAMINA_FRUIT && unk) || isLightFruit() || isAnyTear() || isTriforce() || isGratitudeCrystal()) { + mCyl.SetCoGrp(0x2); + } else { + mCyl.SetCoGrp(0xE); + } + + if (mId == ITEM_STAMINA_FRUIT || isHeartPiece() || isTriforce()) { + mCyl.ClrTg_0x800000(); + } else { + mCyl.OnTg_0x800000(); + } + + if (isHeartPiece()) { + mCyl.OnTg_0x1000000(); + } + + if (isHeartPiece()) { + mCyl.SetTg_0x4C(0x6CC0); + } else if (isBabyRattle()) { + mCyl.SetTg_0x4C(0x6480); + } else if (!isAnyRupee() && !isHeartV() && mId != ITEM_STAMINA_FRUIT) { + mCyl.SetTg_0x4C(0x6480); + } + + if (isBabyRattle()) { + mCyl.SetTgInfo_0x1(0x13); + } else if (isHeartPiece()) { + mCyl.SetTgInfo_0x1(0x15); + } else if (!isAnyRupee() && !isHeartV() && mId != ITEM_STAMINA_FRUIT) { + mCyl.SetTgInfo_0x1(0x13); + } + + if (isHeartPiece()) { + mCyl.ClrTg_0x200000(); + } else { + mCyl.OnTg_0x200000(); + } + + mCyl.SetCoCallback(hitCallback); + mAcchCir.SetWall( + getItemFlagStruct(getItemId())->field_0x01 * 0.5f, getItemFlagStruct(getItemId())->field_0x00 * 0.6f + ); + mObjAcch.Set(this, 1, &mAcchCir); + mObjAcch.field_0x0D4 = 50.0f; + mObjAcch.SetClrSpeedY(); + mObjAcch.SetField_0xC(4); + mAcceleration = -2.0f; + mMaxSpeed = -80.0f; + + mGetItemPouchSlot = sGetItemPouchSlot; + mItemQuantity = sGetItemQuantity; + s32 subType = getSubtypeFromParam(mParams); + if (subType != 1 && subType != 2 && subType != 3 && subType != 4 && subType != 5 && subType != 6) { + fn_80253F90(true); + } else { + fn_80253F90(false); + } + + if (getSubtypeFromParam(mParams) == 2) { + fn_80256790(); + } else { + fn_802567D0(); + } + + switch (getSubtypeFromParam(mParams)) { + default: mStateMgr.changeState(StateID_Wait); break; + case 1: mStateMgr.changeState(StateID_Wait); break; + case 2: mStateMgr.changeState(StateID_Wait); break; + case 3: onTouchLink(); break; + case 4: mStateMgr.changeState(StateID_Get); break; + case 5: mStateMgr.changeState(StateID_WaitForcedGetDemo); break; + case 6: mStateMgr.changeState(StateID_GetBeetle); break; + case 7: mStateMgr.changeState(StateID_WaitTBoxGetDemo); break; + } + + fn_80255DF0(); + fn_80254BB0(); + + if (isHeart()) { + setDespawnTimer(600); + } else { + setDespawnTimer(300); + } + + if (isGreenRupee() || isBlueRupee() || isRedRupee() || isRupoor()) { + mFnSetBoundingBox = &dAcItem_c::setLowValueRupeeBoundingBox; + } else if (isSilverRupee() || isGoldRupee()) { + mFnSetBoundingBox = &dAcItem_c::setHighValueRupeeBoundingBox; + } else if (isArrowBundle()) { + mFnSetBoundingBox = &dAcItem_c::setArrowBundleBoundingBox; + } else { + mFnSetBoundingBox = &dAcItem_c::setDefaultBoundingBox; + } + + applyBoundingBox(); + + switch (mId) { + case ITEM_SMALL_KEY: mFnGetGravity1 = &dAcItem_c::getSmallKeyGravity1; break; + case ITEM_GREEN_RUPEE: mFnGetGravity1 = &dAcItem_c::getGreenRupeeGravity1; break; + case ITEM_BLUE_RUPEE: mFnGetGravity1 = &dAcItem_c::getBlueRupeeGravity1; break; + case ITEM_RED_RUPEE: mFnGetGravity1 = &dAcItem_c::getRedRupeeGravity1; break; + case ITEM_HEART: mFnGetGravity1 = &dAcItem_c::getHeartGravity1; break; + case ITEM_SINGLE_ARROW: mFnGetGravity1 = &dAcItem_c::getSingleArrowGravity1; break; + case ITEM_BUNDLE_ARROWS: mFnGetGravity1 = &dAcItem_c::getArrowBundleGravity1; break; + case ITEM_SILVER_RUPEE: mFnGetGravity1 = &dAcItem_c::getSilverRupeeGravity1; break; + case ITEM_GOLD_RUPEE: mFnGetGravity1 = &dAcItem_c::getGoldRupeeGravity1; break; + case ITEM_RUPOOR: mFnGetGravity1 = &dAcItem_c::getRupoorGravity1; break; + case ITEM_5_BOMBS: mFnGetGravity1 = &dAcItem_c::get5BombsGravity1; break; + case ITEM_10_BOMBS: mFnGetGravity1 = &dAcItem_c::get10BombsGravity1; break; + case ITEM_FARORE_TEAR: mFnGetGravity1 = &dAcItem_c::getFaroreTearGravity1; break; + case ITEM_5_DEKU_SEEDS: mFnGetGravity1 = &dAcItem_c::get5SeedsGravity1; break; + default: mFnGetGravity1 = &dAcItem_c::getDefaultGravity1; break; + } + + switch (mId) { + case ITEM_HEART: mFnGetHeartGravity = &dAcItem_c::getHeartGravity2; break; + default: mFnGetHeartGravity = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetRupeeGravity = &dAcItem_c::getGreenRupeeGravity3; break; + case ITEM_BLUE_RUPEE: mFnGetRupeeGravity = &dAcItem_c::getBlueRupeeGravity3; break; + case ITEM_RED_RUPEE: mFnGetRupeeGravity = &dAcItem_c::getRedRupeeGravity3; break; + case ITEM_SILVER_RUPEE: mFnGetRupeeGravity = &dAcItem_c::getSilverRupeeGravity3; break; + case ITEM_GOLD_RUPEE: mFnGetRupeeGravity = &dAcItem_c::getGoldRupeeGravity3; break; + case ITEM_RUPOOR: mFnGetRupeeGravity = &dAcItem_c::getRupoorGravity3; break; + default: mFnGetRupeeGravity = nullptr; break; + } + + switch (mId) { + case ITEM_SMALL_KEY: mFnGetGravity4 = &dAcItem_c::getSmallKeyGravity4; break; + case ITEM_GREEN_RUPEE: mFnGetGravity4 = &dAcItem_c::getGreenRupeeGravity4; break; + case ITEM_BLUE_RUPEE: mFnGetGravity4 = &dAcItem_c::getBlueRupeeGravity4; break; + case ITEM_RED_RUPEE: mFnGetGravity4 = &dAcItem_c::getRedRupeeGravity4; break; + case ITEM_HEART: mFnGetGravity4 = &dAcItem_c::getHeartGravity4; break; + case ITEM_SINGLE_ARROW: mFnGetGravity4 = &dAcItem_c::getSingleArrowGravity4; break; + case ITEM_BUNDLE_ARROWS: mFnGetGravity4 = &dAcItem_c::getArrowBundleGravity4; break; + case ITEM_SILVER_RUPEE: mFnGetGravity4 = &dAcItem_c::getSilverRupeeGravity4; break; + case ITEM_GOLD_RUPEE: mFnGetGravity4 = &dAcItem_c::getGoldRupeeGravity4; break; + case ITEM_RUPOOR: mFnGetGravity4 = &dAcItem_c::getRupoorGravity4; break; + case ITEM_5_BOMBS: mFnGetGravity4 = &dAcItem_c::get5BombsGravity4; break; + case ITEM_10_BOMBS: mFnGetGravity4 = &dAcItem_c::get10BombsGravity4; break; + case ITEM_FARORE_TEAR: mFnGetGravity4 = &dAcItem_c::getFaroreTearGravity4; break; + case ITEM_5_DEKU_SEEDS: mFnGetGravity4 = &dAcItem_c::get5SeedsGravity4; break; + default: mFnGetGravity4 = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetDirHitKnockback = &dAcItem_c::getGreenRupeeDirHitKnockback; break; + case ITEM_BLUE_RUPEE: mFnGetDirHitKnockback = &dAcItem_c::getBlueRupeeDirHitKnockback; break; + case ITEM_RED_RUPEE: mFnGetDirHitKnockback = &dAcItem_c::getRedRupeeDirHitKnockback; break; + case ITEM_SILVER_RUPEE: mFnGetDirHitKnockback = &dAcItem_c::getSilverRupeeDirHitKnockback; break; + case ITEM_GOLD_RUPEE: mFnGetDirHitKnockback = &dAcItem_c::getGoldRupeeDirHitKnockback; break; + case ITEM_RUPOOR: mFnGetDirHitKnockback = &dAcItem_c::getRupoorDirHitKnockback; break; + default: mFnGetDirHitKnockback = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetDirHitKnockbackRand = &dAcItem_c::getGreenRupeeDirHitKnockbackRand; break; + case ITEM_BLUE_RUPEE: mFnGetDirHitKnockbackRand = &dAcItem_c::getBlueRupeeDirHitKnockbackRand; break; + case ITEM_RED_RUPEE: mFnGetDirHitKnockbackRand = &dAcItem_c::getRedRupeeDirHitKnockbackRand; break; + case ITEM_SILVER_RUPEE: mFnGetDirHitKnockbackRand = &dAcItem_c::getSilverRupeeDirHitKnockbackRand; break; + case ITEM_GOLD_RUPEE: mFnGetDirHitKnockbackRand = &dAcItem_c::getGoldRupeeDirHitKnockbackRand; break; + case ITEM_RUPOOR: mFnGetDirHitKnockbackRand = &dAcItem_c::getRupoorDirHitKnockbackRand; break; + default: mFnGetDirHitKnockbackRand = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetHitKnockback = &dAcItem_c::getGreenRupeeHitKnockback; break; + case ITEM_BLUE_RUPEE: mFnGetHitKnockback = &dAcItem_c::getBlueRupeeHitKnockback; break; + case ITEM_RED_RUPEE: mFnGetHitKnockback = &dAcItem_c::getRedRupeeHitKnockback; break; + case ITEM_SILVER_RUPEE: mFnGetHitKnockback = &dAcItem_c::getSilverRupeeHitKnockback; break; + case ITEM_GOLD_RUPEE: mFnGetHitKnockback = &dAcItem_c::getGoldRupeeHitKnockback; break; + case ITEM_RUPOOR: mFnGetHitKnockback = &dAcItem_c::getRupoorHitKnockback; break; + default: mFnGetHitKnockback = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetHitKnockbackRand = &dAcItem_c::getGreenRupeeHitKnockbackRand; break; + case ITEM_BLUE_RUPEE: mFnGetHitKnockbackRand = &dAcItem_c::getBlueRupeeHitKnockbackRand; break; + case ITEM_RED_RUPEE: mFnGetHitKnockbackRand = &dAcItem_c::getRedRupeeHitKnockbackRand; break; + case ITEM_SILVER_RUPEE: mFnGetHitKnockbackRand = &dAcItem_c::getSilverRupeeHitKnockbackRand; break; + case ITEM_GOLD_RUPEE: mFnGetHitKnockbackRand = &dAcItem_c::getGoldRupeeHitKnockbackRand; break; + case ITEM_RUPOOR: mFnGetHitKnockbackRand = &dAcItem_c::getRupoorHitKnockbackRand; break; + default: mFnGetHitKnockbackRand = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetHitSquareDistance2 = &dAcItem_c::getGreenRupeeHitSquareDistance2; break; + case ITEM_BLUE_RUPEE: mFnGetHitSquareDistance2 = &dAcItem_c::getBlueRupeeHitSquareDistance2; break; + case ITEM_RED_RUPEE: mFnGetHitSquareDistance2 = &dAcItem_c::getRedRupeeHitSquareDistance2; break; + case ITEM_SILVER_RUPEE: mFnGetHitSquareDistance2 = &dAcItem_c::getSilverRupeeHitSquareDistance2; break; + case ITEM_GOLD_RUPEE: mFnGetHitSquareDistance2 = &dAcItem_c::getGoldRupeeHitSquareDistance2; break; + case ITEM_RUPOOR: mFnGetHitSquareDistance2 = &dAcItem_c::getRupoorHitSquareDistance2; break; + case ITEM_HEART: mFnGetHitSquareDistance2 = &dAcItem_c::getHeartHitSquareDistance2; break; + default: mFnGetHitSquareDistance2 = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetDirHitKnockback2 = &dAcItem_c::getGreenRupeeDirHitKnockback2; break; + case ITEM_BLUE_RUPEE: mFnGetDirHitKnockback2 = &dAcItem_c::getBlueRupeeDirHitKnockback2; break; + case ITEM_RED_RUPEE: mFnGetDirHitKnockback2 = &dAcItem_c::getRedRupeeDirHitKnockback2; break; + case ITEM_SILVER_RUPEE: mFnGetDirHitKnockback2 = &dAcItem_c::getSilverRupeeDirHitKnockback2; break; + case ITEM_GOLD_RUPEE: mFnGetDirHitKnockback2 = &dAcItem_c::getGoldRupeeDirHitKnockback2; break; + case ITEM_RUPOOR: mFnGetDirHitKnockback2 = &dAcItem_c::getRupoorDirHitKnockback2; break; + case ITEM_HEART: mFnGetDirHitKnockback2 = &dAcItem_c::getHeartDirHitKnockback2; break; + default: mFnGetDirHitKnockback2 = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetDirHitKnockbackRand2 = &dAcItem_c::getGreenRupeeDirHitKnockbackRand2; break; + case ITEM_BLUE_RUPEE: mFnGetDirHitKnockbackRand2 = &dAcItem_c::getBlueRupeeDirHitKnockbackRand2; break; + case ITEM_RED_RUPEE: mFnGetDirHitKnockbackRand2 = &dAcItem_c::getRedRupeeDirHitKnockbackRand2; break; + case ITEM_SILVER_RUPEE: mFnGetDirHitKnockbackRand2 = &dAcItem_c::getSilverRupeeDirHitKnockbackRand2; break; + case ITEM_GOLD_RUPEE: mFnGetDirHitKnockbackRand2 = &dAcItem_c::getGoldRupeeDirHitKnockbackRand2; break; + case ITEM_RUPOOR: mFnGetDirHitKnockbackRand2 = &dAcItem_c::getRupoorDirHitKnockbackRand2; break; + case ITEM_HEART: mFnGetDirHitKnockbackRand2 = &dAcItem_c::getHeartDirHitKnockbackRand2; break; + default: mFnGetDirHitKnockbackRand2 = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetHitKnockback2 = &dAcItem_c::getGreenRupeeHitKnockback2; break; + case ITEM_BLUE_RUPEE: mFnGetHitKnockback2 = &dAcItem_c::getBlueRupeeHitKnockback2; break; + case ITEM_RED_RUPEE: mFnGetHitKnockback2 = &dAcItem_c::getRedRupeeHitKnockback2; break; + case ITEM_SILVER_RUPEE: mFnGetHitKnockback2 = &dAcItem_c::getSilverRupeeHitKnockback2; break; + case ITEM_GOLD_RUPEE: mFnGetHitKnockback2 = &dAcItem_c::getGoldRupeeHitKnockback2; break; + case ITEM_RUPOOR: mFnGetHitKnockback2 = &dAcItem_c::getRupoorHitKnockback2; break; + case ITEM_HEART: mFnGetHitKnockback2 = &dAcItem_c::getHeartHitKnockback2; break; + default: mFnGetHitKnockback2 = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetHitKnockbackRand2 = &dAcItem_c::getGreenRupeeHitKnockbackRand2; break; + case ITEM_BLUE_RUPEE: mFnGetHitKnockbackRand2 = &dAcItem_c::getBlueRupeeHitKnockbackRand2; break; + case ITEM_RED_RUPEE: mFnGetHitKnockbackRand2 = &dAcItem_c::getRedRupeeHitKnockbackRand2; break; + case ITEM_SILVER_RUPEE: mFnGetHitKnockbackRand2 = &dAcItem_c::getSilverRupeeHitKnockbackRand2; break; + case ITEM_GOLD_RUPEE: mFnGetHitKnockbackRand2 = &dAcItem_c::getGoldRupeeHitKnockbackRand2; break; + case ITEM_RUPOOR: mFnGetHitKnockbackRand2 = &dAcItem_c::getRupoorHitKnockbackRand2; break; + case ITEM_HEART: mFnGetHitKnockbackRand2 = &dAcItem_c::getHeartHitKnockbackRand2; break; + default: mFnGetHitKnockbackRand2 = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetDirHitKnockback3 = &dAcItem_c::getGreenRupeeDirHitKnockback3; break; + case ITEM_BLUE_RUPEE: mFnGetDirHitKnockback3 = &dAcItem_c::getBlueRupeeDirHitKnockback3; break; + case ITEM_RED_RUPEE: mFnGetDirHitKnockback3 = &dAcItem_c::getRedRupeeDirHitKnockback3; break; + case ITEM_SILVER_RUPEE: mFnGetDirHitKnockback3 = &dAcItem_c::getSilverRupeeDirHitKnockback3; break; + case ITEM_GOLD_RUPEE: mFnGetDirHitKnockback3 = &dAcItem_c::getGoldRupeeDirHitKnockback3; break; + case ITEM_RUPOOR: mFnGetDirHitKnockback3 = &dAcItem_c::getRupoorDirHitKnockback3; break; + case ITEM_HEART: mFnGetDirHitKnockback3 = &dAcItem_c::getHeartDirHitKnockback3; break; + default: mFnGetDirHitKnockbackRand2 = nullptr; break; // @bug copypasta mistake + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetDirHitKnockbackRand3 = &dAcItem_c::getGreenRupeeDirHitKnockbackRand3; break; + case ITEM_BLUE_RUPEE: mFnGetDirHitKnockbackRand3 = &dAcItem_c::getBlueRupeeDirHitKnockbackRand3; break; + case ITEM_RED_RUPEE: mFnGetDirHitKnockbackRand3 = &dAcItem_c::getRedRupeeDirHitKnockbackRand3; break; + case ITEM_SILVER_RUPEE: mFnGetDirHitKnockbackRand3 = &dAcItem_c::getSilverRupeeDirHitKnockbackRand3; break; + case ITEM_GOLD_RUPEE: mFnGetDirHitKnockbackRand3 = &dAcItem_c::getGoldRupeeDirHitKnockbackRand3; break; + case ITEM_RUPOOR: mFnGetDirHitKnockbackRand3 = &dAcItem_c::getRupoorDirHitKnockbackRand3; break; + case ITEM_HEART: mFnGetDirHitKnockbackRand3 = &dAcItem_c::getHeartDirHitKnockbackRand3; break; + default: mFnGetDirHitKnockbackRand2 = nullptr; break; // @bug copypasta mistake + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetHitKnockback3 = &dAcItem_c::getGreenRupeeHitKnockback3; break; + case ITEM_BLUE_RUPEE: mFnGetHitKnockback3 = &dAcItem_c::getBlueRupeeHitKnockback3; break; + case ITEM_RED_RUPEE: mFnGetHitKnockback3 = &dAcItem_c::getRedRupeeHitKnockback3; break; + case ITEM_SILVER_RUPEE: mFnGetHitKnockback3 = &dAcItem_c::getSilverRupeeHitKnockback3; break; + case ITEM_GOLD_RUPEE: mFnGetHitKnockback3 = &dAcItem_c::getGoldRupeeHitKnockback3; break; + case ITEM_RUPOOR: mFnGetHitKnockback3 = &dAcItem_c::getRupoorHitKnockback3; break; + case ITEM_HEART: mFnGetHitKnockback3 = &dAcItem_c::getHeartHitKnockback3; break; + default: mFnGetHitKnockback3 = nullptr; break; + } + + switch (mId) { + case ITEM_GREEN_RUPEE: mFnGetHitKnockbackRand3 = &dAcItem_c::getGreenRupeeHitKnockbackRand3; break; + case ITEM_BLUE_RUPEE: mFnGetHitKnockbackRand3 = &dAcItem_c::getBlueRupeeHitKnockbackRand3; break; + case ITEM_RED_RUPEE: mFnGetHitKnockbackRand3 = &dAcItem_c::getRedRupeeHitKnockbackRand3; break; + case ITEM_SILVER_RUPEE: mFnGetHitKnockbackRand3 = &dAcItem_c::getSilverRupeeHitKnockbackRand3; break; + case ITEM_GOLD_RUPEE: mFnGetHitKnockbackRand3 = &dAcItem_c::getGoldRupeeHitKnockbackRand3; break; + case ITEM_RUPOOR: mFnGetHitKnockbackRand3 = &dAcItem_c::getRupoorHitKnockbackRand3; break; + case ITEM_HEART: mFnGetHitKnockbackRand3 = &dAcItem_c::getHeartHitKnockbackRand3; break; + default: mFnGetHitKnockbackRand3 = nullptr; break; + } + + if (isHeartV()) { + mFnGetSinkSpeed = &dAcItem_c::getSinkSpeedHeart; + } else { + mFnGetSinkSpeed = &dAcItem_c::getSinkSpeedDefault; + } + + if (mbNoDespawn) { + dBgS::GetInstance()->SetLightingCode(this, 10.0f); + } else if (isHeartV()) { + mLinkage.bushTpFunc(mObjAcch); + } + + if (isHeartV()) { + field_0xD20 = 6; + } + + if (isAnyTear()) { + mSomeStr = "force"; + } + + if (isAnyTear()) { + s32 type = getTearSubtype(mId); + if (type == TEAR_MAX) { + type = TEAR_FARON; + } + dAcObjBase_c *forceSign = + dAcObjBase_c::create(this, fProfile::OBJ_FORCE_SIGN, type & 0xFF, nullptr, nullptr, nullptr, nullptr, 0x3F); + if (forceSign != nullptr) { + mForceSignRef.link(forceSign); + } + } + + if (isAnyTear()) { + dAcBase_c *forceGetFlag = dAcBase_c::createActorStage( + fProfile::TAG_FORCE_GET_FLAG, dTgForceGetFlag_c::tearIdxToParam(getTearIdx()), &mPosition, &mRotation, + &mScale, 0, mRoomID, this + ); + if (forceGetFlag == nullptr) { + return FAILED; + } + } + + if (mId == ITEM_STAMINA_FRUIT && unk) { + u32 p1 = (getFirstBitParams2() & 0x1) << 8; + u32 parms = ((mParams >> 0x13) & 0x1) | (p1 & ~0x1); + dAcObjBase_c *leaves = + dAcObjBase_c::create(fProfile::OBJ_FRUIT_GUTS_LEAF, mRoomID, parms, &mPosition, &mRotation, &mScale, -1); + if (leaves == nullptr) { + return FAILED; + } + } + + if (isGreenRupee() || isBlueRupee() || isRedRupee() || isSilverRupee() || isGoldRupee()) { + mDowsingTarget.initialize(DowsingTarget::SLOT_RUPEE, 0, &sFreestandingDowsingOffset, 0.0f); + mDowsingTarget.doRegister(); + } else if (isHeart()) { + mDowsingTarget.initialize(DowsingTarget::SLOT_HEART, 0, &sFreestandingDowsingOffset, 0.0f); + mDowsingTarget.doRegister(); + } else if (is5GratitudeCrystals() || isGratitudeCrystal()) { + mDowsingTarget.initialize(DowsingTarget::SLOT_CRYSTAL, 0, &sFreestandingDowsingOffset, 0.0f); + mDowsingTarget.doRegister(); + } else if (isTreasure2((ITEM_ID)mId)) { + mDowsingTarget.initialize(DowsingTarget::SLOT_TREASURE, 0, &sFreestandingDowsingOffset, 0.0f); + mDowsingTarget.doRegister(); + } + + if (isGratitudeCrystal() || isUnkTreasureGroup1()) { + setFreestandingYOffset(-mpMdl->getMdl()->getResMdl().GetResNode(sResNodeName).GetTranslate().y); + } + + if (mId == ITEM_STAMINA_FRUIT && unk == 0) { + mItemFlags |= 4; + } + + if ((isGratitudeCrystal() || is5GratitudeCrystals()) && !isItemDropFromEnemy() && mStateMgr.isState(StateID_Wait)) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_ENERGY_SOURCE_OUTWELL); + } + + if (EventManager::isInEvent() && EventManager::isCurrentEvent("GetGenkiItem")) { + setItemFlags(mItemFlags | 0x20); + } + + // okay + bool is = isHeartPiece(); + if (is) { + is = dScGame_c::isCurrentStage("D100"); + } + if (is) { + is = mPosition.squareDistance(mVec3_c(0.0f, -190.0f, -9590.0f)) < 10000.0f; + } + if (is) { + // Skyview Temple - Heart Piece behind bars in main room + setItemFlags(mItemFlags | 0x80); + } + + field_0xD48 = cM::rndInt(0x10000); + mColorFilter.r = 0; + mColorFilter.g = 0; + mColorFilter.b = 0; + mLightLevelMaybe = 0.0f; + + return SUCCEEDED; +} + +int dAcItem_c::doDelete() { + sItemList.remove(&this->mNode); + dAcItem_c *prev = mItemQueuePrev.get(); + dAcItem_c *next = mItemQueueNext.get(); + + if (prev == nullptr) { + if (next == nullptr) { + if (this == sItemListHead.get()) { + sItemListHead.unlink(); + } + if (this == sItemListTail.get()) { + sItemListTail.unlink(); + } + } else { + sItemListHead.link(next); + next->mItemQueuePrev.unlink(); + } + } else if (next == nullptr) { + sItemListTail.link(prev); + prev->mItemQueueNext.unlink(); + } else { + prev->mItemQueueNext.link(next); + next->mItemQueuePrev.link(prev); + } + + return SUCCEEDED; +} + +int dAcItem_c::actorExecute() { + if (!checkActorProperty(AC_PROP_0x10000000)) { + if (mId == ITEM_STAMINA_FRUIT) { + if (isFirstBitParams2NotSet() && !fn_802577A0()) { + field_0xCD8 = 0.0f; + } else { + field_0xCD8 = 1.0f; + } + } else if (isLightFruit()) { + if ((this->*mFnAction4)()) { + field_0xCD8 = 1.0f; + } else { + field_0xCD8 = 0.0f; + } + } + + dAcOScatterSand *ac = + static_cast<dAcOScatterSand *>(fManager_c::searchBaseByProfName(fProfile::OBJ_VSD, nullptr)); + bool keepGoing = true; + while (keepGoing && ac != nullptr) { + if (mPosition.squareDistance(ac->mPosition) < 90000.0f) { + mCoveredSand.link(ac); + keepGoing = false; + } else { + ac = static_cast<dAcOScatterSand *>(fManager_c::searchBaseByProfName(fProfile::OBJ_VSD, ac)); + } + } + } + + if (field_0xD4C < 0xFF) { + field_0xD4C++; + } + + fn_80254BC0(); + fn_80255B10(); + + field_0xD5C = 0; + field_0xD66 = 0; + + mStateMgr.executeState(); + + updateLightingMaybe(); + if (mDespawnTimer == 0) { + deleteRequest(); + return SUCCEEDED; + } + + if ((mItemFlags & 0x8) != 0) { + deleteRequest(); + return SUCCEEDED; + } + + mRotation.y += field_0xD38; + f32 scaleF = getCurrentScale(); + mScale.set(scaleF, scaleF, scaleF); + mVec3_c tmp1; + fn_802518C0(&tmp1); + mPositionCopy2.set(tmp1); + mVec3_c tmp2; + fn_802518C0(&tmp2); + mPositionCopy3.set(tmp2); + + mLinkage.fn_800511E0(this); + + if (!checkObjectProperty(OBJ_PROP_0x200)) { + mMtx_c mtx = mWorldMtx; + mtx.YrotM(mMdlRotY); + mtx.ZrotM(field_0xD42); + + if (isGratitudeCrystal() || isUnkTreasureGroup1()) { + if (mStateMgr.isState(StateID_Wait) || mStateMgr.isState(StateID_Carry)) { + f32 off = mFreestandingOffsetH; + f32 sc = getCurrentScale(); + mtx.m[1][3] += sc * off; + } + } else if (isInsect()) { + if (mStateMgr.isState(StateID_Get)) { + mtx.YrotM(-0x2000); + } + } + + mpMdl->setLocalMtx(mtx); + mpMdl->setScale(mScale); + + if (isFairyV() || isBottleFairyV()) { + m3d::smdl_c *mdl = mpMdl->getMdl(); + if (mdl != nullptr) { + mdl->calc(false); + } + } + } + + field_0xD51 = 0; + mCyl.ClrTgHit(); + mCyl.ClrCoHit(); + field_0xD65 = 0; + if ((isAnyRupeeV() || mId == ITEM_STAMINA_FRUIT) && field_0xD66 && mObjAcch.ChkGroundLanding()) { + dJEffManager_c::spawnGroundEffect(mPosition, mPolyAttr0, mPolyAttr1, field_0x1B4, 1, 0.7f, field_0x1B0); + } + + if (isStarryFireflyV() && !checkObjectProperty(OBJ_PROP_0x200)) { + fn_802546A0(); + } + + if (isFairyV() && !checkObjectProperty(OBJ_PROP_0x200)) { + fn_80254710(); + } + + if (isBottleFairyV() && !checkObjectProperty(OBJ_PROP_0x200)) { + fn_80254790(); + } + + if (checkAbovePosition()) { + mItemFlags |= 0x10; + f32 f = mPosition.y - dBgS_ObjGndChk::GetGroundHeight(); + field_0xD18 = f < 0.0f ? 0.0f : f; + } else { + mItemFlags &= ~0x10; + } + + applyBoundingBox(); + + if (isField_0xD04GtZero() || mStateMgr.isState(StateID_WaitGetDemo) || mStateMgr.isState(StateID_Get) || + mStateMgr.isState(StateID_GetBeetle)) { + setActorProperty(AC_PROP_0x4); + } else { + unsetActorProperty(AC_PROP_0x4); + } + + return SUCCEEDED; +} + +int dAcItem_c::draw() { + if (mMdlScaleType == 2 || 0.0f < field_0xCD8) { + bool shouldDraw = true; + if (isMdlHidden()) { + shouldDraw = false; + } else if ((mStateMgr.isState(StateID_Wait) || mStateMgr.isState(StateID_Carry)) && mbIsWaiting) { + shouldDraw = isBlinkBeforeDespawnShown(mDespawnTimer); + } + if (shouldDraw) { + mpMdl->draw(); + } + + if (mLinkage.checkConnection(dLinkage_c::CONNECTION_9) || + (mId == ITEM_STAMINA_FRUIT && getParams2Lower_shift1_0x7()) || isLightFruit() || (mItemFlags & 0x10) == 0) { + /* nothing */ + } else if (mMdlScaleType == 2) { + mQuat_c v(mVec3_c(0.0f, 0.0f, 0.0f), getItemFlagStruct(getItemId())->field_0x02); + drawShadow(mShdw, nullptr, mWorldMtx, &v, -1, -1, -1, -1, -1, field_0xD18); + } else { + mQuat_c v( + mVec3_c(0.0f, field_0xCD8 * 0.5f * getItemFlagStruct(getItemId())->field_0x01, 0.0f), + field_0xCD8 * getItemFlagStruct(getItemId())->field_0x02 + ); + drawShadow(mShdw, nullptr, mWorldMtx, &v, -1, -1, -1, -1, -1, field_0xD18); + } + } + return SUCCEEDED; +} + +void dAcItem_c::setSpawnQuantity(s32 quantity) { + sGetItemQuantity = quantity; +} + +void dAcItem_c::setFreestandingYOffset(f32 off) { + mFreestandingOffsetH = off; +} + +void dAcItem_c::setFramesInAir(u32 numFrames) { + mFramesInAir = numFrames; +} + +void dAcItem_c::setItemFlags(u32 flags) { + mItemFlags = flags; +} + +bool dAcItem_c::isItemDropFromEnemy() const { + return mObjID != 0xFFFF; +} + +void dAcItem_c::unsetSpawnQuantity() { + sGetItemQuantity = 0; +} + +void dAcItem_c::unsetFramesInAir() { + setFramesInAir(0); +} + +void dAcItem_c::incrementFramesInAir() { + u32 v = mFramesInAir; + increment(&v); + setFramesInAir(v); +} + +void dAcItem_c::initializeState_Wait() { + if (mbNoGravity) { + setActorProperty(AC_PROP_0x1); + mSpeed = 0.0f; + mVelocity.y = 0.0f; + } + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Put); + field_0xD5B = 0; + field_0xD38 = field_0xD3A = field_0xD3C = 0; + fn_80253E20(); + if (mbNoGravity) { + mObjAcch.SetMoveBGOnly(); + } + mMdlScaleType = 0; + mSinkOffset = 0.0f; + mYOffset = 0.0f; +} + +void dAcItem_c::executeState_Wait() { + bool isFixedPosition; + + bool tmp = false; + mVec3_c topPos = getPosition() + mVec3_c::Ey * mCyl.GetH(); + bool chk = dBgS_ObjRoofChk::CheckPos(&getPosition()); + if (chk) { + tmp = dBgS_ObjRoofChk::GetRoofHeight() < topPos.y; + } + if (tmp) { + isFixedPosition = false; + } else { + f32 f = chk ? dBgS_ObjRoofChk::GetRoofHeight() : 500.0f; + mVec3_c chkPos = getPosition() + mVec3_c::Ey * f; + if (dBgS_ObjGndChk::CheckPos(chkPos)) { + if (topPos.y < dBgS_ObjGndChk::GetGroundHeight()) { + const dAcObjBase_c *obj = dBgS::GetInstance()->GetActorPointer(dBgS_ObjGndChk::GetInstance()); + if (obj == nullptr) { + isFixedPosition = false; + } else { + isFixedPosition = obj->mProfileName == fProfile::OBJ_DESERT; + } + } else { + isFixedPosition = false; + } + } else { + isFixedPosition = false; + } + } + + if (isBabyRattle() && !isFixedPosition) { + isFixedPosition = mCoveredSand.isLinked(); + } + + if (fn_80255CF0() && field_0xD4C > 16 && (!mbNoGravity || !isFixedPosition)) { + mCyl.OnTgCoFlag(0x1); + } else { + mCyl.OffTgCoFlag(0x1); + } + + if ((mItemFlags & 0x80) != 0) { + if (SceneflagManager::sInstance->checkBoolFlag(mRoomID, 0x1D)) { + mCyl.OnTgType(0x2); + } else { + mCyl.OffTgType(0x2); + } + } + + dAcPy_c *link = dAcPy_c::GetLinkM(); + bool tgHit = mCyl.ChkTgHit(); + bool tgBit1; + if (tgHit) { + tgBit1 = mCyl.ChkTgBit1(); + } else { + tgBit1 = false; + } + if (!link->checkFlags0x340(0x10)) { + if (field_0xD65 || (tgHit && (mCyl.ChkTgAtHitType(AT_TYPE_SWORD) || mCyl.ChkTgAtHitType(AT_TYPE_BUGNET)))) { + onTouchLink(); + return; + } + + if (fn_802574A0() && !tgBit1) { + // TODO weird double load of link + link = dAcPy_c::GetLinkM(); + if (!link->vt_0x1C0()) { + addToGetQueue(); + + if ((link->ifHasHealthAndSomethingElse() && this == sItemListHead.get() && + FileManager::GetInstance()->getCurrentHealth() != 0)) { + if (isSmallKey() || isBabyRattle()) { + mStateMgr.changeState(StateID_WaitForcedGetDemo); + } else { + mStateMgr.changeState(StateID_Get); + } + } else { + mStateMgr.changeState(StateID_Get); + } + } else { + mStateMgr.changeState(StateID_GetBeetle); + } + + return; + } + } + + u32 fruitParam = getParams2Lower_shift1_0x7(); + if (tgHit) { + if (mId == ITEM_STAMINA_FRUIT) { + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_373_, mPosition, &mRotation, &mScale, nullptr, nullptr, 0, 0 + ); + startSound(SE_O_REFRESH_FRUIT_BREAK); + if (!fruitParam) { + deleteRequest(); + } else { + mStateMgr.changeState(StateID_ResurgeWait); + } + return; + } else if (isLightFruit()) { + mStateMgr.changeState(StateID_ResurgeWait); + return; + } + + if (mCyl.ChkTgAtHitType(AT_TYPE_GLITTERING_SPORES)) { + if (isHeart()) { + if (fn_8024A230()) { + mVec3_c spawnPos(mPosition.x, mPosition.y + 30.0f, mPosition.z); + dAcObjBase_c::create(fProfile::OBJ_FAIRY, mRoomID, 0x3F, &spawnPos, nullptr, nullptr, -1); + dJEffManager_c::spawnEffect( + PARTICLE_RESOURCE_ID_MAPPING_375_, spawnPos, nullptr, nullptr, nullptr, nullptr, 0, 0 + ); + deleteRequest(); + return; + } + } else { + s32 accWeight = 0; + for (int i = 0; i <= (int)ARRAY_LENGTH(sSporeRupeeChances) - 1; i++) { + if (getItemId() != sSporeRupeeChances[i].itemId) { + accWeight += sSporeRupeeChances[i].weight; + } + } + s32 roll = cM::rndInt(accWeight); + s32 acc = 0; + bool found = false; + int i = 0; + while (!found && i <= (int)ARRAY_LENGTH(sSporeRupeeChances) - 1) { + if (getItemId() == sSporeRupeeChances[i].itemId) { + i++; + } else { + acc += sSporeRupeeChances[i].weight; + if (roll < acc) { + found = true; + } else { + i++; + } + } + } + setItemId(sSporeRupeeChances[i].itemId); + mpMdl->changeItemId(sSporeRupeeChances[i].itemId); + unsetHaveNoGravity(); + mVelocity.y = 10.0f; + fn_80252A80(); + } + } + } + + tickDespawnTimer(); + if (mDespawnTimer == 0) { + return; + } + + if (mLinkage.checkState(dLinkage_c::STATE_ACTIVE)) { + mStateMgr.changeState(StateID_Carry); + return; + } + + fn_80253D50(); + + if (mId == ITEM_STAMINA_FRUIT) { + if (isFirstBitParams2NotSet() && !fn_802577A0()) { + sLib::chase(&field_0xCD8, 0.0f, 0.05f); + } else { + sLib::chase(&field_0xCD8, 1.0f, 0.05f); + } + } else if (isLightFruit()) { + if ((this->*mFnAction4)()) { + sLib::chase(&field_0xCD8, 1.0f, 0.05f); + } else { + field_0xCD8 = 0.0f; + } + } + + bool tgHitArrow = tgHit && mCyl.ChkTgAtHitType(AT_TYPE_ARROW); + bool tgHitClawshot = tgHit && mCyl.ChkTgAtHitType(AT_TYPE_CLAWSHOT); + if (mbNoGravity && tgHit && + ((isAnyRupee() && tgHitArrow) || (isHeartV() && mCyl.ChkTgAtHitType(AT_TYPE_BELLOWS)) || + ((isAnyRupee() || isHeartV()) && + (mCyl.ChkTgAtHitType(AT_TYPE_SLINGSHOT) || mCyl.ChkTgAtHitType(AT_TYPE_CLAWSHOT))) || + mCyl.ChkTgAtHitType(AT_TYPE_BOMB) || mCyl.ChkTgAtHitType(AT_TYPE_0x800000))) { + unsetHaveNoGravity(); + } + + if (mbNoGravity && mCyl.ChkCoHit()) { + unsetHaveNoGravity(); + } + + if (!mbNoGravity) { + unsetActorProperty(AC_PROP_0x1); + } + + if (mbNoGravity) { + mObjAcch.SetMoveBGOnly(); + } else { + mObjAcch.ClrMoveBGOnly(); + } + + if (tgHitArrow) { + field_0xD62 = true; + } else if (tgHit || (!mObjAcch.ChkGroundLanding() && mObjAcch.ChkGndHit())) { + field_0xD62 = false; + } + if (tgHitClawshot) { + field_0xD63 = true; + } else if (tgHit || (!mObjAcch.ChkGroundLanding() && mObjAcch.ChkGndHit())) { + field_0xD63 = false; + } + + if (!mbNoGravity) { + if (!field_0xD51) { + if (isAnyRupee()) { + s32 which; + if (field_0xD62 || field_0xD63) { + which = 1; + } else { + which = 2; + } + if (which == 1 && mFnGetRupeeGravity == nullptr) { + which = 2; + } + if (which == 2 && mFnGetGravity1 == nullptr) { + which = 0; + } + + switch (which) { + case 1: mAcceleration = (this->*mFnGetRupeeGravity)(); break; + case 2: mAcceleration = (this->*mFnGetGravity1)(); break; + } + } else if (isHeartV()) { + if (field_0xD52) { + if (mFnGetHeartGravity != nullptr) { + mAcceleration = (this->*mFnGetHeartGravity)(); + } + } else { + if (mFnGetGravity1 != nullptr) { + mAcceleration = (this->*mFnGetGravity1)(); + } + } + } else { + if (mFnGetRupeeGravity == nullptr || !field_0xD62) { + if (mFnGetGravity1 != nullptr) { + mAcceleration = (this->*mFnGetGravity1)(); + } + } else { + if (mFnGetRupeeGravity != nullptr) { + mAcceleration = (this->*mFnGetRupeeGravity)(); + } + } + } + + if (mFnGetGravity4 != nullptr) { + mMaxSpeed = (this->*mFnGetGravity4)(); + } + + fn_80256F20(); + (this->*mFnAction)(); + calcVelocity(); + mPosition += mVelocity; + mPosition += mStts.GetCcMove(); + } + + if ((mId == ITEM_STAMINA_FRUIT && fruitParam) || isLightFruit()) { + /* nothing */ + } else { + if (!mbNoGravity && !field_0xD51 && 0.0f < mVelocity.y) { + mObjAcch.ClrRoofNone(); + mObjAcch.Clr_0x2000000(); + } else { + mObjAcch.SetRoofNone(); + mObjAcch.Set_0x2000000(); + } + + fn_80256E80(); + + if (mObjAcch.ChkGndHit() && mVelocity.y <= 0.0f) { + u32 specialCode = dBgS::GetInstance()->GetSpecialCode(mObjAcch.GetGnd()); + if (isItemDeleteGround(specialCode)) { + if (sLib::chase(&mSinkOffset, -100.0f, (this->*mFnGetSinkSpeed)())) { + deleteRequest(); + } + } else if (isItemSwimGround(specialCode)) { + sLib::chase(&mSinkOffset, -30.0f, (this->*mFnGetSinkSpeed)()); + } else { + sLib::chase(&mSinkOffset, 0.0f, 6.0f); + } + } else { + mSinkOffset = 0.0f; + } + + mYOffset = mSinkOffset; + if (isAnyTear() && mObjAcch.ChkGroundLanding()) { + startSoundWithFloatParam(SE_Item_A43_FALL, mVelocity.y); + } + } + } + + /* This Function keeps Triforce postion locked 8024edbc */ + if (isTriforce()) { + f32 factor = field_0xD48.sin(); + mPosition = mPositionCopy + mVec3_c::Ey * (factor * 16.0f); + field_0xD48.mVal += 182; + } + + if ((mItemFlags & 0x4) != 0 && 3000.0f < mPositionCopy.y - mPosition.y) { + mItemFlags |= 0x8; + } + + if ((mItemFlags & 0x8) == 0) { + (this->*mFnAction3)(); + if (isAnyRupee() && field_0xD3A > 0) { + holdSoundWithIntParam(SE_O_RUPEE_ROULETTE, field_0xD3A); + } + + if (!field_0xD51) { + mCyl.SetC(mPosition); + dCcS::GetInstance()->Set(&mCyl); + } + + if (isSmallKey()) { + if (dScGame_c::isCurrentStage("F302")) { + f32 fScale; + getCurrentModelScale(&fScale); + mVec3_c scale(fScale, fScale, fScale); + mEff_0x8F4.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_820_, mPosition, nullptr, &scale, nullptr, nullptr); + } + } else if (isTriforce()) { + f32 fScale; + getCurrentModelScale(&fScale); + mVec3_c scale(fScale, fScale, fScale); + mVec3_c offsetPos(mPosition.x, fScale * 20.0f + mPosition.y, mPosition.z); + dCamera_c *cam = dScGame_c::getCamera(); + mVec3_c dir = offsetPos - cam->getPosition(); + if (!dir.normalizeRS()) { + dir = cam->getTarget() - cam->getPosition(); + if (!dir.normalizeRS()) { + dir.set(mVec3_c::Ez); + dir.rotX(cam->getYAngle()); + dir.rotY(cam->getXZAngle()); + } + } + dir *= -40.0f; + mVec3_c efPos = offsetPos + dir; + mEff_0x928.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_821_, efPos, nullptr, &scale, nullptr, nullptr); + } + makeLinkLookTowardItem(); + if (!mbNoDespawn && !isItemSmallKeyOrHeartPieceOrStaminaFruit()) { + fn_80254CA0(); + } + } +} + +void dAcItem_c::finalizeState_Wait() { + unsetActorProperty(AC_PROP_0x1); + mObjAcch.SetRoofNone(); + mObjAcch.Clr_0x2000000(); + mSinkOffset = 0.0f; + mYOffset = 0.0f; + if (isTriforce() && mEff_0x928.hasEmitters()) { + mEff_0x928.remove(true); + } +} + +void dAcItem_c::initializeState_Carry() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Put); + mSpeed = 0.0f; + mVelocity.y = 0.0f; + unsetHaveNoGravity(); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + mCyl.OnTgSet(); + mCyl.ClrCoSet(); + fn_80254BA0(); + field_0xD4A = 0; + mMdlScaleType = 0; +} + +void dAcItem_c::executeState_Carry() { + if (!mbNoDespawn && !isItemSmallKeyOrHeartPieceOrStaminaFruit() && !mbIsWaiting && + mLinkage.checkConnection(dLinkage_c::CONNECTION_8)) { + fn_80254CA0(); + } + tickDespawnTimer(); + if (mDespawnTimer == 0) { + return; + } + + if (fn_802574A0()) { + // TODO weird double load + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (!link->vt_0x1C0()) { + addToGetQueue(); + if (link->ifHasHealthAndSomethingElse() && this == sItemListHead.get() && + FileManager::sInstance->getCurrentHealth() != 0) { + mStateMgr.changeState(StateID_Get); + } else { + mStateMgr.changeState(StateID_WaitGet); + } + } else { + mStateMgr.changeState(StateID_GetBeetle); + } + } else if (!mLinkage.checkState(dLinkage_c::STATE_ACTIVE)) { + mStateMgr.changeState(StateID_Wait); + } else if (mLinkage.checkConnection(dLinkage_c::CONNECTION_9) && mCyl.ChkTgHit() && + !mCyl.ChkTgAtHitType(AT_TYPE_WHIP)) { + mLinkage.forceRemove(this); + mStateMgr.changeState(StateID_Wait); + } else { + fn_80256E80(); + if (mLinkage.checkConnection(dLinkage_c::CONNECTION_9) || mLinkage.checkConnection(dLinkage_c::CONNECTION_8)) { + mCyl.SetC(mPosition); + dCcS::GetInstance()->Set(&mCyl); + } + + if (mLinkage.checkConnection(dLinkage_c::CONNECTION_7)) { + makeLinkLookTowardItem(); + } + } +} + +void dAcItem_c::finalizeState_Carry() { + setupUnkColliderFlags2(); +} + +void dAcItem_c::initializeState_GetBeetle() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Put); + setNotWaiting(); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + field_0xD0C = 0.0f; + if (isAnyRupee()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_BE_GET_RUPEE); + } else if (isHeartV()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_BE_GET_HART); + } else if (isSmallKey()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_BE_GET_KEY); + } else if (mId == ITEM_STAMINA_FRUIT) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_BE_GET_REFRESH_FRUIT); + } else if (isUnkTreasureGroup1()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_BE_GET_MATERIAL); + } else { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_BE_GET_CONSUMP_ITEM); + } -void dAcItem_c::initializeState_Carry() {} -void dAcItem_c::executeState_Carry() {} -void dAcItem_c::finalizeState_Carry() {} + addToGetQueue(); + mMdlScaleType = 3; + fn_802548A0(); +} + +void dAcItem_c::executeState_GetBeetle() { + // TODO weird double load + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link == nullptr) { + return; + } + dAcBoomerang_c *beetlePtr = (dAcBoomerang_c *)link->vt_0x1C0(); + if (beetlePtr == nullptr) { + if (link->ifHasHealthAndSomethingElse() && this == sItemListHead.get() && + FileManager::sInstance->getCurrentHealth() != 0) { + decideOnGetOrForcedGet(); + } else { + mStateMgr.changeState(StateID_WaitGet); + } + } else if (37.6f - field_0xD0C < 1.6f) { + // TODO what are these numbers + mStateMgr.changeState(StateID_WaitGet); + } else { + mVec3_c v(0.0f, 5.0f, 0.0f); + // This + is weird... inline? + v.rotY(+beetlePtr->mRotation.y); + mPosition = beetlePtr->mPosition + v; + mPosition.y += field_0xD0C; + rotateTowardsCamera(); + sLib::addCalcScaledDiff(&field_0xD0C, 37.6f, 0.1f, 10000.0f); + } +} -void dAcItem_c::initializeState_GetBeetle() {} -void dAcItem_c::executeState_GetBeetle() {} void dAcItem_c::finalizeState_GetBeetle() {} -void dAcItem_c::initializeState_WaitGet() {} -void dAcItem_c::executeState_WaitGet() {} -void dAcItem_c::finalizeState_WaitGet() {} +void dAcItem_c::initializeState_WaitGet() { + field_0xD64 = 0; + setObjectProperty(OBJ_PROP_0x200); + // TODO double load + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link != nullptr) { + mPosition.set(link->getPosition()); + } + mMdlScaleType = 1; + fn_802548A0(); +} -void dAcItem_c::initializeState_Get() {} -void dAcItem_c::executeState_Get() {} -void dAcItem_c::finalizeState_Get() {} +void dAcItem_c::executeState_WaitGet() { + // TODO double load + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link != nullptr) { + if (link->ifHasHealthAndSomethingElse()) { + field_0xD64 = true; + } + if (field_0xD64 && this == sItemListHead.get() && FileManager::GetInstance()->getCurrentHealth() != 0) { + decideOnGetOrForcedGet(); + } + } +} + +void dAcItem_c::finalizeState_WaitGet() { + unsetObjectProperty(OBJ_PROP_0x200); +} + +void dAcItem_c::initializeState_Get() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Put); + performCollection(); + if (isAnyTear()) { + mVec3_c tmp; + fn_80256710(tmp); + fn_80257560(tmp); + } + fn_80254D10(); + fn_80254D70(); + setNotWaiting(); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + field_0xD4D = false; + mMdlScaleType = 1; + fn_802548A0(); +} + +void dAcItem_c::executeState_Get() { + if (!fn_80254D70()) { + fn_802542E0(); + } else { + // @bug always true + if (field_0xD4D < 0xFFFF) { + field_0xD4D++; + } + if (field_0xD4D > 12) { + removeFromGetQueue(); + } + } +} + +void dAcItem_c::finalizeState_Get() { + removeFromGetQueue(); +} + +void dAcItem_c::initializeState_WaitGetDemo() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Get); + setObjectProperty(OBJ_PROP_0x200); + setNotWaiting(); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + mMdlScaleType = 2; + fn_802548A0(); + unsetFramesInAir(); +} + +void dAcItem_c::executeState_WaitGetDemo() { + s32 which = 0; + if (EventManager::isInEvent()) { + which = 2; + } else if (fn_80247BB0()) { + which = 2; + } else if ((isInsect() || isTreasure3()) && checkTreasureTempCollect(getItemId())) { + which = 2; + } else if (checkShouldDemo() && fn_80254EC0()) { + which = 1; + } else if (mFramesInAir > 10) { + which = 2; + } + + switch (which) { + case 1: addGetEvent(); break; + case 2: + unsetObjectProperty(OBJ_PROP_0x200); + mStateMgr.changeState(StateID_Get); + break; + } + unsetFramesInAir(); +} -void dAcItem_c::initializeState_WaitGetDemo() {} -void dAcItem_c::executeState_WaitGetDemo() {} void dAcItem_c::finalizeState_WaitGetDemo() {} -void dAcItem_c::initializeState_WaitForcedGetDemo() {} -void dAcItem_c::executeState_WaitForcedGetDemo() {} +void dAcItem_c::initializeState_WaitForcedGetDemo() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Get); + setObjectProperty(OBJ_PROP_0x200); + setNotWaiting(); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + mMdlScaleType = 2; + fn_802548A0(); +} + +void dAcItem_c::executeState_WaitForcedGetDemo() { + if (isAnyTear() && mFramesInAir < 10) { + incrementFramesInAir(); + if (mFramesInAir == 10) { + fn_80257560(mPosition); + } + } + addGetEvent(); +} + void dAcItem_c::finalizeState_WaitForcedGetDemo() {} -void dAcItem_c::initializeState_GetDemo() {} -void dAcItem_c::executeState_GetDemo() {} -void dAcItem_c::finalizeState_GetDemo() {} +void dAcItem_c::initializeState_GetDemo() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Get); + switch (getItemId()) { + case ITEM_FARON_GRASSHOPPER: sCollectionCurrentCount = getFaronGrasshooperCounter(); break; + case ITEM_WOODLAND_RHINO_BEETLE: sCollectionCurrentCount = getWoodlandRhinoBeetleCounter(); break; + case ITEM_DEKU_HORNET: sCollectionCurrentCount = getDekuHornetCounter(); break; + case ITEM_SKYLOFT_MANTIS: sCollectionCurrentCount = getSkyloftMantisCounter(); break; + case ITEM_VOLCANIC_LADYBUG: sCollectionCurrentCount = getVolcanicLadybugCounter(); break; + case ITEM_BLESSED_BUTTERFLY: sCollectionCurrentCount = getBlessedButterflyCounter(); break; + case ITEM_LANAYRU_ANT: sCollectionCurrentCount = getLanayruAntCounter(); break; + case ITEM_SAND_CICADA: sCollectionCurrentCount = getSandCicadaCounter(); break; + case ITEM_GERUDO_DRAGONFLY: sCollectionCurrentCount = getGerudoDragonflyCounter(); break; + case ITEM_ELDIN_ROLLER: sCollectionCurrentCount = getEldinRollerCounter(); break; + case ITEM_SKY_STAG_BEETLE: sCollectionCurrentCount = getSkyStagBeetleCounter(); break; + case ITEM_STARRY_FIREFLY: sCollectionCurrentCount = getStarryFireflyCounter(); break; + case ITEM_HORNET_LARVAE: sCollectionCurrentCount = getHornetLarvaeCounter(); break; + case ITEM_BIRD_FEATHER: sCollectionCurrentCount = getBirdFeatherCounter(); break; + case ITEM_TUMBLE_WEED: sCollectionCurrentCount = getTumbleWeedCounter(); break; + case ITEM_LIZARD_TAIL: sCollectionCurrentCount = getLizardTailCounter(); break; + case ITEM_ELDIN_ORE: sCollectionCurrentCount = getEldinOreCounter(); break; + case ITEM_ANCIENT_FLOWER: sCollectionCurrentCount = getAncientFlowerCounter(); break; + case ITEM_AMBER_RELIC: sCollectionCurrentCount = getAmberRelicCounter(); break; + case ITEM_DUSK_RELIC: sCollectionCurrentCount = getDuskRelicCounter(); break; + case ITEM_JELLY_BLOB: sCollectionCurrentCount = getJellyBlobCounter(); break; + case ITEM_MONSTER_CLAW: sCollectionCurrentCount = getMonsterClawCounter(); break; + case ITEM_MONSTER_HORN: sCollectionCurrentCount = getMonsterHornCounter(); break; + case ITEM_ORNAMENTAL_SKULL: sCollectionCurrentCount = getSkullCounter(); break; + case ITEM_EVIL_CRYSTAL: sCollectionCurrentCount = getEvilCrystalCounter(); break; + case ITEM_BLUE_BIRD_FEATHER: sCollectionCurrentCount = getBlueBirdFeatherCounter(); break; + case ITEM_GOLDEN_SKULL: sCollectionCurrentCount = getGoldenSkullCounter(); break; + case ITEM_GODDESS_PLUME: sCollectionCurrentCount = getGoddessPlumeCounter(); break; + } + + performCollectionPart1(); + if (checkItemFlagV()) { + if (isAnyTear()) { + dAcOWarp_c *warp = static_cast<dAcOWarp_c *>(fManager_c::searchBaseByProfName(fProfile::OBJ_WARP)); + if (warp != nullptr) { + warp->onCollectFirstTear(); + } + } + } else { + bool doCollect = true; + if (ITEM_FARON_GRASSHOPPER <= mId && mId <= ITEM_STARRY_FIREFLY && + MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + doCollect = false; + } + if (doCollect) { + setItemFlagV(); + } + } + + setTreasureTempCollect(getItemId()); + setNotWaiting(); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + mMdlRotY = 0; + setObjectProperty(OBJ_PROP_0x200); + mMdlScaleType = 2; + if (isBirdStatuette()) { + mFn_0xC9C = &dAcItem_c::rotateFixedBirdStatuette; + } else { + mFn_0xC9C = &dAcItem_c::rotateTowardsCamera; + } +} + +void dAcItem_c::executeState_GetDemo() { + switch (mEventRelated.getCurrentEventCommand()) { + case 'act0': mEventRelated.advanceNext(); break; + case 'wait': mEventRelated.advanceNext(); break; + case 'halo': { + mVec3_c efPos; + fn_80254590(efPos); + mVec3_c diff = dScGame_c::getCamera()->getPosition() - mPosition; + // TODO close but an extsh is missing + // Same pattern as in rotateTowardsCamera + mAng3_c rot; + setRotXYVec(rot, diff); + u32 alpha = 0xFF; + if (dScGame_c::currentSpawnInfo.getTrial() == SpawnInfo::TRIAL) { + alpha = 0x80; + } + mEff_0x95C.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_82_, efPos, &rot, nullptr, nullptr, nullptr); + mEff_0x95C.setGlobalAlpha(alpha); + mEventRelated.advanceNext(); + break; + } + case '????': break; + default: mEventRelated.advanceNext(); break; + } + + if (!checkObjectProperty(OBJ_PROP_0x200)) { + mPosition = getLinkPtr()->vt_0x1A4(); + if (isUpgradedPotion((ITEM_ID)getItemId())) { + fn_80254680(); + } else if (isAnyTear()) { + fn_80254810(); + } + mbShowItemLighting = true; + field_0x340 = mPosition; + (this->*mFn_0xC9C)(); + if (!isGratitudeCrystal() && !is5GratitudeCrystals()) { + mMdlRotY += getItemRotateAngle(); + } + field_0xD42 = mAng::d2s_c(0.0f); + + // TODO - ... + } + makeLinkLookTowardItem(); +} + +void dAcItem_c::finalizeState_GetDemo() { + mMdlRotY = 0; + field_0xD42 = 0; + performCollectionPart2(); + mbShowItemLighting = false; + if (mEff_0x95C.hasEmitters()) { + mEff_0x95C.remove(true); + } + if (isAnyTear() && mEff_0xA60.hasEmitters()) { + mEff_0xA60.remove(true); + } +} + +void dAcItem_c::initializeState_WaitTBoxGetDemo() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Get); + setNotWaiting(); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + setObjectProperty(OBJ_PROP_0x200); + mMdlScaleType = 2; + fn_802548A0(); +} + +void dAcItem_c::executeState_WaitTBoxGetDemo() { + const char *name; + getItemGetTboxEventName(getItemId(), &name); + Event ev(name, 1, 0x100001, (void *)itemGetEventStart, (void *)itemGetEventEnd); + EventManager::alsoSetAsCurrentEvent(this, &ev, nullptr); +} -void dAcItem_c::initializeState_WaitTBoxGetDemo() {} -void dAcItem_c::executeState_WaitTBoxGetDemo() {} void dAcItem_c::finalizeState_WaitTBoxGetDemo() {} -void dAcItem_c::initializeState_ResurgeWait() {} -void dAcItem_c::executeState_ResurgeWait() {} +void dAcItem_c::initializeState_ResurgeWait() { + mpMdl->setDrawMode(dItemMdl_c::DrawMode_Put); + // TODO FPR swap + mPosition = mPositionCopy; + mRotation = mRotationCopy; + mpResurgeCtl->startResurgeTimer(); + setNotWaiting(); + // TODO ??? + mbNoGravity = mbNoDespawn; + field_0xD38 = field_0xD3A = field_0xD3C = 0; + mMdlScaleType = 0; + field_0xCD8 = 0.0f; +} + +void dAcItem_c::executeState_ResurgeWait() { + if (mpResurgeCtl->canResurge(this)) { + if (!mpResurgeCtl->isTimerExpired()) { + mpResurgeCtl->execute(); + if (mpResurgeCtl->isTimerExpired()) { + if (mId == ITEM_STAMINA_FRUIT) { + startSound(SE_O_REFRESH_FRUIT_SPROUT); + } + mStateMgr.changeState(StateID_Wait); + } + } + } else { + mpResurgeCtl->resetTimer(); + } +} + void dAcItem_c::finalizeState_ResurgeWait() {} -void dAcItem_c::initializeState_WaitTurnOff() {} -void dAcItem_c::executeState_WaitTurnOff() {} +void dAcItem_c::initializeState_WaitTurnOff() { + setNotWaiting(); + setObjectProperty(OBJ_PROP_0x200); + mSpeed = 0.0f; + mVelocity.set(0.0f, 0.0f, 0.0f); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + mMdlScaleType = 2; +} + +void dAcItem_c::executeState_WaitTurnOff() { + if (!isField_0xD04GtZero()) { + deleteRequest(); + } +} + void dAcItem_c::finalizeState_WaitTurnOff() {} -void dAcItem_c::initializeState_WaitSacredDewGetEffect() {} -void dAcItem_c::executeState_WaitSacredDewGetEffect() {} +void dAcItem_c::initializeState_WaitSacredDewGetEffect() { + setNotWaiting(); + setObjectProperty(OBJ_PROP_0x200); + mSpeed = 0.0f; + mVelocity.set(0.0f, 0.0f, 0.0f); + field_0xD38 = field_0xD3A = field_0xD3C = 0; + mMdlScaleType = 2; +} + +void dAcItem_c::executeState_WaitSacredDewGetEffect() { + if (!EventManager::isInEvent()) { + mVec3_c tmp; + fn_80247540(tmp); + fn_80247560(tmp); + mStateMgr.changeState(StateID_WaitTurnOff); + } +} + void dAcItem_c::finalizeState_WaitSacredDewGetEffect() {} + +STATE_DEFINE(dAcItem_c, Wait); +STATE_DEFINE(dAcItem_c, Carry); +STATE_DEFINE(dAcItem_c, GetBeetle); +STATE_DEFINE(dAcItem_c, WaitGet); +STATE_DEFINE(dAcItem_c, Get); +STATE_DEFINE(dAcItem_c, WaitGetDemo); +STATE_DEFINE(dAcItem_c, WaitForcedGetDemo); +STATE_DEFINE(dAcItem_c, GetDemo); +STATE_DEFINE(dAcItem_c, WaitTBoxGetDemo); +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); + item->mStateMgr.changeState(StateID_GetDemo); + item->setObtainedItemId(item->getItemId(), true); + if (item->mId == ITEM_DUNGEON_MAP_FI && ItemflagManager::sInstance->getItemCounterOrFlag(0x32) == 0) { + Event ev("fays_map_guide", 100, 0x100001, nullptr, nullptr); + EventManager::changeOwnEvent(item, dAcNpcTalkKensei_c::GetInstance(), &ev, 0); + } +} + +void dAcItem_c::applyBoundingBox() { + (this->*mFnSetBoundingBox)(); +} + +void dAcItem_c::performCollection() { + performCollectionPart1(); + performCollectionPart2(); +} + +void dAcItem_c::performCollectionPart1() { + u16 id = getItemId(); + if (isKeyPieceV()) { + increaseKeyPieceCounter(1); + } else if (isLightFruit()) { + dTgSiren_c::setLightFruitTime(getLightFruitTime()); + } else if (isHeartPiece()) { + increaseHeartPieceCounter(1); + increaseTotalHeartPieceCounter(1); + } else { + f32 count; + switch (id) { + case ITEM_FARON_GRASSHOPPER: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseFaronGrasshopperCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_WOODLAND_RHINO_BEETLE: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseWoodlandRhinoBeetleCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_DEKU_HORNET: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseDekuHornetCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_SKYLOFT_MANTIS: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseSkyloftMantisCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_VOLCANIC_LADYBUG: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseVolcanicLadybugCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_BLESSED_BUTTERFLY: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseBlessedButterflyCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_LANAYRU_ANT: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseLanayruAntCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_SAND_CICADA: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseSandCicadaCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_GERUDO_DRAGONFLY: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseGerudoDragonflyCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_ELDIN_ROLLER: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseEldinRollerCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_SKY_STAG_BEETLE: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseSkyStagBeetleCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_STARRY_FIREFLY: + if (!MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + increaseStarryFireflyCounter(mItemQuantity != 0 ? mItemQuantity : 1); + } + break; + case ITEM_HORNET_LARVAE: increaseHornetLarvaeCounter(1); break; + case ITEM_BIRD_FEATHER: + // ??? + count = mItemQuantity != 0 ? mItemQuantity : 1; + increaseBirdFeatherCounter(0.0f < count ? count : 1.0f); + break; + case ITEM_TUMBLE_WEED: increaseTumbleWeedCounter(1); break; + case ITEM_LIZARD_TAIL: increaseLizardTailCounter(1); break; + case ITEM_ELDIN_ORE: increaseEldinOreCounter(1); break; + case ITEM_ANCIENT_FLOWER: increaseAncientFlowerCounter(1); break; + case ITEM_AMBER_RELIC: increaseAmberRelicCounter(1); break; + case ITEM_DUSK_RELIC: increaseDuskRelicCounter(1); break; + case ITEM_JELLY_BLOB: increaseJellyBlobCounter(1); break; + case ITEM_MONSTER_CLAW: increaseMonsterClawCounter(1); break; + case ITEM_MONSTER_HORN: increaseMonsterHornCounter(1); break; + case ITEM_ORNAMENTAL_SKULL: increaseSkullCounter(1); break; + case ITEM_EVIL_CRYSTAL: increaseEvilCrystalCounter(1); break; + case ITEM_BLUE_BIRD_FEATHER: + // ??? + count = mItemQuantity != 0 ? mItemQuantity : 1; + increaseBlueBirdFeatherCounter(0.0f < count ? count : 1.0f); + break; + case ITEM_GOLDEN_SKULL: increaseGoldenSkullCounter(1); break; + case ITEM_GODDESS_PLUME: increaseGoddessPlumeCounter(1); break; + default: { + if (isTriforce()) { + doFullHeal(); + } else if (isGratitudeCrystalV()) { + increaseGratitudeCrystalCounter(1); + } else if (is5GratitudeCrystalsV()) { + increaseGratitudeCrystalCounter(5); + } else if (id == ITEM_EXTRA_WALLET) { + increaseExtraWalletCounter(1); + } + break; + } + } + } + + if (mStateMgr.isState(StateID_GetDemo)) { + sIsPerformingInitialCollection = !checkFlagV(); + } + + bool doCollect = true; + if (ITEM_FARON_GRASSHOPPER <= mId && mId <= ITEM_STARRY_FIREFLY && + MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE)) { + doCollect = false; + } + if (doCollect) { + setFlagV(); + } + setSceneFlag(); + setDungeonFlag(); + + if (getSubtypeFromParam(mParams) == 7) { + return; + } + + if (isGreenRupee()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_RUPEE_GREEN); + } else if (isBlueRupee()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_RUPEE_BLUE); + } else if (isRedRupee()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_RUPEE_RED); + } else if (isSilverRupee()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_RUPEE_SILVER); + } else if (isGoldRupee()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_RUPEE_BLUE); + } else if (isRupoor()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_RUPEE_BABA); + } else if (isHeartV()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_HEART_PIECE_GET); + } else if (isAnyTear()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SIREN_GET_SHINE_DEW); + } else if (mId == ITEM_STAMINA_FRUIT) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_REFRESH_FRUIT); + } else if (isLightFruit()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SIREN_GET_HOLY_FRUIT); + } else if (mId == ITEM_5_DEKU_SEEDS || is10DekuSeeds()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CONSUMP_ITEM_GET); + } else if (isAnyArrow()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CONSUMP_ITEM_GET); + } else if (isAnyBombs()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_CONSUMP_ITEM_GET); + } else if (isInsect()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_MATERIAL); + } else if (isTreasureV()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_MATERIAL); + } else if (is5GratitudeCrystals() || isGratitudeCrystal()) { + if ((mItemFlags & 0x20) == 0) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_SOURCE_OUTWELL); + } + } else if (isBabyRattle()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_GARAGARA); + } else if (isLifeTreeFruit()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_LIFE_FRUIT); + } else if (mId == ITEM_HEART_CONTAINER) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_HEART_CONTAINER); + } else if (isTriforce()) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GET_TRIFORCE); + } +} + +void dAcItem_c::performCollectionPart2() { + u16 id = getItemId(); + if (id == ITEM_SMALL_KEY) { + increaseSmallKeyCounter(1); + } else if (id == ITEM_GREEN_RUPEE) { + if (!MinigameManager::isInMinigameState(MinigameManager::THRILL_DIGGER)) { + increaseRupeeCounter(1); + } + } else if (id == ITEM_BLUE_RUPEE) { + if (!MinigameManager::isInMinigameState(MinigameManager::THRILL_DIGGER)) { + increaseRupeeCounter(5); + } + } else if (id == ITEM_RED_RUPEE) { + if (!MinigameManager::isInMinigameState(MinigameManager::THRILL_DIGGER)) { + increaseRupeeCounter(20); + } + } else if (isHeartV()) { + healLink(4, true); + } else if (id == ITEM_SINGLE_ARROW) { + increaseArrowAndPouchCounter(1); + } else if (id == ITEM_BUNDLE_ARROWS) { + increaseArrowAndPouchCounter(10); + } else if (id == ITEM_SILVER_RUPEE) { + if (!MinigameManager::isInMinigameState(MinigameManager::THRILL_DIGGER)) { + increaseRupeeCounter(100); + } + } else if (id == ITEM_GOLD_RUPEE) { + if (!MinigameManager::isInMinigameState(MinigameManager::THRILL_DIGGER)) { + increaseRupeeCounter(300); + } + } else if (id == ITEM_RUPOOR) { + if (!MinigameManager::isInMinigameState(MinigameManager::THRILL_DIGGER)) { + increaseRupeeCounter(-10); + } + } else if (id == ITEM_5_BOMBS) { + increaseBombAndPouchCounter(5); + } else if (id == ITEM_10_BOMBS) { + increaseBombAndPouchCounter(10); + } else if (mId == ITEM_STAMINA_FRUIT) { + restoreStamina(); + } else if (id == ITEM_5_DEKU_SEEDS) { + increaseDekuSeedAndPouchCounter(5); + } else if (is10DekuSeeds()) { + increaseDekuSeedAndPouchCounter(10); + } else if (id == ITEM_POUCH_EXPANSION) { + increaseExtraPouchCounter(1); + } else if (id == ITEM_HEART_CONTAINER) { + increaseHealthCapacity(getHeartContainerHeartIncrease()); + doFullHeal(); + } else if (isHeartPiece()) { + if (getNumRemainingHeartPiecesForNextHeart() == 0) { + increaseHealthCapacity(getCompletedHeartPieceHeartIncrease()); + } + doFullHeal(); + } else if (id == ITEM_LIFE_TREE_SEED) { + setLifeTreeSeedlingFlag(1); + } else if (id == ITEM_BOW || id == ITEM_IRON_BOW || id == ITEM_SACRED_BOW) { + if (!checkFlagV()) { + increaseArrowCounter(getBowArrowCapacity() - getBowArrowCount()); + } + } else if (id == ITEM_SLINGSHOT || id == ITEM_MIGHTY_SCATTERSHOT) { + if (!checkFlagV()) { + increaseDekuSeedCounter(getSlingshotSeedCapacity() - getSlingshotSeedCount()); + } + } else if (isAnyPouchItem((ITEM_ID)id)) { + if (mGetItemPouchSlot == -1) { + collectPouchItem(id); + } else { + collectPouchItemIntoSlot(mGetItemPouchSlot, id, -1, false); + } + } + + if (MinigameManager::isInMinigameState(MinigameManager::INSECT_CAPTURE) && + dTgMinigameInsectCapture_c::GetInstance() != nullptr) { + 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 dAcItemPickupPositionOff_c::init() { + // no-op +} + +bool dAcItemPickupPositionOff_c::execute(dAcItem_c *item) { + return false; +} + +void dAcItemPickupPositionOn_c::init() { + // TODO weird double load + dAcPy_c *link = dAcPy_c::GetLinkM(); + if (link != nullptr) { + mHighestRelativeHeadHeight = link->getHeadTranslation().y - link->getPosition().y; + } + mNumFrames = 0; +} + +bool dAcItemPickupPositionOn_c::execute(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 dAcItemResurgeIf_c::startResurgeTimer() { + resetTimer(); + postReset(); +} + +bool dAcItemResurgeIf_c::canResurge(dAcItem_c *item) { + if (item->getSquareDistToPlayer() < 40000.0f) { + return false; + } + return isResurgeAllowed(item); +} + +void dAcItemResurgeIf_c::resetTimer() { + mTimer = getTimerInitVal(); +} + +void dAcItemResurgeIf_c::execute() { + if (mTimer == 0) { + return; + } + if (!EventManager::isInEvent()) { + mTimer--; + } +} + +bool dAcItemResurgeIf_c::isTimerExpired() const { + return mTimer == 0; +} + +void dAcItemResurgeOff_c::setTimerInitVal(u16 arg) { + // no-op +} + +void dAcItemResurgeOff_c::postReset() { + // no-op +} + +bool dAcItemResurgeOff_c::isResurgeAllowed(dAcItem_c *) { + return false; +} + +s32 dAcItemResurgeOff_c::getTimerInitVal() { + return 0; +} + +void dAcItemResurgeOn_c::setTimerInitVal(u16 arg) { + mInitVal = arg; +} + +void dAcItemResurgeOn_c::postReset() { + // no-op +} + +bool dAcItemResurgeOn_c::isResurgeAllowed(dAcItem_c *) { + return (this->*mCb2)(); +} + +s32 dAcItemResurgeOn_c::getTimerInitVal() { + return mInitVal; +} |
