From 3af8f03e78a56701d300a8c8f2639615c6cdc4ad Mon Sep 17 00:00:00 2001 From: robojumper Date: Tue, 30 Sep 2025 23:55:21 +0200 Subject: [PATCH] more map --- config/SOUE01/symbols.txt | 48 ++-- include/d/d_cs_game.h | 4 + include/d/lyt/d_lyt_map.h | 98 +++++++-- include/d/lyt/d_lyt_map_global.h | 29 ++- include/toBeSorted/d_beacon.h | 7 +- src/d/lyt/d_lyt_map.cpp | 366 ++++++++++++++++++++++++++++--- src/d/lyt/d_lyt_map_global.cpp | 2 +- 7 files changed, 474 insertions(+), 80 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 3f699681..6ceb1bd8 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -7581,8 +7581,8 @@ init__17dLytMapFloorBtn_cFv = .text:0x8012FC30; // type:function size:0x18 changeState__86sStateMgr_c<17dLytMapFloorBtn_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x8012FC50; // type:function size:0x10 execute__17dLytMapFloorBtn_cFv = .text:0x8012FC60; // type:function size:0x10 executeState__86sStateMgr_c<17dLytMapFloorBtn_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x8012FC70; // type:function size:0x10 -fn_8012FC80 = .text:0x8012FC80; // type:function size:0xB4 -fn_8012FD40 = .text:0x8012FD40; // type:function size:0xAC +directlyDecide__17dLytMapFloorBtn_cFv = .text:0x8012FC80; // type:function size:0xB4 +directlyUndecide__17dLytMapFloorBtn_cFv = .text:0x8012FD40; // type:function size:0xAC initializeState_Wait__17dLytMapFloorBtn_cFv = .text:0x8012FDF0; // type:function size:0x4 executeState_Wait__17dLytMapFloorBtn_cFv = .text:0x8012FE00; // type:function size:0xA0 finalizeState_Wait__17dLytMapFloorBtn_cFv = .text:0x8012FEA0; // type:function size:0x4 @@ -7627,15 +7627,15 @@ remove__20dLytMapFloorBtnMgr_cFv = .text:0x80130F40; // type:function size:0xB4 execute__20dLytMapFloorBtnMgr_cFv = .text:0x80131000; // type:function size:0x2D4 getStateID__89sStateMgr_c<20dLytMapFloorBtnMgr_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x801312E0; // type:function size:0x10 executeState__89sStateMgr_c<20dLytMapFloorBtnMgr_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x801312F0; // type:function size:0x10 -fn_80131300 = .text:0x80131300; // type:function size:0xF0 -fn_801313F0 = .text:0x801313F0; // type:function size:0x58 +checkPointedAtBtn__20dLytMapFloorBtnMgr_cFv = .text:0x80131300; // type:function size:0xF0 +getPointedAtBtnIdx__20dLytMapFloorBtnMgr_cCFv = .text:0x801313F0; // type:function size:0x58 fn_80131450 = .text:0x80131450; // type:function size:0x8 -fn_80131460 = .text:0x80131460; // type:function size:0xC4 -fn_80131530 = .text:0x80131530; // type:function size:0x5C -fn_80131590 = .text:0x80131590; // type:function size:0x1D8 +resetFloor__20dLytMapFloorBtnMgr_cFl = .text:0x80131460; // type:function size:0xC4 +decideSelectedFloor__20dLytMapFloorBtnMgr_cFv = .text:0x80131530; // type:function size:0x5C +canDecideFloor__20dLytMapFloorBtnMgr_cCFv = .text:0x80131590; // type:function size:0x1D8 getStateID__86sStateMgr_c<17dLytMapFloorBtn_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80131770; // type:function size:0x10 -fn_80131780 = .text:0x80131780; // type:function size:0x50 -fn_801317D0 = .text:0x801317D0; // type:function size:0x27C +getCurrentFloor__20dLytMapFloorBtnMgr_cCFv = .text:0x80131780; // type:function size:0x50 +init__20dLytMapFloorBtnMgr_cFlll = .text:0x801317D0; // type:function size:0x27C initializeState_Invisible__20dLytMapFloorBtnMgr_cFv = .text:0x80131A50; // type:function size:0x4 executeState_Invisible__20dLytMapFloorBtnMgr_cFv = .text:0x80131A60; // type:function size:0x4 finalizeState_Invisible__20dLytMapFloorBtnMgr_cFv = .text:0x80131A70; // type:function size:0x4 @@ -7807,7 +7807,7 @@ __dt__52sFStateMgr_c<13dLytMapMain_c,20sStateMethodUsr_FI_c>Fv = .text:0x8013651 fn_801365C0 = .text:0x801365C0; // type:function size:0x4 fn_801365D0 = .text:0x801365D0; // type:function size:0x40 __dt__13dLytMapMain_cFv = .text:0x80136610; // type:function size:0x608 -fn_80136C20 = .text:0x80136C20; // type:function size:0xC +getGlobal__13dLytMapMain_cFv = .text:0x80136C20; // type:function size:0xC fn_80136C30 = .text:0x80136C30; // type:function size:0xC8 fn_80136D00 = .text:0x80136D00; // type:function size:0x6CC changeState__82sStateMgr_c<13dLytMapMain_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x801373D0; // type:function size:0x10 @@ -7818,11 +7818,11 @@ fn_801378E0 = .text:0x801378E0; // type:function size:0x838 getStateID__94sStateMgr_c<25dLytMapPinIconAggregate_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x80138120; // type:function size:0x10 draw__13dLytMapMain_cFv = .text:0x80138130; // type:function size:0x238 fn_80138370 = .text:0x80138370; // type:function size:0x138 -fn_801384B0 = .text:0x801384B0; // type:function size:0x5C -fn_80138510 = .text:0x80138510; // type:function size:0x140 -fn_80138650 = .text:0x80138650; // type:function size:0x1E0 +canChangeUpDirection__13dLytMapMain_cCFlUc = .text:0x801384B0; // type:function size:0x5C +canZoomIn__13dLytMapMain_cCFl = .text:0x80138510; // type:function size:0x140 +canZoomOut__13dLytMapMain_cCFl = .text:0x80138650; // type:function size:0x1E0 fn_80138830 = .text:0x80138830; // type:function size:0x254 -fn_80138A90 = .text:0x80138A90; // type:function size:0x8C +needsNav__13dLytMapMain_cCFl = .text:0x80138A90; // type:function size:0x8C fn_80138B20 = .text:0x80138B20; // type:function size:0x110 fn_80138C30 = .text:0x80138C30; // type:function size:0x38 fn_80138C70 = .text:0x80138C70; // type:function size:0xA4 @@ -7830,7 +7830,7 @@ fn_80138D20 = .text:0x80138D20; // type:function size:0x5C fn_80138D80 = .text:0x80138D80; // type:function size:0xB0 fn_80138E30 = .text:0x80138E30; // type:function size:0xD4 fn_80138F10 = .text:0x80138F10; // type:function size:0xA0 -fn_80138FB0 = .text:0x80138FB0; // type:function size:0xA4 +canResetPosition__13dLytMapMain_cCFlUc = .text:0x80138FB0; // type:function size:0xA4 fn_80139060 = .text:0x80139060; // type:function size:0x28 isOpenMaybe__13dLytMapMain_cCFv = .text:0x80139090; // type:function size:0x478 fn_80139510 = .text:0x80139510; // type:function size:0xA8 @@ -7865,8 +7865,8 @@ fn_8013C6B0 = .text:0x8013C6B0; // type:function size:0xA8 fn_8013C760 = .text:0x8013C760; // type:function size:0x100 fn_8013C860 = .text:0x8013C860; // type:function size:0x1C fn_8013C880 = .text:0x8013C880; // type:function size:0x64 -fn_8013C8F0 = .text:0x8013C8F0; // type:function size:0x644 -fn_8013CF40 = .text:0x8013CF40; // type:function size:0x54C +zoomIn__13dLytMapMain_cFv = .text:0x8013C8F0; // type:function size:0x644 +zoomOut__13dLytMapMain_cFv = .text:0x8013CF40; // type:function size:0x54C initializeState_Active__13dLytMapMain_cFv = .text:0x8013D490; // type:function size:0x4 executeState_Active__13dLytMapMain_cFv = .text:0x8013D4A0; // type:function size:0x65C finalizeState_Active__13dLytMapMain_cFv = .text:0x8013DB00; // type:function size:0x10 @@ -8006,7 +8006,7 @@ fn_80143120 = .text:0x80143120; // type:function size:0xC0 fn_801431E0 = .text:0x801431E0; // type:function size:0x11C fn_80143300 = .text:0x80143300; // type:function size:0x54 fn_80143360 = .text:0x80143360; // type:function size:0x1D4 -fn_80143540 = .text:0x80143540; // type:function size:0x374 +checkScroll__13dLytMapMain_cFv = .text:0x80143540; // type:function size:0x374 fn_801438C0 = .text:0x801438C0; // type:function size:0x6C fn_80143930 = .text:0x80143930; // type:function size:0x60 fn_80143990 = .text:0x80143990; // type:function size:0x4C @@ -10066,7 +10066,7 @@ fn_801897D0 = .text:0x801897D0; // type:function size:0x168 fn_80189940 = .text:0x80189940; // type:function size:0x8C fn_801899D0 = .text:0x801899D0; // type:function size:0xEC fn_80189AC0 = .text:0x80189AC0; // type:function size:0x68 -fn_80189B30 = .text:0x80189B30; // type:function size:0x50 +setIslandNamesOn__19dLytMapDecoration_cFb = .text:0x80189B30; // type:function size:0x50 fn_80189B80 = .text:0x80189B80; // type:function size:0x4 fn_80189B90 = .text:0x80189B90; // type:function size:0x27C fn_80189E10 = .text:0x80189E10; // type:function size:0xF4 @@ -10108,11 +10108,11 @@ fn_8018B230 = .text:0x8018B230; // type:function size:0x74 ActorLink__handleHotPumpkinSoup = .text:0x8018B2B0; // type:function size:0xE4 fn_8018B3A0 = .text:0x8018B3A0; // type:function size:0x80 shouldDropItemForChance = .text:0x8018B420; // type:function size:0x84 -getBeaconCount__Fv = .text:0x8018B4B0; // type:function size:0x44 +getMaxBeaconCount__Fv = .text:0x8018B4B0; // type:function size:0x44 fn_8018B500 = .text:0x8018B500; // type:function size:0x40 getBeaconPositionByIndex = .text:0x8018B540; // type:function size:0x60 setBeaconPosition__FPC7mVec3_cUl = .text:0x8018B5A0; // type:function size:0x7C -placeBeaconButCheckGround = .text:0x8018B620; // type:function size:0x194 +setBeaconPositionChecked__FPC7mVec3_cUl = .text:0x8018B620; // type:function size:0x194 fn_8018B7C0 = .text:0x8018B7C0; // type:function size:0x40 fn_8018B800 = .text:0x8018B800; // type:function size:0x24 fn_8018B830 = .text:0x8018B830; // type:function size:0x4 @@ -33500,8 +33500,10 @@ lbl_8051ED54 = .data:0x8051ED54; // type:object size:0xC lbl_8051ED60 = .data:0x8051ED60; // type:object size:0x10 lbl_8051ED70 = .data:0x8051ED70; // type:object size:0xC lbl_8051ED7C = .data:0x8051ED7C; // type:object size:0x10 -lbl_8051ED8C = .data:0x8051ED8C; // type:object size:0x64 -lbl_8051EDF0 = .data:0x8051EDF0; // type:object size:0xC +lbl_8051ED8C = .data:0x8051ED8C; // type:object size:0x9 data:string +lbl_8051ED98 = .data:0x8051ED98; // type:object size:0x40 +lbl_8051EDD8 = .data:0x8051EDD8; // type:object size:0x15 data:string +lbl_8051EDF0 = .data:0x8051EDF0; // type:object size:0x9 data:string lbl_8051EDFC = .data:0x8051EDFC; // type:object size:0xC lbl_8051EE08 = .data:0x8051EE08; // type:object size:0xC lbl_8051EE14 = .data:0x8051EE14; // type:object size:0xC diff --git a/include/d/d_cs_game.h b/include/d/d_cs_game.h index b8dd9831..11c1373b 100644 --- a/include/d/d_cs_game.h +++ b/include/d/d_cs_game.h @@ -435,6 +435,10 @@ public: return mCursorIf.getHit(); } + dCursorInterfaceGame_c *getCursorIf() { + return &mCursorIf; + } + private: static dCsGame_c *sInstance; bool isForcedHidden() const; diff --git a/include/d/lyt/d_lyt_map.h b/include/d/lyt/d_lyt_map.h index 7b420a56..6ca15fb8 100644 --- a/include/d/lyt/d_lyt_map.h +++ b/include/d/lyt/d_lyt_map.h @@ -170,6 +170,8 @@ private: }; class dLytMapPinIconAggregate_c { + friend class dLytMapMain_c; + public: dLytMapPinIconAggregate_c() : mStateMgr(*this, sStateID::null) { field_0x9A0 = nullptr; @@ -211,6 +213,7 @@ private: // Size 0x50 class dLytMapFloorBtn_c { friend class dLytMapFloorBtnMgr_c; + public: dLytMapFloorBtn_c() : mStateMgr(*this, sStateID::null), @@ -218,8 +221,8 @@ public: mpAnmGroups(nullptr), field_0x44(0), mpBounding(nullptr), - field_0x4C(0), - field_0x4D(0) {} + mSelected(false), + mDecided(false) {} ~dLytMapFloorBtn_c() {} STATE_FUNC_DECLARE(dLytMapFloorBtn_c, Wait); @@ -237,27 +240,30 @@ public: bool build(d2d::ResAccIf_c *resAcc); + void directlyDecide(); + void directlyUndecide(); + private: /* 0x00 */ UI_STATE_MGR_DECLARE(dLytMapFloorBtn_c); /* 0x3C */ d2d::LytBase_c *mpOwnerLyt; /* 0x40 */ dLytMapFloorBtnAnmGroups *mpAnmGroups; /* 0x44 */ UNKWORD field_0x44; /* 0x48 */ nw4r::lyt::Bounding *mpBounding; - /* 0x4C */ u8 field_0x4C; - /* 0x4D */ u8 field_0x4D; + /* 0x4C */ bool mSelected; + /* 0x4D */ bool mDecided; }; class dLytMapFloorBtnMgr_c : public d2d::dSubPane { public: dLytMapFloorBtnMgr_c(dLytMapGlobal_c *global) : mpGlobal(global), mpPane(nullptr), mStateMgr(*this, sStateID::null) { - field_0x700 = 1; - field_0x704 = 0; - field_0x708 = 0; + mNumFloors = 1; + mBaseFloorOffset = 0; + mSelectedBtnIdx = 0; field_0x70C = 4; - field_0x710 = 0; - field_0x711 = 0; - field_0x712 = 0; + field_0x710 = false; + field_0x711 = false; + field_0x712 = false; } virtual ~dLytMapFloorBtnMgr_c(); @@ -277,7 +283,22 @@ public: STATE_FUNC_DECLARE(dLytMapFloorBtnMgr_c, Invisible); STATE_FUNC_DECLARE(dLytMapFloorBtnMgr_c, Wait); + void init(s32 numFloors, s32 baseFloorOffset, s32 selectedFloor); + + bool canDecideFloor() const; + void decideSelectedFloor(); + s32 getCurrentFloor() const; + s32 getPointedAtBtnIdx() const; + + bool hasPointedAtABtnIdx() const { + return getPointedAtBtnIdx() >= 0; + } + + void resetFloor(s32 newFloor); + private: + void checkPointedAtBtn(); + /* 0x008 */ dLytMapGlobal_c *mpGlobal; /* 0x00C */ UI_STATE_MGR_DECLARE(dLytMapFloorBtnMgr_c); /* 0x048 */ d2d::dLytSub mLyt; @@ -286,13 +307,13 @@ private: /* 0x51C */ nw4r::lyt::Pane *mpPane; /* 0x520 */ dCursorHitCheckLyt_c mCsHitChecks[4]; /* 0x5C0 */ dLytMapFloorBtn_c mFloorBtns[4]; - /* 0x700 */ UNKWORD field_0x700; - /* 0x704 */ UNKWORD field_0x704; - /* 0x708 */ UNKWORD field_0x708; + /* 0x700 */ s32 mNumFloors; + /* 0x704 */ s32 mBaseFloorOffset; + /* 0x708 */ s32 mSelectedBtnIdx; /* 0x70C */ UNKWORD field_0x70C; - /* 0x710 */ u8 field_0x710; - /* 0x711 */ u8 field_0x711; - /* 0x712 */ u8 field_0x712; + /* 0x710 */ bool field_0x710; + /* 0x711 */ bool field_0x711; + /* 0x712 */ bool field_0x712; }; // Size 0x4C @@ -383,6 +404,8 @@ class dLytMapDecoration_c { public: dLytMapDecoration_c() {} virtual ~dLytMapDecoration_c() {} + + void setIslandNamesOn(bool on); }; /** 2D UI - Map - beacon preview icon following the cursor */ @@ -463,6 +486,21 @@ public: STATE_FUNC_DECLARE(dLytMapMain_c, EventSaveObjDecide); private: + dLytMapGlobal_c *getGlobal(); + void checkScroll(); + bool needsNav(s32 mapMode) const; + bool canZoomOut(s32 mapMode) const; + bool canZoomIn(s32 mapMode) const; + bool canResetPosition(s32 mapMode, u8) const; + bool canChangeUpDirection(s32 mapMode, u8) const; + + f32 fn_80142D90(s32); + void fn_80142F00(mVec3_c &, s32 mapMode, u8, const mVec3_c &, const mAng &); + void fn_8013FB70(const mVec3_c&, f32); + + void zoomOut(); + void zoomIn(); + /* 0x0010 */ UI_STATE_MGR_DECLARE(dLytMapMain_c); /* 0x004C */ dFlowMgrBase_c mFlowMgr; /* 0x00A4 */ dFlow_c mFlow; @@ -511,12 +549,24 @@ private: /* 0x8948 */ LytMapTwoVecs field_0x8948[33]; - /* 0x8C60 */ u8 _0x8C60[0x8C94 - 0x8C60]; + /* 0x8C60 */ s32 mMaxBeaconCount; + /* 0x8C64 */ s32 field_0x8C64; + /* 0x8C68 */ s32 field_0x8C68; + /* 0x8C6C */ u8 _0x8C6C[0x8C90 - 0x8C6C]; + + /* 0x8C90 */ u8 field_0x8C90; /* 0x8C94 */ s32 field_0x8C94; - /* 0x8C98 */ u8 _0x8C98[0x8CC4 - 0x8C98]; + /* 0x8C98 */ u8 _0x8C98[0x8CA4 - 0x8C98]; + /* 0x8CA4 */ s32 field_0x8CA4; + /* 0x8CA8 */ s32 field_0x8CA8; + + /* 0x8CAC */ u8 _0x8CAC[0x8CC0 - 0x8CAC]; + + /* 0x8CC0 */ bool field_0x8CC0; + /* 0x8CC1 */ bool field_0x8CC1; /* 0x8CC4 */ mVec3_c field_0x8CC4; /* 0x8CD0 */ mVec3_c field_0x8CD0; /* 0x8CDC */ mVec3_c field_0x8CDC; @@ -535,9 +585,9 @@ private: /* 0x8D4C */ f32 field_0x8D4C; /* 0x8D50 */ f32 field_0x8D50; /* 0x8D54 */ u8 _0x8D54[0x8D58 - 0x8D54]; - /* 0x8D58 */ UNKWORD field_0x8D58; + /* 0x8D58 */ s32 field_0x8D58; /* 0x8D5C */ UNKWORD field_0x8D5C; - /* 0x8D60 */ UNKWORD field_0x8D60; + /* 0x8D60 */ s32 field_0x8D60; /* 0x8D64 */ UNKWORD field_0x8D64; /* 0x8D68 */ mAng field_0x8D68; /* 0x8D6A */ u8 field_0x8D6A; @@ -547,7 +597,13 @@ private: /* 0x8D74 */ u8 _0x8D74[0x8D94 - 0x8D74]; /* 0x8D94 */ d2d::SubPaneList mSubpaneList; /* 0x8DA0 */ d2d::SubPaneListNode mSubpane; - /* 0x8DB0 */ u8 _0x8DB0[0x8DC8 - 0x8DB0]; + /* 0x8DB0 */ u8 _0x8DB0[0x8DB4 - 0x8DB0]; + /* 0x8DB4 */ bool mNavEnabled; + /* 0x8DB4 */ bool field_0x8DB5; + /* 0x8DB6 */ u8 _0x8DB6[0x8DBC - 0x8DB6]; + /* 0x8DBC */ bool mIslandNamesOn; + /* 0x8DBD */ bool field_0x8DBD; + /* 0x8DBE */ u8 _0x8DBE[0x8DC8 - 0x8DBE]; /* 0x8DC8 */ dLytMapGlobal_c mGlobal; }; diff --git a/include/d/lyt/d_lyt_map_global.h b/include/d/lyt/d_lyt_map_global.h index a9b742a5..646bac8a 100644 --- a/include/d/lyt/d_lyt_map_global.h +++ b/include/d/lyt/d_lyt_map_global.h @@ -15,24 +15,35 @@ public: enum MapMode_e { MAPMODE_WORLD = 0, MAPMODE_PROVINCE = 1, + MAPMODE_WORLD_SKY = 2, MAPMODE_STAGE = 3, MAPMODE_ZOOM = 4, - - // There probably are more special-purpose modes... }; static dLytMapGlobal_c *GetInstance() { return sInstance; } + const mVec3_c &getField_0x00() const { + return field_0x00; + } + const mVec2_c &getField_0x20() const { return field_0x20; } + const mVec3_c &getMapRotationCenter() const { + return mMapRotationCenter; + } + const mVec3_c &getPlayerPos() const { return mPlayerPosition; } + const mAng &getField_0x56() const { + return field_0x56; + } + u8 getAlpha() const { return mAlpha; } @@ -53,6 +64,14 @@ public: return field_0x44; } + s32 getFloor() const { + return mFloor; + } + + void setFloor(s32 floor) { + mFloor = floor; + } + void projectOntoMap(mVec2_c &result, const mVec3_c &position) const; void unprojectFromMap(mVec3_c &result, const mVec2_c &position) const; void unprojectFromMap(mVec3_c &result, const mVec2_c &position, const mAng &rot) const; @@ -81,13 +100,15 @@ private: /* 0x3C */ mAng mMapRotation; /* 0x40 */ f32 field_0x40; /* 0x44 */ f32 field_0x44; - /* 0x48 */ UNKWORD mLevel; + /* 0x48 */ s32 mFloor; /* 0x4C */ u8 field_0x4C; /* 0x4D */ u8 field_0x4D; /* 0x4E */ u8 mAlpha; /* 0x4F */ u8 field_0x4F; /* 0x50 */ UNKWORD field_0x50; - /* 0x54 */ u8 _0x54[0x5C - 0x54]; + /* 0x54 */ u8 _0x54[0x56 - 0x54]; + /* 0x56 */ mAng field_0x56; + /* 0x58 */ u8 _0x58[0x5C - 0x58]; /* 0x5C */ s32 mCurrentMapMode; /* 0x60 */ s32 mNextMapMode; /* 0x64 */ f32 mZoomFrame; ///< 0.0f when zoomed out, 1.0f when zoomed in diff --git a/include/toBeSorted/d_beacon.h b/include/toBeSorted/d_beacon.h index 71631457..27efce6a 100644 --- a/include/toBeSorted/d_beacon.h +++ b/include/toBeSorted/d_beacon.h @@ -3,7 +3,7 @@ #include "m/m_vec.h" -u32 getBeaconCount(); +u32 getMaxBeaconCount(); /** * When passed a position, sets the beacon with the given index to the position. @@ -11,4 +11,9 @@ u32 getBeaconCount(); */ void setBeaconPosition(const mVec3_c *position, u32 beaconIndex); +/** + * Sets a beacon position similar to `setBeaconPosition`, but corrects the ground level + */ +void setBeaconPositionChecked(const mVec3_c *position, u32 beaconIndex); + #endif diff --git a/src/d/lyt/d_lyt_map.cpp b/src/d/lyt/d_lyt_map.cpp index cf2c122a..cd1f6491 100644 --- a/src/d/lyt/d_lyt_map.cpp +++ b/src/d/lyt/d_lyt_map.cpp @@ -6,16 +6,20 @@ #include "d/d_cs_game.h" #include "d/d_cursor_hit_check.h" #include "d/d_d2d.h" +#include "d/d_message.h" #include "d/d_pad.h" #include "d/d_pad_nav.h" #include "d/d_player.h" +#include "d/d_rumble.h" #include "d/lyt/d2d.h" #include "d/lyt/d_lyt_control_game.h" #include "d/lyt/d_lyt_map_global.h" +#include "d/lyt/d_textbox.h" #include "d/snd/d_snd_small_effect_mgr.h" #include "egg/core/eggColorFader.h" #include "m/m_vec.h" #include "m/m_video.h" +#include "nw4r/g3d/g3d_obj.h" #include "nw4r/lyt/lyt_bounding.h" #include "nw4r/lyt/lyt_pane.h" #include "sized_string.h" @@ -248,8 +252,6 @@ void dLytMapFootPrints_c::draw() { mVec2_c scaleV = mVec2_c(scale, scale); mpPane->SetScale(scaleV); - // rgb(104, 222, 222) - // rgb(0, 255, 255) f32 globalAlphaF = globalAlpha; for (int i = 0; i < mCurrentNumSteps; i++) { @@ -560,7 +562,7 @@ dLytMapGlobal_c *dLytMapPinIcon_c::getGlobal() const { static const d2d::LytBrlanMapping sMapPinIconBrlanMap[] = { {"mapPutIcon_00_scale.brlan", "G_scale_00"}, {"mapPutIcon_00_erase.brlan", "G_scale_00"}, - { "mapPutIcon_00_loop.brlan", "G_scale_00"}, + { "mapPutIcon_00_loop.brlan", "G_loop_00"}, }; bool dLytMapPinIcon_c::build(d2d::ResAccIf_c *resAcc) { @@ -685,7 +687,7 @@ void dLytMapPinIconAggregate_c::finalizeState_Remove() {} bool dLytMapPinIconAggregate_c::findNewBeaconId(s32 *pOutId) { bool ret = false; - for (s32 idx = 0; idx < getBeaconCount(); idx++) { + for (s32 idx = 0; idx < getMaxBeaconCount(); idx++) { s32 existingIndex = mPins[idx].mIndex; if (!mPins[idx].mIsSet) { // If we have an unused id, use that @@ -795,42 +797,161 @@ void dLytMapFloorBtn_c::execute() { mStateMgr.executeState(); } +void dLytMapFloorBtn_c::directlyDecide() { + if (mpAnmGroups->mOnOff.isBound()) { + mpAnmGroups->mOnOff.unbind(); + } + if (mpAnmGroups->mDecide.isBound()) { + mpAnmGroups->mDecide.unbind(); + } + mpAnmGroups->mOnOffLight.bind(false); + mpAnmGroups->mOnOffLight.setToEnd(); + mpOwnerLyt->calc(); + mpAnmGroups->mOnOffLight.unbind(); +} + +void dLytMapFloorBtn_c::directlyUndecide() { + if (mpAnmGroups->mOnOffLight.isBound()) { + mpAnmGroups->mOnOffLight.unbind(); + } + if (mpAnmGroups->mDecide.isBound()) { + mpAnmGroups->mDecide.unbind(); + } + mpAnmGroups->mOnOff.bind(false); + mpAnmGroups->mOnOff.setFrame(0.0f); + mpOwnerLyt->calc(); + mpAnmGroups->mOnOff.unbind(); +} + void dLytMapFloorBtn_c::initializeState_Wait() {} -void dLytMapFloorBtn_c::executeState_Wait() {} +void dLytMapFloorBtn_c::executeState_Wait() { + if (mSelected) { + dRumble_c::start(dRumble_c::sRumblePreset1, dRumble_c::FLAG_SLOT0); + mpAnmGroups->mOnOff.bind(false); + mpAnmGroups->mOnOff.setFrame(0.0f); + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_POINT_FLOOR); + mStateMgr.changeState(StateID_ToSelect); + } +} void dLytMapFloorBtn_c::finalizeState_Wait() {} void dLytMapFloorBtn_c::initializeState_ToSelect() {} -void dLytMapFloorBtn_c::executeState_ToSelect() {} +void dLytMapFloorBtn_c::executeState_ToSelect() { + if (mpAnmGroups->mOnOff.isEndReached()) { + mpOwnerLyt->calc(); + mpAnmGroups->mOnOff.unbind(); + mStateMgr.changeState(StateID_Select); + } +} void dLytMapFloorBtn_c::finalizeState_ToSelect() {} void dLytMapFloorBtn_c::initializeState_Select() {} -void dLytMapFloorBtn_c::executeState_Select() {} +void dLytMapFloorBtn_c::executeState_Select() { + if (!mSelected) { + mpAnmGroups->mOnOff.bind(false); + mpAnmGroups->mOnOff.setBackward(); + mpAnmGroups->mOnOff.setToStart(); + mStateMgr.changeState(StateID_ToWait); + } else if (mDecided) { + mpAnmGroups->mDecide.bind(false); + mpAnmGroups->mDecide.setFrame(0.0f); + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_POINT_SELECT_FLOOR); + mStateMgr.changeState(StateID_ToSelectInDecide); + } +} void dLytMapFloorBtn_c::finalizeState_Select() {} void dLytMapFloorBtn_c::initializeState_ToWait() {} -void dLytMapFloorBtn_c::executeState_ToWait() {} +void dLytMapFloorBtn_c::executeState_ToWait() { + if (mpAnmGroups->mOnOff.isStop2()) { + mpOwnerLyt->calc(); + mpAnmGroups->mOnOff.unbind(); + mStateMgr.changeState(StateID_Wait); + } +} void dLytMapFloorBtn_c::finalizeState_ToWait() {} void dLytMapFloorBtn_c::initializeState_ToSelectInDecide() {} -void dLytMapFloorBtn_c::executeState_ToSelectInDecide() {} +void dLytMapFloorBtn_c::executeState_ToSelectInDecide() { + if (mpAnmGroups->mDecide.isStop2()) { + mpOwnerLyt->calc(); + mpAnmGroups->mDecide.unbind(); + mStateMgr.changeState(StateID_SelectInDecide); + } +} void dLytMapFloorBtn_c::finalizeState_ToSelectInDecide() {} void dLytMapFloorBtn_c::initializeState_SelectInDecide() {} -void dLytMapFloorBtn_c::executeState_SelectInDecide() {} +void dLytMapFloorBtn_c::executeState_SelectInDecide() { + if (!mSelected) { + mpAnmGroups->mOnOffLight.bind(false); + mpAnmGroups->mOnOffLight.setToStart(); + mStateMgr.changeState(StateID_ToDecide); + } +} void dLytMapFloorBtn_c::finalizeState_SelectInDecide() {} void dLytMapFloorBtn_c::initializeState_ToDecide() {} -void dLytMapFloorBtn_c::executeState_ToDecide() {} +void dLytMapFloorBtn_c::executeState_ToDecide() { + if (mpAnmGroups->mOnOffLight.isStop2()) { + mpAnmGroups->mOnOffLight.unbind(); + mpOwnerLyt->calc(); + mStateMgr.changeState(StateID_Decide); + } +} void dLytMapFloorBtn_c::finalizeState_ToDecide() {} void dLytMapFloorBtn_c::initializeState_Decide() {} -void dLytMapFloorBtn_c::executeState_Decide() {} +void dLytMapFloorBtn_c::executeState_Decide() { + if (mSelected) { + mpAnmGroups->mOnOffLight.bind(false); + mpAnmGroups->mOnOffLight.setBackward(); + mpAnmGroups->mOnOffLight.setToStart(); + dRumble_c::start(dRumble_c::sRumblePreset1, dRumble_c::FLAG_SLOT0); + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_POINT_FLOOR); + mStateMgr.changeState(StateID_DecideToSelectInDecide); + } else if (!mDecided) { + mpAnmGroups->mOnOff.bind(false); + mpAnmGroups->mOnOff.setFrame(0.0f); + mpOwnerLyt->getLayout()->Animate(0); + mpOwnerLyt->calc(); + mpAnmGroups->mOnOff.unbind(); + mStateMgr.changeState(StateID_Wait); + } +} void dLytMapFloorBtn_c::finalizeState_Decide() {} void dLytMapFloorBtn_c::initializeState_DecideToSelectInDecide() {} -void dLytMapFloorBtn_c::executeState_DecideToSelectInDecide() {} +void dLytMapFloorBtn_c::executeState_DecideToSelectInDecide() { + if (mpAnmGroups->mOnOffLight.isStop2()) { + mpOwnerLyt->calc(); + mpAnmGroups->mOnOffLight.unbind(); + mStateMgr.changeState(StateID_SelectInDecide); + } +} void dLytMapFloorBtn_c::finalizeState_DecideToSelectInDecide() {} +static const char *sFloorBtnBoundings[] = { + "B_choices_00", + "B_choices_01", + "B_choices_02", + "B_choices_03", +}; + +static const char *sFloorBtnText[] = { + "T_text_00", + "T_text_01", + "T_text_02", + "T_text_03", +}; + +static const char *sFloorBtnTextS[] = { + "T_textS_00", + "T_textS_01", + "T_textS_02", + "T_textS_03", +}; + static const d2d::LytBrlanMapping brlanMapFloorBtnMgr[] = { {"mapFloorBtn_00_btnV.brlan", "G_btnV_00"}, }; @@ -852,13 +973,6 @@ static const char *groupListFloorBtn[][4] = { {"G_btnLoop_03", "G_btn_03", "G_btn_03", "G_btn_03"}, }; -static const char *sFloorBtnBoundings[] = { - "B_choices_00", - "B_choices_01", - "B_choices_02", - "B_choices_03", -}; - #define MAP_FLOOR_BTN_MGR_NUM_BTNS 4 bool dLytMapFloorBtnMgr_c::build(d2d::ResAccIf_c *resAcc) { @@ -916,11 +1030,11 @@ bool dLytMapFloorBtnMgr_c::build(d2d::ResAccIf_c *resAcc) { mCsHitChecks[i].execute(); } - field_0x710 = 0; - field_0x711 = 0; + field_0x710 = false; + field_0x711 = false; for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { - mFloorBtns[i].field_0x4C = 0; + mFloorBtns[i].mSelected = false; } mStateMgr.changeState(StateID_Invisible); @@ -960,13 +1074,13 @@ bool dLytMapFloorBtnMgr_c::execute() { s32 direction = dPadNav::getFSStickNavDirection(); if (field_0x710 != field_0x711) { for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { - if (mFloorBtns[i].field_0x4D) { + if (mFloorBtns[i].mDecided) { activeBtn = i; } } } else { for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { - if (mFloorBtns[i].field_0x4C) { + if (mFloorBtns[i].mSelected) { activeBtn = i; } } @@ -974,11 +1088,11 @@ bool dLytMapFloorBtnMgr_c::execute() { // Handle navigation if (activeBtn > 0 && (direction == dPadNav::FS_STICK_UP || direction == dPadNav::FS_STICK_UP_RIGHT || - direction == dPadNav::FS_STICK_UP_LEFT)) { + direction == dPadNav::FS_STICK_UP_LEFT)) { activeBtn--; } - if (activeBtn < field_0x700 - 1 && + if (activeBtn < mNumFloors - 1 && (direction == dPadNav::FS_STICK_DOWN || direction == dPadNav::FS_STICK_DOWN_RIGHT || direction == dPadNav::FS_STICK_DOWN_LEFT)) { activeBtn++; @@ -986,12 +1100,12 @@ bool dLytMapFloorBtnMgr_c::execute() { for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { if (i == activeBtn) { - mFloorBtns[i].field_0x4C = 1; + mFloorBtns[i].mSelected = true; if (dCsBase_c::GetInstance() != nullptr) { dCsBase_c::GetInstance()->setCursorStickTargetPane(mFloorBtns[i].mpBounding); } } else { - mFloorBtns[i].field_0x4C = 0; + mFloorBtns[i].mSelected = false; } } for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { @@ -1021,6 +1135,93 @@ bool dLytMapFloorBtnMgr_c::execute() { return true; } +void dLytMapFloorBtnMgr_c::checkPointedAtBtn() { + field_0x711 = field_0x710; + field_0x710 = dPadNav::isPointerVisible(); + if (field_0x712) { + dPadNav::stopFSStickNav(); + field_0x710 = true; + } + + if (field_0x710) { + for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { + mFloorBtns[i].mSelected = false; + } + + dCursorHitCheck_c *chk = dCsGame_c::GetInstance()->getCursorHit(); + if (chk != nullptr && chk->getType() == 'lyt ') { + for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { + if (chk == &mCsHitChecks[i]) { + mFloorBtns[i].mSelected = true; + } + } + } + } +} + +s32 dLytMapFloorBtnMgr_c::getPointedAtBtnIdx() const { + s32 idx = -1; + for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { + if (mFloorBtns[i].mSelected) { + idx = i; + break; + } + } + return idx; +} + +// What it says on the tin +static const char *sFloorBtnLabels[] = { + "FLOOR_F3", "FLOOR_F2", "FLOOR_F1", "FLOOR_B1", "FLOOR_B2", "FLOOR_B3", +}; + +void dLytMapFloorBtnMgr_c::init(s32 numFloors, s32 baseFloorOffset, s32 selectedFloor) { + mNumFloors = numFloors; + mBaseFloorOffset = baseFloorOffset; + for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { + bool visible = i < mNumFloors && mNumFloors >= 2; + mLyt.findPane(sFloorBtnBoundings[i])->SetVisible(visible); + } + + if (mNumFloors >= 2) { + mLyt.getLayout()->GetRootPane()->SetVisible(true); + mAnmGroups[0].bind(false); + mAnmGroups[0].setFrame(mNumFloors - 2); + + for (int i = 0; i < MAP_FLOOR_BTN_MGR_NUM_BTNS; i++) { + bool visible = i < mNumFloors && mNumFloors >= 2; + mLyt.findPane(sFloorBtnBoundings[i])->SetVisible(visible); + if (visible) { + int labelIdx = (2 - mBaseFloorOffset) + i; + dTextBox_c *textBox = mLyt.getTextBox(sFloorBtnText[i]); + textBox->setMessageWithGlobalTextProcessor2(sFloorBtnLabels[labelIdx], nullptr); + textBox = mLyt.getTextBox(sFloorBtnTextS[i]); + textBox->setMessageWithGlobalTextProcessor2(sFloorBtnLabels[labelIdx], nullptr); + } + } + + // Floor buttons are descending but selectedFloor is ascending + s32 tmp = -(selectedFloor - baseFloorOffset); + mSelectedBtnIdx = tmp; + mFloorBtns[tmp].mDecided = true; + mFloorBtns[tmp].mStateMgr.changeState(dLytMapFloorBtn_c::StateID_Decide); + + // TODO probably an inline + d2d::AnmGroup_c &anm = mBtnGroups[tmp].mOnOffLight; + + anm.bind(false); + mBtnGroups[tmp].mOnOffLight.setToEnd(); + mLyt.getLayout()->Animate(0); + mLyt.calc(); + anm.unbind(); + if (mAnmGroups[0].bind(false)) { + mAnmGroups[0].unbind(); + } + } else { + mLyt.getLayout()->GetRootPane()->SetVisible(false); + } +} + void dLytMapFloorBtnMgr_c::initializeState_Invisible() {} void dLytMapFloorBtnMgr_c::executeState_Invisible() {} void dLytMapFloorBtnMgr_c::finalizeState_Invisible() {} @@ -1134,6 +1335,10 @@ dLytMapMain_c::~dLytMapMain_c() { } } +dLytMapGlobal_c *dLytMapMain_c::getGlobal() { + return &mGlobal; +} + void dLytMapMain_c::draw() {} void dLytMap_c::build() { @@ -1164,7 +1369,108 @@ void dLytMapMain_c::executeState_In() {} void dLytMapMain_c::finalizeState_In() {} void dLytMapMain_c::initializeState_Active() {} -void dLytMapMain_c::executeState_Active() {} +void dLytMapMain_c::executeState_Active() { + dLytMapGlobal_c *global = getGlobal(); + if (dMessage_c::getInstance()->getField_0x328()) { + return; + } + + // TODO figure out and double check numbers + if (field_0x8C68 == 4 && field_0x8CA4 == dLytMapGlobal_c::MAPMODE_STAGE && + field_0x8CA8 == dLytMapGlobal_c::MAPMODE_STAGE && dPad::getDownTrigZ()) { + if (mIslandNamesOn) { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_ISLAND_NAME_OFF); + } else { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_ISLAND_NAME_ON); + } + mIslandNamesOn = !mIslandNamesOn; + field_0x2060.setIslandNamesOn(mIslandNamesOn); + } + checkScroll(); + + if (needsNav(field_0x8CA4) && needsNav(field_0x8CA8)) { + if (!mNavEnabled) { + dPadNav::setNavEnabled(true, false); + mNavEnabled = true; + } + if (mFloorBtnMgr.canDecideFloor() && dPad::getDownTrigA()) { + mFloorBtnMgr.decideSelectedFloor(); + field_0x8C64 = mFloorBtnMgr.getCurrentFloor(); + global->setFloor(field_0x8C64); + mStateMgr.changeState(StateID_FloorChange); + } + } else { + if (mNavEnabled) { + dPadNav::setNavEnabled(false, false); + mNavEnabled = false; + } + } + + if (field_0x8CA4 == dLytMapGlobal_c::MAPMODE_STAGE && field_0x8CA8 == dLytMapGlobal_c::MAPMODE_STAGE && + canZoomIn(dLytMapGlobal_c::MAPMODE_STAGE)) { + if (field_0x8CC0 && (field_0x8D5C < 2 || !mFloorBtnMgr.hasPointedAtABtnIdx())) { + const mVec3_c &pos = global->getPlayerPos(); + getGlobal()->unprojectFromMap(field_0x8CF4, dCsGame_c::GetInstance()->getCursorIf()->getCursorPos()); + f32 tmp = fn_80142D90(4); + fn_8013FB70(field_0x8CF4, getGlobal()->getField_0x44() / tmp); + field_0x8DB5 = true; + } else { + f32 tmp = fn_80142D90(4); + f32 val = getGlobal()->getField_0x44() / tmp; + fn_8013FB70(getGlobal()->getPlayerPos(), val); + field_0x8DB5 = true; + } + } + + if (field_0x8DBD && *mPinIconAggregate.mStateMgr.getStateID() != dLytMapPinIconAggregate_c::StateID_Select && + dPad::getDownTrigC() && field_0x8CC1) { + s32 id = -1; + mPinIconAggregate.findNewBeaconId(&id); + if (id >= 0) { + mVec3_c pos3d; + dLytMapGlobal_c *global = getGlobal(); + global->unprojectFromMap(pos3d, dCsGame_c::GetInstance()->getCursorIf()->getCursorPos()); + mPinIconAggregate.setPosition(id, pos3d); + setBeaconPositionChecked(&pos3d, id); + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_BEACON_SET); + } + } else if ((dPad::getDownTrigLeft() && canZoomOut(field_0x8CA4)) || + (dPad::getDownTrigA() && field_0x8CA4 == dLytMapGlobal_c::MAPMODE_ZOOM && canZoomOut(field_0x8CA4))) { + zoomOut(); + } else if ((dPad::getDownTrigRight() && canZoomIn(field_0x8CA4)) || + (dPad::getDownTrigA() && field_0x8CA4 == dLytMapGlobal_c::MAPMODE_STAGE && canZoomIn(field_0x8CA4))) { + zoomIn(); + } else if ((field_0x8C68 == dLytMapGlobal_c::MAPMODE_WORLD || field_0x8C68 == dLytMapGlobal_c::MAPMODE_PROVINCE || + field_0x8C68 == dLytMapGlobal_c::MAPMODE_WORLD_SKY || field_0x8C68 == dLytMapGlobal_c::MAPMODE_ZOOM) && + canResetPosition(field_0x8CA4, field_0x8C90) && dPad::getDownTrigUp()) { + mVec3_c pos; + fn_80142F00(pos, field_0x8CA4, field_0x8C90, global->getMapRotationCenter(), global->getField_0x56()); + f32 distSq = global->getField_0x00().squareDistanceToXZ(pos); + if (field_0x8D58 != global->getFloor()) { + mFloorBtnMgr.resetFloor(-(field_0x8D58 - field_0x8D60)); + global->setFloor(field_0x8D58); + mStateMgr.changeState(StateID_ResetPosWithFloorChange); + } else if (distSq >= 1.0f) { + mStateMgr.changeState(StateID_ResetPos); + } else { + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_RESET_NOT_MOVE); + } + } else if (canChangeUpDirection(field_0x8CA4, field_0x8C90) && dPad::getDownTrigZ()) { + mStateMgr.changeState(StateID_ChgMapUpDirection); + } + + if ((field_0x8CA4 == dLytMapGlobal_c::MAPMODE_STAGE && field_0x8CA8 == dLytMapGlobal_c::MAPMODE_STAGE) || + (field_0x8CA4 == dLytMapGlobal_c::MAPMODE_ZOOM && field_0x8CA8 == dLytMapGlobal_c::MAPMODE_ZOOM)) { + field_0xF1C.field_0x05 = true; + } + + mPinIconAggregate.execute(); + + for (int idx = 0; idx < (int)ARRAY_LENGTH(field_0x832C); idx++) { + field_0x832C[idx].resetCachedHitboxes(); + field_0x832C[idx].execute(); + } +} void dLytMapMain_c::finalizeState_Active() {} void dLytMapMain_c::initializeState_Out() {} diff --git a/src/d/lyt/d_lyt_map_global.cpp b/src/d/lyt/d_lyt_map_global.cpp index 5785ecb3..18d8d611 100644 --- a/src/d/lyt/d_lyt_map_global.cpp +++ b/src/d/lyt/d_lyt_map_global.cpp @@ -14,7 +14,7 @@ dLytMapGlobal_c::dLytMapGlobal_c() mMapRotation(0), field_0x40(1.0f), field_0x44(1.0f), - mLevel(0), + mFloor(0), field_0x4C(0), field_0x4D(0), mAlpha(0),