diff --git a/config/SOUE01/rels/d_a_obj_chestNP/symbols.txt b/config/SOUE01/rels/d_a_obj_chestNP/symbols.txt index 10a99356..b88e98de 100644 --- a/config/SOUE01/rels/d_a_obj_chestNP/symbols.txt +++ b/config/SOUE01/rels/d_a_obj_chestNP/symbols.txt @@ -8,21 +8,17 @@ __dt__24sFState_c<11dAcOChest_c>Fv = .text:0x000001F0; // type:function size:0x5 __dt__27sFStateFct_c<11dAcOChest_c>Fv = .text:0x00000250; // type:function size:0x6C __dt__80sStateMgr_c<11dAcOChest_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x000002C0; // type:function size:0xA0 __dt__50sFStateMgr_c<11dAcOChest_c,20sStateMethodUsr_FI_c>Fv = .text:0x00000360; // type:function size:0xA4 -fn_326_410 = .text:0x00000410; // type:function size:0xC -fn_326_41C = .text:0x0000041C; // type:function size:0x4 -fn_326_420 = .text:0x00000420; // type:function size:0xC -fn_326_42C = .text:0x0000042C; // type:function size:0x4 -fn_326_430 = .text:0x00000430; // type:function size:0xC -fn_326_43C = .text:0x0000043C; // type:function size:0x4 -fn_326_440 = .text:0x00000440; // type:function size:0xC -fn_326_44C = .text:0x0000044C; // type:function size:0x4 -AcOChest__initModels = .text:0x00000450; // type:function size:0x1B0 -AcOChest__init = .text:0x00000600; // type:function size:0x26C +changeStateOpenCallback__11dAcOChest_cFP11dAcOChest_c = .text:0x00000410; // type:function size:0x10 +changeStateWaitCallback__11dAcOChest_cFP11dAcOChest_c = .text:0x00000420; // type:function size:0x10 +changeStateFailCallback__11dAcOChest_cFP11dAcOChest_c = .text:0x00000430; // type:function size:0x10 +changeStateWait2Callback__11dAcOChest_cFP11dAcOChest_c = .text:0x00000440; // type:function size:0x10 +createHeap__11dAcOChest_cFv = .text:0x00000450; // type:function size:0x1B0 +create__11dAcOChest_cFv = .text:0x00000600; // type:function size:0x26C changeState__80sStateMgr_c<11dAcOChest_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00000870; // type:function size:0x10 -fn_326_880 = .text:0x00000880; // type:function size:0x8 -AcOChest__update = .text:0x00000890; // type:function size:0x98 +doDelete__11dAcOChest_cFv = .text:0x00000880; // type:function size:0x8 +actorExecute__11dAcOChest_cFv = .text:0x00000890; // type:function size:0x98 executeState__80sStateMgr_c<11dAcOChest_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000930; // type:function size:0x10 -AcOChest__draw = .text:0x00000940; // type:function size:0x50 +draw__11dAcOChest_cFv = .text:0x00000940; // type:function size:0x50 initializeState_Wait__11dAcOChest_cFv = .text:0x00000990; // type:function size:0x4 executeState_Wait__11dAcOChest_cFv = .text:0x000009A0; // type:function size:0x2C finalizeState_Wait__11dAcOChest_cFv = .text:0x000009D0; // type:function size:0x4 @@ -35,27 +31,25 @@ finalizeState_OrderOpenEventAfter__11dAcOChest_cFv = .text:0x00000B60; // type:f initializeState_FailEvent__11dAcOChest_cFv = .text:0x00000B70; // type:function size:0x4 executeState_FailEvent__11dAcOChest_cFv = .text:0x00000B80; // type:function size:0x4 finalizeState_FailEvent__11dAcOChest_cFv = .text:0x00000B90; // type:function size:0x4 -AcOChest__performInteraction = .text:0x00000BA0; // type:function size:0xE4 -fn_326_C90 = .text:0x00000C90; // type:function size:0x68 -fn_326_D00 = .text:0x00000D00; // type:function size:0x80 -fn_326_D80 = .text:0x00000D80; // type:function size:0x5C -fn_326_DE0 = .text:0x00000DE0; // type:function size:0x48 -fn_326_E30 = .text:0x00000E30; // type:function size:0x50 -AcOChest__getName = .text:0x00000E80; // type:function size:0xC -AcOChest__getSubtypeName = .text:0x00000E90; // type:function size:0x78 -AcOChest__getModelName = .text:0x00000F10; // type:function size:0xC -AcOChest__getOpenOrClose = .text:0x00000F20; // type:function size:0x34 -fn_326_F60 = .text:0x00000F60; // type:function size:0x78 -AcOChest__getSubtype = .text:0x00000FE0; // type:function size:0xC -AcOChest__hasBeenOpened = .text:0x00000FF0; // type:function size:0x8C -AcOChest__stateOpenUpdate2 = .text:0x00001080; // type:function size:0x39C -AcOChest__stateOpenEventEnter2 = .text:0x00001420; // type:function size:0x1C -fn_326_1440 = .text:0x00001440; // type:function size:0x1C -fn_326_1460 = .text:0x00001460; // type:function size:0x8 -fn_326_1470 = .text:0x00001470; // type:function size:0x28 -fn_326_1498 = .text:0x00001498; // type:function size:0x4 -fn_326_14A0 = .text:0x000014A0; // type:function size:0x28 -fn_326_14C8 = .text:0x000014C8; // type:function size:0x4 +doInteraction__11dAcOChest_cFl = .text:0x00000BA0; // type:function size:0xE4 +fn_326_C90__11dAcOChest_cFv = .text:0x00000C90; // type:function size:0x68 +changeStateOpen__11dAcOChest_cFv = .text:0x00000D00; // type:function size:0x80 +changeStateWait__11dAcOChest_cFv = .text:0x00000D80; // type:function size:0x5C +changeStateFail__11dAcOChest_cFv = .text:0x00000DE0; // type:function size:0x48 +changeStateWait2__11dAcOChest_cFv = .text:0x00000E30; // type:function size:0x50 +getName__11dAcOChest_cFv = .text:0x00000E80; // type:function size:0xC +getSubtypeName__11dAcOChest_cFv = .text:0x00000E90; // type:function size:0x78 +getModelName__11dAcOChest_cFv = .text:0x00000F10; // type:function size:0xC +getOpenOrClose__11dAcOChest_cFUc = .text:0x00000F20; // type:function size:0x34 +getDzbPlcName__11dAcOChest_cFv = .text:0x00000F60; // type:function size:0x78 +getSubtype__11dAcOChest_cFv = .text:0x00000FE0; // type:function size:0xC +hasBeenOpened__11dAcOChest_cFv = .text:0x00000FF0; // type:function size:0x8C +stateOpenUpdate2__11dAcOChest_cFv = .text:0x00001080; // type:function size:0x39C +stateOpenEventEnter2__11dAcOChest_cFv = .text:0x00001420; // type:function size:0x1C +fn_326_1440__11dAcOChest_cFv = .text:0x00001440; // type:function size:0x1C +hasInsideModel__11dAcOChest_cFv = .text:0x00001460; // type:function size:0x8 +fn_326_1470__11dAcOChest_cFv = .text:0x00001470; // type:function size:0x2C +fn_326_14A0__11dAcOChest_cFv = .text:0x000014A0; // type:function size:0x2C __dt__11dAcOChest_cFv = .text:0x000014D0; // type:function size:0xFC getStateID__80sStateMgr_c<11dAcOChest_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x000015D0; // type:function size:0x10 build__27sFStateFct_c<11dAcOChest_c>FRC12sStateIDIf_c = .text:0x000015E0; // type:function size:0x60 @@ -86,28 +80,28 @@ lbl_326_data_10 = .data:0x00000010; // type:object size:0x10 lbl_326_data_20 = .data:0x00000020; // type:object size:0x4 data:4byte lbl_326_data_24 = .data:0x00000024; // type:object size:0xC lbl_326_data_30 = .data:0x00000030; // type:object size:0x8 data:4byte -AcOChest__OPEN_WARDROBE_INTERACTION = .data:0x00000038; // type:object size:0x30 align:4 data:float +OPEN_WARDROBE_INTERACTION__11dAcOChest_c = .data:0x00000038; // type:object size:0x30 align:4 data:float g_profile_OBJ_CHEST = .data:0x00000068; // type:object size:0x10 lbl_326_data_78 = .data:0x00000078; // type:object size:0x10 lbl_326_data_88 = .data:0x00000088; // type:object size:0x10 lbl_326_data_98 = .data:0x00000098; // type:object size:0x10 lbl_326_data_A8 = .data:0x000000A8; // type:object size:0x10 -AcOChest__INSIDE_MODEL_NAMES = .data:0x000000B8; // type:object size:0x10 +INSIDE_MODEL_NAMES__11dAcOChest_c = .data:0x000000B8; // type:object size:0x10 lbl_326_data_C8 = .data:0x000000C8; // type:object size:0xC data:string lbl_326_data_D4 = .data:0x000000D4; // type:object size:0x1C lbl_326_data_F0 = .data:0x000000F0; // type:object size:0x8 lbl_326_data_F8 = .data:0x000000F8; // type:object size:0x28 lbl_326_data_120 = .data:0x00000120; // type:object size:0xC lbl_326_data_12C = .data:0x0000012C; // type:object size:0xC -AcOChest__vtable = .data:0x00000138; // type:object size:0x80 -lbl_326_data_1B8 = .data:0x000001B8; // type:object size:0x30 -lbl_326_data_1E8 = .data:0x000001E8; // type:object size:0x30 -lbl_326_data_218 = .data:0x00000218; // type:object size:0x18 -lbl_326_data_230 = .data:0x00000230; // type:object size:0x130 -lbl_326_data_360 = .data:0x00000360; // type:object size:0x34 +__vt__11dAcOChest_c = .data:0x00000138; // type:object size:0x80 +__vt__50sFStateMgr_c<11dAcOChest_c,20sStateMethodUsr_FI_c> = .data:0x000001B8; // type:object size:0x30 +__vt__80sStateMgr_c<11dAcOChest_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x000001E8; // type:object size:0x30 +__vt__27sFStateFct_c<11dAcOChest_c> = .data:0x00000218; // type:object size:0x18 +__vt__24sFState_c<11dAcOChest_c> = .data:0x00000230; // type:object size:0x130 +__vt__26sFStateID_c<11dAcOChest_c> = .data:0x00000360; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global lbl_326_bss_8 = .bss:0x00000008; // type:object size:0x10 data:4byte -AcOChest__STATE_WAIT = .bss:0x00000018; // type:object size:0x40 data:4byte -AcOChest__STATE_OPEN_EVENT = .bss:0x00000058; // type:object size:0x40 data:4byte -AcOChest__STATE_FAIL_EVENT = .bss:0x00000098; // type:object size:0x40 data:4byte -AcOChest__STATE_ORDER_OPEN_EVENT_AFTER = .bss:0x000000D8; // type:object size:0x30 data:4byte +StateID_Wait__11dAcOChest_c = .bss:0x00000018; // type:object size:0x30 data:4byte +StateID_OpenEvent__11dAcOChest_c = .bss:0x00000058; // type:object size:0x30 data:4byte +StateID_FailEvent__11dAcOChest_c = .bss:0x00000098; // type:object size:0x30 data:4byte +StateID_OrderOpenEventAfter__11dAcOChest_c = .bss:0x000000D8; // type:object size:0x30 data:4byte diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index baf51582..9da56ed6 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -3526,7 +3526,7 @@ ActorEventRelated__getSomeEventRelatedNumber = .text:0x8009CFA0; // type:functio isAdvance__17ActorEventRelatedFv = .text:0x8009D020; // type:function size:0x34 advanceNext__17ActorEventRelatedFv = .text:0x8009D060; // type:function size:0x50 ActorEventRelated__getSingleIntData2 = .text:0x8009D0B0; // type:function size:0x8C -ActorEventRelated__getSingleIntData = .text:0x8009D140; // type:function size:0x8C +getSingleIntData__17ActorEventRelatedFPiUlUl = .text:0x8009D140; // type:function size:0x8C getSingleFloatData__17ActorEventRelatedFPfUlUl = .text:0x8009D1D0; // type:function size:0x8C getSingleVecData__17ActorEventRelatedFP7mVec3_cUlUl = .text:0x8009D260; // type:function size:0x9C ActorEventRelated__getIntDataWithDefault = .text:0x8009D300; // type:function size:0x98 @@ -13369,7 +13369,7 @@ giveItem22 = .text:0x802490F0; // type:function size:0x4 fn_80249100 = .text:0x80249100; // type:function size:0x44 giveItem3 = .text:0x80249150; // type:function size:0x60 fn_802491B0 = .text:0x802491B0; // type:function size:0x54 -AcItem__giveItem = .text:0x80249210; // type:function size:0x84 +giveItem__9dAcItem_cF7ITEM_IDii = .text:0x80249210; // type:function size:0x84 fn_802492A0 = .text:0x802492A0; // type:function size:0x78 fn_80249320 = .text:0x80249320; // type:function size:0x78 fn_802493A0 = .text:0x802493A0; // type:function size:0x3C8 @@ -17268,7 +17268,7 @@ ModuleUnresolved = .text:0x802DFCD0; // type:function size:0x4 ModuleConstructorsX = .text:0x802DFCE0; // type:function size:0x44 ModuleDestructorsX = .text:0x802DFD30; // type:function size:0x44 cLib__memSet = .text:0x802DFD80; // type:function size:0x4 -cLib__addCalcPos = .text:0x802DFD90; // type:function size:0x234 +addCalcPos__4cLibFP7mVec3_cRC7mVec3_cfff = .text:0x802DFD90; // type:function size:0x234 addCalcPosXZ__4cLibFP7mVec3_cRC7mVec3_cfff = .text:0x802DFFD0; // type:function size:0x1B8 cLib__addCalcPos2 = .text:0x802E0190; // type:function size:0x13C cLib__addCalcPosXZ2 = .text:0x802E02D0; // type:function size:0xF8 diff --git a/include/d/a/d_a_item.h b/include/d/a/d_a_item.h index 997683c8..f1653c64 100644 --- a/include/d/a/d_a_item.h +++ b/include/d/a/d_a_item.h @@ -16,8 +16,8 @@ #include "nw4r/ut/ut_Color.h" #include "s/s_State.hpp" #include "toBeSorted/actor_event.h" -#include "toBeSorted/dowsing_target.h" #include "toBeSorted/d_emitter.h" +#include "toBeSorted/dowsing_target.h" class dAcItem_0xB34 { public: @@ -46,6 +46,7 @@ public: static void spawnItem(u16 item, u32 room, const mVec3_c &pos, const mAng3_c &rot, u32 params, u32 arg); static void spawnDrop(u16 item, u32 room, const mVec3_c &pos, const mAng3_c &rot); + static void giveItem(ITEM_ID, int, int); static u32 checkFlag(u32 flag); static bool hasItem(u32 flag) { return checkFlag(flag); diff --git a/include/d/a/obj/d_a_obj_chest.h b/include/d/a/obj/d_a_obj_chest.h index 52752c20..bf169d5b 100644 --- a/include/d/a/obj/d_a_obj_chest.h +++ b/include/d/a/obj/d_a_obj_chest.h @@ -1,22 +1,80 @@ #ifndef D_A_OBJ_CHEST_H #define D_A_OBJ_CHEST_H +#include "common.h" #include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_w.h" +#include "m/m3d/m_smdl.h" +#include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" -#include "s/s_StateMgr.hpp" +#include "toBeSorted/actor_event.h" +#include "toBeSorted/attention.h" +#include "toBeSorted/d_d3d.h" +#include "toBeSorted/dowsing_target.h" class dAcOChest_c : public dAcObjBase_c { public: - dAcOChest_c() : mStateMgr(*this, sStateID::null) {} + dAcOChest_c() + : mStateMgr(*this, sStateID::null), mEvent(*this, nullptr), mDowsingTarget(this, DowsingTarget::SLOT_NONE) {} virtual ~dAcOChest_c() {} + static void changeStateOpenCallback(dAcOChest_c *); + static void changeStateWaitCallback(dAcOChest_c *); + static void changeStateFailCallback(dAcOChest_c *); + static void changeStateWait2Callback(dAcOChest_c *); + + virtual bool createHeap() override; + virtual int create() override; + virtual int draw() override; + virtual int doDelete() override; + virtual int actorExecute() override; + STATE_FUNC_DECLARE(dAcOChest_c, Wait); STATE_FUNC_DECLARE(dAcOChest_c, OpenEvent); STATE_FUNC_DECLARE(dAcOChest_c, FailEvent); STATE_FUNC_DECLARE(dAcOChest_c, OrderOpenEventAfter); + virtual void doInteraction(s32) override; + + void fn_326_C90(); + void changeStateOpen(); + void changeStateWait(); + void changeStateFail(); + void changeStateWait2(); + char *getName(); + char *getSubtypeName(); + char *getModelName(); + char *getOpenOrClose(u8); + char *getDzbPlcName(); + s32 getSubtype(); + bool hasBeenOpened(); + void stateOpenUpdate2(); + void stateOpenEventEnter2(); + void fn_326_1440(); + bool hasInsideModel(); + void fn_326_1470(); + void fn_326_14A0(); + private: - /* 0x??? */ STATE_MGR_DECLARE(dAcOChest_c); + /* 0x330 */ nw4r::g3d::ResFile mResFile; + /* 0x334 */ d3d::AnmMdlWrapper mAnmMdl; + /* 0x3A4 */ m3d::smdl_c mMdl; + /* 0x3C0 */ dBgW mBgW; + /* 0x5D0 */ STATE_MGR_DECLARE(dAcOChest_c); + /* 0x60C */ ActorEventRelated mEvent; + /* 0x65C */ bool mGaveItem; + /* 0x65D */ bool mField_0x65D; + /* 0x65E */ bool mHasInsideModel; + /* 0x65F */ bool mIsLinksCloset; + /* 0x660 */ DowsingTarget mDowsingTarget; + + static const float OPEN_WARDROBE_INTERACTION_FIELD_0x24; + static const char *CHEST_OPEN; + static const char *CHEST_OPEN_AFTER; + static const char *CHEST_FAIL; + static InteractionTargetDef OPEN_WARDROBE_INTERACTION; + static char *INSIDE_MODEL_NAMES[4]; + static const u32 unused; }; #endif diff --git a/include/m/m_vec.h b/include/m/m_vec.h index 0fb52aea..1aafe812 100644 --- a/include/m/m_vec.h +++ b/include/m/m_vec.h @@ -235,6 +235,10 @@ public: f32 squareMagXZ() const { return x * x + z * z; } + f32 squareDistanceToXZ(const mVec3_c &other) const { + return (*this - other).squareMagXZ(); + } + void rotX(const mAng &angle); void rotY(const mAng &angle); void rotZ(const mAng &angle); diff --git a/include/toBeSorted/actor_event.h b/include/toBeSorted/actor_event.h index 5a691f53..afbc9ba1 100644 --- a/include/toBeSorted/actor_event.h +++ b/include/toBeSorted/actor_event.h @@ -17,6 +17,7 @@ public: void advanceNext(); bool isAdvance(); + int getSingleIntData(int *result, u32 code, u32); int getSingleFloatData(f32 *result, u32 code, u32); int getSingleVecData(mVec3_c *result, u32 code, u32); diff --git a/src/REL/d/a/obj/d_a_obj_chest.cpp b/src/REL/d/a/obj/d_a_obj_chest.cpp index 38ad9d16..d4b7060a 100644 --- a/src/REL/d/a/obj/d_a_obj_chest.cpp +++ b/src/REL/d/a/obj/d_a_obj_chest.cpp @@ -1,21 +1,437 @@ #include "d/a/obj/d_a_obj_chest.h" +#include "c/c_lib.h" +#include "common.h" +#include "d/a/d_a_item.h" +#include "d/a/d_a_itembase.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/col/bg/d_bg_s.h" +#include "d/d_message.h" +#include "d/d_sc_game.h" +#include "d/flag/sceneflag_manager.h" +#include "d/flag/storyflag_manager.h" +#include "f/f_base.h" +#include "m/m3d/m_fanm.h" +#include "m/m3d/m_mdl.h" +#include "m/m_angle.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "rvl/MTX/mtx.h" +#include "s/s_Math.h" +#include "toBeSorted/attention.h" +#include "toBeSorted/dowsing_target.h" +#include "toBeSorted/event.h" +#include "toBeSorted/event_manager.h" + +const char *dAcOChest_c::CHEST_OPEN = "ChestOpen"; +const char *dAcOChest_c::CHEST_OPEN_AFTER = "ChestOpenAfter"; +const char *dAcOChest_c::CHEST_FAIL = "ChestFail"; + +const float dAcOChest_c::OPEN_WARDROBE_INTERACTION_FIELD_0x24 = 10.0f; + +InteractionTargetDef dAcOChest_c::OPEN_WARDROBE_INTERACTION = {0, 3, 1, OPEN, 0, 140.0f, + 40.0f, 40.0f, -100.0f, 100.0f, 50.0f, 1.0f}; + SPECIAL_ACTOR_PROFILE(OBJ_CHEST, dAcOChest_c, fProfile::OBJ_CHEST, 0x13E, 0, 3); +char *dAcOChest_c::INSIDE_MODEL_NAMES[4] = { + "TansuInsideA", + "TansuInsideB", + "TansuInsideC", + "TansuInsideD", +}; + STATE_DEFINE(dAcOChest_c, Wait); STATE_DEFINE(dAcOChest_c, OpenEvent); STATE_DEFINE(dAcOChest_c, FailEvent); STATE_DEFINE(dAcOChest_c, OrderOpenEventAfter); +void dAcOChest_c::changeStateOpenCallback(dAcOChest_c *chest) { + if (chest == nullptr) { + return; + } + chest->changeStateOpen(); +} + +void dAcOChest_c::changeStateWaitCallback(dAcOChest_c *chest) { + if (chest == nullptr) { + return; + } + chest->changeStateWait(); +} + +void dAcOChest_c::changeStateFailCallback(dAcOChest_c *chest) { + if (chest == nullptr) { + return; + } + chest->changeStateFail(); +} + +void dAcOChest_c::changeStateWait2Callback(dAcOChest_c *chest) { + if (chest == nullptr) { + return; + } + chest->changeStateWait2(); +} + +bool dAcOChest_c::createHeap() { + char *name = getName(); + char *subtype = getSubtypeName(); + char *modelName = getModelName(); + char *openOrClose = getOpenOrClose(0); + + void *mdlData = getOarcResFile(name); + void *anmData = getOarcResFile(modelName); + + TRY_CREATE(mAnmMdl.create3(*this, mdlData, anmData, subtype, openOrClose, 0x120)); + if (!getFromParams(0x1C, 0xFF)) { + mAnmMdl.getModel().setPriorityDraw(0x1C, 0xFFFFFFFF); + } + if ((s32)getFromParams(0x10, 0xFF) != 0xFF) { + void *data2 = getOarcResFile("TansuInside"); + mResFile = nw4r::g3d::ResFile(data2); + + nw4r::g3d::ResMdl mdl = mResFile.GetResMdl(INSIDE_MODEL_NAMES[getFromParams(0x10, 0xFF)]); + if (!mMdl.create(mdl, &heap_allocator, 0x120, 1, nullptr)) { + return NOT_READY; + } + } + char *dzbPlcName = getDzbPlcName(); + void *dzb = getOarcDZB(name, dzbPlcName); + void *plc = getOarcPLC(name, dzbPlcName); + fn_326_C90(); + bool ok = !mBgW.Set((cBgD_t *)dzb, (PLC *)plc, cBgW::MOVE_BG_e, &mWorldMtx, &mScale); + if (!ok) { + return NOT_READY; + } + return mBgW.InitMapStuff(&heap_allocator); +} + +int dAcOChest_c::create() { + if (!initAllocatorWork1Heap(0x4000, "dAcOChest_c::m_allocator", 0x20)) { + return FAILED; + } + mBgW.Lock(); + dBgS::GetInstance()->Regist(&mBgW, this); + dBgS::GetInstance()->RegistBg(&mBgW, this); + + forwardAccel = 0.0f; + forwardMaxSpeed = 0.0f; + + mStateMgr.changeState(StateID_Wait); + + boundingBox.Set(mVec3_c(-200.0f, -0.0f, -100.0f), mVec3_c(200.0f, 500.0f, 100.0f)); + + mAnmMdl.setAnm(getOpenOrClose(0), m3d::PLAY_MODE_4); + mAnmMdl.setRate(0.0f); + + poscopy2.y = position.y + 150.0f; + poscopy3 = poscopy2; + if ((s32)getFromParams(0x10, 0xFF) != 0xFF) { + mMdl.setLocalMtx(mWorldMtx); + } + + if (dScGame_c::isCurrentStage("F001r") && roomid == 1 && 900.0f < position.x && position.x < 1000.0f && + -50.0f < position.y && position.y < 50.0f && -2730.0f < position.z && position.z < -2630.0f) { + mIsLinksCloset = true; + } + + mVec3_c dowsingPos(0.0f, 150.0f, 0.0f); + ITEM_ID itemId = (ITEM_ID)getFromParams(0x8, /* ITEM_LANAYRU_SOTH | ITEM_EVIL_CRYSTAL */ 0xFF); + bool isTreasure = dAcItem_c::isTreasure(itemId); + if (isTreasure) { + mDowsingTarget.initialize(DowsingTarget::SLOT_TREASURE, 0, &dowsingPos, 0.0f); + } else if (dAcItem_c::isRupee(itemId)) { + mDowsingTarget.initialize(DowsingTarget::SLOT_RUPEE, 0, &dowsingPos, 0.0f); + } + + return SUCCEEDED; +} + +int dAcOChest_c::doDelete() { + return SUCCEEDED; +} +int dAcOChest_c::actorExecute() { + ITEM_ID itemId = (ITEM_ID)getFromParams(0x8, /* ITEM_LANAYRU_SOTH | ITEM_EVIL_CRYSTAL */ 0xFF); + if (!hasBeenOpened() && (dAcItem_c::isTreasure(itemId) || dAcItem_c::isRupee(itemId))) { + mDowsingTarget.doRegister(); + } else { + mDowsingTarget.doUnregister(); + } + mStateMgr.executeState(); + fn_326_C90(); + return SUCCEEDED; +} + +int dAcOChest_c::draw() { + drawModelType1(&mAnmMdl.getModel()); + if (hasInsideModel()) { + drawModelType1(&mMdl); + } + return SUCCEEDED; +} + void dAcOChest_c::initializeState_Wait() {} -void dAcOChest_c::executeState_Wait() {} + +void dAcOChest_c::executeState_Wait() { + OPEN_WARDROBE_INTERACTION.field_0x24 = OPEN_WARDROBE_INTERACTION_FIELD_0x24; + AttentionManager::GetInstance()->addTarget(*this, OPEN_WARDROBE_INTERACTION, 0, (mVec3_c *)0); +} + void dAcOChest_c::finalizeState_Wait() {} -void dAcOChest_c::initializeState_OpenEvent() {} -void dAcOChest_c::executeState_OpenEvent() {} + +void dAcOChest_c::initializeState_OpenEvent() { + stateOpenEventEnter2(); +} + +void dAcOChest_c::executeState_OpenEvent() { + stateOpenUpdate2(); +} + void dAcOChest_c::finalizeState_OpenEvent() {} -void dAcOChest_c::initializeState_FailEvent() {} -void dAcOChest_c::executeState_FailEvent() {} -void dAcOChest_c::finalizeState_FailEvent() {} + void dAcOChest_c::initializeState_OrderOpenEventAfter() {} -void dAcOChest_c::executeState_OrderOpenEventAfter() {} + +void dAcOChest_c::executeState_OrderOpenEventAfter() { + if (mGaveItem && EventManager::sInstance->isInEvent0Or7()) { + char *name = getName(); + void *data = dAcObjBase_c::getOarcZev(name); + Event event(CHEST_OPEN_AFTER, data, 400, 0x100001, nullptr, (void *)changeStateWaitCallback); + mEvent.scheduleEvent(event, 0); + } else if (EventManager::sInstance->isInEvent(this, CHEST_OPEN_AFTER)) { + ITEM_ID itemId = (ITEM_ID)getFromParams(0x8, /* ITEM_LANAYRU_SOTH | ITEM_EVIL_CRYSTAL */ 0xFF); + if (dAcItem_c::isRupee(itemId)) { + dMessage_c::getInstance()->setField_0x2FC(0xFFFFFFFF); + } + mField_0x65D = true; + stateOpenUpdate2(); + mStateMgr.changeState(StateID_OpenEvent); + } +} void dAcOChest_c::finalizeState_OrderOpenEventAfter() {} + +void dAcOChest_c::initializeState_FailEvent() { + stateOpenEventEnter2(); +} + +void dAcOChest_c::executeState_FailEvent() { + stateOpenUpdate2(); +} + +void dAcOChest_c::finalizeState_FailEvent() {} + +void dAcOChest_c::doInteraction(s32 _unused) { + char *name = getName(); + void *data = dAcObjBase_c::getOarcZev(name); + + if (hasBeenOpened()) { + Event event(CHEST_FAIL, data, 100, 0x100001, (void *)changeStateFailCallback, (void *)changeStateWait2Callback); + mEvent.scheduleEvent(event, 0); + } else { + Event event(CHEST_OPEN, data, 100, 0x100001, (void *)changeStateOpenCallback, nullptr); + mEvent.scheduleEvent(event, 0); + } +} + +void dAcOChest_c::fn_326_C90() { + PSMTXTrans(mWorldMtx.m, position.x, position.y, position.z); + mWorldMtx.ZXYrotM(rotation); + mAnmMdl.getModel().setLocalMtx(mWorldMtx); + mAnmMdl.getModel().calc(false); +} + +void dAcOChest_c::changeStateOpen() { + if (mField_0x65D) { + return; + } + u32 flag = getFromParams(0, 0xFF); + if (flag < 0xFF) { + SceneflagManager::sInstance->setFlag(roomid, flag); + } + fn_326_1470(); + mStateMgr.changeState(StateID_OpenEvent); +} + +void dAcOChest_c::changeStateWait() { + if (!mField_0x65D) { + return; + } + fn_326_1440(); + fn_326_14A0(); + mStateMgr.changeState(StateID_Wait); +} + +void dAcOChest_c::changeStateFail() { + fn_326_1470(); + mStateMgr.changeState(StateID_FailEvent); +} + +void dAcOChest_c::changeStateWait2() { + fn_326_1440(); + fn_326_14A0(); + mStateMgr.changeState(StateID_Wait); +} + +char *dAcOChest_c::getName() { + return "Tansu"; +} + +char *dAcOChest_c::getSubtypeName() { + switch (getSubtype()) { + case 0: return "TansuA"; + case 1: return "TansuB"; + case 2: return "TansuC"; + case 3: return "TansuD"; + } + return "TansuA"; +} + +char *dAcOChest_c::getModelName() { + return "Tansu"; +} + +char *dAcOChest_c::getOpenOrClose(u8 openOrClose) { + switch (openOrClose) { + case 0: return "TansuOpen"; + case 1: return "TansuClose"; + } + return nullptr; +} + +char *dAcOChest_c::getDzbPlcName() { + switch (getSubtype()) { + case 0: return "TansuA"; + case 1: return "TansuB"; + case 2: return "TansuC"; + case 3: return "TansuD"; + } + return "TansuA"; +} + +s32 dAcOChest_c::getSubtype() { + return getFromParams(0x1C, 0xFF); +} + +bool dAcOChest_c::hasBeenOpened() { + if ((s32)getFromParams(8, 0xFF) == 0xFF) { + return true; + } + u32 flag = getFromParams(0, 0xFF); + if (flag >= 0xFF) { + return true; + } + return (flag < 0xFF) && SceneflagManager::sInstance->checkBoolFlag(roomid, flag); +} + +void dAcOChest_c::stateOpenUpdate2() { + dAcPy_c *player = dAcPy_c::LINK; + switch (mEvent.getCurrentEventCommand()) { + case 'wait': { + mEvent.advanceNext(); + break; + } + case 'move': { + if (mEvent.isAdvance()) { + int i; + mEvent.getSingleIntData(&i, 'type', 0); + if (i == 1) { + char *openOrClose = getOpenOrClose(0); + mAnmMdl.setAnm(openOrClose, m3d::PLAY_MODE_4); + mAnmMdl.setFrame(0.0f); + mAnmMdl.setRate(1.0f); + mAnmMdl.getAnm().setPlayState(m3d::PLAY_MODE_1); + } else if (i == 2) { + char *openOrClose = getOpenOrClose(1); + mAnmMdl.setAnm(openOrClose, m3d::PLAY_MODE_4); + mAnmMdl.setFrame(0.0f); + mAnmMdl.setRate(1.0f); + mAnmMdl.getAnm().setPlayState(m3d::PLAY_MODE_1); + } + } else { + mAnmMdl.play(); + if (mAnmMdl.getAnm().isStop()) { + mEvent.advanceNext(); + } + } + break; + } + case 'comp': { + mVec3_c targetPosition; + mVec3_c playerPosition; + mVec3_c t(0.0f, 0.0f, 122.35f); + s32 targetAngle = 0x7FFF; + targetPosition = t; + targetAngle += rotation.y; + targetPosition.rotY(rotation.y); + targetPosition += position; + + if (player != nullptr) { + playerPosition = player->position; + cLib::addCalcPos(&playerPosition, targetPosition, 0.25f, 200.0f, 0.0f); + s16 YRot = rotation.y; + sLib::addCalcAngle(&YRot, targetAngle, 4, 0x7FFF, 0); + + if ((targetPosition.squareDistanceToXZ(playerPosition) < 25.0f) && + mAng::abs(YRot - mAng(targetAngle)) < 0xb6) { + playerPosition = targetPosition; + YRot = targetAngle; + mEvent.advanceNext(); + } + player->setPosYRot(playerPosition, YRot, 0, 0, 0); + } else { + mEvent.advanceNext(); + } + break; + } + case 'item': { + ITEM_ID itemId = (ITEM_ID)getFromParams(0x8, /* ITEM_LANAYRU_SOTH | ITEM_EVIL_CRYSTAL */ 0xFF); + dAcItem_c::giveItem(itemId, 0, 0); + mGaveItem = true; + mStateMgr.changeState(StateID_OrderOpenEventAfter); + mEvent.advanceNext(); + break; + } + case '????': { + break; + } + default: { + mEvent.advanceNext(); + } + } +} + +void dAcOChest_c::stateOpenEventEnter2() { + if ((s32)getFromParams(0x10, 0xFF) == 0xFF) { + return; + } + mHasInsideModel = true; +} + +void dAcOChest_c::fn_326_1440() { + if ((s32)getFromParams(0x10, 0xFF) == 0xFF) { + return; + } + mHasInsideModel = false; +} + +bool dAcOChest_c::hasInsideModel() { + return mHasInsideModel; +} + +void dAcOChest_c::fn_326_1470() { + if (!mIsLinksCloset) { + return; + } + StoryflagManager::sInstance->setFlag(0x331); +} + +void dAcOChest_c::fn_326_14A0() { + if (!mIsLinksCloset) { + return; + } + StoryflagManager::sInstance->unsetFlag(0x331); +} + +const u32 dAcOChest_c::unused = 0;