1#include "MapObj/MeganeMapParts.h"
2
3#include "Library/LiveActor/ActorClippingFunction.h"
4#include "Library/LiveActor/ActorInitUtil.h"
5#include "Library/LiveActor/ActorModelFunction.h"
6#include "Library/LiveActor/ActorSensorUtil.h"
7#include "Library/LiveActor/LiveActorFunction.h"
8#include "Library/Nerve/NerveSetupUtil.h"
9#include "Library/Nerve/NerveUtil.h"
10#include "Library/Placement/PlacementFunction.h"
11
12#include "Util/PlayerUtil.h"
13
14namespace {
15NERVE_IMPL(MeganeMapParts, Hide);
16NERVE_IMPL(MeganeMapParts, Show);
17NERVE_IMPL(MeganeMapParts, SwitchAppear);
18NERVE_IMPL(MeganeMapParts, On);
19NERVE_IMPL(MeganeMapParts, Off);
20
21NERVES_MAKE_STRUCT(MeganeMapParts, Hide, Show, SwitchAppear, On, Off);
22} // namespace
23
24MeganeMapParts::MeganeMapParts(const char* name) : al::LiveActor(name) {}
25
26void MeganeMapParts::init(const al::ActorInitInfo& info) {
27 const char* modelName = nullptr;
28 if (alPlacementFunction::tryGetModelName(modelName: &modelName, initInfo: info))
29 al::initActorWithArchiveName(actor: this, initInfo: info, archiveName: modelName, suffix: nullptr);
30 else
31 al::initActor(actor: this, initInfo: info);
32
33 al::initNerve(actor: this, nerve: &NrvMeganeMapParts.Hide, maxStates: 0);
34 al::setMaterialProgrammable(this);
35 makeActorAlive();
36 al::hideModelIfShow(actor: this);
37}
38
39bool MeganeMapParts::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
40 al::HitSensor* self) {
41 if (al::isMsgRestart(msg: message)) {
42 appear();
43 al::showModelIfHide(actor: this);
44 al::invalidateClipping(actor: this);
45
46 mAlpha = 1.0f;
47 updateAlpha();
48
49 if (rs::isPlayerEnableToSeeOddSpace(this))
50 al::setNerve(user: this, nerve: &NrvMeganeMapParts.Show);
51 else
52 al::setNerve(user: this, nerve: &NrvMeganeMapParts.SwitchAppear);
53
54 return true;
55 }
56 return false;
57}
58
59void MeganeMapParts::control() {
60 al::setModelMaterialParameterF32(actor: this, al::getMaterialName(actor: this, 0), "const_single0", mAlpha);
61}
62
63void MeganeMapParts::updateAlpha() {
64 if (!al::isExistSubActorKeeper(actor: this))
65 return;
66
67 f32 alpha = sead::Mathf::clamp(value: (mAlpha - (7.0f / 15.0f)) / (8.0f / 15.0f), low: 0.0f, high: 1.0f);
68 s32 subActorNum = al::getSubActorNum(actor: this);
69 for (s32 i = 0; i < subActorNum; ++i)
70 al::setModelAlphaMask(actor: al::getSubActor(actor: this, index: i), alpha);
71}
72
73void MeganeMapParts::exeHide() {
74 if (al::isFirstStep(user: this))
75 al::hideModelIfShow(actor: this);
76
77 if (rs::isPlayerEnableToSeeOddSpace(this))
78 al::setNerve(user: this, nerve: &NrvMeganeMapParts.On);
79}
80
81void MeganeMapParts::exeOn() {
82 if (al::isFirstStep(user: this))
83 al::showModelIfHide(actor: this);
84
85 mAlpha = sead::Mathf::min(a: mAlpha + (1.0f / 30.0f), b: 1.0f);
86 if (!rs::isPlayerEnableToSeeOddSpace(this)) {
87 al::setNerve(user: this, nerve: &NrvMeganeMapParts.Off);
88 return;
89 }
90
91 updateAlpha();
92 if (mAlpha == 1.0f)
93 al::setNerve(user: this, nerve: &NrvMeganeMapParts.Show);
94}
95
96void MeganeMapParts::exeShow() {
97 if (!rs::isPlayerEnableToSeeOddSpace(this))
98 al::setNerve(user: this, nerve: &NrvMeganeMapParts.Off);
99}
100
101void MeganeMapParts::exeOff() {
102 mAlpha = sead::Mathf::clampMin(val: mAlpha - (1.0f / 30.0f), min_: 0.0f);
103 if (rs::isPlayerEnableToSeeOddSpace(this)) {
104 al::setNerve(user: this, nerve: &NrvMeganeMapParts.On);
105 return;
106 }
107
108 updateAlpha();
109 if (mAlpha == 0.0f)
110 al::setNerve(user: this, nerve: &NrvMeganeMapParts.Hide);
111}
112
113void MeganeMapParts::exeSwitchAppear() {
114 mAlpha = sead::Mathf::clampMax(val: (40 - (u32)al::getNerveStep(user: this)) / 40.0f, max_: 1.0f);
115 updateAlpha();
116
117 if (rs::isPlayerEnableToSeeOddSpace(this)) {
118 al::setNerve(user: this, nerve: &NrvMeganeMapParts.On);
119 return;
120 }
121
122 if (al::isGreaterEqualStep(user: this, step: 40)) {
123 mAlpha = 0.0f;
124 al::validateClipping(actor: this);
125 al::setNerve(user: this, nerve: &NrvMeganeMapParts.Hide);
126 }
127}
128