OdysseyDecomp/src/Layout/Compass.cpp

117 lines
3.1 KiB
C++

#include "Layout/Compass.h"
#include "Library/Area/AreaObjUtil.h"
#include "Library/Camera/CameraDirector.h"
#include "Library/Camera/CameraUtil.h"
#include "Library/Layout/LayoutActionFunction.h"
#include "Library/Layout/LayoutInitInfo.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/Math/MathUtil.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Player/PlayerUtil.h"
#include "Layout/MapLayout.h"
#include "System/GameDataFunction.h"
#include "System/GameDataHolderAccessor.h"
namespace {
NERVE_IMPL(Compass, Appear);
NERVE_IMPL(Compass, End);
NERVE_IMPL(Compass, Wait);
NERVES_MAKE_NOSTRUCT(Compass, Appear, End, Wait);
} // namespace
namespace {
bool isAreaMadness(al::AreaObj* area) {
bool isMadness = false;
return al::tryGetAreaObjArg(&isMadness, area, "IsMadness") && isMadness;
}
} // namespace
Compass::Compass(const char* name, const al::LayoutInitInfo& info,
const al::PlayerHolder* playerHolder)
: al::LayoutActor(name), mPlayerHolder(playerHolder) {
al::initLayoutActor(this, info, "TestCompass");
initNerve(&Appear);
mSceneCamInfo = getCameraDirector()->getSceneCameraInfo();
kill();
}
void Compass::appear() {
if (GameDataFunction::isMainStage(this)) {
al::LayoutActor::appear();
al::setNerve(this, &Appear);
field_14c = 0.0f;
al::LiveActor* player = al::tryGetPlayerActor(mPlayerHolder, 0);
if (player) {
al::AreaObj* area = al::tryFindAreaObj(player, "CompassArea", al::getTrans(player));
if (area && isAreaMadness(area))
return;
}
sead::Vector3f camDir{0.0f, 0.0f, 0.0f};
if (!al::tryCalcCameraLookDirH(&camDir, mSceneCamInfo, sead::Vector3f::ey, 0))
return;
sead::Vector3f northDir{0.0f, 0.0f, 0.0f};
if (!rs::tryCalcMapNorthDir(&northDir, this))
return;
f32 angle = al::calcAngleOnPlaneDegree(northDir, camDir, -sead::Vector3f::ey);
angle = al::wrapAngle(angle);
f32 maxFrame = al::getActionFrameMax(this, "Direction", "State");
f32 frame = al::normalize(angle, 0.0f, maxFrame);
al::startFreezeAction(this, "Direction", frame, "State");
} else {
al::LiveActor* player = al::tryGetPlayerActor(mPlayerHolder, 0);
if (!player || !al::isInAreaObj(player, "CompassArea", al::getTrans(player)))
return;
al::LayoutActor::appear();
al::setNerve(this, &Appear);
field_14c = 0.0f;
}
}
void Compass::end() {
if (!al::isNerve(this, &End))
al::setNerve(this, &End);
}
void Compass::exeAppear() {
if (al::isFirstStep(this))
al::startAction(this, "Appear");
updateLayout();
al::setNerveAtActionEnd(this, &Wait);
}
// void Compass::updateLayout();
void Compass::exeWait() {
if (al::isFirstStep(this))
al::startAction(this, "Wait");
updateLayout();
}
void Compass::exeEnd() {
if (al::isFirstStep(this))
al::startAction(this, "End");
updateLayout();
if (al::isActionEnd(this))
kill();
}