mirror of
https://github.com/zeldaret/ss
synced 2026-08-29 00:51:53 -04:00
348 lines
9.2 KiB
C++
348 lines
9.2 KiB
C++
#include "d/lyt/d_lyt_drop_line.h"
|
|
|
|
#include "common.h"
|
|
#include "d/a/d_a_item.h"
|
|
#include "d/lyt/meter/d_lyt_meter.h"
|
|
#include "d/snd/d_snd_small_effect_mgr.h"
|
|
#include "d/snd/d_snd_wzsound.h"
|
|
#include "f/f_base.h"
|
|
#include "m/m_color.h"
|
|
#include "m/m_vec.h"
|
|
#include "nw4r/math/math_types.h"
|
|
#include "toBeSorted/d_d3d.h"
|
|
#include "toBeSorted/d_emitter.h"
|
|
|
|
class dLytDropLine_HIO_c {
|
|
public:
|
|
dLytDropLine_HIO_c();
|
|
virtual ~dLytDropLine_HIO_c();
|
|
|
|
/* 0x04 */ f32 field_0x04;
|
|
/* 0x08 */ s32 mMoveDuration;
|
|
/* 0x0C */ u8 field_0x0C;
|
|
};
|
|
|
|
static dLytDropLine_HIO_c sHio;
|
|
|
|
dLytDropLine_HIO_c::dLytDropLine_HIO_c() : field_0x04(5.0f), mMoveDuration(10), field_0x0C(0) {}
|
|
dLytDropLine_HIO_c::~dLytDropLine_HIO_c() {}
|
|
|
|
STATE_DEFINE(dLytDropLineParts_c, Wait);
|
|
STATE_DEFINE(dLytDropLineParts_c, Move);
|
|
|
|
int dLytDropLineParts_c::create(dLytDropLine_c *main) {
|
|
mEmitter.init(main);
|
|
mpTargetPane = nullptr;
|
|
reset();
|
|
mStateMgr.changeState(StateID_Wait);
|
|
return fBase_c::SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLineParts_c::doDelete() {
|
|
// no-op
|
|
return fBase_c::SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLineParts_c::execute() {
|
|
mStateMgr.executeState();
|
|
return fBase_c::SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLineParts_c::draw() {
|
|
// no-op
|
|
return fBase_c::SUCCEEDED;
|
|
}
|
|
|
|
void dLytDropLineParts_c::startPickup(mVec3_c tearWorldPos, s32 trial) {
|
|
d3d::worldToScreen(mStartPos, tearWorldPos);
|
|
mStartPos.z = 0.0f;
|
|
mEffectPos = mStartPos;
|
|
mEffectPos.z = 0.0f;
|
|
|
|
mTrial = trial;
|
|
mMoveRequest = true;
|
|
mIsDone = false;
|
|
mLeftRight = false;
|
|
mIsChangeAnim = false;
|
|
}
|
|
|
|
void dLytDropLineParts_c::startChange(mVec3_c startPos, s32 trial, bool leftRight) {
|
|
mStartPos = startPos;
|
|
mEffectPos = mStartPos;
|
|
|
|
mTrial = trial;
|
|
mMoveRequest = true;
|
|
mIsDone = false;
|
|
mLeftRight = leftRight;
|
|
mIsChangeAnim = true;
|
|
}
|
|
|
|
void dLytDropLineParts_c::reset() {
|
|
mStartPos.setZero();
|
|
mEffectPos.setZero();
|
|
mMoveLinearCoeff.setZero();
|
|
mMoveTimer = 0;
|
|
mTrial = 4;
|
|
mMoveRequest = false;
|
|
mIsDone = false;
|
|
mLeftRight = false;
|
|
mIsChangeAnim = false;
|
|
}
|
|
|
|
void dLytDropLineParts_c::initializeState_Wait() {}
|
|
|
|
void dLytDropLineParts_c::executeState_Wait() {
|
|
if (mMoveRequest) {
|
|
mStateMgr.changeState(StateID_Move);
|
|
}
|
|
}
|
|
|
|
void dLytDropLineParts_c::finalizeState_Wait() {}
|
|
|
|
void dLytDropLineParts_c::initializeState_Move() {
|
|
mMoveTimer = 0;
|
|
if (mpTargetPane != nullptr) {
|
|
nw4r::math::MTX34 mtx = mpTargetPane->GetGlobalMtx();
|
|
|
|
// Set up the coefficients for the quadratic parabola below
|
|
mVec3_c v1 = mVec3_c(mtx._03, mtx._13, 0.0f);
|
|
|
|
mMoveLinearCoeff.x =
|
|
((v1.x - mStartPos.x) + (sHio.field_0x04 * (f32)sHio.mMoveDuration * (f32)sHio.mMoveDuration)) /
|
|
(f32)sHio.mMoveDuration;
|
|
mMoveLinearCoeff.y = (v1.y - mStartPos.y) / (f32)sHio.mMoveDuration;
|
|
|
|
if (!mIsChangeAnim) {
|
|
dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SIREN_SHIZUKU_GET_MOVE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void dLytDropLineParts_c::executeState_Move() {
|
|
bool isDone = false;
|
|
if (mpTargetPane != nullptr) {
|
|
nw4r::math::MTX34 mtx = mpTargetPane->GetGlobalMtx();
|
|
mVec3_c panePos(mtx._03, mtx._13, 0.0f);
|
|
|
|
if (!mIsChangeAnim) {
|
|
if (dLytMeter_c::getfn_800C9FE0()) {
|
|
mEffectPos = panePos;
|
|
mStateMgr.changeState(StateID_Wait);
|
|
mMoveRequest = false;
|
|
mIsDone = true;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (mMoveTimer < sHio.mMoveDuration) {
|
|
// Quadratic parabola
|
|
if (mLeftRight) {
|
|
mEffectPos.x = mStartPos.x - (mMoveLinearCoeff.x * (f32)mMoveTimer -
|
|
sHio.field_0x04 * (f32)mMoveTimer * (f32)mMoveTimer);
|
|
} else {
|
|
mEffectPos.x = mStartPos.x + mMoveLinearCoeff.x * (f32)mMoveTimer -
|
|
sHio.field_0x04 * (f32)mMoveTimer * (f32)mMoveTimer;
|
|
}
|
|
|
|
mEffectPos.y = mStartPos.y + mMoveLinearCoeff.y * (f32)mMoveTimer;
|
|
mEffectPos.z = 0.0f;
|
|
mMoveTimer++;
|
|
} else {
|
|
isDone = true;
|
|
mEffectPos = panePos;
|
|
}
|
|
|
|
static const mColor sColors1[] = {
|
|
mColor(0xA0, 0xFF, 0xB4, 0xFF), // #A0FFB4FF
|
|
mColor(0xFF, 0x80, 0xB4, 0xFF), // #FF80B4FF
|
|
mColor(0xFF, 0xFF, 0x80, 0xFF), // #FFFF80FF
|
|
mColor(0x80, 0xC8, 0xFF, 0xFF), // #80C8FFFF
|
|
};
|
|
|
|
static const mColor sColors2[] = {
|
|
mColor(0x00, 0xFF, 0x30, 0xFF), // #00FF30FF
|
|
mColor(0xFF, 0x40, 0x80, 0xFF), // #FF4080FF
|
|
mColor(0xFF, 0xFF, 0x00, 0xFF), // #FFFF00FF
|
|
mColor(0x60, 0x96, 0xFF, 0xFF), // #6096FFFF
|
|
};
|
|
|
|
mColor c1 = 0xFFFFFFFF;
|
|
mColor c2 = 0xFFFFFFFF;
|
|
switch (mTrial) {
|
|
case dAcItem_c::TRIAL_SKYLOFT:
|
|
c1 = sColors1[0];
|
|
c2 = sColors2[0];
|
|
break;
|
|
case dAcItem_c::TRIAL_FARON:
|
|
c1 = sColors1[1];
|
|
c2 = sColors2[1];
|
|
break;
|
|
case dAcItem_c::TRIAL_ELDIN:
|
|
c1 = sColors1[2];
|
|
c2 = sColors2[2];
|
|
break;
|
|
case dAcItem_c::TRIAL_LANAYRU:
|
|
c1 = sColors1[3];
|
|
c2 = sColors2[3];
|
|
break;
|
|
}
|
|
|
|
mEmitter.holdUIEffect(PARTICLE_RESOURCE_ID_MAPPING_138_, mEffectPos, nullptr, nullptr, &c1, &c2);
|
|
} else {
|
|
isDone = true;
|
|
}
|
|
|
|
if (isDone) {
|
|
mStateMgr.changeState(StateID_Wait);
|
|
mMoveRequest = false;
|
|
mIsDone = true;
|
|
mIsChangeAnim = false;
|
|
}
|
|
}
|
|
|
|
void dLytDropLineParts_c::finalizeState_Move() {}
|
|
|
|
SPECIAL_BASE_PROFILE(LYT_DROP_LINE, dLytDropLine_c, fProfile::LYT_DROP_LINE, 0x2B0, 0x6FD);
|
|
|
|
dLytDropLine_c *dLytDropLine_c::sInstance;
|
|
|
|
int dLytDropLine_c::create() {
|
|
sInstance->createInternal();
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLine_c::doDelete() {
|
|
sInstance->doDeleteInternal();
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLine_c::execute() {
|
|
if (sInstance != nullptr) {
|
|
sInstance->executeInternal();
|
|
}
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLine_c::draw() {
|
|
if (sInstance != nullptr) {
|
|
sInstance->drawInternal();
|
|
}
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
void dLytDropLine_c::startPickup(mVec3_c tearWorldPos, dAcItem_c::Trial_e trial) {
|
|
if (sInstance != nullptr) {
|
|
sInstance->startPickupInternal(tearWorldPos, trial);
|
|
}
|
|
}
|
|
|
|
void dLytDropLine_c::startChange(
|
|
nw4r::lyt::Pane *tearSlotPane, nw4r::lyt::Pane *flowerPane, dAcItem_c::Trial_e trial, bool leftRight
|
|
) {
|
|
if (sInstance != nullptr) {
|
|
sInstance->startChangeInternal(tearSlotPane, flowerPane, trial, leftRight);
|
|
}
|
|
}
|
|
|
|
bool dLytDropLine_c::finishPart() {
|
|
if (sInstance != nullptr) {
|
|
return sInstance->finishPartInternal();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void dLytDropLine_c::setPane(nw4r::lyt::Pane *pane) {
|
|
if (sInstance != nullptr) {
|
|
sInstance->setPaneInternal(pane);
|
|
}
|
|
}
|
|
|
|
nw4r::lyt::Pane *dLytDropLine_c::getActivePane() {
|
|
if (sInstance != nullptr) {
|
|
return sInstance->getActivePaneInternal();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
int dLytDropLine_c::createInternal() {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
mParts[i].create(this);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int dLytDropLine_c::doDeleteInternal() {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
mParts[i].doDelete();
|
|
}
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLine_c::executeInternal() {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
mParts[i].execute();
|
|
}
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
int dLytDropLine_c::drawInternal() {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
mParts[i].draw();
|
|
}
|
|
return SUCCEEDED;
|
|
}
|
|
|
|
void dLytDropLine_c::startPickupInternal(mVec3_c tearWorldPos, dAcItem_c::Trial_e trial) {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
if (!mParts[i].isMoveRequest()) {
|
|
mParts[i].startPickup(tearWorldPos, trial);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void dLytDropLine_c::startChangeInternal(
|
|
nw4r::lyt::Pane *tearSlotPane, nw4r::lyt::Pane *flowerPane, dAcItem_c::Trial_e trial, bool leftRight
|
|
) {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
if (!mParts[i].isMoveRequest()) {
|
|
mParts[i].setTargetPane(flowerPane);
|
|
if (tearSlotPane != nullptr) {
|
|
nw4r::math::MTX34 mtx = tearSlotPane->GetGlobalMtx();
|
|
mVec3_c startPos(mtx._03, mtx._13, 0.0f);
|
|
mParts[i].startChange(startPos, trial, leftRight);
|
|
} else {
|
|
mVec3_c startPos(0.0f, -200.0f, 0.0f);
|
|
mParts[i].startChange(startPos, trial, leftRight);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool dLytDropLine_c::finishPartInternal() {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
if (mParts[i].isDone()) {
|
|
mParts[i].finish();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void dLytDropLine_c::setPaneInternal(nw4r::lyt::Pane *pane) {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
mParts[i].setTargetPane(pane);
|
|
}
|
|
}
|
|
|
|
nw4r::lyt::Pane *dLytDropLine_c::getActivePaneInternal() {
|
|
for (int i = 0; i < NUM_PARTS; i++) {
|
|
if (mParts[i].getTargetPane() != nullptr) {
|
|
return mParts[i].getTargetPane();
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|