diff --git a/include/Actor/Navi/ActorNaviBase.hpp b/include/Actor/Navi/ActorNaviBase.hpp index 4434c1ff8..f7e348be0 100644 --- a/include/Actor/Navi/ActorNaviBase.hpp +++ b/include/Actor/Navi/ActorNaviBase.hpp @@ -60,7 +60,7 @@ class ActorNaviBase : public Actor { /* 214 */ unk16 mUnk_214; /* 216 */ unk8 mUnk_216[0x2]; /* 218 */ ActorNaviBase_Unk1 mUnk_218[2]; - /* 220 */ unk8 mUnk_220[0x2]; + /* 220 */ s16 mUnk_220; /* 222 */ unk16 mUnk_222; /* 224 */ UnkStruct_ov000_020d18f4 mUnk_224; /* 280 */ unk32 mUnk_280; @@ -68,12 +68,12 @@ class ActorNaviBase : public Actor { /* 288 */ unk8 mUnk_288; /* 288 */ unk8 mUnk_289; /* 28a */ unk16 mUnk_28a; - /* 28c */ unk8 mUnk_28c; - /* 28d */ unk8 mUnk_28d; - /* 28e */ unk8 mUnk_28e; - /* 28e */ unk8 mUnk_28f; - /* 290 */ unk8 mUnk_290; - /* 291 */ unk8 mUnk_291; + /* 28c */ u8 mUnk_28c; + /* 28d */ u8 mUnk_28d; + /* 28e */ u8 mUnk_28e; + /* 28f */ u8 mUnk_28f; + /* 290 */ u8 mUnk_290; + /* 291 */ u8 mUnk_291; /* 294 */ /* 00 */ virtual ~ActorNaviBase() override; diff --git a/src/00_Core/Actor/Navi/ActorNaviBase.cpp b/src/00_Core/Actor/Navi/ActorNaviBase.cpp index 0bbe0f8af..635a0c5b1 100644 --- a/src/00_Core/Actor/Navi/ActorNaviBase.cpp +++ b/src/00_Core/Actor/Navi/ActorNaviBase.cpp @@ -1,46 +1,393 @@ #include "Actor/Navi/ActorNaviBase.hpp" -u16 ActorNaviBase::vfunc_c4() {} -u16 ActorNaviBase::vfunc_c8() {} -unk32 ActorNaviBase::vfunc_30() {} -s32 ActorNaviBase::vfunc_b8() {} -bool ActorNaviBase::vfunc_cc(unk32 *param1) {} -void ActorNaviBase::GetOffsetPos(Vec3p *pos) {} -unk32 ActorNaviBase::vfunc_38() {} -void ActorNaviBase::vfunc_d0() {} -void ActorNaviBase::func_ov000_020b8c50(unk32) {} -void ActorNaviBase::func_ov000_020b8c98(unk32 param1, unk32 param2, unk32 param3) {} -void ActorNaviBase::vfunc_d4() {} -void ActorNaviBase::vfunc_d8() {} -void ActorNaviBase::SetActive(unk32 active) {} -void ActorNaviBase::TeleportAboveLink() {} -void ActorNaviBase::vfunc_e0() {} -void ActorNaviBase::vfunc_e4() {} -void ActorNaviBase::func_ov000_020b9770(s32 param1) {} -void ActorNaviBase::vfunc_e8() {} -void ActorNaviBase::vfunc_14(u32 param1) {} -void ActorNaviBase::vfunc_18(u32 param1) {} -void ActorNaviBase::func_ov000_020b9fdc() {} -void ActorNaviBase::func_ov000_020b9fe8() {} -void ActorNaviBase::vfunc_20(bool param1) {} -void ActorNaviBase::vfunc_10(u32 param1) {} +#include "Physics/Cylinder.hpp" +#include "DTCM/UnkStruct_027e0e58.hpp" +#include "Item/ItemManager.hpp" +#include "Map/MapManager.hpp" +#include "Map/TilePos.hpp" +#include "Player/PlayerBase.hpp" +#include "Player/PlayerLinkBase.hpp" +#include "Unknown/UnkStruct_020e9360.hpp" +#include "Unknown/UnkStruct_ov000_020beba8.hpp" + +extern "C" u16 func_ov000_020b8790(s32); +extern "C" u16 func_ov000_020b87cc(s32); +extern bool func_ov000_02087e8c(); +extern "C" bool func_0202b2e8(Vec3p *dst, Vec3p *target, q20 speed); +extern "C" bool Lerp(s32 *pValue, s32 dest, s32 factor, unk32 param4, u32 step); +extern "C" void Vec3p_RotateY(u32 angle, Vec3p *v); +extern "C" void func_ov000_020c0e24(UnkStruct_ov000_020c0c08 *self, s32 param2); +extern "C" void func_ov000_0207c1f8(UnkStruct_027e0e58 *self, ActorNaviBase_Unk1 *ref, u32 modelId, Vec3p *pos, s32 param5); +extern "C" void func_ov000_020b7e6c(ActorNaviBase_Unk1 *ref); +extern "C" void *func_0201e544(void *self, const char *name); +extern "C" void func_ov000_020c0cc8(UnkStruct_ov000_020c0c08 *self, void *param2, unk32 param3, unk32 param4); +extern char *data_ov000_020e678c[]; +extern "C" void func_ov000_020b8830(ItemModel *model, u32 color1, u32 color2); +extern "C" void func_02019534(void *model, unk32 materialIdx, unk32 color); +extern "C" u32 func_ov000_020b3ec4(ActorNaviBase_Unk3 *unk); +extern ItemModel *data_ov000_020ee1f8; +extern Mat3p gDefaultMatrix; + +static const u32 sFairyModelIds[FairyId_COUNT] = {0x24f, 0x251, 0x250}; + +struct ActorNaviBase_NameEntry { + char name[16]; + u32 id; +}; +static const ActorNaviBase_NameEntry sNaviNames[1] = {{"navi", 0}}; + +extern Vec3p data_ov000_020dc83c; +extern Vec3p data_ov000_020dc848; + +ARM u16 ActorNaviBase::vfunc_c4() { + if (mUnk_28d != 0) { + return 0x6318; + } + return func_ov000_020b8790(GetFairyId()); +} + +ARM u16 ActorNaviBase::vfunc_c8() { + if (mUnk_28d != 0) { + return 0x739c; + } + return func_ov000_020b87cc(GetFairyId()); +} + +ARM unk32 ActorNaviBase::vfunc_30() { + return 1; +} + +ARM s32 ActorNaviBase::vfunc_b8() { + return -1; +} + +ARM void ActorNaviBase::GetOffsetPos(Vec3p *pos) { + pos->x = mOffsetPos.x; + pos->y = mOffsetPos.y; + pos->z = mOffsetPos.z; +} + +ARM unk32 ActorNaviBase::vfunc_38() { + if (func_ov000_02087e8c()) { + return 0x22; + } + return 0x20; +} + +ARM void ActorNaviBase::vfunc_e4() { + this->vfunc_e0(); +} + +ARM void ActorNaviBase::vfunc_84() { + this->SetActive(5); +} + +ARM void ActorNaviBase::func_ov000_020bad18() { + mUnk_164 = 0; + if (mUnk_130 == 7) { + this->SetActive(5); + } +} + +ARM void ActorNaviBase::vfunc_80() { + this->func_ov000_020ba4e4(); + this->SetActive(8); +} + +ARM void ActorNaviBase::vfunc_d0() { + Vec3p linkPos; + GetLinkPos(&linkPos); + switch (mUnk_130) { + case 1: + mOffsetPos.x = linkPos.x; + mOffsetPos.y = linkPos.y; + mOffsetPos.z = linkPos.z; + mOffsetPos.y += 0x199a; + break; + case 6: + mOffsetPos.x = linkPos.x; + mOffsetPos.y = linkPos.y; + mOffsetPos.z = linkPos.z; + mOffsetPos.y += 0x800; + break; + } +} + +ARM void ActorNaviBase::vfunc_d8() {} +ARM void ActorNaviBase::vfunc_ec() {} + +ARM bool ActorNaviBase::vfunc_cc(unk32 *param1) {} +ARM void ActorNaviBase::func_ov000_020b8c50(unk32 param1) { + Vec3p tmp = mPos; + func_0202b2e8(&tmp, &mOffsetPos, param1); + Vec3p_Sub(&tmp, &mPos, &mVel); +} + +ARM void ActorNaviBase::func_ov000_020b8c98(unk32 param1, unk32 param2, unk32 param3) { + mVel.x = 0; + mVel.y = 0; + mVel.z = 0; + Vec3p tmp = mPos; + Lerp(&tmp.x, mOffsetPos.x, param1, param2, param3); + Lerp(&tmp.y, mOffsetPos.y, 0x400, 0, 0x7FFFFFFF); + Lerp(&tmp.z, mOffsetPos.z, param1, param2, param3); + Vec3p_Sub(&tmp, &mPos, &mVel); +} + +ARM void ActorNaviBase::vfunc_d4() {} +ARM void ActorNaviBase::SetActive(unk32 active) { + if (mUnk_130 == 0 && active != 0) { + u32 i; + UnkStruct_027e0e58 *inst; + ActorNaviBase_Unk1 *p; + mVisible = true; + mUnk_290 = 0; + i = 0; + p = &mUnk_218[0]; + do { + if (p->mUnk_0 == 0) { + inst = data_027e0e58; + func_ov000_0207c1f8(inst, p, sFairyModelIds[GetFairyId()], &mPos, 2); + } + i++; + p++; + } while (i < 2); + TeleportAboveLink(); + } + switch (active) { + case 0: { + ActorNaviBase_Unk1 *end; + ActorNaviBase_Unk1 *p; + mVisible = false; + p = mUnk_218; + end = mUnk_218 + 2; + if (p != end) { + do { + func_ov000_020b7e6c(p); + p++; + } while (p != end); + } + break; + } + case 1: { + mUnk_280 = -1; + mUnk_284 = -1; + TilePos tilePos = gMapManager->func_ov00_02083a1c(&mPos); + mUnk_288 = tilePos.x; + mUnk_289 = tilePos.y; + break; + } + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 9: + break; + case 8: + mUnk_28a = 0; + break; + } + mActiveFrames = 0; + mUnk_130 = active; +} +ARM void ActorNaviBase::TeleportAboveLink() { + Vec3p linkPos; + GetLinkPos(&linkPos); + linkPos.y += 0x800; + mPos.x = linkPos.x; + mPos.y = linkPos.y; + mPos.z = linkPos.z; + mPrevPos.x = linkPos.x; + mPrevPos.y = linkPos.y; + mPrevPos.z = linkPos.z; +} + +ARM void ActorNaviBase::vfunc_e0() {} +ARM void ActorNaviBase::func_ov000_020b9770(s32 param1) { + void *resource = func_0201e544(data_ov000_020e678c[8], sNaviNames[param1].name); + func_ov000_020c0cc8(&mUnk_1d0, resource, 0, sNaviNames[param1].id); + mUnk_168.vfunc_28(); + mUnk_168.vfunc_24(&mUnk_1d0); +} +ARM void ActorNaviBase::vfunc_e8() { + switch (mUnk_130) { + case 4: + case 7: + if (mUnk_130 == 7 && XzDistanceTo(&mOffsetPos) <= 0x20) { + mUnk_1d0.mUnk_0c.mUnk_04 = 0x1800; + } else { + s32 factor = CoDivide64By32(XzDistanceToLink(), 0x4000); + if (factor > 0x1000) { + factor = 0x1000; + } else if (factor < 0) { + factor = 0; + } + mUnk_1d0.mUnk_0c.mUnk_04 = MUL_Q20(factor, 0x800) + 0x1000; + } + break; + case 5: + break; + case 8: + switch (mUnk_28a) { + case 1: + mUnk_1d0.mUnk_0c.mUnk_04 = 0x2000; + break; + case 3: { + u16 angle = (u16) (mActiveFrames * 0xaab); + mUnk_1d0.mUnk_0c.mUnk_04 = 0x1800 - MUL_Q20(SIN(angle), 0x800); + break; + } + case 2: + if ((s32) mVel.y >= 0) { + mUnk_1d0.mUnk_0c.mUnk_04 = 0xb33; + } else { + func_ov000_020c0e24(&mUnk_1d0, 0); + mUnk_1d0.mUnk_0c.mUnk_04 = 0; + } + break; + default: + mUnk_1d0.mUnk_0c.mUnk_04 = 0x1000; + break; + } + break; + default: + mUnk_1d0.mUnk_0c.mUnk_04 = 0x1000; + break; + } + mUnk_1d0.func_ov000_020c0e04(); +} + +ARM void ActorNaviBase::vfunc_14(u32 param1) {} + +ARM void ActorNaviBase::vfunc_18(u32 param1) {} +ARM void ActorNaviBase::func_ov000_020b9fdc() { + this->func_ov000_020b9fe8(); +} + +ARM void ActorNaviBase::func_ov000_020b9fe8() { + u16 color1 = this->vfunc_c4(); + u16 color2 = this->vfunc_c8(); + func_ov000_020b8830(data_ov000_020ee1f8, color1, color2); + + unk32 colorResult = data_ov000_020e9360.func_ov000_02079e68(2); + func_02019534(data_ov000_020ee1f8, 0, colorResult); + + Vec3p pos; + Vec3p scale; + pos.x = mPos.x; + pos.y = mPos.y - func_ov000_020b3ec4(&mUnk_168); + pos.z = mPos.z; + + if (mUnk_164 == 0) { + scale.x = 0xe66; + scale.y = 0xe66; + scale.z = 0xe66; + } else { + scale.x = 0x119a; + scale.y = 0x119a; + scale.z = 0x119a; + } + mUnk_168.SetTransform(&scale, &gDefaultMatrix, &pos); +} +ARM void ActorNaviBase::vfunc_20(bool param1) {} +ARM void ActorNaviBase::vfunc_10(u32 param1) { + if (mUnk_130 == 0 && gItemManager->GetEquippedFairy() == GetFairyId()) { + this->SetActive(1); + return; + } + this->TeleportAboveLink(); + if (this->vfunc_cc(NULL)) { + this->SetActive(0); + } +} + unk32 ActorNaviBase::func_ov000_020ba204(Vec3p *param1, Vec3p *param2, s32 param3) {} -unk32 func_ov000_020ba350(unk32 param1) {} -bool ActorNaviBase::vfunc_c0(Vec3p *param1) {} -unk32 ActorNaviBase::func_ov000_020ba3b4() {} -void ActorNaviBase::func_ov000_020ba414(Vec3p *param1) {} -bool ActorNaviBase::func_ov000_020ba458() {} -void ActorNaviBase::func_ov000_020ba4e4() {} -void ActorNaviBase::func_ov000_020ba53c() {} -void ActorNaviBase::vfunc_80() {} -void ActorNaviBase::vfunc_84() {} +ARM unk32 func_ov000_020ba350(unk32 param1) { + ((UnkStruct_ov000_020beba8 *) param1)->UnkStruct_ov000_020beba8::~UnkStruct_ov000_020beba8(); + return param1; +} +ARM bool ActorNaviBase::vfunc_c0(Vec3p *param1) { + mOffsetPos.x = param1->x; + mOffsetPos.y = param1->y; + mOffsetPos.z = param1->z; + if (mUnk_130 != 4) { + u32 oldState = mUnk_130; + this->SetActive(4); + return oldState != 5; + } + return false; +} +ARM unk32 ActorNaviBase::func_ov000_020ba3b4() { + if (gItemManager->GetEquippedFairy() == GetFairyId()) { + this->SetActive(1); + } else { + this->SetActive(6); + } + return 1; +} + +ARM void ActorNaviBase::func_ov000_020ba414(Vec3p *param1) { + Cylinder cyl; + gPlayer->vfunc_10(&cyl); + Vec3p_Add(param1, &cyl.pos, &mOffsetPos); +} + +ARM bool ActorNaviBase::func_ov000_020ba458() { + if (gItemManager->GetEquippedFairy() == GetFairyId() && !this->vfunc_cc(NULL) && mUnk_130 != 8 && mUnk_130 != 9) { + this->SetActive(5); + this->func_ov000_020ba53c(); + return true; + } + return false; +} + +ARM void ActorNaviBase::func_ov000_020ba4e4() { + Vec3p tmp = data_ov000_020dc83c; + s16 angle = *(s16 *) &gPlayerAngle; + if (angle < 0) { + tmp.x = -tmp.x; + } + Vec3p_RotateY(angle, &tmp); + func_ov000_020ba414(&tmp); +} + +ARM void ActorNaviBase::func_ov000_020ba53c() { + Vec3p tmp = data_ov000_020dc848; + s16 angle = *(s16 *) &gPlayerAngle; + if ((angle > 0 && angle < 0x4000) || angle < -0x4000) { + tmp.x = -tmp.x; + } + Vec3p_RotateY(angle, &tmp); + func_ov000_020ba414(&tmp); +} bool ActorNaviBase::vfunc_78() {} -bool ActorNaviBase::vfunc_bc(unk32 param1, unk8 param2, s32 param3) {} +ARM bool ActorNaviBase::vfunc_bc(unk32 param1, unk8 param2, s32 param3) {} void ActorNaviBase::vfunc_74() {} -void ActorNaviBase::func_ov000_020baca8(Vec3p *param1, unk32 param2) {} -void ActorNaviBase::func_ov000_020bad18() {} +ARM void ActorNaviBase::func_ov000_020baca8(Vec3p *param1, unk32 param2) { + if (*(u8 *) &mUnk_11c != 0 || mUnk_291 != 0) { + return; + } + if (gPlayerLink->GetCurrentCharacter() != 0) { + return; + } + mOffsetPos.x = param1->x; + mOffsetPos.y = param1->y; + mOffsetPos.z = param1->z; + mUnk_164 = param2; + this->SetActive(7); +} bool ActorNaviBase::vfunc_90() {} void ActorNaviBase::vfunc_94() {} -void ActorNaviBase::func_ov000_020bb0ac() {} -void ActorNaviBase::func_ov000_020bb0e0() {} -void ActorNaviBase::vfunc_ec() {} +ARM void ActorNaviBase::func_ov000_020bb0ac() { + for (s32 i = 0; i < FairyId_COUNT; i++) { + gItemManager->GetFairy(i)->mUnk_290 = 1; + } +} + +ARM void ActorNaviBase::func_ov000_020bb0e0() { + for (s32 i = 0; i < FairyId_COUNT; i++) { + gItemManager->GetFairy(i)->mUnk_290 = 0; + } +}