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

249 lines
7.1 KiB
C++

#include "Library/Play/Layout/BalloonMessage.h"
#include "Library/Layout/LayoutActionFunction.h"
#include "Library/Layout/LayoutActorUtil.h"
#include "Library/Layout/LayoutInitInfo.h"
#include "Library/LiveActor/ActorClippingFunction.h"
#include "Library/LiveActor/ActorFlagFunction.h"
#include "Library/LiveActor/ActorInitUtil.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/LiveActor.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"
#include "Library/Play/Layout/TalkMessageVoicePlayer.h"
#include "Library/Player/PlayerUtil.h"
#include "Library/Screen/ScreenFunction.h"
#include "Library/Se/SeFunction.h"
namespace {
using namespace al;
NERVE_IMPL(BalloonMessage, Wait)
NERVE_IMPL(BalloonMessage, Appear)
NERVE_IMPL(BalloonMessage, Hide)
NERVE_IMPL(BalloonMessage, End)
NERVES_MAKE_NOSTRUCT(BalloonMessage, Wait)
NERVES_MAKE_STRUCT(BalloonMessage, Appear, Hide, End)
} // namespace
namespace al {
BalloonMessage* BalloonMessage::create(const LiveActor* hostActor, const LayoutInitInfo& info,
const BalloonMessageInitParam& initParam,
bool isAutoUpdate) {
return new BalloonMessage(hostActor, info, initParam, isAutoUpdate);
}
BalloonMessage::BalloonMessage(const LiveActor* hostActor, const LayoutInitInfo& info,
const BalloonMessageInitParam& initParam, bool isAutoUpdate)
: LayoutActor(initParam.name), mHostActor(hostActor), mPaneName(initParam.paneName),
mAppearDist(initParam.appearDist), mKillDist(initParam.killDist),
mPlayerIndex(initParam.playerIndex), _158(initParam._38), mIsAutoUpdate(isAutoUpdate),
_15d(initParam._3c) {
mPosOffset.y = initParam.yPosOffset;
initLayoutActor(this, info, initParam.archiveName, initParam.suffix);
mTalkMessageVoicePlayer = new TalkMessageVoicePlayer();
mTalkMessageVoicePlayer->set_420(true);
setText(initParam.message);
initNerve(&Wait, 0);
kill();
}
void BalloonMessage::setText(const char* message) {
setPaneStringFormat(this, mPaneName, message);
}
inline void startAppear(LayoutActor* layout) {
startAction(layout, "Appear", nullptr);
}
void BalloonMessage::appear() {
updateTrans();
hidePushA();
if (!mIsAutoUpdate) {
startAppear(this);
LayoutActor::appear();
if (!mIsTalkMessageVoicePlayerStarted)
mTalkMessageVoicePlayer->start(this, mHostActor, getPaneStringBuffer(this, mPaneName),
5);
setNerve(this, &NrvBalloonMessage.Appear);
return;
}
if (isEnableAppear()) {
startAppear(this);
LayoutActor::appear();
setActionFrameRate(this, 1.0f, nullptr);
setNerve(this, &NrvBalloonMessage.Appear);
return;
}
LayoutActor::appear();
startFreezeActionEnd(this, "End", nullptr);
setNerve(this, &NrvBalloonMessage.Hide);
}
void BalloonMessage::updateTrans() {
sead::Vector2f layoutPos = sead::Vector2f::zero;
if (_158 == 0)
calcLayoutPosFromWorldPos(&layoutPos, mHostActor, getTrans(mHostActor) + mPosOffset);
else
calcLayoutPosFromWorldPosSub(&layoutPos, mHostActor, getTrans(mHostActor) + mPosOffset);
setLocalTrans(this, layoutPos);
}
void BalloonMessage::hidePushA() {
if (!isExistPane(this, "TxtA"))
return;
hidePane(this, "TxtA");
}
bool BalloonMessage::isEnableAppear() const {
if (!isNerve(this, &NrvBalloonMessage.End) && !isNerve(this, &NrvBalloonMessage.Hide) &&
isAlive())
return false;
return isNearPlayerActor(mAppearDist);
}
void BalloonMessage::appearWithPushA() {
appear();
showPushA();
}
void BalloonMessage::showPushA() {
if (!isExistPane(this, "TxtA"))
return;
showPane(this, "TxtA");
}
void BalloonMessage::control() {
if (mIsAutoUpdate)
update();
if (_15d && !isNerve(this, &NrvBalloonMessage.End) && !isNerve(this, &NrvBalloonMessage.Hide) &&
(isClipped(mHostActor) || isDead(mHostActor))) {
setNerve(this, &NrvBalloonMessage.End);
return;
}
mTalkMessageVoicePlayer->update();
updateTrans();
}
void BalloonMessage::update() {
if (isEnableAppear())
appear();
if (isEnableEnd())
setNerve(this, &NrvBalloonMessage.End);
}
bool BalloonMessage::isWait() const {
return isNerve(this, &Wait);
}
bool BalloonMessage::isVoicePlayerPlaying() const {
if (mTalkMessageVoicePlayer->isPlaying())
return true;
if (!mSeName.cstr())
return false;
return checkIsPlayingSe(mHostActor, mSeName.cstr(), nullptr);
}
bool BalloonMessage::isShowPushA() const {
return !isHidePane(this, "TxtA");
}
bool BalloonMessage::isEnableEnd() const {
if (isNerve(this, &NrvBalloonMessage.End) || isNerve(this, &NrvBalloonMessage.Hide) ||
!isAlive())
return false;
return !isNearPlayerActor(mKillDist);
}
void BalloonMessage::end() {
if (isNerve(this, &NrvBalloonMessage.End) || isNerve(this, &NrvBalloonMessage.Hide))
return;
setNerve(this, &NrvBalloonMessage.End);
}
void BalloonMessage::setTextW(const char16* message) {
setPaneString(this, mPaneName, message, 0);
}
void BalloonMessage::exeAppear() {
if (isActionEnd(this, nullptr))
setNerve(this, &Wait);
}
void BalloonMessage::exeWait() {
if (isFirstStep(this))
startAction(this, "Wait", nullptr);
}
void BalloonMessage::exeEnd() {
if (isFirstStep(this))
startAction(this, "End", nullptr);
if (isActionEnd(this, nullptr)) {
if (mIsAutoUpdate)
setNerve(this, &NrvBalloonMessage.Hide);
else
kill();
}
}
void BalloonMessage::exeHide() {}
bool BalloonMessage::isNearPlayerActor(f32 threshold) const {
if (mPlayerIndex >= 0)
return isNear(mHostActor, getPlayerActor(mHostActor, mPlayerIndex), threshold);
return isNearPlayer(mHostActor, threshold);
}
BalloonMessage* createBalloonMessage(const LiveActor* hostActor, const ActorInitInfo& info,
const BalloonMessageInitParam& initParam) {
return BalloonMessage::create(hostActor, getLayoutInitInfo(info), initParam, true);
}
BalloonMessage* createBalloonMessageNoAutoUpdate(const LiveActor* hostActor,
const ActorInitInfo& info,
const BalloonMessageInitParam& initParam) {
return BalloonMessage::create(hostActor, getLayoutInitInfo(info), initParam, false);
}
BalloonMessage* createBalloonMessage(const LiveActor* hostActor, const ActorInitInfo& info) {
BalloonMessageInitParam initParam = {.message = "未設定"};
return BalloonMessage::create(hostActor, getLayoutInitInfo(info), initParam, true);
}
BalloonMessage* createBalloonMessage(const LiveActor* hostActor, const ActorInitInfo& info,
const char* message) {
BalloonMessageInitParam initParam = {.message = message};
return BalloonMessage::create(hostActor, getLayoutInitInfo(info), initParam, true);
}
} // namespace al