protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(TargetIndex.A);

            //Define Toil
            Toil toilWait = new Toil();

            toilWait.initAction = () =>
            {
                toilWait.actor.pather.StopDead();
            };

            Toil toilNothing = new Toil();

            //toilNothing.initAction = () => {};
            toilNothing.defaultCompleteMode = ToilCompleteMode.Delay;
            toilNothing.defaultDuration     = getUpCheckInterval;

            // Start Toil
            yield return(toilWait);

            yield return(toilNothing);

            yield return(Toils_Jump.JumpIf(toilNothing, () =>
            {
                CompSuppressable comp = pawn.TryGetComp <CompSuppressable>();
                if (comp == null)
                {
                    return false;
                }
                float distToSuppressor = (pawn.Position - comp.suppressorLoc).LengthHorizontal;
                if (distToSuppressor < CompSuppressable.minSuppressionDist)
                {
                    return false;
                }
                return comp.isHunkering;
            }));
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(TargetIndex.A);

            //Define Toil
            Toil toilWait = new Toil();

            toilWait.initAction = () =>
            {
                toilWait.actor.pather.StopDead();
            };

            Toil toilNothing = new Toil();

            //toilNothing.initAction = () => {};
            toilNothing.defaultCompleteMode = ToilCompleteMode.Delay;
            toilNothing.defaultDuration     = GetUpCheckInterval;

            // Start Toil
            yield return(toilWait);

            yield return(toilNothing);

            yield return(Toils_Jump.JumpIf(toilNothing, () =>
            {
                CompSuppressable comp = pawn.TryGetComp <CompSuppressable>();
                if (comp == null)
                {
                    return false;
                }
                if (!comp.CanReactToSuppression)
                {
                    return false;
                }
                return comp.IsHunkering;
            }));
        }
Esempio n. 3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var wait = Toils_General.Wait(50, TargetIndex.A).FailOnNotDiningQueued(TargetIndex.A);

            //this.FailOnNotDining(TargetIndex.A);
            this.FailOnDestroyedOrNull(TargetIndex.B);
            this.FailOnForbidden(TargetIndex.B);
            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch));

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

            yield return(Toils_Waiting.UpdateOrderConsumableTo(TargetIndex.A, TargetIndex.B));

            yield return(Toils_Waiting.FindRandomAdjacentCell(TargetIndex.A, TargetIndex.C)); // A is the patron, C is the spot

            yield return(Toils_Haul.CarryHauledThingToCell(TargetIndex.C));

            yield return(wait);

            yield return(Toils_Jump.JumpIf(wait, () => pawn.jobs.curJob?.GetTarget(TargetIndex.A).Pawn?.GetDriver <JobDriver_Dine>() == null)); // Driver not available

            yield return(Toils_Waiting.GetDiningSpot(TargetIndex.A, TargetIndex.C));

            yield return(Toils_Haul.CarryHauledThingToCell(TargetIndex.C));

            yield return(Toils_Jump.JumpIf(wait, () => pawn.jobs.curJob?.GetTarget(TargetIndex.A).Pawn?.GetDriver <JobDriver_Dine>() == null)); // Driver not available

            yield return(Toils_Waiting.AnnounceServing(TargetIndex.A, TargetIndex.B));

            yield return(Toils_Waiting.ClearOrder(TargetIndex.A, TargetIndex.B, TargetIndex.B, TargetIndex.C)); // Got no silver or register? Job successful

            yield return(Toils_Misc.TakeItemFromInventoryToCarrier(pawn, TargetIndex.B));

            yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.Touch));

            yield return(Toils_Haul.DepositHauledThingInContainer(TargetIndex.C, TargetIndex.None));
        }
Esempio n. 4
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            AddEndCondition(() => (!RefuelableComp.IsFull) ? JobCondition.Ongoing : JobCondition.Succeeded);
            AddFailCondition(() => (!job.playerForced && !RefuelableComp.ShouldAutoRefuelNowIgnoringFuelPct) || !RefuelableComp.allowAutoRefuel);
            AddFailCondition(() => !RefuelableComp.allowAutoRefuel && !job.playerForced);
            yield return(Toils_General.DoAtomic(delegate
            {
                job.count = RefuelableComp.GetFuelCountToFullyRefuel();
            }));

            Toil getNextIngredient = Toils_General.Label();

            yield return(getNextIngredient);

            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B));

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: false, subtractNumTakenFromJobCount: true).FailOnDestroyedNullOrForbidden(TargetIndex.B));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);

            yield return(findPlaceTarget);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, storageMode: false));

            yield return(Toils_Jump.JumpIf(getNextIngredient, () => !job.GetTargetQueue(TargetIndex.B).NullOrEmpty()));

            yield return(Toils_General.Wait(240).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch)
                         .WithProgressBarToilDelay(TargetIndex.A));

            yield return(FinalizeRefueling(TargetIndex.A, TargetIndex.None, RefuelableComp));
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            base.AddEndCondition(() => (!this.RefuelableComp.IsFull) ? JobCondition.Ongoing : JobCondition.Succeeded);
            base.AddFailCondition(() => !this.job.playerForced && !this.RefuelableComp.ShouldAutoRefuelNowIgnoringFuelPct);
            yield return(Toils_General.DoAtomic(delegate
            {
                this.job.count = this.RefuelableComp.GetFuelCountToFullyRefuel();
            }));

            Toil getNextIngredient = Toils_General.Label();

            yield return(getNextIngredient);

            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true));

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B, false, true, false).FailOnDestroyedNullOrForbidden(TargetIndex.B));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);

            yield return(findPlaceTarget);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

            yield return(Toils_Jump.JumpIf(getNextIngredient, () => !this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

            yield return(Toils_General.Wait(240, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f));

            yield return(Toils_Refuel.FinalizeRefueling(TargetIndex.A, TargetIndex.None));

            yield break;
        }
Esempio n. 6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Waiting());

            Toil stageEnded = Toils_ReligionActivity.StageEnded(pawn);

            yield return(Toils_Jump.JumpIf(stageEnded, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

            Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);

            yield return(extract);

            Toil getToTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);

            yield return(getToTarget);

            yield return(Sacrifce(TargetIndex.B));

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));

            yield return(Waiting());

            yield return(stageEnded);
        }
Esempio n. 7
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Bill bill = job.bill;

            AddEndCondition(delegate
            {
                Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate()
            {
                IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });
            AddFinishAction(delegate()
            {
                //Log.Message("LearnWeapon: finishing");
                ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                if (pawn.equipment.Primary != null)
                {
                    pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false);
                }
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

            Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);

            yield return(extract);

            Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);

            yield return(getToHaulTarget);

            //temporary equip
            yield return(new Toil
            {
                initAction = delegate()
                {
                    ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                    ThingWithComps thingWithComps2;
                    if (thingWithComps.def.stackLimit > 1 && thingWithComps.stackCount > 1)
                    {
                        thingWithComps2 = (ThingWithComps)thingWithComps.SplitOff(1);
                    }
                    else
                    {
                        thingWithComps2 = thingWithComps;
                        thingWithComps2.DeSpawn(DestroyMode.Vanish);
                    }
                    pawn.equipment.MakeRoomFor(thingWithComps2);
                    pawn.equipment.AddEquipment(thingWithComps2);
                    if (thingWithComps.def.soundInteract != null)
                    {
                        thingWithComps.def.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));

            yield return(gotoBillGiver);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil train = new Toil();

            train.initAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = job.targetB.Thing.def;
                workLeft                  = curJob.bill.recipe.WorkAmountTotal(null);
                billStartTick             = Find.TickManager.TicksGame;
                ticksSpentDoingRecipeWork = 0;
                curJob.bill.Notify_DoBillStarted(actor);
                //sound:
                if (weapon.soundInteract != null)
                {
                    weapon.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                }
            };
            train.tickAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = job.targetB.Thing.def;
                ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);
                IBillGiverWithTickAction billGiverWithTickAction = train.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    billGiverWithTickAction.UsedThisTick();
                }
                float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                if (curJob.RecipeDef.workTableSpeedStat != null)
                {
                    Building_WorkTable building_WorkTable = BillGiver as Building_WorkTable;
                    if (building_WorkTable != null)
                    {
                        num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true);
                    }
                }
                if (DebugSettings.fastCrafting)
                {
                    num *= 30f;
                }
                workLeft -= num;
                actor.GainComfortFromCellIfPossible();
                if (workLeft <= 0f)
                {
                    ReadyForNextToil();
                }

                //pawn posture
                Verb            verbToUse = actor.jobs.curJob.verbToUse;
                LocalTargetInfo target    = actor.jobs.curJob.GetTarget(TargetIndex.A);
                pawn.stances.SetStance(new Stance_Warmup(1, target, verbToUse));

                //sound:
                if (verbToUse.verbProps != null && verbToUse.verbProps.warmupTime > 0)
                {
                    if ((ticksSpentDoingRecipeWork % verbToUse.verbProps.AdjustedFullCycleTime(verbToUse, actor).SecondsToTicks()) == 0)
                    {
                        if (verbToUse.verbProps.soundCast != null)
                        {
                            verbToUse.verbProps.soundCast.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                        }
                        if (verbToUse.verbProps.soundCastTail != null)
                        {
                            verbToUse.verbProps.soundCastTail.PlayOneShotOnCamera(pawn.Map);
                        }
                    }
                }
                if (job.RecipeDef.workSkill != null)
                {
                    //float xpDelta = techComp.proficientWeapons.Contains(job.targetB.Thing.def) ? 1f : 0.1f;
                    float xp = 0.1f * job.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(job.RecipeDef.workSkill).Learn(xp, false);
                }
            };
            train.defaultCompleteMode = ToilCompleteMode.Never;
            train.WithEffect(() => train.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A);
            train.PlaySustainerOrSound(() => train.actor.CurJob.bill.recipe.soundWorking);
            train.WithProgressBar(TargetIndex.A, delegate
            {
                Pawn actor = train.actor;
                Job curJob = actor.CurJob;
                //return 1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(null);
                return(1f - (workLeft / curJob.bill.recipe.WorkAmountTotal(null)));
            }, false, -0.5f);
            train.FailOn(() => train.actor.CurJob.bill.suspended);
            train.activeSkill = () => train.actor.CurJob.bill.recipe.workSkill;
            yield return(train.FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            Toil finalizeTraining = new Toil();

            finalizeTraining.initAction = delegate
            {
                Pawn          actor    = finalizeTraining.actor;
                CompKnowledge techComp = actor.TryGetComp <CompKnowledge>();
                if (!techComp.proficientWeapons.Contains(job.targetB.Thing.def))
                {
                    techComp.proficientWeapons.Add(TargetThingB.def);
                }
                job.bill.Notify_IterationCompleted(actor, new List <Thing> {
                });
                actor.jobs.EndCurrentJob(JobCondition.Succeeded, false);
            };
            finalizeTraining.defaultCompleteMode = ToilCompleteMode.Instant;
            finalizeTraining.FailOnDespawnedOrNull(TargetIndex.A);
            yield return(finalizeTraining);

            //testing
            yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null));

            Toil findPlaceTarget = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(findPlaceTarget);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget, true, true));

            yield break;
        }
