示例#1
0
        public void DistributeYieldAndResources(HomelandData homelandData, IMapTemplate mapTemplate)
        {
            LuxuryDistributor.DistributeLuxuriesAcrossHomeland(homelandData);
            StrategicDistributor.DistributeStrategicsAcrossHomeland(homelandData);

            HomelandBalancer.BalanceHomelandYields(homelandData);
        }
        private void DrawForbiddenLine(
            HashSet <MapSection> unassignedSections, HashSet <MapSection> forbiddenSections,
            GridPartition partition, IMapTemplate mapTemplate
            )
        {
            int lineXCoord = Mathf.RoundToInt(Grid.CellCountX * UnityEngine.Random.Range(
                                                  mapTemplate.ContinentSeparationLineXMin, mapTemplate.ContinentSeparationLineXMax
                                                  ));

            IHexCell startCell = Grid.GetCellAtCoordinates(HexCoordinates.FromOffsetCoordinates(lineXCoord, 0));
            IHexCell endCell   = Grid.GetCellAtCoordinates(HexCoordinates.FromOffsetCoordinates(lineXCoord, Grid.CellCountZ - 1));

            var cellLine = Grid.GetCellsInLine(startCell, endCell);

            var sectionsOnLine = cellLine.Select(cell => partition.GetSectionOfCell(cell)).Distinct();

            var sectionsToForbid = sectionsOnLine.SelectMany(section => partition.GetNeighbors(section))
                                   .Concat(sectionsOnLine).Distinct();

            foreach (var section in sectionsToForbid)
            {
                unassignedSections.Remove(section);
                forbiddenSections.Add(section);
            }
        }
