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

142 lines
3.9 KiB
C++

#include "Library/MapObj/SeesawMapParts.h"
#include "Library/LiveActor/ActorAreaFunction.h"
#include "Library/LiveActor/ActorInitFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorModelFunction.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/MapObj/ChildStep.h"
#include "Library/Math/MathUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Placement/PlacementFunction.h"
#include "Library/Se/SeFunction.h"
namespace {
using namespace al;
NERVE_ACTION_IMPL(SeesawMapParts, Wait)
NERVE_ACTIONS_MAKE_STRUCT(SeesawMapParts, Wait)
} // namespace
namespace al {
SeesawMapParts::SeesawMapParts(const char* name) : LiveActor(name) {}
void SeesawMapParts::init(const ActorInitInfo& info) {
tryInitSubActorKeeperChildStep(this, info);
initNerveAction(this, "Wait", &NrvSeesawMapParts.collector, 0);
initMapPartsActor(this, info, nullptr);
tryGetQuatPtr(this);
registerAreaHostMtx(this, info);
tryGetQuatPtr(this);
mQuat = getQuat(this);
calcQuatSide(&mSide, mQuat);
calcQuatFront(&mFront, mQuat);
tryGetArg(&mMaxDegree, info, "MaxDegree");
tryGetArg(&mRotateAccelOn, info, "RotateAccelOn");
tryGetArg(&mRotateAccelOff, info, "RotateAccelOff");
initMaterialCode(this, info);
createChildStep(info, this, true);
trySyncStageSwitchAppear(this);
}
inline bool isGreaterThanOrEqualToZero(f32 val) { // sead::Mathf::assertGreaterThanOrEqualToZero_ ?
return val >= 0.0f;
}
bool SeesawMapParts::receiveMsg(const SensorMsg* message, HitSensor* other, HitSensor* self) {
if (isMsgFloorTouch(message)) {
sead::Vector3f pos;
if (isMySensor(self, this))
pos.set(getSensorPos(other));
else
pos.set(getActorTrans(self));
f32 weight = isMsgEnemyFloorTouch(message) ? 0.9f : 1.0f;
if (!isGreaterThanOrEqualToZero((pos - getTrans(this)).dot(mFront)))
weight = -weight;
mWeight += weight;
return true;
}
if (isMsgShowModel(message)) {
showModelIfHide(this);
return true;
}
if (isMsgHideModel(message)) {
hideModelIfShow(this);
return true;
}
if (isMsgRestart(message)) {
appearAndSetStart();
return true;
}
return false;
}
void SeesawMapParts::appearAndSetStart() {
mRotateDegree = 0.0f;
mRotateSpeed = 0.0f;
mWeight = 0.0f;
mRemainingAccelOnFrames = 0;
setQuat(this, mQuat);
makeActorAlive();
}
void SeesawMapParts::exeWait() {
if (mWeight > 0.0f)
mRemainingAccelOnFrames = mRemainingAccelOnFrames > 59 ? 60 : mRemainingAccelOnFrames + 1;
else if (mWeight < 0.0f)
mRemainingAccelOnFrames = mRemainingAccelOnFrames < -59 ? -60 : mRemainingAccelOnFrames - 1;
else if (mRemainingAccelOnFrames > 0)
mRemainingAccelOnFrames--;
else if (mRemainingAccelOnFrames < 0)
mRemainingAccelOnFrames++;
mWeight = 0.0f;
if (mRemainingAccelOnFrames > 0)
mRotateSpeed += mRotateAccelOn;
else if (mRemainingAccelOnFrames < 0)
mRotateSpeed -= mRotateAccelOn;
else if (mRotateDegree >= 0.0f)
mRotateSpeed -= mRotateAccelOff;
else
mRotateSpeed += mRotateAccelOff;
mRotateSpeed *= 0.95f;
mRotateDegree += mRotateSpeed;
f32 rotateSpeed = sead::Mathf::abs(mRotateSpeed);
if (sead::Mathf::abs(mRotateDegree) > mMaxDegree) {
if (isSameSign(mRotateSpeed, mRotateDegree))
mRotateSpeed *= -0.5f;
mRotateDegree = sead::Mathf::clamp(mRotateDegree, -mMaxDegree, mMaxDegree);
if (rotateSpeed > 0.2f)
tryStartSeWithParam(this, "Stop", rotateSpeed, "");
}
if (rotateSpeed > 0.1f)
tryHoldSeWithParam(this, "Rotate", rotateSpeed, "");
rotateQuatRadian(getQuatPtr(this), mQuat, mSide, sead::Mathf::deg2rad(mRotateDegree));
}
} // namespace al