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);
        }
    bool Update_DoJob(float deltaTime)
    {
        if (myJob == null)
        {
            myJob = currTile.world.jobQueue.Dequeue();

            if (myJob != null)
            {
                //We have a job!
                destTile = myJob.tile;
                myJob.RegisterJobCancelCallback(OnJobEnded);
                myJob.RegisterJobCompleteCallback(OnJobEnded);
            }
        }

        if (currTile == destTile)
        {
            pathAStar = null;
            if (myJob != null)
            {
                myJob.DoWork(deltaTime);
            }

            return(false);
        }

        return(true);
    }
Ejemplo n.º 3
0
    public Path_AStar GetPathToClosestInventoryOfType(string objectType, Tile t, int desiredAmount, bool canTakeFromStockpile)
    {
        QuickCheck(objectType);

        // We can also avoid going through the Astar construction if we know
        // that all available inventories are stockpiles and we are not allowed
        // to touch those
        if (!canTakeFromStockpile && inventories[objectType].TrueForAll(i => i.tile != null && i.tile.Furniture != null && i.tile.Furniture.IsStockpile()))
        {
            return(null);
        }

        // We shouldn't search if all inventories are locked.
        if (inventories[objectType].TrueForAll(i => i.tile != null && i.tile.Furniture != null && i.tile.Inventory != null && i.tile.Inventory.locked))
        {
            return(null);
        }

        // Test that there is at least one stack on the floor, otherwise the
        // search below might cause a full map search for nothing.
        if (inventories[objectType].Find(i => i.tile != null) == null)
        {
            return(null);
        }

        // We know the objects are out there, now find the closest.
        Path_AStar path = new Path_AStar(World.Current, t, null, objectType, desiredAmount, canTakeFromStockpile);

        return(path);
    }
Ejemplo n.º 4
0
 public void AbandonJob()
 {
     nextTile   = destTile = currTile;
     path_AStar = null;
     currTile.world.jobsQueue.Enqueue(myJob);
     myJob = null;
 }
Ejemplo n.º 5
0
 public void AbandonJob()
 {
     nextTile   = destTile = currTile;
     path_AStar = null;
     WorldController.Instance.World.jobQueue.Enqueue(myJob);
     myJob = null;
 }
Ejemplo n.º 6
0
    /// <summary>
    /// Get a job from the world list and tests it reachability.
    /// </summary>
    /// <returns>True if succeeded</returns>
    void GetNewJob() {
        myJob = currTile.world.jobQueue.Dequeue();
        if (myJob == null) {
            // There was no job on the queue for us, so just return false.
            return;
        }
        // We have a Job!

        // Immediately check if the job tile is reachable
        // NOTE: We might not be pathing to it right away.

        // Set job's nearest walkable tile as destination
        //destTile = GetNearestWalkableNeighbour(myJob.tile);
        destTile = myJob.tile;
        // Job Ended Callback
        myJob.RegisterJobCancelCallback(OnJobEnded);
        myJob.RegisterJobCompleteCallback(OnJobEnded);

        // Try to get a pathfinding from character to destTile.
        pathAStar = new Path_AStar(WorldController.Instance.world, currTile, destTile);
        if (pathAStar.Lenght() == 0) {
            // Pathfinding couldn't get a path to the destination.
            Debug.LogError("Path_AStar returned no path to target job tile!");

            // Re-enqueue Job, set current to null and return false.
            AbandonJob();
            return;
        }
        return;
    }
Ejemplo n.º 7
0
 public void AbandonJob(bool ReEnqueue = true)
 {
     this.nextTile  = this.destTile = this.currTile;
     this.pathAStar = null;
     this.currTile.world.jobQueue.Enqueue(this.currJob);
     this.currJob = null;
 }
Ejemplo n.º 8
0
    void GetNewJob()
    {
        // Get the first job on the queue.
        myJob = World.current.jobQueue.Dequeue();

        if (myJob == null)
        {
            myJob = new Job(CurrTile,
                            "Waiting",
                            null,
                            UnityEngine.Random.Range(0.1f, 0.5f),
                            null,
                            false);
        }

        // Get our destination from the job
        DestTile = myJob.tile;

        myJob.cbJobStopped += OnJobStopped;

        // Immediately check to see if the job tile is reachable.
        // NOTE: We might not be pathing to it right away (due to
        // requiring materials), but we still need to verify that the
        // final location can be reached.
        Profiler.BeginSample("PathGeneration");
        pathAStar = new Path_AStar(World.current, CurrTile, DestTile);  // This will calculate a path from curr to dest.
        Profiler.EndSample();
        if (pathAStar.Length() == 0)
        {
            Debug.LogError("Path_AStar returned no path to target job tile!");
            AbandonJob();
            DestTile = CurrTile;
        }
    }
Ejemplo n.º 9
0
    void GetNewJob()
    {
        myJob = World.Current.jobQueue.Dequeue();

        if (myJob == null)
        {
            myJob = new Job(CurrTile,
                            "Waiting",
                            null,
                            UnityEngine.Random.Range(0.1f, 0.5f),
                            null,
                            false);
        }

        DestTile            = myJob.tile;
        myJob.cbJobStopped += OnJobStopped;

        // Immediately check to see if the job tile is reachable
        pathAStar = new Path_AStar(World.Current, CurrTile, DestTile);  // This will calculate path from curr to dest
        if (pathAStar.Length() == 0)
        {
            Debug.LogError("Path_AStar returned no path to destination!");
            AbandonJob();
            DestTile = CurrTile;
        }
    }
Ejemplo n.º 10
0
    /// <summary>
    /// Grab a new job from the queue. This will first check if the tile is reachable.
    /// </summary>
    private void GetNewJob()
    {
        // Grab job from jobQueue
        currentJob = currentTile.World.jobQueue.Dequeue();

        if (currentJob == null)
        {
            return;
        }

        // Set the destinationtile
        DestinationTile = currentJob.tile;

        // Add job callback actions
        currentJob.RegisterJobCancelCallback(OnJobEnded);
        currentJob.RegisterJobCompleteCallback(OnJobEnded);

        // Check if the job tile is reachable
        // NOTE: We might not be pathing to it right away (due to requiring materials),
        // but we still need to verify that the final tile is reachalbe.
        #region Check tile is reachable
        // Generate new A* path from currentTile to destinationTile
        path_AStar = new Path_AStar(currentTile.World, currentTile, DestinationTile);

        // Check if path isn't null
        if (path_AStar.Length() == 0)
        {
            Debug.LogError("Path_AStar: Returned no path to target job tile!");
            // FIXME: Job should get added back to queue
            AbandonJob();
            DestinationTile = currentTile;
        }
        #endregion
    }
Ejemplo n.º 11
0
        /* #################################################################### */
        /* #                              METHODS                             # */
        /* #################################################################### */

        public void AbandonJob()
        {
            nextTile  = destTile = currTile;
            pathAStar = null;
            currTile.World.JobQueue.Enqueue(myJob);
            myJob = null;
        }
Ejemplo n.º 12
0
 void AbandonJob()
 {
     nextTile = destTile = currTile;
     path     = null;
     // FIXME BLUEPRINT CONTROLLER 25, JOBQUEUE 21; CHARACTER 68/85/115; WORLD 52; WORLDCOMTROLLER 26 - ELEMENT WITH THE SAME KEY ALLREADY EXISTS
     currTile.World.jobQueue.Enqueue(myJob);
     myJob = null;
 }
Ejemplo n.º 13
0
 public void AbandonJob()
 {
     Debug.Log("Character Abandon Job");
     nextTile = destTile = currTile;
     pather   = null;
     currTile.world.jobQueue.Enqueue(myJob, true);
     myJob = null;
 }
Ejemplo n.º 14
0
    void StopMove()
    {
        isMoving    = false;
        movePercent = 0;

        SetDirection();
        path = null;
        //aI_Controller.anim.SetTrigger("idle");
    }
Ejemplo n.º 15
0
    void UpdateDoMovement(float deltaTime)
    {
        if (currentTile == destinationTile)
        {
            pathAStar = null;
            return;
        }

        if (nextTile == null || nextTile == currentTile)
        {
            if (pathAStar == null || pathAStar.count() == 0)
            {
                pathAStar = new Path_AStar(World.worldInstance, currentTile, destinationTile);

                if (pathAStar.count() == 0)
                {
                    Debug.LogError("Path_AStar -- returned (0) no path to destinationTile");
                    AbbandonJob();
                    return;
                }

                pathAStar.Dequeue();
            }

            nextTile = pathAStar.Dequeue();

            /*if (nextTile == destinationTile) {
             *      nextTile = currentTile;
             *      destinationTile = currentTile;
             * }*/
        }

        float distanceToTravel = Mathf.Sqrt(Mathf.Pow(currentTile.X - nextTile.X, 2) + Mathf.Pow(currentTile.Y - nextTile.Y, 2));

        if (nextTile.isAccessible() == Accessiblity.NEVER)
        {
            Debug.LogError("Charcter tried to enter in unwalkable tile");
            nextTile  = null;
            pathAStar = null;
            return;
        }
        else if (nextTile.isAccessible() == Accessiblity.SOON)
        {
            return;
        }

        float distanceThisFrame   = speed / nextTile.movementCost * deltaTime;
        float percentageThisFrame = distanceThisFrame / distanceToTravel;

        movementPercentage += percentageThisFrame;

        if (movementPercentage >= 1)
        {
            currentTile        = nextTile;
            movementPercentage = 0;
        }
    }
Ejemplo n.º 16
0
        private BehaviourTreeStatus DoWork_Action(float deltaTime)
        {
            // Debug.Log("DoWork_Action");

            // If there isn't a current job, that probably means while this step was running, the job was completed.
            if (CurrentJob == null)
            {
                if (DebugAi)
                {
                    Debug.Log(Name + ": DoWork returning success");
                }
                return(BehaviourTreeStatus.Success);
            }

            // TODO: Not sure if we need to check this - that should've been handled by the preceeding actions. Can jobs move by themselves?
            var rangeToJob = 0;

            if (CurrentTile == CurrentJob.Tile)
            {
                // We're stood on the Job site.
                rangeToJob = 0;
            }

            if (_path != null)
            {
                // We're stood close enough to the job site.
                rangeToJob = _path.Length();
            }

            // If we're too far from the job site, something went wrong.
            if (rangeToJob > CurrentJob.MinRange)
            {
                if (DebugAi)
                {
                    Debug.Log(Name + ": DoWork returning failure");
                }
                return(BehaviourTreeStatus.Failure);
            }

            // Debug.LogFormat("DoWork_Action working job \"{3}\" at [{0},{1}] ({2:F2})", CurrentTile.X, CurrentTile.Y, CurrentJob.JobTime, CurrentJob.Name);

            CurrentState = State.WorkingJob;

            // Set dest to current, just in case it was the proximity-check that got us here.
            DestinationTile = CurrentTile;
            _path           = null;

            // Do some work.
            CurrentJob.DoWork(deltaTime);
            if (DebugAi)
            {
                Debug.Log(Name + ": DoWork returning running");
            }
            return(BehaviourTreeStatus.Running);
        }
Ejemplo n.º 17
0
    void Update_DoMovement(float deltaTime)
    {
        if (CurrentTile == _destTile)
        {
            CurrentTile.SetUnit(this);
            _pathAStar = null;
            return; // We're already were we want to be.
        }

        if (_nextTile == null || _nextTile == CurrentTile)
        {
            // Get the next tile from the pathfinder.
            if (_pathAStar == null || _pathAStar.Length() == 0)
            {
                // Generate a path to our destination
                CurrentTile.SetUnit(null);
                _pathAStar = new Path_AStar(CurrentTile.World, CurrentTile, _destTile); // This will calculate a path from curr to dest.
                if (_pathAStar.Length() == 0)
                {
                    Debug.LogError("Path_AStar returned no path to destination!");
                    _destTile  = CurrentTile;
                    _pathAStar = null;
                    return;
                }
            }

            // Grab the next waypoint from the pathing system!
            _nextTile = _pathAStar.Dequeue();
        }

        float distToTravel = Mathf.Sqrt(
            Mathf.Pow(CurrentTile.X - _nextTile.X, 2) +
            Mathf.Pow(CurrentTile.Y - _nextTile.Y, 2)
            );
        // How much distance can be travel this Update?
        float distThisFrame = Speed * deltaTime;

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

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

        if (_movementPercentage >= 1)
        {
            // We have reached our destination

            //       If there are no more tiles, then we have TRULY
            //       reached our destination.

            CurrentTile         = _nextTile;
            _movementPercentage = 0;
        }
    }
