Exemplo 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);
        }
Exemplo n.º 2
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;
        }
    }
Exemplo n.º 3
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
    }
Exemplo n.º 4
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;
        }
    }
Exemplo n.º 5
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;
        }
    }
Exemplo n.º 6
0
 public Block GetNextPathBlock()
 {
     if (myPath.Length() > 0)
     {
         return(myPath.GetNextBlock());
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
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;
        }
    }
Exemplo n.º 9
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);
        }
    }
Exemplo n.º 10
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);
        }
    }
Exemplo n.º 11
0
    void GetNewJob()
    {
        _myJob = _currentTile.World.JobQueue.Dequeue();

        if (_myJob == null)
        {
            return;
        }

        DestinationTile = _myJob.Tile;

        _myJob.RegisterJobCompletedCallback(RegisterOnJobEnded);
        _myJob.RegisterJobCancelledCallback(RegisterOnJobEnded);

        _pathAStar = new Path_AStar(WorldController.Instance.World, _currentTile, _destinationTile);
        if (_pathAStar.Length() == 0)
        {
            Debug.LogError("Path_AStart returned no path to current job tile!");
            AbandonJob();
        }
    }
Exemplo n.º 12
0
    void GetNewJob()
    {
        myJob = currentTile.World.jobQueue.Dequeue();

        if (myJob == null)
        {
            return;
        }

        DestinationTile = myJob.tile;
        myJob.RegisterJobCancelCallback(OnJobEnded);
        myJob.RegisterJobCompleteCallback(OnJobEnded);

        //check to see if final job tile is reachable
        //generate a path to check
        pathAStar = new Path_AStar(currentTile.World, currentTile, DestinationTile); //calculate a path from the current tile to the destination tile
        if (pathAStar.Length() == 0)
        {
            Debug.LogError("Character -- Update_DoMovement: Path_AStar returned no path to target job");
            AbandonJob();
            DestinationTile = currentTile;
        }
    }
