From 1d666f62e5c3f0e431ab7b7d69c5815cec4eeec1 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 19 Jun 2024 12:57:05 -0400 Subject: [PATCH] Implement/match LegoPlantManager interaction functions (#1041) --- .../legoomni/include/legobuildingmanager.h | 4 +- .../legoomni/include/legocharactermanager.h | 6 +- .../lego/legoomni/include/legoplantmanager.h | 8 +- .../src/common/legobuildingmanager.cpp | 16 +- .../src/common/legocharactermanager.cpp | 8 +- .../legoomni/src/common/legoplantmanager.cpp | 183 ++++++++++++++++-- LEGO1/lego/legoomni/src/entity/legoentity.cpp | 12 +- 7 files changed, 191 insertions(+), 46 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legobuildingmanager.h b/LEGO1/lego/legoomni/include/legobuildingmanager.h index 8514985f..782dccb9 100644 --- a/LEGO1/lego/legoomni/include/legobuildingmanager.h +++ b/LEGO1/lego/legoomni/include/legobuildingmanager.h @@ -76,8 +76,8 @@ class LegoBuildingManager : public MxCore { MxBool SwitchSound(LegoEntity* p_entity); MxBool SwitchMove(LegoEntity* p_entity); MxBool SwitchMood(LegoEntity* p_entity); - MxU32 GetBuildingEntityId(LegoEntity* p_entity); - MxU32 FUN_1002ff40(LegoEntity* p_entity, MxBool); + MxU32 GetAnimationId(LegoEntity* p_entity); + MxU32 GetSoundId(LegoEntity* p_entity, MxBool); MxBool FUN_10030000(LegoEntity* p_entity); MxBool FUN_10030030(MxS32 p_index); MxBool FUN_10030110(LegoBuildingInfo* p_data); diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 2c2238d6..57208ec7 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -74,10 +74,11 @@ class LegoCharacterManager { MxBool SwitchSound(LegoROI* p_roi); MxBool SwitchMove(LegoROI* p_roi); MxBool SwitchMood(LegoROI* p_roi); - MxU32 FUN_10085120(LegoROI* p_roi); - MxU32 FUN_10085140(LegoROI* p_roi, MxBool p_und); + MxU32 GetAnimationId(LegoROI* p_roi); + MxU32 GetSoundId(LegoROI* p_roi, MxBool p_und); MxU8 GetMood(LegoROI* p_roi); LegoROI* CreateAutoROI(const char* p_name, const char* p_lodName, MxBool p_createEntity); + MxResult FUN_10085870(LegoROI* p_roi); LegoROI* FUN_10085a80(const char* p_name, const char* p_lodName, MxBool p_createEntity); static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; } @@ -86,7 +87,6 @@ class LegoCharacterManager { LegoROI* CreateActorROI(const char* p_key); void RemoveROI(LegoROI* p_roi); LegoROI* FindChildROI(LegoROI* p_roi, const char* p_name); - MxResult FUN_10085870(LegoROI* p_roi); static char* g_customizeAnimFile; static MxU32 g_maxMove; diff --git a/LEGO1/lego/legoomni/include/legoplantmanager.h b/LEGO1/lego/legoomni/include/legoplantmanager.h index f1eb0544..6f02774b 100644 --- a/LEGO1/lego/legoomni/include/legoplantmanager.h +++ b/LEGO1/lego/legoomni/include/legoplantmanager.h @@ -6,6 +6,7 @@ class LegoEntity; class LegoPathBoundary; +struct LegoPlantInfo; class LegoROI; class LegoStorage; class LegoWorld; @@ -36,8 +37,8 @@ class LegoPlantManager : public MxCore { MxBool SwitchSound(LegoEntity* p_entity); MxBool SwitchMove(LegoEntity* p_entity); MxBool SwitchMood(LegoEntity* p_entity); - MxU32 FUN_10026b70(LegoEntity* p_entity); - MxU32 FUN_10026ba0(LegoEntity* p_entity, MxBool); + MxU32 GetAnimationId(LegoEntity* p_entity); + MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state); void FUN_10026c50(LegoEntity* p_entity); void FUN_10027120(); @@ -51,8 +52,11 @@ class LegoPlantManager : public MxCore { LegoEntity* CreatePlant(MxS32 p_index, LegoWorld* p_world, MxS32 p_worldId); void RemovePlant(MxS32 p_index, MxS32 p_worldId); void FUN_10026860(MxS32 p_index); + LegoPlantInfo* GetInfo(LegoEntity* p_entity); static char* g_customizeAnimFile; + static MxS32 g_maxMove[4]; + static MxU32 g_maxSound; MxS32 m_worldId; // 0x08 undefined m_unk0x0c; // 0x0c diff --git a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp index 88b443b5..00cfa8dc 100644 --- a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp @@ -196,14 +196,14 @@ LegoBuildingInfo g_buildingInfoInit[16] = { MxU32 LegoBuildingManager::g_maxSound = 6; // GLOBAL: LEGO1 0x100f373c -MxU32 g_cycleLengthOffset1 = 0x3c; +MxU32 g_unk0x100f373c = 0x3c; // GLOBAL: LEGO1 0x100f3740 -MxU32 g_cycleLengthOffset3 = 0x42; +MxU32 g_unk0x100f3740 = 0x42; // clang-format off // GLOBAL: LEGO1 0x100f3788 -MxU32 g_buildingEntityId[16] = { +MxU32 g_buildingAnimationId[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x49, 0x4c, @@ -531,12 +531,12 @@ MxBool LegoBuildingManager::SwitchMood(LegoEntity* p_entity) // FUNCTION: LEGO1 0x1002ff00 // FUNCTION: BETA10 0x1006432d -MxU32 LegoBuildingManager::GetBuildingEntityId(LegoEntity* p_entity) +MxU32 LegoBuildingManager::GetAnimationId(LegoEntity* p_entity) { LegoBuildingInfo* info = GetInfo(p_entity); if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasMoves) { - return g_buildingEntityId[info - g_buildingInfo] + info->m_move; + return g_buildingAnimationId[info - g_buildingInfo] + info->m_move; } return 0; @@ -544,7 +544,7 @@ MxU32 LegoBuildingManager::GetBuildingEntityId(LegoEntity* p_entity) // FUNCTION: LEGO1 0x1002ff40 // FUNCTION: BETA10 0x10064398 -MxU32 LegoBuildingManager::FUN_1002ff40(LegoEntity* p_entity, MxBool p_state) +MxU32 LegoBuildingManager::GetSoundId(LegoEntity* p_entity, MxBool p_state) { LegoBuildingInfo* info = GetInfo(p_entity); @@ -553,11 +553,11 @@ MxU32 LegoBuildingManager::FUN_1002ff40(LegoEntity* p_entity, MxBool p_state) } if (p_state) { - return info->m_mood + g_cycleLengthOffset3; + return info->m_mood + g_unk0x100f3740; } if (info != NULL) { - return info->m_sound + g_cycleLengthOffset1; + return info->m_sound + g_unk0x100f373c; } return 0; diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index 826f471b..1ddf49e1 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -28,7 +28,7 @@ MxU32 LegoCharacterManager::g_maxMove = 4; MxU32 LegoCharacterManager::g_maxSound = 9; // GLOBAL: LEGO1 0x100fc4e0 -MxU32 g_unk0x100fc4e0 = 10; +MxU32 g_characterAnimationId = 10; // GLOBAL: LEGO1 0x100fc4e4 char* LegoCharacterManager::g_customizeAnimFile = NULL; @@ -884,19 +884,19 @@ MxBool LegoCharacterManager::SwitchMood(LegoROI* p_roi) // FUNCTION: LEGO1 0x10085120 // FUNCTION: BETA10 0x1007680c -MxU32 LegoCharacterManager::FUN_10085120(LegoROI* p_roi) +MxU32 LegoCharacterManager::GetAnimationId(LegoROI* p_roi) { LegoActorInfo* info = GetActorInfo(p_roi); if (info != NULL) { - return info->m_move + g_unk0x100fc4e0; + return info->m_move + g_characterAnimationId; } return 0; } // FUNCTION: LEGO1 0x10085140 -MxU32 LegoCharacterManager::FUN_10085140(LegoROI* p_roi, MxBool p_und) +MxU32 LegoCharacterManager::GetSoundId(LegoROI* p_roi, MxBool p_und) { LegoActorInfo* info = GetActorInfo(p_roi); diff --git a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp index 09739ae6..723a3981 100644 --- a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp @@ -1,13 +1,16 @@ #include "legoplantmanager.h" +#include "3dmanager/lego3dmanager.h" #include "legocharactermanager.h" #include "legoentity.h" #include "legoplants.h" +#include "legovideomanager.h" #include "legoworld.h" #include "misc.h" #include "misc/legostorage.h" #include "scripts.h" #include "sndanim_actions.h" +#include "viewmanager/viewmanager.h" #include @@ -27,6 +30,21 @@ float g_unk0x100f16b0[] = {0.1f, 0.7f, 0.5f, 0.9f}; // GLOBAL: LEGO1 0x100f16c0 MxU8 g_unk0x100f16c0[] = {1, 2, 2, 3}; +// GLOBAL: LEGO1 0x100f315c +MxU32 LegoPlantManager::g_maxSound = 8; + +// GLOBAL: LEGO1 0x100f3160 +MxU32 g_unk0x100f3160 = 56; + +// GLOBAL: LEGO1 0x100f3164 +MxU32 g_unk0x100f3164 = 66; + +// GLOBAL: LEGO1 0x100f3168 +MxS32 LegoPlantManager::g_maxMove[4] = {3, 3, 3, 3}; + +// GLOBAL: LEGO1 0x100f3178 +MxU32 g_plantAnimationId[4] = {30, 33, 36, 39}; + // GLOBAL: LEGO1 0x100f3188 char* LegoPlantManager::g_customizeAnimFile = NULL; @@ -233,52 +251,175 @@ void LegoPlantManager::FUN_10026860(MxS32 p_index) } } -// STUB: LEGO1 0x10026920 +// FUNCTION: LEGO1 0x100268e0 +// FUNCTION: BETA10 0x100c5c95 +LegoPlantInfo* LegoPlantManager::GetInfo(LegoEntity* p_entity) +{ + MxS32 i; + + for (i = 0; i < sizeOfArray(g_plantInfo); i++) { + if (g_plantInfo[i].m_entity == p_entity) { + break; + } + } + + if (i < sizeOfArray(g_plantInfo)) { + return &g_plantInfo[i]; + } + + return NULL; +} + +// FUNCTION: LEGO1 0x10026920 +// FUNCTION: BETA10 0x100c5dc9 MxBool LegoPlantManager::SwitchColor(LegoEntity* p_entity) { - // TODO - return FALSE; + LegoPlantInfo* info = GetInfo(p_entity); + + if (info == NULL) { + return FALSE; + } + + LegoROI* roi = p_entity->GetROI(); + info->m_color++; + + if (info->m_color > LegoPlantInfo::e_green) { + info->m_color = LegoPlantInfo::e_white; + } + + ViewLODList* lodList = GetViewLODListManager()->Lookup(g_plantLodNames[info->m_variant][info->m_color]); + + if (roi->GetUnknown0xe0() >= 0) { + VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveROIDetailFromScene(roi); + } + + roi->SetLODList(lodList); + lodList->Release(); + CharacterManager()->FUN_10085870(roi); + return TRUE; } -// STUB: LEGO1 0x100269e0 +// FUNCTION: LEGO1 0x100269e0 +// FUNCTION: BETA10 0x100c5ee2 MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity) { - // TODO - return FALSE; + LegoPlantInfo* info = GetInfo(p_entity); + + if (info == NULL || info->m_unk0x16 != -1) { + return FALSE; + } + + LegoROI* roi = p_entity->GetROI(); + info->m_variant++; + + if (info->m_variant > LegoPlantInfo::e_palm) { + info->m_variant = LegoPlantInfo::e_flower; + } + + ViewLODList* lodList = GetViewLODListManager()->Lookup(g_plantLodNames[info->m_variant][info->m_color]); + + if (roi->GetUnknown0xe0() >= 0) { + VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveROIDetailFromScene(roi); + } + + roi->SetLODList(lodList); + lodList->Release(); + CharacterManager()->FUN_10085870(roi); + + if (info->m_move != 0 && info->m_move >= g_maxMove[info->m_variant]) { + info->m_move = g_maxMove[info->m_variant] - 1; + } + + return TRUE; } -// STUB: LEGO1 0x10026ad0 +// FUNCTION: LEGO1 0x10026ad0 +// FUNCTION: BETA10 0x100c6049 MxBool LegoPlantManager::SwitchSound(LegoEntity* p_entity) { - // TODO - return FALSE; + MxBool result = FALSE; + LegoPlantInfo* info = GetInfo(p_entity); + + if (info != NULL) { + info->m_sound++; + + if (info->m_sound >= g_maxSound) { + info->m_sound = 0; + } + + result = TRUE; + } + + return result; } -// STUB: LEGO1 0x10026b00 +// FUNCTION: LEGO1 0x10026b00 +// FUNCTION: BETA10 0x100c60a7 MxBool LegoPlantManager::SwitchMove(LegoEntity* p_entity) { - // TODO - return FALSE; + MxBool result = FALSE; + LegoPlantInfo* info = GetInfo(p_entity); + + if (info != NULL) { + info->m_move++; + + if (info->m_move >= g_maxMove[info->m_variant]) { + info->m_move = 0; + } + + result = TRUE; + } + + return result; } -// STUB: LEGO1 0x10026b40 +// FUNCTION: LEGO1 0x10026b40 +// FUNCTION: BETA10 0x100c610e MxBool LegoPlantManager::SwitchMood(LegoEntity* p_entity) { - // TODO - return FALSE; + MxBool result = FALSE; + LegoPlantInfo* info = GetInfo(p_entity); + + if (info != NULL) { + info->m_mood++; + + if (info->m_mood > 3) { + info->m_mood = 0; + } + + result = TRUE; + } + + return result; } -// STUB: LEGO1 0x10026b70 -MxU32 LegoPlantManager::FUN_10026b70(LegoEntity* p_entity) +// FUNCTION: LEGO1 0x10026b70 +// FUNCTION: BETA10 0x100c6168 +MxU32 LegoPlantManager::GetAnimationId(LegoEntity* p_entity) { - // TODO + LegoPlantInfo* info = GetInfo(p_entity); + + if (info != NULL) { + return g_plantAnimationId[info->m_variant] + info->m_move; + } + return 0; } -// STUB: LEGO1 0x10026ba0 -MxU32 LegoPlantManager::FUN_10026ba0(LegoEntity* p_entity, MxBool) +// FUNCTION: LEGO1 0x10026ba0 +// FUNCTION: BETA10 0x100c61ba +MxU32 LegoPlantManager::GetSoundId(LegoEntity* p_entity, MxBool p_state) { - // TODO + LegoPlantInfo* info = GetInfo(p_entity); + + if (p_state) { + return (info->m_mood & 1) + g_unk0x100f3164; + } + + if (info != NULL) { + return info->m_sound + g_unk0x100f3160; + } + return 0; } diff --git a/LEGO1/lego/legoomni/src/entity/legoentity.cpp b/LEGO1/lego/legoomni/src/entity/legoentity.cpp index cca706a7..f18c689e 100644 --- a/LEGO1/lego/legoomni/src/entity/legoentity.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoentity.cpp @@ -256,15 +256,15 @@ void LegoEntity::ClickSound(MxBool p_und) switch (m_type) { case e_actor: - objectId = CharacterManager()->FUN_10085140(m_roi, p_und); + objectId = CharacterManager()->GetSoundId(m_roi, p_und); break; case e_unk1: break; case e_plant: - objectId = PlantManager()->FUN_10026ba0(this, p_und); + objectId = PlantManager()->GetSoundId(this, p_und); break; case e_building: - objectId = BuildingManager()->FUN_1002ff40(this, p_und); + objectId = BuildingManager()->GetSoundId(this, p_und); break; } @@ -290,19 +290,19 @@ void LegoEntity::ClickAnimation() switch (m_type) { case e_actor: - objectId = LegoOmni::GetInstance()->GetCharacterManager()->FUN_10085120(m_roi); + objectId = LegoOmni::GetInstance()->GetCharacterManager()->GetAnimationId(m_roi); action.SetAtomId(MxAtomId(LegoCharacterManager::GetCustomizeAnimFile(), e_lowerCase2)); sprintf(extra, "SUBST:actor_01:%s", name); break; case e_unk1: break; case e_plant: - objectId = LegoOmni::GetInstance()->GetPlantManager()->FUN_10026b70(this); + objectId = LegoOmni::GetInstance()->GetPlantManager()->GetAnimationId(this); action.SetAtomId(MxAtomId(LegoPlantManager::GetCustomizeAnimFile(), e_lowerCase2)); sprintf(extra, "SUBST:bush:%s:tree:%s:flwrred:%s:palm:%s", name, name, name, name); break; case e_building: - objectId = LegoOmni::GetInstance()->GetBuildingManager()->GetBuildingEntityId(this); + objectId = LegoOmni::GetInstance()->GetBuildingManager()->GetAnimationId(this); action.SetAtomId(MxAtomId(BuildingManager()->GetCustomizeAnimFile(), e_lowerCase2)); sprintf(extra, "SUBST:haus1:%s", name); break;