From 53924c3d2d6382725b71b3b461abf3ce7f0f6679 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 9 Aug 2024 11:32:46 -0700 Subject: [PATCH] Implement/match TowTrack::HandleEndAction (#1082) * Implement/match TowTrack::HandleEndAction * Fix offset --- LEGO1/lego/legoomni/include/towtrack.h | 82 +++++--- LEGO1/lego/legoomni/src/actors/towtrack.cpp | 202 ++++++++++++++++---- 2 files changed, 229 insertions(+), 55 deletions(-) diff --git a/LEGO1/lego/legoomni/include/towtrack.h b/LEGO1/lego/legoomni/include/towtrack.h index 3783b611..74f710be 100644 --- a/LEGO1/lego/legoomni/include/towtrack.h +++ b/LEGO1/lego/legoomni/include/towtrack.h @@ -28,40 +28,77 @@ public: MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c - MxS16 GetHighScore(MxU8 p_id) + MxS16 GetHighScore(MxU8 p_actorId) { - switch (p_id) { - case 1: - return m_score1; - case 2: - return m_score2; - case 3: - return m_score3; - case 4: - return m_score4; - case 5: - return m_score5; + switch (p_actorId) { + case LegoActor::c_pepper: + return m_peHighScore; + case LegoActor::c_mama: + return m_maHighScore; + case LegoActor::c_papa: + return m_paHighScore; + case LegoActor::c_nick: + return m_niHighScore; + case LegoActor::c_laura: + return m_laHighScore; default: return 0; } } + // FUNCTION: BETA10 0x100f8530 + void UpdateScore(ScoreColor p_score, MxS16 p_actorId) + { + switch (p_actorId) { + case LegoActor::c_pepper: + m_peScore = p_score; + if (m_peHighScore < p_score) { + m_peHighScore = p_score; + } + break; + case LegoActor::c_mama: + m_maScore = p_score; + if (m_maHighScore < p_score) { + m_maHighScore = p_score; + } + break; + case LegoActor::c_papa: + m_paScore = p_score; + if (m_paHighScore < p_score) { + m_paHighScore = p_score; + } + break; + case LegoActor::c_nick: + m_niScore = p_score; + if (m_niHighScore < p_score) { + m_niHighScore = p_score; + } + break; + case LegoActor::c_laura: + m_laScore = p_score; + if (m_laHighScore < p_score) { + m_laHighScore = p_score; + } + break; + } + } + // SYNTHETIC: LEGO1 0x1004e060 // TowTrackMissionState::`scalar deleting destructor' undefined4 m_unk0x08; // 0x08 MxLong m_startTime; // 0x0c MxBool m_unk0x10; // 0x10 - MxS16 m_unk0x12; // 0x12 - MxS16 m_unk0x14; // 0x14 - MxS16 m_unk0x16; // 0x16 - MxS16 m_unk0x18; // 0x18 - MxS16 m_unk0x1a; // 0x1a - MxS16 m_score1; // 0x1c - MxS16 m_score2; // 0x1e - MxS16 m_score3; // 0x20 - MxS16 m_score4; // 0x22 - MxS16 m_score5; // 0x24 + MxS16 m_peScore; // 0x12 + MxS16 m_maScore; // 0x14 + MxS16 m_paScore; // 0x16 + MxS16 m_niScore; // 0x18 + MxS16 m_laScore; // 0x1a + MxS16 m_peHighScore; // 0x1c + MxS16 m_maHighScore; // 0x1e + MxS16 m_paHighScore; // 0x20 + MxS16 m_niHighScore; // 0x22 + MxS16 m_laHighScore; // 0x24 }; // VTABLE: LEGO1 0x100d7ee0 @@ -106,6 +143,7 @@ public: private: void Leave(); void PlayFinalAnimation(IsleScript::Script p_objectId); + void FUN_1004dcb0(IsleScript::Script p_objectId); void PlayAction(IsleScript::Script p_objectId); undefined4 m_unk0x160; // 0x160 diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index d2b5158e..65ab9105 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -12,6 +12,7 @@ #include "legovariables.h" #include "legoworld.h" #include "misc.h" +#include "mxactionnotificationparam.h" #include "mxbackgroundaudiomanager.h" #include "mxmisc.h" #include "mxsoundpresenter.h" @@ -146,11 +147,137 @@ MxLong TowTrack::HandleEndAnim(LegoEndAnimNotificationParam& p_param) return 1; } -// STUB: LEGO1 0x1004cd40 +// FUNCTION: LEGO1 0x1004cd40 +// FUNCTION: BETA10 0x100f6f1f MxLong TowTrack::HandleEndAction(MxEndActionNotificationParam& p_param) { - // TODO - return 0; + if (p_param.GetAction() != NULL) { + IsleScript::Script objectId = (IsleScript::Script) p_param.GetAction()->GetObjectId(); + + if (m_lastAnimation == objectId) { + m_lastAnimation = IsleScript::c_noneIsle; + } + + if (m_lastAction == objectId) { + if (m_lastAnimation == IsleScript::c_noneIsle) { + BackgroundAudioManager()->RaiseVolume(); + } + + m_lastAction = IsleScript::c_noneIsle; + } + else if (objectId == IsleScript::c_wrt060bm_RunAnim) { + if (m_actorId < LegoActor::c_pepper || m_actorId > LegoActor::c_laura) { + m_actorId = LegoActor::c_laura; + } + + switch ((rand() % ((m_actorId != 4 ? 4 : 3))) + 1) { + case 1: + PlayFinalAnimation(IsleScript::c_wrt074sl_RunAnim); + break; + case 2: + PlayFinalAnimation(IsleScript::c_wrt075rh_RunAnim); + break; + case 3: + PlayFinalAnimation(IsleScript::c_wrt076df_RunAnim); + break; + case 4: + PlayFinalAnimation(IsleScript::c_wrt078ni_RunAnim); + break; + } + } + else if (objectId == IsleScript::c_wrt074sl_RunAnim || objectId == IsleScript::c_wrt075rh_RunAnim || objectId == IsleScript::c_wrt076df_RunAnim || objectId == IsleScript::c_wrt078ni_RunAnim) { + m_state->m_unk0x08 = 2; + CurrentWorld()->PlaceActor(UserActor()); + HandleClick(); + } + else if (objectId == IsleScript::c_wgs083nu_RunAnim) { + if (m_actorId < LegoActor::c_pepper || m_actorId > LegoActor::c_laura) { + m_actorId = LegoActor::c_laura; + } + + switch (m_actorId) { + case c_pepper: + FUN_1004dcb0(IsleScript::c_wgs085nu_RunAnim); + break; + case c_mama: + FUN_1004dcb0(IsleScript::c_wgs086nu_RunAnim); + break; + case c_papa: + FUN_1004dcb0(IsleScript::c_wgs088nu_RunAnim); + break; + case c_nick: + FUN_1004dcb0(IsleScript::c_wgs087nu_RunAnim); + break; + case c_laura: + FUN_1004dcb0(IsleScript::c_wgs089nu_RunAnim); + break; + } + + m_state->UpdateScore(LegoState::e_red, m_actorId); + + AnimationManager()->FUN_1005f6d0(TRUE); + g_isleFlags |= Isle::c_playMusic; + AnimationManager()->EnableCamAnims(TRUE); + } + else if (objectId == IsleScript::c_wgs090nu_RunAnim) { + if (m_actorId < LegoActor::c_pepper || m_actorId > LegoActor::c_laura) { + m_actorId = LegoActor::c_laura; + } + + switch (m_actorId) { + case c_pepper: + FUN_1004dcb0(IsleScript::c_wgs091nu_RunAnim); + break; + case c_mama: + FUN_1004dcb0(IsleScript::c_wgs092nu_RunAnim); + break; + case c_papa: + FUN_1004dcb0(IsleScript::c_wgs094nu_RunAnim); + break; + case c_nick: + FUN_1004dcb0(IsleScript::c_wgs093nu_RunAnim); + break; + case c_laura: + FUN_1004dcb0(IsleScript::c_wgs095nu_RunAnim); + break; + } + + m_state->UpdateScore(LegoState::e_blue, m_actorId); + } + else if (objectId == IsleScript::c_wgs097nu_RunAnim) { + if (m_actorId < LegoActor::c_pepper || m_actorId > LegoActor::c_laura) { + m_actorId = LegoActor::c_laura; + } + + switch (m_actorId) { + case c_pepper: + FUN_1004dcb0(IsleScript::c_wgs098nu_RunAnim); + break; + case c_mama: + FUN_1004dcb0(IsleScript::c_wgs099nu_RunAnim); + break; + case c_papa: + FUN_1004dcb0(IsleScript::c_wgs101nu_RunAnim); + break; + case c_nick: + FUN_1004dcb0(IsleScript::c_wgs100nu_RunAnim); + break; + case c_laura: + FUN_1004dcb0(IsleScript::c_wgs102nu_RunAnim); + break; + } + + m_state->UpdateScore(LegoState::e_yellow, m_actorId); + } + else if (objectId == IsleScript::c_wgs098nu_RunAnim || objectId == IsleScript::c_wgs099nu_RunAnim || objectId == IsleScript::c_wgs100nu_RunAnim || objectId == IsleScript::c_wgs101nu_RunAnim || objectId == IsleScript::c_wgs102nu_RunAnim || objectId == IsleScript::c_wgs085nu_RunAnim || objectId == IsleScript::c_wgs086nu_RunAnim || objectId == IsleScript::c_wgs087nu_RunAnim || objectId == IsleScript::c_wgs088nu_RunAnim || objectId == IsleScript::c_wgs089nu_RunAnim || objectId == IsleScript::c_wgs091nu_RunAnim || objectId == IsleScript::c_wgs092nu_RunAnim || objectId == IsleScript::c_wgs093nu_RunAnim || objectId == IsleScript::c_wgs094nu_RunAnim || objectId == IsleScript::c_wgs095nu_RunAnim) { + ((Act1State*) GameState()->GetState("Act1State"))->m_unk0x018 = 0; + AnimationManager()->FUN_1005f6d0(TRUE); + g_isleFlags |= Isle::c_playMusic; + AnimationManager()->EnableCamAnims(TRUE); + } + } + + return 1; } // FUNCTION: LEGO1 0x1004d330 @@ -250,6 +377,7 @@ MxLong TowTrack::HandlePathStruct(LegoPathStructNotificationParam& p_param) objectId = IsleScript::c_wns040na_PlayWav; break; } + break; case c_laura: switch ((rand() % 2) + 1) { case 1: @@ -439,6 +567,14 @@ void TowTrack::PlayFinalAnimation(IsleScript::Script p_objectId) m_lastAnimation = p_objectId; } +// FUNCTION: LEGO1 0x1004dcb0 +void TowTrack::FUN_1004dcb0(IsleScript::Script p_objectId) +{ + AnimationManager()->FUN_1005f6d0(TRUE); + AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, TRUE, NULL, FALSE, TRUE, TRUE, TRUE); + m_lastAnimation = p_objectId; +} + // FUNCTION: LEGO1 0x1004dcf0 void TowTrack::PlayAction(IsleScript::Script p_objectId) { @@ -453,19 +589,19 @@ void TowTrack::PlayAction(IsleScript::Script p_objectId) // FUNCTION: LEGO1 0x1004dd30 TowTrackMissionState::TowTrackMissionState() { - m_unk0x12 = 0; - m_unk0x14 = 0; - m_unk0x16 = 0; m_unk0x08 = 0; - m_unk0x18 = 0; m_startTime = 0; - m_unk0x1a = 0; m_unk0x10 = FALSE; - m_score1 = 0; - m_score2 = 0; - m_score3 = 0; - m_score4 = 0; - m_score5 = 0; + m_peScore = 0; + m_maScore = 0; + m_paScore = 0; + m_niScore = 0; + m_laScore = 0; + m_peHighScore = 0; + m_maHighScore = 0; + m_paHighScore = 0; + m_niHighScore = 0; + m_laHighScore = 0; } // FUNCTION: LEGO1 0x1004dde0 @@ -474,28 +610,28 @@ MxResult TowTrackMissionState::Serialize(LegoFile* p_file) LegoState::Serialize(p_file); if (p_file->IsReadMode()) { - Read(p_file, &m_unk0x12); - Read(p_file, &m_unk0x14); - Read(p_file, &m_unk0x16); - Read(p_file, &m_unk0x18); - Read(p_file, &m_unk0x1a); - Read(p_file, &m_score1); - Read(p_file, &m_score2); - Read(p_file, &m_score3); - Read(p_file, &m_score4); - Read(p_file, &m_score5); + Read(p_file, &m_peScore); + Read(p_file, &m_maScore); + Read(p_file, &m_paScore); + Read(p_file, &m_niScore); + Read(p_file, &m_laScore); + Read(p_file, &m_peHighScore); + Read(p_file, &m_maHighScore); + Read(p_file, &m_paHighScore); + Read(p_file, &m_niHighScore); + Read(p_file, &m_laHighScore); } else if (p_file->IsWriteMode()) { - Write(p_file, m_unk0x12); - Write(p_file, m_unk0x14); - Write(p_file, m_unk0x16); - Write(p_file, m_unk0x18); - Write(p_file, m_unk0x1a); - Write(p_file, m_score1); - Write(p_file, m_score2); - Write(p_file, m_score3); - Write(p_file, m_score4); - Write(p_file, m_score5); + Write(p_file, m_peScore); + Write(p_file, m_maScore); + Write(p_file, m_paScore); + Write(p_file, m_niScore); + Write(p_file, m_laScore); + Write(p_file, m_peHighScore); + Write(p_file, m_maHighScore); + Write(p_file, m_paHighScore); + Write(p_file, m_niHighScore); + Write(p_file, m_laHighScore); } return SUCCESS;