| 1 | #include "Item/Coin2DCityDirector.h" |
| 2 | |
| 3 | #include "Library/Bgm/BgmBeatCounter.h" |
| 4 | #include "Library/Bgm/BgmLineFunction.h" |
| 5 | #include "Library/LiveActor/ActorClippingFunction.h" |
| 6 | #include "Library/LiveActor/ActorInitFunction.h" |
| 7 | #include "Library/LiveActor/ActorInitUtil.h" |
| 8 | #include "Library/LiveActor/ActorPoseUtil.h" |
| 9 | #include "Library/Nerve/NerveSetupUtil.h" |
| 10 | #include "Library/Nerve/NerveUtil.h" |
| 11 | #include "Library/Placement/PlacementFunction.h" |
| 12 | #include "Library/Placement/PlacementInfo.h" |
| 13 | |
| 14 | #include "Item/Coin2DCity.h" |
| 15 | |
| 16 | namespace { |
| 17 | NERVE_IMPL(Coin2DCityDirector, Wait); |
| 18 | |
| 19 | NERVES_MAKE_STRUCT(Coin2DCityDirector, Wait); |
| 20 | } // namespace |
| 21 | |
| 22 | Coin2DCityDirector::Coin2DCityDirector(const char* name) : al::LiveActor(name) {} |
| 23 | |
| 24 | void Coin2DCityDirector::init(const al::ActorInitInfo& initInfo) { |
| 25 | al::initActorWithArchiveName(actor: this, initInfo, archiveName: "Coin2DCityDirector" , suffix: nullptr); |
| 26 | if (!al::isExistLinkChild(initInfo, linkName: "FirstCoin" , index: 0)) { |
| 27 | kill(); |
| 28 | return; |
| 29 | } |
| 30 | |
| 31 | al::tryGetArg(arg: &mNextCoinLightTime, initInfo, key: "NextCoinLightTime" ); |
| 32 | al::tryGetArg(arg: &mLightTime, initInfo, key: "LightTime" ); |
| 33 | al::tryGetArg(arg: &mLightInterval, initInfo, key: "LightInterval" ); |
| 34 | al::tryGetArg(arg: &mDelayTime, initInfo, key: "DelayTime" ); |
| 35 | if (mNextCoinLightTime <= -1 || mLightTime <= -1 || mLightInterval <= -1 || mDelayTime <= -1) { |
| 36 | kill(); |
| 37 | return; |
| 38 | } |
| 39 | |
| 40 | mCoinHolder.allocBuffer(ptrNumMax: 100, heap: nullptr); |
| 41 | |
| 42 | al::PlacementInfo placementInfo; |
| 43 | al::getLinksInfo(linkPlacementInfo: &placementInfo, initInfo, linkName: "FirstCoin" ); |
| 44 | s32 linkNestNum = al::calcLinkNestNum(placementInfo, linkName: "NextCoin" ); |
| 45 | |
| 46 | Coin2DCity* coin = new Coin2DCity("コイン2D都市" , this); |
| 47 | al::initCreateActorWithPlacementInfo(actor: coin, initInfo, placementInfo); |
| 48 | al::initSubActorKeeperNoFile(this, initInfo, linkNestNum + 1); |
| 49 | |
| 50 | mBgmBeatCounter = new al::BgmBeatCounter(this, -0.28f); |
| 51 | al::initNerve(actor: this, nerve: &NrvCoin2DCityDirector.Wait, maxStates: 0); |
| 52 | makeActorAlive(); |
| 53 | } |
| 54 | |
| 55 | void Coin2DCityDirector::initAfterPlacement() { |
| 56 | sead::Vector3f minPos = sead::Vector3f::zero; |
| 57 | sead::Vector3f maxPos = sead::Vector3f::zero; |
| 58 | |
| 59 | s32 size = mCoinHolder.size(); |
| 60 | for (s32 i = 0; i < size; i++) { |
| 61 | al::registerSubActorSyncClipping(this, mCoinHolder[i]); |
| 62 | const sead::Vector3f& trans = al::getTrans(actor: mCoinHolder[i]); |
| 63 | |
| 64 | if (i == 0) { |
| 65 | minPos = trans; |
| 66 | maxPos = trans; |
| 67 | continue; |
| 68 | } |
| 69 | |
| 70 | minPos.x = sead::Mathf::min(a: minPos.x, b: trans.x); |
| 71 | minPos.y = sead::Mathf::min(a: minPos.y, b: trans.y); |
| 72 | minPos.z = sead::Mathf::min(a: minPos.z, b: trans.z); |
| 73 | |
| 74 | maxPos.x = sead::Mathf::max(a: maxPos.x, b: trans.x); |
| 75 | maxPos.y = sead::Mathf::max(a: maxPos.y, b: trans.y); |
| 76 | maxPos.z = sead::Mathf::max(a: maxPos.z, b: trans.z); |
| 77 | } |
| 78 | |
| 79 | mClippingPos = (maxPos + minPos) * 0.5f; |
| 80 | f32 clippingSize = (maxPos - minPos).length() * 0.5f + 500.0f; |
| 81 | al::setClippingInfo(actor: this, clippingSize, &mClippingPos); |
| 82 | } |
| 83 | |
| 84 | void Coin2DCityDirector::control() { |
| 85 | return mBgmBeatCounter->update(); |
| 86 | } |
| 87 | |
| 88 | void Coin2DCityDirector::registerCoin(Coin2DCity* coin) { |
| 89 | mCoinHolder.pushBack(ptr: coin); |
| 90 | } |
| 91 | |
| 92 | void Coin2DCityDirector::getCoin() { |
| 93 | if (++mCoinsCollected < mCoinHolder.size()) |
| 94 | return; |
| 95 | |
| 96 | s32 size = mCoinHolder.size(); |
| 97 | for (s32 i = 0; i < size; i++) |
| 98 | mCoinHolder[i]->kill(); |
| 99 | |
| 100 | kill(); |
| 101 | } |
| 102 | |
| 103 | bool Coin2DCityDirector::isTriggerBeat() const { |
| 104 | return mBgmBeatCounter->isOnBeat(); |
| 105 | } |
| 106 | |
| 107 | void Coin2DCityDirector::exeWait() { |
| 108 | if (al::isEnableRhythmAnim(this, nullptr)) { |
| 109 | if (mBgmBeatCounter->isTriggerBeat(interval: mLightInterval, delayTime: mDelayTime)) |
| 110 | mCoinHolder.front()->startLight(); |
| 111 | return; |
| 112 | } |
| 113 | |
| 114 | if (al::isFirstStep(user: this)) |
| 115 | return; |
| 116 | |
| 117 | if (al::getNerveStep(user: this) % mLightInterval == 0) |
| 118 | mCoinHolder.front()->startLight(); |
| 119 | } |
| 120 | |