示例#1
0
        /// <summary>
        /// Adds edge noise to next to a give tile position
        /// </summary>
        /// <param name="row">Tile row index</param>
        /// <param name="column">Tile column index</param>
        /// <param name="rowCount">Number of rows per grid</param>
        /// <param name="columnCount">Number of columns per grid</param>
        /// <param name="tileIdValue">Edge noise tile id value</param>
        /// <param name="tileFlags">Tile flags</param>
        /// <param name="percentage">Percentage to add edge noise</param>
        /// <param name="allowedDirection">Direction of free tiles</param>
        /// <param name="map">A Representation of a grid</param>
        private void AddEdgeNoise(int row, int column, int rowCount, int columnCount, ushort tileIdValue, byte tileFlags, float percentage, List <Direction> allowedDirection, Tile[] map)
        {
            if (allowedDirection.Count > 0)
            {
                float calculatedPercentage = random.Next(0, 100) / 100f;
                while (allowedDirection.Count > 0 && percentage >= calculatedPercentage)
                {
                    //replace allowedDirections
                    int result = random.Next(0, allowedDirection.Count);
                    if (allowedDirection[result].Axis == DirectionAxis.Horizontal)
                    {
                        column += allowedDirection[result].Value;
                    }
                    else
                    {
                        row += allowedDirection[result].Value;
                    }

                    if (TileMathHelper.IsOutOfRange(row, column, rowCount, columnCount))
                    {
                        return;
                    }

                    allowedDirection = CheckDirections(row, column, rowCount, columnCount, map);
                    int id = TileMathHelper.ToIndex(row, column, columnCount);
                    if (map[id].Id == 0)
                    {
                        map[id] = new Tile(tileIdValue, tileFlags);
                    }

                    percentage          -= 0.01f;
                    calculatedPercentage = random.Next(0, 100) / 100f;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Converts a pixel position into a tile index
        /// </summary>
        /// <param name="x">X position</param>
        /// <param name="y">Y position</param>
        /// <returns>Returns a tile index from flatten map array</returns>
        public int GetTileIndex(int x, int y)
        {
            int column = x / tileSize;
            int row    = y / tileSize;

            return(TileMathHelper.ToIndex(row, column, GridColumnCount));
        }
示例#3
0
 /// <summary>
 /// Checks whenther a tile position is free or out of range
 /// </summary>
 /// <param name="row">Row index of the tile</param>
 /// <param name="column">Column index of the tile</param>
 /// <param name="columnCount">Number of column per grid</param>
 /// <param name="rowCount">Number of rows per grid</param>
 /// <param name="map">A representation of a grid</param>
 /// <returns>Retruns 0 if the tile is out of range or has already a flag, otherwise 1</returns>
 private int CheckDirection(int row, int column, int columnCount, int rowCount, Tile[] map)
 {
     if (TileMathHelper.IsOutOfRange(row, column, rowCount, columnCount))
     {
         return(0);
     }
     return(map[TileMathHelper.ToIndex(row, column, columnCount)].Id == 0 ? 1 : 0);
 }
示例#4
0
 /// <summary>
 /// Returns a grid position of a given tile position
 /// </summary>
 /// <param name="row">Tile row index</param>
 /// <param name="column">Tile column index</param>
 /// <param name="gridRow">Returns the grid row index</param>
 /// <param name="gridColumn">Returns the grid column index</param>
 public void ConvertTileToGridPosition(int row, int column, out int gridRow, out int gridColumn)
 {
     gridRow    = (int)Math.Floor((double)row / (double)TileRowCount);
     gridColumn = (int)Math.Floor((double)column / (double)TileColumnCount);
     if (TileMathHelper.IsOutOfRange(gridRow, gridColumn, GridRowCount, GridColumnCount))
     {
         gridRow    = TileMathHelper.FixTileIndex(gridRow, GridRowCount);
         gridColumn = TileMathHelper.FixTileIndex(gridColumn, GridColumnCount);
     }
 }
示例#5
0
        /// <summary>
        /// Determine all tiles on screen based on the given viewport
        /// </summary>
        /// <param name="viewportWidth">Viewport width in pixel</param>
        /// <param name="viewportHeight">Viewport height in pixel</param>
        /// <returns>Returns a flatten byte array which represants the tiles</returns>
        public Tile[] GetTileMapInScreen(int viewportWidth, int viewportHeight)
        {
            ScreenWidth  = viewportWidth;
            ScreenHeight = viewportHeight;

            int screenColumnCount = (viewportWidth / tileSize);
            int screenRowCount    = (viewportHeight / tileSize);

            Tile[] tilesInScreen = new Tile[screenRowCount * screenColumnCount];

            int posRow    = tileRow + (screenRowCount / 2);
            int negRow    = tileRow - (screenRowCount / 2);
            int posColumn = tileColumn + (screenColumnCount / 2);
            int negColumn = tileColumn - (screenColumnCount / 2);

            int rowIndex = 0;

            for (int r = negRow; r < posRow; r++)
            {
                int columnIndex = 0;
                for (int c = negColumn; c < posColumn; c++)
                {
                    int newMapIndex = CurrentMapIndex;
                    int realRow     = r;
                    int realColumn  = c;
                    if (TileMathHelper.IsOutOfRange(r, c, TileRowCount, TileColumnCount))
                    {
                        newMapIndex = TileMathHelper.GetMapIndex(r, c, TileRowCount, TileColumnCount, newMapIndex);
                        realRow     = TileMathHelper.FixTileIndex(r, TileRowCount);
                        realColumn  = TileMathHelper.FixTileIndex(c, TileColumnCount);
                    }

                    //GetValues and merge
                    if (newMapIndex < 0)
                    {
                        tilesInScreen[TileMathHelper.ToIndex(rowIndex, columnIndex++, screenColumnCount)] = new Tile(ushort.MaxValue, 255);
                        int newGridRow    = (int)Math.Floor((double)r / (double)TileRowCount);
                        int newGridColumn = (int)Math.Floor((double)c / (double)TileColumnCount);
                        GridGenerationIsSlow?.Invoke(this, new GridEventArgs(newGridRow, newGridColumn, GridRow, GridColumn, false));
                    }
                    else
                    {
                        tilesInScreen[TileMathHelper.ToIndex(rowIndex, columnIndex++, screenColumnCount)] = maps[newMapIndex].MapSurface[TileMathHelper.ToIndex(realRow, realColumn, TileColumnCount)];
                    }
                }
                rowIndex++;
            }

            return(tilesInScreen);
        }
示例#6
0
 /// <summary>
 /// Initzializes a new streamed tile map
 /// </summary>
 /// <param name="spawnTileRow">Tile row index</param>
 /// <param name="spawnTileColumn">Tile column index</param>
 /// <param name="gridColumnCount">Number of grid columns</param>
 /// <param name="gridRowCount">Number of grid rows</param>
 /// <param name="tileRowCount">Number of tile rows per grid</param>
 /// <param name="tileColumnCount">Number of tile columns per grid</param>
 /// <param name="tileSize">Tile size in pixel</param>
 /// <param name="maps">Loaded grids</param>
 public StreamedTileMap(int spawnTileRow, int spawnTileColumn, int gridColumnCount, int gridRowCount, int tileRowCount, int tileColumnCount, int tileSize, List <TileMapPart> maps)
 {
     this.maps            = maps;
     this.gridColumnCount = gridColumnCount;
     this.gridRowCount    = gridRowCount;
     this.tileSize        = tileSize;
     this.tileRowCount    = tileRowCount;
     this.tileColumnCount = tileColumnCount;
     currentMapIndex      = 4;
     tileRow    = spawnTileRow;
     tileColumn = spawnTileColumn;
     gridRow    = (int)Math.Floor((double)spawnTileRow / (double)tileRowCount);
     gridColumn = (int)Math.Floor((double)spawnTileColumn / (double)tileColumnCount);
     gridRow    = TileMathHelper.FixTileIndex(gridRow, gridRowCount);
     gridColumn = TileMathHelper.FixTileIndex(gridColumn, gridColumnCount);
 }
示例#7
0
        /// <summary>
        /// Calculate all surrounding grid id's
        /// </summary>
        /// <param name="gridCount">Number of grids</param>
        /// <param name="gridColumn">Grid column index</param>
        /// <param name="gridRow">Grid row index</param>
        /// <param name="gridsPerRow">Number of grids per row</param>
        /// <returns>Returns grid id's of all surrounding grids</returns>
        private int[] CreateSuroundings(int gridCount, int gridColumn, int gridRow, int gridsPerRow)
        {
            int[] suroundingGrids = new int[gridCount];
            //Line 1
            suroundingGrids[0] = TileMathHelper.CalculateGridTranslation(-1, -1, gridColumn, gridRow, gridsPerRow, gridsPerRow);
            suroundingGrids[1] = TileMathHelper.CalculateGridTranslation(0, -1, gridColumn, gridRow, gridsPerRow, gridsPerRow);
            suroundingGrids[2] = TileMathHelper.CalculateGridTranslation(1, -1, gridColumn, gridRow, gridsPerRow, gridsPerRow);
            //Line 2
            suroundingGrids[3] = TileMathHelper.CalculateGridTranslation(-1, 0, gridColumn, gridRow, gridsPerRow, gridsPerRow);
            suroundingGrids[4] = TileMathHelper.CalculateGridTranslation(0, 0, gridColumn, gridRow, gridsPerRow, gridsPerRow); //Center
            suroundingGrids[5] = TileMathHelper.CalculateGridTranslation(1, 0, gridColumn, gridRow, gridsPerRow, gridsPerRow);
            //Line 3
            suroundingGrids[6] = TileMathHelper.CalculateGridTranslation(-1, 1, gridColumn, gridRow, gridsPerRow, gridsPerRow);
            suroundingGrids[7] = TileMathHelper.CalculateGridTranslation(0, 1, gridColumn, gridRow, gridsPerRow, gridsPerRow);
            suroundingGrids[8] = TileMathHelper.CalculateGridTranslation(1, 1, gridColumn, gridRow, gridsPerRow, gridsPerRow);

            return(suroundingGrids);
        }
示例#8
0
        /// <summary>
        /// Create the StreamedTileMap from the generated grids
        /// </summary>
        /// <param name="maps">Current grid with all it's surrounding grids</param>
        /// <param name="suroundingGrids">Ids of all surrounding grids</param>
        /// <param name="gridsPerRow">Number grids per row</param>
        /// <param name="streamedTileMap">A reference to a streamedTileMap</param>
        private void CreateTileMapParts(Tile[][] maps, List <ObjectTile>[] objectTiles, int[] suroundingGrids, int gridsPerRow, StreamedTileMap streamedTileMap)
        {
            //create TileMapPart
            for (int i = 0; i < maps.Length; i++)
            {
                int gridId = suroundingGrids[i];

                int gridRow;
                int gridColumn;
                TileMathHelper.ToPosition(gridId, gridsPerRow, out gridRow, out gridColumn);

                gridRow    = TileMathHelper.FixTileIndex(gridRow, gridsPerRow);
                gridColumn = TileMathHelper.FixTileIndex(gridColumn, gridsPerRow);

                TileMapPart part = new TileMapPart(gridId, maps[i], null, objectTiles[i].ToArray(), gridColumn, gridRow);
                streamedTileMap.Add(part);
            }
        }
示例#9
0
        /// <summary>
        /// Initzializes a new streamed tile map
        /// </summary>
        /// <param name="generator">Tile map generator</param>
        /// <param name="spawnTileRow">Tile row index</param>
        /// <param name="spawnTileColumn">Tile column index</param>
        /// <param name="gridColumnCount">Number of grid columns</param>
        /// <param name="gridRowCount">Number of grid rows</param>
        /// <param name="tileRowCount">Number of tile rows per grid</param>
        /// <param name="tileColumnCount">Number of tile columns per grid</param>
        /// <param name="tileSize">Tile size in pixel</param>
        public StreamedTileMap(TileMapGenerator generator, int spawnTileRow, int spawnTileColumn, int gridColumnCount, int gridRowCount, int tileRowCount, int tileColumnCount, int tileSize)
        {
            maps = new List <TileMapPart>();
            this.gridColumnCount = gridColumnCount;
            this.gridRowCount    = gridRowCount;
            this.tileSize        = tileSize;
            this.tileRowCount    = tileRowCount;
            this.tileColumnCount = tileColumnCount;
            this.generator       = generator;
            currentMapIndex      = 4;
            tileRow    = spawnTileRow;
            tileColumn = spawnTileColumn;
            gridRow    = (int)Math.Floor((double)spawnTileRow / (double)tileRowCount);
            gridColumn = (int)Math.Floor((double)spawnTileColumn / (double)tileColumnCount);

            gridRow    = TileMathHelper.FixTileIndex(gridRow, gridRowCount);
            gridColumn = TileMathHelper.FixTileIndex(gridColumn, gridColumnCount);
        }
示例#10
0
        /// <summary>
        /// Create a circular area to a given map
        /// </summary>
        /// <param name="map">The map where the area should be placed on</param>
        /// <param name="rowIndex">Tile row index</param>
        /// <param name="columnIndex">Tile column index</param>
        /// <param name="rowCount">Number of rows per grid</param>
        /// <param name="columnCount">Number of columns per grid</param>
        /// <param name="radius">Radius of the circle</param>
        /// <param name="tileSize">Size of a tile in pixel</param>
        /// <param name="metersPerTile">Size of a tile in meter</param>
        /// <param name="tileIdValue">Tile id value for the circular area</param>
        /// <param name="tileFlag">Tile flag</param>
        /// <param name="allowEdgeManipulation">Allows areas to overlap tiles from other maps</param>
        /// <returns>Returns the number of changed tiles</returns>
        private int CreateCircleArea(Tile[] map, int rowIndex, int columnIndex, int rowCount, int columnCount, int radius, int tileSize, float metersPerTile, ushort tileIdValue, byte tileFlag, bool allowEdgeManipulation)
        {
            int modified      = 0;
            int minRadiusTile = (int)Math.Ceiling(radius / metersPerTile);
            int minRadiusPx   = minRadiusTile * tileSize;
            int x             = columnIndex * tileSize;
            int y             = rowIndex * tileSize;

            for (int r = rowIndex - minRadiusTile; r < rowIndex + minRadiusTile; r++)
            {
                for (int c = columnIndex - minRadiusTile; c < columnIndex + minRadiusTile; c++)
                {
                    int realRow    = r;
                    int realColumn = c;

                    if (TileMathHelper.IsOutOfRange(r, c, rowCount, columnCount))
                    {
                        if (allowEdgeManipulation)
                        {
                            realRow    = TileMathHelper.FixTileIndex(r, rowCount);
                            realColumn = TileMathHelper.FixTileIndex(c, columnCount);
                        }
                        else
                        {
                            continue;
                        }
                    }


                    int distance = TileMathHelper.GetDistance(x, y, c * tileSize, r * tileSize);
                    if (distance <= minRadiusPx)
                    {
                        int id = TileMathHelper.ToIndex(realRow, realColumn, columnCount);
                        if (map[id].Id == 0)
                        {
                            map[id] = new Tile(tileIdValue, tileFlag);
                            modified++;
                        }
                    }
                }
            }

            return(modified);
        }
示例#11
0
        /// <summary>
        /// Sets a tile value
        /// </summary>
        /// <param name="row">Tile row index</param>
        /// <param name="column">Tile column index</param>
        /// <param name="value">New tile value</param>
        public bool SetTileValue(int row, int column, Tile value)
        {
            int newGridRow;
            int newGridColumn;

            ConvertTileToGridPosition(row, column, out newGridRow, out newGridColumn);

            int tileMapId       = TileMathHelper.ToIndex(newGridRow, newGridColumn, GridColumnCount);
            int tileRow         = TileMathHelper.FixTileIndex(row, TileRowCount);
            int tileColumn      = TileMathHelper.FixTileIndex(column, TileColumnCount);
            int currentMapIndex = maps.FindIndex(m => m.Id == tileMapId);

            if (currentMapIndex != -1)
            {
                maps[currentMapIndex].MapSurface[TileMathHelper.ToIndex(tileRow, tileColumn, TileColumnCount)] = value;
                return(true);
            }

            return(false);
        }
示例#12
0
        private ObjectTile[] CreateObjectLayer(Tile[] map, AreaSpread area, int rowCount, int columnCount)
        {
            List <ObjectTile> tiles        = new List <ObjectTile>();
            float             tilesChanged = 0;
            float             tileCount    = rowCount * columnCount;

            while (tilesChanged / tileCount < area.Percentage)
            {
                int row        = random.Next(0, rowCount);
                int column     = random.Next(0, columnCount);
                int fieldIndex = TileMathHelper.ToIndex(row, column, columnCount);

                if (map[fieldIndex].Id == 0)
                {
                    ObjectTile tile = new ObjectTile(fieldIndex, area.Id);
                    tiles.Add(tile);
                    tilesChanged++;
                }
            }
            return(tiles.ToArray());
        }
示例#13
0
        /// <summary>
        /// Create the first (height) layer with circular areas
        /// </summary>
        /// <param name="map">The map where the area should be placed on</param>
        /// <param name="rowCount">Number of rows per grid</param>
        /// <param name="columnCount">Number of columns per grid</param>
        /// <param name="tileSize">Size of a tile in pixel</param>
        /// <param name="meterPerTile">Size of a tile in meter</param>
        /// <param name="area">Area that should be generated and placed on the given map</param>
        /// <param name="allowEdgeManipulation">Allows areas to overlap tiles from other maps</param>
        private void CreateLayerOne(Tile[] map, int rowCount, int columnCount, int tileSize, float meterPerTiles, AreaSpread area, bool allowEdgeManipulation)
        {
            float tilesChanged = 0;
            float tileCount    = rowCount * columnCount;

            while (tilesChanged / tileCount < area.Percentage)
            {
                int row        = random.Next(0, rowCount);
                int column     = random.Next(0, columnCount);
                int fieldIndex = TileMathHelper.ToIndex(row, column, columnCount);
                int minRadius  = random.Next(area.MinSizeInMeter, area.MaxSizeInMeter + 1);

                if (map[fieldIndex].Id == 0 || map[fieldIndex].Id == area.Id)
                {
                    if (area.SpreadType == SpreadOption.Circle)
                    {
                        tilesChanged += CreateCircleArea(map, row, column, rowCount, columnCount, minRadius, tileSize, meterPerTiles, area.Id, area.Flag, allowEdgeManipulation);
                    }
                }
            }
        }
示例#14
0
        /// <summary>
        /// Create the first (height) layer with circular areas
        /// </summary>
        /// <param name="mapIndex">Index of the map</param>
        /// <param name="maps">Current grids</param>
        /// <param name="edgeOverrides">Current edge override maps</param>
        /// <param name="rowCount">Number of rows per grid</param>
        /// <param name="columnCount">Number of columns per grid</param>
        /// <param name="tileSize">Size of a tile in pixel</param>
        /// <param name="meterPerTile">Size of a tile in meter</param>
        /// <param name="area">Area that should be generated and placed on the given map</param>
        /// <param name="allowEdgeOverflow">Allows areas to overlap tiles from other maps</param>
        private void CreateLayerOne(int mapIndex, Tile[][] maps, Tile[][] edgeOverrides, int rowCount, int columnCount, int tileSize, float meterPerTiles, AreaSpread area, bool allowEdgeOverflow)
        {
            int tilesChanged = 0;
            int tileCount    = rowCount * columnCount;

            while (((float)tilesChanged) / ((float)tileCount) < area.Percentage)
            {
                int row        = random.Next(0, rowCount);
                int column     = random.Next(0, columnCount);
                int fieldIndex = TileMathHelper.ToIndex(row, column, columnCount);
                int minRadius  = random.Next(area.MinSizeInMeter, area.MaxSizeInMeter + 1);

                if (maps[mapIndex][fieldIndex].Id == 0 || maps[mapIndex][fieldIndex].Id == area.Id)
                {
                    if (area.SpreadType == SpreadOption.Circle)
                    {
                        tilesChanged += CreateCircleArea(mapIndex, maps, edgeOverrides, row, column, rowCount, columnCount, minRadius, tileSize, meterPerTiles, area.Id, area.Flag, allowEdgeOverflow, area.UseEdgeNoise);
                    }
                }
            }
        }
示例#15
0
        /// <summary>
        /// Updates the grids based one the given tile location
        /// </summary>
        /// <param name="currentTileRow">Tile row index</param>
        /// <param name="currentTileColumn">Tile column index</param>
        public void Update(int currentTileRow, int currentTileColumn)
        {
            int newGridRow;
            int newGridColumn;

            ConvertTileToGridPosition(currentTileRow, currentTileColumn, out newGridRow, out newGridColumn);

            currentMapId = TileMathHelper.ToIndex(newGridRow, newGridColumn, GridColumnCount);
            tileRow      = TileMathHelper.FixTileIndex(currentTileRow, TileRowCount);
            tileColumn   = TileMathHelper.FixTileIndex(currentTileColumn, TileColumnCount);

            TryMapUpdate(newGridRow, newGridColumn);

            CurrentMapIndex = maps.FindIndex(m => m.Id == currentMapId);

            if ((newGridRow != GridRow || newGridColumn != GridColumn) && !newMapRequested)
            {
                GridChangeRequested?.Invoke(this, new GridEventArgs(GridRow, GridColumn, maps[4].GridRow, maps[4].GridColumn, false));
                gridRow    = newGridRow;
                gridColumn = newGridColumn;
                Resize(currentTileRow, currentTileColumn);
            }
        }
示例#16
0
        /// <summary>
        /// Deframgment maps and adds edge noise
        /// </summary>
        /// <param name="maps">Current gird and it's surrounding grids</param>
        /// <param name="areas">Area spread information to add edge noise if neccessary</param>
        /// <param name="suroundingGrids">Grid ids of all surrounding grids</param>
        /// <param name="rowCount">Number of row per grid</param>
        /// <param name="columnCount">Number of columns per grid</param>
        private void DefragmentMaps(Tile[][] maps, AreaSpread[] areas, int[] suroundingGrids, int rowCount, int columnCount)
        {
            for (int i = 0; i < maps.Length; i++)
            {
                random = new Random(suroundingGrids[i] * settings.Seed);

                for (int r = 0; r < rowCount; r++)
                {
                    for (int c = 0; c < columnCount; c++)
                    {
                        ushort id = maps[i][TileMathHelper.ToIndex(r, c, columnCount)].Id;
                        if (id != 0)
                        {
                            for (int j = 0; j < areas.Length; j++)
                            {
                                if (id == areas[j].Id)
                                {
                                    //EdgeNoise
                                    if (areas[j].UseEdgeNoise)
                                    {
                                        List <Direction> allowedDirections = CheckDirections(r, c, rowCount, columnCount, maps[i]);
                                        AddEdgeNoise(r, c, rowCount, columnCount, areas[j].Id, areas[j].Flag, 0.3f, allowedDirections, maps[i]);
                                    }

                                    if (areas[j].ConnectEqualFlags)
                                    {
                                        TryConnect(r, c, rowCount, columnCount, maps[i], id, areas[j].Flag, areas[j].ConnectDistance, DirectionAxis.Vertical);
                                        TryConnect(r, c, rowCount, columnCount, maps[i], id, areas[j].Flag, areas[j].ConnectDistance, DirectionAxis.Horizontal);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
示例#17
0
        /// <summary>
        /// Tries to connects close areas with the same flag
        /// </summary>
        /// <param name="row">Tile row index</param>
        /// <param name="column">Tile column index</param>
        /// <param name="rowCount">Grid row count</param>
        /// <param name="columnCount">Grid column count</param>
        /// <param name="map">Current map as flatten array</param>
        /// <param name="tileIdValue">Tile id value</param>
        /// <param name="tileFlags">Tile flags</param>
        /// <param name="distance">Maximum tile distance between areas</param>
        /// <param name="axis">Direction of connection</param>
        private void TryConnect(int row, int column, int rowCount, int columnCount, Tile[] map, ushort tileIdValue, byte tileFlags, int distance, DirectionAxis axis)
        {
            bool connectPos = false;
            bool connectNeg = false;

            int realRow    = row;
            int realColumn = column;

            for (int i = distance; i > 0; i--)
            {
                if (axis == DirectionAxis.Horizontal)
                {
                    realColumn = column + i;
                }
                else
                {
                    realRow = row + i;
                }

                if (!TileMathHelper.IsOutOfRange(realRow, realColumn, rowCount, columnCount))
                {
                    int id = TileMathHelper.ToIndex(realRow, realColumn, columnCount);
                    if (!connectPos)
                    {
                        if (map[id].Id == tileIdValue)
                        {
                            connectPos = true;
                        }
                    }
                    else
                    {
                        if (map[id].Id == 0)
                        {
                            map[id] = new Tile(tileIdValue, tileFlags);
                        }
                    }
                }

                if (axis == DirectionAxis.Horizontal)
                {
                    realColumn = column - i;
                }
                else
                {
                    realRow = row - i;
                }
                if (!TileMathHelper.IsOutOfRange(realRow, realColumn, rowCount, columnCount))
                {
                    int id = TileMathHelper.ToIndex(realRow, realColumn, columnCount);
                    if (!connectNeg)
                    {
                        if (map[id].Id == tileIdValue)
                        {
                            connectNeg = true;
                        }
                    }
                    else
                    {
                        if (map[id].Id == 0)
                        {
                            map[id] = new Tile(tileIdValue, tileFlags);
                        }
                    }
                }
            }
        }
示例#18
0
        /// <summary>
        /// Create a circular area to a given map
        /// </summary>
        /// <param name="mapIndex">Index of the map</param>
        /// <param name="maps">Current grids</param>
        /// <param name="edgeOverrides">Current edge override maps</param>
        /// <param name="rowIndex">Tile row index</param>
        /// <param name="columnIndex">Tile column index</param>
        /// <param name="rowCount">Number of rows per grid</param>
        /// <param name="columnCount">Number of columns per grid</param>
        /// <param name="radius">Radius of the circle</param>
        /// <param name="tileSize">Size of a tile in pixel</param>
        /// <param name="metersPerTile">Size of a tile in meter</param>
        /// <param name="tileIdValue">Tile id value for the circular area</param>
        /// <param name="tileFlags">Tile flags</param>
        /// <param name="allowEdgeOverflow">Allows areas to overlap tiles from other maps</param>
        /// <param name="useEdgeNoise">Adds edge noise to the generated area</param>
        /// <returns>Returns the number of changed tiles</returns>
        private int CreateCircleArea(int mapIndex, Tile[][] maps, Tile[][] edgeOverrides, int rowIndex, int columnIndex, int rowCount, int columnCount, int radius, int tileSize, float metersPerTile, ushort tileIdValue, byte tileFlags, bool allowEdgeOverflow, bool useEdgeNoise)
        {
            int modified      = 0;
            int minRadiusTile = (int)Math.Ceiling(radius / metersPerTile);
            int minRadiusPx   = minRadiusTile * tileSize;
            int x             = columnIndex * tileSize;
            int y             = rowIndex * tileSize;

            for (int r = rowIndex - minRadiusTile; r < rowIndex + minRadiusTile; r++)
            {
                for (int c = columnIndex - minRadiusTile; c < columnIndex + minRadiusTile; c++)
                {
                    int currentMapIndex = mapIndex;
                    int realRow         = r;
                    int realColumn      = c;

                    if (TileMathHelper.IsOutOfRange(r, c, rowCount, columnCount))
                    {
                        if (allowEdgeOverflow)
                        {
                            currentMapIndex = TileMathHelper.GetMapIndex(r, c, rowCount, columnCount, currentMapIndex);
                            if (currentMapIndex >= 0)
                            {
                                realRow    = TileMathHelper.FixTileIndex(r, rowCount);
                                realColumn = TileMathHelper.FixTileIndex(c, columnCount);
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }

                    int distance = TileMathHelper.GetDistance(x, y, c * tileSize, r * tileSize);
                    if (distance <= minRadiusPx)
                    {
                        int id = TileMathHelper.ToIndex(realRow, realColumn, columnCount);
                        if (mapIndex == currentMapIndex)
                        {
                            if (maps[currentMapIndex][id].Id == 0)
                            {
                                maps[currentMapIndex][id] = new Tile(tileIdValue, tileFlags);
                                modified++;
                            }
                        }
                        else
                        {
                            if (edgeOverrides[currentMapIndex][id].Id == 0)
                            {
                                edgeOverrides[currentMapIndex][id] = new Tile(tileIdValue, tileFlags);
                            }
                        }
                    }
                }
            }

            return(modified);
        }
示例#19
0
        /// <summary>
        /// Generates a map based on the given tile location, generator settings and area spreads
        /// </summary>
        /// <param name="settings">Generator settings to modify the generation process</param>
        /// <param name="areas">Areas that should be placed on the map</param>
        /// <param name="tileColumn">Tile column index</param>
        /// <param name="tileRow">Tile row index</param>
        /// <returns>Returns a StreamedTileMap</returns>
        public StreamedTileMap GenerateMap(GeneratorSettings settings, AreaSpread[] areas, int tileColumn, int tileRow)
        {
            if (settings.Seed > 0)
            {
                random = new Random(settings.Seed);
            }
            else if (random == null)
            {
                throw new ArgumentOutOfRangeException();
            }

            this.settings = settings;
            spreads       = areas;

            double tilesPerGrid   = Math.Round(settings.MeterPerGrid / settings.MeterPerTile);
            int    tilesPerColumn = (int)tilesPerGrid;
            int    size           = tilesPerColumn * tilesPerColumn;
            int    gridsPerRow    = (int)Math.Ceiling(GetMapSize(settings) / tilesPerGrid);

            int gridColumn = (int)Math.Floor(tileColumn / tilesPerGrid);
            int gridRow    = (int)Math.Floor(tileRow / tilesPerGrid);

            Tile[][]            edgeOverrides = new Tile[9][];
            Tile[][]            maps          = new Tile[9][];
            List <ObjectTile>[] objectTiles   = new List <ObjectTile> [9];
            for (int i = 0; i < maps.Length; i++)
            {
                edgeOverrides[i] = new Tile[size];
                maps[i]          = new Tile[size];
                objectTiles[i]   = new List <ObjectTile>();
            }

            int[] suroundingGrids = CreateSuroundings(maps.Length, gridColumn, gridRow, gridsPerRow);

            StreamedTileMap streamedTileMap = new StreamedTileMap(this, tileRow, tileColumn, gridsPerRow, gridsPerRow, tilesPerColumn, tilesPerColumn, settings.TileSize);

            //Create Map
            foreach (LayerType currentLayerType in Enum.GetValues(typeof(LayerType)).Cast <LayerType>().OrderBy(k => (int)k))
            {
                for (int i = 0; i < suroundingGrids.Length; i++)
                {
                    AreaSpread[] layerAreas = areas.Where(a => a.Layer == currentLayerType).ToArray();
                    random = new Random(suroundingGrids[i] * settings.Seed);
                    for (int j = 0; j < layerAreas.Length; j++)
                    {
                        switch (layerAreas[j].Layer)
                        {
                        case LayerType.Height:
                        {
                            if (layerAreas[j].MaxSizeInMeter <= settings.MeterPerGrid / 2f)
                            {
                                CreateLayerOne(i, maps, edgeOverrides, (int)tilesPerGrid, (int)tilesPerGrid, settings.TileSize, settings.MeterPerTile, layerAreas[j], settings.RadiusOfCylinder);
                            }
                            else
                            {
                                throw new Exception("AreaSpread MaxSize must be smaller then (MetersPerGrid / 2)!");
                            }
                            break;
                        }

                        case LayerType.Biome:
                            CreateBiomeLayer(i, maps, layerAreas[j]);
                            break;

                        case LayerType.Paths:
                            CreateLayerFour();
                            break;

                        case LayerType.PointsOfInterest:
                        {
                            objectTiles[i].AddRange(CreateObjectLayer(maps[i], layerAreas[j], tilesPerColumn, tilesPerColumn));
                        }
                        break;
                        }
                    }
                }

                if (currentLayerType == LayerType.Height)
                {
                    //DefragementMap and add edgenoise
                    DefragmentMaps(maps, areas, suroundingGrids, (int)tilesPerGrid, (int)tilesPerGrid);

                    //Merge edgeOverrides
                    for (int k = 0; k < maps.Length; k++)
                    {
                        maps[k] = TileMathHelper.MergeMaps(maps[k], edgeOverrides[k]);
                    }
                }
            }

            CreateTileMapParts(maps, objectTiles, suroundingGrids, gridsPerRow, streamedTileMap);

            return(streamedTileMap);
        }