private int RiverStartWeightFunction(IHexCell cell) { int nearbyDesert = Grid.GetCellsInRadius(cell, 1).Count(nearby => nearby.Terrain == CellTerrain.Desert); int nearbyArctic = Grid.GetCellsInRadius(cell, 1).Count(nearby => nearby.Terrain.IsArctic()); return(1 + nearbyDesert * Config.RiverEndpointOnDesertWeight + nearbyArctic * Config.RiverEndpointOnArcticWeight); }
public float GetUtilityForUnit(IUnit unit, InfluenceMaps maps) { if (!unit.CanAttack) { return(0f); } IEnumerable <IHexCell> attackCandidates = null; if (unit.RangedAttackStrength > 0) { var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit); attackCandidates = Grid.GetCellsInRadius(unitLocation, unit.AttackRange) .Where(FilterLogic.GetRangedAttackFilter(unit)); } else { attackCandidates = UnitVisibilityLogic.GetCellsVisibleToUnit(unit) .Where(FilterLogic.GetMeleeAttackFilter(unit)); } if (attackCandidates.Any()) { return(attackCandidates.Max(UtilityLogic.GetAttackUtilityFunction(unit, maps))); } else { return(0f); } }
public float GetUtilityForUnit(IUnit unit, InfluenceMaps maps) { var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit); return(Grid.GetCellsInRadius(unitLocation, Mathf.RoundToInt(unit.MaxMovement)).Max( UtilityLogic.GetPillageUtilityFunction(unit, maps) )); }
private void OnCityPossessionChanged(Tuple <ICivilization, ICity> data) { var affectedChunks = CellPossessionCanon.GetPossessionsOfOwner(data.Item2) .SelectMany(cell => Grid.GetCellsInRadius(cell, 1)) .SelectMany(cell => cell.OverlappingChunks) .Distinct(); foreach (var chunk in affectedChunks) { chunk.Refresh(TerrainRefreshType.Culture); } }
private void EditCells(IHexCell center) { foreach (var cell in Grid.GetCellsInRadius(center, BrushSize)) { EditCell(cell); } }
private void AssignLandOrphans( MapRegion region, IRegionBiomeTemplate template, HashSet <IHexCell> unassignedLandCells ) { foreach (var orphan in unassignedLandCells.ToArray()) { var adjacentLandTerrains = Grid.GetCellsInRadius(orphan, 3) .Except(unassignedLandCells) .Intersect(region.LandCells) .Select(neighbor => neighbor.Terrain) .Where(terrain => !terrain.IsWater() && ModLogic.CanChangeTerrainOfCell(orphan, terrain)); if (adjacentLandTerrains.Any()) { var newTerrain = adjacentLandTerrains.Random(); ModLogic.ChangeTerrainOfCell(orphan, newTerrain); unassignedLandCells.Remove(orphan); } else { Debug.LogWarning("Could not find a valid terrain for an orphaned cell"); } } }
public UnitSpawnInfo TryGetValidSpawn( IEncampment encampment, Func <IHexCell, IEnumerable <IUnitTemplate> > unitSelector ) { var encampmentLocation = EncampmentLocationCanon.GetOwnerOfPossession(encampment); foreach (var cell in Grid.GetCellsInRadius(encampmentLocation, 1, true)) { var availableUnits = unitSelector(cell); if (availableUnits.Any()) { return(new UnitSpawnInfo() { IsValidSpawn = true, LocationOfUnit = cell, TemplateToBuild = Randomizer.TakeRandom(availableUnits) }); } } return(new UnitSpawnInfo() { IsValidSpawn = false, LocationOfUnit = null, TemplateToBuild = null }); }
public void PerformDamageOnUnitFromImprovements(IUnit unit) { var unitOwner = UnitPossessionCanon.GetOwnerOfPossession(unit); var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit); float highestDamage = 0f; foreach (var nearbyCell in Grid.GetCellsInRadius(unitLocation, 1)) { var ownerOfCell = CivTerritoryLogic.GetCivClaimingCell(nearbyCell); if (ownerOfCell == null || !WarCanon.AreAtWar(unitOwner, ownerOfCell)) { continue; } foreach (var improvement in ImprovementLocationCanon.GetPossessionsOfOwner(nearbyCell)) { highestDamage = Mathf.Max(highestDamage, improvement.Template.AdjacentEnemyDamagePercentage); } } if (highestDamage > 0f) { unit.CurrentHitpoints -= Mathf.RoundToInt(unit.MaxHitpoints * highestDamage); } }
public float GetUtilityForUnit(IUnit unit, InfluenceMaps maps) { var unitPosition = UnitPositionCanon.GetOwnerOfPossession(unit); if (EncampmentLocationCanon.GetPossessionsOfOwner(unitPosition).Any()) { return(BarbarianConfig.StayInEncampmentUtility); } else if (Grid.GetCellsInRadius(unitPosition, BarbarianConfig.DefendEncampmentRadius).Any(HasUndefendedEncampment)) { return(BarbarianConfig.HeadTowardsEncampmentUtility); } else { return(0f); } }
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); } } }
public bool TryIncreaseYield( MapRegion region, RegionData regionData, YieldType type, out YieldSummary yieldAdded ) { if (type != YieldType.Food) { yieldAdded = YieldSummary.Empty; return(false); } var candidates = region.Cells.Where(GetLakeCandidateFilter(region)); if (candidates.Any()) { var newLake = candidates.Random(); var oldYields = new Dictionary <IHexCell, YieldSummary>(); foreach (var cell in Grid.GetCellsInRadius(newLake, 1)) { oldYields[cell] = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs); } ModLogic.ChangeTerrainOfCell(newLake, CellTerrain.FreshWater); yieldAdded = YieldSummary.Empty; foreach (var cell in oldYields.Keys) { yieldAdded += YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs) - oldYields[cell]; } return(true); } else { yieldAdded = YieldSummary.Empty; return(false); } }
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); }
private bool HasRangedAttackTarget() { var cityLocation = CityLocationCanon.GetOwnerOfPossession(ObjectToDisplay); foreach (var cell in Grid.GetCellsInRadius(cityLocation, Config.CityAttackRange)) { foreach (var unit in UnitPositionCanon.GetPossessionsOfOwner(cell)) { if (CombatExecuter.CanPerformRangedAttack(ObjectToDisplay.CombatFacade, unit)) { return(true); } } } return(false); }
private IEnumerable <IUnit> GetNearbyAllies(IUnit unit, int maxRange) { var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit); var unitOwner = UnitPossessionCanon.GetOwnerOfPossession(unit); var retval = new List <IUnit>(); if (unitLocation != null && unitOwner != null) { var cellsInRange = Grid.GetCellsInRadius(unitLocation, maxRange); foreach (var nearbyUnit in cellsInRange.SelectMany(cell => UnitPositionCanon.GetPossessionsOfOwner(cell))) { if (UnitPossessionCanon.GetOwnerOfPossession(nearbyUnit) == unitOwner) { retval.Add(nearbyUnit); } } } return(retval); }
public void HandleCommandOnUnit(AbilityCommandRequest command, IUnit unit) { if (CanHandleCommandOnUnit(command, unit)) { var unitPosition = UnitPositionCanon.GetOwnerOfPossession(unit); var unitOwner = UnitPossessionCanon.GetOwnerOfPossession(unit); var nearbyCells = Grid.GetCellsInRadius(unitPosition, 1); foreach (var nearbyUnit in nearbyCells.SelectMany(cell => UnitPositionCanon.GetPossessionsOfOwner(cell))) { var nearbyOwner = UnitPossessionCanon.GetOwnerOfPossession(nearbyUnit); if (nearbyUnit.Type.IsWaterMilitary() && nearbyOwner == unitOwner) { nearbyUnit.CurrentHitpoints = nearbyUnit.MaxHitpoints; } } } else { throw new InvalidOperationException("Cannot handle command"); } }
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); }
public IEnumerable <IHexCell> GetCellsVisibleToUnit(IUnit unit) { var retval = new List <IHexCell>(); var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit); foreach (var cell in Grid.GetCellsInRadius(unitLocation, unit.VisionRange)) { if (!HasObstructionsBetween(unitLocation, cell)) { retval.Add(cell); } } foreach (var cell in Grid.GetCellsInRing(unitLocation, unit.VisionRange + 1)) { if (!HasObstructionsBetween(unitLocation, cell) && cell.Terrain.IsWater()) { retval.Add(cell); } } return(retval); }
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 )); }
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); }