1#include "Library/MapObj/SwitchOpenMapParts.h"
2
3#include "Library/LiveActor/ActorActionFunction.h"
4#include "Library/LiveActor/ActorAreaFunction.h"
5#include "Library/LiveActor/ActorClippingFunction.h"
6#include "Library/LiveActor/ActorInitUtil.h"
7#include "Library/LiveActor/ActorPoseUtil.h"
8#include "Library/Math/MathUtil.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#include "Library/Stage/StageSwitchUtil.h"
14#include "Library/Thread/FunctorV0M.h"
15
16namespace al {
17namespace {
18NERVE_ACTION_IMPL(SwitchOpenMapParts, Wait)
19NERVE_ACTION_IMPL(SwitchOpenMapParts, DelayOpen)
20NERVE_ACTION_IMPL(SwitchOpenMapParts, Open)
21NERVE_ACTION_IMPL(SwitchOpenMapParts, WaitOpend)
22NERVE_ACTION_IMPL(SwitchOpenMapParts, DelayClose)
23NERVE_ACTION_IMPL(SwitchOpenMapParts, Close)
24
25NERVE_ACTIONS_MAKE_STRUCT(SwitchOpenMapParts, Wait, DelayOpen, Open, WaitOpend, DelayClose, Close)
26} // namespace
27
28SwitchOpenMapParts::SwitchOpenMapParts(const char* name) : LiveActor(name) {}
29
30void SwitchOpenMapParts::init(const ActorInitInfo& info) {
31 using SwitchOpenMapPartsFunctor =
32 FunctorV0M<SwitchOpenMapParts*, void (SwitchOpenMapParts::*)()>;
33
34 initNerveAction(actor: this, actionName: "Wait", collector: &NrvSwitchOpenMapParts.collector, maxStates: 0);
35
36 const char* suffix = nullptr;
37 tryGetStringArg(arg: &suffix, initInfo: info, key: "SuffixName");
38 initMapPartsActor(actor: this, initInfo: info, suffix);
39
40 tryGetQuatPtr(actor: this);
41 getTrans(trans: &mTrans, initInfo: info);
42
43 PlacementInfo endPointInfo;
44 getLinksInfo(linkPlacementInfo: &endPointInfo, initInfo: info, linkName: "EndPoint");
45
46 sead::Vector3f endPointTrans;
47 getTrans(trans: &endPointTrans, placementInfo: endPointInfo);
48 endPointTrans.set(endPointTrans - mTrans);
49 mEndPointDist = endPointTrans.length();
50 normalize(out: &mEndPointDir, vec: endPointTrans);
51
52 registerAreaHostMtx(actor: this, initInfo: info);
53
54 tryGetArg(arg: &mDelayTimeOpen, initInfo: info, key: "DelayTimeOpen");
55 tryGetArg(arg: &mDelayTimeClose, initInfo: info, key: "DelayTimeClose");
56 tryGetArg(arg: &mSpeedOpen, initInfo: info, key: "SpeedOpen");
57 tryGetArg(arg: &mSpeedClose, initInfo: info, key: "SpeedClose");
58
59 listenStageSwitchOnOff(user: this, eventName: "SwitchStart",
60 actionOn: SwitchOpenMapPartsFunctor(this, &SwitchOpenMapParts::open),
61 actionOff: SwitchOpenMapPartsFunctor(this, &SwitchOpenMapParts::close));
62
63 makeActorAlive();
64}
65
66void SwitchOpenMapParts::open() {
67 if (isNerve(user: this, nerve: NrvSwitchOpenMapParts.Wait.data()))
68 if (mDelayTimeOpen > 0)
69 startNerveAction(actor: this, actionName: "DelayOpen");
70 else
71 startNerveAction(actor: this, actionName: "Open");
72 else if (isNerve(user: this, nerve: NrvSwitchOpenMapParts.DelayClose.data()))
73 startNerveAction(actor: this, actionName: "WaitOpend");
74 else if (isNerve(user: this, nerve: NrvSwitchOpenMapParts.Close.data()))
75 startNerveAction(actor: this, actionName: "Open");
76}
77
78void SwitchOpenMapParts::close() {
79 if (isNerve(user: this, nerve: NrvSwitchOpenMapParts.WaitOpend.data()))
80 if (mDelayTimeClose > 0)
81 startNerveAction(actor: this, actionName: "DelayOpen");
82 else
83 startNerveAction(actor: this, actionName: "Close");
84 else if (isNerve(user: this, nerve: NrvSwitchOpenMapParts.DelayOpen.data()))
85 startNerveAction(actor: this, actionName: "Wait");
86 else if (isNerve(user: this, nerve: NrvSwitchOpenMapParts.Open.data()))
87 startNerveAction(actor: this, actionName: "Close");
88}
89
90void SwitchOpenMapParts::exeWait() {
91 if (isFirstStep(user: this))
92 validateClipping(actor: this);
93}
94
95void SwitchOpenMapParts::exeDelayOpen() {
96 if (isGreaterEqualStep(user: this, step: mDelayTimeOpen - 1))
97 startNerveAction(actor: this, actionName: "Open");
98}
99
100void SwitchOpenMapParts::exeOpen() {
101 if (isFirstStep(user: this)) {
102 invalidateClipping(actor: this);
103 if (isExistAction(actor: this, actionName: "MoveLoop"))
104 tryStartActionIfNotPlaying(actor: this, actionName: "MoveLoop");
105 }
106
107 mCoord += mSpeedOpen;
108 if (mCoord > mEndPointDist) {
109 mCoord = mEndPointDist;
110 setTrans(actor: this, trans: mCoord * mEndPointDir + mTrans);
111 startNerveAction(actor: this, actionName: "WaitOpend");
112 } else {
113 setTrans(actor: this, trans: mCoord * mEndPointDir + mTrans);
114 }
115}
116
117void SwitchOpenMapParts::exeWaitOpend() {}
118
119void SwitchOpenMapParts::exeDelayClose() {
120 if (isGreaterEqualStep(user: this, step: mDelayTimeClose - 1))
121 startNerveAction(actor: this, actionName: "Close");
122}
123
124void SwitchOpenMapParts::exeClose() {
125 if (isFirstStep(user: this) && isExistAction(actor: this, actionName: "MoveLoop"))
126 tryStartActionIfNotPlaying(actor: this, actionName: "MoveLoop");
127
128 mCoord -= mSpeedClose;
129 if (mCoord < 0.0f) {
130 mCoord = 0.0f;
131 setTrans(actor: this, trans: mTrans);
132 startNerveAction(actor: this, actionName: "Wait");
133 } else {
134 setTrans(actor: this, trans: mCoord * mEndPointDir + mTrans);
135 }
136}
137} // namespace al
138