Esempio n. 8
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ///
            //Set fail conditions
            ///

            this.FailOnDestroyedOrNull(CartInd);
            //Note we only fail on forbidden if the target doesn't start that way
            //This helps haul-aside jobs on forbidden items
            if (!TargetThingA.IsForbidden(pawn.Faction))
            {
                this.FailOnForbidden(CartInd);
            }


            ThingWithComps cart = TargetThingA as ThingWithComps;

            if (ToolsForHaulUtility.FindStorageCell(pawn, cart) == IntVec3.Invalid)
            {
                JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceForCart);
            }


            if (cart.TryGetComp <CompMountable>().Driver != null)
            {
                this.FailOnSomeonePhysicallyInteracting(CartInd);
            }

            ///
            //Define Toil
            ///

            Toil toilGoToCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch);

            ///
            //Toils Start
            ///


            //Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.Reserve(CartInd));

            yield return(Toils_Reserve.Reserve(StoreCellInd));

            //JumpIf already mounted
            yield return(Toils_Jump.JumpIf(toilGoToCell, () =>
            {
                return cart.TryGetComp <CompMountable>().Driver == pawn ? true : false;
            }));

            //Mount on Target
            yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.ClosestTouch)
                         .FailOnDestroyedOrNull(CartInd));

            yield return(Toils_Cart.MountOn(CartInd));

            //Dismount
            yield return(toilGoToCell);

            yield return(Toils_Cart.DismountAt(CartInd, StoreCellInd));
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
                    base.AddEndCondition(() => (!base.RefuelableComp.IsFull) ? JobCondition.Ongoing : JobCondition.Succeeded);
                    base.AddFailCondition(() => !this.job.playerForced && !base.RefuelableComp.ShouldAutoRefuelNowIgnoringFuelPct);
                    this.$current = Toils_General.DoAtomic(delegate
                    {
                        this.job.count = base.RefuelableComp.GetFuelCountToFullyRefuel();
                    });
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);

                case 1u:
                    getNextIngredient = Toils_General.Label();
                    this.$current     = getNextIngredient;
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

                case 2u:
                    this.$current = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);
                    if (!this.$disposing)
                    {
                        this.$PC = 3;
                    }
                    return(true);

                case 3u:
                    this.$current = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);

                case 4u:
                    this.$current = Toils_Haul.StartCarryThing(TargetIndex.B, false, true, false).FailOnDestroyedNullOrForbidden(TargetIndex.B);
                    if (!this.$disposing)
                    {
                        this.$PC = 5;
                    }
                    return(true);

                case 5u:
                    this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
                    if (!this.$disposing)
                    {
                        this.$PC = 6;
                    }
                    return(true);

                case 6u:
                    findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                    this.$current   = findPlaceTarget;
                    if (!this.$disposing)
                    {
                        this.$PC = 7;
                    }
                    return(true);

                case 7u:
                    this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false);
                    if (!this.$disposing)
                    {
                        this.$PC = 8;
                    }
                    return(true);

                case 8u:
                    this.$current = Toils_Jump.JumpIf(getNextIngredient, () => !this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>());
                    if (!this.$disposing)
                    {
                        this.$PC = 9;
                    }
                    return(true);

                case 9u:
                    this.$current = Toils_General.Wait(240, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
                    if (!this.$disposing)
                    {
                        this.$PC = 10;
                    }
                    return(true);

                case 10u:
                    this.$current = Toils_Refuel.FinalizeRefueling(TargetIndex.A, TargetIndex.None);
                    if (!this.$disposing)
                    {
                        this.$PC = 11;
                    }
                    return(true);

                case 11u:
                    this.$PC = -1;
                    break;
                }
                return(false);
            }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Workbench giver destroyed (only in bill using phase! Not in carry phase)
            this.AddEndCondition(() =>
            {
                var targ = GetActor().jobs.curJob.GetTarget(StationIndex).Thing;
                if (targ == null || (targ is Building && !targ.Spawned))
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(StationIndex);  //Rechargestation is burning

            this.FailOn(() =>
            {
                X2_Building_AIRobotRechargeStation workbench = job.GetTarget(StationIndex).Thing as X2_Building_AIRobotRechargeStation;

                //conditions only apply during the billgiver-use phase
                if (workbench == null)
                {
                    return(true);
                }
                return(false);
            });

            //Go to the recharge station, this is yielded later, but needed here!
            Toil gotoStation = Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch);

            //Jump over ingredient gathering if there are no ingredients needed
            yield return(Toils_Jump.JumpIf(gotoStation, () => this.job.GetTargetQueue(IngredientIndex).NullOrEmpty()));

            {
                //Get to ingredient and pick it up
                //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked
                //   your targetB into another object on the bill giver square.

                Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(IngredientIndex);
                yield return(extract);

                //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked
                //   your targetB into another object on the bill giver square.
                var getToHaulTarget2 = Toils_Goto.GotoThing(IngredientIndex, PathEndMode.Touch)
                                       .FailOnDespawnedNullOrForbidden(IngredientIndex)
                                       .FailOnSomeonePhysicallyInteracting(IngredientIndex);
                yield return(getToHaulTarget2);

                //Carry ingredient to the workbench
                yield return(Toils_Haul.StartCarryThing(IngredientIndex, true));

                //Jump to pick up more in this run if we're collecting from multiple stacks at once
                yield return(JumpToAlsoCollectTargetInQueue(getToHaulTarget2, IngredientIndex));

                //Carry ingredient to the workbench
                yield return(Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch)
                             .FailOnDestroyedOrNull(IngredientIndex));

                //Place ingredient on the appropriate cell
                Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(StationIndex, IngredientIndex, IngredientPlaceCellIndex);
                yield return(findPlaceTarget2);

                yield return(Toils_Haul.PlaceHauledThingInCell(IngredientPlaceCellIndex, findPlaceTarget2, false, false));

                // save the ingredient, so that it can be deleted later on!
                Toil saveIngredient = new Toil();
                saveIngredient.initAction          = delegate { this.ingredients.Add(GetActor().jobs.curJob.GetTarget(IngredientIndex).Thing); };
                saveIngredient.defaultCompleteMode = ToilCompleteMode.Instant;
                yield return(saveIngredient);

                //Jump back if another ingredient is queued, or you didn't finish carrying your current ingredient target
                yield return(Toils_Jump.JumpIfHaveTargetInQueue(IngredientIndex, extract));

                extract          = null;
                getToHaulTarget2 = null;
                findPlaceTarget2 = null;
            }

            //yield return GetDebugToil("goto station", true);

            //Go to the recharge station
            yield return(gotoStation);


            //Do the repair work
            yield return(DoRepairWork(500, "Interact_ConstructMetal")
                         .FailOnDespawnedNullOrForbiddenPlacedThings()
                         .FailOnCannotTouch(StationIndex, PathEndMode.Touch));

            yield break;
        }
