示例#1
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Init();
            yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A));

            Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A);

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A));

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

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

            Toil  cut   = new Toil();
            Plant plant = (Plant)Thing;
            CompHarvestableReagent reagent = Thing.TryGetComp <CompHarvestableReagent>();

            cut.tickAction = delegate
            {
                Pawn actor = cut.actor;
                if (actor.skills != null)
                {
                    actor.skills.Learn(DefDatabase <SkillDef> .GetNamed("Alchemy", true), xpPerTick, false);
                }
                float statValue = actor.GetStatValue(DefDatabase <StatDef> .GetNamed("ReagentHarvestingSpeed"), true);
                float num       = statValue;
                workDone += num;
                if (!reagent.IsSecondaryHarvest)
                {
                    if (plant != null)
                    {
                        if (workDone >= plant.def.plant.harvestWork)
                        {
                            if (plant.def.plant.harvestedThingDef != null)
                            {
                                if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(DefDatabase <StatDef> .GetNamed("ReagentHarvestingYield"), true))
                                {
                                    Vector3 loc = (pawn.DrawPos + plant.DrawPos) / 2f;
                                    MoteMaker.ThrowText(loc, Map, "TextMote_ReagentHarvestFailed".Translate(), 3.65f);
                                }
                                else
                                {
                                    int num2 = plant.YieldNow();
                                    if (num2 > 0)
                                    {
                                        Thing harvestedThing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null);
                                        harvestedThing.stackCount = num2;
                                        if (actor.Faction != Faction.OfPlayer)
                                        {
                                            harvestedThing.SetForbidden(true, true);
                                        }
                                        GenPlace.TryPlaceThing(harvestedThing, actor.Position, Map, ThingPlaceMode.Near, null);
                                        actor.records.Increment(DefDatabase <RecordDef> .GetNamed("ReagentsHarvested"));
                                    }
                                }
                            }
                            plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                            plant.PlantCollected();
                            workDone = 0f;
                            ReadyForNextToil();
                            return;
                        }
                    }
                    // Animal
                    // Inanimate
                }
                else
                {
                    if (workDone >= reagent.HarvestWork)
                    {
                        if (reagent.HarvestedThingDef != null)
                        {
                            if (actor.RaceProps.Humanlike && reagent.HarvestFailable && Rand.Value > actor.GetStatValue(DefDatabase <StatDef> .GetNamed("ReagentHarvestingYield"), true))
                            {
                                Vector3 loc = (pawn.DrawPos + reagent.parent.DrawPos) / 2f;
                                MoteMaker.ThrowText(loc, Map, "TextMote_ReagentHarvestFailed".Translate(), 3.65f);
                            }
                            else
                            {
                                int num2 = reagent.YieldNow();
                                if (num2 > 0)
                                {
                                    Thing harvestedThing = ThingMaker.MakeThing(reagent.HarvestedThingDef, null);
                                    harvestedThing.stackCount = num2;
                                    if (actor.Faction != Faction.OfPlayer)
                                    {
                                        harvestedThing.SetForbidden(true, true);
                                    }
                                    GenPlace.TryPlaceThing(harvestedThing, actor.Position, Map, ThingPlaceMode.Near, null);
                                    actor.records.Increment(DefDatabase <RecordDef> .GetNamed("ReagentsHarvested"));
                                }
                            }
                        }
                        if (plant != null)
                        {
                            plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                        }

                        reagent.ReagentCollected(actor);
                        workDone = 0f;
                        ReadyForNextToil();
                        return;
                    }
                }
            };
            cut.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            cut.defaultCompleteMode = ToilCompleteMode.Never;
            cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A);
            if (!reagent.IsSecondaryHarvest)
            {
                if (plant != null)
                {
                    cut.WithProgressBar(TargetIndex.A, () => workDone / plant.def.plant.harvestWork, true, -0.5f);
                    cut.PlaySustainerOrSound(() => plant.def.plant.soundHarvesting);
                }

                // Animals
            }
            else
            {
                cut.WithProgressBar(TargetIndex.A, () => workDone / reagent.HarvestWork, true, -0.5f);
                if (plant != null)
                {
                    cut.PlaySustainerOrSound(() => plant.def.plant.soundHarvesting);
                }
            }

            yield return(cut);

            Toil workDoneToil = WorkDoneToil();

            if (workDoneToil != null)
            {
                yield return(workDoneToil);
            }
            yield return(Toils_Jump.Jump(initExtractTargetFromQueue));
        }
示例#2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil toil = new Toil();

            yield return(new Toil
            {
                initAction = delegate()
                {
                    try
                    {
                        ZLogger.Message("--------------------------");
                        for (int i = job.targetQueueB.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueB[i];

                            ZLogger.Message("-1 job.targetQueueB: " + target.Thing);
                            ZLogger.Message("-1 job.targetQueueB.Map: " + target.Thing.Map);
                            ZLogger.Message("-1 job.targetQueueB.stackCount: " + target.Thing.stackCount);
                            ZLogger.Message("-1 job.targetQueueB.countQueue: " + job.countQueue[i]);
                        }
                    }
                    catch { }

                    ZLogger.Message("-1 toil.actor: " + toil.actor);
                    ZLogger.Message("-1 toil.actor.Position: " + toil.actor.Position);
                    ZLogger.Message("-1 toil.actor.Map: " + toil.actor.Map);
                    ZLogger.Message("-1 TargetB.Thing: " + TargetB.Thing);
                    ZLogger.Message("-1 TargetB.Thing.Position: " + TargetB.Thing?.Position);
                    ZLogger.Message("-1 TargetB.Thing.Map: " + TargetB.Thing?.Map);

                    ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true);
                    ZLogger.Message("-1 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB));
                    ZLogger.Message("-1 TargetB.Thing == null: " + (TargetB.Thing == null).ToString());
                    ZLogger.Message("-1 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString());
                    ZLogger.Message("-1 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString());
                    ZLogger.Message("-1 failcondition" + ((TargetB == null ||
                                                           !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) ||
                                                           toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB))
                        ? JobCondition.Ongoing : JobCondition.Incompletable).ToString());
                    try
                    {
                        for (int i = job.targetQueueA.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueA[i];
                            ZLogger.Message("-1 job.targetQueueA: " + target.Thing);
                            ZLogger.Message("-1 job.targetQueueA: " + target.Thing.Map);
                        }
                    }
                    catch { }
                }
            });

            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)
                    {
                        Log.Message(this.pawn + " - 1 fail", true);
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        Log.Message(this.pawn + " - 2 fail", true);
                        return(true);
                    }
                }
                return(false);
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            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(new Toil
            {
                initAction = delegate()
                {
                    ZLogger.Message("1 toil.actor: " + toil.actor);
                    ZLogger.Message("1 toil.actor.Position: " + toil.actor.Position);
                    ZLogger.Message("1 toil.actor.Map: " + toil.actor.Map);
                    ZLogger.Message("1 TargetB.Thing: " + TargetB.Thing);
                    ZLogger.Message("1 TargetB.Thing.Position: " + TargetB.Thing?.Position);
                    ZLogger.Message("1 TargetB.Thing.Map: " + TargetB.Thing?.Map);

                    ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true);
                    ZLogger.Message("1 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB));
                    ZLogger.Message("1 TargetB.Thing == null: " + (TargetB.Thing == null).ToString());
                    ZLogger.Message("1 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString());
                    ZLogger.Message("1 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString());
                    ZLogger.Message("1 failcondition" + ((TargetB == null ||
                                                          !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) ||
                                                          toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB))
                        ? JobCondition.Ongoing : JobCondition.Incompletable).ToString());
                    try
                    {
                        for (int i = job.targetQueueA.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueA[i];
                            ZLogger.Message("1 job.targetQueueA: " + target.Thing);
                            ZLogger.Message("1 job.targetQueueA: " + target.Thing.Map);
                            ZLogger.Message("1 job.targetQueueA: " + target.Thing.stackCount);
                        }
                    }
                    catch { }
                    try
                    {
                        ZLogger.Message("--------------------------");
                        for (int i = job.targetQueueB.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueB[i];

                            ZLogger.Message("1 job.targetQueueB: " + target.Thing);
                            ZLogger.Message("1 job.targetQueueB.Map: " + target.Thing.Map);
                            ZLogger.Message("1 job.targetQueueB.stackCount: " + target.Thing.stackCount);
                            ZLogger.Message("1 job.targetQueueB.countQueue: " + job.countQueue[i]);
                        }
                    }
                    catch { }
                }
            });

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

            Toil extract = ExtractNextTargetFromQueue(TargetIndex.B);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    ZLogger.Message("2 toil.actor: " + toil.actor);
                    ZLogger.Message("2 toil.actor.Position: " + toil.actor.Position);
                    ZLogger.Message("2 toil.actor.Map: " + toil.actor.Map);
                    ZLogger.Message("2 TargetB.Thing: " + TargetB.Thing);
                    ZLogger.Message("2 TargetB.Thing.Position: " + TargetB.Thing?.Position);
                    ZLogger.Message("2 TargetB.Thing.Map: " + TargetB.Thing?.Map);

                    ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true);
                    ZLogger.Message("2 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB));
                    ZLogger.Message("2 TargetB.Thing == null: " + (TargetB.Thing == null).ToString());
                    ZLogger.Message("2 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString());
                    ZLogger.Message("2 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString());
                    ZLogger.Message("2 failcondition" + ((TargetB == null ||
                                                          !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) ||
                                                          toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB))
                        ? JobCondition.Ongoing : JobCondition.Incompletable).ToString());

                    try
                    {
                        for (int i = job.targetQueueA.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueA[i];
                            ZLogger.Message("2 job.targetQueueA: " + target.Thing);
                            ZLogger.Message("2 job.targetQueueA: " + target.Thing.Map);
                        }
                    }
                    catch { }
                    try
                    {
                        ZLogger.Message("--------------------------");
                        for (int i = job.targetQueueB.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueB[i];

                            ZLogger.Message("2 job.targetQueueB: " + target.Thing);
                            ZLogger.Message("2 job.targetQueueB.Map: " + target.Thing.Map);
                            ZLogger.Message("2 job.targetQueueB.stackCount: " + target.Thing.stackCount);
                            ZLogger.Message("2 job.targetQueueB.countQueue: " + job.countQueue[i]);
                        }
                    }
                    catch { }
                }
            });

            yield return(extract);

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

            yield return(new Toil
            {
                initAction = delegate()
                {
                    ZLogger.Message("3 toil.actor: " + toil.actor);
                    ZLogger.Message("3 toil.actor.Position: " + toil.actor.Position);
                    ZLogger.Message("3 toil.actor.Map: " + toil.actor.Map);
                    ZLogger.Message("3 TargetB.Thing: " + TargetB.Thing);
                    ZLogger.Message("3 TargetB.Thing.Position: " + TargetB.Thing?.Position);
                    ZLogger.Message("3 TargetB.Thing.Map: " + TargetB.Thing?.Map);

                    ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true);
                    ZLogger.Message("3 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB));
                    ZLogger.Message("3 TargetB.Thing == null: " + (TargetB.Thing == null).ToString());
                    ZLogger.Message("3 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString());
                    ZLogger.Message("3 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString());
                    ZLogger.Message("3 failcondition" + ((TargetB == null ||
                                                          !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) ||
                                                          toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB))
                        ? JobCondition.Ongoing : JobCondition.Incompletable).ToString());
                    try
                    {
                        for (int i = job.targetQueueA.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueA[i];
                            ZLogger.Message("3 job.targetQueueA: " + target.Thing);
                            ZLogger.Message("3 job.targetQueueA: " + target.Thing.Map);
                        }
                    }
                    catch { }
                    try
                    {
                        ZLogger.Message("--------------------------");
                        for (int i = job.targetQueueB.Count - 1; i >= 0; i--)
                        {
                            var target = job.targetQueueB[i];

                            ZLogger.Message("3 job.targetQueueB: " + target.Thing);
                            ZLogger.Message("3 job.targetQueueB.Map: " + target.Thing.Map);
                            ZLogger.Message("3 job.targetQueueB.stackCount: " + target.Thing.stackCount);
                            ZLogger.Message("3 job.targetQueueB.countQueue: " + job.countQueue[i]);
                        }
                    }
                    catch { }
                }
            });

            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(DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(FinishRecipeAndStartStoringProduct());

            if (!job.RecipeDef.products.NullOrEmpty() || !job.RecipeDef.specialProducts.NullOrEmpty())
            {
                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);
            }
        }
