Implement/match LegoPlantManager interaction functions (#1041)

This commit is contained in:
Christian Semmler 2024-06-19 12:57:05 -04:00 committed by GitHub
parent 656e7fc674
commit 1d666f62e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 191 additions and 46 deletions

View file

@ -76,8 +76,8 @@ class LegoBuildingManager : public MxCore {
MxBool SwitchSound(LegoEntity* p_entity); MxBool SwitchSound(LegoEntity* p_entity);
MxBool SwitchMove(LegoEntity* p_entity); MxBool SwitchMove(LegoEntity* p_entity);
MxBool SwitchMood(LegoEntity* p_entity); MxBool SwitchMood(LegoEntity* p_entity);
MxU32 GetBuildingEntityId(LegoEntity* p_entity); MxU32 GetAnimationId(LegoEntity* p_entity);
MxU32 FUN_1002ff40(LegoEntity* p_entity, MxBool); MxU32 GetSoundId(LegoEntity* p_entity, MxBool);
MxBool FUN_10030000(LegoEntity* p_entity); MxBool FUN_10030000(LegoEntity* p_entity);
MxBool FUN_10030030(MxS32 p_index); MxBool FUN_10030030(MxS32 p_index);
MxBool FUN_10030110(LegoBuildingInfo* p_data); MxBool FUN_10030110(LegoBuildingInfo* p_data);

View file

@ -74,10 +74,11 @@ class LegoCharacterManager {
MxBool SwitchSound(LegoROI* p_roi); MxBool SwitchSound(LegoROI* p_roi);
MxBool SwitchMove(LegoROI* p_roi); MxBool SwitchMove(LegoROI* p_roi);
MxBool SwitchMood(LegoROI* p_roi); MxBool SwitchMood(LegoROI* p_roi);
MxU32 FUN_10085120(LegoROI* p_roi); MxU32 GetAnimationId(LegoROI* p_roi);
MxU32 FUN_10085140(LegoROI* p_roi, MxBool p_und); MxU32 GetSoundId(LegoROI* p_roi, MxBool p_und);
MxU8 GetMood(LegoROI* p_roi); MxU8 GetMood(LegoROI* p_roi);
LegoROI* CreateAutoROI(const char* p_name, const char* p_lodName, MxBool p_createEntity); 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); LegoROI* FUN_10085a80(const char* p_name, const char* p_lodName, MxBool p_createEntity);
static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; } static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; }
@ -86,7 +87,6 @@ class LegoCharacterManager {
LegoROI* CreateActorROI(const char* p_key); LegoROI* CreateActorROI(const char* p_key);
void RemoveROI(LegoROI* p_roi); void RemoveROI(LegoROI* p_roi);
LegoROI* FindChildROI(LegoROI* p_roi, const char* p_name); LegoROI* FindChildROI(LegoROI* p_roi, const char* p_name);
MxResult FUN_10085870(LegoROI* p_roi);
static char* g_customizeAnimFile; static char* g_customizeAnimFile;
static MxU32 g_maxMove; static MxU32 g_maxMove;

View file

@ -6,6 +6,7 @@
class LegoEntity; class LegoEntity;
class LegoPathBoundary; class LegoPathBoundary;
struct LegoPlantInfo;
class LegoROI; class LegoROI;
class LegoStorage; class LegoStorage;
class LegoWorld; class LegoWorld;
@ -36,8 +37,8 @@ class LegoPlantManager : public MxCore {
MxBool SwitchSound(LegoEntity* p_entity); MxBool SwitchSound(LegoEntity* p_entity);
MxBool SwitchMove(LegoEntity* p_entity); MxBool SwitchMove(LegoEntity* p_entity);
MxBool SwitchMood(LegoEntity* p_entity); MxBool SwitchMood(LegoEntity* p_entity);
MxU32 FUN_10026b70(LegoEntity* p_entity); MxU32 GetAnimationId(LegoEntity* p_entity);
MxU32 FUN_10026ba0(LegoEntity* p_entity, MxBool); MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state);
void FUN_10026c50(LegoEntity* p_entity); void FUN_10026c50(LegoEntity* p_entity);
void FUN_10027120(); void FUN_10027120();
@ -51,8 +52,11 @@ class LegoPlantManager : public MxCore {
LegoEntity* CreatePlant(MxS32 p_index, LegoWorld* p_world, MxS32 p_worldId); LegoEntity* CreatePlant(MxS32 p_index, LegoWorld* p_world, MxS32 p_worldId);
void RemovePlant(MxS32 p_index, MxS32 p_worldId); void RemovePlant(MxS32 p_index, MxS32 p_worldId);
void FUN_10026860(MxS32 p_index); void FUN_10026860(MxS32 p_index);
LegoPlantInfo* GetInfo(LegoEntity* p_entity);
static char* g_customizeAnimFile; static char* g_customizeAnimFile;
static MxS32 g_maxMove[4];
static MxU32 g_maxSound;
MxS32 m_worldId; // 0x08 MxS32 m_worldId; // 0x08
undefined m_unk0x0c; // 0x0c undefined m_unk0x0c; // 0x0c

View file

@ -196,14 +196,14 @@ LegoBuildingInfo g_buildingInfoInit[16] = {
MxU32 LegoBuildingManager::g_maxSound = 6; MxU32 LegoBuildingManager::g_maxSound = 6;
// GLOBAL: LEGO1 0x100f373c // GLOBAL: LEGO1 0x100f373c
MxU32 g_cycleLengthOffset1 = 0x3c; MxU32 g_unk0x100f373c = 0x3c;
// GLOBAL: LEGO1 0x100f3740 // GLOBAL: LEGO1 0x100f3740
MxU32 g_cycleLengthOffset3 = 0x42; MxU32 g_unk0x100f3740 = 0x42;
// clang-format off // clang-format off
// GLOBAL: LEGO1 0x100f3788 // GLOBAL: LEGO1 0x100f3788
MxU32 g_buildingEntityId[16] = { MxU32 g_buildingAnimationId[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x46, 0x49, 0x4c, 0x00, 0x46, 0x49, 0x4c,
@ -531,12 +531,12 @@ MxBool LegoBuildingManager::SwitchMood(LegoEntity* p_entity)
// FUNCTION: LEGO1 0x1002ff00 // FUNCTION: LEGO1 0x1002ff00
// FUNCTION: BETA10 0x1006432d // FUNCTION: BETA10 0x1006432d
MxU32 LegoBuildingManager::GetBuildingEntityId(LegoEntity* p_entity) MxU32 LegoBuildingManager::GetAnimationId(LegoEntity* p_entity)
{ {
LegoBuildingInfo* info = GetInfo(p_entity); LegoBuildingInfo* info = GetInfo(p_entity);
if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasMoves) { 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; return 0;
@ -544,7 +544,7 @@ MxU32 LegoBuildingManager::GetBuildingEntityId(LegoEntity* p_entity)
// FUNCTION: LEGO1 0x1002ff40 // FUNCTION: LEGO1 0x1002ff40
// FUNCTION: BETA10 0x10064398 // 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); LegoBuildingInfo* info = GetInfo(p_entity);
@ -553,11 +553,11 @@ MxU32 LegoBuildingManager::FUN_1002ff40(LegoEntity* p_entity, MxBool p_state)
} }
if (p_state) { if (p_state) {
return info->m_mood + g_cycleLengthOffset3; return info->m_mood + g_unk0x100f3740;
} }
if (info != NULL) { if (info != NULL) {
return info->m_sound + g_cycleLengthOffset1; return info->m_sound + g_unk0x100f373c;
} }
return 0; return 0;

View file

@ -28,7 +28,7 @@ MxU32 LegoCharacterManager::g_maxMove = 4;
MxU32 LegoCharacterManager::g_maxSound = 9; MxU32 LegoCharacterManager::g_maxSound = 9;
// GLOBAL: LEGO1 0x100fc4e0 // GLOBAL: LEGO1 0x100fc4e0
MxU32 g_unk0x100fc4e0 = 10; MxU32 g_characterAnimationId = 10;
// GLOBAL: LEGO1 0x100fc4e4 // GLOBAL: LEGO1 0x100fc4e4
char* LegoCharacterManager::g_customizeAnimFile = NULL; char* LegoCharacterManager::g_customizeAnimFile = NULL;
@ -884,19 +884,19 @@ MxBool LegoCharacterManager::SwitchMood(LegoROI* p_roi)
// FUNCTION: LEGO1 0x10085120 // FUNCTION: LEGO1 0x10085120
// FUNCTION: BETA10 0x1007680c // FUNCTION: BETA10 0x1007680c
MxU32 LegoCharacterManager::FUN_10085120(LegoROI* p_roi) MxU32 LegoCharacterManager::GetAnimationId(LegoROI* p_roi)
{ {
LegoActorInfo* info = GetActorInfo(p_roi); LegoActorInfo* info = GetActorInfo(p_roi);
if (info != NULL) { if (info != NULL) {
return info->m_move + g_unk0x100fc4e0; return info->m_move + g_characterAnimationId;
} }
return 0; return 0;
} }
// FUNCTION: LEGO1 0x10085140 // 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); LegoActorInfo* info = GetActorInfo(p_roi);

View file

@ -1,13 +1,16 @@
#include "legoplantmanager.h" #include "legoplantmanager.h"
#include "3dmanager/lego3dmanager.h"
#include "legocharactermanager.h" #include "legocharactermanager.h"
#include "legoentity.h" #include "legoentity.h"
#include "legoplants.h" #include "legoplants.h"
#include "legovideomanager.h"
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
#include "misc/legostorage.h" #include "misc/legostorage.h"
#include "scripts.h" #include "scripts.h"
#include "sndanim_actions.h" #include "sndanim_actions.h"
#include "viewmanager/viewmanager.h"
#include <stdio.h> #include <stdio.h>
@ -27,6 +30,21 @@ float g_unk0x100f16b0[] = {0.1f, 0.7f, 0.5f, 0.9f};
// GLOBAL: LEGO1 0x100f16c0 // GLOBAL: LEGO1 0x100f16c0
MxU8 g_unk0x100f16c0[] = {1, 2, 2, 3}; 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 // GLOBAL: LEGO1 0x100f3188
char* LegoPlantManager::g_customizeAnimFile = NULL; 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) MxBool LegoPlantManager::SwitchColor(LegoEntity* p_entity)
{ {
// TODO LegoPlantInfo* info = GetInfo(p_entity);
if (info == NULL) {
return FALSE; return FALSE;
} }
// STUB: LEGO1 0x100269e0 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;
}
// FUNCTION: LEGO1 0x100269e0
// FUNCTION: BETA10 0x100c5ee2
MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity) MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity)
{ {
// TODO LegoPlantInfo* info = GetInfo(p_entity);
if (info == NULL || info->m_unk0x16 != -1) {
return FALSE; return FALSE;
} }
// STUB: LEGO1 0x10026ad0 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;
}
// FUNCTION: LEGO1 0x10026ad0
// FUNCTION: BETA10 0x100c6049
MxBool LegoPlantManager::SwitchSound(LegoEntity* p_entity) MxBool LegoPlantManager::SwitchSound(LegoEntity* p_entity)
{ {
// TODO MxBool result = FALSE;
return FALSE; LegoPlantInfo* info = GetInfo(p_entity);
if (info != NULL) {
info->m_sound++;
if (info->m_sound >= g_maxSound) {
info->m_sound = 0;
} }
// STUB: LEGO1 0x10026b00 result = TRUE;
}
return result;
}
// FUNCTION: LEGO1 0x10026b00
// FUNCTION: BETA10 0x100c60a7
MxBool LegoPlantManager::SwitchMove(LegoEntity* p_entity) MxBool LegoPlantManager::SwitchMove(LegoEntity* p_entity)
{ {
// TODO MxBool result = FALSE;
return 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;
} }
// STUB: LEGO1 0x10026b40 result = TRUE;
}
return result;
}
// FUNCTION: LEGO1 0x10026b40
// FUNCTION: BETA10 0x100c610e
MxBool LegoPlantManager::SwitchMood(LegoEntity* p_entity) MxBool LegoPlantManager::SwitchMood(LegoEntity* p_entity)
{ {
// TODO MxBool result = FALSE;
return FALSE; LegoPlantInfo* info = GetInfo(p_entity);
if (info != NULL) {
info->m_mood++;
if (info->m_mood > 3) {
info->m_mood = 0;
} }
// STUB: LEGO1 0x10026b70 result = TRUE;
MxU32 LegoPlantManager::FUN_10026b70(LegoEntity* p_entity) }
return result;
}
// 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; return 0;
} }
// STUB: LEGO1 0x10026ba0 // FUNCTION: LEGO1 0x10026ba0
MxU32 LegoPlantManager::FUN_10026ba0(LegoEntity* p_entity, MxBool) // 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; return 0;
} }

