diff --git a/LEGO1/lego/legoomni/include/legocarbuild.h b/LEGO1/lego/legoomni/include/legocarbuild.h index 6337aafd..945d7d06 100644 --- a/LEGO1/lego/legoomni/include/legocarbuild.h +++ b/LEGO1/lego/legoomni/include/legocarbuild.h @@ -126,9 +126,12 @@ class LegoCarBuild : public LegoWorld { ); // vtable+0x80 MxS16 GetPlacedPartCount(); + void SetPlacedPartCount(MxU8 p_placedPartCount); void InitPresenters(); + void FUN_10022f00(); void FUN_10022f30(); void FUN_10023130(MxLong p_x, MxLong p_y); + void FUN_100236d0(); undefined4 FUN_10024250(LegoEventNotificationParam* p_param); void FUN_100243a0(); undefined4 FUN_10024480(MxActionNotificationParam* p_param); diff --git a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h index 2e61b1e5..e6239bf5 100644 --- a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h +++ b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h @@ -70,6 +70,7 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { void FUN_10079680(LegoChar* p_param); LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name); LegoTreeNode* FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name); + void FUN_10079790(const LegoChar* p_name); void RotateAroundYAxis(MxFloat p_angle); MxBool FUN_10079c30(const LegoChar* p_name); MxBool PartIsPlaced(const LegoChar* p_name); diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index 604e860c..ceb64416 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -28,6 +28,7 @@ enum Cursor { e_cursorNone }; +class BoundingSphere; class MxAtomId; class LegoEntity; class LegoFile; @@ -43,6 +44,7 @@ LegoEntity* PickEntity(MxLong, MxLong); LegoROI* PickROI(MxLong, MxLong); LegoROI* PickParentROI(MxLong p_a, MxLong p_b); void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2); +MxBool SpheresIntersect(const BoundingSphere& p_sphere1, const BoundingSphere& p_sphere2); MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3]); MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4]); MxS16 CountTotalTreeNodes(LegoTreeNode* p_node); diff --git a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp index 4a921511..7ab16e56 100644 --- a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp @@ -358,6 +358,7 @@ undefined4 MxBackgroundAudioManager::FUN_1007f610( } // FUNCTION: LEGO1 0x1007f650 +// FUNCTION: BETA10 0x100e9663 void MxBackgroundAudioManager::Init() { this->m_unk0xa0 = 0; diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index 825b37e4..c904718c 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -235,6 +235,14 @@ MxS16 LegoCarBuild::GetPlacedPartCount() } } +// FUNCTION: LEGO1 0x10022cf0 +void LegoCarBuild::SetPlacedPartCount(MxU8 p_placedPartCount) +{ + if (m_buildState) { + m_buildState->m_placedPartCount = p_placedPartCount; + } +} + // FUNCTION: LEGO1 0x10022d10 // FUNCTION: BETA10 0x1006b27a void LegoCarBuild::InitPresenters() @@ -281,6 +289,16 @@ void LegoCarBuild::InitPresenters() } } +// FUNCTION: LEGO1 0x10022f00 +void LegoCarBuild::FUN_10022f00() +{ + if (m_unk0x110) { + VTable0x6c(); + m_unk0x258->SetUnknown0xbc(0); + m_unk0x100 = 5; + } +} + // FUNCTION: LEGO1 0x10022f30 // FUNCTION: BETA10 0x1006b835 void LegoCarBuild::FUN_10022f30() @@ -458,6 +476,55 @@ void LegoCarBuild::VTable0x80(MxFloat p_param1[2], MxFloat p_param2[2], MxFloat p_param4[1] = p_param3; } +// FUNCTION: LEGO1 0x100236d0 +// FUNCTION: BETA10 0x1006c076 +void LegoCarBuild::FUN_100236d0() +{ + MxS32 pLVar2; + + FUN_10024f70(FALSE); + FUN_100250e0(FALSE); + m_unk0x258->FUN_10079790(m_unk0x110->GetName()); + m_unk0x258->SetUnknown0xbc(1); + m_unk0x110 = NULL; + m_unk0x100 = 0; + + if (m_unk0x258->AllPartsPlaced()) { + // Note the code duplication with LEGO1 0x10025ee0 + switch (m_carId) { + case 1: + pLVar2 = 0x2f; + break; + case 2: + pLVar2 = 0x31; + break; + case 3: + pLVar2 = 0x33; + break; + case 4: + pLVar2 = 0x35; + } + + BackgroundAudioManager()->Init(); + InvokeAction(Extra::e_stop, *g_jukeboxScript, pLVar2, NULL); + + if (m_numAnimsRun > 0) { + DeleteObjects(&m_atomId, 500, 510); + } + + if (GameState()->GetCurrentAct() == LegoGameState::e_act2) { + FUN_100243a0(); + } + else { + m_buildState->m_unk0x4d = TRUE; + InvokeAction(Extra::e_start, m_atomId, m_carId, NULL); + NotificationManager()->Send(this, MxNotificationParam()); + m_buildState->m_animationState = LegoVehicleBuildState::e_unknown4; + m_buildState->m_placedPartCount = 0; + } + } +} + #define LEGOCARBUILD_TICKLE_CASE(subtract, start, end, str) \ if (start < dTime && dTime < end) { \ FUN_10025db0(str, dTime - subtract); \ @@ -812,11 +879,49 @@ undefined4 LegoCarBuild::FUN_100244e0(MxLong p_x, MxLong p_y) return 1; } -// STUB: LEGO1 0x100246e0 +// FUNCTION: LEGO1 0x100246e0 undefined4 LegoCarBuild::FUN_100246e0(MxLong p_x, MxLong p_y) { - // TODO - return 0; + switch (m_unk0x100) { + case 3: + FUN_10022f30(); + return 1; + case 4: + FUN_10022f00(); + return 1; + case 6: + if (m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) { + if (SpheresIntersect(m_unk0x114, m_unk0x110->GetWorldBoundingSphere())) { + FUN_10024f70(FALSE); + FUN_100250e0(FALSE); + m_unk0x100 = 0; + m_unk0x110 = NULL; + m_PlaceBrick_Sound->Enable(FALSE); + m_PlaceBrick_Sound->Enable(TRUE); + m_unk0x258->SetUnknown0xbc(1); + return 1; + } + } + + if (m_unk0x258->FUN_10079c30(m_unk0x110->GetName())) { + if (SpheresIntersect(m_unk0x114, m_unk0x110->GetWorldBoundingSphere())) { + m_PlaceBrick_Sound->Enable(FALSE); + m_PlaceBrick_Sound->Enable(TRUE); + FUN_100236d0(); + return 1; + } + + VTable0x6c(); + m_unk0x100 = 5; + return 1; + } + + VTable0x6c(); + m_unk0x100 = 5; + return 1; + default: + return 0; + } } // FUNCTION: LEGO1 0x10024850 diff --git a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp index 546aac67..c9968fc4 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp @@ -507,6 +507,44 @@ LegoTreeNode* LegoCarBuildAnimPresenter::FindNodeByName(LegoTreeNode* p_treeNode return NULL; } +// FUNCTION: BETA10 0x10073c20 +inline void Exchange(MxS16* p_value1, MxS16* p_value2) +{ + MxS16 temp = *p_value1; + *p_value1 = *p_value2; + *p_value2 = temp; +} + +// FUNCTION: LEGO1 0x10079790 +// FUNCTION: BETA10 0x100720a3 +void LegoCarBuildAnimPresenter::FUN_10079790(const LegoChar* p_name) +{ + MxS16 i; + LegoChar buffer[40]; + + if (strcmpi(m_parts[m_placedPartCount].m_name, p_name) != 0) { + // Something is still of by 1 here + for (i = m_placedPartCount + 1; i < m_numberOfParts; i++) { + if (stricmp(m_parts[i].m_name, p_name) == 0) { + break; + } + } + + strcpy(buffer, m_parts[m_placedPartCount].m_name); + strcpy(m_parts[m_placedPartCount].m_name, m_parts[i].m_name); + strcpy(m_parts[i].m_name, buffer); + Exchange(&m_parts[m_placedPartCount].m_objectId, &m_parts[i].m_objectId); + } + FUN_10079050(m_placedPartCount); + m_placedPartCount++; + + ((LegoCarBuild*)m_currentWorld)->SetPlacedPartCount(m_placedPartCount); + + if (m_placedPartCount < m_numberOfParts) { + FUN_10079680(m_parts[m_placedPartCount].m_wiredName); + } +} + // FUNCTION: LEGO1 0x10079920 // FUNCTION: BETA10 0x1007225d void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle) diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index d38ff896..c5e658a6 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -72,6 +72,14 @@ void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2) // TODO } +// FUNCTION: LEGO1 0x1003de80 +MxBool SpheresIntersect(const BoundingSphere& p_sphere1, const BoundingSphere& p_sphere2) +{ + // This doesn't look clean, but it matches. + // p_sphere1.Center().GetData() doesn't work out + return sqrt(DISTSQRD3(&p_sphere1.Center()[0], &p_sphere2.Center()[0])) < p_sphere1.Radius() + p_sphere2.Radius(); +} + // FUNCTION: LEGO1 0x1003ded0 // FUNCTION: BETA10 0x100d3802 MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3]) diff --git a/LEGO1/lego/legoomni/src/main/scripts.cpp b/LEGO1/lego/legoomni/src/main/scripts.cpp index b5d7fe54..b5b8f9fe 100644 --- a/LEGO1/lego/legoomni/src/main/scripts.cpp +++ b/LEGO1/lego/legoomni/src/main/scripts.cpp @@ -64,6 +64,7 @@ MxAtomId* g_act2mainScript = NULL; MxAtomId* g_act3Script = NULL; // GLOBAL: LEGO1 0x100f456c +// GLOBAL: BETA10 0x102114e0 MxAtomId* g_jukeboxScript = NULL; // GLOBAL: LEGO1 0x100f4570