protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Goto.GotoThing(PuzzleBoxInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(PuzzleBoxInd)); yield return(Toils_Ingest.PickupIngestible(PuzzleBoxInd, this.pawn)); yield return(CarryPuzzleToSpot(pawn, PuzzleBoxInd)); yield return(Toils_Ingest.FindAdjacentEatSurface(joySpot, PuzzleBoxInd)); Toil puzzle; puzzle = new Toil(); puzzle.tickAction = this.WaitTickAction(); puzzle.AddFinishAction(() => { JoyUtility.TryGainRecRoomThought(this.pawn); this.RollForLuck(); }); puzzle.defaultCompleteMode = ToilCompleteMode.Delay; puzzle.defaultDuration = this.job.def.joyDuration; puzzle.handlingFacing = true; yield return(puzzle); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Goto.GotoThing(ToyInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(ToyInd)); yield return(Toils_Ingest.PickupIngestible(ToyInd, pawn)); yield return(CarryToyToSpot(pawn, ToyInd)); yield return(Toils_Ingest.FindAdjacentEatSurface(joySpot, ToyInd)); var playWithToy = new Toil { tickAction = WaitTickAction() }; playWithToy.AddFinishAction(() => { JoyUtility.TryGainRecRoomThought(pawn); TalkToDoll(); }); playWithToy.defaultCompleteMode = ToilCompleteMode.Delay; playWithToy.defaultDuration = job.def.joyDuration; playWithToy.handlingFacing = true; yield return(playWithToy); }
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)); }
private static IEnumerable <Toil> Postfix(IEnumerable <Toil> values, JobDriver_Ingest __instance, Toil chewToil) { LocalTargetInfo food = __instance.job.GetTarget(TargetIndex.A);; foreach (Toil baseToil in values) { if (carryToils.Contains(baseToil)) { carryToils.Remove(baseToil); foreach (Toil toil in HeatMealInjector.Heat(__instance)) { yield return(toil); } } yield return(baseToil); } if (food.Thing.def.IsDrug) { foreach (Toil toil in HeatMealInjector.Heat(__instance)) { yield return(toil); } yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); } yield break; }
private IEnumerable <Toil> PrepareToIngestToils_ToolUser(Toil chewToil) { if (eatingFromInventory) { yield return(Toils_Misc.TakeItemFromInventoryToCarrier(pawn, TargetIndex.A)); } else { yield return(ReserveFoodIfWillIngestWholeStack()); Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Jump.JumpIf(gotoToPickup, () => pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Jump.Jump(chewToil)); yield return(gotoToPickup); yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, pawn)); Toil reserveExtraFoodToCollect = Toils_Reserve.Reserve(TargetIndex.C); Toil findExtraFoodToCollect = new Toil(); findExtraFoodToCollect.initAction = delegate { if (pawn.inventory.innerContainer.TotalStackCountOfDef(IngestibleSource.def) < job.takeExtraIngestibles) { Predicate <Thing> validator = (Thing x) => pawn.CanReserve(x) && !x.IsForbidden(pawn) && x.IsSociallyProper(pawn); Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(IngestibleSource.def), PathEndMode.Touch, TraverseParms.For(pawn), 12f, validator); if (thing != null) { pawn.CurJob.SetTarget(TargetIndex.C, thing); JumpToToil(reserveExtraFoodToCollect); } } }; findExtraFoodToCollect.defaultCompleteMode = ToilCompleteMode.Instant; yield return(Toils_Jump.Jump(findExtraFoodToCollect)); yield return(reserveExtraFoodToCollect); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.Touch)); yield return(Toils_Haul.TakeToInventory(TargetIndex.C, () => job.takeExtraIngestibles - pawn.inventory.innerContainer.TotalStackCountOfDef(IngestibleSource.def))); yield return(findExtraFoodToCollect); } yield return(Toils_Ingest.CarryIngestibleToChewSpot(pawn, TargetIndex.A).FailOnDestroyedOrNull(TargetIndex.A)); yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); }
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); }
private IEnumerable <Toil> PrepareToIngestToils_Dispenser() { yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Ingest.TakeMealFromDispenser(TargetIndex.A, pawn)); yield return(Toils_Ingest.CarryIngestibleToChewSpot(pawn, TargetIndex.A).FailOnDestroyedNullOrForbidden(TargetIndex.A)); yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); }
static IEnumerable <Toil> prepToils(JobDriver_Ingest driver) { yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Ingest.TakeMealFromDispenser(TargetIndex.A, driver.pawn)); if (!driver.pawn.Drafted) { yield return(JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.reserveChewSpot(TargetIndex.A, TargetIndex.B)); } Toil gotospot = JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A); if (!Utility.IncapableOfCleaning(driver.pawn)) { TargetIndex filthListIndex = TargetIndex.B; TargetIndex progListIndex = TargetIndex.A; Toil FilthList = JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.makeFilthListToil(filthListIndex); yield return(FilthList); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(filthListIndex, true); yield return(nextTarget); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); yield return(Toils_Goto.GotoThing(filthListIndex, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget).JumpIfOutsideHomeArea(filthListIndex, nextTarget)); // if (driver.job.GetTargetQueue(progListIndex).Count == 0) { driver.job.GetTargetQueue(progListIndex).Add(new IntVec3(0, 0, 0)); } // Toil clean = JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.makeCleanToil(progListIndex, filthListIndex, nextTarget); yield return(clean); yield return(Toils_Jump.Jump(nextTarget)); } yield return(gotospot); yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); }
static IEnumerable <Toil> prepToils(JobDriver_Ingest driver, Toil chewToil) { if ((bool)LeatingFromInventory.GetValue(driver)) { yield return(Toils_Misc.TakeItemFromInventoryToCarrier(driver.pawn, TargetIndex.A)); } else { yield return((Toil)LReserveFood.Invoke(driver, new object[] { })); Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Jump.JumpIf(gotoToPickup, () => driver.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Jump.Jump(chewToil)); yield return(gotoToPickup); yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, driver.pawn)); gotoToPickup = null; } if (driver.job.takeExtraIngestibles > 0) { foreach (Toil toil in (IEnumerable <Toil>)LTakeExtraIngestibles.Invoke(driver, new object[] { })) { yield return(toil); } } if (!driver.pawn.Drafted) { yield return(reserveChewSpot(driver.pawn, TargetIndex.A, TargetIndex.B)); Toil gotospot = gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A); if (!Utility.IncapableOfCleaning(driver.pawn)) { TargetIndex filthListIndex = TargetIndex.B; TargetIndex progIndex = TargetIndex.A; Toil FilthList = new Toil(); FilthList.initAction = delegate() { Job curJob = FilthList.actor.jobs.curJob; // if (curJob.GetTargetQueue(filthListIndex).NullOrEmpty()) { LocalTargetInfo A = curJob.GetTarget(filthListIndex); if (!A.HasThing) { return; } IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num); Utility.AddFilthToQueue(curJob, filthListIndex, l, FilthList.actor); FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(filthListIndex), curJob); curJob.GetTargetQueue(filthListIndex).Add(A); } }; yield return(FilthList); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(filthListIndex, true); yield return(nextTarget); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); yield return(Toils_Goto.GotoThing(filthListIndex, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget).JumpIfOutsideHomeArea(filthListIndex, nextTarget)); // if (driver.job.GetTargetQueue(progIndex).Count == 0) { driver.job.GetTargetQueue(progIndex).Add(new IntVec3(0, 0, 0)); } // Toil clean = new Toil(); clean.initAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth; var progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex); progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness); }; clean.tickAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth; var progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex); IntVec3 iv = progQue[0].Cell; iv.x += 1; iv.y += 1; if (iv.x > filth.def.filth.cleaningWorkToReduceThickness) { filth.ThinFilth(); iv.x = 0; if (filth.Destroyed) { clean.actor.records.Increment(RecordDefOf.MessesCleaned); driver.ReadyForNextToil(); return; } } progQue[0] = iv; }; clean.defaultCompleteMode = ToilCompleteMode.Never; clean.WithEffect(EffecterDefOf.Clean, filthListIndex); clean.WithProgressBar(filthListIndex, delegate() { var q = driver.job.GetTargetQueue(progIndex)[0]; float result = (float)q.Cell.y / q.Cell.z; return(result); } , true, -0.5f); clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); clean.JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget); clean.JumpIfOutsideHomeArea(filthListIndex, nextTarget); clean.FailOnDestroyedOrNull(TargetIndex.A); yield return(clean); yield return(Toils_Jump.Jump(nextTarget)); } yield return(gotospot); } yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); yield break; }
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; })); }
static IEnumerable <Toil> prepToils(JobDriver_Ingest driver, Toil chewToil) { if ((bool)LeatingFromInventory.GetValue(driver)) { yield return(Toils_Misc.TakeItemFromInventoryToCarrier(driver.pawn, TargetIndex.A)); } else { yield return((Toil)LReserveFood.Invoke(driver, new object[] { })); Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Jump.JumpIf(gotoToPickup, () => driver.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Jump.Jump(chewToil)); yield return(gotoToPickup); yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, driver.pawn)); gotoToPickup = null; } if (driver.job.takeExtraIngestibles > 0) { foreach (Toil toil in (IEnumerable <Toil>)LTakeExtraIngestibles.Invoke(driver, new object[] { })) { yield return(toil); } } if (!driver.pawn.Drafted) { yield return(reserveChewSpot(TargetIndex.A, TargetIndex.B)); Toil gotospot = gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A); if (!Utility.IncapableOfCleaning(driver.pawn)) { TargetIndex filthListIndex = TargetIndex.B; TargetIndex progListIndex = TargetIndex.A; Toil FilthList = makeFilthListToil(filthListIndex); yield return(FilthList); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(filthListIndex, true); yield return(nextTarget); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); yield return(Toils_Goto.GotoThing(filthListIndex, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget).JumpIfOutsideHomeArea(filthListIndex, nextTarget)); // if (driver.job.GetTargetQueue(progListIndex).Count == 0) { driver.job.GetTargetQueue(progListIndex).Add(new IntVec3(0, 0, 0)); } // Toil clean = makeCleanToil(progListIndex, filthListIndex, nextTarget); yield return(clean); yield return(Toils_Jump.Jump(nextTarget)); } yield return(gotospot); } yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); yield break; }