public void GenerateTopology(MapRegion region, IRegionTopologyTemplate template) { var landCells = region.LandCells; int desiredMountainCount = Mathf.RoundToInt(template.MountainsPercentage * landCells.Count() * 0.01f); int desiredHillsCount = Mathf.RoundToInt(template.HillsPercentage * landCells.Count() * 0.01f); var elevatedCells = CellRandomSampler.SampleElementsFromSet( landCells, desiredHillsCount + desiredMountainCount, HillsStartingWeightFunction, HillsDynamicWeightFunction, cell => Grid.GetNeighbors(cell) ); foreach (var cell in elevatedCells) { ModLogic.ChangeShapeOfCell(cell, CellShape.Hills); } var mountainousCells = CellRandomSampler.SampleElementsFromSet( elevatedCells, desiredMountainCount, MountainWeightFunction ); foreach (var cell in mountainousCells) { ModLogic.ChangeShapeOfCell(cell, CellShape.Mountains); } }
private void DistributeLuxuryAcrossSingleRegion( MapRegion region, int nodeCount, List <IResourceDefinition> validLuxuries, Dictionary <IResourceDefinition, int> weightForResources, HashSet <IResourceDefinition> luxuriesAlreadyChosen ) { while (validLuxuries.Any()) { var candidate = ResourceRandomSampler.SampleElementsFromSet( validLuxuries, 1, luxury => weightForResources[luxury] ).FirstOrDefault(); validLuxuries.Remove(candidate); if (luxuriesAlreadyChosen.Contains(candidate)) { continue; } var validCells = region.Cells.Where( cell => ResourceRestrictionCanon.IsResourceValidOnCell(candidate, cell) ); if (validCells.Count() >= nodeCount) { DistributeResource(candidate, validCells, nodeCount); luxuriesAlreadyChosen.Add(candidate); return; } } Debug.LogWarning("Failed to perform luxury distribution on region"); }
private void DistributeResource( IResourceDefinition resource, IEnumerable <IHexCell> validLocations, int count ) { var nodeLocations = CellRandomSampler.SampleElementsFromSet( validLocations, count, GetResourceWeightFunction(resource) ); if (nodeLocations.Count < count) { Debug.LogWarningFormat( "Could not find enough valid locations to place {0} {1} after weighting. Only found {2}", count, resource.name, nodeLocations.Count ); } foreach (var location in nodeLocations) { int copies = resource.Type == ResourceType.Strategic ? UnityEngine.Random.Range(Config.MinStrategicCopies, Config.MaxStrategicCopies) : 1; NodeFactory.BuildNode(location, resource, copies); } }
public void PaintVegetation(MapRegion region, IRegionBiomeTemplate template) { var treeType = template.AreTreesJungle ? CellVegetation.Jungle : CellVegetation.Forest; var openCells = new List <IHexCell>(); foreach (var cell in region.LandCells) { if (ShouldBeMarsh(cell, template)) { ModLogic.ChangeVegetationOfCell(cell, CellVegetation.Marsh); } else if (ModLogic.CanChangeVegetationOfCell(cell, treeType)) { openCells.Add(cell); } } int treeCount = Mathf.RoundToInt(template.TreePercentage * openCells.Count * 0.01f); var treeSeeds = CellRandomSampler.SampleElementsFromSet( openCells, UnityEngine.Random.Range(template.MinTreeClumps, template.MaxTreeClumps), GetTreeSeedWeightFunction(treeType, template) ); var treeCells = new List <IHexCell>(); var treeCrawlers = treeSeeds.Select( seed => GridTraversalLogic.GetCrawlingEnumerator( seed, openCells, treeCells, GetTreeCrawlingCostFunction(treeType, template) ) ).ToList(); for (int i = 0; i < treeCount; i++) { if (treeCrawlers.Count == 0) { Debug.LogWarning("Failed to paint correct number of trees into region"); break; } var crawler = treeCrawlers.Random(); if (crawler.MoveNext()) { treeCells.Add(crawler.Current); openCells.Remove(crawler.Current); } else { treeCrawlers.Remove(crawler); i--; } } foreach (var treeCell in treeCells) { ModLogic.ChangeVegetationOfCell(treeCell, treeType); } }
public void DistributeStrategicsAcrossHomeland(HomelandData homelandData) { int nodesLeft = Mathf.CeilToInt(homelandData.YieldAndResources.StrategicNodesPerCell * homelandData.Cells.Count()); int copiesLeft = Mathf.CeilToInt(homelandData.YieldAndResources.StrategicCopiesPerCell * homelandData.Cells.Count()); var validStrategics = new List <IResourceDefinition>(StrategicResources); var resourceWeightsByRegion = new Dictionary <MapRegion, Dictionary <IResourceDefinition, int> >(); foreach (var region in homelandData.AllRegions) { resourceWeightsByRegion[region] = homelandData.GetDataOfRegion(region).GetResourceWeights(); } var regions = homelandData.AllRegions.ToList(); int iterations = regions.Count * 10; while (nodesLeft > 0 && copiesLeft > 0 && iterations-- > 0) { if (regions.Count == 0) { regions.AddRange(homelandData.AllRegions); } var region = regions.Random(); regions.Remove(region); var resourceWeights = resourceWeightsByRegion[region]; var strategic = ResourceRandomSampler.SampleElementsFromSet( validStrategics, 1, resource => resourceWeights.ContainsKey(resource) ? resourceWeights[resource] : 0 ).FirstOrDefault(); if (strategic == null) { continue; } var location = CellRandomSampler.SampleElementsFromSet( region.Cells, 1, cell => ResourceRestrictionCanon.GetPlacementWeightOnCell(strategic, cell) ).FirstOrDefault(); if (location != null && NodeFactory.CanBuildNode(location, strategic)) { int copies = StrategicCopiesLogic.GetWeightedRandomCopies(); copies = Math.Min(copies, copiesLeft); NodeFactory.BuildNode(location, strategic, copies); nodesLeft--; copiesLeft -= copies; } } }
public bool TryIncreaseYield( MapRegion region, RegionData regionData, YieldType type, out YieldSummary yieldAdded ) { var availableResources = BonusResourcesWithYield[type].ToList(); while (availableResources.Count > 0) { var chosenResource = ResourceRandomSampler.SampleElementsFromSet( availableResources, 1, GetResourceSelectionWeightFunction(region, regionData) ).FirstOrDefault(); if (chosenResource == null) { break; } var cell = CellRandomSampler.SampleElementsFromSet( region.Cells, 1, GetCellPlacementWeightFunction(chosenResource) ).FirstOrDefault(); if (cell != null) { var oldYield = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs); int copies = chosenResource.Type == ResourceType.Strategic ? StrategicCopiesLogic.GetWeightedRandomCopies() : 0; ResourceNodeFactory.BuildNode(cell, chosenResource, copies); yieldAdded = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs) - oldYield; return(true); } else { availableResources.Remove(chosenResource); } } yieldAdded = YieldSummary.Empty; return(false); }
public void CreateRivers( IEnumerable <IHexCell> landCells, IEnumerable <IHexCell> waterCells, int desiredRiveredCells ) { var riveredCells = new HashSet <IHexCell>(); var riverStartCandidates = landCells.Where(GetRiverStartFilter(waterCells)).ToList(); HashSet <IHexCell> cellsAdjacentToNewRiver = new HashSet <IHexCell>(); int iterations = landCells.Count() * 10; while (riveredCells.Count < desiredRiveredCells && riverStartCandidates.Count > 0 && iterations-- > 0) { var start = CellRandomSampler.SampleElementsFromSet( riverStartCandidates, 1, RiverStartWeightFunction ).FirstOrDefault(); riverStartCandidates.Remove(start); if (TryBuildNewRiver( landCells, waterCells, start, desiredRiveredCells - riveredCells.Count, ref cellsAdjacentToNewRiver )) { foreach (var cell in cellsAdjacentToNewRiver) { riveredCells.Add(cell); riverStartCandidates.Remove(cell); foreach (var startingNeighbor in Grid.GetNeighbors(start)) { riverStartCandidates.Remove(startingNeighbor); } } } } }
public void TrySpawnEncampment(InfluenceMaps maps) { var validCells = Grid.Cells.Where(SpawningTools.EncampmentValidityFilter).ToList(); if (validCells.Any()) { var candidate = CellSampler.SampleElementsFromSet( validCells, 1, SpawningTools.BuildEncampmentWeightFunction(maps) ).FirstOrDefault(); if (candidate != null) { var newEncampment = EncampmentFactory.CreateEncampment(candidate); UnitSpawner.TrySpawnUnit(newEncampment); } } }
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(); }
public bool TryIncreaseYield( MapRegion region, RegionData regionData, YieldType type, out YieldSummary yieldAdded ) { yieldAdded = YieldSummary.Empty; if (type != YieldType.Food && type != YieldType.Gold) { return(false); } var newOasis = CellRandomSampler.SampleElementsFromSet( region.LandCells, 1, GetOasisCandidateWeightFunction(region) ).FirstOrDefault(); if (newOasis == null) { return(false); } var oldYields = new Dictionary <IHexCell, YieldSummary>(); foreach (var cell in Grid.GetCellsInRadius(newOasis, 1)) { oldYields[cell] = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs); } ModLogic.ChangeFeatureOfCell(newOasis, CellFeature.Oasis); yieldAdded = YieldSummary.Empty; foreach (var cell in oldYields.Keys) { yieldAdded += YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs) - oldYields[cell]; } return(true); }
public List <IUnitCommand> GetCommandsForUnit(IUnit unit, InfluenceMaps maps) { var retval = new List <IUnitCommand>(); var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit); var nearbyCells = Grid.GetCellsInRadius(unitLocation, Mathf.RoundToInt(unit.MaxMovement)); var bestCandidate = CellRandomSampler.SampleElementsFromSet( nearbyCells, 1, BrainTools.GetWanderWeightFunction(unit, maps) ).FirstOrDefault(); if (bestCandidate != null) { var moveCommand = Container.Instantiate <MoveUnitCommand>(); moveCommand.UnitToMove = unit; moveCommand.DesiredLocation = bestCandidate; retval.Add(moveCommand); } return(retval); }
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); }
private IBalanceStrategy GetStrategy(Dictionary <IBalanceStrategy, int> strategyWeights) { return(BalanceStrategySampler.SampleElementsFromSet( strategyWeights.Keys, 1, strategy => strategyWeights[strategy] ).FirstOrDefault()); }