View file

@ -256,15 +256,15 @@ void LegoEntity::ClickSound(MxBool p_und)
switch (m_type) { switch (m_type) {
case e_actor: case e_actor:
objectId = CharacterManager()->FUN_10085140(m_roi, p_und); objectId = CharacterManager()->GetSoundId(m_roi, p_und);
break; break;
case e_unk1: case e_unk1:
break; break;
case e_plant: case e_plant:
objectId = PlantManager()->FUN_10026ba0(this, p_und); objectId = PlantManager()->GetSoundId(this, p_und);
break; break;
case e_building: case e_building:
objectId = BuildingManager()->FUN_1002ff40(this, p_und); objectId = BuildingManager()->GetSoundId(this, p_und);
break; break;
} }
@ -290,19 +290,19 @@ void LegoEntity::ClickAnimation()
switch (m_type) { switch (m_type) {
case e_actor: 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)); action.SetAtomId(MxAtomId(LegoCharacterManager::GetCustomizeAnimFile(), e_lowerCase2));
sprintf(extra, "SUBST:actor_01:%s", name); sprintf(extra, "SUBST:actor_01:%s", name);
break; break;
case e_unk1: case e_unk1:
break; break;
case e_plant: case e_plant:
objectId = LegoOmni::GetInstance()->GetPlantManager()->FUN_10026b70(this); objectId = LegoOmni::GetInstance()->GetPlantManager()->GetAnimationId(this);
action.SetAtomId(MxAtomId(LegoPlantManager::GetCustomizeAnimFile(), e_lowerCase2)); action.SetAtomId(MxAtomId(LegoPlantManager::GetCustomizeAnimFile(), e_lowerCase2));
sprintf(extra, "SUBST:bush:%s:tree:%s:flwrred:%s:palm:%s", name, name, name, name); sprintf(extra, "SUBST:bush:%s:tree:%s:flwrred:%s:palm:%s", name, name, name, name);
break; break;
case e_building: case e_building:
objectId = LegoOmni::GetInstance()->GetBuildingManager()->GetBuildingEntityId(this); objectId = LegoOmni::GetInstance()->GetBuildingManager()->GetAnimationId(this);
action.SetAtomId(MxAtomId(BuildingManager()->GetCustomizeAnimFile(), e_lowerCase2)); action.SetAtomId(MxAtomId(BuildingManager()->GetCustomizeAnimFile(), e_lowerCase2));
sprintf(extra, "SUBST:haus1:%s", name); sprintf(extra, "SUBST:haus1:%s", name);
break; break;