diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f84d674..3154739b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -387,15 +387,16 @@ function(add_lego_libraries NAME) LEGO1/lego/legoomni/src/entity/legoactorpresenter.cpp LEGO1/lego/legoomni/src/worlds/registrationbook.cpp LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp - LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp - LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp LEGO1/lego/legoomni/src/entity/act2brick.cpp LEGO1/lego/legoomni/src/video/legovideomanager.cpp LEGO1/lego/legoomni/src/video/legopartpresenter.cpp LEGO1/lego/legoomni/src/actors/jetski.cpp LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp + LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp LEGO1/lego/legoomni/src/race/legoracespecial.cpp + + LEGO1/lego/legoomni/src/worlds/historybook.cpp LEGO1/lego/legoomni/src/common/legocharactermanager.cpp LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp diff --git a/LEGO1/lego/legoomni/include/legojetskiraceactor.h b/LEGO1/lego/legoomni/include/legojetskiraceactor.h deleted file mode 100644 index c9964e8d..00000000 --- a/LEGO1/lego/legoomni/include/legojetskiraceactor.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef LEGOJETSKIRACEACTOR_H -#define LEGOJETSKIRACEACTOR_H - -#include "legoracespecial.h" - -// VTABLE: LEGO1 0x100da208 LegoCarRaceActor -// VTABLE: LEGO1 0x100da228 LegoRaceActor -// VTABLE: LEGO1 0x100da230 LegoAnimActor -// VTABLE: LEGO1 0x100da240 LegoPathActor -// VTABLE: BETA10 0x101bd348 LegoCarRaceActor -// VTABLE: BETA10 0x101bd370 LegoRaceActor -// VTABLE: BETA10 0x101bd378 LegoAnimActor -// VTABLE: BETA10 0x101bd390 LegoPathActor -// SIZE 0x1a8 -class LegoJetskiRaceActor : public virtual LegoCarRaceActor { -public: - LegoJetskiRaceActor(); - - // FUNCTION: LEGO1 0x10081d90 - // FUNCTION: BETA10 0x100aa920 - const char* ClassName() const override // vtable+0x0c - { - // STRING: LEGO1 0x100f0554 - return "LegoJetskiRaceActor"; - } - - // FUNCTION: LEGO1 0x10081db0 - // FUNCTION: BETA10 0x100aa960 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, LegoJetskiRaceActor::ClassName()) || LegoCarRaceActor::IsA(p_name); - } - - 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 - MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c - - // SYNTHETIC: LEGO1 0x10013a80 - // LegoJetskiRaceActor::`vbase destructor' - - // SYNTHETIC: LEGO1 0x10081d50 - // LegoJetskiRaceActor::`scalar deleting destructor' - - // SYNTHETIC: LEGO1 0x10013ba0 - // LegoJetskiRaceActor::~LegoJetskiRaceActor -}; - -// GLOBAL: LEGO1 0x100da1f0 -// LegoJetskiRaceActor::`vbtable'{for `LegoJetskiRaceActor'} - -// GLOBAL: LEGO1 0x100da1e8 -// LegoJetskiRaceActor::`vbtable'{for `LegoAnimActor'} - -// GLOBAL: LEGO1 0x100da1d8 -// LegoJetskiRaceActor::`vbtable'{for `LegoRaceActor'} - -// GLOBAL: LEGO1 0x100da1c8 -// LegoJetskiRaceActor::`vbtable'{for `LegoCarRaceActor'} - -#endif // LEGOJETSKIRACEACTOR_H diff --git a/LEGO1/lego/legoomni/include/legoracers.h b/LEGO1/lego/legoomni/include/legoracers.h index 461b3a52..54a29eca 100644 --- a/LEGO1/lego/legoomni/include/legoracers.h +++ b/LEGO1/lego/legoomni/include/legoracers.h @@ -1,9 +1,10 @@ #ifndef LEGORACERS_H #define LEGORACERS_H -#include "legojetskiraceactor.h" -#include "legoracemap.h" +// clang-format off #include "legoracespecial.h" +// clang-format on +#include "legoracemap.h" #define LEGORACECAR_UNKNOWN_0 0 #define LEGORACECAR_UNKNOWN_1 1 diff --git a/LEGO1/lego/legoomni/include/legoracespecial.h b/LEGO1/lego/legoomni/include/legoracespecial.h index c65605ff..b187e5d8 100644 --- a/LEGO1/lego/legoomni/include/legoracespecial.h +++ b/LEGO1/lego/legoomni/include/legoracespecial.h @@ -99,6 +99,55 @@ class LegoCarRaceActor : public virtual LegoRaceActor { static MxFloat g_unk0x100f7aec; }; +// VTABLE: LEGO1 0x100da208 LegoCarRaceActor +// VTABLE: LEGO1 0x100da228 LegoRaceActor +// VTABLE: LEGO1 0x100da230 LegoAnimActor +// VTABLE: LEGO1 0x100da240 LegoPathActor +// VTABLE: BETA10 0x101bd348 LegoCarRaceActor +// VTABLE: BETA10 0x101bd370 LegoRaceActor +// VTABLE: BETA10 0x101bd378 LegoAnimActor +// VTABLE: BETA10 0x101bd390 LegoPathActor +// SIZE 0x1a8 +class LegoJetskiRaceActor : public virtual LegoCarRaceActor { +public: + LegoJetskiRaceActor(); + + // FUNCTION: LEGO1 0x10081d90 + // FUNCTION: BETA10 0x100aa920 + const char* ClassName() const override // vtable+0x0c + { + // STRING: LEGO1 0x100f0554 + return "LegoJetskiRaceActor"; + } + + // FUNCTION: LEGO1 0x10081db0 + // FUNCTION: BETA10 0x100aa960 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, LegoJetskiRaceActor::ClassName()) || LegoCarRaceActor::IsA(p_name); + } + + 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 + MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c + + // SYNTHETIC: LEGO1 0x10013a80 + // LegoJetskiRaceActor::`vbase destructor' + + // SYNTHETIC: LEGO1 0x10081d50 + // LegoJetskiRaceActor::`scalar deleting destructor' + + // SYNTHETIC: LEGO1 0x10013ba0 + // LegoJetskiRaceActor::~LegoJetskiRaceActor +}; + // GLOBAL: LEGO1 0x100da0b0 // LegoCarRaceActor::`vbtable' @@ -108,4 +157,16 @@ class LegoCarRaceActor : public virtual LegoRaceActor { // GLOBAL: LEGO1 0x100da098 // LegoCarRaceActor::`vbtable'{for `LegoRaceActor'} +// GLOBAL: LEGO1 0x100da1f0 +// LegoJetskiRaceActor::`vbtable'{for `LegoJetskiRaceActor'} + +// GLOBAL: LEGO1 0x100da1e8 +// LegoJetskiRaceActor::`vbtable'{for `LegoAnimActor'} + +// GLOBAL: LEGO1 0x100da1d8 +// LegoJetskiRaceActor::`vbtable'{for `LegoRaceActor'} + +// GLOBAL: LEGO1 0x100da1c8 +// LegoJetskiRaceActor::`vbtable'{for `LegoCarRaceActor'} + #endif // LEGOCARRACEACTOR_H diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index 06bf7746..68a3b35a 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -72,7 +72,6 @@ #include "legoentitypresenter.h" #include "legoflctexturepresenter.h" #include "legohideanimpresenter.h" -#include "legojetskiraceactor.h" #include "legoloadcachesoundpresenter.h" #include "legolocomotionanimpresenter.h" #include "legoloopinganimpresenter.h" diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp deleted file mode 100644 index a4104078..00000000 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#include "legojetskiraceactor.h" - -#include "legonavcontroller.h" -#include "legopathcontroller.h" -#include "misc.h" -#include "mxmisc.h" -#include "mxvariabletable.h" - -#include - -DECOMP_SIZE_ASSERT(LegoJetskiRaceActor, 0x1a8) - -// GLOBAL: LEGO1 0x100da044 -// GLOBAL: BETA10 0x101be9fc -MxFloat g_unk0x100da044 = 8.0f; - -// FUNCTION: LEGO1 0x10080ef0 -// FUNCTION: BETA10 0x100a8990 -LegoJetskiRaceActor::LegoJetskiRaceActor() -{ - m_unk0x10 = 0.95f; - m_unk0x14 = 0.04f; - m_unk0x18 = 0.5f; - m_unk0x150 = 1.5f; -} - -// FUNCTION: LEGO1 0x10081120 -// FUNCTION: BETA10 0x100ce19f -MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) -{ - // These are almost certainly not the correct names, but they produce the correct BETA10 stack - Mx3DPointFloat a; - Mx3DPointFloat bbb; - Mx3DPointFloat c; - - // These names are verified by an assertion below - Vector3* v1 = NULL; - Vector3* v2 = NULL; - - if (m_actorState == c_one) { - if (m_destEdge == LegoPathController::GetControlEdgeA(13)) { - m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(13)); - } - else if (m_destEdge == LegoPathController::GetControlEdgeA(15)) { - m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(15)); - } - - m_actorState = c_initial; - m_unk0x7c = 0; - - if (m_userNavFlag) { - NavController()->SetLinearVel(m_worldSpeed); - return 0; - } - else { - return 1; - } - } - else { - if (p_edge == LegoPathController::GetControlEdgeA(12)) { - m_actorState = c_one; - - if (m_worldSpeed < g_unk0x100da044) { - m_worldSpeed = g_unk0x100da044; - } - - m_destEdge = LegoPathController::GetControlEdgeA(13); - m_boundary = LegoPathController::GetControlBoundaryA(13); - } - else if (p_edge == LegoPathController::GetControlEdgeA(14)) { - m_actorState = c_one; - - if (m_worldSpeed < g_unk0x100da044) { - m_worldSpeed = g_unk0x100da044; - } - - m_destEdge = LegoPathController::GetControlEdgeA(15); - m_boundary = LegoPathController::GetControlBoundaryA(15); - } - - if (m_actorState == c_one) { - if (m_userNavFlag) { - m_unk0xe4 = 0.5f; - } - - v1 = m_destEdge->CCWVertex(*m_boundary); - v2 = m_destEdge->CWVertex(*m_boundary); - assert(v1 && v2); - - LERP3(a, *v1, *v2, m_unk0xe4); - - m_destEdge->FUN_1002ddc0(*m_boundary, bbb); - c.EqualsCross(bbb, *m_boundary->GetUnknown0x14()); - c.Unitize(); - - Mx3DPointFloat worldDirection(m_roi->GetWorldDirection()); - - if (!m_userNavFlag) { - worldDirection *= -1.0f; - } - - if (VTable0x80(m_roi->GetWorldPosition(), worldDirection, a, c)) { -#ifndef BETA10 - m_unk0x7c = 0; - return 0; -#else - assert(0); - return -1; -#endif - } - - m_unk0x7c = 0; - return 0; - } - else { - return 1; - } - } -} - -// FUNCTION: LEGO1 0x10081550 -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_time - 1.0f; - m_unk0x1c = p_time; - } - else if (!m_userNavFlag) { - LegoAnimActor::Animate(m_lastTime + 1.0f); - } - } - - if (m_unk0x0c == 1) { - LegoAnimActor::Animate(p_time); - } -} - -// FUNCTION: LEGO1 0x10081fd0 -MxU32 LegoJetskiRaceActor::VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 -) -{ - LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); - - for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { - if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { - return 1; - } - } - - LegoPathActorSet& plpas = p_boundary->GetActors(); - LegoPathActorSet lpas(plpas); - - for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) { - if (plpas.find(*itpa) != plpas.end()) { - LegoPathActor* actor = *itpa; - - if (this != actor) { - 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->GetCollideBox())) { - HitActor(actor, TRUE); - - if (actor->HitActor(this, FALSE) < 0) { - return 0; - } - else { - return 2; - } - } - } - } - } - } - - return 0; -} diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp index d15a561f..aba79900 100644 --- a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp @@ -13,6 +13,7 @@ // File name verified by BETA10 0x100cedf7 DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0) +DECOMP_SIZE_ASSERT(LegoJetskiRaceActor, 0x1a8) // GLOBAL: LEGO1 0x100f0c68 // STRING: LEGO1 0x100f0c5c @@ -33,6 +34,10 @@ const char* g_racing = "RACING"; // GLOBAL: LEGO1 0x100f7aec MxFloat LegoCarRaceActor::g_unk0x100f7aec = 8.0f; +// GLOBAL: LEGO1 0x100da044 +// GLOBAL: BETA10 0x101be9fc +MxFloat g_unk0x100da044 = 8.0f; + // FUNCTION: LEGO1 0x10080350 // FUNCTION: BETA10 0x100cd6b0 LegoCarRaceActor::LegoCarRaceActor() @@ -284,6 +289,130 @@ MxResult LegoCarRaceActor::VTable0x9c() return SUCCESS; } +// FUNCTION: LEGO1 0x10080ef0 +// FUNCTION: BETA10 0x100a8990 +LegoJetskiRaceActor::LegoJetskiRaceActor() +{ + m_unk0x10 = 0.95f; + m_unk0x14 = 0.04f; + m_unk0x18 = 0.5f; + m_unk0x150 = 1.5f; +} + +// FUNCTION: LEGO1 0x10081120 +// FUNCTION: BETA10 0x100ce19f +MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) +{ + // These are almost certainly not the correct names, but they produce the correct BETA10 stack + Mx3DPointFloat a; + Mx3DPointFloat bbb; + Mx3DPointFloat c; + + // These names are verified by an assertion below + Vector3* v1 = NULL; + Vector3* v2 = NULL; + + if (m_actorState == c_one) { + if (m_destEdge == LegoPathController::GetControlEdgeA(13)) { + m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(13)); + } + else if (m_destEdge == LegoPathController::GetControlEdgeA(15)) { + m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(15)); + } + + m_actorState = c_initial; + m_unk0x7c = 0; + + if (m_userNavFlag) { + NavController()->SetLinearVel(m_worldSpeed); + return 0; + } + else { + return 1; + } + } + else { + if (p_edge == LegoPathController::GetControlEdgeA(12)) { + m_actorState = c_one; + + if (m_worldSpeed < g_unk0x100da044) { + m_worldSpeed = g_unk0x100da044; + } + + m_destEdge = LegoPathController::GetControlEdgeA(13); + m_boundary = LegoPathController::GetControlBoundaryA(13); + } + else if (p_edge == LegoPathController::GetControlEdgeA(14)) { + m_actorState = c_one; + + if (m_worldSpeed < g_unk0x100da044) { + m_worldSpeed = g_unk0x100da044; + } + + m_destEdge = LegoPathController::GetControlEdgeA(15); + m_boundary = LegoPathController::GetControlBoundaryA(15); + } + + if (m_actorState == c_one) { + if (m_userNavFlag) { + m_unk0xe4 = 0.5f; + } + + v1 = m_destEdge->CCWVertex(*m_boundary); + v2 = m_destEdge->CWVertex(*m_boundary); + assert(v1 && v2); + + LERP3(a, *v1, *v2, m_unk0xe4); + + m_destEdge->FUN_1002ddc0(*m_boundary, bbb); + c.EqualsCross(bbb, *m_boundary->GetUnknown0x14()); + c.Unitize(); + + Mx3DPointFloat worldDirection(m_roi->GetWorldDirection()); + + if (!m_userNavFlag) { + worldDirection *= -1.0f; + } + + if (VTable0x80(m_roi->GetWorldPosition(), worldDirection, a, c)) { +#ifndef BETA10 + m_unk0x7c = 0; + return 0; +#else + assert(0); + return -1; +#endif + } + + m_unk0x7c = 0; + return 0; + } + else { + return 1; + } + } +} + +// FUNCTION: LEGO1 0x10081550 +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_time - 1.0f; + m_unk0x1c = p_time; + } + else if (!m_userNavFlag) { + LegoAnimActor::Animate(m_lastTime + 1.0f); + } + } + + if (m_unk0x0c == 1) { + LegoAnimActor::Animate(p_time); + } +} + // FUNCTION: LEGO1 0x10081840 // FUNCTION: BETA10 0x100cf680 MxU32 LegoCarRaceActor::VTable0x6c( @@ -383,3 +512,50 @@ MxU32 LegoCarRaceActor::VTable0x6c( return 0; } + +// FUNCTION: LEGO1 0x10081fd0 +MxU32 LegoJetskiRaceActor::VTable0x6c( + LegoPathBoundary* p_boundary, + Vector3& p_v1, + Vector3& p_v2, + float p_f1, + float p_f2, + Vector3& p_v3 +) +{ + LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); + + for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) { + if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) { + return 1; + } + } + + LegoPathActorSet& plpas = p_boundary->GetActors(); + LegoPathActorSet lpas(plpas); + + for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) { + if (plpas.find(*itpa) != plpas.end()) { + LegoPathActor* actor = *itpa; + + if (this != actor) { + 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->GetCollideBox())) { + HitActor(actor, TRUE); + + if (actor->HitActor(this, FALSE) < 0) { + return 0; + } + else { + return 2; + } + } + } + } + } + } + + return 0; +}