mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-23 16:34:06 +00:00
Implement FUN_10025720()
and others (#1134)
* Implement `FUN_10025720()` and others * Address review comments, get 100 % --------- Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "mxstillpresenter.h"
|
||||
#include "mxticklemanager.h"
|
||||
#include "mxtransitionmanager.h"
|
||||
#include "mxvariabletable.h"
|
||||
#include "racecar.h"
|
||||
#include "racecar_actions.h"
|
||||
#include "scripts.h"
|
||||
@@ -40,6 +41,42 @@
|
||||
|
||||
DECOMP_SIZE_ASSERT(LegoCarBuild, 0x34c)
|
||||
DECOMP_SIZE_ASSERT(LegoVehicleBuildState, 0x50)
|
||||
DECOMP_SIZE_ASSERT(LegoCarBuild::LookupTableActions, 0x1c);
|
||||
|
||||
// These four structs can be matched to the vehicle types using BETA10 0x10070520
|
||||
|
||||
// GLOBAL: LEGO1 0x100d65b0
|
||||
// GLOBAL: BETA10 0x101bb7c0
|
||||
LegoCarBuild::LookupTableActions LegoCarBuild::g_unk0x100d65b0[] = {
|
||||
{DunecarScript::c_igs001d3_RunAnim,
|
||||
DunecarScript::c_igs002d3_RunAnim,
|
||||
DunecarScript::c_igs003d3_RunAnim,
|
||||
DunecarScript::c_igs004d3_RunAnim,
|
||||
DunecarScript::c_igs005d3_RunAnim,
|
||||
DunecarScript::c_igs004d3_RunAnim,
|
||||
DunecarScript::c_igsxx1d3_RunAnim},
|
||||
{JetskiScript::c_ijs001d4_RunAnim,
|
||||
JetskiScript::c_ijs003d4_RunAnim,
|
||||
JetskiScript::c_ijs004d4_RunAnim,
|
||||
JetskiScript::c_ijs005d4_RunAnim,
|
||||
JetskiScript::c_ijs006d4_RunAnim,
|
||||
JetskiScript::c_ijs007d4_RunAnim,
|
||||
JetskiScript::c_ijsxx2d4_RunAnim},
|
||||
{CopterScript::c_ips001d2_RunAnim,
|
||||
CopterScript::c_ips002d2_RunAnim,
|
||||
CopterScript::c_ips003d2_RunAnim,
|
||||
CopterScript::c_ips005d2_RunAnim,
|
||||
CopterScript::c_ips004d2_RunAnim,
|
||||
CopterScript::c_ips004d2_RunAnim,
|
||||
CopterScript::c_ipsxx1d2_RunAnim},
|
||||
{RacecarScript::c_irt001d1_RunAnim,
|
||||
RacecarScript::c_irt002d1_RunAnim,
|
||||
RacecarScript::c_irt003d1_RunAnim,
|
||||
RacecarScript::c_irt004d1_RunAnim,
|
||||
RacecarScript::c_irt005d1_RunAnim,
|
||||
RacecarScript::c_irt004d1_RunAnim,
|
||||
RacecarScript::c_irtxx4d1_RunAnim}
|
||||
};
|
||||
|
||||
// GLOBAL: LEGO1 0x100d65a4
|
||||
MxFloat LegoCarBuild::g_unk0x100d65a4 = -0.1f;
|
||||
@@ -84,10 +121,10 @@ LegoCarBuild::LegoCarBuild()
|
||||
m_buildState = NULL;
|
||||
m_unk0x104 = 0;
|
||||
m_unk0x109 = 0;
|
||||
m_unk0x108 = 0;
|
||||
m_numAnimsRun = 0;
|
||||
m_unk0x338 = 0;
|
||||
m_destLocation = LegoGameState::e_undefined;
|
||||
m_unk0x344 = 0xffffffff;
|
||||
m_unk0x344 = DS_NOT_A_STREAM;
|
||||
m_unk0x174 = 0;
|
||||
NotificationManager()->Register(this);
|
||||
}
|
||||
@@ -610,8 +647,8 @@ MxLong LegoCarBuild::Notify(MxParam& p_param)
|
||||
|
||||
break;
|
||||
case c_notificationEndAnim:
|
||||
if (m_unk0x108 > 0) {
|
||||
m_unk0x108 -= 1;
|
||||
if (m_numAnimsRun > 0) {
|
||||
m_numAnimsRun -= 1;
|
||||
}
|
||||
|
||||
FUN_10025e40();
|
||||
@@ -632,7 +669,7 @@ MxLong LegoCarBuild::Notify(MxParam& p_param)
|
||||
undefined4 LegoCarBuild::FUN_10024250(LegoEventNotificationParam* p_param)
|
||||
{
|
||||
if (p_param->GetKey() == ' ' && m_buildState->m_animationState != 4 && m_buildState->m_animationState != 2) {
|
||||
if (m_unk0x108 > 0) {
|
||||
if (m_numAnimsRun > 0) {
|
||||
DeleteObjects(&m_atomId, 500, 0x1fe);
|
||||
BackgroundAudioManager()->RaiseVolume();
|
||||
m_unk0x109 = 0;
|
||||
@@ -815,7 +852,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
|
||||
m_buildState->m_animationState != LegoVehicleBuildState::e_unknown2 &&
|
||||
m_buildState->m_animationState != LegoVehicleBuildState::e_exiting &&
|
||||
GameState()->GetCurrentAct() != LegoGameState::e_act2) {
|
||||
if (m_unk0x108 > 0) {
|
||||
if (m_numAnimsRun > 0) {
|
||||
DeleteObjects(&m_atomId, 500, 510);
|
||||
}
|
||||
|
||||
@@ -829,7 +866,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
|
||||
case CopterScript::c_Exit_Ctl:
|
||||
if (m_buildState->m_animationState != LegoVehicleBuildState::e_exiting &&
|
||||
m_buildState->m_animationState != LegoVehicleBuildState::e_unknown4) {
|
||||
if (m_unk0x108 > 0) {
|
||||
if (m_numAnimsRun > 0) {
|
||||
DeleteObjects(&m_atomId, 500, 510);
|
||||
}
|
||||
|
||||
@@ -1201,11 +1238,44 @@ void LegoCarBuild::FUN_100250e0(MxBool p_enabled)
|
||||
}
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x10025350
|
||||
// STUB: BETA10 0x1006e3c0
|
||||
void LegoCarBuild::FUN_10025350(MxS32 p_param)
|
||||
// FUNCTION: LEGO1 0x10025350
|
||||
// FUNCTION: BETA10 0x1006e3c0
|
||||
void LegoCarBuild::FUN_10025350(MxS32 p_objectId)
|
||||
{
|
||||
// TODO
|
||||
const LegoChar* color;
|
||||
LegoChar buffer[256];
|
||||
|
||||
if (!m_unk0x110) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Yellow_Ctl->GetAction()->GetObjectId() == p_objectId) {
|
||||
color = "lego yellow";
|
||||
}
|
||||
else if (m_Red_Ctl->GetAction()->GetObjectId() == p_objectId) {
|
||||
color = "lego red";
|
||||
}
|
||||
else if (m_Blue_Ctl->GetAction()->GetObjectId() == p_objectId) {
|
||||
color = "lego blue";
|
||||
}
|
||||
else if (m_Green_Ctl->GetAction()->GetObjectId() == p_objectId) {
|
||||
color = "lego green";
|
||||
}
|
||||
else if (m_Gray_Ctl->GetAction()->GetObjectId() == p_objectId) {
|
||||
color = "lego white";
|
||||
}
|
||||
else if (m_Black_Ctl->GetAction()->GetObjectId() == p_objectId) {
|
||||
color = "lego black";
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Paint_Sound->Enable(FALSE);
|
||||
m_Paint_Sound->Enable(TRUE);
|
||||
m_unk0x110->FUN_100a93b0(color);
|
||||
sprintf(buffer, "c_%s", m_unk0x110->GetName());
|
||||
VariableTable()->SetVariable(buffer, color);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10025450
|
||||
@@ -1277,12 +1347,172 @@ void LegoCarBuild::Enable(MxBool p_enable)
|
||||
}
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x10025720
|
||||
// STUB: BETA10 0x1006e9df
|
||||
undefined4 LegoCarBuild::FUN_10025720(undefined4 p_param1)
|
||||
// FUNCTION: BETA10 0x10070520
|
||||
inline MxU32 LegoCarBuild::Beta0x10070520()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
switch (m_carId) {
|
||||
case Helicopter_Actor:
|
||||
return 2;
|
||||
case DuneBugy_Actor:
|
||||
return 0;
|
||||
case Jetski_Actor:
|
||||
return 1;
|
||||
case RaceCar_Actor:
|
||||
return 3;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void LegoCarBuild::StopActionIn0x344()
|
||||
{
|
||||
// There is no direct evidence for this inline function in LEGO1,
|
||||
// but some code doesn't make much sense otherwise. For example,
|
||||
// sometimes `m_unk0x344` is set to another value right below this call,
|
||||
// which the original developer would likely have refactored.
|
||||
if (m_unk0x344 != DS_NOT_A_STREAM) {
|
||||
InvokeAction(Extra::ActionType::e_stop, m_atomId, m_unk0x344, NULL);
|
||||
m_unk0x344 = DS_NOT_A_STREAM;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10025720
|
||||
// FUNCTION: BETA10 0x1006e9df
|
||||
void LegoCarBuild::FUN_10025720(undefined4 p_param)
|
||||
{
|
||||
m_numAnimsRun++;
|
||||
m_unk0x10a = 0;
|
||||
MxS32 uVar6;
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
if (GameState()->GetCurrentAct() == LegoGameState::e_act2) {
|
||||
// This is most likely related to the helicopter rebuild in Act 2
|
||||
switch (p_param) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
switch (rand() % 3) {
|
||||
case 0:
|
||||
m_unk0x10a = CopterScript::c_ips004d2_RunAnim;
|
||||
StopActionIn0x344();
|
||||
m_unk0x344 = CopterScript::c_ips004d2_RunAnim;
|
||||
BackgroundAudioManager()->LowerVolume();
|
||||
InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_ips004d2_RunAnim, NULL);
|
||||
break;
|
||||
case 1:
|
||||
m_unk0x10a = CopterScript::c_ips006d2_RunAnim;
|
||||
StopActionIn0x344();
|
||||
m_unk0x344 = CopterScript::c_ips006d2_RunAnim;
|
||||
BackgroundAudioManager()->LowerVolume();
|
||||
InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_ips006d2_RunAnim, NULL);
|
||||
break;
|
||||
case 2:
|
||||
m_unk0x10a = CopterScript::c_slp01xd2_RunAnim;
|
||||
StopActionIn0x344();
|
||||
m_unk0x344 = CopterScript::c_slp01xd2_RunAnim;
|
||||
BackgroundAudioManager()->LowerVolume();
|
||||
InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_slp01xd2_RunAnim, NULL);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x04);
|
||||
break;
|
||||
case 5:
|
||||
FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x08);
|
||||
break;
|
||||
case 6:
|
||||
m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x18;
|
||||
uVar6 = m_unk0x10a;
|
||||
StopActionIn0x344();
|
||||
|
||||
if (uVar6 != DS_NOT_A_STREAM) {
|
||||
m_unk0x344 = uVar6;
|
||||
BackgroundAudioManager()->LowerVolume();
|
||||
InvokeAction(Extra::ActionType::e_start, m_atomId, uVar6, NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
m_numAnimsRun--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
// This part doesn't match BETA10 perfectly, but it's the closest we get without hundreds of #ifdef's
|
||||
switch (p_param) {
|
||||
case 0:
|
||||
m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x00;
|
||||
FUN_10025d10(m_unk0x10a);
|
||||
break;
|
||||
case 1:
|
||||
m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x0c;
|
||||
FUN_10025d10(m_unk0x10a);
|
||||
|
||||
if (m_carId == 2) {
|
||||
m_unk0x10a = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x10;
|
||||
FUN_10025d10(m_unk0x10a);
|
||||
|
||||
if (m_carId != 3) {
|
||||
m_unk0x10a = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case 3:
|
||||
FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x14);
|
||||
break;
|
||||
case 4:
|
||||
FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x04);
|
||||
break;
|
||||
case 5:
|
||||
FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x08);
|
||||
break;
|
||||
case 6:
|
||||
m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x18;
|
||||
FUN_10025d10(m_unk0x10a);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
m_numAnimsRun--;
|
||||
|
||||
// Weird: This assertion can never be executed. The `assert(0)` above was probably introduced later.
|
||||
assert(m_numAnimsRun >= 0);
|
||||
return;
|
||||
}
|
||||
#ifdef NDEBUG
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_unk0x10a != 0) {
|
||||
m_unk0x10c = timeGetTime();
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10025d10
|
||||
// FUNCTION: BETA10 0x10070490
|
||||
void LegoCarBuild::FUN_10025d10(MxS32 p_param)
|
||||
{
|
||||
// this function has a different signature and partially different body in BETA10, but it is called in the same
|
||||
// places
|
||||
if (m_unk0x344 != DS_NOT_A_STREAM) {
|
||||
InvokeAction(Extra::ActionType::e_stop, m_atomId, m_unk0x344, NULL);
|
||||
m_unk0x344 = DS_NOT_A_STREAM;
|
||||
}
|
||||
|
||||
if (p_param != DS_NOT_A_STREAM) {
|
||||
m_unk0x344 = p_param;
|
||||
BackgroundAudioManager()->LowerVolume();
|
||||
InvokeAction(Extra::ActionType::e_start, m_atomId, p_param, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10025d70
|
||||
|
Reference in New Issue
Block a user