public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            if (t is ThingWithComps thing)
            {
                if (!pawn.Dead && !pawn.Downed && !pawn.IsBurning() && !thing.Destroyed && !thing.IsBurning() && pawn.CanReserveAndReach(thing, PathEndMode.InteractionCell, Danger.Deadly))
                {
                    CompUpgrade comp = null;
                    foreach (var c in thing.AllComps.OfType <CompUpgrade>())
                    {
                        if (c.beginUpgrade)
                        {
                            comp = c;
                            break;
                        }
                    }
                    if (comp == null)
                    {
                        return(null);
                    }

                    ThingDefCount needThingCount = comp.TryGetOneMissingMaterial();

                    if (!comp.PawnMeetsSkillRequirement(pawn))
                    {
                        JobFailReason.Is("ConstructionSkillTooLow");
                        return(null);
                    }
                    if (needThingCount.Count > 0)
                    {
                        Thing foundRes = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(needThingCount.ThingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.Deadly), 9999f, (Thing r) => { return(r.def == needThingCount.ThingDef && !r.IsForbidden(pawn) && pawn.CanReserve(r)); });
                        if (foundRes == null)
                        {
                            JobFailReason.Is("Upgrade_missingMaterial");
                            return(null);
                        }
                    }
                    return(new Job(PESDefOf.PES_Job_InstallUpgrade, t));
                }
            }
            return(null);
        }
Ejemplo n.º 2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompUpgrade comp = FindOneComp();

            if (comp == null)
            {
                EndJobWith(JobCondition.Incompletable);
                yield break;
            }
            AddFailCondition(() => comp == null || !comp.parent.Spawned || !comp.beginUpgrade);
            this.FailOnDestroyedNullOrForbidden(TargetIndex.A);

            Toil gotoBuilding = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            Toil findMaterial = new Toil
            {
                initAction = delegate()
                {
                    ThingDefCount thingDefCount = comp.TryGetOneMissingMaterial();
                    job.count = thingDefCount.Count;
                    if (thingDefCount.Count > 0)
                    {
                        Thing foundRes = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(thingDefCount.ThingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.Deadly), 9999f, (Thing r) => { return(r.def == thingDefCount.ThingDef && !r.IsForbidden(pawn) && pawn.CanReserve(r)); });
                        if (foundRes == null)
                        {
                            EndJobWith(JobCondition.Incompletable);
                        }
                        else
                        {
                            job.SetTarget(TargetIndex.B, foundRes);
                        }
                    }
                    else
                    {
                        JumpToToil(gotoBuilding);
                    }
                }
            };

            //Haul things to building
            yield return(findMaterial);

            yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, job.count));

            yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch).FailOnDestroyedNullOrForbidden(TargetIndex.B));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B));

            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    var tracker = pawn.carryTracker;
                    if (tracker.CarriedThing != null)
                    {
                        tracker.innerContainer.TryTransferToContainer(tracker.CarriedThing, comp.GetDirectlyHeldThings(), tracker.CarriedThing.stackCount, true);
                        pawn.Map.reservationManager.ReleaseAllForTarget(TargetThingB);
                        job.SetTarget(TargetIndex.B, null);
                        JumpToToil(findMaterial);
                    }
                }
            });

            //Do upgrade
            yield return(gotoBuilding);

            yield return(new Toil
            {
                tickAction = delegate()
                {
                    Pawn actor = GetActor();
                    comp.Work(actor, actor.GetStatValue(StatDefOf.ConstructionSpeed));
                    if (comp.complete)
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Never
            }.WithEffect(EffecterDefOf.ConstructMetal, TargetIndex.A).WithProgressBar(TargetIndex.A, () => comp.FinishPercentage));

            yield break;
        }