Esempio n. 11
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Building_ShellfishTrap crabPot = this.job.GetTarget(CrabPotIndex).Thing as Building_ShellfishTrap;
            Pawn actor = this.pawn;

            Toil unloadProcess = new Toil()
            {
                initAction = () =>
                {
                    storemode = crabPot.StoreMode;
                },
                defaultDuration     = BaseUnloadDuration,
                defaultCompleteMode = ToilCompleteMode.Delay,
                activeSkill         = (() => SkillDefOf.Animals)
            }
            .FailOnDespawnedNullOrForbidden(CrabPotIndex)
            .FailOnBurningImmobile(CrabPotIndex)
            .FailOnThingHavingDesignation(CrabPotIndex, DesignationDefOf.Uninstall)
            .FailOnCannotTouch(CrabPotIndex, PathEndMode.Touch)
            .WithProgressBarToilDelay(CrabPotIndex);

            Toil unloadPot = new Toil()
            {
                initAction = () =>
                {
                    //Log.Message("unloadPot");
                    AddFinishAction(DropStuff);

                    crabPot.LastOpenTick = Find.TickManager.TicksGame;

                    var items = crabPot.GetDirectlyHeldThings();

                    //Log.Message("items");
                    //foreach(var item in items)
                    //{
                    //    Log.Message(item.def.defName + " " + item.stackCount);
                    //}

                    //Log.Message("unloading");
                    while (!MassUtility.IsOverEncumbered(pawn) && items.Count > 0)
                    {
                        int count = Math.Min(MassUtility.CountToPickUpUntilOverEncumbered(actor, items[0]), items[0].stackCount);

                        //Log.Message(count + " " + items[0].stackCount + MassUtility.CountToPickUpUntilOverEncumbered(actor, items[0]));

                        if (items.TryTransferToContainer(items[0], pawn.inventory.innerContainer, count, out Thing resultingItem, false) > 0)
                        {
                            if (!resultingItem.Destroyed && resultingItem.stackCount > 0)
                            {
                                LoadedFish.Add(resultingItem);
                            }
                        }
                    }

                    items.TryDropAll(pawn.Position, pawn.Map, ThingPlaceMode.Near);

                    //actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            this.FailOnDespawnedNullOrForbidden(CrabPotIndex);
            this.FailOnBurningImmobile(CrabPotIndex);
            this.FailOnThingHavingDesignation(CrabPotIndex, DesignationDefOf.Uninstall);
            yield return(Toils_Goto.GotoThing(CrabPotIndex, PathEndMode.Touch)
                         .FailOnDespawnedNullOrForbidden(CrabPotIndex)
                         .FailOnBurningImmobile(CrabPotIndex)
                         .FailOnThingHavingDesignation(CrabPotIndex, DesignationDefOf.Uninstall));

            yield return(unloadProcess);

            yield return(unloadPot);

            //todo: repeatetive haul
            Toil finishAndStartHaul = FinishAndStartHaul();

            yield return(finishAndStartHaul);

            yield return(Toils_Misc.TakeItemFromInventoryToCarrier(pawn, HaulableInd));

            yield return(Toils_Reserve.Reserve(StoreCellInd));

            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: true));

            yield return(Toils_Jump.JumpIf(finishAndStartHaul, () => LoadedFish.Count > 0));
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                {
                    this.FailOn(delegate()
                        {
                            if (!this.job.ignoreDesignations)
                            {
                                Pawn victim = base.Victim;
                                if (victim != null && !victim.Dead && base.Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                                {
                                    return(true);
                                }
                            }
                            return(false);
                        });
                    Toil init = new Toil();
                    init.initAction = delegate()
                    {
                        this.jobStartTick = Find.TickManager.TicksGame;
                    };
                    this.$current = init;
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);
                }

                case 1u:
                    this.$current = Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

                case 2u:
                    startCollectCorpseLabel = Toils_General.Label();
                    slaughterLabel          = Toils_General.Label();
                    gotoCastPos             = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000);
                    this.$current           = gotoCastPos;
                    if (!this.$disposing)
                    {
                        this.$PC = 3;
                    }
                    return(true);

                case 3u:
                    slaughterIfPossible = Toils_Jump.JumpIf(slaughterLabel, delegate
                    {
                        Pawn victim = base.Victim;
                        return((victim.RaceProps.DeathActionWorker == null || !victim.RaceProps.DeathActionWorker.DangerousInMelee) && victim.Downed);
                    });
                    this.$current = slaughterIfPossible;
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);

                case 4u:
                    this.$current = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos);
                    if (!this.$disposing)
                    {
                        this.$PC = 5;
                    }
                    return(true);

                case 5u:
                    this.$current = Toils_Combat.CastVerb(TargetIndex.A, false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000);
                    if (!this.$disposing)
                    {
                        this.$PC = 6;
                    }
                    return(true);

                case 6u:
                    this.$current = Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel);
                    if (!this.$disposing)
                    {
                        this.$PC = 7;
                    }
                    return(true);

                case 7u:
                    this.$current = Toils_Jump.Jump(slaughterIfPossible);
                    if (!this.$disposing)
                    {
                        this.$PC = 8;
                    }
                    return(true);

                case 8u:
                    this.$current = slaughterLabel;
                    if (!this.$disposing)
                    {
                        this.$PC = 9;
                    }
                    return(true);

                case 9u:
                    this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnMobile(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 10;
                    }
                    return(true);

                case 10u:
                    this.$current = Toils_General.WaitWith(TargetIndex.A, 180, true, false).FailOnMobile(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 11;
                    }
                    return(true);

                case 11u:
                    this.$current = Toils_General.Do(delegate
                    {
                        if (base.Victim.Dead)
                        {
                            return;
                        }
                        ExecutionUtility.DoExecutionByCut(this.pawn, base.Victim);
                        this.pawn.records.Increment(RecordDefOf.AnimalsSlaughtered);
                        if (this.pawn.InMentalState)
                        {
                            this.pawn.MentalState.Notify_SlaughteredAnimal();
                        }
                    });
                    if (!this.$disposing)
                    {
                        this.$PC = 12;
                    }
                    return(true);

                case 12u:
                    this.$current = Toils_Jump.Jump(startCollectCorpseLabel);
                    if (!this.$disposing)
                    {
                        this.$PC = 13;
                    }
                    return(true);

                case 13u:
                    this.$current = startCollectCorpseLabel;
                    if (!this.$disposing)
                    {
                        this.$PC = 14;
                    }
                    return(true);

                case 14u:
                    this.$current = base.StartCollectCorpseToil();
                    if (!this.$disposing)
                    {
                        this.$PC = 15;
                    }
                    return(true);

                case 15u:
                    this.$current = Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 16;
                    }
                    return(true);

                case 16u:
                    this.$current = Toils_Haul.StartCarryThing(TargetIndex.A, false, false, false);
                    if (!this.$disposing)
                    {
                        this.$PC = 17;
                    }
                    return(true);

                case 17u:
                    carryToCell   = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
                    this.$current = carryToCell;
                    if (!this.$disposing)
                    {
                        this.$PC = 18;
                    }
                    return(true);

                case 18u:
                    this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true);
                    if (!this.$disposing)
                    {
                        this.$PC = 19;
                    }
                    return(true);

                case 19u:
                    this.$PC = -1;
                    break;
                }
                return(false);
            }
Esempio n. 13
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            AddFailCondition(() => pawn.WorkTagIsDisabled(WorkTags.Violent));

            this.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            jobStartTick = Find.TickManager.TicksGame;

            startingEquippedWeapon = pawn.equipment.Primary;
            trainingWeapon         = null;
            if (startingEquippedWeapon == null || !startingEquippedWeapon.def.IsWithinCategory(CombatTrainingDefOf.TrainingWeapons))
            {
                trainingWeapon = GetNearestTrainingWeapon(startingEquippedWeapon);
                if (trainingWeapon != null && !trainingWeapon.IsForbidden(pawn))
                {
                    if (Map.reservationManager.CanReserve(pawn, trainingWeapon))
                    {
                        pawn.Reserve(trainingWeapon, job);
                        job.SetTarget(TargetIndex.B, trainingWeapon);
                        yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B));

                        yield return(CreateEquipToil(TargetIndex.B));
                    }
                    if (Map.reservationManager.CanReserve(pawn, startingEquippedWeapon))
                    {
                        pawn.Reserve(startingEquippedWeapon, job);
                        job.SetTarget(TargetIndex.C, startingEquippedWeapon);
                    }
                }
            }
            Toil endOfTraining = Toils_General.Label();
            Toil gotoCastPos   = Toils_Combat.GotoCastPosition(TargetIndex.A, closeIfDowned: true, 0.95f).EndOnDespawnedOrNull(TargetIndex.A);
            Toil ifTrainingDoneJumpToReequip = Toils_Jump.JumpIf(endOfTraining, HasTrainingEnded);
            Toil castVerb = Toils_Combat.CastVerb(TargetIndex.A, canHitNonTargetPawns: false);

            castVerb.AddFinishAction(delegate
            {
                LearnAttackSkill();
            });
            Toil trainingRoomImpressivenessMoodBoost = Toils_General.Do(delegate
            {
                TryGainCombatTrainingRoomThought();
            });
            Toil dropTrainingWeapon = Toils_General.Do(delegate
            {
                pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, forbid: false);
            });
            Toil reequipSwappedStartingWeapon = Toils_General.Do(delegate
            {
                pawn.inventory.innerContainer.Remove(startingEquippedWeapon);
                pawn.equipment.AddEquipment(startingEquippedWeapon);
            });
            Toil jobEndedLabel = Toils_General.Label();


            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            yield return(gotoCastPos);

            yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos));

            yield return(trainingRoomImpressivenessMoodBoost);

            yield return(ifTrainingDoneJumpToReequip);

            yield return(castVerb);

            yield return(Toils_Jump.Jump(ifTrainingDoneJumpToReequip));

            yield return(endOfTraining);

            if (trainingWeapon != null)
            {
                yield return(dropTrainingWeapon);
            }

            yield return(Toils_Jump.JumpIf(reequipSwappedStartingWeapon, () => pawn.inventory.Contains(startingEquippedWeapon)));

            yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.C));

            yield return(CreateEquipToil(TargetIndex.C));

            yield return(Toils_Jump.Jump(jobEndedLabel));

            yield return(reequipSwappedStartingWeapon);

            yield return(jobEndedLabel);
        }
