From 7846082220c2abe8b528ce8a694bdfb471bde9d9 Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Mon, 13 Apr 2026 11:51:26 +0300 Subject: [PATCH] valid connection doors positions --- .../editScene/systems/RoomLayoutSystem.cpp | 128 ++++++++++++++---- .../editScene/systems/RoomLayoutSystem.hpp | 3 + 2 files changed, 102 insertions(+), 29 deletions(-) diff --git a/src/features/editScene/systems/RoomLayoutSystem.cpp b/src/features/editScene/systems/RoomLayoutSystem.cpp index d2f19e1..51c84d1 100644 --- a/src/features/editScene/systems/RoomLayoutSystem.cpp +++ b/src/features/editScene/systems/RoomLayoutSystem.cpp @@ -411,19 +411,35 @@ void RoomLayoutSystem::processRoomConnection(flecs::entity roomAEntity, const Ro int xB = cellsB[index].first; int zB = cellsB[index].second; - // Determine which side of roomA faces roomB - int sideA = -1; - if (zA == roomA.minZ) sideA = 0; // Z- - else if (zA == roomA.maxZ - 1) sideA = 1; // Z+ - else if (xA == roomA.minX) sideA = 2; // X- - else if (xA == roomA.maxX - 1) sideA = 3; // X+ + // Calculate relative position (like original Lua: dx = seg1[index].first - seg2[index].first) + int dx = xA - xB; + int dz = zA - zB; - // Determine which side of roomB faces roomA - int sideB = -1; - if (zB == roomB.minZ) sideB = 0; // Z- - else if (zB == roomB.maxZ - 1) sideB = 1; // Z+ - else if (xB == roomB.minX) sideB = 2; // X- - else if (xB == roomB.maxX - 1) sideB = 3; // X+ + // Determine sides based on relative position of cells (matching original Lua) + // If dz < 0: roomA is north of roomB, so roomA needs Z+ door, roomB needs Z- door + // If dz > 0: roomA is south of roomB, so roomA needs Z- door, roomB needs Z+ door + // If dx < 0: roomA is west of roomB, so roomA needs X+ door, roomB needs X- door + // If dx > 0: roomA is east of roomB, so roomA needs X- door, roomB needs X+ door + + int sideA = -1, sideB = -1; + + if (dz < 0) { + // roomA is north of roomB + sideA = 1; // Z+ + sideB = 0; // Z- + } else if (dz > 0) { + // roomA is south of roomB + sideA = 0; // Z- + sideB = 1; // Z+ + } else if (dx < 0) { + // roomA is west of roomB + sideA = 3; // X+ + sideB = 2; // X- + } else if (dx > 0) { + // roomA is east of roomB + sideA = 2; // X- + sideB = 3; // X+ + } // Create door in roomA if (sideA >= 0) { @@ -669,6 +685,65 @@ std::vector> RoomLayoutSystem::getRoomEdgeCells(const RoomCo return cells; } +std::vector> RoomLayoutSystem::getAllEdgeCells(const RoomComponent& room) +{ + // This mirrors the original Lua roomEdge() function + // Returns ALL cells on the perimeter of the room (all 4 sides) + std::vector> cells; + + int sizeX = room.getSizeX(); + int sizeZ = room.getSizeZ(); + + // Handle edge cases (1D rooms) + if (sizeX <= 0 || sizeZ <= 0) { + return cells; + } else if (sizeX == 1 && sizeZ == 1) { + // Single cell room + cells.push_back({ room.minX, room.minZ }); + return cells; + } else if (sizeZ == 1) { + // Single row + for (int x = 0; x < sizeX; x++) { + cells.push_back({ room.minX + x, room.minZ }); + } + return cells; + } else if (sizeX == 1) { + // Single column + for (int z = 0; z < sizeZ; z++) { + cells.push_back({ room.minX, room.minZ + z }); + } + return cells; + } + + // Normal 2D room - collect all perimeter cells + // Use a set to avoid duplicates at corners + std::set> seen; + + // Bottom edge (Z-) + for (int x = 0; x < sizeX; x++) { + seen.insert({ room.minX + x, room.minZ }); + } + // Left edge (X-) + for (int z = 0; z < sizeZ; z++) { + seen.insert({ room.minX, room.minZ + z }); + } + // Top edge (Z+) + for (int x = 0; x < sizeX; x++) { + seen.insert({ room.minX + x, room.maxZ - 1 }); + } + // Right edge (X+) + for (int z = 0; z < sizeZ; z++) { + seen.insert({ room.maxX - 1, room.minZ + z }); + } + + // Copy from set to vector + for (const auto& cell : seen) { + cells.push_back(cell); + } + + return cells; +} + bool RoomLayoutSystem::areCellsAdjacent(int x1, int z1, int x2, int z2) { int dx = std::abs(x1 - x2); @@ -680,23 +755,18 @@ void RoomLayoutSystem::findAdjacentCells(const RoomComponent& roomA, const RoomC std::vector>& outCellsA, std::vector>& outCellsB) { - const int sides[] = { 0, 1, 2, 3 }; - - for (int sideA : sides) { - auto edgeA = getRoomEdgeCells(roomA, sideA); - - for (int sideB : sides) { - if (sideA == sideB) continue; - - auto edgeB = getRoomEdgeCells(roomB, sideB); - - for (const auto& cellA : edgeA) { - for (const auto& cellB : edgeB) { - if (areCellsAdjacent(cellA.first, cellA.second, cellB.first, cellB.second)) { - outCellsA.push_back(cellA); - outCellsB.push_back(cellB); - } - } + // This mirrors the original Lua adjacentCells() function + // Get ALL edge cells from both rooms (all 4 sides), then find adjacent pairs + // We use a set to collect all unique edge cells (like the original) + std::vector> edgeA = getAllEdgeCells(roomA); + std::vector> edgeB = getAllEdgeCells(roomB); + + // Find all pairs of adjacent cells between the two rooms + for (const auto& cellA : edgeA) { + for (const auto& cellB : edgeB) { + if (areCellsAdjacent(cellA.first, cellA.second, cellB.first, cellB.second)) { + outCellsA.push_back(cellA); + outCellsB.push_back(cellB); } } } diff --git a/src/features/editScene/systems/RoomLayoutSystem.hpp b/src/features/editScene/systems/RoomLayoutSystem.hpp index bd432ea..b074505 100644 --- a/src/features/editScene/systems/RoomLayoutSystem.hpp +++ b/src/features/editScene/systems/RoomLayoutSystem.hpp @@ -74,6 +74,9 @@ private: // Helper: Get all cells on the edge of a room on a specific side std::vector> getRoomEdgeCells(const class RoomComponent& room, int side); + + // Helper: Get all edge cells (perimeter) of a room - mirrors original roomEdge() function + std::vector> getAllEdgeCells(const class RoomComponent& room); // Helper: Check if two cells are adjacent bool areCellsAdjacent(int x1, int z1, int x2, int z2);