// Token: 0x06000077 RID: 119 RVA: 0x00004B80 File Offset: 0x00002D80
        private void FindAvailableNearbyResources(Thing firstFoundResource, Pawn pawn, out int resTotalAvailable)
        {
            int num = Mathf.Min(firstFoundResource.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(firstFoundResource.def));

            resTotalAvailable = 0;
            WorkGiver_WPConstructDeliverResources.resourcesAvailable.Clear();
            WorkGiver_WPConstructDeliverResources.resourcesAvailable.Add(firstFoundResource);
            resTotalAvailable += firstFoundResource.stackCount;
            bool flag = resTotalAvailable < num;

            if (flag)
            {
                foreach (Thing thing in GenRadial.RadialDistinctThingsAround(firstFoundResource.Position, firstFoundResource.Map, 5f, false))
                {
                    bool flag2 = resTotalAvailable >= num;
                    if (flag2)
                    {
                        break;
                    }
                    bool flag3 = thing.def == firstFoundResource.def && GenAI.CanUseItemForWork(pawn, thing);
                    if (flag3)
                    {
                        WorkGiver_WPConstructDeliverResources.resourcesAvailable.Add(thing);
                        resTotalAvailable += thing.stackCount;
                    }
                }
            }
        }
예제 #2
0
        private void FindAvailableNearbyResources(Thing firstFoundResource, Pawn pawn, out int resTotalAvailable)
        {
            int num = Mathf.Min(firstFoundResource.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(firstFoundResource.def));

            resTotalAvailable = 0;
            WorkGiver_ConstructDeliverResources.resourcesAvailable.Clear();
            WorkGiver_ConstructDeliverResources.resourcesAvailable.Add(firstFoundResource);
            resTotalAvailable += firstFoundResource.stackCount;
            if (resTotalAvailable < num)
            {
                foreach (Thing current in GenRadial.RadialDistinctThingsAround(firstFoundResource.Position, firstFoundResource.Map, 5f, false))
                {
                    if (resTotalAvailable >= num)
                    {
                        break;
                    }
                    if (current.def == firstFoundResource.def)
                    {
                        if (GenAI.CanUseItemForWork(pawn, current))
                        {
                            WorkGiver_ConstructDeliverResources.resourcesAvailable.Add(current);
                            resTotalAvailable += current.stackCount;
                        }
                    }
                }
            }
        }
예제 #3
0
        private void FindAvailableNearbyResources(Thing firstFoundResource, Pawn pawn, out int resTotalAvailable)
        {
            int num = Mathf.Min(firstFoundResource.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(firstFoundResource.def));

            resTotalAvailable = 0;
            resourcesAvailable.Clear();
            resourcesAvailable.Add(firstFoundResource);
            resTotalAvailable += firstFoundResource.stackCount;
            if (resTotalAvailable >= num)
            {
                return;
            }
            foreach (Thing item in GenRadial.RadialDistinctThingsAround(firstFoundResource.Position, firstFoundResource.Map, 5f, useCenter: false))
            {
                if (resTotalAvailable >= num)
                {
                    break;
                }
                if (item.def == firstFoundResource.def && GenAI.CanUseItemForWork(pawn, item))
                {
                    resourcesAvailable.Add(item);
                    resTotalAvailable += item.stackCount;
                }
            }
        }
        private static Toil JumpToCollectNextIntoHandsForBill(Toil gotoGetTargetToil, TargetIndex ind)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor = toil.actor;
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something.");
                    return;
                }
                if (actor.carryTracker.Full)
                {
                    return;
                }
                Job curJob = actor.jobs.curJob;
                List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(ind);
                if (targetQueue.NullOrEmpty <LocalTargetInfo>())
                {
                    return;
                }
                for (int i = 0; i < targetQueue.Count; i++)
                {
                    if (GenAI.CanUseItemForWork(actor, targetQueue[i].Thing))
                    {
                        if (targetQueue[i].Thing.CanStackWith(actor.carryTracker.CarriedThing))
                        {
                            if ((actor.Position - targetQueue[i].Thing.Position).LengthHorizontalSquared <= 64f)
                            {
                                int num  = (actor.carryTracker.CarriedThing != null) ? actor.carryTracker.CarriedThing.stackCount : 0;
                                int num2 = curJob.countQueue[i];
                                num2 = Mathf.Min(num2, targetQueue[i].Thing.def.stackLimit - num);
                                num2 = Mathf.Min(num2, actor.carryTracker.AvailableStackSpace(targetQueue[i].Thing.def));
                                if (num2 > 0)
                                {
                                    curJob.count = num2;
                                    curJob.SetTarget(ind, targetQueue[i].Thing);
                                    List <int> countQueue;
                                    List <int> expr_1B2 = countQueue = curJob.countQueue;
                                    int        num3;
                                    int        expr_1B6 = num3 = i;
                                    num3 = countQueue[num3];
                                    expr_1B2[expr_1B6] = num3 - num2;
                                    if (curJob.countQueue[i] == 0)
                                    {
                                        curJob.countQueue.RemoveAt(i);
                                        targetQueue.RemoveAt(i);
                                    }
                                    actor.jobs.curDriver.JumpToToil(gotoGetTargetToil);
                                    return;
                                }
                            }
                        }
                    }
                }
            };
            return(toil);
        }
