#include "Library/MapObj/KeyMoveMapParts.h" #include "Library/Area/SwitchKeepOnAreaGroup.h" #include "Library/Area/SwitchOnAreaGroup.h" #include "Library/Demo/DemoFunction.h" #include "Library/Fluid/RippleCtrl.h" #include "Library/KeyPose/KeyPoseKeeper.h" #include "Library/KeyPose/KeyPoseKeeperUtil.h" #include "Library/LiveActor/ActorActionFunction.h" #include "Library/LiveActor/ActorAreaFunction.h" #include "Library/LiveActor/ActorClippingFunction.h" #include "Library/LiveActor/ActorInitUtil.h" #include "Library/LiveActor/ActorModelFunction.h" #include "Library/LiveActor/ActorMovementFunction.h" #include "Library/LiveActor/ActorPoseUtil.h" #include "Library/LiveActor/ActorSensorUtil.h" #include "Library/MapObj/ChildStep.h" #include "Library/Nerve/NerveSetupUtil.h" #include "Library/Nerve/NerveUtil.h" #include "Library/Placement/PlacementFunction.h" #include "Library/Se/SeFunction.h" #include "Library/Stage/StageSwitchUtil.h" #include "Library/Thread/FunctorV0M.h" namespace al { namespace { NERVE_ACTION_IMPL(KeyMoveMapParts, StandBy) NERVE_ACTION_IMPL(KeyMoveMapParts, Delay) NERVE_ACTION_IMPL(KeyMoveMapParts, Wait) NERVE_ACTION_IMPL(KeyMoveMapParts, MoveSign) NERVE_ACTION_IMPL(KeyMoveMapParts, Move) NERVE_ACTION_IMPL(KeyMoveMapParts, StopSign) NERVE_ACTION_IMPL(KeyMoveMapParts, Stop) NERVE_ACTIONS_MAKE_STRUCT(KeyMoveMapParts, StandBy, Delay, Wait, MoveSign, Move, StopSign, Stop) } // namespace KeyMoveMapParts::KeyMoveMapParts(const char* name) : LiveActor(name) {} void KeyMoveMapParts::init(const ActorInitInfo& info) { using KeyMoveMapPartsFunctor = FunctorV0M; initNerveAction(this, "Wait", &NrvKeyMoveMapParts.collector, 0); const char* suffix = nullptr; tryGetStringArg(&suffix, info, "SuffixName"); initMapPartsActor(this, info, suffix); tryGetQuatPtr(this); mKeyPoseKeeper = createKeyPoseKeeper(info); registerAreaHostMtx(this, info); setKeyMoveClippingInfo(this, &mClippingOffset, mKeyPoseKeeper); tryGetArg(&mIsFloorTouchStart, info, "IsFloorTouchStart"); tryGetArg(&mIsHipDropStart, info, "IsHipDropStart"); tryGetArg(&mIsStopKill, info, "IsStopKill"); tryGetArg(&mDelayTime, info, "DelayTime"); if (mDelayTime > 0) startNerveAction(this, "Delay"); bool isListenStart = listenStageSwitchOnStart(this, KeyMoveMapPartsFunctor(this, &KeyMoveMapParts::start)); if (getKeyPoseCount(mKeyPoseKeeper) < 2 || mIsFloorTouchStart || mIsHipDropStart || isListenStart) startNerveAction(this, "StandBy"); mSwitchKeepOnAreaGroup = tryCreateSwitchKeepOnAreaGroup(this, info); mSwitchOnAreaGroup = tryCreateSwitchOnAreaGroup(this, info); trySyncStageSwitchAppear(this); tryListenStageSwitchKill(this); listenStageSwitchOn(this, "SwitchStop", KeyMoveMapPartsFunctor(this, &KeyMoveMapParts::stop)); listenStageSwitchOn(this, "SwitchReset", KeyMoveMapPartsFunctor(this, &KeyMoveMapParts::appearAndSetStart)); registActorToDemoInfo(this, info); tryInitSubActorKeeperChildStep(this, info); createChildStep(info, this, true); if (!isExistModel(this)) return; mRippleCtrl = RippleCtrl::tryCreate(this); if (mRippleCtrl) mRippleCtrl->init(info); } void KeyMoveMapParts::start() { if (!isNerve(this, NrvKeyMoveMapParts.StandBy.data()) || getKeyPoseCount(mKeyPoseKeeper) <= 1) return; if (isExistAction(this, "Start")) startAction(this, "Start"); if (mDelayTime >= 1) startNerveAction(this, "Delay"); else startNerveAction(this, "Wait"); } void KeyMoveMapParts::stop() { if (isNerve(this, NrvKeyMoveMapParts.StopSign.data()) || isNerve(this, NrvKeyMoveMapParts.Stop.data())) return; if (isExistAction(this, "StopSign")) startNerveAction(this, "StopSign"); else startNerveAction(this, "Stop"); if (mSeMoveName) { tryStopSe(this, mSeMoveName, -1, nullptr); mSeMoveName = nullptr; } tryStartSe(this, "MoveEnd"); } void KeyMoveMapParts::appearAndSetStart() { resetKeyPose(mKeyPoseKeeper); setQuat(this, getCurrentKeyQuat(mKeyPoseKeeper)); setTrans(this, getCurrentKeyTrans(mKeyPoseKeeper)); resetPosition(this); if (mDelayTime >= 1) startNerveAction(this, "Delay"); else startNerveAction(this, "Wait"); if (getKeyPoseCount(mKeyPoseKeeper) < 2 || mIsFloorTouchStart || mIsHipDropStart || isValidStageSwitch(this, "SwitchStart")) startNerveAction(this, "StandBy"); makeActorAlive(); } bool KeyMoveMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) { if (mIsFloorTouchStart && isMsgFloorTouch(message)) { start(); return true; } if (mIsHipDropStart && isMsgPlayerHipDropAll(message)) { start(); return false; } if (isMsgShowModel(message)) { showModelIfHide(this); return true; } if (isMsgHideModel(message)) { hideModelIfShow(this); return true; } if (isMsgRestart(message)) { appearAndSetStart(); return true; } return false; } void KeyMoveMapParts::control() { if (mSwitchKeepOnAreaGroup) mSwitchKeepOnAreaGroup->update(getTrans(this)); if (mSwitchOnAreaGroup) mSwitchOnAreaGroup->update(getTrans(this)); if (mRippleCtrl) mRippleCtrl->update(); } void KeyMoveMapParts::appearAndSetEnd() { resetKeyPose(mKeyPoseKeeper); while (!isLastKey(mKeyPoseKeeper)) nextKeyPose(mKeyPoseKeeper); setQuat(this, getCurrentKeyQuat(mKeyPoseKeeper)); setTrans(this, getCurrentKeyTrans(mKeyPoseKeeper)); resetPosition(this); startNerveAction(this, "Stop"); if (getKeyPoseCount(mKeyPoseKeeper) < 2 || mIsFloorTouchStart || mIsHipDropStart || isValidStageSwitch(this, "SwitchStart")) startNerveAction(this, "StandBy"); makeActorAlive(); } void KeyMoveMapParts::exeStandBy() {} void KeyMoveMapParts::exeDelay() { if (isGreaterEqualStep(this, mDelayTime - 1)) startNerveAction(this, "Wait"); } void KeyMoveMapParts::exeWait() { if (isFirstStep(this)) { s32 moveWaitTime = calcKeyMoveWaitTime(mKeyPoseKeeper); if (moveWaitTime > -1) mKeyMoveWaitTime = moveWaitTime; } if (isGreaterEqualStep(this, mKeyMoveWaitTime)) setWaitEndNerve(); } void KeyMoveMapParts::setWaitEndNerve() { if (isRestart(mKeyPoseKeeper)) { restartKeyPose(mKeyPoseKeeper, getTransPtr(this), getQuatPtr(this)); resetPosition(this); startNerveAction(this, "Wait"); return; } if (isMoveSignKey(mKeyPoseKeeper) && isExistAction(this, "MoveKeySign")) { startNerveAction(this, "MoveSign"); return; } startNerveAction(this, "Move"); } void KeyMoveMapParts::exeMoveSign() { if (isFirstStep(this)) startAction(this, "MoveKeySign"); if (isActionEnd(this)) startNerveAction(this, "Move"); } void KeyMoveMapParts::exeMove() { if (isFirstStep(this)) { if (isExistAction(this, "MoveLoop")) tryStartActionIfNotPlaying(this, "MoveLoop"); mKeyMoveMoveTime = calcKeyMoveMoveTime(mKeyPoseKeeper); mSeMoveName = getSeNameByIndex(mKeyPoseKeeper->getKeyPoseCurrentIdx()); if (mSeMoveName) tryStartSe(this, mSeMoveName); } f32 rate = calcNerveRate(this, mKeyMoveMoveTime); calcLerpKeyTrans(getTransPtr(this), mKeyPoseKeeper, rate); calcSlerpKeyQuat(getQuatPtr(this), mKeyPoseKeeper, rate); if (isGreaterEqualStep(this, mKeyMoveMoveTime)) { nextKeyPose(mKeyPoseKeeper); if (isStop(mKeyPoseKeeper)) stop(); else if (calcKeyMoveWaitTime(mKeyPoseKeeper) == 0) setWaitEndNerve(); else { startNerveAction(this, "Wait"); if (mSeMoveName) { tryStopSe(this, mSeMoveName, -1, nullptr); mSeMoveName = nullptr; } tryStartSe(this, "MoveEnd"); } } } void KeyMoveMapParts::exeStopSign() { if (isFirstStep(this)) startAction(this, "StopSign"); if (isActionEnd(this)) startNerveAction(this, "Stop"); } void KeyMoveMapParts::exeStop() { if (isFirstStep(this)) { if (isExistAction(this, "Stop")) tryStartAction(this, "Stop"); if (isInvalidClipping(this)) validateClipping(this); if (mIsStopKill) kill(); } } } // namespace al