示例#3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            /*
             *
             *  Toil Configurations
             *
             */
            Toil prepareToSpin = new Toil();

            prepareToSpin.initAction = delegate
            {
                if (Prey == null && Corpse == null)
                {
                    this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                if (Prey.Dead)
                {
                    this.pawn.CurJob.SetTarget(TargetIndex.A, Prey.Corpse);
                }
            };

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

            gotoBody.AddPreInitAction(new Action(delegate
            {
                this.pawn.ClearAllReservations();
                this.pawn.Reserve(TargetA, this.job);
                //this.Map.physicalInteractionReservationManager.ReleaseAllForTarget(TargetA);
                //this.Map.physicalInteractionReservationManager.Reserve(this.GetActor(), TargetA);
                currentActivity = "Spinning Cocoon";
            }));

            Toil spinDelay = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = 500,
                initAction          = delegate
                {
                    currentActivity = "Spinning Cocoon";
                }
            };

            spinDelay.WithProgressBarToilDelay(TargetIndex.B);
            Toil spinBody = new Toil
            {
                initAction = delegate
                {
                    //Log.Message("5");
                    var spinner = this.GetActor() as Spider;
                    if (spinner != null)
                    {
                        Building_Cocoon newCocoon;
                        Thing           toLoad;
                        IntVec3         newPosition;
                        if (Prey.Dead)
                        {
                            toLoad      = Prey.Corpse;
                            newPosition = Prey.Corpse.Position;
                        }
                        else
                        {
                            toLoad      = Prey;
                            newPosition = Prey.Position;
                        }
                        if (!toLoad.Spawned)
                        {
                            this.EndJobWith(JobCondition.Incompletable); return;
                        }

                        toLoad.DeSpawn();
                        toLoad.holdingOwner = null;
                        if (!GenConstruct.CanPlaceBlueprintAt(CocoonDef, newPosition, Rot4.North, this.pawn.Map).Accepted)
                        {
                            var cells = GenAdj.CellsAdjacent8Way(new TargetInfo(newPosition, this.pawn.Map));
                            foreach (IntVec3 cell in cells)
                            {
                                if (GenConstruct.CanPlaceBlueprintAt(CocoonDef, cell, Rot4.North, this.Map).Accepted)
                                {
                                    newPosition = cell;
                                    break;
                                }
                            }
                        }

                        newCocoon = (Building_Cocoon)GenSpawn.Spawn(CocoonDef, newPosition, spinner.Map);
                        //Log.Message("New Spinner: " + newCocoon.Spinner.Label);
                        newCocoon.TryGetInnerInteractableThingOwner().TryAdd(toLoad);
                        this.pawn?.CurJob?.SetTarget(TargetIndex.B, newCocoon);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            Toil pickupCocoon = Toils_Haul.StartCarryThing(TargetIndex.B);

            pickupCocoon.AddPreInitAction(new Action(delegate
            {
                //this.TargetB.Thing.DeSpawn();
                this.pawn.CurJob.SetTarget(TargetIndex.C, TargetB.Thing);
                this.pawn.Reserve(TargetC, this.job);
                //this.pawn.Map.physicalInteractionReservationManager.Reserve(this.pawn, TargetC);
            }));
            Toil relocateCocoon = Toils_Haul.CarryHauledThingToCell(TargetIndex.C);
            Toil dropCocoon     = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, relocateCocoon, false).FailOn(() => !GenConstruct.CanPlaceBlueprintAt(CocoonDef, TargetC.Cell, Rot4.North, this.Map).Accepted);

            this.AddFinishAction(new Action(delegate
            {
                this.pawn.Map.physicalInteractionReservationManager.ReleaseAllClaimedBy(this.pawn);
            }));


            /*
             *
             *  Toil Execution
             *
             */
            yield return(new Toil
            {
                initAction = delegate
                {
                    this.Map.attackTargetsCache.UpdateTarget(this.pawn);
                },
                atomicWithPrevious = true,
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            Action onHitAction = delegate
            {
                Pawn prey           = this.Prey;
                bool surpriseAttack = this.firstHit && !prey.IsColonist;
                if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack))
                {
                    if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey))
                    {
                        this.notifiedPlayer = true;
                        Messages.Message("MessageAttackedByPredator".Translate(new object[]
                        {
                            prey.LabelShort,
                            this.pawn.LabelIndefinite()
                        }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatBig);// MessageSound.SeriousAlert);
                    }
                    this.Map.attackTargetsCache.UpdateTarget(this.pawn);
                }
                this.firstHit = false;
            };

            //yield return Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIf(() => Prey.Downed || Prey.Dead, prepareToSpin).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (float)(this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f);
            yield return(prepareToSpin.FailOn(() => Prey == null));

            yield return(gotoBody.FailOn(() => Prey == null));

            yield return(spinDelay.FailOn(() => Prey == null));

            yield return(spinBody.FailOn(() => Prey == null));
            //yield return pickupCocoon;
            //yield return relocateCocoon;
            //yield return dropCocoon;

            //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.pawn.needs.food.CurLevelPercentage < 0.9f);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            rotateToFace = Facing;


            AddEndCondition(delegate
            {
                if (ExecutionerPawn?.CurJob == null)
                {
                    return(JobCondition.Incompletable);
                }

                if (ExecutionerPawn.CurJob.def == CultsDefOf.Cults_ReflectOnResult)
                {
                    return(JobCondition.Succeeded);
                }

                if (ExecutionerPawn.CurJob.def != CultsDefOf.Cults_HoldSacrifice)
                {
                    return(JobCondition.Incompletable);
                }

                return(JobCondition.Ongoing);
            });

            this.EndOnDespawnedOrNull(Spot);
            this.EndOnDespawnedOrNull(Build);


            yield return(Toils_Reserve.Reserve(Spot));

            //Toil 1: Go to the locations
            var gotoExecutioner = TargetC.HasThing
                ? Toils_Goto.GotoThing(Spot, PathEndMode.OnCell)
                : Toils_Goto.GotoCell(Spot, PathEndMode.OnCell);

            yield return(gotoExecutioner);

            //Toil 2: 'Attend'
            var altarToil = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = CultUtility.ritualDuration
            };

            altarToil.AddPreTickAction(() =>
            {
                pawn.GainComfortFromCellIfPossible();
                pawn.rotationTracker.FaceCell(TargetB.Cell);
                if (report == "")
                {
                    report = "Cults_AttendingSacrifice".Translate();
                }

                if (ExecutionerPawn?.CurJob == null)
                {
                    return;
                }

                if (ExecutionerPawn.CurJob.def != CultsDefOf.Cults_HoldSacrifice)
                {
                    ReadyForNextToil();
                }
            });
            altarToil.JumpIf(() => ExecutionerPawn.CurJob.def == CultsDefOf.Cults_HoldSacrifice, altarToil);
            yield return(altarToil);

            //ToDo -- Add random Ia! Ia!
            yield return(new Toil
            {
                initAction = delegate
                {
                    //Do something? Ia ia!
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            //Toil 3 Reflect on worship
            var reflectingTime = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = CultUtility.reflectDuration
            };

            reflectingTime.AddPreTickAction(() => report = "Cults_ReflectingOnSacrifice".Translate());
            yield return(reflectingTime);

            //Toil 3 Reset the altar and clear variables.
            yield return(new Toil
            {
                initAction = delegate
                {
                    if (Altar == null)
                    {
                        return;
                    }

                    if (Altar.currentSacrificeState != Building_SacrificialAltar.SacrificeState.finished)
                    {
                        Altar.ChangeState(Building_SacrificialAltar.State.sacrificing,
                                          Building_SacrificialAltar.SacrificeState.finished);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });


            AddFinishAction(() =>
            {
                //When the ritual is finished -- then let's give the thoughts

                /*
                 * if (Altar.currentSacrificeState == Building_SacrificialAltar.SacrificeState.finished)
                 * {
                 *  if (this.pawn == null) return;
                 *  if (Altar.sacrifice != null)
                 *  {
                 *      CultUtility.AttendSacrificeTickCheckEnd(this.pawn, Altar.sacrifice);
                 *  }
                 *  else
                 *  {
                 *      CultUtility.AttendSacrificeTickCheckEnd(this.pawn, null);
                 *  }
                 * }
                 */
                if (TargetC.Cell.GetEdifice(pawn.Map) != null)
                {
                    if (pawn.Map.reservationManager.ReservedBy(TargetC.Cell.GetEdifice(pawn.Map), pawn))
                    {
                        pawn.ClearAllReservations(); // this.pawn.Map.reservationManager.Release(this.TargetC.Cell.GetEdifice(this.pawn.Map), pawn);
                    }
                }
                else
                {
                    if (pawn.Map.reservationManager.ReservedBy(TargetC.Cell.GetEdifice(pawn.Map), pawn))
                    {
                        pawn.ClearAllReservations(); //this.pawn.Map.reservationManager.Release(this.job.targetC.Cell, this.pawn);
                    }
                }
            });
        }
示例#5
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(iPrisoner);
            this.FailOnDestroyedOrNull(iSacrificeBuilding);
            this.FailOnAggroMentalState(iPrisoner);

            yield return(Toils_Goto.GotoThing(iPrisoner, PathEndMode.OnCell));

            yield return(Toils_Haul.StartCarryThing(iPrisoner, true, false));

            yield return(Toils_Goto.GotoThing(iSacrificeBuilding, SacrificeSpot.InteractionCell));

            yield return(Toils_Reserve.Release(iPrisoner));

            var doSacrificePrisoner = new Toil
            {
                socialMode = RandomSocialMode.Off,
            };

            doSacrificePrisoner.initAction = () =>
            {
                Sacrificer.carryTracker.TryDropCarriedThing(SacrificeSpot.InteractionCell, ThingPlaceMode.Direct, out var thing, null);
                Prisoner.jobs.StartJob(JobMaker.MakeJob(Defs.PrisonerWait));
            };
            doSacrificePrisoner.AddFailCondition(() => Prisoner.Dead);
            doSacrificePrisoner.defaultCompleteMode = ToilCompleteMode.Never;
            doSacrificePrisoner.AddPreTickAction(() =>
            {
                --TicksLeft;
                if (TicksLeft <= 0)
                {
                    ReadyForNextToil();
                }
            });
            yield return(doSacrificePrisoner.WithProgressBar(iPawn, () => (TicksMax - (float)TicksLeft) / TicksMax));

            var afterSacrificePrisoner = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Instant,
                initAction          = () =>
                {
                    var heartBpr = Prisoner.RaceProps.body.AllParts.Find(bpr => bpr.def.defName == "Heart");
                    var dInfo    = new DamageInfo(Defs.HeartExtraction, 99999f, armorPenetration: 999f, hitPart: heartBpr);
                    Prisoner.Kill(dInfo);
                    ThoughtUtility.GiveThoughtsForPawnExecuted(Prisoner, Sacrificer, PawnExecutionKind.GenericBrutal);

                    // Apply negative relations modifier.
                    if (pawn.Faction != null && Prisoner.Faction != null)
                    {
                        Faction          playerFaction   = pawn.Faction;
                        Faction          prisonerFaction = Prisoner.Faction;
                        string           reason          = "GoodwillChangedReason_RemovedBodyPart".Translate(heartBpr.Label);
                        GlobalTargetInfo?LookTargets     = pawn;
                        playerFaction.TryAffectGoodwillWith(prisonerFaction, -25);
                    }

                    // Apply thoughts to pawns.
                    foreach (var mapPawn in Map.mapPawns.FreeColonistsAndPrisoners)
                    {
                        if (mapPawn.IsPrisoner)
                        {
                            mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedFear);
                        }
                        else if (mapPawn.IsColonist && (mapPawn.IsRevia() || mapPawn.IsSkarnite()))
                        {
                            mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedPositive);
                        }
                        else if (mapPawn.IsColonist &&
                                 !(mapPawn.IsCannibal() || mapPawn.IsPsychopath() || mapPawn.IsBloodlust()))
                        {
                            mapPawn.needs.mood.thoughts.memories.TryGainMemory(Defs.SacrificedNegative);
                        }
                    }

                    // Spawn the product, or handle one of the other effects.
                    // Find a good spot to spawn the product.
                    IntVec3 spawnPos = CellFinder.FindNoWipeSpawnLocNear(
                        Prisoner.Position,
                        Map,
                        Defs.Bloodstone,
                        Rot4.Random, 6, pos =>
                    {
                        return
                        ((pos.x < Prisoner.Position.x - 1 || pos.x > Prisoner.Position.x + 1) &&
                         // F**k you Tynan. Learn your coordinates!
                         (pos.z < Prisoner.Position.z - 1 || pos.z > Prisoner.Position.z + 1));
                    });

                    if (Map.GameConditionManager.ConditionIsActive(Defs.Eclipse))
                    {
                        var missingParts = pawn.health.hediffSet.GetMissingPartsCommonAncestors();
                        if (missingParts.Count > 0)
                        {
                            var missing = missingParts.RandomElement();
                            pawn.health.hediffSet.hediffs.Remove(missing);
                            var maxHp = missing.Part.def.GetMaxHealth(pawn);

                            var injuryHediff   = pawn.health.AddHediff(HediffDefOf.Cut, missing.Part, new DamageInfo(DamageDefOf.Rotting, 1.0f, 10000.00f));
                            var permHediffComp = injuryHediff.TryGetComp <HediffComp_GetsPermanent>();
                            injuryHediff.Severity      = maxHp / 2.0f;
                            permHediffComp.IsPermanent = true;
                        }
                        else
                        {
                            var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map);
                            thing.stackCount += 2;
                        }
                    }
                    else if (Map.GameConditionManager.ConditionIsActive(Defs.SolarFlare))
                    {
                        var permInjuries = pawn.health.hediffSet.hediffs.Where(h => h.IsPermanent() && !(h is Hediff_MissingPart)).ToList();
                        if (permInjuries.Count > 0)
                        {
                            var randomInjury = permInjuries.RandomElement();
                            randomInjury.Severity -= randomInjury.Part.depth == BodyPartDepth.Inside ? 2.0f : 4.0f;
                        }
                        else
                        {
                            var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map);
                            thing.stackCount += 1;
                        }
                    }
                    else
                    {
                        var thing = GenSpawn.Spawn(Defs.Bloodstone, spawnPos, Map);
                    }

                    var bloodthirst = Sacrificer.needs.TryGetNeed <BloodthirstNeed>();
                    if (bloodthirst != null)
                    {
                        bloodthirst.CurLevel += 0.80f * Prisoner.BodySize;
                    }
                    TaleRecorder.RecordTale(Defs.TaleSacrificed, new[] { Sacrificer, Prisoner });

                    // Find a good spot to move the prisoner corpse.
                    IntVec3 movePos = CellFinder.FindNoWipeSpawnLocNear(
                        Prisoner.Position,
                        Map,
                        Prisoner.Corpse.def,
                        Rot4.Random, 6, pos =>
                    {
                        return
                        ((pos.x < Prisoner.Position.x - 1 || pos.x > Prisoner.Position.x + 1) &&
                         // F**k you Tynan. Learn your coordinates!
                         (pos.z < Prisoner.Position.z - 1 || pos.z > Prisoner.Position.z + 1));
                    });
                    Prisoner.Corpse.Position = movePos;
                }
            };

            yield return(afterSacrificePrisoner);
        }