Ejemplo n.º 18
0
        public static Room FindNearestRoom(Tile start)
        {
            Path_AStar tileResolver = new Path_AStar(World.Current, start, GoalHasRoomEvaluator(), DijkstraDistance());

            if (tileResolver.Length() >= 1)
            {
                return(tileResolver.EndTile().Room);
            }

            return(null);
        }
Ejemplo n.º 19
0
    public void AbandonJob()
    {
        myJob.UnRegisterJobCompleteCallback(OnJobEnded);
        myJob.UnRegisterJobCanceledCallback(OnJobEnded);

        nextTile = currTile;
        destTile = null;
        mainPath = null;
        WorldController.Instance.World.jobQueue.Requeue(myJob); //TODO: Puts the job back on the jobQueue, might not be best idea??
        myJob = null;
    }
Ejemplo n.º 20
0
    public void OnJobEnded(Job j)
    {
        if (this.currJob != j)
        {
            Debug.LogError("Job does not match the current job this character is handling.");
            return;
        }

        this.nextTile  = this.destTile = this.currTile;
        this.pathAStar = null;
        this.currJob   = null;
    }
Ejemplo n.º 21
0
    public void PrioritizeJob(Job job)
    {
        AbandonJob(false);
        World.Current.jobQueue.Remove(job);
        job.IsBeingWorked = true;

        /*Check if the character is carrying any materials and if they could be used for the new job,
         * if the character is carrying materials but is not used in the new job, then drop them
         * on the current tile for now.*/

        if (inventory != null && !job.inventoryRequirements.ContainsKey(inventory.ObjectType))
        {
            World.Current.inventoryManager.PlaceInventory(CurrTile, inventory);
            DumpExcessInventory();
        }

        MyJob = job;

        // Get our destination from the job.
        DestTile = MyJob.tile;

        // If the destination tile does not have neighbours that are walkable it's very likable that they can't be walked to.
        if (DestTile.HasWalkableNeighbours() == false)
        {
            Debug.ULogChannel("Character", "No neighbouring floor tiles! Abandoning job.");
            AbandonJob(false);
            return;
        }

        MyJob.OnJobStopped += OnJobStopped;

        pathAStar = new Path_AStar(World.Current, CurrTile, DestTile);

        if (pathAStar != null && pathAStar.Length() == 0)
        {
            Debug.ULogChannel("Character", "Path_AStar returned no path to target job tile!");
            AbandonJob(false);
            return;
        }

        if (MyJob.adjacent)
        {
            IEnumerable <Tile> reversed = pathAStar.Reverse();
            reversed  = reversed.Skip(1);
            pathAStar = new Path_AStar(new Queue <Tile>(reversed.Reverse()));
            DestTile  = pathAStar.EndTile();
            jobTile   = DestTile;
        }
        else
        {
            jobTile = MyJob.tile;
        }
    }
Ejemplo n.º 22
0
    public Path_AStar GetPathToClosestInventoryOfType(string objectType, Tile t, int desiredAmount, bool canTakeFromStockpile)
    {
        if (inventories.ContainsKey(objectType) == false)
        {
            //Debug.LogError("GetClosestInventoryType -- no itmes of desired type.");
            return(null);
        }

        Path_AStar path = new Path_AStar(World.Current, t, null, objectType, desiredAmount, canTakeFromStockpile);

        return(path);
    }
