summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/SOUE01/splits.txt7
-rw-r--r--config/SOUE01/symbols.txt50
-rw-r--r--include/d/a/d_a_salbage_obj.h8
-rw-r--r--include/d/a/obj/d_a_obj_base.h4
-rw-r--r--include/d/flag/storyflag_map.h30
-rw-r--r--include/toBeSorted/salvage_mgr.h42
-rw-r--r--src/d/a/d_a_salbage_obj.cpp10
-rw-r--r--src/toBeSorted/salvage_mgr.cpp451
8 files changed, 554 insertions, 48 deletions
diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt
index 7d3f498f..eecc4a63 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
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index d616b4be..e6a90828 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
@@ -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
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/obj/d_a_obj_base.h b/include/d/a/obj/d_a_obj_base.h
index fab81e6d..ccd41832 100644
--- a/include/d/a/obj/d_a_obj_base.h
+++ b/include/d/a/obj/d_a_obj_base.h
@@ -167,6 +167,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/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/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<dAcSalbageObj_c> mObjRef;
/* 0x0C */ dAcRef_c<dAcNpcSlb_c> mSlbRef;
+ /* 0x18 */ dAcRef_c<dAcObjBase_c> mDeliverToRef;
+ /* 0x24 */ s32 mCurrentPickupIdx;
+ /* 0x28 */ s32 mCurrentPickupMaskBit;
+ /* 0x2C */ s16 field_0x2C;
+
private:
};
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/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, // <nothing>
+ -1, // <nothing>
+ 11790, // Does not exist?
+ },
+ {
+ 51001, // (?) 510_01: This is the Windmill Propeller...
+ -1, // <nothing>
+ -1, // <nothing>
+ 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;
+}