mirror of
https://github.com/isledecomp/isle.git
synced 2024-11-23 16:18:31 -05:00
Complete LegoCarBuild
(#1144)
* Complete `LegoCarBuild` * Fix match error * Address review comments * Fix regression * Fix minor sign comparison issue --------- Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
parent
26f8dd1a6a
commit
6cda0d95c7
9 changed files with 163 additions and 9 deletions
|
@ -126,9 +126,12 @@ class LegoCarBuild : public LegoWorld {
|
||||||
); // vtable+0x80
|
); // vtable+0x80
|
||||||
|
|
||||||
MxS16 GetPlacedPartCount();
|
MxS16 GetPlacedPartCount();
|
||||||
|
void SetPlacedPartCount(MxU8 p_placedPartCount);
|
||||||
void InitPresenters();
|
void InitPresenters();
|
||||||
|
void FUN_10022f00();
|
||||||
void FUN_10022f30();
|
void FUN_10022f30();
|
||||||
void FUN_10023130(MxLong p_x, MxLong p_y);
|
void FUN_10023130(MxLong p_x, MxLong p_y);
|
||||||
|
void FUN_100236d0();
|
||||||
undefined4 FUN_10024250(LegoEventNotificationParam* p_param);
|
undefined4 FUN_10024250(LegoEventNotificationParam* p_param);
|
||||||
void FUN_100243a0();
|
void FUN_100243a0();
|
||||||
undefined4 FUN_10024480(MxActionNotificationParam* p_param);
|
undefined4 FUN_10024480(MxActionNotificationParam* p_param);
|
||||||
|
|
|
@ -70,6 +70,7 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
|
||||||
void FUN_10079680(LegoChar* p_param);
|
void FUN_10079680(LegoChar* p_param);
|
||||||
LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
|
LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
|
||||||
LegoTreeNode* FindNodeByName(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);
|
void RotateAroundYAxis(MxFloat p_angle);
|
||||||
MxBool FUN_10079c30(const LegoChar* p_name);
|
MxBool FUN_10079c30(const LegoChar* p_name);
|
||||||
MxBool PartIsPlaced(const LegoChar* p_name);
|
MxBool PartIsPlaced(const LegoChar* p_name);
|
||||||
|
@ -77,7 +78,7 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
|
||||||
MxBool StringEqualsPlatform(const LegoChar* p_string);
|
MxBool StringEqualsPlatform(const LegoChar* p_string);
|
||||||
MxBool StringEqualsShelf(const LegoChar* p_string);
|
MxBool StringEqualsShelf(const LegoChar* p_string);
|
||||||
MxBool StringEndsOnY(const LegoChar* p_string);
|
MxBool StringEndsOnY(const LegoChar* p_string);
|
||||||
MxBool StringEndsOnZero(const LegoChar* p_string);
|
MxBool StringDoesNotEndOnZero(const LegoChar* p_string);
|
||||||
const LegoChar* GetWiredNameByPartName(const LegoChar* p_name);
|
const LegoChar* GetWiredNameByPartName(const LegoChar* p_name);
|
||||||
void SetPartObjectIdByName(const LegoChar* p_name, MxS16 p_objectId);
|
void SetPartObjectIdByName(const LegoChar* p_name, MxS16 p_objectId);
|
||||||
|
|
||||||
|
@ -130,7 +131,7 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
|
||||||
MxFloat m_unk0x130; // 0x130
|
MxFloat m_unk0x130; // 0x130
|
||||||
MxFloat m_unk0x134; // 0x134
|
MxFloat m_unk0x134; // 0x134
|
||||||
MxFloat m_unk0x138; // 0x138
|
MxFloat m_unk0x138; // 0x138
|
||||||
MxLong m_unk0x13c; // 0x13c
|
MxULong m_unk0x13c; // 0x13c
|
||||||
LegoEntity* m_unk0x140; // 0x140
|
LegoEntity* m_unk0x140; // 0x140
|
||||||
MxS32 m_unk0x144; // 0x144
|
MxS32 m_unk0x144; // 0x144
|
||||||
MxS32 m_unk0x148; // 0x148
|
MxS32 m_unk0x148; // 0x148
|
||||||
|
|
|
@ -28,6 +28,7 @@ enum Cursor {
|
||||||
e_cursorNone
|
e_cursorNone
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BoundingSphere;
|
||||||
class MxAtomId;
|
class MxAtomId;
|
||||||
class LegoEntity;
|
class LegoEntity;
|
||||||
class LegoFile;
|
class LegoFile;
|
||||||
|
@ -43,6 +44,7 @@ LegoEntity* PickEntity(MxLong, MxLong);
|
||||||
LegoROI* PickROI(MxLong, MxLong);
|
LegoROI* PickROI(MxLong, MxLong);
|
||||||
LegoROI* PickParentROI(MxLong p_a, MxLong p_b);
|
LegoROI* PickParentROI(MxLong p_a, MxLong p_b);
|
||||||
void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2);
|
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 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]);
|
MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4]);
|
||||||
MxS16 CountTotalTreeNodes(LegoTreeNode* p_node);
|
MxS16 CountTotalTreeNodes(LegoTreeNode* p_node);
|
||||||
|
|
|
@ -358,6 +358,7 @@ undefined4 MxBackgroundAudioManager::FUN_1007f610(
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1007f650
|
// FUNCTION: LEGO1 0x1007f650
|
||||||
|
// FUNCTION: BETA10 0x100e9663
|
||||||
void MxBackgroundAudioManager::Init()
|
void MxBackgroundAudioManager::Init()
|
||||||
{
|
{
|
||||||
this->m_unk0xa0 = 0;
|
this->m_unk0xa0 = 0;
|
||||||
|
|
|
@ -196,7 +196,7 @@ MxResult LegoCarBuild::Create(MxDSAction& p_dsAction)
|
||||||
else if (m_atomId == *g_racecarScript) {
|
else if (m_atomId == *g_racecarScript) {
|
||||||
buildStateClassName = "LegoRaceCarBuildState";
|
buildStateClassName = "LegoRaceCarBuildState";
|
||||||
GameState()->m_currentArea = LegoGameState::e_racecarbuild;
|
GameState()->m_currentArea = LegoGameState::e_racecarbuild;
|
||||||
m_carId = Helicopter_Actor;
|
m_carId = RaceCar_Actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
LegoGameState* gameState = GameState();
|
LegoGameState* gameState = GameState();
|
||||||
|
@ -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: LEGO1 0x10022d10
|
||||||
// FUNCTION: BETA10 0x1006b27a
|
// FUNCTION: BETA10 0x1006b27a
|
||||||
void LegoCarBuild::InitPresenters()
|
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: LEGO1 0x10022f30
|
||||||
// FUNCTION: BETA10 0x1006b835
|
// FUNCTION: BETA10 0x1006b835
|
||||||
void LegoCarBuild::FUN_10022f30()
|
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;
|
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) \
|
#define LEGOCARBUILD_TICKLE_CASE(subtract, start, end, str) \
|
||||||
if (start < dTime && dTime < end) { \
|
if (start < dTime && dTime < end) { \
|
||||||
FUN_10025db0(str, dTime - subtract); \
|
FUN_10025db0(str, dTime - subtract); \
|
||||||
|
@ -812,11 +879,49 @@ undefined4 LegoCarBuild::FUN_100244e0(MxLong p_x, MxLong p_y)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100246e0
|
// FUNCTION: LEGO1 0x100246e0
|
||||||
undefined4 LegoCarBuild::FUN_100246e0(MxLong p_x, MxLong p_y)
|
undefined4 LegoCarBuild::FUN_100246e0(MxLong p_x, MxLong p_y)
|
||||||
{
|
{
|
||||||
// TODO
|
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;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10024850
|
// FUNCTION: LEGO1 0x10024850
|
||||||
|
@ -1207,7 +1312,7 @@ void LegoCarBuild::TogglePresentersEnabled()
|
||||||
// FUNCTION: BETA10 0x1006e124
|
// FUNCTION: BETA10 0x1006e124
|
||||||
void LegoCarBuild::FUN_100250e0(MxBool p_enabled)
|
void LegoCarBuild::FUN_100250e0(MxBool p_enabled)
|
||||||
{
|
{
|
||||||
if (m_unk0x258->StringEndsOnZero(m_unk0x110->GetName()) && m_Decals_Ctl) {
|
if (m_unk0x258->StringDoesNotEndOnZero(m_unk0x110->GetName()) && m_Decals_Ctl) {
|
||||||
if (strnicmp(m_unk0x110->GetName(), "JSFRNT", strlen("JSFRNT")) == 0) {
|
if (strnicmp(m_unk0x110->GetName(), "JSFRNT", strlen("JSFRNT")) == 0) {
|
||||||
m_Decal_Bitmap->Enable(p_enabled);
|
m_Decal_Bitmap->Enable(p_enabled);
|
||||||
m_Decals_Ctl->Enable(p_enabled);
|
m_Decals_Ctl->Enable(p_enabled);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "legovideomanager.h"
|
#include "legovideomanager.h"
|
||||||
#include "legoworld.h"
|
#include "legoworld.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "misc/legoutil.h"
|
||||||
#include "mxautolock.h"
|
#include "mxautolock.h"
|
||||||
#include "mxcompositepresenter.h"
|
#include "mxcompositepresenter.h"
|
||||||
#include "mxmisc.h"
|
#include "mxmisc.h"
|
||||||
|
@ -507,6 +508,35 @@ LegoTreeNode* LegoCarBuildAnimPresenter::FindNodeByName(LegoTreeNode* p_treeNode
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
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);
|
||||||
|
Swap(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: LEGO1 0x10079920
|
||||||
// FUNCTION: BETA10 0x1007225d
|
// FUNCTION: BETA10 0x1007225d
|
||||||
void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle)
|
void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle)
|
||||||
|
@ -622,9 +652,9 @@ MxBool LegoCarBuildAnimPresenter::StringEndsOnY(const LegoChar* p_string)
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10079d30
|
// FUNCTION: LEGO1 0x10079d30
|
||||||
// FUNCTION: BETA10 0x1007280e
|
// FUNCTION: BETA10 0x1007280e
|
||||||
MxBool LegoCarBuildAnimPresenter::StringEndsOnZero(const LegoChar* p_string)
|
MxBool LegoCarBuildAnimPresenter::StringDoesNotEndOnZero(const LegoChar* p_string)
|
||||||
{
|
{
|
||||||
return (p_string[strlen(p_string) - 2] != '0');
|
return (p_string[strlen(p_string) - 1] != '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10079d60
|
// FUNCTION: LEGO1 0x10079d60
|
||||||
|
|
|
@ -72,6 +72,14 @@ void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2)
|
||||||
// TODO
|
// 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: LEGO1 0x1003ded0
|
||||||
// FUNCTION: BETA10 0x100d3802
|
// FUNCTION: BETA10 0x100d3802
|
||||||
MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3])
|
MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3])
|
||||||
|
|
|
@ -64,6 +64,7 @@ MxAtomId* g_act2mainScript = NULL;
|
||||||
MxAtomId* g_act3Script = NULL;
|
MxAtomId* g_act3Script = NULL;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f456c
|
// GLOBAL: LEGO1 0x100f456c
|
||||||
|
// GLOBAL: BETA10 0x102114e0
|
||||||
MxAtomId* g_jukeboxScript = NULL;
|
MxAtomId* g_jukeboxScript = NULL;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f4570
|
// GLOBAL: LEGO1 0x100f4570
|
||||||
|
|
|
@ -39,6 +39,9 @@ inline void Swap(T& p_t1, T& p_t2)
|
||||||
p_t2 = t;
|
p_t2 = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEMPLATE: BETA10 0x10073c20
|
||||||
|
// Swap
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T DToR(T p_d)
|
inline T DToR(T p_d)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue