public static Arena Generate(GameAssets gameAssets, int seed, int biome_count) { // Prepare stuff Arena arena = new Arena(WIDTH, HEIGHT); arena.Biomes = new Biome[biome_count]; arena.Seed = seed; List <int>[] biome_tiles_list = new List <int> [biome_count]; Random rnd = new Random(seed); HaltonSet hlt = new HaltonSet(seed); // halton sequence is used for generating evenly distributed points // generate temperature map double[] heatmap = GenerateNoise(seed, 3); for (int i = 0; i < arena.Heatmap.Length; i++) { arena.Heatmap[i] = (int)((heatmap[i] - 0.5) * 30 + 0.8 * (i % arena.Width)); } // set locations of biome pivots for (int i = 0; i < biome_count; i++) { double halton2 = hlt.Seq2(i + 1); double halton3 = hlt.Seq3(i + 1); arena.Biomes[i] = new Biome((int)(halton2 * arena.Width), (int)(halton3 * arena.Height)); biome_tiles_list[i] = new List <int>(); } // calc which tile belongs in which biome for (int i = 0; i < arena.Tiles.Length; i++) { Point tile_pos = new Point(i % arena.Width, i / arena.Width); int minDist2 = 40 * 40; int owner = 0; // go thru all the pivots and pick the closest to current tile for (int p = 0; p < biome_count; p++) { Point pivot = new Point(arena.Biomes[p].Pivot.X, arena.Biomes[p].Pivot.Y); // add a bit of noise Point noise = new Point((int)((rnd.NextDouble() - 0.5) * 2.5), (int)((rnd.NextDouble() - 0.5) * 2)); pivot += noise; int dist2 = tile_pos.distanceSquared(pivot); if (dist2 < minDist2) { minDist2 = dist2; owner = p; } } biome_tiles_list[owner].Add(i); } // assign the calculated tiles to actual biomes for (int i = 0; i < biome_count; i++) { int pivotPos = arena.Biomes[i].Pivot.X + arena.Biomes[i].Pivot.Y * arena.Width; arena.Biomes[i].TilesOwned = biome_tiles_list[i].ToArray(); arena.Biomes[i].Asset = gameAssets.PickBiomeAmountBased(rnd, arena.Heatmap[pivotPos]); } // time to populate *BIOMES* // (with tiles) for (int b = 0; b < biome_count; b++) { Biome biome = arena.Biomes[b]; BiomeAsset biome_asset = gameAssets.BiomeAssets[biome.AssetName]; List <TileAsset> special_tiles = new List <TileAsset>(); foreach (TileAsset t in gameAssets.TileAssets.Values) { if (t.SpawnDestinations.Length > 0 && t.SpawnDestinations.Where(a => a.Name == biome_asset.AssetName).Count() > 0) { special_tiles.Add(t); } } for (int t = 0; t < biome.TilesOwned.Length; t++) { Tile tile = biome_asset.GenerateTile(rnd); // test, if current tile shouldn't be special tile foreach (TileAsset ta in special_tiles) { SpawnDestination local = ta.SpawnDestinations.Where(a => a.Name == biome_asset.AssetName).First(); int amt = local.Amount.Evaluate(rnd); if (amt > 0) { tile = ta.GenerateTile(rnd); } } arena.Tiles[biome.TilesOwned[t]] = tile; } } // time to populate *TILES* for (int i = 0; i < arena.Tiles.Length; i++) { Tile tile = arena.Tiles[i]; Asset tileAsset = null; // tileAsset can be a regular biome asset or a special tile asset tileAsset = gameAssets.GetAssetByName(tile.AssetName); foreach (string spwnHere in tileAsset.SpawnsHere) { // following asset will be spawned in current tile SpawnableAsset assetToSpawn = (SpawnableAsset)gameAssets.GetAssetByName(spwnHere); SpawnDestination local = assetToSpawn.SpawnDestinations.Where(a => a.Name == tile.AssetName).First(); if (assetToSpawn is ItemAsset) { int amt = local.Amount.Evaluate(rnd); } } } return(arena); }