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);
            }
        }
        public float GetUtilityForUnit(IUnit unit, InfluenceMaps maps)
        {
            var unitPosition = UnitPositionCanon.GetOwnerOfPossession(unit);

            var reachableCells = HexPathfinder.GetAllCellsReachableIn(
                unitPosition, unit.CurrentMovement,
                (current, next) => UnitPositionCanon.GetTraversalCostForUnit(unit, current, next, true),
                Grid.Cells
                );

            if (reachableCells.Keys.Any(FilterLogic.GetCaptureCivilianFilter(unit)))
            {
                return(BarbarianConfig.CaptureCivilianUtility);
            }
            else
            {
                return(0f);
            }
        }
        public void StartExecution()
        {
            if (DesiredLocation == null)
            {
                throw new InvalidOperationException("Cannot execute while DesiredLocation is null");
            }

            Status = CommandStatus.Running;

            UnitToMove.CurrentPath = null;

            var unitLocation = UnitPositionCanon.GetOwnerOfPossession(UnitToMove);

            if (unitLocation == null)
            {
                throw new InvalidOperationException("Cannot move a unit with a null location");
            }

            if (unitLocation == DesiredLocation)
            {
                Status = CommandStatus.Succeeded;
            }
            else
            {
                var pathTo = HexPathfinder.GetShortestPathBetween(
                    unitLocation, DesiredLocation,
                    (current, next) => UnitPositionCanon.GetTraversalCostForUnit(UnitToMove, current, next, false)
                    );

                if (pathTo != null)
                {
                    UnitToMove.CurrentPath = pathTo;

                    UnitToMove.PerformMovement(false, OnUnitFinishedMovement);
                }
                else
                {
                    Status = CommandStatus.Failed;
                }
            }
        }
        public List <IUnitCommand> GetCommandsForUnit(IUnit unit, InfluenceMaps maps)
        {
            var retval = new List <IUnitCommand>();

            var unitPosition = UnitPositionCanon.GetOwnerOfPossession(unit);

            Dictionary <IHexCell, float> cellsByCost = HexPathfinder.GetCostToAllCells(
                unitPosition, (current, next) => UnitPositionCanon.GetTraversalCostForUnit(unit, current, next, false),
                Grid.Cells
                );

            IHexCell bestCandidate = null;
            float    lowestCost    = float.MaxValue;

            foreach (var candidate in cellsByCost.Keys)
            {
                if (!EncampmentLocationCanon.GetPossessionsOfOwner(candidate).Any())
                {
                    continue;
                }

                if (bestCandidate == null || lowestCost > cellsByCost[candidate])
                {
                    bestCandidate = candidate;
                    lowestCost    = cellsByCost[candidate];
                }
            }

            if (bestCandidate != null)
            {
                var moveCommand = Container.Instantiate <MoveUnitCommand>();

                moveCommand.UnitToMove      = unit;
                moveCommand.DesiredLocation = bestCandidate;

                retval.Add(moveCommand);
            }

            return(retval);
        }
        public void RespondToCombat(IUnit attacker, IUnit defender, CombatInfo combatInfo)
        {
            if (!attacker.CombatSummary.CanMoveAfterAttacking)
            {
                attacker.CurrentMovement = 0;
            }
            else if (combatInfo.CombatType == CombatType.Melee)
            {
                var attackerLocation = UnitPositionCanon.GetOwnerOfPossession(attacker);
                var defenderLocation = UnitPositionCanon.GetOwnerOfPossession(defender);

                var costToMove = UnitPositionCanon.GetTraversalCostForUnit(
                    attacker, attackerLocation, defenderLocation, true
                    );

                attacker.CurrentMovement = Math.Max(0, attacker.CurrentMovement - costToMove);
            }
            else if (combatInfo.CombatType == CombatType.Ranged)
            {
                attacker.CurrentMovement--;
            }
        }
        public bool IsMeleeAttackValid(IUnit attacker, IUnit defender)
        {
            if (!CommonAttackValidityLogic.DoesAttackMeetCommonConditions(attacker, defender))
            {
                return(false);
            }

            var attackerLocation = UnitPositionCanon.GetOwnerOfPossession(attacker);
            var defenderLocation = UnitPositionCanon.GetOwnerOfPossession(defender);

            if (defenderLocation == null)
            {
                return(false);
            }

            var shortestPath = HexPathfinder.GetShortestPathBetween(
                attackerLocation, defenderLocation, attacker.CurrentMovement,
                (current, next) => UnitPositionCanon.GetTraversalCostForUnit(attacker, current, next, true),
                Grid.Cells
                );

            if (shortestPath == null)
            {
                return(false);
            }

            if (!LineOfSightLogic.GetCellsVisibleToUnit(attacker).Contains(defenderLocation))
            {
                return(false);
            }

            if (attacker.CombatStrength <= 0)
            {
                return(false);
            }

            return(true);
        }
