Fixed room connectivity code

This commit is contained in:
2026-04-14 12:35:20 +03:00
parent 7846082220
commit e3b90e8bba
3 changed files with 76 additions and 23 deletions

View File

@@ -381,22 +381,29 @@ void RoomLayoutSystem::processRoomConnection(flecs::entity roomAEntity, const Ro
// This mirrors the original Lua connectRooms() logic
size_t index = 0;
if (cellsA.size() > 1) {
// Calculate average (center) point
// Calculate average (center) point using the SAME method as original Lua
// Note: Original Lua uses integer division which truncates toward zero
int sumX = 0, sumZ = 0;
for (const auto& cell : cellsA) {
sumX += cell.first;
sumZ += cell.second;
for (size_t i = 0; i < cellsA.size(); i++) {
sumX += cellsA[i].first;
sumZ += cellsA[i].second;
}
int avgX = sumX / cellsA.size();
int avgZ = sumZ / cellsA.size();
sumX /= cellsA.size();
sumZ /= cellsA.size();
// Find closest point to average
// Find closest point to average (using same logic as original Lua)
// Original: if (distance > mdx * mdx + mdz * mdz) - uses > not >=
// This keeps the first cell in case of ties
int minDistance = -1;
for (size_t i = 0; i < cellsA.size(); i++) {
int dx = cellsA[i].first - avgX;
int dz = cellsA[i].second - avgZ;
int dist = dx * dx + dz * dz;
if (minDistance == -1 || dist < minDistance) {
int mdx = cellsA[i].first - sumX;
int mdz = cellsA[i].second - sumZ;
int dist = mdx * mdx + mdz * mdz;
if (i == 0) {
index = 0;
minDistance = dist;
} else if (dist < minDistance) {
minDistance = dist;
index = i;
}

View File

@@ -121,8 +121,6 @@ bool RoomEditor::renderComponent(flecs::entity entity, RoomComponent& room)
if (ImGui::CollapsingHeader("Connections", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Indent();
ImGui::Text("Connected to %zu room(s):", room.connectedRoomIds.size());
// Build a map of persistent ID -> room info for displaying connections
std::unordered_map<std::string, flecs::entity> roomMap;
std::unordered_map<std::string, std::string> roomLabels;
@@ -138,15 +136,28 @@ bool RoomEditor::renderComponent(flecs::entity entity, RoomComponent& room)
});
}
ImGui::Text("Connected to %zu room(s):", room.connectedRoomIds.size());
// List current connections with remove buttons
int removeIndex = -1;
for (size_t i = 0; i < room.connectedRoomIds.size(); i++) {
const std::string& connectedId = room.connectedRoomIds[i];
ImGui::PushID((int)i);
auto it = roomLabels.find(connectedId);
if (it != roomLabels.end()) {
ImGui::Text(" %zu: %s", i + 1, it->second.c_str());
auto it = roomMap.find(connectedId);
if (it != roomMap.end()) {
// Check if rooms are actually adjacent
const auto& otherRoom = it->second.get<RoomComponent>();
bool isAdjacent = areRoomsAdjacent(room, otherRoom);
if (isAdjacent) {
ImGui::Text(" %zu: %s", i + 1, roomLabels[connectedId].c_str());
} else {
// Mark non-adjacent connections in yellow
ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.0f, 1.0f),
" %zu: %s (Not adjacent - will not create door)",
i + 1, roomLabels[connectedId].c_str());
}
} else {
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f),
" %zu: (Invalid room ID: %s)", i + 1, connectedId.c_str());
@@ -198,19 +209,28 @@ bool RoomEditor::renderComponent(flecs::entity entity, RoomComponent& room)
if (availableRooms.empty()) {
ImGui::TextDisabled(" No available rooms to connect");
} else {
static int selectedRoomIdx = 0;
// Use non-static index to avoid flickering when list changes
// Store index in a map keyed by entity ID
flecs::entity_t entityId = entity.id();
if (m_selectedRoomIndex.find(entityId) == m_selectedRoomIndex.end()) {
m_selectedRoomIndex[entityId] = 0;
}
int& selectedRoomIdx = m_selectedRoomIndex[entityId];
if (selectedRoomIdx >= (int)availableRooms.size()) selectedRoomIdx = 0;
// Build combo items
std::string comboItems;
// Build combo items using ImGui style (null-terminated strings)
// Each item is terminated by \0, and the list is terminated by an extra \0
std::vector<char> comboItems;
for (size_t i = 0; i < availableRoomLabels.size(); i++) {
if (i > 0) comboItems += "\0";
comboItems += availableRoomLabels[i];
for (char c : availableRoomLabels[i]) {
comboItems.push_back(c);
}
comboItems.push_back('\0'); // End of this item
}
comboItems += "\0";
comboItems.push_back('\0'); // End of list
ImGui::PushID("add_conn");
if (ImGui::Combo("Room", &selectedRoomIdx, comboItems.c_str())) {
if (ImGui::Combo("Room", &selectedRoomIdx, comboItems.data())) {
// Selection changed
}
@@ -263,3 +283,23 @@ std::string RoomEditor::formatRoomLabel(flecs::entity entity, const RoomComponen
return label;
}
bool RoomEditor::areRoomsAdjacent(const RoomComponent& roomA, const RoomComponent& roomB)
{
// Two rooms are adjacent if they share at least one edge
// Check if roomB is directly adjacent to roomA on any side
// Check Z- side of roomA (is roomB at z = roomA.minZ - 1 with overlapping X?)
if (roomB.maxZ == roomA.minZ && roomB.maxX > roomA.minX && roomB.minX < roomA.maxX) return true;
// Check Z+ side of roomA
if (roomB.minZ == roomA.maxZ && roomB.maxX > roomA.minX && roomB.minX < roomA.maxX) return true;
// Check X- side of roomA
if (roomB.maxX == roomA.minX && roomB.maxZ > roomA.minZ && roomB.minZ < roomA.maxZ) return true;
// Check X+ side of roomA
if (roomB.minX == roomA.maxX && roomB.maxZ > roomA.minZ && roomB.minZ < roomA.maxZ) return true;
return false;
}

View File

@@ -15,4 +15,10 @@ private:
// Format a room label for display in connection lists
// Format: "Name [E:entityId P:persistentId] (Type)"
std::string formatRoomLabel(flecs::entity entity, const RoomComponent& room);
// Check if two rooms are adjacent (share at least one edge)
bool areRoomsAdjacent(const RoomComponent& roomA, const RoomComponent& roomB);
// Track selected room index per entity to avoid static variable issues
std::unordered_map<flecs::entity_t, int> m_selectedRoomIndex;
};