Merge remote-tracking branch 'isle/master'
Some checks failed
Build / Current msys2 mingw32 (push) Has been cancelled
Build / Current msys2 mingw64 (push) Has been cancelled
Build / Current MSVC (32-bit) (push) Has been cancelled
Build / Current MSVC (64-bit) (push) Has been cancelled
Format / C++ (push) Has been cancelled
Naming / C++ (push) Has been cancelled

This commit is contained in:
Christian Semmler 2024-11-09 10:11:57 -07:00
commit 9f9294694d
No known key found for this signature in database
GPG key ID: 086DAA1360BEEE5C
60 changed files with 1850 additions and 481 deletions

View file

@ -7,7 +7,7 @@
// SIZE 0x1f8
class Doors : public LegoPathActor {
public:
Doors() : m_unk0x154(0), m_unk0x15c(0), m_unk0x160(0), m_unk0x1f4(0) {}
Doors() : m_unk0x154(0), m_unk0x15c(NULL), m_unk0x160(NULL), m_unk0x1f4(0) {}
// FUNCTION: LEGO1 0x1000e430
const char* ClassName() const override // vtable+0x0c
@ -31,12 +31,12 @@ class Doors : public LegoPathActor {
private:
undefined4 m_unk0x154; // 0x154
undefined4 m_unk0x158; // 0x158
undefined4 m_unk0x15c; // 0x15c
undefined4 m_unk0x160; // 0x160
MxFloat m_unk0x158; // 0x158
Matrix4* m_unk0x15c; // 0x15c
Matrix4* m_unk0x160; // 0x160
MxMatrix m_unk0x164; // 0x164
MxMatrix m_unk0x1ac; // 0x1ac
undefined4 m_unk0x1f4; // 0x1f4
MxFloat m_unk0x1f4; // 0x1f4
};
#endif // DOORS_H

View file

@ -38,19 +38,19 @@ class GasStationState : public LegoState {
// SYNTHETIC: LEGO1 0x10006290
// GasStationState::`scalar deleting destructor'
void FUN_10006430(GarageScript::Script);
void FUN_10006460(GarageScript::Script);
void FUN_10006490();
void PlayAction(GarageScript::Script p_objectId);
void StopAction(GarageScript::Script p_objectId);
void StopActions();
// TODO: Most likely getters/setters are not used according to BETA.
undefined4 m_unk0x08[3]; // 0x08
Unknown0x14 m_unk0x14; // 0x14
MxS16 m_unk0x18; // 0x18
MxS16 m_unk0x1a; // 0x1a
MxS16 m_unk0x1c; // 0x1c
MxS16 m_unk0x1e; // 0x1e
MxS16 m_unk0x20; // 0x20
GarageScript::Script m_actions[3]; // 0x08
Unknown0x14 m_unk0x14; // 0x14
MxS16 m_pepperAction; // 0x18
MxS16 m_mamaAction; // 0x1a
MxS16 m_papaAction; // 0x1c
MxS16 m_nickAction; // 0x1e
MxS16 m_lauraAction; // 0x20
};
// VTABLE: LEGO1 0x100d4650

View file

@ -28,7 +28,7 @@ class HelicopterState : public LegoState {
MxBool IsSerializable() override { return FALSE; } // vtable+0x14
// FUNCTION: LEGO1 0x1000e0c0
MxBool SetFlag() override
MxBool Reset() override
{
m_unk0x08 = 0;
return TRUE;

View file

@ -3,6 +3,7 @@
#include "actionsfwd.h"
#include "legogamestate.h"
#include "legonamedplane.h"
#include "legostate.h"
#include "legoworld.h"
#include "radio.h"
@ -32,47 +33,6 @@ class Act1State : public LegoState {
c_floor3
};
enum {
e_unk953 = 953,
e_unk954 = 954,
e_unk955 = 955,
};
// SIZE 0x4c
class NamedPlane {
public:
// FUNCTION: LEGO1 0x10033800
NamedPlane() {}
void SetName(const char* p_name) { m_name = p_name; }
const MxString* GetName() const { return &m_name; }
// FUNCTION: LEGO1 0x100344d0
MxResult Serialize(LegoFile* p_file)
{
if (p_file->IsWriteMode()) {
p_file->WriteString(m_name);
p_file->WriteVector3(m_point1);
p_file->WriteVector3(m_point2);
p_file->WriteVector3(m_point3);
}
else if (p_file->IsReadMode()) {
p_file->ReadString(m_name);
p_file->ReadVector3(m_point1);
p_file->ReadVector3(m_point2);
p_file->ReadVector3(m_point3);
}
return SUCCESS;
}
private:
MxString m_name; // 0x00
Mx3DPointFloat m_point1; // 0x10
Mx3DPointFloat m_point2; // 0x24
Mx3DPointFloat m_point3; // 0x38
};
Act1State();
// FUNCTION: LEGO1 0x100338a0
@ -88,12 +48,12 @@ class Act1State : public LegoState {
return !strcmp(p_name, Act1State::ClassName()) || LegoState::IsA(p_name);
}
MxBool SetFlag() override; // vtable+0x18
MxBool Reset() override; // vtable+0x18
MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
void FUN_10034660();
void FUN_100346a0();
void FUN_10034b60();
void PlayCptClickDialogue();
void StopCptClickDialogue();
void RemoveActors();
void FUN_10034d00();
MxU32 GetUnknown18() { return m_unk0x018; }
@ -109,45 +69,38 @@ class Act1State : public LegoState {
// TODO: Most likely getters/setters are not used according to BETA.
MxS32* m_unk0x008; // 0x008 FIXME: count for m_unk0x008
MxS16 m_unk0x00c; // 0x00c
undefined2 m_unk0x00e; // 0x00e
undefined2 m_unk0x010; // 0x010
undefined m_unk0x012; // 0x012
MxS32 m_unk0x014; // 0x014
MxU32 m_unk0x018; // 0x018
MxS16 m_elevFloor; // 0x01c
MxBool m_unk0x01e; // 0x01e
MxBool m_unk0x01f; // 0x01f
MxBool m_planeActive; // 0x020
undefined m_unk0x021; // 0x021
MxBool m_unk0x022; // 0x022
undefined m_unk0x023; // 0x023
NamedPlane m_unk0x024; // 0x024
NamedPlane m_unk0x070; // 0x070
NamedPlane m_unk0x0bc; // 0x0bc
NamedPlane m_unk0x108; // 0x108
LegoNamedTexture* m_unk0x154; // 0x154
LegoNamedTexture* m_unk0x158; // 0x158
LegoNamedTexture* m_unk0x15c; // 0x15c
Helicopter* m_helicopter; // 0x160
NamedPlane m_unk0x164; // 0x164
LegoNamedTexture* m_unk0x1b0; // 0x1b0
LegoNamedTexture* m_unk0x1b4; // 0x1b4
Jetski* m_jetski; // 0x1b8
NamedPlane m_unk0x1bc; // 0x1bc
LegoNamedTexture* m_unk0x208; // 0x208
DuneBuggy* m_dunebuggy; // 0x20c
NamedPlane m_unk0x210; // 0x210
LegoNamedTexture* m_unk0x25c; // 0x25c
LegoNamedTexture* m_unk0x260; // 0x260
LegoNamedTexture* m_unk0x264; // 0x264
RaceCar* m_racecar; // 0x268
Playlist m_cptClickDialogue; // 0x008
IsleScript::Script m_currentCptClickDialogue; // 0x014
MxU32 m_unk0x018; // 0x018
MxS16 m_elevFloor; // 0x01c
MxBool m_unk0x01e; // 0x01e
MxBool m_unk0x01f; // 0x01f
MxBool m_planeActive; // 0x020
undefined m_unk0x021; // 0x021
MxBool m_unk0x022; // 0x022
undefined m_unk0x023; // 0x023
LegoNamedPlane m_motocyclePlane; // 0x024
LegoNamedPlane m_bikePlane; // 0x070
LegoNamedPlane m_skateboardPlane; // 0x0bc
LegoNamedPlane m_helicopterPlane; // 0x108
LegoNamedTexture* m_unk0x154; // 0x154
LegoNamedTexture* m_unk0x158; // 0x158
LegoNamedTexture* m_unk0x15c; // 0x15c
Helicopter* m_helicopter; // 0x160
LegoNamedPlane m_jetskiPlane; // 0x164
LegoNamedTexture* m_unk0x1b0; // 0x1b0
LegoNamedTexture* m_unk0x1b4; // 0x1b4
Jetski* m_jetski; // 0x1b8
LegoNamedPlane m_dunebuggyPlane; // 0x1bc
LegoNamedTexture* m_unk0x208; // 0x208
DuneBuggy* m_dunebuggy; // 0x20c
LegoNamedPlane m_racecarPlane; // 0x210
LegoNamedTexture* m_unk0x25c; // 0x25c
LegoNamedTexture* m_unk0x260; // 0x260
LegoNamedTexture* m_unk0x264; // 0x264
RaceCar* m_racecar; // 0x268
};
// FUNCTION: LEGO1 0x10033a70
// Act1State::NamedPlane::~NamedPlane
// VTABLE: LEGO1 0x100d6fb8
// SIZE 0x140
class Isle : public LegoWorld {
@ -190,9 +143,12 @@ class Isle : public LegoWorld {
virtual void VTable0x6c(LegoPathActor* p_actor); // vtable+6c
void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; }
MxBool HasHelicopter() { return m_helicopter != NULL; }
void FUN_10033350();
friend class Act1State;
// SYNTHETIC: LEGO1 0x10030a30
// Isle::`scalar deleting destructor'

View file

@ -1,7 +1,6 @@
#ifndef LEGOANIMATIONMANAGER_H
#define LEGOANIMATIONMANAGER_H
#include "actionsfwd.h"
#include "decomp.h"
#include "legolocations.h"
#include "legostate.h"
@ -68,7 +67,7 @@ class AnimState : public LegoState {
return !strcmp(p_name, AnimState::ClassName()) || LegoState::IsA(p_name);
}
MxBool SetFlag() override; // vtable+0x18
MxBool Reset() override; // vtable+0x18
MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
void CopyToAnims(MxU32, AnimInfo* p_anims, MxU32& p_outExtraCharacterId);
@ -161,7 +160,7 @@ class LegoAnimationManager : public MxCore {
void FUN_10060570(MxBool p_unk0x1a);
MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity);
MxResult FUN_10060dc0(
IsleScript::Script p_objectId,
MxU32 p_objectId,
MxMatrix* p_matrix,
MxBool p_param3,
MxBool p_param4,

View file

@ -6,6 +6,7 @@
#include "legoworld.h"
class LegoCarBuildAnimPresenter;
class LegoControlManagerNotificationParam;
class LegoEventNotificationParam;
class MxControlPresenter;
class MxStillPresenter;
@ -21,6 +22,7 @@ class LegoVehicleBuildState : public LegoState {
e_entering = 1,
e_unknown2 = 2,
e_cutscene = 3,
e_unknown4 = 4,
e_exiting = 6
};
@ -71,6 +73,22 @@ typedef LegoVehicleBuildState LegoJetskiBuildState;
// SIZE 0x34c
class LegoCarBuild : public LegoWorld {
public:
// SIZE 0x1c
struct LookupTableActions {
undefined4 m_unk0x00; // 0x00
undefined4 m_unk0x04; // 0x04
undefined4 m_unk0x08; // 0x08
undefined4 m_unk0x0c; // 0x0c
undefined4 m_unk0x10; // 0x10
undefined4 m_unk0x14; // 0x14
undefined4 m_unk0x18; // 0x18
};
enum Unknown0xf8 {
c_unknownminusone = -1,
c_unknown8 = 8
};
LegoCarBuild();
~LegoCarBuild() override;
@ -117,16 +135,19 @@ class LegoCarBuild : public LegoWorld {
undefined4 FUN_100244e0(MxLong p_x, MxLong p_y);
undefined4 FUN_100246e0(MxLong p_x, MxLong p_y);
MxS32 FUN_10024850(MxLong p_x, MxLong p_y);
undefined4 FUN_10024890(LegoEventNotificationParam* p_param);
undefined4 FUN_10024890(MxParam* p_param);
undefined4 FUN_10024c20(LegoEventNotificationParam* p_param);
void FUN_10024ef0();
void FUN_10024f30();
void FUN_10024f50();
void FUN_10024f70(MxBool p_enabled);
void SetPresentersEnabled(MxBool p_enabled);
void TogglePresentersEnabled();
void FUN_100250e0(MxBool p_param);
void FUN_10025350(MxS32 p_objectId);
void FUN_10025450();
undefined4 FUN_10025720(undefined4 p_param1);
void FUN_10025720(undefined4 p_param1);
void FUN_10025d10(MxS32 p_param);
MxS32 FUN_10025d70();
void FUN_10025db0(const char* p_param1, undefined4 p_param2);
void FUN_10025e40();
@ -139,12 +160,18 @@ class LegoCarBuild : public LegoWorld {
// LegoCarBuild::`scalar deleting destructor'
private:
undefined4 m_unk0xf8; // 0xf8
MxS16 m_unk0xfc; // 0xfc
undefined m_unk0xfe[2]; // 0xfe
MxS32 m_unk0x100; // 0x100
undefined4 m_unk0x104; // 0x104
MxS8 m_unk0x108; // 0x108
// inline functions
MxU32 Beta0x10070520();
void StopActionIn0x344();
Unknown0xf8 m_unk0xf8; // 0xf8
MxS16 m_unk0xfc; // 0xfc
MxS32 m_unk0x100; // 0x100
undefined4 m_unk0x104; // 0x104
// name verified by BETA10 0x1006ebba
MxS8 m_numAnimsRun; // 0x108
MxU8 m_unk0x109; // 0x109
MxU16 m_unk0x10a; // 0x10a
DWORD m_unk0x10c; // 0x10c
@ -197,7 +224,8 @@ class LegoCarBuild : public LegoWorld {
// variable name verified by BETA10 0x1006b219
LegoVehicleBuildState* m_buildState; // 0x32c
undefined4 m_unk0x330; // 0x330
// variable name verified by BETA10 0x1006d742
undefined4 m_carId; // 0x330
// variable name verified by BETA10 0x1006cba7
LegoGameState::Area m_destLocation; // 0x334
@ -211,6 +239,7 @@ class LegoCarBuild : public LegoWorld {
static MxS16 g_unk0x100f11cc;
static MxFloat g_unk0x100d65a4;
static MxFloat g_rotationAngleStepYAxis;
static LookupTableActions g_unk0x100d65b0[];
};
#endif // LEGOCARBUILD_H

View file

@ -21,7 +21,7 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
{
m_name = NULL;
m_wiredName = NULL;
m_unk0x08 = 0;
m_objectId = 0;
}
// variable name verified by BETA10 0x10071b56
@ -30,7 +30,8 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
// variable name verified by BETA10 0x100719f0
LegoChar* m_wiredName; // 0x04
undefined2 m_unk0x08; // 0x08
// variable name guessed based on the setter at LEGO1 0x0x10079dc0 and its use in LEGO1 0x10024890
MxS16 m_objectId; // 0x08
};
LegoCarBuildAnimPresenter();
@ -77,15 +78,33 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
MxBool StringEqualsShelf(const LegoChar* p_string);
MxBool StringEndsOnY(const LegoChar* p_string);
MxBool StringEndsOnZero(const LegoChar* p_string);
const LegoChar* GetWiredNameByPartName(const LegoChar* p_name);
void SetPartObjectIdByName(const LegoChar* p_name, MxS16 p_objectId);
// FUNCTION: BETA10 0x10070180
void SetUnknown0xbc(undefined2 p_unk0xbc) { m_unk0xbc = p_unk0xbc; }
// FUNCTION: BETA10 0x100703b0
MxMatrix& GetUnknown0xe0() { return m_unk0xe0; }
MxBool StringEndsOnW(LegoChar* p_param);
MxBool StringEndsOnYOrN(const LegoChar* p_string);
const BoundingSphere& FUN_10079e20();
// FUNCTION: BETA10 0x100703e0
const LegoChar* GetWiredNameOfLastPlacedPart() { return m_parts[m_placedPartCount].m_wiredName; }
MxS16 GetNumberOfParts() { return m_numberOfParts; }
MxS16 GetPlacedPartCount() { return m_placedPartCount; }
// FUNCTION: BETA10 0x10070270
MxBool AllPartsPlaced()
{
// this function differs in BETA10
return m_placedPartCount == m_numberOfParts;
}
// SYNTHETIC: LEGO1 0x10078660
// LegoCarBuildAnimPresenter::`scalar deleting destructor'
@ -118,8 +137,6 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
// name verified by BETA10 0x10070d63
LegoChar* m_mainSourceId; // 0x14c
friend class LegoCarBuild;
};
#endif // LEGOCARBUILDPRESENTER_H

View file

@ -172,13 +172,11 @@ class LegoGameState {
Act GetCurrentAct() { return m_currentAct; }
Act GetLoadedAct() { return m_loadedAct; }
Area GetCurrentArea() { return m_currentArea; }
Area GetPreviousArea() { return m_previousArea; }
Area GetUnknown0x42c() { return m_unk0x42c; }
History* GetHistory() { return &m_history; }
void SetDirty(MxBool p_isDirty) { m_isDirty = p_isDirty; }
void SetCurrentArea(Area p_currentArea) { m_currentArea = p_currentArea; }
void SetPreviousArea(Area p_previousArea) { m_previousArea = p_previousArea; }
void SetActorId(MxU8 p_actorId) { m_actorId = p_actorId; }
void SetUnknown0x42c(Area p_unk0x42c) { m_unk0x42c = p_unk0x42c; }

View file

@ -120,7 +120,9 @@ class LegoInputManager : public MxPresenter {
// FUNCTION: BETA10 0x10031ba0
LegoControlManager* GetControlManager() { return m_controlManager; }
// FUNCTION: BETA10 0x10017870
LegoWorld* GetWorld() { return m_world; }
LegoCameraController* GetCamera() { return m_camera; }
void ProcessEvents();

View file

@ -147,7 +147,10 @@ class LegoOmni : public MxOmni {
void SetNavController(LegoNavController* p_navController) { m_navController = p_navController; }
void SetUserActor(LegoPathActor* p_userActor) { m_userActor = p_userActor; }
void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; }
// FUNCTION: BETA10 0x100d55c0
void SetExit(MxBool p_exit) { m_exit = p_exit; }
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; }
void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; }

View file

@ -0,0 +1,50 @@
#ifndef LEGONAMEDPLANE_H
#define LEGONAMEDPLANE_H
#include "misc/legostorage.h"
#include "mxgeometry/mxgeometry3d.h"
#include "mxstring.h"
// SIZE 0x4c
class LegoNamedPlane {
public:
// FUNCTION: LEGO1 0x10033800
LegoNamedPlane() {}
// FUNCTION: LEGO1 0x10033a70
// LegoNamedPlane::~LegoNamedPlane
void SetName(const char* p_name) { m_name = p_name; }
const MxString* GetName() const { return &m_name; }
void SetPosition(const Mx3DPointFloat& p_position) { m_position = p_position; }
void SetDirection(const Mx3DPointFloat& p_direction) { m_direction = p_direction; }
void SetUp(const Mx3DPointFloat& p_up) { m_up = p_up; }
// FUNCTION: LEGO1 0x100344d0
MxResult Serialize(LegoFile* p_file)
{
if (p_file->IsWriteMode()) {
p_file->WriteString(m_name);
p_file->WriteVector3(m_position);
p_file->WriteVector3(m_direction);
p_file->WriteVector3(m_up);
}
else if (p_file->IsReadMode()) {
p_file->ReadString(m_name);
p_file->ReadVector3(m_position);
p_file->ReadVector3(m_direction);
p_file->ReadVector3(m_up);
}
return SUCCESS;
}
private:
MxString m_name; // 0x00
Mx3DPointFloat m_position; // 0x10
Mx3DPointFloat m_direction; // 0x24
Mx3DPointFloat m_up; // 0x38
};
#endif // LEGONAMEDPLANE_H

View file

@ -7,6 +7,7 @@
#include "mxtypes.h"
struct LegoEdge;
class LegoNamedPlane;
class LegoPathBoundary;
class LegoPathController;
struct LegoPathEdgeContainer;
@ -140,6 +141,8 @@ class LegoPathActor : public LegoActor {
void SetController(LegoPathController* p_controller) { m_controller = p_controller; }
void UpdatePlane(LegoNamedPlane& p_namedPlane);
// SYNTHETIC: LEGO1 0x1002d800
// LegoPathActor::`scalar deleting destructor'

View file

@ -27,6 +27,7 @@ class LegoState : public MxCore {
};
// FUNCTION: LEGO1 0x10017c00
// FUNCTION: BETA10 0x10031dc0
Playlist()
{
m_objectIds = NULL;
@ -35,28 +36,30 @@ class LegoState : public MxCore {
m_nextIndex = 0;
}
Playlist(MxU32* p_objectIds, MxS16 p_length)
// FUNCTION: BETA10 0x10031e10
Playlist(MxU32* p_objectIds, MxS16 p_length, MxS16 p_mode)
{
m_objectIds = p_objectIds;
m_length = p_length;
m_mode = e_loop;
m_mode = p_mode;
m_nextIndex = 0;
}
// FUNCTION: LEGO1 0x10071800
Playlist& operator=(const Playlist& p_shuffle)
// FUNCTION: BETA10 0x10031e70
Playlist& operator=(const Playlist& p_playlist)
{
m_objectIds = p_shuffle.m_objectIds;
m_length = p_shuffle.m_length;
m_nextIndex = p_shuffle.m_nextIndex;
m_mode = p_shuffle.m_mode;
m_objectIds = p_playlist.m_objectIds;
m_length = p_playlist.m_length;
m_nextIndex = p_playlist.m_nextIndex;
m_mode = p_playlist.m_mode;
return *this;
}
MxU32 Next();
MxBool Contains(MxU32 p_objectId);
void SetUnknown0x08(MxS16 p_unk0x08) { m_nextIndex = p_unk0x08; }
void SetNextIndex(MxS16 p_nextIndex) { m_nextIndex = p_nextIndex; }
MxResult ReadFromFile(LegoFile* p_file)
{
@ -70,7 +73,6 @@ class LegoState : public MxCore {
return SUCCESS;
}
private:
MxU32* m_objectIds; // 0x00
MxS16 m_length; // 0x04
MxS16 m_mode; // 0x06
@ -97,7 +99,7 @@ class LegoState : public MxCore {
virtual MxBool IsSerializable() { return TRUE; } // vtable+0x14
// FUNCTION: LEGO1 0x10005fa0
virtual MxBool SetFlag() { return FALSE; } // vtable+0x18
virtual MxBool Reset() { return FALSE; } // vtable+0x18
// FUNCTION: LEGO1 0x10005fb0
virtual MxResult Serialize(LegoFile* p_file)

View file

@ -10,6 +10,9 @@
#define WM_ISLE_SETCURSOR 0x5400
// name verified by BETA10 0x100d4054
#define DS_NOT_A_STREAM -1
enum Cursor {
e_cursorArrow = 0,
e_cursorBusy,
@ -46,7 +49,7 @@ MxS16 CountTotalTreeNodes(LegoTreeNode* p_node);
LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index);
void FUN_1003e050(LegoAnimPresenter* p_presenter);
Extra::ActionType MatchActionString(const char*);
void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender);
void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender);
void SetCameraControllerFromIsle();
void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bOut, float* p_gOut);
void PlayCamAnim(LegoPathActor* p_actor, MxBool p_unused, MxU32 p_location, MxBool p_bool);

View file

@ -34,7 +34,7 @@ class MxTransitionManager : public MxCore {
virtual MxResult GetDDrawSurfaceFromVideoManager(); // vtable+0x14
enum TransitionType {
e_notTransitioning = 0,
e_idle = 0, // name verified by BETA10 0x100ec4e6
e_noAnimation,
e_dissolve,
e_mosaic,
@ -45,7 +45,7 @@ class MxTransitionManager : public MxCore {
MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim);
TransitionType GetTransitionType() { return m_transitionType; }
TransitionType GetTransitionType() { return m_mode; }
// SYNTHETIC: LEGO1 0x1004b9e0
// MxTransitionManager::`scalar deleting destructor'
@ -68,13 +68,16 @@ class MxTransitionManager : public MxCore {
FlagBitfield m_copyFlags; // 0x20
undefined4 m_unk0x24; // 0x24
FlagBitfield m_unk0x28; // 0x28
TransitionType m_transitionType; // 0x2c
LPDIRECTDRAWSURFACE m_ddSurface; // 0x30
MxU16 m_animationTimer; // 0x34
MxU16 m_columnOrder[640]; // 0x36
MxU16 m_randomShift[480]; // 0x536
MxULong m_systemTime; // 0x8f8
MxS32 m_animationSpeed; // 0x8fc
// name verified by BETA10 0x100ec4e6
TransitionType m_mode; // 0x2c
LPDIRECTDRAWSURFACE m_ddSurface; // 0x30
MxU16 m_animationTimer; // 0x34
MxU16 m_columnOrder[640]; // 0x36
MxU16 m_randomShift[480]; // 0x536
MxULong m_systemTime; // 0x8f8
MxS32 m_animationSpeed; // 0x8fc
};
#endif // MXTRANSITIONMANAGER_H

View file

@ -1,11 +1,13 @@
#ifndef PIZZA_H
#define PIZZA_H
#include "actionsfwd.h"
#include "decomp.h"
#include "isleactor.h"
#include "legostate.h"
class Act1State;
class PizzeriaState;
class SkateBoard;
// VTABLE: LEGO1 0x100d7408
@ -13,14 +15,89 @@ class SkateBoard;
class PizzaMissionState : public LegoState {
public:
// SIZE 0x20
struct Entry {
public:
struct Mission {
// FUNCTION: LEGO1 0x10039220
// FUNCTION: BETA10 0x100ef880
Mission() {}
// FUNCTION: BETA10 0x100ef8a0
Mission(
MxU8 p_actorId,
undefined2 p_unk0x04,
MxLong* p_finishTimes,
IsleScript::Script* p_actions,
MxS16 p_numActions
)
{
m_numActions = p_numActions;
m_actorId = p_actorId;
m_unk0x04 = p_unk0x04;
m_unk0x06 = 1;
m_unk0x08 = 1;
m_finishTimes = p_finishTimes;
m_startTime = INT_MIN;
m_unk0x14 = 1;
m_score = LegoState::e_grey;
m_hiScore = LegoState::e_grey;
m_actions = p_actions;
}
// FUNCTION: LEGO1 0x10039230
Mission& operator=(const Mission& p_mission)
{
m_actorId = p_mission.m_actorId;
m_unk0x04 = p_mission.m_unk0x04;
m_unk0x06 = p_mission.m_unk0x06;
m_unk0x08 = p_mission.m_unk0x08;
m_finishTimes = p_mission.m_finishTimes;
m_startTime = p_mission.m_startTime;
m_unk0x14 = p_mission.m_unk0x14;
m_score = p_mission.m_score;
m_hiScore = p_mission.m_hiScore;
m_actions = p_mission.m_actions;
m_numActions = p_mission.m_numActions;
return *this;
}
// FUNCTION: BETA10 0x100ef610
IsleScript::Script GetRedFinishAction() { return m_actions[m_numActions + 6]; }
// FUNCTION: BETA10 0x100ef640
IsleScript::Script GetBlueFinishAction() { return m_actions[m_numActions + 7]; }
// FUNCTION: BETA10 0x100ef670
IsleScript::Script GetYellowFinishAction() { return m_actions[m_numActions + 8]; }
// FUNCTION: BETA10 0x100ef6a0
MxLong GetRedFinishTime() { return m_finishTimes[0]; }
// FUNCTION: BETA10 0x100ef6d0
MxLong GetBlueFinishTime() { return m_finishTimes[1]; }
// FUNCTION: BETA10 0x100ef700
void UpdateScore(ScoreColor p_score)
{
m_score = p_score;
if (m_hiScore < p_score) {
m_hiScore = p_score;
}
}
// FUNCTION: BETA10 0x100ef780
IsleScript::Script* GetActions() { return m_actions; }
// FUNCTION: BETA10 0x100ef7b0
IsleScript::Script GetUnknownFinishAction() { return m_actions[m_numActions + 2]; }
// FUNCTION: BETA10 0x100ef7e0
MxLong GetTimeoutTime() { return m_finishTimes[3]; }
MxResult WriteToFile(LegoFile* p_file)
{
Write(p_file, m_unk0x06);
Write(p_file, m_unk0x14);
Write(p_file, m_unk0x16);
Write(p_file, m_score);
Write(p_file, m_hiScore);
return SUCCESS;
}
@ -28,21 +105,22 @@ class PizzaMissionState : public LegoState {
{
Read(p_file, &m_unk0x06);
Read(p_file, &m_unk0x14);
Read(p_file, &m_unk0x16);
Read(p_file, &m_score);
Read(p_file, &m_hiScore);
return SUCCESS;
}
undefined2 m_unk0x00; // 0x00
MxU8 m_id; // 0x02
undefined m_unk0x03[3]; // 0x03
MxS16 m_unk0x06; // 0x06
undefined m_unk0x08[8]; // 0x08
undefined4 m_unk0x10; // 0x10
MxS16 m_unk0x14; // 0x14
MxS16 m_unk0x16; // 0x16
MxS16 m_score; // 0x18
undefined m_unk0x1a[6]; // 0x1a
MxS16 m_numActions; // 0x00
MxU8 m_actorId; // 0x02
undefined2 m_unk0x04; // 0x04
MxS16 m_unk0x06; // 0x06
undefined m_unk0x08; // 0x08
MxLong* m_finishTimes; // 0x0c
MxLong m_startTime; // 0x10
MxS16 m_unk0x14; // 0x14
MxS16 m_score; // 0x16
MxS16 m_hiScore; // 0x18
IsleScript::Script* m_actions; // 0x1c
};
PizzaMissionState();
@ -62,17 +140,36 @@ class PizzaMissionState : public LegoState {
MxResult Serialize(LegoFile* p_file) override; // vtable+0x1c
MxS16 GetHighScore(MxU8 p_id) { return GetState(p_id)->m_score; }
// FUNCTION: BETA10 0x100ef470
void SetUnknown0xb0(MxU32 p_unk0xb0) { m_unk0xb0 = p_unk0xb0; }
// FUNCTION: BETA10 0x100ef850
MxU32 GetUnknown0xb0() { return m_unk0xb0; }
MxS16 GetHighScore(MxU8 p_actorId) { return GetMission(p_actorId)->m_hiScore; }
// SYNTHETIC: LEGO1 0x10039350
// PizzaMissionState::`scalar deleting destructor'
Entry* GetState(MxU8 p_id);
Mission* GetMission(MxU8 p_actorId);
MxS16 FUN_10039540();
undefined4 m_unk0x08; // 0x08
undefined4 m_unk0x0c; // 0x0c
Entry m_state[5]; // 0x10
undefined4 m_unk0xb0; // 0xb0
PizzeriaState* m_pizzeriaState; // 0x08
undefined4 m_unk0x0c; // 0x0c
Mission m_missions[5]; // 0x10
MxU32 m_unk0xb0; // 0xb0
static IsleScript::Script g_pepperActions[];
static IsleScript::Script g_mamaActions[];
static IsleScript::Script g_papaActions[];
static IsleScript::Script g_nickActions[];
static IsleScript::Script g_lauraActions[];
static MxLong g_pepperFinishTimes[];
static MxLong g_mamaFinishTimes[];
static MxLong g_papaFinishTimes[];
static MxLong g_nickFinishTimes[];
static MxLong g_lauraFinishTimes[];
};
// VTABLE: LEGO1 0x100d7380
@ -97,31 +194,31 @@ class Pizza : public IsleActor {
return !strcmp(p_name, Pizza::ClassName()) || IsleActor::IsA(p_name);
}
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
MxLong HandleClick() override; // vtable+0x68
MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74
MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x80
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
MxLong HandleClick() override; // vtable+0x68
MxLong HandleEndAction(MxEndActionNotificationParam& p_param) override; // vtable+0x74
MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0x80
void CreateState();
void FUN_10038220(MxU32 p_objectId);
void FUN_10038220(IsleScript::Script p_objectId);
void FUN_100382b0();
void FUN_10038380();
void FUN_10038fe0(MxU32 p_objectId, MxBool);
void StopActions();
void PlayAction(MxU32 p_objectId, MxBool p_param7);
void SetSkateboard(SkateBoard* p_skateboard) { m_skateboard = p_skateboard; }
void SetSkateboard(SkateBoard* p_skateBoard) { m_skateBoard = p_skateBoard; }
// SYNTHETIC: LEGO1 0x100380e0
// Pizza::`scalar deleting destructor'
private:
PizzaMissionState* m_state; // 0x7c
PizzaMissionState::Entry* m_entry; // 0x80
SkateBoard* m_skateboard; // 0x84
Act1State* m_act1state; // 0x88
undefined4 m_unk0x8c; // 0x8c
undefined4 m_unk0x90; // 0x90
undefined4 m_unk0x94; // 0x94
undefined m_unk0x98; // 0x98
PizzaMissionState* m_state; // 0x7c
PizzaMissionState::Mission* m_mission; // 0x80
SkateBoard* m_skateBoard; // 0x84
Act1State* m_act1state; // 0x88
IsleScript::Script m_unk0x8c; // 0x8c
MxLong m_unk0x90; // 0x90
MxLong m_unk0x94; // 0x94
MxBool m_unk0x98; // 0x98
};
#endif // PIZZA_H

View file

@ -1,6 +1,7 @@
#ifndef PIZZERIA_H
#define PIZZERIA_H
#include "actionsfwd.h"
#include "decomp.h"
#include "isleactor.h"
#include "legostate.h"
@ -11,15 +12,6 @@ class PizzaMissionState;
// SIZE 0x58
class PizzeriaState : public LegoState {
public:
// SIZE 0x14
struct StateStruct {
undefined4 m_unk0x00; // 0x00
undefined4 m_unk0x04; // 0x04
undefined4 m_unk0x08; // 0x08
undefined4 m_unk0x0c; // 0x0c
undefined4 m_unk0x10; // 0x10
};
PizzeriaState();
// FUNCTION: LEGO1 0x10017c20
@ -40,12 +32,17 @@ class PizzeriaState : public LegoState {
// SYNTHETIC: LEGO1 0x10017ce0
// PizzeriaState::`scalar deleting destructor'
MxU32 FUN_10017d70();
// TODO: Most likely getters/setters are not used according to BETA.
MxS16 FUN_10017d50();
MxU32 NextAction();
Playlist m_unk0x08[5]; // 0x08
StateStruct m_unk0x44; // 0x44
MxS32 m_unk0x44[5]; // 0x44
static IsleScript::Script g_pepperActions[];
static IsleScript::Script g_mamaActions[];
static IsleScript::Script g_papaActions[];
static IsleScript::Script g_nickActions[];
static IsleScript::Script g_lauraActions[];
};
// VTABLE: LEGO1 0x100d5520

View file

@ -31,7 +31,7 @@ class ScoreState : public LegoState {
MxBool IsSerializable() override { return FALSE; } // vtable+0x14
// FUNCTION: LEGO1 0x1000de30
MxBool SetFlag() override
MxBool Reset() override
{
m_playCubeTutorial = TRUE;
return TRUE;

View file

@ -35,13 +35,12 @@ class SkateBoard : public IslePathActor {
void SetUnknown0x160(MxBool p_unk0x160) { m_unk0x160 = p_unk0x160; }
void ActivateSceneActions();
void EnableScenePresentation(MxBool p_enable);
// SYNTHETIC: LEGO1 0x1000ff60
// SkateBoard::`scalar deleting destructor'
private:
void EnableScenePresentation(MxBool p_enable);
MxBool m_unk0x160; // 0x160
Act1State* m_act1state; // 0x164
};

View file

@ -40,7 +40,7 @@ MxResult Bike::Create(MxDSAction& p_dsAction)
void Bike::Exit()
{
IslePathActor::Exit();
GameState()->SetCurrentArea(LegoGameState::Area::e_bike);
GameState()->m_currentArea = LegoGameState::Area::e_bike;
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_BikeDashboard_Bitmap);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_BikeArms_Ctl);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_BikeHorn_Ctl);

View file

@ -1,6 +1,7 @@
#include "bumpbouy.h"
#include "isle.h"
#include "isle_actions.h"
#include "islepathactor.h"
#include "legogamestate.h"
#include "legovideomanager.h"
@ -44,7 +45,7 @@ MxLong BumpBouy::Notify(MxParam& p_param)
assert(isleState);
isleState->m_unk0x018 = 5;
Isle* isle = (Isle*) FindWorld(*g_isleScript, 0);
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
assert(isle);
isle->SetDestLocation(LegoGameState::e_jetrace);

View file

@ -1,12 +1,21 @@
#include "doors.h"
#include "mxmisc.h"
#include "mxtimer.h"
DECOMP_SIZE_ASSERT(Doors, 0x1f8)
// STUB: LEGO1 0x10066100
// FUNCTION: LEGO1 0x10066100
MxResult Doors::VTable0x94(LegoPathActor* p_actor, MxBool p_bool)
{
// TODO
return 0;
if (m_unk0x154 == 1) {
m_unk0x154 = 2;
m_unk0x158 = Timer()->GetTime();
m_unk0x164 = m_unk0x15c[2];
m_unk0x1ac = m_unk0x160[2];
}
return m_unk0x1f4 < 0.001 ? SUCCESS : FAILURE;
}
// STUB: LEGO1 0x10066250

View file

@ -76,7 +76,7 @@ void Helicopter::Exit()
IslePathActor::Exit();
if (GameState()->GetCurrentAct() == LegoGameState::e_act1) {
GameState()->SetCurrentArea(LegoGameState::e_copter);
GameState()->m_currentArea = LegoGameState::e_copter;
if (UserActor() && UserActor()->IsA("IslePathActor")) {
((IslePathActor*) UserActor())
->SpawnPlayer(
@ -180,7 +180,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
break;
}
Exit();
GameState()->SetCurrentArea(LegoGameState::e_unk66);
GameState()->m_currentArea = LegoGameState::e_unk66;
ret = 1;
break;
case IsleScript::c_Helicopter_TakeOff_Ctl: {

View file

@ -41,7 +41,7 @@ MxLong JukeBoxEntity::Notify(MxParam& p_param)
((IslePathActor*) UserActor())->Exit();
}
((Isle*) FindWorld(*g_isleScript, 0))->SetDestLocation(LegoGameState::e_jukeboxw);
((Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle))->SetDestLocation(LegoGameState::e_jukeboxw);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
return 1;
}

View file

@ -2,30 +2,143 @@
#include "isle.h"
#include "isle_actions.h"
#include "jukebox_actions.h"
#include "legoanimationmanager.h"
#include "legoeventnotificationparam.h"
#include "legogamestate.h"
#include "legoinputmanager.h"
#include "legopathstruct.h"
#include "legoutils.h"
#include "legoworld.h"
#include "misc.h"
#include "mxactionnotificationparam.h"
#include "mxbackgroundaudiomanager.h"
#include "mxdebug.h"
#include "mxmisc.h"
#include "mxticklemanager.h"
#include "mxtimer.h"
#include "mxtransitionmanager.h"
#include "pizzeria.h"
#include "skateboard.h"
#include "sndanim_actions.h"
DECOMP_SIZE_ASSERT(Pizza, 0x9c)
DECOMP_SIZE_ASSERT(PizzaMissionState, 0xb4)
DECOMP_SIZE_ASSERT(PizzaMissionState::Entry, 0x20)
DECOMP_SIZE_ASSERT(PizzaMissionState::Mission, 0x20)
// Flags used in isle.cpp
extern MxU32 g_isleFlags;
// GLOBAL: LEGO1 0x100f3a80
IsleScript::Script PizzaMissionState::g_pepperActions[] = {
IsleScript::c_pnsx48pr_RunAnim,
IsleScript::c_pnsx69pr_RunAnim,
IsleScript::c_pns125ni_RunAnim,
IsleScript::c_pns122pr_RunAnim,
IsleScript::c_noneIsle,
IsleScript::c_noneIsle,
IsleScript::c_ppz120pa_RunAnim,
IsleScript::c_ppz117ma_RunAnim,
IsleScript::c_ppz118ma_RunAnim,
IsleScript::c_ppz119ma_RunAnim,
IsleScript::c_nja001pr_RunAnim,
IsleScript::c_nja001pr_RunAnim,
IsleScript::c_nja001pr_RunAnim
};
// GLOBAL: LEGO1 0x100f3ab8
MxLong PizzaMissionState::g_pepperFinishTimes[] = {100000, 200000, 300000, 350000};
// GLOBAL: LEGO1 0x100f3ac8
IsleScript::Script PizzaMissionState::g_lauraActions[] = {
IsleScript::c_pns096pr_RunAnim,
IsleScript::c_pns097pr_RunAnim,
IsleScript::c_pns098pr_RunAnim,
IsleScript::c_pns099pr_RunAnim,
IsleScript::c_noneIsle,
IsleScript::c_ppz086bs_RunAnim,
IsleScript::c_ppz090ma_RunAnim,
IsleScript::c_ppz088ma_RunAnim,
IsleScript::c_ppz089ma_RunAnim,
IsleScript::c_ppz095pe_RunAnim,
IsleScript::c_pho104re_RunAnim,
IsleScript::c_pho105re_RunAnim,
IsleScript::c_pho106re_RunAnim
};
// GLOBAL: LEGO1 0x100f3b00
MxLong PizzaMissionState::g_lauraFinishTimes[] = {100000, 200000, 300000, 350000};
// GLOBAL: LEGO1 0x100f3b10
IsleScript::Script PizzaMissionState::g_nickActions[] = {
IsleScript::c_pns042bm_RunAnim,
IsleScript::c_pns043en_RunAnim,
IsleScript::c_pns045p1_RunAnim,
IsleScript::c_pns048pr_RunAnim,
IsleScript::c_ppz029rd_RunAnim,
IsleScript::c_noneIsle,
IsleScript::c_ppz038ma_RunAnim,
IsleScript::c_ppz037ma_RunAnim,
IsleScript::c_ppz037ma_RunAnim,
IsleScript::c_ppz037ma_RunAnim,
IsleScript::c_pgs050nu_RunAnim,
IsleScript::c_pgs051nu_RunAnim,
IsleScript::c_pgs052nu_RunAnim
};
// GLOBAL: LEGO1 0x100f3b48
MxLong PizzaMissionState::g_nickFinishTimes[] = {100000, 200000, 300000, 350000};
// GLOBAL: LEGO1 0x100f3b58
IsleScript::Script PizzaMissionState::g_mamaActions[] = {
IsleScript::c_pns022pr_RunAnim,
IsleScript::c_pns021dl_RunAnim,
IsleScript::c_pns018rd_RunAnim,
IsleScript::c_pns019pr_RunAnim,
IsleScript::c_ppz008rd_RunAnim,
IsleScript::c_noneIsle,
IsleScript::c_ppz013pa_RunAnim,
IsleScript::c_ppz010pa_RunAnim,
IsleScript::c_ppz011pa_RunAnim,
IsleScript::c_ppz016pe_RunAnim,
IsleScript::c_pps025ni_RunAnim,
IsleScript::c_pps026ni_RunAnim,
IsleScript::c_pps027ni_RunAnim
};
// GLOBAL: LEGO1 0x100f3b90
MxLong PizzaMissionState::g_mamaFinishTimes[] = {100000, 200000, 300000, 350000};
// GLOBAL: LEGO1 0x100f3ba0
IsleScript::Script PizzaMissionState::g_papaActions[] = {
IsleScript::c_pns065rd_RunAnim,
IsleScript::c_pns066db_RunAnim,
IsleScript::c_pns067gd_RunAnim,
IsleScript::c_pns069pr_RunAnim,
IsleScript::c_noneIsle,
IsleScript::c_noneIsle,
IsleScript::c_ppz061ma_RunAnim,
IsleScript::c_ppz059ma_RunAnim,
IsleScript::c_ppz060ma_RunAnim,
IsleScript::c_ppz064ma_RunAnim,
IsleScript::c_prt072sl_RunAnim,
IsleScript::c_prt073sl_RunAnim,
IsleScript::c_prt074sl_RunAnim
};
// GLOBAL: LEGO1 0x100f3bd8
MxLong PizzaMissionState::g_papaFinishTimes[] = {100000, 200000, 300000, 350000};
// FUNCTION: LEGO1 0x10037ef0
Pizza::Pizza()
{
m_state = NULL;
m_entry = NULL;
m_skateboard = NULL;
m_mission = NULL;
m_skateBoard = NULL;
m_act1state = NULL;
m_unk0x8c = -1;
m_unk0x98 = 0;
m_unk0x90 = 0x80000000;
m_unk0x8c = IsleScript::c_noneIsle;
m_unk0x98 = FALSE;
m_unk0x90 = INT_MIN;
}
// FUNCTION: LEGO1 0x10038100
@ -41,13 +154,14 @@ MxResult Pizza::Create(MxDSAction& p_dsAction)
if (result == SUCCESS) {
CreateState();
m_skateboard = (SkateBoard*) m_world->Find(m_atomId, IsleScript::c_SkateBoard_Actor);
m_skateBoard = (SkateBoard*) m_world->Find(m_atomId, IsleScript::c_SkateBoard_Actor);
}
return result;
}
// FUNCTION: LEGO1 0x100381b0
// FUNCTION: BETA10 0x100edaec
void Pizza::CreateState()
{
m_state = (PizzaMissionState*) GameState()->GetState("PizzaMissionState");
@ -62,68 +176,431 @@ void Pizza::CreateState()
}
// FUNCTION: LEGO1 0x10038220
void Pizza::FUN_10038220(MxU32 p_objectId)
// FUNCTION: BETA10 0x100edb81
void Pizza::FUN_10038220(IsleScript::Script p_objectId)
{
AnimationManager()->FUN_10064740(NULL);
m_entry = m_state->GetState(GameState()->GetActorId());
m_mission = m_state->GetMission(GameState()->GetActorId());
m_state->m_unk0x0c = 1;
m_act1state->m_unk0x018 = 3;
m_entry->m_unk0x10 = 0x80000000;
m_mission->m_startTime = INT_MIN;
g_isleFlags &= ~Isle::c_playMusic;
AnimationManager()->EnableCamAnims(FALSE);
AnimationManager()->FUN_1005f6d0(FALSE);
FUN_10038fe0(p_objectId, FALSE);
m_unk0x8c = -1;
PlayAction(p_objectId, FALSE);
m_unk0x8c = IsleScript::c_noneIsle;
}
// STUB: LEGO1 0x100382b0
// FUNCTION: LEGO1 0x100382b0
// FUNCTION: BETA10 0x100edc9b
void Pizza::FUN_100382b0()
{
if (m_state->m_unk0x0c != 8) {
if (m_unk0x8c != IsleScript::c_noneIsle) {
InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x8c, NULL);
}
m_act1state->m_unk0x018 = 0;
m_state->m_unk0x0c = 0;
UserActor()->SetState(0);
g_isleFlags |= Isle::c_playMusic;
AnimationManager()->EnableCamAnims(TRUE);
AnimationManager()->FUN_1005f6d0(TRUE);
m_mission->m_startTime = INT_MIN;
m_mission = NULL;
m_unk0x98 = FALSE;
m_unk0x8c = IsleScript::c_noneIsle;
BackgroundAudioManager()->RaiseVolume();
TickleManager()->UnregisterClient(this);
m_unk0x90 = INT_MIN;
m_skateBoard->EnableScenePresentation(FALSE);
m_skateBoard->SetUnknown0x160(FALSE);
MxTrace("Pizza mission: idle\n");
}
}
// STUB: LEGO1 0x10038380
void Pizza::FUN_10038380()
// FUNCTION: LEGO1 0x10038380
void Pizza::StopActions()
{
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_pns050p1_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns050p1_RunAnim, NULL);
PizzaMissionState::Mission* mission = m_mission;
if (mission != NULL) {
for (MxS32 i = 0; i < mission->m_numActions; i++) {
InvokeAction(Extra::e_stop, *g_isleScript, mission->GetActions()[i], NULL);
}
}
}
// STUB: LEGO1 0x100383f0
// FUNCTION: LEGO1 0x100383f0
// FUNCTION: BETA10 0x100edd10
MxLong Pizza::HandleClick()
{
// TODO
if (m_state->m_unk0x0c == 1) {
m_state->m_unk0x0c = 2;
m_mission->m_startTime = Timer()->GetTime();
TickleManager()->RegisterClient(this, 200);
AnimationManager()->FUN_10061010(FALSE);
}
if (m_state->m_unk0x0c == 2) {
m_act1state->m_unk0x018 = 3;
if (m_skateBoard == NULL) {
m_skateBoard = (SkateBoard*) m_world->Find(m_atomId, IsleScript::c_SkateBoard_Actor);
assert(m_skateBoard);
}
IsleScript::Script action;
switch (m_state->FUN_10039540()) {
case 0:
action = m_mission->m_actions[m_mission->m_numActions + 3];
break;
case 1:
action = m_mission->m_actions[m_mission->m_numActions + 4];
break;
default:
action = m_mission->m_actions[m_mission->m_numActions + 5];
}
PlayAction(action, TRUE);
m_state->m_unk0x0c = 3;
PlayMusic(JukeboxScript::c_PizzaMission_Music);
return 1;
}
return 0;
}
// STUB: LEGO1 0x100384f0
MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam&)
// FUNCTION: LEGO1 0x100384f0
// FUNCTION: BETA10 0x100ede53
MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
{
// TODO
if (m_state->m_unk0x0c == 4) {
MxLong time = Timer()->GetTime() - m_mission->m_startTime;
if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x12e &&
GameState()->GetActorId() == LegoActor::c_pepper) {
m_state->m_unk0x0c = 5;
m_state->SetUnknown0xb0(SndanimScript::c_TRS302_OpenJailDoor);
if (time < m_mission->GetRedFinishTime()) {
m_mission->UpdateScore(LegoState::e_red);
}
else if (time < m_mission->GetBlueFinishTime()) {
m_mission->UpdateScore(LegoState::e_blue);
}
else {
m_mission->UpdateScore(LegoState::e_yellow);
}
MxTrace("Pizza mission: ending\n");
}
else if ((p_param.GetTrigger() == LegoPathStruct::c_camAnim && (
((p_param.GetData() == 0x24 || p_param.GetData() == 0x22) && GameState()->GetActorId() == LegoActor::c_mama) ||
(p_param.GetData() == 0x33 && GameState()->GetActorId() == LegoActor::c_papa) ||
((p_param.GetData() == 0x08 || p_param.GetData() == 0x09) && GameState()->GetActorId() == LegoActor::c_nick) ||
(p_param.GetData() == 0x0b && GameState()->GetActorId() == LegoActor::c_laura)
)) || (p_param.GetTrigger() == LegoPathStruct::c_w && p_param.GetData() == 0x169 && GameState()->GetActorId() == LegoActor::c_nick)) {
IsleScript::Script action;
if (time < m_mission->GetRedFinishTime()) {
action = m_mission->GetRedFinishAction();
m_mission->UpdateScore(LegoState::e_red);
}
else if (time < m_mission->GetBlueFinishTime()) {
action = m_mission->GetBlueFinishAction();
m_mission->UpdateScore(LegoState::e_blue);
}
else {
action = m_mission->GetYellowFinishAction();
m_mission->UpdateScore(LegoState::e_yellow);
}
StopActions();
switch (action) {
case IsleScript::c_pps025ni_RunAnim:
case IsleScript::c_pps026ni_RunAnim:
case IsleScript::c_pps027ni_RunAnim:
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 3800;
break;
case IsleScript::c_pgs050nu_RunAnim:
case IsleScript::c_pgs051nu_RunAnim:
case IsleScript::c_pgs052nu_RunAnim:
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 6400;
break;
case IsleScript::c_prt072sl_RunAnim:
case IsleScript::c_prt073sl_RunAnim:
case IsleScript::c_prt074sl_RunAnim:
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 7000;
break;
case IsleScript::c_pho104re_RunAnim:
case IsleScript::c_pho105re_RunAnim:
case IsleScript::c_pho106re_RunAnim:
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 6500;
break;
}
m_state->m_unk0x0c = 5;
PlayAction(action, TRUE);
MxTrace("Pizza mission: ending\n");
}
else if (p_param.GetTrigger() == LegoPathStruct::c_w) {
if (p_param.GetData() == 0x15e && GameState()->GetActorId() == LegoActor::c_pepper) {
if (!m_unk0x98) {
m_unk0x98 = TRUE;
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns050p1_RunAnim, NULL);
}
}
else if (p_param.GetData() == 0x15f && GameState()->GetActorId() == LegoActor::c_papa && !m_unk0x98) {
m_unk0x98 = TRUE;
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns050p1_RunAnim, NULL);
}
}
}
return 0;
}
// STUB: LEGO1 0x100388a0
// FUNCTION: LEGO1 0x100388a0
// FUNCTION: BETA10 0x100ee2d9
MxResult Pizza::Tickle()
{
// TODO
MxLong time = Timer()->GetTime();
if (m_unk0x90 != INT_MIN && m_unk0x94 + m_unk0x90 <= time) {
m_unk0x90 = INT_MIN;
m_skateBoard->EnableScenePresentation(FALSE);
m_skateBoard->SetUnknown0x160(FALSE);
TickleManager()->UnregisterClient(this);
}
if (m_mission != NULL && m_mission->m_startTime != INT_MIN) {
if (m_state->m_unk0x0c == 4) {
assert(m_mission);
if (time > m_mission->m_startTime + m_mission->GetTimeoutTime()) {
StopActions();
m_mission->UpdateScore(LegoState::e_grey);
FUN_100382b0();
BackgroundAudioManager()->LowerVolume();
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_Avo917In_PlayWav, NULL);
MxTrace("Pizza mission: timeout, stop\n");
}
else if (time >= m_mission->m_startTime + 35000 && m_unk0x8c == IsleScript::c_noneIsle) {
switch (GameState()->GetActorId()) {
case LegoActor::c_pepper:
m_unk0x8c = IsleScript::c_Avo914In_PlayWav;
break;
case LegoActor::c_mama:
m_unk0x8c = IsleScript::c_Avo910In_PlayWav;
break;
case LegoActor::c_papa:
m_unk0x8c = IsleScript::c_Avo912In_PlayWav;
break;
case LegoActor::c_nick:
m_unk0x8c = IsleScript::c_Avo911In_PlayWav;
break;
case LegoActor::c_laura:
m_unk0x8c = IsleScript::c_Avo913In_PlayWav;
break;
}
BackgroundAudioManager()->LowerVolume();
if (m_unk0x8c != IsleScript::c_noneIsle) {
InvokeAction(Extra::e_start, *g_isleScript, m_unk0x8c, NULL);
}
}
}
else if (m_state->m_unk0x0c == 2) {
assert(m_mission);
if (Timer()->GetTime() > m_mission->m_startTime + 5000) {
m_skateBoard->SetUnknown0x160(FALSE);
m_skateBoard->EnableScenePresentation(FALSE);
TickleManager()->UnregisterClient(this);
m_mission->UpdateScore(LegoState::e_grey);
m_state->m_unk0x0c = 9;
AnimationManager()->FUN_1005f6d0(TRUE);
PlayAction(m_mission->GetUnknownFinishAction(), TRUE);
MxTrace("Pizza mission: timeout, declining\n");
}
}
}
return SUCCESS;
}
// STUB: LEGO1 0x10038b10
MxLong Pizza::HandleEndAction(MxEndActionNotificationParam&)
// FUNCTION: LEGO1 0x10038b10
// FUNCTION: BETA10 0x100ee4f5
MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
{
// TODO
return 0;
MxLong result = 0;
MxU32 objectId = p_param.GetAction()->GetObjectId();
if (m_unk0x8c == objectId) {
BackgroundAudioManager()->RaiseVolume();
return 1;
}
switch (m_state->m_unk0x0c) {
case 1:
if (m_state->GetUnknown0xb0() == objectId) {
m_state->m_unk0x0c = 2;
m_mission->m_startTime = Timer()->GetTime();
TickleManager()->RegisterClient(this, 200);
MxTrace("Pizza mission: proposed\n");
}
break;
case 3:
if (m_state->GetUnknown0xb0() == objectId) {
m_mission->m_startTime = Timer()->GetTime();
PizzaMissionState::Mission* mission = m_mission;
for (MxS32 i = 0; i < mission->m_numActions; i++) {
InvokeAction(Extra::e_start, *g_isleScript, mission->GetActions()[i], NULL);
}
m_state->m_unk0x0c = 4;
m_state->SetUnknown0xb0(IsleScript::c_noneIsle);
UserActor()->SetState(0);
m_skateBoard->SetUnknown0x160(TRUE);
m_world->PlaceActor(m_skateBoard, "int37", 2, 0.5, 3, 0.5);
#ifdef COMPAT_MODE
{
LegoEventNotificationParam param(c_notificationClick, NULL, 0, 0, 0, 0);
m_skateBoard->Notify(param);
}
#else
m_skateBoard->Notify(LegoEventNotificationParam(c_notificationClick, NULL, 0, 0, 0, 0));
#endif
MxTrace("Pizza mission: continues\n");
result = 1;
}
break;
case 5:
if (m_state->GetUnknown0xb0() == objectId) {
StopActions();
if (GameState()->GetActorId() == LegoActor::c_pepper) {
IsleScript::Script action = IsleScript::c_noneIsle;
if (!((Isle*) CurrentWorld())->HasHelicopter()) {
switch (m_mission->m_unk0x14) {
case 1:
action = IsleScript::c_pja126br_RunAnim;
m_mission->m_unk0x14++;
m_state->m_unk0x0c = 6;
MxTrace("Pizza mission: succeeds\n");
break;
case 2:
action = IsleScript::c_pja129br_RunAnim;
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 500;
m_mission->m_unk0x14++;
m_state->m_unk0x0c = 6;
MxTrace("Pizza mission: succeeds\n");
break;
case 3:
action = IsleScript::c_pja131br_RunAnim;
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 500;
m_state->m_unk0x0c = 6;
break;
}
}
else {
action = IsleScript::c_pja132br_RunAnim;
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 2300;
m_state->m_unk0x0c = 8;
InputManager()->DisableInputProcessing();
InputManager()->SetUnknown336(TRUE);
MxTrace("Pizza mission: go to Act2\n");
}
PlayAction(action, TRUE);
}
else {
FUN_100382b0();
m_state->m_unk0x0c = 0;
m_state->SetUnknown0xb0(IsleScript::c_noneIsle);
}
}
break;
case 6:
if (m_state->GetUnknown0xb0() == objectId) {
if (objectId == IsleScript::c_pja126br_RunAnim) {
PlayAction(IsleScript::c_pja127br_RunAnim, TRUE);
m_unk0x90 = Timer()->GetTime();
m_unk0x94 = 700;
}
else if (objectId == IsleScript::c_pja129br_RunAnim) {
PlayAction(IsleScript::c_pja130br_RunAnim, TRUE);
}
else {
FUN_100382b0();
m_state->m_unk0x0c = 0;
m_state->SetUnknown0xb0(IsleScript::c_noneIsle);
}
}
break;
case 8:
if (m_state->GetUnknown0xb0() == objectId) {
m_act1state->m_unk0x018 = 0;
m_state->m_unk0x0c = 0;
GameState()->m_currentArea = LegoGameState::e_isle;
TickleManager()->UnregisterClient(this);
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_act2main);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
}
break;
case 9:
if (m_state->GetUnknown0xb0() == objectId) {
FUN_100382b0();
}
break;
}
return result;
}
// STUB: LEGO1 0x10038fe0
void Pizza::FUN_10038fe0(MxU32 p_objectId, MxBool)
// FUNCTION: LEGO1 0x10038fe0
// FUNCTION: BETA10 0x100ef520
void Pizza::PlayAction(MxU32 p_objectId, MxBool p_param7)
{
// TODO
m_state->SetUnknown0xb0(p_objectId);
if (m_unk0x8c != IsleScript::c_noneIsle) {
InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x8c, NULL);
}
AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, FALSE, NULL, FALSE, p_param7, TRUE, TRUE);
}
// STUB: LEGO1 0x10039030
// FUNCTION: LEGO1 0x10039030
// FUNCTION: BETA10 0x100eea25
PizzaMissionState::PizzaMissionState()
{
// TODO
m_unk0x0c = 0;
m_missions[0] = Mission(LegoActor::c_pepper, 2, g_pepperFinishTimes, g_pepperActions, 4);
m_missions[1] = Mission(LegoActor::c_mama, 2, g_mamaFinishTimes, g_mamaActions, 4);
m_missions[2] = Mission(LegoActor::c_papa, 2, g_papaFinishTimes, g_papaActions, 4);
m_missions[3] = Mission(LegoActor::c_nick, 2, g_nickFinishTimes, g_nickActions, 4);
m_missions[4] = Mission(LegoActor::c_laura, 2, g_lauraFinishTimes, g_lauraActions, 4);
m_pizzeriaState = (PizzeriaState*) GameState()->GetState("PizzeriaState");
m_unk0xb0 = IsleScript::c_noneIsle;
}
// FUNCTION: LEGO1 0x100393c0
@ -133,12 +610,12 @@ MxResult PizzaMissionState::Serialize(LegoFile* p_file)
if (p_file->IsReadMode()) {
for (MxS16 i = 0; i < 5; i++) {
m_state[i].ReadFromFile(p_file);
m_missions[i].ReadFromFile(p_file);
}
}
else if (p_file->IsWriteMode()) {
for (MxS16 i = 0; i < 5; i++) {
m_state[i].WriteToFile(p_file);
m_missions[i].WriteToFile(p_file);
}
}
@ -146,13 +623,19 @@ MxResult PizzaMissionState::Serialize(LegoFile* p_file)
}
// FUNCTION: LEGO1 0x10039510
PizzaMissionState::Entry* PizzaMissionState::GetState(MxU8 p_id)
PizzaMissionState::Mission* PizzaMissionState::GetMission(MxU8 p_actorId)
{
for (MxS16 i = 0; i < 5; i++) {
if (m_state[i].m_id == p_id) {
return m_state + i;
if (m_missions[i].m_actorId == p_actorId) {
return m_missions + i;
}
}
return NULL;
}
// FUNCTION: LEGO1 0x10039540
MxS16 PizzaMissionState::FUN_10039540()
{
return m_pizzeriaState->FUN_10017d50();
}

View file

@ -13,7 +13,26 @@
DECOMP_SIZE_ASSERT(Pizzeria, 0x84)
DECOMP_SIZE_ASSERT(PizzeriaState, 0x58)
DECOMP_SIZE_ASSERT(PizzeriaState::StateStruct, 0x14)
// GLOBAL: LEGO1 0x100f0ce8
IsleScript::Script PizzeriaState::g_pepperActions[] =
{IsleScript::c_ppz107ma_RunAnim, IsleScript::c_ppz114pa_RunAnim, IsleScript::c_ppz114pa_RunAnim};
// GLOBAL: LEGO1 0x100f0cf8
IsleScript::Script PizzeriaState::g_mamaActions[] =
{IsleScript::c_ppz001pe_RunAnim, IsleScript::c_ppz006pa_RunAnim, IsleScript::c_ppz007pa_RunAnim};
// GLOBAL: LEGO1 0x100f0d08
IsleScript::Script PizzeriaState::g_papaActions[] =
{IsleScript::c_ppz054ma_RunAnim, IsleScript::c_ppz055ma_RunAnim, IsleScript::c_ppz056ma_RunAnim};
// GLOBAL: LEGO1 0x100f0d18
IsleScript::Script PizzeriaState::g_nickActions[] =
{IsleScript::c_ppz031ma_RunAnim, IsleScript::c_ppz035pa_RunAnim, IsleScript::c_ppz036pa_RunAnim};
// GLOBAL: LEGO1 0x100f0d28
IsleScript::Script PizzeriaState::g_lauraActions[] =
{IsleScript::c_ppz075pa_RunAnim, IsleScript::c_ppz082pa_RunAnim, IsleScript::c_ppz084pa_RunAnim};
// FUNCTION: LEGO1 0x100179c0
MxResult Pizzeria::Create(MxDSAction& p_dsAction)
@ -28,6 +47,7 @@ MxResult Pizzeria::Create(MxDSAction& p_dsAction)
}
// FUNCTION: LEGO1 0x100179f0
// FUNCTION: BETA10 0x100efbfc
void Pizzeria::CreateState()
{
LegoGameState* gameState = GameState();
@ -46,6 +66,7 @@ void Pizzeria::CreateState()
}
// FUNCTION: LEGO1 0x10017a50
// FUNCTION: BETA10 0x100efc91
MxLong Pizzeria::HandleClick()
{
if (FUN_1003ef60() && m_pizzaMissionState->m_unk0x0c == 0) {
@ -58,22 +79,41 @@ MxLong Pizzeria::HandleClick()
AnimationManager()->FUN_10061010(FALSE);
Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor);
pizza->FUN_10038220(m_pizzeriaState->FUN_10017d70());
pizza->FUN_10038220((IsleScript::Script) m_pizzeriaState->NextAction());
}
return 1;
}
// STUB: LEGO1 0x10017af0
// FUNCTION: LEGO1 0x10017af0
// FUNCTION: BETA10 0x100efd14
PizzeriaState::PizzeriaState()
{
// TODO
m_unk0x08[0] = Playlist((MxU32*) g_pepperActions, sizeOfArray(g_pepperActions), Playlist::e_once);
m_unk0x08[1] = Playlist((MxU32*) g_mamaActions, sizeOfArray(g_mamaActions), Playlist::e_once);
m_unk0x08[2] = Playlist((MxU32*) g_papaActions, sizeOfArray(g_papaActions), Playlist::e_once);
m_unk0x08[3] = Playlist((MxU32*) g_nickActions, sizeOfArray(g_nickActions), Playlist::e_once);
m_unk0x08[4] = Playlist((MxU32*) g_lauraActions, sizeOfArray(g_lauraActions), Playlist::e_once);
memset(m_unk0x44, -1, sizeof(m_unk0x44));
}
// STUB: LEGO1 0x10017d70
MxU32 PizzeriaState::FUN_10017d70()
// FUNCTION: LEGO1 0x10017d50
MxS16 PizzeriaState::FUN_10017d50()
{
return 0;
return m_unk0x44[GameState()->GetActorId() - 1];
}
// FUNCTION: LEGO1 0x10017d70
// FUNCTION: BETA10 0x100effc0
MxU32 PizzeriaState::NextAction()
{
MxU8 actorId = GameState()->GetActorId();
if (m_unk0x44[actorId - 1] < 2) {
m_unk0x44[actorId - 1]++;
}
return m_unk0x08[actorId - 1].Next();
}
// FUNCTION: LEGO1 0x10017da0

View file

@ -18,7 +18,7 @@ DECOMP_SIZE_ASSERT(Radio, 0x10)
DECOMP_SIZE_ASSERT(RadioState, 0x30)
// GLOBAL: LEGO1 0x100f3218
JukeboxScript::Script g_unk0x100f3218[6] = {
JukeboxScript::Script g_unk0x100f3218[] = {
JukeboxScript::c_sns002ra_Audio,
JukeboxScript::c_sns001ja_Audio,
JukeboxScript::c_snsc01js_Audio,
@ -28,7 +28,7 @@ JukeboxScript::Script g_unk0x100f3218[6] = {
};
// GLOBAL: LEGO1 0x100f3230
JukeboxScript::Script g_unk0x100f3230[14] = {
JukeboxScript::Script g_unk0x100f3230[] = {
JukeboxScript::c_ham035ra_Audio,
JukeboxScript::c_ham039ra_Audio,
JukeboxScript::c_sns005ra_Audio,
@ -46,7 +46,7 @@ JukeboxScript::Script g_unk0x100f3230[14] = {
};
// GLOBAL: LEGO1 0x100f3268
JukeboxScript::Script g_unk0x100f3268[9] = {
JukeboxScript::Script g_unk0x100f3268[] = {
JukeboxScript::c_CentralRoads_Music,
JukeboxScript::c_BeachBlvd_Music,
JukeboxScript::c_ResidentalArea_Music,
@ -214,14 +214,14 @@ RadioState::RadioState()
MxS32 random = rand();
m_unk0x2c = random % 3;
m_unk0x08[0] = LegoState::Playlist((MxU32*) g_unk0x100f3218, sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0]));
m_unk0x08[0].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3218) / sizeof(g_unk0x100f3218[0])));
m_unk0x08[0] = Playlist((MxU32*) g_unk0x100f3218, sizeOfArray(g_unk0x100f3218), Playlist::e_loop);
m_unk0x08[0].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3218));
m_unk0x08[1] = LegoState::Playlist((MxU32*) g_unk0x100f3230, sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0]));
m_unk0x08[1].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3230) / sizeof(g_unk0x100f3230[0])));
m_unk0x08[1] = Playlist((MxU32*) g_unk0x100f3230, sizeOfArray(g_unk0x100f3230), Playlist::e_loop);
m_unk0x08[1].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3230));
m_unk0x08[2] = LegoState::Playlist((MxU32*) g_unk0x100f3268, sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0]));
m_unk0x08[2].SetUnknown0x08(rand() % (sizeof(g_unk0x100f3268) / sizeof(g_unk0x100f3268[0])));
m_unk0x08[2] = Playlist((MxU32*) g_unk0x100f3268, sizeOfArray(g_unk0x100f3268), Playlist::e_loop);
m_unk0x08[2].SetNextIndex(rand() % sizeOfArray(g_unk0x100f3268));
m_active = FALSE;
}

