diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0f84d67431..40a701fe42 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -387,20 +387,19 @@ 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
-    LEGO1/main.cpp
     # We need to get rid of / refactor the below units into existing/other ones
+    LEGO1/main.cpp
     LEGO1/lego/legoomni/src/entity/legolocations.cpp
     LEGO1/lego/legoomni/src/notify/legoeventnotificationparam.cpp
     LEGO1/lego/legoomni/src/common/legoactors.cpp
diff --git a/LEGO1/lego/legoomni/include/legoextraactor.h b/LEGO1/lego/legoomni/include/legoextraactor.h
index 5f9308204d..05ee8510c5 100644
--- a/LEGO1/lego/legoomni/include/legoextraactor.h
+++ b/LEGO1/lego/legoomni/include/legoextraactor.h
@@ -2,7 +2,6 @@
 #define LEGOEXTRAACTOR_H
 
 #include "legoanimactor.h"
-#include "legopathboundary.h"
 
 // VTABLE: LEGO1 0x100d6c00 LegoAnimActor
 // VTABLE: LEGO1 0x100d6c10 LegoPathActor
@@ -78,108 +77,6 @@ class LegoExtraActor : public virtual LegoAnimActor {
 	LegoAnimActorStruct* m_disAnim; // 0x64
 };
 