Example #7
0
        public void PerformMeleeAttack(IUnit attacker, IUnit defender, Action successAction, Action failAction)
        {
            if (!CanPerformMeleeAttack(attacker, defender))
            {
                throw new InvalidOperationException("CanPerformMeleeCombat must return true");
            }

            var attackerLocation = UnitPositionCanon.GetOwnerOfPossession(attacker);
            var defenderLocation = UnitPositionCanon.GetOwnerOfPossession(defender);

            var pathToDefender = HexPathfinder.GetShortestPathBetween(
                attackerLocation, defenderLocation, attacker.CurrentMovement,
                (current, next) => UnitPositionCanon.GetTraversalCostForUnit(attacker, current, next, true),
                Grid.Cells
                );

            attacker.CurrentPath = pathToDefender.GetRange(0, pathToDefender.Count - 1);

            attacker.PerformMovement(
                false, PerformMeleeAttack_GetPostMovementCallback(
                    attacker, defender, defenderLocation, successAction, failAction
                    )
                );
        }
Example #8
0
        private IEnumerator PerformMovementCoroutine(bool ignoreMoveCosts, Action postMovementCallback)
        {
            Animator.SetTrigger("Moving Requested");

            IHexCell startingCell = PositionCanon.GetOwnerOfPossession(this);
            IHexCell currentCell  = startingCell;

            Vector3 currentLocation = Grid.PerformIntersectionWithTerrainSurface(currentCell.AbsolutePosition);

            Vector3 a, b, c = currentLocation;

            yield return(LookAt(CurrentPath.First().AbsolutePosition));

            float t = Time.deltaTime * Config.TravelSpeedPerSecond;

            while ((ignoreMoveCosts || CurrentMovement > 0) && CurrentPath != null && CurrentPath.Count > 0)
            {
                var nextCell = CurrentPath.FirstOrDefault();

                Vector3 nextLocation = Grid.PerformIntersectionWithTerrainSurface(nextCell.AbsolutePosition);

                if (!PositionCanon.CanChangeOwnerOfPossession(this, nextCell) || nextCell == null)
                {
                    CurrentPath.Clear();
                    break;
                }

                if (!ignoreMoveCosts)
                {
                    CurrentMovement = Math.Max(0,
                                               CurrentMovement - PositionCanon.GetTraversalCostForUnit(this, currentCell, nextCell, false)
                                               );
                }

                PositionCanon.ChangeOwnerOfPossession(this, nextCell);

                CurrentPath.RemoveAt(0);

                a = c;
                b = currentLocation;
                c = (b + nextLocation) * 0.5f;

                for (; t < 1f; t += Time.deltaTime * Config.TravelSpeedPerSecond)
                {
                    transform.position = BezierQuadratic.GetPoint(a, b, c, t);
                    Vector3 d = BezierQuadratic.GetFirstDerivative(a, b, c, t);
                    d.y = 0f;
                    transform.localRotation = Quaternion.LookRotation(d);
                    yield return(null);
                }
                t -= 1f;

                currentCell = nextCell;

                currentLocation = Grid.PerformIntersectionWithTerrainSurface(currentCell.AbsolutePosition);
            }

            if (currentCell != startingCell)
            {
                a = c;
                b = currentLocation;
                c = b;

                for (; t < 1f; t += Time.deltaTime * Config.TravelSpeedPerSecond)
                {
                    transform.position = BezierQuadratic.GetPoint(a, b, c, t);
                    Vector3 d = BezierQuadratic.GetFirstDerivative(a, b, c, t);
                    d.y = 0f;
                    transform.localRotation = Quaternion.LookRotation(d);
                    yield return(null);
                }
            }

            postMovementCallback();

            Animator.SetTrigger("Idling Requested");
        }