1#include "Layout/FilterFly.h"
2
3#include "Library/Layout/LayoutActionFunction.h"
4#include "Library/Layout/LayoutActorUtil.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
10namespace {
11NERVE_IMPL(FilterFly, Wait);
12NERVE_IMPL(FilterFly, WaitEnd);
13NERVE_IMPL(FilterFly, Move);
14
15NERVES_MAKE_NOSTRUCT(FilterFly, Wait, WaitEnd, Move);
16} // namespace
17
18const sead::Vector2f sStartingPosition = {600.0f, -300.0f};
19
20FilterFly::FilterFly(const char* name, const al::LayoutInitInfo& info, const char* suffix)
21 : al::LayoutActor(name) {
22 al::initLayoutActor(this, info, "FilterFly", suffix);
23 initNerve(&Wait, 0);
24 al::setPaneLocalTrans(this, "RootPane", sStartingPosition);
25 kill();
26}
27
28void FilterFly::exeWait() {
29 if (al::isFirstStep(user: this))
30 al::startAction(layout: this, actionName: "Wait", paneName: 0);
31 if (al::isGreaterStep(user: this, step: 180))
32 al::setNerve(user: this, nerve: &WaitEnd);
33}
34
35void FilterFly::exeWaitEnd() {}
36
37void FilterFly::exeMove() {
38 if (al::isFirstStep(user: this))
39 al::startAction(layout: this, actionName: "Loop", paneName: 0);
40
41 sead::Vector2f currentPos = {al::getLocalTrans(this).x, al::getLocalTrans(this).y};
42 sead::Vector2f direction = mTargetPos - currentPos;
43
44 f32 len = direction.length();
45 if (!(len > 15.0f)) {
46 al::setNerve(user: this, nerve: &Wait);
47 return;
48 }
49
50 if (al::tryNormalizeOrZero(vec: &direction)) {
51 mVelocity += direction * 0.9f;
52 currentPos += mVelocity;
53 al::setPaneLocalTrans(this, "RootPane", currentPos);
54
55 f32 angleY = al::calcAngleDegree(a: direction, b: sead::Vector2f::ey);
56
57 al::setPaneLocalRotate(
58 this, "RootPane",
59 {0, 0, al::calcAngleDegree(a: direction, b: sead::Vector2f::ex) < 90.0f ? -angleY : angleY});
60 }
61 mVelocity *= 0.98f;
62}
63
64void FilterFly::move(const sead::Vector2f& target) {
65 mTargetPos.set(target);
66 if (!al::isNerve(user: this, nerve: &Move))
67 return al::setNerve(user: this, nerve: &Move);
68}
69
70bool FilterFly::isWaitEnd() const {
71 return al::isNerve(user: this, nerve: &WaitEnd);
72}
73