public static void Postfix(Pawn pawn, JobGiver_GetFood __instance, ref Job __result) { // Don't need to do this if TryGiveJob was already successful, or if the animal is not starving if (__result != null || !DesperateHungerMod.settings.featureEnabled || pawn.needs.food.CurCategory != HungerCategory.Starving || (!DesperateHungerMod.settings.desperateHumans && !pawn.AnimalOrWildMan())) { return; } // Find something to eat Pawn prey = BestPawnToHuntForPredator(pawn, __instance.forceScanWholeMap); if (prey != null) { Hediff malnutrition = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Malnutrition); float malnutritionLevel = (malnutrition == null) ? 0.0f : malnutrition.Severity; float preyHealth = prey.health.summaryHealth.SummaryHealthPercent; bool preyWounded = preyHealth < 0.99f; // Check if malnourish enough to attack target bool willAttack = (malnutritionLevel > DesperateHungerMod.settings.minimumMalnutritionToHuntHealthyTarget || (preyWounded && malnutritionLevel > DesperateHungerMod.settings.minimumMalnutritionToHuntWoundedTarget)); if (willAttack) { __result = JobMaker.MakeJob(JobDefOf.PredatorHunt, prey); __result.killIncappedTarget = true; } } }
public static void TryGiveJob_PostFix(JobGiver_GetFood __instance, ref Job __result, Pawn pawn) { if (__result?.targetA.Thing != null && (__result?.targetA.Thing as Corpse != null || __result?.targetA.Thing as Pawn != null && ((Pawn)__result?.targetA.Thing).Downed)) { return; } if (__result?.def == JobDefOf.PredatorHunt && pawn?.GetComp <CompVampire>() != null) { __result = new Job(RWBDefOf.RWBVampireBite, __result.targetA); } }
public static void ChowHall(List <Pawn> pawns) { foreach (var pawn in pawns) { if (!pawn.mindState.IsIdle && pawn.CurJobDef != JobDefOf.Ingest) { ThinkResult result = ThinkResult.NoJob; try { var joyGiver = new JobGiver_GetFood(); joyGiver.ResolveReferences(); result = joyGiver.TryIssueJobPackage(pawn, default(JobIssueParams)); } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, pawn.ToStringSafe() + " threw exception while determining job (main)", exception); } if (result.Job != null && result.Job.def != JobDefOf.GotoWander) { pawn.jobs.TryTakeOrderedJob(result.Job); } } } }
internal static Job _TryGiveJob(this JobGiver_GetFood obj, Pawn pawn) { bool desperate = pawn.needs.food.CurCategory == HungerCategory.Starving; Thing foodSource; ThingDef foodDef; //CCL_Log.Message( "JobGiver_GetFood for " + pawn.LabelShort ); // Find an appropriate food source for the pawn if (!FoodUtility.TryFindBestFoodSourceFor( pawn, pawn, desperate, out foodSource, out foodDef, true, true, false, true) ) { return(null); } //CCL_Log.Message( string.Format( "Found {0} ({1}) for {2}", foodSource.ThingID, foodDef.defName, pawn.LabelShort ) ); // Predator-Prey var prey = foodSource as Pawn; if (prey != null) { var hunterJob = new Job(JobDefOf.PredatorHunt, prey); hunterJob.killIncappedTarget = true; return(hunterJob); } // Nutrient Paste Dispensers and Food Synthesizers (Building_AutomatedFactory) if (foodSource is Building) { var hopperNeedsFilling = false; var hopper = (Building)null; if (foodSource is Building_NutrientPasteDispenser) { var NPD = foodSource as Building_NutrientPasteDispenser; if (!NPD.HasEnoughFeedstockInHoppers()) { //CCL_Log.Message( string.Format( "Hopper for {0} needs filling", foodSource.ThingID ) ); hopperNeedsFilling = true; hopper = NPD.AdjacentReachableHopper(pawn); } } if (foodSource is Building_AutomatedFactory) { var FS = foodSource as Building_AutomatedFactory; if (foodDef == null) { //CCL_Log.Message( string.Format( "Hopper for {0} needs filling", foodSource.ThingID ) ); hopperNeedsFilling = true; hopper = FS.AdjacentReachableHopper(pawn); } } if (hopperNeedsFilling) { if (hopper != null) { //CCL_Log.Message( string.Format( "Found hopper {0} for {1} that needs filling", hopper.ThingID, foodSource.ThingID ) ); return(HopperFillFoodJob(pawn, hopper, foodSource)); } else { // Find an alternate source that isn't an NPD or FS //CCL_Log.Message( "Searching for non-machine food for " + pawn.LabelShort ); foodSource = FoodUtility.BestFoodSourceOnMap( pawn, pawn, desperate, FoodPreferability.MealLavish, false, false, false, false, false, false); if (foodSource == null) { return(null); } foodDef = FoodUtility.GetFoodDef(foodSource); } } } //CCL_Log.Message( string.Format( "Giving JobDriver_Ingest to {0} using {1}", pawn.LabelShort, foodSource.ThingID ) ); // Ingest job for found food source var ingestJob = new Job(JobDefOf.Ingest, foodSource); ingestJob.maxNumToCarry = FoodUtility.WillEatStackCountOf(pawn, foodDef); return(ingestJob); }
internal static Job _TryGiveTerminalJob(this JobGiver_GetFood obj, Pawn pawn) { Thing foodInInventory = null; if (pawn.RaceProps.ToolUser) { foodInInventory = FoodUtility.FoodInInventory(pawn, (Pawn)null, FoodPreferability.Awful, FoodPreferability.Lavish, 0.0f); if (foodInInventory != null) { if (pawn.Faction != Faction.OfColony) { return(obj.IngestJob(pawn, foodInInventory)); } var comp = foodInInventory.TryGetComp <CompRottable>(); if ( (comp != null) && (comp.TicksUntilRotAtCurrentTemp < 30000) ) { return(obj.IngestJob(pawn, foodInInventory)); } } } ThingDef foodDef; var bestFoodSource = FoodUtility.BestFoodSourceFor(pawn, pawn, false, out foodDef); if ( (foodInInventory != null) && ( (bestFoodSource == null) || (!pawn.Position.InHorDistOf(bestFoodSource.Position, 50f))) ) { return(obj.IngestJob(pawn, foodInInventory)); } if (bestFoodSource == null) { return((Job)null); } if (bestFoodSource is Building) { Building hopper = null; bool needsFilling = false; if ( (bestFoodSource is Building_NutrientPasteDispenser) && (!((Building_NutrientPasteDispenser)bestFoodSource).HasEnoughFeedstockInHoppers()) ) { hopper = ((Building_NutrientPasteDispenser)bestFoodSource).AdjacentReachableHopper(pawn); needsFilling = true; } else if ( (bestFoodSource is Building_AutomatedFactory) && (((Building_AutomatedFactory)bestFoodSource).BestProduct(FoodSynthesis.IsMeal, FoodSynthesis.SortMeal) == null) ) { hopper = ((Building_AutomatedFactory)bestFoodSource).AdjacentReachableHopper(pawn); needsFilling = true; } if (needsFilling) { if (hopper == null) { bestFoodSource = FoodUtility.BestFoodSpawnedFor(pawn, pawn, true, FoodPreferability.Lavish, true); if (bestFoodSource == null) { return((Job)null); } } else { var hopperSgp = hopper as ISlotGroupParent; var job = HopperFillFoodJob(pawn, hopperSgp, bestFoodSource); if (job != null) { return(job); } bestFoodSource = FoodUtility.BestFoodSpawnedFor(pawn, pawn, true, FoodPreferability.Lavish, true); if (bestFoodSource == null) { return((Job)null); } foodDef = bestFoodSource.def; } } } var prey = bestFoodSource as Pawn; if (prey != null) { var predatorHunt = new Job(JobDefOf.PredatorHunt, prey); predatorHunt.killIncappedTarget = true; return(predatorHunt); } var ingestJob = new Job(JobDefOf.Ingest, bestFoodSource); ingestJob.maxNumToCarry = FoodUtility.WillEatStackCountOf(pawn, foodDef); return(ingestJob); }
internal static Job IngestJob(this JobGiver_GetFood obj, Pawn pawn, Thing food) { var _IngestJob = typeof(JobGiver_GetFood).GetMethod("IngestJob", BindingFlags.Instance | BindingFlags.NonPublic); return((Job)_IngestJob.Invoke(obj, new System.Object[] { pawn, food })); }