-// FUNCTION: LEGO1 0x1002b980
-inline MxU32 LegoExtraActor::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 && !(actor->GetActorState() & LegoPathActor::c_noCollide)) {
-				LegoROI* roi = actor->GetROI();
-
-				if ((roi != NULL && roi->GetVisibility()) || actor->GetCameraFlag()) {
-					if (actor->GetUserNavFlag()) {
-						MxMatrix local2world = roi->GetLocal2World();
-						Vector3 local60(local2world[3]);
-						Mx3DPointFloat local54(p_v1);
-
-						local54 -= local60;
-						float local1c = p_v2.Dot(p_v2, p_v2);
-						float local24 = p_v2.Dot(p_v2, local54) * 2.0f;
-						float local20 = local54.Dot(local54, local54);
-
-						if (m_unk0x15 != 0 && local20 < 10.0f) {
-							return 0;
-						}
-
-						local20 -= 1.0f;
-
-						if (local1c >= 0.001 || local1c <= -0.001) {
-							float local40 = (local24 * local24) + (local20 * local1c * -4.0f);
-
-							if (local40 >= -0.001) {
-								local1c *= 2.0f;
-								local24 = -local24;
-
-								if (local40 < 0.0f) {
-									local40 = 0.0f;
-								}
-
-								local40 = sqrt(local40);
-								float local20X = (local24 + local40) / local1c;
-								float local1cX = (local24 - local40) / local1c;
-
-								if (local1cX < local20X) {
-									local40 = local20X;
-									local20X = local1cX;
-									local1cX = local40;
-								}
-
-								if ((local20X >= 0.0f && local20X <= p_f1) || (local1cX >= 0.0f && local1cX <= p_f1) ||
-									(local20X <= -0.01 && p_f1 + 0.01 <= local1cX)) {
-									p_v3 = p_v1;
-
-									if (HitActor(actor, TRUE) < 0) {
-										return 0;
-									}
-
-									actor->HitActor(this, FALSE);
-									return 2;
-								}
-							}
-						}
-					}
-					else {
-						if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
-							if (HitActor(actor, TRUE) < 0) {
-								return 0;
-							}
-
-							actor->HitActor(this, FALSE);
-							return 2;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	if (m_unk0x15 != 0) {
-		m_unk0x15--;
-	}
-
-	return 0;
-}
-
 // GLOBAL: LEGO1 0x100d6be8
 // LegoExtraActor::`vbtable'{for `LegoAnimActor'}
 
diff --git a/LEGO1/lego/legoomni/include/legojetskiraceactor.h b/LEGO1/lego/legoomni/include/legojetskiraceactor.h
deleted file mode 100644
index c9964e8d06..0000000000
--- 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 461b3a52fe..54a29ecab6 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 c65605ff58..3382a39462 100644
--- a/LEGO1/lego/legoomni/include/legoracespecial.h
+++ b/LEGO1/lego/legoomni/include/legoracespecial.h
@@ -35,7 +35,7 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
 		return !strcmp(p_name, LegoCarRaceActor::ClassName()) || LegoRaceActor::IsA(p_name);
 	}
 
-	MxU32 VTable0x6c(
+	inline MxU32 VTable0x6c(
 		LegoPathBoundary* p_boundary,
 		Vector3& p_v1,
 		Vector3& p_v2,
@@ -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);
+	}
+
+	inline 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 06bf77462e..68a3b35a41 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 a410407818..0000000000
--- 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 <vec.h>
-
-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/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp
index 2c2bd16649..3cbbf03206 100644
--- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp
+++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp
@@ -420,3 +420,105 @@ MxS32 LegoExtraActor::VTable0x68(Vector3& p_point1, Vector3& p_point2, Vector3&
 {
 	return LegoPathActor::VTable0x68(p_point1, p_point2, p_point3);
 }
+
+// FUNCTION: LEGO1 0x1002b980
+inline MxU32 LegoExtraActor::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 && !(actor->GetActorState() & LegoPathActor::c_noCollide)) {
+				LegoROI* roi = actor->GetROI();
+
+				if ((roi != NULL && roi->GetVisibility()) || actor->GetCameraFlag()) {
+					if (actor->GetUserNavFlag()) {
+						MxMatrix local2world = roi->GetLocal2World();
+						Vector3 local60(local2world[3]);
+						Mx3DPointFloat local54(p_v1);
+
+						local54 -= local60;
+						float local1c = p_v2.Dot(p_v2, p_v2);
+						float local24 = p_v2.Dot(p_v2, local54) * 2.0f;
+						float local20 = local54.Dot(local54, local54);
+
+						if (m_unk0x15 != 0 && local20 < 10.0f) {
+							return 0;
+						}
+
+						local20 -= 1.0f;
+
+						if (local1c >= 0.001 || local1c <= -0.001) {
+							float local40 = (local24 * local24) + (local20 * local1c * -4.0f);
+
+							if (local40 >= -0.001) {
+								local1c *= 2.0f;
+								local24 = -local24;
+
+								if (local40 < 0.0f) {
+									local40 = 0.0f;
+								}
+
+								local40 = sqrt(local40);
+								float local20X = (local24 + local40) / local1c;
+								float local1cX = (local24 - local40) / local1c;
+
+								if (local1cX < local20X) {
+									local40 = local20X;
+									local20X = local1cX;
+									local1cX = local40;
+								}
+
+								if ((local20X >= 0.0f && local20X <= p_f1) || (local1cX >= 0.0f && local1cX <= p_f1) ||
+									(local20X <= -0.01 && p_f1 + 0.01 <= local1cX)) {
+									p_v3 = p_v1;
+
+									if (HitActor(actor, TRUE) < 0) {
+										return 0;
+									}
+
+									actor->HitActor(this, FALSE);
+									return 2;
+								}
+							}
+						}
+					}
+					else {
+						if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
+							if (HitActor(actor, TRUE) < 0) {
+								return 0;
+							}
+
+							actor->HitActor(this, FALSE);
+							return 2;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if (m_unk0x15 != 0) {
+		m_unk0x15--;
+	}
+
+	return 0;
+}
diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp
index d15a561ff5..06d7908298 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,9 +289,133 @@ 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(
+inline MxU32 LegoCarRaceActor::VTable0x6c(
 	LegoPathBoundary* p_boundary,
 	Vector3& p_v1,
 	Vector3& p_v2,
@@ -383,3 +512,50 @@ MxU32 LegoCarRaceActor::VTable0x6c(
 
 	return 0;
 }
+
+// FUNCTION: LEGO1 0x10081fd0
+inline 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;
+}