From 47f456e4e70b22612911c9a576fd5db916d771f3 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 19 Sep 2020 14:52:43 -0400 Subject: [PATCH] CScriptMazeNode: Start implementing AcceptScriptMsg --- Runtime/CStateManager.hpp | 5 +- Runtime/World/CScriptMazeNode.cpp | 84 +++++++++++++++++++++++++++++++ Runtime/World/CScriptMazeNode.hpp | 14 ++++-- 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 4a2f1c153..556695737 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -191,7 +191,7 @@ private: std::list xf3c_activeFlickerBats; std::list xf54_activeParasites; TUniqueId xf6c_playerActorHead = kInvalidUniqueId; - std::unique_ptr xf70_currentMaze; + std::unique_ptr xf70_currentMaze; TUniqueId xf74_lastTrigger = kInvalidUniqueId; TUniqueId xf76_lastRelay = kInvalidUniqueId; @@ -420,6 +420,9 @@ public: return static_cast(*x808_objLists[7]); } std::pair CalculateScanCompletionRate() const; + void SetCurrentMaze(std::unique_ptr maze) { xf70_currentMaze = std::move(maze); } + void ClearCurrentMaze() { xf70_currentMaze.reset(); } + CScriptMazeState* GetCurrentMaze() { return xf70_currentMaze.get(); } void SetLastTriggerId(TUniqueId uid) { xf74_lastTrigger = uid; } TUniqueId GetLastTriggerId() const { return xf74_lastTrigger; } void SetLastRelayId(TUniqueId uid) { xf76_lastRelay = uid; } diff --git a/Runtime/World/CScriptMazeNode.cpp b/Runtime/World/CScriptMazeNode.cpp index b5ad3da9a..35e66a2fd 100644 --- a/Runtime/World/CScriptMazeNode.cpp +++ b/Runtime/World/CScriptMazeNode.cpp @@ -26,6 +26,30 @@ CScriptMazeNode::CScriptMazeNode(TUniqueId uid, std::string_view name, const CEn void CScriptMazeNode::Accept(IVisitor& visitor) { visitor.Visit(this); } +void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + if (GetActive()) { + if (msg == EScriptObjectMessage::Action) { + // TODO + } else if (msg == EScriptObjectMessage::SetToZero) { + // TODO + } else if (msg == EScriptObjectMessage::Deactivate) { + // TODO + } else if (msg == EScriptObjectMessage::InitializedInArea) { + if (mgr.GetCurrentMaze() == nullptr) { + auto maze = std::make_unique(4, 4, 5, 3); + maze->Reset(sMazeSeeds[mgr.GetActiveRandom()->Next() % sMazeSeeds.size()]); + maze->Initialize(); + // sub_802899c8 + mgr.SetCurrentMaze(std::move(maze)); + } + } else if (msg == EScriptObjectMessage::Deleted) { + mgr.ClearCurrentMaze(); + Reset(mgr); + } + } + CActor::AcceptScriptMsg(msg, uid, mgr); +} + void CScriptMazeNode::LoadMazeSeeds() { const SObjectTag* tag = g_ResFactory->GetResourceIdByName("DUMB_MazeSeeds"); const u32 resSize = g_ResFactory->ResourceSize(*tag); @@ -79,4 +103,64 @@ void CScriptMazeNode::Reset(CStateManager& mgr) { x10c_triggerId = kInvalidUniqueId; x11c_effectId = kInvalidUniqueId; } + +void CScriptMazeState::Reset(s32 seed) { + x0_rand.SetSeed(seed); + x94_24_initialized = false; + x4_arr.fill({}); + // TODO wtf is the rest? +} + +void CScriptMazeState::Initialize() { + std::array arr{}; + arr[0] = x84_ + x88_ * 9; + x4_arr[arr[0]].x1_26_ = true; + size_t i = 1; + while (true) { + if (arr[0] == x8c_ + x90_ * 9) { + break; + } + if (x4_arr[arr[0]].x0_24_) { + if (!x4_arr[arr[0] - 9].x1_26_) { + arr[i] = arr[0] - 9; + i++; + } + } + if (x4_arr[arr[0]].x0_25_) { + if (!x4_arr[arr[0] + 1].x1_26_) { + arr[i] = arr[0] + 1; + i++; + } + } + if (x4_arr[arr[0]].x0_26_) { + if (!x4_arr[arr[0] + 9].x1_26_) { + arr[i] = arr[0] + 9; + i++; + } + } + if (x4_arr[arr[0]].x0_27_) { + if (!x4_arr[arr[0] - 1].x1_26_) { + arr[i] = arr[0] - 1; + i++; + } + } + if (arr[0] == arr[i - 1]) { + i--; + } + arr[0] = arr[i - 1]; + x4_arr[arr[0]].x1_26_ = true; + } + size_t* v = &arr[i]; + while (true) { + if (i == 0) { + break; + } + i--; + v--; + if (x4_arr[*v].x1_26_) { + x4_arr[*v].x1_25_ = true; + } + } + x94_24_initialized = true; +} } // namespace urde diff --git a/Runtime/World/CScriptMazeNode.hpp b/Runtime/World/CScriptMazeNode.hpp index 92247ecdf..be2fafdf6 100644 --- a/Runtime/World/CScriptMazeNode.hpp +++ b/Runtime/World/CScriptMazeNode.hpp @@ -10,7 +10,7 @@ #include namespace urde { -struct CUnknownMazeNodeItem { +struct CScriptMazeStateCell { bool x0_24_ : 1 = false; bool x0_25_ : 1 = false; bool x0_26_ : 1 = false; @@ -23,17 +23,22 @@ struct CUnknownMazeNodeItem { bool x1_25_ : 1 = false; bool x1_26_ : 1 = false; }; -class CUnknownMazeNode { + +class CScriptMazeState { CRandom16 x0_rand{0}; - std::array x4_arr{}; + std::array x4_arr{}; s32 x84_; s32 x88_; s32 x8c_; s32 x90_; bool x94_24_initialized : 1 = false; - CUnknownMazeNode(s32 w1, s32 w2, s32 w3, s32 w4) : x84_(w1), x88_(w2), x8c_(w3), x90_(w4) {} +public: + CScriptMazeState(s32 w1, s32 w2, s32 w3, s32 w4) : x84_(w1), x88_(w2), x8c_(w3), x90_(w4) {} + void Reset(s32 seed); + void Initialize(); }; + class CScriptMazeNode : public CActor { static std::array sMazeSeeds; s32 xe8_; @@ -57,6 +62,7 @@ public: const zeus::CVector3f&, const zeus::CVector3f&, const zeus::CVector3f&); void Accept(IVisitor& visitor) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; static void LoadMazeSeeds(); private: