1#include "Library/MapObj/ConveyerMapParts.h"
2
3#include "Library/LiveActor/ActorClippingFunction.h"
4#include "Library/LiveActor/ActorInitFunction.h"
5#include "Library/LiveActor/ActorInitUtil.h"
6#include "Library/LiveActor/ActorPoseUtil.h"
7#include "Library/LiveActor/ActorSensorUtil.h"
8#include "Library/LiveActor/LiveActorGroup.h"
9#include "Library/MapObj/ConveyerStep.h"
10#include "Library/Math/MathUtil.h"
11#include "Library/Nerve/NerveSetupUtil.h"
12#include "Library/Nerve/NerveUtil.h"
13#include "Library/Placement/PlacementFunction.h"
14#include "Library/Stage/StageSwitchUtil.h"
15#include "Library/Thread/FunctorV0M.h"
16#include "Project/LiveActor/ConveyerKeyKeeper.h"
17
18namespace {
19using namespace al;
20
21NERVE_IMPL(ConveyerMapParts, Move)
22NERVE_IMPL(ConveyerMapParts, StandBy)
23
24NERVES_MAKE_STRUCT(ConveyerMapParts, Move, StandBy)
25} // namespace
26
27namespace al {
28inline void registerConveyerSteps(DeriveActorGroup<ConveyerStep>* conveyerStepGroup,
29 const ActorInitInfo& info) {
30 for (s32 i = 0; i < conveyerStepGroup->getMaxActorCount(); i++) {
31 ConveyerStep* conveyerStep = new ConveyerStep("コンベア足場");
32 initCreateActorWithPlacementInfo(actor: conveyerStep, initInfo: info);
33 conveyerStepGroup->registerActor(conveyerStep);
34 }
35}
36
37ConveyerMapParts::ConveyerMapParts(const char* name) : LiveActor(name) {}
38
39void ConveyerMapParts::init(const ActorInitInfo& info) {
40 using ConveyerMapPartsFunctor = FunctorV0M<ConveyerMapParts*, void (ConveyerMapParts::*)()>;
41
42 initActorSceneInfo(actor: this, info);
43 initExecutorMapObjMovement(actor: this, info);
44 initActorPoseTQSV(actor: this);
45 tryGetQuatPtr(actor: this);
46 initActorSRT(actor: this, info);
47 initActorClipping(actor: this, initInfo: info);
48 initGroupClipping(actor: this, initInfo: info);
49 initNerve(actor: this, nerve: &NrvConveyerMapParts.Move, maxStates: 0);
50 initStageSwitch(this, info);
51
52 mConveyerKeyKeeper = new ConveyerKeyKeeper();
53 mConveyerKeyKeeper->init(info);
54
55 tryGetArg(arg: &mMoveSpeed, initInfo: info, key: "MoveSpeed");
56 tryGetArg(arg: &mPartsInterval, initInfo: info, key: "PartsInterval");
57 tryGetArg(arg: &mIsRideOnlyMove, initInfo: info, key: "IsRideOnlyMove");
58
59 if (mPartsInterval < 10.0f)
60 mPartsInterval = 10.0f;
61
62 f32 totalMoveDistance = mConveyerKeyKeeper->getTotalMoveDistance();
63 if (mConveyerKeyKeeper->getConveyerKeyCount() > 1)
64 isNearZero(value: totalMoveDistance);
65
66 s32 groupCount = (s32)(totalMoveDistance / mPartsInterval) + 1;
67 mMaxCoord = mPartsInterval * (f32)groupCount;
68
69 f32 startRate = 0.0f;
70 tryGetArg(arg: &startRate, initInfo: info, key: "StartRate");
71
72 f32 rate = mPartsInterval * startRate;
73 mOffsetCoord = modf(a: rate + mPartsInterval, b: mPartsInterval) + 0.0f;
74
75 mConveyerStepGroup = new DeriveActorGroup<ConveyerStep>("コンベア足場リスト", groupCount);
76 registerConveyerSteps(conveyerStepGroup: mConveyerStepGroup, info);
77
78 for (s32 i = 0; i < groupCount; i++) {
79 ConveyerStep* conveyerStep = mConveyerStepGroup->getDeriveActor(idx: i);
80 conveyerStep->setHost(this);
81 conveyerStep->setConveyerKeyKeeper(conveyerKeyKeeper: mConveyerKeyKeeper, coord: mMaxCoord);
82 conveyerStep->setTransAndResetByCoord((f32)i * mPartsInterval + mOffsetCoord);
83 }
84
85 f32 clippingRadius = 0.0f;
86 mConveyerKeyKeeper->calcClippingSphere(clippingTrans: &mClippingTrans, clippingRadius: &clippingRadius,
87 offset: getClippingRadius(actor: mConveyerStepGroup->getActor(idx: 0)));
88 setClippingInfo(actor: this, clippingRadius, &mClippingTrans);
89
90 bool isListenStartOnOff =
91 listenStageSwitchOnOffStart(user: this, actionOn: ConveyerMapPartsFunctor(this, &ConveyerMapParts::start),
92 actionOff: ConveyerMapPartsFunctor(this, &ConveyerMapParts::stop));
93 if (isListenStartOnOff)
94 setNerve(user: this, nerve: &NrvConveyerMapParts.StandBy);
95
96 makeActorAlive();
97}
98
99void ConveyerMapParts::start() {
100 if (!isNerve(user: this, nerve: &NrvConveyerMapParts.StandBy))
101 return;
102
103 setNerve(user: this, nerve: &NrvConveyerMapParts.Move);
104}
105
106void ConveyerMapParts::stop() {
107 if (!isNerve(user: this, nerve: &NrvConveyerMapParts.Move))
108 return;
109
110 setNerve(user: this, nerve: &NrvConveyerMapParts.StandBy);
111}
112
113bool ConveyerMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) {
114 if (isMsgFloorTouch(msg: message)) {
115 mAddRideActiveFrames = 2;
116
117 return true;
118 }
119
120 return false;
121}
122
123void ConveyerMapParts::control() {
124 if (mAddRideActiveFrames > 0) {
125 if (mRideActiveFrames < mMaxRideActiveFrames)
126 mRideActiveFrames++;
127 else
128 mRideActiveFrames = mMaxRideActiveFrames;
129
130 mAddRideActiveFrames--;
131
132 return;
133 }
134
135 if (mRideActiveFrames != 0)
136 mRideActiveFrames--;
137}
138
139void ConveyerMapParts::startClipped() {
140 LiveActor::startClipped();
141
142 for (s32 i = 0; i < mConveyerStepGroup->getActorCount(); i++)
143 offDrawClipping(actor: mConveyerStepGroup->getActor(idx: i));
144}
145
146void ConveyerMapParts::endClipped() {
147 LiveActor::endClipped();
148
149 for (s32 i = 0; i < mConveyerStepGroup->getActorCount(); i++)
150 onDrawClipping(actor: mConveyerStepGroup->getActor(idx: i));
151}
152
153void ConveyerMapParts::exeStandBy() {}
154
155void ConveyerMapParts::exeMove() {
156 if (!mIsRideOnlyMove || mRideActiveFrames >= 1) {
157 f32 speedFactor =
158 mIsRideOnlyMove ? (f32)mRideActiveFrames / (f32)mMaxRideActiveFrames : 1.0f;
159 mOffsetCoord = modf(a: mOffsetCoord + speedFactor * mMoveSpeed + mMaxCoord, b: mMaxCoord) + 0.0f;
160
161 bool isForwards = mMoveSpeed >= 0.0f;
162 s32 actorCount = mConveyerStepGroup->getActorCount();
163 for (s32 i = 0; i < actorCount; i++)
164 mConveyerStepGroup->getDeriveActor(idx: i)->setTransByCoord(
165 coord: mPartsInterval * (f32)i + mOffsetCoord, isForwards);
166 }
167}
168} // namespace al
169