1#include "Library/Nerve/NerveUtil.h"
2
3#include <math/seadMathCalcCommon.h>
4
5#include "Library/Math/MathUtil.h"
6#include "Library/Nerve/IUseNerve.h"
7#include "Library/Nerve/NerveAction.h"
8#include "Library/Nerve/NerveActionCtrl.h"
9#include "Library/Nerve/NerveKeeper.h"
10#include "Library/Nerve/NerveStateCtrl.h"
11
12namespace al {
13void setNerve(IUseNerve* user, const Nerve* nerve) {
14 user->getNerveKeeper()->setNerve(nerve);
15}
16
17void setNerveAtStep(IUseNerve* user, const Nerve* nerve, s32 step) {
18 if (user->getNerveKeeper()->getCurrentStep() == step)
19 user->getNerveKeeper()->setNerve(nerve);
20}
21
22bool isStep(const IUseNerve* user, s32 step) {
23 return user->getNerveKeeper()->getCurrentStep() == step;
24}
25
26void setNerveAtGreaterEqualStep(IUseNerve* user, const Nerve* nerve, s32 step) {
27 if (user->getNerveKeeper()->getCurrentStep() >= step)
28 user->getNerveKeeper()->setNerve(nerve);
29}
30
31bool isNerve(const IUseNerve* user, const Nerve* nerve) {
32 return user->getNerveKeeper()->getCurrentNerve() == nerve;
33}
34
35s32 getNerveStep(const IUseNerve* user) {
36 return user->getNerveKeeper()->getCurrentStep();
37}
38
39const Nerve* getCurrentNerve(const IUseNerve* user) {
40 return user->getNerveKeeper()->getCurrentNerve();
41}
42
43bool isFirstStep(const IUseNerve* user) {
44 return isStep(user, step: 0);
45}
46
47bool isGreaterStep(const IUseNerve* user, s32 step) {
48 return user->getNerveKeeper()->getCurrentStep() > step;
49}
50
51bool isGreaterEqualStep(const IUseNerve* user, s32 step) {
52 return user->getNerveKeeper()->getCurrentStep() >= step;
53}
54
55bool isLessStep(const IUseNerve* user, s32 step) {
56 return user->getNerveKeeper()->getCurrentStep() < step;
57}
58
59bool isLessEqualStep(const IUseNerve* user, s32 step) {
60 return user->getNerveKeeper()->getCurrentStep() <= step;
61}
62
63bool isInRangeStep(const IUseNerve* user, s32 startStep, s32 endStep) {
64 NerveKeeper* nerveKeeper = user->getNerveKeeper();
65 return startStep <= nerveKeeper->getCurrentStep() && nerveKeeper->getCurrentStep() <= endStep;
66}
67
68bool isIntervalStep(const IUseNerve* user, s32 interval, s32 offset) {
69 s32 currentStep = user->getNerveKeeper()->getCurrentStep() - offset;
70 return currentStep >= 0 && currentStep % interval == 0;
71}
72
73bool isIntervalOnOffStep(const IUseNerve* user, s32 interval, s32 offset) {
74 return ((user->getNerveKeeper()->getCurrentStep() - offset) / interval) % 2 == 0;
75}
76
77bool isNewNerve(const IUseNerve* user) {
78 return isLessStep(user, step: 0);
79}
80
81s32 calcNerveInterval(const IUseNerve* user, s32 interval, s32 offset) {
82 s32 remain = getNerveStep(user) - offset;
83
84 if (interval < 1 || remain < 1)
85 return 0;
86
87 return remain / interval;
88}
89
90f32 calcNerveRate(const IUseNerve* user, s32 max) {
91 if (max < 1)
92 return 1.0f;
93
94 f32 curStep = getNerveStep(user);
95 return sead::Mathf::clamp(value: curStep / max, low: 0.0f, high: 1.0f);
96}
97
98f32 calcNerveRate(const IUseNerve* user, s32 min, s32 max) {
99 f32 rate = normalize(x: (f32)getNerveStep(user), min: (f32)min, max: (f32)max);
100 return sead::Mathf::clamp(value: rate, low: 0.0f, high: 1.0f);
101}
102
103f32 calcNerveEaseInRate(const IUseNerve* user, s32 max) {
104 return easeIn(t: calcNerveRate(user, max));
105}
106
107f32 calcNerveEaseInRate(const IUseNerve* user, s32 min, s32 max) {
108 return easeIn(t: calcNerveRate(user, min, max));
109}
110
111f32 calcNerveEaseOutRate(const IUseNerve* user, s32 max) {
112 return easeOut(t: calcNerveRate(user, max));
113}
114
115f32 calcNerveEaseOutRate(const IUseNerve* user, s32 min, s32 max) {
116 return easeOut(t: calcNerveRate(user, min, max));
117}
118
119f32 calcNerveEaseInOutRate(const IUseNerve* user, s32 max) {
120 return easeInOut(t: calcNerveRate(user, max));
121}
122
123f32 calcNerveEaseInOutRate(const IUseNerve* user, s32 min, s32 max) {
124 return easeInOut(t: calcNerveRate(user, min, max));
125}
126
127f32 calcNerveSquareInRate(const IUseNerve* user, s32 max) {
128 return squareIn(t: calcNerveRate(user, max));
129}
130
131f32 calcNerveSquareInRate(const IUseNerve* user, s32 min, s32 max) {
132 return squareIn(t: calcNerveRate(user, min, max));
133}
134
135f32 calcNerveSquareOutRate(const IUseNerve* user, s32 max) {
136 return squareOut(t: calcNerveRate(user, max));
137}
138
139f32 calcNerveSquareOutRate(const IUseNerve* user, s32 min, s32 max) {
140 return squareOut(t: calcNerveRate(user, min, max));
141}
142
143f32 calcNerveEaseByTypeRate(const IUseNerve* user, s32 max, s32 type) {
144 return easeByType(t: calcNerveRate(user, max), easeType: type);
145}
146
147f32 calcNerveEaseByTypeRate(const IUseNerve* user, s32 min, s32 max, s32 type) {
148 return easeByType(t: calcNerveRate(user, min, max), easeType: type);
149}
150
151f32 calcNervePowerInRate(const IUseNerve* user, s32 max, f32 power) {
152 return powerIn(t: calcNerveRate(user, max), exp: power);
153}
154
155f32 calcNervePowerInRate(const IUseNerve* user, s32 min, s32 max, f32 power) {
156 return powerIn(t: calcNerveRate(user, min, max), exp: power);
157}
158
159f32 calcNervePowerOutRate(const IUseNerve* user, s32 max, f32 power) {
160 return powerOut(t: calcNerveRate(user, max), exp: power);
161}
162
163f32 calcNervePowerOutRate(const IUseNerve* user, s32 min, s32 max, f32 power) {
164 return powerOut(t: calcNerveRate(user, min, max), exp: power);
165}
166
167f32 calcNerveJumpRate(const IUseNerve* user, s32 inMax, s32 upDuration, s32 release) {
168 s32 step = getNerveStep(user);
169 if (step <= inMax)
170 return calcNerveEaseOutRate(user, max: inMax);
171
172 s32 startRelease = upDuration + inMax;
173 if (step <= startRelease)
174 return 1.0f;
175
176 return lerpValue(a: 1.0f, b: 0.0f, t: calcNerveEaseInRate(user, min: startRelease, max: startRelease + release));
177}
178
179f32 calcNerveEaseInValue(const IUseNerve* user, s32 min, s32 max, f32 start, f32 end) {
180 return lerpValue(a: start, b: end, t: calcNerveEaseInRate(user, min, max));
181}
182
183f32 calcNerveStartEndRate(const IUseNerve* user, s32 inMax, s32 upDuration, s32 release) {
184 s32 step = getNerveStep(user);
185 if (step <= inMax)
186 return calcNerveEaseInOutRate(user, max: inMax);
187
188 s32 startRelease = upDuration + inMax;
189 if (step <= startRelease)
190 return 1.0f;
191
192 return lerpValue(a: 1.0f, b: 0.0f,
193 t: calcNerveEaseInOutRate(user, min: startRelease, max: startRelease + release));
194}
195
196f32 calcNerveEaseInOutValue(const IUseNerve* user, s32 min, s32 max, f32 start, f32 end) {
197 return lerpValue(a: start, b: end, t: calcNerveEaseInOutRate(user, min, max));
198}
199
200f32 calcNerveValue(const IUseNerve* user, s32 max, f32 start, f32 end) {
201 return lerpValue(a: start, b: end, t: calcNerveRate(user, max));
202}
203
204f32 calcNerveValue(const IUseNerve* user, s32 min, s32 max, f32 start, f32 end) {
205 return lerpValue(a: start, b: end, t: calcNerveRate(user, min, max));
206}
207
208f32 calcNerveEaseInValue(const IUseNerve* user, s32 max, f32 start, f32 end) {
209 return lerpValue(a: start, b: end, t: calcNerveEaseInRate(user, max));
210}
211
212f32 calcNerveEaseOutValue(const IUseNerve* user, s32 max, f32 start, f32 end) {
213 return lerpValue(a: start, b: end, t: calcNerveEaseOutRate(user, max));
214}
215
216f32 calcNerveEaseOutValue(const IUseNerve* user, s32 min, s32 max, f32 start, f32 end) {
217 return lerpValue(a: start, b: end, t: calcNerveEaseOutRate(user, min, max));
218}
219
220f32 calcNerveEaseInOutValue(const IUseNerve* user, s32 max, f32 start, f32 end) {
221 return lerpValue(a: start, b: end, t: calcNerveEaseInOutRate(user, max));
222}
223
224f32 calcNerveSquareInValue(const IUseNerve* user, s32 max, f32 start, f32 end) {
225 return lerpValue(a: start, b: end, t: calcNerveSquareInRate(user, max));
226}
227
228f32 calcNerveSquareInValue(const IUseNerve* user, s32 min, s32 max, f32 start, f32 end) {
229 return lerpValue(a: start, b: end, t: calcNerveSquareInRate(user, min, max));
230}
231
232f32 calcNerveSquareOutValue(const IUseNerve* user, s32 max, f32 start, f32 end) {
233 return lerpValue(a: start, b: end, t: calcNerveSquareOutRate(user, max));
234}
235
236f32 calcNerveSquareOutValue(const IUseNerve* user, s32 min, s32 max, f32 start, f32 end) {
237 return lerpValue(a: start, b: end, t: calcNerveSquareOutRate(user, min, max));
238}
239
240f32 calcNerveEaseByTypeValue(const IUseNerve* user, s32 max, f32 start, f32 end, s32 type) {
241 return lerpValue(a: start, b: end, t: calcNerveEaseByTypeRate(user, max, type));
242}
243
244f32 calcNerveEaseByTypeValue(const IUseNerve* user, s32 min, s32 max, f32 start, f32 end,
245 s32 type) {
246 return lerpValue(a: start, b: end, t: calcNerveEaseByTypeRate(user, min, max, type));
247}
248
249f32 calcNerveCosCycle(const IUseNerve* user, s32 max) {
250 if (max == 0)
251 return 1.0f;
252 return sead::Mathf::cos(t: (f32)getNerveStep(user) / max * sead::Mathf::pi2());
253}
254
255f32 calcNerveSinCycle(const IUseNerve* user, s32 max) {
256 if (max == 0)
257 return 1.0f;
258 return sead::Mathf::sin(t: (f32)getNerveStep(user) / max * sead::Mathf::pi2());
259}
260
261f32 calcNerveRepeatRate(const IUseNerve* user, s32 max) {
262 return (getNerveStep(user) % max) / (f32)max;
263}
264
265f32 calcNerveRepeatDegree(const IUseNerve* user, s32 max) {
266 return calcNerveRepeatRate(user, max) * 360.0f;
267}
268
269f32 calcNerveJumpValue(const IUseNerve* user, s32 inMax, s32 upDuration, s32 release, f32 factor) {
270 return calcNerveJumpRate(user, inMax, upDuration, release) * factor;
271}
272
273f32 calcNerveStartEndValue(const IUseNerve* user, s32 inMax, s32 upDuration, s32 release, f32 start,
274 f32 end) {
275 return lerpValue(a: start, b: end, t: calcNerveStartEndRate(user, inMax, upDuration, release));
276}
277
278void initNerveState(IUseNerve* user, NerveStateBase* state, const Nerve* nerve, const char* name) {
279 state->init();
280 user->getNerveKeeper()->getStateCtrl()->addState(state, nerve, name);
281}
282
283void addNerveState(IUseNerve* user, NerveStateBase* state, const Nerve* nerve, const char* name) {
284 user->getNerveKeeper()->getStateCtrl()->addState(state, nerve, name);
285}
286
287bool updateNerveState(IUseNerve* user) {
288 return user->getNerveKeeper()->getStateCtrl()->updateCurrentState();
289}
290
291bool updateNerveStateAndNextNerve(IUseNerve* user, const Nerve* nerve) {
292 if (user->getNerveKeeper()->getStateCtrl()->updateCurrentState()) {
293 user->getNerveKeeper()->setNerve(nerve);
294 return true;
295 }
296
297 return false;
298}
299
300bool isStateEnd(const IUseNerve* user) {
301 return user->getNerveKeeper()->getStateCtrl()->isCurrentStateEnd();
302}
303
304} // namespace al
305
306namespace alNerveFunction {
307
308void setNerveAction(al::IUseNerve* user, const char* action) {
309 al::NerveKeeper* keeper = user->getNerveKeeper();
310 keeper->setNerve(keeper->getActionCtrl()->findNerve(name: action));
311}
312
313} // namespace alNerveFunction
314