Exemplo n.º 13
0
    void GetNewJob()
    {
        myJob = World.current.jobQueue.Dequeue();
        if (myJob == null)
        {
            return;
        }

        DestTile = myJob.tile;
        myJob.RegisterJobStoppedCallback(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.

        pathAStar = new Path_AStar(World.current, currTile, DestTile);          // This will calculate a path from curr to dest.
        if (pathAStar.Length() == 0)
        {
            Debug.LogError("Path_AStar returned no path to target job tile!");
            AbandonJob();
            DestTile = currTile;
        }
    }
Exemplo n.º 14
0
    /// <summary>
    /// 更新移动
    /// </summary>
    /// <param name="deltaTime"></param>
    void Update_DoMovement(float deltaTime)
    {
        if (currTile == destTile)
        {
            path_AStar = null;
            return;
        }
        if (nextTile == null || nextTile == currTile)
        {
            //获取下一个寻路点
            if (path_AStar == null || path_AStar.Length() == 0)
            {
                //生存到目的地寻路
                path_AStar = new Path_AStar(currTile.world, currTile, destTile);
                if (path_AStar.Length() == 0)
                {
                    AbandonJob();
                    path_AStar = null;
                    return;
                }
                //获取下一个路径tile
                nextTile = path_AStar.Dequeue();
            }
            //获取下一个路径tile
            nextTile = path_AStar.Dequeue();
        }
        if (nextTile.IsEnterable() == Enterability.Never)
        {
            //很可能是墙建成了,所以我们只需要重置我们的寻路信息。
            // FIXME:理想情况下,当墙壁产生时,我们应立即使路径无效,
            //这样我们就不会浪费一大堆时间走向死胡同。
            //为了节省CPU,也许我们只能经常检查?
            //或者我们应该注册OnTileChanged事件的回调?
            nextTile   = null;
            path_AStar = null;
            return;
        }
        else if (nextTile.IsEnterable() == Enterability.Soon)
        {
            //我们现在无法进入,但我们应该可以进入
            //未来 这可能是一个DOOR。
            //所以我们不要保佑我们的运动/路径,但我们确实会回来
            //现在并不实际处理运动。
            return;
        }
        //从A点到B点的总距离是多少?
        //我们将使用欧几里德距离现在......
        //但是当我们进行寻路系统时,我们很可能会这样做
        //切换到曼哈顿或切比雪夫的距离
        float distToTravel = Mathf.Sqrt(
            Mathf.Pow(currTile.x - nextTile.x, 2)
            + Mathf.Pow(currTile.y - nextTile.y, 2)
            );

        // 移动速度(通过门的时 缓慢通过)
        float distThisFrame = speed / nextTile.movementCost * deltaTime;

        // 到目的地的需要多久?
        float percThisFrame = distThisFrame / distToTravel;

        //
        movementPercentage += percThisFrame;

        if (movementPercentage >= 1)
        {
            // TODO:从寻路系统中获取下一个图块。
            //如果没有更多的瓷砖,那么我们就有了TRULY
            //到达目的地

            // 我们到达了目的地
            currTile           = nextTile;
            movementPercentage = 0;
            // 我们真的想保留任何超车运动吗?
        }
        if (cbCharacterChanged != null)
        {
            cbCharacterChanged(this);
        }
    }
Exemplo n.º 15
0
    private void GetNewJob()
    {
        float needPercent = 0;
        Need  need        = null;

        foreach (Need n in needs)
        {
            if (n.Amount > needPercent)
            {
                need        = n;
                needPercent = n.Amount;
            }
        }

        if (needPercent > 50 && needPercent < 100 && need.RestoreNeedFurn != null)
        {
            if (World.Current.CountFurnitureType(need.RestoreNeedFurn.ObjectType) > 0)
            {
                MyJob = new Job(null, need.RestoreNeedFurn.ObjectType, need.CompleteJobNorm, need.RestoreNeedTime, null, Job.JobPriority.High, false, true, false);
            }
        }

        if (needPercent == 100 && need != null && need.CompleteOnFail)
        {
            MyJob = new Job(CurrTile, null, need.CompleteJobCrit, need.RestoreNeedTime * 10, null, Job.JobPriority.High, false, true, true);
        }

        // Get the first job on the queue.
        if (MyJob == null)
        {
            MyJob = World.Current.jobQueue.Dequeue();

            // Check if we got a job from the queue.
            if (MyJob == null)
            {
                Debug.ULogChannel("Character", name + " did not find a job.");
                MyJob = new Job(
                    CurrTile,
                    "Waiting",
                    null,
                    UnityEngine.Random.Range(0.1f, 0.5f),
                    null,
                    Job.JobPriority.Low,
                    false);
                MyJob.JobDescription = "job_waiting_desc";
            }
            else
            {
                if (MyJob.tile == null)
                {
                    Debug.ULogChannel("Character", name + " found a job.");
                }
                else
                {
                    Debug.ULogChannel("Character", name + " found a job at x " + MyJob.tile.X + " y " + MyJob.tile.Y + ".");
                }
            }
        }

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

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

        MyJob.OnJobStopped += 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");
        if (MyJob.IsNeed)
        {
            // This will calculate a path from current tile to destination tile.
            pathAStar = new Path_AStar(World.Current, CurrTile, DestTile, need.RestoreNeedFurn.ObjectType, 0, false, true);
        }
        else
        {
            pathAStar = new Path_AStar(World.Current, CurrTile, DestTile);
        }

        Profiler.EndSample();

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

        MyJob.IsBeingWorked = true;
    }
Exemplo n.º 16
0
    private void GetNewJob()
    {
        float needPercent = 0;
        Need  need        = null;

        foreach (Need n in needs)
        {
            if (n.Amount > needPercent)
            {
                need        = n;
                needPercent = n.Amount;
            }
        }
        if (needPercent > 50 && needPercent < 100 && need != null)
        {
            myJob = new Job(null, need.restoreNeedFurn.objectType, need.CompleteJobNorm, need.restoreNeedTime, null, Job.JobPriority.High, false, true, false);
        }
        if (needPercent == 100 && need != null && need.completeOnFail)
        {
            myJob = new Job(CurrTile, null, need.CompleteJobCrit, need.restoreNeedTime * 10, null, Job.JobPriority.High, false, true, true);
        }
        // Get the first job on the queue.
        if (myJob == null)
        {
            myJob = World.current.jobQueue.Dequeue();
        }

        if (myJob == null)
        {
            Debug.Log(name + " did not find a job.");
            myJob = new Job(
                CurrTile,
                "Waiting",
                null,
                UnityEngine.Random.Range(0.1f, 0.5f),
                null,
                Job.JobPriority.Low,
                false);
        }
        else
        {
            if (myJob.tile == null)
            {
                Debug.Log(name + " found a job.");
            }
            else
            {
                Debug.Log(name + " found a job at x " + myJob.tile.X + " y " + myJob.tile.Y + ".");
            }
        }

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

        // If the dest tile does not have neighbours it's very
        if ((DestTile == null || DestTile.HasNeighboursOfType(TileType.Floor) || DestTile.HasNeighboursOfType(TileType.Ladder)) == false)
        {
            Debug.Log("No neighbouring floor tiles! Abandoning job.");
            AbandonJob(false);
            return;
        }

        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");
        if (myJob.isNeed)
        {
            pathAStar = new Path_AStar(World.current, CurrTile, DestTile, need.restoreNeedFurn.objectType, 0, false, true);     // This will calculate a path from curr to dest.
        }
        else
        {
            pathAStar = new Path_AStar(World.current, CurrTile, DestTile);
        }
        Profiler.EndSample();

        if (pathAStar != null && pathAStar.Length() == 0)
        {
            Debug.Log("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;
        }
    }
Exemplo n.º 17
0
    void Update_DoMovement(float _deltaTime)
    {
        //if we don't need to move, don't move, we're already here
        if (currentTile == DestinationTile)
        {
            pathAStar = null;
            return;
        }

        if (nextTile == null || nextTile == currentTile)
        {
            //Get next tile from pathfinder
            if (pathAStar == null || pathAStar.Length() == 0)
            {
                //generate a path
                pathAStar = new Path_AStar(currentTile.World, currentTile, DestinationTile); //calculate a path from the current tile to the destination tile
                if (pathAStar.Length() == 0)
                {
                    Debug.LogError("Character -- Update_DoMovement: Path_AStar returned no path to destination");
                    AbandonJob();
                    return;
                }
                //ignore the first tile, it is what we're on
                nextTile = pathAStar.Dequeue();
            }


            //Grab next waypoint
            nextTile = pathAStar.Dequeue();
            if (nextTile == currentTile)
            {
                Debug.LogError("Character-- Update_DoMovement: nextTile is equal to currentTile");
            }
        }

        //if (pathAStar.Length() == 1)
        //    return;

        //At this point we should have a valid nextTile


        //total distance from point A to point B
        float distanceToTravel = Mathf.Sqrt(Mathf.Pow(currentTile.X - nextTile.X, 2) + Mathf.Pow(currentTile.Y - nextTile.Y, 2));

        if (nextTile.IsEnterable() == ENTERABILITY.Never)
        {
            Debug.LogError("Character -- Update_DoMovement: A character tried to enter an unwalkable tile");
            //the next tile shouldn't be walked on, so the path info is outdated and need to be updated (e.g. a wall was built here after the path was made)
            nextTile  = null;
            pathAStar = null;
            return;
        }
        else if (nextTile.IsEnterable() == ENTERABILITY.Soon)
        {
            //We can't enter the tile now, but we should be able to in the near future. This tile is likely a door, so we will return until the tile is enterable
            //then we process the movement and move thrugh the tile

            return;
        }

        //How much distance can we travel this update
        float distanceThisFrame = speed / nextTile.MovementCost * _deltaTime;


        //How mush is that in terms of percentage to our destination
        float percentageThisFrame = distanceThisFrame / distanceToTravel;

        //add to overall percentage travel
        movementPercentage += percentageThisFrame;

        //if we have reached the destination
        if (movementPercentage >= 1)
        {
            currentTile        = nextTile;
            movementPercentage = 0;
        }
    }
Exemplo n.º 18
0
    /// <summary>
    /// Checks weather the current job has all the materials in place and if not instructs the working character to get the materials there first.
    /// Only ever returns true if all materials for the job are at the job location and thus signals to the calling code, that it can proceed with job execution.
    /// </summary>
    /// <returns></returns>
    bool CheckForJobMaterials()
    {
        if (myJob.HasAllMaterial())
        {
            return(true); //we can return early
        }
        // Job still needs materials
        // Am I carrying anything the job location wants?
        if (inventory != null)
        {
            if (myJob.DesiresInventoryType(inventory) > 0)
            {
                // If so, deliver
                // Walk to the job tile then drop off the stack into the job
                if (CurrTile == myJob.tile)
                {
                    // We are at the job site so drop the inventory
                    World.Current.inventoryManager.PlaceInventory(myJob, inventory);
                    myJob.DoWork(0);  // This will call all cbJobWorked callbacks

                    //at this point we should dump anything in our inventory
                    DumpExcessInventory();
                }
                else
                {
                    // Walk to job site
                    DestTile = myJob.tile;
                    return(false);
                }
            }
            else
            {
                // We are carrying something but the job doesn't want it
                // Dump it
                DumpExcessInventory();
            }
        }
        else
        {
            // At this point, the job still requires inventory but we aren't carrying it
            // Are we standing on a tile with goods desired by job?
            if (CurrTile.inventory != null &&
                myJob.DesiresInventoryType(CurrTile.inventory) > 0 &&
                (myJob.canTakeFromStockpile || CurrTile.furniture == null || CurrTile.furniture.IsStockpile() == false))
            {
                // Pick up the stuff
                World.Current.inventoryManager.PlaceInventory(
                    this,
                    CurrTile.inventory,
                    myJob.DesiresInventoryType(CurrTile.inventory)
                    );
            }
            else
            {
                // If not, walk towards a tile containing the required goods

                // Find the first thing in the job that isn't satisfied
                Inventory desired = myJob.GetFirstDesiredInventory();

                if (CurrTile != NextTile)
                {
                    // We are still moving somewhere so just bail out
                    return(false);
                }

                // Any chance we already have a path that leads to the items we want?
                if (pathAStar != null && pathAStar.EndTile() != null && pathAStar.EndTile().inventory != null && pathAStar.EndTile().inventory.objectType == desired.objectType)
                {
                    // We are already moving towards a tile that we want so do nothing
                }
                else
                {
                    Path_AStar newPath = World.Current.inventoryManager.GetPathToClosestInventoryOfType(
                        desired.objectType,
                        CurrTile,
                        desired.maxStackSize - desired.stackSize,
                        myJob.canTakeFromStockpile
                        );

                    if (newPath == null || newPath.Length() == 0)
                    {
                        Debug.Log("No tile contains objects of type " + desired.objectType + "to satisfy job requirements");
                        AbandonJob();
                        return(false);
                    }

                    Debug.Log("pathAStar returned with length of: " + newPath.Length());

                    DestTile = newPath.EndTile();

                    // Since we already have a path calculated let's just save that
                    pathAStar = newPath;

                    // Ignore the first tile because that's the tile we're already in
                    NextTile = newPath.Dequeue();
                }

                // One way or the other, we are now on route to an object of the right type
                return(false);
            }
        }

        return(false); // Can't continue until all materials are satisifed
    }
Exemplo n.º 19
0
    void Update_DoMovement(float deltaTime)
    {
        if (CurrTile == DestTile)
        {
            pathAStar = null;
            return; // Already there
        }

        // currTile = the tile I'm currently in (and may be leaving)
        // nextTile = the tile I'm currently entering
        // destTile = Our final destination -- we never walk here directly, but instead use it for the pathfinder

        if (NextTile == null || NextTile == CurrTile)
        {
            // Get the next tile from the pathfinder
            if (pathAStar == null || pathAStar.Length() == 0)
            {
                // Generate a path to our destination
                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();
                    return;
                }

                // Let's ignore the first tile because that's the tile we're currently in
                NextTile = pathAStar.Dequeue();
            }

            // Grab the next waypoint from the pathing system!
            NextTile = pathAStar.Dequeue();

            if (NextTile == CurrTile)
            {
                Debug.LogError("Update_DoMovement - nextTile is currTile?");
            }
        }

        // At this point we should have a valid nextTile to move to

        // Total distance between A and B
        // Euclidean distance for now; for pathfinding change to Manhattan or something else
        float distToTravel = Mathf.Sqrt(
            Mathf.Pow(CurrTile.X - NextTile.X, 2) +
            Mathf.Pow(CurrTile.Y - NextTile.Y, 2)
            );

        if (NextTile.IsEnterable() == ENTERABILITY.Never)
        {
            // Most likely a wall got built, so we need to reset pathfinding
            // FIXME: when a wall gets spanwed, invalidate path immediately. or check sometimes to save CPU.
            // or register a callback to ontilechanged event
            Debug.LogError("Fix me - character trying to walk through unwalkable  tile");
            NextTile  = null;   // our next tile is a no-go
            pathAStar = null;   // pathfinding info is out of date
            return;
        }
        else if (NextTile.IsEnterable() == ENTERABILITY.Soon)
        {
            // Can't enter now but should be able to in the future.(Door?)
            // Don't bail on movement path but return now and don't process movement.
            return;
        }

        // How much distance can be travelled this Update
        float distThisFrame = speed / NextTile.movementCost * deltaTime;

        // How much is that in terms of percentage
        float percThisFrame = distThisFrame / distToTravel;

        // Add that to overall percentage travelled
        movementPercentage += percThisFrame;

        if (movementPercentage >= 1)
        {
            // Reached destination

            // TODO: get the next tile from pathfinding system

            CurrTile           = NextTile;
            movementPercentage = 0;

            // FIXME: Overshot movement?
        }
    }
Exemplo n.º 20
0
        private void Update_DoMovement(float deltaTime)
        {
            if (currTile == destTile)
            {
                pathAStar = null;
                return; // We're already were we want to be.
            }

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

                    // Ignore the first tile in the path, as that's the tile we are currently in,
                    // and we can always move out of our current tile.
                    nextTile = pathAStar.Dequeue();
                }

                // Grab the next waypoint from the pathing system!
                nextTile = pathAStar.Dequeue();


                if (nextTile == currTile)
                {
                    //Debug.LogError("Update_DoMovement - nextTile is currTile?");
                }
            }

            /*		if(pathAStar.Length() == 1) {
             *          return;
             *      }
             */
            // At this point we should have a valid nextTile to move to.

            // 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 != currTile)
            {
                distToTravel = (float)Math.Sqrt(
                    Math.Pow(currTile.X - nextTile.X, 2) +
                    Math.Pow(currTile.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)
            {
                // Debug.LogError("Error - character was strying to enter an impassable tile!");
                nextTile  = currTile;
                pathAStar = null;
            }
            else 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.
                return;
            }

            // How much distance can be travel this Update?
            var distThisFrame = (speed / nextTile.MovementCost) * deltaTime;

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

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

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

                // TODO: Get the next tile from the pathfinding system.
                //       If there are no more tiles, then we have TRULY
                //       reached our destination.

                currTile           = nextTile;
                movementPercentage = 0;
                // FIXME?  Do we actually want to retain any overshot movement?
            }
        }
