diff --git a/CMakeLists.txt b/CMakeLists.txt index c96cc111..3d201883 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -363,6 +363,7 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/main/legoomni.cpp LEGO1/lego/legoomni/src/notify/legoeventnotificationparam.cpp LEGO1/lego/legoomni/src/paths/legoanimactor.cpp + LEGO1/lego/legoomni/src/paths/legoextraactor.cpp LEGO1/lego/legoomni/src/paths/legopathactor.cpp LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp LEGO1/lego/legoomni/src/paths/legopathpresenter.cpp diff --git a/LEGO1/lego/legoomni/include/act3.h b/LEGO1/lego/legoomni/include/act3.h index 46ae4e4f..eb4161ff 100644 --- a/LEGO1/lego/legoomni/include/act3.h +++ b/LEGO1/lego/legoomni/include/act3.h @@ -41,8 +41,8 @@ class Act3 : public LegoWorld { // SYNTHETIC: LEGO1 0x10072630 // Act3::`scalar deleting destructor' - MxBool FUN_100727e0(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up); - MxBool FUN_10072980(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up); + 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 FUN_10073400(); void FUN_10073430(); diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index e235af40..3edb6cc9 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -4,14 +4,33 @@ #include "actionsfwd.h" #include "animstate.h" #include "decomp.h" +#include "legoentity.h" #include "legotraninfolist.h" #include "mxcore.h" // SIZE 0x18 struct Character { - char* m_name; // 0x00 - undefined m_unk0x04[0x10]; // 0x04 - MxBool m_active; // 0x14 + char* m_name; // 0x00 + undefined m_unk0x04; // 0x04 + MxS8 m_vehicleId; // 0x05 + undefined m_unk0x06; // 0x06 + MxBool m_unk0x07; // 0x07 + undefined m_unk0x08[12]; // 0x08 + MxBool m_active; // 0x14 +}; + +// SIZE 0x08 +struct Vehicle { + char* m_name; // 0x00 + undefined m_unk0x04; // 0x04 + MxBool m_unk0x05; // 0x05 +}; + +// SIZE 0x18 +struct Unknown0x3c { + LegoROI* m_roi; // 0x00 + MxU32 m_id; // 0x04 + undefined m_unk0x08[0x10]; // 0x08 }; // VTABLE: LEGO1 0x100d8c18 @@ -47,6 +66,7 @@ class LegoAnimationManager : public MxCore { MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info); MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info); void FUN_100603c0(); + MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); undefined4 FUN_10060dc0( IsleScript::Script, undefined4, @@ -86,7 +106,7 @@ class LegoAnimationManager : public MxCore { undefined m_unk0x38; // 0x38 undefined m_unk0x39; // 0x39 undefined m_unk0x3a; // 0x3a - undefined m_unk0x3b[0x3c1]; // 0x3b + Unknown0x3c m_unk0x3c[40]; // 0x3c undefined4 m_unk0x3fc; // 0x3fc MxU8 m_unk0x400; // 0x400 undefined m_unk0x401; // 0x401 diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 4421c74d..2347f55e 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -2,6 +2,7 @@ #define LEGOCHARACTERMANAGER_H #include "decomp.h" +#include "legoextraactor.h" #include "legovariables.h" #include "misc/legostorage.h" #include "mxstl/stlcompat.h" @@ -51,6 +52,7 @@ class LegoCharacterManager { void FUN_100832a0(); void FUN_10083db0(LegoROI* p_roi); void FUN_10083f10(LegoROI* p_roi); + LegoExtraActor* FUN_10084c40(const LegoChar*); LegoCharacterData* Find(const char* p_key); MxBool FUN_10084ec0(LegoROI* p_roi); MxU32 FUN_10085140(LegoROI*, MxBool); diff --git a/LEGO1/lego/legoomni/include/legoentity.h b/LEGO1/lego/legoomni/include/legoentity.h index 5db4180e..69a482cf 100644 --- a/LEGO1/lego/legoomni/include/legoentity.h +++ b/LEGO1/lego/legoomni/include/legoentity.h @@ -70,9 +70,10 @@ class LegoEntity : public MxEntity { Mx3DPointFloat GetWorldUp(); Mx3DPointFloat GetWorldPosition(); - inline LegoROI* GetROI() { return m_roi; } - inline MxU8 GetFlags() { return m_flags; } inline MxBool GetUnknown0x10IsSet(MxU8 p_flag) { return m_unk0x10 & p_flag; } + inline MxU8 GetFlags() { return m_flags; } + inline LegoROI* GetROI() { return m_roi; } + inline MxU8 GetUnknown0x59() { return m_unk0x59; } inline void SetFlags(MxU8 p_flags) { m_flags = p_flags; } inline void SetFlag(MxU8 p_flag) { m_flags |= p_flag; } @@ -90,7 +91,7 @@ class LegoEntity : public MxEntity { MxFloat m_worldSpeed; // 0x50 LegoROI* m_roi; // 0x54 MxBool m_cameraFlag; // 0x58 - undefined m_unk0x59; // 0x59 + MxU8 m_unk0x59; // 0x59 // For tokens from the extra string that look like this: // "Action:openram;\lego\scripts\Race\CarRaceR;0" Extra::ActionType m_actionType; // 0x5c diff --git a/LEGO1/lego/legoomni/include/legoomni.h b/LEGO1/lego/legoomni/include/legoomni.h index a8fb5191..e8e09cbb 100644 --- a/LEGO1/lego/legoomni/include/legoomni.h +++ b/LEGO1/lego/legoomni/include/legoomni.h @@ -200,6 +200,7 @@ class LegoOmni : public MxOmni { void RemoveWorld(const MxAtomId& p_atom, MxLong p_objectId); MxResult RegisterScripts(); MxS32 GetScriptIndex(const char* p_key); + void DeleteAction(); static MxS32 GetCurrPathInfo(LegoPathBoundary**, MxS32&); const char* FindScript(MxU32 p_id); @@ -228,6 +229,13 @@ class LegoOmni : public MxOmni { inline void SetCurrentActor(IslePathActor* p_currentActor) { m_currentActor = p_currentActor; } inline void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; } inline void SetExit(MxBool p_exit) { m_exit = p_exit; } + inline MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) + { + if (m_unk0x13c) { + return Start(&p_dsAction); + } + return SUCCESS; + } inline void CloseMainWindow() { PostMessageA(m_windowHandle, WM_CLOSE, 0, 0); } diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 509b4c18..5c0fb670 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -5,6 +5,8 @@ #include "mxtypes.h" #include "realtime/matrix.h" +class LegoPathController; + // VTABLE: LEGO1 0x100d6e28 // SIZE 0x154 class LegoPathActor : public LegoActor { @@ -82,28 +84,35 @@ class LegoPathActor : public LegoActor { virtual void VTable0xc8(MxU8 p_unk0x148) { m_unk0x148 = p_unk0x148; } // vtable+0xc8 inline MxU32 GetUnknown88() { return m_unk0x88; } + inline LegoPathController* GetController() { return m_controller; } inline void SetUnknown88(MxU32 p_unk0x88) { m_unk0x88 = p_unk0x88; } inline void SetUnknownDC(MxU32 p_unk0xdc) { m_unk0xdc = p_unk0xdc; } + inline void ClearController() { m_controller = NULL; } // SYNTHETIC: LEGO1 0x1002d800 // LegoPathActor::`scalar deleting destructor' protected: - undefined m_unk0x78[0x10]; // 0x78 - MxU32 m_unk0x88; // 0x88 - undefined m_unk0x8c[0x50]; // 0x8c - MxU32 m_unk0xdc; // 0xdc - undefined m_unk0xe0[0xa]; // 0xe0 - MxU8 m_unk0xea; // 0xea - undefined m_unk0xef[0x4d]; // 0xef - MxU32 m_unk0x138; // 0x138 - MxFloat m_unk0x13c; // 0x13c - MxFloat m_unk0x140; // 0x140 - MxFloat m_unk0x144; // 0x144 - MxU8 m_unk0x148; // 0x148 - MxS32 m_unk0x14c; // 0x14c - MxFloat m_unk0x150; // 0x150 + undefined m_unk0x78[0xa]; // 0x78 + MxBool m_userNavFlag; // 0x82 + undefined4 m_unk0x84; // 0x84 + MxU32 m_unk0x88; // 0x88 + undefined4 m_boundary; // 0x8c + undefined m_unk0x8c[0x4c]; // 0x90 + MxU32 m_unk0xdc; // 0xdc + undefined4 m_unk0xe0; // 0xe0 + undefined4 m_destEdge; // 0xe4 + undefined2 m_unk0xe8; // 0xe8 + MxU8 m_unk0xea; // 0xea + undefined m_unk0xef[0x4d]; // 0xef + LegoPathController* m_controller; // 0x138 + MxFloat m_unk0x13c; // 0x13c + MxFloat m_unk0x140; // 0x140 + MxFloat m_unk0x144; // 0x144 + MxU8 m_unk0x148; // 0x148 + MxS32 m_unk0x14c; // 0x14c + MxFloat m_unk0x150; // 0x150 }; #endif // LEGOPATHACTOR_H diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 1fc4f616..303edd18 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -2,9 +2,8 @@ #define LEGOPATHCONTROLLER_H #include "decomp.h" +#include "legopathactor.h" #include "mxcore.h" - -class IslePathActor; class LegoPathBoundary; // VTABLE: LEGO1 0x100d7d60 @@ -35,7 +34,7 @@ class LegoPathController : public MxCore { virtual void VTable0x14(); // vtable+0x14 virtual void Destroy(); // vtable+0x18 - undefined4 FUN_10046770(IslePathActor* p_actor); + undefined4 FUN_10046770(LegoPathActor* p_actor); MxResult FUN_10046b30(LegoPathBoundary** p_path, MxS32& p_value); void Enable(MxBool p_enable); diff --git a/LEGO1/lego/legoomni/include/misc.h b/LEGO1/lego/legoomni/include/misc.h index b5bafcbe..67c97c78 100644 --- a/LEGO1/lego/legoomni/include/misc.h +++ b/LEGO1/lego/legoomni/include/misc.h @@ -3,6 +3,9 @@ #include "compat.h" #include "decomp.h" +#include "legoinputmanager.h" +#include "legoomni.h" +#include "legovideomanager.h" // Long include path due to dependency of misc library on LegoOmni #include "lego/legoomni/include/actions/actionsfwd.h" #include "mxtypes.h" @@ -13,7 +16,6 @@ class LegoBuildingManager; class LegoCharacterManager; class LegoControlManager; class LegoGameState; -class LegoInputManager; class LegoNavController; class LegoOmni; class LegoPlantManager; @@ -32,32 +34,40 @@ class ViewManager; extern MxBool g_isWorldActive; LegoOmni* Lego(); -LegoInputManager* InputManager(); LegoSoundManager* SoundManager(); -MxBackgroundAudioManager* BackgroundAudioManager(); -LegoGameState* GameState(); -MxTransitionManager* TransitionManager(); LegoVideoManager* VideoManager(); +MxBackgroundAudioManager* BackgroundAudioManager(); +LegoInputManager* InputManager(); +LegoControlManager* ControlManager(); +LegoGameState* GameState(); LegoAnimationManager* AnimationManager(); LegoNavController* NavController(); -LegoBuildingManager* BuildingManager(); -LegoControlManager* ControlManager(); IslePathActor* CurrentActor(); -ViewManager* GetViewManager(); -LegoPlantManager* PlantManager(); LegoWorld* CurrentWorld(); LegoCharacterManager* CharacterManager(); +ViewManager* GetViewManager(); +LegoPlantManager* PlantManager(); +LegoBuildingManager* BuildingManager(); LegoTextureContainer* TextureContainer(); ViewLODListManager* GetViewLODListManager(); -LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); +void FUN_10015820(MxBool p_disable, MxU16 p_flags); LegoROI* FindROI(const char* p_name); +void SetROIVisible(const char* p_name, MxBool p_visible); +void SetCurrentActor(IslePathActor* p_currentActor); +MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction); +void DeleteAction(); +LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); MxDSAction& GetCurrentAction(); +void SetCurrentWorld(LegoWorld* p_world); +MxTransitionManager* TransitionManager(); void PlayMusic(JukeboxScript::Script p_script); void SetIsWorldActive(MxBool p_isWorldActive); void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last); -void SetCurrentWorld(LegoWorld* p_world); -void FUN_10015820(MxBool p_disable, MxU16 p_flags); -void SetROIVisible(const char* p_name, MxBool p_visible); -void SetCurrentActor(IslePathActor* p_currentActor); + +// FUNCTION: LEGO1 0x10015890 +inline MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) +{ + return LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction); +} #endif // MISC_H diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 6b473ba4..1a85c4e6 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -220,10 +220,10 @@ MxU32 Helicopter::VTable0xd4(LegoControlManagerEvent& p_param) va4.EqualsCross(v68, dir); v7c.EqualsCross(va4, v90); if (ret) { - if (((Act3*) m_world)->FUN_100727e0(m_unk0x138, loc, dir, v7c)) { + if (((Act3*) m_world)->FUN_100727e0(m_controller, loc, dir, v7c)) { break; } - else if (((Act3*) m_world)->FUN_10072980(m_unk0x138, loc, dir, v7c)) { + else if (((Act3*) m_world)->FUN_10072980(m_controller, loc, dir, v7c)) { break; } } diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 5cf614bf..f922e78c 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -1,13 +1,22 @@ #include "legoanimationmanager.h" +#include "legocharactermanager.h" #include "legogamestate.h" #include "legoomni.h" #include "misc.h" #include "mxutilities.h" +#include "roi/legoroi.h" #include DECOMP_SIZE_ASSERT(LegoAnimationManager, 0x500) +DECOMP_SIZE_ASSERT(Character, 0x18) +DECOMP_SIZE_ASSERT(Vehicle, 0x8) +DECOMP_SIZE_ASSERT(Unknown0x3c, 0x18) + +// GLOBAL: LEGO1 0x100f6d20 +Vehicle g_vehicles[] = {"bikebd", 0, FALSE, "bikepg", 0, FALSE, "bikerd", 0, FALSE, "bikesy", 0, + FALSE, "motoni", 0, FALSE, "motola", 0, FALSE, "board", 0, FALSE}; // GLOBAL: LEGO1 0x100f7048 Character g_characters[47]; // TODO: Initialize this @@ -344,6 +353,45 @@ void LegoAnimationManager::FUN_100603c0() // TODO } +// FUNCTION: LEGO1 0x10060d00 +MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity) +{ + MxResult result = FAILURE; + LegoROI* roi = p_entity->GetROI(); + + if (p_entity->GetUnknown0x59() == 0) { + LegoPathActor* actor = CharacterManager()->FUN_10084c40(roi->GetName()); + + if (actor) { + LegoPathController* controller = actor->GetController(); + + if (controller) { + controller->FUN_10046770(actor); + actor->ClearController(); + + for (MxS32 i = 0; i < (MxS32) _countof(m_unk0x3c); i++) { + if (m_unk0x3c[i].m_roi == roi) { + MxU32 characterId = m_unk0x3c[i].m_id; + g_characters[characterId].m_unk0x07 = TRUE; + MxS32 vehicleId = g_characters[characterId].m_vehicleId; + + if (vehicleId >= 0) { + g_vehicles[vehicleId].m_unk0x05 = FALSE; + } + break; + } + } + } + } + } + + if (StartActionIfUnknown0x13c(p_dsAction) == SUCCESS) { + result = SUCCESS; + } + + return result; +} + // STUB: LEGO1 0x10060dc0 undefined4 LegoAnimationManager::FUN_10060dc0( IsleScript::Script, diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index 9854dd39..b538dbab 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -170,7 +170,7 @@ LegoROI* LegoCharacterManager::GetROI(const char* p_key, MxBool p_createEntity) if (character != NULL) { if (p_createEntity && character->m_roi->GetEntity() == NULL) { // TODO: Match - LegoAnimActor* actor = new LegoAnimActor(); + LegoExtraActor* actor = new LegoExtraActor(); actor->SetROI(character->m_roi, FALSE, FALSE); actor->FUN_100114e0(0); @@ -352,6 +352,11 @@ MxBool LegoCharacterManager::FUN_10084c00(const LegoChar*) return FALSE; } +// STUB: LEGO1 0x10084c40 +LegoExtraActor* LegoCharacterManager::FUN_10084c40(const LegoChar*) +{ + return NULL; +} // FUNCTION: LEGO1 0x10084c60 LegoCharacterData* LegoCharacterManager::Find(const char* p_key) { diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index b5bb13e1..cc1d5218 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -1,8 +1,5 @@ #include "misc.h" -#include "legoinputmanager.h" -#include "legoomni.h" -#include "legovideomanager.h" #include "mxbackgroundaudiomanager.h" #include "mxmisc.h" @@ -139,6 +136,12 @@ void SetCurrentActor(IslePathActor* p_currentActor) LegoOmni::GetInstance()->SetCurrentActor(p_currentActor); } +// FUNCTION: LEGO1 0x100158b0 +void DeleteAction() +{ + LegoOmni::GetInstance()->DeleteAction(); +} + // FUNCTION: LEGO1 0x100158c0 LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid) { diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index c29d8220..a0a89c0a 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -1,5 +1,6 @@ #include "legoworld.h" +#include "islepathactor.h" #include "legoanimationmanager.h" #include "legoanimpresenter.h" #include "legobuildingmanager.h" diff --git a/LEGO1/lego/legoomni/src/main/legoomni.cpp b/LEGO1/lego/legoomni/src/main/legoomni.cpp index 827d3341..2ee2d23f 100644 --- a/LEGO1/lego/legoomni/src/main/legoomni.cpp +++ b/LEGO1/lego/legoomni/src/main/legoomni.cpp @@ -771,6 +771,15 @@ MxResult LegoOmni::Start(MxDSAction* p_dsAction) return result; } +// FUNCTION: LEGO1 0x1005b5c0 +void LegoOmni::DeleteAction() +{ + if (m_action.GetObjectId() != -1) { + DeleteObject(m_action); + m_action.SetObjectId(-1); + } +} + // FUNCTION: LEGO1 0x1005b5f0 MxLong LegoOmni::Notify(MxParam& p_param) { diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index bdc0d585..4fa44b03 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -28,7 +28,7 @@ MxResult LegoPathController::Tickle() } // STUB: LEGO1 0x10046770 -undefined4 LegoPathController::FUN_10046770(IslePathActor* p_actor) +undefined4 LegoPathController::FUN_10046770(LegoPathActor* p_actor) { return 0; } diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index 8df9f4e1..8195e6c7 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -21,13 +21,13 @@ Act3::~Act3() } // STUB: LEGO1 0x100727e0 -MxBool Act3::FUN_100727e0(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up) +MxBool Act3::FUN_100727e0(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up) { return FALSE; } // STUB: LEGO1 0x10072980 -MxBool Act3::FUN_10072980(MxU32, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up) +MxBool Act3::FUN_10072980(LegoPathController*, Mx3DPointFloat& p_loc, Mx3DPointFloat& p_dir, Mx3DPointFloat& p_up) { return FALSE; }