示例#6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddEndCondition(delegate()
            {
                var thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile <JobDriver_DoBill>(TargetIndex.A);
            this.FailOn <JobDriver_DoBill>(delegate()
            {
                if (!(this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver))
                {
                    return(false);
                }
                if (this.job.bill.DeletedOrDereferenced)
                {
                    return(true);
                }
                if (!billGiver.CurrentlyUsableForBills())
                {
                    return(true);
                }
                return(false);
            });
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

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

            var tableThing     = this.job.GetTarget(TargetIndex.A).Thing as Building_СontainmentBreach;
            var refuelableComp = tableThing.GetComp <CompRefuelable>();  //I think you should check this for Null, but i'm not sure where are you using it.
            var toil           = new Toil
            {
                initAction = delegate()
                {
                    this.job.bill.Notify_DoBillStarted(this.pawn);
                    this.workCycleProgress = this.job.bill.recipe.workAmount;
                },
                tickAction = delegate()
                {
                    this.workCycleProgress -= this.pawn.GetStatValue(StatDefOf.WorkToMake, true);
                    tableThing.UsedThisTick();
                    if (!tableThing.CurrentlyUsableForBills() || (refuelableComp != null && !refuelableComp.HasFuel))
                    {
                        this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true, true);
                    }

                    if (!(this.workCycleProgress <= 0f))
                    {
                        return;
                    }
                    var workSkill = this.job.bill.recipe.workSkill;
                    if (workSkill != null)
                    {
                        SkillRecord skill = this.pawn.skills.GetSkill(workSkill);
                        skill?.Learn(0.11f * this.job.bill.recipe.workSkillLearnFactor, false);
                    }
                    GenSpawn.Spawn(tableThing.GetAlienBloodByRecipe(this.job.bill.recipe),
                                   tableThing.InteractionCell, tableThing.Map, 0);
                    Toils_Reserve.Release(TargetIndex.A);
                    this.pawn.GainComfortFromCellIfPossible(false);
                    this.job.bill.Notify_IterationCompleted(this.pawn, null);
                    this.ReadyForNextToil();
                },
                defaultCompleteMode = ToilCompleteMode.Never
            };

            toil.WithEffect(() => this.job.bill.recipe.effectWorking, TargetIndex.A);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(TargetIndex.A, delegate()
            {
                return(PurpleIvyUtils.GetPercentageFromPartWhole
                           (this.job.bill.recipe.workAmount - this.workCycleProgress,
                           (int)this.job.bill.recipe.workAmount) / 100f);
            }, false, 0.5f);
            toil.FailOn <Toil>(delegate()
            {
                return(this.job.bill.suspended || this.job.bill.DeletedOrDereferenced || (this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver && !billGiver.CurrentlyUsableForBills()));
            });
            yield return(toil);

            yield break;
        }
示例#7
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.FailOnDestroyedOrNull(TargetIndex.B);
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

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

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.OnCell));

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

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

            yield return(new Toil
            {
                initAction = delegate
                {
                    Thing straitjacket = null;
                    this.pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out straitjacket, null);

                    Pawn pawnToForceIntoStraitjacket = (Pawn)TargetA.Thing;
                    if (pawnToForceIntoStraitjacket != null)
                    {
                        if (!pawnToForceIntoStraitjacket.InAggroMentalState)
                        {
                            GenClamor.DoClamor(pawn, 10f, ClamorDefOf.Harm);
                            if (!CheckAcceptStraitJacket(pawnToForceIntoStraitjacket, this.pawn))
                            {
                                this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                            }
                        }
                    }
                }, defaultCompleteMode = ToilCompleteMode.Instant
            });

            Toil toil2 = new Toil();

            toil2.defaultCompleteMode = ToilCompleteMode.Delay;
            toil2.defaultDuration     = 500;
            toil2.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            toil2.initAction = delegate
            {
                Pawn pawnToForceIntoStraitjacket = (Pawn)TargetA.Thing;

                if (pawnToForceIntoStraitjacket != null)
                {
                    if (!pawnToForceIntoStraitjacket.InAggroMentalState)
                    {
                        PawnUtility.ForceWait(pawnToForceIntoStraitjacket, toil2.defaultDuration, this.pawn);
                    }
                }
            };
            yield return(toil2);

            yield return(new Toil
            {
                initAction = delegate
                {
                    Takee.apparel.Wear(Straitjacket);
                    Takee.outfits.forcedHandler.SetForced(Straitjacket, true);
                    Hediff pawnJacketHediff = Takee.health.hediffSet.GetFirstHediffOfDef(StraitjacketDefOf.ROM_RestainedByStraitjacket);
                    if (pawnJacketHediff == null)
                    {
                        pawnJacketHediff = HediffMaker.MakeHediff(StraitjacketDefOf.ROM_RestainedByStraitjacket, Takee);
                        Takee.health.AddHediff(pawnJacketHediff);
                    }
                }, defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield break;
        }
示例#8
0
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
                    this.FailOn(() => !base.Patient.InBed() || !base.Patient.Awake());
                    if (base.Chair != null)
                    {
                        this.FailOnDespawnedNullOrForbidden(TargetIndex.B);
                    }
                    if (base.Chair != null)
                    {
                        this.$current = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.OnCell);
                        if (!this.$disposing)
                        {
                            this.$PC = 1;
                        }
                        return(true);
                    }
                    this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

                case 1u:
                    break;

                case 2u:
                    break;

                case 3u:
                {
                    Toil waitAndTalk = new Toil();
                    waitAndTalk.tickAction = delegate()
                    {
                        base.Patient.needs.joy.GainJoy(this.job.def.joyGainRate * 0.000144f, this.job.def.joyKind);
                        if (this.pawn.IsHashIntervalTick(320))
                        {
                            InteractionDef intDef = (Rand.Value >= 0.8f) ? InteractionDefOf.DeepTalk : InteractionDefOf.Chitchat;
                            this.pawn.interactions.TryInteractWith(base.Patient, intDef);
                        }
                        this.pawn.rotationTracker.FaceCell(base.Patient.Position);
                        this.pawn.GainComfortFromCellIfPossible();
                        JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.None, 1f, null);
                        if (this.pawn.needs.joy.CurLevelPercentage > 0.9999f && base.Patient.needs.joy.CurLevelPercentage > 0.9999f)
                        {
                            this.pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                        }
                    };
                    waitAndTalk.handlingFacing      = true;
                    waitAndTalk.socialMode          = RandomSocialMode.Off;
                    waitAndTalk.defaultCompleteMode = ToilCompleteMode.Delay;
                    waitAndTalk.defaultDuration     = this.job.def.joyDuration;
                    this.$current = waitAndTalk;
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);
                }

                case 4u:
                    this.$PC = -1;
                    return(false);

                default:
                    return(false);
                }
                this.$current = Toils_Interpersonal.WaitToBeAbleToInteract(this.pawn);
                if (!this.$disposing)
                {
                    this.$PC = 3;
                }
                return(true);
            }
