protected virtual void ProduceItems() { if (currentBillReport == null) { Log.Error("Project RimFactory :: Tried to make products when assembler isn't engaged in a bill."); return; } // GenRecipe handles creating any bonus products IEnumerable <Thing> products = GenRecipe.MakeRecipeProducts(currentBillReport.bill.recipe, buildingPawn, currentBillReport.selected, ProjectSAL_Utilities.CalculateDominantIngredient(currentBillReport.bill.recipe, currentBillReport.selected), this); foreach (Thing thing in products) { PostProcessRecipeProduct(thing); thingQueue.Add(thing); } for (int i = 0; i < currentBillReport.selected.Count; i++) { if (currentBillReport.selected[i] is Corpse c && c.InnerPawn?.apparel != null) { List <Apparel> apparel = new List <Apparel>(c.InnerPawn.apparel.WornApparel); for (int j = 0; j < apparel.Count; j++) { thingQueue.Add(apparel[j]); c.InnerPawn.apparel.Remove(apparel[j]); } } currentBillReport.bill.recipe.Worker.ConsumeIngredient(currentBillReport.selected[i], currentBillReport.bill.recipe, Map); } thingQueue.AddRange(from Thing t in currentBillReport.selected where t.Spawned select t); }
public virtual void TryMakeProducts() { if (currentRecipe == null) { Log.Warning(ToString() + " had workLeft > 0 when the currentRecipe is NULL. Resetting. (workLeft probably isn't synchronised with recipe. Use resetRecipe() to set currentRecipe to NULL and to synchronise workLeft.)"); ResetRecipe(); return; } foreach (Thing obj in GenRecipe.MakeRecipeProducts(currentRecipe, buildingPawn, thingRecord, CalculateDominantIngredient(currentRecipe, thingRecord))) { thingPlacementQueue.Add(obj); } FindBillAndChangeRepeatCount(WorkTableBillStack, currentRecipe); ResetRecipe(); }
public static Toil FinishRecipeAndStartStoringProduct() { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing) { float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.1f * curJob.RecipeDef.workSkillLearnFactor; actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false); } List <Thing> ingredients = Toils_Recipe.CalculateIngredients(curJob, actor); Thing dominantIngredient = Toils_Recipe.CalculateDominantIngredient(curJob, ingredients); List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, jobDriver_DoBill.BillGiver).ToList <Thing>(); Toils_Recipe.ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map); curJob.bill.Notify_IterationCompleted(actor, ingredients); RecordsUtility.Notify_BillDone(actor, list); UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff) >= 10000f && list.Count > 0) { TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, new object[] { actor, list[0].def }); } if (list.Count == 0) { actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); return; } if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor) { for (int i = 0; i < list.Count; i++) { if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near, null, null)) { Log.Error(string.Concat(new object[] { actor, " could not drop recipe product ", list[i], " near ", actor.Position }), false); } } actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); return; } if (list.Count > 1) { for (int j = 1; j < list.Count; j++) { if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near, null, null)) { Log.Error(string.Concat(new object[] { actor, " could not drop recipe product ", list[j], " near ", actor.Position }), false); } } } IntVec3 invalid = IntVec3.Invalid; if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile) { StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out invalid, true); } else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile) { StoreUtility.TryFindBestBetterStoreCellForIn(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out invalid, true); } else { Log.ErrorOnce("Unknown store mode", 9158246, false); } if (invalid.IsValid) { actor.carryTracker.TryStartCarry(list[0]); curJob.targetB = invalid; curJob.targetA = list[0]; curJob.count = 99999; return; } if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null, null)) { Log.Error(string.Concat(new object[] { "Bill doer could not drop product ", list[0], " near ", actor.Position }), false); } actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); }; return(toil); }
private Toil FinishRecipeAndStartStoringProduct() { //Reflection info MethodInfo CalculateIngredientsInfo = AccessTools.Method(typeof(Toils_Recipe), "CalculateIngredients", new Type[] { typeof(Job), typeof(Pawn) }); MethodInfo CalculateDominantIngredientInfo = AccessTools.Method(typeof(Toils_Recipe), "CalculateDominantIngredient", new Type[] { typeof(Job), typeof(List <Thing>) }); MethodInfo ConsumeIngredientsInfo = AccessTools.Method(typeof(Toils_Recipe), "ConsumeIngredients", new Type[] { typeof(List <Thing>), typeof(RecipeDef), typeof(Map) }); // Toil toil = new Toil(); toil.initAction = delegate() { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing) { float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.1f * curJob.RecipeDef.workSkillLearnFactor; actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false); } List <Thing> ingredients = (List <Thing>)CalculateIngredientsInfo.Invoke(this, new object[] { curJob, actor }); Thing dominantIngredient = (Thing)CalculateDominantIngredientInfo.Invoke(this, new object[] { curJob, ingredients }); List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, jobDriver_DoBill.BillGiver).ToList <Thing>(); ConsumeIngredientsInfo.Invoke(this, new object[] { ingredients, curJob.RecipeDef, actor.Map }); curJob.bill.Notify_IterationCompleted(actor, ingredients); RecordsUtility.Notify_BillDone(actor, list); UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (curJob.bill.recipe.WorkAmountTotal((unfinishedThing != null) ? unfinishedThing.Stuff : null) >= 10000f && list.Count > 0) { TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, new object[] { actor, list[0].GetInnerIfMinified().def }); } if (list.Any <Thing>()) { Find.QuestManager.Notify_ThingsProduced(actor, list); techComp.homework.Remove(project); } if (list.Count == 0) { actor.jobs.EndCurrentJob(JobCondition.Succeeded, true, true); return; } if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor) { for (int i = 0; i < list.Count; i++) { if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4))) { Log.Error(string.Concat(new object[] { actor, " could not drop recipe product ", list[i], " near ", actor.Position }), false); } } actor.jobs.EndCurrentJob(JobCondition.Succeeded, true, true); return; } if (list.Count > 1) { for (int j = 1; j < list.Count; j++) { if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4))) { Log.Error(string.Concat(new object[] { actor, " could not drop recipe product ", list[j], " near ", actor.Position }), false); } } } IHaulDestination destination; if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile) { StoreUtility.TryFindBestBetterNonSlotGroupStorageFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out destination); curJob.targetB = destination as Thing; curJob.targetA = list[0]; curJob.count = 1; } else { Log.ErrorOnce("Unknown store mode", 9158246, false); } if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null, null, default(Rot4))) { Log.Error(string.Concat(new object[] { "Bill doer could not drop product ", list[0], " near ", actor.Position }), false); } }; return(toil); }
public static Toil FinishRecipeAndStartStoringProduct() { Toil toil = new Toil(); toil.initAction = () => { var actor = toil.actor; var curJob = actor.jobs.curJob; var driver = ((JobDriver_DoBill)actor.jobs.curDriver); //Learn (if the recipe doesn't use unfinished thing) if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing) { float xp = driver.ticksSpentDoingRecipeWork * SkillTuning.XpPerTickRecipeBase * curJob.RecipeDef.workSkillLearnFactor; actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp); } //Calculate ingredients List <Thing> ingredients = CalculateIngredients(curJob, actor); Thing dominantIngredient = CalculateDominantIngredient(curJob, ingredients); //Make the products var products = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, driver.BillGiver).ToList(); //Consume the ingredients ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map); //Notify bill curJob.bill.Notify_IterationCompleted(actor, ingredients); //Add records RecordsUtility.Notify_BillDone(actor, products); //Add tale var uft = curJob.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing; if (curJob.bill.recipe.WorkAmountTotal(uft != null ? uft.Stuff : null) >= LongCraftingProjectThreshold && products.Count > 0) { TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, actor, products[0].GetInnerIfMinified().def); } //---------------------------------------------------- //Rearrange the job so the bill doer goes and stores the product //---------------------------------------------------- //Nothing to store? End the job now if (products.Count == 0) { actor.jobs.EndCurrentJob(JobCondition.Succeeded); return; } //Bill is set to drop-on-floor mode? //Drop everything and end the job now if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor) { for (int i = 0; i < products.Count; i++) { if (!GenPlace.TryPlaceThing(products[i], actor.Position, actor.Map, ThingPlaceMode.Near)) { Log.Error(actor + " could not drop recipe product " + products[i] + " near " + actor.Position); } } actor.jobs.EndCurrentJob(JobCondition.Succeeded); return; } //Place all products except the first one on the ground if (products.Count > 1) { for (int i = 1; i < products.Count; i++) { if (!GenPlace.TryPlaceThing(products[i], actor.Position, actor.Map, ThingPlaceMode.Near)) { Log.Error(actor + " could not drop recipe product " + products[i] + " near " + actor.Position); } } } //Try find a cell to take the product to IntVec3 storeCell = IntVec3.Invalid; if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile) { StoreUtility.TryFindBestBetterStoreCellFor(products[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out storeCell); } else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile) { StoreUtility.TryFindBestBetterStoreCellForIn(products[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out storeCell); } else { Log.ErrorOnce("Unknown store mode", 9158246); } if (storeCell.IsValid) { //Start carrying the first product and proceed to the storage toils actor.carryTracker.TryStartCarry(products[0]); curJob.targetB = storeCell; curJob.targetA = products[0]; curJob.count = 99999; } else { //No store cell? Drop the product; we're done. if (!GenPlace.TryPlaceThing(products[0], actor.Position, actor.Map, ThingPlaceMode.Near)) { Log.Error("Bill doer could not drop product " + products[0] + " near " + actor.Position); } actor.jobs.EndCurrentJob(JobCondition.Succeeded); return; } }; return(toil); }
public static Toil FinishRecipeAndStartStoringProduct() { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing) { float xp = (float)((float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.10999999940395355 * curJob.RecipeDef.workSkillLearnFactor); actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false); } List <Thing> ingredients = Toils_Recipe.CalculateIngredients(curJob, actor); Thing dominantIngredient = Toils_Recipe.CalculateDominantIngredient(curJob, ingredients); List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient).ToList(); Toils_Recipe.ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map); curJob.bill.Notify_IterationCompleted(actor, ingredients); RecordsUtility.Notify_BillDone(actor, list); UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff) >= 20000.0 && list.Count > 0) { TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, actor, list[0].def); } if (list.Count == 0) { actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); } else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor) { for (int i = 0; i < list.Count; i++) { if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near, null)) { Log.Error(actor + " could not drop recipe product " + list[i] + " near " + actor.Position); } } actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); } else { if (list.Count > 1) { for (int j = 1; j < list.Count; j++) { if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near, null)) { Log.Error(actor + " could not drop recipe product " + list[j] + " near " + actor.Position); } } } list[0].SetPositionDirect(actor.Position); IntVec3 c = default(IntVec3); if (StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c, true)) { actor.carryTracker.TryStartCarry(list[0]); curJob.targetB = c; curJob.targetA = list[0]; curJob.count = 99999; } else { if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null)) { Log.Error("Bill doer could not drop product " + list[0] + " near " + actor.Position); } actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); } } }; return(toil); }