Beispiel #1
0
        public static bool AreAdjacentCellsReachable(GridDungeonModel gridModel, int cellIdA, int cellIdB)
        {
            var cellA = gridModel.GetCell(cellIdA);
            var cellB = gridModel.GetCell(cellIdB);

            if (cellA == null || cellB == null)
            {
                return(false);
            }


            // If any one is a room, make sure we have a door between them
            if (cellA.CellType == CellType.Room || cellB.CellType == CellType.Room)
            {
                if (!gridModel.DoorManager.ContainsDoorBetweenCells(cellIdA, cellIdB))
                {
                    // We don't have a door between them and is blocked by a room wall
                    return(false);
                }
            }

            // if their height is different, make sure we have a stair between them
            if (cellA.Bounds.Location.y != cellB.Bounds.Location.y)
            {
                if (!gridModel.ContainsStair(cellIdA, cellIdB))
                {
                    // Height difference with no stairs. not reachable
                    return(false);
                }
            }

            // reachable
            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Finds all the nearby tiles that belong to the same cluster
        /// </summary>
        /// <param name="gridModel"></param>
        /// <param name="corridorTileCellId"></param>
        /// <returns></returns>
        public static int[] GetCellCluster(GridDungeonModel gridModel, int sampleCellId)
        {
            var clusters = new List <int>();

            // Check if we are in a room.  Rooms don't need to be clustered as they form a single group
            var startCell = gridModel.GetCell(sampleCellId);

            if (startCell == null || startCell.CellType == CellType.Room)
            {
                clusters.Add(sampleCellId);
                return(clusters.ToArray());
            }

            var visited = new HashSet <int>();
            var stack   = new Stack <int>();

            stack.Push(sampleCellId);

            while (stack.Count > 0)
            {
                var topId = stack.Pop();
                if (visited.Contains(topId))
                {
                    continue;
                }
                visited.Add(topId);

                var top = gridModel.GetCell(topId);
                if (top == null)
                {
                    continue;
                }
                if (top.CellType == CellType.Unknown || top.CellType == CellType.Room)
                {
                    continue;
                }

                if (IsCorridor(top.CellType))
                {
                    clusters.Add(topId);
                }

                // search adjacent cells
                foreach (var adjacentId in top.AdjacentCells)
                {
                    // make sure the adjacent cell is reachable
                    if (AreAdjacentCellsReachable(gridModel, topId, adjacentId))
                    {
                        stack.Push(adjacentId);
                    }
                }
            }

            return(clusters.ToArray());
        }
Beispiel #3
0
        public static void GetAdjacentCorridors(GridDungeonModel gridModel, int startCellId, ref List <int> OutConnectedCorridors, ref List <int> OutConnectedRooms)
        {
            OutConnectedCorridors.Clear();
            OutConnectedRooms.Clear();

            // search all nearby cells till we reach a dead end (or a room)
            var visited = new HashSet <int>();
            var stack   = new Stack <int>();

            stack.Push(startCellId);

            while (stack.Count > 0)
            {
                var topId = stack.Pop();
                if (visited.Contains(topId))
                {
                    continue;
                }
                visited.Add(topId);

                var top = gridModel.GetCell(topId);
                if (top == null)
                {
                    continue;
                }
                if (top.CellType == CellType.Unknown)
                {
                    continue;
                }

                if (top.CellType == CellType.Room && top.Id != startCellId)
                {
                    OutConnectedRooms.Add(topId);
                    continue;
                }

                if (IsCorridor(top.CellType))
                {
                    OutConnectedCorridors.Add(topId);
                }

                // search adjacent cells
                foreach (var adjacentId in top.AdjacentCells)
                {
                    // make sure the adjacent cell is reachable
                    if (AreAdjacentCellsReachable(gridModel, topId, adjacentId))
                    {
                        stack.Push(adjacentId);
                    }
                }
            }
        }
Beispiel #4
0
        public static void DrawAdjacentCells(Cell cell, GridDungeonModel model, Color color, bool mode2D)
        {
            if (model == null)
            {
                return;
            }
            var gridConfig = model.Config as GridDungeonConfig;

            if (gridConfig == null)
            {
                return;
            }

            foreach (var adjacentId in cell.AdjacentCells)
            {
                var adjacentCell = model.GetCell(adjacentId);
                if (adjacentCell == null)
                {
                    return;
                }
                var centerA = Vector3.Scale(cell.Bounds.CenterF(), gridConfig.GridCellSize);
                var centerB = Vector3.Scale(adjacentCell.Bounds.CenterF(), gridConfig.GridCellSize);
                DebugDrawUtils.DrawLine(centerA, centerB, color, 0, false, mode2D);
            }

            foreach (var adjacentId in cell.FixedRoomConnections)
            {
                var adjacentCell = model.GetCell(adjacentId);
                if (adjacentCell == null)
                {
                    return;
                }
                var centerA = Vector3.Scale(cell.Bounds.CenterF(), gridConfig.GridCellSize) + new Vector3(0, 0.2f, 0);
                var centerB = Vector3.Scale(adjacentCell.Bounds.CenterF(), gridConfig.GridCellSize) + new Vector3(0, 0.2f, 0);
                DebugDrawUtils.DrawLine(centerA, centerB, Color.red, 0, false, mode2D);
            }
        }
        public static Cell[] FindFurthestRooms(GridDungeonModel model)
        {
            var bestLength = 0;
            var result     = new Cell[2];

            foreach (var startCell in model.Cells)
            {
                var queue     = new Queue <LongestPathBFSData>();
                var visited   = new HashSet <int>();
                var startData = new LongestPathBFSData {
                    cell = startCell, length = 0
                };
                LongestPathBFSData endData = startData;

                queue.Enqueue(startData);
                while (queue.Count > 0)
                {
                    var front = queue.Dequeue();
                    visited.Add(front.cell.Id);

                    foreach (var childId in front.cell.FixedRoomConnections)
                    {
                        if (visited.Contains(childId))
                        {
                            continue;
                        }
                        var child     = model.GetCell(childId);
                        var childData = new LongestPathBFSData {
                            cell = child, length = front.length + 1
                        };
                        queue.Enqueue(childData);
                    }

                    if (queue.Count == 0)
                    {
                        endData = front;
                    }
                }

                if (endData.length > bestLength)
                {
                    bestLength = endData.length;
                    result[0]  = startData.cell;
                    result[1]  = endData.cell;
                }
            }

            return(result);
        }