diff --git a/data/file_list.yml b/data/file_list.yml index b34e58c11f..27c616fa36 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -50519,7 +50519,7 @@ Item/ShineChipWatcher.o: status: NotDecompiled - offset: 0x1d5898 size: 4 - label: _ZNK12_GLOBAL__N_119HostTypeNrvComplete7executeEPN2al11NerveKeeperE + label: '#_ZNK12_GLOBAL__N_119HostTypeNrvComplete7executeEPN2al11NerveKeeperE' status: NotDecompiled guess: true - offset: 0x1d589c @@ -107181,197 +107181,197 @@ Npc/SessionMusicianLocalFunction.o: - offset: 0x3c2284 size: 136 label: _ZN28SessionMusicianLocalFunction15getMusicianTypeEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c230c size: 160 label: _ZN28SessionMusicianLocalFunction14isMusicianTypeEPKN2al9LiveActorE19SessionMusicianType - status: NotDecompiled + status: Matching - offset: 0x3c23ac size: 48 label: _ZN28SessionMusicianLocalFunction12isSubscribedEPKN2al9LiveActorE19SessionMusicianType - status: NotDecompiled + status: Matching - offset: 0x3c23dc size: 80 label: _ZN28SessionMusicianLocalFunction22isAlreadySessionMemberEPK18SessionMusicianNpc - status: NotDecompiled + status: Matching - offset: 0x3c242c size: 48 label: _ZN28SessionMusicianLocalFunction22entryMusicianToManagerEP18SessionMusicianNpc - status: NotDecompiled + status: Matching - offset: 0x3c245c size: 228 label: _ZN28SessionMusicianLocalFunction20getMemberMusicianNumEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c2540 size: 64 label: _ZN28SessionMusicianLocalFunction19isSessionFullMemberEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c2580 size: 32 label: _ZN28SessionMusicianLocalFunction17startPlayingTheBaEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c25a0 size: 32 label: _ZN28SessionMusicianLocalFunction17startPlayingTheDsEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c25c0 size: 32 label: _ZN28SessionMusicianLocalFunction17startPlayingTheGtEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c25e0 size: 32 label: _ZN28SessionMusicianLocalFunction17startPlayingTheTpEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c2600 size: 28 label: _ZN28SessionMusicianLocalFunction15endPlayingTheBaEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c261c size: 28 label: _ZN28SessionMusicianLocalFunction15endPlayingTheDsEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c2638 size: 28 label: _ZN28SessionMusicianLocalFunction15endPlayingTheGtEPKN2al9LiveActorE - status: NotDecompiled + status: Matching - offset: 0x3c2654 size: 28 label: _ZN28SessionMusicianLocalFunction15endPlayingTheTpEPKN2al9LiveActorE - status: NotDecompiled + status: Matching Npc/SessionMusicianManager.o: '.text': - offset: 0x3c2670 size: 168 label: _ZN22SessionMusicianManagerC2EPKc - status: NotDecompiled + status: Matching - offset: 0x3c2718 size: 164 label: _ZN22SessionMusicianManagerC1EPKc - status: NotDecompiled + status: Matching - offset: 0x3c27bc size: 200 label: _ZN22SessionMusicianManager26initAfterPlacementSceneObjERKN2al13ActorInitInfoE - status: NotDecompiled + status: Matching - offset: 0x3c2884 size: 8 label: _ZThn264_N22SessionMusicianManager26initAfterPlacementSceneObjERKN2al13ActorInitInfoE - status: NotDecompiled + status: Matching - offset: 0x3c288c size: 44 label: _ZN22SessionMusicianManager13entryMusicianEP18SessionMusicianNpc - status: NotDecompiled + status: Matching - offset: 0x3c28b8 size: 84 label: _ZNK22SessionMusicianManager16isJoinedMusicianEv - status: NotDecompiled + status: Matching - offset: 0x3c290c size: 88 label: _ZNK22SessionMusicianManager17getJoinedMusicianEv - status: NotDecompiled + status: Matching - offset: 0x3c2964 size: 116 label: _ZNK22SessionMusicianManager12isSubscribedE19SessionMusicianType - status: NotDecompiled + status: Matching - offset: 0x3c29d8 size: 184 label: _ZN22SessionMusicianManager19tryAppearPowerPlantEv - status: NotDecompiled + status: Matching - offset: 0x3c2a90 size: 92 label: _ZNK22SessionMusicianManager14findPowerPlantEv - status: NotDecompiled + status: Matching - offset: 0x3c2aec size: 152 label: _ZN22SessionMusicianManager12tryStartWarpEPN2al13PlacementInfoE - status: NotDecompiled + status: Matching - offset: 0x3c2b84 size: 72 label: _ZN22SessionMusicianManager19addDemoAllMusiciansEv - status: NotDecompiled + status: Matching - offset: 0x3c2bcc size: 216 label: _ZN22SessionMusicianManager7exeWaitEv - status: NotDecompiled + status: Matching - offset: 0x3c2ca4 size: 16 label: _ZN22SessionMusicianManager11exeCompleteEv - status: NotDecompiled + status: Matching - offset: 0x3c2cb4 size: 232 label: _ZN28SessionMusicianLocalFunction31tryCreateSessionMusicianManagerEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c2d9c size: 36 label: _ZN28SessionMusicianLocalFunction25getSessionMusicianManagerEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c2dc0 size: 8 label: _ZN28SessionMusicianLocalFunction29isExistSessionMusicianManagerEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c2dc8 size: 188 label: _ZN28SessionMusicianLocalFunction26tryStartWarpToSessionMayorEPKN2al18IUseSceneObjHolderEPNS0_13PlacementInfoE - status: NotDecompiled + status: Matching - offset: 0x3c2e84 size: 64 label: _ZN28SessionMusicianLocalFunction26entrySessionMayorToManagerEP15SessionMayorNpc - status: NotDecompiled + status: Matching - offset: 0x3c2ec4 size: 108 label: _ZN28SessionMusicianLocalFunction23isJoinedSessionMusicianEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c2f30 size: 112 label: _ZN28SessionMusicianLocalFunction31tryGetJoinedSessionMusicanActorEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c2fa0 size: 220 label: _ZN28SessionMusicianLocalFunction36tryAddJoinedSessionMusicianDemoActorEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c307c size: 160 label: _ZN28SessionMusicianLocalFunction33tryGetSessionMoonGetDemoPlayerPosEPN4sead7Vector3IfEEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c311c size: 168 label: _ZN28SessionMusicianLocalFunction34tryGetSessionMoonGetDemoPlayerPoseEPN4sead4QuatIfEEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c31c4 size: 152 label: _ZN28SessionMusicianLocalFunction50trySetJoinedSessionMusicianTransformForMoonGetDemoEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c325c size: 88 label: _ZN28SessionMusicianLocalFunction19addDemoAllMusiciansEPKN2al18IUseSceneObjHolderE - status: NotDecompiled + status: Matching - offset: 0x3c32b4 size: 4 label: _ZN22SessionMusicianManagerD1Ev - status: NotDecompiled + status: Matching lazy: true - offset: 0x3c32b8 size: 4 label: _ZN22SessionMusicianManagerD0Ev - status: NotDecompiled + status: Matching lazy: true - offset: 0x3c32bc size: 4 label: _ZThn264_N22SessionMusicianManagerD1Ev - status: NotDecompiled + status: Matching lazy: true - offset: 0x3c32c0 size: 8 label: _ZThn264_N22SessionMusicianManagerD0Ev - status: NotDecompiled + status: Matching lazy: true - offset: 0x3c32c8 size: 8 - label: '' + label: '#_ZNK12_GLOBAL__N_115HostTypeNrvWait7executeEPN2al11NerveKeeperE' status: NotDecompiled - offset: 0x3c32d0 size: 20 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_119HostTypeNrvComplete7executeEPN2al11NerveKeeperE + status: Matching Npc/SessionMusicianNpc.o: '.text': - offset: 0x3c32e4 diff --git a/lib/al/Library/Event/IEventFlowQueryJudge.h b/lib/al/Library/Event/IEventFlowQueryJudge.h new file mode 100644 index 0000000000..20608be7cc --- /dev/null +++ b/lib/al/Library/Event/IEventFlowQueryJudge.h @@ -0,0 +1,11 @@ +#pragma once + +namespace al { +class EventFlowEventData; + +class IEventFlowQueryJudge { +public: + virtual const char* judgeQuery(const char*) const = 0; +}; + +} // namespace al diff --git a/src/Npc/SessionMayorNpc.h b/src/Npc/SessionMayorNpc.h new file mode 100644 index 0000000000..0c5ac2fca7 --- /dev/null +++ b/src/Npc/SessionMayorNpc.h @@ -0,0 +1,58 @@ +#pragma once + +#include + +#include "Library/Event/IEventFlowEventReceiver.h" +#include "Library/LiveActor/LiveActor.h" +#include "Library/Scene/DemoDirector.h" + +namespace al { +class EventFlowExecutor; +class IEventFlowEventReceiver; +class JointSpringControllerHolder; +class PlacementId; +} // namespace al + +struct SessionMayorParam; +class NpcJointLookAtController; +class NpcStateReaction; +class RandomWaitActionUpdater; +class SessionMusicianNpc; +class TalkNpcActionAnimInfo; +class TalkNpcParam; + +class SessionMayorNpc : public al::LiveActor, public al::IEventFlowEventReceiver { +public: + SessionMayorNpc(const char* name) : al::LiveActor(name) {} + + void init(const al::ActorInitInfo& initInfo); + + void movement(); + void attackSensor(al::HitSensor* self, al::HitSensor* other); + + void initIntroductionCamera(const al::ActorInitInfo& initInfo, + sead::PtrArray* musicians); + + bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other, al::HitSensor* self); + bool receiveEvent(const al::EventFlowEventData* event); + + bool tryAppearMemberMusicians(); + + void exeWait(); + void exeReaction(); + +private: + al::EventFlowExecutor* mEventFlowExecutor; + sead::PtrArray mMusicians; + SessionMayorParam* mMayorParam; + TalkNpcParam* mTalkNpcParam; + al::PlacementId* mPlacementId; + NpcStateReaction* mNpcStateReaction; + NpcJointLookAtController* mNpcJointLookAtController; + al::JointSpringControllerHolder* mJointSpringControllerHolder; + al::AddDemoInfo* mDemoInfo; + TalkNpcActionAnimInfo* mTalkNpcActionAnimInfo; + RandomWaitActionUpdater* mRandomWaitActionUpdater; +}; + +static_assert(sizeof(SessionMayorNpc) == 0x170); diff --git a/src/Npc/SessionMusicianLocalFunction.cpp b/src/Npc/SessionMusicianLocalFunction.cpp new file mode 100644 index 0000000000..2b46a83cca --- /dev/null +++ b/src/Npc/SessionMusicianLocalFunction.cpp @@ -0,0 +1,99 @@ +#include "Npc/SessionMusicianLocalFunction.h" + +#include "Library/Bgm/BgmLineFunction.h" +#include "Library/LiveActor/ActorClippingFunction.h" +#include "Library/LiveActor/ActorFlagFunction.h" +#include "Library/LiveActor/ActorMovementFunction.h" +#include "Library/LiveActor/LiveActor.h" +#include "Library/LiveActor/LiveActorFunction.h" +#include "Library/Scene/SceneObjUtil.h" + +#include "Npc/SessionMusicianManager.h" +#include "System/GameDataFunction.h" +#include "System/GameDataHolderAccessor.h" + +namespace SessionMusicianLocalFunction { + +SessionMusicianType getMusicianType(const al::LiveActor* actor) { + if (al::tryGetSubActor(actor, "ドラム")) + return SessionMusicianType::Drum; + if (al::tryGetSubActor(actor, "ベース")) + return SessionMusicianType::Bass; + if (al::tryGetSubActor(actor, "ギター")) + return SessionMusicianType::Guitar; + if (al::tryGetSubActor(actor, "トランペット")) + return SessionMusicianType::Trumpet; + + return SessionMusicianType::Vocal; +} + +bool isMusicianType(const al::LiveActor* actor, SessionMusicianType type) { + return (u32)getMusicianType(actor) == (u32)type; +} + +bool isSubscribed(const al::LiveActor* actor, SessionMusicianType type) { + return getSessionMusicianManager(actor)->isSubscribed(type); +} + +bool isAlreadySessionMember(const SessionMusicianNpc* musician) { + if (al::isAlive(musician)) + return false; + + return GameDataFunction::isGotShine(musician, musician->getLinkedShineIndex()); +} + +void entryMusicianToManager(SessionMusicianNpc* musician) { + getSessionMusicianManager(musician)->entryMusician(musician); +} + +bool isSessionFullMember(const al::LiveActor* actor) { + return (SessionEventProgress::Wait4thMusician < + GameDataFunction::getSessionEventProgress(actor)); +} + +s32 getMemberMusicianNum(const al::LiveActor* actor) { + if (isSubscribed(actor, SessionMusicianType::Vocal)) + return SessionMusicianType::size(); + + s32 count = 0; + + for (s32 i = 0; i < SessionMusicianType::size(); ++i) + if (isSubscribed(actor, i)) + count++; + + return count; +} + +void startPlayingTheBa(const al::LiveActor* actor) { + al::startBgmSituation(actor, "PlayTheBa", false, true); +} + +void startPlayingTheDs(const al::LiveActor* actor) { + al::startBgmSituation(actor, "PlayTheDs", false, true); +} + +void startPlayingTheGt(const al::LiveActor* actor) { + al::startBgmSituation(actor, "PlayTheGt", false, true); +} + +void startPlayingTheTp(const al::LiveActor* actor) { + al::startBgmSituation(actor, "PlayTheTp", false, true); +} + +void endPlayingTheBa(const al::LiveActor* actor) { + al::endBgmSituation(actor, "PlayTheBa", false); +} + +void endPlayingTheDs(const al::LiveActor* actor) { + al::endBgmSituation(actor, "PlayTheDs", false); +} + +void endPlayingTheGt(const al::LiveActor* actor) { + al::endBgmSituation(actor, "PlayTheGt", false); +} + +void endPlayingTheTp(const al::LiveActor* actor) { + al::endBgmSituation(actor, "PlayTheTp", false); +} + +} // namespace SessionMusicianLocalFunction diff --git a/src/Npc/SessionMusicianManager.cpp b/src/Npc/SessionMusicianManager.cpp new file mode 100644 index 0000000000..1d4ea7a7cd --- /dev/null +++ b/src/Npc/SessionMusicianManager.cpp @@ -0,0 +1,225 @@ +#include "Npc/SessionMusicianManager.h" + +#include "Library/LiveActor/ActorClippingFunction.h" +#include "Library/LiveActor/ActorFlagFunction.h" +#include "Library/LiveActor/ActorInitFunction.h" +#include "Library/LiveActor/ActorInitUtil.h" +#include "Library/LiveActor/ActorMovementFunction.h" +#include "Library/Nerve/NerveSetupUtil.h" +#include "Library/Nerve/NerveUtil.h" +#include "Library/Scene/SceneObjUtil.h" + +#include "Npc/SessionMayorNpc.h" +#include "Npc/SessionMusicianBgmController.h" +#include "Npc/SessionMusicianLocalFunction.h" +#include "Npc/SessionMusicianNpc.h" +#include "Npc/SessionMusicianType.h" +#include "Npc/SessionMusicianWarpAgent.h" +#include "System/GameDataFunction.h" +#include "System/GameDataHolderAccessor.h" +#include "Util/DemoUtil.h" + +namespace { +NERVE_HOST_TYPE_IMPL(SessionMusicianManager, Wait); +NERVE_HOST_TYPE_IMPL(SessionMusicianManager, Complete); + +NERVES_MAKE_NOSTRUCT(HostType, Wait, Complete); +} // namespace + +SessionMusicianManager::SessionMusicianManager(const char* name) : al::LiveActor(name) { + mMusicianPtrArray.allocBuffer(7, nullptr); +} + +void SessionMusicianManager::initAfterPlacementSceneObj(const al::ActorInitInfo& info) { + al::initActorSceneInfo(this, info); + al::initActorWithArchiveName(this, info, "SessionMusicianManager", nullptr); + al::initNerve(this, &Wait, 0); + al::initActorSeKeeperWithout3D(this, info, "SessionMusicianManager"); + if (mMayorNpc != nullptr) { + mMayorNpc->initIntroductionCamera(info, &mMusicianPtrArray); + mBgmController = new SessionMusicianBgmController(this, info, false); + } + makeActorAlive(); + return; +} + +void SessionMusicianManager::entryMusician(SessionMusicianNpc* musician) { + if (mMusicianPtrArray.isFull()) + return; + + mMusicianPtrArray.pushBack(musician); +} + +bool SessionMusicianManager::isJoinedMusician() const { + for (auto it = mMusicianPtrArray.begin(); it != mMusicianPtrArray.end(); ++it) + if (it->isJoined()) + return true; + + return false; +} + +SessionMusicianNpc* SessionMusicianManager::getJoinedMusician() const { + for (auto it = mMusicianPtrArray.begin(); it != mMusicianPtrArray.end(); ++it) + if (it->isJoined()) + return &(*it); + + return nullptr; +} + +bool SessionMusicianManager::isSubscribed(SessionMusicianType type) const { + for (auto it = mMusicianPtrArray.begin(); it != mMusicianPtrArray.end(); ++it) { + if (SessionMusicianLocalFunction::isMusicianType(&(*it), type)) { + if (SessionMusicianLocalFunction::isAlreadySessionMember(&(*it))) + return true; + } + } + + return false; +} + +bool SessionMusicianManager::tryAppearPowerPlant() { + SessionMusicianNpc* musician = findPowerPlant(); + + if (!musician) + return false; + + if (al::isAlive(musician) || GameDataFunction::getSessionEventProgress(this) < + SessionEventProgress::WaitThePowerPlantWorks) + return false; + + musician->appear(); + return true; +} + +SessionMusicianNpc* SessionMusicianManager::findPowerPlant() const { + for (auto it = mMusicianPtrArray.begin(); it != mMusicianPtrArray.end(); ++it) { + SessionMusicianType type = SessionMusicianLocalFunction::getMusicianType(&(*it)); + if (type == SessionMusicianType::Vocal) + return &(*it); + } + + return nullptr; +} + +bool SessionMusicianManager::tryStartWarp(al::PlacementInfo* info) { + for (auto it = mMusicianPtrArray.begin(); it != mMusicianPtrArray.end(); ++it) { + if (it->isStateWarp()) { + SessionMusicianWarpAgent* warpAgent = it->getWarpAgent(); + if (warpAgent->tryGetWarpTargetInfo(info) && warpAgent->tryStartWarp()) { + it->doneWarp(); + al::invalidateClipping(mMayorNpc); + return true; + } + } + } + + return false; +} + +void SessionMusicianManager::addDemoAllMusicians() { + for (auto it = mMusicianPtrArray.begin(); it != mMusicianPtrArray.end(); ++it) + rs::addDemoActor(&(*it), 1); +} + +void SessionMusicianManager::exeWait() { + if (mBgmController) + mBgmController->updateNerve(); + + if (!(SessionMusicianLocalFunction::getMemberMusicianNum(this) <= 4)) + al::setNerve(this, &Complete); + else + tryAppearPowerPlant(); +} + +void SessionMusicianManager::exeComplete() { + if (mBgmController != nullptr) + mBgmController->updateNerve(); +} + +namespace SessionMusicianLocalFunction { + +void tryCreateSessionMusicianManager(const al::IUseSceneObjHolder* holder) { + if (al::isExistSceneObj(holder, SessionMusicianManager::sSceneObjId)) + return; + + SessionMusicianManager* manager = new SessionMusicianManager("SessionMusicianManager"); + al::setSceneObj(holder, manager, SessionMusicianManager::sSceneObjId); +} + +SessionMusicianManager* getSessionMusicianManager(const al::IUseSceneObjHolder* holder) { + return al::tryGetSceneObj(holder); +} + +bool isExistSessionMusicianManager(const al::IUseSceneObjHolder* holder) { + return al::isExistSceneObj(holder, SessionMusicianManager::sSceneObjId); +} + +bool tryStartWarpToSessionMayor(const al::IUseSceneObjHolder* holder, al::PlacementInfo* info) { + if (!al::isExistSceneObj(holder)) + return false; + + return getSessionMusicianManager(holder)->tryStartWarp(info); +} + +void entrySessionMayorToManager(SessionMayorNpc* mayor) { + getSessionMusicianManager(mayor)->entryMayor(mayor); +} + +bool isJoinedSessionMusician(const al::IUseSceneObjHolder* holder) { + SessionMusicianManager* manager = getSessionMusicianManager(holder); + return manager && manager->isJoinedMusician(); +} + +SessionMusicianNpc* tryGetJoinedSessionMusicanActor(const al::IUseSceneObjHolder* holder) { + SessionMusicianManager* manager = getSessionMusicianManager(holder); + if (!manager) + return nullptr; + + return manager->getJoinedMusician(); +} + +bool tryAddJoinedSessionMusicianDemoActor(const al::IUseSceneObjHolder* holder) { + SessionMusicianNpc* musician = tryGetJoinedSessionMusicanActor(holder); + if (!musician) + return false; + + rs::addDemoActor(musician, true); + musician->addDemoActors(); + return true; +} + +bool tryGetSessionMoonGetDemoPlayerPos(sead::Vector3f* pos, const al::IUseSceneObjHolder* holder) { + SessionMusicianNpc* musician = tryGetJoinedSessionMusicanActor(holder); + if (!musician) + return false; + + pos->set(musician->getMoonGetDemoPlayerPos()); + return true; +} + +bool tryGetSessionMoonGetDemoPlayerPose(sead::Quatf* pose, const al::IUseSceneObjHolder* holder) { + SessionMusicianNpc* musician = tryGetJoinedSessionMusicanActor(holder); + if (!musician) + return false; + + pose->set(musician->getMoonGetDemoPlayerPose()); + return true; +} + +bool trySetJoinedSessionMusicianTransformForMoonGetDemo(const al::IUseSceneObjHolder* holder) { + SessionMusicianNpc* musician = tryGetJoinedSessionMusicanActor(holder); + if (!musician) + return false; + + sead::Vector3f pos = musician->getMoonGetDemoPlayerPos(); + al::faceToTarget(musician, pos); + return true; +} + +void addDemoAllMusicians(const al::IUseSceneObjHolder* holder) { + SessionMusicianManager* manager = getSessionMusicianManager(holder); + + manager->addDemoAllMusicians(); +} + +} // namespace SessionMusicianLocalFunction diff --git a/src/Npc/SessionMusicianManager.h b/src/Npc/SessionMusicianManager.h new file mode 100644 index 0000000000..36b9201b47 --- /dev/null +++ b/src/Npc/SessionMusicianManager.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include "Library/LiveActor/LiveActor.h" +#include "Library/Scene/ISceneObj.h" + +#include "Npc/SessionMusicianNpc.h" +#include "Scene/SceneObjFactory.h" + +namespace al { +class ISceneObj; +class LiveActor; +class PlacementInfo; +} // namespace al + +class SessionMayorNpc; +class SessionMusicianBgmController; +class SessionMusicianType; + +class SessionMusicianManager : public al::LiveActor, public al::ISceneObj { +public: + static constexpr s32 sSceneObjId = SceneObjID_SessionMusicianManager; + + SessionMusicianManager(const char* name); + + void initAfterPlacementSceneObj(const al::ActorInitInfo& info); + + void entryMayor(SessionMayorNpc* mayor) { mMayorNpc = mayor; }; + + void entryMusician(SessionMusicianNpc* musician); + bool isJoinedMusician() const; + SessionMusicianNpc* getJoinedMusician() const; + bool isSubscribed(SessionMusicianType type) const; + + bool tryAppearPowerPlant(); + SessionMusicianNpc* findPowerPlant() const; + + bool tryStartWarp(al::PlacementInfo* info); + + void addDemoAllMusicians(); + + void exeWait(); + void exeComplete(); + + sead::PtrArray getMusicians() const { return mMusicianPtrArray; } + +private: + sead::PtrArray mMusicianPtrArray; + SessionMusicianBgmController* mBgmController = nullptr; + SessionMayorNpc* mMayorNpc = nullptr; +}; diff --git a/src/Npc/SessionMusicianNpc.h b/src/Npc/SessionMusicianNpc.h new file mode 100644 index 0000000000..1642452a75 --- /dev/null +++ b/src/Npc/SessionMusicianNpc.h @@ -0,0 +1,128 @@ +#pragma once + +#include +#include +#include +#include + +#include "Library/Event/IEventFlowEventReceiver.h" +#include "Library/Event/IEventFlowQueryJudge.h" +#include "Library/LiveActor/LiveActor.h" + +#include "Npc/SessionMayorParam.h" +#include "Util/DemoUtil.h" + +namespace sead { +class PtrArrayImpl; +} // namespace sead + +namespace al { +struct ActorInitInfo; +class ActorItemKeeper; +class EventFlowExecutor; +class EventReceiver; +class HitSensor; +class IEventFlowEventReceiver; +class IEventFlowQueryJudge; +class SensorMsg; +} // namespace al + +class BgmAnimeSynchronizer; +class CityManRhythmInfo; +class IUsePlayerPuppet; +class JointLookAtController; +class NpcJointLookAtController; +class NpcStateReaction; +class SessionMusicianWarpAgent; +class TalkNpcCap; +class TalkNpcParam; + +class SessionMusicianNpc : public al::LiveActor, + public al::IEventFlowEventReceiver, + public al::IEventFlowQueryJudge { +public: + SEAD_ENUM(EventType, + Wait, + Live, + Ceremony, + PowerPlant + ) + + SessionMusicianNpc(const char* name = nullptr) : al::LiveActor(name) {} + + void init(const al::ActorInitInfo& initInfo); + + void startEvent(); + + void appear(); + void kill(); + void attackSensor(al::HitSensor* self, al::HitSensor* other); + + bool receiveMsg(const al::SensorMsg* message, al::HitSensor* other, al::HitSensor* self); + bool receiveEvent(const al::EventFlowEventData* event); + + const char* judgeQuery(const char* query) const; + + void endClipped(); + + void forceControlForDance(); + void control(); + void controlForDance(); + + bool isJoined() const; + bool isStateWarp() const; + bool isEnableMuteBgmTrack() const; + + void exeWait(); + void exeWaitNoEventFlowSabi(); + void exeWaitNoEventFlow(); + void exeReaction(); + void endReaction(); + + void exeWarp(); + void exeWarpStart(); + void exeWarpEnd(); + void doneWarp(); + + EventType getEventType() { return mEventType; } + + sead::PtrArray getFanActors() { return mFanActors; } + + SessionMusicianWarpAgent* getWarpAgent() const { return mWarpAgent; }; + + s32 getLinkedShineIndex() const { return mLinkedShineIndex; }; + + const sead::Vector3f& getMoonGetDemoPlayerPos() const { return mMoonGetDemoPlayerPos; } + + const sead::Quatf& getMoonGetDemoPlayerPose() const { return mMoonGetDemoPlayerPose; } + + void addDemoActors() { + for (s32 i = 0; i < mFanActors.size(); i++) + rs::addDemoActor(mFanActors[i], true); + } + +private: + EventType mEventType; + al::EventFlowExecutor* mEventFlowExecutor; + const MusicianCameraParams* mMusicianCameraParams; + sead::PtrArray mFanActors; + SessionMusicianWarpAgent* mWarpAgent; + NpcStateReaction* mNpcStateReaction; + TalkNpcParam* mTalkNpcParam; + NpcJointLookAtController* mNpcJoint; + TalkNpcCap* mTalkNpcCap; + sead::Vector3f mMoonGetDemoPlayerPos; + sead::Quatf mMoonGetDemoPlayerPose; + s32 mLinkedShineIndex; + IUsePlayerPuppet* mPuppet; + bool mIsJoined; + std::string mWaitAnimName; + std::string mSabiAnimName; + CityManRhythmInfo* mRhythmInfo; + BgmAnimeSynchronizer* mBgmSync; + f32 mAnimBeatFrameOffset; + bool mIsNeedRythmResync; + bool mIsUseBgmTrackMute; +}; + +static_assert(sizeof(SessionMusicianNpc) == 0x1e0);