diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d1e193..c30167db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -330,9 +330,7 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/actors/act2actor.cpp LEGO1/lego/legoomni/src/actors/act2genactor.cpp LEGO1/lego/legoomni/src/actors/act3actors.cpp - LEGO1/lego/legoomni/src/actors/act3brickster.cpp - LEGO1/lego/legoomni/src/actors/act3cop.cpp - LEGO1/lego/legoomni/src/actors/act3shark.cpp + LEGO1/lego/legoomni/src/actors/act3ammo.cpp LEGO1/lego/legoomni/src/actors/ambulance.cpp LEGO1/lego/legoomni/src/actors/bike.cpp LEGO1/lego/legoomni/src/actors/buildingentity.cpp @@ -391,7 +389,6 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp LEGO1/lego/legoomni/src/entity/legoentity.cpp LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp - LEGO1/lego/legoomni/src/entity/legojetski.cpp LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp LEGO1/lego/legoomni/src/entity/legolocations.cpp LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index e830b289..68b8f59d 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -10,11 +10,11 @@ // SIZE 0x1a8 class Act2Actor : public LegoAnimActor { public: - struct UnknownListStructure { + struct Location { MxFloat m_position[3]; // 0x00 MxFloat m_direction[3]; // 0x0c const char* m_boundary; // 0x18 - undefined m_unk0x1c; // 0x1c + MxBool m_unk0x1c; // 0x1c }; Act2Actor(); @@ -22,15 +22,19 @@ class Act2Actor : public LegoAnimActor { void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) override; // vtable+0x24 void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override; // vtable+0x68 - void VTable0x70(float p_und) override; // vtable+0x70 - MxResult VTable0x94(LegoPathActor*, MxBool) override; // vtable+0x94 + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor*, MxBool) override; // vtable+0x94 MxResult VTable0x9c() override; // vtable+0x9c MxS32 VTable0xa0() override; // vtable+0xa0 void FUN_10018980(); + void FUN_10019250(MxFloat p_speed, MxFloat p_param2); void FUN_10019520(); void FUN_10019560(); - void FUN_100192a0(undefined4 p_param); + MxU32 FUN_10019700(MxFloat p_param); + void FUN_100199f0(MxS8 p_param); + void FUN_100192a0(undefined4 p_location); + LegoEntity* FUN_10019b90(MxBool* p_param); // SYNTHETIC: LEGO1 0x1001a0a0 // Act2Actor::`scalar deleting destructor' @@ -44,18 +48,18 @@ class Act2Actor : public LegoAnimActor { MxS8 m_unk0x1d; // 0x1d undefined m_unk0x1e; // 0x1e MxBool m_unk0x1f; // 0x1f - undefined4 m_unk0x20; // 0x20 - undefined4 m_unk0x24; // 0x24 + MxFloat m_unk0x20; // 0x20 + MxFloat m_unk0x24; // 0x24 MxS8 m_unk0x28; // 0x28 - undefined4 m_unk0x2c; // 0x2c - undefined4 m_unk0x30; // 0x30 + MxFloat m_unk0x2c; // 0x2c + MxFloat m_unk0x30; // 0x30 LegoAnimActorStruct* m_shootAnim; // 0x34 LegoCacheSound* m_unk0x38; // 0x38 undefined4 m_unk0x3c; // 0x3c undefined m_unk0x40; // 0x40 - undefined4 m_unk0x44; // 0x44 + MxFloat m_unk0x44; // 0x44 MxS8 m_unk0x48; // 0x48 - undefined4 m_unk0x4c; // 0x4c + LegoEntity* m_unk0x4c; // 0x4c }; // TEMPLATE: LEGO1 0x100194f0 diff --git a/LEGO1/lego/legoomni/include/act2brick.h b/LEGO1/lego/legoomni/include/act2brick.h index 1ad730f2..addc7261 100644 --- a/LEGO1/lego/legoomni/include/act2brick.h +++ b/LEGO1/lego/legoomni/include/act2brick.h @@ -26,7 +26,7 @@ class Act2Brick : public LegoPathActor { return !strcmp(p_name, Act2Brick::ClassName()) || LegoEntity::IsA(p_name); } - MxResult VTable0x94(LegoPathActor* p_actor, MxBool) override; // vtable+0x94 + MxResult HitActor(LegoPathActor* p_actor, MxBool) override; // vtable+0x94 // SYNTHETIC: LEGO1 0x1007a450 // Act2Brick::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/act2genactor.h b/LEGO1/lego/legoomni/include/act2genactor.h index 1831870e..ab0ce47b 100644 --- a/LEGO1/lego/legoomni/include/act2genactor.h +++ b/LEGO1/lego/legoomni/include/act2genactor.h @@ -6,7 +6,7 @@ // VTABLE: LEGO1 0x100d4ed8 // SIZE 0x154 class Act2GenActor : public LegoPathActor { - MxResult VTable0x94(LegoPathActor* p_actor, MxBool) override; // vtable+0x94 + MxResult HitActor(LegoPathActor* p_actor, MxBool) override; // vtable+0x94 // SYNTHETIC: LEGO1 0x1000f5a0 // Act2GenActor::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/act3.h b/LEGO1/lego/legoomni/include/act3.h index 9e5a6d74..da9910d2 100644 --- a/LEGO1/lego/legoomni/include/act3.h +++ b/LEGO1/lego/legoomni/include/act3.h @@ -1,10 +1,51 @@ #ifndef ACT3_H #define ACT3_H +#include "act3ammo.h" #include "legogamestate.h" #include "legostate.h" #include "legoworld.h" +class Act3Brickster; +class Act3Cop; +class Act3Shark; +class Helicopter; + +// Macros confirmed by BETA10 +#define MAX_PIZZAS 20 +#define MAX_DONUTS 20 + +// SIZE 0x0c +struct Act3ListElement { + MxU32 m_objectId; // 0x00 + undefined4 m_unk0x04; // 0x04 + undefined m_unk0x08; // 0x08 + + Act3ListElement() {} + + Act3ListElement(MxU32 p_objectId, undefined4 p_unk0x04, undefined p_unk0x08) + : m_objectId(p_objectId), m_unk0x04(p_unk0x04), m_unk0x08(p_unk0x08) + { + } + + int operator==(Act3ListElement) const { return 0; } + int operator<(Act3ListElement) const { return 0; } +}; + +// SIZE 0x10 +class Act3List : private list { +public: + Act3List() { m_unk0x0c = 0; } + + void Insert(MxS32 p_objectId, MxS32 p_option); + void FUN_10071fa0(); + void Clear(); + void FUN_100720d0(MxU32 p_objectId); + +private: + undefined4 m_unk0x0c; // 0x0c +}; + // VTABLE: LEGO1 0x100d4fc8 // SIZE 0x0c class Act3State : public LegoState { @@ -42,8 +83,7 @@ class Act3State : public LegoState { class Act3 : public LegoWorld { public: Act3(); - - ~Act3() override; // vtable+00 + ~Act3() override; MxLong Notify(MxParam& p_param) override; // vtable+0x04 MxResult Tickle() override; // vtable+0x08 @@ -69,22 +109,85 @@ class Act3 : public LegoWorld { MxBool Escape() override; // vtable+0x64 void Enable(MxBool p_enable) override; // vtable+0x68 - void SetUnknown420c(MxEntity* p_entity) { m_unk0x420c = p_entity; } + void SetHelicopter(Helicopter* p_copter) { m_copter = p_copter; } + void SetShark(Act3Shark* p_shark) { m_shark = p_shark; } void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } // SYNTHETIC: LEGO1 0x10072630 // Act3::`scalar deleting destructor' - MxBool FUN_100727e0(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up); - MxBool FUN_10072980(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up); + void EatPizza(MxS32 p_index); + void EatDonut(MxS32 p_index); + void RemovePizza(Act3Ammo& p_p); + void RemoveDonut(Act3Ammo& p_p); + MxResult ShootPizza(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up); + MxResult ShootDonut(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up); + void FUN_10072ad0(undefined4 p_param1); + MxResult FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2); + MxResult FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2); + void SetBrickster(Act3Brickster* p_brickster); + void AddCop(Act3Cop* p_cop); void FUN_10073400(); void FUN_10073430(); + void GoodEnding(const Matrix4& p_destination); + + // BETA indicates that the following classes access certain members directly. + friend class Act3Ammo; + friend class Act3Brickster; + friend class Act3Cop; + friend class Act3Shark; protected: - undefined m_unk0xf8[0x4114]; // 0xf8 - MxEntity* m_unk0x420c; // 0x420c - undefined m_unk0x4210[0x60]; // 0x4210 + MxLong HandleTransitionEnd(); + + static void DebugPrintf(const char* p_format, ...); + static void DebugCopter( + const Matrix4& p_copter, + const Matrix4& p_destination, + const Matrix4& p_startPosition, + const Matrix4& p_endPosition, + const UnknownMx4DPointFloat& p_unk0x1f4 + ); + + Act3State* m_state; // 0xf8 + Act3Ammo m_pizzas[MAX_PIZZAS]; // 0xfc + Act3Ammo m_donuts[MAX_DONUTS]; // 0x217c + undefined m_unk0x41fc; // 0x41fc + Act3Cop* m_cop1; // 0x4200 + Act3Cop* m_cop2; // 0x4204 + Act3Brickster* m_brickster; // 0x4208 + Helicopter* m_copter; // 0x420c + Act3Shark* m_shark; // 0x4210 + MxFloat m_time; // 0x4214 + MxU8 m_unk0x4218; // 0x4218 + MxU8 m_unk0x4219; // 0x4219 + MxU8 m_unk0x421a; // 0x421a + MxU8 m_unk0x421b; // 0x421b + MxU8 m_unk0x421c; // 0x421c + MxU8 m_unk0x421d; // 0x421d + undefined m_unk0x421e; // 0x421e + Act3List m_unk0x4220; // 0x4220 + MxPresenter* m_helicopterDots[15]; // 0x4230 + Act3Script::Script m_unk0x426c; // 0x426c LegoGameState::Area m_destLocation; // 0x4270 }; +// TEMPLATE: LEGO1 0x10071f10 +// list >::insert + +// TEMPLATE: LEGO1 0x10071f70 +// list >::_Buynode + +// TEMPLATE: LEGO1 0x10072220 +// list >::erase + +// TEMPLATE: LEGO1 0x10072440 +// list >::~list > + +// TEMPLATE: LEGO1 0x100724b0 +// List::~List + +// FUNCTION: LEGO1 0x10072650 +// Act3List::~Act3List + #endif // ACT3_H diff --git a/LEGO1/lego/legoomni/include/act3actors.h b/LEGO1/lego/legoomni/include/act3actors.h index 2fce23b3..660ebba6 100644 --- a/LEGO1/lego/legoomni/include/act3actors.h +++ b/LEGO1/lego/legoomni/include/act3actors.h @@ -5,12 +5,26 @@ // File name verified by multiple assertions, e.g. BETA10 0x10018391 +class Act3Ammo; +class LegoWorld; + // VTABLE: LEGO1 0x100d7668 LegoPathActor // VTABLE: LEGO1 0x100d7738 LegoAnimActor // VTABLE: BETA10 0x101b8a98 LegoPathActor // SIZE 0x178 class Act3Actor : public LegoAnimActor { public: + struct Act3CopDest { + // name verified by BETA10 0x10018776 + const char* m_bName; // 0x00 + + // name verified by BETA10 0x100187cb + LegoPathBoundary* m_boundary; // 0x04 + + MxFloat m_unk0x08[3]; // 0x08 + MxFloat m_unk0x14[3]; // 0x14 + }; + Act3Actor(); // FUNCTION: LEGO1 0x100431b0 @@ -20,8 +34,12 @@ class Act3Actor : public LegoAnimActor { return "Act3Actor"; } - MxU32 VTable0x90(float p_float, Matrix4& p_transform) override; // vtable+0x90 - MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + MxU32 VTable0x90(float p_time, Matrix4& p_transform) override; // vtable+0x90 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + + MxFloat GetUnknown0x1c() { return m_unk0x1c; } + + void SetUnknown0x1c(MxFloat p_unk0x1c) { m_unk0x1c = p_unk0x1c; } // SYNTHETIC: LEGO1 0x10043330 // Act3Actor::`scalar deleting destructor' @@ -30,12 +48,141 @@ class Act3Actor : public LegoAnimActor { // Act3Actor::~Act3Actor private: - MxFloat m_unk0x1c; // 0x1c - static Mx3DPointFloat g_unk0x10104ef0; + + MxFloat m_unk0x1c; // 0x1c }; +// VTABLE: LEGO1 0x100d7750 LegoPathActor +// VTABLE: LEGO1 0x100d7820 LegoAnimActor +// SIZE 0x188 +class Act3Cop : public Act3Actor { +public: + Act3Cop(); + + void ParseAction(char* p_extra) override; // vtable+0x20 + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor*, MxBool) override; // vtable+0x94 + MxResult VTable0x9c() override; // vtable+0x9c + + MxFloat GetUnknown0x20() { return m_unk0x20; } + + void SetUnknown0x20(MxFloat p_unk0x20) { m_unk0x20 = p_unk0x20; } + + MxResult FUN_10040350(Act3Ammo& p_ammo, const Vector3&); + MxResult FUN_10040360(); + + // SYNTHETIC: LEGO1 0x10043120 + // Act3Cop::`scalar deleting destructor' + +private: + MxFloat m_unk0x20; // 0x20 + LegoWorld* m_world; // 0x24 + undefined4 m_unk0x28[2]; // 0x28 +}; + +// VTABLE: LEGO1 0x100d7838 LegoPathActor +// VTABLE: LEGO1 0x100d7908 LegoAnimActor +// SIZE 0x1b4 +class Act3Brickster : public Act3Actor { +public: + Act3Brickster(); + ~Act3Brickster() override; + + void ParseAction(char* p_extra) override; // vtable+0x20 + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + void SwitchBoundary( + LegoPathBoundary*& p_boundary, + LegoUnknown100db7f4*& p_edge, + float& p_unk0xe4 + ) override; // vtable+0x98 + MxResult VTable0x9c() override; // vtable+0x9c + + MxFloat GetUnknown0x20() { return m_unk0x20; } + MxFloat GetUnknown0x24() { return m_unk0x24; } + MxFloat GetUnknown0x50() { return m_unk0x50; } + + void SetUnknown0x20(MxFloat p_unk0x20) { m_unk0x20 = p_unk0x20; } + void SetUnknown0x24(MxFloat p_unk0x24) { m_unk0x24 = p_unk0x24; } + void SetUnknown0x50(MxFloat p_unk0x50) { m_unk0x50 = p_unk0x50; } + + MxResult FUN_100417a0(Act3Ammo& p_ammo, const Vector3&); + MxResult FUN_100417c0(); + + // SYNTHETIC: LEGO1 0x10043250 + // Act3Brickster::`scalar deleting destructor' + +private: + MxFloat m_unk0x20; // 0x20 + MxFloat m_unk0x24; // 0x24 + LegoWorld* m_world; // 0x28 + undefined4 m_unk0x2c; // 0x2c + undefined4 m_unk0x30; // 0x30 + LegoAnimActorStruct* m_shootAnim; // 0x34 + undefined4 m_unk0x38; // 0x38 + Mx3DPointFloat m_unk0x3c; // 0x3c + MxFloat m_unk0x50; // 0x50 + undefined4 m_unk0x54; // 0x54 + undefined m_unk0x58; // 0x58 +}; + +// VTABLE: LEGO1 0x100d7920 LegoPathActor +// VTABLE: LEGO1 0x100d79f0 LegoAnimActor +// SIZE 0x1a8 +class Act3Shark : public LegoAnimActor { +public: + Act3Shark(); + + // FUNCTION: LEGO1 0x100430d0 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f03a0 + return "Act3Shark"; + } + + void ParseAction(char*) override; // vtable+0x20 + void Animate(float p_time) override; // vtable+0x70 + + // LegoAnimActor vtable + virtual MxResult FUN_10042ce0(Act3Ammo* p_ammo); // vtable+0x10 + + MxFloat GetUnknown0x2c() { return m_unk0x2c; } + + void SetUnknown0x2c(MxFloat p_unk0x2c) { m_unk0x2c = p_unk0x2c; } + + // SYNTHETIC: LEGO1 0x10043030 + // Act3Shark::`scalar deleting destructor' + +private: + list m_unk0x1c; // 0x1c + undefined4 m_unk0x28; // 0x28 + MxFloat m_unk0x2c; // 0x2c + LegoWorld* m_world; // 0x30 + LegoAnimActorStruct* m_unk0x34; // 0x34 + LegoROI* m_unk0x38; // 0x38 + Mx3DPointFloat m_unk0x3c; // 0x3c +}; + +// FUNCTION: LEGO1 0x1003ff10 +// Act3Actor::`vbase destructor' + +// TEMPLATE: LEGO1 0x10042c20 +// list >::~list > + +// TEMPLATE: LEGO1 0x10042c90 +// List::~List + // GLOBAL: LEGO1 0x100d7660 // Act3Actor::`vbtable' +// GLOBAL: LEGO1 0x100d7748 +// Act3Cop::`vbtable' + +// GLOBAL: LEGO1 0x100d7830 +// Act3Brickster::`vbtable' + +// GLOBAL: LEGO1 0x100d7918 +// Act3Shark::`vbtable' + #endif // ACT3ACTORS_H diff --git a/LEGO1/lego/legoomni/include/act3ammo.h b/LEGO1/lego/legoomni/include/act3ammo.h new file mode 100644 index 00000000..8beac5be --- /dev/null +++ b/LEGO1/lego/legoomni/include/act3ammo.h @@ -0,0 +1,104 @@ +#ifndef ACT3AMMO_H +#define ACT3AMMO_H + +#include "legopathactor.h" +#include "mxgeometry/mxgeometry3d.h" + +class Act3; + +// VTABLE: LEGO1 0x100d8460 +// SIZE 0x1a0 +class Act3Ammo : public LegoPathActor { +public: + enum { + c_pizza = 0x01, + c_donut = 0x02, + c_valid = 0x04, + c_bit4 = 0x08, + c_bit5 = 0x10 + }; + + Act3Ammo(); + ~Act3Ammo() override; + + void Destroy(MxBool p_fromDestructor) override; // vtable+0x1c + void Animate(float p_time) override; // vtable+0x70 + + // FUNCTION: BETA10 0x10017750 + MxU32 IsValid() { return m_ammoFlag & c_valid; } + + // FUNCTION: BETA10 0x100177b0 + Mx3DPointFloat* GetUnknown0x160() { return m_eq; } + + // FUNCTION: BETA10 0x100177e0 + MxFloat* GetUnknown0x19c() { return &m_unk0x19c; } + + // FUNCTION: BETA10 0x1001fbd0 + void SetValid(MxBool p_valid) + { + if (p_valid) { + m_ammoFlag |= c_valid; + } + else { + m_ammoFlag &= ~c_valid; + } + } + + // FUNCTION: BETA10 0x1001fc80 + MxU32 IsPizza() { return m_ammoFlag & c_pizza; } + + // FUNCTION: BETA10 0x10021d60 + MxU32 IsDonut() { return m_ammoFlag & c_donut; } + + // FUNCTION: BETA10 0x1001fcb0 + void SetBit4(MxBool p_bit4) + { + if (p_bit4) { + m_ammoFlag |= c_bit4; + } + else { + m_ammoFlag &= ~c_bit4; + } + } + + // FUNCTION: BETA10 0x10021d90 + MxU32 IsBit4() { return m_ammoFlag & c_bit4; } + + void SetBit5(MxBool p_bit5) + { + if (p_bit5) { + m_ammoFlag |= c_bit5; + } + else { + m_ammoFlag &= ~c_bit5; + } + } + + MxU32 IsBit5() { return m_ammoFlag & c_bit5; } + + MxFloat GetUnknown0x158() { return m_unk0x158; } + + void SetUnknown0x158(MxFloat p_unk0x158) { m_unk0x158 = p_unk0x158; } + + MxResult Remove(); + MxResult Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index); + MxResult FUN_10053b40(Vector3& p_srcLoc, Vector3& p_srcDir, Vector3& p_srcUp); + MxResult FUN_10053cb0(LegoPathController* p_p, LegoPathBoundary* p_boundary, MxFloat p_unk0x19c); + MxResult FUN_10053d30(LegoPathController* p_p, MxFloat p_unk0x19c); + + // SYNTHETIC: LEGO1 0x10053880 + // Act3Ammo::`scalar deleting destructor' + +private: + MxResult FUN_10053db0(float p_param1, const Matrix4& p_param2); + + static Mx3DPointFloat g_unk0x10104f08; + + MxU16 m_ammoFlag; // 0x154 + MxFloat m_unk0x158; // 0x158 + Act3* m_world; // 0x15c + Mx3DPointFloat m_eq[3]; // 0x160 + MxFloat m_unk0x19c; // 0x19c +}; + +#endif // ACT3AMMO_H diff --git a/LEGO1/lego/legoomni/include/act3brickster.h b/LEGO1/lego/legoomni/include/act3brickster.h deleted file mode 100644 index c84b8dd7..00000000 --- a/LEGO1/lego/legoomni/include/act3brickster.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef ACT3BRICKSTER_H -#define ACT3BRICKSTER_H - -#include "act3actors.h" - -// VTABLE: LEGO1 0x100d7838 LegoPathActor -// VTABLE: LEGO1 0x100d7908 LegoAnimActor -// SIZE 0x1b4 -class Act3Brickster : public Act3Actor { -public: - Act3Brickster(); - ~Act3Brickster() override; - - void ParseAction(char* p_extra) override; // vtable+0x20 - void VTable0x70(float p_und) override; // vtable+0x70 - MxResult VTable0x94(LegoPathActor*, MxBool) override; // vtable+0x94 - void SwitchBoundary( - LegoPathBoundary*& p_boundary, - LegoUnknown100db7f4*& p_edge, - float& p_unk0xe4 - ) override; // vtable+0x98 - MxResult VTable0x9c() override; // vtable+0x9c - - // SYNTHETIC: LEGO1 0x10043250 - // Act3Brickster::`scalar deleting destructor' - -private: - undefined4 m_unk0x20[15]; // 0x20 -}; - -#endif // ACT3BRICKSTER_H diff --git a/LEGO1/lego/legoomni/include/act3cop.h b/LEGO1/lego/legoomni/include/act3cop.h deleted file mode 100644 index a720b84c..00000000 --- a/LEGO1/lego/legoomni/include/act3cop.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef ACT3COP_H -#define ACT3COP_H - -#include "act3actors.h" - -// VTABLE: LEGO1 0x100d7750 LegoPathActor -// VTABLE: LEGO1 0x100d7820 LegoAnimActor -// SIZE 0x188 -class Act3Cop : public Act3Actor { -public: - Act3Cop(); - - void ParseAction(char* p_extra) override; // vtable+0x20 - void VTable0x70(float p_und) override; // vtable+0x70 - MxResult VTable0x94(LegoPathActor*, MxBool) override; // vtable+0x94 - MxResult VTable0x9c() override; // vtable+0x9c - - // SYNTHETIC: LEGO1 0x10043120 - // Act3Cop::`scalar deleting destructor' - -private: - undefined4 m_unk0x20[4]; // 0x20 -}; - -#endif // ACT3COP_H diff --git a/LEGO1/lego/legoomni/include/act3shark.h b/LEGO1/lego/legoomni/include/act3shark.h deleted file mode 100644 index 49b467b2..00000000 --- a/LEGO1/lego/legoomni/include/act3shark.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef ACT3SHARK_H -#define ACT3SHARK_H - -#include "legoanimactor.h" - -// VTABLE: LEGO1 0x100d7920 LegoPathActor -// VTABLE: LEGO1 0x100d79f0 LegoAnimActor -// SIZE 0x1a8 -class Act3Shark : public LegoAnimActor { -public: - Act3Shark(); - - // FUNCTION: LEGO1 0x100430d0 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f03a0 - return "Act3Shark"; - } - - void ParseAction(char*) override; // vtable+0x20 - void VTable0x70(float p_float) override; // vtable+0x70 - - // LegoAnimActor vtable - virtual MxResult FUN_10042ce0(void*); // vtable+0x10 - - // SYNTHETIC: LEGO1 0x10043030 - // Act3Shark::`scalar deleting destructor' - -private: - list m_unk0x1c; // 0x1c - undefined4 m_unk0x28; // 0x28 - undefined4 m_unk0x2c; // 0x2c - undefined m_unk0x30[0x0c]; // 0x30 - Mx3DPointFloat m_unk0x3c; // 0x3c -}; - -// STUB: LEGO1 0x10042c90 -// List::~List -// TODO: Update once type is known. -// STUB to resolve diff in scalar dtor and not create a new one. - -#endif // ACT3SHARK_H diff --git a/LEGO1/lego/legoomni/include/ambulance.h b/LEGO1/lego/legoomni/include/ambulance.h index 7278c126..4908d55c 100644 --- a/LEGO1/lego/legoomni/include/ambulance.h +++ b/LEGO1/lego/legoomni/include/ambulance.h @@ -124,7 +124,7 @@ class Ambulance : public IslePathActor { MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 void Destroy(MxBool p_fromDestructor) override; // vtable+0x1c - void VTable0x70(float p_time) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 MxLong HandleClick() override; // vtable+0xcc MxLong HandleControl(LegoControlManagerNotificationParam& p_param) override; // vtable+0xd4 MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0xdc diff --git a/LEGO1/lego/legoomni/include/doors.h b/LEGO1/lego/legoomni/include/doors.h index 8be10963..3a987c9f 100644 --- a/LEGO1/lego/legoomni/include/doors.h +++ b/LEGO1/lego/legoomni/include/doors.h @@ -24,10 +24,10 @@ class Doors : public LegoPathActor { return !strcmp(p_name, Doors::ClassName()) || LegoPathActor::IsA(p_name); } - void ParseAction(char* p_extra) override; // vtable+0x20 - void VTable0x70(float p_float) override; // vtable+0x70 - MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - virtual MxFloat VTable0xcc(float p_float); // vtable+0xcc + void ParseAction(char* p_extra) override; // vtable+0x20 + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + virtual MxFloat VTable0xcc(float p_time); // vtable+0xcc // SYNTHETIC: LEGO1 0x1000e580 // Doors::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/dunebuggy.h b/LEGO1/lego/legoomni/include/dunebuggy.h index 7302e0ce..cfb8c729 100644 --- a/LEGO1/lego/legoomni/include/dunebuggy.h +++ b/LEGO1/lego/legoomni/include/dunebuggy.h @@ -24,7 +24,7 @@ class DuneBuggy : public IslePathActor { } MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void VTable0x70(float p_time) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 MxLong HandleClick() override; // vtable+0xcc MxLong HandleControl(LegoControlManagerNotificationParam& p_param) override; // vtable+0xd4 MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0xdc diff --git a/LEGO1/lego/legoomni/include/helicopter.h b/LEGO1/lego/legoomni/include/helicopter.h index 74715234..4c9b1c0e 100644 --- a/LEGO1/lego/legoomni/include/helicopter.h +++ b/LEGO1/lego/legoomni/include/helicopter.h @@ -5,6 +5,8 @@ #include "legostate.h" #include "realtime/matrix.h" +class Act3; + // VTABLE: LEGO1 0x100d5418 // SIZE 0x0c class HelicopterState : public LegoState { @@ -66,19 +68,25 @@ class Helicopter : public IslePathActor { } MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void VTable0x70(float p_float) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 MxLong HandleClick() override; // vtable+0xcc MxLong HandleControl(LegoControlManagerNotificationParam& p_param) override; // vtable+0xd4 MxLong HandleEndAnim(LegoEndAnimNotificationParam& p_param) override; // vtable+0xd8 void Exit() override; // vtable+0xe4 + void CreateState(); + void FUN_10004640(const Matrix4& p_matrix); + // SYNTHETIC: LEGO1 0x10003210 // Helicopter::`scalar deleting destructor' - void CreateState(); + // m_state is accessed directly from Act3; confirmed by BETA10 + friend class Act3; protected: + void FUN_100042a0(const Matrix4& p_matrix); + MxMatrix m_unk0x160; // 0x160 MxMatrix m_unk0x1a8; // 0x1a8 float m_unk0x1f0; // 0x1f0 diff --git a/LEGO1/lego/legoomni/include/islepathactor.h b/LEGO1/lego/legoomni/include/islepathactor.h index f332ccc9..767b1b1a 100644 --- a/LEGO1/lego/legoomni/include/islepathactor.h +++ b/LEGO1/lego/legoomni/include/islepathactor.h @@ -134,7 +134,7 @@ class IslePathActor : public LegoPathActor { void Reset() { m_roi->SetVisibility(TRUE); - SetState(0); + SetActorState(c_initial); } void SetWorld(LegoWorld* p_world) { m_world = p_world; } diff --git a/LEGO1/lego/legoomni/include/jetski.h b/LEGO1/lego/legoomni/include/jetski.h index e81824be..4dcdc36a 100644 --- a/LEGO1/lego/legoomni/include/jetski.h +++ b/LEGO1/lego/legoomni/include/jetski.h @@ -26,7 +26,7 @@ class Jetski : public IslePathActor { } MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void VTable0x70(float p_time) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 MxLong HandleClick() override; // vtable+0xcc MxLong HandleControl(LegoControlManagerNotificationParam&) override; // vtable+0xd4 void Exit() override; // vtable+0xe4 diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 797b2249..8788af3e 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -40,9 +40,12 @@ class LegoAct2State : public LegoState { // SYNTHETIC: LEGO1 0x1000e040 // LegoAct2State::`scalar deleting destructor' + // FUNCTION: BETA10 0x100151b0 + void SetUnknown0x08(undefined4 p_unk0x08) { m_unk0x08 = p_unk0x08; } + undefined4 GetUnknown0x08() { return m_unk0x08; } - // TODO: Most likely getters/setters are not used according to BETA. + // TODO: Most likely getters/setters are not used according to BETA. (?) undefined4 m_unk0x08; // 0x08 MxBool m_enabled; // 0x0c @@ -68,6 +71,18 @@ class LegoAct2 : public LegoWorld { void SetUnknown0x1138(Act2Actor* p_unk0x1138) { m_unk0x1138 = p_unk0x1138; } void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } + MxResult FUN_100516b0(); + void FUN_100517b0(); + MxResult BadEnding(); + MxResult FUN_10052560( + Act2mainScript::Script p_objectId, + MxBool p_param2, + MxBool p_param3, + Mx3DPointFloat* p_location, + Mx3DPointFloat* p_direction, + Mx3DPointFloat* p_param6 + ); + // SYNTHETIC: LEGO1 0x1004fe20 // LegoAct2::`scalar deleting destructor' @@ -83,14 +98,6 @@ class LegoAct2 : public LegoWorld { void SpawnBricks(); void FUN_10051fa0(MxS32 p_param1); void FUN_100521f0(MxS32 p_param1); - MxResult FUN_10052560( - Act2mainScript::Script p_objectId, - MxBool p_param2, - MxBool p_param3, - Mx3DPointFloat* p_location, - Mx3DPointFloat* p_direction, - Mx3DPointFloat* p_param6 - ); MxResult FUN_10052800(); Act2Brick m_bricks[10]; // 0x00f8 diff --git a/LEGO1/lego/legoomni/include/legoanimactor.h b/LEGO1/lego/legoomni/include/legoanimactor.h index ea4fcb4b..c1885565 100644 --- a/LEGO1/lego/legoomni/include/legoanimactor.h +++ b/LEGO1/lego/legoomni/include/legoanimactor.h @@ -18,6 +18,9 @@ struct LegoAnimActorStruct { // FUNCTION: BETA10 0x10012210 LegoAnim* GetAnimTreePtr() { return m_AnimTreePtr; } + // FUNCTION: BETA10 0x10012240 + LegoROI** GetROIMap() { return m_roiMap; } + // TODO: Possibly private float m_unk0x00; // 0x00 LegoAnim* m_AnimTreePtr; // 0x04 @@ -55,7 +58,7 @@ class LegoAnimActor : public virtual LegoPathActor { void ParseAction(char* p_extra) override; // vtable+0x20 void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - void VTable0x70(float p_und) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 virtual MxResult FUN_1001c1f0(float& p_und); @@ -101,7 +104,7 @@ class LegoAnimActor : public virtual LegoPathActor { // uninitialized_fill_n // TEMPLATE: LEGO1 0x1001ca10 -// uninitialized_copy +// ?uninitialized_copy@@YAPAPAULegoAnimActorStruct@@PAPAU1@00@Z // clang-format on #endif // LEGOANIMACTOR_H diff --git a/LEGO1/lego/legoomni/include/legobuildingmanager.h b/LEGO1/lego/legoomni/include/legobuildingmanager.h index 409e805c..41b5a8fd 100644 --- a/LEGO1/lego/legoomni/include/legobuildingmanager.h +++ b/LEGO1/lego/legoomni/include/legobuildingmanager.h @@ -87,8 +87,8 @@ class LegoBuildingManager : public MxCore { MxResult FUN_10030630(); LegoBuildingInfo* GetInfoArray(MxS32& p_length); void FUN_100307b0(LegoEntity* p_entity, MxS32 p_adjust); + void FUN_10030800(); - static void FUN_10030800(); static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; } // SYNTHETIC: LEGO1 0x1002f940 diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index a013ed2d..117b9f82 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -101,7 +101,7 @@ class LegoCharacterManager { // list >::_Buynode // TEMPLATE: LEGO1 0x10035790 -// _Construct +// ?_Construct@@YAXPAPAVROI@@ABQAV1@@Z // TEMPLATE: LEGO1 0x10082b90 // _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::~_Tree,map >::_Kfn,LegoCharacterComparator,allocator > diff --git a/LEGO1/lego/legoomni/include/legoextraactor.h b/LEGO1/lego/legoomni/include/legoextraactor.h index f6295efa..5bc316a3 100644 --- a/LEGO1/lego/legoomni/include/legoextraactor.h +++ b/LEGO1/lego/legoomni/include/legoextraactor.h @@ -42,14 +42,14 @@ class LegoExtraActor : public virtual LegoAnimActor { float p_f1, float p_f2, Vector3& p_v3 - ) override; // vtable+0x6c - void VTable0x70(float) override; // vtable+0x70 - void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 - MxU32 VTable0x90(float p_float, Matrix4& p_matrix) override; // vtable+0x90 - MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - MxResult VTable0x9c() override; // vtable+0x9c - void VTable0xa4(MxBool& p_und1, MxS32& p_und2) override; // vtable+0xa4 - void VTable0xc4() override; // vtable+0xc4 + ) override; // vtable+0x6c + void Animate(float p_time) override; // vtable+0x70 + void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 + MxU32 VTable0x90(float p_time, Matrix4& p_matrix) override; // vtable+0x90 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + MxResult VTable0x9c() override; // vtable+0x9c + void VTable0xa4(MxBool& p_und1, MxS32& p_und2) override; // vtable+0xa4 + void VTable0xc4() override; // vtable+0xc4 virtual MxResult FUN_1002aae0(); @@ -87,6 +87,6 @@ class LegoExtraActor : public virtual LegoAnimActor { // vector >::size // TEMPLATE: LEGO1 0x1002b720 -// uninitialized_copy +// ?uninitialized_copy@@YAPAPAEPAPAE00@Z #endif // LEGOEXTRAACTOR_H diff --git a/LEGO1/lego/legoomni/include/legojetski.h b/LEGO1/lego/legoomni/include/legojetski.h deleted file mode 100644 index 56057da2..00000000 --- a/LEGO1/lego/legoomni/include/legojetski.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef LEGOJETSKI_H -#define LEGOJETSKI_H - -#include "legojetskiraceactor.h" -#include "legoracemap.h" - -// VTABLE: LEGO1 0x100d5a08 LegoCarRaceActor -// VTABLE: LEGO1 0x100d5a28 LegoRaceActor -// VTABLE: LEGO1 0x100d5a30 LegoAnimActor -// VTABLE: LEGO1 0x100d5a40 LegoPathActor -// VTABLE: LEGO1 0x100d5b10 LegoRaceMap -// SIZE 0x1dc -class LegoJetski : public LegoJetskiRaceActor, public LegoRaceMap { -public: - LegoJetski(); - ~LegoJetski() override; - - MxLong Notify(MxParam& p_param) override; // vtable+0x04 - - // FUNCTION: LEGO1 0x10013e90 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f053c - return "LegoJetski"; - } - - // FUNCTION: LEGO1 0x10013eb0 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, LegoJetski::ClassName()) || LegoJetskiRaceActor::IsA(p_name); - } - - void ParseAction(char*) override; // vtable+0x20 - void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - MxU32 VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 - ) override; // vtable+0x6c - void VTable0x70(float p_float) override; // vtable+0x70 - MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 - void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) - override; // vtable+0x98 - MxResult VTable0x9c() override; // vtable+0x9c - - virtual void FUN_100136f0(float p_worldSpeed); - - // SYNTHETIC: LEGO1 0x10013e30 - // LegoJetski::`scalar deleting destructor' -}; - -// GLOBAL: LEGO1 0x100d59b8 -// LegoJetski::`vbtable'{for `LegoCarRaceActor'} - -// GLOBAL: LEGO1 0x100d59c8 -// LegoJetski::`vbtable'{for `LegoRaceActor'} - -// GLOBAL: LEGO1 0x100d59d8 -// LegoJetski::`vbtable'{for `LegoAnimActor'} - -// GLOBAL: LEGO1 0x100d59e0 -// LegoJetski::`vbtable' - -// GLOBAL: LEGO1 0x100d59f0 -// LegoJetski::`vbtable'{for `LegoJetskiRaceActor'} - -#endif // LEGOJETSKI_H diff --git a/LEGO1/lego/legoomni/include/legojetskiraceactor.h b/LEGO1/lego/legoomni/include/legojetskiraceactor.h index f60a02ff..c9964e8d 100644 --- a/LEGO1/lego/legoomni/include/legojetskiraceactor.h +++ b/LEGO1/lego/legoomni/include/legojetskiraceactor.h @@ -39,7 +39,7 @@ class LegoJetskiRaceActor : public virtual LegoCarRaceActor { float p_f2, Vector3& p_v3 ) override; // vtable+0x6c - void VTable0x70(float p_float) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x10013a80 diff --git a/LEGO1/lego/legoomni/include/legomain.h b/LEGO1/lego/legoomni/include/legomain.h index 4ac4f309..f0443bd6 100644 --- a/LEGO1/lego/legoomni/include/legomain.h +++ b/LEGO1/lego/legoomni/include/legomain.h @@ -131,8 +131,13 @@ class LegoOmni : public MxOmni { LegoWorld* GetCurrentWorld() { return m_currentWorld; } LegoNavController* GetNavController() { return m_navController; } LegoPathActor* GetUserActor() { return m_userActor; } + + // FUNCTION: BETA10 0x100e53a0 LegoPlantManager* GetPlantManager() { return m_plantManager; } + LegoAnimationManager* GetAnimationManager() { return m_animationManager; } + + // FUNCTION: BETA10 0x100e53d0 LegoBuildingManager* GetBuildingManager() { return m_buildingManager; } // FUNCTION: BETA10 0x100e52b0 diff --git a/LEGO1/lego/legoomni/include/legonavcontroller.h b/LEGO1/lego/legoomni/include/legonavcontroller.h index c99ab3fe..ef882450 100644 --- a/LEGO1/lego/legoomni/include/legonavcontroller.h +++ b/LEGO1/lego/legoomni/include/legonavcontroller.h @@ -38,7 +38,6 @@ class LegoNavController : public MxCore { void SetTargets(int p_hPos, int p_vPos, MxBool p_accel); void SetControlMax(int p_hMax, int p_vMax); - void SetTrackDefaultParams(MxBool p_state) { m_trackDefault = p_state; } void SetToDefaultParams(); MxBool CalculateNewPosDir( const Vector3& p_curPos, @@ -88,13 +87,32 @@ class LegoNavController : public MxCore { // FUNCTION: BETA10 0x100c7880 void SetTrackDefault(MxS32 p_trackDefault) { m_trackDefault = p_trackDefault; } + // FUNCTION: BETA10 0x100178a0 + void Reset() + { + m_trackDefault = TRUE; + SetToDefaultParams(); + } + MxFloat GetLinearVel() { return m_linearVel; } MxFloat GetRotationalVel() { return m_rotationalVel; } MxFloat GetMaxLinearVel() { return m_maxLinearVel; } + MxFloat GetMaxLinearAccel() { return m_maxLinearAccel; } + MxFloat GetMaxLinearDeccel() { return m_maxLinearDeccel; } void ResetMaxLinearVel(MxFloat p_maxLinearVel) { m_maxLinearVel = p_maxLinearVel; - m_trackDefault = 0; + m_trackDefault = FALSE; + } + void ResetMaxLinearAccel(MxFloat p_maxLinearAccel) + { + m_maxLinearAccel = p_maxLinearAccel; + m_trackDefault = FALSE; + } + void ResetMaxLinearDeccel(MxFloat p_maxLinearDeccel) + { + m_maxLinearDeccel = p_maxLinearDeccel; + m_trackDefault = FALSE; } // FUNCTION: BETA10 0x100c9a10 diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 0fe7a3df..cf6dba15 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -22,10 +22,17 @@ extern const char* g_strHIT_WALL_SOUND; // SIZE 0x154 class LegoPathActor : public LegoActor { public: - enum { - c_bit2 = 0x02, - c_bit3 = 0x04, - c_bit9 = 0x100 + enum ActorState { + // States + c_initial = 0, + c_one = 1, + c_two = 2, + c_three = 3, + c_disabled = 4, + c_maxState = 255, + + // Flags + c_noCollide = 0x100 }; LegoPathActor(); @@ -54,7 +61,7 @@ class LegoPathActor : public LegoActor { float p_f2, Vector3& p_v3 ); // vtable+0x6c - virtual void VTable0x70(float p_time); // vtable+0x70 + virtual void Animate(float p_time); // vtable+0x70 virtual void VTable0x74(Matrix4& p_transform); // vtable+0x74 // FUNCTION: LEGO1 0x10002d20 @@ -91,7 +98,7 @@ class LegoPathActor : public LegoActor { virtual MxU32 VTable0x90(float, Matrix4&) { return FALSE; } // vtable+0x90 // FUNCTION: LEGO1 0x10002d50 - virtual MxResult VTable0x94(LegoPathActor*, MxBool) { return 0; } // vtable+0x94 + virtual MxResult HitActor(LegoPathActor*, MxBool) { return 0; } // vtable+0x94 virtual void SwitchBoundary( LegoPathBoundary*& p_boundary, @@ -133,17 +140,21 @@ class LegoPathActor : public LegoActor { LegoPathBoundary* GetBoundary() { return m_boundary; } // FUNCTION: BETA10 0x1001c860 - MxU32 GetState() { return m_state; } + MxU32 GetActorState() { return m_actorState; } - LegoPathController* GetController() { return m_controller; } + LegoPathController* GetController() { return m_pathController; } MxBool GetCollideBox() { return m_collideBox; } + MxFloat GetLastTime() { return m_lastTime; } + MxFloat GetActorTime() { return m_actorTime; } void SetBoundary(LegoPathBoundary* p_boundary) { m_boundary = p_boundary; } // FUNCTION: BETA10 0x10013430 - void SetState(MxU32 p_state) { m_state = p_state; } + void SetActorState(MxU32 p_actorState) { m_actorState = p_actorState; } - void SetController(LegoPathController* p_controller) { m_controller = p_controller; } + void SetController(LegoPathController* p_pathController) { m_pathController = p_pathController; } + void SetLastTime(MxFloat p_lastTime) { m_lastTime = p_lastTime; } + void SetActorTime(MxFloat p_actorTime) { m_actorTime = p_actorTime; } void UpdatePlane(LegoNamedPlane& p_namedPlane); void PlaceActor(LegoNamedPlane& p_namedPlane); @@ -163,27 +174,27 @@ class LegoPathActor : public LegoActor { MxS32 p_und ); - MxFloat m_BADuration; // 0x78 - MxFloat m_unk0x7c; // 0x7c - MxFloat m_actorTime; // 0x80 - MxFloat m_lastTime; // 0x84 - LegoPathBoundary* m_boundary; // 0x88 - LegoUnknown m_unk0x8c; // 0x8c - MxU32 m_state; // 0xdc - LegoUnknown100db7f4* m_destEdge; // 0xe0 - MxFloat m_unk0xe4; // 0xe4 - MxBool m_collideBox; // 0xe8 - MxBool m_unk0xe9; // 0xe9 - MxBool m_userNavFlag; // 0xea - MxMatrix m_unk0xec; // 0xec - LegoPathEdgeContainer* m_grec; // 0x134 - LegoPathController* m_controller; // 0x138 - MxFloat m_maxLinearVel; // 0x13c - MxFloat m_unk0x140; // 0x140 - MxFloat m_unk0x144; // 0x144 - MxU8 m_unk0x148; // 0x148 - MxS32 m_unk0x14c; // 0x14c - MxFloat m_unk0x150; // 0x150 + MxFloat m_BADuration; // 0x78 + MxFloat m_unk0x7c; // 0x7c + MxFloat m_actorTime; // 0x80 + MxFloat m_lastTime; // 0x84 + LegoPathBoundary* m_boundary; // 0x88 + LegoUnknown m_unk0x8c; // 0x8c + MxU32 m_actorState; // 0xdc + LegoUnknown100db7f4* m_destEdge; // 0xe0 + MxFloat m_unk0xe4; // 0xe4 + MxBool m_collideBox; // 0xe8 + MxBool m_unk0xe9; // 0xe9 + MxBool m_userNavFlag; // 0xea + MxMatrix m_unk0xec; // 0xec + LegoPathEdgeContainer* m_grec; // 0x134 + LegoPathController* m_pathController; // 0x138 + MxFloat m_maxLinearVel; // 0x13c + MxFloat m_unk0x140; // 0x140 + MxFloat m_unk0x144; // 0x144 + MxU8 m_unk0x148; // 0x148 + MxS32 m_unk0x14c; // 0x14c + MxFloat m_unk0x150; // 0x150 }; // TEMPLATE: LEGO1 0x10018b70 diff --git a/LEGO1/lego/legoomni/include/legopathboundary.h b/LEGO1/lego/legoomni/include/legopathboundary.h index ad2a216a..020bd3c6 100644 --- a/LEGO1/lego/legoomni/include/legopathboundary.h +++ b/LEGO1/lego/legoomni/include/legopathboundary.h @@ -85,7 +85,10 @@ class LegoPathBoundary : public LegoWEGEdge { // _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::find // TEMPLATE: LEGO1 0x1002c4c0 -// _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Copy +// ?_Copy@?$_Tree@PAVLegoPathActor@@PAV1@U_Kfn@?$set@PAVLegoPathActor@@ULegoPathActorSetCompare@@V?$allocator@PAVLegoPathActor@@@@@@ULegoPathActorSetCompare@@V?$allocator@PAVLegoPathActor@@@@@@IAEXABV1@@Z + +// TEMPLATE: LEGO1 0x1002c5b0 +// ?_Copy@?$_Tree@PAVLegoPathActor@@PAV1@U_Kfn@?$set@PAVLegoPathActor@@ULegoPathActorSetCompare@@V?$allocator@PAVLegoPathActor@@@@@@ULegoPathActorSetCompare@@V?$allocator@PAVLegoPathActor@@@@@@IAEPAU_Node@1@PAU21@0@Z // TEMPLATE: LEGO1 0x1002c630 // _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Erase @@ -122,7 +125,7 @@ class LegoPathBoundary : public LegoWEGEdge { // _Tree >::_Kfn,LegoPathActorSetCompare,allocator >::_Rrotate // TEMPLATE: LEGO1 0x1004a7a0 -// _Construct +// ?_Construct@@YAXPAPAVMxCore@@ABQAV1@@Z // TEMPLATE: LEGO1 0x10056c20 // _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::~_Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::iterator::_Inc // TEMPLATE: LEGO1 0x10056d30 -// _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::erase +// ?erase@?$_Tree@PAVLegoAnimPresenter@@PAV1@U_Kfn@?$set@PAVLegoAnimPresenter@@ULegoAnimPresenterSetCompare@@V?$allocator@PAVLegoAnimPresenter@@@@@@ULegoAnimPresenterSetCompare@@V?$allocator@PAVLegoAnimPresenter@@@@@@QAE?AViterator@1@V21@@Z // TEMPLATE: LEGO1 0x10057180 // _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::_Erase @@ -167,7 +170,7 @@ class LegoPathBoundary : public LegoWEGEdge { // _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::_Rrotate // TEMPLATE: LEGO1 0x10058820 -// _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::erase +// ?erase@?$_Tree@PAVLegoAnimPresenter@@PAV1@U_Kfn@?$set@PAVLegoAnimPresenter@@ULegoAnimPresenterSetCompare@@V?$allocator@PAVLegoAnimPresenter@@@@@@ULegoAnimPresenterSetCompare@@V?$allocator@PAVLegoAnimPresenter@@@@@@QAE?AViterator@1@V21@0@Z // TEMPLATE: LEGO1 0x100588e0 // _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::equal_range @@ -176,7 +179,7 @@ class LegoPathBoundary : public LegoWEGEdge { // _Tree >::_Kfn,LegoAnimPresenterSetCompare,allocator >::_Lbound // TEMPLATE: LEGO1 0x10058980 -// _Construct +// ?_Construct@@YAXPAPAVLegoAnimPresenter@@ABQAV1@@Z // TEMPLATE: LEGO1 0x100589a0 // _Distance diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 4bcf17c9..85ef1f9f 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -111,14 +111,6 @@ class LegoPathController : public MxCore { LegoPathBoundary* GetPathBoundary(const char* p_name); void Enable(MxBool p_enable); void FUN_10046bb0(LegoWorld* p_world); - MxS32 FUN_1004a240( - LegoPathEdgeContainer& p_grec, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - LegoUnknown100db7f4*& p_edge, - LegoPathBoundary*& p_boundary - ); MxResult FUN_10048310( LegoPathEdgeContainer* p_grec, const Vector3& p_oldPosition, @@ -130,6 +122,21 @@ class LegoPathController : public MxCore { LegoU8 p_mask, MxFloat* p_param9 ); + MxS32 FUN_1004a240( + LegoPathEdgeContainer& p_grec, + Vector3& p_v1, + Vector3& p_v2, + float p_f1, + LegoUnknown100db7f4*& p_edge, + LegoPathBoundary*& p_boundary + ); + MxResult FUN_1004a380( + Vector3& p_param1, + Vector3& p_param2, + Mx3DPointFloat* p_param3, + LegoPathBoundary*& p_boundary, + MxFloat& p_param5 + ); static MxResult Init(); static MxResult Reset(); @@ -153,6 +160,31 @@ class LegoPathController : public MxCore { static MxResult ReadVector(LegoStorage* p_storage, Mx3DPointFloat& p_vec); static MxResult ReadVector(LegoStorage* p_storage, Mx4DPointFloat& p_vec); + // FUNCTION: BETA10 0x100c16f0 + static MxU32 IsBetween(MxFloat p_v, MxFloat p_a, MxFloat p_b) + { + if (p_a <= p_b) { + return p_v >= p_a && p_v <= p_b; + } + else { + return p_v <= p_a && p_v >= p_b; + } + } + + // FUNCTION: BETA10 0x100c17a0 + static MxU32 FUN_100c17a0(MxFloat p_v1, MxFloat p_v2, MxFloat p_a, MxFloat p_b) + { + assert(IsBetween(p_v1, p_a, p_b)); + assert(IsBetween(p_v2, p_a, p_b)); + + if (p_a <= p_b) { + return p_v1 < p_v2; + } + else { + return p_v1 > p_v2; + } + } + LegoPathBoundary* m_boundaries; // 0x08 LegoPathCtrlEdge* m_edges; // 0x0c Mx3DPointFloat* m_unk0x10; // 0x10 @@ -188,7 +220,7 @@ class LegoPathController : public MxCore { // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::iterator::_Inc // TEMPLATE: LEGO1 0x100452b0 -// _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::erase +// ?erase@?$_Tree@PAULegoPathCtrlEdge@@PAU1@U_Kfn@?$set@PAULegoPathCtrlEdge@@ULegoPathCtrlEdgeCompare@@V?$allocator@PAULegoPathCtrlEdge@@@@@@ULegoPathCtrlEdgeCompare@@V?$allocator@PAULegoPathCtrlEdge@@@@@@QAE?AViterator@1@V21@@Z // TEMPLATE: LEGO1 0x10045700 // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Erase @@ -308,10 +340,10 @@ class LegoPathController : public MxCore { // multiset >::~multiset > // TEMPLATE: LEGO1 0x1004a760 -// _Construct +// ?_Construct@@YAXPAPAULegoBEWithFloat@@ABQAU1@@Z // TEMPLATE: LEGO1 0x1004a780 -// _Construct +// ?_Construct@@YAXPAPAULegoPathCtrlEdge@@ABQAU1@@Z // GLOBAL: LEGO1 0x100f4360 // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Nil diff --git a/LEGO1/lego/legoomni/include/legoplantmanager.h b/LEGO1/lego/legoomni/include/legoplantmanager.h index 132e1f4f..dcb87ffb 100644 --- a/LEGO1/lego/legoomni/include/legoplantmanager.h +++ b/LEGO1/lego/legoomni/include/legoplantmanager.h @@ -46,9 +46,12 @@ class LegoPlantManager : public MxCore { MxBool SwitchMood(LegoEntity* p_entity); MxU32 GetAnimationId(LegoEntity* p_entity); MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state); + LegoPlantInfo* GetInfoArray(MxS32& p_length); MxBool FUN_10026c50(LegoEntity* p_entity); void ScheduleAnimation(LegoEntity* p_entity, MxLong p_length); + MxResult FUN_10026410(); void FUN_10027120(); + void FUN_10027200(); static void SetCustomizeAnimFile(const char* p_value); static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; } diff --git a/LEGO1/lego/legoomni/include/legorace.h b/LEGO1/lego/legoomni/include/legorace.h index 22fe734b..642d26cb 100644 --- a/LEGO1/lego/legoomni/include/legorace.h +++ b/LEGO1/lego/legoomni/include/legorace.h @@ -140,9 +140,9 @@ class LegoRace : public LegoWorld { // FUNCTION: LEGO1 0x1000dac0 // FUNCTION: BETA10 0x100a87d0 - virtual void VTable0x7c(LegoRaceActor* p_map, MxU32 p_index) // vtable+0x7c + virtual void VTable0x7c(LegoRaceMap* p_map, MxU32 p_index) // vtable+0x7c { - m_unk0x110[p_index] = (LegoRaceActor*) p_map; + m_maps[p_index] = p_map; } // SYNTHETIC: LEGO1 0x10015cc0 @@ -155,7 +155,7 @@ class LegoRace : public LegoWorld { MxS32 m_unk0x104; // 0x104 MxS32 m_unk0x108; // 0x108 MxS32 m_unk0x10c; // 0x10c - LegoRaceActor* m_unk0x110[3]; // 0x110 + LegoRaceMap* m_maps[3]; // 0x110 LegoGameState::Area m_destLocation; // 0x11c LegoPathActor* m_pathActor; // 0x120 Act1State* m_act1State; // 0x124 diff --git a/LEGO1/lego/legoomni/include/legoraceactor.h b/LEGO1/lego/legoomni/include/legoraceactor.h index 6fa69eff..9262f258 100644 --- a/LEGO1/lego/legoomni/include/legoraceactor.h +++ b/LEGO1/lego/legoomni/include/legoraceactor.h @@ -31,8 +31,8 @@ class LegoRaceActor : public virtual LegoAnimActor { } MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override; // vtable+0x68 - MxU32 VTable0x90(float p_float, Matrix4& p_matrix) override; // vtable+0x90 - MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + MxU32 VTable0x90(float p_time, Matrix4& p_matrix) override; // vtable+0x90 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 // FUNCTION: LEGO1 0x10014aa0 // FUNCTION: BETA10 0x100ca038 diff --git a/LEGO1/lego/legoomni/include/legoracemap.h b/LEGO1/lego/legoomni/include/legoracemap.h index 1380cd0c..562581fa 100644 --- a/LEGO1/lego/legoomni/include/legoracemap.h +++ b/LEGO1/lego/legoomni/include/legoracemap.h @@ -21,9 +21,9 @@ class LegoRaceMap : public virtual LegoRaceActor { ~LegoRaceMap() override; // LegoPathActor vtable - MxLong Notify(MxParam& p_param) override; // vtable+0x04 - void ParseAction(char* p_extra) override; // vtable+0x20 - void VTable0x70(float p_und) override = 0; // vtable+0x70 + MxLong Notify(MxParam& p_param) override; // vtable+0x04 + void ParseAction(char* p_extra) override; // vtable+0x20 + void Animate(float p_time) override = 0; // vtable+0x70 // LegoRaceMap vtable virtual void FUN_1005d4b0(); // vtable+0x00 diff --git a/LEGO1/lego/legoomni/include/legoracers.h b/LEGO1/lego/legoomni/include/legoracers.h index 3ccfc06f..8c50bea2 100644 --- a/LEGO1/lego/legoomni/include/legoracers.h +++ b/LEGO1/lego/legoomni/include/legoracers.h @@ -1,6 +1,7 @@ #ifndef LEGORACERS_H #define LEGORACERS_H +#include "legojetskiraceactor.h" #include "legoracemap.h" #include "legoracespecial.h" @@ -65,9 +66,9 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { float p_f1, float p_f2, Vector3& p_v3 - ) override; // vtable+0x6c - void VTable0x70(float p_float) override; // vtable+0x70 - MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + ) override; // vtable+0x6c + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) override; // vtable+0x98 MxResult VTable0x9c() override; // vtable+0x9c @@ -97,31 +98,55 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { // Name verified by BETA10 0x100cb537 LegoPathBoundary* m_kick2B; // 0x7c - - // name verified by BETA10 0x100cbee6 - static EdgeReference g_skBMap[]; - - static const SkeletonKickPhase g_skeletonKickPhases[]; - static const char* g_strSpeed; - static const char* g_srtsl18to29[]; - static const char* g_srtsl6to10[]; - static const char* g_emptySoundKeyList[]; - static const char* g_srtrh[]; - static const char* g_srt001ra; - static const char* g_soundSkel3; - static MxU32 g_srtsl18to29Index; - static MxU32 g_srtsl6to10Index; - static MxU32 g_emptySoundKeyListIndex; - static MxU32 g_srtrhIndex; - static Mx3DPointFloat g_unk0x10102af0; - static MxLong g_timeLastSoundPlayed; - static MxS32 g_unk0x100f0b88; - static MxBool g_unk0x100f0b8c; - static undefined4 g_unk0x100f0bac; - static undefined4 g_unk0x100f0bb0; }; -#endif // LEGORACERS_H +// VTABLE: LEGO1 0x100d5a08 LegoCarRaceActor +// VTABLE: LEGO1 0x100d5a28 LegoRaceActor +// VTABLE: LEGO1 0x100d5a30 LegoAnimActor +// VTABLE: LEGO1 0x100d5a40 LegoPathActor +// VTABLE: LEGO1 0x100d5b10 LegoRaceMap +// SIZE 0x1dc +class LegoJetski : public LegoJetskiRaceActor, public LegoRaceMap { +public: + LegoJetski(); + ~LegoJetski() override; + + MxLong Notify(MxParam& p_param) override; // vtable+0x04 + + // FUNCTION: LEGO1 0x10013e90 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f053c + return "LegoJetski"; + } + + // FUNCTION: LEGO1 0x10013eb0 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, LegoJetski::ClassName()) || LegoJetskiRaceActor::IsA(p_name); + } + + void ParseAction(char* p_extra) override; // vtable+0x20 + void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 + MxU32 VTable0x6c( + LegoPathBoundary* p_boundary, + Vector3& p_v1, + Vector3& p_v2, + float p_f1, + float p_f2, + Vector3& p_v3 + ) override; // vtable+0x6c + void Animate(float p_time) override; // vtable+0x70 + MxResult HitActor(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) + override; // vtable+0x98 + MxResult VTable0x9c() override; // vtable+0x9c + + virtual void FUN_100136f0(float p_worldSpeed); + + // SYNTHETIC: LEGO1 0x10013e30 + // LegoJetski::`scalar deleting destructor' +}; // GLOBAL: LEGO1 0x100d5890 // LegoRaceCar::`vbtable'{for `LegoCarRaceActor'} @@ -134,3 +159,20 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { // GLOBAL: LEGO1 0x100d5868 // LegoRaceCar::`vbtable'{for `LegoRaceActor'} + +// GLOBAL: LEGO1 0x100d59b8 +// LegoJetski::`vbtable'{for `LegoCarRaceActor'} + +// GLOBAL: LEGO1 0x100d59c8 +// LegoJetski::`vbtable'{for `LegoRaceActor'} + +// GLOBAL: LEGO1 0x100d59d8 +// LegoJetski::`vbtable'{for `LegoAnimActor'} + +// GLOBAL: LEGO1 0x100d59e0 +// LegoJetski::`vbtable' + +// GLOBAL: LEGO1 0x100d59f0 +// LegoJetski::`vbtable'{for `LegoJetskiRaceActor'} + +#endif // LEGORACERS_H diff --git a/LEGO1/lego/legoomni/include/legoracespecial.h b/LEGO1/lego/legoomni/include/legoracespecial.h index 42a2d437..c65605ff 100644 --- a/LEGO1/lego/legoomni/include/legoracespecial.h +++ b/LEGO1/lego/legoomni/include/legoracespecial.h @@ -42,31 +42,33 @@ class LegoCarRaceActor : public virtual LegoRaceActor { float p_f1, float p_f2, Vector3& p_v3 - ) override; // vtable+0x6c - void VTable0x70(float p_float) override; // vtable+0x70 + ) override; // vtable+0x6c + void Animate(float p_time) override; // vtable+0x70 void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) override; // vtable+0x98 MxResult VTable0x9c() override; // vtable+0x9c - virtual void FUN_10080590(float p_float); + // LegoCarRaceActor vtable + + virtual void FUN_10080590(float p_time); // vtable+0x00 // FUNCTION: LEGO1 0x10012bb0 - virtual void FUN_10012bb0(float p_unk0x14) { m_unk0x14 = p_unk0x14; } + virtual void FUN_10012bb0(float p_unk0x14) { m_unk0x14 = p_unk0x14; } // vtable+0x04 // FUNCTION: LEGO1 0x10012bc0 - virtual float FUN_10012bc0() { return m_unk0x14; } + virtual float FUN_10012bc0() { return m_unk0x14; } // vtable+0x08 // FUNCTION: LEGO1 0x10012bd0 - virtual void FUN_10012bd0(float p_unk0x10) { m_unk0x10 = p_unk0x10; } + virtual void FUN_10012bd0(float p_unk0x10) { m_unk0x10 = p_unk0x10; } // vtable+0x0c // FUNCTION: LEGO1 0x10012be0 - virtual float FUN_10012be0() { return m_unk0x10; } + virtual float FUN_10012be0() { return m_unk0x10; } // vtable+0x10 // FUNCTION: LEGO1 0x10012bf0 - virtual void FUN_10012bf0(float p_unk0x18) { m_unk0x18 = p_unk0x18; } + virtual void FUN_10012bf0(float p_unk0x18) { m_unk0x18 = p_unk0x18; } // vtable+0x14 // FUNCTION: LEGO1 0x10012c00 - virtual float FUN_10012c00() { return m_unk0x18; } + virtual float FUN_10012c00() { return m_unk0x18; } // vtable+0x18 virtual MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge); // vtable+0x1c diff --git a/LEGO1/lego/legoomni/include/legosoundmanager.h b/LEGO1/lego/legoomni/include/legosoundmanager.h index 3d6f4c80..963f32a1 100644 --- a/LEGO1/lego/legoomni/include/legosoundmanager.h +++ b/LEGO1/lego/legoomni/include/legosoundmanager.h @@ -21,6 +21,7 @@ class LegoSoundManager : public MxSoundManager { void UpdateListener(const float* p_position, const float* p_direction, const float* p_up, const float* p_velocity); + // FUNCTION: BETA10 0x1000f350 LegoCacheSoundManager* GetCacheSoundManager() { return m_cacheSoundManager; } private: diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index e0353ba7..ef816382 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -64,7 +64,7 @@ MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_wor MxS32 UpdateLightPosition(MxS32 p_increase); void SetLightPosition(MxS32 p_index); LegoNamedTexture* ReadNamedTexture(LegoFile* p_file); -void FUN_1003f540(LegoFile* p_file, const char* p_filename); +void WriteDefaultTexture(LegoFile* p_file, const char* p_name); void WriteNamedTexture(LegoFile* p_file, LegoNamedTexture* p_namedTexture); void FUN_1003f930(LegoNamedTexture* p_namedTexture); diff --git a/LEGO1/lego/legoomni/include/legoworld.h b/LEGO1/lego/legoomni/include/legoworld.h index e2aaf8f4..7a3e6d76 100644 --- a/LEGO1/lego/legoomni/include/legoworld.h +++ b/LEGO1/lego/legoomni/include/legoworld.h @@ -193,7 +193,7 @@ class LegoWorld : public LegoEntity { // _Tree >::_Kfn,CoreSetCompare,allocator >::find // TEMPLATE: LEGO1 0x10022360 -// ?_Construct@@YAXPAPAVMxCore@@ABQAV1@@Z +// ?_Construct@@YAXPAPAVLegoPathActor@@ABQAV1@@Z // GLOBAL: LEGO1 0x100f11a0 // _Tree >::_Kfn,CoreSetCompare,allocator >::_Nil diff --git a/LEGO1/lego/legoomni/include/motorcycle.h b/LEGO1/lego/legoomni/include/motorcycle.h index 4a49ea79..a95ba705 100644 --- a/LEGO1/lego/legoomni/include/motorcycle.h +++ b/LEGO1/lego/legoomni/include/motorcycle.h @@ -24,7 +24,7 @@ class Motocycle : public IslePathActor { } MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void VTable0x70(float p_time) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 MxLong HandleClick() override; // vtable+0xcc MxLong HandleControl(LegoControlManagerNotificationParam& p_param) override; // vtable+0xd4 MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0xdc diff --git a/LEGO1/lego/legoomni/include/towtrack.h b/LEGO1/lego/legoomni/include/towtrack.h index 74f710be..822c4ecc 100644 --- a/LEGO1/lego/legoomni/include/towtrack.h +++ b/LEGO1/lego/legoomni/include/towtrack.h @@ -123,7 +123,7 @@ class TowTrack : public IslePathActor { MxLong Notify(MxParam& p_param) override; // vtable+0x04 MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void VTable0x70(float p_time) override; // vtable+0x70 + void Animate(float p_time) override; // vtable+0x70 MxLong HandleClick() override; // vtable+0xcc MxLong HandleControl(LegoControlManagerNotificationParam& p_param) override; // vtable+0xd4 MxLong HandleEndAnim(LegoEndAnimNotificationParam& p_param) override; // vtable+0xd8 diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index b97c08bc..6d0ebba6 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -1,18 +1,31 @@ #include "act2actor.h" +#include "3dmanager/lego3dmanager.h" +#include "act2main_actions.h" +#include "anim/legoanim.h" +#include "legoact2.h" +#include "legobuildingmanager.h" #include "legocachesoundmanager.h" #include "legopathcontroller.h" #include "legopathedgecontainer.h" +#include "legoplantmanager.h" +#include "legoplants.h" #include "legosoundmanager.h" +#include "legovideomanager.h" +#include "legoworld.h" #include "misc.h" +#include "mxdebug.h" #include "roi/legoroi.h" +#include "viewmanager/viewmanager.h" + +#include DECOMP_SIZE_ASSERT(Act2Actor, 0x1a8) -DECOMP_SIZE_ASSERT(Act2Actor::UnknownListStructure, 0x20) +DECOMP_SIZE_ASSERT(Act2Actor::Location, 0x20) // GLOBAL: LEGO1 0x100f0db8 // GLOBAL: BETA10 0x101dbd00 -Act2Actor::UnknownListStructure g_unk0x100f0db8[] = { +Act2Actor::Location g_brickstrLocations[] = { {{-47.92, 7.0699968, -31.58}, {-0.999664, 0.0, -0.025916}, "edg01_27", FALSE}, {{-70.393349, 8.07, 3.151935}, {-0.90653503, 0.0, 0.422131}, "int06", FALSE}, {{-47.74, 4.079995, -52.3}, {-0.98293, 0.0, -0.18398}, "edg01_08", FALSE}, @@ -26,6 +39,72 @@ Act2Actor::UnknownListStructure g_unk0x100f0db8[] = { {{-44.6, 0.1, 45.3}, {0.95, 0.0, -0.3}, "edg00_154", FALSE}, }; +// GLOBAL: LEGO1 0x100f0f1c +MxFloat g_unk0x100f0f1c = 0.0f; + +// GLOBAL: LEGO1 0x100f0f20 +// GLOBAL: BETA10 0x101dbe40 +MxBool g_unk0x100f0f20 = FALSE; + +// GLOBAL: LEGO1 0x100f0f24 +MxBool g_unk0x100f0f24 = FALSE; + +// GLOBAL: LEGO1 0x100f0f28 +// GLOBAL: BETA10 0x101dbe44 +MxBool g_unk0x100f0f28 = FALSE; + +// --- All of these are indices into g_plantInfo (0x10103180) --- + +// GLOBAL: LEGO1 0x100f0f30 +// GLOBAL: BETA10 0x101dbe48 +MxS32 g_unk0x100f0f30[] = {2, 23, 32, 66, 71, 72, 73, -1}; + +// GLOBAL: LEGO1 0x100f0f50 +// GLOBAL: BETA10 0x101dbe68 +MxS32 g_unk0x100f0f50[] = {0, 7, 16, 18, 20, 21, 34, 49, 58, 59, 63, 65, 69, 74, -1}; + +// GLOBAL: LEGO1 0x100f0f90 +// GLOBAL: BETA10 0x101dbea8 +MxS32 g_unk0x100f0f90[] = {12, 19, 24, 48, 60, -1}; + +// GLOBAL: LEGO1 0x100f0fa8 +// GLOBAL: BETA10 0x101dbec0 +MxS32 g_unk0x100f0fa8[] = {8, 15, 46, -1}; + +// GLOBAL: LEGO1 0x100f0fb8 +// GLOBAL: BETA10 0x101dbed0 +MxS32 g_unk0x100f0fb8[] = {25, 26, 28, 29, 38, 39, 42, 50, 51, 56, -1}; + +// GLOBAL: LEGO1 0x100f0fe8 +// GLOBAL: BETA10 0x101dbf00 +MxS32 g_unk0x100f0fe8[] = {3, 40, 53, 55, -1}; + +// GLOBAL: LEGO1 0x100f1000 +// GLOBAL: BETA10 0x101dbf18 +MxS32 g_unk0x100f1000[] = {22, 33, 41, 45, 67, -1}; + +// GLOBAL: LEGO1 0x100f1018 +// GLOBAL: BETA10 0x101dbf30 +MxS32 g_unk0x100f1018[] = {13, 30, 31, 62, -1}; + +// GLOBAL: LEGO1 0x100f1030 +// GLOBAL: BETA10 0x101dbf48 +MxS32 g_unk0x100f1030[] = {1, 27, 37, 44, 47, 54, 61, 64, -1}; + +// --- End of indices into g_plantInfo --- + +// GLOBAL: LEGO1 0x10102b1c +// GLOBAL: BETA10 0x10209f60 +undefined4 g_nextHeadWavIndex = 0; + +// GLOBAL: LEGO1 0x10102b20 +// GLOBAL: BETA10 0x10209f64 +undefined4 g_nextBehindWavIndex = 0; + +// GLOBAL: LEGO1 0x10102b24 +// GLOBAL: BETA10 0x10209f68 +undefined4 g_nextInterruptWavIndex = 0; + // FUNCTION: LEGO1 0x100187e0 // FUNCTION: BETA10 0x1000c7fb Act2Actor::Act2Actor() @@ -43,13 +122,13 @@ Act2Actor::Act2Actor() m_unk0x44 = 0; m_unk0x40 = 1; m_unk0x48 = 0; - m_unk0x4c = 0; + m_unk0x4c = NULL; m_unk0x38 = NULL; m_unk0x3c = 0; // Odd: The code says < 10, but there are 11 entries in the array for (MxS32 i = 0; i < 10; i++) { - g_unk0x100f0db8[i].m_unk0x1c = 0; + g_brickstrLocations[i].m_unk0x1c = FALSE; } } @@ -80,7 +159,7 @@ void Act2Actor::FUN_10018980() // FUNCTION: LEGO1 0x100189f0 // FUNCTION: BETA10 0x1000ca64 -MxResult Act2Actor::VTable0x94(LegoPathActor*, MxBool) +MxResult Act2Actor::HitActor(LegoPathActor*, MxBool) { if (m_unk0x1f == FALSE) { m_unk0x1f = TRUE; @@ -94,7 +173,7 @@ MxResult Act2Actor::VTable0x94(LegoPathActor*, MxBool) // FUNCTION: LEGO1 0x10018a20 MxResult Act2Actor::VTable0x9c() { - if (m_grec && !(m_grec->m_flags & LegoPathEdgeContainer::c_bit1)) { + if (m_grec && !m_grec->GetBit1()) { delete m_grec; m_grec = NULL; return SUCCESS; @@ -115,11 +194,186 @@ MxResult Act2Actor::VTable0x9c() } } -// STUB: LEGO1 0x10018c30 -// STUB: BETA10 0x1000cb52 -void Act2Actor::VTable0x70(float p_und) +// FUNCTION: LEGO1 0x10018c30 +// FUNCTION: BETA10 0x1000cb52 +void Act2Actor::Animate(float p_time) { - // TODO + int dummy1; // for BETA10, not sure what it is being used for + +#ifdef NDEBUG + MxFloat local48float = 0.0f; + if (g_unk0x100f0f1c != 0.0f) { + local48float = p_time - g_unk0x100f0f1c; + } + + g_unk0x100f0f1c = p_time; +#endif + + LegoAnimActor::Animate(p_time); + + if (m_unk0x44 != 0.0f && m_unk0x44 < p_time) { + SetWorldSpeed(m_unk0x28); + } + + if (m_unk0x1f) { + if (m_unk0x20 > 600.0f) { + m_unk0x1f = FALSE; + m_unk0x20 = 0; + } + else { +#ifdef NDEBUG + m_unk0x20 += local48float; +#endif + MxMatrix matrix = m_roi->GetLocal2World(); + matrix[3][1] += 3.0f; + m_roi->UpdateTransformationRelativeToParent(matrix); + +#ifdef NDEBUG + LegoROI* brickstrROI = FindROI("brickstr"); + MxMatrix brickstrMatrix = brickstrROI->GetLocal2World(); + brickstrMatrix[3][1] += 3.0f; + brickstrROI->UpdateTransformationRelativeToParent(brickstrMatrix); +#endif + return; + } + } + + if (!m_grec) { + if (m_unk0x1e == 2) { + m_unk0x1e = 0; + m_unk0x2c = m_shootAnim->GetDuration() + p_time; + m_unk0x30 = m_unk0x2c - 1300.0f; + SetWorldSpeed(0); + m_unk0x1c = FALSE; + } + else if (m_unk0x1e == 1) { + FindROI("pwrbrik")->SetVisibility(FALSE); + FindROI("debrick")->SetVisibility(FALSE); + FindROI("ray")->SetVisibility(FALSE); + m_unk0x4c = NULL; + m_unk0x1e = 2; + VTable0xa0(); + FUN_10019250(m_unk0x28 + 3, p_time + 3000.0f); + } + else if (m_unk0x1e == 0) { + if (m_unk0x40) { + m_unk0x40 = 0; + m_unk0x2c = m_shootAnim->GetDuration() + p_time; + m_unk0x30 = m_unk0x2c - 1300.0f; + } + + if (FUN_10019700(p_time) == TRUE) { + return; + } + } + else if (m_unk0x1e == 5) { + FindROI("brickstr")->SetVisibility(FALSE); + GetROI()->SetVisibility(FALSE); + CurrentWorld()->RemoveActor(this); + return; + } +#ifdef NDEBUG + else if (m_unk0x1e == 4) { + if (m_worldSpeed == 0.0f) { + return; + } + + SetWorldSpeed(0.0f); + ((LegoAct2*) CurrentWorld())->FUN_100517b0(); + return; + } +#endif + } + + if (m_unk0x1e == 5 || m_unk0x1e == 4) { + return; + } + + if (m_unk0x1e == 3) { + if (p_time - m_unk0x24 > 600.0f) { + m_unk0x1e = 2; + FUN_10019250(m_unk0x28 + 4, p_time + 15000.0f); + } + } + else { + LegoROI* roiPepper = FindROI("pepper"); + + if (roiPepper) { + ViewManager* vm = VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager(); + assert(vm); + + MxU32 inFrustum = vm->IsBoundingBoxInFrustum(m_roi->GetWorldBoundingBox()); + + if (inFrustum) { + Mx3DPointFloat local18(roiPepper->GetWorldDirection()); + Mx3DPointFloat local30(m_roi->GetWorldPosition()); + Mx3DPointFloat local60(roiPepper->GetWorldPosition()); + local30 -= local60; + local30.Unitize(); + + MxFloat dotproduct = local18.Dot(&local30, &local18); + + if (dotproduct >= 0.0) { + const MxFloat* pepperWorldPosition = roiPepper->GetWorldPosition(); + const MxFloat* worldPosition = m_roi->GetWorldPosition(); + + MxFloat distance1 = DISTSQRD3(pepperWorldPosition, worldPosition); + + if (distance1 < 75.0f) { + if (!m_unk0x1c) { + m_unk0x1c = 1; + + if (!m_unk0x1e) { + FUN_100199f0(2); + m_unk0x1e = 1; + } + else { + LegoROI* childROI = m_roi->FindChildROI("windsd", m_roi); + const MxFloat* childPosition = childROI->GetWorldPosition(); + MxFloat distance2 = DISTSQRD3(pepperWorldPosition, childPosition); + + childROI = m_roi->FindChildROI("reardr", m_roi); + childPosition = childROI->GetWorldPosition(); + MxFloat distance3 = DISTSQRD3(pepperWorldPosition, childPosition); + + if (distance3 > distance2) { + FUN_100199f0(0); + } + else +#ifdef NDEBUG + if (p_time - m_unk0x24 > 3000.0f) { +#endif + SetWorldSpeed(m_unk0x28 - 1); + m_unk0x1e = 3; + m_unk0x24 = p_time; + + if (((LegoAct2*) CurrentWorld())->FUN_100516b0() == SUCCESS) { + FUN_100199f0(1); + } +#ifdef NDEBUG + } +#endif + } + } + } + else { + if (m_unk0x1c) { + m_unk0x1c = 0; + } + } + } + } + } + } +} + +// FUNCTION: LEGO1 0x10019250 +// FUNCTION: BETA10 0x1000d45c +void Act2Actor::FUN_10019250(MxFloat p_speed, MxFloat p_param2) +{ + // The arguments have been changed from BETA10 to LEGO1 + SetWorldSpeed(p_speed); + m_unk0x44 = p_param2; } // FUNCTION: LEGO1 0x10019280 @@ -132,7 +386,7 @@ void Act2Actor::SetWorldSpeed(MxFloat p_worldSpeed) // FUNCTION: LEGO1 0x100192a0 // FUNCTION: BETA10 0x1000d4d6 -void Act2Actor::FUN_100192a0(undefined4 p_param) +void Act2Actor::FUN_100192a0(undefined4 p_location) { Mx3DPointFloat newPosition(0.0, 0.0, 0.0); Mx3DPointFloat newDirection(0.0, 0.0, 0.0); @@ -144,11 +398,11 @@ void Act2Actor::FUN_100192a0(undefined4 p_param) m_grec = new LegoPathEdgeContainer(); assert(m_grec); - newPosition = g_unk0x100f0db8[p_param].m_position; - newDirection = g_unk0x100f0db8[p_param].m_direction; - LegoPathBoundary* newBoundary = m_controller->GetPathBoundary(g_unk0x100f0db8[p_param].m_boundary); + newPosition = g_brickstrLocations[p_location].m_position; + newDirection = g_brickstrLocations[p_location].m_direction; + LegoPathBoundary* newBoundary = m_pathController->GetPathBoundary(g_brickstrLocations[p_location].m_boundary); - MxResult sts = m_controller->FUN_10048310( + MxResult sts = m_pathController->FUN_10048310( m_grec, m_roi->GetWorldPosition(), m_roi->GetWorldDirection(), @@ -274,8 +528,8 @@ MxS32 Act2Actor::VTable0xa0() undefined4 firstChoice = newLocation; - if (m_unk0x48 < 7 || g_unk0x100f0db8[m_unk0x1d].m_unk0x1c) { - while (g_unk0x100f0db8[newLocation].m_unk0x1c || m_unk0x1d == newLocation) { + if (m_unk0x48 < 7 || g_brickstrLocations[m_unk0x1d].m_unk0x1c) { + while (g_brickstrLocations[newLocation].m_unk0x1c || m_unk0x1d == newLocation) { if (newLocation == 7) { newLocation = 0; } @@ -298,6 +552,322 @@ MxS32 Act2Actor::VTable0xa0() } } +// FUNCTION: LEGO1 0x10019700 +// FUNCTION: BETA10 0x1000dd27 +MxU32 Act2Actor::FUN_10019700(MxFloat p_param) +{ + if (!m_unk0x4c) { + g_unk0x100f0f20 = FALSE; + m_unk0x4c = FUN_10019b90(&g_unk0x100f0f20); + g_unk0x100f0f24 = FALSE; + g_unk0x100f0f28 = FALSE; + } + + if (!m_unk0x4c) { + MxTrace("nothing left to destroy at location %d\n", m_unk0x1d); + m_unk0x1e = 1; + + if (m_unk0x1d == 8) { + ((LegoAct2*) CurrentWorld())->BadEnding(); + } + + return TRUE; + } + + if (!g_unk0x100f0f28 && m_unk0x30 < p_param) { + g_unk0x100f0f28 = TRUE; + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play(m_unk0x38, "brickstr", FALSE); + + if (g_unk0x100f0f20) { + BuildingManager()->ScheduleAnimation(m_unk0x4c, 800, TRUE, FALSE); + } + else { + PlantManager()->ScheduleAnimation(m_unk0x4c, 800); + } + } + + if (m_unk0x2c < p_param) { + g_unk0x100f0f20 = FALSE; + m_unk0x4c = FUN_10019b90(&g_unk0x100f0f20); + m_unk0x2c = m_shootAnim->GetDuration() + p_param; + m_unk0x30 = m_unk0x2c - 1300.0f; + g_unk0x100f0f24 = FALSE; + g_unk0x100f0f28 = FALSE; + return FALSE; + } + + m_lastTime = p_param; + LegoROI* brickstrROI = FindROI("brickstr"); + + MxMatrix matrix = m_roi->GetLocal2World(); + matrix[3][1] += 1.0f; + brickstrROI->FUN_100a58f0(matrix); + brickstrROI->VTable0x14(); + + Vector3 col0(matrix[0]); + Vector3 col1(matrix[1]); + Vector3 col2(matrix[2]); + Vector3 col3(matrix[3]); + + col2 = col3; + col2 -= m_unk0x4c->GetROI()->GetWorldPosition(); + col2.Unitize(); + col0.EqualsCross(&col1, &col2); + col0.Unitize(); + col1.EqualsCross(&col2, &col0); + + assert(!m_cameraFlag); + + LegoTreeNode* root = m_shootAnim->GetAnimTreePtr()->GetRoot(); + MxFloat time = p_param - (m_unk0x2c - m_shootAnim->GetDuration()); + + for (MxS32 i = 0; i < root->GetNumChildren(); i++) { + LegoROI::FUN_100a8e80(root->GetChild(i), matrix, time, m_shootAnim->GetROIMap()); + } + + return FALSE; +} + +// FUNCTION: LEGO1 0x100199f0 +// FUNCTION: BETA10 0x1000e11a +void Act2Actor::FUN_100199f0(MxS8 p_param) +{ + switch (p_param) { + case 0: + switch (g_nextHeadWavIndex) { + case 0: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VOhead0_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + + g_nextHeadWavIndex++; + break; + default: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VOhead1_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + g_nextHeadWavIndex = 0; + break; + } + break; + case 1: + switch (g_nextBehindWavIndex) { + case 0: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VObehind0_PlayWav, FALSE, TRUE, NULL, NULL, NULL); + g_nextBehindWavIndex++; + break; + case 1: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VObehind1_PlayWav, FALSE, TRUE, NULL, NULL, NULL); + g_nextBehindWavIndex++; + break; + case 2: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VObehind2_PlayWav, FALSE, TRUE, NULL, NULL, NULL); + g_nextBehindWavIndex++; + break; + default: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VObehind3_PlayWav, FALSE, TRUE, NULL, NULL, NULL); + g_nextBehindWavIndex = 0; + break; + } + break; + case 2: + switch (g_nextInterruptWavIndex) { + case 0: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VOinterrupt0_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + g_nextInterruptWavIndex++; + break; + case 1: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VOinterrupt1_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + g_nextInterruptWavIndex++; + break; + case 2: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VOinterrupt2_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + g_nextInterruptWavIndex++; + break; + default: + ((LegoAct2*) CurrentWorld()) + ->FUN_10052560(Act2mainScript::c_VOinterrupt3_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + g_nextInterruptWavIndex = 0; + break; + } + } +} + +// FUNCTION: LEGO1 0x10019b90 +// FUNCTION: BETA10 0x1000e374 +LegoEntity* Act2Actor::FUN_10019b90(MxBool* p_param) +{ + MxS32 i; + LegoBuildingInfo* buildingInfo = BuildingManager()->GetInfoArray(i); + LegoPlantInfo* plantInfo = PlantManager()->GetInfoArray(i); + LegoEntity* result = 0; + + switch (m_unk0x1d) { + case 0: + if (buildingInfo[12].m_unk0x11) { + result = buildingInfo[12].m_entity; + *p_param = TRUE; + } + else if (buildingInfo[14].m_unk0x11) { + result = buildingInfo[14].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f0f30[i] != -1; i++) { + if (plantInfo[g_unk0x100f0f30[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f0f30[i]].m_entity; + break; + } + } + } + break; + case 1: + if (buildingInfo[13].m_unk0x11) { + result = buildingInfo[13].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f0f50[i] != -1; i++) { + if (plantInfo[g_unk0x100f0f50[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f0f50[i]].m_entity; + break; + } + } + } + break; + case 2: + if (buildingInfo[9].m_unk0x11) { + result = buildingInfo[9].m_entity; + *p_param = TRUE; + } + else if (buildingInfo[11].m_unk0x11) { + result = buildingInfo[11].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f0f90[i] != -1; i++) { + if (plantInfo[g_unk0x100f0f90[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f0f90[i]].m_entity; + break; + } + } + } + break; + case 3: + if (buildingInfo[7].m_unk0x11) { + result = buildingInfo[7].m_entity; + *p_param = TRUE; + } + else if (buildingInfo[8].m_unk0x11) { + result = buildingInfo[8].m_entity; + *p_param = TRUE; + } + else if (buildingInfo[3].m_unk0x11) { + result = buildingInfo[3].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f0fa8[i] != -1; i++) { + if (plantInfo[g_unk0x100f0fa8[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f0fa8[i]].m_entity; + break; + } + } + } + break; + case 4: + if (buildingInfo[5].m_unk0x11) { + result = buildingInfo[5].m_entity; + *p_param = TRUE; + } + else if (buildingInfo[10].m_unk0x11) { + result = buildingInfo[10].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f0fb8[i] != -1; i++) { + if (plantInfo[g_unk0x100f0fb8[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f0fb8[i]].m_entity; + break; + } + } + } + break; + case 5: + if (buildingInfo[4].m_unk0x11) { + result = buildingInfo[4].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f0fe8[i] != -1; i++) { + if (plantInfo[g_unk0x100f0fe8[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f0fe8[i]].m_entity; + break; + } + } + } + break; + case 6: + if (buildingInfo[2].m_unk0x11) { + result = buildingInfo[2].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f1000[i] != -1; i++) { + if (plantInfo[g_unk0x100f1000[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f1000[i]].m_entity; + break; + } + } + } + break; + case 7: + if (buildingInfo[6].m_unk0x11) { + result = buildingInfo[6].m_entity; + *p_param = TRUE; + } + else { + for (i = 0; g_unk0x100f1018[i] != -1; i++) { + if (plantInfo[g_unk0x100f1018[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f1018[i]].m_entity; + break; + } + } + } + break; + case 8: + for (i = 0; g_unk0x100f1030[i] != -1; i++) { + if (plantInfo[g_unk0x100f1030[i]].m_unk0x16) { + result = plantInfo[g_unk0x100f1030[i]].m_entity; + break; + } + } + + if (result) { + return result; + } + + if (buildingInfo[15].m_unk0x11) { + result = buildingInfo[15].m_entity; + *p_param = TRUE; + } + break; + } + + if (!result && !g_brickstrLocations[m_unk0x1d].m_unk0x1c) { + g_brickstrLocations[m_unk0x1d].m_unk0x1c = TRUE; + m_unk0x48++; + } + + return result; +} + // FUNCTION: LEGO1 0x1001a180 MxS32 Act2Actor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) { diff --git a/LEGO1/lego/legoomni/src/actors/act2genactor.cpp b/LEGO1/lego/legoomni/src/actors/act2genactor.cpp index fa66335e..0a2ef3ba 100644 --- a/LEGO1/lego/legoomni/src/actors/act2genactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2genactor.cpp @@ -14,7 +14,7 @@ MxLong Act2GenActor::g_lastHitActorTime = 0; // FUNCTION: LEGO1 0x10018740 // FUNCTION: BETA10 0x1000c7a0 -MxResult Act2GenActor::VTable0x94(LegoPathActor* p_actor, MxBool) +MxResult Act2GenActor::HitActor(LegoPathActor* p_actor, MxBool) { MxLong time = Timer()->GetTime(); MxLong diff = time - g_lastHitActorTime; diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 7756cb45..7526846d 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -1,8 +1,86 @@ #include "act3actors.h" +#include "act3.h" +#include "act3ammo.h" +#include "define.h" +#include "legocachesoundmanager.h" +#include "legolocomotionanimpresenter.h" +#include "legopathedgecontainer.h" +#include "legosoundmanager.h" +#include "misc.h" +#include "mxmisc.h" +#include "mxtimer.h" +#include "mxutilities.h" #include "roi/legoroi.h" +#include + DECOMP_SIZE_ASSERT(Act3Actor, 0x178) +DECOMP_SIZE_ASSERT(Act3Cop, 0x188) +DECOMP_SIZE_ASSERT(Act3Cop::Act3CopDest, 0x20) +DECOMP_SIZE_ASSERT(Act3Brickster, 0x1b4) +DECOMP_SIZE_ASSERT(Act3Shark, 0x1a8) + +// name verified by BETA10 0x10018776 +// GLOBAL: LEGO1 0x100f4120 +// GLOBAL: BETA10 0x101dcdc8 +Act3Actor::Act3CopDest g_copDest[5] = { + {"INT38", NULL, {3.69, -1.31251, -59.231}, {-0.99601698, 0.0, -0.089166}}, + { + "EDG02_08", + NULL, + { + -96.459999, + 4.0, + 11.22, + }, + { + -0.9725, + 0.0, + -0.23, + }, + }, + { + "INT18", + NULL, + { + 28.076799, + 2.0, + 32.11, + }, + { + -0.19769999, + 0.0, + 0.98, + }, + }, + { + "INT48", + NULL, + { + 84.736, + 9.0, + -1.965, + }, + { + 0.241, + 0.0, + -0.97, + }, + }, + {"INT42", + NULL, + { + 63.76178, + 0.999993, + -77.739998, + }, + { + 0.47999999, + 0.0, + -0.87699997, + }} +}; // Initialized at LEGO1 0x1003fa20 // GLOBAL: LEGO1 0x10104ef0 @@ -15,26 +93,27 @@ Act3Actor::Act3Actor() } // FUNCTION: LEGO1 0x1003fb70 -MxU32 Act3Actor::VTable0x90(float p_float, Matrix4& p_transform) +// FUNCTION: BETA10 0x100180ab +MxU32 Act3Actor::VTable0x90(float p_time, Matrix4& p_transform) { // Note: Code duplication with LegoExtraActor::VTable0x90 - switch (m_state & 0xff) { - case 0: - case 1: + switch (m_actorState & c_maxState) { + case c_initial: + case c_one: return TRUE; - case 2: - m_unk0x1c = p_float + 2000.0f; - m_state = 3; - m_actorTime += (p_float - m_lastTime) * m_worldSpeed; - m_lastTime = p_float; + case c_two: + m_unk0x1c = p_time + 2000.0f; + m_actorState = c_three; + m_actorTime += (p_time - m_lastTime) * m_worldSpeed; + m_lastTime = p_time; return FALSE; - case 3: + case c_three: assert(!m_userNavFlag); Vector3 positionRef(p_transform[3]); p_transform = m_roi->GetLocal2World(); - if (m_unk0x1c > p_float) { + if (m_unk0x1c > p_time) { Mx3DPointFloat position; position = positionRef; @@ -42,14 +121,14 @@ MxU32 Act3Actor::VTable0x90(float p_float, Matrix4& p_transform) p_transform.RotateX(0.6); positionRef = position; - m_actorTime += (p_float - m_lastTime) * m_worldSpeed; - m_lastTime = p_float; + m_actorTime += (p_time - m_lastTime) * m_worldSpeed; + m_lastTime = p_time; VTable0x74(p_transform); return FALSE; } else { - m_state = 0; + m_actorState = c_initial; m_unk0x1c = 0; positionRef -= g_unk0x10104ef0; @@ -63,10 +142,11 @@ MxU32 Act3Actor::VTable0x90(float p_float, Matrix4& p_transform) } // FUNCTION: LEGO1 0x1003fd90 -MxResult Act3Actor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) +// FUNCTION: BETA10 0x10018328 +MxResult Act3Actor::HitActor(LegoPathActor* p_actor, MxBool p_bool) { if (!p_actor->GetUserNavFlag() && p_bool) { - if (p_actor->GetState()) { + if (p_actor->GetActorState() != c_initial) { return FAILURE; } @@ -80,8 +160,279 @@ MxResult Act3Actor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) roi->FUN_100a58f0(local2world); roi->VTable0x14(); - p_actor->SetState(c_bit2 | c_bit9); + p_actor->SetActorState(c_two | c_noCollide); } return SUCCESS; } + +// FUNCTION: LEGO1 0x1003fe30 +// FUNCTION: BETA10 0x10018412 +Act3Cop::Act3Cop() +{ + m_unk0x20 = -1.0f; + m_world = NULL; + SetActorState(c_disabled); +} + +// FUNCTION: LEGO1 0x1003ff70 +// FUNCTION: BETA10 0x10018526 +MxResult Act3Cop::HitActor(LegoPathActor* p_actor, MxBool p_bool) +{ + LegoROI* roi = p_actor->GetROI(); + + if (p_bool && !strncmp(roi->GetName(), "dammo", 5)) { + MxS32 index = -1; + if (sscanf(roi->GetName(), "dammo%d", &index) != 1) { + assert(0); + } + + assert(m_world); + ((Act3*) m_world)->EatDonut(index); + m_unk0x20 = m_lastTime + 2000; + SetWorldSpeed(6.0); + + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("eatdn", NULL, FALSE); + FUN_10040360(); + } + else { + if (((Act3*) m_world)->m_brickster->GetROI() != roi) { + if (p_bool) { + return Act3Actor::HitActor(p_actor, p_bool); + } + } + else { + ((Act3*) m_world)->GoodEnding(roi->GetLocal2World()); + } + } + + return SUCCESS; +} + +// STUB: LEGO1 0x10040060 +// STUB: BETA10 0x100186fa +void Act3Cop::ParseAction(char* p_extra) +{ + // TODO +} + +// STUB: LEGO1 0x100401f0 +void Act3Cop::Animate(float p_time) +{ + // TODO +} + +// FUNCTION: LEGO1 0x10040350 +// FUNCTION: BETA10 0x10018c4a +MxResult Act3Cop::FUN_10040350(Act3Ammo& p_ammo, const Vector3&) +{ + return FUN_10040360(); +} + +// STUB: LEGO1 0x10040360 +// STUB: BETA10 0x10018c6a +MxResult Act3Cop::FUN_10040360() +{ + // TODO + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10040d20 +// FUNCTION: BETA10 0x1001942c +MxResult Act3Cop::VTable0x9c() +{ + if (m_grec && !m_grec->GetBit1()) { + delete m_grec; + m_grec = NULL; + m_lastTime = Timer()->GetTime(); + FUN_10040360(); + return SUCCESS; + } + + return Act3Actor::VTable0x9c(); +} + +// FUNCTION: LEGO1 0x10040e10 +// FUNCTION: BETA10 0x10019516 +Act3Brickster::Act3Brickster() +{ + m_world = NULL; + m_unk0x2c = 0; + m_unk0x30 = 0; + m_shootAnim = NULL; + m_unk0x38 = 0; + m_unk0x20 = 0.0f; + m_unk0x24 = 0.0f; + m_unk0x54 = 0; + + SetActorState(c_disabled); + m_unk0x58 = 0; + + m_unk0x3c.Clear(); +} + +// FUNCTION: LEGO1 0x10040f20 +// FUNCTION: BETA10 0x10019663 +Act3Brickster::~Act3Brickster() +{ + // empty +} + +// FUNCTION: LEGO1 0x10040ff0 +// FUNCTION: BETA10 0x100196ff +void Act3Brickster::ParseAction(char* p_extra) +{ + m_world = CurrentWorld(); + + LegoAnimActor::ParseAction(p_extra); + + ((Act3*) m_world)->SetBrickster(this); + + for (MxS32 i = 0; i < m_animMaps.size(); i++) { + if (m_animMaps[i]->GetUnknown0x00() == -1.0f) { + m_shootAnim = m_animMaps[i]; + } + } + + assert(m_shootAnim); +} + +// STUB: LEGO1 0x10041050 +void Act3Brickster::Animate(float p_time) +{ + // TODO +} + +// FUNCTION: LEGO1 0x100416b0 +// FUNCTION: BETA10 0x1001a299 +MxResult Act3Brickster::HitActor(LegoPathActor* p_actor, MxBool p_bool) +{ + if (!p_bool) { + return FAILURE; + } + + Act3* a3 = (Act3*) m_world; + LegoROI* r = p_actor->GetROI(); + assert(r); + + if (a3->m_cop1->GetROI() != r && a3->m_cop2->GetROI() != r) { + if (!strncmp(r->GetName(), "pammo", 5)) { + MxS32 index = -1; + if (sscanf(r->GetName(), "pammo%d", &index) != 1) { + assert(0); + } + + assert(m_world); + + if (a3->m_pizzas[index].IsValid() && !a3->m_pizzas[index].IsBit5()) { + a3->EatPizza(index); + } + + m_unk0x38 = 2; + return SUCCESS; + } + else { + return Act3Actor::HitActor(p_actor, p_bool); + } + } + + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100417a0 +// FUNCTION: BETA10 0x1001a3cf +MxResult Act3Brickster::FUN_100417a0(Act3Ammo& p_ammo, const Vector3&) +{ + if (m_unk0x58 < 8) { + return FUN_100417c0(); + } + + return SUCCESS; +} + +// STUB: LEGO1 0x100417c0 +// STUB: BETA10 0x1001a407 +MxResult Act3Brickster::FUN_100417c0() +{ + // TODO + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10042990 +// FUNCTION: BETA10 0x1001b6e2 +void Act3Brickster::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) +{ + if (m_unk0x38 != 8) { + m_boundary->SwitchBoundary(this, p_boundary, p_edge, p_unk0xe4); + } +} + +// FUNCTION: LEGO1 0x100429d0 +// FUNCTION: BETA10 0x1001b75b +MxResult Act3Brickster::VTable0x9c() +{ + if (m_grec && !m_grec->GetBit1()) { + delete m_grec; + m_grec = NULL; + m_lastTime = Timer()->GetTime(); + return SUCCESS; + } + + return Act3Actor::VTable0x9c(); +} + +// FUNCTION: LEGO1 0x10042ab0 +Act3Shark::Act3Shark() +{ + m_unk0x2c = 0.0f; + m_unk0x28 = 0; +} + +// FUNCTION: LEGO1 0x10042ce0 +MxResult Act3Shark::FUN_10042ce0(Act3Ammo* p_ammo) +{ + p_ammo->SetBit5(TRUE); + m_unk0x1c.push_back(p_ammo); + return SUCCESS; +} + +// STUB: LEGO1 0x10042d40 +void Act3Shark::Animate(float p_time) +{ + // TODO +} + +// FUNCTION: LEGO1 0x10042f30 +void Act3Shark::ParseAction(char* p_extra) +{ + LegoPathActor::ParseAction(p_extra); + + m_world = (LegoWorld*) CurrentWorld(); + + char value[256]; + if (KeyValueStringParse(value, g_strANIMATION, p_extra)) { + char* token = strtok(value, g_parseExtraTokens); + + while (token != NULL) { + LegoLocomotionAnimPresenter* presenter = + (LegoLocomotionAnimPresenter*) m_world->Find("LegoAnimPresenter", token); + + if (presenter != NULL) { + token = strtok(NULL, g_parseExtraTokens); + + if (token != NULL) { + presenter->FUN_1006d680(this, atof(token)); + } + } + + token = strtok(NULL, g_parseExtraTokens); + } + } + + ((Act3*) m_world)->SetShark(this); + m_unk0x34 = m_animMaps[0]; + m_unk0x38 = m_unk0x34->m_roiMap[1]; + m_unk0x38->SetVisibility(FALSE); + m_world->PlaceActor(this); +} diff --git a/LEGO1/lego/legoomni/src/actors/act3ammo.cpp b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp new file mode 100644 index 00000000..97587e87 --- /dev/null +++ b/LEGO1/lego/legoomni/src/actors/act3ammo.cpp @@ -0,0 +1,480 @@ +#include "act3ammo.h" + +#include "act3.h" +#include "act3actors.h" +#include "legocachesoundmanager.h" +#include "legocharactermanager.h" +#include "legopathboundary.h" +#include "legopathcontroller.h" +#include "legosoundmanager.h" +#include "misc.h" +#include "roi/legoroi.h" + +#include +#include + +DECOMP_SIZE_ASSERT(Act3Ammo, 0x1a0) + +// Initialized at LEGO1 0x100537c0 +// GLOBAL: LEGO1 0x10104f08 +Mx3DPointFloat Act3Ammo::g_unk0x10104f08 = Mx3DPointFloat(0.0, 5.0, 0.0); + +// FUNCTION: LEGO1 0x100537f0 +// FUNCTION: BETA10 0x1001d648 +Act3Ammo::Act3Ammo() +{ + m_ammoFlag = 0; + m_world = NULL; +} + +// FUNCTION: LEGO1 0x100538a0 +// FUNCTION: BETA10 0x1001d6e7 +Act3Ammo::~Act3Ammo() +{ + Destroy(TRUE); +} + +// FUNCTION: LEGO1 0x10053900 +// FUNCTION: BETA10 0x1001d759 +void Act3Ammo::Destroy(MxBool p_fromDestructor) +{ + if (!p_fromDestructor) { + assert(0); + } + else if (m_roi != NULL) { + CharacterManager()->ReleaseActor(m_roi->GetName()); + m_roi = NULL; + } +} + +// FUNCTION: LEGO1 0x10053930 +// FUNCTION: BETA10 0x1001d7d0 +MxResult Act3Ammo::Remove() +{ + assert(IsValid()); + assert(m_roi && m_pathController); + + CharacterManager()->ReleaseActor(m_roi->GetName()); + m_roi = NULL; + + if (m_boundary != NULL) { + m_boundary->RemoveActor(this); + } + + m_pathController->RemoveActor(this); + m_ammoFlag = 0; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10053980 +// FUNCTION: BETA10 0x1001d8b3 +MxResult Act3Ammo::Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index) +{ + assert(m_ammoFlag); + char name[12]; + + if (p_isPizza) { + sprintf(name, "pammo%d", p_index); + m_roi = CharacterManager()->CreateAutoROI(name, "pizpie", FALSE); + m_roi->SetVisibility(TRUE); + + BoundingSphere sphere; + + sphere.Center()[0] = sphere.Center()[1] = sphere.Center()[2] = 0.0f; + sphere.Radius() = m_roi->GetBoundingSphere().Radius() * 2.0f; + m_roi->SetBoundingSphere(sphere); + + m_ammoFlag = c_pizza; + assert(m_roi); + } + else { + sprintf(name, "dammo%d", p_index); + m_roi = CharacterManager()->CreateAutoROI(name, "donut", FALSE); + m_roi->SetVisibility(TRUE); + + BoundingSphere sphere; + + sphere.Center()[0] = sphere.Center()[1] = sphere.Center()[2] = 0.0f; + sphere.Radius() = m_roi->GetBoundingSphere().Radius() * 5.0f; + m_roi->SetBoundingSphere(sphere); + + m_ammoFlag = c_donut; + assert(m_roi); + } + + m_world = p_world; + SetValid(TRUE); + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10053b40 +// FUNCTION: BETA10 0x1001db2a +MxResult Act3Ammo::FUN_10053b40(Vector3& p_srcLoc, Vector3& p_srcDir, Vector3& p_srcUp) +{ + assert(p_srcDir[1] != 0); + + MxFloat local1c = -(p_srcLoc[1] / p_srcDir[1]); + Mx3DPointFloat local18(p_srcDir); + Mx3DPointFloat local34; + + local18 *= local1c; + local18 += p_srcLoc; + + local34[0] = local34[2] = 0.0f; + local34[1] = -1.0f; + + m_eq[1] = p_srcUp; + m_eq[2] = p_srcLoc; + + Mx3DPointFloat local48(local34); + local48 -= m_eq[1]; + + for (MxS32 i = 0; i < 3; i++) { + if (local18[0] == p_srcLoc[0]) { + return FAILURE; + } + + m_eq[0][i] = (local48[i] * local48[i] + local48[i] * m_eq[1][i] * 2.0f) / ((local18[i] - p_srcLoc[i]) * 4.0f); + } + + assert(m_eq[0][0] > 0.000001 || m_eq[0][0] < -0.000001); + + m_unk0x19c = local48[0] / (m_eq[0][0] * 2.0f); + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10053cb0 +// FUNCTION: BETA10 0x1001ddf4 +MxResult Act3Ammo::FUN_10053cb0(LegoPathController* p_p, LegoPathBoundary* p_boundary, MxFloat p_unk0x19c) +{ + assert(p_p); + assert(IsValid()); + + if (IsPizza()) { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("shootpz", NULL, FALSE); + } + else { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("shootdn", NULL, FALSE); + } + + m_pathController = p_p; + m_boundary = p_boundary; + m_BADuration = 10000.0f; + m_unk0x19c = p_unk0x19c; + m_unk0x7c = 0.0f; + m_lastTime = -1.0f; + m_actorState = c_one; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10053d30 +// FUNCTION: BETA10 0x1001df73 +MxResult Act3Ammo::FUN_10053d30(LegoPathController* p_p, MxFloat p_unk0x19c) +{ + assert(p_p); + assert(IsValid()); + + SetBit4(TRUE); + + if (IsPizza()) { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("shootpz", NULL, FALSE); + } + else { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("shootdn", NULL, FALSE); + } + + m_pathController = p_p; + m_BADuration = 10000.0f; + m_unk0x19c = p_unk0x19c; + m_unk0x7c = 0.0f; + m_lastTime = -1.0f; + m_actorState = c_one; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10053db0 +// FUNCTION: BETA10 0x1001e0f0 +MxResult Act3Ammo::FUN_10053db0(float p_param1, const Matrix4& p_param2) +{ + float local34 = p_param1 * p_param1; + + Vector3 local14(p_param2[0]); + Vector3 local3c(p_param2[1]); + Vector3 localc(p_param2[2]); + Vector3 local30(p_param2[3]); + Mx3DPointFloat local28; + + local28 = m_eq[1]; + local28 *= p_param1; + local30 = m_eq[0]; + local30 *= local34; + local30 += local28; + local30 += m_eq[2]; + localc = m_eq[0]; + localc *= 2.0f; + localc *= p_param1; + localc += m_eq[1]; + localc *= -1.0f; + + if (localc.Unitize() != 0) { + assert(0); + return FAILURE; + } + + local14[1] = local14[2] = 0.0f; + local14[0] = 1.0f; + local3c.EqualsCross(&localc, &local14); + + if (local3c.Unitize() != 0) { + local14[0] = local14[1] = 0.0f; + local14[2] = 1.0f; + local3c.EqualsCross(&localc, &local14); + + if (local3c.Unitize() != 0) { + assert(0); + return FAILURE; + } + } + + local14.EqualsCross(&local3c, &localc); + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10054050 +// FUNCTION: BETA10 0x1001e362 +void Act3Ammo::Animate(float p_time) +{ + assert(IsValid()); + + switch (m_actorState & c_maxState) { + case c_initial: + case c_one: + break; + case c_two: + m_unk0x158 = p_time + 2000.0f; + m_actorState = c_three; + return; + case c_three: + MxMatrix transform; + Vector3 positionRef(transform[3]); + + transform = m_roi->GetLocal2World(); + + if (m_unk0x158 > p_time) { + Mx3DPointFloat position; + + position = positionRef; + positionRef.Clear(); + transform.RotateX(0.6); + positionRef = position; + m_roi->FUN_100a58f0(transform); + m_roi->VTable0x14(); + return; + } + else { + m_actorState = c_initial; + m_unk0x158 = 0; + + positionRef -= g_unk0x10104f08; + m_roi->FUN_100a58f0(transform); + m_roi->VTable0x14(); + return; + } + } + + if (m_worldSpeed <= 0.0f) { + return; + } + + if (m_lastTime < 0.0f) { + m_lastTime = p_time; + m_unk0x7c = 0.0f; + } + + MxMatrix local104; + MxMatrix local60; + + float f = (m_BADuration - m_unk0x7c) / m_worldSpeed + m_lastTime; + + undefined4 localb4 = 0; + undefined4 localbc = 0; + MxU32 local14 = FALSE; + MxU32 localb8 = FALSE; + + if (f >= p_time) { + m_actorTime = (p_time - m_lastTime) * m_worldSpeed + m_actorTime; + m_unk0x7c = (p_time - m_lastTime) * m_worldSpeed + m_unk0x7c; + m_lastTime = p_time; + } + else { + localb8 = TRUE; + m_unk0x7c = m_BADuration; + m_lastTime = p_time; + } + + local104.SetIdentity(); + + MxResult r = FUN_10053db0((m_unk0x7c / m_BADuration) * m_unk0x19c, local104); + assert(r == 0); // SUCCESS + + local60.SetIdentity(); + + if (IsPizza()) { + local60.Scale(2.0f, 2.0f, 2.0f); + } + else { + local60.Scale(5.0f, 5.0f, 5.0f); + } + + if (localb8) { + if (m_boundary != NULL) { + Vector3 local17c(local104[0]); + Vector3 local184(local104[1]); + Vector3 local174(local104[2]); + + if (IsPizza()) { + local184 = *m_boundary->GetUnknown0x14(); + local17c[0] = 1.0f; + local17c[1] = local17c[2] = 0.0f; + local174.EqualsCross(&local17c, &local184); + local174.Unitize(); + local17c.EqualsCross(&local184, &local174); + } + else { + local17c = *m_boundary->GetUnknown0x14(); + local184[0] = 1.0f; + local184[1] = local184[2] = 0.0f; + local174.EqualsCross(&local17c, &local184); + local174.Unitize(); + local184.EqualsCross(&local174, &local17c); + } + } + + m_actorState = c_initial; + } + else { + local60.RotateX(m_actorTime / 10.0f); + local60.RotateY(m_actorTime / 6.0f); + } + + MxMatrix localb0(local104); + local104.Product(local60, localb0); + m_roi->FUN_100a58f0(local104); + m_roi->VTable0x14(); + + if (m_BADuration <= m_unk0x7c) { + m_worldSpeed = 0.0f; + } + + Vector3 local68(local104[3]); + + if (localb8) { + if (IsBit4()) { + if (IsPizza()) { + m_world->RemovePizza(*this); + m_world->FUN_10072ad0(2); + } + else { + m_world->RemoveDonut(*this); + m_world->FUN_10072ad0(4); + } + } + else { + if (IsPizza()) { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("stickpz", NULL, FALSE); + } + else { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("stickdn", NULL, FALSE); + } + + LegoPathActorSet& plpas = m_boundary->GetActors(); + LegoPathActorSet lpas(plpas); + + for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) { + if (plpas.find(*itpa) != plpas.end() && this != *itpa) { + LegoROI* r = (*itpa)->GetROI(); + assert(r); + + if (!strncmp(r->GetName(), "pammo", 5)) { + Mx3DPointFloat local1c8; + Mx3DPointFloat local1b4; + + local1c8 = r->GetLocal2World()[3]; + local1b4 = m_roi->GetLocal2World()[3]; + + local1b4 -= local1c8; + + float radius = r->GetWorldBoundingSphere().Radius(); + if (local1b4.LenSquared() <= radius * radius) { + MxS32 index = -1; + if (sscanf(r->GetName(), "pammo%d", &index) != 1) { + assert(0); + } + + assert(m_world); + + if (m_world->m_pizzas[index].IsValid() && !m_world->m_pizzas[index].IsBit5()) { + m_world->EatPizza(index); + m_world->m_brickster->FUN_100417c0(); + } + + if (IsDonut()) { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("dnhitpz", NULL, FALSE); + m_world->RemoveDonut(*this); + local14 = TRUE; + break; + } + } + } + else if (!strncmp(r->GetName(), "dammo", 5)) { + Mx3DPointFloat local1f8; + Mx3DPointFloat local1e4; + + local1f8 = r->GetLocal2World()[3]; + local1e4 = m_roi->GetLocal2World()[3]; + + local1e4 -= local1f8; + + float radius = r->GetWorldBoundingSphere().Radius(); + if (local1e4.LenSquared() <= radius * radius) { + MxS32 index = -1; + if (sscanf(r->GetName(), "dammo%d", &index) != 1) { + assert(0); + } + + assert(m_world); + + m_world->EatDonut(index); + + if (IsPizza()) { + assert(SoundManager()->GetCacheSoundManager()); + SoundManager()->GetCacheSoundManager()->Play("pzhitdn", NULL, FALSE); + m_world->RemovePizza(*this); + local14 = TRUE; + break; + } + } + } + } + } + + if (!local14) { + if (IsPizza()) { + m_world->FUN_10073360(*this, local68); + } + else { + m_world->FUN_10073390(*this, local68); + } + + m_worldSpeed = -1.0f; + } + } + } +} diff --git a/LEGO1/lego/legoomni/src/actors/act3brickster.cpp b/LEGO1/lego/legoomni/src/actors/act3brickster.cpp deleted file mode 100644 index 24340578..00000000 --- a/LEGO1/lego/legoomni/src/actors/act3brickster.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "act3brickster.h" - -DECOMP_SIZE_ASSERT(Act3Brickster, 0x1b4) - -// STUB: LEGO1 0x10040e10 -Act3Brickster::Act3Brickster() -{ - // TODO -} - -// FUNCTION: LEGO1 0x10040f20 -Act3Brickster::~Act3Brickster() -{ - // TODO -} - -// STUB: LEGO1 0x10040ff0 -void Act3Brickster::ParseAction(char* p_extra) -{ - // TODO -} - -// STUB: LEGO1 0x10041050 -void Act3Brickster::VTable0x70(float p_und) -{ - // TODO -} - -// STUB: LEGO1 0x100416b0 -MxResult Act3Brickster::VTable0x94(LegoPathActor*, MxBool) -{ - // TODO - return SUCCESS; -} - -// STUB: LEGO1 0x10042990 -void Act3Brickster::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) -{ - // TODO -} - -// STUB: LEGO1 0x100429d0 -MxResult Act3Brickster::VTable0x9c() -{ - // TODO - return SUCCESS; -} diff --git a/LEGO1/lego/legoomni/src/actors/act3cop.cpp b/LEGO1/lego/legoomni/src/actors/act3cop.cpp deleted file mode 100644 index 557386ce..00000000 --- a/LEGO1/lego/legoomni/src/actors/act3cop.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "act3cop.h" - -DECOMP_SIZE_ASSERT(Act3Cop, 0x188) - -// STUB: LEGO1 0x1003fe30 -Act3Cop::Act3Cop() -{ - // TODO -} - -// STUB: LEGO1 0x1003ff70 -MxResult Act3Cop::VTable0x94(LegoPathActor*, MxBool) -{ - // TODO - return SUCCESS; -} - -// STUB: LEGO1 0x10040060 -void Act3Cop::ParseAction(char* p_extra) -{ - // TODO -} - -// STUB: LEGO1 0x100401f0 -void Act3Cop::VTable0x70(float p_und) -{ - // TODO -} - -// STUB: LEGO1 0x10040d20 -MxResult Act3Cop::VTable0x9c() -{ - // TODO - return SUCCESS; -} diff --git a/LEGO1/lego/legoomni/src/actors/act3shark.cpp b/LEGO1/lego/legoomni/src/actors/act3shark.cpp deleted file mode 100644 index 8cc9f698..00000000 --- a/LEGO1/lego/legoomni/src/actors/act3shark.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "act3shark.h" - -DECOMP_SIZE_ASSERT(Act3Shark, 0x1a8) - -// STUB: LEGO1 0x10042ab0 -Act3Shark::Act3Shark() -{ - // TODO -} - -// STUB: LEGO1 0x10042ce0 -MxResult Act3Shark::FUN_10042ce0(void*) -{ - // TODO - return SUCCESS; -} - -// STUB: LEGO1 0x10042d40 -void Act3Shark::VTable0x70(float p_float) -{ - // TODO -} - -// STUB: LEGO1 0x10042f30 -void Act3Shark::ParseAction(char*) -{ - // TODO -} diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index 92ce90a7..f89610b8 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -87,9 +87,9 @@ MxResult Ambulance::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10036300 -void Ambulance::VTable0x70(float p_time) +void Ambulance::Animate(float p_time) { - IslePathActor::VTable0x70(p_time); + IslePathActor::Animate(p_time); if (UserActor() == this) { char buf[200]; diff --git a/LEGO1/lego/legoomni/src/actors/doors.cpp b/LEGO1/lego/legoomni/src/actors/doors.cpp index 3ff0306d..1f36f91b 100644 --- a/LEGO1/lego/legoomni/src/actors/doors.cpp +++ b/LEGO1/lego/legoomni/src/actors/doors.cpp @@ -24,7 +24,7 @@ MxFloat g_unk0x100d8e84 = 6000.0f; // FUNCTION: LEGO1 0x10066100 // FUNCTION: BETA10 0x10026850 -MxResult Doors::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) +MxResult Doors::HitActor(LegoPathActor* p_actor, MxBool p_bool) { assert(m_ltDoor && m_rtDoor); @@ -40,11 +40,11 @@ MxResult Doors::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) // FUNCTION: LEGO1 0x10066190 // FUNCTION: BETA10 0x1002696b -MxFloat Doors::VTable0xcc(float p_float) +MxFloat Doors::VTable0xcc(float p_time) { MxFloat fVar1; - fVar1 = p_float - m_unk0x158; + fVar1 = p_time - m_unk0x158; if (fVar1 <= 0.0f) { return 0.0f; @@ -65,7 +65,7 @@ MxFloat Doors::VTable0xcc(float p_float) // FUNCTION: LEGO1 0x10066250 // FUNCTION: BETA10 0x10026a45 -void Doors::VTable0x70(float p_float) +void Doors::Animate(float p_time) { assert(m_ltDoor && m_rtDoor); @@ -75,12 +75,12 @@ void Doors::VTable0x70(float p_float) switch (m_unk0x154) { case 0: m_unk0x154 = 1; - m_state = 0; + m_actorState = c_initial; break; case 1: break; case 2: - float local8 = VTable0xcc(p_float); + float local8 = VTable0xcc(p_time); if (local8 > 0.0f) { MxMatrix local58(m_ltDoorLocal); @@ -102,13 +102,13 @@ void Doors::VTable0x70(float p_float) m_unk0x1f4 = local8; } - if (m_unk0x158 + g_unk0x100d8e84 < p_float) { + if (m_unk0x158 + g_unk0x100d8e84 < p_time) { m_ltDoor->FUN_100a58f0(m_ltDoorLocal); m_rtDoor->FUN_100a58f0(m_rtDoorLocal); m_ltDoor->VTable0x14(); m_rtDoor->VTable0x14(); m_unk0x154 = 1; - m_state = 0; + m_actorState = c_initial; m_unk0x1f4 = 0; } } diff --git a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp index a4504310..59890fed 100644 --- a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp +++ b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp @@ -48,9 +48,9 @@ MxResult DuneBuggy::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10067ec0 -void DuneBuggy::VTable0x70(float p_time) +void DuneBuggy::Animate(float p_time) { - IslePathActor::VTable0x70(p_time); + IslePathActor::Animate(p_time); char buf[200]; float speed = abs(m_worldSpeed); diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 1b9c0a76..e1d3571b 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -13,6 +13,7 @@ #include "legoutils.h" #include "legoworld.h" #include "misc.h" +#include "mxdebug.h" #include "mxtransitionmanager.h" #include "scripts.h" @@ -42,7 +43,7 @@ MxResult Helicopter::Create(MxDSAction& p_dsAction) m_world = CurrentWorld(); if (m_world->IsA("Act3")) { - ((Act3*) m_world)->SetUnknown420c(this); + ((Act3*) m_world)->SetHelicopter(this); } if (m_world != NULL) { @@ -133,7 +134,7 @@ MxLong Helicopter::HandleClick() ((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_copter); FUN_10015820(TRUE, 0); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, TRUE); - SetState(LegoPathActor::c_bit3); + SetActorState(c_disabled); PlayMusic(JukeboxScript::c_Jail_Music); break; case LegoGameState::e_act2: @@ -152,9 +153,10 @@ MxLong Helicopter::HandleClick() } // FUNCTION: LEGO1 0x100035e0 +// FUNCTION: BETA10 0x1002a587 MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) { - MxU32 ret = 0; + MxLong result = 0; MxAtomId script; switch (GameState()->GetCurrentAct()) { @@ -169,79 +171,98 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) break; } - if (p_param.GetUnknown0x28() == 1) { - switch (p_param.GetClickedObjectId()) { + if (p_param.m_unk0x28 == 1) { + MxU32 isPizza = FALSE; + + switch (p_param.m_clickedObjectId) { case IsleScript::c_HelicopterArms_Ctl: if (*g_act3Script == script) { ((Act3*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); } - else if (m_state->GetUnkown8() != 0) { + else if (m_state->m_unk0x08 != 0) { break; } + Exit(); GameState()->m_currentArea = LegoGameState::e_unk66; - ret = 1; + result = 1; break; case IsleScript::c_Helicopter_TakeOff_Ctl: { if (*g_act3Script == script) { break; } + Act1State* state = (Act1State*) GameState()->GetState("Act1State"); - if (m_state->GetUnkown8() == 0) { - state->SetUnknown18(4); - m_state->SetUnknown8(1); + if (m_state->m_unk0x08 == 0) { + state->m_unk0x018 = 4; + m_state->m_unk0x08 = 1; m_world->RemoveActor(this); InvokeAction(Extra::ActionType::e_start, script, IsleScript::c_HelicopterTakeOff_Anim, NULL); - SetState(0); + SetActorState(c_initial); } - ret = 1; + + result = 1; break; } case IsleScript::c_Helicopter_Land_Ctl: if (*g_act3Script == script) { break; } - if (m_state->GetUnkown8() == 2) { - m_state->SetUnknown8(3); + + if (m_state->m_unk0x08 == 2) { + m_state->m_unk0x08 = 3; m_world->RemoveActor(this); InvokeAction(Extra::ActionType::e_start, script, IsleScript::c_HelicopterLand_Anim, NULL); - SetState(LegoPathActor::c_bit3); + SetActorState(c_disabled); } - ret = 1; + + result = 1; break; case Act3Script::c_Helicopter_Pizza_Ctl: if (*g_act3Script != script) { break; } - ret = 1; - /* fall through */ + + isPizza = TRUE; case Act3Script::c_Helicopter_Donut_Ctl: if (*g_act3Script != script) { break; } + + assert(m_pathController); + if (m_world && m_world->GetCamera()) { - Mx3DPointFloat loc, dir, lookat; - loc = m_world->GetCamera()->GetWorldLocation(); - dir = m_world->GetCamera()->GetWorldDirection(); - lookat = dir; - float scale = 3; - lookat *= scale; - lookat += loc; - Mx3DPointFloat v68, v7c, v90(0, 1, 0), va4; + Mx3DPointFloat location, direction, lookat; + + location = m_world->GetCamera()->GetWorldLocation(); + direction = m_world->GetCamera()->GetWorldDirection(); + + lookat = direction; + lookat *= 3.0f; + location += lookat; + + Mx3DPointFloat v68, va4, up; + Mx3DPointFloat v90(0, 1, 0); v68 = m_world->GetCamera()->GetWorldUp(); - va4.EqualsCross(&v68, &dir); - v7c.EqualsCross(&va4, &v90); - if (ret) { - if (((Act3*) m_world)->FUN_100727e0(m_controller, loc, dir, v7c)) { + va4.EqualsCross(&v68, &direction); + up.EqualsCross(&va4, &v90); + + if (isPizza) { + if (((Act3*) m_world)->ShootPizza(m_pathController, location, direction, up) != SUCCESS) { + MxTrace("Shoot pizza failed\n"); break; } - else if (((Act3*) m_world)->FUN_10072980(m_controller, loc, dir, v7c)) { + } + else { + if (((Act3*) m_world)->ShootDonut(m_pathController, location, direction, up) != SUCCESS) { + MxTrace("Shoot donut failed\n"); break; } } } - ret = 1; + + result = 1; break; /* case Act3Script::c_Helicopter_Info_Ctl: */ case IsleScript::c_Helicopter_Info_Ctl: @@ -250,14 +271,21 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); Exit(); } - ret = 1; + else if (*g_act3Script == script) { + ((Act3*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain); + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + } + + result = 1; break; + // Unknown object ID case 0x1d: - ret = 1; + result = 1; break; } } - return ret; + + return result; } // FUNCTION: LEGO1 0x10003c20 @@ -354,16 +382,16 @@ void Helicopter::VTable0x74(Matrix4& p_transform) } // FUNCTION: LEGO1 0x10003ee0 -void Helicopter::VTable0x70(float p_float) +void Helicopter::Animate(float p_time) { MxU32 state = m_state->GetUnkown8(); switch (state) { default: - LegoPathActor::VTable0x70(p_float); + LegoPathActor::Animate(p_time); return; case 4: case 5: - float f = m_unk0x1f0 - p_float + 3000; + float f = m_unk0x1f0 - p_time + 3000; if (f >= 0) { float f2 = f / 3000 + 1; if (f2 < 0) { @@ -391,7 +419,23 @@ void Helicopter::VTable0x70(float p_float) else { ((Act3*) m_world)->FUN_10073430(); } - LegoPathActor::m_state = 4; + + LegoPathActor::m_actorState = c_disabled; } } } + +// STUB: LEGO1 0x100042a0 +void Helicopter::FUN_100042a0(const Matrix4& p_matrix) +{ + // TODO +} + +// FUNCTION: LEGO1 0x10004640 +void Helicopter::FUN_10004640(const Matrix4& p_matrix) +{ + if (m_state->m_unk0x08 != 4 && m_state->m_unk0x08 != 5) { + m_state->m_unk0x08 = 4; + FUN_100042a0(p_matrix); + } +} diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index d38117aa..470839d4 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -148,7 +148,7 @@ void IslePathActor::Exit() m_previousActor->SetLocation(GetWorldPosition(), GetWorldDirection(), GetWorldUp(), TRUE); } - m_previousActor->SetState(0); + m_previousActor->SetActorState(c_initial); GameState()->m_currentArea = LegoGameState::Area::e_unk66; } diff --git a/LEGO1/lego/legoomni/src/actors/jetski.cpp b/LEGO1/lego/legoomni/src/actors/jetski.cpp index 158df471..4db9d119 100644 --- a/LEGO1/lego/legoomni/src/actors/jetski.cpp +++ b/LEGO1/lego/legoomni/src/actors/jetski.cpp @@ -49,9 +49,9 @@ MxResult Jetski::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x1007e680 -void Jetski::VTable0x70(float p_time) +void Jetski::Animate(float p_time) { - IslePathActor::VTable0x70(p_time); + IslePathActor::Animate(p_time); char buf[200]; float speed = abs(m_worldSpeed); diff --git a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp index 94d3e0c5..1c8c73db 100644 --- a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp +++ b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp @@ -44,9 +44,9 @@ MxResult Motocycle::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10035ad0 -void Motocycle::VTable0x70(float p_time) +void Motocycle::Animate(float p_time) { - IslePathActor::VTable0x70(p_time); + IslePathActor::Animate(p_time); if (UserActor() == this) { char buf[200]; diff --git a/LEGO1/lego/legoomni/src/actors/pizza.cpp b/LEGO1/lego/legoomni/src/actors/pizza.cpp index 346153a5..fad6c10a 100644 --- a/LEGO1/lego/legoomni/src/actors/pizza.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizza.cpp @@ -202,7 +202,7 @@ void Pizza::FUN_100382b0() m_act1state->m_unk0x018 = 0; m_state->m_unk0x0c = 0; - UserActor()->SetState(0); + UserActor()->SetActorState(LegoPathActor::c_initial); g_isleFlags |= Isle::c_playMusic; AnimationManager()->EnableCamAnims(TRUE); AnimationManager()->FUN_1005f6d0(TRUE); @@ -472,7 +472,7 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam& p_param) m_state->m_unk0x0c = 4; m_state->SetUnknown0xb0(IsleScript::c_noneIsle); - UserActor()->SetState(0); + UserActor()->SetActorState(LegoPathActor::c_initial); m_skateBoard->SetUnknown0x160(TRUE); m_world->PlaceActor(m_skateBoard, "int37", 2, 0.5, 3, 0.5); diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index c329094d..08da9727 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -74,9 +74,9 @@ MxResult TowTrack::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x1004cb10 -void TowTrack::VTable0x70(float p_time) +void TowTrack::Animate(float p_time) { - IslePathActor::VTable0x70(p_time); + IslePathActor::Animate(p_time); if (UserActor() == this) { char buf[200]; diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 6b5d2d78..4b74fdf1 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -1028,7 +1028,7 @@ MxResult LegoAnimationManager::FUN_100605e0( LegoPathActor* actor = UserActor(); if (actor != NULL) { - actor->SetState(LegoPathActor::c_bit3); + actor->SetActorState(LegoPathActor::c_disabled); actor->SetWorldSpeed(0.0f); } } @@ -1592,7 +1592,7 @@ MxU16 LegoAnimationManager::FUN_10062110( { LegoPathActor* actor = (LegoPathActor*) p_roi->GetEntity(); - if (actor != NULL && actor->GetBoundary() == p_boundary && actor->GetState() == 0) { + if (actor != NULL && actor->GetBoundary() == p_boundary && actor->GetActorState() == LegoPathActor::c_initial) { if (GetViewManager()->IsBoundingBoxInFrustum(p_roi->GetWorldBoundingBox())) { Mx3DPointFloat direction(p_roi->GetWorldDirection()); @@ -2786,7 +2786,7 @@ void LegoAnimationManager::FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x LegoPathActor* actor = UserActor(); if (actor != NULL) { - actor->SetState(LegoPathActor::c_bit3); + actor->SetActorState(LegoPathActor::c_disabled); actor->SetWorldSpeed(0.0f); } diff --git a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp index ef3df418..21bad45d 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp @@ -460,7 +460,7 @@ MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time) } } - actor->SetState(0); + actor->SetActorState(LegoPathActor::c_initial); } return TRUE; diff --git a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp index 1c0245c5..9e1ddf62 100644 --- a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp @@ -221,6 +221,7 @@ char* LegoBuildingManager::g_customizeAnimFile = NULL; MxS32 g_buildingManagerConfig = 1; // GLOBAL: LEGO1 0x10104c30 +// GLOBAL: BETA10 0x10209fa0 LegoBuildingInfo g_buildingInfo[16]; // GLOBAL: LEGO1 0x100f3748 @@ -660,6 +661,7 @@ MxBool LegoBuildingManager::FUN_10030110(LegoBuildingInfo* p_data) } // FUNCTION: LEGO1 0x10030150 +// FUNCTION: BETA10 0x100644ff void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_length, MxBool p_haveSound, MxBool p_unk0x28) { m_world = CurrentWorld(); @@ -807,7 +809,7 @@ MxResult LegoBuildingManager::FUN_10030630() for (MxS32 j = 0; j < boundary->GetNumEdges(); j++) { Mx4DPointFloat* normal = boundary->GetEdgeNormal(j); - if (position.Dot(normal, &position) + (*normal)[3] < -0.001) { + if (position.Dot(normal, &position) + (*normal).index_operator(3) < -0.001) { MxTrace( "Building %d shot location (%g, %g, %g) is not in boundary %s.\n", i, @@ -824,26 +826,28 @@ MxResult LegoBuildingManager::FUN_10030630() if (g_buildingInfo[i].m_boundary != NULL) { Mx4DPointFloat& unk0x14 = *g_buildingInfo[i].m_boundary->GetUnknown0x14(); - if (position.Dot(&position, &unk0x14) + unk0x14[3] <= 0.001 && - position.Dot(&position, &unk0x14) + unk0x14[3] >= -0.001) { - continue; + if (position.Dot(&position, &unk0x14) + unk0x14.index_operator(3) > 0.001 || + position.Dot(&position, &unk0x14) + unk0x14.index_operator(3) < -0.001) { + + g_buildingInfo[i].m_y = + -((position[0] * unk0x14.index_operator(0) + unk0x14.index_operator(3) + + position[2] * unk0x14.index_operator(2)) / + unk0x14.index_operator(1)); + + MxTrace( + "Building %d shot location (%g, %g, %g) is not on plane of boundary %s...adjusting to (%g, " + "%g, " + "%g)\n", + i, + position[0], + position[1], + position[2], + g_buildingInfo[i].m_boundary->GetName(), + position[0], + g_buildingInfo[i].m_y, + position[2] + ); } - - g_buildingInfo[i].m_y = - -((unk0x14[3] + unk0x14[0] * position[0] + unk0x14[2] * position[2]) / unk0x14[1]); - - MxTrace( - "Building %d shot location (%g, %g, %g) is not on plane of boundary %s...adjusting to (%g, %g, " - "%g)\n", - i, - position[0], - position[1], - position[2], - g_buildingInfo[i].m_boundary->GetName(), - position[0], - g_buildingInfo[i].m_y, - position[2] - ); } } else { @@ -857,6 +861,7 @@ MxResult LegoBuildingManager::FUN_10030630() } // FUNCTION: LEGO1 0x10030790 +// FUNCTION: BETA10 0x10064db9 LegoBuildingInfo* LegoBuildingManager::GetInfoArray(MxS32& p_length) { if (!m_unk0x09) { @@ -889,7 +894,7 @@ void LegoBuildingManager::FUN_100307b0(LegoEntity* p_entity, MxS32 p_adjust) // FUNCTION: LEGO1 0x10030800 void LegoBuildingManager::FUN_10030800() { - for (MxS32 i = 0; i < sizeOfArray(g_buildingInfo); i++) { + for (MxU32 i = 0; i < sizeOfArray(g_buildingInfo); i++) { g_buildingInfo[i].m_initialUnk0x11 = g_buildingInfo[i].m_unk0x11; } } diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index 0c4a7314..b5c4f521 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -6,9 +6,6 @@ #include "act2policestation.h" #include "act3.h" #include "act3actors.h" -#include "act3brickster.h" -#include "act3cop.h" -#include "act3shark.h" #include "ambulance.h" #include "bike.h" #include "buildings.h" @@ -44,7 +41,6 @@ #include "legoentitypresenter.h" #include "legoflctexturepresenter.h" #include "legohideanimpresenter.h" -#include "legojetski.h" #include "legojetskiraceactor.h" #include "legoloadcachesoundpresenter.h" #include "legolocomotionanimpresenter.h" @@ -78,6 +74,7 @@ DECOMP_SIZE_ASSERT(LegoObjectFactory, 0x1c8) // FUNCTION: LEGO1 0x10006e40 +// FUNCTION: BETA10 0x1009e930 LegoObjectFactory::LegoObjectFactory() { m_idLegoEntityPresenter = MxAtomId("LegoEntityPresenter", e_exact); diff --git a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp index 5b26d576..7544b63e 100644 --- a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp @@ -8,6 +8,7 @@ #include "legoworld.h" #include "misc.h" #include "misc/legostorage.h" +#include "mxdebug.h" #include "mxmisc.h" #include "mxticklemanager.h" #include "mxtimer.h" @@ -54,6 +55,7 @@ MxU32 g_plantAnimationId[4] = {30, 33, 36, 39}; char* LegoPlantManager::g_customizeAnimFile = NULL; // GLOBAL: LEGO1 0x10103180 +// GLOBAL: BETA10 0x1020f4c0 LegoPlantInfo g_plantInfo[81]; // FUNCTION: LEGO1 0x10026220 @@ -115,6 +117,92 @@ void LegoPlantManager::Reset(MxS32 p_worldId) m_unk0x0c = 0; } +// FUNCTION: LEGO1 0x10026410 +// FUNCTION: BETA10 0x100c50e9 +MxResult LegoPlantManager::FUN_10026410() +{ + // similar to LegoBuildingManager::FUN_10030630() + + LegoWorld* world = CurrentWorld(); + + if (world == NULL) { + return FAILURE; + } + + for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) { + if (g_plantInfo[i].m_entity != NULL && g_plantInfo[i].m_name != NULL) { + g_plantInfo[i].m_boundary = world->FindPathBoundary(g_plantInfo[i].m_name); + + if (g_plantInfo[i].m_boundary != NULL) { + Mx3DPointFloat position(g_plantInfo[i].m_x, g_plantInfo[i].m_y, g_plantInfo[i].m_z); + LegoPathBoundary* boundary = g_plantInfo[i].m_boundary; + + for (MxS32 j = 0; j < boundary->GetNumEdges(); j++) { + Mx4DPointFloat* normal = boundary->GetEdgeNormal(j); + + if (position.Dot(normal, &position) + (*normal).index_operator(3) < -0.001) { + MxTrace( + "Plant %d shot location (%g, %g, %g) is not in boundary %s.\n", + i, + position[0], + position[1], + position[2], + boundary->GetName() + ); + g_plantInfo[i].m_boundary = NULL; + break; + } + } + + if (g_plantInfo[i].m_boundary != NULL) { + Mx4DPointFloat& unk0x14 = *g_plantInfo[i].m_boundary->GetUnknown0x14(); + + if (position.Dot(&position, &unk0x14) + unk0x14.index_operator(3) > 0.001 || + position.Dot(&position, &unk0x14) + unk0x14.index_operator(3) < -0.001) { + + g_plantInfo[i].m_y = + -((position[0] * unk0x14.index_operator(0) + unk0x14.index_operator(3) + + position[2] * unk0x14.index_operator(2)) / + unk0x14.index_operator(1)); + + MxTrace( + "Plant %d shot location (%g, %g, %g) is not on plane of boundary %s...adjusting to (%g, " + "%g, " + "%g)\n", + i, + position[0], + position[1], + position[2], + g_plantInfo[i].m_boundary->GetName(), + position[0], + g_plantInfo[i].m_y, + position[2] + ); + } + } + } + else { + MxTrace("Plant %d is in boundary %s that does not exist.\n", i, g_plantInfo[i].m_name); + } + } + } + + m_unk0x0c = TRUE; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10026570 +// FUNCTION: BETA10 0x100c55e0 +LegoPlantInfo* LegoPlantManager::GetInfoArray(MxS32& p_length) +{ + if (!m_unk0x0c) { + FUN_10026410(); + } + + p_length = sizeOfArray(g_plantInfo); + return g_plantInfo; +} + // FUNCTION: LEGO1 0x10026590 // FUNCTION: BETA10 0x100c561e LegoEntity* LegoPlantManager::CreatePlant(MxS32 p_index, LegoWorld* p_world, MxS32 p_worldId) @@ -633,3 +721,11 @@ void LegoPlantManager::FUN_100271b0(LegoEntity* p_entity, MxS32 p_adjust) } } } + +// FUNCTION: LEGO1 0x10027200 +void LegoPlantManager::FUN_10027200() +{ + for (MxU32 i = 0; i < sizeOfArray(g_plantInfo); i++) { + g_plantInfo[i].m_initialUnk0x16 = g_plantInfo[i].m_unk0x16; + } +} diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 463b11c1..8037b901 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -693,9 +693,75 @@ LegoNamedTexture* ReadNamedTexture(LegoFile* p_file) return namedTexture; } -// STUB: LEGO1 0x1003f540 -void FUN_1003f540(LegoFile* p_file, const char* p_filename) +// FUNCTION: LEGO1 0x1003f540 +void WriteDefaultTexture(LegoFile* p_file, const char* p_name) { + MxString name(p_name); + LegoTextureInfo* textureInfo = TextureContainer()->Get(p_name); + + if (textureInfo != NULL) { + DDSURFACEDESC desc; + LegoPaletteEntry paletteEntries[256]; + + LPDIRECTDRAWSURFACE surface = textureInfo->m_surface; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + if (surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR, NULL) == DD_OK) { + LegoImage* image = new LegoImage(desc.dwWidth, desc.dwHeight); + + if (image != NULL) { + if (desc.dwWidth == desc.lPitch) { + memcpy(desc.lpSurface, image->GetBits(), desc.dwWidth * desc.dwHeight); + } + else { + MxU8* surface = (MxU8*) desc.lpSurface; + LegoU8* bits = image->GetBits(); + + for (MxS32 i = 0; i < desc.dwHeight; i++) { + memcpy(surface, bits, desc.dwWidth); + surface += desc.lPitch; + bits += desc.dwWidth; + } + } + + surface->Unlock(desc.lpSurface); + + PALETTEENTRY entries[256]; + if (textureInfo->m_palette->GetEntries(0, 0, sizeOfArray(entries), entries) == DD_OK) { + MxS32 i; + for (i = 0; i < sizeOfArray(entries); i++) { + if (entries[i].peFlags != 0) { + break; + } + + paletteEntries[i].SetRed(entries[i].peRed); + paletteEntries[i].SetGreen(entries[i].peGreen); + paletteEntries[i].SetBlue(entries[i].peBlue); + } + + image->SetCount(i); + + if (i > 0) { + // Note: this appears to be a bug. size should be i * sizeof(LegoPaletteEntry) + memcpy(image->GetPalette(), paletteEntries, i); + } + + LegoTexture texture; + texture.SetImage(image); + + p_file->WriteString(name); + texture.Write(p_file); + } + else { + delete image; + } + } + else { + surface->Unlock(desc.lpSurface); + } + } + } } // FUNCTION: LEGO1 0x1003f8a0 diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index 5913ff74..28f6c039 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -111,14 +111,18 @@ ViewManager* GetViewManager() } // FUNCTION: LEGO1 0x100157e0 +// FUNCTION: BETA10 0x100e4b29 LegoPlantManager* PlantManager() { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->GetPlantManager(); } // FUNCTION: LEGO1 0x100157f0 +// FUNCTION: BETA10 0x100e4b70 LegoBuildingManager* BuildingManager() { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->GetBuildingManager(); } diff --git a/LEGO1/lego/legoomni/src/entity/act2brick.cpp b/LEGO1/lego/legoomni/src/entity/act2brick.cpp index c308912c..f7f47839 100644 --- a/LEGO1/lego/legoomni/src/entity/act2brick.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2brick.cpp @@ -100,14 +100,14 @@ void Act2Brick::FUN_1007a670(MxMatrix& p_param1, MxMatrix& p_param2, LegoPathBou CurrentWorld()->PlaceActor(this); p_boundary->AddActor(this); - SetState(LegoPathActor::c_bit3); + SetActorState(c_disabled); m_roi->FUN_100a58f0(p_param1); m_roi->VTable0x14(); m_roi->SetVisibility(TRUE); } // FUNCTION: LEGO1 0x1007a750 -MxResult Act2Brick::VTable0x94(LegoPathActor* p_actor, MxBool) +MxResult Act2Brick::HitActor(LegoPathActor* p_actor, MxBool) { MxLong time = Timer()->GetTime(); MxLong diff = time - g_lastHitActorTime; diff --git a/LEGO1/lego/legoomni/src/entity/legojetski.cpp b/LEGO1/lego/legoomni/src/entity/legojetski.cpp deleted file mode 100644 index 5ad8524d..00000000 --- a/LEGO1/lego/legoomni/src/entity/legojetski.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "legojetski.h" - -#include "mxmisc.h" -#include "mxnotificationmanager.h" - -DECOMP_SIZE_ASSERT(LegoJetski, 0x1dc) - -// STUB: LEGO1 0x100136a0 -void LegoJetski::SetWorldSpeed(MxFloat p_worldSpeed) -{ - // TODO -} - -// FUNCTION: LEGO1 0x100136f0 -void LegoJetski::FUN_100136f0(float p_worldSpeed) -{ - if (p_worldSpeed < 0) { - LegoCarRaceActor::m_unk0x0c = 2; - m_maxLinearVel = 0; - SetWorldSpeed(0); - } - else { - m_maxLinearVel = p_worldSpeed; - } -} - -// STUB: LEGO1 0x10013740 -void LegoJetski::VTable0x70(float p_float) -{ - // TODO -} - -// FUNCTION: LEGO1 0x10013820 -LegoJetski::LegoJetski() -{ - NotificationManager()->Register(this); -} - -// FUNCTION: LEGO1 0x10013aa0 -LegoJetski::~LegoJetski() -{ - NotificationManager()->Unregister(this); -} - -// STUB: LEGO1 0x10013bb0 -void LegoJetski::ParseAction(char*) -{ - // TODO -} - -// STUB: LEGO1 0x10013c30 -MxLong LegoJetski::Notify(MxParam& p_param) -{ - // TODO - return 0; -} - -// STUB: LEGO1 0x10013c40 -MxResult LegoJetski::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) -{ - // TODO - return 0; -} - -// STUB: LEGO1 0x10014150 -MxU32 LegoJetski::VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 -) -{ - // TODO - return 0; -} - -// STUB: LEGO1 0x100141d0 -void LegoJetski::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) -{ - // TODO -} - -// STUB: LEGO1 0x10014210 -MxResult LegoJetski::VTable0x9c() -{ - // TODO - return SUCCESS; -} diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp index 22a60c40..0ca0335f 100644 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp @@ -37,7 +37,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ Vector3* v1 = NULL; Vector3* v2 = NULL; - if (m_state == 1) { + if (m_actorState == c_one) { if (m_destEdge == LegoPathController::GetControlEdgeA(13)) { m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(13)); } @@ -45,7 +45,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(15)); } - m_state = 0; + m_actorState = c_initial; m_unk0x7c = 0; if (m_userNavFlag) { @@ -58,7 +58,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ } else { if (p_edge == LegoPathController::GetControlEdgeA(12)) { - m_state = 1; + m_actorState = c_one; if (m_worldSpeed < g_unk0x100da044) { m_worldSpeed = g_unk0x100da044; @@ -68,7 +68,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ m_boundary = LegoPathController::GetControlBoundaryA(13); } else if (p_edge == LegoPathController::GetControlEdgeA(14)) { - m_state = 1; + m_actorState = c_one; if (m_worldSpeed < g_unk0x100da044) { m_worldSpeed = g_unk0x100da044; @@ -78,7 +78,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ m_boundary = LegoPathController::GetControlBoundaryA(15); } - if (m_state == 1) { + if (m_actorState == c_one) { if (m_userNavFlag) { m_unk0xe4 = 0.5f; } @@ -119,22 +119,22 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ } // FUNCTION: LEGO1 0x10081550 -void LegoJetskiRaceActor::VTable0x70(float p_float) +void LegoJetskiRaceActor::Animate(float p_time) { if (m_unk0x0c == 0) { const LegoChar* raceState = VariableTable()->GetVariable(g_raceState); if (!stricmp(raceState, g_racing)) { m_unk0x0c = 1; - m_lastTime = p_float - 1.0f; - m_unk0x1c = p_float; + m_lastTime = p_time - 1.0f; + m_unk0x1c = p_time; } else if (!m_userNavFlag) { - LegoAnimActor::VTable0x70(m_lastTime + 1.0f); + LegoAnimActor::Animate(m_lastTime + 1.0f); } } if (m_unk0x0c == 1) { - LegoAnimActor::VTable0x70(p_float); + LegoAnimActor::Animate(p_time); } } @@ -168,9 +168,9 @@ MxU32 LegoJetskiRaceActor::VTable0x6c( if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) { if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { - VTable0x94(actor, TRUE); + HitActor(actor, TRUE); - if (actor->VTable0x94(this, FALSE) < 0) { + if (actor->HitActor(this, FALSE) < 0) { return 0; } else { diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index e16050bd..d3474ced 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -142,6 +142,7 @@ void LegoNavController::SetControlMax(int p_hMax, int p_vMax) } // FUNCTION: LEGO1 0x10054cd0 +// FUNCTION: BETA10 0x1009ad76 void LegoNavController::SetToDefaultParams() { m_deadZone = g_defdeadZone; diff --git a/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp index 6c63abd8..0cff228f 100644 --- a/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legopovcontroller.cpp @@ -106,7 +106,7 @@ MxResult LegoPointOfViewController::Create(Lego3DView* p_lego3DView) m_lego3DView = p_lego3DView; m_nav = new LegoNavController(); LegoOmni::GetInstance()->SetNavController(m_nav); - m_nav->SetTrackDefaultParams(TRUE); + m_nav->SetTrackDefault(TRUE); TickleManager()->RegisterClient(this, 10); return SUCCESS; } diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index 88023db9..2dbcce2e 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -339,6 +339,7 @@ MxResult LegoWorld::PlaceActor( } // FUNCTION: LEGO1 0x1001fc80 +// FUNCTION: BETA10 0x100da4bf void LegoWorld::RemoveActor(LegoPathActor* p_actor) { LegoPathControllerListCursor cursor(&m_list0x68); diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index af7cec1c..f51d711a 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -408,8 +408,8 @@ void LegoOmni::DeleteObject(MxDSAction& p_dsAction) // FUNCTION: BETA10 0x1008ea6d LegoROI* LegoOmni::FindROI(const char* p_name) { - ViewManager* viewManager = GetVideoManager()->Get3DManager()->GetLego3DView()->GetViewManager(); - const CompoundObject& rois = viewManager->GetROIs(); + const CompoundObject& rois = + ((LegoVideoManager*) m_videoManager)->Get3DManager()->GetLego3DView()->GetViewManager()->GetROIs(); if (p_name != NULL && *p_name != '\0' && rois.size() > 0) { for (CompoundObject::const_iterator it = rois.begin(); it != rois.end(); it++) { diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index 6ed0a8c1..66cc40e5 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -30,7 +30,7 @@ LegoAnimActorStruct::~LegoAnimActorStruct() } // FUNCTION: LEGO1 0x1001c130 -// FUNCTION: BETA10 0x1003df5f +// FUNCTION: BETA10 0x1003df3a float LegoAnimActorStruct::GetDuration() { assert(m_AnimTreePtr); @@ -70,13 +70,16 @@ void LegoAnimActor::VTable0x74(Matrix4& p_transform) } // FUNCTION: LEGO1 0x1001c290 -void LegoAnimActor::VTable0x70(float p_float) +// FUNCTION: BETA10 0x1003e144 +void LegoAnimActor::Animate(float p_time) { + assert(m_roi); + if (m_lastTime == 0) { - m_lastTime = p_float - 1.0f; + m_lastTime = p_time - 1.0f; } - if (m_state == 0 && !m_userNavFlag && m_worldSpeed <= 0) { + if (m_actorState == c_initial && !m_userNavFlag && m_worldSpeed <= 0) { if (m_curAnim >= 0) { MxMatrix matrix(m_unk0xec); float f; @@ -84,10 +87,10 @@ void LegoAnimActor::VTable0x70(float p_float) FUN_1001c360(f, matrix); } - m_lastTime = m_actorTime = p_float; + m_lastTime = m_actorTime = p_time; } else { - LegoPathActor::VTable0x70(p_float); + LegoPathActor::Animate(p_time); } } diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index ebfd17d3..b35f19f8 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -50,17 +50,17 @@ LegoExtraActor::~LegoExtraActor() // FUNCTION: LEGO1 0x1002a720 MxU32 LegoExtraActor::VTable0x90(float p_time, Matrix4& p_transform) { - switch (m_state & 0xff) { - case 0: - case 1: + switch (m_actorState & c_maxState) { + case c_initial: + case c_one: return TRUE; - case 2: + case c_two: m_scheduledTime = p_time + 2000.0f; - m_state = 3; + m_actorState = c_three; m_actorTime += (p_time - m_lastTime) * m_worldSpeed; m_lastTime = p_time; return FALSE; - case 3: { + case c_three: { Vector3 positionRef(p_transform[3]); p_transform = m_roi->GetLocal2World(); @@ -95,7 +95,7 @@ MxU32 LegoExtraActor::VTable0x90(float p_time, Matrix4& p_transform) return FALSE; } else { - m_state = 0; + m_actorState = c_initial; m_scheduledTime = 0.0f; positionRef -= g_unk0x10104c18; m_roi->FUN_100a58f0(p_transform); @@ -190,9 +190,9 @@ inline void LegoExtraActor::FUN_1002ad8a() } // FUNCTION: LEGO1 0x1002aba0 -MxResult LegoExtraActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) +MxResult LegoExtraActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) { - if (p_actor->GetState() != 0 || m_state != 0) { + if (p_actor->GetActorState() != c_initial || m_actorState != c_initial) { return FAILURE; } @@ -237,7 +237,7 @@ MxResult LegoExtraActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) VTable0xc4(); SetWorldSpeed(0); m_whichAnim = 1; - m_state = 0x101; + m_actorState = c_one | c_noCollide; } } @@ -245,7 +245,7 @@ MxResult LegoExtraActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) LegoROI* roi = m_roi; SoundManager()->GetCacheSoundManager()->Play("crash5", m_roi->GetName(), FALSE); VTable0xc4(); - m_state = 0x102; + m_actorState = c_two | c_noCollide; Mx3DPointFloat dir = p_actor->GetWorldDirection(); MxMatrix matrix3 = MxMatrix(roi->GetLocal2World()); Vector3 positionRef(matrix3[3]); @@ -328,18 +328,18 @@ void LegoExtraActor::Restart() } // FUNCTION: LEGO1 0x1002b440 -void LegoExtraActor::VTable0x70(float p_time) +void LegoExtraActor::Animate(float p_time) { LegoAnimActorStruct* laas = NULL; switch (m_whichAnim) { case 0: - LegoAnimActor::VTable0x70(p_time); + LegoAnimActor::Animate(p_time); break; case 1: if (m_scheduledTime < p_time) { m_whichAnim = 2; - m_state = 0x101; + m_actorState = c_one | c_noCollide; m_scheduledTime = m_assAnim->GetDuration() + p_time; break; } @@ -350,7 +350,7 @@ void LegoExtraActor::VTable0x70(float p_time) case 2: if (m_scheduledTime < p_time) { m_whichAnim = 0; - m_state = 0; + m_actorState = c_initial; SetWorldSpeed(m_prevWorldSpeed); m_roi->FUN_100a58f0(m_unk0x18); m_lastTime = p_time; @@ -452,7 +452,7 @@ MxU32 LegoExtraActor::VTable0x6c( if (plpas.find(*itpa) != plpas.end()) { LegoPathActor* actor = *itpa; - if (this != actor && !(actor->GetState() & LegoPathActor::c_bit9)) { + if (this != actor && !(actor->GetActorState() & LegoPathActor::c_noCollide)) { LegoROI* roi = actor->GetROI(); if ((roi != NULL && roi->GetVisibility()) || actor->GetCameraFlag()) { @@ -497,11 +497,11 @@ MxU32 LegoExtraActor::VTable0x6c( (local20X <= -0.01 && p_f1 + 0.01 <= local1cX)) { p_v3 = p_v1; - if (VTable0x94(actor, TRUE) < 0) { + if (HitActor(actor, TRUE) < 0) { return 0; } - actor->VTable0x94(this, FALSE); + actor->HitActor(this, FALSE); return 2; } } @@ -509,11 +509,11 @@ MxU32 LegoExtraActor::VTable0x6c( } else { if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { - if (VTable0x94(actor, TRUE) < 0) { + if (HitActor(actor, TRUE) < 0) { return 0; } - actor->VTable0x94(this, FALSE); + actor->HitActor(this, FALSE); return 2; } } diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 1d5bb959..9841b1c6 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -46,9 +46,9 @@ LegoPathActor::LegoPathActor() m_lastTime = 0; m_unk0x7c = 0; m_userNavFlag = FALSE; - m_state = 0; + m_actorState = c_initial; m_grec = NULL; - m_controller = NULL; + m_pathController = NULL; m_collideBox = FALSE; m_unk0x148 = 0; m_unk0x14c = 0; @@ -235,7 +235,7 @@ MxResult LegoPathActor::VTable0x84( // FUNCTION: BETA10 0x100b0520 MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) { - if (m_userNavFlag && m_state == 0) { + if (m_userNavFlag && m_actorState == c_initial) { m_lastTime = p_time; Mx3DPointFloat p1, p2, p3, p4, p5; @@ -380,13 +380,14 @@ void LegoPathActor::VTable0x74(Matrix4& p_transform) } // FUNCTION: LEGO1 0x1002e790 -void LegoPathActor::VTable0x70(float p_time) +// FUNCTION: BETA10 0x100af208 +void LegoPathActor::Animate(float p_time) { MxMatrix transform; MxU32 b = FALSE; while (m_lastTime < p_time) { - if (m_state != 0 && !VTable0x90(p_time, transform)) { + if (m_actorState != c_initial && !VTable0x90(p_time, transform)) { return; } @@ -457,13 +458,13 @@ MxU32 LegoPathActor::VTable0x6c( if (plpas.find(*itpa) != plpas.end()) { LegoPathActor* actor = *itpa; - if (this != actor && !(actor->GetState() & LegoPathActor::c_bit9)) { + if (this != actor && !(actor->GetActorState() & LegoPathActor::c_noCollide)) { LegoROI* roi = actor->GetROI(); if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) { if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->m_collideBox)) { - VTable0x94(actor, TRUE); - actor->VTable0x94(this, FALSE); + HitActor(actor, TRUE); + actor->HitActor(this, FALSE); return 2; } } @@ -608,7 +609,7 @@ MxResult LegoPathActor::VTable0x9c() local20 = 0; Mx3DPointFloat vec; - switch (m_controller->FUN_1004a240(*m_grec, local34, local48, m_unk0xe4, m_destEdge, m_boundary)) { + switch (m_pathController->FUN_1004a240(*m_grec, local34, local48, m_unk0xe4, m_destEdge, m_boundary)) { case 0: case 1: break; diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index 4fd0ace2..b17f1508 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -366,8 +366,8 @@ void LegoPathController::FUN_10046970() LegoPathActor* actor = *itpa; if (m_actors.find(actor) != m_actors.end()) { - if (!((MxU8) actor->GetState() & LegoPathActor::c_bit3)) { - actor->VTable0x70(time); + if (!((MxU8) actor->GetActorState() & LegoPathActor::c_disabled)) { + actor->Animate(time); } } } @@ -1014,3 +1014,98 @@ MxS32 LegoPathController::FUN_1004a240( p_v2.EqualsCross(p_boundary->GetUnknown0x14(), &vec); return 0; } + +// FUNCTION: LEGO1 0x1004a380 +// FUNCTION: BETA10 0x100b957f +MxResult LegoPathController::FUN_1004a380( + Vector3& p_param1, + Vector3& p_param2, + Mx3DPointFloat* p_param3, + LegoPathBoundary*& p_boundary, + MxFloat& p_param5 +) +{ + MxFloat param5 = p_param5; + Mx3DPointFloat local24; + MxU32 local8 = TRUE; + + for (MxS32 i = 0; i < m_numL; i++) { + if (m_boundaries[i].m_flags & LegoPathBoundary::c_bit3) { + continue; + } + + LegoPathBoundary* b = &m_boundaries[i]; + Mx4DPointFloat* unk0x14 = b->GetUnknown0x14(); + float local28 = p_param3[0].Dot(&p_param3[0], unk0x14); + + if (local28 < 0.001 && local28 > -0.001) { + continue; + } + + float local2c = p_param3[1].Dot(&p_param3[1], unk0x14); + float local34 = p_param3[2].Dot(&p_param3[2], unk0x14) + unk0x14->index_operator(3); + float local3c = local2c * local2c - local34 * local28 * 4.0f; + + if (local3c < -0.001) { + continue; + } + + if (local3c < 0.0f) { + local3c = 0.0f; + } + else { + local3c = sqrt(local3c); + } + + float local38 = (local3c - local2c) / (local28 * 2.0f); + float local44 = (-local3c - local2c) / (local28 * 2.0f); + + if (!IsBetween(local38, 0.0f, param5)) { + if (IsBetween(local44, 0.0f, param5)) { + local38 = local44; + } + else { + continue; + } + } + + if (local8 || FUN_100c17a0(local38, p_param5, 0.0f, param5)) { + Mx3DPointFloat local58(p_param3[0]); + + local58 *= local38 * local38; + local24 = p_param3[1]; + local24 *= local38; + local24 += p_param3[2]; + local24 += local58; + + assert(b->GetNumEdges() > 1); + + MxS32 j; + for (j = b->GetNumEdges() - 1; j >= 0; j--) { + Mx4DPointFloat* local60 = b->GetEdgeNormal(j); + + if (local24.Dot(local60, &local24) + local60->index_operator(3) < -0.001) { + break; + } + } + + if (j < 0) { + Mx3DPointFloat local74(p_param1); + local74 -= local24; + + if (local74.Dot(&local74, unk0x14) >= 0.0f) { + p_param5 = local38; + p_boundary = b; + local8 = FALSE; + } + } + } + } + + if (local8) { + p_param5 = param5; + return FAILURE; + } + + return SUCCESS; +} diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index a3f32780..c979db0b 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -154,9 +154,9 @@ MxLong CarRace::HandleEndAction(MxEndActionNotificationParam& p_param) result = 1; } else if (objectId == CarraceScript::c_irtx08ra_PlayWav && m_destLocation == LegoGameState::e_undefined) { - m_unk0x110[0]->Mute(FALSE); - m_unk0x110[1]->Mute(FALSE); - m_unk0x110[2]->Mute(FALSE); + m_maps[0]->Mute(FALSE); + m_maps[1]->Mute(FALSE); + m_maps[2]->Mute(FALSE); VariableTable()->SetVariable(g_raceState, g_racing); result = 1; @@ -200,19 +200,19 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) if (g_unk0x100f0c7c == m_unk0xf8) { VariableTable()->SetVariable(g_raceState, ""); - m_unk0x110[0]->Mute(TRUE); - m_unk0x110[1]->Mute(TRUE); - m_unk0x110[2]->Mute(TRUE); + m_maps[0]->Mute(TRUE); + m_maps[1]->Mute(TRUE); + m_maps[2]->Mute(TRUE); - m_unk0x110[0]->SetMaxLinearVel(-1.0); - m_unk0x110[1]->SetMaxLinearVel(-1.0); - m_unk0x110[2]->SetMaxLinearVel(-1.0); + m_maps[0]->SetMaxLinearVel(-1.0); + m_maps[1]->SetMaxLinearVel(-1.0); + m_maps[2]->SetMaxLinearVel(-1.0); - RemoveActor(m_unk0x110[1]); - m_unk0x110[1]->ClearMaps(); + RemoveActor(m_maps[1]); + m_maps[1]->ClearMaps(); - RemoveActor(m_unk0x110[2]); - m_unk0x110[2]->ClearMaps(); + RemoveActor(m_maps[2]); + m_maps[2]->ClearMaps(); MxS32 position; @@ -273,10 +273,10 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) m_unk0xfc++; if (g_unk0x100f0c7c == m_unk0xfc) { - m_unk0x110[1]->SetMaxLinearVel(-1.0); - RemoveActor(m_unk0x110[1]); - m_unk0x110[1]->ClearMaps(); - m_unk0x110[1]->GetROI()->SetVisibility(FALSE); + m_maps[1]->SetMaxLinearVel(-1.0); + RemoveActor(m_maps[1]); + m_maps[1]->ClearMaps(); + m_maps[1]->GetROI()->SetVisibility(FALSE); LegoROI* roi = FindROI("rcblack"); @@ -301,10 +301,10 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) m_unk0x100++; if (g_unk0x100f0c7c == m_unk0x100) { - m_unk0x110[2]->SetMaxLinearVel(-1.0); - RemoveActor(m_unk0x110[2]); - m_unk0x110[2]->ClearMaps(); - m_unk0x110[2]->GetROI()->SetVisibility(FALSE); + m_maps[2]->SetMaxLinearVel(-1.0); + RemoveActor(m_maps[2]); + m_maps[2]->ClearMaps(); + m_maps[2]->GetROI()->SetVisibility(FALSE); LegoROI* roi = FindROI("rcgreen"); diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index e2564e92..d8f9323d 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -109,9 +109,9 @@ MxLong JetskiRace::HandleEndAction(MxEndActionNotificationParam& p_param) MxLong result = 0; if ((p_param.GetAction()) && (p_param.GetAction()->GetObjectId() == JetraceScript::c_AirHorn_PlayWav)) { - m_unk0x110[0]->Mute(FALSE); - m_unk0x110[1]->Mute(FALSE); - m_unk0x110[2]->Mute(FALSE); + m_maps[0]->Mute(FALSE); + m_maps[1]->Mute(FALSE); + m_maps[2]->Mute(FALSE); VariableTable()->SetVariable(g_raceState, g_racing); result = 1; diff --git a/LEGO1/lego/legoomni/src/race/legorace.cpp b/LEGO1/lego/legoomni/src/race/legorace.cpp index 83d1eddc..c9a878ad 100644 --- a/LEGO1/lego/legoomni/src/race/legorace.cpp +++ b/LEGO1/lego/legoomni/src/race/legorace.cpp @@ -24,9 +24,9 @@ LegoRace::LegoRace() m_unk0x108 = 0; m_unk0x10c = 0; m_raceState = NULL; - m_unk0x110[0] = NULL; - m_unk0x110[1] = NULL; - m_unk0x110[2] = NULL; + m_maps[0] = NULL; + m_maps[1] = NULL; + m_maps[2] = NULL; m_unk0x128 = 0; m_unk0x12c = 0; m_pathActor = 0; diff --git a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp index e640b812..a8a7fccd 100644 --- a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp +++ b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp @@ -45,28 +45,26 @@ MxS32 LegoRaceActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) // FUNCTION: LEGO1 0x100147f0 // FUNCTION: BETA10 0x100c9c93 -MxU32 LegoRaceActor::VTable0x90(float p_float, Matrix4& p_transform) +MxU32 LegoRaceActor::VTable0x90(float p_time, Matrix4& p_transform) { // Note: Code duplication with LegoExtraActor::VTable0x90 - switch (m_state) { - case 0: - case 1: - return 1; - - case 2: - m_unk0x08 = p_float + 2000.0f; - m_state = 3; - m_actorTime += (p_float - m_lastTime) * m_worldSpeed; - m_lastTime = p_float; - return 0; - - case 3: + switch (m_actorState) { + case c_initial: + case c_one: + return TRUE; + case c_two: + m_unk0x08 = p_time + 2000.0f; + m_actorState = c_three; + m_actorTime += (p_time - m_lastTime) * m_worldSpeed; + m_lastTime = p_time; + return FALSE; + case c_three: assert(!m_userNavFlag); Vector3 positionRef(p_transform[3]); p_transform = m_roi->GetLocal2World(); - if (m_unk0x08 > p_float) { + if (m_unk0x08 > p_time) { Mx3DPointFloat position; position = positionRef; @@ -74,31 +72,31 @@ MxU32 LegoRaceActor::VTable0x90(float p_float, Matrix4& p_transform) p_transform.RotateX(0.6); positionRef = position; - m_actorTime += (p_float - m_lastTime) * m_worldSpeed; - m_lastTime = p_float; + m_actorTime += (p_time - m_lastTime) * m_worldSpeed; + m_lastTime = p_time; VTable0x74(p_transform); - return 0; + return FALSE; } else { - m_state = 0; + m_actorState = c_initial; m_unk0x08 = 0; positionRef -= g_unk0x10102b08; m_roi->FUN_100a58f0(p_transform); - return 1; + return TRUE; } } - return 0; + return FALSE; } // FUNCTION: LEGO1 0x10014a00 // FUNCTION: BETA10 0x100c9f5c -MxResult LegoRaceActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) +MxResult LegoRaceActor::HitActor(LegoPathActor* p_actor, MxBool p_bool) { if (!p_actor->GetUserNavFlag()) { - if (p_actor->GetState()) { + if (p_actor->GetActorState() != c_initial) { return FAILURE; } @@ -112,8 +110,9 @@ MxResult LegoRaceActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) roi->FUN_100a58f0(matr); - p_actor->SetState(2); + p_actor->SetActorState(c_two); } } - return 0; + + return SUCCESS; } diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index 4b12e8d7..15d6e66e 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -3,10 +3,12 @@ #include "anim/legoanim.h" #include "carrace.h" #include "define.h" +#include "jetskirace.h" #include "legocachesoundmanager.h" #include "legocameracontroller.h" #include "legonavcontroller.h" #include "legorace.h" +#include "legoracers.h" #include "legosoundmanager.h" #include "misc.h" #include "mxdebug.h" @@ -20,10 +22,12 @@ DECOMP_SIZE_ASSERT(EdgeReference, 0x08) DECOMP_SIZE_ASSERT(SkeletonKickPhase, 0x10) DECOMP_SIZE_ASSERT(LegoRaceCar, 0x200) +DECOMP_SIZE_ASSERT(LegoJetski, 0x1dc) +// name verified by BETA10 0x100cbee6 // GLOBAL: LEGO1 0x100f0a20 // GLOBAL: BETA10 0x101f5e34 -EdgeReference LegoRaceCar::g_skBMap[] = { +EdgeReference g_skBMap[] = { {// STRING: LEGO1 0x100f0a10 "EDG03_772", NULL @@ -52,28 +56,31 @@ EdgeReference LegoRaceCar::g_skBMap[] = { // GLOBAL: LEGO1 0x100f0a50 // GLOBAL: BETA10 0x101f5e60 -const SkeletonKickPhase LegoRaceCar::g_skeletonKickPhases[] = { - {&LegoRaceCar::g_skBMap[0], 0.1, 0.2, LEGORACECAR_KICK2}, - {&LegoRaceCar::g_skBMap[1], 0.2, 0.3, LEGORACECAR_KICK2}, - {&LegoRaceCar::g_skBMap[2], 0.3, 0.4, LEGORACECAR_KICK2}, - {&LegoRaceCar::g_skBMap[2], 0.6, 0.7, LEGORACECAR_KICK1}, - {&LegoRaceCar::g_skBMap[1], 0.7, 0.8, LEGORACECAR_KICK1}, - {&LegoRaceCar::g_skBMap[0], 0.8, 0.9, LEGORACECAR_KICK1}, - {&LegoRaceCar::g_skBMap[3], 0.1, 0.2, LEGORACECAR_KICK1}, - {&LegoRaceCar::g_skBMap[4], 0.2, 0.3, LEGORACECAR_KICK1}, - {&LegoRaceCar::g_skBMap[5], 0.3, 0.4, LEGORACECAR_KICK1}, - {&LegoRaceCar::g_skBMap[5], 0.6, 0.7, LEGORACECAR_KICK2}, - {&LegoRaceCar::g_skBMap[4], 0.7, 0.8, LEGORACECAR_KICK2}, - {&LegoRaceCar::g_skBMap[3], 0.8, 0.9, LEGORACECAR_KICK2}, +const SkeletonKickPhase g_skeletonKickPhases[] = { + {&g_skBMap[0], 0.1, 0.2, LEGORACECAR_KICK2}, + {&g_skBMap[1], 0.2, 0.3, LEGORACECAR_KICK2}, + {&g_skBMap[2], 0.3, 0.4, LEGORACECAR_KICK2}, + {&g_skBMap[2], 0.6, 0.7, LEGORACECAR_KICK1}, + {&g_skBMap[1], 0.7, 0.8, LEGORACECAR_KICK1}, + {&g_skBMap[0], 0.8, 0.9, LEGORACECAR_KICK1}, + {&g_skBMap[3], 0.1, 0.2, LEGORACECAR_KICK1}, + {&g_skBMap[4], 0.2, 0.3, LEGORACECAR_KICK1}, + {&g_skBMap[5], 0.3, 0.4, LEGORACECAR_KICK1}, + {&g_skBMap[5], 0.6, 0.7, LEGORACECAR_KICK2}, + {&g_skBMap[4], 0.7, 0.8, LEGORACECAR_KICK2}, + {&g_skBMap[3], 0.8, 0.9, LEGORACECAR_KICK2}, }; // the STRING is already declared at LEGO1 0x101020b8 // GLOBAL: LEGO1 0x100f0b10 -const char* LegoRaceCar::g_strSpeed = "SPEED"; +const char* g_strSpeed = "SPEED"; + +// GLOBAL: LEGO1 0x100f0b14 +const char* g_strJetSpeed = "jetSPEED"; // GLOBAL: LEGO1 0x100f0b18 // GLOBAL: BETA10 0x101f5f28 -const char* LegoRaceCar::g_srtsl18to29[] = { +const char* g_srtsl18to29[] = { "srt018sl", "srt019sl", "srt020sl", @@ -90,62 +97,80 @@ const char* LegoRaceCar::g_srtsl18to29[] = { // GLOBAL: LEGO1 0x100f0b48 // GLOBAL: BETA10 0x101f5f58 -const char* LegoRaceCar::g_srtsl6to10[] = {"srt006sl", "srt007sl", "srt008sl", "srt009sl", "srt010sl"}; +const char* g_srtsl6to10[] = {"srt006sl", "srt007sl", "srt008sl", "srt009sl", "srt010sl"}; // GLOBAL: LEGO1 0x100f0b5c // GLOBAL: BETA10 0x101f5f6c -const char* LegoRaceCar::g_emptySoundKeyList[] = {NULL}; +const char* g_emptySoundKeyList[] = {NULL}; // GLOBAL: LEGO1 0x100f0b60 // GLOBAL: BETA10 0x101f5f70 -const char* LegoRaceCar::g_srtrh[] = {"srt004rh", "srt005rh", "srt006rh"}; +const char* g_srtrh[] = {"srt004rh", "srt005rh", "srt006rh"}; // GLOBAL: LEGO1 0x100f0b6c // STRING: LEGO1 0x100f08c4 -const char* LegoRaceCar::g_srt001ra = "srt001ra"; +const char* g_srt001ra = "srt001ra"; // GLOBAL: LEGO1 0x100f0b70 // STRING: LEGO1 0x100f08bc -const char* LegoRaceCar::g_soundSkel3 = "skel3"; +const char* g_soundSkel3 = "skel3"; // GLOBAL: LEGO1 0x100f0b74 // GLOBAL: BETA10 0x101f5f80 -MxU32 LegoRaceCar::g_srtsl18to29Index = 0; +MxU32 g_srtsl18to29Index = 0; // GLOBAL: LEGO1 0x100f0b78 // GLOBAL: BETA10 0x101f5f84 -MxU32 LegoRaceCar::g_srtsl6to10Index = 0; +MxU32 g_srtsl6to10Index = 0; // GLOBAL: LEGO1 0x100f0b7c // GLOBAL: BETA10 0x101f5f88 -MxU32 LegoRaceCar::g_emptySoundKeyListIndex = 0; +MxU32 g_emptySoundKeyListIndex = 0; // GLOBAL: LEGO1 0x100f0b80 // GLOBAL: BETA10 0x101f5f8c -MxU32 LegoRaceCar::g_srtrhIndex = 0; +MxU32 g_srtrhIndex = 0; // GLOBAL: LEGO1 0x100f0b84 // GLOBAL: BETA10 0x101f5f90 -MxLong LegoRaceCar::g_timeLastSoundPlayed = 0; +MxLong g_timeLastSoundPlayed = 0; // GLOBAL: LEGO1 0x100f0b88 // GLOBAL: BETA10 0x101f5f94 -MxS32 LegoRaceCar::g_unk0x100f0b88 = 0; +MxS32 g_unk0x100f0b88 = 0; // GLOBAL: LEGO1 0x100f0b8c // GLOBAL: BETA10 0x101f5f98 -MxBool LegoRaceCar::g_unk0x100f0b8c = TRUE; +MxBool g_unk0x100f0b8c = TRUE; + +// GLOBAL: LEGO1 0x100f0b90 +const char* g_hitSnapSounds[] = { + "Svo001Sn", + "Svo002Sn", + "Svo004Sn", + "Svo005Sn", +}; + +// GLOBAL: LEGO1 0x100f0ba0 +const char* g_hitValerieSounds[] = { + "Svo001Va", + "Svo003Va", + "Svo004Va", +}; // GLOBAL: LEGO1 0x100f0bac -undefined4 LegoRaceCar::g_unk0x100f0bac = 0; +undefined4 g_hitSnapSoundsIndex = 0; // GLOBAL: LEGO1 0x100f0bb0 -undefined4 LegoRaceCar::g_unk0x100f0bb0 = 0; +undefined4 g_hitValerieSoundsIndex = 0; + +// GLOBAL: LEGO1 0x100f0bb4 +MxLong g_unk0x100f0bb4 = 0; // Initialized at LEGO1 0x10012db0 // GLOBAL: LEGO1 0x10102af0 // GLOBAL: BETA10 0x102114c0 -Mx3DPointFloat LegoRaceCar::g_unk0x10102af0 = Mx3DPointFloat(0.0f, 2.0f, 0.0f); +Mx3DPointFloat g_unk0x10102af0 = Mx3DPointFloat(0.0f, 2.0f, 0.0f); // FUNCTION: LEGO1 0x10012950 LegoRaceCar::LegoRaceCar() @@ -371,17 +396,17 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1) // FUNCTION: LEGO1 0x100131f0 // FUNCTION: BETA10 0x100cb88a -void LegoRaceCar::VTable0x70(float p_float) +void LegoRaceCar::Animate(float p_time) { if (m_userNavFlag && (m_userState == LEGORACECAR_KICK1 || m_userState == LEGORACECAR_KICK2)) { - FUN_10012ff0(p_float); + FUN_10012ff0(p_time); return; } - LegoCarRaceActor::VTable0x70(p_float); + LegoCarRaceActor::Animate(p_time); if (m_userNavFlag && m_userState == LEGORACECAR_UNKNOWN_1) { - if (HandleSkeletonKicks(p_float)) { + if (HandleSkeletonKicks(p_time)) { return; } } @@ -390,7 +415,7 @@ void LegoRaceCar::VTable0x70(float p_float) FUN_1005d4b0(); if (!m_userNavFlag) { - FUN_10080590(p_float); + FUN_10080590(p_time); return; } @@ -415,11 +440,11 @@ void LegoRaceCar::VTable0x70(float p_float) } if (absoluteSpeed != 0.0f) { - g_unk0x100f0b88 = p_float; + g_unk0x100f0b88 = p_time; g_unk0x100f0b8c = FALSE; } - if (p_float - g_unk0x100f0b88 > 5000.0f && !g_unk0x100f0b8c) { + if (p_time - g_unk0x100f0b88 > 5000.0f && !g_unk0x100f0b8c) { SoundManager()->GetCacheSoundManager()->Play(g_srt001ra, NULL, 0); g_unk0x100f0b8c = TRUE; } @@ -428,11 +453,11 @@ void LegoRaceCar::VTable0x70(float p_float) // FUNCTION: LEGO1 0x100133c0 // FUNCTION: BETA10 0x100cbb84 -MxResult LegoRaceCar::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) +MxResult LegoRaceCar::HitActor(LegoPathActor* p_actor, MxBool p_bool) { - // Note: Code duplication with LegoRaceActor::VTable0x94 + // Note: Code duplication with LegoRaceActor::HitActor if (!p_actor->GetUserNavFlag()) { - if (p_actor->GetState()) { + if (p_actor->GetActorState() != c_initial) { return FAILURE; } @@ -445,7 +470,7 @@ MxResult LegoRaceCar::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) Vector3(matr[3]) += g_unk0x10102af0; roi->FUN_100a58f0(matr); - p_actor->SetState(2); + p_actor->SetActorState(c_two); } if (m_userNavFlag) { @@ -499,6 +524,7 @@ MxResult LegoRaceCar::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) return FAILURE; } } + return SUCCESS; } @@ -542,11 +568,187 @@ MxResult LegoRaceCar::VTable0x9c() // FUNCTION: LEGO1 0x10013670 void LegoRaceCar::FUN_10013670() { - g_unk0x100f0bac = (rand() & 0xc) >> 2; + g_hitSnapSoundsIndex = (rand() & 0xc) >> 2; // Inlining the `rand()` causes this function to mismatch MxU32 uVar1 = rand(); - g_unk0x100f0bb0 = uVar1 % 0xc >> 2; + g_hitValerieSoundsIndex = uVar1 % 0xc >> 2; +} + +// FUNCTION: LEGO1 0x100136a0 +// FUNCTION: BETA10 0x100cbf7e +void LegoJetski::SetWorldSpeed(MxFloat p_worldSpeed) +{ + if (!m_userNavFlag) { + if (!LegoCarRaceActor::m_unk0x0c) { + m_maxLinearVel = p_worldSpeed; + } + LegoAnimActor::SetWorldSpeed(p_worldSpeed); + } + else { + LegoEntity::SetWorldSpeed(p_worldSpeed); + } +} + +// FUNCTION: LEGO1 0x100136f0 +// FUNCTION: BETA10 0x100cc01a +void LegoJetski::FUN_100136f0(float p_worldSpeed) +{ + if (p_worldSpeed < 0) { + LegoCarRaceActor::m_unk0x0c = 2; + m_maxLinearVel = 0; + SetWorldSpeed(0); + } + else { + m_maxLinearVel = p_worldSpeed; + } +} + +// FUNCTION: LEGO1 0x10013740 +// FUNCTION: BETA10 0x100cc0ae +void LegoJetski::Animate(float p_time) +{ + LegoJetskiRaceActor::Animate(p_time); + + if (LegoCarRaceActor::m_unk0x0c == 1) { + FUN_1005d4b0(); + + if (!m_userNavFlag) { + FUN_10080590(p_time); + return; + } + + float absoluteSpeed = abs(m_worldSpeed); + float speedRatio = absoluteSpeed / NavController()->GetMaxLinearVel(); + char buffer[200]; + + sprintf(buffer, "%g", speedRatio); + + VariableTable()->SetVariable(g_strJetSpeed, buffer); + + if (m_sound) { + m_frequencyFactor = speedRatio * 1.2 + 0.7; + } + } +} + +// FUNCTION: LEGO1 0x10013820 +LegoJetski::LegoJetski() +{ + NotificationManager()->Register(this); +} + +// FUNCTION: LEGO1 0x10013aa0 +LegoJetski::~LegoJetski() +{ + NotificationManager()->Unregister(this); +} + +// FUNCTION: LEGO1 0x10013bb0 +// FUNCTION: BETA10 0x100cc6df +void LegoJetski::ParseAction(char* p_extra) +{ + char buffer[256]; + + LegoAnimActor::ParseAction(p_extra); + LegoRaceMap::ParseAction(p_extra); + JetskiRace* currentWorld = (JetskiRace*) CurrentWorld(); + + if (KeyValueStringParse(buffer, g_strCOMP, p_extra) && currentWorld) { + currentWorld->VTable0x7c(this, atoi(buffer)); + } +} + +// FUNCTION: LEGO1 0x10013c30 +// FUNCTION: BETA10 0x100cc76a +MxLong LegoJetski::Notify(MxParam& p_param) +{ + return LegoRaceMap::Notify(p_param); +} + +// FUNCTION: LEGO1 0x10013c40 +MxResult LegoJetski::HitActor(LegoPathActor* p_actor, MxBool p_bool) +{ + // Note: very similar to LegoRaceCar::HitActor + + if (!p_actor->GetUserNavFlag()) { + if (p_actor->GetActorState() != c_initial) { + return FAILURE; + } + + if (p_bool) { + LegoROI* roi = p_actor->GetROI(); + MxMatrix matr; + matr = roi->GetLocal2World(); + + Vector3(matr[3]) += g_unk0x10102af0; + roi->FUN_100a58f0(matr); + + p_actor->SetActorState(c_two); + } + + if (m_userNavFlag) { + MxBool actorIsSnap = strcmpi(p_actor->GetROI()->GetName(), "snap") == 0; + MxBool actorIsValerie = strcmpi(p_actor->GetROI()->GetName(), "valerie") == 0; + MxLong time = Timer()->GetTime(); + + const char* soundKey = NULL; + MxLong timeElapsed = time - g_unk0x100f0bb4; + + if (timeElapsed > 3000) { + if (actorIsSnap) { + soundKey = g_hitSnapSounds[g_hitSnapSoundsIndex++]; + if (g_hitSnapSoundsIndex >= sizeOfArray(g_hitSnapSounds)) { + g_hitSnapSoundsIndex = 0; + } + } + else if (actorIsValerie) { + soundKey = g_hitValerieSounds[g_hitValerieSoundsIndex++]; + if (g_hitValerieSoundsIndex >= sizeOfArray(g_hitValerieSounds)) { + g_hitValerieSoundsIndex = 0; + } + } + + if (soundKey) { + SoundManager()->GetCacheSoundManager()->Play(soundKey, NULL, FALSE); + g_timeLastSoundPlayed = g_unk0x100f3308 = time; + } + } + + if (p_bool && m_worldSpeed != 0) { + return SUCCESS; + } + + return FAILURE; + } + } + + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10014150 +MxU32 LegoJetski::VTable0x6c( + LegoPathBoundary* p_boundary, + Vector3& p_v1, + Vector3& p_v2, + float p_f1, + float p_f2, + Vector3& p_v3 +) +{ + return LegoJetskiRaceActor::VTable0x6c(p_boundary, p_v1, p_v2, p_f1, p_f2, p_v3); +} + +// FUNCTION: LEGO1 0x100141d0 +void LegoJetski::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) +{ + LegoJetskiRaceActor::SwitchBoundary(p_boundary, p_edge, p_unk0xe4); +} + +// FUNCTION: LEGO1 0x10014210 +MxResult LegoJetski::VTable0x9c() +{ + return LegoJetskiRaceActor::VTable0x9c(); } // FUNCTION: LEGO1 0x10014500 diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp index aaabbff3..a5696b08 100644 --- a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp @@ -54,7 +54,7 @@ LegoCarRaceActor::LegoCarRaceActor() // FUNCTION: LEGO1 0x10080590 // FUNCTION: BETA10 0x100cd8cf -void LegoCarRaceActor::FUN_10080590(float p_float) +void LegoCarRaceActor::FUN_10080590(float p_time) { MxFloat maxSpeed = m_maxLinearVel; Mx3DPointFloat destEdgeUnknownVector; @@ -89,8 +89,8 @@ void LegoCarRaceActor::FUN_10080590(float p_float) } MxFloat deltaSpeed = maxSpeed - m_worldSpeed; - MxFloat changeInSpeed = (p_float - m_unk0x1c) * m_unk0x14; - m_unk0x1c = p_float; + MxFloat changeInSpeed = (p_time - m_unk0x1c) * m_unk0x14; + m_unk0x1c = p_time; if (deltaSpeed < 0.0f) { changeInSpeed = -changeInSpeed; @@ -113,7 +113,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg Mx3DPointFloat destEdgeUnknownVector; Mx3DPointFloat crossProduct; - if (m_state == 1) { + if (m_actorState == c_one) { m_boundary = NULL; // Not sure where the upper bound of 11 comes from, the underlying array has a size of 16 @@ -126,7 +126,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg assert(m_boundary); - m_state = 0; + m_actorState = c_initial; m_unk0x7c = 0; if (m_userNavFlag) { @@ -140,7 +140,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg else { for (MxS32 i = 0; i < 11; i += 2) { if (LegoPathController::GetControlEdgeA(i) == p_edge) { - m_state = 1; + m_actorState = c_one; if (m_worldSpeed < g_unk0x100f7aec) { m_worldSpeed = g_unk0x100f7aec; @@ -152,7 +152,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg } } - if (m_state == 1) { + if (m_actorState == c_one) { if (m_userNavFlag) { m_unk0xe4 = 0.5f; } @@ -214,7 +214,7 @@ void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown // FUNCTION: LEGO1 0x10080b70 // FUNCTION: BETA10 0x100cdbae -void LegoCarRaceActor::VTable0x70(float p_float) +void LegoCarRaceActor::Animate(float p_time) { // m_unk0x0c is not an MxBool, there are places where it is set to 2 or higher if (m_unk0x0c == 0) { @@ -222,13 +222,13 @@ void LegoCarRaceActor::VTable0x70(float p_float) if (strcmpi(value, g_racing) == 0) { m_unk0x0c = 1; - m_lastTime = p_float - 1.0f; - m_unk0x1c = p_float; + m_lastTime = p_time - 1.0f; + m_unk0x1c = p_time; } } if (m_unk0x0c == 1) { - LegoAnimActor::VTable0x70(p_float); + LegoAnimActor::Animate(p_time); } } @@ -333,9 +333,9 @@ MxU32 LegoCarRaceActor::VTable0x6c( p_v3, m_collideBox && actor->GetCollideBox() )) { - VTable0x94(actor, TRUE); + HitActor(actor, TRUE); - if (actor->VTable0x94(this, FALSE) < 0) { + if (actor->HitActor(this, FALSE) < 0) { return 0; } else { @@ -353,9 +353,9 @@ MxU32 LegoCarRaceActor::VTable0x6c( p_v3, m_collideBox && actor->GetCollideBox() )) { - VTable0x94(actor, TRUE); + HitActor(actor, TRUE); - if (actor->VTable0x94(this, FALSE) < 0) { + if (actor->HitActor(this, FALSE) < 0) { return 0; } else { @@ -366,8 +366,9 @@ MxU32 LegoCarRaceActor::VTable0x6c( } else { if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) { - VTable0x94(actor, TRUE); - if (actor->VTable0x94(this, FALSE) < 0) { + HitActor(actor, TRUE); + + if (actor->HitActor(this, FALSE) < 0) { return 0; } else { diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 15140eca..c827043f 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -289,6 +289,7 @@ void LegoAnimPresenter::FUN_100692b0() } // FUNCTION: LEGO1 0x100695c0 +// FUNCTION: BETA10 0x1004f359 void LegoAnimPresenter::FUN_100695c0() { m_unk0x70 = new LegoROIList(); diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index c8ec77c3..170343fd 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -1,12 +1,244 @@ #include "act3.h" +#include "3dmanager/lego3dmanager.h" +#include "act3_actions.h" +#include "act3actors.h" +#include "helicopter.h" +#include "jukebox_actions.h" +#include "legoanimationmanager.h" +#include "legobuildingmanager.h" +#include "legocontrolmanager.h" +#include "legomain.h" +#include "legonavcontroller.h" +#include "legoplantmanager.h" +#include "legoutils.h" +#include "legovideomanager.h" +#include "misc.h" +#include "mxactionnotificationparam.h" +#include "mxbackgroundaudiomanager.h" +#include "mxmisc.h" +#include "mxnotificationmanager.h" +#include "mxticklemanager.h" +#include "mxtimer.h" +#include "mxtransitionmanager.h" +#include "scripts.h" + +#include + DECOMP_SIZE_ASSERT(Act3, 0x4274) DECOMP_SIZE_ASSERT(Act3State, 0x0c) +DECOMP_SIZE_ASSERT(Act3ListElement, 0x0c) +DECOMP_SIZE_ASSERT(Act3List, 0x10) -// STUB: LEGO1 0x10072270 +// GLOBAL: LEGO1 0x100d94f8 +Act3Script::Script g_unk0x100d94f8[] = { + Act3Script::c_sns02xni_PlayWav, + Act3Script::c_sns03xni_PlayWav, + Act3Script::c_sns04xni_PlayWav, + Act3Script::c_sns05xni_PlayWav, + Act3Script::c_sns06xni_PlayWav, + Act3Script::c_sns07xni_PlayWav, + Act3Script::c_sns08xni_PlayWav, + Act3Script::c_sns09xni_PlayWav, + Act3Script::c_sns10xni_PlayWav, + Act3Script::c_sns11xni_PlayWav, + Act3Script::c_sns12xla_PlayWav, + Act3Script::c_sns13xla_PlayWav, + Act3Script::c_sns14xla_PlayWav, + Act3Script::c_sns15xla_PlayWav, + Act3Script::c_sns16xla_PlayWav, + Act3Script::c_sns17xla_PlayWav +}; + +// GLOBAL: LEGO1 0x100d9538 +Act3Script::Script g_unk0x100d9538[] = { + Act3Script::c_sns19xni_PlayWav, + Act3Script::c_sns20xni_PlayWav, + Act3Script::c_sns22xni_PlayWav, + Act3Script::c_sns23xni_PlayWav, + Act3Script::c_sns35xla_PlayWav, + (Act3Script::Script) 0 +}; + +// GLOBAL: LEGO1 0x100d9550 +Act3Script::Script g_unk0x100d9550[] = { + Act3Script::c_sns25xni_PlayWav, + Act3Script::c_sns26xni_PlayWav, + Act3Script::c_sns27xni_PlayWav, + Act3Script::c_sns28xni_PlayWav, + Act3Script::c_sns29xni_PlayWav, + Act3Script::c_sns37xla_PlayWav, + Act3Script::c_sns38xla_PlayWav, + Act3Script::c_sns39xla_PlayWav +}; + +// GLOBAL: LEGO1 0x100d9570 +Act3Script::Script g_unk0x100d9570[] = { + Act3Script::c_sns30xni_PlayWav, + Act3Script::c_sns31xni_PlayWav, + Act3Script::c_sns32xni_PlayWav, + Act3Script::c_sns40xla_PlayWav, + Act3Script::c_sns41xla_PlayWav, + Act3Script::c_sns42xla_PlayWav +}; + +// GLOBAL: LEGO1 0x100d9588 +Act3Script::Script g_unk0x100d9588[] = { + Act3Script::c_sns43xma_PlayWav, Act3Script::c_sns46xin_PlayWav, Act3Script::c_sns60xna_PlayWav, + Act3Script::c_sns52xro_PlayWav, Act3Script::c_sns58xna_PlayWav, Act3Script::c_sns68xbu_PlayWav, + Act3Script::c_sns59xna_PlayWav, Act3Script::c_sns51xin_PlayWav, Act3Script::c_sns61xva_PlayWav, + Act3Script::c_sns44xma_PlayWav, Act3Script::c_sns47xin_PlayWav, Act3Script::c_sns53xro_PlayWav, + Act3Script::c_sns45xma_PlayWav, Act3Script::c_sns69xsn_PlayWav, Act3Script::c_sns48xin_PlayWav, + Act3Script::c_sns66xsl_PlayWav, Act3Script::c_sns49xin_PlayWav, Act3Script::c_sns62xmg_PlayWav, + Act3Script::c_sns54xro_PlayWav, Act3Script::c_sns50xin_PlayWav +}; + +// GLOBAL: LEGO1 0x100d95d8 +Act3Script::Script g_unk0x100d95d8[] = { + Act3Script::c_tns080br_PlayWav, + Act3Script::c_tnsx07br_PlayWav, + Act3Script::c_snsxx2br_PlayWav, + Act3Script::c_snsy23br_PlayWav +}; + +// GLOBAL: LEGO1 0x100f7814 +MxU8 g_unk0x100f7814 = 0; + +// GLOBAL: LEGO1 0x100d95e8 +Act3Script::Script g_unk0x100d95e8[] = + {Act3Script::c_tlp053in_RunAnim, Act3Script::c_tlp064la_RunAnim, Act3Script::c_tlp068in_RunAnim}; + +// FUNCTION: LEGO1 0x10071d40 +void Act3List::Insert(MxS32 p_objectId, MxS32 p_option) +{ + if (m_unk0x0c) { + return; + } + + switch (p_option) { + case 1: + if (!empty()) { + FUN_10071fa0(); + push_back(Act3ListElement(p_objectId, p_option, FALSE)); + } + else { + InvokeAction(Extra::e_start, *g_act3Script, p_objectId, NULL); + push_back(Act3ListElement(p_objectId, p_option, TRUE)); + } + break; + case 2: + if (empty()) { + push_back(Act3ListElement(p_objectId, p_option, TRUE)); + InvokeAction(Extra::e_start, *g_act3Script, p_objectId, NULL); + } + else { + push_back(Act3ListElement(p_objectId, p_option, FALSE)); + } + break; + case 3: + if (empty()) { + push_back(Act3ListElement(p_objectId, p_option, TRUE)); + InvokeAction(Extra::e_start, *g_act3Script, p_objectId, NULL); + } + break; + } +} + +// FUNCTION: LEGO1 0x10071fa0 +void Act3List::FUN_10071fa0() +{ + DeleteAction(); +} + +// FUNCTION: LEGO1 0x10071fb0 +void Act3List::Clear() +{ + m_unk0x0c = 1; + BackgroundAudioManager()->Stop(); + + if (empty()) { + return; + } + + for (Act3List::iterator it = begin(); it != end();) { + if ((*it).m_unk0x08) { + MxDSAction ds; + ds.SetAtomId(*g_act3Script); + ds.SetObjectId((*it).m_objectId); + DeleteObject(ds); + } + + erase(it++); + } +} + +// FUNCTION: LEGO1 0x100720d0 +void Act3List::FUN_100720d0(MxU32 p_objectId) +{ + if (m_unk0x0c == 0) { + MxU32 removed = FALSE; + + if (!empty()) { + if (p_objectId != 0) { + for (Act3List::iterator it = begin(); it != end(); it++) { + if ((*it).m_unk0x08 && (*it).m_objectId == p_objectId) { + erase(it); + removed = TRUE; + break; + } + } + } + else { + pop_front(); + removed = TRUE; + } + + if (removed && size() > 0) { + // TODO: Match + Act3List::iterator it = begin(); + Act3ListElement& item = *(it++); + + for (; it != end(); it++) { + if ((*it).m_unk0x04 == 1) { + for (Act3List::iterator it2 = begin(); it2 != it;) { + if ((*it2).m_unk0x08) { + FUN_10071fa0(); + return; + } + + it2 = erase(it2); + } + } + } + + if (!item.m_unk0x08) { + item.m_unk0x08 = TRUE; + InvokeAction(Extra::e_start, *g_act3Script, item.m_objectId, NULL); + } + } + } + } +} + +// FUNCTION: LEGO1 0x10072270 +// FUNCTION: BETA10 0x10015470 Act3::Act3() { - // TODO + m_state = NULL; + m_unk0x41fc = 0; + m_cop1 = NULL; + m_cop2 = NULL; + m_brickster = NULL; + m_copter = NULL; + m_shark = NULL; + m_time = -1; + m_unk0x421e = 0; + + memset(m_helicopterDots, 0, sizeof(m_helicopterDots)); + + NavController()->ResetMaxLinearAccel(NavController()->GetMaxLinearAccel() * 30.0f); + NavController()->ResetMaxLinearDeccel(NavController()->GetMaxLinearDeccel() * 30.0f); + NotificationManager()->Register(this); } // FUNCTION: LEGO1 0x10072500 @@ -15,82 +247,696 @@ MxBool Act3::VTable0x5c() return TRUE; } -// STUB: LEGO1 0x100726a0 +// FUNCTION: LEGO1 0x100726a0 +// FUNCTION: BETA10 0x100155da Act3::~Act3() { - // TODO + Destroy(TRUE); + NotificationManager()->Unregister(this); + TickleManager()->UnregisterClient(this); } -// STUB: LEGO1 0x100727e0 -MxBool Act3::FUN_100727e0(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up) +// FUNCTION: LEGO1 0x10072780 +// FUNCTION: BETA10 0x100156ac +void Act3::EatPizza(MxS32 p_index) { - return FALSE; + assert(p_index < MAX_PIZZAS); + RemovePizza(m_pizzas[p_index]); } -// STUB: LEGO1 0x10072980 -MxBool Act3::FUN_10072980(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up) +// FUNCTION: LEGO1 0x100727a0 +// FUNCTION: BETA10 0x1001570d +void Act3::EatDonut(MxS32 p_index) { - return FALSE; + assert(p_index < MAX_DONUTS); + RemoveDonut(m_donuts[p_index]); } -// STUB: LEGO1 0x10072c30 +// FUNCTION: LEGO1 0x100727c0 +// FUNCTION: BETA10 0x1001576e +void Act3::RemovePizza(Act3Ammo& p_p) +{ +#ifdef _DEBUG + MxS32 i; + for (i = 0; i < MAX_PIZZAS; i++) { + if (&m_pizzas[i] == &p_p) { + break; + } + } + + assert(i != MAX_PIZZAS); +#endif + + assert(p_p.IsValid()); + p_p.Remove(); +} + +// FUNCTION: LEGO1 0x100727d0 +// FUNCTION: BETA10 0x10015828 +void Act3::RemoveDonut(Act3Ammo& p_p) +{ +#ifdef _DEBUG + MxS32 i; + for (i = 0; i < MAX_DONUTS; i++) { + if (&m_donuts[i] == &p_p) { + break; + } + } + + assert(i != MAX_DONUTS); +#endif + + assert(p_p.IsValid()); + p_p.Remove(); +} + +// FUNCTION: LEGO1 0x100727e0 +// FUNCTION: BETA10 0x100158e2 +MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up) +{ + MxS32 nextPizza; + for (nextPizza = 0; nextPizza < (MxS32) sizeOfArray(m_pizzas); nextPizza++) { + if (!m_pizzas[nextPizza].IsValid()) { + LegoPathBoundary* boundary = NULL; + MxU32 local18 = TRUE; + + m_pizzas[nextPizza].Create(this, TRUE, nextPizza); + + if (m_pizzas[nextPizza].FUN_10053b40(p_location, p_direction, p_up) != SUCCESS) { + return FAILURE; + } + + MxFloat unk0x19c = *m_pizzas[nextPizza].GetUnknown0x19c(); + if (p_controller->FUN_1004a380( + p_location, + p_direction, + m_pizzas[nextPizza].GetUnknown0x160(), + boundary, + unk0x19c + ) == SUCCESS) { + Mx3DPointFloat direction; + + direction = p_direction; + direction *= unk0x19c; + direction += p_location; + + assert(m_brickster && m_brickster->GetROI()); + + direction -= m_brickster->GetROI()->GetLocal2World()[3]; + + local18 = FALSE; + if (m_pizzas[nextPizza].FUN_10053cb0(p_controller, boundary, unk0x19c) == SUCCESS) { + p_controller->PlaceActor(&m_pizzas[nextPizza]); + boundary->AddActor(&m_pizzas[nextPizza]); + m_pizzas[nextPizza].SetWorldSpeed(10.0f); + return SUCCESS; + } + } + + if (local18 && m_pizzas[nextPizza].FUN_10053d30(p_controller, unk0x19c) == SUCCESS) { + p_controller->PlaceActor(&m_pizzas[nextPizza]); + m_pizzas[nextPizza].SetWorldSpeed(10.0f); + return SUCCESS; + } + + break; + } + } + + return FAILURE; +} + +// FUNCTION: LEGO1 0x10072980 +// FUNCTION: BETA10 0x10015c69 +MxResult Act3::ShootDonut(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up) +{ + MxS32 nextDonut; + for (nextDonut = 0; nextDonut < (MxS32) sizeOfArray(m_donuts); nextDonut++) { + if (!m_donuts[nextDonut].IsValid()) { + LegoPathBoundary* boundary = NULL; + + m_donuts[nextDonut].Create(this, FALSE, nextDonut); + + if (m_donuts[nextDonut].FUN_10053b40(p_location, p_direction, p_up) != SUCCESS) { + return FAILURE; + } + + MxFloat unk0x19c = *m_donuts[nextDonut].GetUnknown0x19c(); + if (p_controller->FUN_1004a380( + p_location, + p_direction, + m_donuts[nextDonut].GetUnknown0x160(), + boundary, + unk0x19c + ) == SUCCESS) { + if (m_donuts[nextDonut].FUN_10053cb0(p_controller, boundary, unk0x19c) == SUCCESS) { + p_controller->PlaceActor(&m_donuts[nextDonut]); + boundary->AddActor(&m_donuts[nextDonut]); + m_donuts[nextDonut].SetWorldSpeed(10.0f); + return SUCCESS; + } + } + else if (m_donuts[nextDonut].FUN_10053d30(p_controller, unk0x19c) == SUCCESS) { + p_controller->PlaceActor(&m_donuts[nextDonut]); + m_donuts[nextDonut].SetWorldSpeed(10.0f); + return SUCCESS; + } + } + } + + return FAILURE; +} + +// FUNCTION: LEGO1 0x10072ad0 +// FUNCTION: BETA10 0x10015eec +void Act3::FUN_10072ad0(undefined4 p_param1) +{ + float time = Timer()->GetTime(); + Act3Script::Script objectId; + + switch (p_param1) { + case 1: { + if (m_unk0x4218 >= sizeOfArray(g_unk0x100d94f8)) { + m_unk0x4218 = 0; + } + + objectId = g_unk0x100d94f8[m_unk0x4218++]; + break; + } + case 2: { + if (m_unk0x4219 >= sizeOfArray(g_unk0x100d9538) - 1) { + m_unk0x4219 = 0; + } + + objectId = g_unk0x100d9538[m_unk0x4219++]; + break; + } + case 3: { + if (m_unk0x421a >= sizeOfArray(g_unk0x100d9550)) { + m_unk0x421a = 0; + } + + objectId = g_unk0x100d9550[m_unk0x421a++]; + break; + } + case 4: { + if (m_unk0x421b >= sizeOfArray(g_unk0x100d9570)) { + m_unk0x421b = 0; + } + + objectId = g_unk0x100d9570[m_unk0x421b++]; + break; + } + case 5: { + if (m_unk0x421c >= sizeOfArray(g_unk0x100d9588)) { + m_unk0x421c = 0; + } + + objectId = g_unk0x100d9588[m_unk0x421c++]; + break; + } + case 6: { + if (m_unk0x421d >= sizeOfArray(g_unk0x100d95d8)) { + m_unk0x421d = 0; + } + + m_unk0x4220.Insert(g_unk0x100d95d8[m_unk0x421d++], 1); + return; + } + default: + return; + } + + m_unk0x4220.Insert(objectId, 3); +} + +// FUNCTION: LEGO1 0x10072c30 +// FUNCTION: BETA10 0x100160fb MxResult Act3::Create(MxDSAction& p_dsAction) { - // TODO - return SUCCESS; + GameState()->FindLoadedAct(); + + MxResult result = LegoWorld::Create(p_dsAction); + if (result == SUCCESS) { + ControlManager()->Register(this); + InputManager()->SetWorld(this); + InputManager()->Register(this); + + switch (GameState()->GetLoadedAct()) { + case LegoGameState::e_act2: + GameState()->StopArea(LegoGameState::e_infomain); + GameState()->StopArea(LegoGameState::e_act2main); + break; + case LegoGameState::e_act3: + GameState()->StopArea(LegoGameState::e_infomain); + GameState()->StopArea(LegoGameState::e_act3script); + break; + case LegoGameState::e_act1: + case LegoGameState::e_actNotFound: + GameState()->StopArea(LegoGameState::e_undefined); + if (GameState()->GetPreviousArea() == LegoGameState::e_infomain) { + GameState()->StopArea(LegoGameState::e_isle); + } + } + + LegoGameState* gameState = GameState(); + Act3State* state = (Act3State*) gameState->GetState("Act3State"); + + if (state == NULL) { + state = (Act3State*) gameState->CreateState("Act3State"); + } + + m_state = state; + assert(m_state); + + GameState()->m_currentArea = LegoGameState::e_act3script; + GameState()->SetCurrentAct(LegoGameState::e_act3); + GameState()->SetDirty(TRUE); + } + + return result; } -// STUB: LEGO1 0x10072d50 +// FUNCTION: LEGO1 0x10072d50 +// FUNCTION: BETA10 0x1001627f void Act3::Destroy(MxBool p_fromDestructor) { - // TODO + NavController()->Reset(); + ControlManager()->Unregister(this); + + if (InputManager()->GetWorld() == this) { + InputManager()->ClearWorld(); + } + + InputManager()->UnRegister(this); + + if (UserActor() != NULL) { + if ((IslePathActor*) UserActor() == m_copter) { + ((IslePathActor*) UserActor())->Exit(); + } + + Remove(UserActor()); + } + + if (!p_fromDestructor) { + LegoWorld::Destroy(FALSE); + } } -// STUB: LEGO1 0x10072de0 +// FUNCTION: LEGO1 0x10072de0 +// FUNCTION: BETA10 0x10016322 MxLong Act3::Notify(MxParam& p_param) { - // TODO + MxNotificationParam& param = (MxNotificationParam&) p_param; + LegoWorld::Notify(p_param); + + if (m_worldStarted) { + switch (param.GetNotification()) { + case c_notificationEndAction: { + MxEndActionNotificationParam& param = (MxEndActionNotificationParam&) p_param; + + if (param.GetAction() != NULL && param.GetAction()->GetAtomId() == *g_act3Script) { + if (param.GetAction()->GetObjectId() == Act3Script::c_HelicopterDashboard) { + MxDSAction action; + FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + SetAppCursor(e_cursorArrow); + VideoManager()->Get3DManager()->SetFrustrum(45.0f, 0.1f, 125.0f); + + m_brickster->SetWorldSpeed(5.0f); + m_brickster->SetActorState(LegoPathActor::c_initial); + assert(BackgroundAudioManager()); + + action.SetAtomId(*g_jukeboxScript); + action.SetObjectId(Act3Script::c_pzhitdn_PlayWav); + + BackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating); + m_brickster->FUN_100417c0(); + + m_cop1->SetActorState(LegoPathActor::c_initial); + m_cop1->SetWorldSpeed(2.0f); + m_cop1->VTable0xa8(); + + m_cop2->SetActorState(LegoPathActor::c_initial); + m_cop2->SetWorldSpeed(2.0f); + m_cop2->VTable0xa8(); + + m_brickster->VTable0xa8(); + + m_unk0x4218 = 0; + m_unk0x4219 = 0; + m_unk0x421a = 0; + m_unk0x421b = 0; + m_unk0x421c = 0; + m_unk0x421d = 0; + + MxS32 length; + LegoBuildingInfo* info = BuildingManager()->GetInfoArray(length); + m_unk0x421e = 0; + + while (--length >= 0) { + if (info[length].m_unk0x11 < 0 && info[length].m_boundary != NULL && + info[length].m_entity != NULL) { + m_unk0x421e++; + } + } + + length = 0; + m_unk0x421e--; + char buf[80]; + + do { + sprintf(buf, "HelicopterDotOn%d_Bitmap", length + 1); + m_helicopterDots[length] = (MxPresenter*) Find("MxPresenter", buf); + + if (m_unk0x421e > length) { + m_helicopterDots[length]->Enable(TRUE); + } + else { + m_helicopterDots[length]->Enable(FALSE); + } + + length++; + } while (length < (MxS32) sizeOfArray(m_helicopterDots)); + } + else { + m_unk0x4220.FUN_100720d0(param.GetAction()->GetObjectId()); + } + } + break; + } + case c_notificationKeyPress: + if (m_state->m_unk0x08 == 1 && ((LegoEventNotificationParam&) p_param).GetKey() == ' ') { + AnimationManager()->FUN_10061010(FALSE); + return 1; + } + break; + case c_notificationButtonUp: + case c_notificationButtonDown: + if (m_state->m_unk0x08 == 1) { + return 1; + } + break; + case c_notificationEndAnim: + if (m_state->m_unk0x08 == 1) { + assert(m_copter && m_brickster && m_cop1 && m_cop2); + m_unk0x4220.FUN_100720d0(NULL); + m_state->m_unk0x08 = 0; + FUN_10015820(TRUE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + m_copter->HandleClick(); + m_copter->m_state->m_unk0x08 = 1; + m_copter->HandleEndAnim((LegoEndAnimNotificationParam&) param); + } + break; + case c_notificationTransitioned: + HandleTransitionEnd(); + return 1; + } + } + return 0; } -// STUB: LEGO1 0x10073270 -void Act3::ReadyWorld() +// FUNCTION: LEGO1 0x10073240 +MxLong Act3::HandleTransitionEnd() { - // TODO + if (m_destLocation != LegoGameState::e_undefined) { + GameState()->SwitchArea(m_destLocation); + m_destLocation = LegoGameState::e_undefined; + } + + return 1; } -// STUB: LEGO1 0x10073300 +// FUNCTION: LEGO1 0x10073270 +void Act3::ReadyWorld() +{ + PlantManager()->FUN_10027200(); + BuildingManager()->FUN_10030800(); + AnimationManager()->FUN_1005f6d0(FALSE); + VideoManager()->Get3DManager()->SetFrustrum(90.0f, 0.1f, 125.0f); + + m_unk0x426c = g_unk0x100d95e8[rand() % 3]; + AnimationManager()->FUN_10060dc0(m_unk0x426c, NULL, TRUE, FALSE, NULL, TRUE, FALSE, FALSE, FALSE); + + m_state->m_unk0x08 = 1; +} + +// FUNCTION: LEGO1 0x10073300 MxResult Act3::Tickle() { - // TODO + if (!m_worldStarted) { + LegoWorld::Tickle(); + return SUCCESS; + } + + if (m_unk0x426c != (Act3Script::Script) 0) { + if (AnimationManager()->FUN_10064ee0(m_unk0x426c)) { + FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + TickleManager()->UnregisterClient(this); + m_unk0x426c = (Act3Script::Script) 0; + } + } + return SUCCESS; } -// STUB: LEGO1 0x10073400 +// FUNCTION: LEGO1 0x10073360 +// FUNCTION: BETA10 0x100169d5 +MxResult Act3::FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2) +{ + assert(m_brickster); + m_brickster->FUN_100417a0(p_ammo, p_param2); + FUN_10072ad0(1); + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10073390 +// FUNCTION: BETA10 0x10016a40 +MxResult Act3::FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2) +{ + assert(m_cop1 && m_cop2); + + if (!(g_unk0x100f7814 & 1)) { + m_cop1->FUN_10040350(p_ammo, p_param2); + } + else { + m_cop2->FUN_10040350(p_ammo, p_param2); + } + + FUN_10072ad0(3); + g_unk0x100f7814++; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100733d0 +// FUNCTION: BETA10 0x10016b5d +void Act3::AddCop(Act3Cop* p_cop) +{ + if (m_cop1) { + m_cop2 = p_cop; + } + else { + m_cop1 = p_cop; + } +} + +// FUNCTION: LEGO1 0x100733f0 +// FUNCTION: BETA10 0x10016ba2 +void Act3::SetBrickster(Act3Brickster* p_brickster) +{ + m_brickster = p_brickster; +} + +// FUNCTION: LEGO1 0x10073400 void Act3::FUN_10073400() { + m_state->m_unk0x08 = 2; + m_destLocation = LegoGameState::e_infomain; + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); } -// STUB: LEGO1 0x10073430 +// FUNCTION: LEGO1 0x10073430 void Act3::FUN_10073430() { + m_state->m_unk0x08 = 3; + m_destLocation = LegoGameState::e_infomain; + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); } -// STUB: LEGO1 0x10073a90 +// FUNCTION: LEGO1 0x10073460 +// FUNCTION: BETA10 0x10016bc6 +void Act3::GoodEnding(const Matrix4& p_destination) +{ + assert(m_cop1 && m_cop2 && m_brickster && m_state); + + m_cop1->SetActorState(LegoPathActor::c_disabled); + m_cop2->SetActorState(LegoPathActor::c_disabled); + m_brickster->SetActorState(LegoPathActor::c_disabled); + + m_unk0x4220.Clear(); + m_copter->FUN_10004640(p_destination); + + DebugPrintf("In Good Ending..."); + DebugCopter( + m_copter->GetROI()->GetLocal2World(), + p_destination, + m_copter->m_unk0x160, + m_copter->m_unk0x1a8, + m_copter->m_unk0x1f4 + ); +} + +// FUNCTION: LEGO1 0x10073500 +void Act3::DebugPrintf(const char* p_format, ...) +{ + // empty +} + +// FUNCTION: LEGO1 0x10073510 +void Act3::DebugCopter( + const Matrix4& p_copter, + const Matrix4& p_destination, + const Matrix4& p_startPosition, + const Matrix4& p_endPosition, + const UnknownMx4DPointFloat& p_unk0x1f4 +) +{ + DebugPrintf("Copter matrix...\n\n"); + + // STRING: LEGO1 0x100f78e0 + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_copter[0])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_copter[1])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_copter[2])); + // STRING: LEGO1 0x100f78cc + DebugPrintf("\t%g, %g, %g, %g\n\n", EXPAND4(p_copter[3])); + + DebugPrintf("Destination matrix..."); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_destination[0])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_destination[1])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_destination[2])); + DebugPrintf("\t%g, %g, %g, %g\n\n", EXPAND4(p_destination[3])); + + DebugPrintf("Start position..."); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_startPosition[0])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_startPosition[1])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_startPosition[2])); + DebugPrintf("\t%g, %g, %g, %g\n\n", EXPAND4(p_startPosition[3])); + + DebugPrintf("End position..."); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_endPosition[0])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_endPosition[1])); + DebugPrintf("\t%g, %g, %g, %g", EXPAND4(p_endPosition[2])); + DebugPrintf("\t%g, %g, %g, %g\n\n", EXPAND4(p_endPosition[3])); + + Mx4DPointFloat unk0x00, unk0x18; + + if (p_unk0x1f4.GetUnknown0x30() != 0) { + // TODO: Match + unk0x00 = p_unk0x1f4.GetUnknown0x00(); + unk0x18 = p_unk0x1f4.GetUnknown0x18(); + + DebugPrintf("Source quaternion..."); + // STRING: LEGO1 0x100f7864 + DebugPrintf("\t%g, %g, %g, %g\n", EXPAND4(unk0x00)); + + DebugPrintf("Destination quaternion..."); + DebugPrintf("\t%g, %g, %g, %g\n", EXPAND4(unk0x18)); + } +} + +// FUNCTION: LEGO1 0x10073a90 void Act3::Enable(MxBool p_enable) { - // TODO + if ((MxBool) m_set0xd0.empty() == p_enable) { + return; + } + + LegoWorld::Enable(p_enable); + + if (p_enable) { + if (GameState()->m_previousArea == LegoGameState::e_infomain) { + GameState()->StopArea(LegoGameState::e_infomain); + } + + FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + PlayMusic(JukeboxScript::c_Act3Music); + GameState()->SetDirty(TRUE); + + if (m_time > 0) { + MxFloat delta = Timer()->GetTime() - m_time - 100.0f; + m_time = -1.0f; + + m_cop1->SetLastTime(m_cop1->GetLastTime() + delta); + m_cop1->SetActorTime(m_cop1->GetActorTime() + delta); + m_cop1->SetUnknown0x20(m_cop1->GetUnknown0x20() + delta); + m_cop1->SetUnknown0x1c(m_cop1->GetUnknown0x1c() + delta); + + m_cop2->SetLastTime(m_cop2->GetLastTime() + delta); + m_cop2->SetActorTime(m_cop2->GetActorTime() + delta); + m_cop2->SetUnknown0x20(m_cop2->GetUnknown0x20() + delta); + m_cop2->SetUnknown0x1c(m_cop2->GetUnknown0x1c() + delta); + + m_brickster->SetLastTime(m_brickster->GetLastTime() + delta); + m_brickster->SetActorTime(m_brickster->GetActorTime() + delta); + m_brickster->SetUnknown0x20(m_brickster->GetUnknown0x20() + delta); + m_brickster->SetUnknown0x24(m_brickster->GetUnknown0x24() + delta); + m_brickster->SetUnknown0x50(m_brickster->GetUnknown0x50() + delta); + m_brickster->SetUnknown0x1c(m_brickster->GetUnknown0x1c() + delta); + + m_copter->SetLastTime(m_copter->GetLastTime() + delta); + m_copter->SetActorTime(m_copter->GetActorTime() + delta); + + m_shark->SetLastTime(m_shark->GetLastTime() + delta); + m_shark->SetActorTime(m_shark->GetActorTime() + delta); + m_shark->SetUnknown0x2c(m_shark->GetUnknown0x2c() + delta); + + MxS32 i; + for (i = 0; i < (MxS32) sizeOfArray(m_pizzas); i++) { + if (m_pizzas[i].IsValid()) { + m_pizzas[i].SetLastTime(m_pizzas[i].GetLastTime() + delta); + m_pizzas[i].SetActorTime(m_pizzas[i].GetActorTime() + delta); + m_pizzas[i].SetUnknown0x158(m_pizzas[i].GetUnknown0x158() + delta); + } + } + + for (i = 0; i < (MxS32) sizeOfArray(m_donuts); i++) { + if (m_donuts[i].IsValid()) { + m_donuts[i].SetLastTime(m_donuts[i].GetLastTime() + delta); + m_donuts[i].SetActorTime(m_donuts[i].GetActorTime() + delta); + m_donuts[i].SetUnknown0x158(m_donuts[i].GetUnknown0x158() + delta); + } + } + + PlaceActor(m_copter); + m_copter->GetBoundary()->AddActor(m_copter); + + InputManager()->SetWorld(this); + InputManager()->Register(this); + SetUserActor(m_copter); + m_copter->VTable0xa8(); + SetAppCursor(e_cursorArrow); + } + } + else { + SetUserActor(NULL); + BackgroundAudioManager()->Stop(); + m_time = Timer()->GetTime(); + TickleManager()->UnregisterClient(this); + } } -// STUB: LEGO1 0x10073e40 +// FUNCTION: LEGO1 0x10073e40 void Act3::VTable0x60() { - // TODO + // empty } -// STUB: LEGO1 0x10073e50 +// FUNCTION: LEGO1 0x10073e50 MxBool Act3::Escape() { - // TODO - return FALSE; + BackgroundAudioManager()->Stop(); + AnimationManager()->FUN_10061010(FALSE); + DeleteObjects(&m_atomId, Act3Script::c_tlp053in_RunAnim, 999); + m_destLocation = LegoGameState::e_infomain; + return TRUE; } diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index ef830926..0a516043 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -586,7 +586,7 @@ void Isle::Enable(MxBool p_enable) FALSE, IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3 ); - actor->SetState(0); + actor->SetActorState(LegoPathActor::c_initial); } else { FUN_10032620(); @@ -1334,21 +1334,21 @@ MxResult Act1State::Serialize(LegoFile* p_file) WriteNamedTexture(p_file, m_helicopterWindshield); } else { - FUN_1003f540(p_file, "chwind.gif"); + WriteDefaultTexture(p_file, "chwind.gif"); } if (m_helicopterJetLeft) { WriteNamedTexture(p_file, m_helicopterJetLeft); } else { - FUN_1003f540(p_file, "chjetl.gif"); + WriteDefaultTexture(p_file, "chjetl.gif"); } if (m_helicopterJetRight) { WriteNamedTexture(p_file, m_helicopterJetRight); } else { - FUN_1003f540(p_file, "chjetr.gif"); + WriteDefaultTexture(p_file, "chjetr.gif"); } } @@ -1357,14 +1357,14 @@ MxResult Act1State::Serialize(LegoFile* p_file) WriteNamedTexture(p_file, m_jetskiFront); } else { - FUN_1003f540(p_file, "jsfrnt.gif"); + WriteDefaultTexture(p_file, "jsfrnt.gif"); } if (m_jetskiWindshield) { WriteNamedTexture(p_file, m_jetskiWindshield); } else { - FUN_1003f540(p_file, "jswnsh.gif"); + WriteDefaultTexture(p_file, "jswnsh.gif"); } } @@ -1373,7 +1373,7 @@ MxResult Act1State::Serialize(LegoFile* p_file) WriteNamedTexture(p_file, m_dunebuggyFront); } else { - FUN_1003f540(p_file, "dbfrfn.gif"); + WriteDefaultTexture(p_file, "dbfrfn.gif"); } } @@ -1382,21 +1382,21 @@ MxResult Act1State::Serialize(LegoFile* p_file) WriteNamedTexture(p_file, m_racecarFront); } else { - FUN_1003f540(p_file, "rcfrnt.gif"); + WriteDefaultTexture(p_file, "rcfrnt.gif"); } if (m_racecarBack) { WriteNamedTexture(p_file, m_racecarBack); } else { - FUN_1003f540(p_file, "rcback.gif"); + WriteDefaultTexture(p_file, "rcback.gif"); } if (m_racecarTail) { WriteNamedTexture(p_file, m_racecarTail); } else { - FUN_1003f540(p_file, "rctail.gif"); + WriteDefaultTexture(p_file, "rctail.gif"); } } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 9119eb1b..6e730236 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -177,7 +177,7 @@ MxResult LegoAct2::Tickle() m_unk0x10c4 = 1; break; case 1: - ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); + ((LegoPathActor*) m_pepper->GetEntity())->SetActorState(LegoPathActor::c_disabled); switch (rand() % 3) { case 0: @@ -336,7 +336,7 @@ MxLong LegoAct2::Notify(MxParam& p_param) m_unk0x10c4 = 14; m_unk0x10d0 = 0; - ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); + ((LegoPathActor*) m_pepper->GetEntity())->SetActorState(LegoPathActor::c_disabled); } break; case c_notificationTransitioned: @@ -417,7 +417,7 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) m_unk0x10d0 = 0; FUN_10052560(Act2mainScript::c_tra045la_RunAnim, TRUE, TRUE, NULL, NULL, NULL); - ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); + ((LegoPathActor*) m_pepper->GetEntity())->SetActorState(LegoPathActor::c_disabled); AnimationManager()->EnableCamAnims(TRUE); AnimationManager()->FUN_1005f6d0(TRUE); AnimationManager()->FUN_100604f0(g_unk0x100f4428, sizeOfArray(g_unk0x100f4428)); @@ -450,7 +450,7 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) m_unk0x10c4 = 13; SpawnBricks(); PlayMusic(JukeboxScript::c_BrickHunt); - ((LegoPathActor*) m_pepper->GetEntity())->SetState(0); + ((LegoPathActor*) m_pepper->GetEntity())->SetActorState(LegoPathActor::c_initial); break; } case 14: @@ -602,7 +602,7 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param) { if (m_unk0x10c4 == 5 && p_param.GetData() == 0x32) { LegoPathActor* actor = (LegoPathActor*) m_pepper->GetEntity(); - actor->SetState(LegoPathActor::c_bit3); + actor->SetActorState(LegoPathActor::c_disabled); actor->SetWorldSpeed(0.0f); FUN_10051900(); @@ -630,7 +630,7 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param) FUN_10051fa0(p_param.GetData()); } else if (m_unk0x10c4 == 10 && p_param.GetData() == 0x165) { - ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); + ((LegoPathActor*) m_pepper->GetEntity())->SetActorState(LegoPathActor::c_disabled); if (FUN_10052560(Act2mainScript::c_VOhide_PlayWav, FALSE, TRUE, NULL, NULL, NULL) == SUCCESS) { m_unk0x1140 = Act2mainScript::c_VOhide_PlayWav; @@ -659,6 +659,47 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param) return 0; } +// FUNCTION: LEGO1 0x100516b0 +// FUNCTION: BETA10 0x1003bcbc +MxResult LegoAct2::FUN_100516b0() +{ + if (m_nextBrick > 4) { + return FAILURE; + } + + Act2Brick& brick = m_bricks[m_nextBrick]; + brick.Create(m_nextBrick); + + MxMatrix local2world = m_ambulance->GetLocal2World(); + MxMatrix local2world2 = local2world; + + LegoPathBoundary* boundary = m_unk0x1138->GetBoundary(); + local2world[3][1] += 1.3; + local2world2[3][1] -= 0.1; + + brick.FUN_1007a670(local2world, local2world2, boundary); + m_nextBrick++; + m_unk0x10c4 = 9; + m_unk0x10d0 = 0; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100517b0 +void LegoAct2::FUN_100517b0() +{ + Act2Brick& brick = m_bricks[m_nextBrick]; + brick.Create(m_nextBrick); + + MxMatrix local2world = m_ambulance->GetLocal2World(); + local2world[3][1] += 1.5; + + LegoROI* roi = brick.GetROI(); + roi->FUN_100a58f0(local2world); + roi->VTable0x14(); + brick.PlayWhistleSound(); + m_nextBrick++; +} + // FUNCTION: LEGO1 0x10051840 void LegoAct2::PlayMusic(JukeboxScript::Script p_objectId) { @@ -705,7 +746,7 @@ void LegoAct2::FUN_10051960() roi->SetVisibility(FALSE); } - ((LegoPathActor*) m_pepper->GetEntity())->SetState(0); + ((LegoPathActor*) m_pepper->GetEntity())->SetActorState(LegoPathActor::c_initial); } // FUNCTION: LEGO1 0x100519c0 @@ -887,6 +928,26 @@ void LegoAct2::SpawnBricks() m_nextBrick++; } +// FUNCTION: LEGO1 0x10051f20 +// FUNCTION: BETA10 0x10013f48 +MxResult LegoAct2::BadEnding() +{ + for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_bricks); i++) { + m_bricks[i].Remove(); + } + + LegoPathActor* actor = m_unk0x1138; + actor->SetActorState(LegoPathActor::c_disabled); + + m_gameState->SetUnknown0x08(104); + m_destLocation = LegoGameState::e_infomain; + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + + MxTrace("Bad End of Act2\n"); + m_unk0x10c4 = 14; + return SUCCESS; +} + // FUNCTION: LEGO1 0x10051fa0 // FUNCTION: BETA10 0x10013fd3 void LegoAct2::FUN_10051fa0(MxS32 p_param1) diff --git a/LEGO1/lego/sources/3dmanager/lego3dview.h b/LEGO1/lego/sources/3dmanager/lego3dview.h index 9e0f69eb..1f878a53 100644 --- a/LEGO1/lego/sources/3dmanager/lego3dview.h +++ b/LEGO1/lego/sources/3dmanager/lego3dview.h @@ -46,7 +46,7 @@ class Lego3DView : public LegoView1 { // // Lego3DView implementation -// FUNCTION: BETA10 0x100576b0 +// FUNCTION: BETA10 0x10011810 inline ViewManager* Lego3DView::GetViewManager() { return m_pViewManager; diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index be388c2d..ef29db9b 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -43,6 +43,7 @@ class LegoWEGEdge : public LegoWEEdge { // FUNCTION: BETA10 0x100270c0 LegoU32 GetFlag0x10() { return m_flags & c_bit5 ? FALSE : TRUE; } + // TODO: Other BETA10 reference at 0x1001c9e0, not sure what is going on // FUNCTION: BETA10 0x1001ff80 Mx4DPointFloat* GetUnknown0x14() { return &m_unk0x14; } diff --git a/LEGO1/lego/sources/misc/legoimage.h b/LEGO1/lego/sources/misc/legoimage.h index 7e0fbb17..c62701be 100644 --- a/LEGO1/lego/sources/misc/legoimage.h +++ b/LEGO1/lego/sources/misc/legoimage.h @@ -36,6 +36,7 @@ class LegoImage { LegoU32 GetHeight() { return m_height; } void SetHeight(LegoU32 p_height) { m_height = p_height; } LegoU32 GetCount() { return m_count; } + void SetCount(LegoU32 p_count) { m_count = p_count; } LegoPaletteEntry* GetPalette() { return m_palette; } LegoPaletteEntry& GetPaletteEntry(LegoU32 p_i) { return m_palette[p_i]; } void SetPaletteEntry(LegoU32 p_i, LegoPaletteEntry& p_paletteEntry) { m_palette[p_i] = p_paletteEntry; } diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index ec853d19..f9a8549b 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -409,6 +409,7 @@ LegoResult LegoROI::FUN_100a8da0(LegoTreeNode* p_node, const Matrix4& p_matrix, } // FUNCTION: LEGO1 0x100a8e80 +// FUNCTION: BETA10 0x1018ab3a void LegoROI::FUN_100a8e80(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_time, LegoROI** p_roiMap) { MxMatrix mat; diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 3e72db9a..1cfa82ac 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -44,7 +44,7 @@ class Mx3DPointFloat : public Vector3 { float& index_operator(int idx) { return m_data[idx]; } // SYNTHETIC: LEGO1 0x10010c00 - // Mx3DPointFloat::operator= + // ??4Mx3DPointFloat@@QAEAAV0@ABV0@@Z private: float m_elements[3]; // 0x08 @@ -76,11 +76,16 @@ class Mx4DPointFloat : public Vector4 { // FUNCTION: BETA10 0x1004af10 float& operator[](int idx) { return m_data[idx]; } - const float& operator[](int idx) const { return m_data[idx]; } + // According to the PDB, BETA10 will not link this one if it is never used + // const float& operator[](int idx) const { return m_data[idx]; } + + // only used by a couple of BETA10 functions for some unknown reason + // FUNCTION: BETA10 0x1001c950 + float& index_operator(int idx) { return m_data[idx]; } // SYNTHETIC: LEGO1 0x10064b20 // SYNTHETIC: BETA10 0x10070420 - // Mx4DPointFloat::operator= + // ??4Mx4DPointFloat@@QAEAAV0@ABV0@@Z private: float m_elements[4]; // 0x08 @@ -131,6 +136,10 @@ class UnknownMx4DPointFloat { m_unk0x30 |= c_bit2; } + const Vector4& GetUnknown0x00() const { return m_unk0x00; } + const Vector4& GetUnknown0x18() const { return m_unk0x18; } + undefined4 GetUnknown0x30() const { return m_unk0x30; } + inline int Unknown6(Matrix4& p_matrix, float p_f); inline void Unknown7(); diff --git a/LEGO1/mxgeometry/mxmatrix.h b/LEGO1/mxgeometry/mxmatrix.h index 55a17da1..9f1aa59f 100644 --- a/LEGO1/mxgeometry/mxmatrix.h +++ b/LEGO1/mxgeometry/mxmatrix.h @@ -13,6 +13,7 @@ class MxMatrix : public Matrix4 { MxMatrix() : Matrix4(m_elements) {} // FUNCTION: LEGO1 0x10032770 + // FUNCTION: BETA10 0x1001ff30 MxMatrix(const MxMatrix& p_matrix) : Matrix4(m_elements) { Equals(p_matrix); } // FUNCTION: BETA10 0x1000fc20 diff --git a/LEGO1/realtime/matrix.h b/LEGO1/realtime/matrix.h index 729239e2..b0ace048 100644 --- a/LEGO1/realtime/matrix.h +++ b/LEGO1/realtime/matrix.h @@ -130,6 +130,7 @@ class Matrix4 { inline virtual int FromQuaternion(const Vector4& p_vec); // vtable+0x44 // FUNCTION: LEGO1 0x100a0ff0 + // FUNCTION: BETA10 0x1001fe60 void Scale(const float& p_x, const float& p_y, const float& p_z) { for (int i = 0; i < 4; i++) { diff --git a/LEGO1/viewmanager/viewmanager.h b/LEGO1/viewmanager/viewmanager.h index 92236873..051fe0fa 100644 --- a/LEGO1/viewmanager/viewmanager.h +++ b/LEGO1/viewmanager/viewmanager.h @@ -39,7 +39,9 @@ class ViewManager { inline static int CalculateLODLevel(float p_und1, float p_und2, ViewROI* p_roi); inline static int IsROIVisibleAtLOD(ViewROI* p_roi); + // FUNCTION: BETA10 0x100576b0 const CompoundObject& GetROIs() { return rois; } + void Add(ViewROI* p_roi) { rois.push_back(p_roi); } // SYNTHETIC: LEGO1 0x100a6000 diff --git a/reccmp-project.yml b/reccmp-project.yml new file mode 100644 index 00000000..d2aaf9ba --- /dev/null +++ b/reccmp-project.yml @@ -0,0 +1,35 @@ +targets: + ISLE: + filename: ISLE.EXE + source-root: . + hash: + sha256: 5cf57c284973fce9d14f5677a2e4435fd989c5e938970764d00c8932ed5128ca + LEGO1: + filename: LEGO1.DLL + source-root: LEGO1 + hash: + sha256: 14645225bbe81212e9bc1919cd8a692b81b8622abb6561280d99b0fc4151ce17 + CONFIG: + filename: CONFIG.EXE + source-root: . + hash: + sha256: 864766d024d78330fed5e1f6efb2faf815f1b1c3405713a9718059dc9a54e52c + BETA10: + filename: BETA10.DLL + source-root: LEGO1 + hash: + sha256: d91435a40fa31f405fba33b03bd3bd40dcd4ca36ccf8ef6162c6c5ca0d7190e7 + ghidra: + ignore-types: + # these classes have been changed by hand to account for changes between LEGO1 and BETA10 + - Act2Actor + - Act2Brick + - LegoAct2 + - LegoCarBuild + - LegoCarBuildAnimPresenter + - LegoRace + - LegoWorld + ignore-functions: + # strcpy, strlen, ... (arguments are imported incorrectly) + - 0x100fa200 + - 0x100f9780