//JobDriver_HaulToContainer is Job 'HaulToContainer' public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) { Building_GrowerBase grower = t as Building_GrowerBase; if (grower == null) { return(false); } if (t.IsForbidden(pawn)) { return(false); } if (!pawn.CanReserve(t)) { return(false); } if (grower.status != CrafterStatus.Filling) { return(false); } if (grower.orderProcessor.PendingRequests.Count() <= 0) { return(false); } return(IngredientUtility.FindClosestRequestForThingOrderProcessor(grower.orderProcessor, pawn) is Thing cloestThing && pawn.CanReserve(cloestThing)); }
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) { Building_GrowerBase grower = t as Building_GrowerBase; Thing fillThing = IngredientUtility.FindClosestRequestForThingOrderProcessor(grower.orderProcessor, pawn); int fillCount = grower.orderProcessor.PendingRequests.First(req => req.ThingMatches(fillThing)).amount; Job job = new Job(QEJobDefOf.QE_DepositIntoGrowerJob, t, fillThing); job.count = fillCount; return(job); }
} //end FindClosestIngForBill public static Thing FindClosestIngToBillGiver(Bill theBill, IngredientCount curIng) { IBillGiver billGiver = theBill.billStack.billGiver; IThingHolder holder = billGiver as IThingHolder; Thing building = billGiver as Thing; ThingOwner vatStoredIngredients = holder?.GetDirectlyHeldThings(); if (billGiver == null || building == null || billGiver == null || vatStoredIngredients == null) { return(null); } int countNeededForCrafting = IngredientUtility.RemainingCountForIngredient(vatStoredIngredients, theBill.recipe, curIng); //only check the map for Things if the vat still needs some of this ingredient if (countNeededForCrafting > 0) { //find the closest accessible Thing of that ThingDef on the map ThingRequest tRequest = ThingRequest.ForDef(curIng.FixedIngredient); IEnumerable <Thing> searchSet = billGiver.Map.listerThings.ThingsMatching(tRequest); Thing result = GenClosest.ClosestThing_Global(building.Position, searchSet, validator : delegate(Thing testThing) { if (testThing.def.defName != curIng.FixedIngredient.defName) { return(false); } if (testThing.IsForbidden(building.Faction)) { return(false); } return(true); }); //return the Thing, if we found one if (result != null) { //QEEMod.TryLog("Ingredient found: " + curIng.FixedIngredient.label + " | stackCount: " + result.stackCount + " | recipe: " // + countNeededFromRecipe); return(result); } } return(null); } //end function FindClosestIngToBillGiver
public void UpdateDesiredRequests() { desiredRequests.Clear(); List <Bill> bills = new List <Bill>(); if (_activeBill != null) { bills.Add(_activeBill); } else { bills = (observedThingHolder as IBillGiver)?.BillStack.Bills; } for (int i = 0; i < bills.Count; i++) { Bill_Production theBill = bills[i] as Bill_Production; if (theBill?.recipe?.ingredients == null) { continue; } foreach (IngredientCount curIng in theBill.recipe.ingredients) { ThingFilter filterCopy = new ThingFilter(); filterCopy.CopyAllowancesFrom(curIng.filter); ThingOrderRequest request = new ThingOrderRequest(filterCopy); int countNeededForCrafting = IngredientUtility.RemainingCountForIngredient(ObservedThingOwner, theBill.recipe, curIng); if (countNeededForCrafting > 0) { //QEEMod.TryLog("Adding " + curIng.FixedIngredient.label + " amount: " + countNeededForCrafting); request.amount = countNeededForCrafting; desiredRequests[curIng.FixedIngredient.defName] = request; } } //end foreach loop } //end for loop } //end UpdateDesiredRequests
public bool UpdateAvailIngredientsCache() { anyBillIngredientsAvailable = false; ingredientsAvailableNow.Clear(); if (AnyPendingRequests == false) { return(false); } //Thing giver = (observedThingHolder as Thing); //QEEMod.TryLog("Updating available ingredients cache for " + giver.ThingID); List <Bill> bills = new List <Bill>(); if (_activeBill != null) { bills.Add(_activeBill); } else { bills = (observedThingHolder as IBillGiver)?.BillStack.Bills; } Dictionary <string, Thing> ingsFoundOnMap = new Dictionary <string, Thing>(); int checkIntervalTicks = QEESettings.instance.ingredientCheckIntervalSeconds * 60; for (int i = 0; i < bills.Count; i++) { Bill_Production curBill = bills[i] as Bill_Production; if (Find.TickManager.TicksGame < curBill.lastIngredientSearchFailTicks + checkIntervalTicks) { QEEMod.TryLog("checked " + curBill.GetUniqueLoadID() + " for avail. ingredients recently, skipping"); continue; } curBill.lastIngredientSearchFailTicks = 0; if (curBill.ShouldDoNow()) { //loop through ingredients foreach (IngredientCount curIng in curBill.recipe.ingredients) { Thing ing; //if same ingredient was found on map in previous loop iteration, don't search map again ingsFoundOnMap.TryGetValue(curIng.FixedIngredient.defName, out ing); if (ing != null) { ingredientsAvailableNow[curBill.GetUniqueLoadID()] = ing; //QEEMod.TryLog("Already found " + ing.Label + " on previous iteration. Skipping"); break; } //check if this ingredient is on the map ing = IngredientUtility.FindClosestIngToBillGiver(curBill, curIng); if (ing != null) { QEEMod.TryLog("Found " + ing.Label + " on map, adding to ingredient cache"); ingsFoundOnMap[curIng.FixedIngredient.defName] = ing; ingredientsAvailableNow[curBill.GetUniqueLoadID()] = ing; anyBillIngredientsAvailable = true; break; } else { //QEEMod.TryLog("no ingredients available"); } } Thing dummy; if (!ingredientsAvailableNow.TryGetValue(curBill.GetUniqueLoadID(), out dummy)) { curBill.lastIngredientSearchFailTicks = Find.TickManager.TicksGame; } } } return(anyBillIngredientsAvailable); }
}//end HasJobOnThing() public override Job JobOnThing(Pawn p, Thing t, bool forced = false) { IBillGiver billGiver = t as IBillGiver; Building_GrowerBase_WorkTable grower = t as Building_GrowerBase_WorkTable; BillProcessor processor = grower.billProc; //if null is returned from this function, the game will throw an error. Instead, //return this simple wait job to avoid unnecessary errors. Job returnJobOnFailure = new Job(JobDefOf.Wait, 5); //check if there are any pending requests (unfulfilled bills) if (!processor.AnyPendingRequests) { QEEMod.TryLog("AnyPendingRequests is false inside JobOnThing()!"); return(returnJobOnFailure); } //check if there are ingredients available for those bills if (processor.ingredientsAvailableNow.Count <= 0) { QEEMod.TryLog("ingredientsAvailableNow.Count is 0 inside JobOnThing()!"); return(returnJobOnFailure); } //get the reference to the currently active bill Bill theBill = processor.ActiveBill; if (theBill == null) { QEEMod.TryLog("Attempt to get ActiveBill failed inside JobOnThing()!"); return(returnJobOnFailure); } //get the cached ingredient that's available. This Thing is not always going to be used in the Job, //but we know there's at least one stack of this Thing available on the map Thing cachedThing; grower.billProc.ingredientsAvailableNow.TryGetValue(theBill.GetUniqueLoadID(), out cachedThing); if (cachedThing == null) { QEEMod.TryLog("Attempt to retrieve cached ingredients failed for " + theBill.GetUniqueLoadID()); return(returnJobOnFailure); } //get the nearest Thing to the Pawn with the same ThingDef int countForVat = 0; Thing thingToFill = IngredientUtility.ThingPawnShouldRetrieveForBill(theBill, p, ref countForVat); if (thingToFill == null) { grower.billProc.anyBillIngredientsAvailable = false; QEEMod.TryLog("ThingPawnShouldRetrieveForBill() is null for " + theBill.GetUniqueLoadID()); return(returnJobOnFailure); } //all checks have passed! Return the Job and notify the grower that it's time to start Filling grower.Notify_FillingStarted(theBill); Job returnJob = new Job(QEJobDefOf.QE_LoadGrowerJob, t, thingToFill); returnJob.count = countForVat; returnJob.bill = theBill; return(returnJob); }//end JobOnThing()