Example #1
0
        private bool GenerateBuildings(ArrayGrid <MapElement> map)
        {
            while (buildingCount < requiredMinNumberOfBuildings)
            {
                Vector2Int roomSize   = new Vector2Int((int)(buildingSizeLimitX.Max * 2), (int)(buildingSizeLimitY.Max * 2));
                int        bufferSize = 2;

                for (;;)
                {
                    Vector2Int newBuildingAreaSize = new Vector2Int(roomSize.x + bufferSize, roomSize.y + bufferSize);
                    Vector2Int buildingPos         = Vector2Int.zero;
                    bool       result = map.GetPositionOfRandomAreaOfType(defaultFillElement, newBuildingAreaSize, ref buildingPos);
                    if (result)
                    {
                        //Debug.Log("Creating a building at " + buildingPos + " of size " + roomSize);
                        GenerateBuildingRooms(map, buildingPos, roomSize);
                        //map.FillArea(new Rect(buildingPos, roomSize), defaultDoorElement);
                        //map.FillArea(new Rect(buildingPos, Vector2.one), defaultTreeElement);
                        buildingCount++;
                        if (buildingCount >= requiredMinNumberOfBuildings)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        if (GameRNG.CoinToss())
                        {
                            roomSize.x -= 1;
                        }
                        else
                        {
                            roomSize.y -= 1;
                        }

                        //time to start over
                        if (roomSize.x < buildingSizeLimitX.Min || roomSize.y < buildingSizeLimitY.Min)
                        {
                            Debug.Log("starting over because building size is too small and we don't have enough buildings. " + roomSize + " rooms so far: " + buildingCount);
                            buildingCount = 0;
                            generationAttempts++;
                            return(false);
                        }
                    }
                }
            }

            return(false);
        }
Example #2
0
        bool GenerateMap(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap)
        {
            Vector2Int s0   = Vector2Int.zero;
            Vector2Int s1   = Vector2Int.zero;
            Vector2Int p0   = Vector2Int.zero;
            Vector2Int p1   = Vector2Int.zero;
            Vector2Int p2   = Vector2Int.zero;
            Vector2Int diff = Vector2Int.zero;

            List <Rect> rooms     = new List <Rect>();
            List <int>  roomTypes = new List <int>();

            // Place rooms
            for (int i = 0; i < maxNumberOfRooms; ++i)
            {
                // size of room
                s1 = new Vector2Int(roomSizeLimitX.RandomValuei(), roomSizeLimitY.RandomValuei());

                bool result = map.GetPositionOfRandomAreaOfType(defaultWallElement, s1 + roomSizeOffset, ref p0);
                if (result)
                {
                    p0 = p0.AddScalar(2);

                    // Connect the room to existing one

                    if (rooms.Count > 0)
                    {
                        int selectedRoom = GameRNG.Rand(rooms.Count);

                        Rect r = rooms[selectedRoom];

                        // center of this room
                        p1 = p0 + s1.DivideBy(2);

                        // center of second room
                        p2 = Vector2Int.FloorToInt(r.center);

                        // found the way to connect rooms
                        diff = p2 - p1;

                        diff.x = Mathf.Abs(diff.x);
                        diff.y = Mathf.Abs(diff.y);

                        s0 = p1;

                        while (!(diff.x == 0 && diff.y == 0))
                        {
                            if (GameRNG.Rand(diff.x + diff.y) < diff.x)// move horizontally
                            {
                                diff.x--;
                                s0.x += (s0.x > p2.x ? -1 : 1);
                            }
                            else
                            {
                                diff.y--;
                                s0.y += (s0.y > p2.y ? -1 : 1);
                            }

                            // Check what is on that position
                            if (map[s0] == defaultRoomElement)
                            {
                                break;
                            }
                            else if (map[s0] == defaultCorridorElement)
                            {
                                if (GameRNG.CoinToss())
                                {
                                    break;
                                }
                            }

                            map[s0] = defaultCorridorElement;
                        }
                    }

                    // add to list of rooms

                    Rect roomRect = Rect.MinMaxRect(p0.x, p0.y, p0.x + s1.x, p0.y + s1.y);

                    rooms.Add(roomRect);
                    roomTypes.Add(i);

                    // draw_room

                    int roomType = GameRNG.Rand(4); //select the type of room we should generate

                    if (s1.x == s1.y)
                    {
                        roomType = 3;
                    }

                    if (roomType != 2)
                    {
                        IEnumerator <Vector2Int> areaIter = Mathnv.GetAreaEnumerator(s1);

                        while (areaIter.MoveNext())
                        {
                            Vector2Int current = areaIter.Current;
                            if (roomType == 0 || roomType == 1)// rectangle room
                            {
                                map[p0 + current] = defaultRoomElement;
                            }
                            else// round room
                            {
                                if (Vector2Int.Distance(s1.DivideBy(2), current) < s1.x / 2)
                                {
                                    map[p0 + current] = defaultRoomElement;
                                }
                            }
                        }
                    }
                    else //diamond
                    {
                        IEnumerator <Vector2Int> areaIter = Mathnv.GetAreaEnumerator(s1.DivideBy(2) + Vector2Int.one);

                        while (areaIter.MoveNext())
                        {
                            Vector2Int current = areaIter.Current;
                            if (current.y >= current.x)
                            {
                                int x0 = p0.x + current.x + s1.DivideBy(2).x;
                                int x1 = p0.x + s1.DivideBy(2).x - current.x;

                                int y0 = p0.y + current.y;
                                int y1 = p0.y + s1.y - current.y;

                                map[x0, y0] = defaultRoomElement;
                                map[x0, y1] = defaultRoomElement;
                                map[x1, y0] = defaultRoomElement;
                                map[x1, y1] = defaultRoomElement;
                            }
                        }
                    }
                } // end of room addition
            }

            return(true);
        }
