protected override IEnumerable <Toil> MakeNewToils()
        {
            List <Toil>   toilsList       = new List <Toil>();
            Building_Pyre pyre            = this.TargetThingA as Building_Pyre;
            bool          beerIsAvailable = false;

            if (this.pawn.Position.InHorDistOf(pyre.Position, Building_Pyre.partyAreaRadius) == false)
            {
                // Go around pyre.
                toilsList.Add(base.ToilGetWanderCell(pyre.Position));
                Find.PawnDestinationManager.ReserveDestinationFor(this.pawn, this.CurJob.targetB.Cell);
                toilsList.Add(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell));
                // Release cell (the pawn will either go grab a beer or move on the next job).
                toilsList.Add(base.ToilReleaseCell());
            }
            // Look for an available beer.
            List <Thing> list = Find.ListerThings.ThingsOfDef(ThingDefOf.Beer);

            if (list.Count > 0)
            {
                Predicate <Thing> validator = (Thing t) => pawn.CanReserve(t, 1) && !t.IsForbidden(pawn);
                Thing             beer      = GenClosest.ClosestThing_Global_Reachable(pyre.Position, list, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), Building_Pyre.beerSearchAreaRadius, validator, null);
                if (beer != null)
                {
                    beerIsAvailable = true;
                    this.CurJob.SetTarget(TargetIndex.A, beer);
                    //this.CurJob.targetA = beer;
                    this.CurJob.maxNumToCarry = 1;
                    toilsList.Add(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A));
                    toilsList.Add(Toils_Ingest.PickupIngestible(TargetIndex.A, this.pawn)); // TargetIndex.A becomes the carried beer.
                    toilsList.Add(Toils_Ingest.CarryIngestibleToChewSpot(this.pawn));
                    toilsList.Add(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A));
                    // float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true); // Don't use it so the job duration is nearly the same for all pawns.
                    float durationMultiplier = 1f;
                    toilsList.Add(Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.B).FailOn((Toil x) => !this.Food.Spawned && (this.pawn.carrier == null || this.pawn.carrier.CarriedThing != this.Food)));
                    toilsList.Add(Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A));
                }
            }
            // Draw a mote.
            ThingDef moteDef = null;

            if (beerIsAvailable)
            {
                moteDef = Util_CampfireParty.Mote_BeerAvailable;
            }
            else
            {
                moteDef = Util_CampfireParty.Mote_BeerUnavailable;
            }
            MoteAttached moteAttached = (MoteAttached)ThingMaker.MakeThing(moteDef);

            moteAttached.AttachTo(this.pawn);
            GenSpawn.Spawn(moteAttached, this.pawn.Position);

            return(toilsList);
        }
Beispiel #2
0
        internal static IEnumerable <Toil> _MakeNewToils(this JobDriver_FoodFeedPatient obj)
        {
            var foodThing = obj.TargetThing(FoodInd);
            var deliveree = (Pawn)obj.TargetThing(DelivereeInd);

            obj.FailOnDespawnedNullOrForbidden(DelivereeInd);
            obj.FailOn(() =>
            {
                return(!FoodUtility.ShouldBeFedBySomeone(deliveree));
            });

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

            if (foodThing is Building)
            {
                yield return(Toils_Reserve.Reserve(FoodInd, 1));

                yield return(Toils_Goto.GotoThing(FoodInd, PathEndMode.InteractionCell).FailOnForbidden(FoodInd));

                if (foodThing is Building_NutrientPasteDispenser)
                {
                    yield return(Toils_Ingest.TakeMealFromDispenser(FoodInd, obj.pawn));
                }
                else if (foodThing is Building_AutomatedFactory)
                {
                    yield return(Toils_FoodSynthesizer.TakeMealFromSynthesizer(FoodInd, obj.pawn));
                }
                else // Unknown building
                {
                    throw new Exception("Food target for JobDriver_FoodDeliver is a building but not Building_NutrientPasteDispenser or Building_AutomatedFactory!");
                }
            }
            else if (
                (obj.pawn.inventory != null) &&
                (obj.pawn.inventory.Contains(foodThing))
                )
            {
                yield return(Toils_Misc.TakeItemFromInventoryToCarrier(obj.pawn, FoodInd));
            }
            else
            {
                yield return(Toils_Reserve.Reserve(FoodInd, 1));

                yield return(Toils_Goto.GotoThing(FoodInd, PathEndMode.ClosestTouch).FailOnForbidden(FoodInd));

                yield return(Toils_Ingest.PickupIngestible(FoodInd, deliveree));
            }

            yield return(Toils_Goto.GotoThing(DelivereeInd, PathEndMode.Touch));

            yield return(Toils_Ingest.ChewIngestible(deliveree, FeedDurationMultiplier, FoodInd));

            yield return(Toils_Ingest.FinalizeIngest(deliveree, FoodInd));
        }
