/// <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); }