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); }
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 ) ); }
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"); }