Ejemplo n.º 23
0
    bool find_If_Tile_Job_Is_Rechable(Vector3Int jobTile)
    {
        Path_AStar path_to_job = new Path_AStar(WorldController.Instance.World, currTile, jobTile);

        if (path_to_job.Length() == 0)
        {
            return(false);
        }
        else
        {
            return(true);
        }
    }
Ejemplo n.º 24
0
        /// <summary>
        /// Finds the path to any inventory with type in <paramref name="types"/>
        /// </summary>
        public static List <Tile> FindPathToInventory(Tile start, string[] types, bool canTakeFromStockpile = true)
        {
            if (start == null || types == null || types.Length == 0)
            {
                return(null);
            }

            RoomPath_AStar roomResolver = new RoomPath_AStar(World.Current, start.GetNearestRoom(), RoomGoalInventoryEvaluator(types, canTakeFromStockpile), RoomHeuristic());
            List <Room>    roomPath     = roomResolver.GetList();

            if (roomPath.Count >= 1)
            {
                Tile nearestExit;
                if (roomPath.Count == 1)
                {
                    nearestExit = start;
                }
                else
                {
                    nearestExit = GetNearestExit(roomPath);
                }

                Tile  targetTile = null;
                float distance   = 0f;

                foreach (Inventory inventory in World.Current.InventoryManager.Inventories.Where(dictEntry => types.Contains(dictEntry.Key)).SelectMany(dictEntry => dictEntry.Value))
                {
                    if (inventory.Tile == null || !inventory.CanBePickedUp(canTakeFromStockpile))
                    {
                        continue;
                    }

                    if (targetTile == null || Vector3.Distance(nearestExit.Vector3, inventory.Tile.Vector3) < distance)
                    {
                        distance   = Vector3.Distance(nearestExit.Vector3, inventory.Tile.Vector3);
                        targetTile = inventory.Tile;
                    }
                }

                return(FindPathToTile(start, targetTile));
            }
            else
            {
                // Since we don't have a roomPath, someone's done something weird, like a room of doors, so just use Dijkstra to find our way
                Path_AStar  resolver = new Path_AStar(World.Current, start, GoalInventoryEvaluator(types, canTakeFromStockpile), DijkstraDistance());
                List <Tile> path     = resolver.GetList();
                return(path);
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Finds the path to a nearby tile where inventory of type <paramref name="type"/> can be dumped.
        /// </summary>
        public static List <Tile> FindPathToDumpInventory(Tile start, string type, int amount)
        {
            if (start == null || type == null || amount <= 0)
            {
                return(null);
            }

            Path_AStar  resolver = new Path_AStar(World.Current, start, GoalCanFitInventoryEvaluator(type, amount), DijkstraDistance());
            List <Tile> path     = resolver.GetList();

            DebugLogIf(path.Count > 0, "FindPathToDumpInventory from: {0}, to: {1}, found {2} [Length: {3}, took: {4}ms]", start, type, path.LastOrDefault(), path.Count, (int)(resolver.Duration * 1000));
            DebugLogIf(path == null, "Failed to find path to furniture of type {0}", type);

            return(path);
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Finds the path to an inventory of type <paramref name="type"/>.
        /// </summary>
        public static List <Tile> FindPathToInventory(Tile start, string type, bool canTakeFromStockpile = true)
        {
            if (start == null || type == null)
            {
                return(null);
            }

            Path_AStar  resolver = new Path_AStar(World.Current, start, GoalInventoryEvaluator(type, canTakeFromStockpile), DijkstraDistance());
            List <Tile> path     = resolver.GetList();

            DebugLogIf(path.Count > 0, "FindPathToInventory from: {0}, to: {1}, found {2} [Length: {3}, took: {4}ms]", start, type, path.LastOrDefault(), path.Count, (int)(resolver.Duration * 1000));
            DebugLogIf(path == null, "Failed to find path to inventory of type {0}", type);

            return(path);
        }
Ejemplo n.º 27
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.º 28
0
    void Update_Movement(float deltaTime)
    {
        if (currTile == destTile)
        {
            path = null;
            return;             // we are where we want to be;
        }
        if (nextTile == null || nextTile == currTile)
        {
            //pathfind next tile
            if (path == null || path.Lenght() == 0)
            {
                path = new Path_AStar(currTile.World, currTile, destTile);
                if (path.Lenght() == 0)
                {
                    //Debug.Log ("no path to dest");
                    //FIXME job maybe must be reenqued instead;
                    AbandonJob();
                    //FIXME cancel Job;
                    return;
                }
            }
            //grab next tile
            nextTile = path.DequeueNextTile();
            if (nextTile == currTile)
            {
                //Debug.LogError ("Update movement - next tile is currtile");
            }
        }

        //total distance
        float distToTravel = Mathf.Sqrt(Mathf.Pow(currTile.X - nextTile.X, 2) + Mathf.Pow(currTile.Y - nextTile.Y, 2));
        //
        float distThisFrame = speed * deltaTime;
        float percThisFrame = distThisFrame / distToTravel;

        movementPercentage += percThisFrame;
        if (movementPercentage >= 1)
        {
            currTile           = nextTile;
            movementPercentage = 0;
            // FIXME => overshotmovement?????
        }
    }
Ejemplo n.º 29
0
        /// <summary>
        /// Finds the path to furniture.
        /// </summary>
        /// <returns>The path to furniture.</returns>
        /// <param name="start">Start tile.</param>
        /// <param name="objectType">Object type of the furniture.</param>
        public static List <Tile> FindPathToFurniture(Tile start, string type)
        {
            if (start == null || type == null)
            {
                return(null);
            }

            RoomPath_AStar roomResolver = new RoomPath_AStar(World.Current, start.GetNearestRoom(), RoomGoalFurnitureEvaluator(type), RoomHeuristic());
            List <Room>    roomPath     = roomResolver.GetList();

            if (roomPath.Count >= 1)
            {
                Tile nearestExit;
                if (roomPath.Count == 1)
                {
                    nearestExit = start;
                }
                else
                {
                    nearestExit = GetNearestExit(roomPath);
                }

                Tile  targetTile = null;
                float distance   = float.MaxValue;
                foreach (Furniture furniture in World.Current.FurnitureManager.Where(furniture => furniture.Type == type))
                {
                    if (Vector3.Distance(nearestExit.Vector3, furniture.Tile.Vector3) < distance)
                    {
                        distance   = Vector3.Distance(nearestExit.Vector3, furniture.Tile.Vector3);
                        targetTile = furniture.Tile;
                    }
                }

                return(FindPathToTile(start, targetTile));
            }
            else
            {
                // Since we don't have a roomPath, someone's done something weird, like a room of doors, so just use Dijkstra to find our way
                Path_AStar  resolver = new Path_AStar(World.Current, start, GoalFurnitureEvaluator(type), DijkstraDistance());
                List <Tile> path     = resolver.GetList();
                return(path);
            }
        }
Ejemplo n.º 30
0
    // Start Pathfinding from Start to Goal tile
    public bool StartPathfinding()
    {
        Debug.Log("Start Path Finding");

        if (World.startTile == null || World.goalTile == null)
        {
            Debug.LogError("No Start or Goal tile");
            return(false);
        }

        Path_AStar oldPathAStar = pathAStar;

        // Update old path way not valid anymore
        if (oldPathAStar != null)
        {
            foreach (Tile t in oldPathAStar.Path())
            {
                //Debug.Log("Old Path:"+ tileGraphicController.tileGameObjectMap[t] );
                t.isPathway = false;
                tileGraphicController.tileGameObjectMap[t].GetComponent <GroundCube>().UpdatePathfindingGraphic();
            }
        }
        // Generate New pathway
        pathAStar = new Path_AStar(true, World.startTile, World.goalTile);
        if (pathAStar.Length() == 0)
        {
            // No valid Pathfinding way
            Debug.LogError("Path_AStar returned no path to destination!");
            pathAStar = null;
            return(false);
        }
        else
        {
            foreach (Tile t in pathAStar.Path())
            {
                t.isPathway = true;
                tileGraphicController.tileGameObjectMap[t].GetComponent <GroundCube>().UpdatePathfindingGraphic();
            }
            return(true);
        }
    }