Exemplo n.º 21
0
    void DoMovement()
    {
        if (curTile == DestTile)
        {
            // We made it
            StopMove();
            return;
        }


        if (nextTile == null || nextTile == curTile)
        {
            // Get the next tile
            if (path == null || path.Length() == 0)
            {
                // Generate path
                path = new Path_AStar(activeArea, curTile, DestTile);
                if (path.Length() == 0)
                {
                    StopMove();
                    // Debug.LogError("Enemy's PathAStar did not return a path!");
                    return;
                }

                // Ignore the first tile since we are on it
                nextTile = path.Dequeue();
            }

            nextTile = path.Dequeue();

            SetDirection();

            ENTERABILITY nextTileEnterability = nextTile.CanEnter();
            switch (nextTileEnterability)
            {
            case ENTERABILITY.Never:
                // Cant go on
                StopMove();
                return;
            }

            if (nextTile == curTile)
            {
                StopMove();
                return;
            }
        }
        // How much distance can we travel this frame?
        float distToTravel = Mathf.Sqrt(
            Mathf.Pow(curTile.X - nextTile.X, 2) +
            Mathf.Pow(curTile.Y - nextTile.Y, 2));

        // How much distance can we travel this frame?
        float distThisFrame = speed.GetValue() / nextTile.MovementCost * Time.deltaTime;

        float perThisFrame = distThisFrame / distToTravel;

        movePercent += perThisFrame;

        if (movePercent >= 1)
        {
            movePercent = 0;
            curTile     = nextTile;
        }
    }