示例#3
0
        public void GenerateTopologyAndEcology(HomelandData homelandData, IMapTemplate mapTemplate)
        {
            var regions = homelandData.OtherRegions.ToList();

            regions.Add(homelandData.StartingRegion);

            int riveredCells = 0;

            foreach (var region in regions)
            {
                var regionData = homelandData.GetDataOfRegion(region);

                RegionGenerator.GenerateTopology(region, regionData.Topology);
                RegionGenerator.PaintTerrain(region, regionData.Biome);

                riveredCells += Mathf.CeilToInt(region.LandCells.Count * regionData.Biome.RiverPercentage * 0.01f);
            }

            var allLandCells  = regions.SelectMany(region => region.LandCells);
            var allWaterCells = regions.SelectMany(region => region.WaterCells);

            RiverGenerator.CreateRivers(allLandCells, allWaterCells, riveredCells);

            RegionGenerator.AssignFloodPlains(allLandCells);

            foreach (var region in regions)
            {
                var regionData = homelandData.GetDataOfRegion(region);

                VegetationPainter.PaintVegetation(region, regionData.Biome);
            }
        }
 public void GenerateMap(IMapTemplate template, IMapGenerationVariables variables)
 {
     if (GenerateMapCoroutine == null)
     {
         GenerateMapCoroutine = CoroutineInvoker.StartCoroutine(GenerateMap_Perform(template, variables));
     }
 }
        private int GetBorderAvoidanceWeight(IHexCell cell, IMapTemplate template)
        {
            int distanceIntoBorderX = 0, distanceIntoBorderZ = 0;

            var xOffset = HexCoordinates.ToOffsetCoordinateX(cell.Coordinates);
            var zOffset = HexCoordinates.ToOffsetCoordinateZ(cell.Coordinates);

            if (xOffset < template.SoftMapBorderX)
            {
                distanceIntoBorderX = template.SoftMapBorderX - xOffset;
            }
            else if (Grid.CellCountX - xOffset < template.SoftMapBorderX)
            {
                distanceIntoBorderX = template.SoftMapBorderX - (Grid.CellCountX - xOffset);
            }

            if (zOffset < template.SoftMapBorderZ)
            {
                distanceIntoBorderZ = template.SoftMapBorderZ - zOffset;
            }
            else if (Grid.CellCountZ - zOffset < template.SoftMapBorderZ)
            {
                distanceIntoBorderZ = template.SoftMapBorderZ - (Grid.CellCountZ - zOffset);
            }

            return(-(distanceIntoBorderX + distanceIntoBorderZ) * template.SoftBorderAvoidanceWeight);
        }
        private ExpansionWeightFunction GetExpansionWeightFunction(
            GridPartition partition, IMapTemplate template
            )
        {
            var middleCell = Grid.GetCellAtOffset(Grid.CellCountX / 2, Grid.CellCountZ / 2);

            return(delegate(MapSection section, List <MapSection> chunk) {
                if (IsWithinHardBorder(section.CentroidCell, template))
                {
                    return 0;
                }

                int borderAvoidanceWeight = GetBorderAvoidanceWeight(section.CentroidCell, template);

                int neighborsInContinent = partition.GetNeighbors(section).Intersect(chunk).Count();
                int neighborsInContinentWeight = neighborsInContinent * template.NeighborsInContinentWeight;

                int distanceFromSeedCentroid = Grid.GetDistance(chunk[0].CentroidCell, section.CentroidCell);
                int distanceFromSeedCentroidWeight = distanceFromSeedCentroid * template.DistanceFromSeedCentroidWeight;

                int distanceFromMapCenter = Grid.GetDistance(section.CentroidCell, middleCell) * template.DistanceFromMapCenterWeight;

                int weight = 1 + Math.Max(
                    0, neighborsInContinentWeight + distanceFromSeedCentroidWeight + borderAvoidanceWeight + distanceFromMapCenter
                    );

                return weight;
            });
        }
        private void PaintMap(
            OceanAndContinentData oceansAndContinents, IMapTemplate mapTemplate
            )
        {
            var nonBarbarianCivs = CivFactory.AllCivilizations.Where(civ => !civ.Template.IsBarbaric).ToList();

            foreach (var civ in nonBarbarianCivs)
            {
                var homeland = oceansAndContinents.HomelandDataForCiv[civ];

                HomelandGenerator.GenerateTopologyAndEcology(homeland, mapTemplate);
            }

            OceanGenerator.GenerateTopologyAndEcology(oceansAndContinents.OceanData);

            WaterRationalizer.RationalizeWater(Grid.Cells);

            foreach (var civ in nonBarbarianCivs)
            {
                var homeland = oceansAndContinents.HomelandDataForCiv[civ];

                HomelandGenerator.DistributeYieldAndResources(homeland, mapTemplate);
            }

            OceanGenerator.DistributeYieldAndResources(oceansAndContinents.OceanData);
        }
示例#8
0
        public OceanData GetOceanData(
            IEnumerable <MapSection> oceanSections, IOceanTemplate oceanTemplate,
            IMapTemplate mapTemplate, GridPartition partition
            )
        {
            var shallowOceanSections = oceanSections.Where(
                section => partition.GetNeighbors(section).Any(neighbor => !oceanSections.Contains(neighbor))
                ).ToList();

            var midOceanSections = oceanSections.Except(shallowOceanSections).Where(
                section => partition.GetNeighbors(section).Any(neighbor => shallowOceanSections.Contains(neighbor))
                ).ToList();

            var deepOceanSections = oceanSections.Except(shallowOceanSections).Except(midOceanSections);

            List <MapRegion>  emptyOceanRegions;
            List <MapRegion>  archipelagoRegions;
            List <RegionData> archipelagoRegionData;

            CarveArchipelagoesFromOcean(
                shallowOceanSections, midOceanSections, deepOceanSections, oceanTemplate, partition,
                mapTemplate, out emptyOceanRegions, out archipelagoRegions, out archipelagoRegionData
                );

            return(new OceanData(emptyOceanRegions, archipelagoRegions, archipelagoRegionData));
        }
        private bool IsWithinSoftBorder(IHexCell cell, IMapTemplate template)
        {
            var xOffset = HexCoordinates.ToOffsetCoordinateX(cell.Coordinates);
            var zOffset = HexCoordinates.ToOffsetCoordinateZ(cell.Coordinates);

            return(xOffset <= template.SoftMapBorderX || Grid.CellCountX - xOffset <= template.SoftMapBorderX ||
                   zOffset <= template.SoftMapBorderZ || Grid.CellCountZ - zOffset <= template.SoftMapBorderZ);
        }
        public void Reset(IMapTemplate newTemplate)
        {
            TemperatureOfCell.Clear();
            PrecipitationOfCell.Clear();

            HasSetSampleRegion = false;

            PrecipitationTexture = newTemplate.PrecipitationTexture;
        }
        public IRegionBiomeTemplate GetBiomeForLandRegion(MapRegion landRegion, IMapTemplate mapTemplate)
        {
            float regionTemperature   = GetRegionTemperature(landRegion);
            float regionPrecipitation = GetRegionPrecipitation(landRegion);


            var templatesByPriority = new List <IRegionBiomeTemplate>(mapTemplate.RegionBiomes);
            var templatePriority    = new Dictionary <IRegionBiomeTemplate, float>();

            foreach (var regionTemplate in templatesByPriority)
            {
                templatePriority[regionTemplate] = GetBiomePriority(regionTemplate, regionTemperature, regionPrecipitation);
            }

            templatesByPriority.Sort((a, b) => templatePriority[a].CompareTo(templatePriority[b]));

            return(templatesByPriority.First());
        }
