OdysseyDecomp/lib/al/Library/Play/Layout/RollParts.cpp

219 lines
6 KiB
C++

#include "Library/Play/Layout/RollParts.h"
#include "Library/Base/StringUtil.h"
#include "Library/Layout/LayoutActionFunction.h"
#include "Library/Layout/LayoutActorUtil.h"
#include "Library/Layout/LayoutInitInfo.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
namespace {
using namespace al;
NERVE_IMPL(RollParts, Deactive)
NERVE_IMPL(RollParts, Active)
NERVE_IMPL(RollParts, RollIn)
NERVE_IMPL(RollParts, RollOut)
NERVES_MAKE_STRUCT(RollParts, Deactive, Active, RollIn, RollOut)
} // namespace
namespace al {
RollParts::RollParts(LayoutActor* parent, const LayoutInitInfo& info, const char* archiveName)
: LayoutActor("ロールパーツ") {
initLayoutPartsActor(this, parent, info, archiveName, nullptr);
initNerve(&NrvRollParts.Deactive, 0);
}
void RollParts::startLoopAction(const char* actionName, const char* paneName) {
startAction(this, actionName, paneName);
}
void RollParts::setData(const char16** messages, s32 messageCount, bool isLoop, s32 selectedIdx,
const char* paneName) {
mIsLoop = isLoop;
mMessages = messages;
mMessageCount = messageCount;
mPaneName = paneName;
mCurrentActionType = ActionType::Active;
mNextActionType = ActionType::Active;
if (selectedIdx >= 0)
mSelectedIdx = selectedIdx;
setPaneString(this, mPaneName, mMessages[mSelectedIdx], 0);
updateHeaderText();
if (!mHasStatePane)
return;
if (messageCount == 1) {
if (isExistAction(this, "Off", "State"))
startAction(this, "Off", "State");
} else {
if (isExistAction(this, "On", "State"))
startAction(this, "On", "State");
}
}
void RollParts::updateHeaderText() {
if (!mHeaderPaneName)
return;
WStringTmp<0x20> text;
text.clear();
if (mMessageCount > 1) {
for (s32 i = 0; i < mMessageCount; i++)
if (i == mSelectedIdx)
text.append(u"1");
else
text.append(u"0");
}
setPaneString(this, mHeaderPaneName, text.cstr(), 0);
}
void RollParts::setSelectedIdx(s32 idx) {
mSelectedIdx = idx;
setPaneString(this, mPaneName, mMessages[mSelectedIdx], 0);
}
void RollParts::activate() {
if (isNerve(this, &NrvRollParts.Active))
return;
if (mMessages)
setPaneString(this, mPaneName, mMessages[mSelectedIdx], 0);
setNerve(this, &NrvRollParts.Active);
}
void RollParts::activate(s32 selectedIdx) {
if (isNerve(this, &NrvRollParts.Active))
return;
mSelectedIdx = selectedIdx;
activate();
}
void RollParts::deactivate() {
if (isNerve(this, &NrvRollParts.Active)) {
setNerve(this, &NrvRollParts.Deactive);
return;
}
if (isRoll())
mNextActionType = ActionType::Deactive;
}
void RollParts::rollRight() {
if ((!mIsLoop && mSelectedIdx + 1 >= mMessageCount) || mMessageCount <= 1)
return;
if (isNerve(this, &NrvRollParts.Active)) {
mCurrentActionType = ActionType::RollRight;
setNerve(this, &NrvRollParts.RollOut);
return;
}
if (isNerve(this, &NrvRollParts.RollOut) || isNerve(this, &NrvRollParts.RollIn))
mNextActionType = ActionType::RollRight;
}
void RollParts::rollLeft() {
if ((!mIsLoop && mSelectedIdx <= 0) || mMessageCount <= 1)
return;
if (isNerve(this, &NrvRollParts.Active)) {
mCurrentActionType = ActionType::RollLeft;
setNerve(this, &NrvRollParts.RollOut);
return;
}
if (isNerve(this, &NrvRollParts.RollOut) || isNerve(this, &NrvRollParts.RollIn))
mNextActionType = ActionType::RollLeft;
}
void RollParts::calcCursorTrans(sead::Vector2f* outCursorTrans) const {
calcPaneTrans(outCursorTrans, this, "Cursor");
}
bool RollParts::isJustChangeRoll() const {
return isNerve(this, &NrvRollParts.RollIn) && getNerveStep(this) == 1;
}
bool RollParts::isRoll() const {
return isNerve(this, &NrvRollParts.RollIn) || isNerve(this, &NrvRollParts.RollOut);
}
void RollParts::exeDeactive() {
if (isFirstStep(this) && mDeactiveAction)
startAction(this, mDeactiveAction, nullptr);
}
void RollParts::exeActive() {
if (isFirstStep(this) && mActiveAction)
startAction(this, mActiveAction, nullptr);
}
void RollParts::exeRollOut() {
if (isFirstStep(this)) {
startAction(this,
mCurrentActionType == ActionType::RollLeft ? mRollLeftOutAction :
mRollRightOutAction,
mRollPaneName);
if (mCurrentActionType == ActionType::RollLeft) {
startHitReaction(this, "左ロール", nullptr);
mSelectedIdx--;
if (mSelectedIdx < 0)
mSelectedIdx = mIsLoop ? mMessageCount - 1 : 0;
} else {
startHitReaction(this, "右ロール", nullptr);
mSelectedIdx++;
if (mSelectedIdx >= mMessageCount)
mSelectedIdx = mIsLoop ? 0 : mMessageCount - 1;
}
updateHeaderText();
}
if (isActionEnd(this, mRollPaneName))
setNerve(this, &NrvRollParts.RollIn);
}
void RollParts::exeRollIn() {
if (isFirstStep(this)) {
startAction(this,
mCurrentActionType == ActionType::RollLeft ? mRollLeftInAction :
mRollRightInAction,
mRollPaneName);
setPaneString(this, mPaneName, mMessages[mSelectedIdx], 0);
}
if (isActionEnd(this, mRollPaneName)) {
mCurrentActionType = mNextActionType;
mNextActionType = ActionType::Active;
switch (mCurrentActionType) {
case ActionType::RollRight:
case ActionType::RollLeft:
setNerve(this, &NrvRollParts.RollOut);
break;
case ActionType::Deactive:
setNerve(this, &NrvRollParts.Deactive);
break;
default:
setNerve(this, &NrvRollParts.Active);
break;
}
}
}
} // namespace al