mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-11 18:51:16 +00:00
Merge branch 'isledecomp:master' into master
This commit is contained in:
commit
1efd880871
@ -15,8 +15,6 @@ To access the Ghidra repository, use the following details:
|
||||
- Address: `server.mattkc.com`
|
||||
- Port: `13100`
|
||||
|
||||
**Please note that at the time of writing, much of the information found on the Ghidra server is severely outdated**. Generally, the source code found in this repository represents the latest "source of truth" and should be referenced whenever possible.
|
||||
|
||||
## General Guidelines
|
||||
|
||||
If you feel fit to contribute, feel free to create a pull request! Someone will review and merge it (or provide feedback) as soon as possible.
|
||||
|
||||
@ -14,6 +14,19 @@ class MxStillPresenter;
|
||||
// SIZE 0x24
|
||||
class GasStationState : public LegoState {
|
||||
public:
|
||||
enum {
|
||||
e_unknown0 = 0,
|
||||
e_newState = 1,
|
||||
e_beforeExitingForQuest = 2,
|
||||
e_unknown3 = 3,
|
||||
e_unknown4 = 4,
|
||||
e_introduction = 5,
|
||||
e_explainQuest = 6,
|
||||
e_waitAcceptingQuest = 7,
|
||||
e_afterAcceptingQuest = 8,
|
||||
e_cancelQuest = 9,
|
||||
};
|
||||
|
||||
GasStationState();
|
||||
|
||||
// FUNCTION: LEGO1 0x100061d0
|
||||
@ -42,7 +55,7 @@ class GasStationState : public LegoState {
|
||||
// TODO: Most likely getters/setters are not used according to BETA.
|
||||
|
||||
GarageScript::Script m_actions[3]; // 0x08
|
||||
undefined4 m_unk0x14; // 0x14
|
||||
MxS32 m_state; // 0x14
|
||||
MxS16 m_pepperAction; // 0x18
|
||||
MxS16 m_mamaAction; // 0x1a
|
||||
MxS16 m_papaAction; // 0x1c
|
||||
@ -88,6 +101,13 @@ class GasStation : public LegoWorld {
|
||||
// GasStation::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
enum {
|
||||
e_finished = 0,
|
||||
e_start = 1,
|
||||
e_started = 2,
|
||||
e_canceled = 3,
|
||||
};
|
||||
|
||||
inline void PlayAction(GarageScript::Script p_objectId);
|
||||
inline void StopAction(GarageScript::Script p_objectId);
|
||||
|
||||
@ -99,13 +119,13 @@ class GasStation : public LegoWorld {
|
||||
undefined2 m_unk0xfa; // 0xfa
|
||||
LegoGameState::Area m_destLocation; // 0xfc
|
||||
GasStationState* m_state; // 0x100
|
||||
undefined2 m_unk0x104; // 0x104
|
||||
undefined2 m_unk0x106; // 0x106
|
||||
MxS16 m_waitingState; // 0x104
|
||||
MxS16 m_setWithCurrentAction; // 0x106
|
||||
MxStillPresenter* m_trackLedBitmap; // 0x108
|
||||
MxLong m_unk0x10c; // 0x10c
|
||||
MxLong m_lastIdleAnimation; // 0x10c
|
||||
MxLong m_trackLedTimer; // 0x110
|
||||
MxBool m_unk0x114; // 0x114
|
||||
MxBool m_unk0x115; // 0x115
|
||||
MxBool m_waiting; // 0x114
|
||||
MxBool m_flashingLeds; // 0x115
|
||||
Radio m_radio; // 0x118
|
||||
};
|
||||
|
||||
|
||||
@ -26,10 +26,10 @@ struct LegoBuildingInfo {
|
||||
MxU32 m_sound; // 0x08
|
||||
MxU32 m_move; // 0x0c
|
||||
MxU8 m_mood; // 0x10
|
||||
MxS8 m_unk0x11; // 0x11
|
||||
MxS8 m_initialUnk0x11; // 0x12 - initial value loaded to m_unk0x11
|
||||
MxS8 m_counter; // 0x11
|
||||
MxS8 m_initialCounter; // 0x12 - initial value loaded to m_counter
|
||||
MxU8 m_flags; // 0x13
|
||||
float m_unk0x14; // 0x14
|
||||
float m_adjustedY; // 0x14
|
||||
const char* m_boundaryName; // 0x18
|
||||
float m_x; // 0x1c
|
||||
float m_y; // 0x20
|
||||
@ -46,7 +46,7 @@ class LegoBuildingManager : public MxCore {
|
||||
LegoEntity* m_entity; // 0x00
|
||||
LegoROI* m_roi; // 0x04
|
||||
MxLong m_time; // 0x08
|
||||
float m_unk0x0c; // 0x0c
|
||||
float m_y; // 0x0c
|
||||
MxBool m_muted; // 0x10
|
||||
};
|
||||
|
||||
@ -79,16 +79,16 @@ class LegoBuildingManager : public MxCore {
|
||||
MxBool SwitchMood(LegoEntity* p_entity);
|
||||
MxU32 GetAnimationId(LegoEntity* p_entity);
|
||||
MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state);
|
||||
MxBool FUN_10030000(LegoEntity* p_entity);
|
||||
MxBool FUN_10030030(MxS32 p_index);
|
||||
MxBool FUN_10030110(LegoBuildingInfo* p_data);
|
||||
void ScheduleAnimation(LegoEntity* p_entity, MxLong p_length, MxBool p_haveSound, MxBool p_unk0x28);
|
||||
void FUN_10030590();
|
||||
MxBool DecrementCounter(LegoEntity* p_entity);
|
||||
MxBool DecrementCounter(MxS32 p_index);
|
||||
MxBool DecrementCounter(LegoBuildingInfo* p_data);
|
||||
void ScheduleAnimation(LegoEntity* p_entity, MxLong p_length, MxBool p_haveSound, MxBool p_hideAfterAnimation);
|
||||
void ClearCounters();
|
||||
void AdjustHeight(MxS32 p_index);
|
||||
MxResult FUN_10030630();
|
||||
MxResult DetermineBoundaries();
|
||||
LegoBuildingInfo* GetInfoArray(MxS32& p_length);
|
||||
void FUN_100307b0(LegoEntity* p_entity, MxS32 p_adjust);
|
||||
void FUN_10030800();
|
||||
void AdjustCounter(LegoEntity* p_entity, MxS32 p_adjust);
|
||||
void SetInitialCounters();
|
||||
|
||||
static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; }
|
||||
|
||||
@ -100,13 +100,13 @@ class LegoBuildingManager : public MxCore {
|
||||
static MxS32 g_maxMove[16];
|
||||
static MxU32 g_maxSound;
|
||||
|
||||
MxU8 m_nextVariant; // 0x08
|
||||
MxBool m_unk0x09; // 0x09
|
||||
AnimEntry* m_entries[5]; // 0x0c
|
||||
MxS8 m_numEntries; // 0x20
|
||||
LegoCacheSound* m_sound; // 0x24
|
||||
MxBool m_unk0x28; // 0x28
|
||||
LegoWorld* m_world; // 0x2c
|
||||
MxU8 m_nextVariant; // 0x08
|
||||
MxBool m_boundariesDetermined; // 0x09
|
||||
AnimEntry* m_entries[5]; // 0x0c
|
||||
MxS8 m_numEntries; // 0x20
|
||||
LegoCacheSound* m_sound; // 0x24
|
||||
MxBool m_hideAfterAnimation; // 0x28
|
||||
LegoWorld* m_world; // 0x2c
|
||||
};
|
||||
|
||||
#endif // LEGOBUILDINGMANAGER_H
|
||||
|
||||
@ -67,7 +67,7 @@ class LegoGameState {
|
||||
e_isle,
|
||||
e_infomain,
|
||||
e_infodoor,
|
||||
e_unk4,
|
||||
e_infocenterExited,
|
||||
e_elevbott,
|
||||
e_elevride,
|
||||
e_elevride2,
|
||||
@ -80,10 +80,10 @@ class LegoGameState {
|
||||
e_jetrace,
|
||||
e_jetrace2,
|
||||
e_jetraceExterior,
|
||||
e_unk17,
|
||||
e_jetskibuildExited,
|
||||
e_carrace,
|
||||
e_carraceExterior,
|
||||
e_unk20,
|
||||
e_racecarbuildExited,
|
||||
e_unk21,
|
||||
e_pizzeriaExterior,
|
||||
e_unk23,
|
||||
@ -91,12 +91,12 @@ class LegoGameState {
|
||||
e_garageExterior,
|
||||
e_garage,
|
||||
e_garadoor,
|
||||
e_unk28,
|
||||
e_garageExited,
|
||||
e_hospitalExterior,
|
||||
e_hospital,
|
||||
e_unk31,
|
||||
e_hospitalExited,
|
||||
e_policeExterior,
|
||||
e_unk33,
|
||||
e_policeExited,
|
||||
e_police,
|
||||
e_polidoor,
|
||||
e_copterbuild,
|
||||
@ -129,7 +129,7 @@ class LegoGameState {
|
||||
e_towtrack,
|
||||
e_jetski,
|
||||
|
||||
e_unk66 = 66
|
||||
e_vehicleExited = 66
|
||||
};
|
||||
|
||||
// SIZE 0x0e
|
||||
|
||||
@ -52,11 +52,11 @@ class LegoPlantManager : public MxCore {
|
||||
MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state);
|
||||
LegoPlantInfo* GetInfoArray(MxS32& p_length);
|
||||
LegoEntity* CreatePlant(MxS32 p_index, LegoWorld* p_world, LegoOmni::World p_worldId);
|
||||
MxBool FUN_10026c50(LegoEntity* p_entity);
|
||||
MxBool DecrementCounter(LegoEntity* p_entity);
|
||||
void ScheduleAnimation(LegoEntity* p_entity, MxLong p_length);
|
||||
MxResult FUN_10026410();
|
||||
void FUN_10027120();
|
||||
void FUN_10027200();
|
||||
void ClearCounters();
|
||||
void SetInitialCounters();
|
||||
|
||||
static void SetCustomizeAnimFile(const char* p_value);
|
||||
|
||||
@ -68,10 +68,10 @@ class LegoPlantManager : public MxCore {
|
||||
|
||||
private:
|
||||
void RemovePlant(MxS32 p_index, LegoOmni::World p_worldId);
|
||||
void FUN_10026860(MxS32 p_index);
|
||||
void AdjustHeight(MxS32 p_index);
|
||||
LegoPlantInfo* GetInfo(LegoEntity* p_entity);
|
||||
MxBool FUN_10026c80(MxS32 p_index);
|
||||
void FUN_100271b0(LegoEntity* p_entity, MxS32 p_adjust);
|
||||
MxBool DecrementCounter(MxS32 p_index);
|
||||
void AdjustCounter(LegoEntity* p_entity, MxS32 p_adjust);
|
||||
|
||||
static char* g_customizeAnimFile;
|
||||
static MxS32 g_maxMove[4];
|
||||
|
||||
@ -41,8 +41,8 @@ struct LegoPlantInfo {
|
||||
MxU32 m_move; // 0x10
|
||||
MxU8 m_mood; // 0x14
|
||||
MxU8 m_color; // 0x15 - see enum for possible values
|
||||
MxS8 m_unk0x16; // 0x16
|
||||
MxS8 m_initialUnk0x16; // 0x17 - initial value loaded to m_unk0x16
|
||||
MxS8 m_counter; // 0x16
|
||||
MxS8 m_initialCounter; // 0x17 - initial value loaded to m_counter
|
||||
const char* m_name; // 0x18
|
||||
undefined4 m_unk0x1c; // 0x1c
|
||||
float m_x; // 0x20
|
||||
|
||||
@ -125,10 +125,10 @@ class PizzaMissionState : public LegoState {
|
||||
MxResult Serialize(LegoStorage* p_storage) override; // vtable+0x1c
|
||||
|
||||
// FUNCTION: BETA10 0x100ef470
|
||||
void SetUnknown0xb0(MxU32 p_unk0xb0) { m_unk0xb0 = p_unk0xb0; }
|
||||
void SetPlayedAction(MxU32 p_playedAction) { m_playedAction = p_playedAction; }
|
||||
|
||||
// FUNCTION: BETA10 0x100ef850
|
||||
MxU32 GetUnknown0xb0() { return m_unk0xb0; }
|
||||
MxU32 GetPlayedAction() { return m_playedAction; }
|
||||
|
||||
// FUNCTION: BETA10 0x10088850
|
||||
MxS16 GetHighScore(MxU8 p_actorId) { return GetMission(p_actorId)->m_hiScore; }
|
||||
@ -137,12 +137,12 @@ class PizzaMissionState : public LegoState {
|
||||
// PizzaMissionState::`scalar deleting destructor'
|
||||
|
||||
Mission* GetMission(MxU8 p_actorId);
|
||||
MxS16 FUN_10039540();
|
||||
MxS16 GetActorState();
|
||||
|
||||
PizzeriaState* m_pizzeriaState; // 0x08
|
||||
undefined4 m_unk0x0c; // 0x0c
|
||||
Mission m_missions[5]; // 0x10
|
||||
MxU32 m_unk0xb0; // 0xb0
|
||||
MxU32 m_playedAction; // 0xb0
|
||||
|
||||
static IsleScript::Script g_pepperActions[];
|
||||
static IsleScript::Script g_mamaActions[];
|
||||
@ -202,9 +202,9 @@ class Pizza : public IsleActor {
|
||||
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
|
||||
IsleScript::Script m_speechAction; // 0x8c
|
||||
MxLong m_startTime; // 0x90
|
||||
MxLong m_duration; // 0x94
|
||||
MxBool m_unk0x98; // 0x98
|
||||
};
|
||||
|
||||
|
||||
@ -34,11 +34,11 @@ class PizzeriaState : public LegoState {
|
||||
// SYNTHETIC: LEGO1 0x10017ce0
|
||||
// PizzeriaState::`scalar deleting destructor'
|
||||
|
||||
MxS16 FUN_10017d50();
|
||||
MxS16 GetActorState();
|
||||
MxU32 NextAction();
|
||||
|
||||
Playlist m_unk0x08[5]; // 0x08
|
||||
MxS32 m_unk0x44[5]; // 0x44
|
||||
Playlist m_playerPlaylists[5]; // 0x08
|
||||
MxS32 m_states[5]; // 0x44
|
||||
|
||||
static IsleScript::Script g_pepperActions[];
|
||||
static IsleScript::Script g_mamaActions[];
|
||||
|
||||
@ -39,14 +39,14 @@ class RadioState : public LegoState {
|
||||
|
||||
void SetActive(MxBool p_active) { m_active = p_active; }
|
||||
|
||||
undefined4 FUN_1002d090();
|
||||
MxBool FUN_1002d0c0(const MxAtomId& p_atom, MxU32 p_objectId);
|
||||
MxU32 NextPlaylistObjectId();
|
||||
MxBool IsRadioObjectId(const MxAtomId& p_atom, MxU32 p_objectId);
|
||||
|
||||
// TODO: Most likely getters/setters are not used according to BETA.
|
||||
|
||||
Playlist m_unk0x08[3]; // 0x08
|
||||
MxS16 m_unk0x2c; // 0x2c
|
||||
MxBool m_active; // 0x2e
|
||||
Playlist m_playlists[3]; // 0x08
|
||||
MxS16 m_activePlaylist; // 0x2c
|
||||
MxBool m_active; // 0x2e
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d6d10
|
||||
@ -85,7 +85,7 @@ class Radio : public MxCore {
|
||||
|
||||
private:
|
||||
RadioState* m_state; // 0x08
|
||||
MxBool m_unk0x0c; // 0x0c
|
||||
MxBool m_enabled; // 0x0c
|
||||
MxBool m_audioEnabled; // 0x0d
|
||||
|
||||
MxLong HandleEndAction(MxEndActionNotificationParam& p_param);
|
||||
|
||||
@ -718,17 +718,17 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
|
||||
switch (m_unk0x1d) {
|
||||
case 0:
|
||||
if (buildingInfo[12].m_unk0x11) {
|
||||
if (buildingInfo[12].m_counter) {
|
||||
result = buildingInfo[12].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else if (buildingInfo[14].m_unk0x11) {
|
||||
else if (buildingInfo[14].m_counter) {
|
||||
result = buildingInfo[14].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f0f30[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f0f30[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f0f30[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f0f30[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -736,13 +736,13 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (buildingInfo[13].m_unk0x11) {
|
||||
if (buildingInfo[13].m_counter) {
|
||||
result = buildingInfo[13].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f0f50[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f0f50[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f0f50[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f0f50[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -750,17 +750,17 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (buildingInfo[9].m_unk0x11) {
|
||||
if (buildingInfo[9].m_counter) {
|
||||
result = buildingInfo[9].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else if (buildingInfo[11].m_unk0x11) {
|
||||
else if (buildingInfo[11].m_counter) {
|
||||
result = buildingInfo[11].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f0f90[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f0f90[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f0f90[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f0f90[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -768,21 +768,21 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (buildingInfo[7].m_unk0x11) {
|
||||
if (buildingInfo[7].m_counter) {
|
||||
result = buildingInfo[7].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else if (buildingInfo[8].m_unk0x11) {
|
||||
else if (buildingInfo[8].m_counter) {
|
||||
result = buildingInfo[8].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else if (buildingInfo[3].m_unk0x11) {
|
||||
else if (buildingInfo[3].m_counter) {
|
||||
result = buildingInfo[3].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f0fa8[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f0fa8[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f0fa8[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f0fa8[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -790,17 +790,17 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (buildingInfo[5].m_unk0x11) {
|
||||
if (buildingInfo[5].m_counter) {
|
||||
result = buildingInfo[5].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else if (buildingInfo[10].m_unk0x11) {
|
||||
else if (buildingInfo[10].m_counter) {
|
||||
result = buildingInfo[10].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f0fb8[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f0fb8[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f0fb8[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f0fb8[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -808,13 +808,13 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (buildingInfo[4].m_unk0x11) {
|
||||
if (buildingInfo[4].m_counter) {
|
||||
result = buildingInfo[4].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f0fe8[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f0fe8[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f0fe8[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f0fe8[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -822,13 +822,13 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (buildingInfo[2].m_unk0x11) {
|
||||
if (buildingInfo[2].m_counter) {
|
||||
result = buildingInfo[2].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f1000[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f1000[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f1000[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f1000[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -836,13 +836,13 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (buildingInfo[6].m_unk0x11) {
|
||||
if (buildingInfo[6].m_counter) {
|
||||
result = buildingInfo[6].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
else {
|
||||
for (i = 0; g_unk0x100f1018[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f1018[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f1018[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f1018[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -851,7 +851,7 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
break;
|
||||
case 8:
|
||||
for (i = 0; g_unk0x100f1030[i] != -1; i++) {
|
||||
if (plantInfo[g_unk0x100f1030[i]].m_unk0x16) {
|
||||
if (plantInfo[g_unk0x100f1030[i]].m_counter) {
|
||||
result = plantInfo[g_unk0x100f1030[i]].m_entity;
|
||||
break;
|
||||
}
|
||||
@ -861,7 +861,7 @@ LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (buildingInfo[15].m_unk0x11) {
|
||||
if (buildingInfo[15].m_counter) {
|
||||
result = buildingInfo[15].m_entity;
|
||||
*p_param = TRUE;
|
||||
}
|
||||
|
||||
@ -607,8 +607,8 @@ void Act3Brickster::Animate(float p_time)
|
||||
assert(m_shootAnim && m_pInfo);
|
||||
|
||||
if (m_unk0x50 < p_time) {
|
||||
while (m_pInfo->m_unk0x16) {
|
||||
PlantManager()->FUN_10026c50(m_pInfo->m_entity);
|
||||
while (m_pInfo->m_counter) {
|
||||
PlantManager()->DecrementCounter(m_pInfo->m_entity);
|
||||
}
|
||||
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
@ -653,8 +653,8 @@ void Act3Brickster::Animate(float p_time)
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
SoundManager()->GetCacheSoundManager()->Play("thpt", NULL, FALSE);
|
||||
|
||||
while (m_bInfo->m_unk0x11 > 0 || m_bInfo->m_unk0x11 == -1) {
|
||||
if (!BuildingManager()->FUN_10030110(m_bInfo)) {
|
||||
while (m_bInfo->m_counter > 0 || m_bInfo->m_counter == -1) {
|
||||
if (!BuildingManager()->DecrementCounter(m_bInfo)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -865,7 +865,7 @@ MxResult Act3Brickster::FUN_100417c0()
|
||||
float local124;
|
||||
|
||||
for (MxS32 i = 0; i < length; i++) {
|
||||
if (bInfo[i].m_unk0x11 < 0 && bInfo[i].m_boundary != NULL && bInfo[i].m_entity != NULL && i != 0 &&
|
||||
if (bInfo[i].m_counter < 0 && bInfo[i].m_boundary != NULL && bInfo[i].m_entity != NULL && i != 0 &&
|
||||
(local120 == -1 || i != 15)) {
|
||||
Mx3DPointFloat local188(bInfo[i].m_x, bInfo[i].m_y, bInfo[i].m_z);
|
||||
|
||||
|
||||
@ -70,7 +70,9 @@ MxResult Act3Ammo::Remove()
|
||||
// FUNCTION: BETA10 0x1001d8b3
|
||||
MxResult Act3Ammo::Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index)
|
||||
{
|
||||
#ifdef BETA10
|
||||
assert(m_ammoFlag);
|
||||
#endif
|
||||
char name[12];
|
||||
|
||||
if (p_isPizza) {
|
||||
|
||||
@ -221,7 +221,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
else if (objectId == IsleScript::c_hps117bd_RunAnim) {
|
||||
CurrentWorld()->PlaceActor(UserActor());
|
||||
HandleClick();
|
||||
SpawnPlayer(LegoGameState::e_unk33, TRUE, 0);
|
||||
SpawnPlayer(LegoGameState::e_policeExited, TRUE, 0);
|
||||
m_unk0x172 = 0;
|
||||
TickleManager()->RegisterClient(this, 40000);
|
||||
|
||||
@ -388,7 +388,7 @@ MxLong Ambulance::HandleClick()
|
||||
ControlManager()->Register(this);
|
||||
|
||||
if (m_state->m_unk0x08 == 1) {
|
||||
SpawnPlayer(LegoGameState::e_unk31, TRUE, 0);
|
||||
SpawnPlayer(LegoGameState::e_hospitalExited, TRUE, 0);
|
||||
m_state->m_startTime = Timer()->GetTime();
|
||||
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns018rd_RunAnim, NULL);
|
||||
}
|
||||
@ -441,14 +441,14 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_AmbulanceArms_Ctl:
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_AmbulanceInfo_Ctl:
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_AmbulanceHorn_Ctl:
|
||||
|
||||
@ -85,7 +85,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_BikeArms_Ctl:
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_BikeInfo_Ctl:
|
||||
|
||||
@ -125,7 +125,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_DuneCarArms_Ctl:
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_DuneCarInfo_Ctl:
|
||||
|
||||
@ -203,7 +203,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
}
|
||||
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_Helicopter_TakeOff_Ctl: {
|
||||
|
||||
@ -148,7 +148,7 @@ void IslePathActor::Exit()
|
||||
}
|
||||
|
||||
m_previousActor->SetActorState(c_initial);
|
||||
GameState()->m_currentArea = LegoGameState::Area::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::Area::e_vehicleExited;
|
||||
}
|
||||
|
||||
FUN_1001b660();
|
||||
@ -199,7 +199,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_Quiet_Audio
|
||||
);
|
||||
g_spawnLocations[3] = SpawnLocation(
|
||||
LegoGameState::e_unk4,
|
||||
LegoGameState::e_infocenterExited,
|
||||
g_isleScript,
|
||||
0,
|
||||
"int46",
|
||||
@ -223,7 +223,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_Beach_Music
|
||||
);
|
||||
g_spawnLocations[5] = SpawnLocation(
|
||||
LegoGameState::e_unk17,
|
||||
LegoGameState::e_jetskibuildExited,
|
||||
g_isleScript,
|
||||
0,
|
||||
"EDG00_46",
|
||||
@ -259,7 +259,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_CentralNorthRoad_Music
|
||||
);
|
||||
g_spawnLocations[8] = SpawnLocation(
|
||||
LegoGameState::e_unk20,
|
||||
LegoGameState::e_racecarbuildExited,
|
||||
g_isleScript,
|
||||
0,
|
||||
"INT16",
|
||||
@ -295,7 +295,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_GarageArea_Music
|
||||
);
|
||||
g_spawnLocations[11] = SpawnLocation(
|
||||
LegoGameState::e_unk28,
|
||||
LegoGameState::e_garageExited,
|
||||
g_isleScript,
|
||||
0,
|
||||
"INT24",
|
||||
@ -319,7 +319,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_Hospital_Music
|
||||
);
|
||||
g_spawnLocations[13] = SpawnLocation(
|
||||
LegoGameState::e_unk31,
|
||||
LegoGameState::e_hospitalExited,
|
||||
g_isleScript,
|
||||
0,
|
||||
"EDG02_28",
|
||||
@ -343,7 +343,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_PoliceStation_Music
|
||||
);
|
||||
g_spawnLocations[15] = SpawnLocation(
|
||||
LegoGameState::e_unk33,
|
||||
LegoGameState::e_policeExited,
|
||||
g_isleScript,
|
||||
0,
|
||||
"EDG02_64",
|
||||
|
||||
@ -143,7 +143,7 @@ MxLong Jetski::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
Exit();
|
||||
((IslePathActor*) UserActor())
|
||||
->SpawnPlayer(LegoGameState::e_jetraceExterior, TRUE, c_spawnBit1 | c_playMusic | c_spawnBit3);
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
return 1;
|
||||
case IsleScript::c_JetskiInfo_Ctl:
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain);
|
||||
|
||||
@ -119,7 +119,7 @@ MxLong Motocycle::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_MotoBikeArms_Ctl:
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_MotoBikeInfo_Ctl:
|
||||
|
||||
@ -136,9 +136,9 @@ Pizza::Pizza()
|
||||
m_mission = NULL;
|
||||
m_skateBoard = NULL;
|
||||
m_act1state = NULL;
|
||||
m_unk0x8c = IsleScript::c_noneIsle;
|
||||
m_speechAction = IsleScript::c_noneIsle;
|
||||
m_unk0x98 = FALSE;
|
||||
m_unk0x90 = INT_MIN;
|
||||
m_startTime = INT_MIN;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10038100
|
||||
@ -188,7 +188,7 @@ void Pizza::FUN_10038220(IsleScript::Script p_objectId)
|
||||
AnimationManager()->EnableCamAnims(FALSE);
|
||||
AnimationManager()->FUN_1005f6d0(FALSE);
|
||||
PlayAction(p_objectId, FALSE);
|
||||
m_unk0x8c = IsleScript::c_noneIsle;
|
||||
m_speechAction = IsleScript::c_noneIsle;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100382b0
|
||||
@ -196,8 +196,8 @@ void Pizza::FUN_10038220(IsleScript::Script p_objectId)
|
||||
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);
|
||||
if (m_speechAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_speechAction, NULL);
|
||||
}
|
||||
|
||||
m_act1state->m_unk0x018 = 0;
|
||||
@ -209,10 +209,10 @@ void Pizza::FUN_100382b0()
|
||||
m_mission->m_startTime = INT_MIN;
|
||||
m_mission = NULL;
|
||||
m_unk0x98 = FALSE;
|
||||
m_unk0x8c = IsleScript::c_noneIsle;
|
||||
m_speechAction = IsleScript::c_noneIsle;
|
||||
BackgroundAudioManager()->RaiseVolume();
|
||||
TickleManager()->UnregisterClient(this);
|
||||
m_unk0x90 = INT_MIN;
|
||||
m_startTime = INT_MIN;
|
||||
m_skateBoard->EnableScenePresentation(FALSE);
|
||||
m_skateBoard->SetPizzaVisible(FALSE);
|
||||
MxTrace("Pizza mission: idle\n");
|
||||
@ -254,7 +254,7 @@ MxLong Pizza::HandleClick()
|
||||
|
||||
IsleScript::Script action;
|
||||
|
||||
switch (m_state->FUN_10039540()) {
|
||||
switch (m_state->GetActorState()) {
|
||||
case 0:
|
||||
action = m_mission->m_actions[m_mission->m_numActions + 3];
|
||||
break;
|
||||
@ -284,7 +284,7 @@ MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
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);
|
||||
m_state->SetPlayedAction(SndanimScript::c_TRS302_OpenJailDoor);
|
||||
|
||||
if (time < m_mission->GetRedFinishTime()) {
|
||||
m_mission->UpdateScore(LegoState::e_red);
|
||||
@ -325,26 +325,26 @@ MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
case IsleScript::c_pps025ni_RunAnim:
|
||||
case IsleScript::c_pps026ni_RunAnim:
|
||||
case IsleScript::c_pps027ni_RunAnim:
|
||||
m_unk0x90 = Timer()->GetTime();
|
||||
m_unk0x94 = 3800;
|
||||
m_startTime = Timer()->GetTime();
|
||||
m_duration = 3800;
|
||||
break;
|
||||
case IsleScript::c_pgs050nu_RunAnim:
|
||||
case IsleScript::c_pgs051nu_RunAnim:
|
||||
case IsleScript::c_pgs052nu_RunAnim:
|
||||
m_unk0x90 = Timer()->GetTime();
|
||||
m_unk0x94 = 6400;
|
||||
m_startTime = Timer()->GetTime();
|
||||
m_duration = 6400;
|
||||
break;
|
||||
case IsleScript::c_prt072sl_RunAnim:
|
||||
case IsleScript::c_prt073sl_RunAnim:
|
||||
case IsleScript::c_prt074sl_RunAnim:
|
||||
m_unk0x90 = Timer()->GetTime();
|
||||
m_unk0x94 = 7000;
|
||||
m_startTime = Timer()->GetTime();
|
||||
m_duration = 7000;
|
||||
break;
|
||||
case IsleScript::c_pho104re_RunAnim:
|
||||
case IsleScript::c_pho105re_RunAnim:
|
||||
case IsleScript::c_pho106re_RunAnim:
|
||||
m_unk0x90 = Timer()->GetTime();
|
||||
m_unk0x94 = 6500;
|
||||
m_startTime = Timer()->GetTime();
|
||||
m_duration = 6500;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -376,8 +376,8 @@ MxResult Pizza::Tickle()
|
||||
{
|
||||
MxLong time = Timer()->GetTime();
|
||||
|
||||
if (m_unk0x90 != INT_MIN && m_unk0x94 + m_unk0x90 <= time) {
|
||||
m_unk0x90 = INT_MIN;
|
||||
if (m_startTime != INT_MIN && m_duration + m_startTime <= time) {
|
||||
m_startTime = INT_MIN;
|
||||
m_skateBoard->EnableScenePresentation(FALSE);
|
||||
m_skateBoard->SetPizzaVisible(FALSE);
|
||||
TickleManager()->UnregisterClient(this);
|
||||
@ -395,29 +395,29 @@ MxResult Pizza::Tickle()
|
||||
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) {
|
||||
else if (time >= m_mission->m_startTime + 35000 && m_speechAction == IsleScript::c_noneIsle) {
|
||||
switch (GameState()->GetActorId()) {
|
||||
case LegoActor::c_pepper:
|
||||
m_unk0x8c = IsleScript::c_Avo914In_PlayWav;
|
||||
m_speechAction = IsleScript::c_Avo914In_PlayWav;
|
||||
break;
|
||||
case LegoActor::c_mama:
|
||||
m_unk0x8c = IsleScript::c_Avo910In_PlayWav;
|
||||
m_speechAction = IsleScript::c_Avo910In_PlayWav;
|
||||
break;
|
||||
case LegoActor::c_papa:
|
||||
m_unk0x8c = IsleScript::c_Avo912In_PlayWav;
|
||||
m_speechAction = IsleScript::c_Avo912In_PlayWav;
|
||||
break;
|
||||
case LegoActor::c_nick:
|
||||
m_unk0x8c = IsleScript::c_Avo911In_PlayWav;
|
||||
m_speechAction = IsleScript::c_Avo911In_PlayWav;
|
||||
break;
|
||||
case LegoActor::c_laura:
|
||||
m_unk0x8c = IsleScript::c_Avo913In_PlayWav;
|
||||
m_speechAction = IsleScript::c_Avo913In_PlayWav;
|
||||
break;
|
||||
}
|
||||
|
||||
BackgroundAudioManager()->LowerVolume();
|
||||
|
||||
if (m_unk0x8c != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_start, *g_isleScript, m_unk0x8c, NULL);
|
||||
if (m_speechAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_start, *g_isleScript, m_speechAction, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,14 +447,14 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
MxLong result = 0;
|
||||
MxU32 objectId = p_param.GetAction()->GetObjectId();
|
||||
|
||||
if (m_unk0x8c == objectId) {
|
||||
if (m_speechAction == objectId) {
|
||||
BackgroundAudioManager()->RaiseVolume();
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (m_state->m_unk0x0c) {
|
||||
case 1:
|
||||
if (m_state->GetUnknown0xb0() == objectId) {
|
||||
if (m_state->GetPlayedAction() == objectId) {
|
||||
m_state->m_unk0x0c = 2;
|
||||
m_mission->m_startTime = Timer()->GetTime();
|
||||
TickleManager()->RegisterClient(this, 200);
|
||||
@ -462,7 +462,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (m_state->GetUnknown0xb0() == objectId) {
|
||||
if (m_state->GetPlayedAction() == objectId) {
|
||||
m_mission->m_startTime = Timer()->GetTime();
|
||||
|
||||
PizzaMissionState::Mission* mission = m_mission;
|
||||
@ -471,7 +471,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
}
|
||||
|
||||
m_state->m_unk0x0c = 4;
|
||||
m_state->SetUnknown0xb0(IsleScript::c_noneIsle);
|
||||
m_state->SetPlayedAction(IsleScript::c_noneIsle);
|
||||
UserActor()->SetActorState(LegoPathActor::c_initial);
|
||||
m_skateBoard->SetPizzaVisible(TRUE);
|
||||
m_world->PlaceActor(m_skateBoard, "int37", 2, 0.5, 3, 0.5);
|
||||
@ -490,7 +490,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (m_state->GetUnknown0xb0() == objectId) {
|
||||
if (m_state->GetPlayedAction() == objectId) {
|
||||
StopActions();
|
||||
|
||||
if (GameState()->GetActorId() == LegoActor::c_pepper) {
|
||||
@ -506,24 +506,24 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
break;
|
||||
case 2:
|
||||
action = IsleScript::c_pja129br_RunAnim;
|
||||
m_unk0x90 = Timer()->GetTime();
|
||||
m_unk0x94 = 500;
|
||||
m_startTime = Timer()->GetTime();
|
||||
m_duration = 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_startTime = Timer()->GetTime();
|
||||
m_duration = 500;
|
||||
m_state->m_unk0x0c = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
action = IsleScript::c_pja132br_RunAnim;
|
||||
m_unk0x90 = Timer()->GetTime();
|
||||
m_unk0x94 = 2300;
|
||||
m_startTime = Timer()->GetTime();
|
||||
m_duration = 2300;
|
||||
m_state->m_unk0x0c = 8;
|
||||
InputManager()->DisableInputProcessing();
|
||||
InputManager()->SetUnknown336(TRUE);
|
||||
@ -535,16 +535,16 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
else {
|
||||
FUN_100382b0();
|
||||
m_state->m_unk0x0c = 0;
|
||||
m_state->SetUnknown0xb0(IsleScript::c_noneIsle);
|
||||
m_state->SetPlayedAction(IsleScript::c_noneIsle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (m_state->GetUnknown0xb0() == objectId) {
|
||||
if (m_state->GetPlayedAction() == objectId) {
|
||||
if (objectId == IsleScript::c_pja126br_RunAnim) {
|
||||
PlayAction(IsleScript::c_pja127br_RunAnim, TRUE);
|
||||
m_unk0x90 = Timer()->GetTime();
|
||||
m_unk0x94 = 700;
|
||||
m_startTime = Timer()->GetTime();
|
||||
m_duration = 700;
|
||||
}
|
||||
else if (objectId == IsleScript::c_pja129br_RunAnim) {
|
||||
PlayAction(IsleScript::c_pja130br_RunAnim, TRUE);
|
||||
@ -552,12 +552,12 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
else {
|
||||
FUN_100382b0();
|
||||
m_state->m_unk0x0c = 0;
|
||||
m_state->SetUnknown0xb0(IsleScript::c_noneIsle);
|
||||
m_state->SetPlayedAction(IsleScript::c_noneIsle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (m_state->GetUnknown0xb0() == objectId) {
|
||||
if (m_state->GetPlayedAction() == objectId) {
|
||||
m_act1state->m_unk0x018 = 0;
|
||||
m_state->m_unk0x0c = 0;
|
||||
GameState()->m_currentArea = LegoGameState::e_isle;
|
||||
@ -567,7 +567,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (m_state->GetUnknown0xb0() == objectId) {
|
||||
if (m_state->GetPlayedAction() == objectId) {
|
||||
FUN_100382b0();
|
||||
}
|
||||
break;
|
||||
@ -580,10 +580,10 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
// FUNCTION: BETA10 0x100ef520
|
||||
void Pizza::PlayAction(MxU32 p_objectId, MxBool p_param7)
|
||||
{
|
||||
m_state->SetUnknown0xb0(p_objectId);
|
||||
m_state->SetPlayedAction(p_objectId);
|
||||
|
||||
if (m_unk0x8c != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x8c, NULL);
|
||||
if (m_speechAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_speechAction, NULL);
|
||||
}
|
||||
|
||||
AnimationManager()
|
||||
@ -601,7 +601,7 @@ PizzaMissionState::PizzaMissionState()
|
||||
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;
|
||||
m_playedAction = IsleScript::c_noneIsle;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100393c0
|
||||
@ -645,7 +645,7 @@ PizzaMissionState::Mission* PizzaMissionState::GetMission(MxU8 p_actorId)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10039540
|
||||
MxS16 PizzaMissionState::FUN_10039540()
|
||||
MxS16 PizzaMissionState::GetActorState()
|
||||
{
|
||||
return m_pizzeriaState->FUN_10017d50();
|
||||
return m_pizzeriaState->GetActorState();
|
||||
}
|
||||
|
||||
@ -89,18 +89,18 @@ MxLong Pizzeria::HandleClick()
|
||||
// FUNCTION: BETA10 0x100efd14
|
||||
PizzeriaState::PizzeriaState()
|
||||
{
|
||||
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));
|
||||
m_playerPlaylists[0] = Playlist((MxU32*) g_pepperActions, sizeOfArray(g_pepperActions), Playlist::e_once);
|
||||
m_playerPlaylists[1] = Playlist((MxU32*) g_mamaActions, sizeOfArray(g_mamaActions), Playlist::e_once);
|
||||
m_playerPlaylists[2] = Playlist((MxU32*) g_papaActions, sizeOfArray(g_papaActions), Playlist::e_once);
|
||||
m_playerPlaylists[3] = Playlist((MxU32*) g_nickActions, sizeOfArray(g_nickActions), Playlist::e_once);
|
||||
m_playerPlaylists[4] = Playlist((MxU32*) g_lauraActions, sizeOfArray(g_lauraActions), Playlist::e_once);
|
||||
memset(m_states, -1, sizeof(m_states));
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10017d50
|
||||
MxS16 PizzeriaState::FUN_10017d50()
|
||||
MxS16 PizzeriaState::GetActorState()
|
||||
{
|
||||
return m_unk0x44[GameState()->GetActorId() - 1];
|
||||
return m_states[GameState()->GetActorId() - 1];
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10017d70
|
||||
@ -109,11 +109,11 @@ MxU32 PizzeriaState::NextAction()
|
||||
{
|
||||
MxU8 actorId = GameState()->GetActorId();
|
||||
|
||||
if (m_unk0x44[actorId - 1] < 2) {
|
||||
m_unk0x44[actorId - 1]++;
|
||||
if (m_states[actorId - 1] < 2) {
|
||||
m_states[actorId - 1]++;
|
||||
}
|
||||
|
||||
return m_unk0x08[actorId - 1].Next();
|
||||
return m_playerPlaylists[actorId - 1].Next();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10017da0
|
||||
@ -124,12 +124,12 @@ MxResult PizzeriaState::Serialize(LegoStorage* p_storage)
|
||||
|
||||
if (p_storage->IsReadMode()) {
|
||||
for (MxS16 i = 0; i < 5; i++) {
|
||||
p_storage->ReadS16(m_unk0x08[i].m_nextIndex);
|
||||
p_storage->ReadS16(m_playerPlaylists[i].m_nextIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (MxS16 i = 0; i < 5; i++) {
|
||||
p_storage->WriteS16(m_unk0x08[i].m_nextIndex);
|
||||
p_storage->WriteS16(m_playerPlaylists[i].m_nextIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ DECOMP_SIZE_ASSERT(Radio, 0x10)
|
||||
DECOMP_SIZE_ASSERT(RadioState, 0x30)
|
||||
|
||||
// GLOBAL: LEGO1 0x100f3218
|
||||
JukeboxScript::Script g_unk0x100f3218[] = {
|
||||
JukeboxScript::Script g_jingles[] = {
|
||||
JukeboxScript::c_sns002ra_Audio,
|
||||
JukeboxScript::c_sns001ja_Audio,
|
||||
JukeboxScript::c_snsc01js_Audio,
|
||||
@ -28,7 +28,7 @@ JukeboxScript::Script g_unk0x100f3218[] = {
|
||||
};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f3230
|
||||
JukeboxScript::Script g_unk0x100f3230[] = {
|
||||
JukeboxScript::Script g_news[] = {
|
||||
JukeboxScript::c_ham035ra_Audio,
|
||||
JukeboxScript::c_ham039ra_Audio,
|
||||
JukeboxScript::c_sns005ra_Audio,
|
||||
@ -46,7 +46,7 @@ JukeboxScript::Script g_unk0x100f3230[] = {
|
||||
};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f3268
|
||||
JukeboxScript::Script g_unk0x100f3268[] = {
|
||||
JukeboxScript::Script g_songs[] = {
|
||||
JukeboxScript::c_CentralRoads_Music,
|
||||
JukeboxScript::c_BeachBlvd_Music,
|
||||
JukeboxScript::c_ResidentalArea_Music,
|
||||
@ -64,7 +64,7 @@ Radio::Radio()
|
||||
NotificationManager()->Register(this);
|
||||
ControlManager()->Register(this);
|
||||
|
||||
m_unk0x0c = TRUE;
|
||||
m_enabled = TRUE;
|
||||
CreateState();
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ MxLong Radio::Notify(MxParam& p_param)
|
||||
{
|
||||
MxLong result = 0;
|
||||
|
||||
if (m_unk0x0c) {
|
||||
if (m_enabled) {
|
||||
MxNotificationParam& param = (MxNotificationParam&) p_param;
|
||||
switch (param.GetNotification()) {
|
||||
case c_notificationEndAction:
|
||||
@ -108,7 +108,7 @@ void Radio::Play()
|
||||
CurrentWorld();
|
||||
|
||||
MxDSAction action;
|
||||
action.SetObjectId(m_state->FUN_1002d090());
|
||||
action.SetObjectId(m_state->NextPlaylistObjectId());
|
||||
action.SetAtomId(*g_jukeboxScript);
|
||||
action.SetLoopCount(1);
|
||||
|
||||
@ -174,11 +174,11 @@ MxLong Radio::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
MxLong Radio::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
{
|
||||
if (m_state->IsActive() &&
|
||||
m_state->FUN_1002d0c0(p_param.GetAction()->GetAtomId(), p_param.GetAction()->GetObjectId())) {
|
||||
m_state->IsRadioObjectId(p_param.GetAction()->GetAtomId(), p_param.GetAction()->GetObjectId())) {
|
||||
|
||||
MxDSAction action;
|
||||
action.SetAtomId(*g_jukeboxScript);
|
||||
action.SetObjectId(m_state->FUN_1002d090());
|
||||
action.SetObjectId(m_state->NextPlaylistObjectId());
|
||||
action.SetLoopCount(1);
|
||||
|
||||
BackgroundAudioManager()->PlayMusic(action, 3, MxPresenter::e_repeating);
|
||||
@ -191,8 +191,8 @@ MxLong Radio::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
// FUNCTION: LEGO1 0x1002cdc0
|
||||
void Radio::Initialize(MxBool p_und)
|
||||
{
|
||||
if (m_unk0x0c != p_und) {
|
||||
m_unk0x0c = p_und;
|
||||
if (m_enabled != p_und) {
|
||||
m_enabled = p_und;
|
||||
CreateState();
|
||||
}
|
||||
}
|
||||
@ -216,39 +216,39 @@ RadioState::RadioState()
|
||||
srand(Timer()->GetTime());
|
||||
|
||||
MxS32 random = rand();
|
||||
m_unk0x2c = random % 3;
|
||||
m_activePlaylist = random % 3;
|
||||
|
||||
m_unk0x08[0] = Playlist((MxU32*) g_unk0x100f3218, sizeOfArray(g_unk0x100f3218), Playlist::e_loop);
|
||||
m_unk0x08[0].m_nextIndex = (rand() % sizeOfArray(g_unk0x100f3218));
|
||||
m_playlists[0] = Playlist((MxU32*) g_jingles, sizeOfArray(g_jingles), Playlist::e_loop);
|
||||
m_playlists[0].m_nextIndex = (rand() % sizeOfArray(g_jingles));
|
||||
|
||||
m_unk0x08[1] = Playlist((MxU32*) g_unk0x100f3230, sizeOfArray(g_unk0x100f3230), Playlist::e_loop);
|
||||
m_unk0x08[1].m_nextIndex = (rand() % sizeOfArray(g_unk0x100f3230));
|
||||
m_playlists[1] = Playlist((MxU32*) g_news, sizeOfArray(g_news), Playlist::e_loop);
|
||||
m_playlists[1].m_nextIndex = (rand() % sizeOfArray(g_news));
|
||||
|
||||
m_unk0x08[2] = Playlist((MxU32*) g_unk0x100f3268, sizeOfArray(g_unk0x100f3268), Playlist::e_loop);
|
||||
m_unk0x08[2].m_nextIndex = (rand() % sizeOfArray(g_unk0x100f3268));
|
||||
m_playlists[2] = Playlist((MxU32*) g_songs, sizeOfArray(g_songs), Playlist::e_loop);
|
||||
m_playlists[2].m_nextIndex = (rand() % sizeOfArray(g_songs));
|
||||
|
||||
m_active = FALSE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1002d090
|
||||
MxU32 RadioState::FUN_1002d090()
|
||||
MxU32 RadioState::NextPlaylistObjectId()
|
||||
{
|
||||
if (m_unk0x2c == 2) {
|
||||
m_unk0x2c = 0;
|
||||
if (m_activePlaylist == 2) {
|
||||
m_activePlaylist = 0;
|
||||
}
|
||||
else {
|
||||
m_unk0x2c++;
|
||||
m_activePlaylist++;
|
||||
}
|
||||
|
||||
return m_unk0x08[m_unk0x2c].Next();
|
||||
return m_playlists[m_activePlaylist].Next();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1002d0c0
|
||||
MxBool RadioState::FUN_1002d0c0(const MxAtomId& p_atom, MxU32 p_objectId)
|
||||
MxBool RadioState::IsRadioObjectId(const MxAtomId& p_atom, MxU32 p_objectId)
|
||||
{
|
||||
if (*g_jukeboxScript == p_atom) {
|
||||
for (MxS16 i = 0; i < 3; i++) {
|
||||
if (m_unk0x08[i].Contains(p_objectId)) {
|
||||
if (m_playlists[i].Contains(p_objectId)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ MxLong SkateBoard::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
|
||||
if (p_param.m_unk0x28 == 1 && p_param.m_clickedObjectId == IsleScript::c_SkateArms_Ctl) {
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::Area::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::Area::e_vehicleExited;
|
||||
result = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -435,7 +435,7 @@ MxLong TowTrack::HandleClick()
|
||||
FindROI("rcred")->SetVisibility(FALSE);
|
||||
}
|
||||
else {
|
||||
SpawnPlayer(LegoGameState::e_unk28, TRUE, 0);
|
||||
SpawnPlayer(LegoGameState::e_garageExited, TRUE, 0);
|
||||
m_lastAction = IsleScript::c_noneIsle;
|
||||
m_lastAnimation = IsleScript::c_noneIsle;
|
||||
m_state->m_startTime = Timer()->GetTime();
|
||||
@ -486,14 +486,14 @@ MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_TowTrackArms_Ctl:
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_TowInfo_Ctl:
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
result = 1;
|
||||
break;
|
||||
case IsleScript::c_TowHorn_Ctl:
|
||||
|
||||
@ -784,11 +784,11 @@ void LegoCarBuild::FUN_100243a0()
|
||||
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case Jetski_Actor:
|
||||
m_destLocation = LegoGameState::Area::e_unk17;
|
||||
m_destLocation = LegoGameState::Area::e_jetskibuildExited;
|
||||
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case RaceCar_Actor:
|
||||
m_destLocation = LegoGameState::Area::e_unk20;
|
||||
m_destLocation = LegoGameState::Area::e_racecarbuildExited;
|
||||
TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,10 +253,10 @@ void LegoBuildingManager::Init()
|
||||
}
|
||||
|
||||
m_nextVariant = 0;
|
||||
m_unk0x09 = FALSE;
|
||||
m_boundariesDetermined = FALSE;
|
||||
m_numEntries = 0;
|
||||
m_sound = NULL;
|
||||
m_unk0x28 = FALSE;
|
||||
m_hideAfterAnimation = FALSE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1002fa00
|
||||
@ -274,7 +274,7 @@ void LegoBuildingManager::LoadWorldInfo()
|
||||
LegoEntity* entity = (LegoEntity*) world->Find("MxEntity", g_buildingInfoVariants[0]);
|
||||
if (entity) {
|
||||
entity->GetROI()->SetVisibility(TRUE);
|
||||
m_unk0x09 = FALSE;
|
||||
m_boundariesDetermined = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -286,7 +286,7 @@ void LegoBuildingManager::LoadWorldInfo()
|
||||
}
|
||||
}
|
||||
|
||||
m_unk0x09 = FALSE;
|
||||
m_boundariesDetermined = FALSE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1002fa90
|
||||
@ -301,7 +301,7 @@ void LegoBuildingManager::CreateBuilding(MxS32 p_index, LegoWorld* p_world)
|
||||
LegoROI* roi = entity->GetROI();
|
||||
AdjustHeight(p_index);
|
||||
MxMatrix mat = roi->GetLocal2World();
|
||||
mat[3][1] = g_buildingInfo[p_index].m_unk0x14;
|
||||
mat[3][1] = g_buildingInfo[p_index].m_adjustedY;
|
||||
roi->UpdateTransformationRelativeToParent(mat);
|
||||
VideoManager()->Get3DManager()->Moved(*roi);
|
||||
}
|
||||
@ -316,7 +316,7 @@ void LegoBuildingManager::Reset()
|
||||
g_buildingInfo[i].m_entity = NULL;
|
||||
}
|
||||
|
||||
m_unk0x09 = FALSE;
|
||||
m_boundariesDetermined = FALSE;
|
||||
|
||||
for (i = 0; i < m_numEntries; i++) {
|
||||
delete m_entries[i];
|
||||
@ -343,7 +343,7 @@ MxResult LegoBuildingManager::Write(LegoStorage* p_storage)
|
||||
if (p_storage->Write(&info->m_mood, sizeof(MxU8)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&info->m_initialUnk0x11, sizeof(MxS8)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_initialCounter, sizeof(MxS8)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -376,11 +376,11 @@ MxResult LegoBuildingManager::Read(LegoStorage* p_storage)
|
||||
if (p_storage->Read(&info->m_mood, sizeof(MxU8)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&info->m_unk0x11, sizeof(MxS8)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_counter, sizeof(MxS8)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
info->m_initialUnk0x11 = info->m_unk0x11;
|
||||
info->m_initialCounter = info->m_counter;
|
||||
AdjustHeight(i);
|
||||
}
|
||||
|
||||
@ -402,15 +402,15 @@ MxResult LegoBuildingManager::Read(LegoStorage* p_storage)
|
||||
// FUNCTION: BETA10 0x10063f1a
|
||||
void LegoBuildingManager::AdjustHeight(MxS32 p_index)
|
||||
{
|
||||
if (g_buildingInfo[p_index].m_unk0x11 > 0) {
|
||||
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11;
|
||||
g_buildingInfo[p_index].m_unk0x14 =
|
||||
g_buildingInfoInit[p_index].m_unk0x14 - value * g_buildingInfoDownshiftScale[p_index];
|
||||
if (g_buildingInfo[p_index].m_counter > 0) {
|
||||
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_counter;
|
||||
g_buildingInfo[p_index].m_adjustedY =
|
||||
g_buildingInfoInit[p_index].m_adjustedY - value * g_buildingInfoDownshiftScale[p_index];
|
||||
}
|
||||
else if (g_buildingInfo[p_index].m_unk0x11 == 0) {
|
||||
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11;
|
||||
g_buildingInfo[p_index].m_unk0x14 =
|
||||
g_buildingInfoInit[p_index].m_unk0x14 - value * g_buildingInfoDownshiftScale[p_index];
|
||||
else if (g_buildingInfo[p_index].m_counter == 0) {
|
||||
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_counter;
|
||||
g_buildingInfo[p_index].m_adjustedY =
|
||||
g_buildingInfoInit[p_index].m_adjustedY - value * g_buildingInfoDownshiftScale[p_index];
|
||||
|
||||
if (g_buildingInfo[p_index].m_entity != NULL) {
|
||||
LegoROI* roi = g_buildingInfo[p_index].m_entity->GetROI();
|
||||
@ -420,7 +420,7 @@ void LegoBuildingManager::AdjustHeight(MxS32 p_index)
|
||||
}
|
||||
}
|
||||
else {
|
||||
g_buildingInfo[p_index].m_unk0x14 = g_buildingInfoInit[p_index].m_unk0x14;
|
||||
g_buildingInfo[p_index].m_adjustedY = g_buildingInfoInit[p_index].m_adjustedY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,7 +453,7 @@ MxBool LegoBuildingManager::SwitchVariant(LegoEntity* p_entity)
|
||||
|
||||
LegoBuildingInfo* info = GetInfo(p_entity);
|
||||
|
||||
if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasVariants && info->m_unk0x11 == -1) {
|
||||
if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasVariants && info->m_counter == -1) {
|
||||
LegoROI* roi = p_entity->GetROI();
|
||||
if (++m_nextVariant >= sizeOfArray(g_buildingInfoVariants)) {
|
||||
m_nextVariant = 0;
|
||||
@ -587,7 +587,7 @@ void LegoBuildingManager::SetCustomizeAnimFile(const char* p_value)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10030000
|
||||
MxBool LegoBuildingManager::FUN_10030000(LegoEntity* p_entity)
|
||||
MxBool LegoBuildingManager::DecrementCounter(LegoEntity* p_entity)
|
||||
{
|
||||
LegoBuildingInfo* info = GetInfo(p_entity);
|
||||
|
||||
@ -595,7 +595,7 @@ MxBool LegoBuildingManager::FUN_10030000(LegoEntity* p_entity)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FUN_10030030(info - g_buildingInfo);
|
||||
return DecrementCounter(info - g_buildingInfo);
|
||||
}
|
||||
|
||||
inline LegoBuildingInfo* GetBuildingInfo(MxS32 p_index)
|
||||
@ -608,7 +608,7 @@ inline LegoBuildingInfo* GetBuildingInfo(MxS32 p_index)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10030030
|
||||
MxBool LegoBuildingManager::FUN_10030030(MxS32 p_index)
|
||||
MxBool LegoBuildingManager::DecrementCounter(MxS32 p_index)
|
||||
{
|
||||
if (p_index >= sizeOfArray(g_buildingInfo)) {
|
||||
return FALSE;
|
||||
@ -621,25 +621,25 @@ MxBool LegoBuildingManager::FUN_10030030(MxS32 p_index)
|
||||
|
||||
MxBool result = TRUE;
|
||||
|
||||
if (info->m_unk0x11 < 0) {
|
||||
info->m_unk0x11 = g_buildingInfoDownshift[p_index];
|
||||
if (info->m_counter < 0) {
|
||||
info->m_counter = g_buildingInfoDownshift[p_index];
|
||||
}
|
||||
|
||||
if (info->m_unk0x11 <= 0) {
|
||||
if (info->m_counter <= 0) {
|
||||
result = FALSE;
|
||||
}
|
||||
else {
|
||||
LegoROI* roi = info->m_entity->GetROI();
|
||||
|
||||
info->m_unk0x11 -= 2;
|
||||
if (info->m_unk0x11 == 1) {
|
||||
info->m_unk0x11 = 0;
|
||||
info->m_counter -= 2;
|
||||
if (info->m_counter == 1) {
|
||||
info->m_counter = 0;
|
||||
roi->SetVisibility(FALSE);
|
||||
}
|
||||
else {
|
||||
AdjustHeight(p_index);
|
||||
MxMatrix mat = roi->GetLocal2World();
|
||||
mat[3][1] = g_buildingInfo[p_index].m_unk0x14;
|
||||
mat[3][1] = g_buildingInfo[p_index].m_adjustedY;
|
||||
roi->UpdateTransformationRelativeToParent(mat);
|
||||
VideoManager()->Get3DManager()->Moved(*roi);
|
||||
}
|
||||
@ -649,11 +649,11 @@ MxBool LegoBuildingManager::FUN_10030030(MxS32 p_index)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10030110
|
||||
MxBool LegoBuildingManager::FUN_10030110(LegoBuildingInfo* p_data)
|
||||
MxBool LegoBuildingManager::DecrementCounter(LegoBuildingInfo* p_data)
|
||||
{
|
||||
for (MxS32 i = 0; i < sizeOfArray(g_buildingInfo); i++) {
|
||||
if (&g_buildingInfo[i] == p_data) {
|
||||
return FUN_10030030(i);
|
||||
return DecrementCounter(i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,7 +661,12 @@ MxBool LegoBuildingManager::FUN_10030110(LegoBuildingInfo* p_data)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10030150
|
||||
void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_length, MxBool p_haveSound, MxBool p_unk0x28)
|
||||
void LegoBuildingManager::ScheduleAnimation(
|
||||
LegoEntity* p_entity,
|
||||
MxLong p_length,
|
||||
MxBool p_haveSound,
|
||||
MxBool p_hideAfterAnimation
|
||||
)
|
||||
{
|
||||
m_world = CurrentWorld();
|
||||
|
||||
@ -671,7 +676,7 @@ void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_lengt
|
||||
}
|
||||
|
||||
if (m_numEntries == 0) {
|
||||
m_unk0x28 = p_unk0x28;
|
||||
m_hideAfterAnimation = p_hideAfterAnimation;
|
||||
TickleManager()->RegisterClient(this, 50);
|
||||
}
|
||||
|
||||
@ -685,9 +690,9 @@ void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_lengt
|
||||
time += p_length;
|
||||
entry->m_time = time + 1000;
|
||||
|
||||
entry->m_unk0x0c = entry->m_roi->GetWorldPosition()[1];
|
||||
entry->m_y = entry->m_roi->GetWorldPosition()[1];
|
||||
entry->m_muted = p_haveSound == FALSE;
|
||||
FUN_100307b0(p_entity, -2);
|
||||
AdjustCounter(p_entity, -2);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10030220
|
||||
@ -724,33 +729,33 @@ MxResult LegoBuildingManager::Tickle()
|
||||
MxMatrix local48;
|
||||
MxMatrix locald8;
|
||||
|
||||
MxMatrix local120(entry->m_roi->GetLocal2World());
|
||||
Mx3DPointFloat local134(local120[3]);
|
||||
MxMatrix transformationMatrix(entry->m_roi->GetLocal2World());
|
||||
Mx3DPointFloat position(transformationMatrix[3]);
|
||||
|
||||
ZEROVEC3(local120[3]);
|
||||
ZEROVEC3(transformationMatrix[3]);
|
||||
|
||||
locald8.SetIdentity();
|
||||
local48 = local120;
|
||||
local48 = transformationMatrix;
|
||||
|
||||
local134[1] = sin(((entry->m_time - time) * 10) * 0.0062831999f) * 0.4 + (entry->m_unk0x0c -= 0.05);
|
||||
SET3(local120[3], local134);
|
||||
position[1] = sin(((entry->m_time - time) * 10) * 0.0062831999f) * 0.4 + (entry->m_y -= 0.05);
|
||||
SET3(transformationMatrix[3], position);
|
||||
|
||||
entry->m_roi->UpdateTransformationRelativeToParent(local120);
|
||||
entry->m_roi->UpdateTransformationRelativeToParent(transformationMatrix);
|
||||
VideoManager()->Get3DManager()->Moved(*entry->m_roi);
|
||||
|
||||
if (entry->m_time < time) {
|
||||
LegoBuildingInfo* info = GetInfo(entry->m_entity);
|
||||
|
||||
if (info->m_unk0x11 && !m_unk0x28) {
|
||||
if (info->m_counter && !m_hideAfterAnimation) {
|
||||
MxS32 index = info - g_buildingInfo;
|
||||
AdjustHeight(index);
|
||||
MxMatrix mat = entry->m_roi->GetLocal2World();
|
||||
mat[3][1] = g_buildingInfo[index].m_unk0x14;
|
||||
mat[3][1] = g_buildingInfo[index].m_adjustedY;
|
||||
entry->m_roi->UpdateTransformationRelativeToParent(mat);
|
||||
VideoManager()->Get3DManager()->Moved(*entry->m_roi);
|
||||
}
|
||||
else {
|
||||
info->m_unk0x11 = 0;
|
||||
info->m_counter = 0;
|
||||
entry->m_roi->SetVisibility(FALSE);
|
||||
}
|
||||
|
||||
@ -774,17 +779,17 @@ MxResult LegoBuildingManager::Tickle()
|
||||
|
||||
// FUNCTION: LEGO1 0x10030590
|
||||
// FUNCTION: BETA10 0x1006474c
|
||||
void LegoBuildingManager::FUN_10030590()
|
||||
void LegoBuildingManager::ClearCounters()
|
||||
{
|
||||
for (MxS32 i = 0; i < sizeOfArray(g_buildingInfo); i++) {
|
||||
g_buildingInfo[i].m_unk0x11 = -1;
|
||||
g_buildingInfo[i].m_initialUnk0x11 = -1;
|
||||
g_buildingInfo[i].m_counter = -1;
|
||||
g_buildingInfo[i].m_initialCounter = -1;
|
||||
AdjustHeight(i);
|
||||
|
||||
if (g_buildingInfo[i].m_entity != NULL) {
|
||||
LegoROI* roi = g_buildingInfo[i].m_entity->GetROI();
|
||||
MxMatrix mat = roi->GetLocal2World();
|
||||
mat[3][1] = g_buildingInfo[i].m_unk0x14;
|
||||
mat[3][1] = g_buildingInfo[i].m_adjustedY;
|
||||
roi->UpdateTransformationRelativeToParent(mat);
|
||||
VideoManager()->Get3DManager()->Moved(*roi);
|
||||
}
|
||||
@ -793,7 +798,7 @@ void LegoBuildingManager::FUN_10030590()
|
||||
|
||||
// FUNCTION: LEGO1 0x10030630
|
||||
// FUNCTION: BETA10 0x100648ab
|
||||
MxResult LegoBuildingManager::FUN_10030630()
|
||||
MxResult LegoBuildingManager::DetermineBoundaries()
|
||||
{
|
||||
LegoWorld* world = CurrentWorld();
|
||||
|
||||
@ -859,7 +864,7 @@ MxResult LegoBuildingManager::FUN_10030630()
|
||||
}
|
||||
}
|
||||
|
||||
m_unk0x09 = TRUE;
|
||||
m_boundariesDetermined = TRUE;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -867,8 +872,8 @@ MxResult LegoBuildingManager::FUN_10030630()
|
||||
// FUNCTION: BETA10 0x10064db9
|
||||
LegoBuildingInfo* LegoBuildingManager::GetInfoArray(MxS32& p_length)
|
||||
{
|
||||
if (!m_unk0x09) {
|
||||
FUN_10030630();
|
||||
if (!m_boundariesDetermined) {
|
||||
DetermineBoundaries();
|
||||
}
|
||||
|
||||
p_length = sizeOfArray(g_buildingInfo);
|
||||
@ -876,28 +881,28 @@ LegoBuildingInfo* LegoBuildingManager::GetInfoArray(MxS32& p_length)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100307b0
|
||||
void LegoBuildingManager::FUN_100307b0(LegoEntity* p_entity, MxS32 p_adjust)
|
||||
void LegoBuildingManager::AdjustCounter(LegoEntity* p_entity, MxS32 p_adjust)
|
||||
{
|
||||
LegoBuildingInfo* info = GetInfo(p_entity);
|
||||
|
||||
if (info != NULL) {
|
||||
if (info->m_unk0x11 < 0) {
|
||||
info->m_unk0x11 = g_buildingInfoDownshift[info - g_buildingInfo];
|
||||
if (info->m_counter < 0) {
|
||||
info->m_counter = g_buildingInfoDownshift[info - g_buildingInfo];
|
||||
}
|
||||
|
||||
if (info->m_unk0x11 > 0) {
|
||||
info->m_unk0x11 += p_adjust;
|
||||
if (info->m_unk0x11 <= 1 && p_adjust < 0) {
|
||||
info->m_unk0x11 = 0;
|
||||
if (info->m_counter > 0) {
|
||||
info->m_counter += p_adjust;
|
||||
if (info->m_counter <= 1 && p_adjust < 0) {
|
||||
info->m_counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10030800
|
||||
void LegoBuildingManager::FUN_10030800()
|
||||
void LegoBuildingManager::SetInitialCounters()
|
||||
{
|
||||
for (MxU32 i = 0; i < sizeOfArray(g_buildingInfo); i++) {
|
||||
g_buildingInfo[i].m_initialUnk0x11 = g_buildingInfo[i].m_unk0x11;
|
||||
g_buildingInfo[i].m_initialCounter = g_buildingInfo[i].m_counter;
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,7 +643,7 @@ MxBool LegoCharacterManager::SetHeadTexture(LegoROI* p_roi, LegoTextureInfo* p_t
|
||||
lodList->Release();
|
||||
lodList = dupLodList;
|
||||
|
||||
if (head->GetUnknown0xe0() >= 0) {
|
||||
if (head->GetLodLevel() >= 0) {
|
||||
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveROIDetailFromScene(head);
|
||||
}
|
||||
|
||||
@ -844,7 +844,7 @@ MxBool LegoCharacterManager::SwitchVariant(LegoROI* p_roi)
|
||||
lodList->Release();
|
||||
lodList = dupLodList;
|
||||
|
||||
if (childROI->GetUnknown0xe0() >= 0) {
|
||||
if (childROI->GetLodLevel() >= 0) {
|
||||
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveROIDetailFromScene(childROI);
|
||||
}
|
||||
|
||||
|
||||
@ -868,17 +868,17 @@ void LegoGameState::SwitchArea(Area p_area)
|
||||
VideoManager()->SetUnk0x554(TRUE);
|
||||
InvokeAction(Extra::ActionType::e_opendisk, *g_infodoorScript, InfodoorScript::c__StartUp, NULL);
|
||||
break;
|
||||
case e_unk4:
|
||||
case e_infocenterExited:
|
||||
case e_jetrace2:
|
||||
case e_jetraceExterior:
|
||||
case e_unk17:
|
||||
case e_jetskibuildExited:
|
||||
case e_carraceExterior:
|
||||
case e_unk20:
|
||||
case e_racecarbuildExited:
|
||||
case e_unk21:
|
||||
case e_pizzeriaExterior:
|
||||
case e_garageExterior:
|
||||
case e_hospitalExterior:
|
||||
case e_unk31:
|
||||
case e_hospitalExited:
|
||||
case e_policeExterior:
|
||||
case e_bike:
|
||||
case e_dunecar:
|
||||
@ -886,7 +886,7 @@ void LegoGameState::SwitchArea(Area p_area)
|
||||
case e_copter:
|
||||
case e_skateboard:
|
||||
case e_jetski:
|
||||
case e_unk66:
|
||||
case e_vehicleExited:
|
||||
LoadIsle();
|
||||
break;
|
||||
case e_elevbott:
|
||||
@ -948,7 +948,7 @@ void LegoGameState::SwitchArea(Area p_area)
|
||||
VideoManager()->Get3DManager()->SetFrustrum(90, 0.1f, 250.0f);
|
||||
InvokeAction(Extra::ActionType::e_start, *g_isleScript, IsleScript::c_GaraDoor, NULL);
|
||||
break;
|
||||
case e_unk28: {
|
||||
case e_garageExited: {
|
||||
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||
LoadIsle();
|
||||
|
||||
@ -973,7 +973,7 @@ void LegoGameState::SwitchArea(Area p_area)
|
||||
VideoManager()->SetUnk0x554(TRUE);
|
||||
InvokeAction(Extra::ActionType::e_opendisk, *g_hospitalScript, HospitalScript::c__StartUp, NULL);
|
||||
break;
|
||||
case e_unk33:
|
||||
case e_policeExited:
|
||||
LoadIsle();
|
||||
SetCameraControllerFromIsle();
|
||||
UserActor()->ResetWorldTransform(TRUE);
|
||||
|
||||
@ -31,10 +31,10 @@ const char* g_plantLodNames[4][5] = {
|
||||
};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f16b0
|
||||
float g_unk0x100f16b0[] = {0.1f, 0.7f, 0.5f, 0.9f};
|
||||
float g_heightPerCount[] = {0.1f, 0.7f, 0.5f, 0.9f};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f16c0
|
||||
MxU8 g_unk0x100f16c0[] = {1, 2, 2, 3};
|
||||
MxU8 g_counters[] = {1, 2, 2, 3};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f315c
|
||||
MxU32 LegoPlantManager::g_maxSound = 8;
|
||||
@ -217,7 +217,7 @@ LegoEntity* LegoPlantManager::CreatePlant(MxS32 p_index, LegoWorld* p_world, Leg
|
||||
if (p_index < sizeOfArray(g_plantInfo)) {
|
||||
MxU32 world = 1 << (MxU8) p_worldId;
|
||||
|
||||
if (g_plantInfo[p_index].m_worlds & world && g_plantInfo[p_index].m_unk0x16 != 0) {
|
||||
if (g_plantInfo[p_index].m_worlds & world && g_plantInfo[p_index].m_counter != 0) {
|
||||
if (g_plantInfo[p_index].m_entity == NULL) {
|
||||
char name[256];
|
||||
char lodName[256];
|
||||
@ -285,7 +285,7 @@ MxResult LegoPlantManager::Write(LegoStorage* p_storage)
|
||||
if (p_storage->Write(&info->m_color, sizeof(info->m_color)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&info->m_initialUnk0x16, sizeof(info->m_initialUnk0x16)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_initialCounter, sizeof(info->m_initialCounter)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -320,12 +320,12 @@ MxResult LegoPlantManager::Read(LegoStorage* p_storage)
|
||||
if (p_storage->Read(&info->m_color, sizeof(MxU8)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&info->m_unk0x16, sizeof(MxS8)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_counter, sizeof(MxS8)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
info->m_initialUnk0x16 = info->m_unk0x16;
|
||||
FUN_10026860(i);
|
||||
info->m_initialCounter = info->m_counter;
|
||||
AdjustHeight(i);
|
||||
}
|
||||
|
||||
result = SUCCESS;
|
||||
@ -336,13 +336,13 @@ MxResult LegoPlantManager::Read(LegoStorage* p_storage)
|
||||
|
||||
// FUNCTION: LEGO1 0x10026860
|
||||
// FUNCTION: BETA10 0x100c5be0
|
||||
void LegoPlantManager::FUN_10026860(MxS32 p_index)
|
||||
void LegoPlantManager::AdjustHeight(MxS32 p_index)
|
||||
{
|
||||
MxU8 variant = g_plantInfo[p_index].m_variant;
|
||||
|
||||
if (g_plantInfo[p_index].m_unk0x16 >= 0) {
|
||||
float value = g_unk0x100f16c0[variant] - g_plantInfo[p_index].m_unk0x16;
|
||||
g_plantInfo[p_index].m_position[1] = g_plantInfoInit[p_index].m_position[1] - value * g_unk0x100f16b0[variant];
|
||||
if (g_plantInfo[p_index].m_counter >= 0) {
|
||||
float value = g_counters[variant] - g_plantInfo[p_index].m_counter;
|
||||
g_plantInfo[p_index].m_position[1] = g_plantInfoInit[p_index].m_position[1] - value * g_heightPerCount[variant];
|
||||
}
|
||||
else {
|
||||
g_plantInfo[p_index].m_position[1] = g_plantInfoInit[p_index].m_position[1];
|
||||
@ -394,7 +394,7 @@ MxBool LegoPlantManager::SwitchColor(LegoEntity* p_entity)
|
||||
|
||||
ViewLODList* lodList = GetViewLODListManager()->Lookup(g_plantLodNames[info->m_variant][info->m_color]);
|
||||
|
||||
if (roi->GetUnknown0xe0() >= 0) {
|
||||
if (roi->GetLodLevel() >= 0) {
|
||||
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveROIDetailFromScene(roi);
|
||||
}
|
||||
|
||||
@ -410,7 +410,7 @@ MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity)
|
||||
{
|
||||
LegoPlantInfo* info = GetInfo(p_entity);
|
||||
|
||||
if (info == NULL || info->m_unk0x16 != -1) {
|
||||
if (info == NULL || info->m_counter != -1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -423,7 +423,7 @@ MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity)
|
||||
|
||||
ViewLODList* lodList = GetViewLODListManager()->Lookup(g_plantLodNames[info->m_variant][info->m_color]);
|
||||
|
||||
if (roi->GetUnknown0xe0() >= 0) {
|
||||
if (roi->GetLodLevel() >= 0) {
|
||||
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveROIDetailFromScene(roi);
|
||||
}
|
||||
|
||||
@ -550,7 +550,7 @@ void LegoPlantManager::SetCustomizeAnimFile(const char* p_value)
|
||||
|
||||
// FUNCTION: LEGO1 0x10026c50
|
||||
// FUNCTION: BETA10 0x100c6349
|
||||
MxBool LegoPlantManager::FUN_10026c50(LegoEntity* p_entity)
|
||||
MxBool LegoPlantManager::DecrementCounter(LegoEntity* p_entity)
|
||||
{
|
||||
LegoPlantInfo* info = GetInfo(p_entity);
|
||||
|
||||
@ -558,12 +558,12 @@ MxBool LegoPlantManager::FUN_10026c50(LegoEntity* p_entity)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FUN_10026c80(info - g_plantInfo);
|
||||
return DecrementCounter(info - g_plantInfo);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10026c80
|
||||
// FUNCTION: BETA10 0x100c63eb
|
||||
MxBool LegoPlantManager::FUN_10026c80(MxS32 p_index)
|
||||
MxBool LegoPlantManager::DecrementCounter(MxS32 p_index)
|
||||
{
|
||||
if (p_index >= sizeOfArray(g_plantInfo)) {
|
||||
return FALSE;
|
||||
@ -577,23 +577,23 @@ MxBool LegoPlantManager::FUN_10026c80(MxS32 p_index)
|
||||
|
||||
MxBool result = TRUE;
|
||||
|
||||
if (info->m_unk0x16 < 0) {
|
||||
info->m_unk0x16 = g_unk0x100f16c0[info->m_variant];
|
||||
if (info->m_counter < 0) {
|
||||
info->m_counter = g_counters[info->m_variant];
|
||||
}
|
||||
|
||||
if (info->m_unk0x16 > 0) {
|
||||
if (info->m_counter > 0) {
|
||||
LegoROI* roi = info->m_entity->GetROI();
|
||||
info->m_unk0x16--;
|
||||
info->m_counter--;
|
||||
|
||||
if (info->m_unk0x16 == 1) {
|
||||
info->m_unk0x16 = 0;
|
||||
if (info->m_counter == 1) {
|
||||
info->m_counter = 0;
|
||||
}
|
||||
|
||||
if (info->m_unk0x16 == 0) {
|
||||
if (info->m_counter == 0) {
|
||||
roi->SetVisibility(FALSE);
|
||||
}
|
||||
else {
|
||||
FUN_10026860(info - g_plantInfo);
|
||||
AdjustHeight(info - g_plantInfo);
|
||||
info->m_entity->SetLocation(info->m_position, info->m_direction, info->m_up, FALSE);
|
||||
}
|
||||
}
|
||||
@ -623,7 +623,7 @@ void LegoPlantManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_length)
|
||||
time += p_length;
|
||||
entry->m_time = time + 1000;
|
||||
|
||||
FUN_100271b0(p_entity, -1);
|
||||
AdjustCounter(p_entity, -1);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10026e00
|
||||
@ -672,11 +672,11 @@ MxResult LegoPlantManager::Tickle()
|
||||
if (entry->m_time < time) {
|
||||
LegoPlantInfo* info = GetInfo(entry->m_entity);
|
||||
|
||||
if (info->m_unk0x16 == 0) {
|
||||
if (info->m_counter == 0) {
|
||||
entry->m_roi->SetVisibility(FALSE);
|
||||
}
|
||||
else {
|
||||
FUN_10026860(info - g_plantInfo);
|
||||
AdjustHeight(info - g_plantInfo);
|
||||
info->m_entity->SetLocation(info->m_position, info->m_direction, info->m_up, FALSE);
|
||||
}
|
||||
|
||||
@ -699,14 +699,14 @@ MxResult LegoPlantManager::Tickle()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10027120
|
||||
void LegoPlantManager::FUN_10027120()
|
||||
void LegoPlantManager::ClearCounters()
|
||||
{
|
||||
LegoWorld* world = CurrentWorld();
|
||||
|
||||
for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
|
||||
g_plantInfo[i].m_unk0x16 = -1;
|
||||
g_plantInfo[i].m_initialUnk0x16 = -1;
|
||||
FUN_10026860(i);
|
||||
g_plantInfo[i].m_counter = -1;
|
||||
g_plantInfo[i].m_initialCounter = -1;
|
||||
AdjustHeight(i);
|
||||
|
||||
if (g_plantInfo[i].m_entity != NULL) {
|
||||
g_plantInfo[i].m_entity->SetLocation(
|
||||
@ -720,28 +720,28 @@ void LegoPlantManager::FUN_10027120()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100271b0
|
||||
void LegoPlantManager::FUN_100271b0(LegoEntity* p_entity, MxS32 p_adjust)
|
||||
void LegoPlantManager::AdjustCounter(LegoEntity* p_entity, MxS32 p_adjust)
|
||||
{
|
||||
LegoPlantInfo* info = GetInfo(p_entity);
|
||||
|
||||
if (info != NULL) {
|
||||
if (info->m_unk0x16 < 0) {
|
||||
info->m_unk0x16 = g_unk0x100f16c0[info->m_variant];
|
||||
if (info->m_counter < 0) {
|
||||
info->m_counter = g_counters[info->m_variant];
|
||||
}
|
||||
|
||||
if (info->m_unk0x16 > 0) {
|
||||
info->m_unk0x16 += p_adjust;
|
||||
if (info->m_unk0x16 <= 1 && p_adjust < 0) {
|
||||
info->m_unk0x16 = 0;
|
||||
if (info->m_counter > 0) {
|
||||
info->m_counter += p_adjust;
|
||||
if (info->m_counter <= 1 && p_adjust < 0) {
|
||||
info->m_counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10027200
|
||||
void LegoPlantManager::FUN_10027200()
|
||||
void LegoPlantManager::SetInitialCounters()
|
||||
{
|
||||
for (MxU32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
|
||||
g_plantInfo[i].m_initialUnk0x16 = g_plantInfo[i].m_unk0x16;
|
||||
g_plantInfo[i].m_initialCounter = g_plantInfo[i].m_counter;
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,10 +500,10 @@ MxLong LegoEntity::Notify(MxParam& p_param)
|
||||
case e_unk1:
|
||||
break;
|
||||
case e_plant:
|
||||
PlantManager()->FUN_10026c50(this);
|
||||
PlantManager()->DecrementCounter(this);
|
||||
break;
|
||||
case e_building:
|
||||
BuildingManager()->FUN_10030000(this);
|
||||
BuildingManager()->DecrementCounter(this);
|
||||
break;
|
||||
case e_autoROI:
|
||||
break;
|
||||
|
||||
@ -701,7 +701,7 @@ MxLong LegoNavController::Notify(MxParam& p_param)
|
||||
Mx3DPointFloat roiPosition(roi->GetWorldPosition());
|
||||
roiPosition -= viewPosition;
|
||||
|
||||
if (roiPosition.LenSquared() < 2000.0 || roi->GetUnknown0xe0() > 0) {
|
||||
if (roiPosition.LenSquared() < 2000.0 || roi->GetLodLevel() > 0) {
|
||||
entity->ClickAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
@ -559,27 +559,32 @@ MxResult LegoPathController::ReadEdges(LegoStorage* p_storage)
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numN);
|
||||
edge.m_pointA = &m_nodes[s];
|
||||
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numN);
|
||||
edge.m_pointB = &m_nodes[s];
|
||||
|
||||
if (edge.m_flags & LegoOrientedEdge::c_hasFaceA) {
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numL);
|
||||
edge.m_faceA = &m_boundaries[s];
|
||||
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numE);
|
||||
edge.m_ccwA = &m_edges[s];
|
||||
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numE);
|
||||
edge.m_cwA = &m_edges[s];
|
||||
}
|
||||
|
||||
@ -587,16 +592,19 @@ MxResult LegoPathController::ReadEdges(LegoStorage* p_storage)
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numL);
|
||||
edge.m_faceB = &m_boundaries[s];
|
||||
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numE);
|
||||
edge.m_ccwB = &m_edges[s];
|
||||
|
||||
if (p_storage->Read(&s, sizeof(MxU16)) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
assert(s < m_numE);
|
||||
edge.m_cwB = &m_edges[s];
|
||||
}
|
||||
|
||||
@ -617,6 +625,9 @@ MxResult LegoPathController::ReadEdges(LegoStorage* p_storage)
|
||||
MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage)
|
||||
{
|
||||
for (MxS32 i = 0; i < m_numL; i++) {
|
||||
#ifdef BETA10
|
||||
Mx4DPointFloat unused;
|
||||
#endif
|
||||
LegoPathBoundary& boundary = m_boundaries[i];
|
||||
MxU8 numE;
|
||||
MxU16 s;
|
||||
@ -626,6 +637,8 @@ MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
assert(numE > 2);
|
||||
|
||||
boundary.m_edgeNormals = new Mx4DPointFloat[numE];
|
||||
|
||||
LegoOrientedEdge** edges = new LegoOrientedEdge*[numE];
|
||||
@ -636,6 +649,8 @@ MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
assert(s < m_numE);
|
||||
|
||||
edges[j] = &m_edges[s];
|
||||
}
|
||||
|
||||
@ -693,6 +708,8 @@ MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
assert(s < m_numT);
|
||||
|
||||
boundary.m_pathTrigger[j].m_pathStruct = &m_structs[s];
|
||||
|
||||
if (p_storage->Read(&boundary.m_pathTrigger[j].m_data, sizeof(boundary.m_pathTrigger[j].m_data)) !=
|
||||
|
||||
@ -588,7 +588,7 @@ MxLong Act3::Notify(MxParam& p_param)
|
||||
m_unk0x421e = 0;
|
||||
|
||||
while (--length >= 0) {
|
||||
if (info[length].m_unk0x11 < 0 && info[length].m_boundary != NULL &&
|
||||
if (info[length].m_counter < 0 && info[length].m_boundary != NULL &&
|
||||
info[length].m_entity != NULL) {
|
||||
m_unk0x421e++;
|
||||
}
|
||||
@ -664,8 +664,8 @@ MxLong Act3::HandleTransitionEnd()
|
||||
// FUNCTION: LEGO1 0x10073270
|
||||
void Act3::ReadyWorld()
|
||||
{
|
||||
PlantManager()->FUN_10027200();
|
||||
BuildingManager()->FUN_10030800();
|
||||
PlantManager()->SetInitialCounters();
|
||||
BuildingManager()->SetInitialCounters();
|
||||
AnimationManager()->FUN_1005f6d0(FALSE);
|
||||
VideoManager()->Get3DManager()->SetFrustrum(90.0f, 0.1f, 125.0f);
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ DECOMP_SIZE_ASSERT(GasStation, 0x128)
|
||||
DECOMP_SIZE_ASSERT(GasStationState, 0x24)
|
||||
|
||||
// GLOBAL: LEGO1 0x100f0160
|
||||
undefined4 g_unk0x100f0160 = 3;
|
||||
MxS32 g_animationSkipCounterGasStation = 3;
|
||||
|
||||
// GLOBAL: LEGO1 0x100f0164
|
||||
MxBool g_trackLedEnabled = FALSE;
|
||||
@ -38,11 +38,11 @@ GasStation::GasStation()
|
||||
m_state = NULL;
|
||||
m_destLocation = LegoGameState::e_undefined;
|
||||
m_trackLedBitmap = NULL;
|
||||
m_unk0x104 = 0;
|
||||
m_unk0x114 = FALSE;
|
||||
m_unk0x106 = 0;
|
||||
m_unk0x10c = 0;
|
||||
m_unk0x115 = FALSE;
|
||||
m_waitingState = e_finished;
|
||||
m_waiting = FALSE;
|
||||
m_setWithCurrentAction = 0;
|
||||
m_lastIdleAnimation = 0;
|
||||
m_flashingLeds = FALSE;
|
||||
m_trackLedTimer = 0;
|
||||
|
||||
NotificationManager()->Register(this);
|
||||
@ -59,7 +59,7 @@ GasStation::~GasStation()
|
||||
ControlManager()->Unregister(this);
|
||||
TickleManager()->UnregisterClient(this);
|
||||
NotificationManager()->Unregister(this);
|
||||
g_unk0x100f0160 = 3;
|
||||
g_animationSkipCounterGasStation = 3;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10004990
|
||||
@ -77,13 +77,13 @@ MxResult GasStation::Create(MxDSAction& p_dsAction)
|
||||
m_state = (GasStationState*) GameState()->GetState("GasStationState");
|
||||
if (!m_state) {
|
||||
m_state = (GasStationState*) GameState()->CreateState("GasStationState");
|
||||
m_state->m_unk0x14 = 1;
|
||||
m_state->m_state = GasStationState::e_newState;
|
||||
}
|
||||
else if (m_state->m_unk0x14 == 4) {
|
||||
m_state->m_unk0x14 = 4;
|
||||
else if (m_state->m_state == GasStationState::e_unknown4) {
|
||||
m_state->m_state = GasStationState::e_unknown4;
|
||||
}
|
||||
else {
|
||||
m_state->m_unk0x14 = 3;
|
||||
m_state->m_state = GasStationState::e_unknown3;
|
||||
}
|
||||
|
||||
GameState()->m_currentArea = LegoGameState::e_garage;
|
||||
@ -139,25 +139,25 @@ void GasStation::ReadyWorld()
|
||||
case LegoActor::c_pepper:
|
||||
switch (m_state->m_pepperAction) {
|
||||
case 0:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs002nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
case 1:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs003nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
case 2:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs004nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
default:
|
||||
m_state->m_unk0x14 = 6;
|
||||
m_state->m_state = GasStationState::e_explainQuest;
|
||||
PlayAction(GarageScript::c_wgs008nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_unk0x104 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
m_waitingState = e_start;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -168,20 +168,20 @@ void GasStation::ReadyWorld()
|
||||
case LegoActor::c_mama:
|
||||
switch (m_state->m_mamaAction) {
|
||||
case 0:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs006nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
case 1:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs007nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
default:
|
||||
m_state->m_unk0x14 = 6;
|
||||
m_state->m_state = GasStationState::e_explainQuest;
|
||||
PlayAction(GarageScript::c_wgs008nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_unk0x104 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
m_waitingState = e_start;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -192,20 +192,20 @@ void GasStation::ReadyWorld()
|
||||
case LegoActor::c_nick:
|
||||
switch (m_state->m_nickAction) {
|
||||
case 0:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs009nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
case 1:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs010nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
default:
|
||||
m_state->m_unk0x14 = 6;
|
||||
m_state->m_state = GasStationState::e_explainQuest;
|
||||
PlayAction(GarageScript::c_wgs008nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_unk0x104 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
m_waitingState = e_start;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -216,20 +216,20 @@ void GasStation::ReadyWorld()
|
||||
case LegoActor::c_papa:
|
||||
switch (m_state->m_papaAction) {
|
||||
case 0:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs012nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
case 1:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs014nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
default:
|
||||
m_state->m_unk0x14 = 6;
|
||||
m_state->m_state = GasStationState::e_explainQuest;
|
||||
PlayAction(GarageScript::c_wgs017nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_unk0x104 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
m_waitingState = e_start;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -240,20 +240,20 @@ void GasStation::ReadyWorld()
|
||||
case LegoActor::c_laura:
|
||||
switch (m_state->m_lauraAction) {
|
||||
case 0:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs020nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
case 1:
|
||||
m_state->m_unk0x14 = 5;
|
||||
m_state->m_state = GasStationState::e_introduction;
|
||||
PlayAction(GarageScript::c_wgs021nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
break;
|
||||
default:
|
||||
m_state->m_unk0x14 = 6;
|
||||
m_state->m_state = GasStationState::e_explainQuest;
|
||||
PlayAction(GarageScript::c_wgs022nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_unk0x104 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
m_waitingState = e_start;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -301,35 +301,35 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
|
||||
if (action->GetAtomId() == m_atomId && action->GetObjectId()) {
|
||||
m_state->StopAction((GarageScript::Script) action->GetObjectId());
|
||||
m_unk0x106 = 0;
|
||||
m_setWithCurrentAction = 0;
|
||||
|
||||
switch (m_state->m_unk0x14) {
|
||||
case 5:
|
||||
g_unk0x100f0160 = 0;
|
||||
m_state->m_unk0x14 = 6;
|
||||
m_unk0x115 = TRUE;
|
||||
switch (m_state->m_state) {
|
||||
case GasStationState::e_introduction:
|
||||
g_animationSkipCounterGasStation = 0;
|
||||
m_state->m_state = GasStationState::e_explainQuest;
|
||||
m_flashingLeds = TRUE;
|
||||
PlayAction(GarageScript::c_wgs023nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_unk0x104 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
m_waitingState = e_start;
|
||||
break;
|
||||
case 6:
|
||||
g_unk0x100f0160 = 0;
|
||||
m_unk0x115 = TRUE;
|
||||
case GasStationState::e_explainQuest:
|
||||
g_animationSkipCounterGasStation = 0;
|
||||
m_flashingLeds = TRUE;
|
||||
|
||||
if (m_unk0x104 == 3) {
|
||||
m_state->m_unk0x14 = 8;
|
||||
if (m_waitingState == e_canceled) {
|
||||
m_state->m_state = GasStationState::e_afterAcceptingQuest;
|
||||
PlayAction(GarageScript::c_wgs029nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
}
|
||||
else {
|
||||
m_state->m_unk0x14 = 7;
|
||||
m_unk0x114 = TRUE;
|
||||
m_state->m_state = GasStationState::e_waitAcceptingQuest;
|
||||
m_waiting = TRUE;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
m_state->m_unk0x14 = 2;
|
||||
case GasStationState::e_afterAcceptingQuest:
|
||||
m_state->m_state = GasStationState::e_beforeExitingForQuest;
|
||||
((Act1State*) GameState()->GetState("Act1State"))->m_unk0x018 = 7;
|
||||
m_destLocation = LegoGameState::e_unk28;
|
||||
m_destLocation = LegoGameState::e_garageExited;
|
||||
m_radio.Stop();
|
||||
BackgroundAudioManager()->Stop();
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
@ -346,7 +346,7 @@ MxLong GasStation::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
// FUNCTION: LEGO1 0x10005920
|
||||
MxLong GasStation::HandleKeyPress(MxS8 p_key)
|
||||
{
|
||||
if (p_key == VK_SPACE && g_unk0x100f0160 == 0 && m_unk0x106 != 0) {
|
||||
if (p_key == VK_SPACE && g_animationSkipCounterGasStation == 0 && m_setWithCurrentAction != 0) {
|
||||
m_state->StopActions();
|
||||
return 1;
|
||||
}
|
||||
@ -358,18 +358,18 @@ MxLong GasStation::HandleKeyPress(MxS8 p_key)
|
||||
// FUNCTION: BETA10 0x10029319
|
||||
MxLong GasStation::HandleButtonDown(LegoControlManagerNotificationParam& p_param)
|
||||
{
|
||||
if (m_unk0x104 == 1 || m_unk0x104 == 2) {
|
||||
if (m_waitingState == e_start || m_waitingState == e_started) {
|
||||
LegoROI* roi = PickROI(p_param.GetX(), p_param.GetY());
|
||||
|
||||
if (roi != NULL) {
|
||||
if (!strnicmp(roi->GetName(), "capdb", 5) || !strnicmp(roi->GetName(), "*capdb", 6)) {
|
||||
m_unk0x104 = 3;
|
||||
m_unk0x114 = FALSE;
|
||||
m_waitingState = e_canceled;
|
||||
m_waiting = FALSE;
|
||||
|
||||
if (m_state->m_unk0x14 == 7) {
|
||||
m_state->m_unk0x14 = 8;
|
||||
if (m_state->m_state == GasStationState::e_waitAcceptingQuest) {
|
||||
m_state->m_state = GasStationState::e_afterAcceptingQuest;
|
||||
PlayAction(GarageScript::c_wgs029nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
}
|
||||
else {
|
||||
StopAction(GarageScript::c_wgs023nu_RunAnim);
|
||||
@ -393,7 +393,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case GarageScript::c_LeftArrow_Ctl:
|
||||
case GarageScript::c_RightArrow_Ctl:
|
||||
m_state->m_unk0x14 = 0;
|
||||
m_state->m_state = GasStationState::e_unknown0;
|
||||
m_destLocation = LegoGameState::Area::e_garadoor;
|
||||
|
||||
m_state->StopActions();
|
||||
@ -402,7 +402,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case GarageScript::c_Info_Ctl:
|
||||
m_state->m_unk0x14 = 0;
|
||||
m_state->m_state = GasStationState::e_unknown0;
|
||||
m_destLocation = LegoGameState::Area::e_infomain;
|
||||
|
||||
m_state->StopActions();
|
||||
@ -411,7 +411,7 @@ MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case GarageScript::c_Buggy_Ctl:
|
||||
m_state->m_unk0x14 = 0;
|
||||
m_state->m_state = GasStationState::e_unknown0;
|
||||
m_destLocation = LegoGameState::Area::e_dunecarbuild;
|
||||
|
||||
m_state->StopActions();
|
||||
@ -451,29 +451,29 @@ MxResult GasStation::Tickle()
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (g_unk0x100f0160 != 0) {
|
||||
g_unk0x100f0160--;
|
||||
if (g_animationSkipCounterGasStation != 0) {
|
||||
g_animationSkipCounterGasStation--;
|
||||
}
|
||||
|
||||
MxLong time = Timer()->GetTime();
|
||||
|
||||
if (m_unk0x114) {
|
||||
if (time - m_unk0x10c > 15000) {
|
||||
m_unk0x10c = time;
|
||||
if (m_unk0x104 == 1) {
|
||||
m_unk0x104 = 2;
|
||||
if (m_waiting) {
|
||||
if (time - m_lastIdleAnimation > 15000) {
|
||||
m_lastIdleAnimation = time;
|
||||
if (m_waitingState == e_start) {
|
||||
m_waitingState = e_started;
|
||||
}
|
||||
else if (m_unk0x104 != 0) {
|
||||
m_unk0x104 = 0;
|
||||
else if (m_waitingState != e_finished) {
|
||||
m_waitingState = e_finished;
|
||||
MxDSAction action;
|
||||
m_state->m_unk0x14 = 9;
|
||||
m_state->m_state = GasStationState::e_cancelQuest;
|
||||
PlayAction(GarageScript::c_wgs031nu_RunAnim);
|
||||
m_unk0x106 = 1;
|
||||
m_setWithCurrentAction = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_unk0x115) {
|
||||
if (m_flashingLeds) {
|
||||
if (time - m_trackLedTimer > 300) {
|
||||
m_trackLedTimer = time;
|
||||
g_trackLedEnabled = !g_trackLedEnabled;
|
||||
@ -489,7 +489,7 @@ MxBool GasStation::Escape()
|
||||
{
|
||||
m_radio.Stop();
|
||||
m_state->StopActions();
|
||||
m_state->m_unk0x14 = 0;
|
||||
m_state->m_state = GasStationState::e_unknown0;
|
||||
m_destLocation = LegoGameState::Area::e_infomain;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ DECOMP_SIZE_ASSERT(Hospital, 0x12c)
|
||||
DECOMP_SIZE_ASSERT(HospitalState, 0x18)
|
||||
|
||||
// GLOBAL: LEGO1 0x100f7918
|
||||
undefined4 g_animationSkipCounter = 3;
|
||||
undefined4 g_animationSkipCounterHospital = 3;
|
||||
|
||||
// GLOBAL: LEGO1 0x100f791c
|
||||
MxBool g_copLedEnabled = FALSE;
|
||||
@ -64,7 +64,7 @@ Hospital::~Hospital()
|
||||
m_hospitalState->m_state = HospitalState::e_unknown3;
|
||||
|
||||
NotificationManager()->Unregister(this);
|
||||
g_animationSkipCounter = 3;
|
||||
g_animationSkipCounterHospital = 3;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100748c0
|
||||
@ -222,7 +222,7 @@ MxLong Hospital::HandleKeyPress(MxS8 p_key)
|
||||
{
|
||||
MxLong result = 0;
|
||||
|
||||
if (p_key == VK_SPACE && g_animationSkipCounter == 0) {
|
||||
if (p_key == VK_SPACE && g_animationSkipCounterHospital == 0) {
|
||||
DeleteObjects(&m_atomId, HospitalScript::c_hho002cl_RunAnim, HospitalScript::c_hho006cl_RunAnim);
|
||||
result = 1;
|
||||
}
|
||||
@ -251,7 +251,7 @@ MxLong Hospital::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
m_currentAction = HospitalScript::c_hho006cl_RunAnim;
|
||||
m_setWithCurrentAction = 1;
|
||||
m_flashingLeds = 1;
|
||||
g_animationSkipCounter = 0;
|
||||
g_animationSkipCounterHospital = 0;
|
||||
break;
|
||||
case HospitalState::e_explainQuestShort:
|
||||
m_time = Timer()->GetTime();
|
||||
@ -369,7 +369,7 @@ MxLong Hospital::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
case HospitalState::e_exitToFront:
|
||||
if (m_unk0x128 == 0) {
|
||||
m_unk0x128 = 1;
|
||||
m_destLocation = LegoGameState::e_unk31;
|
||||
m_destLocation = LegoGameState::e_hospitalExited;
|
||||
|
||||
DeleteObjects(&m_atomId, HospitalScript::c_hho002cl_RunAnim, HospitalScript::c_hho006cl_RunAnim);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
@ -421,7 +421,7 @@ MxLong Hospital::HandleButtonDown(LegoControlManagerNotificationParam& p_param)
|
||||
|
||||
act1State->m_unk0x018 = 9;
|
||||
|
||||
m_destLocation = LegoGameState::e_unk31;
|
||||
m_destLocation = LegoGameState::e_hospitalExited;
|
||||
DeleteObjects(
|
||||
&m_atomId,
|
||||
HospitalScript::c_hho002cl_RunAnim,
|
||||
@ -590,7 +590,7 @@ MxBool Hospital::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
else if (m_unk0x128 == 0) {
|
||||
m_unk0x128 = 1;
|
||||
m_hospitalState->m_state = HospitalState::e_exitImmediately;
|
||||
m_destLocation = LegoGameState::e_unk31;
|
||||
m_destLocation = LegoGameState::e_hospitalExited;
|
||||
|
||||
DeleteObjects(&m_atomId, HospitalScript::c_hho002cl_RunAnim, HospitalScript::c_hho006cl_RunAnim);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
@ -637,8 +637,8 @@ MxResult Hospital::Tickle()
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (g_animationSkipCounter != 0) {
|
||||
g_animationSkipCounter -= 1;
|
||||
if (g_animationSkipCounterHospital != 0) {
|
||||
g_animationSkipCounterHospital -= 1;
|
||||
}
|
||||
|
||||
MxLong time = Timer()->GetTime();
|
||||
|
||||
@ -1385,8 +1385,8 @@ void Infocenter::Reset()
|
||||
break;
|
||||
}
|
||||
|
||||
PlantManager()->FUN_10027120();
|
||||
BuildingManager()->FUN_10030590();
|
||||
PlantManager()->ClearCounters();
|
||||
BuildingManager()->ClearCounters();
|
||||
AnimationManager()->Reset(FALSE);
|
||||
CharacterManager()->ReleaseAllActors();
|
||||
GameState()->SetCurrentAct(LegoGameState::e_act1);
|
||||
|
||||
@ -119,7 +119,7 @@ MxLong InfocenterDoor::HandleControl(LegoControlManagerNotificationParam& p_para
|
||||
if (GameState()->GetActorId() != LegoActor::c_none) {
|
||||
InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState");
|
||||
if (state->HasRegistered()) {
|
||||
m_destLocation = LegoGameState::e_unk4;
|
||||
m_destLocation = LegoGameState::e_infocenterExited;
|
||||
}
|
||||
else {
|
||||
MxDSAction action;
|
||||
|
||||
@ -430,7 +430,7 @@ MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case IsleScript::c_PoliDoor_Door_Ctl:
|
||||
m_destLocation = LegoGameState::e_unk33;
|
||||
m_destLocation = LegoGameState::e_policeExited;
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case IsleScript::c_GaraDoor_LeftArrow_Ctl:
|
||||
@ -440,7 +440,7 @@ MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case IsleScript::c_GaraDoor_Door_Ctl:
|
||||
m_destLocation = LegoGameState::e_unk28;
|
||||
m_destLocation = LegoGameState::e_garageExited;
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
}
|
||||
@ -712,7 +712,7 @@ void Isle::Enable(MxBool p_enable)
|
||||
if (GameState()->m_currentArea == LegoGameState::e_pizzeriaExterior) {
|
||||
AnimationManager()->FUN_10064740(NULL);
|
||||
}
|
||||
else if (GameState()->m_currentArea == LegoGameState::e_unk66) {
|
||||
else if (GameState()->m_currentArea == LegoGameState::e_vehicleExited) {
|
||||
Mx3DPointFloat position(UserActor()->GetROI()->GetWorldPosition());
|
||||
|
||||
Mx3DPointFloat sub(-21.375f, 0.0f, -41.75f);
|
||||
@ -820,7 +820,7 @@ void Isle::Enable(MxBool p_enable)
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
EnableAnimations(TRUE);
|
||||
m_jukebox->StartAction();
|
||||
break;
|
||||
@ -863,21 +863,21 @@ void Isle::FUN_10032620()
|
||||
VideoManager()->Get3DManager()->SetFrustrum(90.0, 0.1, 250.0);
|
||||
|
||||
switch (GameState()->m_currentArea) {
|
||||
case LegoGameState::e_unk66: {
|
||||
case LegoGameState::e_vehicleExited: {
|
||||
MxMatrix mat(UserActor()->GetROI()->GetLocal2World());
|
||||
LegoPathBoundary* boundary = UserActor()->GetBoundary();
|
||||
((IslePathActor*) UserActor())->VTable0xec(mat, boundary, TRUE);
|
||||
break;
|
||||
}
|
||||
case LegoGameState::e_unk4:
|
||||
case LegoGameState::e_infocenterExited:
|
||||
case LegoGameState::e_jetraceExterior:
|
||||
case LegoGameState::e_unk17:
|
||||
case LegoGameState::e_jetskibuildExited:
|
||||
case LegoGameState::e_carraceExterior:
|
||||
case LegoGameState::e_unk20:
|
||||
case LegoGameState::e_racecarbuildExited:
|
||||
case LegoGameState::e_pizzeriaExterior:
|
||||
case LegoGameState::e_garageExterior:
|
||||
case LegoGameState::e_hospitalExterior:
|
||||
case LegoGameState::e_unk31:
|
||||
case LegoGameState::e_hospitalExited:
|
||||
case LegoGameState::e_policeExterior:
|
||||
((IslePathActor*) UserActor())
|
||||
->SpawnPlayer(
|
||||
@ -885,7 +885,7 @@ void Isle::FUN_10032620()
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
GameState()->m_currentArea = LegoGameState::e_unk66;
|
||||
GameState()->m_currentArea = LegoGameState::e_vehicleExited;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -955,7 +955,7 @@ MxLong Isle::HandleTransitionEnd()
|
||||
VariableTable()->SetVariable("VISIBILITY", "Hide Gas");
|
||||
FUN_10032d30(IsleScript::c_GaraDoor_Background_Bitmap, JukeboxScript::c_JBMusic2, "LCAMZG1,90", FALSE);
|
||||
break;
|
||||
case LegoGameState::e_unk28:
|
||||
case LegoGameState::e_garageExited:
|
||||
GameState()->SwitchArea(m_destLocation);
|
||||
GameState()->StopArea(LegoGameState::e_previousArea);
|
||||
m_destLocation = LegoGameState::e_undefined;
|
||||
@ -965,7 +965,7 @@ MxLong Isle::HandleTransitionEnd()
|
||||
SetAppCursor(e_cursorArrow);
|
||||
SetIsWorldActive(TRUE);
|
||||
break;
|
||||
case LegoGameState::e_unk33:
|
||||
case LegoGameState::e_policeExited:
|
||||
GameState()->SwitchArea(m_destLocation);
|
||||
GameState()->StopArea(LegoGameState::e_previousArea);
|
||||
m_destLocation = LegoGameState::e_undefined;
|
||||
|
||||
@ -25,6 +25,7 @@ class LegoWEEdge {
|
||||
// FUNCTION: BETA10 0x100373f0
|
||||
LegoU32 IsEqual(LegoWEEdge* p_other) { return this == p_other; }
|
||||
|
||||
// FUNCTION: BETA10 0x100bd410
|
||||
void SetEdges(LegoOrientedEdge** p_edges, LegoU8 p_numEdges)
|
||||
{
|
||||
m_edges = p_edges;
|
||||
|
||||
@ -16,7 +16,7 @@ DECOMP_SIZE_ASSERT(LegoLOD::Mesh, 0x08)
|
||||
LPDIRECT3DRMMATERIAL g_unk0x101013d4 = NULL;
|
||||
|
||||
// GLOBAL: LEGO1 0x101013dc
|
||||
const char* g_unk0x101013dc = "inh";
|
||||
const char* g_InhPrefix = "inh";
|
||||
|
||||
inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer);
|
||||
inline BOOL GetMeshData(IDirect3DRMMesh*& mesh, D3DRMGROUPINDEX& index, Tgl::Mesh* pMesh);
|
||||
@ -66,7 +66,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
|
||||
LegoU32(*textureIndices)[3] = NULL;
|
||||
LegoTextureInfo* textureInfo = NULL;
|
||||
|
||||
LegoU32 i, meshUnd1, meshUnd2, tempNumVertsAndNormals;
|
||||
LegoU32 i, indexBackwards, indexForwards, tempNumVertsAndNormals;
|
||||
unsigned char paletteEntries[256];
|
||||
|
||||
if (p_storage->Read(&m_unk0x08, sizeof(undefined4)) != SUCCESS) {
|
||||
@ -93,8 +93,8 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
|
||||
m_melems = new Mesh[m_numMeshes];
|
||||
memset(m_melems, 0, sizeof(*m_melems) * m_numMeshes);
|
||||
|
||||
meshUnd1 = m_numMeshes - 1;
|
||||
meshUnd2 = 0;
|
||||
indexBackwards = m_numMeshes - 1;
|
||||
indexForwards = 0;
|
||||
|
||||
if (p_storage->Read(&tempNumVertsAndNormals, sizeof(LegoU32)) != SUCCESS) {
|
||||
goto done;
|
||||
@ -184,13 +184,13 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
|
||||
textureName = mesh->GetTextureName();
|
||||
materialName = mesh->GetMaterialName();
|
||||
|
||||
if (FUN_100aae20(textureName) || FUN_100aae20(materialName)) {
|
||||
meshIndex = meshUnd1;
|
||||
meshUnd1--;
|
||||
if (HasInhPrefix(textureName) || HasInhPrefix(materialName)) {
|
||||
meshIndex = indexBackwards;
|
||||
indexBackwards--;
|
||||
}
|
||||
else {
|
||||
meshIndex = meshUnd2;
|
||||
meshUnd2++;
|
||||
meshIndex = indexForwards;
|
||||
indexForwards++;
|
||||
}
|
||||
|
||||
m_melems[meshIndex].m_tglMesh = m_meshBuilder->CreateMesh(
|
||||
@ -211,7 +211,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
|
||||
m_melems[meshIndex].m_tglMesh->SetShadingModel(shadingModel);
|
||||
|
||||
if (textureName != NULL) {
|
||||
if (mesh->GetUnknown0x21()) {
|
||||
if (mesh->GetUseAlias()) {
|
||||
LegoROI::GetPaletteEntries(textureName, paletteEntries, sizeOfArray(paletteEntries));
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
|
||||
LegoFloat blue = 1.0F;
|
||||
LegoFloat alpha = 0.0F;
|
||||
|
||||
if (mesh->GetUnknown0x21()) {
|
||||
if (mesh->GetUseAlias()) {
|
||||
LegoROI::GetRGBAColor(materialName, red, green, blue, alpha);
|
||||
}
|
||||
else {
|
||||
@ -265,7 +265,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
|
||||
}
|
||||
}
|
||||
|
||||
m_meshOffset = meshUnd2;
|
||||
m_meshOffset = indexForwards;
|
||||
|
||||
if (textureVertices != NULL) {
|
||||
delete[] textureVertices;
|
||||
@ -377,10 +377,10 @@ LegoResult LegoLOD::GetTextureInfo(LegoTextureInfo*& p_textureInfo)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100aae20
|
||||
LegoBool LegoLOD::FUN_100aae20(const LegoChar* p_name)
|
||||
LegoBool LegoLOD::HasInhPrefix(const LegoChar* p_name)
|
||||
{
|
||||
if (p_name != NULL) {
|
||||
if (!strnicmp(p_name, g_unk0x101013dc, strlen(g_unk0x101013dc))) {
|
||||
if (!strnicmp(p_name, g_InhPrefix, strlen(g_InhPrefix))) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ class LegoLOD : public ViewLOD {
|
||||
void ClearMeshOffset();
|
||||
LegoResult GetTextureInfo(LegoTextureInfo*& p_textureInfo);
|
||||
|
||||
static LegoBool FUN_100aae20(const LegoChar* p_name);
|
||||
static LegoBool HasInhPrefix(const LegoChar* p_name);
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100aa430
|
||||
// LegoLOD::`scalar deleting destructor'
|
||||
|
||||
@ -15,7 +15,7 @@ LegoMesh::LegoMesh()
|
||||
m_unk0x0d = 0;
|
||||
m_unk0x10 = NULL;
|
||||
m_unk0x20 = 0;
|
||||
m_unk0x21 = FALSE;
|
||||
m_useAlias = FALSE;
|
||||
m_materialName = NULL;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ LegoResult LegoMesh::Read(LegoStorage* p_storage)
|
||||
if ((result = p_storage->Read(&m_unk0x20, sizeof(undefined))) != SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
if ((result = p_storage->Read(&m_unk0x21, sizeof(LegoU8))) != SUCCESS) {
|
||||
if ((result = p_storage->Read(&m_useAlias, sizeof(LegoU8))) != SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ class LegoMesh {
|
||||
LegoU8 GetUnknown0x0d() { return m_unk0x0d; }
|
||||
const LegoChar* GetTextureName() { return m_textureName; }
|
||||
const LegoChar* GetMaterialName() { return m_materialName; }
|
||||
LegoBool GetUnknown0x21() { return m_unk0x21; }
|
||||
LegoBool GetUseAlias() { return m_useAlias; }
|
||||
LegoResult Read(LegoStorage* p_storage);
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100d3840
|
||||
@ -72,7 +72,7 @@ class LegoMesh {
|
||||
LegoChar* m_textureName; // 0x18
|
||||
LegoChar* m_materialName; // 0x1c
|
||||
undefined m_unk0x20; // 0x20 - unused
|
||||
LegoBool m_unk0x21; // 0x21
|
||||
LegoBool m_useAlias; // 0x21
|
||||
};
|
||||
|
||||
#endif // __LEGOMESH_H
|
||||
|
||||
@ -25,7 +25,7 @@ float g_minLODThreshold = 0.00097656297;
|
||||
int g_maxLODLevels = 6;
|
||||
|
||||
// GLOBAL: LEGO1 0x1010105c
|
||||
float g_unk0x1010105c = 0.000125F;
|
||||
float g_viewDistance = 0.000125F;
|
||||
|
||||
// GLOBAL: LEGO1 0x10101060
|
||||
float g_elapsedSeconds = 0;
|
||||
@ -65,19 +65,19 @@ unsigned int ViewManager::IsBoundingBoxInFrustum(const BoundingBox& p_bounding_b
|
||||
{
|
||||
const Vector3* box[] = {&p_bounding_box.Min(), &p_bounding_box.Max()};
|
||||
|
||||
float und[8][3];
|
||||
float box_corners[8][3];
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
und[i][j] = box[g_boundingBoxCornerMap[i][j]]->operator[](j);
|
||||
box_corners[i][j] = box[g_boundingBoxCornerMap[i][j]]->operator[](j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
for (k = 0; k < 8; k++) {
|
||||
if (frustum_planes[i][0] * und[k][0] + frustum_planes[i][2] * und[k][2] + frustum_planes[i][1] * und[k][1] +
|
||||
frustum_planes[i][3] >=
|
||||
if (frustum_planes[i][0] * box_corners[k][0] + frustum_planes[i][2] * box_corners[k][2] +
|
||||
frustum_planes[i][1] * box_corners[k][1] + frustum_planes[i][3] >=
|
||||
0.0f) {
|
||||
break;
|
||||
}
|
||||
@ -98,7 +98,7 @@ void ViewManager::Remove(ViewROI* p_roi)
|
||||
if (*it == p_roi) {
|
||||
rois.erase(it);
|
||||
|
||||
if (p_roi->GetUnknown0xe0() >= 0) {
|
||||
if (p_roi->GetLodLevel() >= 0) {
|
||||
RemoveROIDetailFromScene(p_roi);
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ void ViewManager::Remove(ViewROI* p_roi)
|
||||
|
||||
if (comp != NULL) {
|
||||
for (CompoundObject::const_iterator it = comp->begin(); !(it == comp->end()); it++) {
|
||||
if (((ViewROI*) *it)->GetUnknown0xe0() >= 0) {
|
||||
if (((ViewROI*) *it)->GetLodLevel() >= 0) {
|
||||
RemoveROIDetailFromScene((ViewROI*) *it);
|
||||
}
|
||||
}
|
||||
@ -128,11 +128,11 @@ void ViewManager::RemoveAll(ViewROI* p_roi)
|
||||
rois.erase(rois.begin(), rois.end());
|
||||
}
|
||||
else {
|
||||
if (p_roi->GetUnknown0xe0() >= 0) {
|
||||
if (p_roi->GetLodLevel() >= 0) {
|
||||
RemoveROIDetailFromScene(p_roi);
|
||||
}
|
||||
|
||||
p_roi->SetUnknown0xe0(-1);
|
||||
p_roi->SetLodLevel(ViewROI::c_lodLevelUnset);
|
||||
const CompoundObject* comp = p_roi->GetComp();
|
||||
|
||||
if (comp != NULL) {
|
||||
@ -146,15 +146,15 @@ void ViewManager::RemoveAll(ViewROI* p_roi)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100a65b0
|
||||
void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_und)
|
||||
void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_lodLevel)
|
||||
{
|
||||
if (p_roi->GetLODCount() <= p_und) {
|
||||
p_und = p_roi->GetLODCount() - 1;
|
||||
if (p_roi->GetLODCount() <= p_lodLevel) {
|
||||
p_lodLevel = p_roi->GetLODCount() - 1;
|
||||
}
|
||||
|
||||
int unk0xe0 = p_roi->GetUnknown0xe0();
|
||||
int lodLevel = p_roi->GetLodLevel();
|
||||
|
||||
if (unk0xe0 == p_und) {
|
||||
if (lodLevel == p_lodLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -162,8 +162,8 @@ void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_und)
|
||||
Tgl::MeshBuilder* meshBuilder;
|
||||
ViewLOD* lod;
|
||||
|
||||
if (unk0xe0 < 0) {
|
||||
lod = (ViewLOD*) p_roi->GetLOD(p_und);
|
||||
if (lodLevel < 0) {
|
||||
lod = (ViewLOD*) p_roi->GetLOD(p_lodLevel);
|
||||
|
||||
if (lod->GetUnknown0x08() & ViewLOD::c_bit4) {
|
||||
scene->Add((Tgl::MeshBuilder*) group);
|
||||
@ -171,7 +171,7 @@ void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_und)
|
||||
}
|
||||
}
|
||||
else {
|
||||
lod = (ViewLOD*) p_roi->GetLOD(unk0xe0);
|
||||
lod = (ViewLOD*) p_roi->GetLOD(lodLevel);
|
||||
|
||||
if (lod != NULL) {
|
||||
meshBuilder = lod->GetMeshBuilder();
|
||||
@ -181,7 +181,7 @@ void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_und)
|
||||
}
|
||||
}
|
||||
|
||||
lod = (ViewLOD*) p_roi->GetLOD(p_und);
|
||||
lod = (ViewLOD*) p_roi->GetLOD(p_lodLevel);
|
||||
}
|
||||
|
||||
if (lod->GetUnknown0x08() & ViewLOD::c_bit4) {
|
||||
@ -190,18 +190,18 @@ void ViewManager::UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_und)
|
||||
if (meshBuilder != NULL) {
|
||||
group->Add(meshBuilder);
|
||||
SetAppData(p_roi, reinterpret_cast<LPD3DRM_APPDATA>(p_roi));
|
||||
p_roi->SetUnknown0xe0(p_und);
|
||||
p_roi->SetLodLevel(p_lodLevel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
p_roi->SetUnknown0xe0(-1);
|
||||
p_roi->SetLodLevel(ViewROI::c_lodLevelUnset);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100a66a0
|
||||
void ViewManager::RemoveROIDetailFromScene(ViewROI* p_roi)
|
||||
{
|
||||
const ViewLOD* lod = (const ViewLOD*) p_roi->GetLOD(p_roi->GetUnknown0xe0());
|
||||
const ViewLOD* lod = (const ViewLOD*) p_roi->GetLOD(p_roi->GetLodLevel());
|
||||
|
||||
if (lod != NULL) {
|
||||
const Tgl::MeshBuilder* meshBuilder = NULL;
|
||||
@ -216,58 +216,61 @@ void ViewManager::RemoveROIDetailFromScene(ViewROI* p_roi)
|
||||
scene->Remove(roiGeometry);
|
||||
}
|
||||
|
||||
p_roi->SetUnknown0xe0(-1);
|
||||
p_roi->SetLodLevel(ViewROI::c_lodLevelUnset);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100a66f0
|
||||
inline void ViewManager::ManageVisibilityAndDetailRecursively(ViewROI* p_roi, int p_und)
|
||||
// FUNCTION: BETA10 0x1017297f
|
||||
inline void ViewManager::ManageVisibilityAndDetailRecursively(ViewROI* p_from, int p_lodLevel)
|
||||
{
|
||||
if (!p_roi->GetVisibility() && p_und != -2) {
|
||||
ManageVisibilityAndDetailRecursively(p_roi, -2);
|
||||
assert(p_from);
|
||||
|
||||
if (!p_from->GetVisibility() && p_lodLevel != ViewROI::c_lodLevelInvisible) {
|
||||
ManageVisibilityAndDetailRecursively(p_from, ViewROI::c_lodLevelInvisible);
|
||||
}
|
||||
else {
|
||||
const CompoundObject* comp = p_roi->GetComp();
|
||||
const CompoundObject* comp = p_from->GetComp();
|
||||
|
||||
if (p_und == -1) {
|
||||
if (p_roi->GetWorldBoundingSphere().Radius() > 0.001F) {
|
||||
float und = ProjectedSize(p_roi->GetWorldBoundingSphere());
|
||||
if (p_lodLevel == ViewROI::c_lodLevelUnset) {
|
||||
if (p_from->GetWorldBoundingSphere().Radius() > 0.001F) {
|
||||
float projectedSize = ProjectedSize(p_from->GetWorldBoundingSphere());
|
||||
|
||||
if (und < seconds_allowed * g_unk0x1010105c) {
|
||||
if (p_roi->GetUnknown0xe0() == -2) {
|
||||
return;
|
||||
if (projectedSize < seconds_allowed * g_viewDistance) {
|
||||
if (p_from->GetLodLevel() != ViewROI::c_lodLevelInvisible) {
|
||||
ManageVisibilityAndDetailRecursively(p_from, ViewROI::c_lodLevelInvisible);
|
||||
}
|
||||
|
||||
ManageVisibilityAndDetailRecursively(p_roi, -2);
|
||||
return;
|
||||
}
|
||||
|
||||
p_und = CalculateLODLevel(und, RealtimeView::GetUserMaxLodPower() * seconds_allowed, p_roi);
|
||||
else {
|
||||
p_lodLevel =
|
||||
CalculateLODLevel(projectedSize, RealtimeView::GetUserMaxLodPower() * seconds_allowed, p_from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_und == -2) {
|
||||
if (p_roi->GetUnknown0xe0() >= 0) {
|
||||
RemoveROIDetailFromScene(p_roi);
|
||||
p_roi->SetUnknown0xe0(-2);
|
||||
if (p_lodLevel == ViewROI::c_lodLevelInvisible) {
|
||||
if (p_from->GetLodLevel() >= 0) {
|
||||
RemoveROIDetailFromScene(p_from);
|
||||
p_from->SetLodLevel(ViewROI::c_lodLevelInvisible);
|
||||
}
|
||||
|
||||
if (comp != NULL) {
|
||||
for (CompoundObject::const_iterator it = comp->begin(); !(it == comp->end()); it++) {
|
||||
ManageVisibilityAndDetailRecursively((ViewROI*) *it, p_und);
|
||||
for (CompoundObject::const_iterator it = comp->begin(); it != comp->end(); it++) {
|
||||
ManageVisibilityAndDetailRecursively((ViewROI*) *it, p_lodLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (comp == NULL) {
|
||||
if (p_roi->GetLODs() != NULL && p_roi->GetLODCount() > 0) {
|
||||
UpdateROIDetailBasedOnLOD(p_roi, p_und);
|
||||
return;
|
||||
if (p_from->GetLODs() != NULL && p_from->GetLODCount() > 0) {
|
||||
UpdateROIDetailBasedOnLOD(p_from, p_lodLevel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
p_roi->SetUnknown0xe0(-1);
|
||||
p_from->SetLodLevel(ViewROI::c_lodLevelUnset);
|
||||
|
||||
for (CompoundObject::const_iterator it = comp->begin(); !(it == comp->end()); it++) {
|
||||
ManageVisibilityAndDetailRecursively((ViewROI*) *it, p_und);
|
||||
for (CompoundObject::const_iterator it = comp->begin(); it != comp->end(); it++) {
|
||||
ManageVisibilityAndDetailRecursively((ViewROI*) *it, p_lodLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -290,7 +293,7 @@ void ViewManager::Update(float p_previousRenderTime, float)
|
||||
}
|
||||
|
||||
for (CompoundObject::iterator it = rois.begin(); it != rois.end(); it++) {
|
||||
ManageVisibilityAndDetailRecursively((ViewROI*) *it, -1);
|
||||
ManageVisibilityAndDetailRecursively((ViewROI*) *it, ViewROI::c_lodLevelUnset);
|
||||
}
|
||||
|
||||
stopWatch.Stop();
|
||||
@ -306,7 +309,7 @@ inline int ViewManager::CalculateFrustumTransformations()
|
||||
}
|
||||
else {
|
||||
float fVar7 = tan(view_angle / 2.0F);
|
||||
view_area_at_one = view_angle * view_angle * 4.0F;
|
||||
view_area_at_one = fVar7 * fVar7 * 4.0F;
|
||||
|
||||
float fVar1 = front * fVar7;
|
||||
float fVar2 = (width / height) * fVar1;
|
||||
@ -350,30 +353,38 @@ inline int ViewManager::CalculateFrustumTransformations()
|
||||
}
|
||||
}
|
||||
|
||||
inline int ViewManager::CalculateLODLevel(float p_und1, float p_und2, ViewROI* p_roi)
|
||||
// FUNCTION: BETA10 0x10172be5
|
||||
inline int ViewManager::CalculateLODLevel(float p_maximumScale, float p_initialScale, ViewROI* from)
|
||||
{
|
||||
int result;
|
||||
float i;
|
||||
int lodLevel;
|
||||
|
||||
if (IsROIVisibleAtLOD(p_roi) != 0) {
|
||||
if (p_und1 < g_minLODThreshold) {
|
||||
assert(from);
|
||||
|
||||
if (GetFirstLODIndex(from) != 0) {
|
||||
if (p_maximumScale < g_minLODThreshold) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = 1;
|
||||
else {
|
||||
lodLevel = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = 0;
|
||||
lodLevel = 0;
|
||||
}
|
||||
|
||||
for (i = p_und2; result < g_maxLODLevels && p_und1 >= i; i *= g_LODScaleFactor) {
|
||||
result++;
|
||||
for (float i = p_initialScale; lodLevel < g_maxLODLevels; lodLevel++) {
|
||||
if (i >= p_maximumScale) {
|
||||
break;
|
||||
}
|
||||
|
||||
i *= g_LODScaleFactor;
|
||||
}
|
||||
|
||||
return result;
|
||||
return lodLevel;
|
||||
}
|
||||
|
||||
inline int ViewManager::IsROIVisibleAtLOD(ViewROI* p_roi)
|
||||
// FUNCTION: BETA10 0x10172cb0
|
||||
inline int ViewManager::GetFirstLODIndex(ViewROI* p_roi)
|
||||
{
|
||||
const LODListBase* lods = p_roi->GetLODs();
|
||||
|
||||
@ -381,22 +392,24 @@ inline int ViewManager::IsROIVisibleAtLOD(ViewROI* p_roi)
|
||||
if (((ViewLOD*) p_roi->GetLOD(0))->GetUnknown0x08Test8()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const CompoundObject* comp = p_roi->GetComp();
|
||||
|
||||
if (comp != NULL) {
|
||||
for (CompoundObject::const_iterator it = comp->begin(); !(it == comp->end()); it++) {
|
||||
for (CompoundObject::const_iterator it = comp->begin(); it != comp->end(); it++) {
|
||||
const LODListBase* lods = ((ViewROI*) *it)->GetLODs();
|
||||
|
||||
if (lods != NULL && lods->Size() > 0) {
|
||||
if (((ViewLOD*) ((ViewROI*) *it)->GetLOD(0))->GetUnknown0x08Test8()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -480,7 +493,7 @@ float ViewManager::ProjectedSize(const BoundingSphere& p_bounding_sphere)
|
||||
// is then the ratio of the area of that projected circle to the view surface area
|
||||
// at Z == 1.0.
|
||||
//
|
||||
float sphere_projected_area = 3.14159265359 * (p_bounding_sphere.Radius() * p_bounding_sphere.Radius());
|
||||
float sphere_projected_area = 3.14159265359 * p_bounding_sphere.Radius() * p_bounding_sphere.Radius();
|
||||
float square_dist_to_sphere = DISTSQRD3(p_bounding_sphere.Center(), pov[3]);
|
||||
return sphere_projected_area / view_area_at_one / square_dist_to_sphere;
|
||||
}
|
||||
|
||||
@ -24,20 +24,20 @@ class ViewManager {
|
||||
void Remove(ViewROI* p_roi);
|
||||
void RemoveAll(ViewROI* p_roi);
|
||||
unsigned int IsBoundingBoxInFrustum(const BoundingBox& p_bounding_box);
|
||||
void UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_und);
|
||||
void UpdateROIDetailBasedOnLOD(ViewROI* p_roi, int p_lodLevel);
|
||||
void RemoveROIDetailFromScene(ViewROI* p_roi);
|
||||
void SetPOVSource(const OrientableROI* point_of_view);
|
||||
float ProjectedSize(const BoundingSphere& p_bounding_sphere);
|
||||
ViewROI* Pick(Tgl::View* p_view, unsigned long x, unsigned long y);
|
||||
void SetResolution(int width, int height);
|
||||
void SetFrustrum(float fov, float front, float back);
|
||||
inline void ManageVisibilityAndDetailRecursively(ViewROI* p_roi, int p_und);
|
||||
inline void ManageVisibilityAndDetailRecursively(ViewROI* p_from, int p_lodLevel);
|
||||
void Update(float p_previousRenderTime, float);
|
||||
inline int CalculateFrustumTransformations();
|
||||
void UpdateViewTransformations();
|
||||
|
||||
inline static int CalculateLODLevel(float p_und1, float p_und2, ViewROI* p_roi);
|
||||
inline static int IsROIVisibleAtLOD(ViewROI* p_roi);
|
||||
inline static int CalculateLODLevel(float p_maximumScale, float p_initalScale, ViewROI* from);
|
||||
inline static int GetFirstLODIndex(ViewROI* p_roi);
|
||||
|
||||
// FUNCTION: BETA10 0x100576b0
|
||||
const CompoundObject& GetROIs() { return rois; }
|
||||
|
||||
@ -16,11 +16,16 @@
|
||||
// SIZE 0xe4
|
||||
class ViewROI : public OrientableROI {
|
||||
public:
|
||||
enum {
|
||||
c_lodLevelUnset = -1,
|
||||
c_lodLevelInvisible = -2,
|
||||
};
|
||||
|
||||
ViewROI(Tgl::Renderer* pRenderer, ViewLODList* lodList)
|
||||
{
|
||||
SetLODList(lodList);
|
||||
geometry = pRenderer->CreateGroup();
|
||||
m_unk0xe0 = -1;
|
||||
m_lodLevel = c_lodLevelUnset;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100a9e20
|
||||
@ -56,8 +61,8 @@ class ViewROI : public OrientableROI {
|
||||
virtual Tgl::Group* GetGeometry(); // vtable+0x30
|
||||
virtual const Tgl::Group* GetGeometry() const; // vtable+0x34
|
||||
|
||||
int GetUnknown0xe0() { return m_unk0xe0; }
|
||||
void SetUnknown0xe0(int p_unk0xe0) { m_unk0xe0 = p_unk0xe0; }
|
||||
int GetLodLevel() { return m_lodLevel; }
|
||||
void SetLodLevel(int p_lodLevel) { m_lodLevel = p_lodLevel; }
|
||||
|
||||
static unsigned char SetLightSupport(unsigned char p_lightSupport);
|
||||
|
||||
@ -65,7 +70,7 @@ class ViewROI : public OrientableROI {
|
||||
void UpdateWorldDataWithTransformAndChildren(const Matrix4& parent2world) override; // vtable+0x28
|
||||
|
||||
Tgl::Group* geometry; // 0xdc
|
||||
int m_unk0xe0; // 0xe0
|
||||
int m_lodLevel; // 0xe0
|
||||
};
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100aa250
|
||||
|
||||
@ -38,3 +38,8 @@ targets:
|
||||
- 0x100fb080
|
||||
# memset etc.
|
||||
- 0x100f9570
|
||||
ALPHA:
|
||||
filename: ALPHA.DLL
|
||||
source-root: LEGO1
|
||||
hash:
|
||||
sha256: dc7e5ed8ec9d96851126a40c4d23755f1783a8df61def44c667dfaa992ac509e
|
||||
|
||||
220
tools/README.md
220
tools/README.md
@ -2,202 +2,15 @@
|
||||
|
||||
Accuracy to the game's original code is the main goal of this project. To facilitate the decompilation effort and maintain overall quality, we have devised a set of annotations, to be embedded in the source code, which allow us to automatically verify the accuracy of re-compiled functions' assembly, virtual tables, variable offsets and more.
|
||||
|
||||
In order for contributions to be accepted, the annotations must be used in accordance to the rules outlined here. Proper use is enforced by [GitHub Actions](/.github/workflows) which run the Python tools found in this folder. It is recommended to integrate these tools into your local development workflow as well.
|
||||
The tooling we have developed has been moved to the [reccmp](https://github.com/isledecomp/reccmp) repo to facilitate its use in other decompilation projects.
|
||||
* See the [README](https://github.com/isledecomp/reccmp?tab=readme-ov-file#getting-started) on how to get started.
|
||||
* Familiarize yourself with the available [annotations](https://github.com/isledecomp/reccmp/blob/master/docs/annotations.md) and the [best practices](https://github.com/isledecomp/reccmp/blob/master/docs/recommendations.md) we have established.
|
||||
|
||||
# Overview
|
||||
|
||||
We are continually working on extending the capabilities of our "decompilation language" and the toolset around it. Some of the following annotations have not made it into formal verification and thus are not technically enforced on the source code level yet (marked as **WIP**). Nevertheless, it is recommended to use them since it is highly likely they will eventually be fully integrated.
|
||||
|
||||
## Functions
|
||||
|
||||
All non-inlined functions in the code base with the exception of [3rd party code](/3rdparty) must be annotated with one of the following markers, which include the module name and address of the function as found in the original binaries. This information is then used to compare the recompiled assembly with the original assembly, resulting in an accuracy score. Functions in a given compilation unit must be ordered by their address in ascending order.
|
||||
|
||||
The annotations can be attached to the function implementation, which is the most common case, or use the "comment" syntax (see examples below) for functions that cannot be referred to directly (such as templated, synthetic or non-inlined inline functions). The latter should only ever appear in `.h` files.
|
||||
|
||||
### `FUNCTION`
|
||||
|
||||
Functions with a reasonably complete implementation which are not templated or synthetic (see below) should be annotated with `FUNCTION`.
|
||||
|
||||
```
|
||||
// FUNCTION: LEGO1 0x100b12c0
|
||||
MxCore* MxObjectFactory::Create(const char* p_name)
|
||||
{
|
||||
// implementation
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100140d0
|
||||
// MxCore::IsA
|
||||
```
|
||||
|
||||
### `STUB`
|
||||
|
||||
Functions with no or a very incomplete implementation should be annotated with `STUB`. These will not be compared to the original assembly.
|
||||
|
||||
```
|
||||
// STUB: LEGO1 0x10011d50
|
||||
LegoCameraController::LegoCameraController()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
```
|
||||
|
||||
### `TEMPLATE`
|
||||
|
||||
Templated functions should be annotated with `TEMPLATE`. Since the goal is to eventually have a full accounting of all the functions present in the binaries, please make an effort to find and annotate every function of a templated class.
|
||||
|
||||
```
|
||||
// TEMPLATE: LEGO1 0x100c0ee0
|
||||
// list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >::_Buynode
|
||||
|
||||
// TEMPLATE: LEGO1 0x100c0fc0
|
||||
// MxStreamListMxDSSubscriber::~MxStreamListMxDSSubscriber
|
||||
|
||||
// TEMPLATE: LEGO1 0x100c1010
|
||||
// MxStreamListMxDSAction::~MxStreamListMxDSAction
|
||||
```
|
||||
|
||||
### `SYNTHETIC`
|
||||
|
||||
Synthetic functions should be annotated with `SYNTHETIC`. A synthetic function is generated by the compiler; most common is the "scalar deleting destructor" found in virtual tables. Other cases include default destructors and assignment operators. Note: `SYNTHETIC` takes precedence over `TEMPLATE`.
|
||||
|
||||
```
|
||||
// SYNTHETIC: LEGO1 0x10003210
|
||||
// Helicopter::`scalar deleting destructor'
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100c4f50
|
||||
// MxCollection<MxRegionLeftRight *>::`scalar deleting destructor'
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100c4fc0
|
||||
// MxList<MxRegionLeftRight *>::`scalar deleting destructor'
|
||||
```
|
||||
|
||||
### `LIBRARY`
|
||||
|
||||
Functions located in 3rd party libraries should be annotated with `LIBRARY`. Since the goal is to eventually have a full accounting of all the functions present in the binaries, please make an effort to find and annotate every function of every statically linked library, including the MSVC standard libraries.
|
||||
|
||||
```
|
||||
// LIBRARY: ISLE 0x4061b0
|
||||
// _MemPoolInit@4
|
||||
|
||||
// LIBRARY: ISLE 0x406520
|
||||
// _MemPoolSetPageSize@8
|
||||
|
||||
// LIBRARY: ISLE 0x406630
|
||||
// _MemPoolSetBlockSizeFS@8
|
||||
```
|
||||
|
||||
## Virtual tables
|
||||
|
||||
Classes with a virtual table should be annotated using the `VTABLE` marker, which includes the module name and address of the virtual table. Additionally, virtual function declarations should be annotated with a comment indicating their relative offset. Please use the following example as a reference.
|
||||
|
||||
```
|
||||
// VTABLE: LEGO1 0x100dc900
|
||||
class MxEventManager : public MxMediaManager {
|
||||
public:
|
||||
MxEventManager();
|
||||
virtual ~MxEventManager() override;
|
||||
|
||||
virtual void Destroy() override; // vtable+0x18
|
||||
virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread); // vtable+0x28
|
||||
```
|
||||
|
||||
## Class size
|
||||
|
||||
Classes should be annotated using the `SIZE` marker to indicate their size. If you are unsure about the class size in the original binary, please use the currently available information (known member variables) and detail the circumstances in an extra comment if necessary.
|
||||
|
||||
```
|
||||
// SIZE 0x1c
|
||||
class MxCriticalSection {
|
||||
public:
|
||||
MxCriticalSection();
|
||||
~MxCriticalSection();
|
||||
static void SetDoMutex();
|
||||
```
|
||||
|
||||
Furthermore, add `DECOMP_SIZE_ASSERT(MxCriticalSection, 0x1c)` to the respective `.cpp` file (if the class has no dedicated `.cpp` file, use any appropriate `.cpp` file where the class is used).
|
||||
|
||||
## Member variables
|
||||
|
||||
Member variables should be annotated with their relative offsets.
|
||||
|
||||
```
|
||||
class MxDSObject : public MxCore {
|
||||
private:
|
||||
MxU32 m_sizeOnDisk; // 0x8
|
||||
MxU16 m_type; // 0xc
|
||||
char* m_sourceName; // 0x10
|
||||
undefined4 m_unk0x14; // 0x14
|
||||
```
|
||||
|
||||
## Global variables
|
||||
|
||||
Global variables should be annotated using the `GLOBAL` marker, which includes the module name and address of the variable.
|
||||
|
||||
```
|
||||
// GLOBAL: LEGO1 0x100f456c
|
||||
MxAtomId* g_jukeboxScript = NULL;
|
||||
|
||||
// GLOBAL: LEGO1 0x100f4570
|
||||
MxAtomId* g_pz5Script = NULL;
|
||||
|
||||
// GLOBAL: LEGO1 0x100f4574
|
||||
MxAtomId* g_introScript = NULL;
|
||||
```
|
||||
|
||||
## Strings
|
||||
|
||||
String values should be annotated using the `STRING` marker, which includes the module name and address of the string.
|
||||
|
||||
```
|
||||
inline virtual const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
// STRING: LEGO1 0x100f03fc
|
||||
return "Act2PoliceStation";
|
||||
}
|
||||
```
|
||||
|
||||
# Tooling
|
||||
|
||||
Use `pip` to install the required packages to be able to use the Python tools found in this folder:
|
||||
|
||||
```sh
|
||||
pip install -r tools/requirements.txt
|
||||
```
|
||||
|
||||
Run the following command to allow reccmp to detect the original LEGO binaries:
|
||||
|
||||
```sh
|
||||
reccmp-project detect --what original --search-path <paths-to-directories0containing-lego-binaries>
|
||||
```
|
||||
|
||||
After building recompiled binaries, run the following command in this repository's root:
|
||||
|
||||
```sh
|
||||
reccmp-project detect --what recompiled --search-path <paths-to-build-directories>
|
||||
```
|
||||
|
||||
The example usages below assume that the current working directory is this repository's root and that the retail binaries have been copied to `./legobin`.
|
||||
|
||||
* `reccmp-decomplint`: Checks the decompilation annotations (see above)
|
||||
* e.g. `reccmp-decomplint --module LEGO1 LEGO1`
|
||||
* [`ncc`](/tools/ncc): Checks naming conventions based on a set of rules
|
||||
* `reccmp-reccmp`: Compares an original binary with a recompiled binary, provided a PDB file. For example:
|
||||
* Display the diff for a single function: `py -m tools.reccmp.reccmp --verbose 0x100ae1a0 legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .`
|
||||
* Generate an HTML report: `py -m tools.reccmp.reccmp --html output.html legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .`
|
||||
* Create a base file for diffs: `py -m tools.reccmp.reccmp --json base.json --silent legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .`
|
||||
* Diff against a base file: `py -m tools.reccmp.reccmp --diff base.json legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .`
|
||||
* `reccmp-stackcmp`: Compares the stack layout for a given function that almost matches.
|
||||
* e.g. `reccmp-stackcmp legobin/BETA10.DLL build_debug/LEGO1.DLL build_debug/LEGO1.pdb . 0x1007165d`
|
||||
* `reccmp-roadmap`: Compares symbol locations in an original binary with the same symbol locations of a recompiled binary
|
||||
* `reccmp-verexp`: Verifies exports by comparing the exports of the original DLL and the recompiled DLL
|
||||
* `reccmp-vtable`: Asserts virtual table correctness by comparing a recompiled binary with the original
|
||||
* e.g. `reccmp-vtable legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .`
|
||||
* `reccmp-datacmp`: Compares global data found in the original with the recompiled version
|
||||
* e.g. `reccmp-datacmp legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .`
|
||||
* [`patch_c2.py`](/tools/patch_c2.py): Patches `C2.EXE` (part of MSVC 4.20) to get rid of a bugged warning
|
||||
The following scripts are specific to LEGO Island and have thus remained here:
|
||||
* [`patch_c2.py`](/tools/patch_c2.py): Patches `C2.EXE` (part of MSVC 4.20) to get rid of a bugged warning.
|
||||
|
||||
# Modules
|
||||
The following is a list of all the modules found in the annotations (e.g. `// FUNCTION: [module] [address]`) and which binaries they refer to. See [this list of all known versions of the game](https://www.legoisland.org/wiki/LEGO_Island#Download).
|
||||
The following is a list of all the modules found in the annotations (e.g. `// FUNCTION: [module] [address]`) and which binaries they refer to. See also [this list of all known versions of the game](https://www.legoisland.org/wiki/LEGO_Island#Download).
|
||||
|
||||
## Retail v1.1.0.0 (v1.1)
|
||||
* `LEGO1` -> `LEGO1.DLL`
|
||||
@ -219,23 +32,28 @@ It is therefore advisable to search for the corresponding function in `BETA10` w
|
||||
|
||||
Unfortunately, some code has been changed after this beta version was created. Therefore, we are not aiming for a perfect binary match of `BETA10`. In case of discrepancies, `LEGO1` (as defined above) is our "gold standard" for matching.
|
||||
|
||||
### Re-compiling a beta build (**WIP**)
|
||||
## Pre-Alpha
|
||||
|
||||
* `ALPHA` -> `LEGO1D.DLL`
|
||||
|
||||
This debug build is hardly used since it has little benefit over `BETA10`.
|
||||
|
||||
|
||||
# Re-compiling a beta build
|
||||
|
||||
If you want to match the code against `BETA10`, use the following `cmake` setup to create a debug build:
|
||||
```
|
||||
cmake <path-to-source> -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_BUILD_TYPE=Debug -DISLE_USE_SMARTHEAP=OFF
|
||||
cmake <path-to-source> -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_BUILD_TYPE=Debug -DISLE_USE_SMARTHEAP=OFF -DISLE_BUILD_BETA10=ON -DISLE_BUILD_LEGO1=OFF
|
||||
```
|
||||
**TODO**: If you can figure out how to make a debug build with SmartHeap enabled, please add it here.
|
||||
|
||||
If you want to run scripts to compare your debug build to `BETA10` (e.g. `reccmp-reccmp`), it is advisable to add a copy of `LEGO1D.DLL` to `/legobin` and rename it to `BETA10.DLL`.
|
||||
If you can figure out how to make a debug build with SmartHeap enabled, please add it here.
|
||||
|
||||
### Finding matching functions
|
||||
If you want to run scripts to compare your debug build to `BETA10` (e.g. `reccmp-reccmp`), it is advisable to add a copy of `LEGO1D.DLL` from Beta 1.0 to `/legobin` and rename it to `BETA10.DLL`. Analogously, you can add `LEGO1D.DLL` from the Pre-Alpha and rename it to `ALPHA.DLL`.
|
||||
|
||||
# Finding matching functions
|
||||
|
||||
This is not a recipe, but rather a list of things you can try.
|
||||
* If you are working on a virtual function in a class, try to find the class' vtable. Many (but not all) classes implement `ClassName()`. These functions are usually easy to find by searching the memory for the string consisting of the class name. Keep in mind that not all child classes overwrite this function, so if the function you found is used in multiple vtables (or if you found multiple `ClassName()`-like functions), make sure you actually have the parent's vtable.
|
||||
* If that does not help, you can try to walk up the call tree and try to locate a function that calls the function you are interested in.
|
||||
* Assertions can also help you - most `.cpp` file names have already been matched based on `BETA10`, so you can search for the name of your `.cpp` file and check all the assertions in that file. While that does not find all functions in a given source file, it usually finds the more complex ones.
|
||||
* _If you have found any other strategies, please add them here._
|
||||
|
||||
## Others (**WIP**)
|
||||
* `ALPHA` (only used twice)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user