From 001b46b2aba636d0c00bb432151b8cdf68f8ac1c Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 9 May 2024 12:49:43 -0400 Subject: [PATCH] Implement/match LegoAnimationManager::FUN_10062110 (#892) * Implement/match LegoAnimationManager::FUN_10062110 * Fix param name * Return other value in stub --- LEGO1/lego/legoomni/include/animstate.h | 4 +- .../legoomni/include/legoanimationmanager.h | 2 +- .../src/common/legoanimationmanager.cpp | 87 ++++++++++++++++--- LEGO1/viewmanager/viewmanager.cpp | 7 ++ LEGO1/viewmanager/viewmanager.h | 1 + 5 files changed, 87 insertions(+), 14 deletions(-) diff --git a/LEGO1/lego/legoomni/include/animstate.h b/LEGO1/lego/legoomni/include/animstate.h index 9d15fd50..1cdf489c 100644 --- a/LEGO1/lego/legoomni/include/animstate.h +++ b/LEGO1/lego/legoomni/include/animstate.h @@ -24,9 +24,9 @@ struct AnimInfo { MxU8 m_unk0x0d; // 0x0d MxU32 m_unk0x10[4]; // 0x10 MxU8 m_modelCount; // 0x20 - MxS16 m_unk0x22; // 0x22 + MxU16 m_unk0x22; // 0x22 ModelInfo* m_models; // 0x24 - MxU8 m_unk0x28; // 0x28 + MxS8 m_unk0x28; // 0x28 MxBool m_unk0x29; // 0x29 MxS8 m_unk0x2a[3]; // 0x2a }; diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index bc3200f3..9d2122ab 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -133,7 +133,7 @@ class LegoAnimationManager : public MxCore { Vector3& p_position, LegoPathBoundary* p_boundary, float p_speed, - MxU8 p_und, + MxU8 p_unk0x0c, MxBool p_unk0x14 ); MxS8 GetCharacterIndex(const char* p_name); diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index ae486e93..64004ef8 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -21,6 +21,7 @@ #include "mxticklemanager.h" #include "mxtimer.h" #include "mxutilities.h" +#include "viewmanager/viewmanager.h" #include @@ -96,10 +97,14 @@ Character g_characters[47] = { }; // GLOBAL: LEGO1 0x100f74b0 -float g_unk0x100f74b0 = 10.0f; - -// GLOBAL: LEGO1 0x100f74ec -float g_unk0x100f74ec = -1.0f; +float g_unk0x100f74b0[6][3] = { + {10.0f, -1.0f, 1.0f}, + {7.0f, 144.0f, 100.0f}, + {5.0f, 100.0f, 36.0f}, + {3.0f, 36.0f, 25.0f}, + {1.0f, 25.0f, 16.0f}, + {-1.0f, 16.0f, 2.0f} +}; // GLOBAL: LEGO1 0x100f74f8 MxS32 g_legoAnimationManagerConfig = 1; @@ -1219,24 +1224,24 @@ MxResult LegoAnimationManager::Tickle() FUN_10064b50(time); - if (!m_unk0x39 && time - m_unk0x404 > 10000 && speed < g_unk0x100f74b0 && speed > g_unk0x100f74ec) { + if (!m_unk0x39 && time - m_unk0x404 > 10000 && speed < g_unk0x100f74b0[0][0] && speed > g_unk0x100f74b0[5][0]) { LegoPathBoundary* boundary = actor->GetBoundary(); Mx3DPointFloat position(roi->GetWorldPosition()); Mx3DPointFloat direction(roi->GetWorldDirection()); - MxU8 und = 0; + MxU8 unk0x0c = 0; MxU8 actorId = GameState()->GetActorId(); if (actorId <= 5) { - und = g_unk0x100d8b28[actorId]; + unk0x0c = g_unk0x100d8b28[actorId]; } for (MxS32 i = 0; i < (MxS32) _countof(m_unk0x3c); i++) { LegoROI* roi = m_unk0x3c[i].m_roi; if (roi != NULL) { - MxU16 result = FUN_10062110(roi, direction, position, boundary, speed, und, m_unk0x3c[i].m_unk0x14); + MxU16 result = FUN_10062110(roi, direction, position, boundary, speed, unk0x0c, m_unk0x3c[i].m_unk0x14); if (result) { MxMatrix mat; @@ -1283,7 +1288,7 @@ MxResult LegoAnimationManager::Tickle() return SUCCESS; } -// STUB: LEGO1 0x10062110 +// FUNCTION: LEGO1 0x10062110 // FUNCTION: BETA10 0x10042f41 MxU16 LegoAnimationManager::FUN_10062110( LegoROI* p_roi, @@ -1291,11 +1296,71 @@ MxU16 LegoAnimationManager::FUN_10062110( Vector3& p_position, LegoPathBoundary* p_boundary, float p_speed, - MxU8 p_und, + MxU8 p_unk0x0c, MxBool p_unk0x14 ) { - // TODO + LegoPathActor* actor = (LegoPathActor*) p_roi->GetEntity(); + + if (actor != NULL && actor->GetBoundary() == p_boundary && actor->GetState() == 0) { + if (GetViewManager()->FUN_100a6150(p_roi->GetWorldBoundingBox())) { + Mx3DPointFloat direction(p_roi->GetWorldDirection()); + + if (direction.Dot(&direction, &p_direction) > 0.707) { + Mx3DPointFloat position(p_roi->GetWorldPosition()); + + ((Vector3&) position).Sub(&p_position); + float len = position.LenSquared(); + float min, max; + + for (MxU32 i = 0; i < _countof(g_unk0x100f74b0); i++) { + if (g_unk0x100f74b0[i][0] < p_speed) { + max = g_unk0x100f74b0[i][1]; + min = g_unk0x100f74b0[i][2]; + break; + } + } + + if (len < max && len > min) { + MxS8 index = GetCharacterIndex(p_roi->GetName()); + + for (MxU16 i = m_unk0x0e; i <= m_unk0x10; i++) { + if (m_anims[i].m_unk0x28 == index && m_anims[i].m_unk0x0c & p_unk0x0c && m_anims[i].m_unk0x29) { + MxS32 vehicleId = g_characters[index].m_vehicleId; + if (vehicleId >= 0) { + MxBool found = FALSE; + + for (MxS32 j = 0; j < (MxS32) _countof(m_anims[i].m_unk0x2a); j++) { + if (m_anims[i].m_unk0x2a[j] == vehicleId) { + found = TRUE; + break; + } + } + + if (p_unk0x14 != found) { + continue; + } + } + + MxU16 result = i; + MxU16 unk0x22 = m_anims[i].m_unk0x22; + + for (i = i + 1; i <= m_unk0x10; i++) { + if (m_anims[i].m_unk0x28 == index && m_anims[i].m_unk0x0c & p_unk0x0c && + m_anims[i].m_unk0x29 && m_anims[i].m_unk0x22 < unk0x22) { + result = i; + unk0x22 = m_anims[i].m_unk0x22; + } + } + + return result; + } + } + } + } + } + } + return 0; } diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp index 395e4397..9db4ba6f 100644 --- a/LEGO1/viewmanager/viewmanager.cpp +++ b/LEGO1/viewmanager/viewmanager.cpp @@ -55,6 +55,13 @@ ViewManager::~ViewManager() SetPOVSource(NULL); } +// STUB: LEGO1 0x100a6150 +// FUNCTION: BETA10 0x10172164 +undefined4 ViewManager::FUN_100a6150(const BoundingBox& p_bounding_box) +{ + return 1; +} + // FUNCTION: LEGO1 0x100a6410 void ViewManager::Remove(ViewROI* p_roi) { diff --git a/LEGO1/viewmanager/viewmanager.h b/LEGO1/viewmanager/viewmanager.h index 8a7e50d0..f2fdcdb4 100644 --- a/LEGO1/viewmanager/viewmanager.h +++ b/LEGO1/viewmanager/viewmanager.h @@ -23,6 +23,7 @@ class ViewManager { void Remove(ViewROI* p_roi); void RemoveAll(ViewROI* p_roi); + undefined4 FUN_100a6150(const BoundingBox& p_bounding_box); void FUN_100a65b0(ViewROI* p_roi, int p_und); void FUN_100a66a0(ViewROI* p_roi); void SetPOVSource(const OrientableROI* point_of_view);