#include "Library/MapObj/FallMapParts.h" #include "Library/LiveActor/ActorActionFunction.h" #include "Library/LiveActor/ActorAreaFunction.h" #include "Library/LiveActor/ActorClippingFunction.h" #include "Library/LiveActor/ActorCollisionFunction.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/Nerve/NerveSetupUtil.h" #include "Library/Nerve/NerveUtil.h" #include "Library/Placement/PlacementFunction.h" namespace { using namespace al; NERVE_ACTION_IMPL(FallMapParts, Appear) NERVE_ACTION_IMPL(FallMapParts, Wait) NERVE_ACTION_IMPL(FallMapParts, FallSign) NERVE_ACTION_IMPL(FallMapParts, Fall) NERVE_ACTION_IMPL(FallMapParts, End) NERVE_ACTIONS_MAKE_STRUCT(FallMapParts, Appear, Wait, FallSign, Fall, End) } // namespace namespace al { FallMapParts::FallMapParts(const char* name) : LiveActor(name) {} void FallMapParts::init(const ActorInitInfo& info) { initNerveAction(this, "Wait", &NrvFallMapParts.collector, 0); initMapPartsActor(this, info, nullptr); registerAreaHostMtx(this, info); mPos = getTrans(this); tryGetArg(&mFallTime, info, "FallTime"); tryGetArg(&mIsInvalidAutoRestart, info, "IsInvalidAutoRestart"); trySyncStageSwitchAppear(this); } bool FallMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) { if (isMsgFloorTouch(message) && isNerve(this, NrvFallMapParts.Wait.data())) { startNerveAction(this, "FallSign"); invalidateClipping(this); return true; } if (isMsgShowModel(message)) { if (!isNerve(this, NrvFallMapParts.End.data())) showModelIfHide(this); return true; } if (isMsgHideModel(message)) { if (!isNerve(this, NrvFallMapParts.End.data())) hideModelIfShow(this); return true; } if (isMsgRestart(message)) { appearAndSetStart(); return true; } return false; } void FallMapParts::appearAndSetStart() { setTrans(this, mPos); resetPosition(this); showModelIfHide(this); startNerveAction(this, "Appear"); setVelocityZero(this); makeActorAlive(); } void FallMapParts::exeAppear() { if (isFirstStep(this)) { validateCollisionParts(this); if (!tryStartAction(this, "Appear")) { startNerveAction(this, "Wait"); return; } } if (!isExistAction(this) || isActionEnd(this)) startNerveAction(this, "Wait"); } void FallMapParts::exeWait() { if (isFirstStep(this)) { tryStartAction(this, "Wait"); validateClipping(this); } } void FallMapParts::exeFallSign() { if (isFirstStep(this)) mIsStartAction = tryStartAction(this, "FallSign"); if (!mIsStartAction) { f32 offset = sead::Mathf::sin(calcNerveValue(this, 20, 0.0f, sead::Mathf::pi() * 3)) * 3; setTrans(this, offset * sead::Vector3f::ey + mPos); } if (isEndFallSign()) startNerveAction(this, "Fall"); } bool FallMapParts::isEndFallSign() const { return mIsStartAction ? isActionEnd(this) : isGreaterEqualStep(this, 20); } void FallMapParts::exeFall() { if (isFirstStep(this)) { tryStartAction(this, "Fall"); setTrans(this, mPos); } addVelocityToGravity(this, 0.3f); scaleVelocity(this, 0.9f); if (isGreaterStep(this, mFallTime)) startNerveAction(this, "End"); } void FallMapParts::exeEnd() { if (isFirstStep(this)) { tryStartAction(this, "End"); hideModelIfShow(this); invalidateCollisionParts(this); setVelocityZero(this); if (mIsInvalidAutoRestart) { kill(); return; } } if (isGreaterStep(this, 120)) { setTrans(this, mPos); resetPosition(this); showModelIfHide(this); startNerveAction(this, "Appear"); } } } // namespace al