예제 #1
0
        public MapGenerator(IRMap map, IMobPackManager mobPackManager)
        {
            _map                = map;
            _mobPackManager     = mobPackManager;
            _rows               = map.Rows;
            _cols               = map.Columns;
            _directions         = RHelper.GetDirections();
            _oppositeDirections = new Dictionary <Direction, Direction>
            {
                { Direction.North, Direction.South },
                { Direction.East, Direction.West },
                { Direction.South, Direction.North },
                { Direction.West, Direction.East },
                { Direction.Center, Direction.Center }
            };

            var roomGen         = new RoomGenerator(5, 5, 10, 10, _map);
            var corridorGen     = new HallwayGenerator(20, 20, 50, 50, _map);
            var drunkDrigger    = new DrunkDigger(50, 50, 100, 100, _map);
            var treasureRoomGen = new TreasureRoom(5, 5, 13, 13, _map);

            _generators = new RandomContainer <IGenerator>
            {
                { roomGen, 60 },
                { corridorGen, 5 },
                { drunkDrigger, 180 },
                { treasureRoomGen, 2 }
            };

            roomGen.EnableEnemySpawning(_mobPackManager, 15);
            drunkDrigger.EnableEnemySpawning(_mobPackManager, 20);
        }
예제 #2
0
    public HallwayType[,] GenerateHallwayMap(Room startingRoom, List <Room> rooms)
    {
        var width  = Mathf.CeilToInt(maxX - minX) / hallwaySize;
        var height = Mathf.CeilToInt(maxY - minY) / hallwaySize;

        HallwayType[,] map = new HallwayType[width, height];
        for (var x = 0; x < width; x++)
        {
            for (var y = 0; y < height; y++)
            {
                var worldX = x * hallwaySize + minX;
                var worldY = y * hallwaySize + minY;

                // Check if this hallway position would overlap with a room.
                var overlaps = false;
                foreach (var room in rooms)
                {
                    var left1   = room.position.x - room.width / 2f;
                    var left2   = worldX - hallwaySize / 2f;
                    var right1  = room.position.x + room.width / 2f;
                    var right2  = worldX + hallwaySize / 2f;
                    var top1    = room.position.y - room.height / 2f;
                    var top2    = worldY - hallwaySize / 2f;
                    var bottom1 = room.position.y + room.height / 2f;
                    var bottom2 = worldY + hallwaySize / 2f;
                    var epsilon = 0.02;
                    if (right2 - left1 > epsilon && right1 - left2 > epsilon &&
                        bottom2 - top1 > epsilon && bottom1 - top2 > epsilon)
                    {
                        overlaps = true;
                    }

                    if (overlaps)
                    {
                        break;
                    }
                }

                if (overlaps)
                {
                    map[x, y] = HallwayType.Invalid;
                    if (GeneratorDebugSettings.DebugOverlays)
                    {
                        Debug.DrawLine(
                            new Vector3(worldX - hallwaySize / 2f, 0, worldY - hallwaySize / 2f),
                            new Vector3(worldX + hallwaySize / 2f, 0, worldY + hallwaySize / 2f),
                            Color.black, 1000000f);
                        Debug.DrawLine(
                            new Vector3(worldX - hallwaySize / 2f, 0, worldY + hallwaySize / 2f),
                            new Vector3(worldX + hallwaySize / 2f, 0, worldY - hallwaySize / 2f),
                            Color.black, 1000000f);
                    }
                }
                else
                {
                    map[x, y] = HallwayType.None;
                    if (GeneratorDebugSettings.DebugOverlays)
                    {
                        Debug.DrawLine(
                            new Vector3(worldX - hallwaySize / 2f, 0, worldY - hallwaySize / 2f),
                            new Vector3(worldX + hallwaySize / 2f, 0, worldY + hallwaySize / 2f),
                            Color.white, 1000000f);
                        Debug.DrawLine(
                            new Vector3(worldX - hallwaySize / 2f, 0, worldY + hallwaySize / 2f),
                            new Vector3(worldX + hallwaySize / 2f, 0, worldY - hallwaySize / 2f),
                            Color.white, 1000000f);
                    }
                }
            }
        }
        var hallwayGenerator = new HallwayGenerator(map);

        var queue = new Queue <Room>();

        queue.Enqueue(startingRoom);
        var seen = new HashSet <Room>(queue);

        var hallwayPaths = new List <System.Tuple <int, int, int, int> >();

        while (queue.Count > 0)
        {
            var room = queue.Dequeue();
            foreach (var connectedRoom in room.connectedRooms)
            {
                // TODO: This hardcodes the room rotation.
                hallwayPaths.Add(new System.Tuple <int, int, int, int>(
                                     Mathf.CeilToInt((room.exit.x - minX - hallwaySize / 2f) / hallwaySize),
                                     Mathf.CeilToInt((room.exit.y - minY) / hallwaySize),
                                     Mathf.CeilToInt((connectedRoom.entrance.x - minX) / hallwaySize),
                                     Mathf.CeilToInt((connectedRoom.entrance.y - minY) / hallwaySize)));

                if (!seen.Contains(connectedRoom))
                {
                    queue.Enqueue(connectedRoom);
                    seen.Add(connectedRoom);
                }
            }
        }

        // Fill hallways in order of length.
        foreach (var hallwayPath in hallwayPaths.OrderBy(p => Mathf.Pow(p.Item1 - p.Item3, 2) + Mathf.Pow(p.Item2 - p.Item4, 2)))
        {
            hallwayGenerator.FillShortestHallwayPath(hallwayPath.Item1, hallwayPath.Item2, hallwayPath.Item3, hallwayPath.Item4);
        }

        return(map);
    }