示例#12
0
        private OceanAndContinentData GenerateOceansAndContinents(IMapTemplate mapTemplate, IMapGenerationVariables variables)
        {
            var nonBarbarianCivs = CivFactory.AllCivilizations.Where(civ => !civ.Template.IsBarbaric).ToList();

            var partition = GridPartitionLogic.GetPartitionOfGrid(Grid, mapTemplate);

            int totalLandCells  = Mathf.RoundToInt(Grid.Cells.Count * variables.ContinentalLandPercentage * 0.01f);
            int landCellsPerCiv = Mathf.RoundToInt((float)totalLandCells / nonBarbarianCivs.Count);

            HashSet <MapSection> unassignedSections = new HashSet <MapSection>(partition.Sections);

            List <List <MapSection> > homelandChunks = SubdivisionLogic.DivideSectionsIntoChunks(
                unassignedSections, partition, nonBarbarianCivs.Count,
                landCellsPerCiv, mapTemplate.MinStartingLocationDistance,
                GetExpansionWeightFunction(partition, mapTemplate), mapTemplate
                );

            var homelandOfCivs = new Dictionary <ICivilization, HomelandData>();

            for (int i = 0; i < nonBarbarianCivs.Count; i++)
            {
                var civ = nonBarbarianCivs[i];

                var landSections  = homelandChunks[i];
                var waterSections = GetCoastForLandSection(landSections, unassignedSections, partition);

                var homelandTemplate = TemplateSelectionLogic.GetHomelandTemplateForCiv(civ, mapTemplate);

                homelandOfCivs[civ] = HomelandGenerator.GetHomelandData(
                    civ, landSections, waterSections, partition, homelandTemplate, mapTemplate
                    );
            }

            var oceanTemplate = mapTemplate.OceanTemplates.Random();

            var oceanData = OceanGenerator.GetOceanData(unassignedSections, oceanTemplate, mapTemplate, partition);

            return(new OceanAndContinentData()
            {
                HomelandDataForCiv = homelandOfCivs,
                OceanData = oceanData
            });
        }