Beispiel #3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(() => !IngestibleSource.Destroyed && !IngestibleSource.IngestibleNow);
            Toil chew = Toils_Ingest.ChewIngestible(pawn, ChewDurationMultiplier, TargetIndex.A, TargetIndex.None).FailOn((Toil x) => !IngestibleSource.Spawned && (pawn.carryTracker == null || pawn.carryTracker.CarriedThing != IngestibleSource)).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);

            foreach (Toil toil in PrepareToIngestToils())
            {
                yield return(toil);
            }
            yield return(chew);

            yield return(Toils_Ingest.FinalizeIngest(pawn, TargetIndex.A));
        }
Beispiel #4
0
        private IEnumerable <Toil> Nibble()
        {
            Toil gotoCorpse = Toils_Goto.GotoThing(CorpseInd, PathEndMode.Touch);

            yield return(gotoCorpse);

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

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

            yield return(Toils_Ingest.FinalizeIngest(this.pawn, CorpseInd));

            yield return(Toils_Jump.JumpIf(gotoCorpse, () => this.pawn.needs.food.CurLevelPercentage < 0.9f));
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (this.pawn.inventory != null && this.pawn.inventory.Contains(base.TargetThingA))
            {
                yield return(Toils_Misc.TakeItemFromInventoryToCarrier(this.pawn, TargetIndex.A));
            }
            else
            {
                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnForbidden(TargetIndex.A));

                yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, this.pawn));
            }
            yield return(Toils_Ingest.ChewIngestible(this.pawn, 1f, TargetIndex.A));

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

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (!usingNutrientPasteDispenser)
            {
                this.FailOn(() => !IngestibleSource.Destroyed && !IngestibleSource.IngestibleNow);
            }
            Toil chew = Toils_Ingest.ChewIngestible(pawn, ChewDurationMultiplier, TargetIndex.A, TargetIndex.B).FailOn((Toil x) => (!IngestibleSource.Spawned && (pawn.carryTracker != null)) || pawn.mindState.anyCloseHostilesRecently).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);

            foreach (Toil item in PrepareToIngestToils(chew))
            {
                yield return(item);
            }
            yield return(chew);

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

            yield return(Toils_Jump.JumpIf(chew, () => job.GetTarget(TargetIndex.A).Thing is Corpse && pawn.needs.food.CurLevelPercentage < 0.9f));
        }
