コード例 #1
0
        internal static IEnumerable <Toil> _PrepareToEatToils_Dispenser(this JobDriver_Ingest obj)
        {
            var foodSource = obj.TargetThing(FoodInd);
            var alcohol    = obj.TargetThing(AlcoholInd);

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

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

            if (foodSource is Building_NutrientPasteDispenser)
            {
                yield return(Toils_Ingest.TakeMealFromDispenser(FoodInd, obj.pawn));
            }
            else if (foodSource is Building_AutomatedFactory)
            {
                if (alcohol == null)
                {
                    yield return(Toils_FoodSynthesizer.TakeMealFromSynthesizer(FoodInd, obj.pawn));
                }
                else
                {
                    yield return(Toils_FoodSynthesizer.TakeAlcoholFromSynthesizer(AlcoholInd, obj.pawn));
                }
            }
            yield return(Toils_Ingest.CarryIngestibleToChewSpot(obj.pawn)
                         .FailOnDestroyedNullOrForbidden(FoodInd));

            yield return(Toils_Ingest.FindAdjacentEatSurface(TableCellInd, FoodInd));
        }
コード例 #2
0
        internal static IEnumerable <Toil> _MakeNewToils(this JobDriver_SocialRelax obj)
        {
            obj.EndOnDespawnedOrNull(GatherSpotParentInd, JobCondition.Incompletable);

            if (obj.HasChair())
            {
                obj.EndOnDespawnedOrNull(ChairOrSpotInd, JobCondition.Incompletable);
            }
            yield return(Toils_Reserve.Reserve(ChairOrSpotInd, 1));

            if (obj.HasDrinkOrDispenser())
            {
                obj.FailOnDestroyedNullOrForbidden(OptionalDrinkInd);
                yield return(Toils_Reserve.Reserve(OptionalDrinkInd, 1));

                if (obj.IsDispenser())
                {
                    yield return(Toils_Goto.GotoThing(OptionalDrinkInd, PathEndMode.InteractionCell));

                    yield return(Toils_FoodSynthesizer.TakeAlcoholFromSynthesizer(OptionalDrinkInd, obj.pawn));
                }
                else
                {
                    yield return(Toils_Goto.GotoThing(OptionalDrinkInd, PathEndMode.OnCell));

                    yield return(Toils_Haul.StartCarryThing(OptionalDrinkInd));
                }
            }

            yield return(Toils_Goto.GotoCell(ChairOrSpotInd, PathEndMode.OnCell));

            var relax = new Toil()
            {
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = obj.pawn.CurJob.def.joyDuration,
                tickAction          = () =>
                {
                    var pawnDrawer     = obj.pawn.GetPawnDrawTracker();
                    var pawnFaceTarget = obj.ClosestGatherSpotParentCell();
                    pawnDrawer.rotator.FaceCell(pawnFaceTarget);
                    obj.pawn.GainComfortFromCellIfPossible();
                    JoyUtility.JoyTickCheckEnd(obj.pawn, JoyTickFullJoyAction.GoToNextToil, 1f);
                }
            };

            relax.AddFinishAction(() =>
                                  JoyUtility.TryGainRecRoomThought(obj.pawn)
                                  );
            relax.socialMode = RandomSocialMode.SuperActive;
            yield return(relax);

            if (obj.IsDrink())
            {
                yield return(Toils_Ingest.FinalizeIngest(obj.pawn, OptionalDrinkInd));
            }
        }
コード例 #3
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));
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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;
            }));
        }
コード例 #6
0
        internal static IEnumerable <Toil> _MakeNewToils(this JobDriver_FoodDeliver obj)
        {
            var foodThing = obj.TargetThing(FoodInd);
            var deliveree = (Pawn)obj.TargetThing(DelivereeInd);
            var dropCell  = obj.TargetCell(DeliverToInd);

            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));

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

            var pathToTarget = new Toil();

            pathToTarget.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            pathToTarget.initAction          = new Action(() =>
            {
                var pawn = obj.pawn;
                var job  = pawn.jobs.curJob;
                pawn.pather.StartPath(job.targetC, PathEndMode.OnCell);
            }
                                                          );
            pathToTarget.FailOnDestroyedNullOrForbidden(DelivereeInd);
            pathToTarget.AddFailCondition(() =>
            {
                return
                ((deliveree.Downed) ||
                 (!deliveree.IsPrisonerOfColony) ||
                 (!deliveree.guest.ShouldBeBroughtFood));
            });
            yield return(pathToTarget);

            var dropFoodAtTarget = new Toil();

            dropFoodAtTarget.initAction = new Action(() =>
            {
                Thing resultingThing;
                obj.pawn.carrier.TryDropCarriedThing(dropCell, ThingPlaceMode.Direct, out resultingThing);
            }
                                                     );
            dropFoodAtTarget.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(dropFoodAtTarget);
        }
コード例 #7
0
        internal static IEnumerable <Toil> _MakeNewToils(this JobDriver_FoodDeliver obj)
        {
            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));

                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
            {
                var deliveree = (Pawn)obj.pawn.CurJob.targetB.Thing;
                yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

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

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

            var pathToTarget = new Toil();

            pathToTarget.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            pathToTarget.initAction          = new Action(() =>
            {
                Pawn pawn = obj.pawn;
                Job job   = pawn.jobs.curJob;
                pawn.pather.StartPath(job.targetC, PathEndMode.OnCell);
            }
                                                          );
            pathToTarget.FailOnDestroyedNullOrForbidden(TargetIndex.B);
            pathToTarget.AddFailCondition(() =>
            {
                Pawn pawn = (Pawn)obj.pawn.jobs.curJob.targetB.Thing;
                return
                ((pawn.Downed) ||
                 (!pawn.IsPrisonerOfColony) ||
                 (!pawn.guest.ShouldBeBroughtFood));
            });
            yield return(pathToTarget);

            var dropFoodAtTarget = new Toil();

            dropFoodAtTarget.initAction = new Action(() =>
            {
                Thing resultingThing;
                obj.pawn.carrier.TryDropCarriedThing(obj.pawn.jobs.curJob.targetC.Cell, ThingPlaceMode.Direct, out resultingThing);
            }
                                                     );
            dropFoodAtTarget.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(dropFoodAtTarget);
        }