mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-27 10:11:15 +00:00
Start work on building save data
* Add LegoBuildingData struct to LegoBuildingManager, naming mirrors LegoCharacterData in LegoCharacterManager. * 100% match of many methods in LegoBuildingManager using the struct.
This commit is contained in:
parent
ec7df356cf
commit
7cd19ed475
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
class LegoEntity;
|
class LegoEntity;
|
||||||
class LegoROI;
|
class LegoROI;
|
||||||
|
class LegoWorld;
|
||||||
|
struct LegoBuildingData;
|
||||||
|
|
||||||
// VTABLE: LEGO1 0x100d6f50
|
// VTABLE: LEGO1 0x100d6f50
|
||||||
// SIZE 0x30
|
// SIZE 0x30
|
||||||
@ -29,13 +31,21 @@ class LegoBuildingManager : public MxCore {
|
|||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void FUN_1002fa00();
|
void FUN_1002fa00();
|
||||||
|
void UpdatePosition(int p_index, LegoWorld* p_world);
|
||||||
void FUN_1002fb30();
|
void FUN_1002fb30();
|
||||||
MxResult Write(LegoStorage* p_storage);
|
MxResult Write(LegoStorage* p_storage);
|
||||||
MxResult Read(LegoStorage* p_storage);
|
MxResult Read(LegoStorage* p_storage);
|
||||||
MxBool FUN_1002fdb0(LegoEntity* p_entity);
|
LegoBuildingData* GetData(LegoEntity* p_entity);
|
||||||
|
MxBool IncrementVariant(LegoEntity* p_entity);
|
||||||
|
MxBool FUN_1002fe40(LegoEntity* p_entity);
|
||||||
|
MxBool FUN_1002fe80(LegoEntity* p_entity);
|
||||||
|
MxBool FUN_1002fed0(LegoEntity* p_entity);
|
||||||
MxU32 FUN_1002ff40(LegoEntity*, MxBool);
|
MxU32 FUN_1002ff40(LegoEntity*, MxBool);
|
||||||
void FUN_10030000(LegoEntity* p_entity);
|
MxBool FUN_10030000(LegoEntity* p_entity);
|
||||||
|
MxBool FUN_10030030(int p_index);
|
||||||
|
MxBool FUN_10030110(LegoBuildingData* p_data);
|
||||||
void FUN_10030590();
|
void FUN_10030590();
|
||||||
|
void AdjustHeight(int p_index);
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1002f940
|
// SYNTHETIC: LEGO1 0x1002f940
|
||||||
// LegoBuildingManager::`scalar deleting destructor'
|
// LegoBuildingManager::`scalar deleting destructor'
|
||||||
@ -43,7 +53,17 @@ class LegoBuildingManager : public MxCore {
|
|||||||
private:
|
private:
|
||||||
static char* g_customizeAnimFile;
|
static char* g_customizeAnimFile;
|
||||||
|
|
||||||
undefined m_unk0x08[0x28]; // 0x08
|
MxU8 m_nextVariant; // 0x08
|
||||||
|
MxU8 m_unk1;
|
||||||
|
void* m_pSomething;
|
||||||
|
undefined4 m_unk2; // 0x10
|
||||||
|
undefined4 m_unk3;
|
||||||
|
undefined4 m_unk4;
|
||||||
|
undefined4 m_unk5;
|
||||||
|
MxU8 m_unk6; // 0x20
|
||||||
|
undefined4 m_unk7; // 0x24
|
||||||
|
MxU8 m_unk8;
|
||||||
|
undefined4 m_unk9; // 0x2c
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LEGOBUILDINGMANAGER_H
|
#endif // LEGOBUILDINGMANAGER_H
|
||||||
|
|||||||
@ -1,13 +1,71 @@
|
|||||||
#include "legobuildingmanager.h"
|
#include "legobuildingmanager.h"
|
||||||
|
|
||||||
|
#include "legoentity.h"
|
||||||
|
|
||||||
|
#include "legoworld.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(LegoBuildingManager, 0x30)
|
DECOMP_SIZE_ASSERT(LegoBuildingManager, 0x30)
|
||||||
|
|
||||||
|
struct LegoBuildingData {
|
||||||
|
LegoEntity* m_pEntity;
|
||||||
|
const char* m_hausName;
|
||||||
|
MxU32 m_int1;
|
||||||
|
MxU32 m_int2;
|
||||||
|
MxU8 m_byte1;
|
||||||
|
MxS8 m_byte2;
|
||||||
|
MxS8 m_initialByte2;
|
||||||
|
MxU8 m_flags;
|
||||||
|
float m_float;
|
||||||
|
char m_unk[16];
|
||||||
|
undefined4 m_something;
|
||||||
|
};
|
||||||
|
|
||||||
|
DECOMP_SIZE_ASSERT(LegoBuildingData, 0x2c);
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x100f3410
|
||||||
|
const char* g_buildingDataHausName[5] = {
|
||||||
|
"haus1",
|
||||||
|
"haus4",
|
||||||
|
"haus5",
|
||||||
|
"haus6",
|
||||||
|
"haus7",
|
||||||
|
};
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x100f3428
|
||||||
|
float g_buildingDataDownshiftScale[16] = {
|
||||||
|
0.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x100f3468
|
||||||
|
MxU8 g_buildingDataDownshift[16] = {
|
||||||
|
5, 5, 5, 5,
|
||||||
|
3, 5, 5, 5,
|
||||||
|
3, 5, 5, 5,
|
||||||
|
5, 5, 5, 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x100f3478
|
||||||
|
LegoBuildingData g_buildingDataTemplate[16];
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x100f3738
|
||||||
|
MxU32 g_buildingCycle1Length = 6;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f37c8
|
// GLOBAL: LEGO1 0x100f37c8
|
||||||
char* LegoBuildingManager::g_customizeAnimFile = NULL;
|
char* LegoBuildingManager::g_customizeAnimFile = NULL;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f37cc
|
// GLOBAL: LEGO1 0x100f37cc
|
||||||
int g_buildingManagerConfig = 1;
|
int g_buildingManagerConfig = 1;
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x10104c30
|
||||||
|
LegoBuildingData g_buildingData[16];
|
||||||
|
|
||||||
|
// Unclear what the offset of this global is.
|
||||||
|
int g_buildingCycle2Length[16];
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1002f8b0
|
// FUNCTION: LEGO1 0x1002f8b0
|
||||||
void LegoBuildingManager::configureLegoBuildingManager(MxS32 p_buildingManagerConfig)
|
void LegoBuildingManager::configureLegoBuildingManager(MxS32 p_buildingManagerConfig)
|
||||||
{
|
{
|
||||||
@ -20,22 +78,66 @@ LegoBuildingManager::LegoBuildingManager()
|
|||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002f960
|
// FUNCTION: LEGO1 0x1002f960
|
||||||
LegoBuildingManager::~LegoBuildingManager()
|
LegoBuildingManager::~LegoBuildingManager()
|
||||||
{
|
{
|
||||||
// TODO
|
delete g_customizeAnimFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002f9d0
|
// FUNCTION: LEGO1 0x1002f9d0
|
||||||
void LegoBuildingManager::Init()
|
void LegoBuildingManager::Init()
|
||||||
{
|
{
|
||||||
// TODO
|
for (MxS32 i = 0; i < _countof(g_buildingData); i++) {
|
||||||
|
g_buildingData[i] = g_buildingDataTemplate[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nextVariant = 0;
|
||||||
|
m_unk1 = 0;
|
||||||
|
m_unk6 = 0;
|
||||||
|
m_unk7 = 0;
|
||||||
|
m_unk8 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002fa00
|
// FUNCTION: LEGO1 0x1002fa00
|
||||||
void LegoBuildingManager::FUN_1002fa00()
|
void LegoBuildingManager::FUN_1002fa00()
|
||||||
{
|
{
|
||||||
// TODO
|
MxS32 i = 0;
|
||||||
|
LegoWorld* world = CurrentWorld();
|
||||||
|
for (; i < _countof(g_buildingData); i++) {
|
||||||
|
UpdatePosition(i, world);
|
||||||
|
}
|
||||||
|
if (g_buildingManagerConfig <= 1) {
|
||||||
|
LegoEntity* entity = (LegoEntity*)world->Find("MxEntity", g_buildingDataHausName[0]);
|
||||||
|
if (entity) {
|
||||||
|
entity->GetROI()->SetVisibility(TRUE);
|
||||||
|
m_unk1 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < _countof(g_buildingDataHausName); i++) {
|
||||||
|
LegoEntity* entity = (LegoEntity*)world->Find("MxEntity", g_buildingDataHausName[i]);
|
||||||
|
if (entity)
|
||||||
|
entity->GetROI()->SetVisibility(m_nextVariant == i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_unk1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x1002fa90
|
||||||
|
void LegoBuildingManager::UpdatePosition(int p_index, LegoWorld* p_world)
|
||||||
|
{
|
||||||
|
LegoEntity* entity = (LegoEntity*)p_world->Find(
|
||||||
|
"MxEntity", g_buildingData[p_index].m_hausName);
|
||||||
|
if (entity) {
|
||||||
|
entity->SetType(3);
|
||||||
|
g_buildingData[p_index].m_pEntity = entity;
|
||||||
|
LegoROI* roi = entity->GetROI();
|
||||||
|
AdjustHeight(p_index);
|
||||||
|
MxMatrix mat = roi->GetLocal2World();
|
||||||
|
mat.SetY(g_buildingData[p_index].m_float);
|
||||||
|
roi->FUN_100a46b0(mat);
|
||||||
|
VideoManager()->Get3DManager()->GetLego3DView()->Moved(*roi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002fb30
|
// STUB: LEGO1 0x1002fb30
|
||||||
@ -44,25 +146,164 @@ void LegoBuildingManager::FUN_1002fb30()
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002fb80
|
// FUNCTION: LEGO1 0x1002fb80
|
||||||
MxResult LegoBuildingManager::Write(LegoStorage* p_storage)
|
MxResult LegoBuildingManager::Write(LegoStorage* p_storage)
|
||||||
{
|
{
|
||||||
return SUCCESS;
|
MxResult result = FAILURE;
|
||||||
|
for (MxS32 i = 0; i < _countof(g_buildingData); i++) {
|
||||||
|
LegoBuildingData* data = &g_buildingData[i];
|
||||||
|
if (p_storage->Write(&data->m_int1, 4) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
if (p_storage->Write(&data->m_int2, 4) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
if (p_storage->Write(&data->m_byte1, 1) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
if (p_storage->Write(&data->m_initialByte2, 1) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (p_storage->Write(&m_nextVariant, 1) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
result = SUCCESS;
|
||||||
|
done:
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002fc10
|
// FUNCTION: LEGO1 0x1002fc10
|
||||||
MxResult LegoBuildingManager::Read(LegoStorage* p_storage)
|
MxResult LegoBuildingManager::Read(LegoStorage* p_storage)
|
||||||
{
|
{
|
||||||
return SUCCESS;
|
MxResult result = FAILURE;
|
||||||
|
for (MxS32 i = 0; i < _countof(g_buildingData); i++) {
|
||||||
|
LegoBuildingData* data = &g_buildingData[i];
|
||||||
|
|
||||||
|
if (p_storage->Read(&data->m_int1, 4) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
if (p_storage->Read(&data->m_int2, 4) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
if (p_storage->Read(&data->m_byte1, 1) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
if (p_storage->Read(&data->m_byte2, 1) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
data->m_initialByte2 = data->m_byte2;
|
||||||
|
AdjustHeight(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_storage->Read(&m_nextVariant, 1) != SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (g_buildingManagerConfig <= 1)
|
||||||
|
m_nextVariant = 0;
|
||||||
|
|
||||||
|
result = SUCCESS;
|
||||||
|
done:
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002fdb0
|
// FUNCTION: LEGO1 0x1002fcc0
|
||||||
MxBool LegoBuildingManager::FUN_1002fdb0(LegoEntity* p_entity)
|
void LegoBuildingManager::AdjustHeight(int p_i)
|
||||||
{
|
{
|
||||||
// TODO
|
// Not close assembly yet.
|
||||||
|
// Does not use any member variables but we can be sure that
|
||||||
|
// this is a THISCALL method because LegoBuildingManager::Read
|
||||||
|
// goes to the trouble of restoring ECX before calling it.
|
||||||
|
MxS8 value = g_buildingData[p_i].m_byte2;
|
||||||
|
if (value > 0) {
|
||||||
|
g_buildingData[p_i].m_float = g_buildingDataTemplate[p_i].m_float -
|
||||||
|
(g_buildingDataDownshift[p_i] - value) * g_buildingDataDownshiftScale[p_i];
|
||||||
|
} else if (value == 0) {
|
||||||
|
g_buildingData[p_i].m_float = g_buildingDataTemplate[p_i].m_float -
|
||||||
|
g_buildingDataDownshift[p_i] * g_buildingDataDownshiftScale[p_i];
|
||||||
|
if (g_buildingData[p_i].m_pEntity != NULL)
|
||||||
|
{
|
||||||
|
LegoROI* roi = g_buildingData[p_i].m_pEntity->GetROI();
|
||||||
|
if (roi != NULL)
|
||||||
|
roi->SetVisibility(FALSE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_buildingData[p_i].m_float = g_buildingDataTemplate[p_i].m_float;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x1002fd70
|
||||||
|
LegoBuildingData* LegoBuildingManager::GetData(LegoEntity* p_entity)
|
||||||
|
{
|
||||||
|
MxS32 i;
|
||||||
|
for (i = 0; i < _countof(g_buildingData); i++) {
|
||||||
|
if (g_buildingData[i].m_pEntity == p_entity)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < _countof(g_buildingData))
|
||||||
|
return &g_buildingData[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x1002fdb0
|
||||||
|
MxBool LegoBuildingManager::IncrementVariant(LegoEntity* p_entity)
|
||||||
|
{
|
||||||
|
if (g_buildingManagerConfig <= 1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
LegoBuildingData* data = GetData(p_entity);
|
||||||
|
if (data != NULL && (data->m_flags & 1) && data->m_byte2 == -1) {
|
||||||
|
LegoROI* roi = p_entity->GetROI();
|
||||||
|
if (++m_nextVariant >= _countof(g_buildingDataHausName))
|
||||||
|
m_nextVariant = 0;
|
||||||
|
|
||||||
|
roi->SetVisibility(FALSE);
|
||||||
|
data->m_hausName = g_buildingDataHausName[m_nextVariant];
|
||||||
|
UpdatePosition(12, CurrentWorld());
|
||||||
|
if (data->m_pEntity != NULL)
|
||||||
|
data->m_pEntity->GetROI()->SetVisibility(TRUE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x1002fe40
|
||||||
|
MxBool LegoBuildingManager::FUN_1002fe40(LegoEntity* p_entity)
|
||||||
|
{
|
||||||
|
MxBool result = FALSE;
|
||||||
|
LegoBuildingData* data = GetData(p_entity);
|
||||||
|
if (data != NULL && (data->m_flags & 2)) {
|
||||||
|
data->m_int1++;
|
||||||
|
if (data->m_int1 >= g_buildingCycle1Length) {
|
||||||
|
data->m_int1 = 0;
|
||||||
|
}
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x1002fe80
|
||||||
|
MxBool LegoBuildingManager::FUN_1002fe80(LegoEntity* p_entity)
|
||||||
|
{
|
||||||
|
MxBool result = FALSE;
|
||||||
|
LegoBuildingData* data = GetData(p_entity);
|
||||||
|
if (data != NULL && (data->m_flags & 4)) {
|
||||||
|
data->m_int2++;
|
||||||
|
if (data->m_int2 >= g_buildingCycle2Length[data - g_buildingData]) {
|
||||||
|
data->m_int2 = 0;
|
||||||
|
}
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x1002fed0
|
||||||
|
MxBool LegoBuildingManager::FUN_1002fed0(LegoEntity* p_entity)
|
||||||
|
{
|
||||||
|
MxBool result = FALSE;
|
||||||
|
LegoBuildingData* data = GetData(p_entity);
|
||||||
|
if (data != NULL && (data->m_flags & 8)) {
|
||||||
|
data->m_byte1++;
|
||||||
|
if (data->m_byte1 > 3) {
|
||||||
|
data->m_byte1 = 0;
|
||||||
|
}
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1002ff40
|
// STUB: LEGO1 0x1002ff40
|
||||||
MxU32 LegoBuildingManager::FUN_1002ff40(LegoEntity*, MxBool)
|
MxU32 LegoBuildingManager::FUN_1002ff40(LegoEntity*, MxBool)
|
||||||
{
|
{
|
||||||
@ -89,10 +330,31 @@ void LegoBuildingManager::SetCustomizeAnimFile(const char* p_value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10030000
|
// FUNCTION: LEGO1 0x10030000
|
||||||
void LegoBuildingManager::FUN_10030000(LegoEntity* p_entity)
|
MxBool LegoBuildingManager::FUN_10030000(LegoEntity* p_entity)
|
||||||
{
|
{
|
||||||
// TODO
|
LegoBuildingData* data = GetData(p_entity);
|
||||||
|
if (data == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return FUN_10030030(data - g_buildingData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// STUB: LEGO1 0x10030030
|
||||||
|
MxBool LegoBuildingManager::FUN_10030030(int p_index)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x10030110
|
||||||
|
MxBool LegoBuildingManager::FUN_10030110(LegoBuildingData* p_data)
|
||||||
|
{
|
||||||
|
for (MxS32 i = 0; i < _countof(g_buildingData); i++) {
|
||||||
|
if (&g_buildingData[i] == p_data) {
|
||||||
|
return FUN_10030030(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10030220
|
// STUB: LEGO1 0x10030220
|
||||||
|
|||||||
@ -290,7 +290,7 @@ void LegoEntity::VTable0x3c()
|
|||||||
PlantManager()->FUN_100269e0(this);
|
PlantManager()->FUN_100269e0(this);
|
||||||
break;
|
break;
|
||||||
case e_building:
|
case e_building:
|
||||||
BuildingManager()->FUN_1002fdb0(this);
|
BuildingManager()->IncrementVariant(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,10 @@ class MxMatrix : public Matrix4 {
|
|||||||
float* operator[](int idx) { return m_data[idx]; }
|
float* operator[](int idx) { return m_data[idx]; }
|
||||||
const float* operator[](int idx) const { return m_data[idx]; }
|
const float* operator[](int idx) const { return m_data[idx]; }
|
||||||
|
|
||||||
|
inline void SetX(float p_x) { m_data[3][0] = p_x; }
|
||||||
|
inline void SetY(float p_y) { m_data[3][1] = p_y; }
|
||||||
|
inline void SetZ(float p_z) { m_data[3][2] = p_z; }
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10002850
|
// FUNCTION: LEGO1 0x10002850
|
||||||
void operator=(const Matrix4& p_matrix) override { Equals(p_matrix); } // vtable+0x28
|
void operator=(const Matrix4& p_matrix) override { Equals(p_matrix); } // vtable+0x28
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user