Example #3
0
        public override IEnumerator Generate()
        {
            //cannot generate with nonzero map size
            if (mapSize.sqrMagnitude <= 0)
            {
                yield break;
            }

            generationAttempts = 0;
            //roomCount = 0;

            ArrayGrid <MapElement> map      = null;
            ArrayGrid <int>        valueMap = null;

            Debug.Log("Starting generation");
            for (;;)
            {
                //brief yield before each genration attempt
                yield return(null);

                if (generationAttempts > maxGenerationAttempts)
                {
                    Debug.LogError("Failed to generate map with current settings");
                    break;
                }

                map      = CreateBaseMap();
                valueMap = new ArrayGrid <int>(mapSize, 0);

                Vector2Int p        = Vector2Int.zero;
                Vector2Int roomSize = Vector2Int.zero;

                for (int i = 0; i < maxNumberOfRooms; ++i)
                {
                    roomSize.x = roomSizeLimitX.RandomValuei();
                    roomSize.y = roomSizeLimitY.RandomValuei();

                    bool result = map.GetPositionOfRandomAreaOfType(defaultFillElement, roomSize, ref p);
                    if (result)
                    {
                        for (int y = 1; y < roomSize.y - 1; ++y)
                        {
                            for (int x = 1; x < roomSize.x - 1; ++x)
                            {
                                map[p.x + x, p.y + y] = defaultRoomElement;
                            }
                        }
                    }
                }

                ConnectClosestRooms(map, valueMap, true, true);
                ConvertValuesToTiles(map, valueMap);

                if (placeDoors)
                {
                    AddDoors(map, valueMap);
                }

                //TODO: logic to check if dungeon is valid

                generationAttempts++;
                GeneratedMap = map;

                break;
            }

            Debug.Log("Done");

            yield return(WriteTestOutput(map));

            yield return(WriteTestOutput(valueMap));

            yield break;
        }