| 1 | #include "Library/MapObj/KeyMoveMapParts.h" |
| 2 | |
| 3 | #include "Library/Area/SwitchKeepOnAreaGroup.h" |
| 4 | #include "Library/Area/SwitchOnAreaGroup.h" |
| 5 | #include "Library/Demo/DemoFunction.h" |
| 6 | #include "Library/Fluid/RippleCtrl.h" |
| 7 | #include "Library/KeyPose/KeyPoseKeeper.h" |
| 8 | #include "Library/KeyPose/KeyPoseKeeperUtil.h" |
| 9 | #include "Library/LiveActor/ActorActionFunction.h" |
| 10 | #include "Library/LiveActor/ActorAreaFunction.h" |
| 11 | #include "Library/LiveActor/ActorClippingFunction.h" |
| 12 | #include "Library/LiveActor/ActorInitUtil.h" |
| 13 | #include "Library/LiveActor/ActorModelFunction.h" |
| 14 | #include "Library/LiveActor/ActorMovementFunction.h" |
| 15 | #include "Library/LiveActor/ActorPoseUtil.h" |
| 16 | #include "Library/LiveActor/ActorSensorUtil.h" |
| 17 | #include "Library/MapObj/ChildStep.h" |
| 18 | #include "Library/Nerve/NerveSetupUtil.h" |
| 19 | #include "Library/Nerve/NerveUtil.h" |
| 20 | #include "Library/Placement/PlacementFunction.h" |
| 21 | #include "Library/Se/SeFunction.h" |
| 22 | #include "Library/Stage/StageSwitchUtil.h" |
| 23 | #include "Library/Thread/FunctorV0M.h" |
| 24 | |
| 25 | namespace al { |
| 26 | namespace { |
| 27 | NERVE_ACTION_IMPL(KeyMoveMapParts, StandBy) |
| 28 | NERVE_ACTION_IMPL(KeyMoveMapParts, Delay) |
| 29 | NERVE_ACTION_IMPL(KeyMoveMapParts, Wait) |
| 30 | NERVE_ACTION_IMPL(KeyMoveMapParts, MoveSign) |
| 31 | NERVE_ACTION_IMPL(KeyMoveMapParts, Move) |
| 32 | NERVE_ACTION_IMPL(KeyMoveMapParts, StopSign) |
| 33 | NERVE_ACTION_IMPL(KeyMoveMapParts, Stop) |
| 34 | |
| 35 | NERVE_ACTIONS_MAKE_STRUCT(KeyMoveMapParts, StandBy, Delay, Wait, MoveSign, Move, StopSign, Stop) |
| 36 | } // namespace |
| 37 | |
| 38 | KeyMoveMapParts::KeyMoveMapParts(const char* name) : LiveActor(name) {} |
| 39 | |
| 40 | void KeyMoveMapParts::init(const ActorInitInfo& info) { |
| 41 | using KeyMoveMapPartsFunctor = FunctorV0M<KeyMoveMapParts*, void (KeyMoveMapParts::*)()>; |
| 42 | |
| 43 | initNerveAction(actor: this, actionName: "Wait" , collector: &NrvKeyMoveMapParts.collector, maxStates: 0); |
| 44 | |
| 45 | const char* suffix = nullptr; |
| 46 | tryGetStringArg(arg: &suffix, initInfo: info, key: "SuffixName" ); |
| 47 | initMapPartsActor(actor: this, initInfo: info, suffix); |
| 48 | |
| 49 | tryGetQuatPtr(actor: this); |
| 50 | |
| 51 | mKeyPoseKeeper = createKeyPoseKeeper(info); |
| 52 | |
| 53 | registerAreaHostMtx(actor: this, initInfo: info); |
| 54 | |
| 55 | setKeyMoveClippingInfo(this, &mClippingOffset, mKeyPoseKeeper); |
| 56 | |
| 57 | tryGetArg(arg: &mIsFloorTouchStart, initInfo: info, key: "IsFloorTouchStart" ); |
| 58 | tryGetArg(arg: &mIsHipDropStart, initInfo: info, key: "IsHipDropStart" ); |
| 59 | tryGetArg(arg: &mIsStopKill, initInfo: info, key: "IsStopKill" ); |
| 60 | tryGetArg(arg: &mDelayTime, initInfo: info, key: "DelayTime" ); |
| 61 | |
| 62 | if (mDelayTime > 0) |
| 63 | startNerveAction(actor: this, actionName: "Delay" ); |
| 64 | |
| 65 | bool isListenStart = |
| 66 | listenStageSwitchOnStart(user: this, action: KeyMoveMapPartsFunctor(this, &KeyMoveMapParts::start)); |
| 67 | |
| 68 | if (getKeyPoseCount(keyPoseKeeper: mKeyPoseKeeper) < 2 || mIsFloorTouchStart || mIsHipDropStart || |
| 69 | isListenStart) |
| 70 | startNerveAction(actor: this, actionName: "StandBy" ); |
| 71 | |
| 72 | mSwitchKeepOnAreaGroup = tryCreateSwitchKeepOnAreaGroup(actor: this, initInfo: info); |
| 73 | mSwitchOnAreaGroup = tryCreateSwitchOnAreaGroup(actor: this, initInfo: info); |
| 74 | |
| 75 | trySyncStageSwitchAppear(actor: this); |
| 76 | tryListenStageSwitchKill(actor: this); |
| 77 | listenStageSwitchOn(user: this, eventName: "SwitchStop" , action: KeyMoveMapPartsFunctor(this, &KeyMoveMapParts::stop)); |
| 78 | listenStageSwitchOn(user: this, eventName: "SwitchReset" , |
| 79 | action: KeyMoveMapPartsFunctor(this, &KeyMoveMapParts::appearAndSetStart)); |
| 80 | |
| 81 | registActorToDemoInfo(actor: this, initInfo: info); |
| 82 | |
| 83 | tryInitSubActorKeeperChildStep(actor: this, info); |
| 84 | createChildStep(info, parent: this, isSyncClipping: true); |
| 85 | if (!isExistModel(actor: this)) |
| 86 | return; |
| 87 | |
| 88 | mRippleCtrl = RippleCtrl::tryCreate(parent: this); |
| 89 | if (mRippleCtrl != nullptr) |
| 90 | mRippleCtrl->init(info); |
| 91 | } |
| 92 | |
| 93 | void KeyMoveMapParts::start() { |
| 94 | if (!isNerve(user: this, nerve: NrvKeyMoveMapParts.StandBy.data()) || getKeyPoseCount(keyPoseKeeper: mKeyPoseKeeper) <= 1) |
| 95 | return; |
| 96 | |
| 97 | if (isExistAction(actor: this, actionName: "Start" )) |
| 98 | startAction(actor: this, actionName: "Start" ); |
| 99 | |
| 100 | if (mDelayTime >= 1) |
| 101 | startNerveAction(actor: this, actionName: "Delay" ); |
| 102 | else |
| 103 | startNerveAction(actor: this, actionName: "Wait" ); |
| 104 | } |
| 105 | |
| 106 | void KeyMoveMapParts::stop() { |
| 107 | if (isNerve(user: this, nerve: NrvKeyMoveMapParts.StopSign.data()) || |
| 108 | isNerve(user: this, nerve: NrvKeyMoveMapParts.Stop.data())) |
| 109 | return; |
| 110 | |
| 111 | if (isExistAction(actor: this, actionName: "StopSign" )) |
| 112 | startNerveAction(actor: this, actionName: "StopSign" ); |
| 113 | else |
| 114 | startNerveAction(actor: this, actionName: "Stop" ); |
| 115 | |
| 116 | if (mSeMoveName != nullptr) { |
| 117 | tryStopSe(this, mSeMoveName, -1, nullptr); |
| 118 | mSeMoveName = nullptr; |
| 119 | } |
| 120 | |
| 121 | tryStartSe(this, "MoveEnd" ); |
| 122 | } |
| 123 | |
| 124 | void KeyMoveMapParts::appearAndSetStart() { |
| 125 | resetKeyPose(keyPoseKeeper: mKeyPoseKeeper); |
| 126 | setQuat(actor: this, quat: getCurrentKeyQuat(keyPoseKeeper: mKeyPoseKeeper)); |
| 127 | setTrans(actor: this, trans: getCurrentKeyTrans(keyPoseKeeper: mKeyPoseKeeper)); |
| 128 | resetPosition(actor: this); |
| 129 | |
| 130 | if (mDelayTime >= 1) |
| 131 | startNerveAction(actor: this, actionName: "Delay" ); |
| 132 | else |
| 133 | startNerveAction(actor: this, actionName: "Wait" ); |
| 134 | |
| 135 | if (getKeyPoseCount(keyPoseKeeper: mKeyPoseKeeper) < 2 || mIsFloorTouchStart || mIsHipDropStart || |
| 136 | isValidStageSwitch(user: this, linkName: "SwitchStart" )) |
| 137 | startNerveAction(actor: this, actionName: "StandBy" ); |
| 138 | |
| 139 | makeActorAlive(); |
| 140 | } |
| 141 | |
| 142 | bool KeyMoveMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) { |
| 143 | if (mIsFloorTouchStart && isMsgFloorTouch(msg: message)) { |
| 144 | start(); |
| 145 | |
| 146 | return true; |
| 147 | } |
| 148 | |
| 149 | if (mIsHipDropStart && isMsgPlayerHipDropAll(msg: message)) { |
| 150 | start(); |
| 151 | |
| 152 | return false; |
| 153 | } |
| 154 | |
| 155 | if (isMsgShowModel(msg: message)) { |
| 156 | showModelIfHide(actor: this); |
| 157 | |
| 158 | return true; |
| 159 | } |
| 160 | |
| 161 | if (isMsgHideModel(msg: message)) { |
| 162 | hideModelIfShow(actor: this); |
| 163 | |
| 164 | return true; |
| 165 | } |
| 166 | |
| 167 | if (isMsgRestart(msg: message)) { |
| 168 | appearAndSetStart(); |
| 169 | |
| 170 | return true; |
| 171 | } |
| 172 | |
| 173 | return false; |
| 174 | } |
| 175 | |
| 176 | void KeyMoveMapParts::control() { |
| 177 | if (mSwitchKeepOnAreaGroup != nullptr) |
| 178 | mSwitchKeepOnAreaGroup->update(playerPos: getTrans(actor: this)); |
| 179 | |
| 180 | if (mSwitchOnAreaGroup != nullptr) |
| 181 | mSwitchOnAreaGroup->update(trans: getTrans(actor: this)); |
| 182 | |
| 183 | if (mRippleCtrl != nullptr) |
| 184 | mRippleCtrl->update(); |
| 185 | } |
| 186 | |
| 187 | void KeyMoveMapParts::appearAndSetEnd() { |
| 188 | resetKeyPose(keyPoseKeeper: mKeyPoseKeeper); |
| 189 | while (!isLastKey(keyPoseKeeper: mKeyPoseKeeper)) |
| 190 | nextKeyPose(keyPoseKeeper: mKeyPoseKeeper); |
| 191 | |
| 192 | setQuat(actor: this, quat: getCurrentKeyQuat(keyPoseKeeper: mKeyPoseKeeper)); |
| 193 | setTrans(actor: this, trans: getCurrentKeyTrans(keyPoseKeeper: mKeyPoseKeeper)); |
| 194 | resetPosition(actor: this); |
| 195 | |
| 196 | startNerveAction(actor: this, actionName: "Stop" ); |
| 197 | |
| 198 | if (getKeyPoseCount(keyPoseKeeper: mKeyPoseKeeper) < 2 || mIsFloorTouchStart || mIsHipDropStart || |
| 199 | isValidStageSwitch(user: this, linkName: "SwitchStart" )) |
| 200 | startNerveAction(actor: this, actionName: "StandBy" ); |
| 201 | |
| 202 | makeActorAlive(); |
| 203 | } |
| 204 | |
| 205 | void KeyMoveMapParts::exeStandBy() {} |
| 206 | |
| 207 | void KeyMoveMapParts::exeDelay() { |
| 208 | if (isGreaterEqualStep(user: this, step: mDelayTime - 1)) |
| 209 | startNerveAction(actor: this, actionName: "Wait" ); |
| 210 | } |
| 211 | |
| 212 | void KeyMoveMapParts::exeWait() { |
| 213 | if (isFirstStep(user: this)) { |
| 214 | s32 moveWaitTime = calcKeyMoveWaitTime(keyPoseKeeper: mKeyPoseKeeper); |
| 215 | if (moveWaitTime > -1) |
| 216 | mKeyMoveWaitTime = moveWaitTime; |
| 217 | } |
| 218 | |
| 219 | if (isGreaterEqualStep(user: this, step: mKeyMoveWaitTime)) |
| 220 | setWaitEndNerve(); |
| 221 | } |
| 222 | |
| 223 | void KeyMoveMapParts::setWaitEndNerve() { |
| 224 | if (isRestart(keyPoseKeeper: mKeyPoseKeeper)) { |
| 225 | restartKeyPose(keyPoseKeeper: mKeyPoseKeeper, pos: getTransPtr(actor: this), orientation: getQuatPtr(actor: this)); |
| 226 | resetPosition(actor: this); |
| 227 | startNerveAction(actor: this, actionName: "Wait" ); |
| 228 | |
| 229 | return; |
| 230 | } |
| 231 | |
| 232 | if (isMoveSignKey(keyPoseKeeper: mKeyPoseKeeper) && isExistAction(actor: this, actionName: "MoveKeySign" )) { |
| 233 | startNerveAction(actor: this, actionName: "MoveSign" ); |
| 234 | |
| 235 | return; |
| 236 | } |
| 237 | |
| 238 | startNerveAction(actor: this, actionName: "Move" ); |
| 239 | } |
| 240 | |
| 241 | void KeyMoveMapParts::exeMoveSign() { |
| 242 | if (isFirstStep(user: this)) |
| 243 | startAction(actor: this, actionName: "MoveKeySign" ); |
| 244 | |
| 245 | if (isActionEnd(actor: this)) |
| 246 | startNerveAction(actor: this, actionName: "Move" ); |
| 247 | } |
| 248 | |
| 249 | void KeyMoveMapParts::exeMove() { |
| 250 | if (isFirstStep(user: this)) { |
| 251 | if (isExistAction(actor: this, actionName: "MoveLoop" )) |
| 252 | tryStartActionIfNotPlaying(actor: this, actionName: "MoveLoop" ); |
| 253 | |
| 254 | mKeyMoveMoveTime = calcKeyMoveMoveTime(keyPoseKeeper: mKeyPoseKeeper); |
| 255 | |
| 256 | mSeMoveName = getSeNameByIndex(index: mKeyPoseKeeper->getKeyPoseCurrentIdx()); |
| 257 | if (mSeMoveName != nullptr) |
| 258 | tryStartSe(this, mSeMoveName); |
| 259 | } |
| 260 | |
| 261 | f32 rate = calcNerveRate(user: this, max: mKeyMoveMoveTime); |
| 262 | calcLerpKeyTrans(out: getTransPtr(actor: this), keyPoseKeeper: mKeyPoseKeeper, rate); |
| 263 | calcSlerpKeyQuat(out: getQuatPtr(actor: this), keyPoseKeeper: mKeyPoseKeeper, rate); |
| 264 | |
| 265 | if (isGreaterEqualStep(user: this, step: mKeyMoveMoveTime)) { |
| 266 | nextKeyPose(keyPoseKeeper: mKeyPoseKeeper); |
| 267 | if (isStop(keyPoseKeeper: mKeyPoseKeeper)) |
| 268 | stop(); |
| 269 | else if (calcKeyMoveWaitTime(keyPoseKeeper: mKeyPoseKeeper) == 0) |
| 270 | setWaitEndNerve(); |
| 271 | else { |
| 272 | startNerveAction(actor: this, actionName: "Wait" ); |
| 273 | if (mSeMoveName != nullptr) { |
| 274 | tryStopSe(this, mSeMoveName, -1, nullptr); |
| 275 | mSeMoveName = nullptr; |
| 276 | } |
| 277 | |
| 278 | tryStartSe(this, "MoveEnd" ); |
| 279 | } |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | void KeyMoveMapParts::exeStopSign() { |
| 284 | if (isFirstStep(user: this)) |
| 285 | startAction(actor: this, actionName: "StopSign" ); |
| 286 | |
| 287 | if (isActionEnd(actor: this)) |
| 288 | startNerveAction(actor: this, actionName: "Stop" ); |
| 289 | } |
| 290 | |
| 291 | void KeyMoveMapParts::exeStop() { |
| 292 | if (isFirstStep(user: this)) { |
| 293 | if (isExistAction(actor: this, actionName: "Stop" )) |
| 294 | tryStartAction(actor: this, actionName: "Stop" ); |
| 295 | |
| 296 | if (isInvalidClipping(this)) |
| 297 | validateClipping(actor: this); |
| 298 | |
| 299 | if (mIsStopKill) |
| 300 | kill(); |
| 301 | } |
| 302 | } |
| 303 | } // namespace al |
| 304 | |