示例#13
0
        private IEnumerator GenerateMap_Perform(IMapTemplate template, IMapGenerationVariables variables)
        {
            MapComposer.ClearRuntime(false);

            while (MapComposer.IsProcessing)
            {
                yield return(new WaitForEndOfFrame());
            }

            Profiler.BeginSample("GenerateMap()");

            CellClimateLogic.Reset(template);

            var oldRandomState = SetRandomState();

            Grid.Build(variables.CellCountX, variables.CellCountZ);

            GeneratePlayers(variables);

            var oceansAndContinents = GenerateOceansAndContinents(template, variables);

            PaintMap(oceansAndContinents, template);

            foreach (var civ in oceansAndContinents.HomelandDataForCiv.Keys)
            {
                var civHomeland = oceansAndContinents.HomelandDataForCiv[civ];

                StartingUnitPlacementLogic.PlaceStartingUnitsInRegion(
                    civHomeland.StartingRegion, civ, template
                    );
            }

            UnityEngine.Random.state = oldRandomState;

            GenerateMapCoroutine = null;

            foreach (var chunk in Grid.Chunks)
            {
                chunk.Refresh(MapRendering.TerrainRefreshType.All);
            }

            Profiler.EndSample();
        }
示例#14
0
        private Func <MapSection, int> GetArchipelagoWeightFunction(IMapTemplate template)
        {
            return(delegate(MapSection section) {
                int centroidCellX = HexCoordinates.ToOffsetCoordinateX(section.CentroidCell.Coordinates);
                int centroidCellZ = HexCoordinates.ToOffsetCoordinateZ(section.CentroidCell.Coordinates);

                if (centroidCellX < template.HardMapBorderX ||
                    Grid.CellCountX - centroidCellX < template.HardMapBorderX ||
                    centroidCellZ < template.HardMapBorderZ ||
                    Grid.CellCountZ - centroidCellZ < template.HardMapBorderZ
                    )
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            });
        }
示例#15
0
        public void PlaceStartingUnitsInRegion(
            MapRegion region, ICivilization owner, IMapTemplate mapTemplate
            )
        {
            if (owner.Template.IsBarbaric)
            {
                return;
            }

            var centralLocation = GetBestStartingCell(region);

            if (centralLocation == null)
            {
                throw new InvalidOperationException("Failed to find an appropriate central location");
            }

            UnitFactory.BuildUnit(centralLocation, mapTemplate.StartingUnits[0], owner);

            for (int i = 1; i < mapTemplate.StartingUnits.Count; i++)
            {
                var unitTemplate = mapTemplate.StartingUnits[i];

                var location = Grid.GetCellsInRadius(centralLocation, 2).Where(
                    cell => !UnitPositionCanon.GetPossessionsOfOwner(cell).Any() &&
                    UnitFactory.CanBuildUnit(cell, unitTemplate, owner) &&
                    cell != null
                    ).FirstOrDefault();

                if (location == null)
                {
                    throw new InvalidOperationException(
                              string.Format("Failed to place starting unit {0} for civ {1}", unitTemplate, owner)
                              );
                }
                else
                {
                    UnitFactory.BuildUnit(location, unitTemplate, owner);
                }
            }
        }
示例#16
0
        private void CarveArchipelagoesFromOcean(
            IEnumerable <MapSection> shallowOceanSections, List <MapSection> midOceanSections,
            IEnumerable <MapSection> deepOceanSections, IOceanTemplate oceanTemplate, GridPartition partition,
            IMapTemplate mapTemplate, out List <MapRegion> emptyOceanRegions,
            out List <MapRegion> archipelagoRegions, out List <RegionData> archipelagoRegionData
            )
        {
            int landSectionCount = Mathf.RoundToInt(oceanTemplate.DeepOceanLandPercentage * 0.01f * deepOceanSections.Count());

            var deepOceanLand = MapSectionRandomSampler.SampleElementsFromSet(
                deepOceanSections, landSectionCount, GetArchipelagoWeightFunction(mapTemplate)
                ).ToList();

            var deepOceanWater = deepOceanSections.Except(deepOceanLand).ToList();

            List <MapSection> emptyDeepOcean;

            GetArchipelagoesFromLandAndWater(
                deepOceanLand, deepOceanWater, midOceanSections, oceanTemplate,
                partition, out archipelagoRegions, out emptyDeepOcean
                );

            var emptyOceanCells = shallowOceanSections.Concat(midOceanSections).Concat(emptyDeepOcean);

            var emptyOcean = new MapRegion(
                new List <IHexCell>(),
                emptyOceanCells.SelectMany(section => section.Cells).ToList()
                );

            emptyOceanRegions = new List <MapRegion>()
            {
                emptyOcean
            };

            archipelagoRegionData = archipelagoRegions.Select(region => new RegionData(
                                                                  TemplateSelectionLogic.GetBiomeForLandRegion(region, mapTemplate),
                                                                  TemplateSelectionLogic.GetTopologyForLandRegion(region, mapTemplate),
                                                                  AvailableBalanceStrategies
                                                                  )).ToList();
        }
        private MapSection GetStartingSection(
            HashSet <MapSection> unassignedSections, IEnumerable <MapSection> startingSections,
            int minSeparation, IMapTemplate mapTemplate
            )
        {
            var candidates = new List <MapSection>();

            foreach (var unassignedSection in unassignedSections)
            {
                if (unassignedSection.Cells.Count == 0 || IsWithinSoftBorder(unassignedSection.CentroidCell, mapTemplate))
                {
                    continue;
                }

                bool unassignedIsValid = true;
                foreach (var startingSection in startingSections)
                {
                    if (Grid.GetDistance(unassignedSection.CentroidCell, startingSection.CentroidCell) < minSeparation)
                    {
                        unassignedIsValid = false;
                        break;
                    }
                }

                if (unassignedIsValid)
                {
                    candidates.Add(unassignedSection);
                }
            }

            if (candidates.Count == 0)
            {
                throw new InvalidOperationException("Failed to acquire a valid starting location");
            }
            else
            {
                return(candidates.Random());
            }
        }