Exemplo n.º 22
0
    // Set Patrol Point in 4 Quadrant
    public void SetValidPatrolPoints(World world)
    {
        minionState  = MinionState.Patrol;
        patrolPoints = new List <Tile>();

        if (patrolRange == 0)
        {
            return;
        }

        // Set tile graph width and height
        int startW = charStartTile.X - patrolRange <= 0 ? 0 : charStartTile.X - patrolRange;
        int endW   = charStartTile.X + patrolRange >= world.Width - 1 ? world.Width - 1 : charStartTile.X + patrolRange;
        //Debug.Log("StartWidth : " + startW + "EndWidth : " + endW);
        int startH = charStartTile.Z - patrolRange <= 0 ? 0 : charStartTile.Z - patrolRange;
        int endH   = charStartTile.Z + patrolRange >= world.Height - 1 ? world.Height - 1 : charStartTile.Z + patrolRange;

        //Debug.Log("StartHeight : " + startH + "EndHeight  : " + endH);

        // Create Tile Graph within Patrol range
        mTileGraph = new Path_TileGraph(startW, endW, startH, endH);

        //// Check 4 Quadrant have at least 1 patrol tile?
        Tile LUtile = null;
        Tile RUtile = null;
        Tile LLtile = null;
        Tile RLtile = null;

        // ======Loop Outer in 4 Quadrant============

        // Left-Lower Q ,X(min > max), Z(min > max)
        // Loop the X axis farest tile
        for (int x = startW; x < charStartTile.X; x++)
        {
            int  z      = startH;
            Tile checkT = world.GetTileAt(x, z);
            if (LLtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add LLtile to patrol point : " + checkT.X + "," + checkT.Z);
                    LLtile = checkT;
                }
            }
        }
        // Loop the Z axis farest tile
        for (int z = startH; z < charStartTile.Z; z++)
        {
            int  x      = startW;
            Tile checkT = world.GetTileAt(x, z);
            //Debug.Log("Check tile : " + checkT.X + "," + checkT.Z);

            // Check the farest tile first and Check it not CharTile
            if (LLtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add LLtile to patrol point : " + checkT.X + "," + checkT.Z);
                    LLtile = checkT;
                }
            }
        }


        // Left-Upper Q ,X(min > max),Z(max > min)
        // Loop the X axis farest tile
        for (int x = startW; x <= charStartTile.X; x++)
        {
            int  z      = endH;
            Tile checkT = world.GetTileAt(x, z);
            if (LUtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add LUtile to patrol point : " + checkT.X + "," + checkT.Z);
                    LUtile = checkT;
                }
            }
        }
        // Loop the Z axis farest tile
        for (int z = endH; z >= charStartTile.Z; z--)
        {
            int  x      = startW;
            Tile checkT = world.GetTileAt(x, z);

            // Check the farest tile first and Check it not CharTile
            if (LUtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add LUtile to patrol point : " + checkT.X + "," + checkT.Z);
                    LUtile = checkT;
                }
            }
        }


        // Right-Upper Q ,X(max > min),Z(max > min)
        // Loop the X axis farest tile
        for (int x = endW; x >= charStartTile.X; x--)
        {
            int  z      = endH;
            Tile checkT = world.GetTileAt(x, z);

            // Check the farest tile first and Check it not CharTile
            if (RUtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add RUtile to patrol point : " + checkT.X + "," + checkT.Z);
                    RUtile = checkT;
                }
            }
        }
        // Loop the Z axis farest tile
        for (int z = endH; z >= charStartTile.Z; z--)
        {
            int  x      = endW;
            Tile checkT = world.GetTileAt(x, z);

            // Check the farest tile first and Check it not CharTile
            if (RUtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add RUtile to patrol point : " + checkT.X + "," + checkT.Z);
                    RUtile = checkT;
                }
            }
        }


        // Right-Lower Q ,X(max > min),Z(min > max)
        // Loop the X axis farest tile
        for (int x = endW; x >= charStartTile.X; x--)
        {
            int  z      = startH;
            Tile checkT = world.GetTileAt(x, z);

            // Check the farest tile first and Check it not CharTile
            if (RLtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add RLtile to patrol point : " + checkT.X + "," + checkT.Z);
                    RLtile = checkT;
                }
            }
        }
        // Loop the Z axis farest tile
        for (int z = startH; z > charStartTile.Z; z++)
        {
            int  x      = startW;
            Tile checkT = world.GetTileAt(x, z);

            // Check the farest tile first and Check it not CharTile
            if (RLtile == null && checkT != charStartTile)
            {
                mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                // There is valid pathfinder to this tile
                if (mPathAStar.Length() != 0)
                {
                    Debug.Log("Add RLtile to patrol point : " + checkT.X + "," + checkT.Z);
                    RLtile = checkT;
                }
            }
        }

        // ======== Loop Inner in 4 Quadrant ==========

        // Left-Lower Q ,X(min > max), Z(min > max)
        // Loop the inner tile
        if (LLtile == null)
        {
            for (int x = startW + 1; x < charStartTile.X; x++)
            {
                for (int z = startH + 1; z < charStartTile.Z; z++)
                {
                    Tile checkT = world.GetTileAt(x, z);
                    if (LLtile == null && checkT != charStartTile)
                    {
                        mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                        // There is valid pathfinder to this tile
                        if (mPathAStar.Length() != 0)
                        {
                            Debug.Log("Add LLtile to patrol point : " + checkT.X + "," + checkT.Z);
                            LLtile = checkT;
                        }
                    }
                }
            }
        }


        // Left-Upper Q ,X(min > max),Z(max > min)
        // Loop the X axis farest tile
        if (LUtile == null)
        {
            for (int x = startW + 1; x <= charStartTile.X; x++)
            {
                for (int z = endH - 1; z >= charStartTile.Z; z--)
                {
                    Tile checkT = world.GetTileAt(x, z);
                    if (LUtile == null && checkT != charStartTile)
                    {
                        mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                        // There is valid pathfinder to this tile
                        if (mPathAStar.Length() != 0)
                        {
                            Debug.Log("Add LUtile to patrol point : " + checkT.X + "," + checkT.Z);
                            LUtile = checkT;
                        }
                    }
                }
            }
        }

        // Right-Upper Q ,X(max > min),Z(max > min)
        // Loop the X axis farest tile
        if (RUtile == null)
        {
            for (int x = endW - 1; x >= charStartTile.X; x--)
            {
                for (int z = endH - 1; z >= charStartTile.Z; z--)
                {
                    Tile checkT = world.GetTileAt(x, z);

                    // Check the farest tile first and Check it not CharTile
                    if (RUtile == null && checkT != charStartTile)
                    {
                        mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                        // There is valid pathfinder to this tile
                        if (mPathAStar.Length() != 0)
                        {
                            Debug.Log("Add RUtile to patrol point : " + checkT.X + "," + checkT.Z);
                            RUtile = checkT;
                        }
                    }
                }
            }
        }


        // Right-Lower Q ,X(max > min),Z(min > max)
        // Loop the X axis farest tile
        if (RLtile == null)
        {
            for (int x = endW - 1; x >= charStartTile.X; x--)
            {
                for (int z = startH + 1; z < charStartTile.Z; z++)
                {
                    Tile checkT = world.GetTileAt(x, z);

                    // Check the farest tile first and Check it not CharTile
                    if (RLtile == null && checkT != charStartTile)
                    {
                        mPathAStar = new Path_AStar(false, charStartTile, checkT, mTileGraph, startW, endW, startH, endH);
                        // There is valid pathfinder to this tile
                        if (mPathAStar.Length() != 0)
                        {
                            Debug.Log("Add RLtile to patrol point : " + checkT.X + "," + checkT.Z);
                            RLtile = checkT;
                        }
                    }
                }
            }
        }


        if (LUtile != null)
        {
            patrolPoints.Add(LUtile);
        }
        if (RUtile != null)
        {
            patrolPoints.Add(RUtile);
        }
        if (LLtile != null)
        {
            patrolPoints.Add(LLtile);
        }
        if (RLtile != null)
        {
            patrolPoints.Add(RLtile);
        }
    }
