1#include "Library/MapObj/SlideMapParts.h"
2
3#include "Library/Effect/EffectSystemInfo.h"
4#include "Library/LiveActor/ActorActionFunction.h"
5#include "Library/LiveActor/ActorAreaFunction.h"
6#include "Library/LiveActor/ActorInitUtil.h"
7#include "Library/LiveActor/ActorModelFunction.h"
8#include "Library/LiveActor/ActorMovementFunction.h"
9#include "Library/LiveActor/ActorPoseUtil.h"
10#include "Library/LiveActor/ActorSensorUtil.h"
11#include "Library/Math/MathUtil.h"
12#include "Library/Nerve/NerveSetupUtil.h"
13#include "Library/Nerve/NerveUtil.h"
14#include "Library/Placement/PlacementFunction.h"
15#include "Library/Se/SeFunction.h"
16#include "Library/Stage/StageSwitchUtil.h"
17#include "Library/Thread/FunctorV0M.h"
18
19namespace {
20using namespace al;
21
22NERVE_ACTION_IMPL(SlideMapParts, StandBy)
23NERVE_ACTION_IMPL(SlideMapParts, Delay)
24NERVE_ACTION_IMPL(SlideMapParts, Wait)
25NERVE_ACTION_IMPL(SlideMapParts, Move)
26
27NERVE_ACTIONS_MAKE_STRUCT(SlideMapParts, StandBy, Delay, Wait, Move)
28} // namespace
29
30namespace al {
31SlideMapParts::SlideMapParts(const char* name) : LiveActor(name) {}
32
33void SlideMapParts::init(const ActorInitInfo& info) {
34 using SlideMapPartsFunctor = FunctorV0M<SlideMapParts*, void (SlideMapParts::*)()>;
35
36 initNerveAction(actor: this, actionName: "Move", collector: &NrvSlideMapParts.collector, maxStates: 0);
37 initMapPartsActor(actor: this, initInfo: info, suffix: tryGetMapPartsSuffix(initInfo: info, suffix: "SlideMapParts"));
38 registerAreaHostMtx(actor: this, initInfo: info);
39
40 mTrans = getTrans(actor: this);
41 tryGetArg(arg: (s32*)&mMoveAxis, initInfo: info, key: "MoveAxis");
42 tryGetArg(arg: &mMoveDistance, initInfo: info, key: "MoveDistance");
43 tryGetArg(arg: &mMoveSpeed, initInfo: info, key: "MoveSpeed");
44 tryGetArg(arg: &mWaitTime, initInfo: info, key: "WaitTime");
45 if (mWaitTime < 0)
46 mWaitTime = 0;
47 tryGetArg(arg: &mMoveTime, initInfo: info, key: "MoveTime");
48 tryGetArg(arg: &mDelayTime, initInfo: info, key: "DelayTime");
49
50 f32 surfaceHeight = 0.0f;
51 tryGetArg(arg: &surfaceHeight, initInfo: info, key: "SurfaceHeight");
52
53 initMaterialCode(actor: this, initInfo: info);
54
55 sead::Vector3f t;
56 calcQuatLocalAxis(&t, getQuat(actor: this), (s32)mMoveAxis);
57
58 sead::Vector3f ts;
59 ts.x = surfaceHeight * t.x + mTrans.x;
60 ts.y = surfaceHeight * t.y + mTrans.y;
61 ts.z = surfaceHeight * t.z + mTrans.z;
62
63 mSurfaceEffectMtx.makeQT(q: getQuat(actor: this), t: ts);
64
65 trySetEffectNamedMtxPtr(this, "Surface", &mSurfaceEffectMtx);
66
67 if (listenStageSwitchOnStart(user: this, action: SlideMapPartsFunctor(this, &SlideMapParts::start)))
68 startNerveAction(actor: this, actionName: "StandBy");
69 else if (mDelayTime >= 1)
70 startNerveAction(actor: this, actionName: "Delay");
71
72 trySyncStageSwitchAppear(actor: this);
73}
74
75void SlideMapParts::start() {
76 if (!isNerve(user: this, nerve: NrvSlideMapParts.StandBy.data()))
77 return;
78
79 if (mDelayTime >= 1) {
80 startNerveAction(actor: this, actionName: "Delay");
81
82 return;
83 }
84
85 startNerveAction(actor: this, actionName: "Move");
86}
87
88bool SlideMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) {
89 if (isMsgShowModel(msg: message)) {
90 showModelIfHide(actor: this);
91
92 return true;
93 }
94
95 if (isMsgHideModel(msg: message)) {
96 hideModelIfShow(actor: this);
97
98 return true;
99 }
100
101 return false;
102}
103
104void SlideMapParts::exeStandBy() {}
105
106void SlideMapParts::exeDelay() {
107 if (isGreaterEqualStep(user: this, step: mDelayTime))
108 startNerveAction(actor: this, actionName: "Move");
109}
110
111void SlideMapParts::exeWait() {
112 if (isGreaterStep(user: this, step: mWaitTime))
113 startNerveAction(actor: this, actionName: "Move");
114}
115
116void SlideMapParts::exeMove() {
117 if (isFirstStep(user: this)) {
118 if (mIsMoveForwards)
119 tryStartSe(this, "MoveStart1");
120 else
121 tryStartSe(this, "MoveStart2");
122 }
123
124 f32 rate = calcNerveRate(user: this, max: calcMoveTime());
125 if (!mIsMoveForwards)
126 rate = 1.0f - rate;
127
128 setTransOffsetLocalDir(actor: this, quat: getQuat(actor: this), globalOffset: mTrans, localOffset: mMoveDistance * rate, axis: (s32)mMoveAxis);
129
130 if (isGreaterEqualStep(user: this, step: calcMoveTime())) {
131 if (mIsMoveForwards)
132 tryStartSe(this, "MoveEnd1");
133 else
134 tryStartSe(this, "MoveEnd2");
135
136 mIsMoveForwards = !mIsMoveForwards;
137 tryStartSe(this, "MoveEnd");
138 startNerveAction(actor: this, actionName: "Wait");
139 }
140}
141
142s32 SlideMapParts::calcMoveTime() const {
143 if (mMoveTime >= 0)
144 return mMoveTime;
145
146 if (mMoveSpeed < 1.0f)
147 return 0;
148
149 return (s32)sead::Mathf::abs(x: mMoveDistance / mMoveSpeed);
150}
151} // namespace al
152