valid connection doors positions

This commit is contained in:
2026-04-13 11:51:26 +03:00
parent a955f0b218
commit 7846082220
2 changed files with 102 additions and 29 deletions

View File

@@ -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<std::pair<int, int>> RoomLayoutSystem::getRoomEdgeCells(const RoomCo
return cells;
}
std::vector<std::pair<int, int>> 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<std::pair<int, int>> 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<std::pair<int, int>> 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<std::pair<int, int>>& outCellsA,
std::vector<std::pair<int, int>>& 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<std::pair<int, int>> edgeA = getAllEdgeCells(roomA);
std::vector<std::pair<int, int>> 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);
}
}
}

View File

@@ -74,6 +74,9 @@ private:
// Helper: Get all cells on the edge of a room on a specific side
std::vector<std::pair<int, int>> getRoomEdgeCells(const class RoomComponent& room, int side);
// Helper: Get all edge cells (perimeter) of a room - mirrors original roomEdge() function
std::vector<std::pair<int, int>> getAllEdgeCells(const class RoomComponent& room);
// Helper: Check if two cells are adjacent
bool areCellsAdjacent(int x1, int z1, int x2, int z2);