Exemplo n.º 23
0
    void Update_DoMovement(float deltaTime)
    {
        if (currTile == destTile)
        {
            path_AStar = null;
            return;
        }
        if (nextTile == null || nextTile == currTile)
        {
            //get the next tile from pathfinding
            if (path_AStar == null || path_AStar.Length() == 0)
            {
                path_AStar = new Path_AStar(WorldController.Instance.World, currTile, destTile);
                if (path_AStar.Length() == 0)
                {
                    Debug.LogError("Path_AStar returned no path to destination");
                    AbandonJob();
                    path_AStar = null;
                    return;
                }
                nextTile = path_AStar.GetNextTile();
            }
            nextTile = path_AStar.GetNextTile();  //removes it from the path list
            if (nextTile == currTile)
            {
                Debug.Log("Update_DoMovement::NextTile is curr tile ?");
            }
        }

        float        totalDisToTravel = Vector3Int.Distance(currTile, nextTile); //total distance from A to B
        float        movementCost     = 1;
        ENTERABILITY enterability     = ENTERABILITY.Yes;

        if (WorldController.Instance.World.foundationGameMap.ContainsKey(nextTile) == true)
        {
            movementCost = WorldController.Instance.World.foundationGameMap[nextTile].movementCost;
            try{
                enterability = WorldController.Instance.World.foundationGameMap[nextTile].IsEnterable(WorldController.Instance.World.foundationGameMap[nextTile]);
            }
            catch { enterability = ENTERABILITY.Never; }
            if (movementCost > 0 && enterability == ENTERABILITY.Never)
            {
                enterability = ENTERABILITY.Yes;
            }
        }
        if (enterability == ENTERABILITY.Never)
        {
            Debug.LogError("Character " + name + " was trying to enter an unwalkable tile");
            nextTile   = currTile;
            path_AStar = null;
            return;
        }
        else if (enterability == ENTERABILITY.Soon)
        {
            //Have to wait to enter the tile, this is likely a door
            //No bailing on the movement/path, but we do return now and don't actually process the movement;
            return;
        }
        float distanceThisFrame   = speed / movementCost * deltaTime;     //how much distance can character tavel this update
        float percantageThisFrame = distanceThisFrame / totalDisToTravel; //how much is that in percentage

        movementPercentage += percantageThisFrame;                        //increase percentage moved
        if (movementPercentage >= 1)
        {
            //Destination reached
            currTile           = nextTile;
            movementPercentage = 0;
        }
        if (cbCharacterMoved != null)
        {
            cbCharacterMoved(this);
        }
    }
Exemplo n.º 24
0
    void Update_DoMovement(float deltaTime)
    {
        if (CurrTile == DestTile)
        {
            pathAStar = null;
            return;     // We're already were we want to be.
        }

        // currTile = The tile I am currently in (and may be in the process of leaving)
        // nextTile = The tile I am currently entering
        // destTile = Our final destination -- we never walk here directly, but instead use it for the pathfinding

        if (NextTile == null || NextTile == CurrTile)
        {
            // Get the next tile from the pathfinder.
            if (pathAStar == null || pathAStar.Length() == 0)
            {
                // Generate a path to our destination
                pathAStar = new Path_AStar(World.current, CurrTile, DestTile);  // This will calculate a path from curr to dest.
                if (pathAStar.Length() == 0)
                {
                    Debug.LogError("Path_AStar returned no path to destination!");
                    AbandonJob();
                    return;
                }

                // Let's ignore the first tile, because that's the tile we're currently in.
                NextTile = pathAStar.Dequeue();
            }


            // Grab the next waypoint from the pathing system!
            NextTile = pathAStar.Dequeue();

            if (NextTile == CurrTile)
            {
                //Debug.LogError("Update_DoMovement - nextTile is currTile?");
            }
        }

        // At this point we should have a valid nextTile to move to.

        // 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 = Mathf.Sqrt(
            Mathf.Pow(CurrTile.X - NextTile.X, 2) +
            Mathf.Pow(CurrTile.Y - NextTile.Y, 2)
            );

        if (NextTile.IsEnterable() == ENTERABILITY.Never)
        {
            // Most likely a wall got built, so we just need to reset our pathfinding information.
            // FIXME: Ideally, when a wall gets spawned, we should invalidate our path immediately,
            //		  so that we don't waste a bunch of time walking towards a dead end.
            //		  To save CPU, maybe we can only check every so often?
            //		  Or maybe we should register a callback to the OnTileChanged event?
            Debug.LogError("FIXME: A character was trying to enter an unwalkable tile.");
            NextTile  = null;   // our next tile is a no-go
            pathAStar = null;   // clearly our pathfinding info is out of date.
            return;
        }
        else if (NextTile.IsEnterable() == ENTERABILITY.Soon)
        {
            // We can't enter the NOW, but we should be able to in the
            // future. This is likely a DOOR.
            // So we DON'T bail on our movement/path, but we do return
            // now and don't actually process the movement.
            return;
        }

        // How much distance can be travel this Update?
        float distThisFrame = speed / NextTile.movementCost * 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

            // TODO: Get the next tile from the pathfinding system.
            //       If there are no more tiles, then we have TRULY
            //       reached our destination.

            CurrTile           = NextTile;
            movementPercentage = 0;
            // FIXME?  Do we actually want to retain any overshot movement?
        }
    }