Esempio n. 14
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(delegate
            {
                if (!job.ignoreDesignations)
                {
                    Pawn victim = Victim;
                    if (victim != null && !victim.Dead && Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                    {
                        return(true);
                    }
                }
                return(false);
            });

            yield return(Toils_Reserve.Reserve(VictimInd, 1));

            var init = new Toil();

            init.initAction = delegate
            {
                jobStartTick = Find.TickManager.TicksGame;
            };
            yield return(init);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            var comp = (pawn.equipment != null && pawn.equipment.Primary != null) ? pawn.equipment.Primary.TryGetComp <CompAmmoUser>() : null;
            var startCollectCorpse = StartCollectCorpseToil();
            var gotoCastPos        = GotoCastPosition(VictimInd, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse).FailOn(() => Find.TickManager.TicksGame > jobStartTick + MaxHuntTicks);

            yield return(gotoCastPos);

            //var moveIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(VictimInd, gotoCastPos);
            var moveIfCannotHit = Toils_Jump.JumpIf(gotoCastPos, delegate
            {
                var verb         = pawn.CurJob.verbToUse;
                var optimalRange = HuntRangePerBodysize(Victim.RaceProps.baseBodySize, Victim.RaceProps.executionRange, verb.verbProps.range);
                if (pawn.Position.DistanceTo(Victim.Position) > optimalRange)
                {
                    return(true);
                }
                return(!verb.CanHitTarget(Victim));
            });

            yield return(moveIfCannotHit);

            yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(VictimInd, startCollectCorpse));

            var startExecuteDowned = Toils_Goto.GotoThing(VictimInd, PathEndMode.Touch).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse);

            yield return(Toils_Jump.JumpIf(startExecuteDowned, () => Victim.Downed && Victim.RaceProps.executionRange <= 2));

            yield return(Toils_Jump.JumpIfTargetDowned(VictimInd, gotoCastPos));

            yield return(Toils_Combat.CastVerb(VictimInd, false).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse)
                         .FailOn(() =>
            {
                if (Find.TickManager.TicksGame <= jobStartTick + MaxHuntTicks)
                {
                    if (comp == null || comp.HasAndUsesAmmoOrMagazine)
                    {
                        return false;
                    }
                }
                return true;
            }));

            yield return(Toils_Jump.Jump(moveIfCannotHit));

            // Execute downed animal - adapted from JobDriver_Slaughter
            yield return(startExecuteDowned);

            yield return(Toils_General.WaitWith(VictimInd, 180, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse));

            yield return(new Toil
            {
                initAction = delegate
                {
                    ExecutionUtility.DoExecutionByCut(pawn, Victim);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            // Haul corpse to stockpile
            yield return(startCollectCorpse);

            yield return(Toils_Goto.GotoCell(VictimInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(VictimInd).FailOnSomeonePhysicallyInteracting(VictimInd));

            yield return(Toils_Haul.StartCarryThing(VictimInd));

            var carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, true));
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Apparel_Backpack backpack = CurJob.GetTarget(BackpackInd).Thing as Apparel_Backpack;

            ///
            //Set fail conditions
            ///


            //Backpack is full.
            this.FailOn(() => { return((pawn.inventory.container.Count < backpack.MaxItem) ? false : true); });

            ///
            //Define Toil
            ///

            Toil extractB = new Toil();

            extractB.initAction = () =>
            {
                if (!CurJob.targetQueueB.NullOrEmpty())
                {
                    CurJob.targetB = CurJob.targetQueueB.First();
                    CurJob.targetQueueB.RemoveAt(0);
                    this.FailOnDestroyedOrNull(HaulableInd);
                }
                else
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
            };

            Toil toilGoToThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch)
                                 .FailOnDestroyedOrNull(HaulableInd);

            ///
            //Toils Start
            ///

            //Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.Reserve(BackpackInd));

            yield return(Toils_Reserve.Reserve(HaulableInd));

            yield return(Toils_Reserve.ReserveQueue(HaulableInd));


            yield return(Toils_Jump.JumpIf(toilGoToThing, () => { return (CurJob.targetB.HasThing) ? true : false; }));

            //Collect TargetQueue
            {
                //Extract an haulable into TargetA
                yield return(extractB);

                yield return(toilGoToThing);

                //CollectIntoCarrier
                Toil toilPutInInventory = new Toil();
                toilPutInInventory.initAction = () =>
                {
                    if (pawn.inventory.container.Count < backpack.MaxItem &&
                        backpack.wearer.inventory.container.TotalStackCount < backpack.MaxStack)
                    {
                        if (CurJob.targetB.Thing.TryGetComp <CompForbiddable>() != null && CurJob.targetB.Thing.TryGetComp <CompForbiddable>().Forbidden == true)
                        {
                            CurJob.targetB.Thing.TryGetComp <CompForbiddable>().Forbidden = false;
                        }
                        if (pawn.inventory.container.TryAdd(CurJob.targetB.Thing, CurJob.maxNumToCarry))
                        {
                            CurJob.targetB.Thing.holder       = pawn.inventory.GetContainer();
                            CurJob.targetB.Thing.holder.owner = pawn.inventory;
                            backpack.numOfSavedItems++;
                        }
                    }
                    else
                    {
                        this.EndJobWith(JobCondition.Incompletable);
                    }
                };
                yield return(toilPutInInventory);

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractB));
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddFinishAction(delegate
            {
                this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn);
            });
            Toil prepareToEatCorpse = new Toil();

            prepareToEatCorpse.initAction = delegate
            {
                Pawn   actor  = prepareToEatCorpse.actor;
                Corpse corpse = this.$this.Corpse;
                if (corpse == null)
                {
                    Pawn prey = this.$this.Prey;
                    if (prey == null)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        return;
                    }
                    corpse = prey.Corpse;
                    if (corpse == null || !corpse.Spawned)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        return;
                    }
                }
                if (actor.Faction == Faction.OfPlayer)
                {
                    corpse.SetForbidden(false, false);
                }
                else
                {
                    corpse.SetForbidden(true, false);
                }
                actor.CurJob.SetTarget(TargetIndex.A, corpse);
            };
            yield return(Toils_General.DoAtomic(delegate
            {
                this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn);
            }));

            Action onHitAction = delegate
            {
                Pawn prey           = this.$this.Prey;
                bool surpriseAttack = this.$this.firstHit && !prey.IsColonist;
                if (this.$this.pawn.meleeVerbs.TryMeleeAttack(prey, this.$this.job.verbToUse, surpriseAttack))
                {
                    if (!this.$this.notifiedPlayerAttacked && PawnUtility.ShouldSendNotificationAbout(prey))
                    {
                        this.$this.notifiedPlayerAttacked = true;
                        Messages.Message("MessageAttackedByPredator".Translate(prey.LabelShort, this.$this.pawn.LabelIndefinite(), prey.Named("PREY"), this.$this.pawn.Named("PREDATOR")).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatSmall, true);
                    }
                    this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn);
                    this.$this.firstHit = false;
                }
            };
            Toil followAndAttack = Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIfDespawnedOrNull(TargetIndex.A, prepareToEatCorpse).JumpIf(() => this.$this.Corpse != null, prepareToEatCorpse).FailOn(() => Find.TickManager.TicksGame > this.$this.startTick + 5000 && (float)(this.$this.job.GetTarget(TargetIndex.A).Cell - this.$this.pawn.Position).LengthHorizontalSquared > 4f);

            followAndAttack.AddPreTickAction(new Action(this.CheckWarnPlayer));
            yield return(followAndAttack);

            yield return(prepareToEatCorpse);

            Toil gotoCorpse = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);

            yield return(gotoCorpse);

            float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true);

            yield return(Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.None).FailOnDespawnedOrNull(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch));

            yield return(Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A));

            yield return(Toils_Jump.JumpIf(gotoCorpse, () => this.$this.pawn.needs.food.CurLevelPercentage < 0.9f));
        }
Esempio n. 17
0
        public static IEnumerable <Toil> Heat(JobDriver jd, TargetIndex foodIndex = TargetIndex.A, TargetIndex finalLocation = TargetIndex.C, TargetIndex tableIndex = TargetIndex.None)
        {
            LocalTargetInfo oldFinal = jd.job.GetTarget(finalLocation);

            Toil empty = new Toil();

            yield return(Toils_Jump.JumpIf(empty, delegate()
            {
                Pawn actor = empty.actor;
                Job curJob = actor.jobs.curJob;
                LocalTargetInfo food = curJob.GetTarget(foodIndex).Thing;
                if (food.Thing == null)
                {
                    return true;
                }
                CompDFoodTemperature comp = food.Thing.TryGetComp <CompDFoodTemperature>();
                if (comp == null)
                {
                    return true;
                }
                if (comp.PropsTemp.likesHeat)
                {
                    return comp.curTemp >= comp.PropsTemp.tempLevels.goodTemp;
                }
                else if (HotMealsSettings.thawIt && !comp.PropsTemp.okFrozen)
                {
                    return comp.curTemp > 0;
                }
                return true;
            }));

            Toil getHeater = new Toil();

            getHeater.initAction = delegate()
            {
                Pawn  actor      = getHeater.actor;
                Job   curJob     = actor.jobs.curJob;
                Thing foodToHeat = curJob.GetTarget(foodIndex).Thing;
                Thing table      = null;
                if (tableIndex != TargetIndex.None)
                {
                    table = curJob.GetTarget(tableIndex).Thing;
                }
                Thing heater = Toils_HeatMeal.FindPlaceToHeatFood(foodToHeat, actor, searchNear: table);
                if (heater != null)
                {
                    curJob.SetTarget(finalLocation, heater);
                }
            };
            yield return(getHeater);

            yield return(Toils_Jump.JumpIf(empty, delegate()
            {
                Pawn actor = getHeater.actor;
                Job curJob = actor.jobs.curJob;
                Thing heater = curJob.GetTarget(finalLocation).Thing;
                return (heater == null);
            }));

            if (!HotMealsSettings.multipleHeat)
            {
                yield return(Toils_Reserve.Reserve(finalLocation));

                yield return(Toils_Goto.GotoThing(finalLocation, PathEndMode.InteractionCell));

                yield return(Toils_HeatMeal.HeatMeal(foodIndex, finalLocation).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(finalLocation, PathEndMode.InteractionCell));

                yield return(Toils_Reserve.Release(finalLocation));
            }
            else
            {
                yield return(Toils_Goto.GotoThing(finalLocation, PathEndMode.Touch));

                yield return(Toils_HeatMeal.HeatMeal(foodIndex, finalLocation).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(finalLocation, PathEndMode.Touch));
            }
            yield return(empty);

            if (oldFinal != LocalTargetInfo.Invalid)
            {
                Toil resetC = new Toil();
                resetC.initAction = delegate()
                {
                    Pawn actor  = resetC.actor;
                    Job  curJob = actor.jobs.curJob;
                    curJob.SetTarget(finalLocation, oldFinal);
                };
                yield return(resetC);
            }
        }
