From 66e3c9a2e1e87264cb65c4247fc253c035a5ef5b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 17 Dec 2024 11:11:47 -0700 Subject: [PATCH] Implement/match `Act3Brickster::Animate` (#1237) * Implement/match `Act3Brickster::Animate` * Improve loop --- LEGO1/lego/legoomni/include/act3.h | 1 + LEGO1/lego/legoomni/include/act3actors.h | 12 +- LEGO1/lego/legoomni/src/actors/act3actors.cpp | 186 +++++++++++++++++- LEGO1/lego/legoomni/src/worlds/act3.cpp | 7 + 4 files changed, 196 insertions(+), 10 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act3.h b/LEGO1/lego/legoomni/include/act3.h index da9910d2..8f29f41a 100644 --- a/LEGO1/lego/legoomni/include/act3.h +++ b/LEGO1/lego/legoomni/include/act3.h @@ -130,6 +130,7 @@ class Act3 : public LegoWorld { void FUN_10073400(); void FUN_10073430(); void GoodEnding(const Matrix4& p_destination); + void FUN_10073a60(); // BETA indicates that the following classes access certain members directly. friend class Act3Ammo; diff --git a/LEGO1/lego/legoomni/include/act3actors.h b/LEGO1/lego/legoomni/include/act3actors.h index 6b80a8f8..2970e45c 100644 --- a/LEGO1/lego/legoomni/include/act3actors.h +++ b/LEGO1/lego/legoomni/include/act3actors.h @@ -6,6 +6,8 @@ // File name verified by multiple assertions, e.g. BETA10 0x10018391 class Act3Ammo; +struct LegoBuildingInfo; +struct LegoPlantInfo; class LegoWorld; // VTABLE: LEGO1 0x100d7668 LegoPathActor @@ -118,17 +120,19 @@ class Act3Brickster : public Act3Actor { // Act3Brickster::`scalar deleting destructor' private: + MxS32 FUN_10042300(); + MxFloat m_unk0x20; // 0x20 MxFloat m_unk0x24; // 0x24 LegoWorld* m_world; // 0x28 - undefined4 m_unk0x2c; // 0x2c - undefined4 m_unk0x30; // 0x30 + LegoPlantInfo* m_pInfo; // 0x2c + LegoBuildingInfo* m_bInfo; // 0x30 LegoAnimActorStruct* m_shootAnim; // 0x34 undefined4 m_unk0x38; // 0x38 Mx3DPointFloat m_unk0x3c; // 0x3c MxFloat m_unk0x50; // 0x50 - undefined4 m_unk0x54; // 0x54 - undefined m_unk0x58; // 0x58 + MxFloat m_unk0x54; // 0x54 + MxU8 m_unk0x58; // 0x58 }; // VTABLE: LEGO1 0x100d7920 LegoPathActor diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 83fe23ab..306a6e3b 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -4,9 +4,12 @@ #include "act3ammo.h" #include "anim/legoanim.h" #include "define.h" +#include "legobuildingmanager.h" #include "legocachesoundmanager.h" #include "legolocomotionanimpresenter.h" #include "legopathedgecontainer.h" +#include "legoplantmanager.h" +#include "legoplants.h" #include "legosoundmanager.h" #include "misc.h" #include "mxdebug.h" @@ -345,13 +348,13 @@ MxResult Act3Cop::VTable0x9c() Act3Brickster::Act3Brickster() { m_world = NULL; - m_unk0x2c = 0; - m_unk0x30 = 0; + m_pInfo = NULL; + m_bInfo = NULL; m_shootAnim = NULL; m_unk0x38 = 0; m_unk0x20 = 0.0f; m_unk0x24 = 0.0f; - m_unk0x54 = 0; + m_unk0x54 = 0.0f; SetActorState(c_disabled); m_unk0x58 = 0; @@ -385,11 +388,174 @@ void Act3Brickster::ParseAction(char* p_extra) assert(m_shootAnim); } -// STUB: LEGO1 0x10041050 -// STUB: BETA10 0x100197d7 +// FUNCTION: LEGO1 0x10041050 +// FUNCTION: BETA10 0x100197d7 void Act3Brickster::Animate(float p_time) { - // TODO + if (m_lastTime <= m_unk0x20 && m_unk0x20 <= p_time) { + SetWorldSpeed(5.0f); + } + + if (m_unk0x38 != 3 && m_unk0x38 != 4) { + Act3Actor::Animate(p_time); + } + + if (m_unk0x54 < p_time) { + ((Act3*) m_world)->FUN_10072ad0(5); + m_unk0x54 = p_time + 15000.0f; + } + + switch (m_unk0x38) { + case 1: + FUN_100417c0(); + break; + case 2: + m_unk0x58++; + m_unk0x20 = p_time + 2000.0f; + SetWorldSpeed(3.0f); + + assert(SoundManager()->GetCacheSoundManager()); + + if (m_unk0x58 >= 8) { + ((Act3*) m_world)->FUN_10072ad0(6); + } + else { + SoundManager()->GetCacheSoundManager()->Play("eatpz", NULL, FALSE); + } + + FUN_100417c0(); + break; + case 3: + assert(m_shootAnim && m_pInfo); + + if (m_unk0x50 < p_time) { + while (m_pInfo->m_unk0x16) { + PlantManager()->FUN_10026c50(m_pInfo->m_entity); + } + + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("thpt", NULL, FALSE); + m_unk0x58 = 0; + FUN_100417c0(); + } + else { + MxMatrix local70; + local70 = m_unk0xec; + + Vector3 local14(local70[0]); + Vector3 local28(local70[1]); + Vector3 localc(local70[2]); + Vector3 local20(local70[3]); + + localc = local20; + localc -= m_pInfo->m_position; + localc.Unitize(); + local14.EqualsCross(&local28, &localc); + local14.Unitize(); + local28.EqualsCross(&localc, &local14); + + assert(!m_cameraFlag); + + LegoTreeNode* root = m_shootAnim->GetAnimTreePtr()->GetRoot(); + float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration()); + + for (MxS32 i = 0; i < root->GetNumChildren(); i++) { + LegoROI::FUN_100a8e80(root->GetChild(i), local70, time, m_shootAnim->GetROIMap()); + } + } + + m_lastTime = p_time; + break; + case 4: + assert(m_shootAnim && m_bInfo); + + if (m_unk0x50 < p_time) { + ((Act3*) m_world)->FUN_10073a60(); + m_unk0x58 = 0; + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("thpt", NULL, FALSE); + + while (m_bInfo->m_unk0x11 > 0 || m_bInfo->m_unk0x11 == -1) { + if (!BuildingManager()->FUN_10030110(m_bInfo)) { + break; + } + } + + FUN_100417c0(); + } + else { + MxMatrix locale4; + locale4 = m_unk0xec; + + Vector3 local88(locale4[0]); + Vector3 local9c(locale4[1]); + Vector3 local80(locale4[2]); + Vector3 local94(locale4[3]); + + local80 = local94; + assert(m_bInfo->m_entity && m_bInfo->m_entity->GetROI()); + + local80 -= m_unk0x3c; + local80.Unitize(); + local88.EqualsCross(&local9c, &local80); + local88.Unitize(); + local9c.EqualsCross(&local80, &local88); + + assert(!m_cameraFlag); + + LegoTreeNode* root = m_shootAnim->GetAnimTreePtr()->GetRoot(); + float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration()); + + for (MxS32 i = 0; i < root->GetNumChildren(); i++) { + LegoROI::FUN_100a8e80(root->GetChild(i), locale4, time, m_shootAnim->GetROIMap()); + } + } + + m_lastTime = p_time; + break; + case 5: + if (m_grec == NULL) { + assert(m_shootAnim && m_pInfo); + m_unk0x38 = 3; + m_unk0x50 = p_time + m_shootAnim->GetDuration(); + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("xarrow", NULL, FALSE); + } + else { + FUN_10042300(); + } + break; + case 6: + if (m_grec == NULL) { + assert(m_shootAnim && m_bInfo); + m_unk0x38 = 4; + m_unk0x50 = p_time + m_shootAnim->GetDuration(); + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("xarrow", NULL, FALSE); + BuildingManager()->ScheduleAnimation(m_bInfo->m_entity, 0, FALSE, TRUE); + m_unk0x3c = m_bInfo->m_entity->GetROI()->GetLocal2World()[3]; + } + else { + FUN_10042300(); + } + break; + case 7: + default: + FUN_10042300(); + break; + case 8: + m_unk0x24 = p_time + 10000.0f; + m_unk0x38 = 9; + break; + case 9: + if (m_unk0x24 < p_time) { + FUN_100417c0(); + } + else if (m_unk0x24 - 9000.0f < p_time) { + FUN_10042300(); + } + break; + } } // FUNCTION: LEGO1 0x100416b0 @@ -447,6 +613,14 @@ MxResult Act3Brickster::FUN_100417c0() return SUCCESS; } +// STUB: LEGO1 0x10042300 +// STUB: BETA10 0x1001b017 +MxS32 Act3Brickster::FUN_10042300() +{ + // TODO + return -1; +} + // FUNCTION: LEGO1 0x10042990 // FUNCTION: BETA10 0x1001b6e2 void Act3Brickster::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index 170343fd..f4b812da 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -844,6 +844,13 @@ void Act3::DebugCopter( } } +// FUNCTION: LEGO1 0x10073a60 +void Act3::FUN_10073a60() +{ + m_unk0x421e--; + m_helicopterDots[m_unk0x421e]->Enable(FALSE); +} + // FUNCTION: LEGO1 0x10073a90 void Act3::Enable(MxBool p_enable) {