mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-05-06 23:38:32 +00:00
249 lines
7.1 KiB
C++
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
|