示例#9
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.Init();
            yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A));

            Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, (this.RequiredDesignation == null) ? null : new Func <Thing, bool>((Thing t) => this.$this.Map.designationManager.DesignationOn(t, this.$this.RequiredDesignation) != null));

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A));

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

            Toil gotoThing = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue);

            if (this.RequiredDesignation != null)
            {
                gotoThing.FailOnThingMissingDesignation(TargetIndex.A, this.RequiredDesignation);
            }
            yield return(gotoThing);

            Toil cut = new Toil();

            cut.tickAction = delegate
            {
                Pawn actor = cut.actor;
                if (actor.skills != null)
                {
                    actor.skills.Learn(SkillDefOf.Plants, this.$this.xpPerTick, false);
                }
                float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                float num       = statValue;
                Plant plant     = this.$this.Plant;
                num *= Mathf.Lerp(3.3f, 1f, plant.Growth);
                this.$this.workDone += num;
                if (this.$this.workDone >= plant.def.plant.harvestWork)
                {
                    if (plant.def.plant.harvestedThingDef != null)
                    {
                        if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true))
                        {
                            Vector3 loc = (this.$this.pawn.DrawPos + plant.DrawPos) / 2f;
                            MoteMaker.ThrowText(loc, this.$this.Map, "TextMote_HarvestFailed".Translate(), 3.65f);
                        }
                        else
                        {
                            int num2 = plant.YieldNow();
                            if (num2 > 0)
                            {
                                Thing thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null);
                                thing.stackCount = num2;
                                if (actor.Faction != Faction.OfPlayer)
                                {
                                    thing.SetForbidden(true, true);
                                }
                                GenPlace.TryPlaceThing(thing, actor.Position, this.$this.Map, ThingPlaceMode.Near, null, null);
                                actor.records.Increment(RecordDefOf.PlantsHarvested);
                            }
                        }
                    }
                    plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                    plant.PlantCollected();
                    this.$this.workDone = 0f;
                    this.$this.ReadyForNextToil();
                    return;
                }
            };
            cut.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            if (this.RequiredDesignation != null)
            {
                cut.FailOnThingMissingDesignation(TargetIndex.A, this.RequiredDesignation);
            }
            cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            cut.defaultCompleteMode = ToilCompleteMode.Never;
            cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A);
            cut.WithProgressBar(TargetIndex.A, () => this.$this.workDone / this.$this.Plant.def.plant.harvestWork, true, -0.5f);
            cut.PlaySustainerOrSound(() => this.$this.Plant.def.plant.soundHarvesting);
            cut.activeSkill = (() => SkillDefOf.Plants);
            yield return(cut);

            Toil plantWorkDoneToil = this.PlantWorkDoneToil();

            if (plantWorkDoneToil != null)
            {
                yield return(plantWorkDoneToil);
            }
            yield return(Toils_Jump.Jump(initExtractTargetFromQueue));
        }
示例#10
0
        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.Error("[HumanResources] 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_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($"[HumanResources] {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($"[HumanResources] {pawn} tried to place a book in {shelf}, but it won't accept it.");
                            return;
                        }
                        pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true, true);
                    }
                });
            }
            yield break;
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable);
                    if (base.HasChair)
                    {
                        this.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable);
                    }
                    if (base.HasDrink)
                    {
                        this.FailOnDestroyedNullOrForbidden(TargetIndex.C);
                        this.$current = Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.C);
                        if (!this.$disposing)
                        {
                            this.$PC = 1;
                        }
                        return(true);
                    }
                    break;

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

                case 2u:
                    break;

                case 3u:
                    chew            = new Toil();
                    chew.tickAction = delegate()
                    {
                        this.pawn.rotationTracker.FaceCell(base.ClosestGatherSpotParentCell);
                        this.pawn.GainComfortFromCellIfPossible();
                        JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.GoToNextToil, 1f, null);
                    };
                    chew.handlingFacing      = true;
                    chew.defaultCompleteMode = ToilCompleteMode.Delay;
                    chew.defaultDuration     = this.job.def.joyDuration;
                    chew.AddFinishAction(delegate
                    {
                        JoyUtility.TryGainRecRoomThought(this.pawn);
                    });
                    chew.socialMode = RandomSocialMode.SuperActive;
                    Toils_Ingest.AddIngestionEffects(chew, this.pawn, TargetIndex.C, TargetIndex.None);
                    this.$current = chew;
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);

                case 4u:
                    if (base.HasDrink)
                    {
                        this.$current = Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.C);
                        if (!this.$disposing)
                        {
                            this.$PC = 5;
                        }
                        return(true);
                    }
                    goto IL_1D9;

                case 5u:
                    goto IL_1D9;

                default:
                    return(false);
                }
                this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell);
                if (!this.$disposing)
                {
                    this.$PC = 3;
                }
                return(true);

IL_1D9:
                this.$PC = -1;
                return(false);
            }
示例#12
0
        public static IEnumerable <Toil> MakeFeedToils(JobDriver thisDriver, Pawn actor, LocalTargetInfo TargetA, float workLeft, Action effect, Func <Pawn, Pawn, bool> stopCondition)
        {
            yield return(Toils_Reserve.Reserve(TargetIndex.A));

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

            yield return(gotoToil);

            Toil grappleToil = new Toil()
            {
                initAction = delegate
                {
                    MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking);

                    workLeft = JobDriver_Feed.BaseFeedTime;
                    Pawn victim = (Pawn)TargetA.Thing;
                    if (victim != null)
                    {
                        if (victim.InAggroMentalState || victim.Faction != actor.Faction)
                        {
                            if (!JecsTools.GrappleUtility.CanGrapple(actor, victim))
                            {
                                thisDriver.EndJobWith(JobCondition.Incompletable);
                            }
                        }
                        GenClamor.DoClamor(actor, 10f, ClamorDefOf.Harm);
                        if (!AllowFeeding(actor, victim))
                        {
                            actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                        }
                        if (actor?.VampComp()?.Bloodline?.bloodlineHediff?.CompProps <HediffCompProperties_VerbGiver>()?.verbs is List <VerbProperties> verbProps)
                        {
                            if (actor?.VerbTracker?.AllVerbs is List <Verb> verbs)
                            {
                                if (verbs.Find(x => verbProps.Contains(x.verbProps)) is Verb_MeleeAttack v)
                                {
                                    victim.TakeDamage(new DamageInfo(v.verbProps.meleeDamageDef, v.verbProps.meleeDamageBaseAmount, v.verbProps.meleeArmorPenetrationBase, -1, actor));
                                }
                            }
                        }
                        victim.stances.stunner.StunFor((int)BaseFeedTime, actor);
                    }
                }
            };

            yield return(grappleToil);

            Toil feedToil = new Toil()
            {
                tickAction = delegate
                {
                    Pawn victim = (Pawn)TargetA.Thing;
                    if (victim == null || !victim.Spawned || victim.Dead)
                    {
                        thisDriver.ReadyForNextToil();
                    }
                    workLeft--;

                    if (workLeft <= 0f)
                    {
                        if (actor?.VampComp() is CompVampire v && v.IsVampire && actor.Faction == Faction.OfPlayer)
                        {
                            MoteMaker.ThrowText(actor.DrawPos, actor.Map, "XP +" + 15);
                            v.XP += 15;
                        }
                        workLeft = BaseFeedTime;
                        MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking);
                        effect();
                        if ((victim.HostileTo(actor.Faction) || victim.IsPrisoner) && !JecsTools.GrappleUtility.CanGrapple(actor, victim))
                        {
                            thisDriver.EndJobWith(JobCondition.Incompletable);
                        }

                        if (!stopCondition(actor, victim))
                        {
                            thisDriver.ReadyForNextToil();
                        }
                        else
                        {
                            if (victim != null && !victim.Dead)
                            {
                                victim.stances.stunner.StunFor((int)BaseFeedTime, actor);
                                PawnUtility.ForceWait((Pawn)TargetA.Thing, (int)BaseFeedTime, actor);
                            }
                        }
                    }
                },
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            Toil gotoTurret   = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            Toil loadIfNeeded = new Toil();

            loadIfNeeded.initAction = delegate
            {
                Pawn               actor3 = loadIfNeeded.actor;
                Building           obj    = (Building)actor3.CurJob.targetA.Thing;
                Building_TurretGun building_TurretGun2 = obj as Building_TurretGun;
                if (!GunNeedsLoading(obj))
                {
                    JumpToToil(gotoTurret);
                }
                else
                {
                    Thing thing = FindAmmoForTurret(pawn, building_TurretGun2);
                    if (thing == null)
                    {
                        if (actor3.Faction == Faction.OfPlayer)
                        {
                            Messages.Message("MessageOutOfNearbyShellsFor".Translate(actor3.LabelShort, building_TurretGun2.Label, actor3.Named("PAWN"), building_TurretGun2.Named("GUN")).CapitalizeFirst(), building_TurretGun2, MessageTypeDefOf.NegativeEvent);
                        }
                        actor3.jobs.EndCurrentJob(JobCondition.Incompletable);
                    }
                    actor3.CurJob.targetB = thing;
                    actor3.CurJob.count   = 1;
                }
            };
            yield return(loadIfNeeded);

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

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

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

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

            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor2 = loadIfNeeded.actor;
                Building_TurretGun building_TurretGun = ((Building)actor2.CurJob.targetA.Thing) as Building_TurretGun;
                SoundDefOf.Artillery_ShellLoaded.PlayOneShot(new TargetInfo(building_TurretGun.Position, building_TurretGun.Map));
                building_TurretGun.gun.TryGetComp <CompChangeableProjectile>().LoadShell(actor2.CurJob.targetB.Thing.def, 1);
                actor2.carryTracker.innerContainer.ClearAndDestroyContents();
            };
            yield return(toil);

            yield return(gotoTurret);

            Toil man = new Toil();

            man.tickAction = delegate
            {
                Pawn     actor    = man.actor;
                Building building = (Building)actor.CurJob.targetA.Thing;
                if (GunNeedsLoading(building))
                {
                    JumpToToil(loadIfNeeded);
                }
                else
                {
                    building.GetComp <CompMannable>().ManForATick(actor);
                    man.actor.rotationTracker.FaceCell(building.Position);
                }
            };
            man.handlingFacing      = true;
            man.defaultCompleteMode = ToilCompleteMode.Never;
            man.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
            yield return(man);
        }
示例#14
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var upgrade = TargetThingA.FirstUpgradeableComp();

            if (upgrade == null)
            {
                EndJobWith(JobCondition.Incompletable);
                yield break;
            }
            AddFailCondition(() => {
                var comp = TargetThingA.FirstUpgradeableComp();
                return(comp == null || !comp.parent.Spawned || !comp.WantsWork);
            });
            this.FailOnDestroyedNullOrForbidden(TargetIndex.A);
            var gotoUpgradeable   = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            var lookForIngredient = new Toil {
                initAction = () => {
                    var missingIngredient = upgrade.TryGetNextMissingIngredient();
                    job.count = missingIngredient.Count;
                    if (missingIngredient.Count > 0)
                    {
                        bool SearchPredicate(Thing thing) => !thing.IsForbidden(pawn) && pawn.CanReserve(thing);

                        var t = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(missingIngredient.ThingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 999,
                                                                 SearchPredicate);
                        if (t == null)
                        {
                            EndJobWith(JobCondition.Incompletable);
                        }
                        else
                        {
                            job.SetTarget(TargetIndex.B, t);
                        }
                    }
                    else
                    {
                        JumpToToil(gotoUpgradeable);
                    }
                }
            };

            yield return(lookForIngredient);

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

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

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

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

            yield return(new Toil {
                initAction = () => {
                    if (pawn.carryTracker.CarriedThing != null)
                    {
                        pawn.carryTracker.innerContainer.TryTransferToContainer(pawn.carryTracker.CarriedThing, upgrade.GetDirectlyHeldThings(), pawn.carryTracker.CarriedThing.stackCount);
                        pawn.Map.reservationManager.ReleaseAllForTarget(TargetThingB);
                        job.SetTarget(TargetIndex.B, null);
                        JumpToToil(lookForIngredient);
                    }
                }
            });

            yield return(gotoUpgradeable);

            yield return(new Toil {
                tickAction = () => {
                    upgrade.DoWork(GetActor().GetStatValue(StatDefOf.ConstructionSpeed));
                    if (upgrade.Complete)
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Never
            }.WithEffect(EffecterDefOf.ConstructMetal, TargetIndex.A)
                         .WithProgressBar(TargetIndex.A, () => upgrade.WorkProgress));
        }
    }