Esempio n. 18
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddEndCondition(delegate
            {
                Thing thing = this.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            //       this.FailOn(delegate
            //       {
            //           IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
            //           if (billGiver != null)
            //           {
            //               if (this.job.bill.DeletedOrDereferenced)
            //{
            //	return true;
            //}
            //if (!billGiver.CurrentlyUsableForBills())
            //{
            //	return true;
            //}
            //           }
            //           return false;
            //       });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

            Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);

            yield return(extract);

            Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);

            yield return(getToHaulTarget);

            yield return(new Toil()
            {
                initAction = delegate
                {
                    if (PawnRelic != null)
                    {
                        if (this.job.def.makeTargetPrisoner)
                        {
                            Lord lord = PawnRelic.GetLord();
                            if (lord != null)
                            {
                                lord.Notify_PawnAttemptArrested(PawnRelic);
                            }
                            GenClamor.DoClamor(PawnRelic, 10f, ClamorDefOf.Harm);
                            if (!PawnRelic.CheckAcceptArrest(this.pawn))
                            {
                                this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                            }
                        }
                    }
                }
            });

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true));

            yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B));

            Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);

            yield return(findPlaceTarget);

            yield return(PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

            yield return(new Toil
            {
                initAction = delegate
                {
                    if (PawnRelic != null)
                    {
                        IntVec3 position = this.job.GetTarget(TargetIndex.B).Cell;
                        this.pawn.Notify_Teleported(false, true);
                        this.pawn.stances.CancelBusyStanceHard();
                        PawnRelic.jobs.StartJob(new Job(MiscDefOf.TiedDown, (LocalTargetInfo)position), JobCondition.InterruptForced, (ThinkNode)null, false, true, (ThinkTreeDef)null, new JobTag?(JobTag.Idle), false);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));

            yield return(gotoBillGiver);

            yield return(StartActivity());
            //yield return Waiting();
            //yield return DoRecipeWork();
            //yield return Toils_Recipe.FinishRecipeAndStartStoringProduct();///////////////////////
            //if (!this.job.RecipeDef.products.NullOrEmpty<ThingDefCountClass>() || !this.job.RecipeDef.specialProducts.NullOrEmpty<SpecialProductType>())
            //{
            //    yield return Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null);
            //    Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
            //    yield return carryToCell;
            //    yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true);
            //    Toil recount = new Toil();
            //    recount.initAction = delegate
            //    {
            //        Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production;
            //        if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
            //        {
            //            this.Map.resourceCounter.UpdateResourceCounts();
            //        }
            //    };
            //    yield return recount;
            //}
        }
Esempio n. 19
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Bill bill = job.bill;

            AddEndCondition(delegate
            {
                Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate()
            {
                IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });
            AddFinishAction(delegate()
            {
                if (pawn.equipment.Primary != null && !practice)
                {
                    if (pawn.equipment.Primary == (ThingWithComps)job.targetB.Thing)
                    {
                        ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                        pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false);
                    }
                    if (job.GetTarget(TargetIndex.C).IsValid)
                    {
                        Equip(TargetIndex.C, false);
                    }
                }
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            if (!practice)
            {
                yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

                Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);
                yield return(extract);

                Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                yield return(getToHaulTarget);

                yield return(new Toil
                {
                    initAction = delegate()
                    {
                        Equip(TargetIndex.B, true);
                    },
                    defaultCompleteMode = ToilCompleteMode.Instant
                });

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));
            }
            Thing currentWeapon = practice ? pawn.equipment.Primary : job.targetB.Thing;

            yield return(gotoBillGiver);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            yield return(Train(currentWeapon).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(FinalizeTraining());

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            AddEndCondition(delegate
            {
                Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate()
            {
                IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                    if (project == null)
                    {
                        Log.Warning("[HumanResources] " + pawn + " tried to document a null project.");
                        TryMakePreToilReservations(true);
                        return(true);
                    }
                    if (!techComp.homework.Contains(project))
                    {
                        return(true);
                    }
                }
                return(false);
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (job.targetQueueB != null && job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)job.bill;
                        }
                    }
                }
            });

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

            Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);

            yield return(extract);

            Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);

            yield return(getToHaulTarget);

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B));

            Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);

            yield return(findPlaceTarget);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false, false));

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));

            extract         = null;
            getToHaulTarget = null;
            findPlaceTarget = null;
            yield return(gotoBillGiver);

            yield return(MakeUnfinishedThingIfNeeded());

            yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(FinishRecipeAndStartStoringProduct());

            if (!job.RecipeDef.products.NullOrEmpty <ThingDefCountClass>() || !job.RecipeDef.specialProducts.NullOrEmpty <SpecialProductType>())
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.B));

                //yield return Toils_Reserve.Reserve(TargetIndex.A);
                yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false));

                findPlaceTarget = Toils_Haul.CarryHauledThingToContainer();
                yield return(findPlaceTarget);

                Toil prepare = Toils_General.Wait(250);
                prepare.WithProgressBarToilDelay(TargetIndex.B, false, -0.5f);
                yield return(prepare);

                yield return(new Toil
                {
                    initAction = delegate
                    {
                        Building_BookStore shelf = (Building_BookStore)job.GetTarget(TargetIndex.B).Thing;
                        CurToil.FailOn(() => shelf == null);
                        Thing book = pawn.carryTracker.CarriedThing;
                        if (pawn.carryTracker.CarriedThing == null)
                        {
                            Log.Error(pawn + " tried to place a book on shelf but is not hauling anything.");
                            return;
                        }
                        if (shelf.Accepts(book))
                        {
                            bool flag = false;
                            if (book.holdingOwner != null)
                            {
                                book.holdingOwner.TryTransferToContainer(book, shelf.TryGetInnerInteractableThingOwner(), book.stackCount, true);
                                flag = true;
                            }
                            else
                            {
                                flag = shelf.TryGetInnerInteractableThingOwner().TryAdd(book, true);
                            }
                            pawn.carryTracker.innerContainer.Remove(book);
                        }
                        else
                        {
                            Log.Error(pawn + " tried to place a book in " + shelf + ", but won't accept it.");
                            return;
                        }
                        pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true, true);
                    }
                });
            }
            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Apparel_Backpack backpack = this.CurJob.GetTarget(BackpackInd).Thing as Apparel_Backpack;

            ///
            // Set fail conditions
            ///
            // no free slots
            this.FailOn(() => backpack.SlotsComp.slots.Count >= backpack.MaxItem);

            //// hauling stuff not allowed
            // foreach (ThingCategoryDef category in CurJob.targetA.Thing.def.thingCategories)
            // {
            // this.FailOn(() => !backpack.slotsComp.Properties.allowedThingCategoryDefs.Contains(category));
            // this.FailOn(() => backpack.slotsComp.Properties.forbiddenSubThingCategoryDefs.Contains(category));
            // }


            ///
            // Define Toil
            ///

            Toil endOfJob = new Toil {
                initAction = () => { this.EndJobWith(JobCondition.Succeeded); }
            };
            Toil checkStoreCellEmpty = Toils_Jump.JumpIf(endOfJob, () => this.CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty());
            Toil checkHaulableEmpty  = Toils_Jump.JumpIf(checkStoreCellEmpty, () => this.CurJob.GetTargetQueue(HaulableInd).NullOrEmpty());

            Toil checkBackpackEmpty = Toils_Jump.JumpIf(endOfJob, () => backpack.SlotsComp.slots.Count <= 0);

            ///
            // Toils Start
            ///

            // Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.ReserveQueue(HaulableInd));

            yield return(Toils_Reserve.ReserveQueue(StoreCellInd));

            // JumpIf checkStoreCellEmpty
            yield return(checkHaulableEmpty);

            {
                // Collect TargetQueue
                Toil extractA = Toils_Collect.Extract(HaulableInd);
                yield return(extractA);

                Toil gotoThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch)
                                 .FailOnDestroyedOrNull(HaulableInd);
                yield return(gotoThing);

                // yield return Toils_Collect.CollectInBackpack(HaulableInd, backpack);
                Toil pickUpThingIntoSlot = new Toil
                {
                    initAction = () =>
                    {
                        if (!backpack.SlotsComp.slots.TryAdd(this.CurJob.targetA.Thing))
                        {
                            this.EndJobWith(JobCondition.Incompletable);
                        }
                    }
                };
                yield return(pickUpThingIntoSlot);

                yield return(Toils_Collect.CheckDuplicates(gotoThing, BackpackInd, HaulableInd));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA));
            }

            // JumpIf toilEnd
            yield return(checkStoreCellEmpty);

            {
                // Drop TargetQueue
                yield return(checkBackpackEmpty);

                Toil extractB = Toils_Collect.Extract(StoreCellInd);
                yield return(extractB);

                Toil gotoCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch);
                yield return(gotoCell);

                yield return(Toils_Collect.DropTheCarriedFromBackpackInCell(StoreCellInd, ThingPlaceMode.Direct, backpack));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkBackpackEmpty));

                yield return(Toils_Collect.CheckNeedStorageCell(gotoCell, BackpackInd, StoreCellInd));
            }

            yield return(endOfJob);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(delegate()
            {
                if (!this.job.ignoreDesignations)
                {
                    Pawn victim = this.Victim;
                    if (victim != null && !victim.Dead && base.Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                    {
                        return(true);
                    }
                }
                return(false);
            });
            yield return(new Toil
            {
                initAction = delegate()
                {
                    this.jobStartTick = Find.TickManager.TicksGame;
                }
            });

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil startCollectCorpseLabel = Toils_General.Label();
            Toil slaughterLabel          = Toils_General.Label();
            Toil gotoCastPos             = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000);

            yield return(gotoCastPos);

            Toil slaughterIfPossible = Toils_Jump.JumpIf(slaughterLabel, delegate
            {
                Pawn victim = this.Victim;
                return((victim.RaceProps.DeathActionWorker == null || !victim.RaceProps.DeathActionWorker.DangerousInMelee) && victim.Downed);
            });

            yield return(slaughterIfPossible);

            yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos));

            yield return(Toils_Combat.CastVerb(TargetIndex.A, false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000));

            yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel));

            yield return(Toils_Jump.Jump(slaughterIfPossible));

            yield return(slaughterLabel);

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnMobile(TargetIndex.A));

            yield return(Toils_General.WaitWith(TargetIndex.A, 180, true, false).FailOnMobile(TargetIndex.A));

            yield return(Toils_General.Do(delegate
            {
                if (this.Victim.Dead)
                {
                    return;
                }
                ExecutionUtility.DoExecutionByCut(this.pawn, this.Victim);
                this.pawn.records.Increment(RecordDefOf.AnimalsSlaughtered);
                if (this.pawn.InMentalState)
                {
                    this.pawn.MentalState.Notify_SlaughteredAnimal();
                }
            }));

            yield return(Toils_Jump.Jump(startCollectCorpseLabel));

            yield return(startCollectCorpseLabel);

            yield return(this.StartCollectCorpseToil());

            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, false, false));

            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));

            yield break;
        }
        //get next, goto, take, check for more. Branches off to "all over the place"
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>();

            Toil wait = Toils_General.Wait(2);

            Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A); //also does count

            yield return(nextTarget);

            //honestly the workgiver checks for encumbered, so until CE checks are in this is unnecessary
            //yield return CheckForOverencumbered();//Probably redundant without CE checks

            Toil gotoThing = new Toil
            {
                initAction = () =>
                {
                    pawn.pather.StartPath(TargetThingA, PathEndMode.ClosestTouch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            gotoThing.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(gotoThing);

            Toil takeThing = new Toil
            {
                initAction = () =>
                {
                    Pawn  actor = pawn;
                    Thing thing = actor.CurJob.GetTarget(TargetIndex.A).Thing;
                    Toils_Haul.ErrorCheckForCarry(actor, thing);

                    //get max we can pick up
                    int countToPickUp = Mathf.Min(job.count, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing));
                    Log.Message($"{actor} is hauling to inventory {thing}:{countToPickUp}");

                    // yo dawg, I heard you like delegates so I put delegates in your delegate, so you can delegate your delegates.
                    // because compilers don't respect IF statements in delegates and toils are fully iterated over as soon as the job starts.
                    try
                    {
                        ((Action)(() =>
                        {
                            if (ModCompatibilityCheck.CombatExtendedIsActive)
                            {
                                //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>();
                                //ceCompInventory.CanFitInInventory(thing, out countToPickUp);
                            }
                        }))();
                    }
                    catch (TypeLoadException) { }

                    if (countToPickUp > 0)
                    {
                        Thing splitThing  = thing.SplitOff(countToPickUp);
                        bool  shouldMerge = takenToInventory.GetHashSet().Any(x => x.def == thing.def);
                        actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, shouldMerge);
                        takenToInventory.RegisterHauledItem(splitThing);

                        try
                        {
                            ((Action)(() =>
                            {
                                if (ModCompatibilityCheck.CombatExtendedIsActive)
                                {
                                    //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>();
                                    //ceCompInventory.UpdateInventory();
                                }
                            }))();
                        }
                        catch (TypeLoadException)
                        {
                        }
                    }

                    //thing still remains, so queue up hauling if we can + end the current job (smooth/instant transition)
                    //This will technically release the reservations in the queue, but what can you do
                    if (thing.Spawned)
                    {
                        Job haul = HaulAIUtility.HaulToStorageJob(actor, thing);
                        if (haul?.TryMakePreToilReservations(actor, false) ?? false)
                        {
                            actor.jobs.jobQueue.EnqueueFirst(haul, JobTag.Misc);
                        }
                        actor.jobs.curDriver.JumpToToil(wait);
                    }
                }
            };

            yield return(takeThing);

            yield return(Toils_Jump.JumpIf(nextTarget, () => !job.targetQueueA.NullOrEmpty()));

            //Find more to haul, in case things spawned while this was in progess
            yield return(new Toil
            {
                initAction = () =>
                {
                    List <Thing> haulables = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling();
                    WorkGiver_HaulToInventory haulMoreWork = DefDatabase <WorkGiverDef> .AllDefsListForReading.First(wg => wg.Worker is WorkGiver_HaulToInventory).Worker as WorkGiver_HaulToInventory;

                    Thing haulMoreThing = GenClosest.ClosestThing_Global(pawn.Position, haulables, 12, t => haulMoreWork.HasJobOnThing(pawn, t));

                    //WorkGiver_HaulToInventory found more work nearby
                    if (haulMoreThing != null)
                    {
                        Log.Message($"{pawn} hauling again : {haulMoreThing}");
                        Job haulMoreJob = haulMoreWork.JobOnThing(pawn, haulMoreThing);

                        if (haulMoreJob.TryMakePreToilReservations(pawn, false))
                        {
                            pawn.jobs.jobQueue.EnqueueFirst(haulMoreJob, JobTag.Misc);
                            EndJobWith(JobCondition.Succeeded);
                        }
                    }
                }
            });

            //maintain cell reservations on the trip back
            //TODO: do that when we carry things
            //I guess that means TODO: implement carrying the rest of the items in this job instead of falling back on HaulToStorageJob
            yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.ClosestTouch));

            yield return(new Toil //Queue next job
            {
                initAction = () =>
                {
                    Pawn actor = pawn;
                    Job curJob = actor.jobs.curJob;
                    LocalTargetInfo storeCell = curJob.targetB;

                    Job unloadJob = new Job(PickUpAndHaulJobDefOf.UnloadYourHauledInventory, storeCell);
                    if (unloadJob.TryMakePreToilReservations(actor, false))
                    {
                        actor.jobs.jobQueue.EnqueueFirst(unloadJob, JobTag.Misc);
                        EndJobWith(JobCondition.Succeeded);
                        //This will technically release the cell reservations in the queue, but what can you do
                    }
                }
            });

            yield return(wait);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            AddEndCondition(delegate
            {
                Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                return((!(thing is Building) || thing.Spawned) ? JobCondition.Ongoing : JobCondition.Incompletable);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate
            {
                IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            Toil toil          = new Toil();

            toil.initAction = delegate
            {
                if (job.targetQueueB != null && job.targetQueueB.Count == 1)
                {
                    UnfinishedThing unfinishedThing = job.targetQueueB[0].Thing as UnfinishedThing;
                    if (unfinishedThing != null)
                    {
                        unfinishedThing.BoundBill = (Bill_ProductionWithUft)job.bill;
                    }
                }
            };
            yield return(toil);

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty()));

            Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B);

            yield return(extract);

            Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);

            yield return(getToHaulTarget);

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: true, subtractNumTakenFromJobCount: false, failIfStackCountLessThanJobCount: true));

            yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B));

            Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);

            yield return(findPlaceTarget2);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget2, storageMode: false));

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));

            yield return(gotoBillGiver);

            yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded());

            yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct());

            if (job.RecipeDef.products.NullOrEmpty() && job.RecipeDef.specialProducts.NullOrEmpty())
            {
                yield break;
            }
            yield return(Toils_Reserve.Reserve(TargetIndex.B));

            findPlaceTarget2 = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
            yield return(findPlaceTarget2);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget2, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: true));

            Toil recount = new Toil();

            recount.initAction = delegate
            {
                Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production;
                if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
                {
                    base.Map.resourceCounter.UpdateResourceCounts();
                }
            };
            yield return(recount);
        }
