public static WorkGiverDef GetWorkgiver(this IBillGiver billGiver) { Thing thing = billGiver as Thing; if (thing == null) { Log.ErrorOnce(string.Format("Attempting to get the workgiver for a non-Thing IBillGiver {0}", billGiver.ToString()), 96810282, false); return(null); } List <WorkGiverDef> allDefsListForReading = DefDatabase <WorkGiverDef> .AllDefsListForReading; for (int i = 0; i < allDefsListForReading.Count; i++) { WorkGiverDef workGiverDef = allDefsListForReading[i]; WorkGiver_DoBill workGiver_DoBill = workGiverDef.Worker as WorkGiver_DoBill; if (workGiver_DoBill != null) { if (workGiver_DoBill.ThingIsUsableBillGiver(thing)) { return(workGiverDef); } } } Log.ErrorOnce(string.Format("Can't find a WorkGiver for a BillGiver {0}", thing.ToString()), 57348705, false); return(null); }
private static bool TryFindBestBillIngredientsInSet(List <Thing> availableThings, Bill bill, List <ThingCount> chosen) { if (bill.recipe.allowMixingIngredients) { return(WorkGiver_DoBill.TryFindBestBillIngredientsInSet_AllowMix(availableThings, bill, chosen)); } return(WorkGiver_DoBill.TryFindBestBillIngredientsInSet_NoMix(availableThings, bill, chosen)); }
private Job StartOrResumeBillJob(Pawn pawn, IBillGiver giver) { for (int i = 0; i < giver.BillStack.Count; i++) { Bill bill = giver.BillStack[i]; if ((bill.recipe.requiredGiverWorkType == null || bill.recipe.requiredGiverWorkType == base.def.workType) && (Find.TickManager.TicksGame >= bill.lastIngredientSearchFailTicks + WorkGiver_DoBill.ReCheckFailedBillTicksRange.RandomInRange || FloatMenuMakerMap.makingFor == pawn)) { bill.lastIngredientSearchFailTicks = 0; if (bill.ShouldDoNow() && bill.PawnAllowedToStartAnew(pawn)) { if (bill.recipe.PawnSatisfiesSkillRequirements(pawn)) { Bill_ProductionWithUft bill_ProductionWithUft = bill as Bill_ProductionWithUft; if (bill_ProductionWithUft != null) { if (bill_ProductionWithUft.BoundUft != null) { if (bill_ProductionWithUft.BoundWorker == pawn && pawn.CanReserveAndReach(bill_ProductionWithUft.BoundUft, PathEndMode.Touch, Danger.Deadly, 1, -1, null, false) && !bill_ProductionWithUft.BoundUft.IsForbidden(pawn)) { return(WorkGiver_DoBill.FinishUftJob(pawn, bill_ProductionWithUft.BoundUft, bill_ProductionWithUft)); } continue; } UnfinishedThing unfinishedThing = WorkGiver_DoBill.ClosestUnfinishedThingForBill(pawn, bill_ProductionWithUft); if (unfinishedThing != null) { return(WorkGiver_DoBill.FinishUftJob(pawn, unfinishedThing, bill_ProductionWithUft)); } } if (!WorkGiver_DoBill.TryFindBestBillIngredients(bill, pawn, (Thing)giver, this.chosenIngThings)) { if (FloatMenuMakerMap.makingFor != pawn) { bill.lastIngredientSearchFailTicks = Find.TickManager.TicksGame; } else { JobFailReason.Is(WorkGiver_DoBill.MissingMaterialsTranslated); } continue; } return(this.TryStartNewDoBillJob(pawn, bill, giver)); } JobFailReason.Is(WorkGiver_DoBill.MissingSkillTranslated); } } } return(null); }
private static void AddEveryMedicineToRelevantThings(Pawn pawn, Thing billGiver, List <Thing> relevantThings, Predicate <Thing> baseValidator, Map map) { MedicalCareCategory medicalCareCategory = WorkGiver_DoBill.GetMedicalCareCategory(billGiver); List <Thing> list = map.listerThings.ThingsInGroup(ThingRequestGroup.Medicine); WorkGiver_DoBill.tmpMedicine.Clear(); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; if (medicalCareCategory.AllowsMedicine(thing.def) && baseValidator(thing) && pawn.CanReach(thing, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { WorkGiver_DoBill.tmpMedicine.Add(thing); } } WorkGiver_DoBill.tmpMedicine.SortBy((Thing x) => - x.GetStatValue(StatDefOf.MedicalPotency, true), (Thing x) => x.Position.DistanceToSquared(billGiver.Position)); relevantThings.AddRange(WorkGiver_DoBill.tmpMedicine); WorkGiver_DoBill.tmpMedicine.Clear(); }
private static bool TryFindBestBillIngredients(Bill bill, Pawn pawn, Thing billGiver, List <ThingCount> chosen) { chosen.Clear(); WorkGiver_DoBill.newRelevantThings.Clear(); if (bill.recipe.ingredients.Count == 0) { return(true); } IntVec3 rootCell = WorkGiver_DoBill.GetBillGiverRootCell(billGiver, pawn); Region rootReg = rootCell.GetRegion(pawn.Map, RegionType.Set_Passable); if (rootReg == null) { return(false); } WorkGiver_DoBill.MakeIngredientsListInProcessingOrder(WorkGiver_DoBill.ingredientsOrdered, bill); WorkGiver_DoBill.relevantThings.Clear(); WorkGiver_DoBill.processedThings.Clear(); bool foundAll = false; Predicate <Thing> baseValidator = (Thing t) => t.Spawned && !t.IsForbidden(pawn) && (float)(t.Position - billGiver.Position).LengthHorizontalSquared < bill.ingredientSearchRadius * bill.ingredientSearchRadius && bill.IsFixedOrAllowedIngredient(t) && bill.recipe.ingredients.Any((IngredientCount ingNeed) => ingNeed.filter.Allows(t)) && pawn.CanReserve(t, 1, -1, null, false); bool billGiverIsPawn = billGiver is Pawn; if (billGiverIsPawn) { WorkGiver_DoBill.AddEveryMedicineToRelevantThings(pawn, billGiver, WorkGiver_DoBill.relevantThings, baseValidator, pawn.Map); if (WorkGiver_DoBill.TryFindBestBillIngredientsInSet(WorkGiver_DoBill.relevantThings, bill, chosen)) { WorkGiver_DoBill.relevantThings.Clear(); WorkGiver_DoBill.ingredientsOrdered.Clear(); return(true); } } TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, false); int adjacentRegionsAvailable = rootReg.Neighbors.Count((Region region) => entryCondition(rootReg, region)); int regionsProcessed = 0; WorkGiver_DoBill.processedThings.AddRange(WorkGiver_DoBill.relevantThings); RegionProcessor regionProcessor = delegate(Region r) { List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver)); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; if (!WorkGiver_DoBill.processedThings.Contains(thing)) { if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn)) { if (baseValidator(thing) && (!thing.def.IsMedicine || !billGiverIsPawn)) { WorkGiver_DoBill.newRelevantThings.Add(thing); WorkGiver_DoBill.processedThings.Add(thing); } } } } regionsProcessed++; if (WorkGiver_DoBill.newRelevantThings.Count > 0 && regionsProcessed > adjacentRegionsAvailable) { Comparison <Thing> comparison = delegate(Thing t1, Thing t2) { float num = (float)(t1.Position - rootCell).LengthHorizontalSquared; float value = (float)(t2.Position - rootCell).LengthHorizontalSquared; return(num.CompareTo(value)); }; WorkGiver_DoBill.newRelevantThings.Sort(comparison); WorkGiver_DoBill.relevantThings.AddRange(WorkGiver_DoBill.newRelevantThings); WorkGiver_DoBill.newRelevantThings.Clear(); if (WorkGiver_DoBill.TryFindBestBillIngredientsInSet(WorkGiver_DoBill.relevantThings, bill, chosen)) { foundAll = true; return(true); } } return(false); }; RegionTraverser.BreadthFirstTraverse(rootReg, entryCondition, regionProcessor, 99999, RegionType.Set_Passable); WorkGiver_DoBill.relevantThings.Clear(); WorkGiver_DoBill.newRelevantThings.Clear(); WorkGiver_DoBill.processedThings.Clear(); WorkGiver_DoBill.ingredientsOrdered.Clear(); return(foundAll); }
private Job StartOrResumeBillJob(Pawn pawn, IBillGiver giver) { for (int i = 0; i < giver.BillStack.Count; i++) { Bill bill = giver.BillStack[i]; if (bill.recipe.requiredGiverWorkType == null || bill.recipe.requiredGiverWorkType == this.def.workType) { if (Find.TickManager.TicksGame >= bill.lastIngredientSearchFailTicks + WorkGiver_DoBill.ReCheckFailedBillTicksRange.RandomInRange || FloatMenuMakerMap.makingFor == pawn) { bill.lastIngredientSearchFailTicks = 0; if (bill.ShouldDoNow()) { if (bill.PawnAllowedToStartAnew(pawn)) { SkillRequirement skillRequirement = bill.recipe.FirstSkillRequirementPawnDoesntSatisfy(pawn); if (skillRequirement != null) { JobFailReason.Is("UnderRequiredSkill".Translate(skillRequirement.minLevel), bill.Label); } else { Bill_ProductionWithUft bill_ProductionWithUft = bill as Bill_ProductionWithUft; if (bill_ProductionWithUft != null) { if (bill_ProductionWithUft.BoundUft != null) { if (bill_ProductionWithUft.BoundWorker != pawn || !pawn.CanReserveAndReach(bill_ProductionWithUft.BoundUft, PathEndMode.Touch, Danger.Deadly, 1, -1, null, false) || bill_ProductionWithUft.BoundUft.IsForbidden(pawn)) { goto IL_1D0; } return(WorkGiver_DoBill.FinishUftJob(pawn, bill_ProductionWithUft.BoundUft, bill_ProductionWithUft)); } else { UnfinishedThing unfinishedThing = WorkGiver_DoBill.ClosestUnfinishedThingForBill(pawn, bill_ProductionWithUft); if (unfinishedThing != null) { return(WorkGiver_DoBill.FinishUftJob(pawn, unfinishedThing, bill_ProductionWithUft)); } } } if (WorkGiver_DoBill.TryFindBestBillIngredients(bill, pawn, (Thing)giver, this.chosenIngThings)) { Job result = this.TryStartNewDoBillJob(pawn, bill, giver); this.chosenIngThings.Clear(); return(result); } if (FloatMenuMakerMap.makingFor != pawn) { bill.lastIngredientSearchFailTicks = Find.TickManager.TicksGame; } else { JobFailReason.Is(WorkGiver_DoBill.MissingMaterialsTranslated, bill.Label); } this.chosenIngThings.Clear(); } } } } } IL_1D0 :; } this.chosenIngThings.Clear(); return(null); }