diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 7d3f498f..c1b27cab 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -478,12 +478,19 @@ toBeSorted/d_event_director.cpp: toBeSorted/minigame_mgr.cpp: .text start:0x800A5060 end:0x800A5608 align:16 .ctors start:0x804DB6C4 end:0x804DB6C8 + .data start:0x8050FF00 end:0x8050FF18 + .sdata start:0x80572250 end:0x80572260 .sbss start:0x80575390 end:0x805753A0 toBeSorted/salvage_mgr.cpp: .text start:0x800A5610 end:0x800A668C align:16 .ctors start:0x804DB6C8 end:0x804DB6CC + .rodata start:0x804E3718 end:0x804E3850 + .data start:0x8050FF18 end:0x8050FFB8 + .sdata start:0x80572260 end:0x80572288 .sbss start:0x805753A0 end:0x805753A8 + .sdata2 start:0x805796B8 end:0x80579748 + .bss start:0x805A60A8 end:0x805A6140 toBeSorted/d_path.cpp: .text start:0x800A6690 end:0x800A9B00 align:16 @@ -1579,10 +1586,13 @@ d/d_thp_player.cpp: d/tg/d_t_alldie.cpp: .text start:0x80273BC0 end:0x8027405C align:16 .data start:0x805360A0 end:0x80536128 + .sdata2 start:0x8057C4F0 end:0x8057C508 d/tg/d_t_view_clip.cpp: .text start:0x80274060 end:0x802743DC align:16 .data start:0x80536128 end:0x805361B0 + .sdata2 start:0x8057C508 end:0x8057C518 + .bss start:0x805B5668 end:0x805B56A8 d/tg/d_t_switch.cpp: .text start:0x802743E0 end:0x802756D8 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index d9d65341..28b41460 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -3644,35 +3644,35 @@ fn_800A54E0 = .text:0x800A54E0; // type:function size:0x44 startSpecialMinigameState = .text:0x800A5530; // type:function size:0x2C endSpecialMinigameState2 = .text:0x800A5560; // type:function size:0x54 fn_800A55C0 = .text:0x800A55C0; // type:function size:0x48 -ScrapperPickupMgr__ctor = .text:0x800A5610; // type:function size:0x70 -ScrapperPickupMgr__dtor = .text:0x800A5680; // type:function size:0x74 -ScrapperPickupMgr__init = .text:0x800A5700; // type:function size:0xB4 -ScrapperPickupMgr__update = .text:0x800A57C0; // type:function size:0x34 -ScrapperPickupMgr__handlePickupIndex = .text:0x800A5800; // type:function size:0x11C -ScrapperPickupMgr__setupDeliverToActorLink = .text:0x800A5920; // type:function size:0xC0 -fn_800A59E0 = .text:0x800A59E0; // type:function size:0x40 +create__13dSalvageMgr_cFv = .text:0x800A5610; // type:function size:0x70 +remove__13dSalvageMgr_cFv = .text:0x800A5680; // type:function size:0x74 +init__13dSalvageMgr_cFv = .text:0x800A5700; // type:function size:0xB4 +execute__13dSalvageMgr_cFv = .text:0x800A57C0; // type:function size:0x34 +handlePickupIndex__13dSalvageMgr_cFv = .text:0x800A5800; // type:function size:0x11C +setupDeliverToTarget__13dSalvageMgr_cFv = .text:0x800A5920; // type:function size:0xC0 +__dt__22SalvageMgrObjTransformFv = .text:0x800A59E0; // type:function size:0x40 getCarryRotMtx__13dSalvageMgr_cCFRCl = .text:0x800A5A20; // type:function size:0x84 -ScrapperPickupMgr__setPickupIndex = .text:0x800A5AB0; // type:function size:0x84 +setPickupIndex__13dSalvageMgr_cFRCl = .text:0x800A5AB0; // type:function size:0x84 deleteObjAndSlb__13dSalvageMgr_cFv = .text:0x800A5B40; // type:function size:0x4C -ScrapperPickupMgr__checkIsOnDeliveryStage2 = .text:0x800A5B90; // type:function size:0x1C -startedQuestForSalvageObj__13dSalvageMgr_cCFPC15dAcSalbageObj_c = .text:0x800A5BB0; // type:function size:0x5C -ScrapperPickupMgr__checkQuestStartedStoryflag = .text:0x800A5C10; // type:function size:0x7C +checkIsOnDeliveryStage2__13dSalvageMgr_cCFv = .text:0x800A5B90; // type:function size:0x1C +hasStartedQuestForSalvageObj__13dSalvageMgr_cCFPC15dAcSalbageObj_c = .text:0x800A5BB0; // type:function size:0x5C +hasStartedQuestForId__13dSalvageMgr_cCFRCl = .text:0x800A5C10; // type:function size:0x7C hasDowsingForSalvageObj__13dSalvageMgr_cCFPC15dAcSalbageObj_c = .text:0x800A5C90; // type:function size:0x5C -ScrapperPickupMgr__checkHasDowsing = .text:0x800A5CF0; // type:function size:0xB8 -ScrapperPickupMgr__getActorId = .text:0x800A5DB0; // type:function size:0x18 -fn_800A5DD0 = .text:0x800A5DD0; // type:function size:0x4 +hasDowsingForId__13dSalvageMgr_cCFRCl = .text:0x800A5CF0; // type:function size:0xB8 +getDeliverToActorId__13dSalvageMgr_cFl = .text:0x800A5DB0; // type:function size:0x18 +noop__13dSalvageMgr_cFv = .text:0x800A5DD0; // type:function size:0x4 getCurrentSalvageObjId__13dSalvageMgr_cCFv = .text:0x800A5DE0; // type:function size:0x8 checkDeliveredStoryflag__13dSalvageMgr_cCFRCl = .text:0x800A5DF0; // type:function size:0x7C -ScrapperPickupMgr__unsetPickupStoryflag = .text:0x800A5E70; // type:function size:0xBC -ScrapperPickupMgr__checkPickupStoryflag = .text:0x800A5F30; // type:function size:0x7C -ScrapperPickupMgr__checkIsOnDeliveryStage = .text:0x800A5FB0; // type:function size:0x5C -ScrapperPickupMgr__findDeliverToActor = .text:0x800A6010; // type:function size:0x48 -fn_800A6060 = .text:0x800A6060; // type:function size:0xBC -fn_800A6120 = .text:0x800A6120; // type:function size:0x98 -fn_800A61C0 = .text:0x800A61C0; // type:function size:0x9C -fn_800A6260 = .text:0x800A6260; // type:function size:0x9C -fn_800A6300 = .text:0x800A6300; // type:function size:0x368 -fn_800A6670 = .text:0x800A6670; // type:function size:0x1C +unsetPickupStoryflag__13dSalvageMgr_cFRCl = .text:0x800A5E70; // type:function size:0xBC +checkPickupStoryflag__13dSalvageMgr_cCFRCl = .text:0x800A5F30; // type:function size:0x7C +checkIsOnDeliveryStage__13dSalvageMgr_cCFv = .text:0x800A5FB0; // type:function size:0x5C +findDeliveryTarget__13dSalvageMgr_cFv = .text:0x800A6010; // type:function size:0x48 +triggerDeliveryEvent__13dSalvageMgr_cFv = .text:0x800A6060; // type:function size:0xBC +getTalkEntryPoint1ForPickup__13dSalvageMgr_cFP12dAcObjBase_c = .text:0x800A6120; // type:function size:0x98 +getTalkEntryPoint2ForPickup__13dSalvageMgr_cFP12dAcObjBase_c = .text:0x800A61C0; // type:function size:0x9C +getTalkEntryPoint3ForPickup__13dSalvageMgr_cFP12dAcObjBase_c = .text:0x800A6260; // type:function size:0x9C +__sinit_\salvage_mgr_cpp = .text:0x800A6300; // type:function size:0x368 +__arraydtor$21000 = .text:0x800A6670; // type:function size:0x1C __ct__7dPath_cFv = .text:0x800A6690; // type:function size:0x3C __dt__7dPath_cFv = .text:0x800A66D0; // type:function size:0x40 clear__7dPath_cFv = .text:0x800A6710; // type:function size:0x18 @@ -4008,7 +4008,7 @@ isTimeshiftStoneActive = .text:0x800BBC10; // type:function size:0x14 fn_800BBC30 = .text:0x800BBC30; // type:function size:0x58 fn_800BBC90 = .text:0x800BBC90; // type:function size:0x4C fn_800BBCE0 = .text:0x800BBCE0; // type:function size:0x54 -fn_800BBD40 = .text:0x800BBD40; // type:function size:0xC0 +fn_800BBD40__14dTimeAreaMgr_cFv = .text:0x800BBD40; // type:function size:0xC0 fn_800BBE00 = .text:0x800BBE00; // type:function size:0xAC TimeStoneBase__setActiveStone = .text:0x800BBEB0; // type:function size:0x3C fn_800BBEF0 = .text:0x800BBEF0; // type:function size:0x14 @@ -14493,26 +14493,26 @@ destroy__12dThpPlayer_cFv = .text:0x80273A40; // type:function size:0x98 isDone__12dThpPlayer_cFv = .text:0x80273AE0; // type:function size:0x2C draw__14ThpVideoScreenFv = .text:0x80273B10; // type:function size:0x38 THPVideoDecodeLC = .text:0x80273B50; // type:function size:0x68 -TgAlldie__ctor = .text:0x80273BC0; // type:function size:0x5C -TgAlldie__init = .text:0x80273C20; // type:function size:0x74 -fn_80273CA0 = .text:0x80273CA0; // type:function size:0x8 -TgAlldie__update = .text:0x80273CB0; // type:function size:0x26C -fn_80273F20 = .text:0x80273F20; // type:function size:0x8 -fn_80273F30 = .text:0x80273F30; // type:function size:0xD0 -fn_80274000 = .text:0x80274000; // type:function size:0x5C -TgViewClip__ctor = .text:0x80274060; // type:function size:0x4C -TgViewClip__init = .text:0x802740B0; // type:function size:0x74 -fn_80274130 = .text:0x80274130; // type:function size:0x8 -fn_80274140 = .text:0x80274140; // type:function size:0x8 -TgViewClip__draw = .text:0x80274150; // type:function size:0xC0 -fn_80274210 = .text:0x80274210; // type:function size:0x8 -resetViewClipVals = .text:0x80274220; // type:function size:0x40 -getViewClipCull = .text:0x80274260; // type:function size:0x80 -fn_802742E0 = .text:0x802742E0; // type:function size:0x44 -checkIdxMask = .text:0x80274330; // type:function size:0x14 -fn_80274350 = .text:0x80274350; // type:function size:0x18 -setViewClipVals = .text:0x80274370; // type:function size:0x10 -fn_80274380 = .text:0x80274380; // type:function size:0x5C +dTgAllDie_c_classInit__Fv = .text:0x80273BC0; // type:function size:0x5C +create__11dTgAllDie_cFv = .text:0x80273C20; // type:function size:0x74 +doDelete__11dTgAllDie_cFv = .text:0x80273CA0; // type:function size:0x8 +actorExecute__11dTgAllDie_cFv = .text:0x80273CB0; // type:function size:0x26C +draw__11dTgAllDie_cFv = .text:0x80273F20; // type:function size:0x8 +getNearestToPlayer__11dTgAllDie_cFl = .text:0x80273F30; // type:function size:0xD0 +__dt__11dTgAllDie_cFv = .text:0x80274000; // type:function size:0x5C +dTgViewClip_c_classInit__Fv = .text:0x80274060; // type:function size:0x4C +create__13dTgViewClip_cFv = .text:0x802740B0; // type:function size:0x74 +doDelete__13dTgViewClip_cFv = .text:0x80274130; // type:function size:0x8 +actorExecute__13dTgViewClip_cFv = .text:0x80274140; // type:function size:0x8 +draw__13dTgViewClip_cFv = .text:0x80274150; // type:function size:0xC0 +setViewClip__13dTgViewClip_cFUc = .text:0x80274210; // type:function size:0x8 +resetViewClip__13dTgViewClip_cFv = .text:0x80274220; // type:function size:0x40 +getCull__13dTgViewClip_cFlf = .text:0x80274260; // type:function size:0x80 +checkForceOn__13dTgViewClip_cFl = .text:0x802742E0; // type:function size:0x44 +getViewClipBit__13dTgViewClip_cFlUc = .text:0x80274330; // type:function size:0x14 +setViewClipBit__13dTgViewClip_cFlUc = .text:0x80274350; // type:function size:0x18 +setViewClip__13dTgViewClip_cFlUc = .text:0x80274370; // type:function size:0x10 +__dt__13dTgViewClip_cFv = .text:0x80274380; // type:function size:0x5C dTgSw_c_classInit__Fv = .text:0x802743E0; // type:function size:0xBC __dt__19sFState_c<7dTgSw_c>Fv = .text:0x802744A0; // type:function size:0x58 scope:weak __dt__22sFStateFct_c<7dTgSw_c>Fv = .text:0x80274500; // type:function size:0x6C scope:weak @@ -28213,7 +28213,7 @@ lbl_804E36B8 = .rodata:0x804E36B8; // type:object size:0x10 data:4byte lbl_804E36C8 = .rodata:0x804E36C8; // type:object size:0x24 data:4byte lbl_804E36EC = .rodata:0x804E36EC; // type:object size:0xC data:4byte lbl_804E36F8 = .rodata:0x804E36F8; // type:object size:0x20 data:4byte -AcSalbageObj__DEFINITIONS = .rodata:0x804E3718; // type:object size:0x100 +sDefs = .rodata:0x804E3718; // type:object size:0x100 lbl_804E3818 = .rodata:0x804E3818; // type:object size:0x38 @LOCAL@initializeState_Complete__14dLytDrawMark_cFv@sFlags = .rodata:0x804E3850; // type:object size:0xC scope:local brlanMapVariant01 = .rodata:0x804E3860; // type:object size:0x80 scope:local data:4byte @@ -36470,9 +36470,9 @@ g_profile_THPPLAYER = .data:0x80535FB8; // type:object size:0xC __vt__12dThpPlayer_c = .data:0x80536040; // type:object size:0x4C __vt__14ThpVideoScreen = .data:0x80536090; // type:object size:0x10 g_profile_ALLDIE_TAG = .data:0x805360A0; // type:object size:0x10 -TgAlldie__vtable = .data:0x805360B0; // type:object size:0x78 +__vt__11dTgAllDie_c = .data:0x805360B0; // type:object size:0x74 g_profile_VIEW_CLIP_TAG = .data:0x80536128; // type:object size:0x10 -TgViewClip__vtable = .data:0x80536138; // type:object size:0x78 +__vt__13dTgViewClip_c = .data:0x80536138; // type:object size:0x74 g_profile_SW_TAG = .data:0x805361B0; // type:object size:0x10 ...data.0 = .data:0x805361B0; // type:label scope:local @5858 = .data:0x805361C0; // type:object size:0xD scope:local data:string @@ -42206,7 +42206,7 @@ s_Create_Scale__9dAcBase_c = .sbss:0x80575088; // type:object size:0x4 data:4byt s_Create_Parent__9dAcBase_c = .sbss:0x8057508C; // type:object size:0x4 data:4byte s_Create_ActorInfo__9dAcBase_c = .sbss:0x80575090; // type:object size:0x4 data:4byte s_Create_Subtype__9dAcBase_c = .sbss:0x80575094; // type:object size:0x1 data:byte -ENEMY_LIST = .sbss:0x80575098; // type:object size:0x8 data:4byte +sEnemyList__11dAcEnBase_c = .sbss:0x80575098; // type:object size:0x8 data:4byte NPC_ACTOR_LIST = .sbss:0x805750A0; // type:object size:0x8 data:4byte lbl_805750A8 = .sbss:0x805750A8; // type:object size:0x8 data:4byte lbl_805750B0 = .sbss:0x805750B0; // type:object size:0x8 data:2byte @@ -52522,7 +52522,7 @@ StateID_OffWait__8dAcOsw_c = .bss:0x805B55B8; // type:object size:0x30 data:4byt StateID_Off__8dAcOsw_c = .bss:0x805B55F8; // type:object size:0x30 data:4byte @8419 = .bss:0x805B5628; // type:object size:0xC scope:local StateID_None__8dAcOsw_c = .bss:0x805B5638; // type:object size:0x30 data:4byte -ViewClip_Vals = .bss:0x805B5668; // type:object size:0x40 +sViewClips__13dTgViewClip_c = .bss:0x805B5668; // type:object size:0x40 @5114 = .bss:0x805B56A8; // type:object size:0xC scope:local ...bss.0 = .bss:0x805B56A8; // type:label scope:local StateID_OnWait__7dTgSw_c = .bss:0x805B56B8; // type:object size:0x30 data:4byte diff --git a/configure.py b/configure.py index 908e3ee2..389bd0e0 100644 --- a/configure.py +++ b/configure.py @@ -647,8 +647,8 @@ config.libs = [ Object(NonMatching, "d/a/obj/d_a_obj_time_area.cpp"), Object(Matching, "d/a/obj/d_a_obj_switch.cpp"), Object(Matching, "d/d_thp_player.cpp"), - Object(NonMatching, "d/tg/d_t_alldie.cpp"), - Object(NonMatching, "d/tg/d_t_view_clip.cpp"), + Object(Matching, "d/tg/d_t_alldie.cpp"), + Object(Matching, "d/tg/d_t_view_clip.cpp"), Object(Matching, "d/tg/d_t_switch.cpp"), Object(NonMatching, "d/tg/d_t_mass_object.cpp"), Object(NonMatching, "d/tg/d_t_camera.cpp"), diff --git a/include/d/a/d_a_salbage_obj.h b/include/d/a/d_a_salbage_obj.h index 742224bd..70b1d082 100644 --- a/include/d/a/d_a_salbage_obj.h +++ b/include/d/a/d_a_salbage_obj.h @@ -17,11 +17,17 @@ class dAcSalbageObj_c; enum SalvageObj_e { + SALVAGE_OBJ_NONE = -1, + SALVAGE_OBJ_PROPERA = 0, SALVAGE_OBJ_ROULETTE = 1, SALVAGE_OBJ_DIVINER_CRYSTAL = 2, + SALVAGE_OBJ_SALVAGE_MORRY = 3, + SALVAGE_OBJ_MOLE_ELDER = 4, SALVAGE_OBJ_WATER_JAR = 5, SALVAGE_OBJ_POT = 6, + + SALVAGE_OBJ_MAX = 7, }; class dSalvageIfObj_c : public dSalvageIf_c { @@ -176,7 +182,7 @@ protected: /* 0x908 */ mMtx_c mWorldSRMtx; /* 0x938 */ f32 field_0x938; /* 0x93C */ DowsingTarget mDowsingTarget; - /* 0x95C */ mVec3_c field_0x95C; + /* 0x95C */ mVec3_c mDowsingOffset; /* 0x968 */ bool mIsDowsingRegistered; /* 0x96C */ const sStateID_c *mpNextStateId; }; diff --git a/include/d/a/e/d_a_en_base.h b/include/d/a/e/d_a_en_base.h index 1c1382e8..8d60823a 100644 --- a/include/d/a/e/d_a_en_base.h +++ b/include/d/a/e/d_a_en_base.h @@ -5,6 +5,7 @@ #include "d/a/obj/d_a_obj_base.h" #include "d/a/obj/d_a_obj_bomb.h" #include "d/d_cc.h" +#include "f/f_list_mg.h" #include "m/m3d/m_mdl.h" #include "m/m_angle.h" #include "m/m_vec.h" @@ -96,6 +97,10 @@ public: bool ChkCrossPlayer(f32 height); + static dAcEnBase_c *GetNextEnemy(dAcEnBase_c *pParent) { + return static_cast(getNextObject(&sEnemyList, pParent)); + } + protected: // TODO: Make accessors for this list to auto-convert to dAcEnBase? static fLiMgBa_c sEnemyList; diff --git a/include/d/a/obj/d_a_obj_base.h b/include/d/a/obj/d_a_obj_base.h index 1d8eff2e..d82181ef 100644 --- a/include/d/a/obj/d_a_obj_base.h +++ b/include/d/a/obj/d_a_obj_base.h @@ -164,6 +164,10 @@ public: mLinkage.field_0xA0 = pCol; } + dSalvageIf_c *getSalvageIf() const { + return mpSalvageIf; + } + // could be their own thing? static void *getOarcFile(const char *oarcName, const char *fileName); static void *getOarcSubEntry(const char *oarcName, const char *fileName); diff --git a/include/d/d_stage.h b/include/d/d_stage.h index 5b69d38d..c3d95b9e 100644 --- a/include/d/d_stage.h +++ b/include/d/d_stage.h @@ -163,8 +163,13 @@ public: s8 getCurrRoomId() const { return curr_room_id; } + bool isRoomID(s32 id) const { + return curr_room_id == id; + } - dFader_c& getFader() { return mFader; } + dFader_c &getFader() { + return mFader; + } bool fn_801B3EE0(); void fn_801B3F20(); diff --git a/include/d/flag/storyflag_map.h b/include/d/flag/storyflag_map.h index a8c617a8..785184a9 100644 --- a/include/d/flag/storyflag_map.h +++ b/include/d/flag/storyflag_map.h @@ -1640,12 +1640,12 @@ enum StoryFlags_e { /** [Windmill Propeller picked up] * Story Flag #324 (0x0144) - JP 805ACD7F 0x04 / US 805A9AFF 0x04 */ - STORYFLAG_324, + STORYFLAG_PROPERA_PICKUP, /** [Village Windmill reparation cutscene] * Story Flag #325 (0x0145) - JP 805ACD7F 0x08 / US 805A9AFF 0x08 */ - STORYFLAG_325, + STORYFLAG_WINDMILL_REPAIRED, /** [Wyrna's 5 gratitude crystals collected (not the crystals themselves)] * Story Flag #326 (0x0146) - JP 805ACD7F 0x10 / US 805A9AFF 0x10 @@ -1842,12 +1842,12 @@ enum StoryFlags_e { /** [Spiral Charge Ability] * Story Flag #364 (0x016C) - JP 805ACD83 0x04 / US 805A9B03 0x04 */ - STORYFLAG_364, + STORYFLAG_SPIRAL_CHARGE_UNLOCKED, /** [Pumpkin Soup for Levias Collected, unset by picking up something else] * Story Flag #365 (0x016D) - JP 805ACD83 0x08 / US 805A9B03 0x08 */ - STORYFLAG_365, + STORYFLAG_PUMPKIN_SOUP_PICKUP, /** [Unset when Scrapper has a job, set when he has finished it] * Story Flag #366 (0x016E) - JP 805ACD83 0x10 / US 805A9B03 0x10 @@ -1877,17 +1877,17 @@ enum StoryFlags_e { /** [Accepting the Fortune Teller Crystal Sidequest] * Story Flag #371 (0x0173) - JP 805ACD82 0x02 / US 805A9B02 0x02 */ - STORYFLAG_371, + STORYFLAG_CRYSTAL_QUEST_STARTED, /** [Sets after Sprapper picked the Crystal Ball up] * Story Flag #372 (0x0174) - JP 805ACD82 0x04 / US 805A9B02 0x04 */ - STORYFLAG_372, + STORYFLAG_CRYSTAL_PICKUP, /** [Sets before the Fortune Teller gives his Crystals] * Story Flag #373 (0x0175) - JP 805ACD82 0x08 / US 805A9B02 0x08 */ - STORYFLAG_373, + STORYFLAG_CRYSTAL_DELIVERED, /** [Sets when talking to the Fortune Teller in the Bazzar after 8x08 (Fortunes only cost half)] * Story Flag #374 (0x0176) - JP 805ACD82 0x10 / US 805A9B02 0x10 @@ -2002,17 +2002,17 @@ enum StoryFlags_e { /** [Search for Party Wheel Crystal Quest started] * Story Flag #396 (0x018C) - JP 805ACD8F 0x20 / US 805A9B0F 0x20 */ - STORYFLAG_396, + STORYFLAG_PARTY_WHEEL_QUEST_STARTED, /** [Set after Scrapper picks up Party Wheel] * Story Flag #397 (0x018D) - JP 805ACD8F 0x80 / US 805A9B0F 0x80 */ - STORYFLAG_397, + STORYFLAG_PARTY_WHEEL_PICKUP, /** [Set before Fun Fun Owner gives his Crystals] * Story Flag #398 (0x018E) - JP 805ACD8E 0x01 / US 805A9B0E 0x01 */ - STORYFLAG_398, + STORYFLAG_PARTY_WHEEL_DELIVERED, /** [Sets after you get a free try at Diveing game] * Story Flag #399 (0x018F) - JP 805ACD91 0x80 / US 805A9B11 0x80 @@ -2357,7 +2357,7 @@ enum StoryFlags_e { /** [Goron Text near Big Frog] * Story Flag #467 (0x01D3) - JP 805ACD8F 0x10 / US 805A9B0F 0x10 */ - STORYFLAG_467, + STORYFLAG_WATER_BASIN_QUEST_STARTED, /** [Goron Text after Watering 1st Frog] * Story Flag #468 (0x01D4) - JP 805ACD8F 0x40 / US 805A9B0F 0x40 @@ -2372,17 +2372,17 @@ enum StoryFlags_e { /** [Kina's Crystal Quest started] * Story Flag #470 (0x01D6) - JP 805ACD8E 0x04 / US 805A9B0E 0x04 */ - STORYFLAG_470, + STORYFLAG_MOLE_ELDER_QUEST_STARTED, /** [Guld picked up (unsets after)] * Story Flag #471 (0x01D7) - JP 805ACD8E 0x08 / US 805A9B0E 0x08 */ - STORYFLAG_471, + STORYFLAG_MOLE_ELDER_PICKUP, /** [Kina's Crystal Quest related] * Story Flag #472 (0x01D8) - JP 805ACD8E 0x10 / US 805A9B0E 0x10 */ - STORYFLAG_472, + STORYFLAG_MOLE_ELDER_DELIVERED, /** [Kina's Crystal Quest related] * Story Flag #473 (0x01D9) - JP 805ACD8E 0x20 / US 805A9B0E 0x20 @@ -2417,7 +2417,7 @@ enum StoryFlags_e { /** [Owlans Crystal Sidequest started] * Story Flag #479 (0x01DF) - JP 805ACD91 0x08 / US 805A9B11 0x08 */ - STORYFLAG_479, + STORYFLAG_PLANT_SPECIES_QUEST_STARTED, /** [] * Story Flag #480 (0x01E0) - JP 805ACD91 0x10 / US 805A9B11 0x10 diff --git a/include/d/t/d_t_alldie.h b/include/d/t/d_t_alldie.h new file mode 100644 index 00000000..3fe18e82 --- /dev/null +++ b/include/d/t/d_t_alldie.h @@ -0,0 +1,32 @@ +#ifndef D_T_ALL_DIE_H +#define D_T_ALL_DIE_H + +#include "d/t/d_tg.h" +#include "m/m_mtx.h" +#include "toBeSorted/time_area_mgr.h" + +class dTgAllDie_c : public dTg_c { +public: + dTgAllDie_c() {} + virtual ~dTgAllDie_c() {} + + virtual int create() override; + virtual int doDelete() override; + virtual int draw() override; + virtual int actorExecute() override; + + static dTgAllDie_c *getNearestToPlayer(s32 roomId); + +private: + /* 0x0FC */ mMtx_c mArea; + /* 0x12C */ TimeAreaStruct mTimeArea; + /* 0x138 */ s32 mNumEnemiesInArea; + /* 0x13C */ u16 mTimer0x13C; + /* 0x13E */ u8 mType; + /* 0x13F */ u8 mSceneflag; + /* 0x140 */ u8 mTimer0x140; + /* 0x144 */ u32 field_0x144; + /* 0x145 */ u8 field_0x148; +}; + +#endif diff --git a/include/d/t/d_t_view_clip.h b/include/d/t/d_t_view_clip.h new file mode 100644 index 00000000..0b81b35c --- /dev/null +++ b/include/d/t/d_t_view_clip.h @@ -0,0 +1,49 @@ +#ifndef D_T_VIEW_CLIP_H +#define D_T_VIEW_CLIP_H + +#include "d/t/d_tg.h" +#include "m/m_mtx.h" + +class dTgViewClip_c : public dTg_c { +public: + static const s32 sNumEntries = 0x40; + + enum Flag_e { + FLAG_NORMAL = 0, + FLAG_FORCE_ON = (1 << 0), + FLAG_FORCE_OFF = (1 << 1), + }; + + enum Type_e { + TYPE_FORCE_ON, + TYPE_FORCE_OFF, + }; + + dTgViewClip_c() {} + virtual ~dTgViewClip_c() {} + + virtual int create() override; + virtual int doDelete() override; + virtual int draw() override; + virtual int actorExecute() override; + + void setViewClip(u8 setBit); + static void resetViewClip(); + static f32 getCull(s32 idx, f32 cullDistance); + static bool checkForceOn(s32 idx); + + static u8 getViewClipBit(s32 idx, u8 setBit); + static void setViewClipBit(s32 idx, u8 setBit); + + static void setViewClip(s32 idx, u8 value); + +private: + /* 0x0DC */ mMtx_c mArea; + /* 0x12C */ u8 mIndex; + /* 0x12D */ u8 mType; + /* 0x12E */ u8 mAreaIndex; + + static u8 sViewClips[sNumEntries]; +}; + +#endif diff --git a/include/toBeSorted/salvage_mgr.h b/include/toBeSorted/salvage_mgr.h index 3e268936..a30633ff 100644 --- a/include/toBeSorted/salvage_mgr.h +++ b/include/toBeSorted/salvage_mgr.h @@ -3,6 +3,8 @@ #include "common.h" #include "d/a/d_a_base.h" +#include "d/a/d_a_salbage_obj.h" +#include "d/a/npc/d_a_npc_salbage_robot.h" #include "m/m_mtx.h" class dAcSalbageObj_c; @@ -15,8 +17,11 @@ public: // return sInstance; // } - bool checkDeliveredStoryflag(const s32& id) const; - bool startedQuestForSalvageObj(const dAcSalbageObj_c *obj) const; + // TODO a fun theory is that all those `const s32 &`s are just `const SalvageObj_e &`s. + + bool checkDeliveredStoryflag(const s32 &id) const; + bool checkPickupStoryflag(const s32 &id) const; + bool hasStartedQuestForSalvageObj(const dAcSalbageObj_c *obj) const; bool hasDowsingForSalvageObj(const dAcSalbageObj_c *obj) const; mMtx_c getCarryRotMtx(const s32 &id) const; mMtx_c getCarryRotMtx2(const s32 &id) const { @@ -26,13 +31,46 @@ public: void deleteObjAndSlb(); static dSalvageMgr_c *sInstance; + static void create(); + static void remove(); + + void init(); + void execute(); + + void setPickupIndex(const s32 &id); + void unsetPickupStoryflag(const s32 &id); + void handlePickupIndex(); + void setupDeliverToTarget(); + bool checkIsOnDeliveryStage() const; + bool checkIsOnDeliveryStage2() const; + u16 getDeliverToActorId(s32 id); + dAcObjBase_c *findDeliveryTarget(); + bool hasStartedQuestForId(const s32 &id) const; + bool hasDowsingForId(const s32 &id) const; + + void noop(); + + bool triggerDeliveryEvent(); + + u16 getTalkEntryPoint1ForPickup(dAcObjBase_c *obj); + u16 getTalkEntryPoint2ForPickup(dAcObjBase_c *obj); + u16 getTalkEntryPoint3ForPickup(dAcObjBase_c *obj); bool hasObjAndSlb() const { return mObjRef.isLinked() && mSlbRef.isLinked(); } + bool checkPickupMask(const s32 &id) const { + return (mCurrentPickupMaskBit & (1 << id)) != 0; + } + /* 0x00 */ dAcRef_c mObjRef; /* 0x0C */ dAcRef_c mSlbRef; + /* 0x18 */ dAcRef_c mDeliverToRef; + /* 0x24 */ s32 mCurrentPickupIdx; + /* 0x28 */ s32 mCurrentPickupMaskBit; + /* 0x2C */ s16 field_0x2C; + private: }; diff --git a/include/toBeSorted/time_area_mgr.h b/include/toBeSorted/time_area_mgr.h index 04c2a360..2732d577 100644 --- a/include/toBeSorted/time_area_mgr.h +++ b/include/toBeSorted/time_area_mgr.h @@ -41,7 +41,7 @@ struct TimeAreaStruct { return fabsf(field_0x00) <= FLT_EPSILON; } - f32 getDistMaybe() { + f32 getDistMaybe() const { return field_0x00; } @@ -72,6 +72,8 @@ public: s32 fn_800B9B60(s32 roomId, const mVec3_c &position); f32 fn_800B9CE0(const mVec3_c &position); + static bool fn_800BBD40(); + bool isInLanayruMiningFacility() const { return mIsInLanayruMiningFacility; } diff --git a/src/d/a/d_a_salbage_obj.cpp b/src/d/a/d_a_salbage_obj.cpp index 73232f06..6fef71f6 100644 --- a/src/d/a/d_a_salbage_obj.cpp +++ b/src/d/a/d_a_salbage_obj.cpp @@ -97,9 +97,9 @@ int dAcSalbageObj_c::preExecute() { } } - getDowsingUnusedF32(); - field_0x95C.set(0.0f, getDowsingTargetYOffset(), 0.0f); - mDowsingTarget.setOffset(field_0x95C); + (void)getDowsingUnusedF32(); + mDowsingOffset.set(0.0f, getDowsingTargetYOffset(), 0.0f); + mDowsingTarget.setOffset(mDowsingOffset); return result; } @@ -312,7 +312,7 @@ void dAcSalbageObj_c::loadBehaviorFromParams() { } void dAcSalbageObj_c::initializeState_Wait() { - mDowsingTarget.initialize(getDowsingSlot(), 0, &field_0x95C, getDowsingUnusedF32()); + mDowsingTarget.initialize(getDowsingSlot(), 0, &mDowsingOffset, getDowsingUnusedF32()); mDowsingTarget.doRegister(); mIsDowsingRegistered = true; } @@ -323,7 +323,7 @@ void dAcSalbageObj_c::executeState_Wait() { dAcObjBase_c::create(fProfile::NPC_SLB, mRoomID, 0xFFFFFD01, &pos, nullptr, nullptr, -1); } - if (dSalvageMgr_c::sInstance->startedQuestForSalvageObj(this)) { + if (dSalvageMgr_c::sInstance->hasStartedQuestForSalvageObj(this)) { addAttentionTargetIfNeeded(); } } diff --git a/src/d/tg/d_t_alldie.cpp b/src/d/tg/d_t_alldie.cpp new file mode 100644 index 00000000..a205ce09 --- /dev/null +++ b/src/d/tg/d_t_alldie.cpp @@ -0,0 +1,112 @@ +#include "d/t/d_t_alldie.h" + +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/e/d_a_en_base.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/d_stage.h" +#include "d/flag/sceneflag_manager.h" +#include "f/f_base.h" +#include "f/f_manager.h" +#include "f/f_profile_name.h" +#include "s/s_Math.h" +#include "toBeSorted/area_math.h" +#include "toBeSorted/event_manager.h" + +SPECIAL_ACTOR_PROFILE(ALLDIE_TAG, dTgAllDie_c, fProfile::ALLDIE_TAG, 0x23, 0, 4); + +int dTgAllDie_c::create() { + mSceneflag = getFromParams(4, 0xFF); + mType = getFromParams(12, 0x3); + mTimer0x140 = getFromParams(22, 0xFF); + field_0x148 = 0; + field_0x144 = getFromParams(30, 0xFF); + mRotation.x.set(0); + matrixCreateFromPosRotYScale(mArea, mPosition, mRotation.y, mScale, nullptr, 0.0f); + return SUCCEEDED; +} + +int dTgAllDie_c::doDelete() { + return SUCCEEDED; +} + +int dTgAllDie_c::actorExecute() { + if (!dStage_c::GetInstance()->isRoomID(mRoomID)) { + return SUCCEEDED; + } + + if (mType <= 1) { + if (dTimeAreaMgr_c::fn_800BBD40()) { + return SUCCEEDED; + } + + mTimeArea.check(mRoomID, mPosition, 0, 10.0f, 0.1f); + f32 f = mTimeArea.getDistMaybe(); + if (mType == 0 && f < 1.0f) { + return SUCCEEDED; + } + if (mType == 1 && 0.0f < f) { + return SUCCEEDED; + } + } + + mNumEnemiesInArea = 0; + dAcEnBase_c *pEnemy = nullptr; + while ((pEnemy = dAcEnBase_c::GetNextEnemy(pEnemy))) { + if (pEnemy->mRoomID == mRoomID && !pEnemy->checkInteractionFlags(0x2)) { + if (pEnemy->checkProcControl(DISABLE_EXECUTE) == 0 && pEnemy->mLifecycleState != TO_BE_DELETED) { + if (checkAreaBox(mArea, pEnemy->mPosition)) { + mNumEnemiesInArea++; + } + } + } + } + + if (mNumEnemiesInArea == 0) { + if (field_0x148 != 0 && EventManager::isInEvent()) { + return SUCCEEDED; + } + + if (sLib::calcTimer(&mTimer0x13C) == 0) { + if (mSceneflag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mSceneflag)) { + SceneflagManager::sInstance->setFlag(mRoomID, mSceneflag); + } + } + } else { + mTimer0x13C = (mTimer0x140 <= 128 ? mTimer0x140 + 40 : 40 - (256 - mTimer0x140)); + if (mSceneflag < 0xFF && SceneflagManager::sInstance->checkBoolFlag(mRoomID, mSceneflag)) { + SceneflagManager::sInstance->unsetFlag(mRoomID, mSceneflag); + } + } + return SUCCEEDED; +} + +int dTgAllDie_c::draw() { + return SUCCEEDED; +} + +dTgAllDie_c *dTgAllDie_c::getNearestToPlayer(s32 roomId) { + fBase_c *pPrev = nullptr; + dTgAllDie_c *pReturn = nullptr; + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + f32 minDist = 1e10f; + + while (true) { + dTgAllDie_c *pTgAllDie = + static_cast(fManager_c::searchBaseByProfName(fProfile::ALLDIE_TAG, pPrev)); + pPrev = pTgAllDie; + + if (pTgAllDie == nullptr) { + break; + } + + if (roomId == pTgAllDie->mRoomID) { + f32 dist = pPlayer->getPosition().squareDistanceToXZ(pTgAllDie->getPosition()); + if (dist < minDist) { + pReturn = pTgAllDie; + minDist = dist; + } + } + } + return pReturn; +} diff --git a/src/d/tg/d_t_view_clip.cpp b/src/d/tg/d_t_view_clip.cpp new file mode 100644 index 00000000..30ef9cba --- /dev/null +++ b/src/d/tg/d_t_view_clip.cpp @@ -0,0 +1,93 @@ +#include "d/t/d_t_view_clip.h" + +#include "common.h" +#include "d/d_camera.h" +#include "d/d_sc_game.h" +#include "f/f_base.h" +#include "toBeSorted/area_math.h" +#include "toBeSorted/area_utils.h" + +SPECIAL_ACTOR_PROFILE(VIEW_CLIP_TAG, dTgViewClip_c, fProfile::VIEW_CLIP_TAG, 0xB, 0, 0); + +u8 dTgViewClip_c::sViewClips[dTgViewClip_c::sNumEntries] = {}; + +int dTgViewClip_c::create() { + mIndex = getFromParams(0, 0x3F); + mType = getFromParams(8, 0xF); + if (mType == 0xF) { + mType = TYPE_FORCE_OFF; + } + + mAreaIndex = getFromParams(12, 0xFF); + matrixCreateFromPosRotYScale(mArea, mPosition, mRotation.y, mScale, nullptr, 0.0f); + + return SUCCEEDED; +} + +int dTgViewClip_c::doDelete() { + return SUCCEEDED; +} + +int dTgViewClip_c::actorExecute() { + return SUCCEEDED; +} + +int dTgViewClip_c::draw() { + dCamera_c *pCamera = dScGame_c::getCamera(); + if (!checkAreaBox(mArea, pCamera->getPosition())) { + if (mAreaIndex == 0xFF) { + return SUCCEEDED; + } + if (!checkPosInArea(mAreaIndex, mRoomID, pCamera->getPosition(), nullptr)) { + return SUCCEEDED; + } + } + + switch (mType) { + case TYPE_FORCE_ON: setViewClip(FLAG_FORCE_ON); break; + case TYPE_FORCE_OFF: setViewClip(FLAG_FORCE_OFF); break; + } + + return SUCCEEDED; +} + +void dTgViewClip_c::setViewClip(u8 setBit) { + setViewClipBit(mIndex, setBit); +} + +void dTgViewClip_c::resetViewClip() { + for (int i = 0; i < sNumEntries - 1; ++i) { + setViewClip(i, 0); + } +} + +f32 dTgViewClip_c::getCull(s32 idx, f32 cullDistance) { + if (idx > ARRAY_LENGTH(sViewClips) - 2) { + return cullDistance; + } + + if (getViewClipBit(idx, FLAG_FORCE_ON)) { + return FLOAT_MAX; + } else if (getViewClipBit(idx, FLAG_FORCE_OFF)) { + return -1.0f; + } + + return cullDistance; +} +bool dTgViewClip_c::checkForceOn(s32 idx) { + if (idx <= ARRAY_LENGTH(sViewClips) - 2) { + return getViewClipBit(idx, FLAG_FORCE_ON); + } + return false; +} + +u8 dTgViewClip_c::getViewClipBit(s32 idx, u8 setBit) { + return sViewClips[idx] & setBit; +} +void dTgViewClip_c::setViewClipBit(s32 idx, u8 setBit) { + sViewClips[idx] |= setBit; +} + +void dTgViewClip_c::setViewClip(s32 idx, u8 value) { + sViewClips[idx] = value; +} diff --git a/src/toBeSorted/salvage_mgr.cpp b/src/toBeSorted/salvage_mgr.cpp new file mode 100644 index 00000000..0a972c38 --- /dev/null +++ b/src/toBeSorted/salvage_mgr.cpp @@ -0,0 +1,451 @@ + +#include "toBeSorted/salvage_mgr.h" + +#include "common.h" +#include "d/d_sc_game.h" +#include "d/flag/storyflag_manager.h" +#include "toBeSorted/event_manager.h" + +dSalvageMgr_c *dSalvageMgr_c::sInstance; + +void dSalvageMgr_c::create() { + if (sInstance == nullptr) { + sInstance = new dSalvageMgr_c(); + if (sInstance != nullptr) { + sInstance->init(); + } + } +} + +void dSalvageMgr_c::remove() { + delete sInstance; + sInstance = nullptr; +} + +void dSalvageMgr_c::init() { + mCurrentPickupIdx = -1; + mCurrentPickupMaskBit = 0; + for (int i = 0; i < SALVAGE_OBJ_MAX; i++) { + s32 it = i; + if (!checkDeliveredStoryflag(it) && checkPickupStoryflag(it)) { + mCurrentPickupIdx = it; + mCurrentPickupMaskBit |= 1 << it; + } + } + field_0x2C = 10; + setupDeliverToTarget(); +} + +void dSalvageMgr_c::execute() { + handlePickupIndex(); + setupDeliverToTarget(); +} + +void dSalvageMgr_c::handlePickupIndex() { + if (mCurrentPickupIdx != -1 && checkDeliveredStoryflag(mCurrentPickupIdx)) { + mCurrentPickupIdx = -1; + } + + s32 target = -1; + for (int i = 0; i < SALVAGE_OBJ_MAX; i++) { + s32 it = i; + if (!checkDeliveredStoryflag(it) && checkPickupStoryflag(it)) { + // TODO instruction swap + if (target == -1 && it != mCurrentPickupIdx && !checkPickupMask(it)) { + target = it; + } + mCurrentPickupMaskBit |= 1 << it; + } else { + mCurrentPickupMaskBit &= ~(1 << it); + } + } + + if (target != -1) { + setPickupIndex(target); + } +} + +void dSalvageMgr_c::setupDeliverToTarget() { + if (checkIsOnDeliveryStage2() && field_0x2C > 0) { + // TODO wrong registers + if (!mDeliverToRef.isLinked() || mDeliverToRef.get()->mProfileName != getDeliverToActorId(mCurrentPickupIdx)) { + dAcObjBase_c *deliverTo = findDeliveryTarget(); + if (deliverTo == nullptr) { + mDeliverToRef.unlink(); + field_0x2C = field_0x2C - 1 < 0 ? 0 : field_0x2C - 1; + } else { + mDeliverToRef.link(deliverTo); + field_0x2C = 10; + } + } + } else { + mDeliverToRef.unlink(); + } +} + +struct SalvageMgrObjTransform { + ~SalvageMgrObjTransform() {} + + /* 0x00 */ mVec3_c offset; + /* 0x0C */ mAng3_c rotation; +}; + +#define deg_ang(x, y, z) mAng3_c(mAng::fromDeg(x), mAng::fromDeg(y), mAng::fromDeg(z)) + +static const SalvageMgrObjTransform sTransforms[SALVAGE_OBJ_MAX] = { + { mVec3_c(29.22f, 4.51f, -46.36f), deg_ang(81.83f, 56.65f, -12.683f)}, + { mVec3_c(37.05f, -65.41f, -10.07f), deg_ang(4.149f, 21.983f, 134.444f)}, + {mVec3_c(-28.28f, -27.73f, -5.12f), deg_ang(16.224f, 5.528f, -73.192f)}, + { mVec3_c(-44.5f, -37.32f, -7.17f), deg_ang(4.237f, 15.61f, -90.026f)}, + {mVec3_c(-26.64f, -8.95f, -95.21f), deg_ang(83.418f, 19.082f, -73.081f)}, + {mVec3_c(-97.98f, -194.72f, 0.119f), deg_ang(-1.184f, 1.26f, -52.992f)}, + {mVec3_c(-97.98f, -194.72f, 0.119f), deg_ang(-1.184f, 1.26f, -52.992f)}, +}; + +#undef deg_ang + +struct SalvageMgrObjDef { + /* 0x00 */ u16 profileId; + /* 0x02 */ u16 deliverToProfileId; + /* 0x04 */ const char *fayCallEvnt; + /* 0x08 */ const char *deliveryEvnt; + /* 0x0C */ const char *postDeliveryEvnt; + /* 0x10 */ const char *stage; + /* 0x14 */ s32 questStartedStoryflag; + /* 0x18 */ s32 pickedUpStoryFlag; + /* 0x1C */ s32 additionalPickupUnsetFlag; + /* 0x20 */ s32 deliveredStoryflag; +}; + +// TODO - the docs for the plant species flags might be wrong +// clang-format off +static const SalvageMgrObjDef sDefs[SALVAGE_OBJ_MAX] = { + { fProfile::OBJ_PROPERA, fProfile::NPC_SORAJIMA_FATHER, "SalbageFayCall", "DelivaryPropera", "RepearPropera", "F000", STORYFLAG_SCRAPPER_UNLOCKED, STORYFLAG_PROPERA_PICKUP, -1, STORYFLAG_WINDMILL_REPAIRED }, + { fProfile::OBJ_ROULETTE, fProfile::NPC_DIVE_GAME_JUDGE, "SalbageFayCall", "DelivaryRoulette", "DefaultTalk", "F020", STORYFLAG_PARTY_WHEEL_QUEST_STARTED, STORYFLAG_PARTY_WHEEL_PICKUP, -1, STORYFLAG_PARTY_WHEEL_DELIVERED }, + {fProfile::OBJ_DIVINER_CRYSTAL, fProfile::NPC_SHA, "SalbageFayCall", "DelivarySuisho", "DefaultTalk", "F013r", STORYFLAG_CRYSTAL_QUEST_STARTED, STORYFLAG_CRYSTAL_PICKUP, -1, STORYFLAG_CRYSTAL_DELIVERED }, + { fProfile::NPC_SALBAGE_MORRY, fProfile::NPC_SKN, "SalbageFayCall", "DelivaryKyui", "RepearPropera", "F001r", STORYFLAG_PLANT_SPECIES_QUEST_STARTED, STORYFLAG_480, -1, STORYFLAG_481 }, + { fProfile::NPC_MOLE_ELDER, fProfile::NPC_PDU, "SalbageFayCall", "DelivaryMole", "DefaultTalk", "F020", STORYFLAG_MOLE_ELDER_QUEST_STARTED, STORYFLAG_MOLE_ELDER_PICKUP, -1, STORYFLAG_MOLE_ELDER_DELIVERED }, + { fProfile::OBJ_WATER_JAR, fProfile::NPC_SORAJIMA_FATHER, "SalbageFayCall", "DelivaryPot", "DefaultTalk", "F000", STORYFLAG_WATER_BASIN_QUEST_STARTED, STORYFLAG_SCRAPPER_HAS_WATER_BASIN, -1, STORYFLAG_SUMMIT_BIG_FROG_WATERED }, + { fProfile::OBJ_POT_SAL, fProfile::NPC_SORAJIMA_FATHER, "SalbageFayCall", "DelivaryPumpPot", "DefaultTalk", "F023", STORYFLAG_SPIRAL_CHARGE_UNLOCKED, STORYFLAG_PUMPKIN_SOUP_PICKUP, -1, STORYFLAG_LEVIAS_FIGHT_STARTED }, +}; +// clang-format on + +struct SalvageMgrObjEntrypoints { + /* 0x00 */ u16 talkEntrypoint1; + /* 0x02 */ u16 talkEntrypoint2; + /* 0x04 */ u16 talkEntrypoint3; + /* 0x06 */ u16 talkEntrypoint4; // unused +}; + +// clang-format off +static const SalvageMgrObjEntrypoints sEntrypoints[SALVAGE_OBJ_MAX] = { + { + 51001, // 510_01: This is the Windmill Propeller... + 51004, // 510_04: Master, I suggest that we also return... + 51005, // 510_05: Hey! Master Shortpants! You're in my may... + 11818, // 118_18: Here's that windmill propeller, zzzazt! + }, + { + 45101, // 451_01: I have identified the item that the... highly unusual man... + 45104, // 451_04: Master, I suggest that we also return... + 45105, // 451_05: OK, OK, zrrft... You just sit tight there + 11005, // 110_05: Here's your wheel thing, bzzzrrrt! + }, + { + 35101, // 351_01: I have located a substance that closely resembles... + 35104, // 351_04: Master, I suggest we also return... + 35105, // 351_05: Hey, Master Shortpants! How come... + 11820, // 118_20: Here's that bright and shiny crystal ball, BZZAT! + }, + { + 25106, // 251_06: I can verify with only 40% accuracy that this person is a plant... + 25104, // 251_04: Master, I suggest we also return... + 25105, // 251_05: Move it! Move it! Zrrppt! Forcing me... + 11821, // 118_21: I have come bearing the unusual Kikwi... + }, + { + 51001, // (?) 510_01: This is the Windmill Propeller... + 35111, // 351_11: Master, I suggest that we also return... + 35112, // 351_12: You don't have to tell me twice, zrrbt! + 11820, // (?) 118_20: Here's that bright and shiny crystal ball, BZZAT! + }, + { + 51001, // (?) 510_01: This is the Windmill Propeller... + -1, // + -1, // + 11790, // Does not exist? + }, + { + 51001, // (?) 510_01: This is the Windmill Propeller... + -1, // + -1, // + 12020, // 120_20: I'm unloading this cargo of pumpkin soup... + }, +}; +// clang-format off + +mMtx_c dSalvageMgr_c::getCarryRotMtx(const s32 &id) const { + SalvageMgrObjTransform tf = sTransforms[id]; + mMtx_c result; + result.transS(tf.offset); + result.ZYXrotM(tf.rotation); + return result; +} + +void dSalvageMgr_c::setPickupIndex(const s32 &id) { + for (int i = 0; i < SALVAGE_OBJ_MAX; i++) { + if (i != id) { + unsetPickupStoryflag(i); + } + } + + if (!checkDeliveredStoryflag(id)) { + mCurrentPickupIdx = id; + } +} + +void dSalvageMgr_c::deleteObjAndSlb() { + dAcObjBase_c *slb = mSlbRef.get(); + dAcObjBase_c *obj = mObjRef.get(); + + if (obj != nullptr) { + obj->deleteRequest(); + } + if (slb != nullptr) { + slb->deleteRequest(); + } +} + +bool dSalvageMgr_c::checkIsOnDeliveryStage2() const { + if (mCurrentPickupIdx == -1) { + return false; + } + return checkIsOnDeliveryStage(); +} + +bool dSalvageMgr_c::hasStartedQuestForSalvageObj(const dAcSalbageObj_c *obj) const { + s32 id = obj->getSalvageIf()->getSalvageObjId(); + if (id < 0) { + return false; + } + s32 it = id; + return hasStartedQuestForId(it); +} + +bool dSalvageMgr_c::hasStartedQuestForId(const s32 &id) const { + if (id == -1) { + return false; + } else if (sDefs[id].questStartedStoryflag == -1) { + return false; + } else { + return StoryflagManager::sInstance->getFlag(sDefs[id].questStartedStoryflag) != 0; + } +} + +bool dSalvageMgr_c::hasDowsingForSalvageObj(const dAcSalbageObj_c *obj) const { + s32 id = obj->getSalvageIf()->getSalvageObjId(); + if (id < 0) { + return false; + } + s32 it = id; + return hasDowsingForId(it); +} + +bool dSalvageMgr_c::hasDowsingForId(const s32 &id) const { + if (id == -1) { + return false; + } else if (checkDeliveredStoryflag(id)) { + return false; + } else { + bool ret = false; + switch (id) { + case SALVAGE_OBJ_PROPERA: { + ret = DowsingTarget::hasPropellerDowsing(); + break; + } + case SALVAGE_OBJ_ROULETTE: { + ret = DowsingTarget::hasPartyWheelDowsing(); + break; + } + case SALVAGE_OBJ_DIVINER_CRYSTAL: { + ret = DowsingTarget::hasCrystalBallDowsing(); + break; + } + case SALVAGE_OBJ_SALVAGE_MORRY: { + ret = DowsingTarget::hasNewPlantSpeciesDowsing(); + break; + } + case SALVAGE_OBJ_MOLE_ELDER: { + ret = DowsingTarget::hasPumpkinDowsing(); + break; + } + case SALVAGE_OBJ_WATER_JAR: { + ret = DowsingTarget::hasWaterBasinDowsing(); + break; + } + } + return ret; + } +} + +u16 dSalvageMgr_c::getDeliverToActorId(s32 id) { + return sDefs[id].deliverToProfileId; +} + +void dSalvageMgr_c::noop() {} + +s32 dSalvageMgr_c::getCurrentSalvageObjId() const { + return mCurrentPickupIdx; +} + +bool dSalvageMgr_c::checkDeliveredStoryflag(const s32 &id) const { + if (id == -1) { + return false; + } else if (sDefs[id].deliveredStoryflag == -1) { + return false; + } else { + return StoryflagManager::sInstance->getFlag(sDefs[id].deliveredStoryflag) != 0; + } +} + +void dSalvageMgr_c::unsetPickupStoryflag(const s32 &id) { + if (id == -1) { + return; + } else if (checkDeliveredStoryflag(id)) { + return; + } else { + // TODO - ??? + s32 alsoUnsetFlag = sDefs[id].additionalPickupUnsetFlag; + if (sDefs[id].pickedUpStoryFlag != -1) { + StoryflagManager::sInstance->unsetFlag(sDefs[id].pickedUpStoryFlag); + } + if (alsoUnsetFlag != -1) { + StoryflagManager::sInstance->unsetFlag(sDefs[id].additionalPickupUnsetFlag); + } + } +} + +bool dSalvageMgr_c::checkPickupStoryflag(const s32 &id) const { + if (id == -1) { + return false; + } else if (sDefs[id].pickedUpStoryFlag == -1) { + return false; + } else { + return StoryflagManager::sInstance->getFlag(sDefs[id].pickedUpStoryFlag) != 0; + } +} + +bool dSalvageMgr_c::checkIsOnDeliveryStage() const { + if (mCurrentPickupIdx >= 0 && dScGame_c::currentSpawnInfo.stageName == sDefs[mCurrentPickupIdx].stage) { + return true; + } else { + return false; + } +} + +dAcObjBase_c *dSalvageMgr_c::findDeliveryTarget() { + if (mDeliverToRef.isLinked()) { + return mDeliverToRef.get(); + } else if (mCurrentPickupIdx == -1) { + return nullptr; + } else { + return (dAcObjBase_c *)fManager_c::searchBaseByProfName( + (ProfileName)sDefs[mCurrentPickupIdx].deliverToProfileId, nullptr + ); + } +} + +bool dSalvageMgr_c::triggerDeliveryEvent() { + if (mCurrentPickupIdx == -1) { + return false; + } else { + dAcNpcSlb_c *slb = mSlbRef.get(); + dAcSalbageObj_c *obj = mObjRef.get(); + dAcObjBase_c *deliverTo = mDeliverToRef.get(); + if (slb == nullptr || obj == nullptr || deliverTo == nullptr) { + return false; + } else { + Event ev(sDefs[mCurrentPickupIdx].deliveryEvnt, 100, 0x100001, nullptr, nullptr); + EventManager::alsoSetAsCurrentEvent(slb, &ev, deliverTo); + return true; + } + } +} + +u16 dSalvageMgr_c::getTalkEntryPoint1ForPickup(dAcObjBase_c *obj) { + SalvageObj_e id = SALVAGE_OBJ_NONE; + if (obj != nullptr) { + if (obj->mProfileName == fProfile::OBJ_PROPERA) { + id = SALVAGE_OBJ_PROPERA; + } else if (obj->mProfileName == fProfile::OBJ_ROULETTE) { + id = SALVAGE_OBJ_ROULETTE; + } else if (obj->mProfileName == fProfile::OBJ_DIVINER_CRYSTAL) { + id = SALVAGE_OBJ_DIVINER_CRYSTAL; + } else if (obj->mProfileName == fProfile::NPC_SALBAGE_MORRY) { + id = SALVAGE_OBJ_SALVAGE_MORRY; + } else if (obj->mProfileName == fProfile::NPC_MOLE_ELDER) { + id = SALVAGE_OBJ_MOLE_ELDER; + } else if (obj->mProfileName == fProfile::OBJ_WATER_JAR) { + id = SALVAGE_OBJ_WATER_JAR; + } else { + id = SALVAGE_OBJ_PROPERA; + } + } + + if (id == SALVAGE_OBJ_NONE) { + return -1; + } + return sEntrypoints[id].talkEntrypoint1; +} + +u16 dSalvageMgr_c::getTalkEntryPoint2ForPickup(dAcObjBase_c *obj) { + SalvageObj_e id = SALVAGE_OBJ_NONE; + if (obj != nullptr) { + if (obj->mProfileName == fProfile::OBJ_PROPERA) { + id = SALVAGE_OBJ_PROPERA; + } else if (obj->mProfileName == fProfile::OBJ_ROULETTE) { + id = SALVAGE_OBJ_ROULETTE; + } else if (obj->mProfileName == fProfile::OBJ_DIVINER_CRYSTAL) { + id = SALVAGE_OBJ_DIVINER_CRYSTAL; + } else if (obj->mProfileName == fProfile::NPC_SALBAGE_MORRY) { + id = SALVAGE_OBJ_SALVAGE_MORRY; + } else if (obj->mProfileName == fProfile::NPC_MOLE_ELDER) { + id = SALVAGE_OBJ_MOLE_ELDER; + } else if (obj->mProfileName == fProfile::OBJ_WATER_JAR) { + id = SALVAGE_OBJ_WATER_JAR; + } else { + id = SALVAGE_OBJ_PROPERA; + } + } + + if (id == SALVAGE_OBJ_NONE) { + return -1; + } + return sEntrypoints[id].talkEntrypoint2; +} + +u16 dSalvageMgr_c::getTalkEntryPoint3ForPickup(dAcObjBase_c *obj) { + SalvageObj_e id = SALVAGE_OBJ_NONE; + if (obj != nullptr) { + if (obj->mProfileName == fProfile::OBJ_PROPERA) { + id = SALVAGE_OBJ_PROPERA; + } else if (obj->mProfileName == fProfile::OBJ_ROULETTE) { + id = SALVAGE_OBJ_ROULETTE; + } else if (obj->mProfileName == fProfile::OBJ_DIVINER_CRYSTAL) { + id = SALVAGE_OBJ_DIVINER_CRYSTAL; + } else if (obj->mProfileName == fProfile::NPC_SALBAGE_MORRY) { + id = SALVAGE_OBJ_SALVAGE_MORRY; + } else if (obj->mProfileName == fProfile::NPC_MOLE_ELDER) { + id = SALVAGE_OBJ_MOLE_ELDER; + } else if (obj->mProfileName == fProfile::OBJ_WATER_JAR) { + id = SALVAGE_OBJ_WATER_JAR; + } else { + id = SALVAGE_OBJ_PROPERA; + } + } + + if (id == SALVAGE_OBJ_NONE) { + return -1; + } + return sEntrypoints[id].talkEntrypoint3; +}