Esempio n. 25
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // ツールまで移動
            yield return(Toils_Goto.GotoThing(ToolInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(ToolInd));

            // ツールを手に取る
            yield return(Toils_Haul.StartCarryThing(ToolInd));

            // ターゲットが水やり対象として不適になっていたらリストから外す
            Toil initExtractTargetFromQueue = Toils_Mizu.ClearConditionSatisfiedTargets(WateringInd, (lti) =>
            {
                var mapComp = this.Map.GetComponent <MapComponent_Watering>();
                return(mapComp.Get(this.Map.cellIndices.CellToIndex(lti.Cell)) > 0);
            });

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(WateringInd));

            // ターゲットキューから次のターゲットを取り出す
            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(WateringInd, true));

            // ターゲットの元へ移動
            yield return(Toils_Goto.GotoCell(WateringInd, PathEndMode.Touch));

            // 作業中
            Toil workToil = new Toil();

            workToil.initAction = delegate
            {
                // 必要工数の計算
                this.ticksLeftThisToil = WorkingTicks;
            };
            // 細々とした設定
            workToil.defaultCompleteMode = ToilCompleteMode.Delay;
            workToil.WithProgressBar(WateringInd, () => 1f - (float)this.ticksLeftThisToil / WorkingTicks, true, -0.5f);
            workToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            yield return(workToil);

            // 作業終了
            var finishToil = new Toil();

            finishToil.initAction = () =>
            {
                // 水やり更新
                var mapComp = this.Map.GetComponent <MapComponent_Watering>();
                mapComp.Set(this.Map.cellIndices.CellToIndex(WateringPos), MapComponent_Watering.MaxWateringValue);
                this.Map.mapDrawer.SectionAt(WateringPos).dirtyFlags = MapMeshFlag.Terrain;

                // ツールから水を減らす
                var compTool = Tool.GetComp <CompWaterTool>();
                compTool.StoredWaterVolume -= ConsumeWaterVolume;
            };
            finishToil.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(finishToil);

            // 最初に戻る
            yield return(Toils_Jump.JumpIf(initExtractTargetFromQueue, () =>
            {
                return this.pawn.jobs.curJob.GetTargetQueue(WateringInd).Count > 0;
            }));

            // ツールを片付ける場所を決める
            yield return(Toils_Mizu.TryFindStoreCell(ToolInd, ToolPlaceInd));

            // 倉庫まで移動
            yield return(Toils_Goto.GotoCell(ToolPlaceInd, PathEndMode.Touch));

            // 倉庫に置く
            yield return(Toils_Haul.PlaceHauledThingInCell(ToolPlaceInd, null, true));
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Bill giver destroyed (only in bill using phase! Not in carry phase)
            this.AddEndCondition(() =>
            {
                var targ = this.GetActor().jobs.curJob.GetTarget(BuildingInd).Thing;
                if (targ == null || (targ is Building && !targ.Spawned))
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(BuildingInd);  //Bill giver, or product burning in carry phase

            //Reserve the workbench and the ingredients
            yield return(Toils_Reserve.Reserve(BuildingInd));

            //yield return Toils_Logging("Reserving done.", false);  //-- DEBUG --

            //This toil is yielded later
            Toil gotoBillGiver = Toils_Goto.GotoThing(IngredientInd, PathEndMode.InteractionCell);

            //Jump over ingredient gathering if there are no ingredients needed
            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(IngredientInd).NullOrEmpty()));

            //Gather ingredients
            {
                //Extract an ingredient into IngredientInd target
                Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(IngredientInd);
                yield return(extract);

                //Reserve the the ingredient
                yield return(Toils_Reserve.Reserve(IngredientInd)
                             .FailOnDespawnedNullOrForbidden(IngredientInd));

                //Get to ingredient and pick it up
                //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked
                //   your targetB into another object on the bill giver square.
                var getToHaulTarget = Toils_Goto.GotoThing(IngredientInd, PathEndMode.Touch)
                                      .FailOnDespawnedNullOrForbidden(IngredientInd)
                                      .FailOnSomeonePhysicallyInteracting(IngredientInd);
                yield return(getToHaulTarget);

                yield return(Toils_Haul.StartCarryThing(IngredientInd));

                //Jump to pick up more in this run if we're collecting from multiple stacks at once
                yield return(JumpToCollectNextIntoHands(getToHaulTarget, BuildingInd));

                //Carry ingredient to the bill giver
                yield return(Toils_Goto.GotoThing(BuildingInd, PathEndMode.InteractionCell)
                             .FailOnDestroyedOrNull(BuildingInd));

                //Place ingredient on the appropriate cell
                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(BuildingInd, IngredientInd, IngredientPlaceCellInd);
                yield return(findPlaceTarget);

                yield return(Toils_FillThingIntoConstructor(this.pawn));

                //yield return Toils_Haul.PlaceHauledThingInCell(IngredientPlaceCellInd,
                //                                                nextToilOnPlaceFailOrIncomplete: findPlaceTarget,
                //                                                storageMode: false);


                //Jump back if another ingredient is queued, or you didn't finish carrying your current ingredient target
                yield return(Toils_Jump.JumpIfHaveTargetInQueue(IngredientInd, extract));
            }

            yield return(gotoBillGiver);
        }
