Exemplo n.º 1
0
        public static IEnumerator <Vector2Int> GetEnumerator2D <T>(this ArrayGrid <T> grid)
        {
            IEnumerator <Vector2Int> iterator = Mathnv.GetAreaEnumerator(grid.w, grid.h);

            while (iterator.MoveNext())
            {
                yield return(iterator.Current);
            }
        }
Exemplo n.º 2
0
        public IEnumerator RenderChunks()
        {
            var visibleIter = Mathnv.GetAreaEnumerator(MapSize);

            while (visibleIter.MoveNext())
            {
                Vector2Int current = visibleIter.Current;
                this[current].GenerateMesh(true);
            }
            yield break;
        }
Exemplo n.º 3
0
        public void CreateChunks()
        {
            //Vector2Int center = Vector2Int.FloorToInt(new Vector2(MapSize.x, MapSize.y) * .5f);

            chunks     = new List <MapMesh>();
            chunkViews = new List <GameObject>();

            var visibleIter = Mathnv.GetAreaEnumerator(MapSize);

            while (visibleIter.MoveNext())
            {
                Vector2Int current = visibleIter.Current;
                CreateChunk(current);
            }
        }
Exemplo n.º 4
0
        IEnumerator GenerateMap(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap)
        {
            Vector2Int p1 = Vector2Int.zero;
            Vector2Int p2 = Vector2Int.zero;
            Vector2Int r  = Vector2Int.zero;

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

            int numberOfRooms = 0;

            for (numberOfRooms = 0; numberOfRooms < maxNumberOfRooms;)
            {
                if (numberOfRooms == 0)
                {
                    p1.x = map.w / 2 - GameRNG.Rand((int)roomSizeLimit.Max);
                    p1.y = map.h / 2 - GameRNG.Rand((int)roomSizeLimit.Max) - (int)roomSizeLimit.Min;

                    r.x = GameRNG.Rand((int)roomSizeLimit.Min, (int)roomSizeLimit.Min + (int)roomSizeLimit.Max);
                    r.y = roomSizeLimit.RandomValuei();

                    p2.x = p1.x + r.x;
                    p2.y = map.h / 2;

                    if (p2.x >= map.w)
                    {
                        continue;
                    }
                }
                else
                {
                    p1.x = GameRNG.Rand(map.w - (int)roomSizeLimit.Min) + 1;
                    p1.y = GameRNG.Rand(map.h - (int)roomSizeLimit.Min) / 2 + 1;

                    r.x = roomSizeLimit.RandomValuei();
                    r.y = roomSizeLimit.RandomValuei();

                    p2.x = p1.x + r.x;
                    p2.y = p1.y + r.y;

                    if (p2.x >= map.w - 1 || p2.y >= map.h / 2 + 3)
                    {
                        continue;
                    }
                }

                bool randAgain = false;
                for (int j = 0; j < rooms.Count; ++j)
                {
                    randAgain = true;
                    if (rooms[j].Contains(p1))
                    {
                        if (!rooms[j].Contains(p2))
                        {
                            randAgain = false;
                            roomTypes[j]++;
                        }
                        break;
                    }
                    if (rooms[j].Contains(p2))
                    {
                        if (!rooms[j].Contains(p1))
                        {
                            randAgain = false;
                            roomTypes[j]++;
                        }
                        break;
                    }
                }

                if (randAgain)
                {
                    continue;
                }

                // Create room
                Rect roomRect = Rect.MinMaxRect(p1.x, p1.y, p2.x, p2.y);

                rooms.Add(roomRect);
                roomTypes.Add(0);
                numberOfRooms++;
            }
            yield return(new WaitForEndOfFrame());

            // create mirror
            for (int i = 0; i < numberOfRooms; ++i)
            {
                Rect roomRect = rooms[i];

                if (mirrorVertical)
                {
                    Vector2Int min = Vector2Int.FloorToInt(roomRect.min);
                    Vector2Int max = Vector2Int.FloorToInt(roomRect.max);

                    min.x = map.w - min.x - 1;
                    max.x = map.w - max.x - 1;

                    p1.x = min.x;

                    min.x = max.x;
                    max.x = p1.x;

                    roomRect = Rect.MinMaxRect(min.x, min.y, max.x, max.y);
                }
                else
                {
                    Vector2Int min = Vector2Int.FloorToInt(roomRect.min);
                    Vector2Int max = Vector2Int.FloorToInt(roomRect.max);

                    min.y = map.h - min.y - 1;
                    max.y = map.h - max.y - 1;

                    p1.y = min.y;

                    min.y = max.y;
                    max.y = p1.y;

                    roomRect = Rect.MinMaxRect(min.x, min.y, max.x, max.y);
                }

                roomTypes.Insert(i, roomTypes[i]);
                rooms.Insert(i, roomRect);
            }

            yield return(new WaitForEndOfFrame());

            for (int i = 0; i < rooms.Count; ++i)
            {
                IEnumerator <Vector2Int> areaIter = Mathnv.GetAreaEnumerator(Vector2Int.FloorToInt(rooms[i].min), Vector2Int.FloorToInt(rooms[i].max));

                while (areaIter.MoveNext())
                {
                    Vector2Int current = areaIter.Current;
                    if (valueMap[current] == valueWall)
                    {
                        valueMap[current] = roomTypes[i];
                    }
                }
            }

            yield return(new WaitForEndOfFrame());

            int freeCells = 0;

            for (int x = 0; x < map.MaxValidPosition.x; ++x)
            {
                for (int y = 0; y < map.h / 2; ++y)
                {
                    int currentValue = valueMap[x, y];

                    int[] nearValues = new int[]
                    { valueMap[x + 1, y]
                      , valueMap[x, y + 1]
                      , valueMap[x + 1, y + 1] };


                    if (currentValue != nearValues[0] && nearValues[0] != valueWall)
                    {
                        valueMap[x, y] = valueWall;
                    }
                    if (currentValue != nearValues[1] && nearValues[1] != valueWall)
                    {
                        valueMap[x, y] = valueWall;
                    }
                    if (currentValue != nearValues[2] && nearValues[2] != valueWall)
                    {
                        valueMap[x, y] = valueWall;
                    }

                    if (currentValue != valueWall)
                    {
                        freeCells += 2;// +2 for mirror
                    }

                    valueMap[x, map.h - y - 1] = valueMap[x, y];//mirroring
                }
            }

            if (freeCells < (map.h * map.w * requiredPercentageOfMapNotWalls))
            {
                if (debugOutput)
                {
                    Dev.Log(string.Format("Not enough open map space. {0} < {1}", freeCells, (map.h * map.w * requiredPercentageOfMapNotWalls)));
                }
                success = false;
                yield break;
            }

            ConvertValuesToTiles(map, valueMap);
            ConnectClosestRooms(map, valueMap, true);
            ConvertValuesToTiles(map, valueMap);
            AddDoors(map, valueMap, 1f);

            success = true;
            yield break;
        }
