internal static string _GetReport(this JobDriver_Ingest obj) { var curJob = obj.pawn.jobs.curJob; var foodSource = obj.TargetThing(FoodInd); ThingDef foodDef = null; if (foodSource is Building_AutomatedFactory) { foodDef = ((Building_AutomatedFactory)foodSource).BestProduct(FoodSynthesis.IsMeal, FoodSynthesis.SortMeal); } else if (foodSource is Building_NutrientPasteDispenser) { foodDef = ((Building_NutrientPasteDispenser)foodSource).DispensableDef; } if (foodDef != null) { return(curJob.def.reportString.Replace("TargetA", foodDef.label)); } var str = curJob.def.reportString; str = !curJob.targetA.HasThing ? str.Replace("TargetA", "AreaLower".Translate()) : str.Replace("TargetA", curJob.targetA.Thing.LabelShort); str = !curJob.targetB.HasThing ? str.Replace("TargetB", "AreaLower".Translate()) : str.Replace("TargetB", curJob.targetB.Thing.LabelShort); str = !curJob.targetC.HasThing ? str.Replace("TargetC", "AreaLower".Translate()) : str.Replace("TargetC", curJob.targetC.Thing.LabelShort); return(str); }
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; }
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 Toil ReserveFoodIfWillEatWholeStack(this JobDriver_Ingest obj) { var resFood = new Toil(); resFood.defaultCompleteMode = ToilCompleteMode.Instant; resFood.initAction = new Action(() => { Thing thing = obj.Food(); if (FoodUtility.WillEatStackCountOf(obj.pawn, thing.def) < thing.stackCount) { return; } if ( (!thing.Spawned) || (!Find.Reservations.CanReserve(obj.pawn, (TargetInfo)thing, 1)) ) { obj.pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } else { Find.Reservations.Reserve(obj.pawn, (TargetInfo)thing, 1); } }); return(resFood); }
public static void GetReportIngestModified(ref string __result, JobDriver_Ingest __instance) { if (__instance.job.GetTarget(TargetIndex.A).Thing is Building_NutrientPasteDispenser && !((Pawn)__instance.job.targetB.Thing is null)) { __result = __instance.job.def.reportString.Replace("TargetA", __instance.job.GetTarget(TargetIndex.A).Thing.def.GetModExtension <NPDModExtension>().customMeal[rand.Next( __instance.job.GetTarget(TargetIndex.A).Thing.def.GetModExtension <NPDModExtension>().customMeal.Count)].label).Replace("TargetB", ((Pawn)__instance.job.targetB.Thing).LabelShort); } }
public static bool PrepareToIngestToils_DispenserPrefix(ref JobDriver_Ingest __instance, ref IEnumerable <Toil> __result) { if (WildManUtility.AnimalOrWildMan(__instance.pawn)) // AnimalOrWildMan used to support Pawnmorpher sentient former humans { __result = PrepareToIngestToils_DispenserOverride(__instance.pawn); return(false); } return(true); }
public override bool ModifyCarriedThingDrawPos( ref Vector3 drawPos, ref bool behind, ref bool flip) { IntVec3 gatherSpotParentCell = ClosestGatherSpotParentCell; return(JobDriver_Ingest.ModifyCarriedThingDrawPosWorker(ref drawPos, ref behind, ref flip, gatherSpotParentCell, pawn)); }
internal static bool _UsingNutrientPasteDispenser(this JobDriver_Ingest obj) { var foodSource = obj.TargetThing(FoodInd); if (foodSource is Building_AutomatedFactory) { // JobGivers will check for OutputToPawnsDirectly return(true); } return(foodSource is Building_NutrientPasteDispenser); }
static bool Prefix(ref IEnumerable <Toil> __result, JobDriver_Ingest __instance, Toil chewToil) { if (!Settings.adv_cleaning_ingest) { return(true); } // __result = prepToils(__instance, chewToil); return(false); }
public static void ApplyHediffIfCorpseEaten(JobDriver_Ingest __instance) { if (__instance.pawn.def.defName == "AA_Erin") { if (__instance.job.GetTarget(TargetIndex.A).Thing is Corpse) { __instance.pawn.health.AddHediff(HediffDef.Named("AA_EatenACorpse")); } } }
static void Postfix(JobDriver_Ingest __instance, ref string __result) { if (__instance.usingNutrientPasteDispenser) { if (__instance.job.GetTarget(TargetIndex.A).Thing is Building_ReplimatTerminal) { __result = __instance.job.def.reportString.Replace("TargetA", "ReplicatedMeal".Translate()); } else { __result = __instance.job.def.reportString.Replace("TargetA", __instance.job.GetTarget(TargetIndex.A).Thing.Label); } } }
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)); }
public static void Postfix(Pawn pawn, TargetIndex ingestibleInd, Toil __result) { JobDriver_Ingest jdi = pawn.jobs.curDriver as JobDriver_Ingest; if (jdi == null) { return; } if (pawn.RaceProps.ToolUser) { LocalTargetInfo food = jdi.job.GetTarget(ingestibleInd); CompDFoodTemperature comp = food.Thing.TryGetComp <CompDFoodTemperature>(); if (comp != null && (comp.PropsTemp.likesHeat || (HotMealsSettings.thawIt && comp.curTemp < 0 && !comp.PropsTemp.okFrozen)) ) { Patch_PrepareToIngestToils_ToolUser_Postfix.carryToils.Add(__result); } } }
internal static Thing Table(this JobDriver_Ingest obj) { return(obj.pawn.CurJob.GetTarget(TableCellInd).Thing); }
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 bool ModifyCarriedThingDrawPos(ref Vector3 drawPos, ref bool behind, ref bool flip) { IntVec3 cell = job.GetTarget(TargetIndex.B).Cell; return(JobDriver_Ingest.ModifyCarriedThingDrawPosWorker(ref drawPos, ref behind, ref flip, cell, pawn)); }
internal static bool IsMeal(this JobDriver_Ingest obj) { return(obj.pawn.CurJob.GetTarget(FoodOrDispenserInd).Thing is Meal); }
internal static Thing Food(this JobDriver_Ingest obj) { return(obj.pawn.CurJob.GetTarget(FoodOrDispenserInd).Thing); }
internal static Thing Alcohol(this JobDriver_Ingest obj) { return(obj.pawn.CurJob.GetTarget(AlcoholInd).Thing); }
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; }
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; })); }