Ejemplo n.º 1
0
        public Job TakeClosestJobToTile(Tile t)
        {
            Job found    = null;
            int distance = int.MaxValue;

            foreach (var job in _jobQueue)
            {
                var route = new Path_AStar()
                {
                    World = World.Instance,
                    Start = t,
                    End   = job.Tile
                };
                route.Calculate();

                if (found == null || route.Length() < distance)
                {
                    found    = job;
                    distance = route.Length();
                }
            }

            if (found != null)
            {
                _jobQueue.Remove(found);
            }

            return(found);
        }
Ejemplo n.º 2
0
        public Path_AStar GetClosestPathToInventoryOfType(string objectType, Tile t, int desiredQty, bool searchInStockpiles)
        {
            if (Inventories.ContainsKey(objectType) == false)
            {
                return(null);
            }

            var path = new Path_AStar()
            {
                World                = World.Instance,
                Start                = t,
                ObjectType           = objectType,
                CanTakeFromStockpile = true
            };

            path.Calculate();
            return(path);
        }
Ejemplo n.º 3
0
        private BehaviourTreeStatus SetupMoveToJobSite_Action()
        {
            if (CurrentJob == null)
            {
                Debug.LogFormat("{0}: SetupMoveToJobSite_Action returning failure due to no job", Name);
                AbandonJob();
                AbandonMove();
                return(BehaviourTreeStatus.Failure);
            }

            if (DestinationTile == CurrentJob.Tile)
            {
                // Already moving towards job, so just carry on.
                return(BehaviourTreeStatus.Success);
            }

            // Make sure we're heading for the site.
            DestinationTile = CurrentJob.Tile;

            // See if we're already stood on the tile.
            if (CurrentTile == DestinationTile)
            {
                Debug.LogFormat("{0}: SetupMoveToJobSite_Action returning success due to being at the job", Name);
                return(BehaviourTreeStatus.Success);
            }

            // Make sure we have a route to the job.
            if (_path == null || _path.EndTile() != DestinationTile)
            {
                _path = new Path_AStar()
                {
                    World = World.Instance,
                    Start = CurrentTile,
                    End   = DestinationTile
                };
                _path.Calculate();
            }

            // If we still don't have a path, there is no path.
            if (_path.IsUnReachable)
            {
                Debug.LogFormat("{0}: SetupMoveToJobSite_Action returning failure due to not being able to find a route", Name);
                AbandonJob();
                return(BehaviourTreeStatus.Failure);
            }

            // See if we're "close enough" to the job.
            // _path.Debug();
            if ((_path.Length()) <= CurrentJob.MinRange)
            {
                // Debug.LogFormat("{0}: Close enough to job (is {1} needs to be <= {2})", Name, (_path.Length()), CurrentJob.MinRange);
                // Set dest to current, just in case it was the proximity-check that got us here
                DestinationTile = CurrentTile;
                return(BehaviourTreeStatus.Success);
            }
            else
            {
                Debug.LogFormat("{0}: Distance to job is {1}, needs to be <={2}", Name, (_path.Length()), CurrentJob.MinRange);
            }

            // At this point we should have a valid _nextTile to move to.
            return(BehaviourTreeStatus.Success);
        }
Ejemplo n.º 4
0
        private BehaviourTreeStatus MoveTowardsDestination_Action(float deltaTime)
        {
            // If we've already arrived at our destination, just continue.
            if (CurrentTile == _destinationTile)
            {
                // Debug.Log("MoveTowardsDestination_Action: Destination Reached");
                return(BehaviourTreeStatus.Success);
            }

            // If we don't have a next tile yet, get one.
            if (_nextTile == null || _nextTile == CurrentTile)
            {
                // If we don't have a route to the current destination, plan one.
                if (_path == null || _path.Length() == 0 || _path.EndTile() != DestinationTile)
                {
                    _path = new Path_AStar()
                    {
                        World = World.Instance,
                        Start = CurrentTile,
                        End   = DestinationTile
                    };
                    _path.Calculate();
                }

                // If Path is still null, we were not able to find a route to our goal
                if (_path == null)
                {
                    AbandonJob();
                    Debug.LogFormat("MoveTowardsDestination_Action: Could not find a route to the next tile!");
                    return(BehaviourTreeStatus.Failure);
                }

                // See if we're "close enough" to the job.
                // _path.Debug();
                if ((_path.Length()) <= CurrentJob.MinRange)
                {
                    Debug.LogFormat("{0}: Close enough to job (is {1} needs to be <= {2})", Name, (_path.Length()), CurrentJob.MinRange);
                    // Set dest to current, just in case it was the proximity-check that got us here
                    DestinationTile = CurrentTile;
                    return(BehaviourTreeStatus.Success);
                }
                else
                {
                    Debug.LogFormat("{0}: Distance to job is {1}, needs to be <={2}", Name, (_path.Length()), CurrentJob.MinRange);
                }

                _nextTile = _path.Dequeue();
            }

            if (_nextTile == null)
            {
                _nextTile = CurrentTile; // TODO: Not sure when this might apply
            }

            // What's the total distance from point A to point B?
            // We are going to use Euclidean distance FOR NOW...
            // But when we do the pathfinding system, we'll likely
            // switch to something like Manhattan or Chebyshev distance
            float distToTravel = 0;

            if (_nextTile != CurrentTile)
            {
                distToTravel = Mathf.Sqrt(
                    Mathf.Pow(CurrentTile.X - _nextTile.X, 2) +
                    Mathf.Pow(CurrentTile.Y - _nextTile.Y, 2)
                    );
            }

            // Before entering a Tile, make sure it is not impassable.
            // This might happen if the Tile is changed (e.g. wall built) after the pathfinder runs.
            if (_nextTile.IsEnterable() == Enterability.Never)
            {
                _nextTile = null;
                _path     = null;
                Debug.LogFormat("{0}: MoveTowardsDestination_Action failed trying to move into a blocked tile.", Name);
                return(BehaviourTreeStatus.Failure);
            }

            if (_nextTile.IsEnterable() == Enterability.Soon)
            {
                // The next Tile we're trying to enter is walkable, but maybe for some reason
                // cannot be entered right now. Perhaps it is occupied, or contains a closed door.
                CurrentState = State.WaitingForAccess;
                return(BehaviourTreeStatus.Running);
            }

            // How much distance can be travel this Update?
            if (_nextTile == null)
            {
                _nextTile = CurrentTile;
            }
            var distThisFrame = 0f;

            try
            {
                distThisFrame = (_speed / _nextTile.MovementCost) * deltaTime;
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
            }

            // How much is that in terms of percentage to our destination?
            float percThisFrame;

            if (Mathf.Approximately(distToTravel, 0f))
            {
                percThisFrame = 1f;
            }
            else
            {
                percThisFrame = distThisFrame / distToTravel;
            }

            // Add that to overall percentage travelled.
            _movementPercentage += percThisFrame;

            if (_movementPercentage >= 1)
            {
                // We have reached our (current) destination
                CurrentTile         = _nextTile;
                _movementPercentage = 0;
            }

            // Debug.LogFormat("MoveTowardsDestination_Action: Character at [{0:F2},{1:F2}] {2:P2}", this.X, this.Y, _movementPercentage);

            return(BehaviourTreeStatus.Running);
        }