Implement/match LegoAct2::Enable (#1178)

This commit is contained in:
Christian Semmler 2024-11-29 14:32:40 -07:00 committed by GitHub
parent 362551e279
commit e8e457f01a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 156 additions and 44 deletions

View file

@ -31,7 +31,8 @@ class Act2Brick : public LegoPathActor {
// SYNTHETIC: LEGO1 0x1007a450 // SYNTHETIC: LEGO1 0x1007a450
// Act2Brick::`scalar deleting destructor' // Act2Brick::`scalar deleting destructor'
void StopSound(); void PlayWhistleSound();
void StopWhistleSound();
private: private:
static MxLong g_lastHitActorTime; static MxLong g_lastHitActorTime;

View file

@ -1,6 +1,7 @@
#ifndef ACT3_H #ifndef ACT3_H
#define ACT3_H #define ACT3_H
#include "legogamestate.h"
#include "legostate.h" #include "legostate.h"
#include "legoworld.h" #include "legoworld.h"
@ -69,7 +70,7 @@ class Act3 : public LegoWorld {
void Enable(MxBool p_enable) override; // vtable+0x68 void Enable(MxBool p_enable) override; // vtable+0x68
void SetUnknown420c(MxEntity* p_entity) { m_unk0x420c = p_entity; } void SetUnknown420c(MxEntity* p_entity) { m_unk0x420c = p_entity; }
void SetUnknown4270(MxU32 p_unk0x4270) { m_unk0x4270 = p_unk0x4270; } void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; }
// SYNTHETIC: LEGO1 0x10072630 // SYNTHETIC: LEGO1 0x10072630
// Act3::`scalar deleting destructor' // Act3::`scalar deleting destructor'
@ -80,10 +81,10 @@ class Act3 : public LegoWorld {
void FUN_10073430(); void FUN_10073430();
protected: protected:
undefined m_unk0xf8[0x4114]; // 0xf8 undefined m_unk0xf8[0x4114]; // 0xf8
MxEntity* m_unk0x420c; // 0x420c MxEntity* m_unk0x420c; // 0x420c
undefined m_unk0x4210[0x60]; // 0x4210 undefined m_unk0x4210[0x60]; // 0x4210
MxU32 m_unk0x4270; // 0x4270 LegoGameState::Area m_destLocation; // 0x4270
}; };
#endif // ACT3_H #endif // ACT3_H

View file

@ -17,7 +17,7 @@ class LegoAct2State : public LegoState {
LegoAct2State() LegoAct2State()
{ {
m_unk0x08 = 0; m_unk0x08 = 0;
m_unk0x0c = 0; m_enabled = 0;
} }
~LegoAct2State() override {} ~LegoAct2State() override {}
@ -41,12 +41,11 @@ class LegoAct2State : public LegoState {
// LegoAct2State::`scalar deleting destructor' // LegoAct2State::`scalar deleting destructor'
undefined4 GetUnknown0x08() { return m_unk0x08; } undefined4 GetUnknown0x08() { return m_unk0x08; }
void SetUnknown0x0c(undefined p_unk0x0c) { m_unk0x0c = p_unk0x0c; }
// TODO: Most likely getters/setters are not used according to BETA. // TODO: Most likely getters/setters are not used according to BETA.
undefined4 m_unk0x08; // 0x08 undefined4 m_unk0x08; // 0x08
undefined m_unk0x0c; // 0x0c MxBool m_enabled; // 0x0c
}; };
// VTABLE: LEGO1 0x100d82e0 // VTABLE: LEGO1 0x100d82e0
@ -85,23 +84,26 @@ class LegoAct2 : public LegoWorld {
MxLong HandleEndAction(MxEndActionNotificationParam& p_param); MxLong HandleEndAction(MxEndActionNotificationParam& p_param);
MxLong HandleTransitionEnd(); MxLong HandleTransitionEnd();
MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param); MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param);
void PlayMusic(JukeboxScript::Script p_objectId);
void FUN_10051900(); void FUN_10051900();
void InitBricks();
void UninitBricks();
Act2Brick m_bricks[10]; // 0x00f8 Act2Brick m_bricks[10]; // 0x00f8
undefined m_unk0x10c0; // 0x10c0 undefined m_unk0x10c0; // 0x10c0
undefined m_unk0x10c1; // 0x10c1 undefined m_unk0x10c1; // 0x10c1
undefined m_unk0x10c2; // 0x10c2 undefined m_unk0x10c2; // 0x10c2
undefined4 m_unk0x10c4; // 0x10c4 undefined4 m_unk0x10c4; // 0x10c4
undefined4 m_unk0x10c8; // 0x10c8 JukeboxScript::Script m_music; // 0x10c8
LegoAct2State* m_gameState; // 0x10cc LegoAct2State* m_gameState; // 0x10cc
MxS32 m_unk0x10d0; // 0x10d0 MxS32 m_unk0x10d0; // 0x10d0
// variable name verified by BETA10 0x10014633 // variable name verified by BETA10 0x10014633
char* m_siFile; // 0x10d4 char* m_siFile; // 0x10d4
LegoROI* m_unk0x10d8; // 0x10d8 LegoROI* m_pepper; // 0x10d8
MxMatrix m_unk0x10dc; // 0x10dc MxMatrix m_unk0x10dc; // 0x10dc
undefined4 m_unk0x1124; // 0x1124 LegoPathBoundary* m_unk0x1124; // 0x1124
LegoROI* m_ambulance; // 0x1128 LegoROI* m_ambulance; // 0x1128
undefined4 m_unk0x112c; // 0x112c undefined4 m_unk0x112c; // 0x112c
undefined4 m_unk0x1130; // 0x1130 undefined4 m_unk0x1130; // 0x1130
@ -109,7 +111,7 @@ class LegoAct2 : public LegoWorld {
Act2Actor* m_unk0x1138; // 0x1138 Act2Actor* m_unk0x1138; // 0x1138
undefined m_unk0x113c; // 0x113c undefined m_unk0x113c; // 0x113c
undefined4 m_unk0x1140; // 0x1140 undefined4 m_unk0x1140; // 0x1140
undefined4 m_unk0x1144; // 0x1144 Act2mainScript::Script m_unk0x1144; // 0x1144
undefined m_unk0x1148[0x08]; // 0x1148 undefined m_unk0x1148[0x08]; // 0x1148
LegoGameState::Area m_destLocation; // 0x1150 LegoGameState::Area m_destLocation; // 0x1150
}; };

View file

@ -58,7 +58,7 @@ LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid);
MxDSAction& GetCurrentAction(); MxDSAction& GetCurrentAction();
void SetCurrentWorld(LegoWorld* p_world); void SetCurrentWorld(LegoWorld* p_world);
MxTransitionManager* TransitionManager(); MxTransitionManager* TransitionManager();
void PlayMusic(JukeboxScript::Script p_script); void PlayMusic(JukeboxScript::Script p_objectId);
void SetIsWorldActive(MxBool p_isWorldActive); void SetIsWorldActive(MxBool p_isWorldActive);
void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last); void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last);

View file

@ -62,13 +62,13 @@ MxLong InfoCenterEntity::HandleClick(LegoEventNotificationParam& p_param)
LegoAct2State* act2state = (LegoAct2State*) GameState()->GetState("LegoAct2State"); LegoAct2State* act2state = (LegoAct2State*) GameState()->GetState("LegoAct2State");
if (act2state) { if (act2state) {
act2state->SetUnknown0x0c(0); act2state->m_enabled = FALSE;
} }
break; break;
} }
case LegoGameState::Act::e_act3: case LegoGameState::Act::e_act3:
Act3* act3 = (Act3*) FindWorld(*g_act3Script, Act3Script::c__Act3); Act3* act3 = (Act3*) FindWorld(*g_act3Script, Act3Script::c__Act3);
act3->SetUnknown4270(2); act3->SetDestLocation(LegoGameState::e_infomain);
break; break;
} }

View file