예제 #5
0
        private static Toil JumpToCollectNextIntoHandsForBill(Toil gotoGetTargetToil, TargetIndex ind)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor = toil.actor;
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something.");
                }
                else if (!actor.carryTracker.Full)
                {
                    Job curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(ind);
                    if (!targetQueue.NullOrEmpty())
                    {
                        int num = 0;
                        int a;
                        while (true)
                        {
                            if (num >= targetQueue.Count)
                            {
                                return;
                            }
                            if (GenAI.CanUseItemForWork(actor, targetQueue[num].Thing) && targetQueue[num].Thing.CanStackWith(actor.carryTracker.CarriedThing) && !((float)(actor.Position - targetQueue[num].Thing.Position).LengthHorizontalSquared > 64f))
                            {
                                int num2 = (actor.carryTracker.CarriedThing != null) ? actor.carryTracker.CarriedThing.stackCount : 0;
                                a = curJob.countQueue[num];
                                a = Mathf.Min(a, targetQueue[num].Thing.def.stackLimit - num2);
                                a = Mathf.Min(a, actor.carryTracker.AvailableStackSpace(targetQueue[num].Thing.def));
                                if (a > 0)
                                {
                                    break;
                                }
                            }
                            num++;
                        }
                        curJob.count = a;
                        curJob.SetTarget(ind, targetQueue[num].Thing);
                        List <int> countQueue;
                        int        index;
                        (countQueue = curJob.countQueue)[index = num] = countQueue[index] - a;
                        if (curJob.countQueue[num] <= 0)
                        {
                            curJob.countQueue.RemoveAt(num);
                            targetQueue.RemoveAt(num);
                        }
                        actor.jobs.curDriver.JumpToToil(gotoGetTargetToil);
                    }
                }
            };
            return(toil);
        }
