#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(); }