public static void GenerateTerrain(Map map, LightingEngine lightingEngine, GraphicsDevice gd) { Generating = true; PercentComplete = 0; Thread.Sleep(1000); bool compoundsOK = false; map.Jetties.Clear(); List<Compound> compounds = new List<Compound>(); TileLayer terrainLayer = map.GetLayer("Terrain") as TileLayer; TileLayer wallLayer = map.GetLayer("Wall") as TileLayer; TileLayer waterLayer = map.GetLayer("Water") as TileLayer; TileLayer roofLayer = map.GetLayer("Roof") as TileLayer; float[][] noise = null; while (!compoundsOK) { compounds.Clear(); for (int i = lightingEngine.LightSources.Count - 1; i >= 0; i--) if (lightingEngine.LightSources[i].SpotStencil != null) lightingEngine.LightSources.RemoveAt(i); for (int y = 0; y < map.Width; y++) { for (int x = 0; x < map.Height; x++) { terrainLayer.Tiles[x, y] = null; wallLayer.Tiles[x, y] = null; } } PercentComplete = 5; // Inital terrain noise = PerlinNoise.GeneratePerlinNoise(map.Width, map.Height, 8); for (int y = 0; y < map.Width; y++) { for (int x = 0; x < map.Height; x++) if (noise[y][x] < 0.5f) { terrainLayer.Tiles[x, y] = map.Tiles[WATER]; waterLayer.Tiles[x, y] = map.Tiles[WATER]; } else if (noise[y][x] < 0.6f) { terrainLayer.Tiles[x, y] = map.Tiles[SAND]; waterLayer.Tiles[x, y] = null; } else { terrainLayer.Tiles[x, y] = map.Tiles[GRASS]; waterLayer.Tiles[x, y] = null; } } PercentComplete = 10; // Trees float[][] treeNoise = PerlinNoise.GeneratePerlinNoise(map.Width, map.Height, 4); for (int y = 0; y < map.Width; y++) { for (int x = 0; x < map.Height; x++) { if (noise[y][x] > 0.62f) if (treeNoise[y][x] > 0.5f) wallLayer.Tiles[x, y] = map.Tiles[TREE]; } } PercentComplete = 20; // Compounds CreateCompounds(map, terrainLayer, wallLayer, roofLayer, compounds, noise, 0.65f, 20000f, 20, lightingEngine, gd); CreateCompounds(map, terrainLayer, wallLayer, roofLayer, compounds, noise, 0.75f, 12000f, 30, lightingEngine, gd); // Test to see if compounds are okay int numOKComps = 0; foreach (Compound c in compounds) { if (c.Buildings.Count(b => b.Type != BuildingType.Carpark && b.Type != BuildingType.Helipad) > 0) numOKComps++; } if (numOKComps > 5) compoundsOK = true; } PercentComplete = 35; // Remove stray tiles for (int y = 0; y < map.Width; y++) { for (int x = 0; x < map.Height; x++) { if (GetTileIndex(map, terrainLayer, x, y) == SAND) if (CountSurroundingTiles(map, terrainLayer, x, y, WATER) >= 5) { terrainLayer.Tiles[x, y] = map.Tiles[WATER]; waterLayer.Tiles[x, y] = map.Tiles[WATER]; } //if (GetTileIndex(map, terrainLayer, (map.Width-1) - x, (map.Height-1) - y) == SAND) // if (CountSurroundingTiles(map, terrainLayer, (map.Width - 1) - x, (map.Height - 1) - y, WATER) >= 5) terrainLayer.Tiles[(map.Width - 1) - x, (map.Height - 1) - y] = map.Tiles[WATER]; if (GetTileIndex(map, terrainLayer, x, y) == GRASS) if (CountSurroundingTiles(map, terrainLayer, x, y, SAND) >= 5) terrainLayer.Tiles[x, y] = map.Tiles[SAND]; //if (GetTileIndex(map, terrainLayer, (map.Width - 1) - x, (map.Height - 1) - y) == GRASS) // if (CountSurroundingTiles(map, terrainLayer, (map.Width - 1) - x, (map.Height - 1) - y, SAND) >= 5) terrainLayer.Tiles[(map.Width - 1) - x, (map.Height - 1) - y] = map.Tiles[SAND]; } } PercentComplete = 45; // Jetties! for (int y = 40; y < map.Width - 40; y+=2) { for (int x = 40; x < map.Height - 40; x+=2) { if (GetTileIndex(map, terrainLayer, x, y) == SAND) { switch (Helper.Random.Next(4)) { case 0: if (GetTileIndex(map, terrainLayer, x, y - 10) == WATER && GetTileIndex(map, terrainLayer, x, y - 4) == WATER && GetTileIndex(map, terrainLayer, x, y - 2) == SAND) if (TryMakeJetty(map, terrainLayer, waterLayer, new Point(x, y), new Point(0, -1))) continue; break; case 1: if (GetTileIndex(map, terrainLayer, x, y + 10) == WATER && GetTileIndex(map, terrainLayer, x, y + 4) == WATER && GetTileIndex(map, terrainLayer, x, y + 2) == SAND) if (TryMakeJetty(map, terrainLayer, waterLayer, new Point(x, y), new Point(0, 1))) continue; break; case 2: if (GetTileIndex(map, terrainLayer, x - 10, y) == WATER && GetTileIndex(map, terrainLayer, x - 4, y) == WATER && GetTileIndex(map, terrainLayer, x - 2, y) == SAND) if (TryMakeJetty(map, terrainLayer, waterLayer, new Point(x, y), new Point(-1, 0))) continue; break; case 3: if (GetTileIndex(map, terrainLayer, x + 10, y) == WATER && GetTileIndex(map, terrainLayer, x + 4, y) == WATER && GetTileIndex(map, terrainLayer, x + 2, y) == SAND) if (TryMakeJetty(map, terrainLayer, waterLayer, new Point(x, y), new Point(1, 0))) continue; break; } } } } PercentComplete = 55; // Detail tiling! for (int y = 0; y < map.Width; y++) { for (int x = 0; x < map.Height; x++) { // Sand/Water if (GetTileIndex(map, terrainLayer, x, y) == SAND) { // Edges if (GetTileIndex(map, terrainLayer, x - 1, y) == WATER) if (GetTileIndex(map, terrainLayer, x, y - 1) != WATER) if (GetTileIndex(map, terrainLayer, x, y + 1) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_EDGE_LEFT]; if (GetTileIndex(map, terrainLayer, x + 1, y) == WATER) if (GetTileIndex(map, terrainLayer, x, y - 1) != WATER) if (GetTileIndex(map, terrainLayer, x, y + 1) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_EDGE_RIGHT]; if (GetTileIndex(map, terrainLayer, x, y + 1) == WATER) if (GetTileIndex(map, terrainLayer, x - 1, y) != WATER) if (GetTileIndex(map, terrainLayer, x + 1, y) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_EDGE_DOWN]; if (GetTileIndex(map, terrainLayer, x, y - 1) == WATER) if (GetTileIndex(map, terrainLayer, x - 1, y) != WATER) if (GetTileIndex(map, terrainLayer, x + 1, y) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_EDGE_UP]; // Corners - water inside if (GetTileIndex(map, terrainLayer, x - 1, y - 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y - 1) != WATER) if (GetTileIndex(map, terrainLayer, x - 1, y) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_INSIDE_BR]; if (GetTileIndex(map, terrainLayer, x - 1, y + 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y + 1) != WATER) if (GetTileIndex(map, terrainLayer, x - 1, y) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_INSIDE_TR]; if (GetTileIndex(map, terrainLayer, x + 1, y - 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y - 1) != WATER) if (GetTileIndex(map, terrainLayer, x + 1, y) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_INSIDE_BL]; if (GetTileIndex(map, terrainLayer, x + 1, y + 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y + 1) != WATER) if (GetTileIndex(map, terrainLayer, x + 1, y) != WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_INSIDE_TL]; // Corners - water outside if (GetTileIndex(map, terrainLayer, x - 1, y - 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y - 1) == WATER) if (GetTileIndex(map, terrainLayer, x - 1, y) == WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_OUTSIDE_TL]; if (GetTileIndex(map, terrainLayer, x - 1, y + 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y + 1) == WATER) if (GetTileIndex(map, terrainLayer, x - 1, y) == WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_OUTSIDE_BL]; if (GetTileIndex(map, terrainLayer, x + 1, y - 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y - 1) == WATER) if (GetTileIndex(map, terrainLayer, x + 1, y) == WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_OUTSIDE_TR]; if (GetTileIndex(map, terrainLayer, x + 1, y + 1) == WATER) if (GetTileIndex(map, terrainLayer, x, y + 1) == WATER) if (GetTileIndex(map, terrainLayer, x + 1, y) == WATER) terrainLayer.Tiles[x, y] = map.Tiles[SAND_CORNER_OUTSIDE_BR]; } // Grass/Sand if (GetTileIndex(map, terrainLayer, x, y) == GRASS || GetTileIndex(map, terrainLayer, x, y) == GRASS_ALT1 || GetTileIndex(map, terrainLayer, x, y) == GRASS_ALT2) { // Edges if (GetTileIndex(map, terrainLayer, x - 1, y) == SAND) if (GetTileIndex(map, terrainLayer, x, y - 1) != SAND) if (GetTileIndex(map, terrainLayer, x, y + 1) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_EDGE_LEFT]; if (GetTileIndex(map, terrainLayer, x + 1, y) == SAND) if (GetTileIndex(map, terrainLayer, x, y - 1) != SAND) if (GetTileIndex(map, terrainLayer, x, y + 1) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_EDGE_RIGHT]; if (GetTileIndex(map, terrainLayer, x, y + 1) == SAND) if (GetTileIndex(map, terrainLayer, x - 1, y) != SAND) if (GetTileIndex(map, terrainLayer, x + 1, y) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_EDGE_DOWN]; if (GetTileIndex(map, terrainLayer, x, y - 1) == SAND) if (GetTileIndex(map, terrainLayer, x - 1, y) != SAND) if (GetTileIndex(map, terrainLayer, x + 1, y) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_EDGE_UP]; // Corners - water inside if (GetTileIndex(map, terrainLayer, x - 1, y - 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y - 1) != SAND) if (GetTileIndex(map, terrainLayer, x - 1, y) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_INSIDE_BR]; if (GetTileIndex(map, terrainLayer, x - 1, y + 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y + 1) != SAND) if (GetTileIndex(map, terrainLayer, x - 1, y) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_INSIDE_TR]; if (GetTileIndex(map, terrainLayer, x + 1, y - 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y - 1) != SAND) if (GetTileIndex(map, terrainLayer, x + 1, y) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_INSIDE_BL]; if (GetTileIndex(map, terrainLayer, x + 1, y + 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y + 1) != SAND) if (GetTileIndex(map, terrainLayer, x + 1, y) != SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_INSIDE_TL]; // Corners - water outside if (GetTileIndex(map, terrainLayer, x - 1, y - 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y - 1) == SAND) if (GetTileIndex(map, terrainLayer, x - 1, y) == SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_OUTSIDE_TL]; if (GetTileIndex(map, terrainLayer, x - 1, y + 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y + 1) == SAND) if (GetTileIndex(map, terrainLayer, x - 1, y) == SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_OUTSIDE_BL]; if (GetTileIndex(map, terrainLayer, x + 1, y - 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y - 1) == SAND) if (GetTileIndex(map, terrainLayer, x + 1, y) == SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_OUTSIDE_TR]; if (GetTileIndex(map, terrainLayer, x + 1, y + 1) == SAND) if (GetTileIndex(map, terrainLayer, x, y + 1) == SAND) if (GetTileIndex(map, terrainLayer, x + 1, y) == SAND) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_CORNER_OUTSIDE_BR]; } } } PercentComplete = 75; // Alt tiles for (int y = 0; y < map.Width; y++) { for (int x = 0; x < map.Height; x++) { if (GetTileIndex(map, terrainLayer, x, y) == GRASS) { int r = rand.Next(50); if (r == 9) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_ALT1]; else if (r == 8) terrainLayer.Tiles[x, y] = map.Tiles[GRASS_ALT2]; } if (GetTileIndex(map, terrainLayer, x, y) == SAND) { int r = rand.Next(50); if (r == 9) terrainLayer.Tiles[x, y] = map.Tiles[SAND_ALT]; } // Tree alts if (GetTileIndex(map, wallLayer, x, y) == TREE) { //if (rand.Next(10) == 0) //{ // Big tree if(!TryDrawBigTree(map, wallLayer, x, y)) wallLayer.Tiles[x, y] = map.Tiles[TREES[rand.Next(TREES.Length)]]; } } } PercentComplete = 90; Rectangle spawnRect = new Rectangle((map.Width / 2) - 5, (map.Height / 2) - 5, 10, 10); bool foundspawn = false; while (!foundspawn) { map.HeroSpawn = TryFindSpawn(spawnRect.Left, spawnRect.Top, map, terrainLayer, out foundspawn); if (!foundspawn) map.HeroSpawn = TryFindSpawn(spawnRect.Right, spawnRect.Top, map, terrainLayer, out foundspawn); if (!foundspawn) map.HeroSpawn = TryFindSpawn(spawnRect.Left, spawnRect.Bottom, map, terrainLayer, out foundspawn); if (!foundspawn) map.HeroSpawn = TryFindSpawn(spawnRect.Right, spawnRect.Bottom, map, terrainLayer, out foundspawn); spawnRect.Inflate(5, 5); } map.GetAStarData(); map.Compounds = compounds; PercentComplete = 100; //Generating = false; }