Beispiel #1
0
        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
            });
        }
Beispiel #2
0
        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
            });
        }
Beispiel #3
0
        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
            });
        }
Beispiel #4
0
        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);
        }