/// <summary> /// Choses which terrain generator to use for a single chunk. /// </summary> /// <returns></returns> private int ChooseTerrainGenerator(int[,] terrainMap, WeightedRandom randomTerrainGenerators, int x, int y, Random seededRandom) { //<terrainGenerator, weight> List <ValueTuple <int, int> > neighborGeneratorWeights = new List <(int, int)>(); //The total weight of neighboring terrain generators. int totalWeight = 0; if (terrainMap[x, y] != -1) { int index = neighborGeneratorWeights.FindIndex(a => a.Item1 == terrainMap[x, y]); if (index == -1) { neighborGeneratorWeights.Add((terrainMap[x, y], 1)); } else { neighborGeneratorWeights[index] = (neighborGeneratorWeights[index].Item1, neighborGeneratorWeights[index].Item2 + 1); } totalWeight += CoreSettingsHandler.GenerationSettings.Settings.NeighborWeight; } List <int> weights = new List <int>(); foreach ((int, int)item in neighborGeneratorWeights) { int weightToAdd = item.Item2 * CoreSettingsHandler.GenerationSettings.Settings.NeighborWeight; weights.Add(weightToAdd); } if (totalWeight < 100) { //Add the chance for a new terrain generator to be used, not a neighboring one weights.Add(100 - totalWeight); } WeightedRandom neighborWeightedRandom = new WeightedRandom(weights, seededRandom); int terrainGeneratorIndex = neighborWeightedRandom.GetNext(); if (terrainGeneratorIndex == weights.Count - 1) { //Use new terrain generator, return(randomTerrainGenerators.GetNext()); } else { //Use the chosen terrain generator. return(neighborGeneratorWeights[terrainGeneratorIndex].Item1); } }