CScriptMazeNode: Fix reversed enter/target & add debug rendering

This commit is contained in:
Luke Street 2020-09-21 20:42:54 -04:00
parent df2d191be8
commit a35bfc49b5
3 changed files with 72 additions and 18 deletions

View File

@ -537,6 +537,7 @@ void CStateManager::BuildDynamicLightListForWorld() {
void CStateManager::DrawDebugStuff() const { void CStateManager::DrawDebugStuff() const {
#ifndef NDEBUG #ifndef NDEBUG
CGraphics::SetModelMatrix(zeus::CTransform());
for (CEntity* ent : GetActorObjectList()) { for (CEntity* ent : GetActorObjectList()) {
if (const TCastToPtr<CPatterned> ai = ent) { if (const TCastToPtr<CPatterned> ai = ent) {
if (CPathFindSearch* path = ai->GetSearchPath()) { if (CPathFindSearch* path = ai->GetSearchPath()) {
@ -544,6 +545,9 @@ void CStateManager::DrawDebugStuff() const {
} }
} }
} }
if (xf70_currentMaze) {
xf70_currentMaze->DebugRender();
}
#endif #endif
} }

View File

@ -1,5 +1,7 @@
#include "Runtime/World/CScriptMazeNode.hpp" #include "Runtime/World/CScriptMazeNode.hpp"
#include <ranges>
#include "Runtime/CStateManager.hpp" #include "Runtime/CStateManager.hpp"
#include "Runtime/Character/CModelData.hpp" #include "Runtime/Character/CModelData.hpp"
#include "Runtime/GameGlobalObjects.hpp" #include "Runtime/GameGlobalObjects.hpp"
@ -11,6 +13,10 @@ namespace urde {
std::array<s32, 300> sMazeSeeds; std::array<s32, 300> sMazeSeeds;
#ifndef NDEBUG
std::array<zeus::CVector3f, skMazeRows * skMazeCols> sDebugCellPos;
#endif
CScriptMazeNode::CScriptMazeNode(TUniqueId uid, std::string_view name, const CEntityInfo& info, 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::CTransform& xf, bool active, s32 col, s32 row, s32 side,
const zeus::CVector3f& actorPos, const zeus::CVector3f& triggerPos, const zeus::CVector3f& actorPos, const zeus::CVector3f& triggerPos,
@ -153,12 +159,20 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C
Reset(mgr); Reset(mgr);
} else if (msg == EScriptObjectMessage::InitializedInArea) { } else if (msg == EScriptObjectMessage::InitializedInArea) {
if (mgr.GetCurrentMaze() == nullptr) { if (mgr.GetCurrentMaze() == nullptr) {
auto maze = std::make_unique<CMazeState>(skTargetCol, skTargetRow, skEnterCol, skEnterRow); auto maze = std::make_unique<CMazeState>(skEnterCol, skEnterRow, skTargetCol, skTargetRow);
maze->Reset(sMazeSeeds[mgr.GetActiveRandom()->Next() % sMazeSeeds.size()]); maze->Reset(sMazeSeeds[mgr.GetActiveRandom()->Next() % sMazeSeeds.size()]);
maze->Initialize(); maze->Initialize();
maze->GenerateObstacles(); maze->GenerateObstacles();
mgr.SetCurrentMaze(std::move(maze)); 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) { } else if (msg == EScriptObjectMessage::Deleted) {
mgr.ClearCurrentMaze(); mgr.ClearCurrentMaze();
Reset(mgr); Reset(mgr);
@ -301,10 +315,10 @@ void CMazeState::Reset(s32 seed) {
void CMazeState::Initialize() { void CMazeState::Initialize() {
std::array<s32, skMazeRows * skMazeCols> path{}; std::array<s32, skMazeRows * skMazeCols> path{};
path[0] = x84_targetCol + x88_targetRow * skMazeCols; path[0] = x84_enterCol + x88_enterRow * skMazeCols;
GetCell(path[0]).x1_26_checked = true; GetCell(path[0]).x1_26_checked = true;
s32 pathLength = 1; 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]).x0_24_openTop) {
if (!GetCell(path[0] - skMazeCols).x1_26_checked) { if (!GetCell(path[0] - skMazeCols).x1_26_checked) {
path[pathLength] = path[0] - skMazeCols; path[pathLength] = path[0] - skMazeCols;
@ -342,6 +356,11 @@ void CMazeState::Initialize() {
auto& cell = GetCell(*idx); auto& cell = GetCell(*idx);
if (cell.x1_26_checked) { if (cell.x1_26_checked) {
cell.x1_25_onPath = true; cell.x1_25_onPath = true;
#ifndef NDEBUG
if (pathLength > 0) {
m_path.push_back(*idx);
}
#endif
} }
} }
x94_24_initialized = true; x94_24_initialized = true;
@ -365,12 +384,12 @@ void CMazeState::GenerateObstacles() {
ESide side = ESide::Invalid; ESide side = ESide::Invalid;
s32 idx = 0; s32 idx = 0;
s32 prevCol = x84_targetCol; s32 prevCol = x84_enterCol;
s32 prevRow = x88_targetRow; s32 prevRow = x88_enterRow;
s32 col = x84_targetCol; s32 col = x84_enterCol;
s32 row = x88_targetRow; 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 (idx == gate1Idx || idx == gate2Idx || idx == gate3Idx) {
if (side == ESide::Bottom) { if (side == ESide::Bottom) {
GetCell(col, row).x0_28_gateTop = true; GetCell(col, row).x0_28_gateTop = true;
@ -447,4 +466,25 @@ void CMazeState::GenerateObstacles() {
row = nextRow; 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 } // namespace urde

View File

@ -5,6 +5,7 @@
#include <string_view> #include <string_view>
#include "Runtime/CRandom16.hpp" #include "Runtime/CRandom16.hpp"
#include "Runtime/Graphics/CLineRenderer.hpp"
#include "Runtime/RetroTypes.hpp" #include "Runtime/RetroTypes.hpp"
#include "Runtime/World/CActor.hpp" #include "Runtime/World/CActor.hpp"
@ -13,10 +14,10 @@
namespace urde { namespace urde {
constexpr s32 skMazeCols = 9; constexpr s32 skMazeCols = 9;
constexpr s32 skMazeRows = 7; constexpr s32 skMazeRows = 7;
constexpr s32 skTargetCol = 4; constexpr s32 skEnterCol = 4;
constexpr s32 skTargetRow = 4; constexpr s32 skEnterRow = 4;
constexpr s32 skEnterCol = 5; constexpr s32 skTargetCol = 5;
constexpr s32 skEnterRow = 3; constexpr s32 skTargetRow = 3;
enum class ESide { enum class ESide {
Invalid = -1, Invalid = -1,
@ -47,19 +48,28 @@ struct SMazeCell {
class CMazeState { class CMazeState {
CRandom16 x0_rand{0}; CRandom16 x0_rand{0};
std::array<SMazeCell, skMazeRows * skMazeCols> x4_cells{}; std::array<SMazeCell, skMazeRows * skMazeCols> x4_cells{};
s32 x84_targetCol; s32 x84_enterCol;
s32 x88_targetRow; s32 x88_enterRow;
s32 x8c_enterCol; s32 x8c_targetCol;
s32 x90_enterRow; s32 x90_targetRow;
bool x94_24_initialized : 1 = false; bool x94_24_initialized : 1 = false;
#ifndef NDEBUG
std::vector<s32> m_path;
CLineRenderer m_renderer = {CLineRenderer::EPrimitiveMode::LineStrip, skMazeRows * skMazeCols, {}, true};
#endif
public: public:
CMazeState(s32 targetCol, s32 targetRow, s32 enterCol, s32 enterRow) CMazeState(s32 enterCol, s32 enterRow, s32 targetCol, s32 targetRow)
: x84_targetCol(targetCol), x88_targetRow(targetRow), x8c_enterCol(enterCol), x90_enterRow(enterRow) {} : x84_enterCol(enterCol), x88_enterRow(enterRow), x8c_targetCol(targetCol), x90_targetRow(targetRow) {}
void Reset(s32 seed); void Reset(s32 seed);
void Initialize(); void Initialize();
void GenerateObstacles(); void GenerateObstacles();
#ifndef NDEBUG
void DebugRender();
#endif
[[nodiscard]] SMazeCell& GetCell(u32 col, u32 row) { [[nodiscard]] SMazeCell& GetCell(u32 col, u32 row) {
#ifndef NDEBUG #ifndef NDEBUG
assert(col < skMazeCols); assert(col < skMazeCols);