diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index a997e8e26..d37afdc8d 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -537,6 +537,7 @@ void CStateManager::BuildDynamicLightListForWorld() { void CStateManager::DrawDebugStuff() const { #ifndef NDEBUG + CGraphics::SetModelMatrix(zeus::CTransform()); for (CEntity* ent : GetActorObjectList()) { if (const TCastToPtr ai = ent) { if (CPathFindSearch* path = ai->GetSearchPath()) { @@ -544,6 +545,9 @@ void CStateManager::DrawDebugStuff() const { } } } + if (xf70_currentMaze) { + xf70_currentMaze->DebugRender(); + } #endif } diff --git a/Runtime/World/CScriptMazeNode.cpp b/Runtime/World/CScriptMazeNode.cpp index e72ee62e3..470154ebd 100644 --- a/Runtime/World/CScriptMazeNode.cpp +++ b/Runtime/World/CScriptMazeNode.cpp @@ -1,5 +1,7 @@ #include "Runtime/World/CScriptMazeNode.hpp" +#include + #include "Runtime/CStateManager.hpp" #include "Runtime/Character/CModelData.hpp" #include "Runtime/GameGlobalObjects.hpp" @@ -11,6 +13,10 @@ namespace urde { std::array sMazeSeeds; +#ifndef NDEBUG +std::array sDebugCellPos; +#endif + CScriptMazeNode::CScriptMazeNode(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, bool active, s32 col, s32 row, s32 side, const zeus::CVector3f& actorPos, const zeus::CVector3f& triggerPos, @@ -153,12 +159,20 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C Reset(mgr); } else if (msg == EScriptObjectMessage::InitializedInArea) { if (mgr.GetCurrentMaze() == nullptr) { - auto maze = std::make_unique(skTargetCol, skTargetRow, skEnterCol, skEnterRow); + auto maze = std::make_unique(skEnterCol, skEnterRow, skTargetCol, skTargetRow); maze->Reset(sMazeSeeds[mgr.GetActiveRandom()->Next() % sMazeSeeds.size()]); maze->Initialize(); maze->GenerateObstacles(); mgr.SetCurrentMaze(std::move(maze)); } +#ifndef NDEBUG + if (xf0_side == ESide::Right) { + sDebugCellPos[xe8_col + xec_row * skMazeCols] = GetTranslation(); + } else if (xe8_col == skMazeCols - 1) { + // Last column does not have right nodes, but we can infer the position + sDebugCellPos[xe8_col + xec_row * skMazeCols] = GetTranslation() - zeus::CVector3f{1.1875f, -0.1215f, 1.2187f}; + } +#endif } else if (msg == EScriptObjectMessage::Deleted) { mgr.ClearCurrentMaze(); Reset(mgr); @@ -301,10 +315,10 @@ void CMazeState::Reset(s32 seed) { void CMazeState::Initialize() { std::array path{}; - path[0] = x84_targetCol + x88_targetRow * skMazeCols; + path[0] = x84_enterCol + x88_enterRow * skMazeCols; GetCell(path[0]).x1_26_checked = true; s32 pathLength = 1; - while (path[0] != x8c_enterCol + x90_enterRow * skMazeCols) { + while (path[0] != x8c_targetCol + x90_targetRow * skMazeCols) { if (GetCell(path[0]).x0_24_openTop) { if (!GetCell(path[0] - skMazeCols).x1_26_checked) { path[pathLength] = path[0] - skMazeCols; @@ -342,6 +356,11 @@ void CMazeState::Initialize() { auto& cell = GetCell(*idx); if (cell.x1_26_checked) { cell.x1_25_onPath = true; +#ifndef NDEBUG + if (pathLength > 0) { + m_path.push_back(*idx); + } +#endif } } x94_24_initialized = true; @@ -365,12 +384,12 @@ void CMazeState::GenerateObstacles() { ESide side = ESide::Invalid; s32 idx = 0; - s32 prevCol = x84_targetCol; - s32 prevRow = x88_targetRow; - s32 col = x84_targetCol; - s32 row = x88_targetRow; + s32 prevCol = x84_enterCol; + s32 prevRow = x88_enterRow; + s32 col = x84_enterCol; + s32 row = x88_enterRow; - while (col != x8c_enterCol || row != x90_enterRow) { + while (col != x8c_targetCol || row != x90_targetRow) { if (idx == gate1Idx || idx == gate2Idx || idx == gate3Idx) { if (side == ESide::Bottom) { GetCell(col, row).x0_28_gateTop = true; @@ -447,4 +466,25 @@ void CMazeState::GenerateObstacles() { row = nextRow; }; } + +static logvisor::Module Log("CMazeState"); + +#ifndef NDEBUG +void CMazeState::DebugRender() { + m_renderer.Reset(); + m_renderer.AddVertex(sDebugCellPos[skEnterCol + skEnterRow * skMazeCols], zeus::skBlue, 2.f); + for (s32 i = m_path.size() - 1; i >= 0; --i) { + s32 idx = m_path[i]; + zeus::CVector3f pos; + if (idx == skMazeCols - 1) { + // 8,0 has no node, infer from 8,1 + pos = sDebugCellPos[idx + skMazeCols] + zeus::CVector3f{4.f, 0.f, 0.f}; + } else { + pos = sDebugCellPos[idx]; + } + m_renderer.AddVertex(pos, zeus::skBlue, 2.f); + } + m_renderer.Render(); +} +#endif } // namespace urde diff --git a/Runtime/World/CScriptMazeNode.hpp b/Runtime/World/CScriptMazeNode.hpp index 4ddaa4259..3828d77a1 100644 --- a/Runtime/World/CScriptMazeNode.hpp +++ b/Runtime/World/CScriptMazeNode.hpp @@ -5,6 +5,7 @@ #include #include "Runtime/CRandom16.hpp" +#include "Runtime/Graphics/CLineRenderer.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/World/CActor.hpp" @@ -13,10 +14,10 @@ namespace urde { constexpr s32 skMazeCols = 9; constexpr s32 skMazeRows = 7; -constexpr s32 skTargetCol = 4; -constexpr s32 skTargetRow = 4; -constexpr s32 skEnterCol = 5; -constexpr s32 skEnterRow = 3; +constexpr s32 skEnterCol = 4; +constexpr s32 skEnterRow = 4; +constexpr s32 skTargetCol = 5; +constexpr s32 skTargetRow = 3; enum class ESide { Invalid = -1, @@ -47,19 +48,28 @@ struct SMazeCell { class CMazeState { CRandom16 x0_rand{0}; std::array x4_cells{}; - s32 x84_targetCol; - s32 x88_targetRow; - s32 x8c_enterCol; - s32 x90_enterRow; + s32 x84_enterCol; + s32 x88_enterRow; + s32 x8c_targetCol; + s32 x90_targetRow; bool x94_24_initialized : 1 = false; +#ifndef NDEBUG + std::vector m_path; + CLineRenderer m_renderer = {CLineRenderer::EPrimitiveMode::LineStrip, skMazeRows * skMazeCols, {}, true}; +#endif + public: - CMazeState(s32 targetCol, s32 targetRow, s32 enterCol, s32 enterRow) - : x84_targetCol(targetCol), x88_targetRow(targetRow), x8c_enterCol(enterCol), x90_enterRow(enterRow) {} + CMazeState(s32 enterCol, s32 enterRow, s32 targetCol, s32 targetRow) + : x84_enterCol(enterCol), x88_enterRow(enterRow), x8c_targetCol(targetCol), x90_targetRow(targetRow) {} void Reset(s32 seed); void Initialize(); void GenerateObstacles(); +#ifndef NDEBUG + void DebugRender(); +#endif + [[nodiscard]] SMazeCell& GetCell(u32 col, u32 row) { #ifndef NDEBUG assert(col < skMazeCols);