isle-portable/LEGO1/lego/legoomni/src/worlds/legoact2.cpp
Christian Semmler 8dd7bc63be
Implement/match LegoAct2::SpawnBricks (#1189)
* Implement/match LegoAct2::SpawnBricks

* Name brick vars

* Add LegoAct2::FUN_10051fa0

* Add LegoAct2::FUN_100521f0
2024-12-04 23:11:16 +01:00

1154 lines
28 KiB
C++

#include "legoact2.h"
#include "3dmanager/lego3dmanager.h"
#include "act2actor.h"
#include "act2main_actions.h"
#include "infomain_actions.h"
#include "islepathactor.h"
#include "jukebox_actions.h"
#include "legoanimationmanager.h"
#include "legocachesoundmanager.h"
#include "legogamestate.h"
#include "legoinputmanager.h"
#include "legolocomotionanimpresenter.h"
#include "legomain.h"
#include "legopathstruct.h"
#include "legosoundmanager.h"
#include "legoutils.h"
#include "legovideomanager.h"
#include "misc.h"
#include "mxactionnotificationparam.h"
#include "mxbackgroundaudiomanager.h"
#include "mxdebug.h"
#include "mxmisc.h"
#include "mxnotificationmanager.h"
#include "mxticklemanager.h"
#include "mxtransitionmanager.h"
#include "mxvariabletable.h"
#include "scripts.h"
#include <vec.h>
DECOMP_SIZE_ASSERT(LegoAct2, 0x1154)
DECOMP_SIZE_ASSERT(LegoAct2State, 0x10)
// GLOBAL: LEGO1 0x100f4474
Act2mainScript::Script g_unk0x100f4474 = (Act2mainScript::Script) 0;
// GLOBAL: LEGO1 0x100f43f0
// GLOBAL: BETA10 0x101e14a8
MxS32 g_unk0x100f43f0[] = {
Act2mainScript::c_tns030bd_RunAnim,
Act2mainScript::c_tns030pg_RunAnim,
Act2mainScript::c_tns030rd_RunAnim,
Act2mainScript::c_tns030sy_RunAnim,
Act2mainScript::c_snsx35ro_RunAnim,
Act2mainScript::c_snsx36ro_RunAnim,
Act2mainScript::c_snsx37ro_RunAnim,
Act2mainScript::c_snsx48cl_RunAnim
};
// GLOBAL: LEGO1 0x100f4410
LegoChar* g_unk0x100f4410[] = {"bd", "pg", "rd", "sy", "ro", "cl"};
// GLOBAL: LEGO1 0x100f4428
MxS32 g_unk0x100f4428[] = {
Act2mainScript::c_snsx07pa_RunAnim,
Act2mainScript::c_snsx12ni_RunAnim,
Act2mainScript::c_snsx15la_RunAnim,
Act2mainScript::c_snsx47cl_RunAnim,
Act2mainScript::c_snsx65pg_RunAnim,
Act2mainScript::c_snsx68pg_RunAnim,
Act2mainScript::c_snsx69rd_RunAnim,
Act2mainScript::c_snsx72sy_RunAnim,
0,
0,
0,
0
};
// GLOBAL: LEGO1 0x100f4458
LegoChar* g_unk0x100f4458[] = {"papa", "nick", "laura", "cl", "pg", "rd", "sy"};
// FUNCTION: LEGO1 0x1004fce0
// FUNCTION: BETA10 0x1003a5a0
LegoAct2::LegoAct2()
{
m_unk0x10c4 = 0;
m_gameState = NULL;
m_pepper = NULL;
m_ambulance = NULL;
m_ready = FALSE;
m_unk0x1130 = 0;
m_nextBrick = 0;
m_unk0x10c1 = 0;
m_unk0x1138 = NULL;
m_unk0x1140 = (Act2mainScript::Script) 0;
m_unk0x1144 = (Act2mainScript::Script) 0;
m_destLocation = LegoGameState::e_undefined;
m_music = JukeboxScript::c_MusicTheme1;
m_siFile = "";
m_unk0x113c = 5;
NotificationManager()->Register(this);
}
// FUNCTION: LEGO1 0x1004fe10
MxBool LegoAct2::VTable0x5c()
{
return TRUE;
}
// FUNCTION: LEGO1 0x1004fe40
// FUNCTION: BETA10 0x1003a6f0
LegoAct2::~LegoAct2()
{
if (m_ready) {
TickleManager()->UnregisterClient(this);
}
FUN_10051900();
InputManager()->UnRegister(this);
if (UserActor()) {
Remove(UserActor());
}
NotificationManager()->Unregister(this);
}
// FUNCTION: LEGO1 0x1004ff20
// FUNCTION: BETA10 0x1003a7ff
MxResult LegoAct2::Create(MxDSAction& p_dsAction)
{
GameState()->FindLoadedAct();
MxResult result = LegoWorld::Create(p_dsAction);
if (result == SUCCESS) {
AnimationManager()->EnableCamAnims(FALSE);
LegoGameState* gameState = GameState();
LegoAct2State* state = (LegoAct2State*) gameState->GetState("LegoAct2State");
if (state == NULL) {
state = (LegoAct2State*) gameState->CreateState("LegoAct2State");
}
m_gameState = state;
m_gameState->m_unk0x08 = 0;
switch (GameState()->GetLoadedAct()) {
case LegoGameState::e_act2:
GameState()->StopArea(LegoGameState::e_infomain);
GameState()->StopArea(LegoGameState::e_act2main);
break;
case LegoGameState::e_act3:
GameState()->StopArea(LegoGameState::e_infomain);
GameState()->StopArea(LegoGameState::e_act3script);
break;
case LegoGameState::e_act1:
case LegoGameState::e_actNotFound:
GameState()->StopArea(LegoGameState::e_undefined);
if (GameState()->GetPreviousArea() == LegoGameState::e_infomain) {
GameState()->StopArea(LegoGameState::e_isle);
}
}
GameState()->m_currentArea = LegoGameState::e_act2main;
GameState()->SetCurrentAct(LegoGameState::e_act2);
InputManager()->Register(this);
GameState()->SetDirty(TRUE);
}
return result;
}
// FUNCTION: LEGO1 0x10050040
// FUNCTION: BETA10 0x1003a976
MxResult LegoAct2::Tickle()
{
MxFloat distance;
if (!m_worldStarted) {
LegoWorld::Tickle();
return SUCCESS;
}
switch (m_unk0x10c4) {
case 0:
m_unk0x10c4 = 1;
break;
case 1:
((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3);
switch (rand() % 3) {
case 0:
g_unk0x100f4474 = Act2mainScript::c_tns002br_RunAnim;
break;
case 1:
g_unk0x100f4474 = Act2mainScript::c_tns003br_RunAnim;
break;
case 2:
g_unk0x100f4474 = Act2mainScript::c_tns004br_RunAnim;
break;
}
FUN_10052560(g_unk0x100f4474, TRUE, TRUE, NULL, NULL, NULL);
m_unk0x10d0 = 0;
m_unk0x10c4 = 2;
break;
case 2:
if (g_unk0x100f4474) {
if (AnimationManager()->FUN_10064ee0(g_unk0x100f4474)) {
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
g_unk0x100f4474 = (Act2mainScript::Script) 0;
}
}
m_unk0x10d0 += 50;
break;
case 3:
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
m_unk0x10d0 = 0;
m_unk0x10c4 = 4;
FUN_10052560(Act2mainScript::c_tja009ni_RunAnim, TRUE, TRUE, NULL, NULL, NULL);
AnimationManager()->EnableCamAnims(TRUE);
AnimationManager()->FUN_1005f6d0(TRUE);
AnimationManager()->FUN_100604f0(g_unk0x100f43f0, sizeOfArray(g_unk0x100f43f0));
AnimationManager()->FUN_10060480(g_unk0x100f4410, sizeOfArray(g_unk0x100f4410));
break;
case 4:
m_unk0x10d0 += 50;
break;
case 5:
m_unk0x10d0 += 50;
if (m_unk0x10d0 == 20000) {
const MxFloat* pepperPosition = FindROI("pepper")->GetWorldPosition();
MxFloat otherPoint[] = {-52.0f, 5.25f, -16.5f};
distance = DISTSQRD3(pepperPosition, otherPoint);
if (m_unk0x1144 == (Act2mainScript::Script) 0 && distance > 50.0f && pepperPosition[0] > -57.0f) {
FUN_10052560(Act2mainScript::c_Avo906In_PlayWav, FALSE, FALSE, NULL, NULL, NULL);
m_unk0x1144 = Act2mainScript::c_Avo906In_PlayWav;
}
}
else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == (Act2mainScript::Script) 0) {
FUN_10052560(Act2mainScript::c_Avo908In_PlayWav, FALSE, FALSE, NULL, NULL, NULL);
m_unk0x1144 = Act2mainScript::c_Avo908In_PlayWav;
}
break;
case 6:
m_unk0x10d0 += 50;
break;
case 9:
m_unk0x10d0 += 50;
if (m_unk0x10d0 >= 200) {
if (m_nextBrick < 5) {
m_unk0x10c4 = 7;
}
else {
m_unk0x10c4 = 10;
m_unk0x10d0 = 0;
m_unk0x1138->FUN_10019520();
}
}
break;
case 10:
m_unk0x10d0 += 50;
break;
case 11:
break;
case 12:
break;
}
return SUCCESS;
}
// FUNCTION: LEGO1 0x10050380
// FUNCTION: BETA10 0x1003b049
MxLong LegoAct2::Notify(MxParam& p_param)
{
MxNotificationParam& param = (MxNotificationParam&) p_param;
MxLong result = 0;
LegoWorld::Notify(p_param);
if (m_worldStarted) {
switch (param.GetNotification()) {
case c_notificationEndAction:
result = HandleEndAction((MxEndActionNotificationParam&) p_param);
break;
case c_notificationPathStruct: {
MxTrace("trigger %d\n", ((LegoPathStructNotificationParam&) p_param).GetData());
LegoPathStructNotificationParam& param = (LegoPathStructNotificationParam&) p_param;
LegoEntity* entity = (LegoEntity*) param.GetSender();
if (m_ambulance == NULL) {
m_ambulance = FindROI("ambul");
}
if (entity->GetROI() == m_pepper) {
HandlePathStruct(param);
}
result = 1;
break;
}
case c_notificationType22:
SoundManager()->GetCacheSoundManager()->Play("28bng", NULL, FALSE);
m_unk0x10c1++;
if (m_unk0x10c1 == 10 && m_unk0x10c4 == 13) {
m_unk0x10c4 = 14;
LegoEntity* entity = (LegoEntity*) param.GetSender();
Mx3DPointFloat entityPosition(entity->GetROI()->GetWorldPosition());
Mx3DPointFloat unk0x10d8(m_pepper->GetWorldPosition());
Mx3DPointFloat locala4(unk0x10d8);
((Vector3&) entityPosition).Sub(unk0x10d8);
MxMatrix local2world(m_pepper->GetLocal2World());
Vector3 local30(local2world[0]);
Vector3 localac(local2world[1]);
Vector3 local28(local2world[2]);
local28 = entityPosition;
local28.Unitize();
Mx3DPointFloat local90(local28);
((Vector3&) local90).Mul(1.25f);
((Vector3&) locala4).Add(local90);
locala4[1] += 0.25;
local30.EqualsCross(&localac, &local28);
local30.Unitize();
Mx3DPointFloat direction(local2world[2]);
Mx3DPointFloat location(local2world[1]);
FUN_10052560(Act2mainScript::c_tns051in_RunAnim, TRUE, TRUE, &location, &direction, NULL);
m_unk0x10c4 = 14;
m_unk0x10d0 = 0;
((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3);
}
break;
case c_notificationTransitioned:
result = HandleTransitionEnd();
break;
}
}
return result;
}
// FUNCTION: LEGO1 0x100506f0
MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param)
{
if (m_gameState->m_enabled && p_param.GetAction() != NULL) {
MxU32 objectId = p_param.GetAction()->GetObjectId();
if (m_unk0x10c4 == 5 && m_unk0x1144 == objectId) {
m_unk0x1144 = (Act2mainScript::Script) 0;
return 0;
}
if (m_unk0x1140 != objectId) {
return 0;
}
m_unk0x1140 = (Act2mainScript::Script) 0;
switch (m_unk0x10c4) {
case 2:
m_unk0x10c4 = 3;
break;
case 4:
FUN_10051960();
m_unk0x10c4 = 5;
m_unk0x10d0 = 0;
break;
case 6: {
LegoROI* roi;
roi = FindROI("nick");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("laura");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("motoni");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("motola");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("Block01");
RemoveActor((LegoPathActor*) roi->GetEntity());
roi->SetVisibility(FALSE);
roi = FindROI("Block02");
RemoveActor((LegoPathActor*) roi->GetEntity());
roi->SetVisibility(FALSE);
VariableTable()->SetVariable("ACTOR_01", "brickstr");
FUN_10052800();
m_unk0x10c4 = 7;
PlayMusic(JukeboxScript::c_BrickstrChase);
break;
}
case 11:
m_bricks[m_nextBrick - 1].Mute(TRUE);
m_unk0x10c4 = 12;
m_unk0x10d0 = 0;
FUN_10052560(Act2mainScript::c_tra045la_RunAnim, TRUE, TRUE, NULL, NULL, NULL);
((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3);
AnimationManager()->EnableCamAnims(TRUE);
AnimationManager()->FUN_1005f6d0(TRUE);
AnimationManager()->FUN_100604f0(g_unk0x100f4428, sizeOfArray(g_unk0x100f4428));
AnimationManager()->FUN_10060480(g_unk0x100f4458, sizeOfArray(g_unk0x100f4458));
break;
case 12: {
LegoROI* roi;
roi = FindROI("nick");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("laura");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("motoni");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("motola");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
m_bricks[m_nextBrick - 1].Mute(FALSE);
m_unk0x10c4 = 13;
SpawnBricks();
PlayMusic(JukeboxScript::c_BrickHunt);
((LegoPathActor*) m_pepper->GetEntity())->SetState(0);
break;
}
case 14:
for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_bricks); i++) {
m_bricks[i].Remove();
}
FUN_10051900();
m_destLocation = LegoGameState::e_copterbuild;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
break;
}
}
return 0;
}
// FUNCTION: LEGO1 0x10050a50
MxLong LegoAct2::HandleTransitionEnd()
{
if (m_destLocation != LegoGameState::e_undefined) {
GameState()->SwitchArea(m_destLocation);
m_destLocation = LegoGameState::e_undefined;
}
return 1;
}
// FUNCTION: LEGO1 0x10050a80
void LegoAct2::ReadyWorld()
{
LegoWorld::ReadyWorld();
AnimationManager()->Resume();
TickleManager()->RegisterClient(this, 20);
m_ready = TRUE;
m_siFile = VariableTable()->GetVariable("ACT2_ANIMS_FILE");
GameState()->SetActor(LegoActor::c_pepper);
m_pepper = FindROI("pepper");
IslePathActor* pepper = (IslePathActor*) m_pepper->GetEntity();
pepper->SpawnPlayer(
LegoGameState::e_unk50,
TRUE,
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
);
LegoROI* roi = FindROI("Block01");
BoundingSphere sphere = roi->GetBoundingSphere();
sphere.Radius() *= 1.5;
roi->SetBoundingSphere(sphere);
LegoPathActor* actor = (LegoPathActor*) roi->GetEntity();
PlaceActor(actor, "EDG01_04", 1, 0.5f, 3, 0.5f);
MxMatrix local2world = roi->GetLocal2World();
local2world[3][0] -= 1.5;
roi->FUN_100a58f0(local2world);
roi->VTable0x14();
roi = FindROI("Block02");
sphere = roi->GetBoundingSphere();
sphere.Radius() *= 1.5;
roi->SetBoundingSphere(sphere);
actor = (LegoPathActor*) roi->GetEntity();
PlaceActor(actor, "EDG00_149", 0, 0.5f, 2, 0.5f);
PlayMusic(JukeboxScript::c_Jail_Music);
FUN_10051900();
VideoManager()->Get3DManager()->SetFrustrum(90.0f, 0.1f, 250.f);
m_gameState->m_enabled = TRUE;
}
// FUNCTION: LEGO1 0x10050cf0
// FUNCTION: BETA10 0x1003bb2d
void LegoAct2::Enable(MxBool p_enable)
{
if ((MxBool) 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_nextBrick == 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 = (Act2mainScript::Script) 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::Script) 0) {
MxDSAction action;
action.SetAtomId(m_atomId);
action.SetUnknown24(-2);
action.SetObjectId(m_unk0x1144);
DeleteObject(action);
m_unk0x1144 = (Act2mainScript::Script) 0;
}
TickleManager()->UnregisterClient(this);
}
}
// FUNCTION: LEGO1 0x10051460
// FUNCTION: BETA10 0x1003bb72
MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param)
{
if (m_unk0x10c4 == 5 && p_param.GetData() == 0x32) {
LegoPathActor* actor = (LegoPathActor*) m_pepper->GetEntity();
actor->SetState(LegoPathActor::c_bit3);
actor->SetWorldSpeed(0.0f);
FUN_10051900();
if (m_unk0x10d0 < 90000) {
FUN_10052560(Act2mainScript::c_tra031ni_RunAnim, TRUE, TRUE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_tra032ni_RunAnim, TRUE, TRUE, NULL, NULL, NULL);
}
m_unk0x112c = 50;
m_unk0x10c4 = 6;
m_unk0x10d0 = 0;
}
else if (m_unk0x10c4 == 5 && p_param.GetData() == 0x2a) {
if (m_unk0x1144 == (Act2mainScript::Script) 0) {
FUN_10052560(Act2mainScript::c_Avo907In_PlayWav, FALSE, FALSE, NULL, NULL, NULL);
m_unk0x1144 = Act2mainScript::c_Avo907In_PlayWav;
}
}
else if (m_unk0x10c4 == 5) {
FUN_100521f0(p_param.GetData());
}
else if (m_unk0x10c4 == 7) {
FUN_10051fa0(p_param.GetData());
}
else if (m_unk0x10c4 == 10 && p_param.GetData() == 0x165) {
((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3);
if (FUN_10052560(Act2mainScript::c_VOhide_PlayWav, FALSE, TRUE, NULL, NULL, NULL) == SUCCESS) {
m_unk0x1140 = Act2mainScript::c_VOhide_PlayWav;
}
m_unk0x1138->FUN_10019560();
m_unk0x10c4 = 11;
m_unk0x10d0 = 0;
if (m_nextBrick < 6) {
m_bricks[m_nextBrick].Create(m_nextBrick);
m_nextBrick++;
}
MxMatrix local2world = m_ambulance->GetLocal2World();
MxMatrix local2world2 = local2world;
LegoPathBoundary* boundary = m_unk0x1138->GetBoundary();
local2world[3][1] += 1.5;
local2world2[3][1] -= 0.1;
m_bricks[m_nextBrick - 1].FUN_1007a670(local2world, local2world2, boundary);
}
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: BETA10 0x1003bed1
void LegoAct2::FUN_10051900()
{
if (AnimationManager()) {
AnimationManager()->Suspend();
AnimationManager()->Resume();
AnimationManager()->FUN_10060540(FALSE);
AnimationManager()->FUN_100604d0(FALSE);
AnimationManager()->EnableCamAnims(FALSE);
AnimationManager()->FUN_1005f6d0(FALSE);
}
}
// FUNCTION: LEGO1 0x10051960
// FUNCTION: BETA10 0x1003bf2c
void LegoAct2::FUN_10051960()
{
LegoROI* roi;
roi = FindROI("mama");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("papa");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
roi = FindROI("infoman");
if (roi != NULL) {
roi->SetVisibility(FALSE);
}
((LegoPathActor*) m_pepper->GetEntity())->SetState(0);
}
// FUNCTION: LEGO1 0x100519c0
void LegoAct2::VTable0x60()
{
// empty
}
// FUNCTION: LEGO1 0x100519d0
MxBool LegoAct2::Escape()
{
BackgroundAudioManager()->Stop();
AnimationManager()->FUN_10061010(FALSE);
DeleteObjects(&m_atomId, Act2mainScript::c_snsx50bu_RunAnim, 999);
if (UserActor() != NULL) {
if (UserActor()->GetActorId() != GameState()->GetActorId()) {
((IslePathActor*) UserActor())->Exit();
}
}
if (m_gameState != NULL) {
m_gameState->m_enabled = FALSE;
}
m_destLocation = LegoGameState::e_infomain;
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 0x10051ac0
// FUNCTION: BETA10 0x100138c0
void LegoAct2::SpawnBricks()
{
MxFloat infobridge[] = {79.0625f, 0.5f, -19.75f};
MxFloat palmTreeInPark[] = {67.62728f, 0.917197f, 11.49833f};
MxFloat store[] = {-53.9328f, 2.372259f, -61.2073f};
MxFloat postOffice[] = {-30.9856f, 0.30453f, -47.4378f};
MxFloat h3[] = {-71.2397f, 7.319758f, -23.0f};
MxFloat ht[] = {-59.5102f, 14.37329f, 24.70311f};
MxFloat posta[] = {74.0625f, 1.5f, -91.125f};
MxFloat ptree[] = {-20.4375f, 0.5f, -82.5625f};
MxFloat jail[] = {80.46174f, 0.6f, -59.50533f};
MxFloat hospital[] = {84.0f, 4.5f, 26.0f};
InitBricks();
Act2Brick* brick = &m_bricks[m_nextBrick];
brick->Create(m_nextBrick);
LegoROI* roi = brick->GetROI();
MxMatrix local2world = roi->GetLocal2World();
MxFloat* location;
// Unused but present in BETA
LegoEntity* entity;
if ((MxS16) (rand() % 2) == 1) {
m_firstBrick = 0;
location = infobridge;
MxTrace("infobridge\n");
}
else {
m_firstBrick = 1;
location = palmTreeInPark;
MxTrace("palm tree in park\n");
}
SET3(local2world[3], location);
roi->FUN_100a58f0(local2world);
roi->SetVisibility(TRUE);
roi->VTable0x14();
entity = roi->GetEntity();
brick->PlayWhistleSound();
m_nextBrick++;
brick = &m_bricks[m_nextBrick];
brick->Create(m_nextBrick);
roi = brick->GetROI();
local2world = roi->GetLocal2World();
if ((MxS16) (rand() % 2) == 1) {
m_secondBrick = 2;
location = store;
MxTrace("store\n");
}
else {
m_secondBrick = 3;
location = postOffice;
MxTrace("p.o.\n");
}
SET3(local2world[3], location);
roi->FUN_100a58f0(local2world);
roi->SetVisibility(TRUE);
roi->VTable0x14();
entity = roi->GetEntity();
brick->PlayWhistleSound();
m_nextBrick++;
brick = &m_bricks[m_nextBrick];
brick->Create(m_nextBrick);
roi = brick->GetROI();
local2world = roi->GetLocal2World();
if ((MxS16) (rand() % 2) == 1) {
m_thirdBrick = 4;
location = h3;
MxTrace("h3\n");
}
else {
m_thirdBrick = 5;
location = ht;
MxTrace("ht\n");
}
SET3(local2world[3], location);
roi->FUN_100a58f0(local2world);
roi->SetVisibility(TRUE);
roi->VTable0x14();
entity = roi->GetEntity();
brick->PlayWhistleSound();
m_nextBrick++;
brick = &m_bricks[m_nextBrick];
brick->Create(m_nextBrick);
roi = brick->GetROI();
local2world = roi->GetLocal2World();
if ((MxS16) (rand() % 2) == 1) {
if ((MxS16) (rand() % 2) == 1) {
m_fourthBrick = 6;
location = posta;
MxTrace("po.sta.\n");
}
else {
m_fourthBrick = 7;
location = ptree;
MxTrace("p.tree\n");
}
}
else {
if ((MxS16) (rand() % 2) == 1) {
m_fourthBrick = 8;
location = jail;
MxTrace("jail\n");
}
else {
m_fourthBrick = 9;
location = hospital;
MxTrace("hospi\n");
}
}
SET3(local2world[3], location);
roi->FUN_100a58f0(local2world);
roi->SetVisibility(TRUE);
roi->VTable0x14();
entity = roi->GetEntity();
brick->PlayWhistleSound();
m_nextBrick++;
}
// FUNCTION: LEGO1 0x10051fa0
// FUNCTION: BETA10 0x10013fd3
void LegoAct2::FUN_10051fa0(MxS32 p_param1)
{
MxU8 randN = rand() / (RAND_MAX / 3);
randN++;
switch (p_param1) {
case 2:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx50bu_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx51bu_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 8:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx29nu_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx30nu_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 9:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx33na_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx34na_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 14:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx46cl_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx48cl_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 23:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx58va_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx60va_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 24:
case 25:
FUN_10052560(Act2mainScript::c_snsx31sh_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
break;
case 26:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx52sn_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx53sn_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 34:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx15la_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx16la_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 36:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx10ni_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx11ni_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
case 38:
case 42:
if (randN == 1) {
FUN_10052560(Act2mainScript::c_snsx03ma_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
else {
FUN_10052560(Act2mainScript::c_snsx04ma_RunAnim, TRUE, FALSE, NULL, NULL, NULL);
}
break;
}
}
// FUNCTION: LEGO1 0x100521f0
// FUNCTION: BETA10 0x100142f1
void LegoAct2::FUN_100521f0(MxS32 p_param1)
{
Act2mainScript::Script objectId = (Act2mainScript::Script) 0;
Mx3DPointFloat vec;
switch (p_param1) {
case 0x02: {
vec = Mx3DPointFloat(-9.1f, 0.0f, -16.5f);
VariableTable()->SetVariable("ACTOR_01", "bd");
objectId = Act2mainScript::c_tns030bd_RunAnim;
break;
}
case 0x2a: {
vec = Mx3DPointFloat(-9.67f, 0.0f, -44.3f);
VariableTable()->SetVariable("ACTOR_01", "rd");
objectId = Act2mainScript::c_tns030rd_RunAnim;
break;
}
case 0x133: {
vec = Mx3DPointFloat(25.75f, 0.0f, -13.0f);
VariableTable()->SetVariable("ACTOR_01", "pg");
objectId = Act2mainScript::c_tns030pg_RunAnim;
break;
}
case 0x134: {
vec = Mx3DPointFloat(43.63f, 0.0f, -46.33f);
VariableTable()->SetVariable("ACTOR_01", "sy");
objectId = Act2mainScript::c_tns030sy_RunAnim;
break;
}
case 0x135: {
vec = Mx3DPointFloat(50.0f, 0.0f, -34.6f);
VariableTable()->SetVariable("ACTOR_01", "rd");
objectId = Act2mainScript::c_tns030rd_RunAnim;
break;
}
case 0x138: {
vec = Mx3DPointFloat(-41.15f, 4.0f, 31.0f);
VariableTable()->SetVariable("ACTOR_01", "sy");
objectId = Act2mainScript::c_tns030sy_RunAnim;
break;
}
}
if (objectId != (Act2mainScript::Script) 0) {
Mx3DPointFloat local30(vec);
Mx3DPointFloat position(m_pepper->GetWorldPosition());
((Vector3&) local30).Sub(position);
Mx3DPointFloat local44 = local30;
local30.Unitize();
FUN_10052560(objectId, TRUE, TRUE, &vec, &local30, NULL);
}
}
// FUNCTION: LEGO1 0x10052560
// FUNCTION: BETA10 0x100145c6
MxResult LegoAct2::FUN_10052560(
Act2mainScript::Script p_objectId,
MxBool p_param2,
MxBool p_param3,
Mx3DPointFloat* p_location,
Mx3DPointFloat* p_direction,
Mx3DPointFloat* p_param6
)
{
if (m_unk0x1140 == (Act2mainScript::Script) 0 || p_param3) {
assert(strlen(m_siFile));
if (!p_param2) {
MxDSAction action;
action.SetObjectId(p_objectId);
// World index: see LegoOmni::RegisterWorlds
action.SetAtomId(*Lego()->GetWorldAtom(15));
if (p_location) {
action.SetUp(Mx3DPointFloat(0.0f, 1.0f, 0.0f));
action.SetLocation(*p_location);
}
if (p_direction) {
action.SetDirection(*p_direction);
}
StartActionIfUnknown0x13c(action);
}
else {
MxMatrix matrix;
matrix.SetIdentity();
MxBool oneVectorNotNull = FALSE;
if (p_location) {
matrix[3][0] = (*p_location)[0];
matrix[3][1] = (*p_location)[1];
matrix[3][2] = (*p_location)[2];
oneVectorNotNull = TRUE;
}
if (p_direction) {
matrix[2][0] = (*p_direction)[0];
matrix[2][1] = (*p_direction)[1];
matrix[2][2] = (*p_direction)[2];
oneVectorNotNull = TRUE;
}
if (p_param6) {
matrix[1][0] = (*p_param6)[0];
matrix[1][1] = (*p_param6)[1];
matrix[1][2] = (*p_param6)[2];
oneVectorNotNull = TRUE;
}
Vector3 firstColumn(matrix[0]);
Vector3 secondColumn(matrix[1]);
Vector3 thirdColumn(matrix[2]);
firstColumn.EqualsCross(&secondColumn, &thirdColumn);
firstColumn.Unitize();
MxMatrix* pmatrix = NULL;
if (oneVectorNotNull) {
pmatrix = &matrix;
}
MxResult result;
if (p_objectId == Act2mainScript::c_tja009ni_RunAnim) {
result =
AnimationManager()->FUN_10060dc0(p_objectId, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, TRUE);
}
else {
result =
AnimationManager()->FUN_10060dc0(p_objectId, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, FALSE);
}
if (result == SUCCESS) {
m_unk0x1140 = p_objectId;
}
}
}
return SUCCESS;
}
// FUNCTION: LEGO1 0x10052800
// FUNCTION: BETA10 0x10014aa8
MxResult LegoAct2::FUN_10052800()
{
LegoPathActor* actor = m_unk0x1138;
LegoLocomotionAnimPresenter* ap;
PlaceActor(actor, "EDG01_27", 2, 0.5f, 0, 0.5f);
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim0");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, 0.0f);
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim2");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, 6.0f);
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim3");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, 3.0f);
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "BrShoot");
assert(ap);
ap->FUN_1006d680(m_unk0x1138, -1.0f);
actor->SetWorldSpeed(0.0f);
m_unk0x1138->FUN_10018980();
return SUCCESS;
}