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

158 lines
4 KiB
C++

#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