private void TryRemoveImprovementsFrom(IHexCell location) { foreach (var improvement in new List <IImprovement>(ImprovementLocationCanon.GetPossessionsOfOwner(location))) { improvement.Destroy(); } }
public bool IsCellValidForCity(IHexCell cell) { if (CellPossessionCanon.GetOwnerOfPossession(cell) != null) { return(false); } if (cell.Terrain.IsWater()) { return(false); } if (cell.Feature != CellFeature.None) { return(false); } foreach (var city in CityFactory.AllCities) { var cityLocation = CityLocationCanon.GetOwnerOfPossession(city); if (HexGrid.GetDistance(cell, cityLocation) < Config.MinimumSeparation) { return(false); } } return(true); }
private IEnumerable <IImprovementTemplate> GetImprovementsValidFor( IHexCell cell, IResourceNode nodeAtLocation, IEnumerable <IResourceDefinition> availableResources, IEnumerable <IImprovementTemplate> availableImprovements ) { if (nodeAtLocation != null && nodeAtLocation.Resource.Extractor != null && availableResources.Contains(nodeAtLocation.Resource) && availableImprovements.Contains(nodeAtLocation.Resource.Extractor) ) { return(new List <IImprovementTemplate>() { nodeAtLocation.Resource.Extractor }); } else { var retval = availableImprovements.Where( improvement => ImprovementValidityLogic.IsTemplateValidForCell(improvement, cell, true) ).ToList(); retval.Add(null); return(retval); } }
private void SetProspectiveTravelGoal(IHexCell unitLocation, IHexCell goal) { Clear(); ProspectiveTravelGoal = goal; ProspectivePath = HexPathfinder.GetShortestPathBetween( unitLocation, goal, delegate(IHexCell currentCell, IHexCell nextCell) { return(UnitPositionCanon.GetTraversalCostForUnit( SelectedUnit, currentCell, nextCell, false )); } ); PathDrawer.ClearPath(); if (ProspectivePath != null) { PathDrawer.DrawPath(ProspectivePath); } else { OverlayManager.ShowOverlayOfCell(ProspectiveTravelGoal, CellOverlayType.UnreachableIndicator); } }
protected override void EditCell(IHexCell cell) { if (IsPainting && ModLogic.CanChangeFeatureOfCell(cell, ActiveFeature)) { ModLogic.ChangeFeatureOfCell(cell, ActiveFeature); } }
private IEnumerator FireHoverSignalCoroutine(IHexCell hoveredTile) { yield return(new WaitForSecondsRealtime(HoverDelay)); ConsideredHovered = true; BeginHoverSubject.OnNext(hoveredTile); }
public override bool TryPlaceFeatureAtLocation( IHexCell cell, Vector3 location, int locationIndex, HexHash hash ) { if ((cell.Vegetation != CellVegetation.Forest && cell.Vegetation != CellVegetation.Jungle) || (hash.A >= Config.TreeAppearanceChance && locationIndex % Config.GuaranteedTreeModulo != 0) ) { return(false); } if (cell.Vegetation == CellVegetation.Forest) { int treeIndex = (int)(hash.C * Config.ForestTreePrefabs.Count); AddFeature(Config.ForestTreePrefabs[treeIndex], location, hash); } else { int treeIndex = (int)(hash.C * Config.JungleTreePrefabs.Count); AddFeature(Config.JungleTreePrefabs[treeIndex], location, hash); } return(true); }
public void GetCommandsForUnit_ExcludesLocationsWhereUnitCannotMove() { var unitLocation = BuildCell(); var unit = BuildUnit(20.2f, 3.5f, unitLocation); var maps = new InfluenceMaps(); IHexCell cellOne = BuildCell(), cellTwo = BuildCell(), cellThree = BuildCell(); var reachableCellsDict = new Dictionary <IHexCell, float>() { { cellOne, 1f }, { cellTwo, 4f }, { cellThree, 3f }, }; Func <IHexCell, IHexCell, float> pathfindingCostFunction = (current, next) => 0; MockUnitPositionCanon.Setup(canon => canon.GetPathfindingCostFunction(unit, false)).Returns(pathfindingCostFunction); MockHexPathfinder.Setup( pathfinder => pathfinder.GetAllCellsReachableIn(unitLocation, 3.5f, pathfindingCostFunction, AllCells) ).Returns(reachableCellsDict); MockUnitPositionCanon.Setup(canon => canon.CanPlaceUnitAtLocation(unit, cellOne, false)).Returns(true); MockUnitPositionCanon.Setup(canon => canon.CanPlaceUnitAtLocation(unit, cellTwo, false)).Returns(false); MockUnitPositionCanon.Setup(canon => canon.CanPlaceUnitAtLocation(unit, cellThree, false)).Returns(true); MockBrainTools.Setup(tools => tools.GetFleeWeightFunction(unit, maps)).Returns(cell => reachableCellsDict[cell]); var fleeBrain = Container.Resolve <BarbarianFleeBrain>(); var moveCommand = fleeBrain.GetCommandsForUnit(unit, maps)[0] as MoveUnitCommand; Assert.AreEqual(cellThree, moveCommand.DesiredLocation); }
public float GetHeightForPointForCell( Vector2 xzPoint, IHexCell cell, float elevationDuck, AsyncTextureUnsafe <Color32> flatlandNoise, AsyncTextureUnsafe <Color32> hillsNoise ) { if (cell.Terrain.IsWater()) { return(RenderConfig.SeaFloorElevation); } if (cell.Shape == CellShape.Flatlands) { return(FlatlandsHeightmapLogic.GetHeightForPoint(xzPoint, flatlandNoise)); } else if (cell.Shape == CellShape.Hills) { return(HillsHeightmapLogic.GetHeightForPoint(xzPoint, elevationDuck, flatlandNoise, hillsNoise)); } else if (cell.Shape == CellShape.Mountains) { return(MountainHeightmapLogic.GetHeightForPoint(xzPoint, cell, elevationDuck, flatlandNoise, hillsNoise)); } else { throw new NotImplementedException(); } }
public void OnPointerClick(PointerEventData eventData) { var pointerRay = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(pointerRay, out hit, float.MaxValue)) { if (DidRaycastHitChunk(hit)) { IHexCell cell = PointOrientationLogic.GetCellAtPoint(hit.point); if (cell == null) { return; } var cityAtLocation = GetCityAtLocation(cell); if (cityAtLocation != null) { CitySignals.PointerClicked.OnNext(cityAtLocation); } else { CellSignals.Clicked.OnNext( new Tuple <IHexCell, PointerEventData>(cell, eventData) ); } } } }
public void GetAlphamapForCell(float[] returnedAlphamap, IHexCell cell) { for (int i = 0; i < returnedAlphamap.Length; i++) { returnedAlphamap[i] = 0f; } var improvementsAt = ImprovementLocationCanon.GetPossessionsOfOwner(cell); if (cell.Terrain.IsWater()) { returnedAlphamap[RenderConfig.SeaFloorTextureIndex] = 1f; } else if (cell.Shape == CellShape.Mountains) { returnedAlphamap[RenderConfig.MountainTextureIndex] = 1f; } else if (improvementsAt.Any(improvement => improvement.Template.OverridesTerrain)) { int newIndex = improvementsAt.First(improvement => improvement.Template.OverridesTerrain).Template.OverridingTerrainIndex; returnedAlphamap[newIndex] = 1f; } else if (cell.Terrain == CellTerrain.FloodPlains) { returnedAlphamap[(int)CellTerrain.Desert] = 1f; } else { returnedAlphamap[(int)cell.Terrain] = 1f; } }
private void EditCells(IHexCell center) { foreach (var cell in Grid.GetCellsInRadius(center, BrushSize)) { EditCell(cell); } }
private void OnCellPointerEnter(IHexCell cell) { if (Input.GetMouseButton(0)) { EditCells(cell); } }
private bool IsConditionMetByCell(IHexCell cell) { if (LocationRestriction == LocationRestrictionCategory.RoughTerrain) { return(Restriction == RestrictionType.MustBe ? cell.IsRoughTerrain : !cell.IsRoughTerrain); } else if (LocationRestriction == LocationRestrictionCategory.OfTerrain) { var argumentsContain = TerrainArguments.Contains(cell.Terrain); return(Restriction == RestrictionType.MustBe ? argumentsContain : !argumentsContain); } else if (LocationRestriction == LocationRestrictionCategory.OfShape) { var argumentsContain = ShapeArguments.Contains(cell.Shape); return(Restriction == RestrictionType.MustBe ? argumentsContain : !argumentsContain); } else if (LocationRestriction == LocationRestrictionCategory.OfVegetation) { var argumentsContain = VegetationArguments.Contains(cell.Vegetation); return(Restriction == RestrictionType.MustBe ? argumentsContain : !argumentsContain); } else { return(false); } }
public RiverPath( IHexCell cell, HexDirection pathStart, HexDirection pathEnd, RiverFlow flow, IRiverCanon riverCanon, IHexGrid grid ) { Cell = cell; Path = new List <HexDirection>(); Flow = flow; if (flow == RiverFlow.Clockwise) { for (HexDirection i = pathStart; i != pathEnd; i = i.Next()) { Path.Add(i); } } else { for (HexDirection i = pathStart; i != pathEnd; i = i.Previous()) { Path.Add(i); } } Path.Add(pathEnd); RiverCanon = riverCanon; Grid = grid; }
public bool CanBuildUnit(IHexCell location, IUnitTemplate template, ICivilization owner) { var canPlace = UnitPositionCanon.CanPlaceUnitTemplateAtLocation(template, location, owner); var hasForeignUnits = DoesCellHaveUnitsForeignTo(location, owner);; return(canPlace && !hasForeignUnits); }
//Since we're often triangulating water that goes up against land, //We need to be careful about how we assign colors. There are three //basic cases: center is water, either left or right (but not both) //is water, or all three cells are water. private void GetWaterColors( IHexCell center, HexDirection direction, out Color centerColor, out Color leftColor, out Color rightColor ) { centerColor = GetWaterColor(center); var left = Grid.GetNeighbor(center, direction.Previous()); var right = Grid.GetNeighbor(center, direction); bool isLeftWater = left != null && left.Terrain.IsWater(); bool isRightWater = right != null && right.Terrain.IsWater(); if (isLeftWater) { leftColor = GetWaterColor(left); rightColor = isRightWater ? rightColor = GetWaterColor(right) : Color.Lerp(centerColor, leftColor, 0.5f); } else if (isRightWater) { rightColor = GetWaterColor(right); leftColor = Color.Lerp(centerColor, rightColor, 0.5f); } else { leftColor = centerColor; rightColor = centerColor; } }
public void GetCommandsForUnit_AndUnitHasNoRangedAttackStrength_ReturnsASingleAttackCommand_ConfiguredCorrectly() { var unitLocation = BuildCell(); var unit = BuildUnit(location: unitLocation, canAttack: true); var maps = new InfluenceMaps(); IHexCell cellTwo = BuildCell(); var cellsByUtility = new Dictionary <IHexCell, float>() { { BuildCell(), 1f }, { cellTwo, 3f }, { BuildCell(), 2f }, }; MockUnitVisibilityLogic.Setup(logic => logic.GetCellsVisibleToUnit(unit)).Returns(cellsByUtility.Keys); MockFilterLogic.Setup(logic => logic.GetMeleeAttackFilter(unit)).Returns(cell => true); MockUtilityLogic.Setup(logic => logic.GetAttackUtilityFunction(unit, maps)).Returns(cell => cellsByUtility[cell]); var attackBrain = Container.Resolve <BarbarianAttackBrain>(); var commands = attackBrain.GetCommandsForUnit(unit, maps); Assert.AreEqual(1, commands.Count, "Commands has an unexpected number of elements"); var attackCommand = commands[0] as AttackUnitCommand; Assert.IsNotNull(attackCommand, "Command is not of type AttackUnitCommand"); Assert.AreEqual(unit, attackCommand.Attacker, "Command has an unexpected Attacker value"); Assert.AreEqual(cellTwo, attackCommand.LocationToAttack, "Command has an unexpected LocationToAttack value"); Assert.AreEqual(CombatType.Melee, attackCommand.CombatType, "Command has an unexpected CombatType value"); }
protected override void EditCell(IHexCell cell) { if (IsPaintingTerrain && CellModificationLogic.CanChangeTerrainOfCell(cell, ActiveTerrain)) { CellModificationLogic.ChangeTerrainOfCell(cell, ActiveTerrain); } }
public void GetCommandsForUnit_AndUnitHasNoRangedAttackStrength_ReturnsEmptyListIfNoCandidatePassesFilter() { var unitLocation = BuildCell(); var unit = BuildUnit(location: unitLocation, canAttack: true); var maps = new InfluenceMaps(); IHexCell cellTwo = BuildCell(); var cellsByUtility = new Dictionary <IHexCell, float>() { { BuildCell(), 1f }, { cellTwo, 3f }, { BuildCell(), 2f }, }; MockUnitVisibilityLogic.Setup(logic => logic.GetCellsVisibleToUnit(unit)).Returns(cellsByUtility.Keys); MockFilterLogic.Setup(logic => logic.GetMeleeAttackFilter(unit)).Returns(cell => false); MockUtilityLogic.Setup(logic => logic.GetAttackUtilityFunction(unit, maps)).Returns(cell => cellsByUtility[cell]); var attackBrain = Container.Resolve <BarbarianAttackBrain>(); var commands = attackBrain.GetCommandsForUnit(unit, maps); Assert.AreEqual(0, commands.Count); }
private void TryRemoveUnit(IHexCell location) { foreach (var unit in new List <IUnit>(UnitPositionCanon.GetPossessionsOfOwner(location))) { unit.Destroy(); } }
public List <IUnitCommand> GetCommandsForUnit(IUnit unit, InfluenceMaps maps) { var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit); var reachableCellsByDistance = HexPathfinder.GetAllCellsReachableIn( unitLocation, unit.CurrentMovement, UnitPositionCanon.GetPathfindingCostFunction(unit, false), Grid.Cells ); var validCandidates = reachableCellsByDistance.Keys.Where(cell => UnitPositionCanon.CanPlaceUnitAtLocation(unit, cell, false)); IHexCell bestCandidate = validCandidates.MaxElement(BrainTools.GetFleeWeightFunction(unit, maps)); var retval = new List <IUnitCommand>(); if (bestCandidate != null) { var moveCommand = Container.Instantiate <MoveUnitCommand>(); moveCommand.UnitToMove = unit; moveCommand.DesiredLocation = bestCandidate; retval.Add(moveCommand); } return(retval); }
private void OnCellPointerExited(IHexCell cell) { if (IsDragging) { Clear(); } }
public void TriangulateRoads(IHexCell cell, IHexMesh roadsMesh) { if (cell.HasRoads) { var cellHash = NoiseGenerator.SampleHashGrid(cell.AbsolutePositionXZ); var directionsWithRoad = EnumUtil.GetValues <HexDirection>().Where( direction => Grid.HasNeighbor(cell, direction) && Grid.GetNeighbor(cell, direction).HasRoads ).ToList(); while (directionsWithRoad.Any()) { var startDirection = directionsWithRoad.First(); directionsWithRoad.Remove(startDirection); BezierSpline spline; if (directionsWithRoad.Any()) { var endDirection = GetBestDirection(startDirection, directionsWithRoad, cellHash); directionsWithRoad.Remove(endDirection); spline = BuildSplineBetween(cell, startDirection, endDirection); } else { spline = BuildSplineToCenter(cell, startDirection); } RenderSpline(spline, roadsMesh); } } }
private void OnCellPointerExited(IHexCell cell) { if (IsDragging) { ProspectiveNewLocation = null; } }
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); } }
public bool HasAccessToFreshWater(IHexCell cell) { bool isFreshWater = cell.Terrain == CellTerrain.FreshWater; bool isSaltWater = cell.Terrain.IsWater() && !isFreshWater; bool hasOasis = cell.Feature == CellFeature.Oasis; bool hasRiver = RiverCanon.HasRiver(cell); if (!isSaltWater) { if (isFreshWater || hasOasis || hasRiver) { return(true); } foreach (var neighbor in Grid.GetNeighbors(cell)) { if (neighbor.Terrain == CellTerrain.FreshWater || neighbor.Feature == CellFeature.Oasis) { return(true); } } } return(false); }
private bool HasRiverInDirectionWithFlow(IHexCell cell, HexDirection direction, RiverFlow flow) { return( RiverCanon.HasRiverAlongEdge(Cell, direction) && RiverCanon.GetFlowOfRiverAtEdge(Cell, direction) == Flow ); }
private int CandidateComparer(IHexCell hillOne, IHexCell hillTwo) { var hillOneScore = CellScorer.GetScoreOfCell(hillOne); var hillTwoScore = CellScorer.GetScoreOfCell(hillTwo); return(hillTwoScore.CompareTo(hillOneScore)); }
private int PolarDistanceComparer(IHexCell cellA, IHexCell cellB) { int polarDistanceA, polarDistanceB; int zOffsetA = HexCoordinates.ToOffsetCoordinateZ(cellA.Coordinates); int zOffsetB = HexCoordinates.ToOffsetCoordinateZ(cellB.Coordinates); if (Config.Hemispheres == HemisphereMode.Both) { polarDistanceA = Math.Min(zOffsetA, Grid.CellCountZ - zOffsetA); polarDistanceB = Math.Min(zOffsetB, Grid.CellCountZ - zOffsetB); } else if (Config.Hemispheres == HemisphereMode.North) { polarDistanceA = Grid.CellCountZ - zOffsetA; polarDistanceB = Grid.CellCountZ - zOffsetB; } else if (Config.Hemispheres == HemisphereMode.South) { polarDistanceA = zOffsetA; polarDistanceB = zOffsetB; } else { throw new NotImplementedException("No behavior defined for HemisphereMode " + Config.Hemispheres); } return(polarDistanceB.CompareTo(polarDistanceA)); }