From 6431405e92f8441c93d4d8f8e0bb2e3c50c8e74c Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Mon, 18 Nov 2024 20:32:48 +0100 Subject: [PATCH] Implement parts of LegoJetskiRaceActor (#1159) * Implement part of LegoJetskiRaceActor * Fix linter errors * Update legojetskiraceactor.cpp Fix minor incorrectness * Address review comments --------- Co-authored-by: jonschz --- .../legoomni/include/legojetskiraceactor.h | 18 +++ LEGO1/lego/legoomni/include/legoracespecial.h | 4 + .../src/entity/legojetskiraceactor.cpp | 124 +++++++++++++++++- LEGO1/lego/legoomni/src/race/jetskirace.cpp | 4 - 4 files changed, 141 insertions(+), 9 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legojetskiraceactor.h b/LEGO1/lego/legoomni/include/legojetskiraceactor.h index e2689968..f60a02ff 100644 --- a/LEGO1/lego/legoomni/include/legojetskiraceactor.h +++ b/LEGO1/lego/legoomni/include/legojetskiraceactor.h @@ -7,12 +7,17 @@ // 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 @@ -20,6 +25,7 @@ class LegoJetskiRaceActor : public virtual LegoCarRaceActor { } // 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); @@ -46,4 +52,16 @@ class LegoJetskiRaceActor : public virtual LegoCarRaceActor { // 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/legoracespecial.h b/LEGO1/lego/legoomni/include/legoracespecial.h index 76245493..42a2d437 100644 --- a/LEGO1/lego/legoomni/include/legoracespecial.h +++ b/LEGO1/lego/legoomni/include/legoracespecial.h @@ -3,6 +3,10 @@ #include "legoraceactor.h" +extern const char* g_raceState; +extern const char* g_fuel; +extern const char* g_racing; + // VTABLE: LEGO1 0x100da0c0 LegoRaceActor // VTABLE: LEGO1 0x100da0c8 LegoAnimActor // VTABLE: LEGO1 0x100da0d8 LegoPathActor diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp index ae020f15..7ecaa04a 100644 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp @@ -1,8 +1,21 @@ #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 +const MxFloat g_eight = 8.0f; + // FUNCTION: LEGO1 0x10080ef0 +// FUNCTION: BETA10 0x100a8990 LegoJetskiRaceActor::LegoJetskiRaceActor() { m_unk0x10 = 0.95f; @@ -11,17 +24,118 @@ LegoJetskiRaceActor::LegoJetskiRaceActor() m_unk0x150 = 1.5f; } -// STUB: LEGO1 0x10081120 +// FUNCTION: LEGO1 0x10081120 +// FUNCTION: BETA10 0x100ce19f MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) { - // TODO - return 0; + // 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_state == 1) { + 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_state = 0; + m_unk0x7c = 0; + + if (m_userNavFlag) { + NavController()->SetLinearVel(m_worldSpeed); + return 0; + } + else { + return 1; + } + } + else { + if (p_edge == LegoPathController::GetControlEdgeA(12)) { + m_state = 1; + + if (m_worldSpeed < g_eight) { + m_worldSpeed = g_eight; + } + + m_destEdge = LegoPathController::GetControlEdgeA(13); + m_boundary = LegoPathController::GetControlBoundaryA(13); + } + else if (p_edge == LegoPathController::GetControlEdgeA(14)) { + m_state = 1; + + if (m_worldSpeed < g_eight) { + m_worldSpeed = g_eight; + } + + m_destEdge = LegoPathController::GetControlEdgeA(15); + m_boundary = LegoPathController::GetControlBoundaryA(15); + } + + if (m_state == 1) { + 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) { + ((Vector2*) &worldDirection)->Mul(-1.0f); + } + + if (VTable0x80(m_roi->GetWorldPosition(), worldDirection, a, c)) { +#ifdef NDEBUG + m_unk0x7c = 0; + return 0; +#else + assert(0); + return -1; +#endif + } + + m_unk0x7c = 0; + return 0; + } + else { + return 1; + } + } } -// STUB: LEGO1 0x10081550 +// FUNCTION: LEGO1 0x10081550 void LegoJetskiRaceActor::VTable0x70(float p_float) { - // TODO + 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; + } + else if (!m_userNavFlag) { + LegoAnimActor::VTable0x70(m_lastTime + 1.0f); + } + } + + if (m_unk0x0c == 1) { + LegoAnimActor::VTable0x70(p_float); + } } // STUB: LEGO1 0x10081fd0 diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index e2af449d..b4ffa03e 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -29,10 +29,6 @@ extern MxBool g_unk0x100f119c; extern const char* g_varJSFRNTY5; extern const char* g_varJSWNSHY5; -// Defined in legoracespecial.cpp -extern const char* g_raceState; -extern const char* g_racing; - // Defined in legopathactor.cpp extern const char* g_strHIT_WALL_SOUND;