1#include "MapObj/WeightSwitch.h"
2
3#include "Library/Camera/CameraUtil.h"
4#include "Library/Collision/PartsConnector.h"
5#include "Library/LiveActor/ActorActionFunction.h"
6#include "Library/LiveActor/ActorClippingFunction.h"
7#include "Library/LiveActor/ActorCollisionFunction.h"
8#include "Library/LiveActor/ActorInitFunction.h"
9#include "Library/LiveActor/ActorInitUtil.h"
10#include "Library/LiveActor/ActorSensorUtil.h"
11#include "Library/Nerve/NerveSetupUtil.h"
12#include "Library/Nerve/NerveUtil.h"
13#include "Library/Obj/CollisionObj.h"
14#include "Library/Obj/PartsFunction.h"
15#include "Library/Placement/PlacementFunction.h"
16#include "Library/Stage/StageSwitchUtil.h"
17
18#include "Item/Shine.h"
19#include "Util/DemoUtil.h"
20#include "Util/ItemUtil.h"
21#include "Util/SensorMsgFunction.h"
22
23namespace {
24NERVE_IMPL(WeightSwitch, OffWait);
25NERVE_IMPL(WeightSwitch, OnWait);
26NERVE_IMPL(WeightSwitch, OnDemoWaitStart);
27NERVE_IMPL(WeightSwitch, OnDemoWaitCameraInterpoling);
28NERVE_IMPL(WeightSwitch, OnDemo);
29NERVE_IMPL(WeightSwitch, Off);
30NERVE_IMPL(WeightSwitch, On);
31
32NERVES_MAKE_NOSTRUCT(WeightSwitch, OnDemoWaitCameraInterpoling, OnDemo, Off);
33NERVES_MAKE_STRUCT(WeightSwitch, OffWait, OnWait, OnDemoWaitStart, On);
34} // namespace
35
36WeightSwitch::WeightSwitch(const char* actorName) : al::LiveActor(actorName) {}
37
38void WeightSwitch::init(const al::ActorInitInfo& info) {
39 al::initActorWithArchiveName(actor: this, initInfo: info, archiveName: "TrampleSwitch", suffix: nullptr);
40 al::initNerve(actor: this, nerve: &NrvWeightSwitch.OffWait, maxStates: 0);
41
42 mMtxConnector = al::createMtxConnector(actor: this);
43
44 bool isValidObjectCamera = false;
45 al::tryGetArg(arg: &isValidObjectCamera, initInfo: info, key: "IsValidObjectCamera");
46 if (isValidObjectCamera)
47 mDemoCamera = al::initDemoObjectCamera(user: this, actorInitInfo: info, nullptr, "固定");
48
49 mShine = rs::tryInitLinkShine(info, name: "ShineActor", linkIndex: 0);
50 mCollisionBody = al::createCollisionObj(parent: this, info, collisionFileName: "TrampleSwitch_Body",
51 hitSensor: al::getHitSensor(this, "PPanel"), joinMtxName: nullptr, suffix: nullptr);
52 mCollisionBody->makeActorAlive();
53 al::validateCollisionParts(mCollisionBody);
54
55 makeActorAlive();
56}
57
58void WeightSwitch::initAfterPlacement() {
59 al::attachMtxConnectorToCollision(mtxConnector: mMtxConnector, actor: this, false);
60}
61
62void WeightSwitch::control() {
63 al::connectPoseQT(actor: this, mtxConnector: mMtxConnector);
64}
65
66void WeightSwitch::exeOffWait() {
67 if (al::isFirstStep(user: this)) {
68 al::validateClipping(actor: this);
69 al::validateHitSensors(this);
70 al::startAction(actor: this, actionName: "OffWait");
71 }
72}
73
74void WeightSwitch::exeOn() {
75 if (al::isFirstStep(user: this))
76 al::startAction(actor: this, actionName: "On");
77
78 if (al::isActionEnd(actor: this)) {
79 if (mDemoCamera) {
80 al::setNerve(user: this, nerve: &NrvWeightSwitch.OnDemoWaitStart);
81 return;
82 }
83 al::tryOnStageSwitch(user: this, linkName: "SwitchTrampleOn");
84
85 if (mShine)
86 al::sendMsgRestart(receiver: mShine);
87 al::setNerve(user: this, nerve: &NrvWeightSwitch.OnWait);
88 }
89}
90
91void WeightSwitch::exeOnDemoWaitStart() {
92 if (rs::requestStartDemoNormal(this, false)) {
93 al::startCamera(user: this, ticket: mDemoCamera, unk: -1);
94 al::tryOnStageSwitch(user: this, linkName: "SwitchTrampleOn");
95 al::setNerve(user: this, nerve: &OnDemoWaitCameraInterpoling);
96 }
97}
98
99void WeightSwitch::exeOnDemoWaitCameraInterpoling() {
100 if (!al::isActiveCameraInterpole(user: this, 0))
101 al::setNerve(user: this, nerve: &OnDemo);
102}
103
104void WeightSwitch::exeOnDemo() {
105 if (al::isFirstStep(user: this) && mShine) {
106 al::sendMsgRestart(receiver: mShine);
107 rs::addDemoActor(mShine, false);
108 }
109 if (al::isActionPlaying(actor: this, actionName: "On") && al::isActionEnd(actor: this))
110 al::startAction(actor: this, actionName: "OnWait");
111
112 if (al::isGreaterEqualStep(user: this, step: 150)) {
113 al::endCamera(user: this, ticket: mDemoCamera, -1, 0);
114 rs::requestEndDemoNormal(this);
115 al::setNerve(user: this, nerve: &NrvWeightSwitch.OnWait);
116 }
117}
118
119void WeightSwitch::exeOnWait() {
120 if (al::isFirstStep(user: this))
121 al::startAction(actor: this, actionName: "OnWait");
122
123 mWeight--;
124
125 if (mWeight <= 0) {
126 al::tryOffStageSwitch(user: this, linkName: "SwitchTrampleOn");
127 if (mShine)
128 mShine->kill();
129 al::setNerve(user: this, nerve: &Off);
130 }
131}
132
133void WeightSwitch::exeOff() {
134 if (al::isFirstStep(user: this))
135 al::startAction(actor: this, actionName: "Off");
136
137 if (al::isActionEnd(actor: this))
138 al::setNerve(user: this, nerve: &NrvWeightSwitch.OffWait);
139}
140
141bool WeightSwitch::receiveMsg(const al::SensorMsg* message, al::HitSensor* other,
142 al::HitSensor* self) {
143 if (al::isSensorName(self, "PlayerRegard"))
144 return rs::isMsgPlayerDisregardTargetMarker(message);
145 if (!al::isNerve(user: this, nerve: &NrvWeightSwitch.OffWait) || al::isSensorName(self, "PPanel")) {
146 if (al::isMsgPlayerTouch(msg: message))
147 mWeight = 7;
148 else if (al::isMsgEnemyFloorTouch(msg: message))
149 mWeight = 20;
150 else if (rs::isMsgCapHipDrop(message))
151 mWeight = 28;
152 if (mWeight < 1)
153 return false;
154 if (al::isNerve(user: this, nerve: &NrvWeightSwitch.OffWait)) {
155 al::invalidateClipping(actor: this);
156 al::setNerve(user: this, nerve: &NrvWeightSwitch.On);
157 return true;
158 }
159 }
160 return false;
161}
162