public static Toil FinishRecipeAndStartStoringProduct() { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBillZLevels jobDriver_DoBill = (JobDriver_DoBillZLevels)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); } List <Thing> ingredients = CalculateIngredients(curJob, actor); Thing dominantIngredient = CalculateDominantIngredient(curJob, ingredients); List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, jobDriver_DoBill.BillGiver).ToList(); 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?.Stuff) >= 10000f && list.Count > 0) { TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, actor, list[0].GetInnerIfMinified().def); } if (list.Any()) { Find.QuestManager.Notify_ThingsProduced(actor, list); } if (list.Count == 0) { actor.jobs.EndCurrentJob(JobCondition.Succeeded); } 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)) { Log.Error(string.Concat(actor, " could not drop recipe product ", list[i], " near ", actor.Position)); } } actor.jobs.EndCurrentJob(JobCondition.Succeeded); } else { if (list.Count > 1) { for (int j = 1; j < list.Count; j++) { if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near)) { Log.Error(string.Concat(actor, " could not drop recipe product ", list[j], " near ", actor.Position)); } } } IntVec3 foundCell = IntVec3.Invalid; if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile) { StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell); } else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile) { StoreUtility.TryFindBestBetterStoreCellForIn(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out foundCell); } else { Log.ErrorOnce("Unknown store mode", 9158246); } if (foundCell.IsValid) { actor.carryTracker.TryStartCarry(list[0]); curJob.targetB = foundCell; curJob.targetA = list[0]; curJob.count = 99999; } else { if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near)) { Log.Error(string.Concat("Bill doer could not drop product ", list[0], " near ", actor.Position)); } actor.jobs.EndCurrentJob(JobCondition.Succeeded); } } }; return(toil); }
public static Toil DoRecipeWork() { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor3 = toil.actor; Job curJob3 = actor3.jobs.curJob; JobDriver_DoBillZLevels jobDriver_DoBill2 = (JobDriver_DoBillZLevels)actor3.jobs.curDriver; UnfinishedThing unfinishedThing3 = curJob3.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (unfinishedThing3 != null && unfinishedThing3.Initialized) { jobDriver_DoBill2.workLeft = unfinishedThing3.workLeft; } else { jobDriver_DoBill2.workLeft = curJob3.bill.recipe.WorkAmountTotal(unfinishedThing3?.Stuff); if (unfinishedThing3 != null) { unfinishedThing3.workLeft = jobDriver_DoBill2.workLeft; } } jobDriver_DoBill2.billStartTick = Find.TickManager.TicksGame; jobDriver_DoBill2.ticksSpentDoingRecipeWork = 0; curJob3.bill.Notify_DoBillStarted(actor3); }; toil.tickAction = delegate { Pawn actor2 = toil.actor; Job curJob2 = actor2.jobs.curJob; JobDriver_DoBillZLevels jobDriver_DoBill = (JobDriver_DoBillZLevels)actor2.jobs.curDriver; UnfinishedThing unfinishedThing2 = curJob2.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (unfinishedThing2 != null && unfinishedThing2.Destroyed) { actor2.jobs.EndCurrentJob(JobCondition.Incompletable); } else { jobDriver_DoBill.ticksSpentDoingRecipeWork++; curJob2.bill.Notify_PawnDidWork(actor2); (toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction)?.UsedThisTick(); if (curJob2.RecipeDef.workSkill != null && curJob2.RecipeDef.UsesUnfinishedThing) { actor2.skills.Learn(curJob2.RecipeDef.workSkill, 0.1f * curJob2.RecipeDef.workSkillLearnFactor); } float num = (curJob2.RecipeDef.workSpeedStat == null) ? 1f : actor2.GetStatValue(curJob2.RecipeDef.workSpeedStat); if (curJob2.RecipeDef.workTableSpeedStat != null) { Building_WorkTable building_WorkTable = jobDriver_DoBill.BillGiver as Building_WorkTable; if (building_WorkTable != null) { num *= building_WorkTable.GetStatValue(curJob2.RecipeDef.workTableSpeedStat); } } if (DebugSettings.fastCrafting) { num *= 30f; } jobDriver_DoBill.workLeft -= num; if (unfinishedThing2 != null) { unfinishedThing2.workLeft = jobDriver_DoBill.workLeft; } actor2.GainComfortFromCellIfPossible(chairsOnly: true); if (jobDriver_DoBill.workLeft <= 0f) { jobDriver_DoBill.ReadyForNextToil(); } else if (curJob2.bill.recipe.UsesUnfinishedThing) { int num2 = Find.TickManager.TicksGame - jobDriver_DoBill.billStartTick; if (num2 >= 3000 && num2 % 1000 == 0) { actor2.jobs.CheckForJobOverride(); } } } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A); toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking); toil.WithProgressBar(TargetIndex.A, delegate { Pawn actor = toil.actor; Job curJob = actor.CurJob; UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; return(1f - ((JobDriver_DoBillZLevels)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(unfinishedThing?.Stuff)); }); toil.FailOn((Func <bool>) delegate { RecipeDef recipeDef = toil.actor.CurJob.RecipeDef; if (recipeDef != null && recipeDef.interruptIfIngredientIsRotting) { LocalTargetInfo target = toil.actor.CurJob.GetTarget(TargetIndex.B); if (target.HasThing && (int)target.Thing.GetRotStage() > 0) { return(true); } } return(toil.actor.CurJob.bill.suspended); }); toil.activeSkill = (() => toil.actor.CurJob.bill.recipe.workSkill); return(toil); }