OdysseyDecomp/lib/al/Library/MapObj/KeyMoveMapParts.cpp

304 lines
8.4 KiB
C++

#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<KeyMoveMapParts*, void (KeyMoveMapParts::*)()>;
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