Esempio n. 1
0
        public void generateRoomGraphs()
        {
            Debug.Log("Generating room graphs");
            // pick how many rooms to make
            int           rooms = mt.Next(currentDungeonType.minRooms, currentDungeonType.maxRooms);
            List <Vertex> masterDelaunayPoints = new List <Vertex>();

            // warning: potential infinite loops!
            int infinityGuard = 0;

            for (int i = 0; i < rooms; ++i)
            {
                int  selection = mt.Next(0, dt.vertices.Count - 1);
                bool tooClose  = false;

                // don't pick points on convex hull, they are naughty
                if (isPointOnOrNearConvexHull(dt.vertices[selection]) || dt.vertices[selection].cell.getArea() > VoronoiRoom.MAX_CELL_AREA)
                {
                    infinityGuard++;
                    i--;
                    continue;
                }

                // don't pick something too close to another point already chosen
                foreach (Vertex v in masterDelaunayPoints)
                {
                    double d = dt.vertices[selection].getDistanceTo(v);
                    if (d < currentDungeonType.minimumDistanceBetweenMasterPoints)
                    {
                        tooClose = true;
                        break;
                    }
                }

                if (tooClose && infinityGuard < dt.vertices.Count)
                {
                    i--;
                    infinityGuard++;
                    continue;
                }

                // if we get this far, it's okay to add
                masterDelaunayPoints.Add(dt.vertices[selection]);
                infinityGuard = 0;
            }

            // get triangulation of those points
            masterDt = new Delaunay(masterDelaunayPoints);

            // get spanning tree
            //spanningTree = masterDt.edges.Distinct().ToList();
            spanningTree = masterDt.findSpanningTreeBFS();

            // add back some edges from triangulation to provide multiple routes
            int edgesToAddBack = Mathf.CeilToInt((masterDt.edges.Count - spanningTree.Count) * currentDungeonType.percentageOfEdgesToAddBack);

            for (int i = 0; i < edgesToAddBack; ++i)
            {
                // randomly pick an edge
                int  t;
                Edge e;
                do
                {
                    t = mt.Next(0, masterDt.edges.Count - 1);
                    e = masterDt.edges[t];
                } while (spanningTree.Contains(e));
                spanningTree.Add(e);
            }

            // do voronoi blending around points using the original voronoi cells
            // does not merge separate rooms!
            roomVoronoi = masterDelaunayPoints.Select(v => new VoronoiRoom(v)).Where(r => r.site != null).ToList();
            for (int i = 0; i < currentDungeonType.roomGrowthRadius; ++i)
            {
                foreach (VoronoiRoom r in roomVoronoi)
                {
                    r.grow();
                }
            }

            validCells = getValidCells();
        }