Fixed room connectivity code
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user