From 3cfb91855969f40c19bb996e3eb3eb4fc8eae9b3 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 25 May 2024 19:16:20 -0400 Subject: [PATCH] Implement/match LegoExtraActor::VTable0x6c (#956) --- .../lego/legoomni/include/legoanimpresenter.h | 30 +++--- LEGO1/lego/legoomni/include/legopathactor.h | 1 + .../legoomni/src/paths/legoextraactor.cpp | 99 ++++++++++++++++++- .../lego/legoomni/src/paths/legopathactor.cpp | 4 +- .../legoomni/src/video/legoanimpresenter.cpp | 9 +- 5 files changed, 116 insertions(+), 27 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 09fd00a8..f4745c18 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -54,21 +54,21 @@ class LegoAnimPresenter : public MxVideoPresenter { return !strcmp(p_name, LegoAnimPresenter::ClassName()) || MxVideoPresenter::IsA(p_name); } - void ReadyTickle() override; // vtable+0x18 - void StartingTickle() override; // vtable+0x1c - void StreamingTickle() override; // vtable+0x20 - void DoneTickle() override; // vtable+0x2c - void ParseExtra() override; // vtable+0x30 - MxResult AddToManager() override; // vtable+0x34 - void Destroy() override; // vtable+0x38 - MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c - void EndAction() override; // vtable+0x40 - void PutFrame() override; // vtable+0x6c - virtual MxResult CreateAnim(MxStreamChunk* p_chunk); // vtable+0x88 - virtual void VTable0x8c(); // vtable+0x8c - virtual void VTable0x90(); // vtable+0x90 - virtual MxU32 VTable0x94(Vector3& p_vec1, Vector3& p_vec2, float p_f1, float p_f2, Vector3& p_vec3); // vtable+0x94 - virtual MxResult VTable0x98(LegoPathBoundary* p_boundary); // vtable+0x98 + void ReadyTickle() override; // vtable+0x18 + void StartingTickle() override; // vtable+0x1c + void StreamingTickle() override; // vtable+0x20 + void DoneTickle() override; // vtable+0x2c + void ParseExtra() override; // vtable+0x30 + MxResult AddToManager() override; // vtable+0x34 + void Destroy() override; // vtable+0x38 + MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c + void EndAction() override; // vtable+0x40 + void PutFrame() override; // vtable+0x6c + virtual MxResult CreateAnim(MxStreamChunk* p_chunk); // vtable+0x88 + virtual void VTable0x8c(); // vtable+0x8c + virtual void VTable0x90(); // vtable+0x90 + virtual MxU32 VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3); // vtable+0x94 + virtual MxResult VTable0x98(LegoPathBoundary* p_boundary); // vtable+0x98 // FUNCTION: LEGO1 0x1000c990 virtual LegoROI** GetROIMap(MxU32& p_roiMapSize) diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 10f79b50..71e9f68e 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -126,6 +126,7 @@ class LegoPathActor : public LegoActor { inline LegoPathBoundary* GetBoundary() { return m_boundary; } inline MxU32 GetState() { return m_state; } inline LegoPathController* GetController() { return m_controller; } + inline MxBool GetCollideBox() { return m_collideBox; } inline void SetBoundary(LegoPathBoundary* p_boundary) { m_boundary = p_boundary; } inline void SetState(MxU32 p_state) { m_state = p_state; } diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index 9b3a6304..e1eeedbe 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -287,9 +287,9 @@ MxResult LegoExtraActor::VTable0x9c() if (m_boundary != oldBoundary) { MxU32 b = FALSE; - LegoAnimPresenterSet& set = m_boundary->GetPresenters(); + LegoAnimPresenterSet& presenters = m_boundary->GetPresenters(); - for (LegoAnimPresenterSet::iterator it = set.begin(); it != set.end(); it++) { + for (LegoAnimPresenterSet::iterator it = presenters.begin(); it != presenters.end(); it++) { MxU32 roiMapSize; if ((*it)->GetROIMap(roiMapSize)) { b = TRUE; @@ -312,9 +312,9 @@ void LegoExtraActor::Restart() { if (m_unk0x0e != 0) { MxU32 b = FALSE; - LegoAnimPresenterSet& set = m_boundary->GetPresenters(); + LegoAnimPresenterSet& presenters = m_boundary->GetPresenters(); - for (LegoAnimPresenterSet::iterator it = set.begin(); it != set.end(); it++) { + for (LegoAnimPresenterSet::iterator it = presenters.begin(); it != presenters.end(); it++) { MxU32 roiMapSize; if ((*it)->GetROIMap(roiMapSize)) { b = TRUE; @@ -429,7 +429,7 @@ MxS32 LegoExtraActor::VTable0x68(Vector3& p_point1, Vector3& p_point2, Vector3& return LegoPathActor::VTable0x68(p_point1, p_point2, p_point3); } -// STUB: LEGO1 0x1002b980 +// FUNCTION: LEGO1 0x1002b980 MxU32 LegoExtraActor::VTable0x6c( LegoPathBoundary* p_boundary, Vector3& p_v1, @@ -439,5 +439,94 @@ MxU32 LegoExtraActor::VTable0x6c( Vector3& p_v3 ) { + LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); + + for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { + if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { + return 1; + } + } + + LegoPathActorSet& plpas = p_boundary->GetActors(); + LegoPathActorSet lpas(plpas); + + for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) { + if (plpas.find(*itpa) != plpas.end()) { + LegoPathActor* actor = *itpa; + + if (this != actor && !(actor->GetState() & 0x100)) { + LegoROI* roi = actor->GetROI(); + + if ((roi != NULL && roi->GetVisibility()) || actor->GetCameraFlag()) { + if (actor->GetUserNavFlag()) { + MxMatrix local2world = roi->GetLocal2World(); + Vector3 local60(local2world[3]); + Mx3DPointFloat local54(p_v1); + + ((Vector3&) local54).Sub(&local60); + float local1c = p_v2.Dot(&p_v2, &p_v2); + float local24 = p_v2.Dot(&p_v2, &local54) * 2.0f; + float local20 = local54.Dot(&local54, &local54); + + if (m_unk0x15 != 0 && local20 < 10.0f) { + return 0; + } + + local20 -= 1.0f; + + if (local1c >= 0.001 || local1c <= -0.001) { + float local40 = (local24 * local24) + (local20 * local1c * -4.0f); + + if (local40 >= -0.001) { + local1c *= 2.0f; + local24 = -local24; + + if (local40 < 0.0f) { + local40 = 0.0f; + } + + local40 = sqrt(local40); + float local20X = (local24 + local40) / local1c; + float local1cX = (local24 - local40) / local1c; + + if (local1cX < local20X) { + local40 = local20X; + local20X = local1cX; + local1cX = local40; + } + + if ((local20X >= 0.0f && local20X <= p_f1) || (local1cX >= 0.0f && local1cX <= p_f1) || + (local20X <= -0.01 && p_f1 + 0.01 <= local1cX)) { + p_v3 = p_v1; + + if (VTable0x94(actor, TRUE) < 0) { + return 0; + } + + actor->VTable0x94(this, FALSE); + return 2; + } + } + } + } + else { + if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { + if (VTable0x94(actor, TRUE) < 0) { + return 0; + } + + actor->VTable0x94(this, FALSE); + return 2; + } + } + } + } + } + } + + if (m_unk0x15 != 0) { + m_unk0x15--; + } + return 0; } diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 661c3e95..17d89e68 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -437,9 +437,9 @@ MxU32 LegoPathActor::VTable0x6c( Vector3& p_v3 ) { - LegoAnimPresenterSet& laps = p_boundary->GetPresenters(); + LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); - for (LegoAnimPresenterSet::iterator itap = laps.begin(); itap != laps.end(); itap++) { + for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { return 1; } diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index b463240c..503c6282 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -1113,13 +1113,13 @@ void LegoAnimPresenter::FUN_1006c8a0(MxBool p_bool) // FUNCTION: LEGO1 0x1006c8f0 // FUNCTION: BETA10 0x1005206c -MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_vec1, Vector3& p_vec2, float p_f1, float p_f2, Vector3& p_vec3) +MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3) { Mx3DPointFloat a, b; - b = p_vec2; + b = p_v2; ((Vector3&) b).Mul(p_f1); - ((Vector3&) b).Add(&p_vec1); + ((Vector3&) b).Add(&p_v1); a = b; ((Vector3&) a).Sub(&m_unk0xa8); @@ -1132,8 +1132,7 @@ MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_vec1, Vector3& p_vec2, float p_f1 len = sqrt(len); if (len <= m_unk0xa4 + p_f2 && m_roiMapSize != 0 && m_roiMap != NULL) { for (MxU32 i = 1; i <= m_roiMapSize; i++) { - if (m_roiMap[i]->GetLODCount() != 0 && - m_roiMap[i]->FUN_100a9410(p_vec1, p_vec2, p_f1, p_f2, p_vec3, FALSE)) { + if (m_roiMap[i]->GetLODCount() != 0 && m_roiMap[i]->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, FALSE)) { return TRUE; } }