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)); }
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); }
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; }
protected override IEnumerable <Toil> MakeNewToils() { if (this.job.targetA.HasThing) { // ターゲットがThing=水アイテムを摂取する場合 // 水が使用不可能になったらFail ToilFailConditions.FailOnDestroyedNullOrForbidden <JobDriver_DrinkWater>(this, WaterIndex); // 水を取得 if (this.drinkingFromInventory) { // 所持品から取り出す yield return(Toils_Mizu.StartCarryFromInventory(WaterIndex)); } else { // 水の場所まで行く yield return(Toils_Goto.Goto(WaterIndex, PathEndMode.OnCell)); // 水を拾う yield return(Toils_Ingest.PickupIngestible(WaterIndex, this.pawn)); } // 飲む場所を決めてそこへ移動 yield return(Toils_Mizu.StartPathToDrinkSpot(WaterIndex)); // 水を摂取 yield return(Toils_Mizu.Drink(WaterIndex)); // 水の摂取終了(心情、水分、アイテム個数の処理) yield return(Toils_Mizu.FinishDrink(WaterIndex)); if (this.drinkingFromInventory && !this.TargetA.ThingDestroyed) { // 所持品から取り出した&まだ残っている場合は所持品に戻す yield return(Toils_Mizu.AddCarriedThingToInventory()); } } else { // ターゲットがThingではない=水アイテムを摂取しない場合=水地形を利用する場合 // 選んだ水地形が使用不可能or到達不可能になったらFail ToilFailConditions.FailOn <JobDriver_DrinkWater>(this, () => { return(this.job.targetA.Cell.IsForbidden(pawn) || !pawn.CanReach(this.job.targetA.Cell, PathEndMode.ClosestTouch, Danger.Deadly)); }); // 水地形まで移動 yield return(Toils_Goto.GotoCell(WaterIndex, PathEndMode.OnCell)); // 水地形から水分を摂取 yield return(Toils_Mizu.DrinkTerrain(WaterIndex, BaseDrinkTicksFromTerrain)); // 終了 //yield return Toils_Mizu.FinishDrinkTerrain(WaterIndex); } }
/** * Damn enumerators */ static private IEnumerable <Toil> PrepareToIngestToils_DispenserOverride(Pawn pawn) { 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); }
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); }
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)); } }
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)); }
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)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOn(() => PrisonerFoodReservation.isReserved(TargetA.Thing)); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); if (eatingFromInventory) { yield return(Toils_Misc.TakeItemFromInventoryToCarrier(pawn, TargetIndex.A)); } else if (usingNutrientPasteDispenser) { yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell) .FailOnForbidden(TargetIndex.A)); yield return(Toils_Ingest.TakeMealFromDispenser(TargetIndex.A, pawn)); } else { yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch) .FailOnForbidden(TargetIndex.A)); yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, Deliveree)); } var toil = new Toil(); toil.initAction = delegate { var actor = toil.actor; var curJob = actor.jobs.curJob; actor.pather.StartPath(curJob.targetC, PathEndMode.OnCell); }; toil.defaultCompleteMode = ToilCompleteMode.PatherArrival; toil.FailOnDestroyedNullOrForbidden(TargetIndex.B); toil.AddFailCondition(delegate { var pawn = (Pawn)toil.actor.jobs.curJob.targetB.Thing; return(!pawn.IsPrisonerOfColony || !pawn.guest.CanBeBroughtFood); }); yield return(toil); yield return(new Toil { initAction = delegate { Thing thing; pawn.carryTracker.TryDropCarriedThing(toil.actor.jobs.curJob.targetC.Cell, ThingPlaceMode.Direct, out thing, null); PrisonerFoodReservation.reserve(thing, (Pawn)toil.actor.jobs.curJob.targetB.Thing); }, defaultCompleteMode = ToilCompleteMode.Instant }); }
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)); }
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() { this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); if (HasChair) { this.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable); } if (HasDrink) { this.FailOnDestroyedNullOrForbidden(TargetIndex.C); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.C)); yield return(Toils_Haul.StartCarryThing(TargetIndex.C, false, false, false)); } yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); Toil chew = new Toil(); chew.tickAction = delegate { pawn.rotationTracker.FaceCell(ClosestGatherSpotParentCell); pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.GoToNextToil, 1f); if (pawn.IsHashIntervalTick(100)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Note); } }; chew.handlingFacing = true; chew.defaultCompleteMode = ToilCompleteMode.Delay; chew.defaultDuration = job.def.joyDuration; chew.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(pawn); }); chew.socialMode = RandomSocialMode.SuperActive; Toils_Ingest.AddIngestionEffects(chew, pawn, TargetIndex.C, TargetIndex.None); yield return(chew); if (HasDrink) { yield return(Toils_Ingest.FinalizeIngest(pawn, TargetIndex.C)); } yield break; }
protected override IEnumerable <Toil> MakeNewToils() { yield return(this.ReserveFood()); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, this.pawn)); Toil empty = new Toil(); yield return(Toils_Jump.JumpIf(empty, delegate() { LocalTargetInfo food = this.job.GetTarget(TargetIndex.A); CompDFoodTemperature comp = food.Thing.TryGetComp <CompDFoodTemperature>(); if (comp == null) { return true; } if (comp.PropsTemp.likesHeat) { return comp.curTemp >= comp.targetCookingTemp; } return comp.curTemp > 0; })); if (!HotMealsSettings.multipleHeat) { yield return(Toils_Reserve.Reserve(TargetIndex.C)); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.C)); yield return(Toils_HeatMeal.HeatMeal().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.C, PathEndMode.InteractionCell)); yield return(Toils_Reserve.Release(TargetIndex.C)); } else { yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.Touch).FailOnDestroyedOrNull(TargetIndex.C)); yield return(Toils_HeatMeal.HeatMeal().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.C, PathEndMode.Touch)); } yield return(empty); 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)); }
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() { //Toil definitions AddFinishAction(delegate { if (Cocoon != null) { Cocoon.CurrentDrinker = null; } }); var gotoBody = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); gotoBody.AddPreInitAction(delegate { Cocoon.CurrentDrinker = pawn as PawnWebSpinner; if (Victim != null && (Victim?.Faction != Faction.OfPlayerSilentFail || Victim.Dead || notifiedPlayer)) { return; } notifiedPlayer = true; var sound = Victim?.Dead ?? false ? MessageTypeDefOf.NeutralEvent : MessageTypeDefOf.ThreatBig; Messages.Message("ROM_SpiderEatingColonist".Translate(pawn.Label, Victim?.Label), sound); }); //Toil executions yield return(gotoBody); yield return(Liquify()); var durationMultiplier = 1f / pawn.GetStatValue(StatDefOf.EatingSpeed); yield return(DrinkCorpse(durationMultiplier)); yield return(Toils_Ingest.FinalizeIngest(pawn, TargetIndex.B)); yield return(Toils_Jump.JumpIf(gotoBody, () => pawn.needs.food.CurLevelPercentage < 0.9f) .FailOnDestroyedNullOrForbidden(TargetIndex.B)); }
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)); }
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)); }
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)); }
public static Toil FinalizeIngested(this Toils_Ingest Ingest, Pawn ingester, TargetIndex ingestibleInd, BodyPartDef targetPart) { Toil toil = new Toil(); toil.initAction = delegate() { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; Thing thing = curJob.GetTarget(ingestibleInd).Thing; if (ingester.needs.mood != null && thing.def.IsNutritionGivingIngestible && thing.def.ingestible.chairSearchRadius > 10f) { if (!(ingester.Position + ingester.Rotation.FacingCell).HasEatSurface(actor.Map) && ingester.GetPosture() == PawnPosture.Standing && !ingester.IsWildMan()) { ingester.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.AteWithoutTable, null); } Room room = ingester.GetRoom(RegionType.Set_Passable); if (room != null) { int scoreStageIndex = RoomStatDefOf.Impressiveness.GetScoreStageIndex(room.GetStat(RoomStatDefOf.Impressiveness)); if (ThoughtDefOf.AteInImpressiveDiningRoom.stages[scoreStageIndex] != null) { ingester.needs.mood.thoughts.memories.TryGainMemory(ThoughtMaker.MakeThought(ThoughtDefOf.AteInImpressiveDiningRoom, scoreStageIndex), null); } } } float num = ingester.needs.food.NutritionWanted; if (curJob.overeat) { num = Mathf.Max(num, 0.75f); } float num2 = thing.Ingested(ingester, num); if (!ingester.Dead) { ingester.needs.food.CurLevel += num2; } ingester.records.AddTo(RecordDefOf.NutritionEaten, num2); }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
/// <summary> /// gets the Feeds toils. /// </summary> /// <returns></returns> protected virtual IEnumerable <Toil> FeedToils() { var toil = new Toil(); toil.initAction = delegate { feedNutritionLeft = RequiredNutritionPerFeed(Animal); }; toil.defaultCompleteMode = ToilCompleteMode.Instant; yield return(toil); Toil gotoAnimal = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoAnimal); yield return(StartFeedAnimal(TargetIndex.A)); yield return(Toils_Ingest.FinalizeIngest(Animal, TargetIndex.B)); yield return(Toils_General.PutCarriedThingInInventory()); yield return(Toils_General.ClearTarget(TargetIndex.B)); yield return(Toils_Jump.JumpIf(gotoAnimal, () => feedNutritionLeft > 0f)); }
protected override IEnumerable <Toil> MakeNewToils() { // 水が使用不可能になったらFail ToilFailConditions.FailOnDestroyedNullOrForbidden <JobDriver_WaterDeliver>(this, WaterIndex); if (!this.pawn.CanReserveAndReach(this.TargetA, PathEndMode.Touch, Danger.Deadly, 1, this.job.count)) { // 水を予約できなかったら終了 this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable); yield break; } // 予約する if (!this.pawn.Map.reservationManager.ReservedBy(this.TargetA.Thing, pawn)) { yield return(Toils_Reserve.Reserve(WaterIndex, 1, this.job.count, null)); } if (this.drinkingFromInventory) { // 水を持ち物から取り出す yield return(Toils_Mizu.StartCarryFromInventory(WaterIndex)); } else { // 水の場所まで行く yield return(Toils_Goto.Goto(WaterIndex, PathEndMode.OnCell)); // 水を拾う yield return(Toils_Ingest.PickupIngestible(WaterIndex, this.pawn)); } // スポットまで移動する yield return(Toils_Goto.GotoCell(this.TargetC.Cell, PathEndMode.OnCell)); // 置いて囚人に予約させる yield return(Toils_Mizu.DropCarriedThing(PrisonerIndex, DropSpotIndex)); }
static IEnumerable <Toil> _MakeToils(this JobDriver_SocialRelax driver) { //driver.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); driver.AddEndCondition(delegate { LocalTargetInfo target = driver.GetActor().jobs.curJob.GetTarget(TargetIndex.A); Thing thing = target.Thing; if (thing == null && target.IsValid || thing is Filth) { return(JobCondition.Ongoing); } if (thing == null || !thing.Spawned || thing.Map != driver.GetActor().Map) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); if (driver.HasChair()) { driver.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable); } if (driver.HasDrink()) { driver.FailOnDestroyedNullOrForbidden(TargetIndex.C); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.C)); yield return(Toils_Haul.StartCarryThing(TargetIndex.C, false, false, false)); } //cleaning patch Toil GoToRelaxPlace = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell); if (Settings.adv_cleaning_ingest && !Utility.IncapableOfCleaning(driver.pawn)) { 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); 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(GoToRelaxPlace, () => driver.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(GoToRelaxPlace, () => driver.job.GetTargetQueue(TargetIndex.A).NullOrEmpty())); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList).JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList)); // driver.job.GetTargetQueue(TargetIndex.B).Add(new IntVec3(0, 0, 0)); Toil clean = new Toil(); clean.initAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth; var progQue = clean.actor.jobs.curJob.GetTargetQueue(TargetIndex.B); progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness); }; clean.tickAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth; var progQue = clean.actor.jobs.curJob.GetTargetQueue(TargetIndex.B); 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, TargetIndex.A); clean.WithProgressBar(TargetIndex.A, delegate() { var q = driver.job.GetTargetQueue(TargetIndex.B)[0]; float result = (float)q.Cell.y / q.Cell.z; return(result); } , 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(GoToRelaxPlace); // float joyoffset; ThingDef def = driver.job.GetTarget(TargetIndex.C).HasThing ? driver.job.GetTarget(TargetIndex.C).Thing.def : null; if (Settings.social_relax_economy && def != null && def.IsIngestible) { joyoffset = def.ingestible.joy * driver.pawn.needs.joy.tolerances.JoyFactorFromTolerance(def.ingestible.JoyKind); //minimum amount of time for action to perform float baseoffset = Mathf.Max(0.36f / 2500f * def.ingestible.baseIngestTicks, 0.36f / 2500f * 60f * 4f); float expected = 1f - driver.pawn.needs.joy.CurLevel - joyoffset; if (expected < baseoffset) { float expected2 = 1f - driver.pawn.needs.joy.CurLevel - baseoffset; if (expected2 < 0f) { joyoffset = 0f; } else if (expected2 < baseoffset) { joyoffset = baseoffset - expected2; } else { joyoffset += expected - baseoffset; } } } else { joyoffset = 0f; } Toil toil = new Toil(); toil.tickAction = delegate() { driver.pawn.rotationTracker.FaceCell(driver.ClosestGatherSpotParentCell()); driver.pawn.GainComfortFromCellIfPossible(false); JoyTickCheckEndOffset(driver.pawn, joyoffset, JoyTickFullJoyAction.GoToNextToil); }; toil.handlingFacing = true; toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = driver.job.def.joyDuration; toil.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(driver.pawn); }); toil.socialMode = RandomSocialMode.SuperActive; Toils_Ingest.AddIngestionEffects(toil, driver.pawn, TargetIndex.C, TargetIndex.None); yield return(toil); if (driver.HasDrink()) { yield return(Toils_Ingest.FinalizeIngest(driver.pawn, TargetIndex.C)); } yield break; }
protected override IEnumerable <Toil> MakeNewToils() { this.EndOnDespawnedOrNull(GatherSpotParentInd); if (HasChair) { this.EndOnDespawnedOrNull(ChairOrSpotInd); } this.FailOnDestroyedNullOrForbidden(MateInd); yield return(Toils_Goto.GotoThing(MateInd, PathEndMode.OnCell) .FailOnSomeonePhysicallyInteracting(MateInd)); yield return(Toils_Haul.StartCarryThing(MateInd)); yield return(Toils_Goto.GotoCell(ChairOrSpotInd, PathEndMode.OnCell)); var chew = new Toil { tickAction = delegate { pawn.rotationTracker.FaceCell(ClosestGatherSpotParentCell); pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.GoToNextToil); }, handlingFacing = true, defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = job.def.joyDuration, socialMode = RandomSocialMode.SuperActive }; chew.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(pawn); }); Toils_Ingest.AddIngestionEffects(chew, pawn, MateInd, TargetIndex.None); yield return(chew); Toil toilDrinkMate = new Toil(); toilDrinkMate.initAction = () => { var ingester = pawn; var actor = toilDrinkMate.actor; var curJob = actor.jobs.curJob; var thing = curJob.GetTarget(MateInd).Thing; if (ingester.needs.mood != null && thing.def.IsNutritionGivingIngestible && thing.def.ingestible.chairSearchRadius > 10.0) { var room = ingester.GetRoom(); if (room != null) { var scoreStageIndex = RoomStatDefOf.Impressiveness.GetScoreStageIndex(room.GetStat(RoomStatDefOf.Impressiveness)); if (ThoughtDefOf.AteInImpressiveDiningRoom.stages[scoreStageIndex] != null) { ingester.needs.mood.thoughts.memories.TryGainMemory(ThoughtMaker.MakeThought(ThoughtDefOf.AteInImpressiveDiningRoom, scoreStageIndex)); } } } var num2 = thing.Ingested(ingester, ingester.needs.food.NutritionWanted); if (!ingester.Dead) { ingester.needs.food.CurLevel += num2; } ingester.records.AddTo(RecordDefOf.NutritionEaten, num2); }; toilDrinkMate.defaultCompleteMode = ToilCompleteMode.Instant; yield return(toilDrinkMate); }
protected override IEnumerable <Toil> MakeNewToils() { // ターゲットがThing=水アイテムを摂取する場合 // 水(食事)が使用不可能になったらFail ToilFailConditions.FailOnDestroyedNullOrForbidden(this, WaterIndex); ToilFailConditions.FailOn(this, () => { if (this.Patient == null) { return(true); } // 患者がベッドに入ってなかったらFail if (!this.Patient.InBed()) { return(true); } // 到達不能になっていたらFail if (!this.pawn.CanReach(this.Patient, PathEndMode.ClosestTouch, Danger.Deadly)) { return(true); } return(false); }); // 水が予約出来ない状態なら中断 if (!ReservationUtility.CanReserveAndReach(this.pawn, this.TargetA, PathEndMode.Touch, Danger.Deadly, 1, this.job.count, null, false)) { this.GetActor().jobs.EndCurrentJob(JobCondition.Incompletable); yield break; } // 水を予約する if (!this.pawn.Map.reservationManager.ReservedBy(this.TargetA.Thing, pawn)) { yield return(Toils_Reserve.Reserve(WaterIndex, 1, this.job.count, null)); } if (this.getItemFromInventory) { // 水を持ち物から取り出す yield return(Toils_Mizu.StartCarryFromInventory(WaterIndex)); } else { // 水の場所まで行く yield return(Toils_Goto.Goto(WaterIndex, PathEndMode.OnCell)); // 水を拾う yield return(Toils_Ingest.PickupIngestible(WaterIndex, this.pawn)); } // 患者のもとへ移動 yield return(Toils_Goto.Goto(PatientIndex, PathEndMode.Touch)); // 水を飲ませる yield return(Toils_Mizu.FeedToPatient(WaterIndex, PatientIndex)); // 水の摂取終了(心情、食事の処理) yield return(Toils_Mizu.FinishDrinkPatient(WaterIndex, PatientIndex)); if (this.getItemFromInventory && !this.TargetA.ThingDestroyed) { // 所持品から取り出した&まだ残っている場合は所持品に戻す yield return(Toils_Mizu.AddCarriedThingToInventory()); } }
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; }
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; }