private void TryRemoveImprovementsFrom(IHexCell location)
 {
     foreach (var improvement in new List <IImprovement>(ImprovementLocationCanon.GetPossessionsOfOwner(location)))
     {
         improvement.Destroy();
     }
 }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 7
0
        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;
            }
        }
Esempio n. 12
0
 private void EditCells(IHexCell center)
 {
     foreach (var cell in Grid.GetCellsInRadius(center, BrushSize))
     {
         EditCell(cell);
     }
 }
Esempio n. 13
0
 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);
            }
        }
Esempio n. 15
0
        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;
        }
Esempio n. 16
0
        public bool CanBuildUnit(IHexCell location, IUnitTemplate template, ICivilization owner)
        {
            var canPlace        = UnitPositionCanon.CanPlaceUnitTemplateAtLocation(template, location, owner);
            var hasForeignUnits = DoesCellHaveUnitsForeignTo(location, owner);;

            return(canPlace && !hasForeignUnits);
        }
Esempio n. 17
0
        //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");
        }
Esempio n. 19
0
 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);
        }
Esempio n. 28
0
 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));
        }
Esempio n. 30
0
        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));
        }