From 60b747d7b2687b6df498634c6bc05b5d218c4e26 Mon Sep 17 00:00:00 2001
From: Christian Semmler <mail@csemmler.com>
Date: Tue, 28 May 2024 11:20:23 -0400
Subject: [PATCH] Implement/match LegoPathBoundary::FUN_100586e0 and
 FUN_10057fe0 (#962)

---
 .../lego/legoomni/include/legoanimpresenter.h |  4 ++
 .../lego/legoomni/include/legopathboundary.h  | 33 +++++++++++++++
 .../legoomni/src/paths/legopathboundary.cpp   | 40 ++++++++++++++++---
 LEGO1/lego/sources/geom/legowegedge.h         |  2 +-
 4 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h
index f4745c18..d9d97bb5 100644
--- a/LEGO1/lego/legoomni/include/legoanimpresenter.h
+++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h
@@ -83,8 +83,12 @@ public:
 	MxResult FUN_1006b140(LegoROI* p_roi);
 	const char* GetActionObjectName();
 
+	inline void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; }
+
 	inline LegoAnim* GetAnimation() { return m_anim; }
 
+	friend class LegoPathBoundary;
+
 protected:
 	void Init();
 	void Destroy(MxBool p_fromDestructor);
diff --git a/LEGO1/lego/legoomni/include/legopathboundary.h b/LEGO1/lego/legoomni/include/legopathboundary.h
index f46633d7..570b2ea2 100644
--- a/LEGO1/lego/legoomni/include/legopathboundary.h
+++ b/LEGO1/lego/legoomni/include/legopathboundary.h
@@ -131,6 +131,39 @@ private:
 // TEMPLATE: LEGO1 0x100573e0
 // _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::begin
 
+// TEMPLATE: LEGO1 0x100580c0
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::insert
+
+// TEMPLATE: LEGO1 0x10058330
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::iterator::_Dec
+
+// TEMPLATE: LEGO1 0x10058380
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Buynode
+
+// TEMPLATE: LEGO1 0x100583a0
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Insert
+
+// TEMPLATE: LEGO1 0x10058620
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Lrotate
+
+// TEMPLATE: LEGO1 0x10058680
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Rrotate
+
+// TEMPLATE: LEGO1 0x10058820
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::erase
+
+// TEMPLATE: LEGO1 0x100588e0
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::equal_range
+
+// TEMPLATE: LEGO1 0x10058950
+// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Lbound
+
+// TEMPLATE: LEGO1 0x10058980
+// _Construct
+
+// TEMPLATE: LEGO1 0x100589a0
+// _Distance
+
 // GLOBAL: LEGO1 0x100f11a4
 // _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Nil
 
diff --git a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp
index 057143ec..81108d61 100644
--- a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp
+++ b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp
@@ -2,6 +2,7 @@
 
 #include "decomp.h"
 #include "geom/legounkown100db7f4.h"
+#include "legolocomotionanimpresenter.h"
 #include "legopathactor.h"
 #include "legopathstruct.h"
 
@@ -337,18 +338,47 @@ MxU32 LegoPathBoundary::Intersect(
 	return 0;
 }
 
-// STUB: LEGO1 0x10057fe0
+// FUNCTION: LEGO1 0x10057fe0
 // FUNCTION: BETA10 0x100b2220
 MxU32 LegoPathBoundary::FUN_10057fe0(LegoAnimPresenter* p_presenter)
 {
-	// TODO
-	return 0;
+	Mx3DPointFloat unk0x30;
+
+	unk0x30 = m_unk0x30;
+	((Vector3&) unk0x30).Sub(&p_presenter->m_unk0xa8);
+
+	float len = unk0x30.LenSquared();
+	float local20 = p_presenter->m_unk0xa4 + m_unk0x44;
+
+	if (len > 0.001 && len > local20 * local20) {
+		return 0;
+	}
+
+	// TODO: This only seems to match if the type is not the same as the type of the
+	// key value of the set. Figure out which type the set (or parameter) actually uses.
+	// Also see call to .find in LegoPathController::FUN_10046050
+	m_presenters.insert(static_cast<LegoLocomotionAnimPresenter*>(p_presenter));
+	return 1;
 }
 
-// STUB: LEGO1 0x100586e0
+// FUNCTION: LEGO1 0x100586e0
 // FUNCTION: BETA10 0x100b22d1
 MxU32 LegoPathBoundary::FUN_100586e0(LegoAnimPresenter* p_presenter)
 {
-	// TODO
+	if (p_presenter != NULL) {
+		// TODO: This only seems to match if the type is not the same as the type of the
+		// key value of the set. Figure out which type the set (or parameter) actually uses.
+		// Also see call to .find in LegoPathController::FUN_10046050
+		if (m_presenters.find(static_cast<LegoLocomotionAnimPresenter*>(p_presenter)) != m_presenters.end()) {
+			m_presenters.erase(static_cast<LegoLocomotionAnimPresenter*>(p_presenter));
+			return 1;
+		}
+	}
+	else {
+		for (LegoAnimPresenterSet::iterator it = m_presenters.begin(); it != m_presenters.end(); it++) {
+			(*it)->SetCurrentWorld(NULL);
+		}
+	}
+
 	return 0;
 }
diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h
index aff336e6..efce4662 100644
--- a/LEGO1/lego/sources/geom/legowegedge.h
+++ b/LEGO1/lego/sources/geom/legowegedge.h
@@ -69,7 +69,7 @@ protected:
 	Mx4DPointFloat m_unk0x14;       // 0x14
 	Mx4DPointFloat* m_edgeNormals;  // 0x2c
 	Mx3DPointFloat m_unk0x30;       // 0x30
-	LegoU32 m_unk0x44;              // 0x44
+	float m_unk0x44;                // 0x44
 	LegoU8 m_unk0x48;               // 0x48
 	PathWithTrigger* m_pathTrigger; // 0x4c
 	Mx3DPointFloat* m_unk0x50;      // 0x50