Files
st/src/031_Land/Actor/ActorItemDrop.cpp
T
Alessevan f66583c194 Decompile ActorUnkAROW (83%) (#70)
* refactor: unknown arow actor to arrow

* refactor: rename ActorUnkArow_c4 and remove warning

* refactor: rename class in system files

* feat: match actorprofilearrow

* feat: progress decompilation

* feat: rename actor to ActorShotArrow

* feat: change mangled name

* feat: decompile some functions and mark unmatched functions as non-matching

* feat: progress

* feat: decompiling function 020f206c

* feat: change two fields for struct padding

* feat: remove non-matching comment on matched function

* feat: decompiling function 020f20bc

* refactor: fix .bss mangled names

* feat: decompiling 020f2134

* feat: decompiling func_ov031_020f2160

* feat: matching function func_ov031_020f21dc

* feat: use correct mangled names in jp version

* fix: change back arm9/delinks in eur version

* feat: non-matching function 020f1a64

* feat: decompile 020f2270

* feat: decompile function 020f2280

* feat: uncompile func_ov031_020f229c

* feat: match 020f22d4 add UnkSystem{4,5} as fields

* feat: reverse 020f2b8c

* feat: 020f2bbc

* feat: 020f2bec

* feat: 020f3304

* style: explicitly indicate floating values when using FLOAT_TO_Q20

* style: move external function to the top

* feat: begin of 020f3258

* feat: decompile 020f32c4

* feat: propagate mangled names changes to japan version

* feat: begin decompilation of func_ov031_020f370c

* feat: begin weird decompilation of func_ov031_020f3d4c

* feat: decompile function 020f3d04

* feat: better matching

* feat: matching function func_ov031_020f2214

* feat: decompile the function 020f3258

* feat: increase matched code

* feat: decompile function func_ov031_020f2794

* feat: decompile function func_ov031_020f18bc

* feat: decompile almost all func_ov031_020f195c

* feat: decompile 3/4 of func_ov031_020f173c

* refactor: change back function's return type to void

* feat: begin decompilation of func_ov031_020f1b04

* feat: advance decompilation of 020f1c7c

* feat: decompile 020f1e3c

* feat: decompile function func_ov031_020f1f54

* refactor: move func(Actor *) into ActorShotArrow class

* feat: introduce ActorShotArrow_194 thanks to Yanis002

* fix: use FX32 in macros over old Q20

* fix: praying magic behaviour

* revert: revert before build failure

* revert: remove all relocs.txt magic stuff

* revert: introduce back correct symbols

* revert: introduce back CORRECTLY correct symbols

* feat: rename vtable

* fix: wrong hex in comment

* feat: huge improvements

* fix: undefined 02081d7c

* fix: awful symbol name

* fix: part of mangled name in jp version

* fix: rest of the line disappeared

* fix: try to fix jp version

* fix: apply eur fix to jp

* feat: add function 020f374c

* fix: full match of 020f173c

* feat: move function in upperclass

* feat: change ActorRupee to use class function

* feat: try decompiling func_ov031_020f2ef0

* feat: improvements

* feat: improvements

* docs: add comment

* fix: build issues

* feat: improvements

* feat: improvements

* feat: forget inclusion of unkstruct

* feat: enhanced

* feat: some improvements

* style: better style

* feat: decompile function and cleanup

* refactor: remove .cache ??

* review

---------

Co-authored-by: Yanis002 <35189056+Yanis002@users.noreply.github.com>
2026-06-22 01:20:15 +02:00

559 lines
16 KiB
C++

#include "Actor/ActorItemDrop.hpp"
#include "Actor/ActorManager.hpp"
#include "System/SysNew.hpp"
#include "Unknown/UnkStruct_027e09a8.hpp"
#include "Unknown/UnkStruct_027e09b8.hpp"
#include "Unknown/UnkStruct_027e0cd8.hpp"
#include "Unknown/UnkStruct_027e0ce0.hpp"
#include "Unknown/UnkStruct_027e0d34.hpp"
#include "versions.h"
extern "C" void func_01ffedac(u16 *, VecFx32 *);
extern "C" void func_01fff05c(u32 *, UnkStruct_027e0cd8_0c *, VecFx32 *);
extern "C" void func_ov000_0205c1f0(unk32 *, u16);
extern "C" void func_ov000_0205c204(unk32 *, VecFx32 *, unk32, unk32, unk32);
extern "C" void func_ov017_020bf99c();
static const Cylinder data_ov031_02114ba0(0x800);
static const u32 data_ov031_02110bc8[] = {
0x1D, // ItemDropType_Arrow
0x1E, // ItemDropType_Bomb
0x1F, // ItemDropType_RedPotion
0x20, // ItemDropType_DemonFossil
0x21, // ItemDropType_StalfosSkull
0x22, // ItemDropType_StarFragment
0x23, // ItemDropType_BeeLarvae
0x24, // ItemDropType_WoodHeart
0x25, // ItemDropType_PirateNecklace
};
DECL_PROFILE(ActorProfileArrowDrop);
Actor *ActorProfileArrowDrop::Create() {
return new(HeapIndex_2) ActorItemDrop();
}
ActorProfileArrowDrop::ActorProfileArrowDrop() :
ActorProfile(ActorId_ArrowDrop) {
this->mUnk_04.Init(0x400);
}
DECL_PROFILE(ActorProfileBombDrop);
Actor *ActorProfileBombDrop::Create() {
return new(HeapIndex_2) ActorItemDrop();
}
ActorProfileBombDrop::ActorProfileBombDrop() :
ActorProfile(ActorId_BombDrop) {
this->mUnk_04.Init(0x400);
}
DECL_PROFILE(ActorProfileRedPotionDrop);
Actor *ActorProfileRedPotionDrop::Create() {
return new(HeapIndex_2) ActorItemDrop();
}
ActorProfileRedPotionDrop::ActorProfileRedPotionDrop() :
ActorProfile(ActorId_RedPotionDrop) {
this->mUnk_04.Init(0x400);
}
DECL_PROFILE(ActorProfileTreasureDrop);
Actor *ActorProfileTreasureDrop::Create() {
return new(HeapIndex_2) ActorItemDrop();
}
ActorProfileTreasureDrop::ActorProfileTreasureDrop() :
ActorProfile(ActorId_TreasureDrop) {
this->mUnk_04.Init(0x400);
}
void ActorItemDrop::func_ov031_020f9f8c(ActorRef *pOutRef, const VecFx32 *pPos, u32 params, ActorRef ref) {
ActorParams actorParams;
actorParams.mUnk_28.Reset();
actorParams.func_ov000_020975f8();
actorParams.mInitialPos.x = pPos->x;
actorParams.mInitialPos.y = pPos->y;
actorParams.mInitialPos.z = pPos->z;
actorParams.mUnk_28 = ref;
actorParams.mParams[0] = params & 0xFF;
Actor::func_ov000_020973f4(pOutRef, &data_ov000_020b539c_eur, ActorId_TreasureDrop, &actorParams, 0);
}
ActorItemDrop::ActorItemDrop() :
mUnk_AE(0x0),
mUnk_B0(0x6),
mUnk_D8(FLOAT_TO_FX32(0.5f)),
mUnk_DC(0),
mUnk_E0(0),
mUnk_E4(this),
mUnk_108(0x0) {
this->mUnk_10C.x = FLOAT_TO_FX32(0.0f);
this->mUnk_10C.y = FLOAT_TO_FX32(0.0f);
this->mUnk_10C.z = FLOAT_TO_FX32(0.0f);
this->mUnk_118 = false;
this->mUnk_119 = false;
switch (this->GetActorId()) {
case ActorId_ArrowDrop:
if (GET_FLAG(data_027e0ce0->mUnk_2C->mFlags, ItemFlag_Bow)) {
this->mItemTypeId = ItemDropType_Arrow;
this->mUnk_D8 = FLOAT_TO_FX32(0.5f);
} else {
this->mItemTypeId = ItemDropType_Unknown;
}
break;
case ActorId_BombDrop:
if (GET_FLAG(data_027e0ce0->mUnk_2C->mFlags, ItemFlag_Bombs)) {
this->mItemTypeId = ItemDropType_Bomb;
this->mUnk_D8 = FLOAT_TO_FX32(0.3f);
} else {
this->mItemTypeId = ItemDropType_Unknown;
}
break;
case ActorId_RedPotionDrop:
this->mItemTypeId = ItemDropType_RedPotion;
this->mUnk_D8 = FLOAT_TO_FX32(0.4f);
this->mUnk_119 = true;
break;
case ActorId_TreasureDrop:
ItemDropType itemType;
switch (this->mUnk_5C.mParams[0]) {
case 0:
itemType = ItemDropType_DemonFossil;
break;
case 1:
itemType = ItemDropType_StalfosSkull;
break;
case 2:
itemType = ItemDropType_StarFragment;
break;
case 3:
itemType = ItemDropType_BeeLarvae;
break;
case 4:
itemType = ItemDropType_WoodHeart;
break;
case 9:
itemType = ItemDropType_PirateNecklace;
break;
default:
itemType = ItemDropType_Unknown;
break;
}
this->mItemTypeId = itemType;
this->mUnk_D8 = FLOAT_TO_FX32(0.3f);
this->mUnk_119 = true;
break;
default:
this->mItemTypeId = ItemDropType_Unknown;
break;
}
this->mUnk_B4.mUnk_04 = 0x13100;
this->mUnk_40 = &this->mUnk_E4;
u16 sp0;
func_01ffedac(&sp0, &this->mPos);
if (data_027e0cd8->mUnk_0C->func_ov000_02080180(&sp0) == 0x5) {
this->mUnk_34 = (Cylinder *) &data_ov031_02114ba0;
}
}
bool ActorItemDrop::vfunc_18(unk32 param1) {
if (this->mItemTypeId >= ItemDropType_Unknown) {
return false;
}
this->mUnk_52 = FLOAT_TO_FX32(0.1173f);
this->mUnk_50 = FLOAT_TO_FX32(0.0f);
this->SetState(ActorItemDropState_0);
return true;
}
void ActorItemDrop::vfunc_20() {
this->func_ov031_020fa260();
}
void ActorItemDrop::vfunc_24() {
if (this->mState == ActorItemDropState_6) {
this->func_ov031_020fa260();
}
}
static PTMF<ActorItemDrop> data_ov031_02114bb0[ActorItemDropState_Max] = {
ActorItemDrop::func_ov031_020fa46c, // ActorItemDropState_0
ActorItemDrop::func_ov031_020fa4a0, // ActorItemDropState_1
ActorItemDrop::func_ov031_020fa568, // ActorItemDropState_2
ActorItemDrop::func_ov031_020fa5f0, // ActorItemDropState_3
ActorItemDrop::func_ov031_020fa664, // ActorItemDropState_4
ActorItemDrop::func_ov031_020fa678, // ActorItemDropState_5
ActorItemDrop::func_ov031_020fa72c, // ActorItemDropState_6
};
void ActorItemDrop::func_ov031_020fa260() {
this->mUnk_3C = &this->mUnk_B4;
CALL_PTMF(PTMF<ActorItemDrop>, data_ov031_02114bb0[this->mState]);
if (this->IsTimerOut()) {
this->func_ov000_020989e0();
if (this->mUnk_B4.mUnk_08 & 0x3FFFF) {
switch (this->mUnk_B4.mUnk_1C) {
case 8:
case 16:
if (this->mUnk_119) {
bool var_r1_3 = false;
if (this->mUnk_B4.mUnk_0C.type_index == 0x100 && this->mUnk_B4.mUnk_0C.unk_id == 0) {
var_r1_3 = true;
}
if (var_r1_3 || (this->mUnk_B4.mUnk_0C.type_index == 0x100 && this->mUnk_B4.mUnk_0C.unk_id == 1 &&
data_027e0ce0->func_01fff1e0())) {
this->SetState(ActorItemDropState_6);
}
} else if (this->mUnk_B4.mUnk_0C.type_index & 0x100) {
this->SetState(ActorItemDropState_6);
}
break;
case 12:
this->mUnk_DC = this->mUnk_B4.mUnk_0C;
this->mUnk_B4.mUnk_04 &= ~0x1000;
this->SetState(ActorItemDropState_3);
break;
default:
break;
}
}
}
if (this->mUnk_5C.mUnk_24 < 0 && this->mState != ActorItemDropState_6) {
this->func_ov031_020fa900();
}
VecFx32_Copy(&this->mPos, &this->mPrevPos);
VecFx32_Add(&this->mPos, &this->mVel, &this->mPos);
if (this->mState != ActorItemDropState_3) {
this->func_ov000_02098b8c(0x0, 0x0);
}
if (this->mUnk_46 & 3) {
this->mVel.y = FLOAT_TO_FX32(0.0f);
}
VecFx32_Add(&this->mPos, &this->mUnk_10C, &this->mPos);
this->mUnk_10C.x = FLOAT_TO_FX32(0.0f);
this->mUnk_10C.y = FLOAT_TO_FX32(0.0f);
this->mUnk_10C.z = FLOAT_TO_FX32(0.0f);
}
static PTMF<ActorItemDrop> data_ov031_02114be8[ActorItemDropState_Max] = {
ActorItemDrop::func_ov031_020fa468, // ActorItemDropState_0
ActorItemDrop::func_ov031_020fa494, // ActorItemDropState_1
ActorItemDrop::func_ov031_020fa524, // ActorItemDropState_2
ActorItemDrop::func_ov031_020fa5d8, // ActorItemDropState_3
ActorItemDrop::func_ov031_020fa650, // ActorItemDropState_4
ActorItemDrop::func_ov031_020fa668, // ActorItemDropState_5
ActorItemDrop::func_ov031_020fa6c8, // ActorItemDropState_6
};
void ActorItemDrop::SetState(ActorState state) {
#if IS_JP
if (this->mState == ActorItemDropState_6 && state == ActorItemDropState_6) {
return;
}
#endif
this->mState = state;
this->mUnk_44 = 0x9C;
CALL_PTMF(PTMF<ActorItemDrop>, data_ov031_02114be8[this->mState]);
}
void ActorItemDrop::func_ov031_020fa468() {}
void ActorItemDrop::func_ov031_020fa46c() {
func_ov000_02098838();
if (this->mVel.y > FLOAT_TO_FX32(0.0f)) {
return;
}
this->SetState(ActorItemDropState_1);
}
void ActorItemDrop::func_ov031_020fa494() {
this->mUnk_44 = 0x9F;
}
void ActorItemDrop::func_ov031_020fa4a0() {
u32 stack;
func_ov000_02098838();
if (!(this->mUnk_46 & 0x3)) {
return;
}
func_01fff05c(&stack, data_027e0cd8->mUnk_0C, &this->mPos);
if (((stack >> 0x5) & 0x3) == 0x2 && this->mItemTypeId != ItemDropType_Arrow && this->mItemTypeId != ItemDropType_Bomb) {
this->func_ov000_020984d0();
return;
}
this->SetState(ActorItemDropState_2);
}
void ActorItemDrop::func_ov031_020fa524() {
this->mVel.x = FLOAT_TO_FX32(0.0f);
this->mVel.y = FLOAT_TO_FX32(0.0f);
this->mVel.z = FLOAT_TO_FX32(0.0f);
if (!this->mUnk_118 && this->mUnk_52 - this->mUnk_50 > FLOAT_TO_FX32(0.044f)) {
this->mUnk_52 = FLOAT_TO_FX32(0.044f);
this->mUnk_50 = FLOAT_TO_FX32(0.0f);
}
this->mUnk_44 = 0x9F;
}
// non-matching
void ActorItemDrop::func_ov031_020fa568() {
if (this->mUnk_5C.mUnk_24 >= 0) {
return;
}
switch (this->mUnk_108) {
case 0x0:
if (!(this->mUnk_46 & 0x3)) {
this->mUnk_108++;
}
break;
case 0x1:
this->func_ov000_02098838();
if (this->mUnk_46 & 0x3) {
this->mVel.x = FLOAT_TO_FX32(0.0f);
this->mVel.y = FLOAT_TO_FX32(0.0f);
this->mVel.z = FLOAT_TO_FX32(0.0f);
this->mUnk_108 = 0x0;
}
break;
default:
break;
}
}
void ActorItemDrop::func_ov031_020fa5d8() {
func_ov017_020bf99c();
this->mUnk_B4.func_ov000_02097bec();
}
void ActorItemDrop::func_ov031_020fa5f0() {
this->func_ov017_020bf9c8(gpActorManager->func_01fff3b4(this->mUnk_DC));
if (GET_FLAG(this->mFlags, ActorFlag_5)) {
this->mVel.x = FLOAT_TO_FX32(0.0f);
this->mVel.y = FLOAT_TO_FX32(0.0f);
this->mVel.z = FLOAT_TO_FX32(0.0f);
this->mUnk_B4.mUnk_04 |= 0x1000;
this->SetState(ActorItemDropState_1);
}
}
void ActorItemDrop::func_ov031_020fa650() {
this->mVel.x = FLOAT_TO_FX32(0.0f);
this->mVel.y = FLOAT_TO_FX32(0.0f);
this->mVel.z = FLOAT_TO_FX32(0.0f);
}
void ActorItemDrop::func_ov031_020fa664() {}
void ActorItemDrop::func_ov031_020fa668() {
this->mVel.x = FLOAT_TO_FX32(0.0f);
this->mVel.z = FLOAT_TO_FX32(0.0f);
}
class UnkActor_ov031_020fa678 : public Actor {
public:
/* 000 (base) */
/* 94 */ STRUCT_PAD(0x94, 0xE8);
/* E8 */ VecFx32 mUnk_E8;
};
void ActorItemDrop::func_ov031_020fa678() {
UnkActor_ov031_020fa678 *actor = (UnkActor_ov031_020fa678 *) gpActorManager->func_01fff3b4(this->mUnk_E0);
if (actor == NULL) {
this->SetState(ActorItemDropState_1);
return;
}
VecFx32_Copy(&actor->mUnk_E8, &this->mPos);
}
void ActorItemDrop::func_ov031_020fa6c8() {
this->mUnk_52 = FLOAT_TO_FX32(15.9998f);
this->mUnk_50 = FLOAT_TO_FX32(0.0f);
this->mVel.x = FLOAT_TO_FX32(0.0f);
this->mVel.y = FLOAT_TO_FX32(0.0f);
this->mVel.z = FLOAT_TO_FX32(0.0f);
this->mUnk_4A[0] = 0x0;
this->mUnk_44 = 0x0;
this->mUnk_B4.func_ov000_02097bec();
UNSET_FLAG(this->mFlags, ActorFlag_Visible);
data_027e09a8->func_ov000_02071b30(0x77, &this->mPos, 0x0);
}
void ActorItemDrop::func_ov031_020fa72c() {
this->mUnk_3C = NULL;
if (data_027e09b8->func_01ffd420()) {
return;
}
bool executeFunction = true;
switch (this->mItemTypeId) {
case ItemDropType_Arrow:
data_027e0ce0->mUnk_2C->GiveArrows(5);
break;
case ItemDropType_Bomb:
data_027e0ce0->mUnk_2C->GiveBombs(3);
break;
case ItemDropType_RedPotion:
executeFunction = data_027e0d34->TryItemGive(ItemId_RedPotion);
break;
case ItemDropType_DemonFossil:
executeFunction = data_027e0d34->TryItemGive(ItemId_DemonFossil);
break;
case ItemDropType_StalfosSkull:
executeFunction = data_027e0d34->TryItemGive(ItemId_StalfosSkull);
break;
case ItemDropType_StarFragment:
executeFunction = data_027e0d34->TryItemGive(ItemId_StarFragment);
break;
case ItemDropType_BeeLarvae:
executeFunction = data_027e0d34->TryItemGive(ItemId_BeeLarvae);
break;
case ItemDropType_WoodHeart:
executeFunction = data_027e0d34->TryItemGive(ItemId_WoodHeart);
break;
case ItemDropType_PirateNecklace:
executeFunction = data_027e0d34->TryItemGive(ItemId_PirateNecklace);
break;
default:
executeFunction = true;
break;
}
if (executeFunction) {
this->func_ov000_020984d0();
}
}
void ActorItemDrop::vfunc_2C(unk32 param1) {
VecFx32 vec1;
VecFx32 vec2;
unk32 value;
if (!this->func_01fff5d0(param1, 0x0)) {
return;
}
vec1 = this->mPos;
vec1.y += FLOAT_TO_FX32(0.03113);
this->func_ov017_020bf5c4(&vec1, 0x400, 0x400, 0x1F, 0x0);
func_ov000_0205c1f0(&value, data_ov031_02110bc8[this->mItemTypeId]);
vec2 = this->mPos;
vec2.y += this->mUnk_D8;
func_ov000_0205c204(&value, &vec2, 0x1000, 0x1000, 0x1F);
}
void ActorItemDrop::func_ov031_020fa900() {
bool var_r2 = true;
bool var_r3 = true;
bool var_ip = true;
if (this->mState != ActorItemDropState_3 && this->mState != ActorItemDropState_4) {
var_ip = false;
}
if (!var_ip && this->mState != ActorItemDropState_5) {
var_r3 = false;
}
if (!var_r3 && this->mState != ActorItemDropState_6) {
var_r2 = false;
}
if (var_r2) {
SET_FLAG(this->mFlags, ActorFlag_Visible);
} else if (!this->mUnk_118) {
if (this->Actor::IsTimerOut()) {
this->mUnk_118 = true;
this->mUnk_52 = 60;
this->mUnk_50 = 0;
}
} else {
if ((this->mUnk_50 % 8) < 4) {
UNSET_FLAG(this->mFlags, ActorFlag_Visible);
} else {
SET_FLAG(this->mFlags, ActorFlag_Visible);
}
if (this->Actor::IsTimerOut()) {
this->func_ov000_020984d0();
}
}
}
ActorItemDrop_C4::ActorItemDrop_C4(Actor *param1) :
Actor_C4(param1) {
this->mUnk_20 = param1;
this->mUnk_04 = 0x1;
}
bool ActorItemDrop_C4::vfunc_00(ActorRef ref, unk32 param2) {
if (param2 != 0) {
ActorItemDrop *actorDroppedItem = this->GetActorPtr<ActorItemDrop>();
actorDroppedItem->mUnk_E0 = ref;
actorDroppedItem->SetState(ActorItemDropState_4);
}
return Actor_C4::vfunc_00(ref, param2);
}
void ActorItemDrop_C4::vfunc_04() {
this->GetActorPtr<ActorItemDrop>()->SetState(ActorItemDropState_5);
Actor_C4::vfunc_04();
}
void ActorItemDrop_C4::vfunc_0C(unk32 param1) {
this->GetActorPtr<ActorItemDrop>()->SetState(ActorItemDropState_1);
Actor_C4::vfunc_0C(param1);
}
void ActorItemDrop_C4::vfunc_08() {
this->GetActorPtr<ActorItemDrop>()->SetState(ActorItemDropState_6);
Actor_C4::vfunc_08();
}