示例#18
0
        public HomelandData GetHomelandData(
            ICivilization civ, List <MapSection> landSections, List <MapSection> waterSections,
            GridPartition partition, IHomelandTemplate homelandTemplate, IMapTemplate mapTemplate
            )
        {
            var landChunks  = new List <List <MapSection> >();
            var waterChunks = new List <List <MapSection> >();

            IHexCell seedCentroid = landSections[0].CentroidCell;

            var startingLandSections =
                Grid.GetCellsInRadius(seedCentroid, homelandTemplate.StartingRegionRadius)
                .Select(cell => partition.GetSectionOfCell(cell))
                .Distinct()
                .Intersect(landSections);

            var startingWaterSections =
                Grid.GetCellsInRadius(seedCentroid, homelandTemplate.StartingRegionRadius)
                .Select(cell => partition.GetSectionOfCell(cell))
                .Distinct()
                .Intersect(waterSections);

            var startingRegion = new MapRegion(
                startingLandSections.SelectMany(section => section.Cells).ToList(),
                startingWaterSections.SelectMany(section => section.Cells).ToList()
                );

            foreach (var cell in startingRegion.Cells)
            {
                cell.SetMapData(1f);
            }

            var unassignedLand  = landSections.Except(startingLandSections);
            var unassignedWater = waterSections.Except(startingWaterSections);

            DivideSectionsIntoRectangularChunks(
                unassignedLand, unassignedWater, homelandTemplate.RegionCount,
                out landChunks, out waterChunks
                );

            var regions = new List <MapRegion>();

            regions.Add(startingRegion);

            for (int i = 0; i < landChunks.Count; i++)
            {
                var region = new MapRegion(
                    landChunks [i].SelectMany(section => section.Cells).ToList(),
                    waterChunks[i].SelectMany(section => section.Cells).ToList()
                    );

                regions.Add(region);
            }

            var startingData = new RegionData(
                TemplateSelectionLogic.GetBiomeForLandRegion(startingRegion, mapTemplate),
                TemplateSelectionLogic.GetTopologyForLandRegion(startingRegion, mapTemplate),
                AvailableBalanceStrategies
                );

            var otherRegions = regions.Where(region => region != startingRegion).ToList();

            var otherData = otherRegions.Select(region => new RegionData(
                                                    TemplateSelectionLogic.GetBiomeForLandRegion(region, mapTemplate),
                                                    TemplateSelectionLogic.GetTopologyForLandRegion(region, mapTemplate),
                                                    AvailableBalanceStrategies
                                                    )).ToList();

            return(new HomelandData(
                       startingRegion, startingData, otherRegions, otherData,
                       homelandTemplate.LuxuryResourceData, homelandTemplate.YieldAndResources
                       ));
        }
        public List <List <MapSection> > DivideSectionsIntoChunks(
            HashSet <MapSection> unassignedSections, GridPartition partition,
            int chunkCount, int maxCellsPerChunk, int minSeedSeparation,
            ExpansionWeightFunction weightFunction, IMapTemplate mapTemplate
            )
        {
            if (chunkCount > unassignedSections.Count())
            {
                throw new ArgumentOutOfRangeException("Not enough sections to assign at least one per chunk");
            }

            var finishedChunks   = new List <List <MapSection> >();
            var unfinishedChunks = new List <List <MapSection> >();

            var startingSections  = new List <MapSection>();
            var forbiddenSections = new HashSet <MapSection>();

            if (mapTemplate.SeparateContinents)
            {
                DrawForbiddenLine(unassignedSections, forbiddenSections, partition, mapTemplate);
            }

            for (int i = 0; i < chunkCount; i++)
            {
                var startingSection = GetStartingSection(
                    unassignedSections, startingSections, minSeedSeparation, mapTemplate
                    );

                unfinishedChunks.Add(new List <MapSection>()
                {
                    startingSection
                });

                startingSections.Add(startingSection);

                unassignedSections.Remove(startingSection);
            }

            int desiredContiguousCells = Mathf.RoundToInt(maxCellsPerChunk * mapTemplate.HomelandContiguousPercentage * 0.01f);

            while (unfinishedChunks.Count > 0 && unassignedSections.Count > 0)
            {
                var chunk = unfinishedChunks.Random();

                int cellCount = chunk.Sum(section => section.Cells.Count);

                bool mustBeContiguous = desiredContiguousCells > cellCount;

                if (TryExpandChunk(chunk, unassignedSections, partition, mapTemplate, weightFunction, mustBeContiguous))
                {
                    int cellsInChunk = chunk.Sum(section => section.Cells.Count);

                    if (cellsInChunk >= maxCellsPerChunk)
                    {
                        finishedChunks.Add(chunk);
                        unfinishedChunks.Remove(chunk);
                    }
                }
                else
                {
                    Debug.LogWarning("Failed to assign a new section to a chunk");
                    finishedChunks.Add(chunk);
                    unfinishedChunks.Remove(chunk);
                }
            }

            finishedChunks.AddRange(unfinishedChunks);

            foreach (var section in forbiddenSections)
            {
                unassignedSections.Add(section);
            }

            return(finishedChunks);
        }
 public IRegionTopologyTemplate GetTopologyForLandRegion(MapRegion region, IMapTemplate mapTemplate)
 {
     return(mapTemplate.RegionTopologies.Random());
 }
        private bool TryExpandChunk(
            List <MapSection> chunk, HashSet <MapSection> unassignedSections,
            GridPartition partition, IMapTemplate mapTemplate,
            ExpansionWeightFunction weightFunction, bool mustBeContiguous
            )
        {
            expansionCandidates.Clear();

            foreach (MapSection section in chunk)
            {
                nearbySections.Clear();

                sectionsWithinDistance.Clear();

                if (mustBeContiguous)
                {
                    foreach (var adjacentSection in partition.GetNeighbors(section))
                    {
                        if (unassignedSections.Contains(adjacentSection))
                        {
                            nearbySections.Add(adjacentSection);
                        }
                    }
                }
                else
                {
                    foreach (IHexCell nearbyCell in Grid.GetCellsInRadius(section.CentroidCell, mapTemplate.HomelandExpansionMaxCentroidSeparation))
                    {
                        MapSection sectionOfCell = partition.GetSectionOfCell(nearbyCell);

                        if (unassignedSections.Contains(sectionOfCell))
                        {
                            sectionsWithinDistance.Add(sectionOfCell);
                        }
                    }

                    var sectionsSurroundedByUnassigned = sectionsWithinDistance.Where(
                        nearby => partition.GetNeighbors(nearby).Count(neighbor => !unassignedSections.Contains(neighbor)) <= 0
                        );

                    if (sectionsSurroundedByUnassigned.Any())
                    {
                        foreach (var surroundedSection in sectionsSurroundedByUnassigned)
                        {
                            nearbySections.Add(surroundedSection);
                        }
                    }
                    else
                    {
                        foreach (var sectionWithin in sectionsWithinDistance)
                        {
                            nearbySections.Add(sectionWithin);
                        }
                    }
                }

                foreach (var nearby in nearbySections)
                {
                    expansionCandidates.Add(nearby);
                }
            }

            if (expansionCandidates.Count > 0)
            {
                var newSection = MapSectionRandomSampler.SampleElementsFromSet(
                    expansionCandidates, 1, section => weightFunction(section, chunk)
                    ).FirstOrDefault();

                if (newSection != null)
                {
                    unassignedSections.Remove(newSection);
                    chunk.Add(newSection);
                    return(true);
                }
            }

            return(false);
        }
 public IHomelandTemplate GetHomelandTemplateForCiv(ICivilization civ, IMapTemplate mapTemplate)
 {
     return(mapTemplate.HomelandTemplates.Random());
 }
        //Creates something akin to a Voronoi diagram of the cells,
        //using a process similiar to Lloyd's algorithm to make the
        //shapes more regular
        public GridPartition GetPartitionOfGrid(IHexGrid grid, IMapTemplate template)
        {
            float xMin = 0f, zMin = 0f;
            float xMax = (grid.CellCountX + grid.CellCountZ * 0.5f - grid.CellCountZ / 2) * RenderConfig.InnerRadius * 2f;
            float zMax = grid.CellCountZ * RenderConfig.OuterRadius * 1.5f;

            var randomPoints = new List <Vector3>();

            var regionOfPoint = new Dictionary <Vector3, MapSection>();

            for (int i = 0; i < template.VoronoiPointCount; i++)
            {
                var randomPoint = new Vector3(
                    UnityEngine.Random.Range(xMin, xMax),
                    0f,
                    UnityEngine.Random.Range(zMin, zMax)
                    );

                regionOfPoint[randomPoint] = new MapSection(grid);

                randomPoints.Add(randomPoint);
            }

            int iterationsLeft = template.VoronoiPartitionIterations;

            while (iterationsLeft > 0)
            {
                foreach (var cell in grid.Cells)
                {
                    Vector3 nearestPoint    = Vector3.zero;
                    float   shorestDistance = float.MaxValue;

                    foreach (var voronoiPoint in regionOfPoint.Keys)
                    {
                        float distanceTo = Vector3.Distance(cell.GridRelativePosition, voronoiPoint);

                        if (distanceTo < shorestDistance)
                        {
                            nearestPoint    = voronoiPoint;
                            shorestDistance = distanceTo;
                        }
                    }

                    if (regionOfPoint.ContainsKey(nearestPoint))
                    {
                        regionOfPoint[nearestPoint].AddCell(cell);
                    }
                }

                if (--iterationsLeft > 0)
                {
                    randomPoints.Clear();

                    var newRegionOfPoints = new Dictionary <Vector3, MapSection>();
                    foreach (var region in regionOfPoint.Values)
                    {
                        if (region.Cells.Count > 0)
                        {
                            randomPoints.Add(region.Centroid);

                            newRegionOfPoints[region.Centroid] = new MapSection(grid);
                        }
                    }

                    regionOfPoint = newRegionOfPoints;
                }
            }

            return(new GridPartition(regionOfPoint.Values, grid));
        }
示例#24
0
 public void UpdateSelectedMapTemplate(int optionIndex)
 {
     SelectedMapTemplate = MapTemplates.Where(
         template => template.name.Equals(MapTypeDropdown.options[optionIndex].text)
         ).FirstOrDefault();
 }