예제 #1
0
        public static ArrayGrid <T> MapToSubGrid <T>(this ArrayGrid <T> grid, Vector2Int sourceAreaPos, Vector2Int sourceAreaSize, Vector2Int subGridSize, bool clampOutOfBounds = true)
        {
            if (!clampOutOfBounds)
            {
                if (!grid.IsValidPosition(sourceAreaPos))
                {
                    return(new ArrayGrid <T>());
                }

                if (!grid.IsValidPosition(sourceAreaPos + sourceAreaSize - Vector2Int.one))
                {
                    return(new ArrayGrid <T>());
                }
            }
            else
            {
                sourceAreaPos.Clamp(Vector2Int.zero, grid.MaxValidPosition);

                Vector2Int sourceAreaMax = sourceAreaPos + sourceAreaSize;
                sourceAreaMax.Clamp(Vector2Int.zero, grid.Size);

                sourceAreaSize = sourceAreaMax - sourceAreaPos;

                if (sourceAreaSize.x <= 0 || sourceAreaSize.y <= 0)
                {
                    return(new ArrayGrid <T>());
                }
            }

            ArrayGrid <T> subGrid = new ArrayGrid <T>(subGridSize);

            var subGridIter = subGrid.GetEnumerator2D();

            Vector2 scale = new Vector2((float)sourceAreaSize.x / subGridSize.x, (float)sourceAreaSize.y / subGridSize.y);

            while (subGridIter.MoveNext())
            {
                Vector2Int subCurrent       = subGridIter.Current;
                Vector2    scaledSubCurrent = new Vector2(subCurrent.x * scale.x, subCurrent.y * scale.y);
                Vector2Int sourcePos        = sourceAreaPos + Vector2Int.FloorToInt(scaledSubCurrent);

                subGrid[subCurrent] = grid[sourcePos];
            }

            return(subGrid);
        }
예제 #2
0
        protected bool AddCorridor(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap, KeyValuePair <Vector2Int, Vector2Int> closestCells, bool straightConnections = false)
        {
            if (!map.IsValidPosition(closestCells.Key) || !map.IsValidPosition(closestCells.Value))
            {
                return(false);
            }

            // we start from both sides

            Vector2Int p0  = closestCells.Key;
            Vector2Int p1  = closestCells.Value;
            Vector2Int dir = new Vector2Int(p0.x > p1.x ? -1 : 1, p0.y > p1.y ? -1 : 1);

            bool firstHorizontal  = GameRNG.CoinToss();
            bool secondHorizontal = GameRNG.CoinToss();

            for (; ;)
            {
                if (!straightConnections)
                {
                    firstHorizontal  = GameRNG.CoinToss();
                    secondHorizontal = GameRNG.CoinToss();
                }

                // connect rooms
                dir.x = p0.x > p1.x ? -1 : 1;
                dir.y = p0.y > p1.y ? -1 : 1;

                if (p0.x != p1.x && p0.y != p1.y)
                {
                    if (firstHorizontal)
                    {
                        p0.x += dir.x;
                    }
                    else
                    {
                        p0.y += dir.y;
                    }
                }
                if (p0.x != p1.x && p0.y != p1.y)
                {
                    if (secondHorizontal)
                    {
                        p1.x -= dir.x;
                    }
                    else
                    {
                        p1.y -= dir.y;
                    }
                }

                if (valueMap[p0] == valueWall)
                {
                    valueMap[p0] = valueHall;
                }
                if (valueMap[p1] == valueWall)
                {
                    valueMap[p1] = valueHall;
                }

                // connect corridors if on the same level
                if (p0.x == p1.x)
                {
                    dir.y = p0.y > p1.y ? -1 : 1;
                    while (p0.y != p1.y)
                    {
                        p0.y += dir.y;
                        if (valueMap[p0] == valueWall)
                        {
                            valueMap[p0] = valueHall;
                        }
                    }

                    if (valueMap[p0] == valueWall)
                    {
                        valueMap[p0] = valueHall;
                    }

                    return(true);
                }

                if (p0.y == p1.y)
                {
                    dir.x = p0.x > p1.x ? -1 : 1;
                    while (p0.x != p1.x)
                    {
                        p0.x += dir.x;
                        if (valueMap[p0] == valueWall)
                        {
                            valueMap[p0] = valueHall;
                        }
                    }

                    if (valueMap[p0] == valueWall)
                    {
                        valueMap[p0] = valueHall;
                    }

                    return(true);
                }
            }

            //return true;
        }
예제 #3
0
파일: AntNest.cs 프로젝트: Kerr1291/common
        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);
        }