public override ActivityStep ResolveStep(GameEntity entity) { bool isAtDestination = !_stepsToFollow.Any(); Position nextStep; if (isAtDestination) { return(new ActivityStep { State = ActivityState.FinishedSuccess }); } nextStep = _stepsToFollow.Pop(); Position direction = nextStep - entity.position.Position; if (!PositionUtilities.IsOneStep(direction)) { return(Fail(entity)); } IGameAction moveGameAction = _actionFactory.CreateJustMoveAction(direction, entity); return(new ActivityStep { State = ActivityState.InProgress, GameAction = moveGameAction }); }
public override ActivityStep ResolveStep(GameEntity entity) { if (!_targetEntity.hasPosition) { return(Succeed(entity)); } if (Position.Distance(_targetEntity.position.Position, entity.position.Position) >= _giveUpDistance) { return(Fail(entity)); } Position targetCurrentPosition = _targetEntity.position.Position; bool targetIsOneStepAway = PositionUtilities.IsOneStep(entity.position.Position - targetCurrentPosition); if (targetIsOneStepAway) { return(new ActivityStep { State = ActivityState.InProgress, GameAction = _actionFactory.CreateAttackAction(entity, _targetEntity), }); } if (_rng.Check(0.03f)) { return(Fail(entity, _actionFactory.CreatePassAction(entity, 3f))); } bool targetPositionHasChanged = targetCurrentPosition != _lastTargetPosition; if (targetPositionHasChanged) { _lastTargetPosition = targetCurrentPosition; } if (targetPositionHasChanged || _navigationData == null) { // performance: should in fact be done every couple of turns _navigationData = _navigator.GetNavigationData(entity.position.Position, targetCurrentPosition); } Position nextStep; NavigationResult navigationResult = _navigator.ResolveNextStep(_navigationData, entity.position.Position, out nextStep); if (navigationResult == NavigationResult.Finished) { return(Succeed(entity)); } IGameAction moveGameAction = CreateMoveAction(nextStep, entity); return(new ActivityStep { State = ActivityState.InProgress, GameAction = moveGameAction }); }
public override ActivityStep ResolveStep(GameEntity entity) { Position targetCurrentPosition = _targetPositionGetter(); bool reachedTarget = PositionUtilities.IsOneStep(entity.position.Position - targetCurrentPosition); if (reachedTarget) { return(Succeed(entity)); } bool targetPositionHasChanged = targetCurrentPosition != _lastTargetPosition; if (targetPositionHasChanged) { _lastTargetPosition = targetCurrentPosition; } if (targetPositionHasChanged || _navigationData == null) { // performance: should in fact be done every couple of turns _navigationData = _navigator.GetNavigationData(entity.position.Position, targetCurrentPosition); } Position nextStep; NavigationResult navigationResult = _navigator.ResolveNextStep(_navigationData, entity.position.Position, out nextStep); if (navigationResult == NavigationResult.Finished) { return(Succeed(entity)); } IGameAction moveGameAction = CreateMoveAction(nextStep, entity); return(new ActivityStep { State = ActivityState.InProgress, GameAction = moveGameAction }); }
public NavigationResult ResolveNextStep(NavigationData navigationData, Position currentPosition, out Position nextStep) { nextStep = PositionUtilities.Min; if (navigationData.Destination == currentPosition) { return(NavigationResult.Finished); } bool pathIsCorrupted = !NavigationDataIsValid(currentPosition, navigationData); if (pathIsCorrupted) { #if UNITY_EDITOR //Debug.Log("path is corrupted. recalculating path"); #endif return(ResolveWithRecalculation(navigationData, currentPosition, ref nextStep)); } if (!navigationData.RemainingStepsInCurrentSegment.Any()) { IList <Position> naturalLineToWalk = _naturalLineCreator.GetFirstLongestNaturalLine( currentPosition, navigationData.RemainingNodes, _grid.IsWalkable); Position naturalNextNode = naturalLineToWalk.Last(); bool naturalNextNodeIsSameAsNextNextNode = navigationData.RemainingNodes.Count > 1 && navigationData.RemainingNodes[1] == naturalNextNode; if (naturalNextNodeIsSameAsNextNextNode) { navigationData.RemainingNodes.RemoveAt(0); } else { navigationData.RemainingNodes[0] = naturalNextNode; } navigationData.RemainingStepsInCurrentSegment = new Stack <Position>(naturalLineToWalk.Skip(1).Reverse()); } Position lastStep = navigationData.LastStep; if (!navigationData.RemainingStepsInCurrentSegment.Any()) { throw new InvalidOperationException($"Missing remaining steps. Current: {currentPosition}, navigation: {navigationData}"); } nextStep = navigationData.RemainingStepsInCurrentSegment.Pop(); bool actorWasDisplaced = currentPosition != lastStep; if (actorWasDisplaced) { bool actorWasDisplacedFarFromLastStep = !PositionUtilities.IsOneStep(lastStep - currentPosition); if (actorWasDisplacedFarFromLastStep) { #if UNITY_EDITOR //Debug.Log("actor was displaced far from last step. recalculating path"); #endif return(ResolveWithRecalculation(navigationData, currentPosition, ref nextStep)); } bool shouldMoveAgainToLastPosition = !PositionUtilities.IsOneStep(nextStep - currentPosition); if (shouldMoveAgainToLastPosition) { navigationData.RemainingStepsInCurrentSegment.Push(nextStep); nextStep = lastStep; } } if (!_grid.IsWalkable(nextStep)) { #if UNITY_EDITOR //Debug.Log("next step not walkable. recalculating path"); #endif return(ResolveWithRecalculation(navigationData, currentPosition, ref nextStep)); } bool willBeNextNode = nextStep == navigationData.RemainingNodes[0]; if (willBeNextNode) { navigationData.RemainingNodes.RemoveAt(0); } navigationData.LastStep = nextStep; return(NavigationResult.InProgress); }