diff --git a/LEGO1/lego/legoomni/include/dunebuggy.h b/LEGO1/lego/legoomni/include/dunebuggy.h index b103869b..1fd4154f 100644 --- a/LEGO1/lego/legoomni/include/dunebuggy.h +++ b/LEGO1/lego/legoomni/include/dunebuggy.h @@ -24,22 +24,23 @@ public: } MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void VTable0x70(float p_float) override; // vtable+0x70 + void VTable0x70(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 void Exit() override; // vtable+0xe4 - void FUN_10068350(); + void ActivateSceneActions(); // SYNTHETIC: LEGO1 0x10067dc0 // DuneBuggy::`scalar deleting destructor' private: - // TODO: Double check DuneBuggy field types - undefined4 m_unk0x160; - MxFloat m_unk0x164; - undefined4 m_unk0x168; + static MxS32 GetDashboardOffset(const char* p_variable); + + MxS16 m_dashboard; // 0x160 + MxFloat m_fuel; // 0x164 + MxFloat m_time; // 0x168 }; #endif // DUNEBUGGY_H diff --git a/LEGO1/lego/legoomni/include/legovariables.h b/LEGO1/lego/legoomni/include/legovariables.h index a40289a0..1901a254 100644 --- a/LEGO1/lego/legoomni/include/legovariables.h +++ b/LEGO1/lego/legoomni/include/legovariables.h @@ -3,6 +3,8 @@ #include "mxvariable.h" +extern const char* g_varDUNESPEED; +extern const char* g_varDUNEFUEL; extern const char* g_varMOTOSPEED; extern const char* g_varMOTOFUEL; extern const char* g_varAMBULSPEED; diff --git a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp index 9c5fca9f..f515dc03 100644 --- a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp +++ b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp @@ -1,58 +1,201 @@ #include "dunebuggy.h" #include "decomp.h" +#include "isle.h" +#include "isle_actions.h" +#include "jukebox_actions.h" +#include "legoanimationmanager.h" +#include "legocontrolmanager.h" +#include "legonavcontroller.h" +#include "legopathstruct.h" +#include "legoutils.h" +#include "legovariables.h" +#include "legoworld.h" +#include "misc.h" +#include "mxmisc.h" +#include "mxsoundpresenter.h" +#include "mxtimer.h" +#include "mxtransitionmanager.h" +#include "mxvariabletable.h" DECOMP_SIZE_ASSERT(DuneBuggy, 0x16c) +// GLOBAL: LEGO1 0x100f7660 +// STRING: LEGO1 0x100f7634 +const char* g_varDBFRFNY4 = "C_DBFRFNY4"; + // FUNCTION: LEGO1 0x10067bb0 DuneBuggy::DuneBuggy() { - this->m_maxLinearVel = 25.0; - this->m_unk0x164 = 1.0; + m_maxLinearVel = 25.0; + m_fuel = 1.0; } -// STUB: LEGO1 0x10067e30 +// FUNCTION: LEGO1 0x10067e30 MxResult DuneBuggy::Create(MxDSAction& p_dsAction) { - // TODO - return SUCCESS; + MxResult result = IslePathActor::Create(p_dsAction); + m_world = CurrentWorld(); + + if (m_world) { + m_world->Add(this); + } + + VariableTable()->SetVariable(g_varDUNEFUEL, "1.0"); + m_fuel = 1.0; + m_time = Timer()->GetTime(); + return result; } -// STUB: LEGO1 0x10067ec0 -void DuneBuggy::VTable0x70(float p_float) +// FUNCTION: LEGO1 0x10067ec0 +void DuneBuggy::VTable0x70(float p_time) { - // TODO + IslePathActor::VTable0x70(p_time); + + char buf[200]; + float speed = abs(m_worldSpeed); + float maxLinearVel = NavController()->GetMaxLinearVel(); + + sprintf(buf, "%g", speed / maxLinearVel); + VariableTable()->SetVariable(g_varDUNESPEED, buf); + + m_fuel += (p_time - m_time) * -3.333333333e-06f; + if (m_fuel < 0) { + m_fuel = 0; + } + + m_time = p_time; + + sprintf(buf, "%g", m_fuel); + VariableTable()->SetVariable(g_varDUNEFUEL, buf); } -// STUB: LEGO1 0x10067fa0 +// FUNCTION: LEGO1 0x10067fa0 void DuneBuggy::Exit() { - // TODO + IslePathActor::Exit(); + GameState()->m_currentArea = LegoGameState::e_dunecar; + RemoveFromCurrentWorld(*g_isleScript, m_dashboard); + RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_DuneCarArms_Ctl); + RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_DuneCarHorn_Ctl); + RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_DuneCarHorn_Sound); + RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_DuneCarInfo_Ctl); + RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_DuneCarSpeedMeter); + RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_DuneCarFuelMeter); + ControlManager()->Unregister(this); } -// STUB: LEGO1 0x10068060 +// FUNCTION: LEGO1 0x10068060 MxLong DuneBuggy::HandleClick() { - // TODO - return 0; + if (!FUN_1003ef60()) { + return 1; + } + + FUN_10015820(TRUE, 0); + + ((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::Area::e_dunecar); + TransitionManager()->StartTransition(MxTransitionManager::TransitionType::e_mosaic, 50, FALSE, TRUE); + + if (GameState()->GetActorId() != UserActor()->GetActorId()) { + ((IslePathActor*) UserActor())->Exit(); + } + + m_time = Timer()->GetTime(); + m_dashboard = IsleScript::c_DuneCarSpeedMeter + GetDashboardOffset(g_varDBFRFNY4); + + InvokeAction(Extra::ActionType::e_start, *g_isleScript, m_dashboard, NULL); + InvokeAction(Extra::ActionType::e_start, *g_isleScript, IsleScript::c_DuneCarDashboard, NULL); + GetCurrentAction().SetObjectId(-1); + + Vector3 position = m_roi->GetWorldPosition(); + AnimationManager()->FUN_10064670(&position); + AnimationManager()->FUN_10064740(&position); + Enter(); + ControlManager()->Register(this); + return 1; } -// STUB: LEGO1 0x100681b0 +// FUNCTION: LEGO1 0x100681b0 MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param) { - // TODO - return 0; + MxLong result = 0; + + if (p_param.GetUnknown0x28() == 1) { + switch (p_param.GetClickedObjectId()) { + case IsleScript::c_DuneCarArms_Ctl: + Exit(); + GameState()->m_currentArea = LegoGameState::e_unk66; + result = 1; + break; + case IsleScript::c_DuneCarInfo_Ctl: + ((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain); + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + Exit(); + result = 1; + break; + case IsleScript::c_DuneCarHorn_Ctl: + MxSoundPresenter* presenter = + (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "DuneCarHorn_Sound"); + presenter->Enable(p_param.GetUnknown0x28()); + break; + } + } + + return result; } -// STUB: LEGO1 0x10068270 +// FUNCTION: LEGO1 0x10068270 MxLong DuneBuggy::HandlePathStruct(LegoPathStructNotificationParam& p_param) { - // TODO + // 0x168 corresponds to the path at the gas station + if (p_param.GetData() == 0x168) { + m_fuel = 1.0f; + } + return 0; } -// STUB: LEGO1 0x10068350 -void DuneBuggy::FUN_10068350() +// FUNCTION: LEGO1 0x10068290 +MxS32 DuneBuggy::GetDashboardOffset(const char* p_variable) { - // TODO + MxS32 color = 1; + const char* colorName = VariableTable()->GetVariable(p_variable); + + if (strcmpi(colorName, "lego green")) { + if (!strcmpi(colorName, "lego red")) { + color = 2; + } + else if (!strcmpi(colorName, "lego yellow")) { + color = 3; + } + else if (!strcmpi(colorName, "lego black")) { + color = 4; + } + else if (!strcmpi(colorName, "lego blue")) { + color = 5; + } + else if (!strcmpi(colorName, "lego white")) { + color = 6; + } + } + + return color; +} + +// FUNCTION: LEGO1 0x10068350 +void DuneBuggy::ActivateSceneActions() +{ + PlayMusic(JukeboxScript::c_GarageArea_Music); + + Act1State* act1state = (Act1State*) GameState()->GetState("Act1State"); + if (!act1state->m_unk0x022) { + act1state->m_unk0x022 = TRUE; + + MxMatrix mat(UserActor()->GetROI()->GetLocal2World()); + mat.TranslateBy(mat[2][0] * 2.5, mat[2][1] + 0.7, mat[2][2] * 2.5); + + AnimationManager() + ->FUN_10060dc0(IsleScript::c_sns005in_RunAnim, &mat, TRUE, FALSE, NULL, FALSE, TRUE, TRUE, TRUE); + } } diff --git a/LEGO1/lego/legoomni/src/common/legovariables.cpp b/LEGO1/lego/legoomni/src/common/legovariables.cpp index 6815285d..fcb4b975 100644 --- a/LEGO1/lego/legoomni/src/common/legovariables.cpp +++ b/LEGO1/lego/legoomni/src/common/legovariables.cpp @@ -16,6 +16,14 @@ DECOMP_SIZE_ASSERT(CursorVariable, 0x24) DECOMP_SIZE_ASSERT(WhoAmIVariable, 0x24) DECOMP_SIZE_ASSERT(CustomizeAnimFileVariable, 0x24) +// GLOBAL: LEGO1 0x100f7658 +// STRING: LEGO1 0x100f764c +const char* g_varDUNESPEED = "duneSPEED"; + +// GLOBAL: LEGO1 0x100f765c +// STRING: LEGO1 0x100f7640 +const char* g_varDUNEFUEL = "duneFUEL"; + // GLOBAL: LEGO1 0x100f3994 // STRING: LEGO1 0x100f3988 const char* g_varMOTOSPEED = "motoSPEED"; diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 2f60a19a..d7cabb7b 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -998,7 +998,7 @@ MxLong Isle::HandleTransitionEnd() FUN_10032d30(IsleScript::c_DuneCarFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE); if (!m_act1state->m_unk0x01f) { - m_dunebuggy->FUN_10068350(); + m_dunebuggy->ActivateSceneActions(); } break; case LegoGameState::e_motocycle: