diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index e042e143..a93f8fff 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -1600,6 +1600,7 @@ d/lyt/d_lyt_drop_line.cpp: .ctors start:0x804DB868 end:0x804DB86C .data start:0x80538498 end:0x80538658 .sbss start:0x80575958 end:0x80575960 + .sdata2 start:0x8057C6B0 end:0x8057C6C8 .bss start:0x805B6000 end:0x805B60C0 d/lyt/d_lyt_force_line.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index b7bb0d9d..bae8217b 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -6364,7 +6364,7 @@ isAnyFruitAnimAtFrame__20LytMeterTimerPart1_cCFf = .text:0x80106AD0; // type:fun incrementTearCount__20LytMeterTimerPart1_cFv = .text:0x80106B30; // type:function size:0xF4 initColors__20LytMeterTimerPart1_cFv = .text:0x80106C30; // type:function size:0x394 startEffect__20LytMeterTimerPart1_cFl = .text:0x80106FD0; // type:function size:0x108 -updateDropLine__20LytMeterTimerPart1_cFPQ34nw4r3lyt4Pane = .text:0x801070E0; // type:function size:0x34 +startDropLineChange__20LytMeterTimerPart1_cFPQ34nw4r3lyt4Pane = .text:0x801070E0; // type:function size:0x34 build__20LytMeterTimerPart2_cFPQ23d2d10ResAccIf_c = .text:0x80107120; // type:function size:0xD8 remove__20LytMeterTimerPart2_cFv = .text:0x80107200; // type:function size:0x58 execute__20LytMeterTimerPart2_cFv = .text:0x80107260; // type:function size:0xA0 @@ -15062,67 +15062,67 @@ initializeState__28sFStateID_c<13dLytSaveMgr_c>CFR13dLytSaveMgr_c = .text:0x8028 __sinit_\d_lyt_save_mgr_cpp = .text:0x80286860; // type:function size:0x338 scope:local __dt__28sFStateID_c<13dLytSaveMgr_c>Fv = .text:0x80286BA0; // type:function size:0x58 scope:weak isSameName__28sFStateID_c<13dLytSaveMgr_c>CFPCc = .text:0x80286C00; // type:function size:0x88 scope:weak -fn_80286C90 = .text:0x80286C90; // type:function size:0x28 -fn_80286CC0 = .text:0x80286CC0; // type:function size:0x40 -fn_80286D00 = .text:0x80286D00; // type:function size:0x58 -fn_80286D60 = .text:0x80286D60; // type:function size:0x10 -fn_80286D70 = .text:0x80286D70; // type:function size:0x8 -fn_80286D80 = .text:0x80286D80; // type:function size:0x30 -fn_80286DB0 = .text:0x80286DB0; // type:function size:0x10 -fn_80286DC0 = .text:0x80286DC0; // type:function size:0x8 -fn_80286DD0 = .text:0x80286DD0; // type:function size:0x74 -fn_80286E50 = .text:0x80286E50; // type:function size:0x44 -fn_80286EA0 = .text:0x80286EA0; // type:function size:0x4C -LytDropLineParts__stateWaitEnter = .text:0x80286EF0; // type:function size:0x4 -LytDropLineParts__stateWaitUpdate = .text:0x80286F00; // type:function size:0x28 -LytDropLineParts__stateWaitLeave = .text:0x80286F30; // type:function size:0x4 -LytDropLineParts__stateMoveEnter = .text:0x80286F40; // type:function size:0x158 -LytDropLineParts__stateMoveUpdate = .text:0x802870A0; // type:function size:0x504 -LytDropLineParts__stateMoveLeave = .text:0x802875B0; // type:function size:0x4 -fn_802875C0 = .text:0x802875C0; // type:function size:0x70 -fn_80287630 = .text:0x80287630; // type:function size:0x94 -fn_802876D0 = .text:0x802876D0; // type:function size:0x58 -fn_80287730 = .text:0x80287730; // type:function size:0x6C -fn_802877A0 = .text:0x802877A0; // type:function size:0xA0 -fn_80287840 = .text:0x80287840; // type:function size:0xA4 -fn_802878F0 = .text:0x802878F0; // type:function size:0xB8 -fn_802879B0 = .text:0x802879B0; // type:function size:0x28 -fn_802879E0 = .text:0x802879E0; // type:function size:0x28 -fn_80287A10 = .text:0x80287A10; // type:function size:0x30 -fn_80287A40 = .text:0x80287A40; // type:function size:0x30 -fn_80287A70 = .text:0x80287A70; // type:function size:0x50 -update__14dLytDropLine_cFPQ34nw4r3lyt4PanePQ34nw4r3lyt4PaneQ29dAcItem_c7Trial_eb = .text:0x80287AC0; // type:function size:0x34 -finishPartMaybe__14dLytDropLine_cFv = .text:0x80287B00; // type:function size:0x18 +__ct__18dLytDropLine_HIO_cFv = .text:0x80286C90; // type:function size:0x28 +__dt__18dLytDropLine_HIO_cFv = .text:0x80286CC0; // type:function size:0x40 +create__19dLytDropLineParts_cFP14dLytDropLine_c = .text:0x80286D00; // type:function size:0x58 +changeState__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x80286D60; // type:function size:0x10 +doDelete__19dLytDropLineParts_cFv = .text:0x80286D70; // type:function size:0x8 +execute__19dLytDropLineParts_cFv = .text:0x80286D80; // type:function size:0x30 +executeState__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80286DB0; // type:function size:0x10 +draw__19dLytDropLineParts_cFv = .text:0x80286DC0; // type:function size:0x8 +startPickup__19dLytDropLineParts_cF7mVec3_cl = .text:0x80286DD0; // type:function size:0x74 +startChange__19dLytDropLineParts_cF7mVec3_clb = .text:0x80286E50; // type:function size:0x44 +reset__19dLytDropLineParts_cFv = .text:0x80286EA0; // type:function size:0x4C +initializeState_Wait__19dLytDropLineParts_cFv = .text:0x80286EF0; // type:function size:0x4 +executeState_Wait__19dLytDropLineParts_cFv = .text:0x80286F00; // type:function size:0x28 +finalizeState_Wait__19dLytDropLineParts_cFv = .text:0x80286F30; // type:function size:0x4 +initializeState_Move__19dLytDropLineParts_cFv = .text:0x80286F40; // type:function size:0x158 +executeState_Move__19dLytDropLineParts_cFv = .text:0x802870A0; // type:function size:0x504 +finalizeState_Move__19dLytDropLineParts_cFv = .text:0x802875B0; // type:function size:0x4 +dLytDropLine_c_classInit__Fv = .text:0x802875C0; // type:function size:0x70 +__ct__19dLytDropLineParts_cFv = .text:0x80287630; // type:function size:0x94 +__dt__32sFState_c<19dLytDropLineParts_c>Fv = .text:0x802876D0; // type:function size:0x58 +__dt__35sFStateFct_c<19dLytDropLineParts_c>Fv = .text:0x80287730; // type:function size:0x6C +__dt__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x802877A0; // type:function size:0xA0 +__dt__58sFStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c>Fv = .text:0x80287840; // type:function size:0xA4 +__dt__19dLytDropLineParts_cFv = .text:0x802878F0; // type:function size:0xB8 +create__14dLytDropLine_cFv = .text:0x802879B0; // type:function size:0x28 +doDelete__14dLytDropLine_cFv = .text:0x802879E0; // type:function size:0x28 +execute__14dLytDropLine_cFv = .text:0x80287A10; // type:function size:0x30 +draw__14dLytDropLine_cFv = .text:0x80287A40; // type:function size:0x30 +startPickup__14dLytDropLine_cF7mVec3_cQ29dAcItem_c7Trial_e = .text:0x80287A70; // type:function size:0x50 +startChange__14dLytDropLine_cFPQ34nw4r3lyt4PanePQ34nw4r3lyt4PaneQ29dAcItem_c7Trial_eb = .text:0x80287AC0; // type:function size:0x34 +finishPart__14dLytDropLine_cFv = .text:0x80287B00; // type:function size:0x18 setPane__14dLytDropLine_cFPQ34nw4r3lyt4Pane = .text:0x80287B20; // type:function size:0x1C getActivePane__14dLytDropLine_cFv = .text:0x80287B40; // type:function size:0x18 -fn_80287B60 = .text:0x80287B60; // type:function size:0x60 -fn_80287BC0 = .text:0x80287BC0; // type:function size:0x50 -fn_80287C10 = .text:0x80287C10; // type:function size:0x50 -fn_80287C60 = .text:0x80287C60; // type:function size:0x50 -fn_80287CB0 = .text:0x80287CB0; // type:function size:0x78 -fn_80287D30 = .text:0x80287D30; // type:function size:0x150 -fn_80287E80 = .text:0x80287E80; // type:function size:0x4C -fn_80287ED0 = .text:0x80287ED0; // type:function size:0xBC -fn_80287F90 = .text:0x80287F90; // type:function size:0x40 -fn_80287FD0 = .text:0x80287FD0; // type:function size:0x84 -fn_80288060 = .text:0x80288060; // type:function size:0x60 -fn_802880C0 = .text:0x802880C0; // type:function size:0xC -fn_802880D0 = .text:0x802880D0; // type:function size:0x1C -fn_802880F0 = .text:0x802880F0; // type:function size:0x1C -fn_80288110 = .text:0x80288110; // type:function size:0x1C -fn_80288130 = .text:0x80288130; // type:function size:0x10 -fn_80288140 = .text:0x80288140; // type:function size:0x10 -fn_80288150 = .text:0x80288150; // type:function size:0x10 -fn_80288160 = .text:0x80288160; // type:function size:0x10 -fn_80288170 = .text:0x80288170; // type:function size:0x10 -fn_80288180 = .text:0x80288180; // type:function size:0x10 -fn_80288190 = .text:0x80288190; // type:function size:0x10 -fn_802881A0 = .text:0x802881A0; // type:function size:0x30 -fn_802881D0 = .text:0x802881D0; // type:function size:0x30 -fn_80288200 = .text:0x80288200; // type:function size:0x30 -LytDropLineParts__initStates = .text:0x80288230; // type:function size:0x1DC -LytDropLineParts__dtor = .text:0x80288410; // type:function size:0x58 -fn_80288470 = .text:0x80288470; // type:function size:0x88 +createInternal__14dLytDropLine_cFv = .text:0x80287B60; // type:function size:0x60 +doDeleteInternal__14dLytDropLine_cFv = .text:0x80287BC0; // type:function size:0x50 +executeInternal__14dLytDropLine_cFv = .text:0x80287C10; // type:function size:0x50 +drawInternal__14dLytDropLine_cFv = .text:0x80287C60; // type:function size:0x50 +startPickupInternal__14dLytDropLine_cF7mVec3_cQ29dAcItem_c7Trial_e = .text:0x80287CB0; // type:function size:0x78 +startChangeInternal__14dLytDropLine_cFPQ34nw4r3lyt4PanePQ34nw4r3lyt4PaneQ29dAcItem_c7Trial_eb = .text:0x80287D30; // type:function size:0x150 +finishPartInternal__14dLytDropLine_cFv = .text:0x80287E80; // type:function size:0x4C +setPaneInternal__14dLytDropLine_cFPQ34nw4r3lyt4Pane = .text:0x80287ED0; // type:function size:0xBC +getActivePaneInternal__14dLytDropLine_cFv = .text:0x80287F90; // type:function size:0x40 +__dt__14dLytDropLine_cFv = .text:0x80287FD0; // type:function size:0x84 +build__35sFStateFct_c<19dLytDropLineParts_c>FRC12sStateIDIf_c = .text:0x80288060; // type:function size:0x60 +dispose__35sFStateFct_c<19dLytDropLineParts_c>FRP10sStateIf_c = .text:0x802880C0; // type:function size:0xC +initialize__32sFState_c<19dLytDropLineParts_c>Fv = .text:0x802880D0; // type:function size:0x1C +execute__32sFState_c<19dLytDropLineParts_c>Fv = .text:0x802880F0; // type:function size:0x1C +finalize__32sFState_c<19dLytDropLineParts_c>Fv = .text:0x80288110; // type:function size:0x1C +initializeState__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80288130; // type:function size:0x10 +finalizeState__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80288140; // type:function size:0x10 +refreshState__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x80288150; // type:function size:0x10 +getState__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80288160; // type:function size:0x10 +getNewStateID__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80288170; // type:function size:0x10 +getStateID__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80288180; // type:function size:0x10 +getOldStateID__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80288190; // type:function size:0x10 +finalizeState__34sFStateID_c<19dLytDropLineParts_c>CFR19dLytDropLineParts_c = .text:0x802881A0; // type:function size:0x30 +executeState__34sFStateID_c<19dLytDropLineParts_c>CFR19dLytDropLineParts_c = .text:0x802881D0; // type:function size:0x30 +initializeState__34sFStateID_c<19dLytDropLineParts_c>CFR19dLytDropLineParts_c = .text:0x80288200; // type:function size:0x30 +__sinit_\d_lyt_drop_line_cpp = .text:0x80288230; // type:function size:0x1DC +__dt__34sFStateID_c<19dLytDropLineParts_c>Fv = .text:0x80288410; // type:function size:0x58 +isSameName__34sFStateID_c<19dLytDropLineParts_c>CFPCc = .text:0x80288470; // type:function size:0x88 getNumTadtonesInGroup__Fl = .text:0x80288500; // type:function size:0x14 scope:local __ct__19dLytForceLine_HIO_cFv = .text:0x80288520; // type:function size:0x28 __dt__19dLytForceLine_HIO_cFv = .text:0x80288550; // type:function size:0x40 @@ -36653,12 +36653,13 @@ __vt__26sFState_c<13dLytSaveMgr_c> = .data:0x80538340; // type:object size:0x18 __vt__28sFStateID_c<13dLytSaveMgr_c> = .data:0x80538464; // type:object size:0x34 scope:weak g_profile_LYT_DROP_LINE = .data:0x80538498; // type:object size:0xC lbl_805384A4 = .data:0x805384A4; // type:object size:0xC -lbl_805384B0 = .data:0x805384B0; // type:object size:0x50 -lbl_80538500 = .data:0x80538500; // type:object size:0x30 -lbl_80538530 = .data:0x80538530; // type:object size:0x30 -lbl_80538560 = .data:0x80538560; // type:object size:0x18 -lbl_80538578 = .data:0x80538578; // type:object size:0xA8 -lbl_80538620 = .data:0x80538620; // type:object size:0x38 +__vt__14dLytDropLine_c = .data:0x805384B0; // type:object size:0x50 +__vt__58sFStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c> = .data:0x80538500; // type:object size:0x30 +__vt__88sStateMgr_c<19dLytDropLineParts_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x80538530; // type:object size:0x30 +__vt__35sFStateFct_c<19dLytDropLineParts_c> = .data:0x80538560; // type:object size:0x14 +__vt__32sFState_c<19dLytDropLineParts_c> = .data:0x80538578; // type:object size:0x18 +lbl_80538590 = .data:0x80538590; // type:object size:0x90 +__vt__34sFStateID_c<19dLytDropLineParts_c> = .data:0x80538620; // type:object size:0x34 g_profile_LYT_FORCE_LINE = .data:0x80538658; // type:object size:0xC ...data.0 = .data:0x80538658; // type:label scope:local @23145 = .data:0x80538664; // type:object size:0xC scope:local data:string @@ -42453,7 +42454,7 @@ sInstance__17dLytGameOverMgr_c = .sbss:0x80575948; // type:object size:0x4 data: sInstance__13dLytSaveMgr_c = .sbss:0x80575950; // type:object size:0x4 data:4byte lbl_80575958 = .sbss:0x80575958; // type:object size:0x1 data:byte lbl_80575959 = .sbss:0x80575959; // type:object size:0x1 data:byte -lbl_8057595C = .sbss:0x8057595C; // type:object size:0x4 data:4byte +sInstance__14dLytDropLine_c = .sbss:0x8057595C; // type:object size:0x4 data:4byte sInstance__15dLytForceLine_c = .sbss:0x80575960; // type:object size:0x4 data:4byte lbl_80575968 = .sbss:0x80575968; // type:object size:0x8 data:4byte sInstance__21dLytMiniGamePumpkin_c = .sbss:0x80575970; // type:object size:0x4 data:4byte @@ -42536,13 +42537,8 @@ l_allocator__3m2d = .sbss:0x80575BC8; // type:object size:0x4 data:4byte l_allocator_p__Q23m3d8internal = .sbss:0x80575BD0; // type:object size:0x4 data:4byte l_scnRoot_p__Q23m3d8internal = .sbss:0x80575BD4; // type:object size:0x4 data:4byte l_numLightMgr__Q23m3d8internal = .sbss:0x80575BD8; // type:object size:0x4 data:4byte -l_lightMgr_pp__Q23m3d8internal = .sbss:0x80575BDC; // type:object size:0x4 data:4byte l_numFogMgr__Q23m3d8internal = .sbss:0x80575BE0; // type:object size:0x4 data:4byte l_fogMgr_pp__Q23m3d8internal = .sbss:0x80575BE4; // type:object size:0x4 data:4byte -l_alignment__Q23m3d8internal = .sbss:0x80575BE8; // type:object size:0x4 data:4byte -sInstance__Q23m3d9mShadow_c = .sbss:0x80575BF0; // type:object size:0x4 data:4byte -sTexObj__Q23m3d9mShadow_c = .sbss:0x80575BF4; // type:object size:0x4 data:4byte -sResShp__Q23m3d9mShadow_c = .sbss:0x80575BF8; // type:object size:0x4 data:4byte @GUARD@draw__Q23m3d15mCustomShadow_cFRC6mMtx_c@nullMat = .sbss:0x80575BFC; // type:object size:0x1 data:byte @LOCAL@draw__Q23m3d15mCustomShadow_cFRC6mMtx_c@nullMat = .sbss:0x80575C00; // type:object size:0x4 data:4byte Zero__7mAng3_c = .sbss:0x80575C08; // type:object size:0x6 data:2byte diff --git a/include/d/lyt/d_lyt_drop_line.h b/include/d/lyt/d_lyt_drop_line.h index 173b2b7c..5cfc748e 100644 --- a/include/d/lyt/d_lyt_drop_line.h +++ b/include/d/lyt/d_lyt_drop_line.h @@ -3,9 +3,74 @@ #include "common.h" #include "d/a/d_a_item.h" +#include "d/d_base.h" +#include "m/m_vec.h" #include "nw4r/lyt/lyt_pane.h" +#include "s/s_State.hpp" +#include "toBeSorted/d_emitter.h" -class dLytDropLine_c { +class dLytDropLine_c; + +class dLytDropLineParts_c { +public: + dLytDropLineParts_c() : mStateMgr(*this) {} + + int create(dLytDropLine_c *main); + int doDelete(); + int execute(); + int draw(); + + /** Starts a line from the tear's world position to the tear slot, when picking up a tear. */ + void startPickup(mVec3_c tearWorldPos, s32 trial); + + /** Starts a line from the tear slot to the flower. */ + void startChange(mVec3_c startPos, s32 trial, bool leftRight); + + bool isMoveRequest() const { + return mMoveRequest; + } + + bool isDone() const { + return mIsDone; + } + + void setTargetPane(nw4r::lyt::Pane *pane) { + mIsDone = false; + mIsChangeAnim = false; + mpTargetPane = pane; + } + + void finish() { + mIsDone = false; + mIsChangeAnim = false; + } + + nw4r::lyt::Pane *getTargetPane() const { + return mpTargetPane; + } + +private: + STATE_FUNC_DECLARE(dLytDropLineParts_c, Wait); + STATE_FUNC_DECLARE(dLytDropLineParts_c, Move); + + void reset(); + + /* 0x00 */ UI_STATE_MGR_DECLARE(dLytDropLineParts_c); + /* 0x3C */ nw4r::lyt::Pane *mpTargetPane; + /* 0x40 */ dEmitter_c mEmitter; + /* 0x74 */ mVec3_c mStartPos; + /* 0x80 */ mVec3_c mEffectPos; + /* 0x8C */ mVec3_c field_0x8C; + /* 0x98 */ s32 mTrial; + /* 0x9C */ s32 mMoveTimer; + /* 0xA0 */ bool mMoveRequest; + /* 0xA1 */ bool mIsDone; + /* 0xA2 */ bool mLeftRight; + /* 0xA3 */ bool mIsChangeAnim; +}; + +/** 2D UI - Silent realm tear trail. */ +class dLytDropLine_c : public dBase_c { public: dLytDropLine_c() { sInstance = this; @@ -18,13 +83,35 @@ public: return sInstance; } + virtual int create() override; + virtual int doDelete() override; + virtual int execute() override; + virtual int draw() override; + + static bool finishPart(); + static void setPane(nw4r::lyt::Pane *pane); static nw4r::lyt::Pane *getActivePane(); - static nw4r::lyt::Pane *setPane(nw4r::lyt::Pane *pane); - static nw4r::lyt::Pane *update(nw4r::lyt::Pane *pane, nw4r::lyt::Pane *otherPane, dAcItem_c::Trial_e, bool); - static bool finishPartMaybe(); + static void startPickup(mVec3_c tearWorldPos, dAcItem_c::Trial_e trial); + static void startChange(nw4r::lyt::Pane *tearSlotPane, nw4r::lyt::Pane *flowerPane, dAcItem_c::Trial_e trial, bool leftRight); private: static dLytDropLine_c *sInstance; + + static const s32 NUM_PARTS = 15; + + int createInternal(); + int doDeleteInternal(); + int executeInternal(); + int drawInternal(); + + bool finishPartInternal(); + void setPaneInternal(nw4r::lyt::Pane *pane); + nw4r::lyt::Pane *getActivePaneInternal(); + + void startPickupInternal(mVec3_c tearWorldPos, dAcItem_c::Trial_e trial); + void startChangeInternal(nw4r::lyt::Pane *tearSlotPane, nw4r::lyt::Pane *flowerPane, dAcItem_c::Trial_e trial, bool leftRight); + + /* 0x68 */ dLytDropLineParts_c mParts[NUM_PARTS]; }; #endif diff --git a/include/d/lyt/meter/d_lyt_meter_timer.h b/include/d/lyt/meter/d_lyt_meter_timer.h index 129c2ba8..b57e6538 100644 --- a/include/d/lyt/meter/d_lyt_meter_timer.h +++ b/include/d/lyt/meter/d_lyt_meter_timer.h @@ -11,7 +11,7 @@ class LytMeterTimerPart1_c : public d2d::dSubPane { public: LytMeterTimerPart1_c() - : mActualTearCount(0), mDisplayedTearCount(0), field_0x760(0), mTrial(dAcItem_c::TRIAL_NONE), field_0x780(0) { + : mActualTearCount(0), mDisplayedTearCount(0), field_0x760(0), mTrial(dAcItem_c::TRIAL_NONE), mChangeFruitIndex(0) { sInstance = this; } virtual bool build(d2d::ResAccIf_c *resAcc) override; @@ -50,7 +50,7 @@ public: bool isOutAnimFinished(); void startFruitAnim(s32 index); void resetBowlNuts(); - void updateDropLine(nw4r::lyt::Pane *pane); + void startDropLineChange(nw4r::lyt::Pane *pane); void startEffect(s32 fruitIndex); bool incrementTearCount(); @@ -64,12 +64,12 @@ public: return mDisplayedTearCount; } - s32 getField0x780() const { - return field_0x780; + s32 getChangeFruitIndex() const { + return mChangeFruitIndex; } - void setField0x780(s32 val) { - field_0x780 = val; + void setChangeFruitIndex(s32 val) { + mChangeFruitIndex = val; } private: @@ -92,7 +92,7 @@ private: /* 0x764 */ dAcItem_c::Trial_e mTrial; /* 0x768 */ mColor mColors1[3]; /* 0x774 */ mColor mColors2[3]; - /* 0x780 */ s32 field_0x780; + /* 0x780 */ s32 mChangeFruitIndex; }; class LytMeterTimerPart2_c : public d2d::dSubPane { diff --git a/src/d/lyt/d_lyt_drop_line.cpp b/src/d/lyt/d_lyt_drop_line.cpp new file mode 100644 index 00000000..6d42e07f --- /dev/null +++ b/src/d/lyt/d_lyt_drop_line.cpp @@ -0,0 +1,347 @@ +#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(); + field_0x8C.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(); + + // TODO + mVec2_c v1 = mVec2_c(mtx._03, mtx._13); + v1 -= mVec2_c(mStartPos.x, mStartPos.y); + + field_0x8C.x = + (v1.x + ((f32)sHio.mMoveDuration * sHio.field_0x04 * (f32)sHio.mMoveDuration)) / (f32)sHio.mMoveDuration; + field_0x8C.y = v1.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 - + (field_0x8C.x * (f32)mMoveTimer - sHio.field_0x04 * (f32)mMoveTimer * (f32)mMoveTimer); + } else { + mEffectPos.x = + mStartPos.x + field_0x8C.x * (f32)mMoveTimer - sHio.field_0x04 * (f32)mMoveTimer * (f32)mMoveTimer; + } + + mEffectPos.y = mStartPos.y + field_0x8C.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; +} diff --git a/src/d/lyt/meter/d_lyt_meter_timer.cpp b/src/d/lyt/meter/d_lyt_meter_timer.cpp index 911f2a3e..bea18a95 100644 --- a/src/d/lyt/meter/d_lyt_meter_timer.cpp +++ b/src/d/lyt/meter/d_lyt_meter_timer.cpp @@ -243,7 +243,7 @@ void LytMeterTimerPart1_c::startNextFruitAnim() { } void LytMeterTimerPart1_c::startFruitAnim(s32 index) { - if (field_0x780 < TIMER_01_NUM_TEARS && !mAnm[index + TIMER_01_ANIM_BOWL_NUT_OFFSET].isEnabled()) { + if (mChangeFruitIndex < TIMER_01_NUM_TEARS && !mAnm[index + TIMER_01_ANIM_BOWL_NUT_OFFSET].isEnabled()) { mAnm[index + TIMER_01_ANIM_BOWL_NUT_OFFSET].setAnimEnable(true); } } @@ -264,7 +264,7 @@ void LytMeterTimerPart1_c::disableCurrentFruitAnim() { } void LytMeterTimerPart1_c::stopFinishedFruit() { - for (s32 i = 0; i <= field_0x780; i++) { + for (s32 i = 0; i <= mChangeFruitIndex; i++) { if (mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].isEnabled() && mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].isStop2()) { mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].setAnimEnable(false); return; @@ -292,7 +292,7 @@ bool LytMeterTimerPart1_c::isCurrentFruitAnimFinished() { } bool LytMeterTimerPart1_c::isAnyFruitAnimFinished() { - for (s32 i = 0; i <= field_0x780; i++) { + for (s32 i = 0; i <= mChangeFruitIndex; i++) { if (mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].isEnabled() && mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].isStop2()) { return true; } @@ -312,7 +312,7 @@ bool LytMeterTimerPart1_c::isOutAnimFinished() { } bool LytMeterTimerPart1_c::isAnyFruitAnimAtFrame(f32 f) const { - for (int i = 0; i <= field_0x780; i++) { + for (int i = 0; i <= mChangeFruitIndex; i++) { if (mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].isEnabled() && f - 1.0f < mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].getFrame() && mAnm[i + TIMER_01_ANIM_BOWL_NUT_OFFSET].getFrame() <= f) { @@ -324,7 +324,7 @@ bool LytMeterTimerPart1_c::isAnyFruitAnimAtFrame(f32 f) const { bool LytMeterTimerPart1_c::incrementTearCount() { mActualTearCount = ItemflagManager::sInstance->getFlagDirect(500); - if (mDisplayedTearCount < mActualTearCount && dLytDropLine_c::finishPartMaybe()) { + if (mDisplayedTearCount < mActualTearCount && dLytDropLine_c::finishPart()) { startNextFruitAnim(); if (!dLytMeter_c::getfn_800C9FE0()) { startEffect(mActualTearCount - 1); @@ -402,9 +402,9 @@ void LytMeterTimerPart1_c::startEffect(s32 fruitIndex) { ); } -void LytMeterTimerPart1_c::updateDropLine(nw4r::lyt::Pane *pane) { - u8 idx = field_0x780; - dLytDropLine_c::update(mpPanes[idx], pane, mTrial, field_0x780 % 2 != 0); +void LytMeterTimerPart1_c::startDropLineChange(nw4r::lyt::Pane *pane) { + u8 idx = mChangeFruitIndex; + dLytDropLine_c::startChange(mpPanes[idx], pane, mTrial, mChangeFruitIndex % 2 != 0); } static const d2d::LytBrlanMapping brlanMapPart2[] = { @@ -1226,7 +1226,7 @@ void dLytMeterTimer_c::executeState_ChangeFruits() { mpPart2->resetSingleAnim(TIMER_02_ANIM_FLOWER_LOOP); } - if (dLytDropLine_c::finishPartMaybe()) { + if (dLytDropLine_c::finishPart()) { if (mpPart1->isLastFruitAnimFinished()) { mpPart2->realizeFruitsColor(); mpPart2->enableChangeFruitAnim(); @@ -1238,10 +1238,10 @@ void dLytMeterTimer_c::executeState_ChangeFruits() { } if (mpPart1->isAnyFruitAnimAtFrame(4.0f)) { - s32 fruit = mpPart1->getField0x780() + 1; - mpPart1->setField0x780(fruit); - if (mpPart1->getField0x780() < TIMER_01_NUM_TEARS) { - mpPart1->updateDropLine(mpPart2->i_getPane()); + s32 fruit = mpPart1->getChangeFruitIndex() + 1; + mpPart1->setChangeFruitIndex(fruit); + if (mpPart1->getChangeFruitIndex() < TIMER_01_NUM_TEARS) { + mpPart1->startDropLineChange(mpPart2->i_getPane()); mpPart1->startFruitAnim(fruit); mpPart1->startEffect(fruit); } @@ -1456,9 +1456,9 @@ void dLytMeterTimer_c::gotoSafe() { void dLytMeterTimer_c::gotoChangeFruits6() { if (mStateMgr.isState(StateID_Siren) || mStateMgr.isState(StateID_Safe)) { mpPart1->resetBowlNuts(); - mpPart1->updateDropLine(mpPart2->i_getPane()); - mpPart1->startFruitAnim(mpPart1->getField0x780()); - mpPart1->startEffect(mpPart1->getField0x780()); + mpPart1->startDropLineChange(mpPart2->i_getPane()); + mpPart1->startFruitAnim(mpPart1->getChangeFruitIndex()); + mpPart1->startEffect(mpPart1->getChangeFruitIndex()); field_0x54 = false; field_0x56 = 6; mStateMgr.changeState(StateID_ChangeFruits); @@ -1504,9 +1504,9 @@ void dLytMeterTimer_c::startSafe() { void dLytMeterTimer_c::doPickup() { mpPart1->resetBowlNuts(); - mpPart1->updateDropLine(mpPart2->i_getPane()); - mpPart1->startFruitAnim(mpPart1->getField0x780()); - mpPart1->startEffect(mpPart1->getField0x780()); + mpPart1->startDropLineChange(mpPart2->i_getPane()); + mpPart1->startFruitAnim(mpPart1->getChangeFruitIndex()); + mpPart1->startEffect(mpPart1->getChangeFruitIndex()); field_0x56 = 6; }