diff --git a/data/file_list.yml b/data/file_list.yml index 508e44aa..faa6668b 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -91289,54 +91289,52 @@ MapObj/WorldMapParts.o: size: 28 label: _ZN13WorldMapParts11setLocalMtxERKN4sead8Matrix34IfEE status: Matching -MapObj/WorldMapPartsFloat.o: - '.text': - offset: 0x34bb5c size: 332 label: _ZN18WorldMapPartsFloatC2EPKcRKN4sead7Vector3IfEEif - status: NotDecompiled + status: Matching - offset: 0x34bca8 size: 316 label: _ZN18WorldMapPartsFloatC1EPKcRKN4sead7Vector3IfEEif - status: NotDecompiled + status: Matching - offset: 0x34bde4 size: 288 label: _ZN18WorldMapPartsFloat7controlEv - status: NotDecompiled + status: Matching - offset: 0x34bf04 size: 88 label: _ZN18WorldMapPartsFloat11setLocalMtxERKN4sead8Matrix34IfEE - status: NotDecompiled + status: Matching MapObj/WorldMapPlayerIcon.o: '.text': - offset: 0x34bf5c size: 292 label: _ZN18WorldMapPlayerIcon6createEPKcRKN2al13ActorInitInfoEPKN4sead8Matrix34IfEE - status: NotDecompiled + status: Matching - offset: 0x34c080 size: 148 label: _ZN18WorldMapPlayerIconC1EPKc - status: NotDecompiled + status: Matching - offset: 0x34c114 size: 136 label: _ZN18WorldMapPlayerIconC2EPKc - status: NotDecompiled + status: Matching - offset: 0x34c19c size: 88 label: _ZN18WorldMapPlayerIcon8movementEv - status: NotDecompiled + status: Matching - offset: 0x34c1f4 size: 108 - label: '' - status: NotDecompiled + label: _ZL17movementRecursivePN2al9LiveActorE + status: Matching - offset: 0x34c260 size: 88 label: _ZN18WorldMapPlayerIcon8calcAnimEv - status: NotDecompiled + status: Matching - offset: 0x34c2b8 size: 108 - label: '' - status: NotDecompiled + label: _ZL17calcAnimRecursivePN2al9LiveActorE + status: Matching MapObj/WorldMapRoute.o: '.text': - offset: 0x34c324 diff --git a/src/MapObj/ShineTowerRocket.h b/src/MapObj/ShineTowerRocket.h index c769d5e8..c964fc66 100644 --- a/src/MapObj/ShineTowerRocket.h +++ b/src/MapObj/ShineTowerRocket.h @@ -19,7 +19,7 @@ void setupHomeMeter(al::LiveActor*); void setupHomeMeterFitherParam(al::LiveActor*, ShineTowerCommonKeeper*); void setupHomeSticker(al::LiveActor*); void setupHomeCompLight(al::LiveActor*); -void getHomeArchiveName(const al::LiveActor*); +const char* getHomeArchiveName(const al::LiveActor*); } // namespace rs class ShineTowerRocket : public al::LiveActor, diff --git a/src/MapObj/WorldMapParts.cpp b/src/MapObj/WorldMapParts.cpp index c9c73463..b9ebdd02 100644 --- a/src/MapObj/WorldMapParts.cpp +++ b/src/MapObj/WorldMapParts.cpp @@ -1,10 +1,13 @@ #include "MapObj/WorldMapParts.h" +#include + #include "Library/LiveActor/ActorInitUtil.h" #include "Library/LiveActor/ActorModelFunction.h" #include "Library/LiveActor/ActorPoseUtil.h" #include "Library/LiveActor/LiveActorFunction.h" #include "Library/Math/MathUtil.h" +#include "Library/Matrix/MatrixUtil.h" void recursivelyInvalidateOcclusionQuery(al::LiveActor* actor) { al::invalidateOcclusionQuery(actor); @@ -65,3 +68,22 @@ WorldMapParts* WorldMapParts::create(const char* name, const char* arcName, return newParts; } + +WorldMapPartsFloat::WorldMapPartsFloat(const char* name, const sead::Vector3f& offset, s32 period, + f32 amplitude) + : WorldMapParts(name), mFloatOffset(offset), mPeriod(period), mAmplitude(amplitude) {} + +void WorldMapPartsFloat::control() { + s32 frameCount = mFrameCount++; + f32 sinVal = sead::Mathf::sin((f32)(frameCount) / (f32)mPeriod * sead::Mathf::pi2()); + mLocalMtx.setTranslation(mTranslation + sinVal * mUpDir * mAmplitude); + updatePose(); +} + +void WorldMapPartsFloat::setLocalMtx(const sead::Matrix34f& srcMtx) { + al::addTransMtxLocalOffset(&mLocalMtx, srcMtx, mFloatOffset); + + mTranslation = mLocalMtx.getTranslation(); + + mUpDir = mLocalMtx.getBase(1); +} diff --git a/src/MapObj/WorldMapParts.h b/src/MapObj/WorldMapParts.h index edf8f41e..6c093bda 100644 --- a/src/MapObj/WorldMapParts.h +++ b/src/MapObj/WorldMapParts.h @@ -21,7 +21,27 @@ public: const al::ActorInitInfo& initInfo, const sead::Matrix34f* worldMtx, const sead::Matrix34f& localMtx, const char* suffix); -private: +protected: const sead::Matrix34f* mWorldMtx = nullptr; sead::Matrix34f mLocalMtx = sead::Matrix34f::ident; }; + +static_assert(sizeof(WorldMapParts) == 0x140); + +class WorldMapPartsFloat : public WorldMapParts { +public: + WorldMapPartsFloat(const char* name, const sead::Vector3f& offset, s32 period, f32 amplitude); + + void control() override; + void setLocalMtx(const sead::Matrix34f& srcMtx) override; + +private: + sead::Vector3f mTranslation = sead::Vector3f::zero; + sead::Vector3f mUpDir = sead::Vector3f::ey; + sead::Vector3f mFloatOffset; + s32 mFrameCount = 0; + s32 mPeriod; + f32 mAmplitude; +}; + +static_assert(sizeof(WorldMapPartsFloat) == 0x170); diff --git a/src/MapObj/WorldMapPlayerIcon.cpp b/src/MapObj/WorldMapPlayerIcon.cpp new file mode 100644 index 00000000..ccc04ae7 --- /dev/null +++ b/src/MapObj/WorldMapPlayerIcon.cpp @@ -0,0 +1,51 @@ +#include "MapObj/WorldMapPlayerIcon.h" + +#include "Library/LiveActor/ActorActionFunction.h" +#include "Library/LiveActor/ActorInitFunction.h" +#include "Library/LiveActor/LiveActorFunction.h" + +#include "MapObj/ShineTowerRocket.h" + +static void movementRecursive(al::LiveActor* actor) { + actor->movement(); + if (al::isExistSubActorKeeper(actor)) + for (s32 i = 0; i < al::getSubActorNum(actor); i++) + movementRecursive(al::getSubActor(actor, i)); +} + +static void calcAnimRecursive(al::LiveActor* actor) { + actor->calcAnim(); + if (al::isExistSubActorKeeper(actor)) + for (s32 i = 0; i < al::getSubActorNum(actor); i++) + calcAnimRecursive(al::getSubActor(actor, i)); +} + +static const sead::Vector3f sFloatOffset = {0.0f, 20.0f, 0.0f}; + +WorldMapPlayerIcon* WorldMapPlayerIcon::create(const char* name, const al::ActorInitInfo& initInfo, + const sead::Matrix34f* worldMtx) { + WorldMapPlayerIcon* icon = new WorldMapPlayerIcon(name); + al::initActorSceneInfo(icon, initInfo); + const char* arcName = rs::getHomeArchiveName(icon); + initParts(icon, arcName, initInfo, worldMtx, sead::Matrix34f::ident, "WorldMap"); + al::startAction(icon, "WaitWorldMap"); + al::startAction(al::getSubActor(icon, "旗"), "After"); + rs::setupHomeMeter(icon); + rs::setupHomeSticker(icon); + return icon; +} + +WorldMapPlayerIcon::WorldMapPlayerIcon(const char* name) + : WorldMapPartsFloat(name, sFloatOffset, 360, 10.0f) {} + +void WorldMapPlayerIcon::movement() { + al::LiveActor::movement(); + for (s32 i = 0; i < al::getSubActorNum(this); i++) + movementRecursive(al::getSubActor(this, i)); +} + +void WorldMapPlayerIcon::calcAnim() { + al::LiveActor::calcAnim(); + for (s32 i = 0; i < al::getSubActorNum(this); i++) + calcAnimRecursive(al::getSubActor(this, i)); +} diff --git a/src/MapObj/WorldMapPlayerIcon.h b/src/MapObj/WorldMapPlayerIcon.h new file mode 100644 index 00000000..5e8cc3ab --- /dev/null +++ b/src/MapObj/WorldMapPlayerIcon.h @@ -0,0 +1,20 @@ +#pragma once + +#include "MapObj/WorldMapParts.h" + +namespace al { +struct ActorInitInfo; +} + +class WorldMapPlayerIcon : public WorldMapPartsFloat { +public: + static WorldMapPlayerIcon* create(const char* name, const al::ActorInitInfo& initInfo, + const sead::Matrix34f* worldMtx); + + WorldMapPlayerIcon(const char* name); + + void movement() override; + void calcAnim() override; +}; + +static_assert(sizeof(WorldMapPlayerIcon) == 0x170);