Exemplo n.º 1
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.º 2
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.º 3
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.º 4
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.º 5
0
    /// <summary>
    /// Gets the type of the closest inventory of.
    /// </summary>
    /// <returns>The closest inventory of type.</returns>
    /// <param name="objectType">Object type.</param>
    /// <param name="t">Tile from, which distance is mesured.</param>
    /// <param name="desiredAmount">Desired amount. If no stack has enough, it instead returns the largest.</param>
    public Inventory GetClosestInventoryOfType(string objectType, Tile t, int desiredAmount, bool canTakeFromStockpile)
    {
        Path_AStar path = GetPathToClosestInventoryOfType(objectType, t, desiredAmount, canTakeFromStockpile);

        return(path.EndTile().Inventory);
    }
Exemplo n.º 6
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.º 7
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.º 8
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.º 9
0
    void Update_DoJob(float deltaTime)
    {
        // Do I have a job?
        jobSearchCooldown -= Time.deltaTime;
        if (myJob == null)
        {
            if (jobSearchCooldown > 0)
            {
                // Don't look for job now.
                return;
            }


            GetNewJob();

            if (myJob == null)
            {
                // There was no job on the queue for us, so just return.
                jobSearchCooldown = UnityEngine.Random.Range(0.1f, 0.5f);
                DestTile          = currTile;
                return;
            }
        }

        // We have a job! (And the job tile is reachable)

        // STEP 1: Does the job have all the materials it needs?
        if (myJob.HasAllMaterial() == false)
        {
            // No, we are missing something!

            // STEP 2: Are we CARRYING anything that the job location wants?
            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.

                        // Are we still carrying things?
                        if (inventory.stackSize == 0)
                        {
                            inventory = null;
                        }
                        else
                        {
                            Debug.LogError("Character is still carrying inventory, which shouldn't be. Just setting to NULL for now, but this means we are LEAKING inventory.");
                            inventory = null;
                        }
                    }
                    else
                    {
                        // We still need to walk to the job site.
                        DestTile = myJob.tile;
                        return;
                    }
                }
                else
                {
                    // We are carrying something, but the job doesn't want it!
                    // Dump the inventory at our feet
                    // TODO: Actually, walk to the nearest empty tile and dump it there.
                    if (World.current.inventoryManager.PlaceInventory(currTile, inventory) == false)
                    {
                        Debug.LogError("Character tried to dump inventory into an invalid tile (maybe there's already something here.");
                        // FIXME: For the sake of continuing on, we are still going to dump any
                        // reference to the current inventory, but this means we are "leaking"
                        // inventory.  This is permanently lost now.
                        inventory = null;
                    }
                }
            }
            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.canTakeFromStockpile || currTile.furniture == null || currTile.furniture.IsStockpile() == false) &&
                    myJob.DesiresInventoryType(currTile.inventory) > 0)
                {
                    // 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;
                    }

                    // 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 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)
                        {
                            //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!
                            AbandonJob();
                            return;
                        }


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

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

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

            return;             // We can't continue until all materials are satisfied.
        }

        // If we get here, then the job has all the material that it needs.
        // Lets make sure that our destination tile is the job site tile.
        DestTile = myJob.tile;

        // Are we there yet?
        if (currTile == myJob.tile)
        {
            // We are at the correct tile for our job, so
            // execute the job's "DoWork", which is mostly
            // going to countdown jobTime and potentially
            // call its "Job Complete" callback.
            myJob.DoWork(deltaTime);
        }

        // Nothing left for us to do here, we mostly just need Update_DoMovement to
        // get us where we want to go.
    }
Exemplo n.º 10
0
        private BehaviourTreeStatus FindRequiredStock_Action()
        {
            //Debug.Log("FindRequiredStock_Action");

            // If the current job has all the materials it needs already, we can just skip this step.
            if (CurrentJob.HasAllMaterial())
            {
                AbandonMove();
                return(BehaviourTreeStatus.Success);
            }

            // The job needs some more materials, perhaps we're holding them already so don't need to go anywhere.
            if (Inventory != null && CurrentJob.NeedsMaterial(Inventory) > 0)
            {
                // We are carrying at least some of what the current job needs, so continue on our merry way.
                AbandonMove();
                return(BehaviourTreeStatus.Success);
            }

            // The job needs some more materials, and we're not carrying it already, so we need to move to where there are some.

            // Perhaps the stock is right where we're stood?
            if (CurrentTile.Inventory != null &&
                (CurrentJob.CanTakeFromStockpile || CurrentTile.Furniture == null || CurrentTile.Furniture.IsStockpile() == false) &&
                (CurrentJob.NeedsMaterial(CurrentTile.Inventory) != 0))
            {
                // The materials we need are right where we're stood!
                AbandonMove();
                return(BehaviourTreeStatus.Success);
            }

            // The Job needs some of this:
            var unsatisfied = CurrentJob.GetFirstRequiredInventory();

            // We might have a path to the item we need already
            var endTile = _path == null ? null : _path.EndTile();

            if (_path != null && endTile != null && endTile.Inventory != null && endTile.Inventory.ObjectType == unsatisfied.ObjectType)
            {
                // We are already moving towards a tile with the items we want, just keep going.
                return(BehaviourTreeStatus.Success);
            }

            // Look for the first item that matches.
            _path = World.Instance.InventoryManager.GetClosestPathToInventoryOfType(
                objectType: unsatisfied.ObjectType,
                t: CurrentTile,
                desiredQty: unsatisfied.MaxStackSize - unsatisfied.StackSize,
                searchInStockpiles: CurrentJob.CanTakeFromStockpile);


            // If there are no items anywhere that satisfy the requirements, we have to give up on this job.
            if (_path == null || _path.Length() == 0)
            {
                //// Debug.LogFormat("No Tile found containing the desired type ({0}).", unsatisfied.ObjectType);
                AbandonJob();
                return(BehaviourTreeStatus.Failure);
            }

            // We've identified where the missing items can be found, so head there.
            _destinationTile = _path.EndTile();
            _nextTile        = _path.Dequeue();
            return(BehaviourTreeStatus.Success);
        }