From 1ab29590eeada37ff9434312781cbd638086b06b Mon Sep 17 00:00:00 2001
From: Nathan M Gilbert <tahgtahv@gmail.com>
Date: Tue, 24 Oct 2023 04:14:45 -0400
Subject: [PATCH] Start of helicopter Implementation (#239)

* Start of helicopter Implementation

Mostly Matching, some issues with MxMatrix and/or MxVector4

* Fix some style issues

* Fix some style issues
---
 LEGO1/act3.cpp          |  2 ++
 LEGO1/act3.h            |  5 +++++
 LEGO1/helicopter.cpp    | 38 ++++++++++++++++++++++++++++++++++----
 LEGO1/helicopter.h      | 21 ++++++++++++++++++++-
 LEGO1/islepathactor.cpp |  8 ++++----
 LEGO1/islepathactor.h   | 15 +++++++++++++--
 LEGO1/legoworld.cpp     |  2 +-
 LEGO1/legoworld.h       |  2 +-
 LEGO1/mxentity.h        |  8 +++++++-
 9 files changed, 87 insertions(+), 14 deletions(-)

diff --git a/LEGO1/act3.cpp b/LEGO1/act3.cpp
index eca84fbf..3d152bfc 100644
--- a/LEGO1/act3.cpp
+++ b/LEGO1/act3.cpp
@@ -1,5 +1,7 @@
 #include "act3.h"
 
+DECOMP_SIZE_ASSERT(Act3, 0x4274)
+
 // OFFSET: LEGO1 0x10072270 STUB
 Act3::Act3()
 {
diff --git a/LEGO1/act3.h b/LEGO1/act3.h
index d0cad28a..6bef1711 100644
--- a/LEGO1/act3.h
+++ b/LEGO1/act3.h
@@ -25,6 +25,11 @@ public:
     return !strcmp(name, Act3::ClassName()) || LegoWorld::IsA(name);
   }
 
+  inline void SetUnkown420c(MxEntity *p_entity) { m_unk420c = p_entity; }
+  protected:
+    undefined m_unkf8[0x4114];
+    MxEntity *m_unk420c;
+    undefined m_unk4210[0x64];
 };
 
 
diff --git a/LEGO1/helicopter.cpp b/LEGO1/helicopter.cpp
index 318f3dab..04195407 100644
--- a/LEGO1/helicopter.cpp
+++ b/LEGO1/helicopter.cpp
@@ -1,13 +1,43 @@
 #include "helicopter.h"
+#include "act3.h"
+#include "legoomni.h"
+#include "legocontrolmanager.h"
+#include "legogamestate.h"
+#include "legoworld.h"
 
-// OFFSET: LEGO1 0x10001e60 STUB
+DECOMP_SIZE_ASSERT(Helicopter, 0x230)
+
+// OFFSET: LEGO1 0x10001e60
 Helicopter::Helicopter()
 {
-  // TODO
+  m_unk13c = 60;
 }
 
-// OFFSET: LEGO1 0x10003230 STUB
+// OFFSET: LEGO1 0x10003230
 Helicopter::~Helicopter()
 {
-  // TODO
+  ControlManager()->Unregister(this);
+  IslePathActor::Destroy(TRUE);
 }
+
+// OFFSET: LEGO1 0x100032c0
+MxResult Helicopter::InitFromMxDSObject(MxDSObject &p_dsObject)
+{
+  MxResult result = IslePathActor::InitFromMxDSObject(p_dsObject);
+  LegoWorld *world = GetCurrentWorld();
+  SetWorld(world);
+  if (world->IsA("Act3")) {
+    ((Act3 *)GetWorld())->SetUnkown420c(this);
+  }
+  world = GetWorld();
+  if (world) world->VTable0x58(this); 
+  GetState();
+  return result;
+}
+
+// OFFSET: LEGO1 0x10003320
+void Helicopter::GetState()
+{
+  m_state = (HelicopterState *)GameState()->GetState("HelicopterState");
+  if (!m_state) m_state = (HelicopterState *)GameState()->CreateState("HelicopterState");
+}
\ No newline at end of file
diff --git a/LEGO1/helicopter.h b/LEGO1/helicopter.h
index 15134f32..61cbd2cb 100644
--- a/LEGO1/helicopter.h
+++ b/LEGO1/helicopter.h
@@ -1,7 +1,9 @@
 #ifndef HELICOPTER_H
 #define HELICOPTER_H
 
+#include "helicopterstate.h"
 #include "islepathactor.h"
+#include "mxmatrix.h"
 
 // VTABLE 0x100d40f8
 // SIZE 0x230
@@ -9,7 +11,6 @@ class Helicopter : public IslePathActor
 {
 public:
   Helicopter();
-  virtual ~Helicopter(); // vtable+0x0
 
   // OFFSET: LEGO1 0x10003070
   inline virtual const char *ClassName() const override // vtable+0x0c
@@ -24,6 +25,24 @@ public:
     return !strcmp(name, Helicopter::ClassName()) || IslePathActor::IsA(name);
   }
 
+  virtual MxResult InitFromMxDSObject(MxDSObject &p_dsObject) override; // vtable+0x18
+
+  // OFFSET: LEGO1 0x10003210 TEMPLATE
+  // Helicopter::`scalar deleting destructor'
+  virtual ~Helicopter() override; // vtable+0x0
+
+protected:
+  MxMatrixData m_unk160;
+  MxMatrixData m_unk1a8;
+  undefined4 m_unk1f0;
+  MxVector4Data m_unk1f4;
+  MxVector4Data m_unk20c;
+  undefined4 m_unk224;
+  HelicopterState *m_state;
+  MxAtomId m_unk22c;
+
+private:
+  void GetState();
 };
 
 #endif // HELICOPTER_H
diff --git a/LEGO1/islepathactor.cpp b/LEGO1/islepathactor.cpp
index 0024b4bc..e2b6a6ee 100644
--- a/LEGO1/islepathactor.cpp
+++ b/LEGO1/islepathactor.cpp
@@ -11,7 +11,7 @@ IslePathActor::IslePathActor()
   this->m_unk158 = 0;
 }
 
-// OFFSET: LEGO1 0x10002e10
-IslePathActor::~IslePathActor()
-{
-}
+// OFFSET: LEGO1 0x1001a280
+MxResult IslePathActor::InitFromMxDSObject(MxDSObject &p_dsObject) {
+  return MxEntity::InitFromMxDSObject(p_dsObject);
+}
\ No newline at end of file
diff --git a/LEGO1/islepathactor.h b/LEGO1/islepathactor.h
index f4574355..be10d349 100644
--- a/LEGO1/islepathactor.h
+++ b/LEGO1/islepathactor.h
@@ -11,7 +11,6 @@ class IslePathActor : public LegoPathActor
 {
 public: 
   IslePathActor();
-  ~IslePathActor();
 
   // OFFSET: LEGO1 0x10002ea0
   inline virtual const char *ClassName() const override // vtable+0x0c
@@ -26,8 +25,20 @@ public:
     return !strcmp(name, IslePathActor::ClassName()) || LegoPathActor::IsA(name);
   }
 
+  // OFFSET: LEGO1 0x10002ff0 TEMPLATE
+  // IslePathActor::`scalar deleting destructor'
+  inline virtual ~IslePathActor() override
+  {
+    IslePathActor::Destroy(TRUE);
+  }
+
+  virtual MxResult InitFromMxDSObject(MxDSObject &p_dsObject) override; // vtable+0x18
+  
+  inline void SetWorld(LegoWorld *p_world) { m_pLegoWorld = p_world; }
+  inline LegoWorld *GetWorld() { return m_pLegoWorld; }
+  
 private:
-  LegoWorld* m_pLegoWorld; // 0x154
+  LegoWorld *m_pLegoWorld; // 0x154
   MxFloat m_unk158;
   MxFloat m_unk15c;
 };
diff --git a/LEGO1/legoworld.cpp b/LEGO1/legoworld.cpp
index 7f4c8c34..b56bae3d 100644
--- a/LEGO1/legoworld.cpp
+++ b/LEGO1/legoworld.cpp
@@ -32,7 +32,7 @@ void LegoWorld::VTable0x54()
 }
 
 // OFFSET: LEGO1 0x10020220 STUB
-void LegoWorld::VTable0x58()
+void LegoWorld::VTable0x58(MxCore *p_object)
 {
   // TODO
 }
diff --git a/LEGO1/legoworld.h b/LEGO1/legoworld.h
index 5c404804..8a8fab97 100644
--- a/LEGO1/legoworld.h
+++ b/LEGO1/legoworld.h
@@ -27,7 +27,7 @@ public:
 
   virtual void Stop(); // vtable+50
   virtual void VTable0x54(); // vtable+54
-  virtual void VTable0x58(); // vtable+58
+  virtual void VTable0x58(MxCore *p_object); // vtable+58
   virtual MxBool VTable0x5c();  // vtable+5c
   virtual void VTable0x60();  // vtable+60
   virtual MxBool VTable0x64(); // vtable+64
diff --git a/LEGO1/mxentity.h b/LEGO1/mxentity.h
index c897732d..86baf5a1 100644
--- a/LEGO1/mxentity.h
+++ b/LEGO1/mxentity.h
@@ -4,6 +4,7 @@
 #include "decomp.h"
 #include "mxatomid.h"
 #include "mxcore.h"
+#include "mxdsobject.h"
 #include "mxtypes.h"
 
 // VTABLE 0x100d5390
@@ -28,7 +29,12 @@ public:
   }
 
   virtual MxResult SetEntityId(MxS32 p_id, const MxAtomId &p_atom); // vtable+0x14
-
+  inline  MxResult InitFromMxDSObject(MxDSObject &p_dsObject)
+  {
+    m_mxEntityId = p_dsObject.GetObjectId();
+    m_atom = p_dsObject.GetAtomId();
+    return SUCCESS;
+  }
 protected:
   MxS32 m_mxEntityId; // 0x8
   MxAtomId m_atom; // 0xc