diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 556695737..52ee72a08 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,9 +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 SetCurrentMaze(std::unique_ptr maze) { xf70_currentMaze = std::move(maze); } void ClearCurrentMaze() { xf70_currentMaze.reset(); } - CScriptMazeState* GetCurrentMaze() { return xf70_currentMaze.get(); } + CMazeState* 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 8528d3b41..e72ee62e3 100644 --- a/Runtime/World/CScriptMazeNode.cpp +++ b/Runtime/World/CScriptMazeNode.cpp @@ -12,14 +12,14 @@ namespace urde { std::array sMazeSeeds; CScriptMazeNode::CScriptMazeNode(TUniqueId uid, std::string_view name, const CEntityInfo& info, - const zeus::CTransform& xf, bool active, s32 w1, s32 w2, s32 w3, + const zeus::CTransform& xf, bool active, s32 col, s32 row, s32 side, const zeus::CVector3f& actorPos, const zeus::CVector3f& triggerPos, const zeus::CVector3f& effectPos) : CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(), CActorParameters::None(), kInvalidUniqueId) -, xe8_col(w1) -, xec_row(w2) -, xf0_(w3) +, xe8_col(col) +, xec_row(row) +, xf0_side(static_cast(side)) , x100_actorPos(actorPos) , x110_triggerPos(triggerPos) , x120_effectPos(effectPos) {} @@ -32,15 +32,15 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C if (auto* maze = mgr.GetCurrentMaze()) { bool shouldGenObjs = false; auto& cell = maze->GetCell(xe8_col, xec_row); - if (xf0_ == 0 && cell.x0_24_) { - if (cell.x0_28_) { + if (xf0_side == ESide::Top && cell.x0_24_openTop) { + if (cell.x0_28_gateTop) { shouldGenObjs = true; - x13c_25_ = true; + x13c_25_hasGate = true; } - } else if (xf0_ == 1 && cell.x0_25_) { - if (cell.x0_29_) { + } else if (xf0_side == ESide::Right && cell.x0_25_openRight) { + if (cell.x0_29_gateRight) { shouldGenObjs = true; - x13c_25_ = true; + x13c_25_hasGate = true; } } else { shouldGenObjs = true; @@ -48,10 +48,10 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C if (shouldGenObjs) { GenerateObjects(mgr); } - if (xf0_ == 1 && cell.x1_24_) { - x13c_24_ = true; + if (xf0_side == ESide::Right && cell.x1_24_puddle) { + x13c_24_hasPuddle = true; } - if (x13c_25_) { + if (x13c_25_hasGate) { const auto origin = GetTranslation(); for (const auto& conn : GetConnectionList()) { if (conn.x0_state != EScriptObjectState::Modify || conn.x4_msg != EScriptObjectMessage::Activate) { @@ -63,7 +63,7 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C const auto genObj = mgr.GenerateObject(conn.x8_objId); mgr.SetIsGeneratingObject(wasGeneratingObject); - xf4_ = genObj.second; + xf4_gateEffectId = genObj.second; if (TCastToPtr actor = mgr.ObjectById(genObj.second)) { actor->SetTranslation(origin + x120_effectPos); mgr.SendScriptMsg(actor, GetUniqueId(), EScriptObjectMessage::Activate); @@ -71,7 +71,7 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C break; } } - if (x13c_24_) { + if (x13c_24_hasPuddle) { size_t count = 0; for (const auto& conn : GetConnectionList()) { if ((conn.x0_state == EScriptObjectState::Closed || conn.x0_state == EScriptObjectState::DeactivateState) && @@ -79,7 +79,7 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C count++; } } - x12c_.reserve(count); + x12c_puddleObjectIds.reserve(count); for (const auto& conn : GetConnectionList()) { if ((conn.x0_state == EScriptObjectState::Closed || conn.x0_state == EScriptObjectState::DeactivateState) && conn.x4_msg == EScriptObjectMessage::Activate) { @@ -88,7 +88,7 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C const auto genObj = mgr.GenerateObject(conn.x8_objId); mgr.SetIsGeneratingObject(wasGeneratingObject); - x12c_.push_back(genObj.second); + x12c_puddleObjectIds.push_back(genObj.second); if (TCastToPtr actor = mgr.ObjectById(genObj.second)) { actor->SetTransform(GetTransform()); if (conn.x0_state == EScriptObjectState::Closed) { @@ -101,8 +101,9 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C } } else if (msg == EScriptObjectMessage::SetToZero) { auto* maze = mgr.GetCurrentMaze(); - if (x13c_24_ && maze != nullptr && std::any_of(x12c_.cbegin(), x12c_.cend(), [=](auto v) { return v == uid; })) { - for (const auto& id : x12c_) { + if (x13c_24_hasPuddle && maze != nullptr && + std::any_of(x12c_puddleObjectIds.cbegin(), x12c_puddleObjectIds.cend(), [=](auto v) { return v == uid; })) { + for (const auto& id : x12c_puddleObjectIds) { if (auto* ent = mgr.ObjectById(id)) { if (ent->GetActive()) { mgr.SendScriptMsg(ent, GetUniqueId(), EScriptObjectMessage::Activate); @@ -113,37 +114,36 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C } for (const auto& ent : mgr.GetAllObjectList()) { if (TCastToPtr node = ent) { - s32 col = xe8_col - 1; - if (node->xe8_col == col && node->xec_row == xec_row && node->xf0_ == 1) { - auto& cell = maze->GetCell(col, xec_row); - if (!cell.x0_25_) { - cell.x0_25_ = true; + if (node->xe8_col == xe8_col - 1 && node->xec_row == xec_row && node->xf0_side == ESide::Right) { + auto& cell = maze->GetCell(xe8_col - 1, xec_row); + if (!cell.x0_25_openRight) { + cell.x0_25_openRight = true; node->Reset(mgr); - node->x13c_25_ = false; + node->x13c_25_hasGate = false; } } - if (node->xe8_col == xe8_col && node->xec_row == xec_row && node->xf0_ == 1) { + if (node->xe8_col == xe8_col && node->xec_row == xec_row && node->xf0_side == ESide::Right) { auto& cell = maze->GetCell(xe8_col, xec_row); - if (!cell.x0_25_) { - cell.x0_25_ = true; + if (!cell.x0_25_openRight) { + cell.x0_25_openRight = true; node->Reset(mgr); - node->x13c_25_ = false; + node->x13c_25_hasGate = false; } } - if (node->xe8_col == xe8_col && node->xec_row == xec_row && node->xf0_ == 0) { + if (node->xe8_col == xe8_col && node->xec_row == xec_row && node->xf0_side == ESide::Top) { auto& cell = maze->GetCell(xe8_col, xec_row); - if (!cell.x0_24_) { - cell.x0_24_ = true; + if (!cell.x0_24_openTop) { + cell.x0_24_openTop = true; node->Reset(mgr); - node->x13c_25_ = false; + node->x13c_25_hasGate = false; } } - if (node->xe8_col == xe8_col && node->xec_row == xec_row + 1 && node->xf0_ == 0) { + if (node->xe8_col == xe8_col && node->xec_row == xec_row + 1 && node->xf0_side == ESide::Top) { auto& cell = maze->GetCell(xe8_col, xec_row + 1); - if (!cell.x0_24_) { - cell.x0_24_ = true; + if (!cell.x0_24_openTop) { + cell.x0_24_openTop = true; node->Reset(mgr); - node->x13c_25_ = false; + node->x13c_25_hasGate = false; } } } @@ -153,10 +153,10 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C Reset(mgr); } else if (msg == EScriptObjectMessage::InitializedInArea) { if (mgr.GetCurrentMaze() == nullptr) { - auto maze = std::make_unique(4, 4, 5, 3); + auto maze = std::make_unique(skTargetCol, skTargetRow, skEnterCol, skEnterRow); maze->Reset(sMazeSeeds[mgr.GetActiveRandom()->Next() % sMazeSeeds.size()]); maze->Initialize(); - maze->sub_802899c8(); + maze->GenerateObstacles(); mgr.SetCurrentMaze(std::move(maze)); } } else if (msg == EScriptObjectMessage::Deleted) { @@ -168,17 +168,17 @@ void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, C } void CScriptMazeNode::Think(float dt, CStateManager& mgr) { - if (!GetActive() || !x13c_25_) { + if (!GetActive() || !x13c_25_hasGate) { return; } xf8_msgTimer -= dt; if (xf8_msgTimer <= 0.f) { xf8_msgTimer = 1.f; - if (x13c_26_) { - x13c_26_ = false; + if (x13c_26_gateActive) { + x13c_26_gateActive = false; SendScriptMsgs(mgr, EScriptObjectMessage::Deactivate); } else { - x13c_26_ = true; + x13c_26_gateActive = true; SendScriptMsgs(mgr, EScriptObjectMessage::Activate); } } @@ -203,7 +203,7 @@ void CScriptMazeNode::GenerateObjects(CStateManager& mgr) { TCastToConstPtr scriptEffect{ent}; TCastToConstPtr scriptActor{ent}; TCastToConstPtr scriptTrigger{ent}; - if ((scriptEffect || scriptActor || scriptTrigger) && (!scriptEffect || !x13c_25_)) { + if ((scriptEffect || scriptActor || scriptTrigger) && (!scriptEffect || !x13c_25_hasGate)) { bool wasGeneratingObject = mgr.GetIsGeneratingObject(); mgr.SetIsGeneratingObject(true); const auto genObj = mgr.GenerateObject(conn.x8_objId); @@ -231,8 +231,8 @@ void CScriptMazeNode::Reset(CStateManager& mgr) { mgr.FreeScriptObject(x11c_effectId); mgr.FreeScriptObject(xfc_actorId); mgr.FreeScriptObject(x10c_triggerId); - mgr.FreeScriptObject(xf4_); - xf4_ = kInvalidUniqueId; + mgr.FreeScriptObject(xf4_gateEffectId); + xf4_gateEffectId = kInvalidUniqueId; xfc_actorId = kInvalidUniqueId; x10c_triggerId = kInvalidUniqueId; x11c_effectId = kInvalidUniqueId; @@ -242,125 +242,112 @@ void CScriptMazeNode::SendScriptMsgs(CStateManager& mgr, EScriptObjectMessage ms mgr.SendScriptMsg(x11c_effectId, GetUniqueId(), msg); mgr.SendScriptMsg(xfc_actorId, GetUniqueId(), msg); mgr.SendScriptMsg(x10c_triggerId, GetUniqueId(), msg); - mgr.SendScriptMsg(xf4_, GetUniqueId(), msg); + mgr.SendScriptMsg(xf4_gateEffectId, GetUniqueId(), msg); } -void CScriptMazeState::Reset(s32 seed) { +void CMazeState::Reset(s32 seed) { x0_rand.SetSeed(seed); x94_24_initialized = false; x4_cells.fill({}); - std::array states{}; + std::array sides{}; s32 cellIdx = 0; - for (u32 i = skMazeColumns * skMazeRows - 1; i != 0;) { + for (u32 i = skMazeCols * skMazeRows - 1; i != 0;) { u32 acc = 0; - if (cellIdx - skMazeColumns > 0) { - auto& cell = GetCell(cellIdx - skMazeColumns); - if (!cell.x0_24_ && !cell.x0_25_ && !cell.x0_26_ && !cell.x0_27_) { - states[acc++] = 0; - } + if (cellIdx - skMazeCols > 0 && !GetCell(cellIdx - skMazeCols).IsOpen()) { + sides[acc++] = ESide::Top; } - if (cellIdx < x4_cells.size() - 2 && (cellIdx + 1) % skMazeColumns != 0) { - auto& cell = GetCell(cellIdx + 1); - if (!cell.x0_24_ && !cell.x0_25_ && !cell.x0_26_ && !cell.x0_27_) { - states[acc++] = 1; - } + if (cellIdx < x4_cells.size() - 2 && (cellIdx + 1) % skMazeCols != 0 && !GetCell(cellIdx + 1).IsOpen()) { + sides[acc++] = ESide::Right; } - if (cellIdx + skMazeColumns < x4_cells.size()) { - auto& cell = GetCell(cellIdx + skMazeColumns); - if (!cell.x0_24_ && !cell.x0_25_ && !cell.x0_26_ && !cell.x0_27_) { - states[acc++] = 2; - } + if (cellIdx + skMazeCols < x4_cells.size() && !GetCell(cellIdx + skMazeCols).IsOpen()) { + sides[acc++] = ESide::Bottom; } - if (cellIdx > 0 && cellIdx % skMazeColumns != 0) { - auto& cell = GetCell(cellIdx - 1); - if (!cell.x0_24_ && !cell.x0_25_ && !cell.x0_26_ && !cell.x0_27_) { - states[acc++] = 3; - } + if (cellIdx > 0 && cellIdx % skMazeCols != 0 && !GetCell(cellIdx - 1).IsOpen()) { + sides[acc++] = ESide::Left; } + if (acc == 0) { - while (true) { + do { cellIdx++; if (cellIdx > x4_cells.size() - 1) { cellIdx = 0; } - auto& cell = GetCell(cellIdx); - if (cell.x0_24_ || cell.x0_25_ || cell.x0_26_ || cell.x0_27_) { - break; - } - }; - } else { - i--; - s32 state = states[x0_rand.Next() % acc]; - if (state == 2) { - GetCell(cellIdx).x0_26_ = true; - GetCell(cellIdx + skMazeColumns).x0_24_ = true; - cellIdx += skMazeColumns; - } else if (state == 0) { - GetCell(cellIdx).x0_24_ = true; - GetCell(cellIdx - skMazeColumns).x0_26_ = true; - cellIdx -= skMazeColumns; - } else if (state == 1) { - GetCell(cellIdx).x0_25_ = true; - GetCell(cellIdx + 1).x0_27_ = true; - cellIdx++; - } else if (state == 3) { - GetCell(cellIdx).x0_27_ = true; - GetCell(cellIdx - 1).x0_25_ = true; - cellIdx--; - } + } while (!GetCell(cellIdx).IsOpen()); + continue; + } + + i--; + ESide side = sides[x0_rand.Next() % acc]; + if (side == ESide::Bottom) { + GetCell(cellIdx).x0_26_openBottom = true; + GetCell(cellIdx + skMazeCols).x0_24_openTop = true; + cellIdx += skMazeCols; + } else if (side == ESide::Top) { + GetCell(cellIdx).x0_24_openTop = true; + GetCell(cellIdx - skMazeCols).x0_26_openBottom = true; + cellIdx -= skMazeCols; + } else if (side == ESide::Right) { + GetCell(cellIdx).x0_25_openRight = true; + GetCell(cellIdx + 1).x0_27_openLeft = true; + cellIdx++; + } else if (side == ESide::Left) { + GetCell(cellIdx).x0_27_openLeft = true; + GetCell(cellIdx - 1).x0_25_openRight = true; + cellIdx--; } } } -void CScriptMazeState::Initialize() { - std::array arr{}; - arr[0] = x84_startCol + x88_startRow * skMazeColumns; - GetCell(arr[0]).x1_26_ = true; - s32 i = 1; - while (arr[0] != x8c_endCol + x90_endRow * skMazeColumns) { - if (GetCell(arr[0]).x0_24_) { - if (!GetCell(arr[0] - skMazeColumns).x1_26_) { - arr[i] = arr[0] - skMazeColumns; - i++; +void CMazeState::Initialize() { + std::array path{}; + path[0] = x84_targetCol + x88_targetRow * skMazeCols; + GetCell(path[0]).x1_26_checked = true; + s32 pathLength = 1; + while (path[0] != x8c_enterCol + x90_enterRow * skMazeCols) { + if (GetCell(path[0]).x0_24_openTop) { + if (!GetCell(path[0] - skMazeCols).x1_26_checked) { + path[pathLength] = path[0] - skMazeCols; + pathLength++; } } - if (GetCell(arr[0]).x0_25_) { - if (!GetCell(arr[0] + 1).x1_26_) { - arr[i] = arr[0] + 1; - i++; + if (GetCell(path[0]).x0_25_openRight) { + if (!GetCell(path[0] + 1).x1_26_checked) { + path[pathLength] = path[0] + 1; + pathLength++; } } - if (GetCell(arr[0]).x0_26_) { - if (!GetCell(arr[0] + skMazeColumns).x1_26_) { - arr[i] = arr[0] + skMazeColumns; - i++; + if (GetCell(path[0]).x0_26_openBottom) { + if (!GetCell(path[0] + skMazeCols).x1_26_checked) { + path[pathLength] = path[0] + skMazeCols; + pathLength++; } } - if (GetCell(arr[0]).x0_27_) { - if (!GetCell(arr[0] - 1).x1_26_) { - arr[i] = arr[0] - 1; - i++; + if (GetCell(path[0]).x0_27_openLeft) { + if (!GetCell(path[0] - 1).x1_26_checked) { + path[pathLength] = path[0] - 1; + pathLength++; } } - if (arr[0] == arr[i - 1]) { - i--; + if (path[0] == path[pathLength - 1]) { + pathLength--; } - arr[0] = arr[i - 1]; - GetCell(arr[0]).x1_26_ = true; + path[0] = path[pathLength - 1]; + GetCell(path[0]).x1_26_checked = true; } - s32* v = &arr[i]; - while (i != 0) { - i--; - v--; - if (GetCell(*v).x1_26_) { - GetCell(*v).x1_25_ = true; + s32* idx = &path[pathLength]; + while (pathLength != 0) { + pathLength--; + idx--; + auto& cell = GetCell(*idx); + if (cell.x1_26_checked) { + cell.x1_25_onPath = true; } } x94_24_initialized = true; } -void CScriptMazeState::sub_802899c8() { +void CMazeState::GenerateObstacles() { if (!x94_24_initialized) { Initialize(); } @@ -369,95 +356,90 @@ void CScriptMazeState::sub_802899c8() { s32 tmp = x0_rand.Next(); return tmp + ((tmp / 5) * -5) + offset; }; - s32 rand1 = GetRandom(9); - s32 rand2 = GetRandom(21); - s32 rand3 = GetRandom(33); - s32 rand4 = GetRandom(13); - s32 rand5 = GetRandom(29); + s32 gate1Idx = GetRandom(9); + s32 gate2Idx = GetRandom(21); + s32 gate3Idx = GetRandom(33); + s32 puddle1Idx = GetRandom(13); + s32 puddle2Idx = GetRandom(29); - u32 state = -1; + ESide side = ESide::Invalid; s32 idx = 0; - s32 prevCol = x84_startCol; - s32 prevRow = x88_startRow; - s32 col = x84_startCol; - s32 row = x88_startRow; + s32 prevCol = x84_targetCol; + s32 prevRow = x88_targetRow; + s32 col = x84_targetCol; + s32 row = x88_targetRow; - while (col != x8c_endCol || row != x90_endRow) { - if (idx == rand1 || idx == rand2 || idx == rand3) { - if (state == 2) { - GetCell(col, row).x0_28_ = true; - GetCell(prevCol, prevRow).x0_30_ = true; - } else if (state == 0) { - GetCell(col, row).x0_30_ = true; - GetCell(prevCol, prevRow).x0_28_ = true; - } else if (state == 1) { - GetCell(col, row).x0_31_ = true; - GetCell(prevCol, prevRow).x0_29_ = true; - } else if (state == 3) { - GetCell(col, row).x0_29_ = true; - GetCell(prevCol, prevRow).x0_31_ = true; + while (col != x8c_enterCol || row != x90_enterRow) { + if (idx == gate1Idx || idx == gate2Idx || idx == gate3Idx) { + if (side == ESide::Bottom) { + GetCell(col, row).x0_28_gateTop = true; + GetCell(prevCol, prevRow).x0_30_gateBottom = true; + } else if (side == ESide::Top) { + GetCell(col, row).x0_30_gateBottom = true; + GetCell(prevCol, prevRow).x0_28_gateTop = true; + } else if (side == ESide::Right) { + GetCell(col, row).x0_31_gateLeft = true; + GetCell(prevCol, prevRow).x0_29_gateRight = true; + } else if (side == ESide::Left) { + GetCell(col, row).x0_29_gateRight = true; + GetCell(prevCol, prevRow).x0_31_gateLeft = true; } } - s32 nextCol = col; + s32 nextCol = col; s32 nextRow = -1; - if (row < 1 || state == 2 || !GetCell(col, row).x0_24_ || !GetCell(col, row - 1).x1_25_) { - if (row < 6 && state != 0 && GetCell(col, row).x0_26_ && GetCell(col, row + 1).x1_25_) { - state = 2; + if (row < 1 || side == ESide::Bottom || !GetCell(col, row).x0_24_openTop || !GetCell(col, row - 1).x1_25_onPath) { + if (row < skMazeRows - 1 && side != ESide::Top && GetCell(col, row).x0_26_openBottom && + GetCell(col, row + 1).x1_25_onPath) { + side = ESide::Bottom; nextRow = row + 1; } else { nextRow = row; - if (col < 1 || state == 1 || !GetCell(col, row).x0_27_ || !GetCell((col + row * skMazeColumns) - 1).x1_25_) { - if (col > skMazeRows) { + if (col < 1 || side == ESide::Right || !GetCell(col, row).x0_27_openLeft || + !GetCell(col - 1, row).x1_25_onPath) { + if (col > skMazeRows || side == ESide::Left || !GetCell(col, row).x0_25_openRight || + !GetCell(col + 1, row).x1_25_onPath) { return; } - if (state == 3) { - return; - } - s32 iVar4_ = col + row * skMazeColumns; - if (!GetCell(iVar4_).x0_25_) { - return; - } - if (!GetCell(iVar4_ + 1).x1_25_) { - return; - } - state = 1; + side = ESide::Right; nextCol = col + 1; } else { - state = 3; + side = ESide::Left; nextCol = col - 1; } } } else { - state = 0; + side = ESide::Top; nextRow = row - 1; } - if (idx == rand4 || idx == rand5) { - if (col == 0 || row == 0 || col == 8 || row == 6) { - if (idx == rand4) { - rand4++; + + if (idx == puddle1Idx || idx == puddle2Idx) { + if (col == 0 || row == 0 || col == skMazeCols - 1 || row == skMazeRows - 1) { + if (idx == puddle1Idx) { + puddle1Idx++; } else { - rand5++; + puddle2Idx++; } } else { auto& cell = GetCell(col, row); - cell.x1_24_ = true; - if (state == 2) { - GetCell(nextCol, nextRow).x0_24_ = false; - cell.x0_26_ = false; - } else if (state == 0) { - GetCell(nextCol, nextRow).x0_26_ = false; - cell.x0_24_ = false; - } else if (state == 1) { - GetCell(nextCol, nextRow).x0_27_ = false; - cell.x0_25_ = false; - } else if (state == 3) { - GetCell(nextCol, nextRow).x0_25_ = false; - cell.x0_27_ = false; + cell.x1_24_puddle = true; + if (side == ESide::Bottom) { + GetCell(nextCol, nextRow).x0_24_openTop = false; + cell.x0_26_openBottom = false; + } else if (side == ESide::Top) { + GetCell(nextCol, nextRow).x0_26_openBottom = false; + cell.x0_24_openTop = false; + } else if (side == ESide::Right) { + GetCell(nextCol, nextRow).x0_27_openLeft = false; + cell.x0_25_openRight = false; + } else if (side == ESide::Left) { + GetCell(nextCol, nextRow).x0_25_openRight = false; + cell.x0_27_openLeft = false; } } } + idx++; prevCol = col; prevRow = row; diff --git a/Runtime/World/CScriptMazeNode.hpp b/Runtime/World/CScriptMazeNode.hpp index dd5903e7e..4ddaa4259 100644 --- a/Runtime/World/CScriptMazeNode.hpp +++ b/Runtime/World/CScriptMazeNode.hpp @@ -11,46 +11,63 @@ #include namespace urde { +constexpr s32 skMazeCols = 9; constexpr s32 skMazeRows = 7; -constexpr s32 skMazeColumns = 9; +constexpr s32 skTargetCol = 4; +constexpr s32 skTargetRow = 4; +constexpr s32 skEnterCol = 5; +constexpr s32 skEnterRow = 3; -struct CScriptMazeStateCell { - bool x0_24_ : 1 = false; - bool x0_25_ : 1 = false; - bool x0_26_ : 1 = false; - bool x0_27_ : 1 = false; - bool x0_28_ : 1 = false; - bool x0_29_ : 1 = false; - bool x0_30_ : 1 = false; - bool x0_31_ : 1 = false; - bool x1_24_ : 1 = false; - bool x1_25_ : 1 = false; - bool x1_26_ : 1 = false; +enum class ESide { + Invalid = -1, + Top = 0, + Right = 1, + Bottom = 2, + Left = 3, }; -class CScriptMazeState { +struct SMazeCell { + bool x0_24_openTop : 1 = false; + bool x0_25_openRight : 1 = false; + bool x0_26_openBottom : 1 = false; + bool x0_27_openLeft : 1 = false; + bool x0_28_gateTop : 1 = false; + bool x0_29_gateRight : 1 = false; + bool x0_30_gateBottom : 1 = false; + bool x0_31_gateLeft : 1 = false; + bool x1_24_puddle : 1 = false; + bool x1_25_onPath : 1 = false; + bool x1_26_checked : 1 = false; + + [[nodiscard]] constexpr bool IsOpen() const { + return x0_24_openTop || x0_25_openRight || x0_26_openBottom || x0_27_openLeft; + } +}; + +class CMazeState { CRandom16 x0_rand{0}; - std::array x4_cells{}; - s32 x84_startCol; - s32 x88_startRow; - s32 x8c_endCol; - s32 x90_endRow; + std::array x4_cells{}; + s32 x84_targetCol; + s32 x88_targetRow; + s32 x8c_enterCol; + s32 x90_enterRow; bool x94_24_initialized : 1 = false; public: - CScriptMazeState(s32 w1, s32 w2, s32 w3, s32 w4) : x84_startCol(w1), x88_startRow(w2), x8c_endCol(w3), x90_endRow(w4) {} + CMazeState(s32 targetCol, s32 targetRow, s32 enterCol, s32 enterRow) + : x84_targetCol(targetCol), x88_targetRow(targetRow), x8c_enterCol(enterCol), x90_enterRow(enterRow) {} void Reset(s32 seed); void Initialize(); - void sub_802899c8(); + void GenerateObstacles(); - [[nodiscard]] CScriptMazeStateCell& GetCell(u32 col, u32 row) { + [[nodiscard]] SMazeCell& GetCell(u32 col, u32 row) { #ifndef NDEBUG - assert(col < skMazeColumns); + assert(col < skMazeCols); assert(row < skMazeRows); #endif - return x4_cells[col + row * skMazeColumns]; + return x4_cells[col + row * skMazeCols]; } - [[nodiscard]] CScriptMazeStateCell& GetCell(u32 idx) { + [[nodiscard]] SMazeCell& GetCell(u32 idx) { #ifndef NDEBUG assert(idx < x4_cells.size()); #endif @@ -61,8 +78,8 @@ public: class CScriptMazeNode : public CActor { s32 xe8_col; s32 xec_row; - s32 xf0_; - TUniqueId xf4_ = kInvalidUniqueId; + ESide xf0_side; + TUniqueId xf4_gateEffectId = kInvalidUniqueId; float xf8_msgTimer = 1.f; TUniqueId xfc_actorId = kInvalidUniqueId; zeus::CVector3f x100_actorPos; @@ -70,14 +87,14 @@ class CScriptMazeNode : public CActor { zeus::CVector3f x110_triggerPos; TUniqueId x11c_effectId = kInvalidUniqueId; zeus::CVector3f x120_effectPos; - std::vector x12c_; - bool x13c_24_ : 1 = false; - bool x13c_25_ : 1 = false; - bool x13c_26_ : 1 = true; + std::vector x12c_puddleObjectIds; + bool x13c_24_hasPuddle : 1 = false; + bool x13c_25_hasGate : 1 = false; + bool x13c_26_gateActive : 1 = true; public: CScriptMazeNode(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, - bool active, s32 w1, s32 w2, s32 w3, const zeus::CVector3f& actorPos, + bool active, s32 col, s32 row, s32 side, const zeus::CVector3f& actorPos, const zeus::CVector3f& triggerPos, const zeus::CVector3f& effectPos); void Accept(IVisitor& visitor) override;