1#include "Library/MapObj/SeesawMapParts.h"
2
3#include "Library/LiveActor/ActorAreaFunction.h"
4#include "Library/LiveActor/ActorInitFunction.h"
5#include "Library/LiveActor/ActorInitUtil.h"
6#include "Library/LiveActor/ActorModelFunction.h"
7#include "Library/LiveActor/ActorPoseUtil.h"
8#include "Library/LiveActor/ActorSensorUtil.h"
9#include "Library/MapObj/ChildStep.h"
10#include "Library/Math/MathUtil.h"
11#include "Library/Nerve/NerveSetupUtil.h"
12#include "Library/Placement/PlacementFunction.h"
13#include "Library/Se/SeFunction.h"
14
15namespace {
16using namespace al;
17
18NERVE_ACTION_IMPL(SeesawMapParts, Wait)
19
20NERVE_ACTIONS_MAKE_STRUCT(SeesawMapParts, Wait)
21} // namespace
22
23namespace al {
24SeesawMapParts::SeesawMapParts(const char* name) : LiveActor(name) {}
25
26void SeesawMapParts::init(const ActorInitInfo& info) {
27 tryInitSubActorKeeperChildStep(actor: this, info);
28 initNerveAction(actor: this, actionName: "Wait", collector: &NrvSeesawMapParts.collector, maxStates: 0);
29 initMapPartsActor(actor: this, initInfo: info, suffix: nullptr);
30 tryGetQuatPtr(actor: this);
31
32 registerAreaHostMtx(actor: this, initInfo: info);
33 tryGetQuatPtr(actor: this);
34
35 mQuat = getQuat(actor: this);
36 calcQuatSide(out: &mSide, quat: mQuat);
37 calcQuatFront(out: &mFront, quat: mQuat);
38
39 tryGetArg(arg: &mMaxDegree, initInfo: info, key: "MaxDegree");
40 tryGetArg(arg: &mRotateAccelOn, initInfo: info, key: "RotateAccelOn");
41 tryGetArg(arg: &mRotateAccelOff, initInfo: info, key: "RotateAccelOff");
42
43 initMaterialCode(actor: this, initInfo: info);
44 createChildStep(info, parent: this, isSyncClipping: true);
45 trySyncStageSwitchAppear(actor: this);
46}
47
48inline bool isGreaterThanOrEqualToZero(f32 val) { // sead::Mathf::assertGreaterThanOrEqualToZero_ ?
49 return val >= 0.0f;
50}
51
52bool SeesawMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) {
53 if (isMsgFloorTouch(msg: message)) {
54 sead::Vector3f pos;
55 if (isMySensor(self, this))
56 pos.set(getSensorPos(other));
57 else
58 pos.set(getActorTrans(self));
59
60 f32 weight = isMsgEnemyFloorTouch(msg: message) ? 0.9f : 1.0f;
61 if (!isGreaterThanOrEqualToZero(val: (pos - getTrans(actor: this)).dot(t: mFront)))
62 weight = -weight;
63
64 mWeight += weight;
65
66 return true;
67 }
68
69 if (isMsgShowModel(msg: message)) {
70 showModelIfHide(actor: this);
71
72 return true;
73 }
74
75 if (isMsgHideModel(msg: message)) {
76 hideModelIfShow(actor: this);
77
78 return true;
79 }
80
81 if (isMsgRestart(msg: message)) {
82 appearAndSetStart();
83
84 return true;
85 }
86
87 return false;
88}
89
90void SeesawMapParts::appearAndSetStart() {
91 mRotateDegree = 0.0f;
92 mRotateSpeed = 0.0f;
93 mWeight = 0.0f;
94 mRemainingAccelOnFrames = 0;
95
96 setQuat(actor: this, quat: mQuat);
97
98 makeActorAlive();
99}
100
101void SeesawMapParts::exeWait() {
102 if (mWeight > 0.0f)
103 mRemainingAccelOnFrames = mRemainingAccelOnFrames > 59 ? 60 : mRemainingAccelOnFrames + 1;
104 else if (mWeight < 0.0f)
105 mRemainingAccelOnFrames = mRemainingAccelOnFrames < -59 ? -60 : mRemainingAccelOnFrames - 1;
106 else if (mRemainingAccelOnFrames > 0)
107 mRemainingAccelOnFrames--;
108 else if (mRemainingAccelOnFrames < 0)
109 mRemainingAccelOnFrames++;
110
111 mWeight = 0.0f;
112
113 if (mRemainingAccelOnFrames > 0)
114 mRotateSpeed += mRotateAccelOn;
115 else if (mRemainingAccelOnFrames < 0)
116 mRotateSpeed -= mRotateAccelOn;
117 else if (mRotateDegree >= 0.0f)
118 mRotateSpeed -= mRotateAccelOff;
119 else
120 mRotateSpeed += mRotateAccelOff;
121
122 mRotateSpeed *= 0.95f;
123 mRotateDegree += mRotateSpeed;
124 f32 rotateSpeed = sead::Mathf::abs(x: mRotateSpeed);
125
126 if (sead::Mathf::abs(x: mRotateDegree) > mMaxDegree) {
127 if (isSameSign(mRotateSpeed, mRotateDegree))
128 mRotateSpeed *= -0.5f;
129
130 mRotateDegree = sead::Mathf::clamp(value: mRotateDegree, low: -mMaxDegree, high: mMaxDegree);
131
132 if (rotateSpeed > 0.2f)
133 tryStartSeWithParam(this, "Stop", rotateSpeed, "");
134 }
135
136 if (rotateSpeed > 0.1f)
137 tryHoldSeWithParam(this, "Rotate", rotateSpeed, "");
138
139 rotateQuatRadian(getQuatPtr(actor: this), mQuat, mSide, sead::Mathf::deg2rad(deg: mRotateDegree));
140}
141} // namespace al
142