Exemplo n.º 25
0
    /// <summary>
    /// Checks weather the current job has all the materials in place and if not instructs the working character to get the materials there first.
    /// Only ever returns true if all materials for the job are at the job location and thus signals to the calling code, that it can proceed with job execution.
    /// </summary>
    /// <returns></returns>
    bool CheckForJobMaterials()
    {
        if (myJob.HasAllMaterial())
        {
            return(true); //we can return early
        }
        // At this point we know, that the job still needs materials.
        // First we check if we carry any materials the job wants by chance.
        if (inventory != null)
        {
            if (myJob.DesiresInventoryType(inventory) > 0)
            {
                // If so, deliver the goods.
                // Walk to the job tile, then drop off the stack into the job.
                if (CurrTile == myJob.tile)
                {
                    // We are at the job's site, so drop the inventory
                    World.current.inventoryManager.PlaceInventory(myJob, inventory);
                    myJob.DoWork(0); // This will call all cbJobWorked callbacks, because even though
                                     // we aren't progressing, it might want to do something with the fact
                                     // that the requirements are being met.

                    //at this point we should dump anything in our inventory
                    DumpExcessInventory();
                }
                else
                {
                    // We still need to walk to the job site.
                    DestTile = myJob.tile;
                    return(false);
                }
            }
            else
            {
                // We are carrying something, but the job doesn't want it!
                // Dump the inventory so we can be ready to carry what the job actually wants.
                DumpExcessInventory();
            }
        }
        else
        {
            // At this point, the job still requires inventory, but we aren't carrying it!

            // Are we standing on a tile with goods that are desired by the job?
            Debug.Log("Standing on Tile check");
            if (CurrTile.inventory != null &&
                myJob.DesiresInventoryType(CurrTile.inventory) > 0 &&
                (myJob.canTakeFromStockpile || CurrTile.furniture == null || CurrTile.furniture.IsStockpile() == false))
            {
                // Pick up the stuff!
                Debug.Log("Pick up the stuff");

                World.current.inventoryManager.PlaceInventory(
                    this,
                    CurrTile.inventory,
                    myJob.DesiresInventoryType(CurrTile.inventory)
                    );
            }
            else
            {
                // Walk towards a tile containing the required goods.
                Debug.Log("Walk to the stuff");
                Debug.Log(myJob.canTakeFromStockpile);


                // Find the first thing in the Job that isn't satisfied.
                Inventory desired = myJob.GetFirstDesiredInventory();

                if (CurrTile != NextTile)
                {
                    // We are still moving somewhere, so just bail out.
                    return(false);
                }

                // Any chance we already have a path that leads to the items we want?
                if (pathAStar != null && pathAStar.EndTile() != null && pathAStar.EndTile().inventory != null && (pathAStar.EndTile().furniture != null && !(myJob.canTakeFromStockpile == false && pathAStar.EndTile().furniture.IsStockpile() == true)) && pathAStar.EndTile().inventory.objectType == desired.objectType)
                {
                    // We are already moving towards a tile that contains what we want!
                    // so....do nothing?
                }
                else
                {
                    Path_AStar newPath = World.current.inventoryManager.GetPathToClosestInventoryOfType(
                        desired.objectType,
                        CurrTile,
                        desired.maxStackSize - desired.stackSize,
                        myJob.canTakeFromStockpile
                        );

                    if (newPath == null || newPath.Length() < 1)
                    {
                        //Debug.Log("pathAStar is null and we have no path to object of type: " + desired.objectType);
                        // Cancel the job, since we have no way to get any raw materials!
                        Debug.Log("No tile contains objects of type '" + desired.objectType + "' to satisfy job requirements.");
                        AbandonJob();
                        return(false);
                    }

                    Debug.Log("pathAStar returned with length of: " + newPath.Length());

                    DestTile = newPath.EndTile();

                    // Since we already have a path calculated, let's just save that.
                    pathAStar = newPath;

                    // Ignore first tile, because that's what we're already in.
                    NextTile = newPath.Dequeue();
                }

                // One way or the other, we are now on route to an object of the right type.
                return(false);
            }
        }

        return(false); // We can't continue until all materials are satisfied.
    }
Exemplo n.º 26
0
//	Job myJob;
//
//	void Update_DoJob (float deltaTime) {
//		if (myJob == null) {
//			myJob = currTile.world.jobQueue.Dequeue ();
//
//			if (myJob != null) {
//				// I got a job!
//				destTile = myJob.tile;
//
//				// Register the ended job callback
//				myJob.RegisterJobCompleteCallback (OnJobEnded);
//				myJob.RegisterJobCancelCallback (OnJobEnded);
//			}
//		}
//
//		// moving the character
//		if (myJob != null && currTile == myJob.tile) {
//			myJob.DoJob(deltaTime);
//		}
//
//	}
//
//	public void AbandonJob() {
//		nextTile = destTile = currTile;
//		pathAStar = null;
//		currTile.world.jobQueue.Enqueue(myJob);
//		myJob = null;
//	}

    void Update_DoMovement(float deltaTime)
    {
        if (currTile == destTile)
        {
            pathAStar = null;
            return;             // where are already where we want to be
        }

        if (nextTile == null || nextTile == currTile)
        {
            // get the next tile from the pathfinder
            if (pathAStar == null || pathAStar.Length() == 0)
            {
                // generate a new path to our destination
                pathAStar = new Path_AStar(WorldController.Instance.world, currTile, destTile);
                if (pathAStar.Length() == 0)
                {
                    //Debug.LogError ("pathAStar returned no path to destination");
                    // FIXME: the job should be re-enqued
//					AbandonJob ();
                    pathAStar = null;
                    return;
                }
                nextTile = pathAStar.Dequeue();
            }
            // FIXME: discarding the first node, the current tile of the character
            // from the pathfinding system. Maybe there's a better way?


            nextTile = pathAStar.Dequeue();

            if (nextTile == currTile)
            {
                Debug.LogError("Update_DoMovement: nextTile is currTile?");
            }
        }

        float distToTravel = Vector2.Distance(new Vector2(currTile.X, currTile.Y), new Vector2(nextTile.X, nextTile.Y));

        // float distToTravel = Mathf.Sqrt (Mathf.Pow (currTile.X - nextTile.X, 2) + Mathf.Pow (currTile.Y - nextTile.Y, 2));


        if (nextTile.movementCost == 0)
        {
            //FIXME : this is getting called too much. shouldnt be at all?
            Debug.LogError("character trying to traverse an unwalkble tile");
            nextTile  = null;
            pathAStar = null;
            return;
        }
        float percThisFram = (speed * deltaTime) / (distToTravel * nextTile.movementCost);

        movementPercentage += percThisFram;

        if (movementPercentage >= 1)
        {
            // get the next destination tile from the pathfinding system

            currTile           = nextTile;
            movementPercentage = 0;
        }
    }
