public static Toil JumpToCarryToNextContainerIfPossible(Toil carryToContainerToil, TargetIndex primaryTargetInd) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; if (actor.carryTracker.CarriedThing == null) { return; } if (curJob.targetQueueB != null && curJob.targetQueueB.Count > 0) { Thing primaryTarget = curJob.GetTarget(primaryTargetInd).Thing; bool hasSpareItems = actor.carryTracker.CarriedThing.stackCount > GenConstruct.AmountNeededByOf((IConstructible)primaryTarget, actor.carryTracker.CarriedThing.def); Predicate <Thing> validator = (Thing th) => GenConstruct.CanConstruct(th, actor, false, false) && ((IConstructible)th).MaterialsNeeded().Any((ThingDefCountClass need) => need.thingDef == actor.carryTracker.CarriedThing.def) && (th == primaryTarget || hasSpareItems); Thing nextTarget = GenClosest.ClosestThing_Global_Reachable(actor.Position, actor.Map, from targ in curJob.targetQueueB select targ.Thing, PathEndMode.Touch, TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), 99999f, validator, null); if (nextTarget != null) { curJob.targetQueueB.RemoveAll((LocalTargetInfo targ) => targ.Thing == nextTarget); curJob.targetB = nextTarget; actor.jobs.curDriver.JumpToToil(carryToContainerToil); } } }; return(toil); }
public static void BestIngestItem_Postfix(Pawn pawn, ref Thing __result) { float value = Rand.ValueSeeded(pawn.thingIDNumber ^ 125); if (value < 0.2f) { return; } else if (value < 0.6f && __result != null && __result.def == CoffeeAndTeaDefOf.SyrTea) { bool predicate(Thing t) => CanIngestForJoy(pawn, t); Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerThings.ThingsOfDef(CoffeeAndTeaDefOf.SyrCoffee), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, predicate, null); if (thing != null) { __result = thing; } } else if (value >= 0.6f && __result != null && __result.def == CoffeeAndTeaDefOf.SyrCoffee) { bool predicate(Thing t) => CanIngestForJoy(pawn, t); Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerThings.ThingsOfDef(CoffeeAndTeaDefOf.SyrTea), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, predicate, null); if (thing != null) { __result = thing; } } }
public static Thing FindNextInsulin(Pawn pawn) { Thing insulin = FindInInventory(pawn.inventory.innerContainer); if (insulin != null) { return(insulin); } List <Thing> candidates = new List <Thing>(); candidates.AddRange(pawn.Map.listerThings.ThingsOfDef(TypeGetter.ThingDef(EThingDef.Insulin))); for (int i = 0; i < candidates.Count; i++) { Thing thing = candidates[i]; if (thing.IsForbidden(pawn)) { candidates.Remove(thing); i--; } } Log.Message("Count: " + candidates.Count); if (candidates.Count == 0) { return(null); } insulin = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, candidates, PathEndMode.OnCell, TraverseParms.For(pawn)); return(insulin); }
public static Thing FindBestMedicine(Pawn healer, Pawn patient) { Thing result; if (patient.playerSettings == null || patient.playerSettings.medCare <= MedicalCareCategory.NoMeds) { result = null; } else if (Medicine.GetMedicineCountToFullyHeal(patient) <= 0) { result = null; } else { Predicate <Thing> predicate = (Thing m) => !m.IsForbidden(healer) && patient.playerSettings.medCare.AllowsMedicine(m.def) && healer.CanReserve(m, 10, 1, null, false); Func <Thing, float> priorityGetter = (Thing t) => t.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null); IntVec3 position = patient.Position; Map map = patient.Map; List <Thing> searchSet = patient.Map.listerThings.ThingsInGroup(ThingRequestGroup.Medicine); PathEndMode peMode = PathEndMode.ClosestTouch; TraverseParms traverseParams = TraverseParms.For(healer, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; result = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, priorityGetter); } return(result); }
private Building_InternalStorage FindBestStorage(Pawn p, Thing book) { bool predicate(Thing m) => !m.IsForbidden(p) && p.CanReserveNew(m) && ((Building_InternalStorage)m).Accepts(book); float priorityGetter(Thing t) { var result = 0f; result += (float)((IStoreSettingsParent)t).GetStoreSettings().Priority; if (t is Building_InternalStorage bS && bS.TryGetInnerInteractableThingOwner()?.Count > 0) { result -= bS.TryGetInnerInteractableThingOwner().Count; } return(result); } IntVec3 position = book.Position; Map map = book.Map; List <Thing> searchSet = book.Map.listerThings.AllThings.FindAll(x => x is Building_InternalStorage); PathEndMode peMode = PathEndMode.ClosestTouch; var traverseParams = TraverseParms.For(p, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; return((Building_InternalStorage)GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, priorityGetter)); }
public override bool TryMakePreToilReservations(bool errorOnFailed) { if (Prefs.DevMode) { Log.Message("JobDriver_Slaughter_OnSpot: try to reserve!"); } List <Thing> list = new List <Thing>(); foreach (Building bld in pawn.Map.listerBuildings.AllBuildingsColonistOfDef(ThingDef.Named("AnimalHarvestingSpot"))) { list.Add(bld as Thing); } Pawn target = TargetA.Thing as Pawn; spot = GenClosest.ClosestThing_Global_Reachable( target.Position, target.Map, list, PathEndMode.Touch, TraverseParms.For(target, Danger.Deadly, TraverseMode.ByPawn, false), 999f, null, null); if (spot == null && CanTarget(target)) { if (Prefs.DevMode) { Log.Message("JobDriver_Slaughter_OnSpot: spot is " + spot); } return(pawn.Reserve(job.GetTarget(TargetIndex.A), job, 1, -1, null)); } if (Prefs.DevMode) { Log.Message("JobDriver_Slaughter_OnSpot: spot is not found or unreachable"); } spot = null; return(true); }
private Building_InternalStorage FindBestStorage(Pawn p, ThingBook book) { bool Predicate(Thing m) { return(!m.IsForbidden(p) && p.CanReserveNew(m) && ((Building_InternalStorage)m).Accepts(book)); } float PriorityGetter(Thing t) { var result = 0f; result += (float)((IStoreSettingsParent)t).GetStoreSettings().Priority; if (t is Building_InternalStorage bS && bS.TryGetInnerInteractableThingOwner()?.Count > 0) { result -= bS.TryGetInnerInteractableThingOwner().Count; } return(result); } var position = book.Position; var map = book.Map; var searchSet = book.Map.listerThings.AllThings.FindAll(x => x is Building_InternalStorage); var peMode = PathEndMode.ClosestTouch; var traverseParams = TraverseParms.For(p); var validator = (Predicate <Thing>)Predicate; return((Building_InternalStorage)GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, PriorityGetter)); }
protected virtual Thing BestIngestItem(Pawn pawn, Predicate <Thing> extraValidator) { Predicate <Thing> predicate = delegate(Thing t) { if (!CanIngestForJoy(pawn, t)) { return(false); } return((extraValidator == null || extraValidator(t)) ? true : false); }; ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int i = 0; i < innerContainer.Count; i++) { if (SearchSetWouldInclude(innerContainer[i]) && predicate(innerContainer[i])) { return(innerContainer[i]); } } tmpCandidates.Clear(); GetSearchSet(pawn, tmpCandidates); if (tmpCandidates.Count == 0) { return(null); } Thing result = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, tmpCandidates, PathEndMode.OnCell, TraverseParms.For(pawn), 9999f, predicate); tmpCandidates.Clear(); return(result); }
protected override Job TryGiveJob(Pawn pawn) { Predicate <Thing> validator = delegate(Thing t) { if (t.IsForbidden(pawn)) { return(false); } if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, forced: false)) { return(false); } if (pawn.carryTracker.MaxStackSpaceEver(t.def) <= 0) { return(false); } if (!StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(t), pawn.Faction, out IntVec3 _)) { return(false); } return(true); }; Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn), 9999f, validator); if (thing != null) { return(HaulAIUtility.HaulToStorageJob(pawn, thing)); } return(null); }
private Thing FindIngredient(Pawn pawn, string thirdItem, Building_ItemProcessor building_processor) { if (building_processor.compItemProcessor.Props.isCategoryBuilding) { Predicate <Thing> predicate = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x, 1, 1, null, false); IntVec3 position = pawn.Position; Map map = pawn.Map; List <Thing> searchSet = new List <Thing>(); foreach (ThingDef thingDef in ThingCategoryDef.Named(thirdItem).childThingDefs) { if (!(DefDatabase <CombinationDef> .GetNamed(building_processor.thisRecipe).disallowedThingDefs != null && DefDatabase <CombinationDef> .GetNamed(building_processor.thisRecipe).disallowedThingDefs.Contains(thingDef.defName))) { searchSet.AddRange(pawn.Map.listerThings.ThingsOfDef(thingDef)); } } TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; PathEndMode peMode = PathEndMode.ClosestTouch; return(GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, searchSet, peMode, traverseParams, 9999f, validator, null)); } else { Predicate <Thing> predicate = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x, 1, 1, null, false); IntVec3 position = pawn.Position; Map map = pawn.Map; ThingRequest thingReq = ThingRequest.ForDef(ThingDef.Named(thirdItem)); PathEndMode peMode = PathEndMode.ClosestTouch; TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; return(GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, 9999f, validator, null, 0, -1, false, RegionType.Set_Passable, false)); } }
private Thing FindBestGame(Pawn pawn, bool inBed, IntVec3 partySpot) { JoyGiver_InteractBuilding.tmpCandidates.Clear(); this.GetSearchSet(pawn, JoyGiver_InteractBuilding.tmpCandidates); if (JoyGiver_InteractBuilding.tmpCandidates.Count == 0) { return(null); } Predicate <Thing> predicate = (Thing t) => this.CanInteractWith(pawn, t, inBed); if (partySpot.IsValid) { Predicate <Thing> oldValidator = predicate; predicate = ((Thing x) => PartyUtility.InPartyArea(x.Position, partySpot, pawn.Map) && oldValidator(x)); } IntVec3 position = pawn.Position; Map map = pawn.Map; List <Thing> searchSet = JoyGiver_InteractBuilding.tmpCandidates; PathEndMode peMode = PathEndMode.OnCell; TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; Thing result = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, null); JoyGiver_InteractBuilding.tmpCandidates.Clear(); return(result); }
private static void Postfix(FloatMenuOption __instance, bool colonistOrdering, FloatMenu floatMenu) { if (__instance.Label == "GoDown".Translate() || __instance.Label == "GoUP".Translate()) { if (Find.Selector.SelectedObjects.Where(x => x is Pawn).Count() > 1) { Thing thing; foreach (var pawn in Find.Selector.SelectedObjects.Where(x => x is Pawn)) { if (__instance.Label == "GoDown".Translate()) { thing = GenClosest.ClosestThing_Global_Reachable(UI.MouseMapPosition().ToIntVec3() , ((Pawn)pawn).Map, ((Pawn)pawn).Map.listerThings.AllThings .Where(x => x is Building_StairsDown), PathEndMode.OnCell, TraverseParms.For(TraverseMode.ByPawn, Danger.Deadly, false), 9999f); Job job = JobMaker.MakeJob(ZLevelsDefOf.ZL_GoToStairs, thing); ((Pawn)pawn).jobs.StartJob(job, JobCondition.InterruptForced); } else { thing = GenClosest.ClosestThing_Global_Reachable(UI.MouseMapPosition().ToIntVec3() , ((Pawn)pawn).Map, ((Pawn)pawn).Map.listerThings.AllThings .Where(x => x is Building_StairsUp), PathEndMode.OnCell, TraverseParms.For(TraverseMode.ByPawn, Danger.Deadly, false), 9999f); Job job = JobMaker.MakeJob(ZLevelsDefOf.ZL_GoToStairs, thing); ((Pawn)pawn).jobs.StartJob(job, JobCondition.InterruptForced); } } ZLogger.Message("Choosen"); } } }
private static bool TryFindIngestibleToNurse(IntVec3 center, Pawn ingester, out Thing ingestible) { if (ingester.IsTeetotaler()) { ingestible = null; return(false); } if (ingester.drugs == null) { ingestible = null; return(false); } var thingList = ingester.Map.listerThings.ThingsOfDef(MateDef); MatesMod.Log("thingList.Count() = " + thingList.Count); if (thingList.Count > 0) { bool Validator(Thing t) => ingester.CanReserve((LocalTargetInfo)t) && !t.IsForbidden(ingester); ingestible = GenClosest.ClosestThing_Global_Reachable(center, ingester.Map, thingList, PathEndMode.OnCell, TraverseParms.For(ingester), 40f, Validator); if (ingestible != null) { return(true); } } ingestible = null; return(false); }
public static void Listener(Pawn healer, Pawn patient, ref Thing __result) { try { //On ne soccupe que des patient étant des androids /*if (!) * return true;*/ if (Settings.androidsCanUseOrganicMedicine) { return; } bool patientIsAndroid = Utils.ExceptionAndroidList.Contains(patient.def.defName) || patient.IsCyberAnimal(); if (patient.playerSettings == null || patient.playerSettings.medCare <= MedicalCareCategory.NoMeds) { __result = null; return; } if (Medicine.GetMedicineCountToFullyHeal(patient) <= 0) { __result = null; return; } Predicate <Thing> predicate; //COmpatibilité avec pharmacist, le medoc renvoyé doit avoir une quantitée de soin inferieur ou egal à celui renvoyé par les appels précédents float medicalPotency = 0; if (__result != null) { medicalPotency = __result.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null); } if (patientIsAndroid) { predicate = (Thing m) => Utils.ExceptionNanoKits.Contains(m.def.defName) && m.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null) <= medicalPotency && !m.IsForbidden(healer) && patient.playerSettings.medCare.AllowsMedicine(m.def) && healer.CanReserve(m, 10, 1, null, false); } else { predicate = (Thing m) => !Utils.ExceptionNanoKits.Contains(m.def.defName) && m.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null) <= medicalPotency && !m.IsForbidden(healer) && !m.IsForbidden(healer) && patient.playerSettings.medCare.AllowsMedicine(m.def) && healer.CanReserve(m, 10, 1, null, false); } Func <Thing, float> priorityGetter = (Thing t) => t.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null); IntVec3 position = patient.Position; Map map = patient.Map; List <Thing> searchSet = patient.Map.listerThings.ThingsInGroup(ThingRequestGroup.Medicine); PathEndMode peMode = PathEndMode.ClosestTouch; TraverseParms traverseParams = TraverseParms.For(healer, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; __result = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, priorityGetter); } catch (Exception e) { Log.Message("[ATPP] HealthAIUtility.FindBestMedicine(Error) : " + e.Message + " - " + e.StackTrace); } }
private Building_Grave FindBestGrave(Pawn p, Corpse corpse) { Predicate <Thing> predicate = delegate(Thing m) { if (!m.IsForbidden(p) && p.CanReserveNew(m)) { if (!((Building_Grave)m).Accepts(corpse)) { return(false); } return(true); } return(false); }; if (corpse.InnerPawn.ownership != null && corpse.InnerPawn.ownership.AssignedGrave != null) { Building_Grave assignedGrave = corpse.InnerPawn.ownership.AssignedGrave; if (predicate(assignedGrave) && p.Map.reachability.CanReach(corpse.Position, assignedGrave, PathEndMode.ClosestTouch, TraverseParms.For(p, Danger.Deadly, TraverseMode.ByPawn, false))) { return(assignedGrave); } } Func <Thing, float> priorityGetter = (Thing t) => (float)(int)((IStoreSettingsParent)t).GetStoreSettings().Priority; IntVec3 position = corpse.Position; Map map = corpse.Map; List <Thing> searchSet = corpse.Map.listerThings.ThingsInGroup(ThingRequestGroup.Grave); PathEndMode peMode = PathEndMode.ClosestTouch; TraverseParms traverseParams = TraverseParms.For(p, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; return((Building_Grave)GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, priorityGetter)); }
protected override Job TryGiveTerminalJob(Pawn pawn) { WorkGiver_Scanner scanner = new WorkGiver_Shear(); TargetInfo targetInfo = TargetInfo.Invalid; Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = Find.ListerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThingReachable(pawn.Position, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, scanner.LocalRegionsToScanFirst, enumerable != null); } if (thing != null) { targetInfo = thing; //workGiver_Scanner = scanner; } if (targetInfo.HasThing) { WorkGiver_Shear shearer = new WorkGiver_Shear(); return(shearer.JobOnThing(pawn, targetInfo.Thing)); } return(null); }
public static Toil CheckDuplicates(Toil jumpToil, TargetIndex CarrierInd, TargetIndex HaulableInd) { Toil toil = new Toil(); toil.initAction = () => { IntVec3 storeCell = IntVec3.Invalid; Pawn actor = toil.GetActor(); TargetInfo target = toil.actor.jobs.curJob.GetTarget(HaulableInd); if (target.Thing.def.stackLimit <= 1) { return; } List <TargetInfo> targetQueue = toil.actor.jobs.curJob.GetTargetQueue(HaulableInd); if (!targetQueue.NullOrEmpty() && target.Thing.def.defName == targetQueue.First().Thing.def.defName) { toil.actor.jobs.curJob.SetTarget(HaulableInd, targetQueue.First()); Find.Reservations.Reserve(actor, targetQueue.First()); targetQueue.RemoveAt(0); toil.actor.jobs.curDriver.JumpToToil(jumpToil); return; } Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; Apparel_Backpack backpack = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Apparel_Backpack; if (cart == null && backpack == null) { Log.Error(actor.LabelCap + " Report: Don't have Carrier"); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); return; } int curItemCount = (cart != null ? cart.storage.Count : backpack.slotsComp.slots.Count) + targetQueue.Count; int curItemStack = (cart != null ? cart.storage.TotalStackCount : backpack.slotsComp.slots.TotalStackCount) + targetQueue.Sum(item => item.Thing.stackCount); int maxItem = cart != null ? cart.MaxItem : backpack.MaxItem; int maxStack = cart != null ? cart.MaxStack : backpack.MaxStack; if (curItemCount >= maxItem || curItemStack >= maxStack) { return; } //Check target's nearby Thing thing = GenClosest.ClosestThing_Global_Reachable(actor.Position, ListerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.Touch, TraverseParms.For(actor, Danger.Some), NearbyCell, item => !targetQueue.Contains(item) && item.def.defName == target.Thing.def.defName && !item.IsBurning() && Find.Reservations.CanReserve(actor, item)); if (thing != null) { toil.actor.jobs.curJob.SetTarget(HaulableInd, thing); Find.Reservations.Reserve(actor, thing); toil.actor.jobs.curDriver.JumpToToil(jumpToil); } }; return(toil); }
public static Thing FindBestMedicine(Pawn healer, Pawn patient) { if (patient.playerSettings == null || (int)patient.playerSettings.medCare <= 1) { return(null); } if (Medicine.GetMedicineCountToFullyHeal(patient) <= 0) { return(null); } Predicate <Thing> predicate = delegate(Thing m) { if (m.IsForbidden(healer) || !patient.playerSettings.medCare.AllowsMedicine(m.def) || !healer.CanReserve(m, 10, 1)) { return(false); } return(true); }; Func <Thing, float> priorityGetter = (Thing t) => t.def.GetStatValueAbstract(StatDefOf.MedicalPotency); IntVec3 position = patient.Position; Map map = patient.Map; List <Thing> searchSet = patient.Map.listerThings.ThingsInGroup(ThingRequestGroup.Medicine); PathEndMode peMode = PathEndMode.ClosestTouch; TraverseParms traverseParams = TraverseParms.For(healer); Predicate <Thing> validator = predicate; return(GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, priorityGetter)); }
protected virtual Thing BestIngestItem(Pawn pawn, Predicate <Thing> extraValidator) { Predicate <Thing> predicate = (Thing t) => this.CanIngestForJoy(pawn, t) && (extraValidator == null || extraValidator(t)); ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int i = 0; i < innerContainer.Count; i++) { if (this.SearchSetWouldInclude(innerContainer[i]) && predicate(innerContainer[i])) { return(innerContainer[i]); } } JoyGiver_Ingest.tmpCandidates.Clear(); this.GetSearchSet(pawn, JoyGiver_Ingest.tmpCandidates); if (JoyGiver_Ingest.tmpCandidates.Count == 0) { return(null); } IntVec3 position = pawn.Position; Map map = pawn.Map; List <Thing> searchSet = JoyGiver_Ingest.tmpCandidates; PathEndMode peMode = PathEndMode.OnCell; TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; Thing result = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator, null); JoyGiver_Ingest.tmpCandidates.Clear(); return(result); }
protected override IntVec3 GetWanderRoot(Pawn pawn) { // Start by finding filth to wander around var eligibleFilth = pawn.Map.listerFilthInHomeArea.FilthInHomeArea .Where(x => x is Filth filth && filth.TicksSinceThickened > 600).ToList(); var closestFilth = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, eligibleFilth, PathEndMode.Touch, TraverseParms.For(pawn, maxDanger)); if (closestFilth != null) { return(closestFilth.Position); } // If not, find some place to hang out var randomHangoutSpots = pawn.Map.listerBuildings.allBuildingsColonist .Where(x => (x.def == ThingDefOf.Wall || x.def.building.ai_chillDestination) && pawn.Map.areaManager.Home[x.Position]) .Select(x => GenAdjFast.AdjacentCells8Way(x).RandomElement()) .Where(x => !x.IsForbidden(pawn) && pawn.CanReach(x, PathEndMode.Touch, maxDanger)).ToList(); if (randomHangoutSpots.Count > 0) { return(randomHangoutSpots.RandomElement()); } // If we have neither, wander around your current position. return(pawn.Position); }
private static Apparel FindGarmentCoveringPart(Pawn pawn, BodyPartGroupDef bodyPartGroupDef) { Predicate <Thing> validator = apparel => apparel.def.apparel.bodyPartGroups.Contains(bodyPartGroupDef) & pawn.CanReserve(apparel); return((Apparel)GenClosest.ClosestThing_Global_Reachable(pawn.Position, Find.ListerThings.ThingsInGroup(ThingRequestGroup.Apparel), PathEndMode.InteractionCell, traverseParams, 20, validator)); }
public static void Postfix(Pawn healer, Pawn patient, ref Thing __result) { if (Controller.Settings.RealisticBandages && __result != null && HealthAIUtility_FindBestMedicine_PostPatch.IsBandage(__result.def) && !HealthAIUtility_FindBestMedicine_PostPatch.BandagesValid(patient)) { float medPot = __result.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null); __result = GenClosest.ClosestThing_Global_Reachable(patient.Position, patient.Map, patient.Map.listerThings.ThingsInGroup(ThingRequestGroup.Medicine), PathEndMode.ClosestTouch, TraverseParms.For(healer, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, (Thing m) => !m.IsForbidden(healer) && healer.CanReserve(m, 1, -1, null, false) && !HealthAIUtility_FindBestMedicine_PostPatch.IsBandage(m.def) && m.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null) <= medPot, (Thing m) => m.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null)); } }
public Job EquipTool(Pawn pawn) { // find closest reachable tool of the specific workType name closestAvailableTool = GenClosest.ClosestThing_Global_Reachable(pawn.Position, availableTools, PathEndMode.Touch, TraverseParms.For(pawn), 9999); // job to equip nearest tool return(new Job(JobDefOf.Equip, closestAvailableTool)); }
protected override Thing BestIngestItem(Pawn pawn, Predicate <Thing> extraValidator) { if (pawn.drugs == null) { return(null); } Predicate <Thing> predicate = delegate(Thing t) { if (!CanIngestForJoy(pawn, t)) { return(false); } if (extraValidator != null && !extraValidator(t)) { return(false); } return(true); }; ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int i = 0; i < innerContainer.Count; i++) { if (predicate(innerContainer[i])) { return(innerContainer[i]); } } takeableDrugs.Clear(); DrugPolicy currentPolicy = pawn.drugs.CurrentPolicy; for (int j = 0; j < currentPolicy.Count; j++) { if (currentPolicy[j].allowedForJoy) { takeableDrugs.Add(currentPolicy[j].drug); } } takeableDrugs.Shuffle(); for (int k = 0; k < takeableDrugs.Count; k++) { List <Thing> list = pawn.Map.listerThings.ThingsOfDef(takeableDrugs[k]); if (list.Count > 0) { IntVec3 position = pawn.Position; Map map = pawn.Map; List <Thing> searchSet = list; PathEndMode peMode = PathEndMode.OnCell; TraverseParms traverseParams = TraverseParms.For(pawn); Predicate <Thing> validator = predicate; Thing thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, peMode, traverseParams, 9999f, validator); if (thing != null) { return(thing); } } } return(null); }
public static Thing FindClosestFlammableThing(Pawn pawn, float distance) { //Log.Message("Trying to find target at range: " + distance); IEnumerable <Thing> flammables = from t in pawn.Map.listerThings.AllThings where t.Position.InHorDistOf(pawn.Position, distance) && t.FlammableNow && !t.IsBurning() select t; return(GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, flammables, PathEndMode.Touch, TraverseParms.For(pawn))); }
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); }
public static void JumpToCarryToNextContainerIfPossible_Prefix(ref Toil __result, Toil carryToContainerToil, TargetIndex primaryTargetInd) { Toil toil = new Toil(); toil.initAction = delegate() { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; if (actor.carryTracker.CarriedThing != null) { LocalTargetInfo target; if (curJob.targetQueueB != null && curJob.targetQueueB.Count > 0 && actor.RaceProps.Animal) { target = curJob.GetTarget(primaryTargetInd); Thing primaryTarget2 = target.Thing; bool hasSpareItems2 = actor.carryTracker.CarriedThing.stackCount > GenConstruct.AmountNeededByOf((IConstructible)(object)(IConstructible)primaryTarget2, actor.carryTracker.CarriedThing.def); Predicate <Thing> predicate = (Thing th) => ReservationUtility.CanReserve(actor, primaryTarget2, 1, -1, (ReservationLayerDef)null, false) && GenCollection.Any <ThingDefCountClass>(((IConstructible)th).MaterialsNeeded(), (Predicate <ThingDefCountClass>)((ThingDefCountClass need) => need.thingDef == actor.carryTracker.CarriedThing.def)) && ((th == primaryTarget2) | hasSpareItems2); Thing nextTarget2 = GenClosest.ClosestThing_Global_Reachable(actor.Position, actor.Map, curJob.targetQueueB.Select(delegate(LocalTargetInfo targ) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) LocalTargetInfo val2 = targ; return(val2.Thing); }), (PathEndMode)2, TraverseParms.For(actor, (Danger)3, (TraverseMode)0, false), 99999f, predicate, (Func <Thing, float>)null); if (nextTarget2 != null) { curJob.targetQueueB.RemoveAll((LocalTargetInfo targ) => targ.Thing == nextTarget2); curJob.targetB = nextTarget2; actor.jobs.curDriver.JumpToToil(carryToContainerToil); } } if (curJob.targetQueueB != null && curJob.targetQueueB.Count > 0 && !actor.RaceProps.Animal) { target = curJob.GetTarget(primaryTargetInd); Thing primaryTarget = target.Thing; bool hasSpareItems = actor.carryTracker.CarriedThing.stackCount > GenConstruct.AmountNeededByOf((IConstructible)(object)(IConstructible)primaryTarget, actor.carryTracker.CarriedThing.def); Predicate <Thing> predicate2 = (Thing th) => GenConstruct.CanConstruct(th, actor, false, false) && GenCollection.Any <ThingDefCountClass>(((IConstructible)th).MaterialsNeeded(), (Predicate <ThingDefCountClass>)((ThingDefCountClass need) => need.thingDef == actor.carryTracker.CarriedThing.def)) && ((th == primaryTarget) | hasSpareItems); Thing nextTarget = GenClosest.ClosestThing_Global_Reachable(actor.Position, actor.Map, curJob.targetQueueB.Select(delegate(LocalTargetInfo targ) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) LocalTargetInfo val = targ; return(val.Thing); }), (PathEndMode)2, TraverseParms.For(actor, (Danger)3, (TraverseMode)0, false), 99999f, predicate2, (Func <Thing, float>)null); if (nextTarget != null) { curJob.targetQueueB.RemoveAll((LocalTargetInfo targ) => targ.Thing == nextTarget); curJob.targetB = nextTarget; actor.jobs.curDriver.JumpToToil(carryToContainerToil); } } } }; __result = toil; }
public static Job TryGiveJob(this JobGiver_Haul @this, Pawn pawn) { Predicate <Thing> validator = t => !t.IsForbidden(pawn) && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t) && IsPlaceToPutThing(pawn, t); Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null); if (thing != null) { return(HaulAIUtility.HaulToStorageJob(pawn, thing)); } return(null); }
protected override Thing BestIngestItem(Pawn pawn, Predicate <Thing> extraValidator) { //Find a doll Predicate <Thing> predicate = (Thing t) => (t.def == DefDatabase <ThingDef> .GetNamed("LotRD_DwarfElfToy")) && pawn.CanReserve(t) && (extraValidator == null || extraValidator(t)); List <Thing> searchSet = new List <Thing>(); GetSearchSet(pawn, searchSet); TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); return(GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, searchSet, PathEndMode.OnCell, traverseParams, 9999f, predicate, null)); }
protected override Thing BestIngestItem(Pawn pawn, Predicate <Thing> extraValidator) { if (pawn.drugs == null) { return(null); } Predicate <Thing> predicate = delegate(Thing t) { if (!CanIngestForJoy(pawn, t)) { return(false); } return((extraValidator == null || extraValidator(t)) ? true : false); }; ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int i = 0; i < innerContainer.Count; i++) { if (predicate(innerContainer[i])) { return(innerContainer[i]); } } bool flag = false; if (pawn.story != null && (pawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire) > 0 || pawn.InMentalState)) { flag = true; } takeableDrugs.Clear(); DrugPolicy currentPolicy = pawn.drugs.CurrentPolicy; for (int j = 0; j < currentPolicy.Count; j++) { if (flag || currentPolicy[j].allowedForJoy) { takeableDrugs.Add(currentPolicy[j].drug); } } takeableDrugs.Shuffle(); for (int k = 0; k < takeableDrugs.Count; k++) { List <Thing> list = pawn.Map.listerThings.ThingsOfDef(takeableDrugs[k]); if (list.Count > 0) { Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, list, PathEndMode.OnCell, TraverseParms.For(pawn), 9999f, predicate); if (thing != null) { return(thing); } } } return(null); }