예제 #6
0
        public static List <Thing> FindAvailableNearbyResources(ThingDef resourceDef, Pawn pawn, out int resourcesTotalAvailable)
        {
            float searchDistanceAfterFirst = 25f;

            resourcesTotalAvailable = 0;
            List <Thing> resourcesAvailable = new List <Thing>();

            Predicate <Thing> validator    = (th => th.def == resourceDef && !th.IsForbidden(pawn) && pawn.CanReserve(th));
            Thing             closestThing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(resourceDef), PathEndMode.ClosestTouch,
                                                                              TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator);

            if (closestThing == null || !pawn.Spawned)
            {
                return(null);
            }

            int num = Mathf.Min(closestThing.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(closestThing.def));

            resourcesAvailable.Add(closestThing);
            resourcesTotalAvailable += closestThing.stackCount;

            if (resourcesTotalAvailable < num)
            {
                foreach (Thing current in GenRadial.RadialDistinctThingsAround(closestThing.Position, closestThing.Map, searchDistanceAfterFirst, false))
                {
                    if (resourcesTotalAvailable >= num)
                    {
                        break;
                    }
                    if (current.def == closestThing.def)
                    {
                        if (GenAI.CanUseItemForWork(pawn, current))
                        {
                            resourcesAvailable.Add(current);
                            resourcesTotalAvailable += current.stackCount;
                        }
                    }
                }
            }

            // Only select as much as we need.
            if (resourcesTotalAvailable > num)
            {
                resourcesTotalAvailable = num;
            }

            return(resourcesAvailable);
        }
        private static Toil JumpToAlsoCollectTargetInQueue(Toil gotoGetTargetToil, TargetIndex ind)
        {
            const float MaxDist = 8;

            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn actor = toil.actor;

                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something.");
                    return;
                }

                //Early-out
                if (actor.carryTracker.Full)
                {
                    return;
                }

                Job curJob      = actor.jobs.curJob;
                var targetQueue = curJob.GetTargetQueue(ind);

                if (targetQueue.NullOrEmpty())
                {
                    return;
                }

                //Find an item in the queue matching what you're carrying
                for (int i = 0; i < targetQueue.Count; i++)
                {
                    //Can't use item - skip
                    if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing))
                    {
                        continue;
                    }

                    //Cannot stack with thing in hands - skip
                    if (!targetQueue[i].Thing.CanStackWith(actor.carryTracker.CarriedThing))
                    {
                        continue;
                    }

                    //Too far away - skip
                    if ((actor.Position - targetQueue[i].Thing.Position).LengthHorizontalSquared > MaxDist * MaxDist)
                    {
                        continue;
                    }

                    //Determine num in hands
                    int numInHands = (actor.carryTracker.CarriedThing == null) ? 0 : actor.carryTracker.CarriedThing.stackCount;

                    //Determine num to take
                    int numToTake = curJob.countQueue[i];
                    numToTake = Mathf.Min(numToTake, targetQueue[i].Thing.def.stackLimit - numInHands);
                    numToTake = Mathf.Min(numToTake, actor.carryTracker.AvailableStackSpace(targetQueue[i].Thing.def));

                    //Won't take any - skip
                    if (numToTake <= 0)
                    {
                        continue;
                    }

                    //Set me to go get it
                    curJob.count = numToTake;
                    curJob.SetTarget(ind, targetQueue[i].Thing);

                    //Remove the amount to take from the num to bring list
                    //Remove from queue if I'm going to take all
                    curJob.countQueue[i] -= numToTake;
                    if (curJob.countQueue[i] == 0)
                    {
                        curJob.countQueue.RemoveAt(i);
                        targetQueue.RemoveAt(i);
                    }

                    //Jump to toil
                    actor.jobs.curDriver.JumpToToil(gotoGetTargetToil);
                    return;
                }
            };

            return(toil);
        }