Esempio n. 27
0
        static IEnumerable <Toil> DoMakeToils(JobDriver_DoBill_Access __instance)
        {
            //normal scenario
            __instance.AddEndCondition(delegate
            {
                Thing thing = __instance.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            __instance.FailOnBurningImmobile(TargetIndex.A);
            __instance.FailOn(delegate()
            {
                if (__instance.job.GetTarget(TargetIndex.A).Thing is Filth)
                {
                    return(false);
                }

                IBillGiver billGiver = __instance.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (__instance.job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });

            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (__instance.job.targetQueueB != null && __instance.job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = __instance.job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)__instance.job.bill;
                        }
                    }
                }
            });

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.B).NullOrEmpty()));

            //hauling patch
            if (Settings.adv_haul_all_ings && __instance.pawn.Faction == Faction.OfPlayer)
            {
                Toil checklist = new Toil();
                checklist.initAction = delegate()
                {
                    Pawn actor  = checklist.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (targetQueue.NullOrEmpty())
                    {
                        actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                    }
                    else
                    {
                        foreach (var target in (targetQueue))
                        {
                            if (target == null || target.Thing.DestroyedOrNull())
                            {
                                actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                                break;
                            }
                        }
                    }
                };

                yield return(checklist);

                Toil extract = new Toil();
                extract.initAction = delegate()
                {
                    Pawn actor  = extract.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (!curJob.countQueue.NullOrEmpty())
                    {
                        if (curJob.countQueue[0] > targetQueue[0].Thing.stackCount)
                        {
                            actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                        }
                        else
                        {
                            curJob.SetTarget(TargetIndex.B, targetQueue[0]);
                            targetQueue.RemoveAt(0);
                            curJob.count = curJob.countQueue[0];
                            curJob.countQueue.RemoveAt(0);
                        }
                    }
                };

                Toil PickUpThing;
                List <LocalTargetInfo> L = __instance.job.GetTargetQueue(TargetIndex.B);
                if (L.Count < 2 && (L.Count == 0 || L[0].Thing.def.stackLimit < 2))
                {
                    PickUpThing = Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true);
                }
                else
                {
                    PickUpThing            = new Toil();
                    PickUpThing.initAction = delegate()
                    {
                        Pawn  actor  = PickUpThing.actor;
                        Job   curJob = actor.jobs.curJob;
                        Thing thing  = curJob.GetTarget(TargetIndex.B).Thing;
                        List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                        bool InventorySpawned = thing.ParentHolder == actor.inventory;
                        if (InventorySpawned || !Toils_Haul.ErrorCheckForCarry(actor, thing))
                        {
                            if (thing.stackCount < curJob.count)
                            {
                                actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                            }
                            else
                            {
                                Thing splitThing = thing.SplitOff(curJob.count);
                                if (splitThing.ParentHolder != actor.inventory && !actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, false))
                                {
                                    actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                                }


                                if (!splitThing.Destroyed && splitThing.stackCount != 0)
                                {
                                    targetQueue.Add(splitThing);

                                    if (!InventorySpawned)
                                    {
                                        CompUnloadChecker CUC = splitThing.TryGetComp <CompUnloadChecker>();
                                        if (CUC != null)
                                        {
                                            CUC.ShouldUnload = true;
                                        }
                                    }
                                }

                                if (splitThing != thing && actor.Map.reservationManager.ReservedBy(thing, actor, curJob))
                                {
                                    actor.Map.reservationManager.Release(thing, actor, curJob);
                                }
                            }
                        }
                    };
                }

                Toil TakeToHands = new Toil();
                TakeToHands.initAction = delegate()
                {
                    Pawn actor  = TakeToHands.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (!targetQueue.NullOrEmpty() && targetQueue[0].Thing.ParentHolder != actor.carryTracker)
                    {
                        actor.inventory.innerContainer.TryTransferToContainer(targetQueue[0].Thing, actor.carryTracker.innerContainer);
                        actor.Reserve(targetQueue[0], curJob);
                        curJob.SetTarget(TargetIndex.B, targetQueue[0]);
                        targetQueue.RemoveAt(0);
                    }
                };

                yield return(extract);

                Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                yield return(Toils_Jump.JumpIf(PickUpThing, () => __instance.job.GetTarget(TargetIndex.B).Thing.ParentHolder == __instance.pawn.inventory));

                yield return(getToHaulTarget);

                yield return(PickUpThing);

                yield return(Toils_Jump.JumpIf(extract, () => !__instance.job.countQueue.NullOrEmpty()));

                yield return(TakeToHands);

                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B));

                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                yield return(findPlaceTarget);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, TakeToHands));
            }
            else
            {
                Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);
                yield return(extract);

                Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                yield return(getToHaulTarget);

                yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true));

                yield return(JobDriver_DoBill_Access.JumpToCollectNextIntoHandsForBillCrutch(getToHaulTarget, TargetIndex.B));

                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B));

                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                yield return(findPlaceTarget);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));
            }

            yield return(gotoBillGiver); //one line from normal scenario

            //cleaning patch
            if (Settings.adv_cleaning && !Utility.IncapableOfCleaning(__instance.pawn))
            {
                Toil returnToBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
                Toil FilthList         = new Toil();
                FilthList.initAction = delegate()
                {
                    Job curJob = FilthList.actor.jobs.curJob;
                    if (curJob.GetTargetQueue(TargetIndex.A).NullOrEmpty())
                    {
                        LocalTargetInfo A = curJob.GetTarget(TargetIndex.A);
                        DoCleanComp     comp;
                        if (!Settings.clean_gizmo || (comp = A.Thing?.TryGetComp <DoCleanComp>()) == null || comp.Active)
                        {
                            IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num);
                            Utility.AddFilthToQueue(curJob, TargetIndex.A, l, FilthList.actor);
                            FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(TargetIndex.A), curJob);
                        }
                        curJob.targetQueueA.Add(A);
                    }
                };
                yield return(FilthList);

                yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

                Toil CleanFilthList = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null);
                yield return(CleanFilthList);

                yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true));

                yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList).JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList));

                Toil clean = new Toil();
                clean.initAction = delegate()
                {
                    Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    __instance.billStartTick             = 0;
                    __instance.ticksSpentDoingRecipeWork = 0;
                    __instance.workLeft = filth.def.filth.cleaningWorkToReduceThickness * filth.thickness;
                };
                clean.tickAction = delegate()
                {
                    Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    __instance.billStartTick             += 1;
                    __instance.ticksSpentDoingRecipeWork += 1;
                    if (__instance.billStartTick > filth.def.filth.cleaningWorkToReduceThickness)
                    {
                        filth.ThinFilth();
                        __instance.billStartTick = 0;
                        if (filth.Destroyed)
                        {
                            clean.actor.records.Increment(RecordDefOf.MessesCleaned);
                            __instance.ReadyForNextToil();
                            return;
                        }
                    }
                };
                clean.defaultCompleteMode = ToilCompleteMode.Never;
                clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A);
                clean.WithProgressBar(TargetIndex.A, () => __instance.ticksSpentDoingRecipeWork / __instance.workLeft, true, -0.5f);
                clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
                clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList);
                clean.JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList);
                yield return(clean);

                yield return(Toils_Jump.Jump(CleanFilthList));

                yield return(returnToBillGiver);
            }

            //continuation of normal scenario
            yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded());

            yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct());

            if (!__instance.job.RecipeDef.products.NullOrEmpty() || !__instance.job.RecipeDef.specialProducts.NullOrEmpty())
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null));

                Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
                yield return(carryToCell);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));

                Toil recount = new Toil();
                recount.initAction = delegate()
                {
                    Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production;
                    if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
                    {
                        __instance.MapCrutch().resourceCounter.UpdateResourceCounts();
                    }
                };
                yield return(recount);
            }
            yield break;
        }
        /// <summary>
        /// Generates a series of actions (toils) that the pawn should perform.
        /// </summary>
        /// <returns>Ienumerable of type Toil</returns>
        /// <remarks>Remember that, in the case of jobs, effectively the entire method is executed before any actual activity occurs.</remarks>
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // Error checking and 'helpful' messages for what is wrong.
            if (holder == null) // A later check will catch this (failon) but that fails silently.
            {
                Log.Error(errorBase + "TargetThingA is null.  A Pawn is required to perform a reload.");
                yield return(null);
            }
            if (weapon == null) // Required.
            {
                Log.Error(errorBase + "TargetThingB is null.  A weapon (ThingWithComps) is required to perform a reload.");
                yield return(null);
            }
            if (compReloader == null) // Required.
            {
                Log.Error(errorBase + pawn + " tried to do reload job on " + weapon.LabelCap + " which doesn't have a required CompAmmoUser.");
                yield return(null);
            }
            if (holder != pawn) // Helps restrict what this job does, not really necessary and may work fine (though possibly undesirable behavior) without this check.
            {
                Log.Error(errorBase + "TargetThingA (" + holder.Name + ") is not the same Pawn (" + pawn.Name + ") that was given the job.");
                yield return(null);
            }
            // get the state of the job (inventory vs other) at the start.
            reloadingInventory = weaponInInventory;
            reloadingEquipment = weaponEquipped;
            // A couple more more 'helpful' error check/message.
            if (!reloadingInventory && !reloadingEquipment) // prevent some bad states/behavior on FailOn and job text.
            {
                Log.Error(errorBase + "Unable to find the weapon to be reloaded (" + weapon.LabelCap + ") in the inventory nor equipment of " + pawn.Name);
                yield return(null);
            }
            if (reloadingInventory && reloadingEquipment) // prevent incorrect information on job text.  If somehow this was true may cause a FailOn to trip.
            {
                Log.Error(errorBase + "Something went spectacularly wrong as the weapon to be reloaded was found in both the Pawn's equipment AND inventory at the same time.");
                yield return(null);
            }

            // current state of equipment, want to interrupt the reload if a pawn's equipment changes.
            initEquipment = pawn.equipment?.Primary;

            // choose ammo to be loaded and set failstate for no ammo in inventory
            if (compReloader.UseAmmo)
            {
                this.FailOn(() => !compReloader.TryFindAmmoInInventory(out initAmmo));
            }

            // setup fail states, if something goes wrong with the pawn performing the reload, the weapon, or something else that we want to fail on.
            this.FailOnDespawnedOrNull(indReloader);
            this.FailOnMentalState(indReloader);
            this.FailOnDestroyedOrNull(indWeapon);
            this.FailOn(HasNoGunOrAmmo);

            // Throw mote
            if (compReloader.ShouldThrowMote && holder.Map != null)     //holder.Map is temporarily null after game load, skip mote if a pawn was reloading when game was saved
            {
                MoteMaker.ThrowText(pawn.Position.ToVector3Shifted(), holder.Map, string.Format("CE_ReloadingMote".Translate(), weapon.def.LabelCap));
            }

            //Toil of do-nothing
            Toil waitToil = new Toil()
            {
                actor = pawn
            };                                           // actor was always null in testing...

            waitToil.initAction          = () => waitToil.actor.pather.StopDead();
            waitToil.defaultCompleteMode = ToilCompleteMode.Delay;
            waitToil.defaultDuration     = Mathf.CeilToInt(compReloader.Props.reloadTime.SecondsToTicks() / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed));
            yield return(waitToil.WithProgressBarToilDelay(indReloader));

            //Actual reloader
            Toil reloadToil = new Toil();

            reloadToil.AddFinishAction(() => compReloader.LoadAmmo(initAmmo));
            yield return(reloadToil);

            // If reloading one shot at a time and if possible to reload, jump back to do-nothing toil
            System.Func <bool> jumpCondition =
                () => compReloader.Props.reloadOneAtATime &&
                compReloader.CurMagCount < compReloader.Props.magazineSize &&
                (!compReloader.UseAmmo || compReloader.TryFindAmmoInInventory(out initAmmo));
            Toil jumpToil = Toils_Jump.JumpIf(waitToil, jumpCondition);

            yield return(jumpToil);

            //Continue previous job if possible
            Toil continueToil = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(continueToil);
        }