示例#15
0
        public override IEnumerable <Toil> MakeNewToils()
        {
            var ZTracker = ZUtils.ZTracker;

            if (pawn.Map == this.job.targetA.Thing.Map && pawn.Map == ZTracker.jobTracker[pawn].targetDest.Map)
            {
                ZLogger.Message("pawn map and thing map and dest map are same, yield breaking in JobDriver_HaulThingToDest");
                yield break;
            }
            yield return(new Toil
            {
                initAction = delegate()
                {
                    this.savedThing = this.job.targetA.Thing;
                }
            });

            Toil reserveItem = Toils_Reserve.Reserve(TargetIndex.A);

            ZLogger.Message($"JobDriver HaulThingToDest1 About to call findRouteWithStairs, with pawn {GetActor()}, dest { TargetA.Thing}, instance {this}");
            Log.Message("3 - pawn.Map: " + pawn.Map + " - dest: " + new TargetInfo(TargetA.Thing).Map, true);

            foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), new TargetInfo(TargetA.Thing).Map, this))
            {
                yield return(toil);
            }
            yield return(new Toil
            {
                initAction = delegate()
                {
                    ZLogger.Message("JobDriver_HaulThingToDest 1: " + pawn + " trying to reserve: " + TargetA, true);
                }
            });

            Toil toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch);

            yield return(reserveItem.FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    ZLogger.Message("JobDriver_HaulThingToDest 1: " + pawn + " reserved: " + TargetA, true);
                }
            });

            yield return(toilGoto);

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

            if (job.haulOpportunisticDuplicates)
            {
                yield return(new Toil
                {
                    initAction = delegate()
                    {
                        ZLogger.Message("2: " + pawn + " trying to reserve other things: " + TargetA, true);
                    }
                });

                yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveItem, TargetIndex.A, TargetIndex.None, takeFromValidStorage: true));

                yield return(new Toil
                {
                    initAction = delegate()
                    {
                        ZLogger.Message("2: " + pawn + " reserved other things: " + TargetA, true);
                    }
                });
            }
            yield return(new Toil
            {
                initAction = delegate()
                {
                    try
                    {
                        if (ZTracker.jobTracker.ContainsKey(pawn))
                        {
                            if (ZTracker.jobTracker[pawn].mainJob.targetA.Thing != null &&
                                ZTracker.jobTracker[pawn].mainJob.targetA.Thing == this.savedThing &&
                                ZTracker.jobTracker[pawn].mainJob.targetA.Thing != TargetA.Thing)
                            {
                                ZTracker.jobTracker[pawn].mainJob.targetA = new LocalTargetInfo(TargetA.Thing);
                            }
                            else if (ZTracker.jobTracker[pawn].mainJob.targetB.Thing != null &&
                                     ZTracker.jobTracker[pawn].mainJob.targetB.Thing == this.savedThing &&
                                     ZTracker.jobTracker[pawn].mainJob.targetB.Thing != TargetA.Thing)
                            {
                                ZTracker.jobTracker[pawn].mainJob.targetB = new LocalTargetInfo(TargetA.Thing);
                            }

                            try
                            {
                                for (int i = ZTracker.jobTracker[pawn].mainJob.targetQueueA.Count - 1; i >= 0; i--)
                                {
                                    var target = ZTracker.jobTracker[pawn].mainJob.targetQueueA[i];
                                    if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing)
                                    {
                                        ZTracker.jobTracker[pawn].mainJob.targetQueueA[i] = new LocalTargetInfo(TargetA.Thing);
                                    }
                                }
                            }
                            catch { }
                            try
                            {
                                for (int i = ZTracker.jobTracker[pawn].mainJob.targetQueueB.Count - 1; i >= 0; i--)
                                {
                                    var target = ZTracker.jobTracker[pawn].mainJob.targetQueueB[i];
                                    if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing)
                                    {
                                        if (ZTracker.jobTracker[pawn].mainJob.targetQueueB[i].Thing.stackCount == 0)
                                        {
                                            ZTracker.jobTracker[pawn].mainJob.targetQueueB[i] = new LocalTargetInfo(TargetA.Thing);
                                            ZTracker.jobTracker[pawn].mainJob.countQueue[i] = TargetA.Thing.stackCount;
                                            break;
                                        }
                                        else
                                        {
                                            if (ZTracker.jobTracker[pawn].mainJob.targetQueueB
                                                .Where(x => x.Thing == TargetA.Thing).Count() == 0)
                                            {
                                                var newTarget = new LocalTargetInfo(TargetA.Thing);
                                                ZTracker.jobTracker[this.pawn].mainJob.targetQueueB.Add(newTarget);
                                                ZTracker.jobTracker[this.pawn].mainJob.countQueue.Add(newTarget.Thing.stackCount);
                                                int ind = ZTracker.jobTracker[this.pawn].mainJob.targetQueueB.FirstIndexOf(x => x.Thing == this.savedThing);
                                                ZTracker.jobTracker[this.pawn].mainJob.targetQueueB.RemoveAt(ind);
                                                ZTracker.jobTracker[this.pawn].mainJob.countQueue.RemoveAt(ind);
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            catch { }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Z-Tracker produced an error in JobDriver_HaulThingToStairs class. Report about it to devs. Error: " + ex);
                    }
                }
            });

            ZLogger.Message($"JobDriver HaulThingToDest 2About to call findRouteWithStairs, with pawn {GetActor()}, dest {ZTracker.jobTracker[pawn].targetDest}, instance {this}");
            Log.Message("4 - pawn.Map: " + pawn.Map + " - dest: " + ZTracker.jobTracker[pawn].targetDest.Map, true);

            foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), ZTracker.jobTracker[pawn].targetDest.Map, this))
            {
                yield return(toil);
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var consumeThingList = new List <Thing>();
            var ingList          = this.job.GetTargetQueue(IngredientInd);
            var ingCountList     = this.job.countQueue;
            //this.job.SetTarget(IngredientPlaceCellInd, this.TargetA.Thing.InteractionCell);

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

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

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

            yield return(gotoToil);

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

            // 運ぶものリストの中に同種の材料があり、まだ物を持てる場合、設備へ持っていく前に取りに行く
            yield return(Toils_General.Do(() =>
            {
                Pawn actor = this.pawn;
                Job curJob = actor.jobs.curJob;
                List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(IngredientInd);
                if (targetQueue.NullOrEmpty <LocalTargetInfo>())
                {
                    return;
                }
                if (curJob.count <= 0)
                {
                    return;
                }
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor + " who is not carrying something.");
                    return;
                }
                if (actor.carryTracker.AvailableStackSpace(actor.carryTracker.CarriedThing.def) <= 0)
                {
                    return;
                }
                for (int i = 0; i < targetQueue.Count; i++)
                {
                    if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing))
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        return;
                    }
                    if (targetQueue[i].Thing.def == actor.carryTracker.CarriedThing.def)
                    {
                        curJob.SetTarget(IngredientInd, targetQueue[i].Thing);
                        curJob.count = curJob.countQueue[i];
                        targetQueue.RemoveAt(i);
                        curJob.countQueue.RemoveAt(i);
                        actor.jobs.curDriver.JumpToToil(gotoToil);
                        break;
                    }
                }
            }));

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

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

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

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

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

            // 水の注入完了処理
            yield return(Toils_Mizu.FinishPourRecipe(BillGiverInd, IngredientInd));
        }
示例#17
0
        private IEnumerable <Toil> Clipboard()
        {
            yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A));

            yield return(Toils_Reserve.ReserveQueue(TargetIndex.A));

            Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A);

            yield return(initExtractTargetFromQueue);

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

            Toil checkNextQueuedTarget = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A);

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

            Toil cut = new Toil()
            {
                tickAction = delegate {
                    Pawn actor = GetActor();
                    if (actor.skills != null)
                    {
                        actor.skills.Learn(SkillDefOf.Growing, 0.11f);
                    }
                    float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                    float num       = statValue;
                    workDone += num;
                    if (workDone >= Duration)
                    {
                        if (Plant.def.plant.harvestedThingDef != null)
                        {
                            if (actor.RaceProps.Humanlike && Plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true))
                            {
                                Vector3 loc = (pawn.DrawPos + Plant.DrawPos) / 2f;
                                MoteMaker.ThrowText(loc, Map, "TextMote_HarvestFailed".Translate(), 3.65f);
                            }
                            else
                            {
                                Thing thing = Plant.CollectSecondaryThing();
                                if (actor.Faction != Faction.OfPlayer)
                                {
                                    thing.SetForbidden(true, true);
                                }
                                GenPlace.TryPlaceThing(thing, actor.Position, Map, ThingPlaceMode.Near);
                                actor.records.Increment(RecordDefOf.PlantsHarvested);

                                // If there is a SeedsPlease seed, try to drop it
                                if (Plant.seedDef != null)
                                {
                                    int stack = Rand.RangeInclusive(-1, 1);
                                    if (pawn.skills != null)
                                    {
                                        stack += GenMath.RoundRandom(pawn.skills.GetSkill(SkillDefOf.Growing).Level / 8f);
                                    }
                                    if (stack > 0)
                                    {
                                        Thing seed = ThingMaker.MakeThing(Plant.seedDef);
                                        seed.stackCount = stack;
                                        GenPlace.TryPlaceThing(seed, pawn.Position, pawn.Map, ThingPlaceMode.Near);
                                    }
                                }
                            }
                        }
                        Plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                        workDone = 0f;
                        ReadyForNextToil();
                        return;
                    }
                }
            };

            cut.FailOn(() => !Plant.Sec_HarvestableNow);
            cut.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            cut.defaultCompleteMode = ToilCompleteMode.Never;
            cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A);
            cut.WithProgressBar(TargetIndex.A, () => workDone / Duration, true, -0.5f);
            cut.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting);
            yield return(cut);

            yield return(checkNextQueuedTarget);

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.A, initExtractTargetFromQueue));
        }
