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); }
public static Toil DoRecipeWork() { 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; UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (unfinishedThing != null && unfinishedThing.Initialized) { jobDriver_DoBill.workLeft = unfinishedThing.workLeft; } else { jobDriver_DoBill.workLeft = curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff); if (unfinishedThing != null) { unfinishedThing.workLeft = jobDriver_DoBill.workLeft; } } jobDriver_DoBill.billStartTick = Find.TickManager.TicksGame; jobDriver_DoBill.ticksSpentDoingRecipeWork = 0; curJob.bill.Notify_DoBillStarted(actor); }; toil.tickAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (unfinishedThing != null && unfinishedThing.Destroyed) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } jobDriver_DoBill.ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); IBillGiverWithTickAction billGiverWithTickAction = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction; if (billGiverWithTickAction != null) { billGiverWithTickAction.UsedThisTick(); } if (curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing) { actor.skills.Learn(curJob.RecipeDef.workSkill, 0.1f * curJob.RecipeDef.workSkillLearnFactor, false); } float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f; if (curJob.RecipeDef.workTableSpeedStat != null) { Building_WorkTable building_WorkTable = jobDriver_DoBill.BillGiver as Building_WorkTable; if (building_WorkTable != null) { num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true); } } if (DebugSettings.fastCrafting) { num *= 30f; } jobDriver_DoBill.workLeft -= num; if (unfinishedThing != null) { unfinishedThing.workLeft = jobDriver_DoBill.workLeft; } actor.GainComfortFromCellIfPossible(); if (jobDriver_DoBill.workLeft <= 0f) { jobDriver_DoBill.ReadyForNextToil(); } if (curJob.bill.recipe.UsesUnfinishedThing) { int num2 = Find.TickManager.TicksGame - jobDriver_DoBill.billStartTick; if (num2 >= 3000 && num2 % 1000 == 0) { actor.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_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff)); }, false, -0.5f); toil.FailOn(() => toil.actor.CurJob.bill.suspended); toil.activeSkill = (() => toil.actor.CurJob.bill.recipe.workSkill); return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { base.AddEndCondition(delegate { Thing thing = this.$this.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(TargetIndex.A); this.FailOn(delegate { IBillGiver billGiver = this.$this.job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (this.$this.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(new Toil { initAction = delegate { if (this.$this.job.targetQueueB != null && this.$this.job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = this.$this.job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.$this.job.bill; } } } }); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => this.$this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>())); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); yield return(JobDriver_DoBill.JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(gotoBillGiver); yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded()); yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct()); if (!this.job.RecipeDef.products.NullOrEmpty <ThingCountClass>() || !this.job.RecipeDef.specialProducts.NullOrEmpty <SpecialProductType>()) { yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); Toil recount = new Toil(); recount.initAction = delegate { Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { this.$this.Map.resourceCounter.UpdateResourceCounts(); } }; yield return(recount); } }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: { base.AddEndCondition(delegate { Thing thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(TargetIndex.A); this.FailOn(delegate() { IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (this.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } } return(false); }); gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); Toil bind = new Toil(); bind.initAction = delegate() { if (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill; } } }; this.$current = bind; if (!this.$disposing) { this.$PC = 1; } return(true); } case 1u: this.$current = Toils_Jump.JumpIf(gotoBillGiver, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); this.$current = extract; if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); this.$current = getToHaulTarget; if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: this.$current = Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true); if (!this.$disposing) { this.$PC = 5; } return(true); case 5u: this.$current = JobDriver_DoBill.JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B); if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B); if (!this.$disposing) { this.$PC = 7; } return(true); case 7u: findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); this.$current = findPlaceTarget; if (!this.$disposing) { this.$PC = 8; } return(true); case 8u: this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false); if (!this.$disposing) { this.$PC = 9; } return(true); case 9u: this.$current = Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract); if (!this.$disposing) { this.$PC = 10; } return(true); case 10u: this.$current = gotoBillGiver; if (!this.$disposing) { this.$PC = 11; } return(true); case 11u: this.$current = Toils_Recipe.MakeUnfinishedThingIfNeeded(); if (!this.$disposing) { this.$PC = 12; } return(true); case 12u: this.$current = Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell); if (!this.$disposing) { this.$PC = 13; } return(true); case 13u: this.$current = Toils_Recipe.FinishRecipeAndStartStoringProduct(); if (!this.$disposing) { this.$PC = 14; } return(true); case 14u: if (!this.job.RecipeDef.products.NullOrEmpty <ThingDefCountClass>() || !this.job.RecipeDef.specialProducts.NullOrEmpty <SpecialProductType>()) { this.$current = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null); if (!this.$disposing) { this.$PC = 15; } return(true); } break; case 15u: carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); this.$current = carryToCell; if (!this.$disposing) { this.$PC = 16; } return(true); case 16u: this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true); if (!this.$disposing) { this.$PC = 17; } return(true); case 17u: < MakeNewToils > c__AnonStorey.recount = new Toil(); < MakeNewToils > c__AnonStorey.recount.initAction = delegate() { Bill_Production bill_Production = < MakeNewToils > c__AnonStorey.recount.actor.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { < MakeNewToils > c__AnonStorey.< > f__ref$0.$this.Map.resourceCounter.UpdateResourceCounts(); }
public static Toil DoRecipeWork() { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor3 = toil.actor; Job curJob3 = actor3.jobs.curJob; JobDriver_DoBill jobDriver_DoBill2 = (JobDriver_DoBill)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_DoBill jobDriver_DoBill = (JobDriver_DoBill)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_DoBill)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); }
public static Toil DoRecipeWork() { const int MinWorkDuration = 3000; const int CheckOverrideInterval = 1000; Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill driver = ((JobDriver_DoBill)actor.jobs.curDriver); UnfinishedThing uft = curJob.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing; //Set our work left //If we're starting from an already-initialized UnfinishedThing, just copy its workLeft into the driver //Otherwise, generate a new workLeft and copy it into the UnfinishedThing if (uft != null && uft.Initialized) { driver.workLeft = uft.workLeft; } else { driver.workLeft = curJob.bill.recipe.WorkAmountTotal(uft != null ? uft.Stuff : null); if (uft != null) { uft.workLeft = driver.workLeft; } } driver.billStartTick = Find.TickManager.TicksGame; driver.ticksSpentDoingRecipeWork = 0; curJob.bill.Notify_DoBillStarted(actor); }; toil.tickAction = () => { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill driver = ((JobDriver_DoBill)actor.jobs.curDriver); UnfinishedThing uft = curJob.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing; if (uft != null && uft.Destroyed) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } driver.ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); //Bill giver gets notification that we're working on it var bga = toil.actor.CurJob.GetTarget(JobDriver_DoBill.BillGiverInd).Thing as IBillGiverWithTickAction; if (bga != null) { bga.UsedThisTick(); } //Learn (only if the recipe uses unfinished thing to prevent the exploit with drafting/undrafting colonists and getting unlimited xp) if (curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing) { actor.skills.Learn(curJob.RecipeDef.workSkill, SkillTuning.XpPerTickRecipeBase * curJob.RecipeDef.workSkillLearnFactor); } //Make some progress //Apply it to both the driver's workLeft and, if it exists, the UnfinishedThing's workLeft float progress = (curJob.RecipeDef.workSpeedStat == null) ? 1f : actor.GetStatValue(curJob.RecipeDef.workSpeedStat); if (curJob.RecipeDef.workTableSpeedStat != null) { var t = driver.BillGiver as Building_WorkTable; if (t != null) { progress *= t.GetStatValue(curJob.RecipeDef.workTableSpeedStat); } } if (DebugSettings.fastCrafting) { progress *= 30; } driver.workLeft -= progress; if (uft != null) { uft.workLeft = driver.workLeft; } PawnUtility.GainComfortFromCellIfPossible(actor); //End the toil if there is no more work left if (driver.workLeft <= 0) { driver.ReadyForNextToil(); } //Allow job override periodically if (curJob.bill.recipe.UsesUnfinishedThing) { int billTicks = Find.TickManager.TicksGame - driver.billStartTick; if (billTicks >= MinWorkDuration && billTicks % CheckOverrideInterval == 0) { actor.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(JobDriver_DoBill.BillGiverInd, () => { var actor = toil.actor; var curJob = actor.CurJob; var uft = curJob.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing; return(1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(uft != null ? uft.Stuff : null)); }); toil.FailOn(() => toil.actor.CurJob.bill.suspended); toil.activeSkill = () => toil.actor.CurJob.bill.recipe.workSkill; 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); }