Beispiel #7
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // Declare these early - jumping points
            var waitForWaiter = Toils_Dining.WaitForWaiter(SpotIndex, WaiterIndex).FailOnRestaurantClosed().FailOnDangerous();
            var waitForMeal   = Toils_Dining.WaitForMeal(MealIndex).FailOnDangerous();

            this.FailOn(() => DiningSpot.Destroyed);
            yield return(Toils_Dining.GoToDineSpot(pawn, SpotIndex).FailOnRestaurantClosed());

            yield return(Toils_Dining.TurnToEatSurface(SpotIndex));

            // Order broken? Jump straight to waiter
            yield return(Toils_Jump.JumpIf(waitForWaiter, () => !pawn.GetRestaurant().Orders.CheckOrderOfWaitingPawn(pawn)));

            // Already has ordered? Jump to waiting for meal
            yield return(Toils_Jump.JumpIf(waitForMeal, () => pawn.GetRestaurant().Orders.GetOrderFor(pawn) != null));

            yield return(waitForWaiter);

            yield return(waitForMeal);

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

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

            yield return(Toils_Dining.TurnToEatSurface(SpotIndex, MealIndex));

            yield return(Toils_Dining.WaitDuringDinner(SpotIndex, 100, 250));

            yield return(Toils_Ingest.ChewIngestible(pawn, ChewDurationMultiplier, MealIndex, SpotIndex));

            yield return(Toils_Ingest.FinalizeIngest(pawn, MealIndex));

            yield return(Toils_Dining.OnCompletedMeal(pawn));

            yield return(Toils_Dining.MakeTableMessy(SpotIndex, () => pawn.Position));

            yield return(Toils_Jump.JumpIf(waitForWaiter, () => pawn.needs.food.CurLevelPercentage < 0.9f));

            yield return(Toils_Dining.WaitDuringDinner(SpotIndex, 100, 250));

            yield return(Toils_Dining.PayDebt(pawn));
        }
        internal static IEnumerable <Toil> _MakeNewToils(this JobDriver_FoodFeedPatient obj)
        {
            Pawn deliveree = (Pawn)obj.pawn.CurJob.targetB.Thing;

            obj.FailOnDespawnedNullOrForbidden(TargetIndex.B);
            obj.FailOn(() =>
            {
                return(!FoodUtility.ShouldBeFedBySomeone(deliveree));
            });

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

            var targetThingA = obj.TargetThingA();

            if (targetThingA is Building)
            {
                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnForbidden(TargetIndex.A));

                if (targetThingA is Building_NutrientPasteDispenser)
                {
                    yield return(Toils_Ingest.TakeMealFromDispenser(TargetIndex.A, obj.pawn));
                }
                if (targetThingA is Building_AutomatedFactory)
                {
                    yield return(Toils_FoodSynthesizer.TakeMealFromSynthesizer(TargetIndex.A, obj.pawn));
                }
            }
            else
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

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

                yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, deliveree));
            }

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

            yield return(Toils_Ingest.ChewIngestible(deliveree, 1.5f, TargetIndex.A));

            yield return(Toils_Ingest.FinalizeIngest(deliveree, TargetIndex.A));
        }
Beispiel #9
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (!usingNutrientPasteDispenser)
            {
                this.FailOn(() => !IngestibleSource.Destroyed && !IngestibleSource.IngestibleNow);
            }
            Toil chew = Toils_Ingest.ChewIngestible(pawn, ChewDurationMultiplier, TargetIndex.A, TargetIndex.B)
                        .FailOn((Toil x) => !IngestibleSource.Spawned &&
                                (pawn.carryTracker == null || pawn.carryTracker.CarriedThing != IngestibleSource))
                        .FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);

            foreach (Toil toil in PrepareToIngestToils(chew))
            {
                yield return(toil);
            }
            yield return(chew);

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

            yield return(Toils_Jump.JumpIf(chew, () => pawn?.BloodNeed()?.CurLevelPercentage < 1f));
        }