View file

@ -58,7 +58,7 @@ void SkateBoard::Exit()
{
if (m_act1state->m_unk0x018 == 3) {
Pizza* pizza = (Pizza*) CurrentWorld()->Find(*g_isleScript, IsleScript::c_Pizza_Actor);
pizza->FUN_10038380();
pizza->StopActions();
pizza->FUN_100382b0();
m_unk0x160 = FALSE;
}

View file

@ -300,6 +300,7 @@ void MxBackgroundAudioManager::Stop()
}
// FUNCTION: LEGO1 0x1007f570
// FUNCTION: BETA10 0x100e94e6
void MxBackgroundAudioManager::LowerVolume()
{
if (m_unk0x148 == 0) {

View file

@ -1,8 +1,12 @@
#include "legocarbuild.h"
#include "copter_actions.h"
#include "dunebuggy.h"
#include "dunecar_actions.h"
#include "helicopter.h"
#include "isle_actions.h"
#include "jetski.h"
#include "jetski_actions.h"
#include "jukebox_actions.h"
#include "legocarbuildpresenter.h"
#include "legocontrolmanager.h"
@ -20,14 +24,59 @@
#include "mxstillpresenter.h"
#include "mxticklemanager.h"
#include "mxtransitionmanager.h"
#include "mxvariabletable.h"
#include "racecar.h"
#include "racecar_actions.h"
#include "scripts.h"
#include <isle.h>
#include <vec.h>
// Names and values verified by BETA10 0x1006d742.
// Note that these were probably hard-coded numbers in the original.
#define Helicopter_Actor CopterScript::c_Helicopter_Actor
#define DuneBugy_Actor DunecarScript::c_DuneBugy_Actor
#define Jetski_Actor JetskiScript::c_Jetski_Actor
#define RaceCar_Actor RacecarScript::c_RaceCar_Actor
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;
@ -44,7 +93,7 @@ LegoCarBuild::LegoCarBuild()
{
m_unk0x100 = 0;
m_unk0x110 = 0;
m_unk0xf8 = 0xffffffff;
m_unk0xf8 = c_unknownminusone;
m_unk0x2d4 = FALSE;
m_unk0x258 = 0;
m_ColorBook_Bitmap = NULL;
@ -72,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);
}
@ -87,12 +136,27 @@ MxBool LegoCarBuild::VTable0x5c()
return TRUE;
}
// STUB: LEGO1 0x10022a80
// STUB: BETA10 0x1006aea3
// FUNCTION: LEGO1 0x10022a80
// FUNCTION: BETA10 0x1006aea3
LegoCarBuild::~LegoCarBuild()
{
// TODO
// ...
m_unk0x100 = 0;
m_unk0x110 = NULL;
if (m_unk0x258) {
m_unk0x258->SetUnknown0xbc(0);
m_unk0x258->SetTickleState(MxPresenter::e_idle);
m_unk0x258 = NULL;
}
ControlManager()->Unregister(this);
TickleManager()->UnregisterClient(this);
if (InputManager()->GetWorld() == this) {
InputManager()->ClearWorld();
}
InputManager()->UnRegister(this);
NotificationManager()->Unregister(this);
}
@ -116,23 +180,23 @@ MxResult LegoCarBuild::Create(MxDSAction& p_dsAction)
if (m_atomId == *g_copterScript) {
buildStateClassName = "LegoCopterBuildState";
GameState()->SetCurrentArea(LegoGameState::e_copterbuild);
m_unk0x330 = 1;
GameState()->m_currentArea = LegoGameState::e_copterbuild;
m_carId = Helicopter_Actor;
}
else if (m_atomId == *g_dunecarScript) {
buildStateClassName = "LegoDuneCarBuildState";
GameState()->SetCurrentArea(LegoGameState::e_dunecarbuild);
m_unk0x330 = 2;
GameState()->m_currentArea = LegoGameState::e_dunecarbuild;
m_carId = DuneBugy_Actor;
}
else if (m_atomId == *g_jetskiScript) {
buildStateClassName = "LegoJetskiBuildState";
GameState()->SetCurrentArea(LegoGameState::e_jetskibuild);
m_unk0x330 = 3;
GameState()->m_currentArea = LegoGameState::e_jetskibuild;
m_carId = Jetski_Actor;
}
else if (m_atomId == *g_racecarScript) {
buildStateClassName = "LegoRaceCarBuildState";
GameState()->SetCurrentArea(LegoGameState::e_racecarbuild);
m_unk0x330 = 4;
GameState()->m_currentArea = LegoGameState::e_racecarbuild;
m_carId = Helicopter_Actor;
}
LegoGameState* gameState = GameState();
@ -409,7 +473,7 @@ MxResult LegoCarBuild::Tickle()
return SUCCESS;
}
if (m_unk0xf8 == 8) {
if (m_unk0xf8 == c_unknown8) {
if (m_unk0xfc == 1) {
FUN_10024f50();
}
@ -429,7 +493,7 @@ MxResult LegoCarBuild::Tickle()
DWORD time = timeGetTime();
DWORD dTime = (time - m_unk0x10c) / 100;
if (m_unk0x330 == 4) {
if (m_carId == Helicopter_Actor) {
switch (m_unk0x10a) {
// TODO: Work out constants
case 500:
@ -452,7 +516,7 @@ MxResult LegoCarBuild::Tickle()
return SUCCESS;
}
}
else if (m_unk0x330 == 3) {
else if (m_carId == Jetski_Actor) {
switch (m_unk0x10a) {
case 500:
LEGOCARBUILD_TICKLE_CASE(291, 291, 311, "Exit_Ctl")
@ -473,7 +537,7 @@ MxResult LegoCarBuild::Tickle()
// return SUCCESS;
}
}
else if (m_unk0x330 == 2) {
else if (m_carId == DuneBugy_Actor) {
switch (m_unk0x10a) {
case 500:
LEGOCARBUILD_TICKLE_CASE(155, 155, 175, "Exit_Ctl")
@ -490,7 +554,7 @@ MxResult LegoCarBuild::Tickle()
return SUCCESS;
}
}
else if (m_unk0x330 == 1) {
else if (m_carId == Helicopter_Actor) {
switch (m_unk0x10a) {
case 500:
LEGOCARBUILD_TICKLE_CASE(185, 185, 205, "Exit_Ctl")
@ -575,7 +639,7 @@ MxLong LegoCarBuild::Notify(MxParam& p_param)
break;
case c_notificationControl:
result = FUN_10024890((LegoEventNotificationParam*) &p_param);
result = FUN_10024890(&p_param);
if (result == 1) {
m_unk0x109 = 0;
@ -583,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();
@ -605,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;
@ -624,7 +688,7 @@ void LegoCarBuild::ReadyWorld()
InitPresenters();
if (BackgroundAudioManager()->GetEnabled()) {
InvokeAction(Extra::ActionType::e_start, *g_jukeboxScript, FUN_10025ee0(m_unk0x330), NULL);
InvokeAction(Extra::ActionType::e_start, *g_jukeboxScript, FUN_10025ee0(m_carId), NULL);
m_buildState->m_animationState = LegoVehicleBuildState::e_unknown2;
NotificationManager()->Send(this, MxNotificationParam());
}
@ -636,8 +700,8 @@ void LegoCarBuild::ReadyWorld()
// FUNCTION: LEGO1 0x100243a0
void LegoCarBuild::FUN_100243a0()
{
switch (m_unk0x330) {
case 1:
switch (m_carId) {
case Helicopter_Actor:
if (GameState()->GetCurrentAct() == LegoGameState::Act::e_act2) {
m_destLocation = LegoGameState::Area::e_act3script;
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
@ -648,15 +712,15 @@ void LegoCarBuild::FUN_100243a0()
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
break;
}
case 2:
case DuneBugy_Actor:
m_destLocation = LegoGameState::Area::e_garadoor;
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
break;
case 3:
case Jetski_Actor:
m_destLocation = LegoGameState::Area::e_unk17;
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
break;
case 4:
case RaceCar_Actor:
m_destLocation = LegoGameState::Area::e_unk20;
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
}
@ -771,14 +835,207 @@ MxS32 LegoCarBuild::FUN_10024850(MxLong p_x, MxLong p_y)
return result;
}
// STUB: LEGO1 0x10024890
// STUB: BETA10 0x1006d512
undefined4 LegoCarBuild::FUN_10024890(LegoEventNotificationParam* p_param)
#ifdef NDEBUG
// FUNCTION: LEGO1 0x10024890
undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
{
// TODO
return 0;
undefined4 result = 0;
LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param;
assert(m_buildState);
if (param->m_unk0x28) {
switch (param->m_clickedObjectId) {
// The enum values are all identical between CopterScript, DunecarScript, JetskiScript, and RacecarScript
case CopterScript::c_Info_Ctl:
if (m_buildState->m_animationState != LegoVehicleBuildState::e_unknown4 &&
m_buildState->m_animationState != LegoVehicleBuildState::e_unknown2 &&
m_buildState->m_animationState != LegoVehicleBuildState::e_exiting &&
GameState()->GetCurrentAct() != LegoGameState::e_act2) {
if (m_numAnimsRun > 0) {
DeleteObjects(&m_atomId, 500, 510);
}
m_unk0x258->SetUnknown0xbc(0);
m_destLocation = LegoGameState::e_infomain;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
result = 1;
}
break;
case CopterScript::c_Exit_Ctl:
if (m_buildState->m_animationState != LegoVehicleBuildState::e_exiting &&
m_buildState->m_animationState != LegoVehicleBuildState::e_unknown4) {
if (m_numAnimsRun > 0) {
DeleteObjects(&m_atomId, 500, 510);
}
m_unk0x258->SetUnknown0xbc(0);
if (GameState()->GetCurrentAct() == LegoGameState::e_act2) {
FUN_100243a0();
}
else if (m_unk0x258->AllPartsPlaced() || m_buildState->m_unk0x4d) {
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;
}
else {
FUN_10025720(4);
m_buildState->m_animationState = LegoVehicleBuildState::e_exiting;
}
result = 1;
}
break;
case CopterScript::c_ShelfUp_Ctl:
FUN_10024f30();
m_Shelf_Sound->Enable(FALSE);
m_Shelf_Sound->Enable(TRUE);
result = 1;
break;
case CopterScript::c_Platform_Ctl:
FUN_10024f50();
m_unk0xf8 = c_unknown8;
m_unk0xfc = param->m_unk0x28;
result = 1;
break;
default:
if ((m_Decals_Ctl && m_Decals_Ctl->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl1 && m_Decals_Ctl1->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl2 && m_Decals_Ctl2->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl3 && m_Decals_Ctl3->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl4 && m_Decals_Ctl4->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) {
m_unk0x258->SetPartObjectIdByName(m_unk0x110->GetName(), param->m_clickedObjectId);
m_Decal_Sound->Enable(FALSE);
m_Decal_Sound->Enable(TRUE);
}
else {
FUN_10025350(param->m_clickedObjectId);
}
result = 1;
}
}
else {
m_unk0xf8 = c_unknownminusone;
m_unk0xfc = -1;
}
// It is a bit unexpected that LEGO1 and BETA10 match so well with the `return 1`
// and ignoring the `result` variable, but the match is hard to argue with
return 1;
}
#else
// FUNCTION: BETA10 0x1006d512
undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param)
{
undefined4 result = 0;
LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param;
assert(m_buildState);
if (param->m_unk0x28) {
switch (param->m_clickedObjectId) {
case CopterScript::c_Info_Ctl:
m_unk0x258->SetUnknown0xbc(0);
m_destLocation = LegoGameState::e_infomain;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
result = 1;
break;
case CopterScript::c_Exit_Ctl:
if (m_buildState->m_animationState != LegoVehicleBuildState::e_exiting) {
m_unk0x258->SetUnknown0xbc(0);
if (m_unk0x258->AllPartsPlaced() || m_buildState->m_unk0x4d) {
m_buildState->m_unk0x4d = TRUE;
// GameState()->GetCurrentAct() returns an MxS16 in BETA10
if (GameState()->GetCurrentAct() == 0) {
InvokeAction(Extra::e_start, m_atomId, m_carId, NULL);
NotificationManager()->Send(this, MxNotificationParam());
assert(m_buildState);
m_buildState->m_animationState = LegoVehicleBuildState::e_unknown4;
}
else {
FUN_10025720(5);
m_buildState->m_animationState = LegoVehicleBuildState::e_exiting;
}
}
else {
FUN_10025720(4);
m_buildState->m_animationState = LegoVehicleBuildState::e_exiting;
}
switch (GameState()->m_currentArea) {
case LegoGameState::e_copterbuild:
assert(m_carId == Helicopter_Actor);
break;
case LegoGameState::e_dunecarbuild:
assert(m_carId == DuneBugy_Actor);
break;
case LegoGameState::e_jetskibuild:
assert(m_carId == Jetski_Actor);
break;
case LegoGameState::e_racecarbuild:
assert(m_carId == RaceCar_Actor);
break;
}
result = 1;
}
break;
case CopterScript::c_ShelfUp_Ctl:
FUN_10024f30();
m_Shelf_Sound->Enable(FALSE);
m_Shelf_Sound->Enable(TRUE);
result = 1;
break;
case CopterScript::c_Platform_Ctl:
FUN_10024f50();
m_unk0xf8 = c_unknown8;
m_unk0xfc = param->m_unk0x28;
result = 1;
break;
default:
if ((m_Decals_Ctl && m_Decals_Ctl->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl1 && m_Decals_Ctl1->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl2 && m_Decals_Ctl2->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl3 && m_Decals_Ctl3->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl4 && m_Decals_Ctl4->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl5 && m_Decals_Ctl5->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl6 && m_Decals_Ctl6->GetAction()->GetObjectId() == param->m_clickedObjectId) ||
(m_Decals_Ctl7 && m_Decals_Ctl7->GetAction()->GetObjectId() == param->m_clickedObjectId)) {
m_unk0x258->SetPartObjectIdByName(m_unk0x110->GetName(), param->m_clickedObjectId);
m_Decal_Sound->Enable(FALSE);
m_Decal_Sound->Enable(TRUE);
}
else {
FUN_10025350(param->m_clickedObjectId);
}
result = 1;
}
}
else {
m_unk0xf8 = c_unknownminusone;
m_unk0xfc = -1;
}
return 1;
}
#endif
// FUNCTION: LEGO1 0x10024c20
// FUNCTION: BETA10 0x1006db21
undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
@ -788,25 +1045,25 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
switch (m_buildState->m_animationState) {
case 4:
entity = (LegoEntity*) Find(m_atomId, m_unk0x330);
entity = (LegoEntity*) Find(m_atomId, m_carId);
if (entity && entity->GetROI()) {
// This function was changed between BETA10 and LEGO1.
// These lines looks like a relic from older code.
LegoWorld* destWorld = NULL;
destWorld = FindWorld(*g_isleScript, 0);
destWorld = FindWorld(*g_isleScript, IsleScript::c__Isle);
Act1State* gameState = (Act1State*) GameState()->GetState("Act1State");
switch (GameState()->GetCurrentArea()) {
switch (GameState()->m_currentArea) {
case LegoGameState::e_copterbuild:
if (gameState->m_helicopter) {
delete gameState->m_helicopter;
}
gameState->m_helicopter = (Helicopter*) entity;
gameState->m_unk0x108.SetName("");
gameState->m_helicopterPlane.SetName("");
break;
case LegoGameState::e_dunecarbuild:
if (gameState->m_dunebuggy) {
@ -814,7 +1071,7 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
}
gameState->m_dunebuggy = (DuneBuggy*) entity;
gameState->m_unk0x1bc.SetName("");
gameState->m_dunebuggyPlane.SetName("");
break;
case LegoGameState::e_jetskibuild:
if (gameState->m_jetski) {
@ -822,7 +1079,7 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
}
gameState->m_jetski = (Jetski*) entity;
gameState->m_unk0x164.SetName("");
gameState->m_jetskiPlane.SetName("");
break;
case LegoGameState::e_racecarbuild:
if (gameState->m_racecar) {
@ -830,14 +1087,14 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
}
gameState->m_racecar = (RaceCar*) entity;
gameState->m_unk0x210.SetName("");
gameState->m_racecarPlane.SetName("");
break;
}
assert(destWorld);
m_buildState->m_animationState = LegoVehicleBuildState::e_exiting;
if (m_unk0x258->m_numberOfParts != m_unk0x258->m_placedPartCount) {
if (m_unk0x258->AllPartsPlaced()) {
FUN_100243a0();
}
else {
@ -852,17 +1109,17 @@ undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
case 2:
MxU32 jukeboxScript;
switch (m_unk0x330) {
case 1:
switch (m_carId) {
case Helicopter_Actor:
jukeboxScript = JukeboxScript::c_HelicopterBuild_Music;
break;
case 2:
case DuneBugy_Actor:
jukeboxScript = JukeboxScript::c_DuneCarBuild_Music;
break;
case 3:
case Jetski_Actor:
jukeboxScript = JukeboxScript::c_JetskiBuild_Music;
break;
case 4:
case RaceCar_Actor:
jukeboxScript = JukeboxScript::c_RaceCarBuild_Music;
}
@ -893,6 +1150,14 @@ void LegoCarBuild::FUN_10024ef0()
FUN_10015820(FALSE, 7);
}
// FUNCTION: LEGO1 0x10024f30
// FUNCTION: BETA10 0x1006dfa0
void LegoCarBuild::FUN_10024f30()
{
FUN_10022f30();
m_unk0x258->SetUnknown0xbc(2);
}
// FUNCTION: LEGO1 0x10024f50
// FUNCTION: BETA10 0x1006dfce
void LegoCarBuild::FUN_10024f50()
@ -973,11 +1238,95 @@ void LegoCarBuild::FUN_100250e0(MxBool p_enabled)
}
}
// STUB: LEGO1 0x10025450
// STUB: BETA10 0x1006e599
// FUNCTION: LEGO1 0x10025350
// FUNCTION: BETA10 0x1006e3c0
void LegoCarBuild::FUN_10025350(MxS32 p_objectId)
{
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
// FUNCTION: BETA10 0x1006e599
void LegoCarBuild::FUN_10025450()
{
// TODO
m_unk0x12c = m_unk0x110->GetLocal2World();
m_unk0x1c0 = m_unk0x12c;
Vector3 lastColumnOfUnk0x1c0(m_unk0x1c0[3]);
lastColumnOfUnk0x1c0 = Vector3(m_unk0x258->GetUnknown0xe0()[3]);
// This looks odd, but it improves the LEGO1 match while breaking the BETA10 match.
// I don't know whether this is due to compiler entropy.
// Feel free to replace unk0x178 -> m_unk0x178 and remove this variable if it improves the LEGO1 match
// in the future.
MxMatrix* unk0x178 = &m_unk0x178;
*unk0x178 = m_unk0x12c;
if (m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) {
m_unk0x2a4 = Vector4(m_unk0x110->GetWorldPosition());
if (!m_unk0x2d4) {
m_unk0x2bc = m_unk0x2a4;
m_unk0x208 = m_unk0x12c;
m_unk0x2a4[0] += m_unk0x1c0[3][0] - m_unk0x208[3][0];
m_unk0x2a4[1] += m_unk0x1c0[3][1] - m_unk0x208[3][1];
m_unk0x2a4[2] += m_unk0x1c0[3][2] - m_unk0x208[3][2];
}
*unk0x178 = m_unk0x1c0;
}
else {
const LegoChar* wiredName;
if (!m_unk0x258->FUN_10079c30(m_unk0x110->GetName())) {
wiredName = m_unk0x258->GetWiredNameByPartName(m_unk0x110->GetName());
}
else {
wiredName = m_unk0x258->GetWiredNameOfLastPlacedPart();
}
LegoROI* parentROI = (LegoROI*) m_unk0x110->GetParentROI();
m_unk0x208 = parentROI->FindChildROI(wiredName, parentROI)->GetLocal2World();
m_unk0x2bc = Vector4(parentROI->FindChildROI(wiredName, parentROI)->GetWorldPosition());
m_unk0x2a4 = Vector4(m_unk0x110->GetWorldPosition());
m_unk0x2a4[2] += (m_unk0x1c0[3][2] - m_unk0x12c[3][2]);
m_unk0x178[3][2] = m_unk0x1c0[3][2];
}
}
// FUNCTION: LEGO1 0x100256c0
@ -998,11 +1347,172 @@ void LegoCarBuild::Enable(MxBool p_enable)
}
}
// STUB: LEGO1 0x10025720
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
@ -1057,7 +1567,7 @@ void LegoCarBuild::FUN_10025e40()
MxBool LegoCarBuild::Escape()
{
BackgroundAudioManager()->Init();
MxS32 targetEntityId = FUN_10025ee0(m_unk0x330);
MxS32 targetEntityId = FUN_10025ee0(m_carId);
InvokeAction(Extra::ActionType::e_stop, *g_jukeboxScript, targetEntityId, NULL);
DeleteObjects(&m_atomId, 500, 999);

View file

@ -627,6 +627,31 @@ MxBool LegoCarBuildAnimPresenter::StringEndsOnZero(const LegoChar* p_string)
return (p_string[strlen(p_string) - 2] != '0');
}
// FUNCTION: LEGO1 0x10079d60
// FUNCTION: BETA10 0x1007284c
const LegoChar* LegoCarBuildAnimPresenter::GetWiredNameByPartName(const LegoChar* p_name)
{
for (MxS16 i = 0; i < m_numberOfParts; i++) {
if (strcmpi(p_name, m_parts[i].m_name) == 0) {
return m_parts[i].m_wiredName;
}
}
return NULL;
}
// FUNCTION: LEGO1 0x10079dc0
// FUNCTION: BETA10 0x100728d1
void LegoCarBuildAnimPresenter::SetPartObjectIdByName(const LegoChar* p_name, MxS16 p_objectId)
{
for (MxS16 i = 0; i < m_numberOfParts; i++) {
if (strcmpi(p_name, m_parts[i].m_name) == 0) {
m_parts[i].m_objectId = p_objectId;
return;
}
}
}
// FUNCTION: LEGO1 0x10079e20
// FUNCTION: BETA10 0x10072959
const BoundingSphere& LegoCarBuildAnimPresenter::FUN_10079e20()

View file

@ -383,7 +383,7 @@ void LegoAnimationManager::Reset(MxBool p_und)
m_unk0x402 = FALSE;
if (p_und && m_animState != NULL) {
m_animState->SetFlag();
m_animState->Reset();
}
MxBool suspended = m_suspended;
@ -1108,7 +1108,7 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt
// FUNCTION: LEGO1 0x10060dc0
// FUNCTION: BETA10 0x10041f2c
MxResult LegoAnimationManager::FUN_10060dc0(
IsleScript::Script p_objectId,
MxU32 p_objectId,
MxMatrix* p_matrix,
MxBool p_param3,
MxBool p_param4,
@ -2951,7 +2951,7 @@ MxResult AnimState::Serialize(LegoFile* p_file)
}
// FUNCTION: LEGO1 0x100654f0
MxBool AnimState::SetFlag()
MxBool AnimState::Reset()
{
if (m_unk0x10 != NULL) {
m_extraCharacterId = 0;

View file

@ -302,7 +302,7 @@ MxResult LegoGameState::DeleteState()
m_stateArray = NULL;
for (MxS32 count = 0; count < stateCount; count++) {
if (!stateArray[count]->SetFlag() && stateArray[count]->IsSerializable()) {
if (!stateArray[count]->Reset() && stateArray[count]->IsSerializable()) {
delete stateArray[count];
}
else {
@ -780,7 +780,7 @@ void LegoGameState::StopArea(Area p_area)
inline void LoadIsle()
{
LegoWorld* world = FindWorld(*g_isleScript, 0);
LegoWorld* world = FindWorld(*g_isleScript, IsleScript::c__Isle);
if (world != NULL) {
if (!world->GetUnknown0xd0Empty()) {
NotificationManager()->Send(world, MxNotificationParam(c_notificationType20, NULL));
@ -957,7 +957,7 @@ void LegoGameState::SwitchArea(Area p_area)
InvokeAction(Extra::ActionType::e_opendisk, *g_racecarScript, RacecarScript::c__StartUp, NULL);
break;
case e_act2main: {
LegoWorld* act2main = FindWorld(*g_act2mainScript, 0);
LegoWorld* act2main = FindWorld(*g_act2mainScript, Act2mainScript::c__Act2Main);
if (act2main == NULL) {
InvokeAction(Extra::ActionType::e_opendisk, *g_act2mainScript, Act2mainScript::c__Act2Main, NULL);
@ -969,7 +969,7 @@ void LegoGameState::SwitchArea(Area p_area)
break;
}
case e_act3script: {
LegoWorld* act3 = FindWorld(*g_act3Script, 0);
LegoWorld* act3 = FindWorld(*g_act3Script, Act3Script::c__Act3);
if (act3 == NULL) {
InvokeAction(Extra::ActionType::e_opendisk, *g_act3Script, Act3Script::c__Act3, NULL);
@ -1105,7 +1105,7 @@ void LegoGameState::Init()
SetCurrentAct(e_act1);
if (m_loadedAct == e_act1) {
Isle* isle = (Isle*) FindWorld(*g_isleScript, 0);
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, CopterScript::c_Helicopter_Actor);
if (copter) {
@ -1215,13 +1215,13 @@ void LegoGameState::SetCurrentAct(Act p_currentAct)
// FUNCTION: LEGO1 0x1003ceb0
void LegoGameState::FindLoadedAct()
{
if (FindWorld(*g_isleScript, 0)) {
if (FindWorld(*g_isleScript, IsleScript::c__Isle)) {
m_loadedAct = e_act1;
}
else if (FindWorld(*g_act2mainScript, 0)) {
else if (FindWorld(*g_act2mainScript, Act2mainScript::c__Act2Main)) {
m_loadedAct = e_act2;
}
else if (FindWorld(*g_act3Script, 0)) {
else if (FindWorld(*g_act3Script, Act3Script::c__Act3)) {
m_loadedAct = e_act3;
}
else {

View file

@ -3,6 +3,7 @@
#include "3dmanager/lego3dmanager.h"
#include "anim/legoanim.h"
#include "isle.h"
#include "isle_actions.h"
#include "islepathactor.h"
#include "legoanimationmanager.h"
#include "legoanimpresenter.h"
@ -239,24 +240,31 @@ MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_enti
void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender);
// FUNCTION: LEGO1 0x1003e430
void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender)
// FUNCTION: BETA10 0x100d3fda
void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender)
{
MxDSAction action;
action.SetAtomId(p_pAtom);
action.SetObjectId(p_targetEntityId);
action.SetObjectId(p_streamId);
switch (p_actionId) {
case Extra::ActionType::e_opendisk:
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) {
assert(p_streamId != DS_NOT_A_STREAM);
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) {
Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_diskStream);
Start(&action);
}
break;
case Extra::ActionType::e_openram:
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) {
assert(p_streamId != DS_NOT_A_STREAM);
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) {
Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_RAMStream);
Start(&action);
}
break;
case Extra::ActionType::e_close:
action.SetUnknown24(-2);
@ -264,35 +272,47 @@ void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p
Streamer()->Close(p_pAtom.GetInternal());
break;
case Extra::ActionType::e_start:
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) {
assert(p_streamId != DS_NOT_A_STREAM);
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) {
Start(&action);
}
break;
case Extra::ActionType::e_stop:
assert(p_streamId != DS_NOT_A_STREAM);
action.SetUnknown24(-2);
if (!RemoveFromCurrentWorld(p_pAtom, p_targetEntityId)) {
if (!RemoveFromCurrentWorld(p_pAtom, p_streamId)) {
DeleteObject(action);
}
break;
case Extra::ActionType::e_run:
_spawnl(0, "\\lego\\sources\\main\\main.exe", "\\lego\\sources\\main\\main.exe", "/script", &p_pAtom, 0);
break;
case Extra::ActionType::e_enable:
assert(p_streamId != DS_NOT_A_STREAM);
CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId);
break;
case Extra::ActionType::e_disable:
assert(p_streamId != DS_NOT_A_STREAM);
CheckIfEntityExists(FALSE, p_pAtom.GetInternal(), p_streamId);
break;
case Extra::ActionType::e_exit:
Lego()->SetExit(TRUE);
break;
case Extra::ActionType::e_enable:
CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId);
break;
case Extra::ActionType::e_disable:
CheckIfEntityExists(FALSE, p_pAtom.GetInternal(), p_targetEntityId);
break;
case Extra::ActionType::e_notify:
NotifyEntity(p_pAtom.GetInternal(), p_targetEntityId, p_sender);
assert(p_streamId != DS_NOT_A_STREAM);
NotifyEntity(p_pAtom.GetInternal(), p_streamId, p_sender);
break;
default:
assert("Invalid Action Control" == NULL);
}
}
// FUNCTION: LEGO1 0x1003e670
// FUNCTION: BETA10 0x100d43f2
MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_entityId)
{
LegoWorld* world = FindWorld(MxAtomId(p_filename, e_lowerCase2), p_entityId);
@ -307,6 +327,7 @@ MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_enti
}
// FUNCTION: LEGO1 0x1003e700
// FUNCTION: BETA10 0x100d448a
void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender)
{
MxAtomId atom(p_filename, e_lowerCase2);
@ -333,7 +354,7 @@ void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender
// FUNCTION: LEGO1 0x1003eab0
void SetCameraControllerFromIsle()
{
InputManager()->SetCamera(FindWorld(*g_isleScript, 0)->GetCamera());
InputManager()->SetCamera(FindWorld(*g_isleScript, IsleScript::c__Isle)->GetCamera());
}
// FUNCTION: LEGO1 0x1003eae0
@ -443,6 +464,7 @@ void FUN_1003eda0()
}
// FUNCTION: LEGO1 0x1003ee00
// FUNCTION: BETA10 0x100d4c6f
MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id)
{
LegoWorld* world = CurrentWorld();

View file

@ -33,8 +33,10 @@ LegoVideoManager* VideoManager()
}
// FUNCTION: LEGO1 0x10015730
// FUNCTION: BETA10 0x100e484e
MxBackgroundAudioManager* BackgroundAudioManager()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetBackgroundAudioManager();
}
@ -188,8 +190,10 @@ void SetCurrentWorld(LegoWorld* p_world)
}
// FUNCTION: LEGO1 0x10015900
// FUNCTION: BETA10 0x100e4f02
MxTransitionManager* TransitionManager()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetTransitionManager();
}

View file

@ -21,7 +21,7 @@ RECT g_fullScreenRect = {0, 0, 640, 480};
MxTransitionManager::MxTransitionManager()
{
m_animationTimer = 0;
m_transitionType = e_notTransitioning;
m_mode = e_idle;
m_ddSurface = NULL;
m_waitIndicator = NULL;
m_copyBuffer = NULL;
@ -47,20 +47,20 @@ MxTransitionManager::~MxTransitionManager()
MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14
{
LegoVideoManager* videoManager = VideoManager();
this->m_ddSurface = videoManager->GetDisplaySurface()->GetDirectDrawSurface2();
m_ddSurface = videoManager->GetDisplaySurface()->GetDirectDrawSurface2();
return SUCCESS;
}
// FUNCTION: LEGO1 0x1004bac0
MxResult MxTransitionManager::Tickle()
{
if (this->m_animationSpeed + this->m_systemTime > timeGetTime()) {
if (m_animationSpeed + m_systemTime > timeGetTime()) {
return SUCCESS;
}
this->m_systemTime = timeGetTime();
m_systemTime = timeGetTime();
switch (this->m_transitionType) {
switch (m_mode) {
case e_noAnimation:
NoTransition();
break;
@ -84,6 +84,7 @@ MxResult MxTransitionManager::Tickle()
}
// FUNCTION: LEGO1 0x1004bb70
// FUNCTION: BETA10 0x100ec4c1
MxResult MxTransitionManager::StartTransition(
TransitionType p_animationType,
MxS32 p_speed,
@ -91,13 +92,15 @@ MxResult MxTransitionManager::StartTransition(
MxBool p_playMusicInAnim
)
{
if (this->m_transitionType == e_notTransitioning) {
assert(m_mode == e_idle);
if (m_mode == e_idle) {
if (!p_playMusicInAnim) {
MxBackgroundAudioManager* backgroundAudioManager = BackgroundAudioManager();
backgroundAudioManager->Stop();
}
this->m_transitionType = p_animationType;
m_mode = p_animationType;
m_copyFlags.m_bit0 = p_doCopy;
@ -110,9 +113,9 @@ MxResult MxTransitionManager::StartTransition(
}
MxU32 time = timeGetTime();
this->m_systemTime = time;
m_systemTime = time;
this->m_animationSpeed = p_speed;
m_animationSpeed = p_speed;
MxTickleManager* tickleManager = TickleManager();
tickleManager->RegisterClient(this, p_speed);
@ -133,8 +136,8 @@ MxResult MxTransitionManager::StartTransition(
// FUNCTION: LEGO1 0x1004bc30
void MxTransitionManager::EndTransition(MxBool p_notifyWorld)
{
if (m_transitionType != e_notTransitioning) {
m_transitionType = e_notTransitioning;
if (m_mode != e_idle) {
m_mode = e_idle;
m_copyFlags.m_bit0 = FALSE;

View file

@ -45,6 +45,7 @@ void LegoControlManager::Register(MxCore* p_listener)
}
// FUNCTION: LEGO1 0x10028ea0
// FUNCTION: BETA10 0x1007c330
void LegoControlManager::Unregister(MxCore* p_listener)
{
LegoNotifyListCursor cursor(&m_notifyList);

View file

@ -276,6 +276,7 @@ void LegoInputManager::SetWorld(LegoWorld* p_world)
}
// FUNCTION: LEGO1 0x1005c730
// FUNCTION: BETA10 0x100896dc
void LegoInputManager::ClearWorld()
{
m_world = NULL;

View file

@ -4,6 +4,7 @@
#include "geom/legounkown100db7f4.h"
#include "legocachesoundmanager.h"
#include "legocameracontroller.h"
#include "legonamedplane.h"
#include "legonavcontroller.h"
#include "legopathboundary.h"
#include "legopathedgecontainer.h"
@ -718,3 +719,12 @@ void LegoPathActor::VTable0xa8()
FUN_10010c30();
}
}
// FUNCTION: LEGO1 0x1002f770
void LegoPathActor::UpdatePlane(LegoNamedPlane& p_namedPlane)
{
p_namedPlane.SetName(m_boundary->GetName());
p_namedPlane.SetPosition(GetWorldPosition());
p_namedPlane.SetDirection(GetWorldDirection());
p_namedPlane.SetUp(GetWorldUp());
}

View file

@ -285,7 +285,7 @@ void LegoVideoManager::ToggleFPS(MxBool p_visible)
MxResult LegoVideoManager::Tickle()
{
if (m_unk0x554 && !m_videoParam.Flags().GetFlipSurfaces() &&
TransitionManager()->GetTransitionType() == MxTransitionManager::e_notTransitioning) {
TransitionManager()->GetTransitionType() == MxTransitionManager::e_idle) {
Sleep(30);
}

View file

@ -45,7 +45,7 @@ MxResult ElevatorBottom::Create(MxDSAction& p_dsAction)
SetIsWorldActive(FALSE);
GameState()->SetCurrentArea(LegoGameState::e_elevbott);
GameState()->m_currentArea = LegoGameState::e_elevbott;
GameState()->StopArea(LegoGameState::e_previousArea);
return result;

View file

@ -91,7 +91,7 @@ MxResult GasStation::Create(MxDSAction& p_dsAction)
m_state->m_unk0x14.m_unk0x00 = 3;
}
GameState()->SetCurrentArea(LegoGameState::e_garage);
GameState()->m_currentArea = LegoGameState::e_garage;
GameState()->StopArea(LegoGameState::e_previousArea);
InputManager()->Register(this);
@ -138,7 +138,7 @@ void GasStation::ReadyWorld()
switch (m_currentActorId) {
case LegoActor::c_pepper:
switch (m_state->m_unk0x18) {
switch (m_state->m_pepperAction) {
case 0:
m_state->m_unk0x14.m_unk0x00 = 5;
PlayAction(GarageScript::c_wgs002nu_RunAnim);
@ -162,14 +162,14 @@ void GasStation::ReadyWorld()
break;
}
if (m_state->m_unk0x18 < 5) {
m_state->m_unk0x18++;
if (m_state->m_pepperAction < 5) {
m_state->m_pepperAction++;
}
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
break;
case LegoActor::c_mama:
switch (m_state->m_unk0x1a) {
switch (m_state->m_mamaAction) {
case 0:
m_state->m_unk0x14.m_unk0x00 = 5;
PlayAction(GarageScript::c_wgs006nu_RunAnim);
@ -188,14 +188,14 @@ void GasStation::ReadyWorld()
break;
}
if (m_state->m_unk0x1a < 5) {
m_state->m_unk0x1a++;
if (m_state->m_mamaAction < 5) {
m_state->m_mamaAction++;
}
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
break;
case LegoActor::c_papa:
switch (m_state->m_unk0x1c) {
switch (m_state->m_papaAction) {
case 0:
m_state->m_unk0x14.m_unk0x00 = 5;
PlayAction(GarageScript::c_wgs012nu_RunAnim);
@ -214,14 +214,14 @@ void GasStation::ReadyWorld()
break;
}
if (m_state->m_unk0x1c < 5) {
m_state->m_unk0x1c++;
if (m_state->m_papaAction < 5) {
m_state->m_papaAction++;
}
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
break;
case LegoActor::c_nick:
switch (m_state->m_unk0x1e) {
switch (m_state->m_nickAction) {
case 0:
m_state->m_unk0x14.m_unk0x00 = 5;
PlayAction(GarageScript::c_wgs009nu_RunAnim);
@ -240,14 +240,14 @@ void GasStation::ReadyWorld()
break;
}
if (m_state->m_unk0x1e < 5) {
m_state->m_unk0x1e++;
if (m_state->m_nickAction < 5) {
m_state->m_nickAction++;
}
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
break;
case LegoActor::c_laura:
switch (m_state->m_unk0x20) {
switch (m_state->m_lauraAction) {
case 0:
m_state->m_unk0x14.m_unk0x00 = 5;
PlayAction(GarageScript::c_wgs020nu_RunAnim);
@ -266,8 +266,8 @@ void GasStation::ReadyWorld()
break;
}
if (m_state->m_unk0x20 < 5) {
m_state->m_unk0x20++;
if (m_state->m_lauraAction < 5) {
m_state->m_lauraAction++;
}
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
@ -288,7 +288,7 @@ inline void GasStation::PlayAction(GarageScript::Script p_objectId)
BackgroundAudioManager()->LowerVolume();
Start(&action);
m_state->FUN_10006430(p_objectId);
m_state->PlayAction(p_objectId);
}
// FUNCTION: BETA10 0x10029f00
@ -297,7 +297,7 @@ inline void GasStation::StopAction(GarageScript::Script p_objectId)
if (p_objectId != GarageScript::c_noneGarage) {
InvokeAction(Extra::e_stop, *g_garageScript, p_objectId, NULL);
BackgroundAudioManager()->RaiseVolume();
m_state->FUN_10006460(p_objectId);
m_state->StopAction(p_objectId);
}
}
@ -310,7 +310,7 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param)
MxDSAction* action = p_param.GetAction();
if (action->GetAtomId() == m_atomId && action->GetObjectId()) {
m_state->FUN_10006460((GarageScript::Script) action->GetObjectId());
m_state->StopAction((GarageScript::Script) action->GetObjectId());
m_unk0x106 = 0;
switch (m_state->m_unk0x14.m_unk0x00) {
@ -357,7 +357,7 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param)
MxLong GasStation::HandleKeyPress(MxS8 p_key)
{
if (p_key == VK_SPACE && g_unk0x100f0160 == 0 && m_unk0x106 != 0) {
m_state->FUN_10006490();
m_state->StopActions();
return 1;
}
@ -394,6 +394,7 @@ MxLong GasStation::HandleButtonDown(LegoControlManagerNotificationParam& p_param
}
// FUNCTION: LEGO1 0x10005b20
// FUNCTION: BETA10 0x10029445
MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
{
if (p_param.GetUnknown0x28() == 1) {
@ -405,7 +406,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
m_state->m_unk0x14.m_unk0x00 = 0;
m_destLocation = LegoGameState::Area::e_garadoor;
m_state->FUN_10006490();
m_state->StopActions();
m_radio.Stop();
BackgroundAudioManager()->Stop();
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
@ -414,7 +415,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
m_state->m_unk0x14.m_unk0x00 = 0;
m_destLocation = LegoGameState::Area::e_infomain;
m_state->FUN_10006490();
m_state->StopActions();
m_radio.Stop();
BackgroundAudioManager()->Stop();
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
@ -423,7 +424,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
m_state->m_unk0x14.m_unk0x00 = 0;
m_destLocation = LegoGameState::Area::e_dunecarbuild;
m_state->FUN_10006490();
m_state->StopActions();
m_radio.Stop();
BackgroundAudioManager()->Stop();
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
@ -435,6 +436,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
}
// FUNCTION: LEGO1 0x10005c40
// FUNCTION: BETA10 0x10029551
void GasStation::Enable(MxBool p_enable)
{
LegoWorld::Enable(p_enable);
@ -451,6 +453,7 @@ void GasStation::Enable(MxBool p_enable)
}
// FUNCTION: LEGO1 0x10005c90
// FUNCTION: BETA10 0x100295c6
MxResult GasStation::Tickle()
{
if (!m_worldStarted) {
@ -495,64 +498,79 @@ MxResult GasStation::Tickle()
MxBool GasStation::Escape()
{
m_radio.Stop();
m_state->FUN_10006490();
m_state->StopActions();
m_state->m_unk0x14.m_unk0x00 = 0;
m_destLocation = LegoGameState::Area::e_infomain;
return TRUE;
}
// FUNCTION: LEGO1 0x10005eb0
// FUNCTION: BETA10 0x100296b8
GasStationState::GasStationState()
{
m_unk0x18 = 0;
m_unk0x1a = 0;
m_unk0x1c = 0;
m_unk0x1e = 0;
m_unk0x20 = 0;
undefined4* unk0x08 = m_unk0x08;
unk0x08[0] = -1;
unk0x08[1] = -1;
unk0x08[2] = -1;
m_pepperAction = 0;
m_mamaAction = 0;
m_papaAction = 0;
m_nickAction = 0;
m_lauraAction = 0;
memset(m_actions, GarageScript::c_noneGarage, sizeof(m_actions));
}
// FUNCTION: LEGO1 0x10006300
// FUNCTION: BETA10 0x10029754
MxResult GasStationState::Serialize(LegoFile* p_file)
{
LegoState::Serialize(p_file);
if (p_file->IsWriteMode()) {
Write(p_file, m_unk0x18);
Write(p_file, m_unk0x1a);
Write(p_file, m_unk0x1c);
Write(p_file, m_unk0x1e);
Write(p_file, m_unk0x20);
Write(p_file, m_pepperAction);
Write(p_file, m_mamaAction);
Write(p_file, m_papaAction);
Write(p_file, m_nickAction);
Write(p_file, m_lauraAction);
}
else if (p_file->IsReadMode()) {
Read(p_file, &m_unk0x18);
Read(p_file, &m_unk0x1a);
Read(p_file, &m_unk0x1c);
Read(p_file, &m_unk0x1e);
Read(p_file, &m_unk0x20);
Read(p_file, &m_pepperAction);
Read(p_file, &m_mamaAction);
Read(p_file, &m_papaAction);
Read(p_file, &m_nickAction);
Read(p_file, &m_lauraAction);
}
return SUCCESS;
}
// STUB: LEGO1 0x10006430
void GasStationState::FUN_10006430(GarageScript::Script)
// FUNCTION: LEGO1 0x10006430
void GasStationState::PlayAction(GarageScript::Script p_objectId)
{
// TODO
for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_actions); i++) {
if (m_actions[i] == GarageScript::c_noneGarage) {
m_actions[i] = p_objectId;
return;
}
}
}
// STUB: LEGO1 0x10006460
void GasStationState::FUN_10006460(GarageScript::Script)
// FUNCTION: LEGO1 0x10006460
void GasStationState::StopAction(GarageScript::Script p_objectId)
{
// TODO
for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_actions); i++) {
if (m_actions[i] == p_objectId) {
m_actions[i] = GarageScript::c_noneGarage;
return;
}
}
}
// STUB: LEGO1 0x10006490
void GasStationState::FUN_10006490()
// FUNCTION: LEGO1 0x10006490
void GasStationState::StopActions()
{
// TODO
for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_actions); i++) {
if (m_actions[i] != GarageScript::c_noneGarage) {
InvokeAction(Extra::e_stop, *g_garageScript, m_actions[i], NULL);
m_actions[i] = GarageScript::c_noneGarage;
}
}
BackgroundAudioManager()->RaiseVolume();
}

View file

@ -39,7 +39,7 @@ MxResult HistoryBook::Create(MxDSAction& p_dsAction)
InputManager()->SetCamera(NULL);
InputManager()->Register(this);
GameState()->SetCurrentArea(LegoGameState::Area::e_histbook);
GameState()->m_currentArea = LegoGameState::Area::e_histbook;
GameState()->StopArea(LegoGameState::Area::e_previousArea);
return result;
}

View file

@ -96,7 +96,7 @@ MxResult Hospital::Create(MxDSAction& p_dsAction)
m_hospitalState->m_unk0x08.m_unk0x00 = 3;
}
GameState()->SetCurrentArea(LegoGameState::e_hospital);
GameState()->m_currentArea = LegoGameState::e_hospital;
GameState()->StopArea(LegoGameState::e_previousArea);
InputManager()->Register(this);

View file

@ -210,7 +210,7 @@ MxResult Infocenter::Create(MxDSAction& p_dsAction)
}
}
GameState()->SetCurrentArea(LegoGameState::e_infomain);
GameState()->m_currentArea = LegoGameState::e_infomain;
GameState()->StopArea(LegoGameState::e_previousArea);
if (m_infocenterState->GetUnknown0x74() == 4) {
@ -523,9 +523,9 @@ void Infocenter::ReadyWorld()
bgRed->Enable(TRUE);
if (GameState()->GetCurrentAct() == GameState()->GetLoadedAct()) {
GameState()->SetCurrentArea(LegoGameState::e_act2main);
GameState()->m_currentArea = LegoGameState::e_act2main;
GameState()->StopArea(LegoGameState::e_act2main);
GameState()->SetCurrentArea(LegoGameState::e_infomain);
GameState()->m_currentArea = LegoGameState::e_infomain;
}
m_infocenterState->SetUnknown0x74(5);
@ -579,9 +579,9 @@ void Infocenter::ReadyWorld()
bgRed->Enable(TRUE);
if (GameState()->GetCurrentAct() == GameState()->GetLoadedAct()) {
GameState()->SetCurrentArea(LegoGameState::e_act3script);
GameState()->m_currentArea = LegoGameState::e_act3script;
GameState()->StopArea(LegoGameState::e_act3script);
GameState()->SetCurrentArea(LegoGameState::e_infomain);
GameState()->m_currentArea = LegoGameState::e_infomain;
}
m_infocenterState->SetUnknown0x74(5);
@ -1404,7 +1404,7 @@ void Infocenter::Reset()
HelicopterState* state = (HelicopterState*) GameState()->GetState("HelicopterState");
if (state) {
state->SetFlag();
state->Reset();
}
}
@ -1549,28 +1549,29 @@ void Infocenter::StopBookAnimation()
// FUNCTION: LEGO1 0x10071600
InfocenterState::InfocenterState()
{
m_exitDialogueAct1 = LegoState::Playlist((MxU32*) g_exitDialogueAct1, sizeOfArray(g_exitDialogueAct1));
m_exitDialogueAct23 = LegoState::Playlist((MxU32*) g_exitDialogueAct23, sizeOfArray(g_exitDialogueAct23) - 1);
m_exitDialogueAct1 = Playlist((MxU32*) g_exitDialogueAct1, sizeOfArray(g_exitDialogueAct1), Playlist::e_loop);
m_exitDialogueAct23 =
Playlist((MxU32*) g_exitDialogueAct23, sizeOfArray(g_exitDialogueAct23) - 1, Playlist::e_loop);
m_returnDialogue[LegoGameState::e_act1] =
LegoState::Playlist((MxU32*) g_returnDialogueAct1, sizeOfArray(g_returnDialogueAct1) - 1);
Playlist((MxU32*) g_returnDialogueAct1, sizeOfArray(g_returnDialogueAct1) - 1, Playlist::e_loop);
m_returnDialogue[LegoGameState::e_act2] =
LegoState::Playlist((MxU32*) g_returnDialogueAct2, sizeOfArray(g_returnDialogueAct2) - 1);
Playlist((MxU32*) g_returnDialogueAct2, sizeOfArray(g_returnDialogueAct2) - 1, Playlist::e_loop);
m_returnDialogue[LegoGameState::e_act3] =
LegoState::Playlist((MxU32*) g_returnDialogueAct3, sizeOfArray(g_returnDialogueAct3));
Playlist((MxU32*) g_returnDialogueAct3, sizeOfArray(g_returnDialogueAct3), Playlist::e_loop);
m_leaveDialogue[LegoGameState::e_act1] =
LegoState::Playlist((MxU32*) g_leaveDialogueAct1, sizeOfArray(g_leaveDialogueAct1));
Playlist((MxU32*) g_leaveDialogueAct1, sizeOfArray(g_leaveDialogueAct1), Playlist::e_loop);
m_leaveDialogue[LegoGameState::e_act2] =
LegoState::Playlist((MxU32*) g_leaveDialogueAct2, sizeOfArray(g_leaveDialogueAct2));
Playlist((MxU32*) g_leaveDialogueAct2, sizeOfArray(g_leaveDialogueAct2), Playlist::e_loop);
m_leaveDialogue[LegoGameState::e_act3] =
LegoState::Playlist((MxU32*) g_leaveDialogueAct3, sizeOfArray(g_leaveDialogueAct3) - 1);
Playlist((MxU32*) g_leaveDialogueAct3, sizeOfArray(g_leaveDialogueAct3) - 1, Playlist::e_loop);
m_bricksterDialogue = LegoState::Playlist((MxU32*) g_bricksterDialogue, sizeOfArray(g_bricksterDialogue));
m_bricksterDialogue = Playlist((MxU32*) g_bricksterDialogue, sizeOfArray(g_bricksterDialogue), Playlist::e_loop);
memset(m_letters, 0, sizeof(m_letters));
}

View file

@ -48,7 +48,7 @@ MxResult InfocenterDoor::Create(MxDSAction& p_dsAction)
SetIsWorldActive(FALSE);
GameState()->SetCurrentArea(LegoGameState::e_infodoor);
GameState()->m_currentArea = LegoGameState::e_infodoor;
GameState()->StopArea(LegoGameState::e_previousArea);
return result;

View file

@ -33,23 +33,21 @@
#include "mxvariabletable.h"
#include "pizza.h"
#include "pizzeria.h"
#include "racecar.h"
#include "scripts.h"
#include "skateboard.h"
#include "towtrack.h"
DECOMP_SIZE_ASSERT(Act1State, 0x26c)
DECOMP_SIZE_ASSERT(Act1State::NamedPlane, 0x4c)
DECOMP_SIZE_ASSERT(LegoNamedPlane, 0x4c)
DECOMP_SIZE_ASSERT(Isle, 0x140)
// GLOBAL: LEGO1 0x100f1198
MxU32 g_isleFlags = 0x7f;
// GLOBAL: LEGO1 0x100f37f0
MxS32 g_unk0x100f37f0[] = {
Act1State::e_unk953,
Act1State::e_unk954,
Act1State::e_unk955,
};
IsleScript::Script g_cptClickDialogue[] =
{IsleScript::c_Avo905Ps_PlayWav, IsleScript::c_Avo906Ps_PlayWav, IsleScript::c_Avo907Ps_PlayWav};
// FUNCTION: LEGO1 0x10030820
Isle::Isle()
@ -111,8 +109,8 @@ MxResult Isle::Create(MxDSAction& p_dsAction)
m_destLocation = LegoGameState::e_infomain;
}
if (GameState()->GetCurrentArea() == LegoGameState::e_isle) {
GameState()->SetCurrentArea(LegoGameState::e_undefined);
if (GameState()->m_currentArea == LegoGameState::e_isle) {
GameState()->m_currentArea = LegoGameState::e_undefined;
}
LegoGameState* gameState = GameState();
@ -364,14 +362,14 @@ MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param)
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
break;
case IsleScript::c_Observe_LeftArrow_Ctl:
m_act1state->FUN_100346a0();
m_act1state->StopCptClickDialogue();
m_radio.Stop();
case IsleScript::c_SeaView_RightArrow_Ctl:
m_destLocation = LegoGameState::e_elevopen;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
break;
case IsleScript::c_Observe_RightArrow_Ctl:
m_act1state->FUN_100346a0();
m_act1state->StopCptClickDialogue();
m_radio.Stop();
case IsleScript::c_SeaView_LeftArrow_Ctl:
m_destLocation = LegoGameState::e_elevdown;
@ -422,7 +420,7 @@ MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param)
break;
case IsleScript::c_Observe_Draw1_Ctl:
case IsleScript::c_Observe_Draw2_Ctl:
m_act1state->FUN_10034660();
m_act1state->PlayCptClickDialogue();
break;
case IsleScript::c_ElevDown_Elevator_Ctl:
m_destLocation = LegoGameState::e_elevride2;
@ -853,7 +851,7 @@ void Isle::Enable(MxBool p_enable)
InputManager()->ClearWorld();
}
m_act1state->FUN_10034b60();
m_act1state->RemoveActors();
}
}
@ -1190,7 +1188,7 @@ MxBool Isle::Escape()
switch (m_act1state->m_unk0x018) {
case 3:
if (UserActor() != NULL) {
m_pizza->FUN_10038380();
m_pizza->StopActions();
m_pizza->FUN_100382b0();
}
break;
@ -1257,7 +1255,7 @@ void Isle::FUN_10033350()
if (m_act1state->m_unk0x018 == 3) {
if (UserActor() != NULL) {
m_pizza->FUN_10038380();
m_pizza->StopActions();
m_pizza->FUN_100382b0();
}
}
@ -1282,17 +1280,17 @@ void Isle::FUN_10033350()
m_destLocation = LegoGameState::e_infomain;
}
// STUB: LEGO1 0x100334b0
Act1State::Act1State() : m_unk0x00c(0), m_unk0x00e(0), m_unk0x008(NULL), m_unk0x010(0)
// FUNCTION: LEGO1 0x100334b0
// FUNCTION: BETA10 0x10035197
Act1State::Act1State()
{
m_unk0x01e = FALSE;
m_elevFloor = Act1State::c_floor1;
m_unk0x018 = 1;
m_unk0x010 = 0;
m_planeActive = FALSE;
m_unk0x00e = 0;
m_unk0x01e = FALSE;
m_cptClickDialogue = Playlist((MxU32*) g_cptClickDialogue, sizeOfArray(g_cptClickDialogue), Playlist::e_loop);
m_unk0x01f = FALSE;
m_unk0x008 = g_unk0x100f37f0;
m_unk0x014 = -1;
m_planeActive = FALSE;
m_currentCptClickDialogue = IsleScript::c_noneIsle;
m_unk0x022 = FALSE;
m_unk0x154 = NULL;
m_unk0x158 = NULL;
@ -1300,8 +1298,6 @@ Act1State::Act1State() : m_unk0x00c(0), m_unk0x00e(0), m_unk0x008(NULL), m_unk0x
m_helicopter = NULL;
m_unk0x1b0 = NULL;
m_unk0x021 = 1;
m_elevFloor = Act1State::c_floor1;
m_unk0x00c = sizeOfArray(g_unk0x100f37f0);
m_unk0x1b4 = NULL;
m_jetski = NULL;
m_unk0x208 = NULL;
@ -1310,24 +1306,25 @@ Act1State::Act1State() : m_unk0x00c(0), m_unk0x00e(0), m_unk0x008(NULL), m_unk0x
m_unk0x260 = NULL;
m_unk0x264 = NULL;
m_racecar = NULL;
SetFlag();
Reset();
}
// FUNCTION: LEGO1 0x10033ac0
// FUNCTION: BETA10 0x1003524f
MxResult Act1State::Serialize(LegoFile* p_file)
{
LegoState::Serialize(p_file);
m_unk0x024.Serialize(p_file);
m_unk0x070.Serialize(p_file);
m_unk0x0bc.Serialize(p_file);
m_unk0x108.Serialize(p_file);
m_unk0x164.Serialize(p_file);
m_unk0x1bc.Serialize(p_file);
m_unk0x210.Serialize(p_file);
m_motocyclePlane.Serialize(p_file);
m_bikePlane.Serialize(p_file);
m_skateboardPlane.Serialize(p_file);
m_helicopterPlane.Serialize(p_file);
m_jetskiPlane.Serialize(p_file);
m_dunebuggyPlane.Serialize(p_file);
m_racecarPlane.Serialize(p_file);
if (p_file->IsWriteMode()) {
if (m_unk0x108.GetName()->Compare("") != 0) {
if (m_helicopterPlane.GetName()->Compare("") != 0) {
if (m_unk0x154) {
WriteNamedTexture(p_file, m_unk0x154);
}
@ -1347,7 +1344,7 @@ MxResult Act1State::Serialize(LegoFile* p_file)
FUN_1003f540(p_file, "chjetr.gif");
}
}
if (m_unk0x164.GetName()->Compare("") != 0) {
if (m_jetskiPlane.GetName()->Compare("") != 0) {
if (m_unk0x1b0) {
WriteNamedTexture(p_file, m_unk0x1b0);
}
@ -1361,7 +1358,7 @@ MxResult Act1State::Serialize(LegoFile* p_file)
FUN_1003f540(p_file, "jswnsh.gif");
}
}
if (m_unk0x1bc.GetName()->Compare("") != 0) {
if (m_dunebuggyPlane.GetName()->Compare("") != 0) {
if (m_unk0x208) {
WriteNamedTexture(p_file, m_unk0x208);
}
@ -1369,7 +1366,7 @@ MxResult Act1State::Serialize(LegoFile* p_file)
FUN_1003f540(p_file, "dbfrfn.gif");
}
}
if (m_unk0x210.GetName()->Compare("") != 0) {
if (m_racecarPlane.GetName()->Compare("") != 0) {
if (m_unk0x25c) {
WriteNamedTexture(p_file, m_unk0x25c);
}
@ -1390,11 +1387,11 @@ MxResult Act1State::Serialize(LegoFile* p_file)
}
}
Write(p_file, m_unk0x010);
Write(p_file, m_cptClickDialogue.m_nextIndex);
Write(p_file, m_unk0x022);
}
else if (p_file->IsReadMode()) {
if (m_unk0x108.GetName()->Compare("") != 0) {
if (m_helicopterPlane.GetName()->Compare("") != 0) {
m_unk0x154 = ReadNamedTexture(p_file);
if (m_unk0x154 == NULL) {
return FAILURE;
@ -1410,7 +1407,7 @@ MxResult Act1State::Serialize(LegoFile* p_file)
return FAILURE;
}
}
if (m_unk0x164.GetName()->Compare("") != 0) {
if (m_jetskiPlane.GetName()->Compare("") != 0) {
m_unk0x1b0 = ReadNamedTexture(p_file);
if (m_unk0x1b0 == NULL) {
return FAILURE;
@ -1421,13 +1418,13 @@ MxResult Act1State::Serialize(LegoFile* p_file)
return FAILURE;
}
}
if (m_unk0x1bc.GetName()->Compare("") != 0) {
if (m_dunebuggyPlane.GetName()->Compare("") != 0) {
m_unk0x208 = ReadNamedTexture(p_file);
if (m_unk0x208 == NULL) {
return FAILURE;
}
}
if (m_unk0x210.GetName()->Compare("") != 0) {
if (m_racecarPlane.GetName()->Compare("") != 0) {
m_unk0x25c = ReadNamedTexture(p_file);
if (m_unk0x25c == NULL) {
return FAILURE;
@ -1444,7 +1441,7 @@ MxResult Act1State::Serialize(LegoFile* p_file)
}
}
Read(p_file, &m_unk0x010);
Read(p_file, &m_cptClickDialogue.m_nextIndex);
Read(p_file, &m_unk0x022);
}
@ -1452,29 +1449,35 @@ MxResult Act1State::Serialize(LegoFile* p_file)
return SUCCESS;
}
// STUB: LEGO1 0x10034660
void Act1State::FUN_10034660()
// FUNCTION: LEGO1 0x10034660
void Act1State::PlayCptClickDialogue()
{
// TODO
StopCptClickDialogue();
m_currentCptClickDialogue = (IsleScript::Script) m_cptClickDialogue.Next();
BackgroundAudioManager()->LowerVolume();
if (m_currentCptClickDialogue != IsleScript::c_noneIsle) {
InvokeAction(Extra::e_start, *g_isleScript, m_currentCptClickDialogue, NULL);
}
}
// FUNCTION: LEGO1 0x100346a0
void Act1State::FUN_100346a0()
void Act1State::StopCptClickDialogue()
{
if (m_unk0x014 != -1) {
InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x014, NULL);
m_unk0x014 = -1;
if (m_currentCptClickDialogue != IsleScript::c_noneIsle) {
InvokeAction(Extra::e_stop, *g_isleScript, m_currentCptClickDialogue, NULL);
m_currentCptClickDialogue = IsleScript::c_noneIsle;
}
}
// FUNCTION: LEGO1 0x100346d0
MxBool Act1State::SetFlag()
MxBool Act1State::Reset()
{
m_unk0x024.SetName("");
m_unk0x070.SetName("");
m_unk0x0bc.SetName("");
m_motocyclePlane.SetName("");
m_bikePlane.SetName("");
m_skateboardPlane.SetName("");
m_unk0x022 = FALSE;
m_unk0x108.SetName("");
m_helicopterPlane.SetName("");
if (m_unk0x154) {
delete m_unk0x154;
@ -1496,7 +1499,7 @@ MxBool Act1State::SetFlag()
m_helicopter = NULL;
}
m_unk0x164.SetName("");
m_jetskiPlane.SetName("");
if (m_unk0x1b0) {
delete m_unk0x1b0;
@ -1513,7 +1516,7 @@ MxBool Act1State::SetFlag()
m_jetski = NULL;
}
m_unk0x1bc.SetName("");
m_dunebuggyPlane.SetName("");
if (m_unk0x208) {
delete m_unk0x208;
@ -1525,7 +1528,7 @@ MxBool Act1State::SetFlag()
m_dunebuggy = NULL;
}
m_unk0x210.SetName("");
m_racecarPlane.SetName("");
if (m_unk0x25c) {
delete m_unk0x25c;
@ -1550,10 +1553,50 @@ MxBool Act1State::SetFlag()
return TRUE;
}
// STUB: LEGO1 0x10034b60
void Act1State::FUN_10034b60()
// FUNCTION: LEGO1 0x10034b60
void Act1State::RemoveActors()
{
// TODO
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
isle->m_motocycle->UpdatePlane(m_motocyclePlane);
isle->m_bike->UpdatePlane(m_bikePlane);
isle->m_skateboard->UpdatePlane(m_skateboardPlane);
if (isle->m_helicopter != NULL) {
isle->m_helicopter->UpdatePlane(m_helicopterPlane);
m_helicopter = isle->m_helicopter;
isle->RemoveActor(m_helicopter);
isle->VTable0x6c(m_helicopter);
m_helicopter->SetBoundary(NULL);
m_helicopter->SetController(NULL);
}
if (isle->m_jetski != NULL) {
isle->m_jetski->UpdatePlane(m_jetskiPlane);
m_jetski = isle->m_jetski;
isle->RemoveActor(m_jetski);
isle->VTable0x6c(m_jetski);
m_jetski->SetBoundary(NULL);
m_jetski->SetController(NULL);
}
if (isle->m_dunebuggy != NULL) {
isle->m_dunebuggy->UpdatePlane(m_dunebuggyPlane);
m_dunebuggy = isle->m_dunebuggy;
isle->RemoveActor(m_dunebuggy);
isle->VTable0x6c(m_dunebuggy);
m_dunebuggy->SetBoundary(NULL);
m_dunebuggy->SetController(NULL);
}
if (isle->m_racecar != NULL) {
isle->m_racecar->UpdatePlane(m_racecarPlane);
m_racecar = isle->m_racecar;
isle->RemoveActor(m_racecar);
isle->VTable0x6c(m_racecar);
m_racecar->SetBoundary(NULL);
m_racecar->SetController(NULL);
}
}
// STUB: LEGO1 0x10034d00

View file

@ -61,7 +61,7 @@ MxResult JukeBox::Create(MxDSAction& p_dsAction)
m_state->m_music = JukeBoxState::e_pasquell;
}
GameState()->SetCurrentArea(LegoGameState::e_jukeboxw);
GameState()->m_currentArea = LegoGameState::e_jukeboxw;
GameState()->StopArea(LegoGameState::e_previousArea);
TickleManager()->RegisterClient(this, 2000);
return ret;

View file

@ -63,7 +63,7 @@ MxResult Police::Create(MxDSAction& p_dsAction)
}
m_policeState = policeState;
GameState()->SetCurrentArea(LegoGameState::e_police);
GameState()->m_currentArea = LegoGameState::e_police;
GameState()->StopArea(LegoGameState::e_previousArea);
return ret;
}

View file

@ -97,7 +97,7 @@ MxResult RegistrationBook::Create(MxDSAction& p_dsAction)
SetIsWorldActive(FALSE);
InputManager()->Register(this);
GameState()->SetCurrentArea(LegoGameState::e_regbook);
GameState()->m_currentArea = LegoGameState::e_regbook;
GameState()->StopArea(LegoGameState::e_previousArea);
m_infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState");

View file

@ -63,7 +63,7 @@ MxResult Score::Create(MxDSAction& p_dsAction)
LegoGameState* gameState = GameState();
ScoreState* state = (ScoreState*) gameState->GetState("ScoreState");
m_state = state ? state : (ScoreState*) gameState->CreateState("ScoreState");
GameState()->SetCurrentArea(LegoGameState::e_infoscor);
GameState()->m_currentArea = LegoGameState::e_infoscor;
GameState()->StopArea(LegoGameState::e_previousArea);
}

View file

@ -48,7 +48,7 @@ class LegoWEGEdge : public LegoWEEdge {
Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; }
// FUNCTION: BETA10 0x1001c9b0
LegoChar* GetName() { return m_name; }
const LegoChar* GetName() { return m_name; }
void SetFlag0x10(LegoU32 p_disable)
{

View file

@ -475,6 +475,7 @@ LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time)
}
// FUNCTION: LEGO1 0x100a9170
// FUNCTION: BETA10 0x1018ae09
LegoResult LegoROI::FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha)
{
LegoResult result = SUCCESS;
@ -552,6 +553,13 @@ LegoResult LegoROI::GetTexture(LegoTextureInfo*& p_textureInfo)
return FAILURE;
}
// FUNCTION: LEGO1 0x100a9330
// FUNCTION: BETA10 0x1018b22c
LegoResult LegoROI::FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha)
{
return FUN_100a9170(p_red, p_green, p_blue, p_alpha);
}
// FUNCTION: LEGO1 0x100a9350
// FUNCTION: BETA10 0x1018b25c
LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color)
@ -564,6 +572,18 @@ LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color)
return SUCCESS;
}
// FUNCTION: LEGO1 0x100a93b0
// FUNCTION: BETA10 0x1018b2c0
LegoResult LegoROI::FUN_100a93b0(const LegoChar* p_color)
{
MxFloat red, green, blue, alpha;
if (ColorAliasLookup(p_color, red, green, blue, alpha)) {
return FUN_100a9330(red, green, blue, alpha);
}
return 0;
}
// FUNCTION: LEGO1 0x100a9410
// FUNCTION: BETA10 0x1018b324
LegoU32 LegoROI::FUN_100a9410(
@ -746,6 +766,7 @@ LegoBool LegoROI::FUN_100a9bf0(const LegoChar* p_param, float& p_red, float& p_g
}
// FUNCTION: LEGO1 0x100a9c50
// FUNCTION: BETA10 0x1018bdd9
LegoBool LegoROI::ColorAliasLookup(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha)
{
for (LegoU32 i = 0; i < sizeOfArray(g_roiColorAliases); i++) {

View file

@ -38,7 +38,9 @@ class LegoROI : public ViewROI {
LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo);
LegoResult GetTexture(LegoTextureInfo*& p_textureInfo);
LegoResult FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult FUN_100a9350(const LegoChar* p_color);
LegoResult FUN_100a93b0(const LegoChar* p_color);
LegoU32 FUN_100a9410(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3, LegoBool p_collideBox);
void SetName(const LegoChar* p_name);

View file

@ -19,6 +19,7 @@
// _free
// LIBRARY: LEGO1 0x1008b020
// LIBRARY: BETA10 0x100f8d20
// ___CxxFrameHandler
// LIBRARY: LEGO1 0x1008b24c
@ -731,6 +732,12 @@
// LIBRARY: BETA10 0x1018ed70
// _strupr
// LIBRARY: BETA10 0x100f9690
// sprintf
// LIBRARY: BETA10 0x100fb150
// _spawnl
// LIBRARY: BETA10 0x1001d1a0
// `vector constructor iterator'

View file

@ -78,6 +78,7 @@ class Mx4DPointFloat : public Vector4 {
const float& operator[](int idx) const { return m_data[idx]; }
// SYNTHETIC: LEGO1 0x10064b20
// SYNTHETIC: BETA10 0x10070420
// Mx4DPointFloat::operator=
private:

View file

@ -20,6 +20,7 @@ class MxMatrix : public Matrix4 {
// FUNCTION: BETA10 0x10010860
float* operator[](int idx) { return m_data[idx]; }
// FUNCTION: BETA10 0x1001c670
const float* operator[](int idx) const { return m_data[idx]; }
// FUNCTION: LEGO1 0x10002850

View file

@ -178,6 +178,7 @@ void MxNotificationManager::Register(MxCore* p_listener)
}
// FUNCTION: LEGO1 0x100acdf0
// FUNCTION: BETA10 0x10126785
void MxNotificationManager::Unregister(MxCore* p_listener)
{
AUTOLOCK(m_lock);

View file

@ -51,6 +51,7 @@ class OrientableROI : public ROI {
// FUNCTION: BETA10 0x1004aa70
const float* GetWorldUp() const { return m_local2world[1]; }
// FUNCTION: BETA10 0x10070380
OrientableROI* GetParentROI() const { return m_parentROI; }
void SetParentROI(OrientableROI* p_parentROI) { m_parentROI = p_parentROI; }

View file

@ -152,6 +152,7 @@ class Vector2 {
virtual void SetVector(const Vector2* p_other) { EqualsImpl(p_other->m_data); } // vtable+0x6c
// SYNTHETIC: LEGO1 0x10010be0
// SYNTHETIC: BETA10 0x100121e0
// Vector3::operator=
// SYNTHETIC: BETA10 0x1004af40
@ -301,10 +302,14 @@ class Vector4 : public Vector3 {
// FUNCTION: BETA10 0x10048780
Vector4(float* p_data) : Vector3(p_data) {}
// Hack: Some code initializes a Vector4 from a (most likely) const float* source.
// Example: LegoCarBuild::VTable0x6c
// Some code initializes a Vector4 from a `const float*` source.
// Example: `LegoCarBuild::VTable0x6c`
// Vector4 however is a class that can mutate its underlying source, making
// initialization with a const source fundamentally incompatible.
// BETA10 appears to have two separate constructors for Vector4 as well,
// supporting the theory that this decompilation is correct.
// FUNCTION: BETA10 0x100701b0
Vector4(const float* p_data) : Vector3((float*) p_data) {}
// Note: virtual function overloads appear in the virtual table