1#include "Library/MapObj/FloaterMapParts.h"
2
3#include "Library/Effect/EffectSystemInfo.h"
4#include "Library/KeyPose/KeyPoseKeeperUtil.h"
5#include "Library/LiveActor/ActorActionFunction.h"
6#include "Library/LiveActor/ActorAreaFunction.h"
7#include "Library/LiveActor/ActorClippingFunction.h"
8#include "Library/LiveActor/ActorInitUtil.h"
9#include "Library/LiveActor/ActorModelFunction.h"
10#include "Library/LiveActor/ActorMovementFunction.h"
11#include "Library/LiveActor/ActorPoseUtil.h"
12#include "Library/LiveActor/ActorSensorUtil.h"
13#include "Library/Math/MathUtil.h"
14#include "Library/Nerve/NerveSetupUtil.h"
15#include "Library/Nerve/NerveUtil.h"
16#include "Library/Placement/PlacementFunction.h"
17
18namespace {
19using namespace al;
20
21NERVE_ACTION_IMPL(FloaterMapParts, Wait)
22NERVE_ACTION_IMPL(FloaterMapParts, Sink)
23NERVE_ACTION_IMPL(FloaterMapParts, Back)
24
25NERVE_ACTIONS_MAKE_STRUCT(FloaterMapParts, Wait, Sink, Back)
26} // namespace
27
28namespace al {
29FloaterMapParts::FloaterMapParts(const char* name) : LiveActor(name) {}
30
31void FloaterMapParts::init(const ActorInitInfo& info) {
32 initNerveAction(actor: this, actionName: "Wait", collector: &NrvFloaterMapParts.collector, maxStates: 0);
33 initMapPartsActor(actor: this, initInfo: info, suffix: nullptr);
34
35 tryGetQuatPtr(actor: this);
36 registerAreaHostMtx(actor: this, initInfo: info);
37
38 mKeyPoseKeeper = createKeyPoseKeeper(info);
39
40 tryGetArg(arg: &mSinkSpeed, initInfo: info, key: "SinkSpeed");
41 tryGetArg(arg: &mBackSpeed, initInfo: info, key: "BackSpeed");
42 tryGetArg(arg: &mMaxAccelCount, initInfo: info, key: "MaxAccelCount");
43 tryGetArg(arg: &mSinkKeepTime, initInfo: info, key: "SinkKeepTime");
44 tryGetArg(arg: &mMaxCoord, initInfo: info, key: "MaxCoord");
45
46 initMaterialCode(actor: this, initInfo: info);
47
48 trySetEffectNamedMtxPtr(this, "Surface", &mMtxTR);
49 tryGetLinksMatrixTR(matrix: &mMtxTR, initInfo: info, linkName: "SurfaceEffectPos");
50
51 if (mMaxCoord <= 0.0f)
52 mMaxCoord = calcDistanceNextKeyTrans(keyPoseKeeper: mKeyPoseKeeper);
53
54 trySyncStageSwitchAppear(actor: this);
55}
56
57bool FloaterMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) {
58 if (isMsgFloorTouch(msg: message)) {
59 mMoveType = FloaterMoveType::Sink;
60
61 return true;
62 }
63
64 if (isMsgShowModel(msg: message)) {
65 showModelIfHide(actor: this);
66
67 return true;
68 }
69
70 if (isMsgHideModel(msg: message)) {
71 hideModelIfShow(actor: this);
72
73 return true;
74 }
75
76 if (isMsgRestart(msg: message)) {
77 appearAndSetStart();
78
79 return true;
80 }
81
82 return false;
83}
84
85void FloaterMapParts::appearAndSetStart() {
86 mCoord = 0.0f;
87 mMoveType = FloaterMoveType::Wait;
88
89 calcLerpKeyTrans(out: getTransPtr(actor: this), keyPoseKeeper: mKeyPoseKeeper, rate: 0.0f);
90 calcSlerpKeyQuat(out: getQuatPtr(actor: this), keyPoseKeeper: mKeyPoseKeeper, rate: 0.0f);
91
92 resetPosition(actor: this);
93 startNerveAction(actor: this, actionName: "Wait");
94
95 makeActorAlive();
96}
97
98void FloaterMapParts::control() {
99 f32 rate = isNearZero(value: mMaxCoord) ? 0.0f : mCoord / mMaxCoord;
100
101 calcLerpKeyTrans(out: getTransPtr(actor: this), keyPoseKeeper: mKeyPoseKeeper, rate);
102 calcSlerpKeyQuat(out: getQuatPtr(actor: this), keyPoseKeeper: mKeyPoseKeeper, rate);
103
104 if (mMoveType > FloaterMoveType::Wait)
105 mMoveType = static_cast<FloaterMoveType>(static_cast<s32>(mMoveType) - 1);
106}
107
108void FloaterMapParts::exeWait() {
109 if (isFirstStep(user: this))
110 validateClipping(actor: this);
111
112 if (mMoveType > FloaterMoveType::Wait) {
113 invalidateClipping(actor: this);
114 startNerveAction(actor: this, actionName: "Sink");
115 }
116}
117
118void FloaterMapParts::exeSink() {
119 if (isFirstStep(user: this))
120 mAccelCount = 0;
121
122 if (mMoveType != FloaterMoveType::Wait) {
123 mCoord += (mMaxAccelCount < 1 ? 1.0f : (f32)mAccelCount / (f32)mMaxAccelCount) * mSinkSpeed;
124
125 if (mAccelCount < mMaxAccelCount)
126 mAccelCount++;
127
128 if (mCoord > mMaxCoord)
129 mCoord = mMaxCoord;
130
131 mSinkTime = 0;
132 } else {
133 s32 prevAccelCount = mAccelCount;
134 mSinkTime++;
135 if (prevAccelCount > 0)
136 mAccelCount--;
137 }
138
139 if (mSinkTime >= mSinkKeepTime)
140 startNerveAction(actor: this, actionName: "Back");
141}
142
143void FloaterMapParts::exeBack() {
144 if (isFirstStep(user: this))
145 mAccelCount = 0;
146
147 mCoord -= (mMaxAccelCount < 1 ? 1.0f : (f32)mAccelCount / (f32)mMaxAccelCount) * mBackSpeed;
148
149 if (mAccelCount < mMaxAccelCount)
150 mAccelCount++;
151
152 bool isCoordLesserThan0;
153 if (mCoord < 0.0f) {
154 isCoordLesserThan0 = true;
155 mCoord = 0.0f;
156 } else {
157 isCoordLesserThan0 = false;
158 }
159
160 if (mMoveType >= FloaterMoveType::Back)
161 startNerveAction(actor: this, actionName: "Sink");
162 else if (isCoordLesserThan0)
163 startNerveAction(actor: this, actionName: "Wait");
164}
165} // namespace al
166