Beispiel #10
0
        public 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, true);
                        return;
                    }
                    corpse = prey.Corpse;
                    if (corpse == null || !corpse.Spawned)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, 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 hitAction = delegate()
            {
                Pawn prey           = this.Prey;
                bool surpriseAttack = this.firstHit && !prey.IsColonist;
                if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack))
                {
                    if (!this.notifiedPlayerAttacked && PawnUtility.ShouldSendNotificationAbout(prey))
                    {
                        this.notifiedPlayerAttacked = true;
                        Messages.Message("MessageAttackedByPredator".Translate(prey.LabelShort, this.pawn.LabelIndefinite(), prey.Named("PREY"), this.pawn.Named("PREDATOR")).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatSmall, true);
                    }
                    this.Map.attackTargetsCache.UpdateTarget(this.pawn);
                    this.firstHit = false;
                }
            };
            Toil toil = Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, hitAction).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);

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

            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;
        }
        internal static IEnumerable <Toil> _MakeNewToils(this JobDriver_Ingest obj)
        {
            if (obj.IsDispenser())
            {
                yield return(Toils_Goto.GotoThing(FoodOrDispenserInd, PathEndMode.InteractionCell).FailOnDespawnedNullOrForbidden(FoodOrDispenserInd));

                if (obj.Alcohol() == null)
                {
                    // Meals
                    if (obj.Dispenser() is Building_NutrientPasteDispenser)
                    {
                        yield return(Toils_Ingest.TakeMealFromDispenser(FoodOrDispenserInd, obj.pawn));
                    }
                    if (obj.Dispenser() is Building_AutomatedFactory)
                    {
                        yield return(Toils_FoodSynthesizer.TakeMealFromSynthesizer(FoodOrDispenserInd, obj.pawn));
                    }
                }
                else
                {
                    // Alcohol
                    if (obj.Dispenser() is Building_AutomatedFactory)
                    {
                        yield return(Toils_FoodSynthesizer.TakeAlcoholFromSynthesizer(FoodOrDispenserInd, obj.pawn));
                    }
                }
                yield return(Toils_Ingest.CarryIngestibleToChewSpot(obj.pawn).FailOnDestroyedNullOrForbidden(FoodOrDispenserInd));

                yield return(Toils_Ingest.FindAdjacentEatSurface(TableCellInd, FoodOrDispenserInd));
            }
            else if (obj.pawn.RaceProps.ToolUser)
            {
                if (obj.pawn.CurJob.eatFromInventory)
                {
                    var dropIfNeeded = new Toil();
                    dropIfNeeded.initAction = new Action(() =>
                    {
                        Pawn pawn            = obj.pawn;
                        Thing resultingThing = obj.Food();
                        Thing thing          = resultingThing;
                        if (
                            (pawn.inventory == null) ||
                            (!pawn.inventory.container.Contains(resultingThing))
                            )
                        {
                            return;
                        }
                        int count = Mathf.Min(resultingThing.stackCount, pawn.CurJob.maxNumToCarry);
                        if (!pawn.inventory.container.TryDrop(resultingThing, pawn.Position, ThingPlaceMode.Near, count, out resultingThing))
                        {
                            Verse.Log.Error(pawn + " could not drop their food to eat it.");
                            obj.EndJobWith(JobCondition.Errored);
                        }
                        else
                        {
                            if (resultingThing == thing)
                            {
                                return;
                            }
                            pawn.CurJob.SetTarget(FoodOrDispenserInd, (TargetInfo)resultingThing);
                        }
                    });

                    yield return(dropIfNeeded);
                }
                yield return(obj.ReserveFoodIfWillEatWholeStack());

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

                yield return(Toils_Ingest.PickupIngestible(FoodOrDispenserInd, obj.pawn));

                yield return(Toils_Ingest.CarryIngestibleToChewSpot(obj.pawn).FailOnDestroyedNullOrForbidden(FoodOrDispenserInd));

                yield return(Toils_Ingest.FindAdjacentEatSurface(TableCellInd, FoodOrDispenserInd));
            }
            else // Non-Tool User
            {
                yield return(obj.ReserveFoodIfWillEatWholeStack());

                yield return(Toils_Goto.GotoThing(FoodOrDispenserInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(FoodOrDispenserInd));
            }

            var durationMultiplier = 1f / obj.pawn.GetStatValue(StatDefOf.EatingSpeed, true);
            var chew = Toils_Ingest.ChewIngestible(obj.pawn, durationMultiplier, FoodOrDispenserInd, TableCellInd).FailOn(() =>
            {
                if (!obj.Food().Spawned)
                {
                    return((obj.pawn.carrier == null ? 0 : (obj.pawn.carrier.CarriedThing == obj.Food() ? 1 : 0)) == 0);
                }
                return(false);
            });

            yield return(chew);

            yield return(Toils_Ingest.FinalizeIngest(obj.pawn, FoodOrDispenserInd));

            yield return(Toils_Jump.JumpIf(chew, () =>
            {
                if (obj.Food() is Corpse)
                {
                    return (double)obj.pawn.needs.food.CurLevelPercentage < JobDriver_Ingest.EatCorpseBodyPartsUntilFoodLevelPct;
                }
                return false;
            }));
        }