@ -173,7 +173,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
switch (p_param.GetClickedObjectId()) { switch (p_param.GetClickedObjectId()) {
case IsleScript::c_HelicopterArms_Ctl: case IsleScript::c_HelicopterArms_Ctl:
if (*g_act3Script == script) { if (*g_act3Script == script) {
((Act3*) CurrentWorld())->SetUnknown4270(2); ((Act3*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
} }
else if (m_state->GetUnkown8() != 0) { else if (m_state->GetUnkown8() != 0) {

View file

@ -208,11 +208,11 @@ MxTransitionManager* TransitionManager()
} }
// FUNCTION: LEGO1 0x10015910 // FUNCTION: LEGO1 0x10015910
void PlayMusic(JukeboxScript::Script p_script) void PlayMusic(JukeboxScript::Script p_objectId)
{ {
MxDSAction action; MxDSAction action;
action.SetAtomId(*g_jukeboxScript); action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(p_script); action.SetObjectId(p_objectId);
LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating); LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating);
} }

View file

@ -79,7 +79,7 @@ MxLong Act2Brick::Notify(MxParam& p_param)
m_roi->SetVisibility(FALSE); m_roi->SetVisibility(FALSE);
if (m_whistleSound != NULL) { if (m_whistleSound != NULL) {
StopSound(); StopWhistleSound();
} }
MxNotificationParam param(c_notificationType22, this); MxNotificationParam param(c_notificationType22, this);
@ -90,9 +90,18 @@ MxLong Act2Brick::Notify(MxParam& p_param)
return 0; return 0;
} }
// FUNCTION: LEGO1 0x1007a990
// FUNCTION: BETA10 0x10012fca
void Act2Brick::PlayWhistleSound()
{
if (m_whistleSound == NULL) {
m_whistleSound = SoundManager()->GetCacheSoundManager()->Play("xwhistle", m_roi->GetName(), TRUE);
}
}
// FUNCTION: LEGO1 0x1007a9d0 // FUNCTION: LEGO1 0x1007a9d0
// FUNCTION: BETA10 0x1001300f // FUNCTION: BETA10 0x1001300f
void Act2Brick::StopSound() void Act2Brick::StopWhistleSound()
{ {
if (m_whistleSound != NULL) { if (m_whistleSound != NULL) {
SoundManager()->GetCacheSoundManager()->Stop(m_whistleSound); SoundManager()->GetCacheSoundManager()->Stop(m_whistleSound);

View file

@ -4,6 +4,7 @@
#include "act2main_actions.h" #include "act2main_actions.h"
#include "infomain_actions.h" #include "infomain_actions.h"
#include "islepathactor.h" #include "islepathactor.h"
#include "jukebox_actions.h"
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legocachesoundmanager.h" #include "legocachesoundmanager.h"
#include "legogamestate.h" #include "legogamestate.h"
@ -11,6 +12,7 @@
#include "legomain.h" #include "legomain.h"
#include "legopathstruct.h" #include "legopathstruct.h"
#include "legosoundmanager.h" #include "legosoundmanager.h"
#include "legoutils.h"
#include "misc.h" #include "misc.h"
#include "mxactionnotificationparam.h" #include "mxactionnotificationparam.h"
#include "mxbackgroundaudiomanager.h" #include "mxbackgroundaudiomanager.h"
@ -18,6 +20,7 @@
#include "mxmisc.h" #include "mxmisc.h"
#include "mxnotificationmanager.h" #include "mxnotificationmanager.h"
#include "mxticklemanager.h" #include "mxticklemanager.h"
#include "scripts.h"
#include <vec.h> #include <vec.h>
@ -49,7 +52,7 @@ LegoAct2::LegoAct2()
{ {
m_unk0x10c4 = 0; m_unk0x10c4 = 0;
m_gameState = NULL; m_gameState = NULL;
m_unk0x10d8 = NULL; m_pepper = NULL;
m_ambulance = NULL; m_ambulance = NULL;
m_unk0x10c2 = 0; m_unk0x10c2 = 0;
m_unk0x1130 = 0; m_unk0x1130 = 0;
@ -57,9 +60,9 @@ LegoAct2::LegoAct2()
m_unk0x10c1 = 0; m_unk0x10c1 = 0;
m_unk0x1138 = NULL; m_unk0x1138 = NULL;
m_unk0x1140 = 0; m_unk0x1140 = 0;
m_unk0x1144 = 0; m_unk0x1144 = Act2mainScript::c__Act2Main;
m_destLocation = LegoGameState::e_undefined; m_destLocation = LegoGameState::e_undefined;
m_unk0x10c8 = 0; m_music = JukeboxScript::c_MusicTheme1;
m_siFile = ""; m_siFile = "";
m_unk0x113c = 5; m_unk0x113c = 5;
NotificationManager()->Register(this); NotificationManager()->Register(this);
@ -150,7 +153,7 @@ MxResult LegoAct2::Tickle()
m_unk0x10c4 = 1; m_unk0x10c4 = 1;
break; break;
case 1: case 1:
((LegoPathActor*) m_unk0x10d8->GetEntity())->SetState(LegoPathActor::c_bit3); ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3);
switch (rand() % 3) { switch (rand() % 3) {
case 0: case 0:
@ -201,12 +204,12 @@ MxResult LegoAct2::Tickle()
distance = DISTSQRD3(pepperPosition, otherPoint); distance = DISTSQRD3(pepperPosition, otherPoint);
if (m_unk0x1144 == 0 && distance > 50.0f && pepperPosition[0] > -57.0f) { if (m_unk0x1144 == Act2mainScript::c__Act2Main && distance > 50.0f && pepperPosition[0] > -57.0f) {
FUN_10052560(Act2mainScript::c_Avo906In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); FUN_10052560(Act2mainScript::c_Avo906In_PlayWav, FALSE, FALSE, NULL, NULL, NULL);
m_unk0x1144 = Act2mainScript::c_Avo906In_PlayWav; m_unk0x1144 = Act2mainScript::c_Avo906In_PlayWav;
} }
} }
else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == 0) { else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == Act2mainScript::c__Act2Main) {
FUN_10052560(Act2mainScript::c_Avo908In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); FUN_10052560(Act2mainScript::c_Avo908In_PlayWav, FALSE, FALSE, NULL, NULL, NULL);
m_unk0x1144 = Act2mainScript::c_Avo908In_PlayWav; m_unk0x1144 = Act2mainScript::c_Avo908In_PlayWav;
} }
@ -266,7 +269,7 @@ MxLong LegoAct2::Notify(MxParam& p_param)
m_ambulance = FindROI("ambul"); m_ambulance = FindROI("ambul");
} }
if (entity->GetROI() == m_unk0x10d8) { if (entity->GetROI() == m_pepper) {
HandlePathStruct(param); HandlePathStruct(param);
} }
@ -283,12 +286,12 @@ MxLong LegoAct2::Notify(MxParam& p_param)
LegoEntity* entity = (LegoEntity*) param.GetSender(); LegoEntity* entity = (LegoEntity*) param.GetSender();
Mx3DPointFloat entityPosition(entity->GetROI()->GetWorldPosition()); Mx3DPointFloat entityPosition(entity->GetROI()->GetWorldPosition());
Mx3DPointFloat unk0x10d8(m_unk0x10d8->GetWorldPosition()); Mx3DPointFloat unk0x10d8(m_pepper->GetWorldPosition());
Mx3DPointFloat locala4(unk0x10d8); Mx3DPointFloat locala4(unk0x10d8);
((Vector3&) entityPosition).Sub(unk0x10d8); ((Vector3&) entityPosition).Sub(unk0x10d8);
MxMatrix local2world(m_unk0x10d8->GetLocal2World()); MxMatrix local2world(m_pepper->GetLocal2World());
Vector3 local30(local2world[0]); Vector3 local30(local2world[0]);
Vector3 localac(local2world[1]); Vector3 localac(local2world[1]);
Vector3 local28(local2world[2]); Vector3 local28(local2world[2]);
@ -309,7 +312,7 @@ MxLong LegoAct2::Notify(MxParam& p_param)
m_unk0x10c4 = 14; m_unk0x10c4 = 14;
m_unk0x10d0 = 0; m_unk0x10d0 = 0;
((LegoPathActor*) m_unk0x10d8->GetEntity())->SetState(LegoPathActor::c_bit3); ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3);
} }
break; break;
case c_notificationTransitioned: case c_notificationTransitioned:
@ -345,11 +348,76 @@ void LegoAct2::ReadyWorld()
// TODO // TODO
} }
// STUB: LEGO1 0x10050cf0 // FUNCTION: LEGO1 0x10050cf0
// STUB: BETA10 0x1003bb2d // FUNCTION: BETA10 0x1003bb2d
void LegoAct2::Enable(MxBool p_enable) void LegoAct2::Enable(MxBool p_enable)
{ {
// TODO if (m_set0xd0.empty() == p_enable) {
return;
}
LegoWorld::Enable(p_enable);
if (p_enable) {
m_gameState->m_enabled = TRUE;
GameState()->SetActor(LegoActor::c_pepper);
m_pepper = FindROI("pepper");
((IslePathActor*) m_pepper->GetEntity())->VTable0xec(m_unk0x10dc, m_unk0x1124, TRUE);
if (GameState()->GetPreviousArea() == LegoGameState::e_infomain) {
GameState()->StopArea(LegoGameState::e_infomain);
}
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
if (m_unk0x10c4 != 6 && m_unk0x10c4 != 12) {
PlayMusic(m_music);
}
if (m_unk0x10c4 == 10 && m_unk0x10c0 == 6 && m_bricks[5].GetROI() != NULL) {
m_bricks[5].PlayWhistleSound();
}
else if (m_unk0x10c4 == 13) {
InitBricks();
}
TickleManager()->RegisterClient(this, 20);
SetAppCursor(e_cursorArrow);
if (m_unk0x10c4 == 2 || m_unk0x10c4 == 4 || m_unk0x10c4 == 6 || m_unk0x10c4 == 11 || m_unk0x10c4 == 12 ||
m_unk0x10c4 == 14) {
MxDSAction action;
MxEndActionNotificationParam param(c_notificationEndAction, NULL, &action, FALSE);
m_unk0x1140 = 0;
action.SetObjectId(0);
HandleEndAction(param);
}
GameState()->m_isDirty = TRUE;
}
else {
m_unk0x10dc = m_pepper->GetLocal2World();
m_unk0x1124 = ((LegoPathActor*) m_pepper->GetEntity())->GetBoundary();
FUN_10051900();
BackgroundAudioManager()->Stop();
UninitBricks();
DeleteObjects(&m_atomId, Act2mainScript::c_VOhead0_PlayWav, Act2mainScript::c_VOhide_PlayWav);
if (m_unk0x1144 != Act2mainScript::c__Act2Main) {
MxDSAction action;
action.SetAtomId(m_atomId);
action.SetUnknown24(-2);
action.SetObjectId(m_unk0x1144);
DeleteObject(action);
m_unk0x1144 = Act2mainScript::c__Act2Main;
}
TickleManager()->UnregisterClient(this);
}
} }
// STUB: LEGO1 0x10051460 // STUB: LEGO1 0x10051460
@ -360,6 +428,17 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param)
return 0; return 0;
} }
// FUNCTION: LEGO1 0x10051840
void LegoAct2::PlayMusic(JukeboxScript::Script p_objectId)
{
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(p_objectId);
BackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating);
m_music = p_objectId;
}
// FUNCTION: LEGO1 0x10051900 // FUNCTION: LEGO1 0x10051900
// FUNCTION: BETA10 0x1003bed1 // FUNCTION: BETA10 0x1003bed1
void LegoAct2::FUN_10051900() void LegoAct2::FUN_10051900()
@ -394,13 +473,33 @@ MxBool LegoAct2::Escape()
} }
if (m_gameState != NULL) { if (m_gameState != NULL) {
m_gameState->m_unk0x0c = 0; m_gameState->m_enabled = FALSE;
} }
m_destLocation = LegoGameState::e_infomain; m_destLocation = LegoGameState::e_infomain;
return TRUE; return TRUE;
} }
// FUNCTION: LEGO1 0x10051a60
void LegoAct2::InitBricks()
{
for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_bricks); i++) {
if (m_bricks[i].GetROI() != NULL && m_bricks[i].GetROI()->GetVisibility()) {
m_bricks[i].PlayWhistleSound();
}
}
}
// FUNCTION: LEGO1 0x10051a90
void LegoAct2::UninitBricks()
{
for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_bricks); i++) {
if (m_bricks[i].GetROI() != NULL) {
m_bricks[i].StopWhistleSound();
}
}
}
// FUNCTION: LEGO1 0x10052560 // FUNCTION: LEGO1 0x10052560
// FUNCTION: BETA10 0x100145c6 // FUNCTION: BETA10 0x100145c6
undefined4 LegoAct2::FUN_10052560( undefined4 LegoAct2::FUN_10052560(
@ -420,8 +519,8 @@ undefined4 LegoAct2::FUN_10052560(
MxDSAction action; MxDSAction action;
action.SetObjectId(p_param1); action.SetObjectId(p_param1);
// not entirely sure about the constant // World index: see LegoOmni::RegisterWorlds
action.SetAtomId(*Lego()->GetWorldAtom(InfomainScript::c_Cop_Ctl)); action.SetAtomId(*Lego()->GetWorldAtom(15));
if (p_location) { if (p_location) {
action.SetUp(Mx3DPointFloat(0.0f, 1.0f, 0.0f)); action.SetUp(Mx3DPointFloat(0.0f, 1.0f, 0.0f));