From 90e60e3341d82a6cf9faa84b532ab7d998ea9813 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Mon, 16 Feb 2026 21:39:24 -0500 Subject: [PATCH] porgress on d_t_scene_change. Area calc rename --- config/SOUE01/symbols.txt | 4 +- include/d/d_player_act.h | 2 +- include/d/t/d_t_scene_change.h | 40 +++++++++ include/toBeSorted/area_math.h | 3 +- src/REL/d/t/d_t_action.cpp | 4 +- src/REL/d/t/d_t_gate_to_ground.cpp | 2 +- src/REL/d/t/d_t_heat_resist.cpp | 4 +- src/REL/d/t/d_t_scene_change.cpp | 134 +++++++++++++++++++++++++++++ src/REL/d/t/d_t_sw_area.cpp | 2 +- src/REL/d/t/d_t_time_door_beam.cpp | 2 +- src/REL/d/t/d_t_touch.cpp | 2 +- 11 files changed, 187 insertions(+), 12 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index dca5d34b..23a92d69 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -2900,8 +2900,8 @@ __sinit_\d_rumble_cpp = .text:0x80066E50; // type:function size:0x108 scope:loca fn_80066F60 = .text:0x80066F60; // type:function size:0x50 lzSafeDecompress__FPCvUlPv = .text:0x80066FB0; // type:function size:0x64 matrixCreateFromPosRotYScale__FR6mMtx_cRC7mVec3_c4mAngRC7mVec3_cP6mMtx_cf = .text:0x80067020; // type:function size:0x138 -checkIfVec3fInMatrix__FRC6mMtx_cRC7mVec3_c = .text:0x80067160; // type:function size:0x88 -fn_800671F0 = .text:0x800671F0; // type:function size:0x84 +checkAreaBox__FRC6mMtx_cRC7mVec3_c = .text:0x80067160; // type:function size:0x88 +checkAreaCyl__FRC6mMtx_cRC7mVec3_c = .text:0x800671F0; // type:function size:0x84 __ct__7mVec2_cFv = .text:0x80067280; // type:function size:0x4 fn_80067290 = .text:0x80067290; // type:function size:0xA8 fn_80067340 = .text:0x80067340; // type:function size:0xC0 diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 4d3b9dc2..579e0558 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -372,7 +372,7 @@ public: /* vt 0x26C */ virtual bool doesGameOver() { return true; } - /* vt 0x270 */ virtual void triggerExitRelated() {} + /* vt 0x270 */ virtual void triggerExitRelated(UNKWORD sceneLink, UNKWORD pathIdx, UNKWORD sceneType) {} /* vt 0x274 */ virtual mAng vt_0x274() { return mRotation.y; } diff --git a/include/d/t/d_t_scene_change.h b/include/d/t/d_t_scene_change.h index 0b6c063b..017c8d58 100644 --- a/include/d/t/d_t_scene_change.h +++ b/include/d/t/d_t_scene_change.h @@ -2,13 +2,53 @@ #define D_T_SCENE_CHANGE_H #include "d/t/d_tg.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" class dTgSceneChange_c : public dTg_c { public: + // TODO: Move this somewhere not in d_t_scene_change. + // The Variable gets passed to dAcPy_c::triggerExitRelated + enum Type_e { + /* 0x0 */ TYPE_0, + /* 0x1 */ TYPE_1, // Restricting Movement? + /* 0x2 */ TYPE_2, + /* 0x3 */ TYPE_3, // Forced Walk + /* 0x4 */ TYPE_4, // Loftwing + /* 0x5 */ TYPE_5, // Landing on Skyloft + /* 0x6 */ TYPE_6, // Enter/Exit Dungeon + /* 0x7 */ TYPE_7, // Minecart + /* 0x8 */ TYPE_8, // Cistern Rope to Basement + /* 0x9 */ TYPE_9, // Light Pillar? + /* 0xA */ TYPE_A, // Boat + /* 0xB */ TYPE_B, // Actor Related + }; + dTgSceneChange_c() {} virtual ~dTgSceneChange_c() {} + virtual int create() override; + virtual int draw() override; + virtual int actorExecute() override; + private: + bool checkDisabled() const; + bool checkScrapper(); + + void savePlayerPosition(); + +private: + /* 0x0FC */ mMtx_c mArea; + /* 0x12C */ u8 mSceneLink; + /* 0x12D */ u8 mSceneType; + /* 0x12E */ u8 mPathId; + /* 0x12F */ u8 mEnableSceneflag; + /* 0x130 */ u16 mEnableStoryflag; + /* 0x132 */ u16 mDisableStoryflag; + /* 0x134 */ bool field_0x134; + /* 0x135 */ bool field_0x135; + /* 0x136 */ bool field_0x136; + /* 0x138 */ mVec3_c field_0x138; // Player position on Scrapper Stop }; #endif diff --git a/include/toBeSorted/area_math.h b/include/toBeSorted/area_math.h index b30a62fa..f4f52600 100644 --- a/include/toBeSorted/area_math.h +++ b/include/toBeSorted/area_math.h @@ -6,6 +6,7 @@ #include "m/m_vec.h" void matrixCreateFromPosRotYScale(mMtx_c &, const mVec3_c &, const mAng, const mVec3_c &, mMtx_c *, f32); -bool checkIfVec3fInMatrix(const mMtx_c &, const mVec3_c &); +bool checkAreaBox(const mMtx_c &, const mVec3_c &); +bool checkAreaCyl(const mMtx_c &, const mVec3_c &); #endif diff --git a/src/REL/d/t/d_t_action.cpp b/src/REL/d/t/d_t_action.cpp index 0bab0b68..a40bbacb 100644 --- a/src/REL/d/t/d_t_action.cpp +++ b/src/REL/d/t/d_t_action.cpp @@ -51,7 +51,7 @@ int dTgAction_c::actorExecute() { break; } if (pObj->mProfileName == fProfile::BOMB) { - if (checkIfVec3fInMatrix(mActiveMtx, pObj->getPosition())) { + if (checkAreaBox(mActiveMtx, pObj->getPosition())) { reinterpret_cast(pObj)->On_0xA3C(0x20000000); } } @@ -59,7 +59,7 @@ int dTgAction_c::actorExecute() { } // Check For Player Within Area - if (enabled && checkIfVec3fInMatrix(mActiveMtx, player->getPosition())) { + if (enabled && checkAreaBox(mActiveMtx, player->getPosition())) { if (mType == FORCE_FADE_RESTART) { player->onFlags_0x358(0x10000000); setActiveArea(50.f); diff --git a/src/REL/d/t/d_t_gate_to_ground.cpp b/src/REL/d/t/d_t_gate_to_ground.cpp index 2a4c62c6..3c00617a 100644 --- a/src/REL/d/t/d_t_gate_to_ground.cpp +++ b/src/REL/d/t/d_t_gate_to_ground.cpp @@ -47,7 +47,7 @@ int dTgGateToGround_c::actorExecute() { player = dAcPy_c::LINK; - if (checkIfVec3fInMatrix(matrix, player->mPosition)) { + if (checkAreaBox(matrix, player->mPosition)) { if (player->getRidingActorType() != dAcPy_c::RIDING_LOFTWING) { if (delayFrames > 15) { Event e("CloudHole", 100, 0, nullptr, nullptr); diff --git a/src/REL/d/t/d_t_heat_resist.cpp b/src/REL/d/t/d_t_heat_resist.cpp index 063452b1..045cce17 100644 --- a/src/REL/d/t/d_t_heat_resist.cpp +++ b/src/REL/d/t/d_t_heat_resist.cpp @@ -21,11 +21,11 @@ int dTgHeatResist_c::actorExecute() { dAcPy_c *player = dAcPy_c::LINK; if (mInverted == 1) { - if (!checkIfVec3fInMatrix(matrix, player->mPosition)) { + if (!checkAreaBox(matrix, player->mPosition)) { player->onForceOrPreventActionFlags(0x8000000); } } else { - if (checkIfVec3fInMatrix(matrix, player->mPosition)) { + if (checkAreaBox(matrix, player->mPosition)) { player->onForceOrPreventActionFlags(0x8000000); } } diff --git a/src/REL/d/t/d_t_scene_change.cpp b/src/REL/d/t/d_t_scene_change.cpp index babed843..0ae26989 100644 --- a/src/REL/d/t/d_t_scene_change.cpp +++ b/src/REL/d/t/d_t_scene_change.cpp @@ -1,3 +1,137 @@ #include "d/t/d_t_scene_change.h" +#include "c/c_lib.h" +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/npc/d_a_npc_salbage_robot.h" +#include "d/a/npc/d_a_npc_volcano_f2_salbo.h" +#include "d/flag/sceneflag_manager.h" +#include "d/flag/storyflag_manager.h" +#include "f/f_base.h" +#include "f/f_profile_name.h" +#include "m/m_angle.h" +#include "m/m_vec.h" +#include "toBeSorted/area_math.h" +#include "toBeSorted/d_path.h" +#include "toBeSorted/event_manager.h" + SPECIAL_ACTOR_PROFILE(SC_CHANGE_TAG, dTgSceneChange_c, fProfile::SC_CHANGE_TAG, 0x21, 0, 4); + +int dTgSceneChange_c::create() { + mSceneLink = getFromParams(0, 0xFF); + mPathId = getFromParams(8, 0xFF); + + mSceneType = getFromParams(16, 0xFF); + if (mSceneType == 0xFF) { + mSceneType = 0 /* TODO: Change with enum when used. See note in this files header */; + } + + mEnableSceneflag = getFromParams(24, 0xFF); + mEnableStoryflag = (mRotation.x >> 0) & 0x7FF; + + field_0x134 = ((mRotation.x >> 11) & 0x3) == 1; + mRotation.x = 0; + + mDisableStoryflag = mRotation.z & 0x7FF; + field_0x136 = ((mRotation.z >> 12) & 0xF) != 0; + + mRotation.z = 0; + + matrixCreateFromPosRotYScale(mArea, mPosition, mRotation.y, mScale, nullptr, 0.f); + + return SUCCEEDED; +} + +bool dTgSceneChange_c::checkDisabled() const { + bool disabled = false; + + bool validFlag = mDisableStoryflag != 0 && mDisableStoryflag < 0x7FF; + if (validFlag && StoryflagManager::sInstance->getFlag(mDisableStoryflag)) { + disabled = true; + } + return disabled; +} + +int dTgSceneChange_c::actorExecute() { + if (checkDisabled()) { + return SUCCEEDED; + } + + if (mEnableStoryflag == 0 || mEnableStoryflag >= 0x7FF || !StoryflagManager::sInstance->getFlag(mEnableStoryflag)) { + return SUCCEEDED; + } + + if (mEnableSceneflag < 0xFF && !SceneflagManager::sInstance->checkBoolFlag(mRoomID, mEnableSceneflag)) { + return SUCCEEDED; + } + + dAcPy_c *pPlayer = dAcPy_c::GetLinkM(); + if ((field_0x134 && checkAreaCyl(mArea, pPlayer->mPosition)) || + (!field_0x134 && checkAreaBox(mArea, pPlayer->mPosition))) { + if (!(field_0x136 && checkScrapper())) { + pPlayer->triggerExitRelated(mSceneLink, mPathId, mSceneType); + } + } else { + if (field_0x136) { + savePlayerPosition(); + } + } + + return SUCCEEDED; +} + +extern "C" dAcOrdinaryNpc_c *SCRAPPER_PTR; + +bool dTgSceneChange_c::checkScrapper() { + if (SCRAPPER_PTR == nullptr) { + return false; + } + + if (SCRAPPER_PTR->mProfileName != fProfile::NPC_SLB2) { + return false; + } + + if (!static_cast(SCRAPPER_PTR)->fn_61_6A10()) { + return false; + } + + dPath_c path; + if (path.initWithPathIndex(mPathId, mRoomID, 0) && path.getNumPoints() > 1) { + if (EventManager::isInEvent(SCRAPPER_PTR, "HailToPlayerToStop")) { + mVec3_c p0, p1; + p0.copyFrom(path.getPoint(0)); + p1.copyFrom(path.getPoint(1)); + mAng a = cLib::targetAngleY(p0, p1); + + + + + } + } + + return false; + + +} + +void dTgSceneChange_c::savePlayerPosition() { + if (SCRAPPER_PTR == nullptr) { + return; + } + + if (SCRAPPER_PTR->mProfileName != fProfile::NPC_SLB2) { + return; + } + + const dAcPy_c *pPlayer = dAcPy_c::GetLink(); + if (pPlayer->checkActionFlags(0x800000 | 0x400000 | 0x40000 | 0x20000 | 0x10000 | 0x800 | 0x40 | 0x10 | 0x2) && + !pPlayer->checkActionFlags(0x40000)) { + return; + } + + field_0x138 = pPlayer->mPosition; +} + +int dTgSceneChange_c::draw() { + return SUCCEEDED; +} diff --git a/src/REL/d/t/d_t_sw_area.cpp b/src/REL/d/t/d_t_sw_area.cpp index 3ccb0520..cc9cbee1 100644 --- a/src/REL/d/t/d_t_sw_area.cpp +++ b/src/REL/d/t/d_t_sw_area.cpp @@ -32,7 +32,7 @@ bool isValidStoryFlag(u16 storyflag) { } int dTgSwArea_c::actorExecute() { - if (checkIfVec3fInMatrix(area, dAcPy_c::LINK->mPosition)) { + if (checkAreaBox(area, dAcPy_c::LINK->mPosition)) { SceneflagManager::sInstance->setFlag(mRoomID, setSceneflag); SceneflagManager::sInstance->unsetFlag(mRoomID, unsetSceneflag); diff --git a/src/REL/d/t/d_t_time_door_beam.cpp b/src/REL/d/t/d_t_time_door_beam.cpp index 556d1f77..bc9b2aa6 100644 --- a/src/REL/d/t/d_t_time_door_beam.cpp +++ b/src/REL/d/t/d_t_time_door_beam.cpp @@ -27,5 +27,5 @@ bool dTgTimeDoorBeam_c::checkPlayerPosInMtx() { return false; } - return checkIfVec3fInMatrix(matrix, dAcPy_c::LINK->mPosition); + return checkAreaBox(matrix, dAcPy_c::LINK->mPosition); } diff --git a/src/REL/d/t/d_t_touch.cpp b/src/REL/d/t/d_t_touch.cpp index de9b6999..99b46ad2 100644 --- a/src/REL/d/t/d_t_touch.cpp +++ b/src/REL/d/t/d_t_touch.cpp @@ -48,7 +48,7 @@ void dTgTouchTag::executeState_Wait() { dAcBase_c *actor = static_cast(fManager_c::searchBaseByProfName(ACTIVATORS[mActivatorIndex], nullptr)); while (actor != nullptr) { - if (actor->mRoomID == mRoomID && checkIfVec3fInMatrix(mAreaOfEffect, actor->mPosition)) { + if (actor->mRoomID == mRoomID && checkAreaBox(mAreaOfEffect, actor->mPosition)) { mFlagTimer = 5; if (mZoneFlag != 0xFF) { SceneflagManager::sInstance->setFlag(mRoomID, mZoneFlag);