Exemplo n.º 5
0
        bool GenerateMap(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap)
        {
            map[map.CenterPosition] = defaultCorridorElement;

            Vector2Int s0 = Vector2Int.zero;
            Vector2    s1 = Vector2Int.zero;
            Vector2Int p  = Vector2Int.zero;
            Vector2    d  = Vector2Int.zero;

            int iterCount = map.Count / 3;

            for (int i = 0; i < iterCount; i++)
            {
                s1 = GameRNG.RandomPointOnCircle(map.Size.DivideBy(2)) + map.CenterPosition;

                d.x = strideLimitX.RandomNormalizedValue();
                d.y = strideLimitY.RandomNormalizedValue();

                d.x -= .5f;
                d.y -= .5f;

                int counter = 0;
                for (; ;)
                {
                    //try again
                    if (counter > maxTunnelIterations)
                    {
                        --i;
                        break;
                    }

                    s1 += d;

                    p = Vector2Int.FloorToInt(s1);
                    p = map.Wrap(p);

                    if (map.IsValidPosition(p) && map.GetAdjacentPositionsOfType(p, false, defaultCorridorElement).Count > 0)
                    {
                        map[p] = defaultCorridorElement;
                        break;
                    }
                }
            }

            if (placeRooms)
            {
                var areaIter = Mathnv.GetAreaEnumerator(Vector2Int.one, map.MaxValidPosition - Vector2Int.one);
                while (areaIter.MoveNext())
                {
                    Vector2Int current = areaIter.Current;

                    Range limitX = new Range(map.w / 2 - strideLimitX.Min, map.w / 2 + strideLimitX.Min);
                    Range limitY = new Range(map.h / 2 - strideLimitY.Min, map.h / 2 + strideLimitY.Min);

                    if ((limitX.Contains(current.x) && limitY.Contains(current.y)) || map[current] == defaultWallElement)
                    {
                        continue;
                    }

                    int n = map.GetAdjacentPositionsOfType(current, false, defaultCorridorElement).Count;

                    if (n == 1)
                    {
                        Rect room = new Rect(Vector2.zero, new Vector2(roomSizeX.RandomValuei(), roomSizeY.RandomValuei()));

                        var roomIter = Mathnv.GetAreaEnumerator(Vector2Int.FloorToInt(room.min), Vector2Int.FloorToInt(room.max));
                        while (roomIter.MoveNext())
                        {
                            Vector2Int rCurrent = roomIter.Current;
                            map[current + rCurrent] = defaultRoomElement;
                        }
                    }
                }
            }

            return(true);
        }
Exemplo n.º 6
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);
        }