示例#18
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Set fail conditions
            this.FailOnDestroyedNullOrForbidden(HaulableInd);
            this.FailOnBurningImmobile(CellInd);
            //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(HaulableInd);
            }


            //Reserve target storage cell, if it is a storage
            bool targetIsStorage = StoreUtility.GetSlotGroup(pawn.jobs.curJob.GetTarget(CellInd).Cell, Map) != null;

            if (targetIsStorage)
            {
                yield return(Toils_Reserve.Reserve(CellInd, 1));
            }

            //Reserve thing to be stored
            Toil reserveTargetA = Toils_Reserve.Reserve(HaulableInd, 1);

            yield return(reserveTargetA);

            // Goto object
            //Toil toilGoto = null;
            //toilGoto = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch)
            //    .FailOn(() =>
            //    {
            //        //Note we don't fail on losing hauling designation
            //        //Because that's a special case anyway

            //        //While hauling to cell storage, ensure storage dest is still valid
            //        Pawn actor = toilGoto.actor;
            //        Job curJob = actor.jobs.curJob;
            //        if (curJob.haulMode == HaulMode.ToCellStorage)
            //        {
            //            Thing haulThing = curJob.GetTarget(HaulableInd).Thing;

            //            IntVec3 destLoc = actor.jobs.curJob.GetTarget(CellInd).Cell;
            //            if (!destLoc.IsValidStorageFor(Map, haulThing))
            //                return true;
            //        }

            //        return false;
            //    });
            //yield return toilGoto;
            yield return(Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(HaulableInd));

            // Start hauling to
            yield return(Toils_Haul.StartCarryThing(HaulableInd, false, false));

            if (this.job.haulOpportunisticDuplicates)
            {
                yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveTargetA, HaulableInd, CellInd));
            }

            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(CellInd);

            yield return(carryToCell);

            // start work on target
            yield return(Toils_WaitWithSoundAndEffect(180, "Interact_ConstructMetal", "ConstructMetal", CellInd));


            yield return(Toils_TryToAttachToWeaponBase(pawn, HaulableInd, CellInd));
        }
        public override IEnumerable <Toil> MakeNewToils()
        {
            var ZTracker = ZUtils.ZTracker;

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (pawn.Map == this.job.targetA.Thing?.Map && pawn.Map == ZTracker.jobTracker[pawn].targetDest.Map)
                    {
                        ZLogger.Message("pawn map and thing map and dest map are same, yield breaking in JobDriver_HaulThingToDest");
                        this.EndJobWith(JobCondition.InterruptForced);
                    }
                    this.savedThing = this.job.targetA.Thing;
                }
            });

            Toil reserveItem = Toils_Reserve.Reserve(TargetIndex.A);

            if (TargetA.Thing?.Map != null)
            {
                foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), new TargetInfo(TargetA.Thing).Map, this))
                {
                    yield return(toil);
                }
            }

            Toil toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch);

            yield return(reserveItem.FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(toilGoto);

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

            if (job.haulOpportunisticDuplicates)
            {
                yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveItem, TargetIndex.A, TargetIndex.None, takeFromValidStorage: true));
            }
            yield return(Toils_Haul.JumpIfAlsoCollectingNextTargetInQueue(toilGoto, TargetIndex.A));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (ZTracker.jobTracker.TryGetValue(pawn, out JobTracker jobTracker))
                    {
                        if (jobTracker.mainJob.targetA.Thing != null && jobTracker.mainJob.targetA.Thing == this.savedThing && jobTracker.mainJob.targetA.Thing != TargetA.Thing)
                        {
                            jobTracker.mainJob.targetA = new LocalTargetInfo(TargetA.Thing);
                        }
                        else if (jobTracker.mainJob.targetB.Thing != null && jobTracker.mainJob.targetB.Thing == this.savedThing && jobTracker.mainJob.targetB.Thing != TargetA.Thing)
                        {
                            jobTracker.mainJob.targetB = new LocalTargetInfo(TargetA.Thing);
                        }
                        if (jobTracker.mainJob.targetQueueA != null)
                        {
                            for (int i = jobTracker.mainJob.targetQueueA.Count - 1; i >= 0; i--)
                            {
                                var target = jobTracker.mainJob.targetQueueA[i];
                                if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing)
                                {
                                    jobTracker.mainJob.targetQueueA[i] = new LocalTargetInfo(TargetA.Thing);
                                }
                            }
                        }
                        if (jobTracker.mainJob.targetQueueB != null)
                        {
                            for (int i = jobTracker.mainJob.targetQueueB.Count - 1; i >= 0; i--)
                            {
                                var target = jobTracker.mainJob.targetQueueB[i];
                                if (target.Thing != null && target.Thing == this.savedThing && target.Thing != TargetA.Thing)
                                {
                                    if (jobTracker.mainJob.targetQueueB[i].Thing.stackCount == 0)
                                    {
                                        jobTracker.mainJob.targetQueueB[i] = new LocalTargetInfo(TargetA.Thing);
                                        jobTracker.mainJob.countQueue[i] = TargetA.Thing.stackCount;
                                        break;
                                    }
                                    else if (!jobTracker.mainJob.targetQueueB.Any(x => x.Thing == TargetA.Thing))
                                    {
                                        var newTarget = new LocalTargetInfo(TargetA.Thing);
                                        jobTracker.mainJob.targetQueueB.Add(newTarget);
                                        jobTracker.mainJob.countQueue.Add(newTarget.Thing.stackCount);
                                        int ind = jobTracker.mainJob.targetQueueB.FirstIndexOf(x => x.Thing == this.savedThing);
                                        jobTracker.mainJob.targetQueueB.RemoveAt(ind);
                                        jobTracker.mainJob.countQueue.RemoveAt(ind);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            });
        // Token: 0x06000035 RID: 53 RVA: 0x00003DB8 File Offset: 0x00001FB8
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A));

            Toil build = new Toil();

            build.initAction = delegate()
            {
                IntVec3 root   = build.actor.Position;
                Region  region = build.actor.GetRegion(RegionType.Set_Passable);
                bool    flag   = region == null;
                if (!flag)
                {
                    RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.door == null || r.door.Open, delegate(Region r)
                    {
                        List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                        for (int i = 0; i < list.Count; i++)
                        {
                            Pawn pawn  = list[i] as Pawn;
                            float num  = Mathf.Clamp01(pawn.health.capacities.GetLevel(PawnCapacityDefOf.Hearing));
                            bool flag2 = num > 0f && pawn.Position.InHorDistOf(root, 15f * num);
                            if (flag2)
                            {
                                pawn.HearClamor(build.actor, ClamorDefOf.Construction);
                            }
                        }
                        return(false);
                    }, 15, RegionType.Set_Passable);
                }
            };
            build.tickAction = delegate()
            {
                Pawn  actor = build.actor;
                Frame frame = this.Frame;
                float num   = 1f;
                float value = actor.records.GetValue(RecordDefOf.ThingsConstructed);
                float num2  = value / 20f;
                bool  flag  = num2 < 1f;
                if (flag)
                {
                    num2 = 1f;
                }
                bool flag2 = frame.Stuff != null;
                if (flag2)
                {
                    num *= frame.Stuff.GetStatValueAbstract(StatDefOf.ConstructionSpeedFactor, null);
                }
                float workToBuild = frame.WorkToBuild;
                bool  flag3       = actor.Faction == Faction.OfPlayer && actor.RaceProps.Animal;
                if (flag3)
                {
                    bool flag4 = Rand.Value < 1f - Mathf.Pow(num2, num / workToBuild);
                    if (flag4)
                    {
                        frame.FailConstruction(actor);
                        this.ReadyForNextToil();
                        return;
                    }
                }
                bool flag5 = frame.def.entityDefToBuild is TerrainDef;
                if (flag5)
                {
                    this.Map.snowGrid.SetDepth(frame.Position, 0f);
                }
                frame.workDone += num;
                bool flag6 = frame.workDone >= workToBuild;
                if (flag6)
                {
                    frame.CompleteConstruction(actor);
                    this.ReadyForNextToil();
                }
            };
            build.WithEffect(() => ((Frame)build.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing).ConstructionEffect, TargetIndex.A);
            build.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            build.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            build.defaultCompleteMode = ToilCompleteMode.Delay;
            build.defaultDuration     = 5000;
            build.activeSkill         = (() => SkillDefOf.Construction);
            yield return(build);

            yield break;
        }
示例#21
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 (job.GetTarget(TargetIndex.C).IsValid)
                    {
                        Equip(TargetIndex.C, false);
                    }
                    else
                    {
                        ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                        pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, 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()
        {
            //Bill giver destroyed (only in bill using phase! Not in carry phase)
            this.AddEndCondition(() =>
            {
                var targ = this.GetActor().jobs.curJob.GetTarget(ConstructorInd).Thing;
                if (targ == null || (targ is Building && !targ.Spawned))
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(ConstructorInd);  //Bill giver, or product burning in carry phase

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

            //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, ConstructorInd));

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

                //Place ingredient on the appropriate cell
                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(ConstructorInd, 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);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //--Log.Message("[RJW]JobDriver_GettinLoved::MakeNewToils is called");

            float partner_ability = xxx.get_sex_ability(Partner);

            // More/less hearts based on partner ability.
            if (partner_ability < 0.8f)
            {
                tick_interval += 100;
            }
            else if (partner_ability > 2.0f)
            {
                tick_interval -= 25;
            }

            // More/less hearts based on opinion.
            if (pawn.relations.OpinionOf(Partner) < 0)
            {
                tick_interval += 50;
            }
            else if (pawn.relations.OpinionOf(Partner) > 60)
            {
                tick_interval -= 25;
            }

            if (Partner.CurJob.def == xxx.casual_sex)
            {
                this.FailOnDespawnedOrNull(ipartner);
                this.FailOn(() => !Partner.health.capacities.CanBeAwake);
                this.FailOn(() => pawn.Drafted);
                this.KeepLyingDown(ibed);
                yield return(Toils_Reserve.Reserve(ipartner, 1, 0));

                yield return(Toils_Reserve.Reserve(ibed, Bed.SleepingSlotsCount, 0));

                Toil get_loved = Toils_LayDown.LayDown(ibed, true, false, false, false);
                get_loved.FailOn(() => Partner.CurJob == null || Partner.CurJob.def != xxx.casual_sex);
                get_loved.defaultCompleteMode = ToilCompleteMode.Never;
                get_loved.AddPreTickAction(delegate
                {
                    if (pawn.IsHashIntervalTick(tick_interval))
                    {
                        MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                        xxx.sexTick(pawn, Partner);
                    }
                });
                get_loved.socialMode = RandomSocialMode.Off;
                yield return(get_loved);
            }
            else if (Partner.CurJob.def == xxx.whore_is_serving_visitors)
            {
                this.FailOnDespawnedOrNull(ipartner);
                this.FailOn(() => !Partner.health.capacities.CanBeAwake || Partner.CurJob == null);
                yield return(Toils_Goto.GotoThing(ipartner, PathEndMode.OnCell));

                yield return(Toils_Reserve.Reserve(ipartner, 1, 0));

                Toil get_loved = new Toil();
                get_loved.FailOn(() => (Partner.CurJob.def != xxx.whore_is_serving_visitors));
                get_loved.defaultCompleteMode = ToilCompleteMode.Never;
                get_loved.initAction          = delegate
                {
                    //--Log.Message("[RJW]JobDriver_GettinLoved::MakeNewToils - w***e section is called");
                };
                get_loved.AddPreTickAction(delegate
                {
                    if (pawn.IsHashIntervalTick(tick_interval))
                    {
                        MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                        xxx.sexTick(pawn, Partner);
                    }
                });
                get_loved.socialMode = RandomSocialMode.Off;
                yield return(get_loved);
            }
            else if (Partner.CurJob.def == xxx.bestialityForFemale)
            {
                this.FailOnDespawnedOrNull(ipartner);
                this.FailOn(() => !Partner.health.capacities.CanBeAwake || Partner.CurJob == null);
                yield return(Toils_Goto.GotoThing(ipartner, PathEndMode.OnCell));

                yield return(Toils_Reserve.Reserve(ipartner, 1, 0));

                Toil get_loved = new Toil();
                get_loved.FailOn(() => (Partner.CurJob.def != xxx.bestialityForFemale));
                get_loved.defaultCompleteMode = ToilCompleteMode.Never;
                get_loved.initAction          = delegate
                {
                    //--Log.Message("[RJW]JobDriver_GettinLoved::MakeNewToils - bestialityForFemale section is called");
                };
                get_loved.AddPreTickAction(delegate
                {
                    if (pawn.IsHashIntervalTick(tick_interval))
                    {
                        MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                        xxx.sexTick(pawn, Partner);
                    }
                });
                get_loved.socialMode = RandomSocialMode.Off;
                yield return(get_loved);
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            const float baseFishingDuration    = 1600f;
            const float catchSuccessRateOnPier = 0.90f;
            const float skillGainPerTick       = 0.15f;

            int fishingDuration = (int)baseFishingDuration;
            Building_FishingPier fishingPier = this.TargetThingA as Building_FishingPier;
            Passion passion           = Passion.None;
            int     thrownCornCount   = 0;
            int     nextCornThrowTick = 0;

            this.FailOnBurningImmobile(fishingPierIndex);

            // Drawing.
            this.rotateToFace = TargetIndex.B;
            this.pawn.CurJob.SetTarget(TargetIndex.C, fishingPier.riverCell);
            TargetIndex riverCellIndex = TargetIndex.C;

            // Compute fishing duration.
            float fishingSkillLevel = 0f;

            fishingSkillLevel = this.pawn.skills.AverageOfRelevantSkillsFor(WorkTypeDefOf.Hunting);
            float fishingSkillDurationFactor = fishingSkillLevel / 20f;

            fishingDuration = (int)(baseFishingDuration * (1.5f - fishingSkillDurationFactor));

            yield return(Toils_Goto.GotoThing(fishingPierIndex, fishingPier.riverCell).FailOn(FishingForbiddenOrPierDestroyedOrNoFish));

            Toil attractfishesToil = new Toil()
            {
                tickAction = () =>
                {
                    if (fishingPier.allowUsingCorn == false)
                    {
                        this.ReadyForNextToil();
                        return;
                    }
                    if (Find.TickManager.TicksGame >= nextCornThrowTick)
                    {
                        nextCornThrowTick = Find.TickManager.TicksGame + 3 * GenTicks.TicksPerRealSecond;
                        // Look for corn in inventory.
                        Thing corn = null;
                        foreach (Thing thing in this.pawn.inventory.innerContainer)
                        {
                            if (thing.def == Util_FishIndustry.RawCornDef)
                            {
                                corn = thing;
                                break;
                            }
                        }
                        if ((corn == null) ||
                            (thrownCornCount >= cornCountToAttractFishes))
                        {
                            fishingDuration -= Mathf.CeilToInt((float)fishingDuration * 0.75f * ((float)thrownCornCount / (float)cornCountToAttractFishes));
                            this.ReadyForNextToil();
                            return;
                        }
                        // Throw corn grains.
                        thrownCornCount++;
                        this.pawn.inventory.innerContainer.Take(corn, 1);
                        for (int cornGrainIndex = 0; cornGrainIndex < 5; cornGrainIndex++)
                        {
                            if (!this.pawn.Position.ShouldSpawnMotesAt(this.pawn.Map) || this.pawn.Map.moteCounter.Saturated)
                            {
                                break;
                            }
                            float   speed          = Rand.Range(1.5f, 3f);
                            Vector3 targetPosition = this.pawn.Position.ToVector3Shifted() + new Vector3(0f, 0f, 2f).RotatedBy(fishingPier.Rotation.AsAngle) + Vector3Utility.RandomHorizontalOffset(1.5f);
                            targetPosition.y = this.pawn.DrawPos.y;
                            MoteThrown moteThrown = (MoteThrown)ThingMaker.MakeThing(ThingDefOf.Mote_Stone, null);
                            moteThrown.Scale         = 0.2f;
                            moteThrown.rotationRate  = (float)Rand.Range(-300, 300);
                            moteThrown.exactPosition = this.pawn.DrawPos;
                            moteThrown.SetVelocity((targetPosition - moteThrown.exactPosition).AngleFlat(), speed);
                            moteThrown.airTimeLeft = (float)Mathf.RoundToInt((moteThrown.exactPosition - targetPosition).MagnitudeHorizontal() / speed);
                            GenSpawn.Spawn(moteThrown, this.pawn.Position, this.pawn.Map);
                            MoteMaker.MakeWaterSplash(targetPosition, this.pawn.Map, 1.8f, 0.5f);
                        }
                    }
                },
                defaultDuration     = fishingDuration,
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            yield return(attractfishesToil.FailOn(FishingForbiddenOrPierDestroyedOrNoFish));

            Toil fishToil = new Toil()
            {
                initAction = () =>
                {
                    ThingDef moteDef = null;
                    if (fishingPier.Rotation == Rot4.North)
                    {
                        moteDef = Util_FishIndustry.MoteFishingRodNorthDef;
                    }
                    else if (fishingPier.Rotation == Rot4.East)
                    {
                        moteDef = Util_FishIndustry.MoteFishingRodEastDef;
                    }
                    else if (fishingPier.Rotation == Rot4.South)
                    {
                        moteDef = Util_FishIndustry.MoteFishingRodSouthDef;
                    }
                    else
                    {
                        moteDef = Util_FishIndustry.MoteFishingRodWestDef;
                    }
                    this.fishingRodMote = (Mote)ThingMaker.MakeThing(moteDef, null);
                    this.fishingRodMote.exactPosition = fishingPier.fishingSpotCell.ToVector3Shifted();
                    this.fishingRodMote.Scale         = 1f;
                    GenSpawn.Spawn(this.fishingRodMote, fishingPier.fishingSpotCell, this.Map);
                },
                tickAction = () =>
                {
                    if (passion == Passion.Minor)
                    {
                        this.pawn.needs.joy.GainJoy(NeedTunings.JoyPerXpForPassionMinor, JoyKindDefOf.Work);
                    }
                    else if (passion == Passion.Major)
                    {
                        this.pawn.needs.joy.GainJoy(NeedTunings.JoyPerXpForPassionMajor, JoyKindDefOf.Work);
                    }
                    this.pawn.skills.Learn(SkillDefOf.Shooting, skillGainPerTick);

                    if (this.fishingRodMote != null)
                    {
                        this.fishingRodMote.Maintain();
                    }
                },
                defaultDuration     = fishingDuration,
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            yield return(fishToil.WithProgressBarToilDelay(riverCellIndex).FailOn(FishingForbiddenOrPierDestroyedOrNoFish));

            Toil catchFishToil = new Toil()
            {
                initAction = () =>
                {
                    Thing fishingCatch = null;

                    bool catchIsSuccessful = (Rand.Value <= catchSuccessRateOnPier);
                    if (catchIsSuccessful == false)
                    {
                        MoteMaker.ThrowMetaIcon(this.pawn.Position, this.Map, ThingDefOf.Mote_IncapIcon);
                        this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                        return;
                    }

                    float catchSelectorValue = Rand.Value;

                    if (catchSelectorValue < 0.02)
                    {
                        float bonusCatchValue = Rand.Value;
                        if (bonusCatchValue < 0.01f)
                        {
                            // Really small chance to find a sunken treasure!!!
                            fishingCatch            = GenSpawn.Spawn(ThingDefOf.Gold, this.pawn.Position, this.Map);
                            fishingCatch.stackCount = Rand.RangeInclusive(58, 289);
                            Thing treasureSilver = GenSpawn.Spawn(ThingDefOf.Silver, fishingPier.middleCell, this.Map);
                            treasureSilver.stackCount = Rand.RangeInclusive(237, 2154);
                            Find.LetterStack.ReceiveLetter("FishIndustry.LetterLabelSunkenTreasure".Translate(), "FishIndustry.SunkenTreasure".Translate(this.pawn.Name.ToStringShort.CapitalizeFirst()),
                                                           LetterDefOf.PositiveEvent, this.pawn);
                        }
                        else if (bonusCatchValue < 0.02f)
                        {
                            // Really small chance to find a complete power armor set + sniper or charge rifle.
                            Thing powerArmor = GenSpawn.Spawn(ThingDef.Named("Apparel_PowerArmor"), this.pawn.Position, this.Map);
                            fishingCatch = powerArmor; // Used to carry the power armor.
                            Thing powerArmorHelmet = GenSpawn.Spawn(ThingDef.Named("Apparel_PowerArmorHelmet"), this.pawn.Position, this.Map);
                            Thing rifle            = null;
                            if (Rand.Value < 0.5f)
                            {
                                rifle = GenSpawn.Spawn(ThingDef.Named("Gun_ChargeRifle"), this.pawn.Position, this.Map);
                            }
                            else
                            {
                                rifle = GenSpawn.Spawn(ThingDef.Named("Gun_SniperRifle"), this.pawn.Position, this.Map);
                            }
                            CompQuality qualityComp = powerArmor.TryGetComp <CompQuality>();
                            if (qualityComp != null)
                            {
                                qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider);
                            }
                            qualityComp = powerArmorHelmet.TryGetComp <CompQuality>();
                            if (qualityComp != null)
                            {
                                qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider);
                            }
                            qualityComp = rifle.TryGetComp <CompQuality>();
                            if (qualityComp != null)
                            {
                                qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider);
                            }

                            Faction faction    = Find.FactionManager.FirstFactionOfDef(FactionDefOf.SpacerHostile);
                            Pawn    deadMarine = PawnGenerator.GeneratePawn(PawnKindDefOf.SpaceSoldier, faction);
                            HealthUtility.DamageUntilDead(deadMarine);
                            Corpse       corpse  = deadMarine.ParentHolder as Corpse;
                            CompRottable rotComp = corpse.TryGetComp <CompRottable>();
                            if (rotComp != null)
                            {
                                rotComp.RotProgress = 20f * GenDate.TicksPerDay; // 20 days so the corpse is dessicated.
                            }
                            GenSpawn.Spawn(corpse, fishingPier.bankCell, this.Map);
                            // TODO: set it as a translatble string.
                            string eventText = this.pawn.Name.ToStringShort.CapitalizeFirst() + " has cought a dead body while fishing!\n\n'This is really disgusting but look at his gear! This guy was probably a MiningCo. security member. I wonder what happend to him...'\n";
                            Find.LetterStack.ReceiveLetter("Dead marine", eventText, LetterDefOf.PositiveEvent, this.pawn);
                        }
                        else
                        {
                            // Find a small amount of gold.
                            fishingCatch            = GenSpawn.Spawn(ThingDefOf.Gold, this.pawn.Position, this.Map);
                            fishingCatch.stackCount = Rand.RangeInclusive(1, 7);
                        }
                    }
                    else if (catchSelectorValue < 0.04)
                    {
                        // Find oysters.
                        fishingCatch            = GenSpawn.Spawn(Util_FishIndustry.OysterDef, this.pawn.Position, this.Map);
                        fishingCatch.stackCount = Rand.RangeInclusive(2, 9);
                    }
                    else
                    {
                        // Catch a fish.
                        IntVec3 fishSpot        = fishingPier.aquaticCells.RandomElement();
                        bool    fishSpotIsOcean = (this.Map.terrainGrid.TerrainAt(fishSpot) == TerrainDefOf.WaterOceanShallow) ||
                                                  (this.Map.terrainGrid.TerrainAt(fishSpot) == TerrainDefOf.WaterOceanDeep);
                        bool fishSpotIsMarshy = (this.Map.terrainGrid.TerrainAt(fishSpot) == TerrainDef.Named("Marsh"));

                        PawnKindDef caugthFishDef = null;
                        if (fishSpotIsOcean)
                        {
                            caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList(this.Map.Biome)
                                             where fishSpecies.livesInOcean
                                             select fishSpecies).RandomElementByWeight((PawnKindDef_FishSpecies def) => def.commonality);
                        }
                        else if (fishSpotIsMarshy)
                        {
                            caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList(this.Map.Biome)
                                             where fishSpecies.livesInMarsh
                                             select fishSpecies).RandomElementByWeight((PawnKindDef_FishSpecies def) => def.commonality);
                        }
                        else
                        {
                            caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList(this.Map.Biome)
                                             where fishSpecies.livesInRiver
                                             select fishSpecies).RandomElementByWeight((PawnKindDef_FishSpecies def) => def.commonality);
                        }
                        Pawn caughtFish = PawnGenerator.GeneratePawn(caugthFishDef);
                        ExecutionUtility.DoExecutionByCut(this.pawn, caughtFish);
                        Corpse corpse = caughtFish.ParentHolder as Corpse;
                        GenSpawn.Spawn(corpse, this.pawn.Position, this.Map);
                        fishingCatch = corpse;
                        fishingCatch.SetForbidden(false);
                        if (caughtFish.BodySize >= 0.1f)
                        {
                            fishingPier.fishStock--;
                        }
                    }
                    IntVec3 storageCell;
                    if (StoreUtility.TryFindBestBetterStoreCellFor(fishingCatch, this.pawn, this.Map, StoragePriority.Unstored, this.pawn.Faction, out storageCell, true))
                    {
                        this.pawn.Reserve(fishingCatch, this.job);
                        this.pawn.Reserve(storageCell, this.job);
                        this.pawn.CurJob.SetTarget(TargetIndex.B, storageCell);
                        this.pawn.CurJob.SetTarget(TargetIndex.A, fishingCatch);
                        this.pawn.CurJob.count    = 9999;
                        this.pawn.CurJob.haulMode = HaulMode.ToCellStorage;
                    }
                    else
                    {
                        this.pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                    }
                }
            };

            yield return(catchFishToil);

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

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

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));
        }
示例#25
0
        // Token: 0x0600006A RID: 106 RVA: 0x000045B4 File Offset: 0x000027B4
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOn(delegate()
            {
                bool flag4 = !WorkGiver_WPTend.GoodLayingStatusForTend(this.Deliveree, this.pawn);
                bool result;
                if (flag4)
                {
                    result = true;
                }
                else
                {
                    bool flag5 = this.MedicineUsed != null;
                    if (flag5)
                    {
                        bool flag6 = this.Deliveree.playerSettings == null;
                        if (flag6)
                        {
                            return(true);
                        }
                        bool flag7 = !this.Deliveree.playerSettings.medCare.AllowsMedicine(this.MedicineUsed.def);
                        if (flag7)
                        {
                            return(true);
                        }
                    }
                    result = (this.pawn == this.Deliveree && (this.pawn.playerSettings == null || !this.pawn.playerSettings.selfTend));
                }
                return(result);
            });
            base.AddEndCondition(delegate
            {
                bool flag4 = HealthAIUtility.ShouldBeTendedNowByPlayer(this.Deliveree);
                JobCondition result;
                if (flag4)
                {
                    result = JobCondition.Ongoing;
                }
                else
                {
                    result = JobCondition.Succeeded;
                }
                return(result);
            });
            this.FailOnAggroMentalState(TargetIndex.A);
            Toil reserveMedicine = null;
            bool flag            = this.usesMedicine;

            if (flag)
            {
                reserveMedicine = Toils_Tend.ReserveMedicine(TargetIndex.B, this.Deliveree).FailOnDespawnedNullOrForbidden(TargetIndex.B);
                yield return(reserveMedicine);

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

                yield return(Toils_WPTend.PickupMedicine(TargetIndex.B, this.Deliveree).FailOnDestroyedOrNull(TargetIndex.B));

                yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveMedicine, TargetIndex.B, TargetIndex.None, true, null));
            }
            PathEndMode interactionCell = (this.Deliveree != this.pawn) ? PathEndMode.OnCell : PathEndMode.InteractionCell;
            Toil        gotoToil        = Toils_Goto.GotoThing(TargetIndex.A, interactionCell);

            yield return(gotoToil);

            Toil toil  = Toils_General.Wait((int)(1f / this.pawn.GetStatValue(StatDefOf.MedicalTendSpeed, true) * 600f), TargetIndex.None).FailOnCannotTouch(TargetIndex.A, interactionCell).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f).PlaySustainerOrSound(SoundDefOf.Interact_Tend);
            bool flag2 = this.pawn == this.Deliveree && this.pawn.Faction != Faction.OfPlayer;

            if (flag2)
            {
                toil.tickAction = delegate()
                {
                    bool flag4 = this.pawn.IsHashIntervalTick(100) && !this.pawn.Position.Fogged(this.pawn.Map);
                    if (flag4)
                    {
                        MoteMaker.ThrowMetaIcon(this.pawn.Position, this.pawn.Map, ThingDefOf.Mote_HealingCross);
                    }
                };
            }
            yield return(toil);

            yield return(Toils_WPTend.FinalizeTend(this.Deliveree));

            bool flag3 = this.usesMedicine;

            if (flag3)
            {
                yield return(new Toil
                {
                    initAction = delegate()
                    {
                        bool flag4 = this.MedicineUsed.DestroyedOrNull();
                        if (flag4)
                        {
                            Thing thing = HealthAIUtility.FindBestMedicine(this.pawn, this.Deliveree);
                            bool flag5 = thing != null;
                            if (flag5)
                            {
                                this.job.targetB = thing;
                                this.JumpToToil(reserveMedicine);
                            }
                        }
                    }
                });
            }
            yield return(Toils_Jump.Jump(gotoToil));

            yield break;
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.FailOnThingMissingDesignation(TargetIndex.A, this.Designation);
                    this.FailOnForbidden(TargetIndex.A);
                    this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);

                case 1u:
                {
                    Toil doWork = new Toil().FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
                    doWork.initAction = delegate()
                    {
                        this.totalNeededWork = this.TotalNeededWork;
                        this.workLeft        = this.totalNeededWork;
                    };
                    doWork.tickAction = delegate()
                    {
                        this.workLeft -= this.pawn.GetStatValue(StatDefOf.ConstructionSpeed, true);
                        this.TickAction();
                        if (this.workLeft <= 0f)
                        {
                            doWork.actor.jobs.curDriver.ReadyForNextToil();
                        }
                    };
                    doWork.defaultCompleteMode = ToilCompleteMode.Never;
                    doWork.WithProgressBar(TargetIndex.A, () => 1f - this.workLeft / this.totalNeededWork, false, -0.5f);
                    doWork.activeSkill = (() => SkillDefOf.Construction);
                    this.$current      = doWork;
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);
                }

                case 2u:
                {
                    Toil finalize = new Toil();
                    finalize.initAction = delegate()
                    {
                        this.FinishedRemoving();
                        base.Map.designationManager.RemoveAllDesignationsOn(base.Target, false);
                    };
                    finalize.defaultCompleteMode = ToilCompleteMode.Instant;
                    this.$current = finalize;
                    if (!this.$disposing)
                    {
                        this.$PC = 3;
                    }
                    return(true);
                }

                case 3u:
                    this.$PC = -1;
                    break;
                }
                return(false);
            }
        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;
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
                    this.FailOnBurningImmobile(TargetIndex.A);
                    base.AddEndCondition(() => (base.Barrel.SpaceLeftForWort > 0) ? JobCondition.Ongoing : JobCondition.Succeeded);
                    this.$current = Toils_General.DoAtomic(delegate
                    {
                        this.job.count = base.Barrel.SpaceLeftForWort;
                    });
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);

                case 1u:
                    reserveWort   = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null);
                    this.$current = reserveWort;
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

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

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

                case 4u:
                    this.$current = Toils_Haul.CheckForGetOpportunityDuplicate(reserveWort, TargetIndex.B, TargetIndex.None, true, null);
                    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:
                    this.$current = Toils_General.Wait(200, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.B).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
                    if (!this.$disposing)
                    {
                        this.$PC = 7;
                    }
                    return(true);

                case 7u:
                {
                    Toil finalize = new Toil();
                    finalize.initAction = delegate()
                    {
                        base.Barrel.AddWort(base.Wort);
                    };
                    finalize.defaultCompleteMode = ToilCompleteMode.Instant;
                    this.$current = finalize;
                    if (!this.$disposing)
                    {
                        this.$PC = 8;
                    }
                    return(true);
                }

                case 8u:
                    this.$PC = -1;
                    break;
                }
                return(false);
            }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (fishCaught == null)
            {
                this.EndJobWith(JobCondition.Incompletable);
                fishingZone.someoneFishing = false;
            }

            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.A);
            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch));

            this.pawn.rotationTracker.FaceTarget(base.TargetA);
            Toil fishToil = new Toil();

            fishToil.tickAction = delegate()
            {
                this.pawn.skills.Learn(SkillDefOf.Animals, skillGainperTick);
                if (fishingZone != null)
                {
                    if (!fishingZone.isZoneBigEnough)
                    {
                        this.EndJobWith(JobCondition.Incompletable);
                        fishingZone.someoneFishing = false;
                    }
                }
            };

            Rot4    pawnRotation = pawn.Rotation;
            IntVec3 facingCell   = pawnRotation.FacingCell;

            if (facingCell == new IntVec3(0, 0, 1))
            {
                //Log.Message("Looking north");
                fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectNorth"), () => this.TargetA.Cell + new IntVec3(0, 0, 1));
            }
            else if (facingCell == new IntVec3(1, 0, 0))
            {
                // Log.Message("Looking east");

                fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectEast"), () => this.TargetA.Cell + new IntVec3(1, 0, 0));
            }
            else if (facingCell == new IntVec3(0, 0, -1))
            {
                // Log.Message("Looking south");
                fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectSouth"), () => this.TargetA.Cell + new IntVec3(0, 0, -1));
            }
            else if (facingCell == new IntVec3(-1, 0, 0))
            {
                //  Log.Message("Looking west");
                fishToil.WithEffect(() => DefDatabase <EffecterDef> .GetNamed("VCEF_FishingEffectWest"), () => this.TargetA.Cell + new IntVec3(-1, 0, 0));
            }
            fishToil.defaultCompleteMode = ToilCompleteMode.Delay;

            switch (sizeAtBeginning)
            {
            case FishSizeCategory.Small:
                fishToil.defaultDuration = (int)(-150 * fishingSkill + smallFishDurationFactor * 1.5);
                break;

            case FishSizeCategory.Medium:
                fishToil.defaultDuration = (int)(-300 * fishingSkill + mediumFishDurationFactor * 1.5);
                break;

            case FishSizeCategory.Large:
                fishToil.defaultDuration = (int)(-450 * fishingSkill + largeFishDurationFactor * 1.5);
                break;

            default:
                fishToil.defaultDuration = mediumFishDurationFactor;
                break;
            }

            //Log.Message(fishToil.defaultDuration.ToString());
            fishToil.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            yield return(fishToil.WithProgressBarToilDelay(TargetIndex.A, true));

            yield return(new Toil
            {
                initAction = delegate
                {
                    Thing newFish = ThingMaker.MakeThing(fishCaught);
                    newFish.stackCount = fishAmountWithSkill;
                    GenSpawn.Spawn(newFish, this.TargetA.Cell - GenAdj.CardinalDirections[0], this.Map);
                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(newFish);
                    IntVec3 c;
                    if (StoreUtility.TryFindBestBetterStoreCellFor(newFish, this.pawn, this.Map, currentPriority, this.pawn.Faction, out c, true))
                    {
                        this.job.SetTarget(TargetIndex.C, c);
                        this.job.SetTarget(TargetIndex.B, newFish);
                        this.job.count = newFish.stackCount;
                        fishingZone.someoneFishing = false;
                    }
                    else
                    {
                        this.EndJobWith(JobCondition.Incompletable);
                        fishingZone.someoneFishing = false;
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

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

            yield return(Toils_Reserve.Reserve(TargetIndex.C, 1, -1, null));

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

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

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

            yield return(carryToCell);

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



            yield break;
        }
示例#30
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddFinishAction(delegate
            {
                this.Map.attackTargetsCache.UpdateTarget(this.pawn);
            });
            Toil prepareToEatCorpse = new Toil();

            prepareToEatCorpse.initAction = delegate()
            {
                Pawn   actor  = prepareToEatCorpse.actor;
                Corpse corpse = this.Corpse;
                if (corpse == null)
                {
                    Pawn prey = 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.Map.attackTargetsCache.UpdateTarget(this.pawn);
            }));

            Action onHitAction = delegate()
            {
                Pawn prey           = this.Prey;
                bool surpriseAttack = this.firstHit && !prey.IsColonist;
                if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack))
                {
                    if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey))
                    {
                        this.notifiedPlayer = true;
                        Messages.Message("MessageAttackedByPredator".Translate(new object[]
                        {
                            prey.LabelShort,
                            this.pawn.LabelIndefinite()
                        }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatSmall, true);
                    }
                    this.Map.attackTargetsCache.UpdateTarget(this.pawn);
                }
                this.firstHit = false;
            };

            yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIfDespawnedOrNull(TargetIndex.A, prepareToEatCorpse).JumpIf(() => this.Corpse != null, prepareToEatCorpse).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (float)(this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f));

            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.pawn.needs.food.CurLevelPercentage < 0.9f));

            yield break;
        }