예제 #8
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var ingList      = job.GetTargetQueue(IngredientInd);
            var ingCountList = job.countQueue;

            // this.job.SetTarget(IngredientPlaceCellInd, this.TargetA.Thing.InteractionCell);
            var startToil = Toils_General.Do(
                () =>
            {
                job.SetTarget(IngredientInd, ingList[0].Thing);
                job.count = ingCountList[0];
                ingList.RemoveAt(0);
                ingCountList.RemoveAt(0);
            });

            // 材料キューの先頭を取り出してセット
            yield return(startToil);

            // 材料の置き場所へ移動
            var gotoToil = Toils_Goto.GotoThing(IngredientInd, PathEndMode.Touch);

            yield return(gotoToil);

            // 材料を運ぶ
            yield return(Toils_Haul.StartCarryThing(IngredientInd));

            // 運ぶものリストの中に同種の材料があり、まだ物を持てる場合、設備へ持っていく前に取りに行く
            yield return(Toils_General.Do(
                             () =>
            {
                var actor = pawn;
                var curJob = actor.jobs.curJob;
                var targetQueue = curJob.GetTargetQueue(IngredientInd);
                if (targetQueue.NullOrEmpty())
                {
                    return;
                }

                if (curJob.count <= 0)
                {
                    return;
                }

                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error(
                        "JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something.");
                    return;
                }

                if (actor.carryTracker.AvailableStackSpace(actor.carryTracker.CarriedThing.def) <= 0)
                {
                    return;
                }

                for (var i = 0; i < targetQueue.Count; i++)
                {
                    if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing))
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                        return;
                    }

                    if (targetQueue[i].Thing.def != actor.carryTracker.CarriedThing.def)
                    {
                        continue;
                    }

                    curJob.SetTarget(IngredientInd, targetQueue[i].Thing);
                    curJob.count = curJob.countQueue[i];
                    targetQueue.RemoveAt(i);
                    curJob.countQueue.RemoveAt(i);
                    actor.jobs.curDriver.JumpToToil(gotoToil);
                    break;
                }
            }));

            // 運ぶ
            yield return(Toils_Haul.CarryHauledThingToCell(IngredientPlaceCellInd));

            // 運んだものリスト(使用素材)に追加
            yield return(Toils_Mizu.AddPlacedThing());

            // 運んだものを置く
            yield return(Toils_Haul.PlaceCarriedThingInCellFacing(BillGiverInd));

            // まだ材料があるならさらに運ぶ
            yield return(Toils_General.Do(
                             () =>
            {
                if (job.GetTargetQueue(IngredientInd).Count > 0)
                {
                    pawn.jobs.curDriver.JumpToToil(startToil);
                }
            }));

            // レシピ実行
            yield return(Toils_Recipe.DoRecipeWork());

            // 水の注入完了処理
            yield return(Toils_Mizu.FinishPourRecipe(BillGiverInd));
        }
        public static bool ResourceDeliverJobFor(WorkGiver_ConstructDeliverResources __instance, ref Job __result, Pawn pawn, IConstructible c, bool canRemoveExistingFloorUnderNearbyNeeders = true)
        {
            Blueprint_Install blueprint_Install = c as Blueprint_Install;

            if (blueprint_Install != null)
            {
                __result = InstallJob(pawn, blueprint_Install);
                return(false);
            }
            List <Thing> resourcesAvailable = new List <Thing>();

            bool flag = false;
            ThingDefCountClass        thingDefCountClass = null;
            List <ThingDefCountClass> list = c.MaterialsNeeded();
            int count = list.Count;

            for (int i = 0; i < count; i++)
            {
                ThingDefCountClass need = list[i];
                if (!pawn.Map.itemAvailability.ThingsAvailableAnywhere(need, pawn))
                {
                    flag = true;
                    thingDefCountClass = need;
                    break;
                }

                Thing foundRes = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(need.thingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, (Thing r) => ResourceValidator(pawn, need, r));
                if (foundRes != null)
                {
                    resourcesAvailable.Clear();
                    //FindAvailableNearbyResources2(foundRes, pawn, out int resTotalAvailable, resourcesAvailable);
                    int resTotalAvailable;
                    int num0 = Mathf.Min(foundRes.def.stackLimit, pawn.carryTracker.MaxStackSpaceEver(foundRes.def));
                    resTotalAvailable = 0;
                    resourcesAvailable.Add(foundRes);
                    resTotalAvailable += foundRes.stackCount;
                    if (resTotalAvailable < num0)
                    {
                        foreach (Thing item in GenRadial.RadialDistinctThingsAround(foundRes.Position, foundRes.Map, 5f, useCenter: false))
                        {
                            if (resTotalAvailable >= num0)
                            {
                                break;
                            }
                            if (item.def == foundRes.def && GenAI.CanUseItemForWork(pawn, item))
                            {
                                resourcesAvailable.Add(item);
                                resTotalAvailable += item.stackCount;
                            }
                        }
                    }
                    int             neededTotal;
                    Job             jobToMakeNeederAvailable;
                    HashSet <Thing> hashSet = FindNearbyNeeders(pawn, need, c, resTotalAvailable, canRemoveExistingFloorUnderNearbyNeeders, out neededTotal, out jobToMakeNeederAvailable);
                    if (jobToMakeNeederAvailable != null)
                    {
                        __result = jobToMakeNeederAvailable;
                        return(false);
                    }

                    hashSet.Add((Thing)c);
                    Thing thing = hashSet.MinBy((Thing nee) => IntVec3Utility.ManhattanDistanceFlat(foundRes.Position, nee.Position));
                    hashSet.Remove(thing);
                    int num  = 0;
                    int num2 = 0;
                    do
                    {
                        num += resourcesAvailable[num2].stackCount;
                        num2++;
                    }while (num < neededTotal && num2 < resourcesAvailable.Count);
                    resourcesAvailable.RemoveRange(num2, resourcesAvailable.Count - num2);
                    resourcesAvailable.Remove(foundRes);
                    Job job = JobMaker.MakeJob(JobDefOf.HaulToContainer);
                    job.targetA      = foundRes;
                    job.targetQueueA = new List <LocalTargetInfo>();
                    for (num2 = 0; num2 < resourcesAvailable.Count; num2++)
                    {
                        job.targetQueueA.Add(resourcesAvailable[num2]);
                    }

                    job.targetB = thing;
                    if (hashSet.Count > 0)
                    {
                        job.targetQueueB = new List <LocalTargetInfo>();
                        foreach (Thing item in hashSet)
                        {
                            job.targetQueueB.Add(item);
                        }
                    }

                    job.targetC  = (Thing)c;
                    job.count    = neededTotal;
                    job.haulMode = HaulMode.ToContainer;
                    __result     = job;
                    return(false);
                }

                flag = true;
                thingDefCountClass = need;
            }

            if (flag)
            {
                JobFailReason.Is($"{MissingMaterialsTranslated}: {thingDefCountClass.thingDef.label}");
            }

            __result = null;
            return(false);
        }