Exemplo n.º 27
0
    private void Update_DoMovement(float deltaTime)
    {
        if (CurrTile == DestTile)
        {
            // We're already were we want to be.
            pathAStar = null;
            IsWalking = false;
            VisualPath.Instance.RemoveVisualPoints(name);
            return;
        }

        if (nextTile == null || nextTile == CurrTile)
        {
            // Get the next tile from the pathfinder.
            if (pathAStar == null || pathAStar.Length() == 0)
            {
                // Generate a path to our destination.
                // This will calculate a path from current tile to destination tile.
                pathAStar = new Path_AStar(World.Current, CurrTile, DestTile);
                if (pathAStar.Length() == 0)
                {
                    Debug.ULogErrorChannel("Character", "Path_AStar returned no path to destination!");
                    AbandonJob(false);
                    return;
                }

                // Let's ignore the first tile, because that's the tile we're currently in.
                nextTile = pathAStar.Dequeue();
            }

            if (IsSelected)
            {
                VisualPath.Instance.SetVisualPoints(name, pathAStar.GetList());
            }

            IsWalking = true;

            // Grab the next waypoint from the pathing system!
            nextTile = pathAStar.Dequeue();

            if (nextTile == CurrTile)
            {
                IsWalking = false;
            }
        }

        if (nextTile.IsEnterable() == Enterability.Never)
        {
            //// Most likely a wall got built, so we just need to reset our pathfinding information.
            //// FIXME: Ideally, when a wall gets spawned, we should invalidate our path immediately,
            ////            so that we don't waste a bunch of time walking towards a dead end.
            ////            To save CPU, maybe we can only check every so often?
            ////            Or maybe we should register a callback to the OnTileChanged event?
            //// Debug.ULogErrorChannel("FIXME", "A character was trying to enter an unwalkable tile.");
            nextTile  = null;   // our next tile is a no-go
            pathAStar = null;   // clearly our pathfinding info is out of date.
            return;
        }
        else if (nextTile.IsEnterable() == Enterability.Soon)
        {
            // We can't enter the NOW, but we should be able to in the
            // future. This is likely a DOOR.
            // So we DON'T bail on our movement/path, but we do return
            // now and don't actually process the movement.
            return;
        }

        CharacterFacing();

        // At this point we should have a valid nextTile to move to.
        // 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 = Mathf.Sqrt(
            Mathf.Pow(CurrTile.X - nextTile.X, 2) +
            Mathf.Pow(CurrTile.Y - nextTile.Y, 2));

        // How much distance can be travel this Update?
        float distThisFrame = speed / nextTile.MovementCost * 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

            //// TODO: Get the next tile from the pathfinding system.
            ////       If there are no more tiles, then we have TRULY
            ////       reached our destination.

            CurrTile           = nextTile;
            movementPercentage = 0;

            // FIXME?  Do we actually want to retain any overshot movement?
        }
    }
Exemplo n.º 28
0
    void Update_DoMovement(float deltaTime)
    {
        if (currTile == destTile)
        {
            pathAStar = null;
            return;            //we're already were we want to be.
        }

        if (nextTile == null || nextTile == currTile)
        {
            //get the next tile from the pathfinder
            if (pathAStar == null || pathAStar.Length() == 0)
            {
                //calculate a path from curr to dest
                pathAStar = new Path_AStar(currTile.world, currTile, destTile);
                if (pathAStar.Length() == 0)
                {
                    Debug.LogError("Path_AStar returned no path to destination !");
                    AbandonJob();
                    pathAStar = null;
                    return;
                }
            }
            //grab the next waypoint from the pathfinding system
            nextTile = pathAStar.Dequeue();

            if (nextTile == currTile)
            {
                Debug.LogError("Update_DoMovement - nextTile is currTile ?");
            }
        }

/*		if(pathAStar.Length() == 1 ){
 *                      return;
 *              }
 */
        //at this point we should have a valid nextTile  to move to !



        //on détermnie la distance entre les deux points theoreme de pythagore mec ??
        //for now it is euclidian, but when pathfinding system we do, manhattan or chebyshev system BRO !!
        //Pow !!!
        //public static float Pow(float f, float p);
        //Returns f raised to power p.
        //public static float Sqrt(float f); -- Returns square root of f.
        float distToTravel = Mathf.Sqrt(Mathf.Pow(currTile.X - nextTile.X, 2) + Mathf.Pow(currTile.Y - nextTile.Y, 2));

        //on détermine la distance par frame pour qu'elle soit égale quelque que soit le nombre de fps
        //how much distance can be traveled this update
        float distThisFrame = speed * deltaTime;

        // how much is that in terms of percentage to our destination ? (de 0 a 1)
        float percThisFrame = distThisFrame / distToTravel;

        //add that overall poercentage travelled
        movementPercentage += percThisFrame;

        if (movementPercentage >= 1)
        {
            //we have reached our destination

            //TODO : get the next tile from the pathfinding system
            //If there are no more tiles, then we have TRULKY reach our destination

            currTile           = nextTile;
            movementPercentage = 0;
            //FIXME do we actually want to retain any overshot movement ?
        }
    }
