From 2c61e2fb9c1e456a8f31de50851460f5c4600d6b Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Tue, 22 Sep 2026 12:42:35 -0400 Subject: [PATCH] d_t_alldie --- config/SOUE01/splits.txt | 1 + config/SOUE01/symbols.txt | 20 +++--- configure.py | 2 +- include/d/a/e/d_a_en_base.h | 5 ++ include/d/d_stage.h | 7 +- include/d/t/d_t_alldie.h | 32 +++++++++ include/toBeSorted/time_area_mgr.h | 4 +- src/d/tg/d_t_alldie.cpp | 112 +++++++++++++++++++++++++++++ 8 files changed, 170 insertions(+), 13 deletions(-) create mode 100644 include/d/t/d_t_alldie.h create mode 100644 src/d/tg/d_t_alldie.cpp diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 3918fdc1..c1b27cab 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -1586,6 +1586,7 @@ 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 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 834a99ec..35c5967f 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -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,13 +14493,13 @@ 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 +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 @@ -36470,7 +36470,7 @@ 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 __vt__13dTgViewClip_c = .data:0x80536138; // type:object size:0x74 g_profile_SW_TAG = .data:0x805361B0; // type:object size:0x10 @@ -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 diff --git a/configure.py b/configure.py index 32075dc5..389bd0e0 100644 --- a/configure.py +++ b/configure.py @@ -647,7 +647,7 @@ 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(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"), diff --git a/include/d/a/e/d_a_en_base.h b/include/d/a/e/d_a_en_base.h index adbc1d0c..a9e624ba 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" @@ -95,6 +96,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/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/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/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/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; +}