Implement/match LegoBuildingManager::FUN_10030630 (#1164)

This commit is contained in:
Christian Semmler 2024-11-22 15:08:23 -07:00 committed by GitHub
parent cdc761d920
commit e56ac9ab55
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 85 additions and 18 deletions

View file

@ -29,8 +29,8 @@ struct LegoBuildingInfo {
MxS8 m_unk0x11; // 0x11 MxS8 m_unk0x11; // 0x11
MxS8 m_initialUnk0x11; // 0x12 - initial value loaded to m_unk0x11 MxS8 m_initialUnk0x11; // 0x12 - initial value loaded to m_unk0x11
MxU8 m_flags; // 0x13 MxU8 m_flags; // 0x13
float m_unk0x014; // 0x14 float m_unk0x14; // 0x14
const char* m_unk0x18; // 0x18 const char* m_boundaryName; // 0x18
float m_x; // 0x1c float m_x; // 0x1c
float m_y; // 0x20 float m_y; // 0x20
float m_z; // 0x24 float m_z; // 0x24
@ -100,7 +100,7 @@ class LegoBuildingManager : public MxCore {
static MxU32 g_maxSound; static MxU32 g_maxSound;
MxU8 m_nextVariant; // 0x08 MxU8 m_nextVariant; // 0x08
MxU8 m_unk0x09; // 0x09 MxBool m_unk0x09; // 0x09
AnimEntry* m_entries[5]; // 0x0c AnimEntry* m_entries[5]; // 0x0c
MxS8 m_numEntries; // 0x20 MxS8 m_numEntries; // 0x20
LegoCacheSound* m_sound; // 0x24 LegoCacheSound* m_sound; // 0x24

View file

@ -9,6 +9,7 @@
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
#include "misc/legostorage.h" #include "misc/legostorage.h"
#include "mxdebug.h"
#include "mxmisc.h" #include "mxmisc.h"
#include "mxticklemanager.h" #include "mxticklemanager.h"
#include "mxtimer.h" #include "mxtimer.h"
@ -251,7 +252,7 @@ void LegoBuildingManager::Init()
} }
m_nextVariant = 0; m_nextVariant = 0;
m_unk0x09 = 0; m_unk0x09 = FALSE;
m_numEntries = 0; m_numEntries = 0;
m_sound = NULL; m_sound = NULL;
m_unk0x28 = FALSE; m_unk0x28 = FALSE;
@ -272,7 +273,7 @@ void LegoBuildingManager::LoadWorldInfo()
LegoEntity* entity = (LegoEntity*) world->Find("MxEntity", g_buildingInfoVariants[0]); LegoEntity* entity = (LegoEntity*) world->Find("MxEntity", g_buildingInfoVariants[0]);
if (entity) { if (entity) {
entity->GetROI()->SetVisibility(TRUE); entity->GetROI()->SetVisibility(TRUE);
m_unk0x09 = 0; m_unk0x09 = FALSE;
} }
} }
else { else {
@ -284,7 +285,7 @@ void LegoBuildingManager::LoadWorldInfo()
} }
} }
m_unk0x09 = 0; m_unk0x09 = FALSE;
} }
// FUNCTION: LEGO1 0x1002fa90 // FUNCTION: LEGO1 0x1002fa90
@ -299,7 +300,7 @@ void LegoBuildingManager::CreateBuilding(MxS32 p_index, LegoWorld* p_world)
LegoROI* roi = entity->GetROI(); LegoROI* roi = entity->GetROI();
AdjustHeight(p_index); AdjustHeight(p_index);
MxMatrix mat = roi->GetLocal2World(); MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[p_index].m_unk0x014; mat[3][1] = g_buildingInfo[p_index].m_unk0x14;
roi->UpdateTransformationRelativeToParent(mat); roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*roi); VideoManager()->Get3DManager()->Moved(*roi);
} }
@ -314,7 +315,7 @@ void LegoBuildingManager::Reset()
g_buildingInfo[i].m_entity = NULL; g_buildingInfo[i].m_entity = NULL;
} }
m_unk0x09 = 0; m_unk0x09 = FALSE;
for (i = 0; i < m_numEntries; i++) { for (i = 0; i < m_numEntries; i++) {
delete m_entries[i]; delete m_entries[i];
@ -402,13 +403,13 @@ void LegoBuildingManager::AdjustHeight(MxS32 p_index)
{ {
if (g_buildingInfo[p_index].m_unk0x11 > 0) { if (g_buildingInfo[p_index].m_unk0x11 > 0) {
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11; float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11;
g_buildingInfo[p_index].m_unk0x014 = g_buildingInfo[p_index].m_unk0x14 =
g_buildingInfoInit[p_index].m_unk0x014 - value * g_buildingInfoDownshiftScale[p_index]; g_buildingInfoInit[p_index].m_unk0x14 - value * g_buildingInfoDownshiftScale[p_index];
} }
else if (g_buildingInfo[p_index].m_unk0x11 == 0) { else if (g_buildingInfo[p_index].m_unk0x11 == 0) {
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11; float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11;
g_buildingInfo[p_index].m_unk0x014 = g_buildingInfo[p_index].m_unk0x14 =
g_buildingInfoInit[p_index].m_unk0x014 - value * g_buildingInfoDownshiftScale[p_index]; g_buildingInfoInit[p_index].m_unk0x14 - value * g_buildingInfoDownshiftScale[p_index];
if (g_buildingInfo[p_index].m_entity != NULL) { if (g_buildingInfo[p_index].m_entity != NULL) {
LegoROI* roi = g_buildingInfo[p_index].m_entity->GetROI(); LegoROI* roi = g_buildingInfo[p_index].m_entity->GetROI();
@ -418,7 +419,7 @@ void LegoBuildingManager::AdjustHeight(MxS32 p_index)
} }
} }
else { else {
g_buildingInfo[p_index].m_unk0x014 = g_buildingInfoInit[p_index].m_unk0x014; g_buildingInfo[p_index].m_unk0x14 = g_buildingInfoInit[p_index].m_unk0x14;
} }
} }
@ -637,7 +638,7 @@ MxBool LegoBuildingManager::FUN_10030030(MxS32 p_index)
else { else {
AdjustHeight(p_index); AdjustHeight(p_index);
MxMatrix mat = roi->GetLocal2World(); MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[p_index].m_unk0x014; mat[3][1] = g_buildingInfo[p_index].m_unk0x14;
roi->UpdateTransformationRelativeToParent(mat); roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*roi); VideoManager()->Get3DManager()->Moved(*roi);
} }
@ -739,7 +740,7 @@ MxResult LegoBuildingManager::Tickle()
MxS32 index = info - g_buildingInfo; MxS32 index = info - g_buildingInfo;
AdjustHeight(index); AdjustHeight(index);
MxMatrix mat = entry->m_roi->GetLocal2World(); MxMatrix mat = entry->m_roi->GetLocal2World();
mat[3][1] = g_buildingInfo[index].m_unk0x014; mat[3][1] = g_buildingInfo[index].m_unk0x14;
entry->m_roi->UpdateTransformationRelativeToParent(mat); entry->m_roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*entry->m_roi); VideoManager()->Get3DManager()->Moved(*entry->m_roi);
} }
@ -778,23 +779,87 @@ void LegoBuildingManager::FUN_10030590()
if (g_buildingInfo[i].m_entity != NULL) { if (g_buildingInfo[i].m_entity != NULL) {
LegoROI* roi = g_buildingInfo[i].m_entity->GetROI(); LegoROI* roi = g_buildingInfo[i].m_entity->GetROI();
MxMatrix mat = roi->GetLocal2World(); MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[i].m_unk0x014; mat[3][1] = g_buildingInfo[i].m_unk0x14;
roi->UpdateTransformationRelativeToParent(mat); roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*roi); VideoManager()->Get3DManager()->Moved(*roi);
} }
} }
} }
// STUB: LEGO1 0x10030630 // FUNCTION: LEGO1 0x10030630
// FUNCTION: BETA10 0x100648ab
MxResult LegoBuildingManager::FUN_10030630() MxResult LegoBuildingManager::FUN_10030630()
{ {
LegoWorld* world = CurrentWorld();
if (world == NULL) {
return FAILURE;
}
for (MxS32 i = 0; i < sizeOfArray(g_buildingInfo); i++) {
if (g_buildingInfo[i].m_entity != NULL && g_buildingInfo[i].m_boundaryName != NULL) {
g_buildingInfo[i].m_boundary = world->FindPathBoundary(g_buildingInfo[i].m_boundaryName);
if (g_buildingInfo[i].m_boundary != NULL) {
Mx3DPointFloat position(g_buildingInfo[i].m_x, g_buildingInfo[i].m_y, g_buildingInfo[i].m_z);
LegoPathBoundary* boundary = g_buildingInfo[i].m_boundary;
for (MxS32 j = 0; j < boundary->GetNumEdges(); j++) {
Mx4DPointFloat* normal = boundary->GetEdgeNormal(j);
if (position.Dot(normal, &position) + (*normal)[3] < -0.001) {
MxTrace(
"Building %d shot location (%g, %g, %g) is not in boundary %s.\n",
i,
position[0],
position[1],
position[2],
boundary->GetName()
);
g_buildingInfo[i].m_boundary = NULL;
break;
}
}
if (g_buildingInfo[i].m_boundary != NULL) {
Mx4DPointFloat& unk0x14 = *g_buildingInfo[i].m_boundary->GetUnknown0x14();
if (position.Dot(&position, &unk0x14) + unk0x14[3] <= 0.001 &&
position.Dot(&position, &unk0x14) + unk0x14[3] >= -0.001) {
continue;
}
g_buildingInfo[i].m_y =
-((unk0x14[3] + unk0x14[0] * position[0] + unk0x14[2] * position[2]) / unk0x14[1]);
MxTrace(
"Building %d shot location (%g, %g, %g) is not on plane of boundary %s...adjusting to (%g, %g, "
"%g)\n",
i,
position[0],
position[1],
position[2],
g_buildingInfo[i].m_boundary->GetName(),
position[0],
g_buildingInfo[i].m_y,
position[2]
);
}
}
else {
MxTrace("Building %d is in boundary %s that does not exist.\n", i, g_buildingInfo[i].m_boundaryName);
}
}
}
m_unk0x09 = TRUE;
return SUCCESS; return SUCCESS;
} }
// FUNCTION: LEGO1 0x10030790 // FUNCTION: LEGO1 0x10030790
LegoBuildingInfo* LegoBuildingManager::GetInfoArray(MxS32& p_length) LegoBuildingInfo* LegoBuildingManager::GetInfoArray(MxS32& p_length)
{ {
if (m_unk0x09 == 0) { if (!m_unk0x09) {
FUN_10030630(); FUN_10030630();
} }

View file

@ -16,6 +16,7 @@ class LegoWEEdge {
virtual LegoResult VTable0x04(); // vtable+0x04 virtual LegoResult VTable0x04(); // vtable+0x04
// FUNCTION: BETA10 0x1001c980
LegoU8 GetNumEdges() { return m_numEdges; } LegoU8 GetNumEdges() { return m_numEdges; }
// FUNCTION: BETA10 0x1001cc30 // FUNCTION: BETA10 0x1001cc30

View file

@ -46,6 +46,7 @@ class LegoWEGEdge : public LegoWEEdge {
// FUNCTION: BETA10 0x1001ff80 // FUNCTION: BETA10 0x1001ff80
Mx4DPointFloat* GetUnknown0x14() { return &m_unk0x14; } Mx4DPointFloat* GetUnknown0x14() { return &m_unk0x14; }
// FUNCTION: BETA10 0x1001ca10
Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; } Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; }
// FUNCTION: BETA10 0x1001c9b0 // FUNCTION: BETA10 0x1001c9b0