summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2026-05-07 19:52:36 +0200
committerrobojumper <robojumper@gmail.com>2026-05-14 14:40:32 +0200
commit48fbe8d1da7a82412a73746620291af93354364a (patch)
treeaa7cb0631f3970e41aa4266ca51657237d6917fa
parent02bab6f41fc616ca7d9aa77f4a81782d65b16200 (diff)
Progress
-rw-r--r--config/SOUE01/splits.txt1
-rw-r--r--config/SOUE01/symbols.txt80
-rw-r--r--include/d/a/d_a_item.h120
-rw-r--r--include/d/a/d_a_itembase.h1
-rw-r--r--include/d/d_angle.h17
-rw-r--r--src/d/a/d_a_item.cpp374
-rw-r--r--src/d/a/obj/d_a_obj_tbox.cpp2
-rw-r--r--src/toBeSorted/item_mdl_misc.cpp2
8 files changed, 483 insertions, 114 deletions
diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt
index af44b95e..c8a60407 100644
--- a/config/SOUE01/splits.txt
+++ b/config/SOUE01/splits.txt
@@ -1495,6 +1495,7 @@ d/a/d_a_player.cpp:
.rodata start:0x804EACF0 end:0x804EBBB0
.data start:0x80530170 end:0x80533268
.sbss start:0x805757B8 end:0x805758B8
+ .sdata2 start:0x8057B650 end:0x8057BD88
d/a/d_a_item.cpp:
.text start:0x80247200 end:0x80258E58 align:16
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index b5a0aca9..5cc32b3a 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -13324,10 +13324,10 @@ AcItem__isGoddessPlume = .text:0x802477D0; // type:function size:0x10
isItemRevitalizingPotionPlusPlus = .text:0x802477E0; // type:function size:0x10
isUpgradedPotion__9dAcItem_cF7ITEM_ID = .text:0x802477F0; // type:function size:0xC8
fn_802478C0 = .text:0x802478C0; // type:function size:0x68
-AcItem__isItemFromMittsOrSword = .text:0x80247930; // type:function size:0x20
-fn_80247950 = .text:0x80247950; // type:function size:0x28
-AcItem__isItemFromMitts = .text:0x80247980; // type:function size:0x10
-fn_80247990 = .text:0x80247990; // type:function size:0x8
+isDefaultDeleteGround__Fl = .text:0x80247930; // type:function size:0x20
+isDefaultSwimGround__Fl = .text:0x80247950; // type:function size:0x28
+isHeartDeleteGround__Fl = .text:0x80247980; // type:function size:0x10
+isHeartSwimGround__Fl = .text:0x80247990; // type:function size:0x8
getRandomEntryFromWeightedList = .text:0x802479A0; // type:function size:0x17C
determineActualItemIdFromItem__9dAcItem_cFUs = .text:0x80247B20; // type:function size:0x84
fn_80247BB0 = .text:0x80247BB0; // type:function size:0x10C
@@ -13337,7 +13337,7 @@ fn_80247E70 = .text:0x80247E70; // type:function size:0x50
increment__FPUl = .text:0x80247EC0; // type:function size:0x28
fn_80247EF0 = .text:0x80247EF0; // type:function size:0xA4
getItemId__13dAcItemBase_cCFv = .text:0x80247FA0; // type:function size:0x8
-fn_80247FB0 = .text:0x80247FB0; // type:function size:0x8
+setItemId__13dAcItemBase_cFUs = .text:0x80247FB0; // type:function size:0x8
dAcItem_c_classInit__Fv = .text:0x80247FC0; // type:function size:0x30
AcItem__dontForceDemo = .text:0x80247FF0; // type:function size:0x8
AcItem__shouldForceDemo = .text:0x80248000; // type:function size:0x8
@@ -13392,7 +13392,7 @@ getTearIdx__9dAcItem_cFv = .text:0x8024A2C0; // type:function size:0xC
getFirstBitParams2__9dAcBase_cCFv = .text:0x8024A2D0; // type:function size:0x24
getParams2Lower_shift1_0x7__9dAcItem_cCFv = .text:0x8024A300; // type:function size:0x24
getCurrentTrial__9dAcItem_cFv = .text:0x8024A330; // type:function size:0x68
-getTearSubtype__9dAcItem_cF7ITEM_ID = .text:0x8024A3A0; // type:function size:0x68
+getTearSubtype__9dAcItem_cFUl = .text:0x8024A3A0; // type:function size:0x68
AcItem__GetItemGetType = .text:0x8024A410; // type:function size:0x3C
AcItem__getItemListElement = .text:0x8024A450; // type:function size:0x8
AcItem__getFinalDeterminedItemId = .text:0x8024A460; // type:function size:0x8
@@ -13450,9 +13450,9 @@ executeState_WaitSacredDewGetEffect__9dAcItem_cFv = .text:0x802506B0; // type:fu
finalizeState_WaitSacredDewGetEffect__9dAcItem_cFv = .text:0x80250730; // type:function size:0x4
getItemFromBWheelItem__9dAcItem_cFv = .text:0x80250740; // type:function size:0xEC
setItemPosition__9dAcItem_cFRC7mVec3_c = .text:0x80250830; // type:function size:0x40
-fn_80250870 = .text:0x80250870; // type:function size:0x38
-isStateWait__9dAcItem_cFv = .text:0x802508B0; // type:function size:0x50
-AcItem__setCarriedAndTransitionToGetState = .text:0x80250900; // type:function size:0x50
+setItemVelocity__9dAcItem_cFf = .text:0x80250870; // type:function size:0x38
+isStateWait__9dAcItem_cCFv = .text:0x802508B0; // type:function size:0x50
+stopCarryAndGet__9dAcItem_cFv = .text:0x80250900; // type:function size:0x50
AcItem__isGreenRupee = .text:0x80250950; // type:function size:0x10
AcItem__isBlueRupee = .text:0x80250960; // type:function size:0x10
AcItem__isRedRupee = .text:0x80250970; // type:function size:0x10
@@ -13506,13 +13506,13 @@ isTriforce__9dAcItem_cCFv = .text:0x802510D0; // type:function size:0x8
fn_802510E0 = .text:0x802510E0; // type:function size:0x44
fn_80251130 = .text:0x80251130; // type:function size:0x44
fn_80251180 = .text:0x80251180; // type:function size:0x44
-AcItem__getEventName = .text:0x802511D0; // type:function size:0x6C
-fn_80251240 = .text:0x80251240; // type:function size:0x6C
-AcItem__getEventNamePtrForItemId = .text:0x802512B0; // type:function size:0x4C
-getItemGetEventName__9dAcItem_cFUsPPCc = .text:0x80251300; // type:function size:0x4C
-fn_80251350 = .text:0x80251350; // type:function size:0x54
-AcItem__getPosition = .text:0x802513B0; // type:function size:0x24
-fn_802513E0 = .text:0x802513E0; // type:function size:0xC
+getEventNameForAnim__9dAcItem_cFUlPPCc = .text:0x802511D0; // type:function size:0x6C
+getTboxEventNameForAnim__9dAcItem_cFUlPPCc = .text:0x80251240; // type:function size:0x6C
+getItemGetEventName__9dAcItem_cFUsPPCc = .text:0x802512B0; // type:function size:0x4C
+getItemGetTboxEventName__9dAcItem_cFUsPPCc = .text:0x80251300; // type:function size:0x4C
+playHeartStemCutSound__9dAcItem_cFv = .text:0x80251350; // type:function size:0x54
+getOffsetPosition__9dAcItem_cCFR7mVec3_c = .text:0x802513B0; // type:function size:0x24
+scaleBy__9dAcItem_cCFf = .text:0x802513E0; // type:function size:0xC
AcItem__getSmallKeyFreestandingScale = .text:0x802513F0; // type:function size:0x38
fn_80251430 = .text:0x80251430; // type:function size:0x8
fn_80251440 = .text:0x80251440; // type:function size:0x8
@@ -13746,14 +13746,14 @@ fn_80255B30 = .text:0x80255B30; // type:function size:0x6C
fn_80255BA0 = .text:0x80255BA0; // type:function size:0x28
fn_80255BD0 = .text:0x80255BD0; // type:function size:0x6C
fn_80255C40 = .text:0x80255C40; // type:function size:0x10
-AcItem__IsSpawnedFromMittsOrSwordMaybe = .text:0x80255C50; // type:function size:0x48
-fn_80255CA0 = .text:0x80255CA0; // type:function size:0x48
+isItemDeleteGround__9dAcItem_cCFl = .text:0x80255C50; // type:function size:0x48
+isItemSwimGround__9dAcItem_cCFl = .text:0x80255CA0; // type:function size:0x48
fn_80255CF0 = .text:0x80255CF0; // type:function size:0x60
isDayOrInDungeon = .text:0x80255D50; // type:function size:0x54
fn_80255DB0 = .text:0x80255DB0; // type:function size:0x3C
fn_80255DF0 = .text:0x80255DF0; // type:function size:0x84
-fn_80255E80 = .text:0x80255E80; // type:function size:0xB4
-fn_80255F40 = .text:0x80255F40; // type:function size:0x1C
+rotateTowardsCamera__9dAcItem_cFv = .text:0x80255E80; // type:function size:0xB4
+rotateFixedBirdStatuette__9dAcItem_cFv = .text:0x80255F40; // type:function size:0x1C
fn_80255F60 = .text:0x80255F60; // type:function size:0x8
fn_80255F70 = .text:0x80255F70; // type:function size:0x8
fn_80255F80 = .text:0x80255F80; // type:function size:0x8
@@ -13923,32 +13923,32 @@ isFirstBitParams2NotSet__9dAcItem_cFv = .text:0x80257770; // type:function size:
fn_802577A0 = .text:0x802577A0; // type:function size:0x18
fn_802577C0 = .text:0x802577C0; // type:function size:0x8
fn_802577D0 = .text:0x802577D0; // type:function size:0x8
-fn_802577E0 = .text:0x802577E0; // type:function size:0x4
-fn_802577F0 = .text:0x802577F0; // type:function size:0x8
-fn_80257800 = .text:0x80257800; // type:function size:0x6C
-fn_80257870 = .text:0x80257870; // type:function size:0x15C
-fn_802579D0 = .text:0x802579D0; // type:function size:0x40
+vt_0x0C__15dAcItem_0xB34_1Fv = .text:0x802577E0; // type:function size:0x4
+vt_0x10__15dAcItem_0xB34_1FP9dAcItem_c = .text:0x802577F0; // type:function size:0x8
+vt_0x0C__15dAcItem_0xB34_2Fv = .text:0x80257800; // type:function size:0x6C
+vt_0x10__15dAcItem_0xB34_2FP9dAcItem_c = .text:0x80257870; // type:function size:0x15C
+fn_802579D0__13dAcItem_0xB3CFv = .text:0x802579D0; // type:function size:0x40
fn_80257A10__13dAcItem_0xB3CFP9dAcItem_c = .text:0x80257A10; // type:function size:0x68
fn_80257A80__13dAcItem_0xB3CFv = .text:0x80257A80; // type:function size:0x3C
fn_80257AC0__13dAcItem_0xB3CFv = .text:0x80257AC0; // type:function size:0x44
-fn_80257B10__13dAcItem_0xB3CFv = .text:0x80257B10; // type:function size:0x10
-fn_80257B20 = .text:0x80257B20; // type:function size:0x4
-fn_80257B30 = .text:0x80257B30; // type:function size:0x4
-fn_80257B40 = .text:0x80257B40; // type:function size:0x8
-fn_80257B50 = .text:0x80257B50; // type:function size:0x8
+fn_80257B10__13dAcItem_0xB3CCFv = .text:0x80257B10; // type:function size:0x10
+vt_0x0C__15dAcItem_0xB3C_1FUs = .text:0x80257B20; // type:function size:0x4
+vt_0x10__15dAcItem_0xB3C_1Fv = .text:0x80257B30; // type:function size:0x4
+vt_0x14__15dAcItem_0xB3C_1FP9dAcItem_c = .text:0x80257B40; // type:function size:0x8
+vt_0x18__15dAcItem_0xB3C_1Fv = .text:0x80257B50; // type:function size:0x8
fn_80257B60 = .text:0x80257B60; // type:function size:0x4
fn_80257B70 = .text:0x80257B70; // type:function size:0x4
fn_80257B80 = .text:0x80257B80; // type:function size:0x8
fn_80257B90 = .text:0x80257B90; // type:function size:0x8
isOutOfTime = .text:0x80257BA0; // type:function size:0x1C
-fn_80257BC0 = .text:0x80257BC0; // type:function size:0x8
-fn_80257BD0 = .text:0x80257BD0; // type:function size:0x4
-fn_80257BE0 = .text:0x80257BE0; // type:function size:0x28
-fn_80257C10 = .text:0x80257C10; // type:function size:0x8
-fn_80257C20 = .text:0x80257C20; // type:function size:0x40
-fn_80257C60 = .text:0x80257C60; // type:function size:0x40
-fn_80257CA0 = .text:0x80257CA0; // type:function size:0x40
-fn_80257CE0 = .text:0x80257CE0; // type:function size:0x40
+vt_0x0C__15dAcItem_0xB3C_2FUs = .text:0x80257BC0; // type:function size:0x8
+vt_0x10__15dAcItem_0xB3C_2Fv = .text:0x80257BD0; // type:function size:0x4
+vt_0x14__15dAcItem_0xB3C_2FP9dAcItem_c = .text:0x80257BE0; // type:function size:0x28
+vt_0x18__15dAcItem_0xB3C_2Fv = .text:0x80257C10; // type:function size:0x8
+__dt__15dAcItem_0xB3C_2Fv = .text:0x80257C20; // type:function size:0x40
+__dt__15dAcItem_0xB3C_1Fv = .text:0x80257C60; // type:function size:0x40
+__dt__15dAcItem_0xB34_2Fv = .text:0x80257CA0; // type:function size:0x40
+__dt__15dAcItem_0xB34_1Fv = .text:0x80257CE0; // type:function size:0x40
build__24sFStateFct_c<9dAcItem_c>FRC12sStateIDIf_c = .text:0x80257D20; // type:function size:0x60
dispose__24sFStateFct_c<9dAcItem_c>FRP10sStateIf_c = .text:0x80257D80; // type:function size:0xC
initialize__21sFState_c<9dAcItem_c>Fv = .text:0x80257D90; // type:function size:0x1C
@@ -28530,7 +28530,7 @@ DEFAULT_ITEM_INIT_STRUCT = .rodata:0x804EC42C; // type:object size:0x14
sItemFlagStructs__13dAcItemBase_c = .rodata:0x804EC440; // type:object size:0x538 scope:local
sItemTypeFlags__13dAcItemBase_c = .rodata:0x804EC978; // type:object size:0x7F8 scope:local
TRIAL_INDEX_STRUCTS = .rodata:0x804ED170; // type:object size:0x20
-GLITTERING_SPORES_CHANCES = .rodata:0x804ED190; // type:object size:0x20 data:4byte
+sSporeRupeeChances = .rodata:0x804ED190; // type:object size:0x20 data:4byte
lbl_804ED1B0 = .rodata:0x804ED1B0; // type:object size:0x18
lbl_804ED1C8 = .rodata:0x804ED1C8; // type:object size:0x18
lbl_804ED1E0 = .rodata:0x804ED1E0; // type:object size:0x10
@@ -48030,7 +48030,7 @@ lbl_8057BD74 = .sdata2:0x8057BD74; // type:object size:0x4 align:4 data:float
lbl_8057BD78 = .sdata2:0x8057BD78; // type:object size:0x4 align:4 data:float
lbl_8057BD7C = .sdata2:0x8057BD7C; // type:object size:0x4 align:4 data:float
lbl_8057BD80 = .sdata2:0x8057BD80; // type:object size:0x4 align:4 data:float
-DEFAULT_ITEM_FLAG_STRUCT = .sdata2:0x8057BD88; // type:object size:0x8
+sDefaultFlagStruct__13dAcItemBase_c = .sdata2:0x8057BD88; // type:object size:0x8
lbl_8057BD90 = .sdata2:0x8057BD90; // type:object size:0x4 data:4byte
lbl_8057BD94 = .sdata2:0x8057BD94; // type:object size:0x4 data:4byte
lbl_8057BD98 = .sdata2:0x8057BD98; // type:object size:0x4 data:4byte
diff --git a/include/d/a/d_a_item.h b/include/d/a/d_a_item.h
index 8c28c148..8d06e468 100644
--- a/include/d/a/d_a_item.h
+++ b/include/d/a/d_a_item.h
@@ -1,14 +1,16 @@
#ifndef D_A_ITEM_H
#define D_A_ITEM_H
+// clang-format off
+// vtable order
#include "common.h"
+#include "d/d_shadow.h"
#include "d/a/d_a_base.h"
#include "d/a/d_a_itembase.h"
#include "d/a/obj/d_a_obj_scattersand.h"
#include "d/col/bg/d_bg_s_acch.h"
#include "d/col/c/c_cc_d.h"
#include "d/col/cc/d_cc_d.h"
-#include "d/d_shadow.h"
#include "f/f_list_mg.h"
#include "f/f_list_nd.h"
#include "m/m_angle.h"
@@ -18,84 +20,100 @@
#include "toBeSorted/actor_event.h"
#include "toBeSorted/d_emitter.h"
#include "toBeSorted/dowsing_target.h"
+// clang-format on
class dItemMdl_c;
class dAcItem_c;
+/** Positions picked up items for a bit. */
class dAcItem_0xB34 {
public:
virtual ~dAcItem_0xB34() {}
virtual void vt_0x0C() = 0;
- virtual void vt_0x10() = 0;
+ virtual bool vt_0x10(dAcItem_c *item) = 0;
};
+/** No-op impl that immediately hides the item */
class dAcItem_0xB34_1 : public dAcItem_0xB34 {
public:
virtual ~dAcItem_0xB34_1() {}
virtual void vt_0x0C() override;
- virtual void vt_0x10() override;
+ virtual bool vt_0x10(dAcItem_c *item) override;
};
+/** Impl that positions picked up items above Link's head */
class dAcItem_0xB34_2 : public dAcItem_0xB34 {
public:
virtual ~dAcItem_0xB34_2() {}
virtual void vt_0x0C() override;
- virtual void vt_0x10() override;
+ virtual bool vt_0x10(dAcItem_c *item) override;
private:
- /* 0x04 */ u8 _0x04[0x0C - 0x04];
+ /* 0x04 */ f32 mHighestRelativeHeadHeight;
+ /* 0x08 */ u8 mNumFrames;
};
+/** Respawns certain items. */
class dAcItem_0xB3C {
public:
virtual ~dAcItem_0xB3C() {}
virtual void vt_0x0C(u16) = 0;
virtual void vt_0x10() = 0;
- virtual void vt_0x14() = 0;
- virtual void vt_0x18() = 0;
+ virtual bool vt_0x14(dAcItem_c *) = 0;
+ virtual UNKWORD vt_0x18() = 0;
void fn_802579D0();
- bool fn_80257A10(dAcItem_c*);
- bool fn_80257A80();
+ bool fn_80257A10(dAcItem_c *);
+ void fn_80257A80();
void fn_80257AC0();
- bool fn_80257B10();
+ bool fn_80257B10() const;
protected:
- /* 0x04 */ u8 _0x04[0x08 - 0x04];
+ /* 0x04 */ UNKWORD field_0x04;
};
+/** No-op impl that doesn't respawn items */
class dAcItem_0xB3C_1 : public dAcItem_0xB3C {
public:
dAcItem_0xB3C_1(u16, u16) {}
- virtual ~dAcItem_0xB3C_1();
+ virtual ~dAcItem_0xB3C_1() {}
virtual void vt_0x0C(u16) override;
virtual void vt_0x10() override;
- virtual void vt_0x14() override;
- virtual void vt_0x18() override;
+ virtual bool vt_0x14(dAcItem_c *) override;
+ virtual UNKWORD vt_0x18() override;
};
+/** Impl that respawns items */
class dAcItem_0xB3C_2 : public dAcItem_0xB3C {
public:
dAcItem_0xB3C_2(u16 a1, u16 a2) {
mCb1 = sCb1s[a1];
mCb2 = sCb2s[a2];
}
- virtual ~dAcItem_0xB3C_2();
+ virtual ~dAcItem_0xB3C_2() {}
virtual void vt_0x0C(u16) override;
virtual void vt_0x10() override;
- virtual void vt_0x14() override;
- virtual void vt_0x18() override;
+ virtual bool vt_0x14(dAcItem_c *) override;
+ virtual UNKWORD vt_0x18() override;
public:
typedef void (dAcItem_0xB3C_2::*Callback1)();
+ // May or may not take a dAcItem_c* argument...
typedef bool (dAcItem_0xB3C_2::*Callback2)();
static Callback1 sCb1s[2];
static Callback2 sCb2s[3];
+ void Cb1_1();
+ void Cb1_2();
+
+ bool Cb2_1();
+ bool Cb2_2();
+ bool Cb2_3();
+
/* 0x08 */ Callback1 mCb1;
/* 0x14 */ Callback2 mCb2;
- /* 0x20 */ u8 _0x20[0x24 - 0x20];
+ /* 0x20 */ UNKWORD field_0x20;
};
class dAcItem_c : public dAcItemBase_c {
@@ -110,10 +128,17 @@ public:
virtual int draw() override;
virtual u16 getItemIdFromParams() override;
- virtual void setItemId(u16 id);
+ virtual void setItemId(u16 id) override;
virtual bool shouldDespawn();
virtual bool isItemSmallKeyOrHeartPieceOrStaminaFruit();
+ enum ItemGetAnim_e {
+ ANIM_DEFAULT,
+ ANIM_GORGEOUS,
+ ANIM_FROWN,
+ ANIM_SMALL,
+ };
+
STATE_FUNC_DECLARE(dAcItem_c, Wait);
STATE_FUNC_DECLARE(dAcItem_c, Carry);
STATE_FUNC_DECLARE(dAcItem_c, GetBeetle);
@@ -141,9 +166,11 @@ public:
static void setFlag(s32 id);
static bool checkTreasureTempCollect(u16 itemId);
- void setItemPosition(const mVec3_c &);
void getItemFromBWheelItem();
- bool isStateWait();
+ void setItemPosition(const mVec3_c &);
+ void setItemVelocity(f32 f);
+ bool isStateWait() const;
+ void stopCarryAndGet();
static s32 getTotalBombCount();
static s32 getTotalArrowCount();
@@ -224,7 +251,10 @@ public:
u32 getParams2Lower_shift1_0x7() const;
+ static bool getEventNameForAnim(u32 anim, const char **outName);
+ static bool getTboxEventNameForAnim(u32 anim, const char **outName);
static bool getItemGetEventName(u16 item, const char **outName);
+ static bool getItemGetTboxEventName(u16 item, const char **outName);
static void itemGetEventStart(dAcBase_c *);
static void itemGetEventEnd(dAcBase_c *);
@@ -248,7 +278,7 @@ public:
TEAR_MAX
};
- static Tear_e getTearSubtype(ITEM_ID item);
+ static Tear_e getTearSubtype(u32 item);
static void healLink(u32 amount, bool); // move to dAcPy_c
@@ -265,6 +295,10 @@ public:
}
private:
+ bool isField_0xD04GtZero() const {
+ return 0.0f < field_0xD04;
+ }
+
static bool sIsPerformingInitialCollection;
static s32 sCollectionCurrentCount;
@@ -275,8 +309,17 @@ private:
static const mVec3_c sScale1Maybe;
static const mVec3_c sScale2Maybe;
+ static const mVec3_c sUnkOffset1;
+ static const mVec3_c sUnkOffset2;
+ static const mVec3_c sUnkOffset3;
+ static const mVec3_c sUnkOffset4;
+ static const mVec3_c sUnkOffset5;
+ static const mVec3_c sUnkOffset6;
+ static const mVec2_c sUnkVec2;
+
typedef bool (dAcItem_c::*sStaticPtmf)();
- static const sStaticPtmf sStaticPtmfs[];
+ static const sStaticPtmf sStaticPtmfs1[];
+ static const sStaticPtmf sStaticPtmfs2[];
static dAcRef_c<dAcObjBase_c> sItemListHead;
static dAcRef_c<dAcObjBase_c> sItemListTail;
@@ -397,6 +440,11 @@ private:
void incrementFramesInAir();
void setItemFlags(u32 flags);
+ /** Checks if the ground's specialCode should allow the item to sink, deleting the item when fully submerged */
+ bool isItemDeleteGround(s32 specialCode) const;
+ /** Checks if the ground's specialCode should allow the item to "dip" into the ground */
+ bool isItemSwimGround(s32 specialCode) const;
+
bool fn_80255CF0();
bool fn_802574A0();
void addToGetQueue();
@@ -409,8 +457,6 @@ private:
bool fn_802577A0();
void fn_80256F20();
bool fn_80256E80();
- bool fn_80255C50(u32 specialCode);
- bool fn_80255CA0(u32 specialCode);
void getCurrentModelScale(f32 *scale);
f32 getCurrentScale();
void fn_802518C0(mVec3_c *out);
@@ -456,7 +502,10 @@ private:
void fn_80254810();
static s16 getItemRotateAngle();
- static void getItemGetEventName(u16 id, char *const *name);
+ bool playHeartStemCutSound();
+
+ void getOffsetPosition(mVec3_c &position) const;
+ f32 scaleBy(f32 f) const;
// Could also return vector
static void fn_80247540(mVec3_c &);
@@ -662,12 +711,14 @@ private:
f32 getRupoorHitKnockbackRand3();
f32 getHeartHitKnockbackRand3();
- f32 fn_802577C0();
- f32 fn_802577D0();
+ f32 getSinkSpeedHeart();
+ f32 getSinkSpeedDefault();
- void fn_80255E80();
- void fn_80255F40();
+public:
+ void rotateTowardsCamera();
+ void rotateFixedBirdStatuette();
+private:
/* 0x334 */ dItemMdl_c *mpMdl;
/* 0x338 */ dShadowCircle_c mShdw;
/* 0x340 */ mVec3_c field_0x340;
@@ -688,7 +739,7 @@ private:
/* 0xA60 */ dEmitter_c mEff_0xA60;
/* 0xA94 */ dAcRef_c<dAcOScatterSand> mCoveredSand;
/* 0xAA0 */ dAcRef_c<dAcObjBase_c> mForceSignRef;
- /* 0xAAC */ mVec3_c posCopy;
+ /* 0xAAC */ mVec3_c mItemPosCopy;
/* 0xAB8 */ fLiNdBa_c mNode;
/* 0xAC4 */ ActorEventRelated mEventRelated;
/* 0xB14 */ DowsingTarget mDowsingTarget;
@@ -725,7 +776,7 @@ private:
/* 0xC90 */ f32 (dAcItem_c::*mFn_0xC90)();
/* 0xC9C */ void (dAcItem_c::*mFn_0xC9C)();
/* 0xCA8 */ void (dAcItem_c::*mFnSetBoundingBox)();
- /* 0xCB4 */ f32 (dAcItem_c::*mFn_0xCB4)(void);
+ /* 0xCB4 */ f32 (dAcItem_c::*mFnGetSinkSpeed)(void);
/* 0xCC0 */ dAcRef_c<dAcItem_c> mItemQueuePrev;
/* 0xCCC */ dAcRef_c<dAcItem_c> mItemQueueNext;
/* 0xCD8 */ f32 field_0xCD8;
@@ -735,9 +786,9 @@ private:
/* 0xCE8 */ f32 field_0xCE8;
/* 0xCEC */ f32 field_0xCEC;
/* 0xCF0 */ u8 _CF0[0xD00 - 0xCF0];
- /* 0xD00 */ f32 field_0xD00;
+ /* 0xD00 */ f32 mSinkOffset;
/* 0xD04 */ f32 field_0xD04;
- /* 0xD08 */ u8 _D08[0xD0C - 0xD08];
+ /* 0xD08 */ f32 field_0xD08;
/* 0xD0C */ f32 field_0xD0C;
/* 0xD10 */ u8 _D10[0xD14 - 0xD10];
/* 0xD14 */ f32 mFreestandingOffsetH;
@@ -790,6 +841,7 @@ private:
public:
static fLiMgBa_c sItemList;
+ static fLiMgBa_c sUnusedList;
};
#endif
diff --git a/include/d/a/d_a_itembase.h b/include/d/a/d_a_itembase.h
index d0f29f23..828d98c0 100644
--- a/include/d/a/d_a_itembase.h
+++ b/include/d/a/d_a_itembase.h
@@ -245,6 +245,7 @@ public:
virtual ~dAcItemBase_c() {}
virtual u16 getItemId() const;
virtual u16 getItemIdFromParams() = 0;
+ virtual void setItemId(u16 id);
static bool isValidItemTypeIdx(int itemId);
static bool getItemTypeFromId(u16 itemID, u32 *pOutType);
diff --git a/include/d/d_angle.h b/include/d/d_angle.h
new file mode 100644
index 00000000..dc12dabc
--- /dev/null
+++ b/include/d/d_angle.h
@@ -0,0 +1,17 @@
+#ifndef D_ANGLE_H
+#define D_ANGLE_H
+
+#include "m/m_angle.h"
+#include "m/m_vec.h"
+
+inline void setRotXY(mAng3_c &rot, s32 x, s32 y) {
+ rot.x.mVal = x;
+ rot.y.mVal = y;
+ rot.z.mVal = 0;
+}
+
+inline void setRotXYVec(mAng3_c &rot, const mVec3_c &direction) {
+ setRotXY(rot, -direction.atan2sY_XZ(), direction.atan2sX_Z());
+}
+
+#endif
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);
}
diff --git a/src/toBeSorted/item_mdl_misc.cpp b/src/toBeSorted/item_mdl_misc.cpp
index 0d539f48..b9c345cd 100644
--- a/src/toBeSorted/item_mdl_misc.cpp
+++ b/src/toBeSorted/item_mdl_misc.cpp
@@ -860,7 +860,7 @@ bool dItemMdlTear_c::isMdlForItemId(u16 itemId) {
bool dItemMdlTear_c::init(u16 itemId, dAcItem_c *item, mAllocator_c *allocator) {
// TODO - why is TRY_CREATE used so inconsistently here?
- dAcItem_c::Tear_e tear = dAcItem_c::getTearSubtype((ITEM_ID)itemId);
+ dAcItem_c::Tear_e tear = dAcItem_c::getTearSubtype(itemId);
if (tear == dAcItem_c::TEAR_MAX) {
return false;
}