1#include "Layout/CounterLife.h"
2
3#include "Library/Base/StringUtil.h"
4#include "Library/Layout/LayoutActionFunction.h"
5#include "Library/Layout/LayoutInitInfo.h"
6#include "Library/Math/MathUtil.h"
7#include "Library/Nerve/NerveSetupUtil.h"
8#include "Library/Nerve/NerveUtil.h"
9
10#include "System/GameDataFunction.h"
11#include "System/GameDataHolderAccessor.h"
12
13namespace {
14NERVE_IMPL(CounterLife, End);
15NERVE_IMPL(CounterLife, None);
16NERVE_IMPL(CounterLife, Gauge);
17NERVE_IMPL(CounterLife, Appear);
18NERVE_IMPL(CounterLife, Wait);
19NERVE_IMPL(CounterLife, GaugeWait);
20
21NERVES_MAKE_NOSTRUCT(CounterLife, End, None, Gauge, Appear, Wait, GaugeWait);
22} // namespace
23
24CounterLife::CounterLife(const char* name, const char* resName, const al::LayoutInitInfo& info)
25 : al::LayoutActor(name) {
26 if (al::isEqualString(str1: resName, str2: "CounterLifeUp"))
27 mIsCounterUp = true;
28
29 al::initLayoutActor(this, info, resName, nullptr);
30 initNerve(&End, 0);
31
32 if (mIsCounterUp)
33 return;
34
35 if (GameDataFunction::getPlayerHitPoint(accessor: this) == 1)
36 al::startAction(layout: this, actionName: "Loop", paneName: "Loop");
37 else
38 al::startFreezeAction(layout: this, actionName: "Loop", frame: 0.0f, paneName: "Loop");
39}
40
41void CounterLife::appear() {
42 al::LayoutActor::appear();
43 al::setNerve(user: this, nerve: &None);
44}
45
46void CounterLife::kill() {
47 al::LayoutActor::kill();
48 al::setNerve(user: this, nerve: &End);
49}
50
51void CounterLife::startGauge(f32 goalFrame) {
52 mGoalFrame = goalFrame;
53
54 f32 maxGaugeFrames = al::getActionFrameMax(layout: this, actionName: "Gauge", paneName: "Gauge");
55 f32 maxLifeFrames = al::getActionFrameMax(layout: this, actionName: "Add", paneName: "Life");
56
57 if (mCurFrame < mGoalFrame)
58 maxLifeFrames = al::getActionFrameMax(layout: this, actionName: "Damage", paneName: "Life");
59
60 mStep = (maxGaugeFrames / 3) / maxLifeFrames;
61 al::setNerve(user: this, nerve: &Gauge);
62}
63
64void CounterLife::startGaugeWithFrame(f32 goalFrame, f32 frames) {
65 startGauge(goalFrame);
66
67 mStep = sead::Mathf::abs(x: mGoalFrame - mCurFrame) / frames;
68}
69
70void CounterLife::setEmpty() {
71 setCount(al::getActionFrameMax(layout: this, actionName: "Gauge", paneName: "Gauge"));
72}
73
74void CounterLife::setGaugeAnim() {
75 al::startFreezeAction(layout: this, actionName: "Gauge", frame: mCurFrame, paneName: "Gauge");
76}
77
78void CounterLife::setCount(f32 frame) {
79 mGoalFrame = frame;
80 mCurFrame = frame;
81
82 setGaugeAnim();
83}
84
85void CounterLife::start() {
86 if (al::isNerve(user: this, nerve: &Appear) || al::isNerve(user: this, nerve: &Wait) || al::isNerve(user: this, nerve: &Gauge))
87 return;
88
89 al::startAction(layout: this, actionName: "Appear", paneName: "Main");
90 al::LayoutActor::appear();
91 al::setNerve(user: this, nerve: &Appear);
92}
93
94void CounterLife::end() {
95 if (!al::isNerve(user: this, nerve: &End))
96 al::setNerve(user: this, nerve: &End);
97}
98
99void CounterLife::wait() {
100 if (!al::isNerve(user: this, nerve: &Wait))
101 al::setNerve(user: this, nerve: &Wait);
102}
103
104bool CounterLife::isWait() const {
105 return al::isNerve(user: this, nerve: &Wait);
106}
107
108void CounterLife::exeNone() {}
109
110void CounterLife::exeAppear() {
111 if (al::isActionEnd(layout: this, paneName: nullptr))
112 al::setNerve(user: this, nerve: &Wait);
113}
114
115void CounterLife::exeWait() {
116 if (al::isFirstStep(user: this)) {
117 al::startAction(layout: this, actionName: "Wait", paneName: "Main");
118
119 if (!mIsCounterUp) {
120 if (GameDataFunction::getPlayerHitPoint(accessor: this) == 1)
121 al::startAction(layout: this, actionName: "Loop", paneName: "Loop");
122 else
123 al::startFreezeAction(layout: this, actionName: "Loop", frame: 0.0f, paneName: "Loop");
124 }
125 }
126}
127
128void CounterLife::exeEnd() {
129 if (al::isFirstStep(user: this))
130 al::startAction(layout: this, actionName: "End", paneName: "Main");
131
132 if (al::isActionEnd(layout: this, paneName: nullptr))
133 kill();
134}
135
136void CounterLife::exeGauge() {
137 if (al::isNear(value: mGoalFrame, target: mCurFrame)) {
138 mCurFrame = mGoalFrame;
139
140 setGaugeAnim();
141 al::setNerve(user: this, nerve: &GaugeWait);
142 } else {
143 if (mGoalFrame > mCurFrame)
144 mCurFrame = sead::Mathf::min(a: mCurFrame + mStep, b: mGoalFrame);
145 else
146 mCurFrame = sead::Mathf::max(a: mCurFrame - mStep, b: mGoalFrame);
147
148 setGaugeAnim();
149 }
150}
151
152void CounterLife::exeGaugeWait() {}
153