1#include "Boss/Mofumofu/MofumofuWarpHole.h"
2
3#include <math/seadVector.h>
4
5#include "Library/Effect/EffectSystemInfo.h"
6#include "Library/Joint/JointControllerKeeper.h"
7#include "Library/LiveActor/ActorActionFunction.h"
8#include "Library/LiveActor/ActorInitUtil.h"
9#include "Library/LiveActor/ActorModelFunction.h"
10#include "Library/LiveActor/ActorPoseUtil.h"
11#include "Library/Math/MathUtil.h"
12#include "Library/Nerve/NerveSetupUtil.h"
13#include "Library/Nerve/NerveUtil.h"
14
15#include "Util/PlayerUtil.h"
16
17namespace {
18
19NERVE_IMPL(MofumofuWarpHole, Close);
20NERVE_IMPL(MofumofuWarpHole, Disappear);
21NERVE_IMPL(MofumofuWarpHole, Appear);
22NERVE_IMPL(MofumofuWarpHole, HideMove);
23NERVE_IMPL(MofumofuWarpHole, HideWait);
24NERVE_IMPL(MofumofuWarpHole, Wait);
25NERVE_IMPL(MofumofuWarpHole, DashSign);
26NERVE_IMPL(MofumofuWarpHole, DashSignEnd);
27NERVE_IMPL_(MofumofuWarpHole, CloseAndDisappear, Close);
28
29NERVES_MAKE_NOSTRUCT(MofumofuWarpHole, Close, Disappear, Appear, HideMove, HideWait, Wait, DashSign,
30 DashSignEnd, CloseAndDisappear);
31
32} // namespace
33
34MofumofuWarpHole::MofumofuWarpHole(const char* name)
35 : al::LiveActor(name) {} // TODO minor mismatch about storing `gap`
36
37void MofumofuWarpHole::init(const al::ActorInitInfo& actorInitInfo) {
38 al::initActorWithArchiveName(actor: this, initInfo: actorInitInfo, archiveName: "MofumofuWarpHole", suffix: nullptr);
39 al::initNerve(actor: this, nerve: &Appear, maxStates: 0);
40 al::initJointControllerKeeper(this, 1);
41 al::initJointGlobalQuatController(this, &gap, "DashSign");
42 makeActorDead();
43}
44
45void MofumofuWarpHole::appear() {
46 al::LiveActor::appear();
47 al::setNerve(user: this, nerve: &Appear);
48}
49
50void MofumofuWarpHole::disappear() {
51 al::setNerve(user: this, nerve: &Disappear);
52}
53
54void MofumofuWarpHole::close() {
55 al::setNerve(user: this, nerve: &Close);
56}
57
58void MofumofuWarpHole::closeAndDisappear() {
59 al::setNerve(user: this, nerve: &CloseAndDisappear);
60}
61
62void MofumofuWarpHole::open() {
63 al::setNerve(user: this, nerve: &Appear);
64}
65
66void MofumofuWarpHole::startHideMove() {
67 al::setNerve(user: this, nerve: &HideMove);
68}
69
70void MofumofuWarpHole::startDashSign() {
71 al::setNerve(user: this, nerve: &DashSign);
72}
73
74bool MofumofuWarpHole::isWait() const {
75 return al::isNerve(user: this, nerve: &Wait);
76}
77
78bool MofumofuWarpHole::isHideWait() const {
79 return al::isNerve(user: this, nerve: &HideWait);
80}
81
82void MofumofuWarpHole::calcDashSignFront(sead::Vector3f* front) const {
83 al::calcJointFrontDir(front, actor: this, "DashSign");
84}
85
86void MofumofuWarpHole::exeAppear() {
87 if (al::isFirstStep(user: this))
88 al::startAction(actor: this, actionName: "Appear");
89 al::setNerveAtActionEnd(actor: this, nerve: &Wait);
90}
91
92void MofumofuWarpHole::exeWait() {
93 if (al::isFirstStep(user: this))
94 al::startAction(actor: this, actionName: "Wait");
95}
96
97void MofumofuWarpHole::exeDisappear() {
98 if (al::isFirstStep(user: this))
99 al::startAction(actor: this, actionName: "Disappear");
100 if (!al::isEffectEmitting(this, "Disappear"))
101 kill();
102}
103
104void MofumofuWarpHole::exeClose() {
105 if (al::isFirstStep(user: this))
106 al::startAction(actor: this, actionName: "Disappear");
107
108 if (al::isActionEnd(actor: this)) {
109 if (al::isNerve(user: this, nerve: &CloseAndDisappear))
110 al::setNerve(user: this, nerve: &Disappear);
111 else
112 al::setNerve(user: this, nerve: &HideWait);
113 }
114}
115
116void MofumofuWarpHole::exeHideWait() {}
117
118void MofumofuWarpHole::exeHideMove() {
119 if (al::isFirstStep(user: this))
120 al::startAction(actor: this, actionName: "Move");
121}
122
123void MofumofuWarpHole::exeDashSign() {
124 if (al::isFirstStep(user: this)) {
125 al::startAction(actor: this, actionName: "DashSign");
126 al::calcQuat(quat: &gap, actor: this);
127 }
128
129 const sead::Vector3f& playerPos = rs::getPlayerPos(this);
130 const sead::Vector3f& trans = al::getTrans(actor: this);
131
132 sead::Vector3f a3 = (playerPos) - (trans);
133 al::verticalizeVec(out: &a3, vertical: al::getGravity(actor: this), vec: a3);
134 if (!al::tryNormalizeOrZero(out: &a3))
135 a3.set(al::getFront(actor: this));
136
137 al::turnVecToVecDegree(&a3, al::getFront(actor: this), a3, 55);
138 al::normalize(vec: &a3);
139
140 sead::Vector3f v21{0, 0, 0};
141 al::calcQuatFront(out: &v21, quat: gap);
142
143 f32 v13 = al::calcNerveEaseInRate(user: this, min: 100, max: 120);
144 f32 v14 = al::lerpValue(a: 0.3, b: 0.05, t: v13);
145 al::turnVecToVecRate(&a3, v21, a3, v14);
146 al::normalize(vec: &a3);
147 al::turnVecToVecRate(&v21, v21, a3, 0.15);
148 al::normalize(vec: &v21);
149
150 const sead::Vector3f& v15 = al::getGravity(actor: this);
151 sead::Vector3f v20{-v15.x, -v15.y, -v15.z};
152 al::makeQuatFrontUp(outQuat: &gap, front: v21, up: v20);
153 al::setNerveAtGreaterEqualStep(user: this, nerve: &DashSignEnd, step: 120);
154}
155
156void MofumofuWarpHole::exeDashSignEnd() {
157 if (al::isFirstStep(user: this))
158 al::startAction(actor: this, actionName: "DashSignEnd");
159 al::setNerveAtActionEnd(actor: this, nerve: &Wait);
160}
161