Exemplo n.º 29
0
    /// <summary>
    /// Checks whether the current job has all the materials in place and if not instructs the working character to get the materials there first.
    /// Only ever returns true if all materials for the job are at the job location and thus signals to the calling code, that it can proceed with job execution.
    /// </summary>
    /// <returns></returns>
    private bool CheckForJobMaterials()
    {
        List <string> fulfillableInventoryRequirements = new List <string>();

        if (MyJob != null && MyJob.IsNeed && MyJob.Critical == false)
        {
            MyJob.tile = jobTile = new Path_AStar(World.Current, CurrTile, null, MyJob.JobObjectType, 0, false, true).EndTile();
        }

        if (MyJob == null || MyJob.MaterialNeedsMet())
        {
            // We can return early.
            return(true);
        }
        else
        {
            fulfillableInventoryRequirements = MyJob.FulfillableInventoryRequirements();

            // If we somehow get here and fulfillableInventoryRequirements is empty then there is a problem!
            if (fulfillableInventoryRequirements == null || fulfillableInventoryRequirements.Count() == 0)
            {
                Debug.ULogChannel("Character", "CheckForJobMaterials: no fulfillable inventory requirements");
                AbandonJob(true);
                return(false);
            }
        }

        // At this point we know that the job still needs materials and these needs are satisfiable.
        // First we check if we carry any materials the job wants by chance.
        if (inventory != null)
        {
            if (MyJob.AmountDesiredOfInventoryType(inventory) > 0)
            {
                // If so, deliver the goods.
                // Walk to the job tile, then drop off the stack into the job.
                if (CurrTile == JobTile)
                {
                    // We are at the job's site, so drop the inventory
                    World.Current.inventoryManager.PlaceInventory(MyJob, inventory);
                    MyJob.DoWork(0); // This will call all cbJobWorked callbacks, because even though
                    // we aren't progressing, it might want to do something with the fact
                    // that the requirements are being met.

                    // at this point we should dump anything in our inventory
                    DumpExcessInventory();
                }
                else
                {
                    // We still need to walk to the job site.
                    DestTile = JobTile;
                    return(false);
                }
            }
            else
            {
                // We are carrying something, but the job doesn't want it!
                // Dump the inventory so we can be ready to carry what the job actually wants.
                DumpExcessInventory();
            }
        }
        else
        {
            // At this point, the job still requires inventory, but we aren't carrying it!
            // Are we standing on a tile with goods that are desired by the job?
            if (CurrTile.Inventory != null &&
                MyJob.AmountDesiredOfInventoryType(CurrTile.Inventory) > 0 && !CurrTile.Inventory.Locked &&
                (MyJob.canTakeFromStockpile || CurrTile.Furniture == null || CurrTile.Furniture.IsStockpile() == false))
            {
                // Pick up the stuff!
                World.Current.inventoryManager.PlaceInventory(
                    this,
                    CurrTile.Inventory,
                    MyJob.AmountDesiredOfInventoryType(CurrTile.Inventory));
            }
            else
            {
                // Walk towards a tile containing the required goods.
                if (CurrTile != nextTile)
                {
                    // We are still moving somewhere, so just bail out.
                    return(false);
                }

                // Any chance we already have a path that leads to the items we want?
                // Check that we have an end tile and that it has content.
                // Check if contains the desired objectType�.
                if (WalkingToUsableInventory() && fulfillableInventoryRequirements.Contains(pathAStar.EndTile().Inventory.ObjectType))
                {
                    // We are already moving towards a tile that contains what we want!
                    // so....do nothing?
                    return(false);
                }
                else
                {
                    Inventory  desired = null;
                    Path_AStar newPath = null;
                    foreach (string itemType in fulfillableInventoryRequirements)
                    {
                        desired = MyJob.inventoryRequirements[itemType];
                        newPath = World.Current.inventoryManager.GetPathToClosestInventoryOfType(
                            desired.ObjectType,
                            CurrTile,
                            desired.MaxStackSize - desired.StackSize,
                            MyJob.canTakeFromStockpile);

                        if (newPath == null || newPath.Length() < 1)
                        {
                            // Try the next requirement
                            Debug.ULogChannel("Character", "No tile contains objects of type '" + desired.ObjectType + "' to satisfy job requirements.");
                            continue;
                        }

                        // else, there is a valid path to an item that will satisfy the job
                        break;
                    }

                    if (newPath == null || newPath.Length() < 1)
                    {
                        // tried all requirements and found no path
                        Debug.ULogChannel("Character", "No reachable tile contains objects able to satisfy job requirements.");
                        AbandonJob(true);
                        return(false);
                    }

                    Debug.ULogChannel("Character", "pathAStar returned with length of: " + newPath.Length());

                    DestTile = newPath.EndTile();

                    // Since we already have a path calculated, let's just save that.
                    pathAStar = newPath;

                    // Ignore first tile, because that's what we're already in.
                    nextTile = newPath.Dequeue();
                }

                // One way or the other, we are now on route to an object of the right type.
                return(false);
            }
        }

        return(false); // We can't continue until all materials are satisfied.
    }
Exemplo n.º 30
0
    /// <summary>
    /// Update all movement related things of a character
    /// </summary>
    /// <param name="deltaTime">The time passed since last tick</param>
    void UpdateCharacter_Movement(float deltaTime)
    {
        // Is movement needed? Is character already at the correct location
        if (currentTile == DestinationTile)
        {
            // Reset the current A* path
            path_AStar = null;
            return;
        }

        // currentTile = The tile a character is currently standing on and might be in the process of leaving
        // nextTile = The tile a character is entering
        // destinationTile = The final destination -- a character never gets here directly, but it's used for pathfinding instead

        // Grab 'next' nextTile
        if (nextTile == null || nextTile == currentTile)
        {
            // Get next tile from the path (calculted path wiht A*)
            if (path_AStar == null || path_AStar.Length() == 0)
            {
                // 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 destination!");
                    // FIXME: Job should get added back to queue
                    AbandonJob();
                    return;
                }

                // Grab the first tile and right away override it.
                // First tile is the file the character is standing on, this results in some problems. (tile might have a movementCost of 0, like a wall that was just build by the character)
                nextTile = path_AStar.DequeueNextTile();
            }

            // Grab the next tile
            nextTile = path_AStar.DequeueNextTile();

            // Check for error
            if (nextTile == currentTile)
            {
                Debug.LogError("UpdateCharacter_Movement: nextTile == currentTile? -- Only valid for startingTile.");
            }
        }

        // At this point there a valid nextTile to move to.

        // Total distance from A to B (pythagorean theorem)
        float totalDistanceToTravel = Mathf.Sqrt(
            Mathf.Pow(currentTile.X - nextTile.X, 2) +
            Mathf.Pow(currentTile.Y - nextTile.Y, 2));

        /// Check if movementCost is 0, which it never should be.
        /// Set nextTile to null, so that the character won't move.
        /// Set path_AStart to null, this one is no longer valid.
        /// MovementCost can be 0 if something was build in the mean time
        if (nextTile.IsEnterable() == EnterAbility.Never)
        {
            Debug.LogError("FIXME: A charcter tried to enter an unwalkable tile!");
            nextTile   = null;
            path_AStar = null;
            return;
        }
        // Character can't enter right now, but will be in the near future. (like a door or something)
        else if (nextTile.IsEnterable() == EnterAbility.Soon)
        {
            // Temp
            return;
        }

        // Distance to travel in one tick (one frame)
        // nextTile.MovementCost can be 0 (which would throw an error) but it should never happen.
        // Moving to a tile with a movementCost of 0 is NOT allowed
        float distanceThisTick = (movementSpeed / nextTile.MovementCost) * deltaTime;

        // Progression in one tick
        float progressionThisTick = distanceThisTick / totalDistanceToTravel;

        // Increase the movement progression each tick
        movementProgression += progressionThisTick;

        // Has the character reached it's destination yet?
        if (movementProgression >= 1)
        {
            currentTile         = nextTile;
            movementProgression = 0;
        }
    }