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