Esempio n. 29
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // モップまで移動
            yield return(Toils_Goto.GotoThing(MopInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(MopInd));

            // モップを手に取る
            yield return(Toils_Haul.StartCarryThing(MopInd));

            // ターゲットが掃除対象として不適になっていたらリストから外す
            // Thing系にしか使えない
            var initExtractTargetFromQueue = Toils_Mizu.ClearConditionSatisfiedTargets(
                MoppingInd,
                lti => lti.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null);

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(MoppingInd));

            // ターゲットキューから次のターゲットを取り出す
            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(MoppingInd));

            // ターゲットの元へ移動
            yield return(Toils_Goto.GotoCell(MoppingInd, PathEndMode.Touch).JumpIf(
                             () =>
            {
                var target = pawn.jobs.curJob.GetTarget(MoppingInd);
                if (target.HasThing)
                {
                    return true;
                }

                return target.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null;
            },
                             initExtractTargetFromQueue).JumpIfOutsideMopArea(MoppingInd, initExtractTargetFromQueue));

            // モップ掛け作業中
            var mopToil = new Toil
            {
                initAction = delegate
                {
                    // 必要工数の計算
                    ticksLeftThisToil = MoppingTicks;
                },

                // 細々とした設定
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            mopToil.WithProgressBar(MoppingInd, () => 1f - ((float)ticksLeftThisToil / MoppingTicks), true);
            mopToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);

            // 掃除中に条件が変更されたら最初に戻る
            mopToil.JumpIf(
                () =>
            {
                var target = pawn.jobs.curJob.GetTarget(MoppingInd);
                if (target.HasThing)
                {
                    return(true);
                }

                return(target.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null);
            },
                initExtractTargetFromQueue);
            mopToil.JumpIfOutsideMopArea(MoppingInd, initExtractTargetFromQueue);
            yield return(mopToil);

            // モップ掛け終了
            var finishToil = new Toil
            {
                initAction = () =>
                {
                    // モップオブジェクト生成
                    var moppedThing = ThingMaker.MakeThing(MizuDef.Thing_MoppedThing);
                    GenSpawn.Spawn(moppedThing, MoppingPos, mopToil.actor.Map);

                    // モップから水を減らす
                    var compTool = Mop.GetComp <CompWaterTool>();
                    compTool.StoredWaterVolume -= ConsumeWaterVolume;
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(finishToil);

            // 最初に戻る
            yield return(Toils_Jump.JumpIf(
                             initExtractTargetFromQueue,
                             () => pawn.jobs.curJob.GetTargetQueue(MoppingInd).Count > 0));

            // モップを片付ける場所を決める
            yield return(Toils_Mizu.TryFindStoreCell(MopInd, MopPlaceInd));

            // Toil startCarryToil = new Toil();
            // startCarryToil.initAction = () =>
            // {
            // var actor = startCarryToil.actor;
            // var curJob = actor.jobs.curJob;
            // IntVec3 c;
            // if (StoreUtility.TryFindBestBetterStoreCellFor(Mop, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c))
            // {
            // curJob.targetC = c;
            // curJob.count = 99999;
            // return;
            // }
            // };
            // startCarryToil.defaultCompleteMode = ToilCompleteMode.Instant;
            // yield return startCarryToil;

            // 倉庫まで移動
            yield return(Toils_Goto.GotoCell(MopPlaceInd, PathEndMode.Touch));

            // 倉庫に置く
            yield return(Toils_Haul.PlaceHauledThingInCell(MopPlaceInd, null, true));
        }
Esempio n. 30
0
        static IEnumerable <Toil> prepToils(JobDriver_Ingest driver, Toil chewToil)
        {
            if ((bool)LeatingFromInventory.GetValue(driver))
            {
                yield return(Toils_Misc.TakeItemFromInventoryToCarrier(driver.pawn, TargetIndex.A));
            }
            else
            {
                yield return((Toil)LReserveFood.Invoke(driver, new object[] { }));

                Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A);
                yield return(Toils_Jump.JumpIf(gotoToPickup, () => driver.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)));

                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A));

                yield return(Toils_Jump.Jump(chewToil));

                yield return(gotoToPickup);

                yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, driver.pawn));

                gotoToPickup = null;
            }
            if (driver.job.takeExtraIngestibles > 0)
            {
                foreach (Toil toil in (IEnumerable <Toil>)LTakeExtraIngestibles.Invoke(driver, new object[] { }))
                {
                    yield return(toil);
                }
            }
            if (!driver.pawn.Drafted)
            {
                yield return(reserveChewSpot(driver.pawn, TargetIndex.A, TargetIndex.B));

                Toil gotospot = gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A);

                if (!Utility.IncapableOfCleaning(driver.pawn))
                {
                    TargetIndex filthListIndex = TargetIndex.B;
                    TargetIndex progIndex      = TargetIndex.A;
                    Toil        FilthList      = new Toil();
                    FilthList.initAction = delegate()
                    {
                        Job curJob = FilthList.actor.jobs.curJob;
                        //
                        if (curJob.GetTargetQueue(filthListIndex).NullOrEmpty())
                        {
                            LocalTargetInfo A = curJob.GetTarget(filthListIndex);
                            if (!A.HasThing)
                            {
                                return;
                            }
                            IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num);
                            Utility.AddFilthToQueue(curJob, filthListIndex, l, FilthList.actor);
                            FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(filthListIndex), curJob);
                            curJob.GetTargetQueue(filthListIndex).Add(A);
                        }
                    };

                    yield return(FilthList);

                    yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty()));

                    Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(filthListIndex, true);
                    yield return(nextTarget);

                    yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty()));

                    yield return(Toils_Goto.GotoThing(filthListIndex, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget).JumpIfOutsideHomeArea(filthListIndex, nextTarget));

                    //
                    if (driver.job.GetTargetQueue(progIndex).Count == 0)
                    {
                        driver.job.GetTargetQueue(progIndex).Add(new IntVec3(0, 0, 0));
                    }
                    //
                    Toil clean = new Toil();
                    clean.initAction = delegate()
                    {
                        Filth filth   = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth;
                        var   progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex);
                        progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness);
                    };
                    clean.tickAction = delegate()
                    {
                        Filth   filth   = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth;
                        var     progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex);
                        IntVec3 iv      = progQue[0].Cell;
                        iv.x += 1;
                        iv.y += 1;
                        if (iv.x > filth.def.filth.cleaningWorkToReduceThickness)
                        {
                            filth.ThinFilth();
                            iv.x = 0;
                            if (filth.Destroyed)
                            {
                                clean.actor.records.Increment(RecordDefOf.MessesCleaned);
                                driver.ReadyForNextToil();
                                return;
                            }
                        }
                        progQue[0] = iv;
                    };
                    clean.defaultCompleteMode = ToilCompleteMode.Never;
                    clean.WithEffect(EffecterDefOf.Clean, filthListIndex);
                    clean.WithProgressBar(filthListIndex,
                                          delegate()
                    {
                        var q        = driver.job.GetTargetQueue(progIndex)[0];
                        float result = (float)q.Cell.y / q.Cell.z;
                        return(result);
                    }
                                          , true, -0.5f);
                    clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
                    clean.JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget);
                    clean.JumpIfOutsideHomeArea(filthListIndex, nextTarget);
                    clean.FailOnDestroyedOrNull(TargetIndex.A);
                    yield return(clean);

                    yield return(Toils_Jump.Jump(nextTarget));
                }
                yield return(gotospot);
            }
            yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A));

            yield break;
        }