private static void GetReport(JobDriver_DoBill __instance) { bool isSurgery = (hasSurgeryAsJob(__instance.pawn)); //Log.Message("isSurgery:" + isSurgery + " (" + __instance.pawn.jobs.curJob.RecipeDef.workerClass + ")"); if (!isSurgery) { UIRoot_Play_UIRootOnGUI_Prefix.shouldDrawSurgeryRect = false; return; } Bill bill = __instance.pawn.jobs.curJob.bill; Recipe_Surgery surgery = bill.recipe.Worker as Recipe_Surgery; Pawn surgeon = __instance.pawn; Pawn patient = bill.billStack.billGiver as Pawn; if (surgeon != UIRoot_Play_UIRootOnGUI_Prefix.surgeon || patient != UIRoot_Play_UIRootOnGUI_Prefix.patient) { UIRoot_Play_UIRootOnGUI_Prefix.ResetToEmpty(); } Medicine medicine = null; BodyPartRecord part = (bill as Bill_Medical).Part; if (surgeon.CurJob.placedThings != null) { List <ThingStackPartClass> placedThings = surgeon.CurJob.placedThings; for (int i = 0; i < placedThings.Count; i++) { if (placedThings[i].thing is Medicine) { medicine = placedThings[i].thing as Medicine; break; } } } if (medicine == null) { if (surgeon.carryTracker.CarriedThing != null) { medicine = surgeon.carryTracker.CarriedThing as Medicine; } } if (medicine != null) { cachedMedicine = medicine; } SurgeryOdds data = new SurgeryOdds() { }; SurgeryFailChance(data, surgeon, patient, cachedMedicine, part, surgery); }
public static Toil FinishRecipeAndStartStoringProduct(Func <Thing> makeRecipeProduct) { 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) { float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.11f * curJob.RecipeDef.workSkillLearnFactor; actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false); } // 生産物の生成 Thing thing = makeRecipeProduct(); if (thing == null) { actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); return; } curJob.bill.Notify_IterationCompleted(actor, null); // 水汲み記録追加 actor.records.AddTo(MizuDef.Record_WaterDrew, thing.stackCount); //RecordsUtility.Notify_BillDone(actor, new List<Thing>() { thing }); // 床置き指定 if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor) { if (!GenPlace.TryPlaceThing(thing, actor.Position, actor.Map, ThingPlaceMode.Near, null)) { Log.Error(string.Concat(new object[] { actor, " could not drop recipe product ", thing, " near ", actor.Position })); } actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); return; } // 最適な倉庫まで持っていく thing.SetPositionDirect(actor.Position); IntVec3 c; if (StoreUtility.TryFindBestBetterStoreCellFor(thing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c, true)) { actor.carryTracker.TryStartCarry(thing); curJob.targetA = thing; curJob.targetB = c; curJob.count = 99999; return; } if (!GenPlace.TryPlaceThing(thing, actor.Position, actor.Map, ThingPlaceMode.Near, null)) { Log.Error(string.Concat(new object[] { "Bill doer could not drop product ", thing, " near ", actor.Position })); } actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
public static Toil DoRecipeWorkDrawing(TargetIndex billGiverIndex) { 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; jobDriver_DoBill.workLeft = curJob.bill.recipe.WorkAmountTotal(null); 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; jobDriver_DoBill.ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); IBillGiverWithTickAction billGiverWithTickAction = actor.CurJob.GetTarget(billGiverIndex).Thing as IBillGiverWithTickAction; if (billGiverWithTickAction != null) { // 設備の時間経過処理 billGiverWithTickAction.UsedThisTick(); } // 工数を進める処理 float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f; Building_WorkTable building_WorkTable = jobDriver_DoBill.BillGiver as Building_WorkTable; if (building_WorkTable != null) { num *= building_WorkTable.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor, true); } if (DebugSettings.fastCrafting) { num *= 30f; } jobDriver_DoBill.workLeft -= num; // 椅子から快適さを得る actor.GainComfortFromCellIfPossible(); // 完了チェック if (jobDriver_DoBill.workLeft <= 0f) { jobDriver_DoBill.ReadyForNextToil(); } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, billGiverIndex); toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking); toil.WithProgressBar(billGiverIndex, delegate { Pawn actor = toil.actor; Job curJob = actor.CurJob; return(1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(null)); }, false, -0.5f); toil.FailOn(() => toil.actor.CurJob.bill.suspended); return(toil); }
public static Toil FinishPourRecipe(TargetIndex billGiverIndex, TargetIndex ingListIndex) { 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) { float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.11f * curJob.RecipeDef.workSkillLearnFactor; actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false); } // 注ぎ込んだ水の総量と水質を求める float totalWaterVolume = 0f; var totalWaterType = WaterType.NoWater; foreach (var tspc in curJob.placedThings) { var thingDef = tspc.thing.def; var compprop = thingDef.GetCompProperties <CompProperties_WaterSource>(); if (compprop == null) { Log.Error("compprop is null"); actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } totalWaterVolume += compprop.waterVolume * tspc.Count; totalWaterType = totalWaterType.GetMinType(compprop.waterType); } var billGiver = curJob.GetTarget(billGiverIndex).Thing as Building_WaterNetWorkTable; if (billGiver == null) { Log.Error("billGiver is null"); actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } // 水の増加 billGiver.AddWaterVolume(totalWaterVolume); // 水質変更 billGiver.TankComp.StoredWaterType = billGiver.TankComp.StoredWaterType.GetMinType(totalWaterType); // 水アイテムの消費 foreach (var tspc in curJob.placedThings) { Thing thing; if (tspc.Count < tspc.thing.stackCount) { thing = tspc.thing.SplitOff(tspc.Count); } else { thing = tspc.thing; } curJob.RecipeDef.Worker.ConsumeIngredient(thing, curJob.RecipeDef, actor.Map); } curJob.bill.Notify_IterationCompleted(actor, null); //RecordsUtility.Notify_BillDone(actor, new List<Thing>()); actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
// Token: 0x060000EE RID: 238 RVA: 0x00008574 File Offset: 0x00006774 public static void DoRecipeWork_Prefix(ref Toil __result) { Toil toil = new Toil(); toil.initAction = delegate() { Log.Message("init delegated.", false); Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; bool animal = actor.RaceProps.Animal; if (animal) { Log.Message("I am in.", false); JobDriver curDriver = actor.jobs.curDriver; JobDriver_WPDoBill jobDriver_WPDoBill = curDriver as JobDriver_WPDoBill; UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; jobDriver_WPDoBill.workLeft = curJob.bill.recipe.WorkAmountTotal(unfinishedThing.def); bool flag = unfinishedThing != null; if (flag) { unfinishedThing.workLeft = jobDriver_WPDoBill.workLeft; } jobDriver_WPDoBill.billStartTick = Find.TickManager.TicksGame; jobDriver_WPDoBill.ticksSpentDoingRecipeWork = 0; curJob.bill.Notify_DoBillStarted(actor); } else { Log.Message("I am here instead.", false); JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; UnfinishedThing unfinishedThing2 = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; bool flag2 = unfinishedThing2 != null && unfinishedThing2.Initialized; if (flag2) { jobDriver_DoBill.workLeft = unfinishedThing2.workLeft; } else { jobDriver_DoBill.workLeft = curJob.bill.recipe.WorkAmountTotal((unfinishedThing2 == null) ? null : unfinishedThing2.Stuff); bool flag3 = unfinishedThing2 != null; if (flag3) { unfinishedThing2.workLeft = jobDriver_DoBill.workLeft; } } jobDriver_DoBill.billStartTick = Find.TickManager.TicksGame; jobDriver_DoBill.ticksSpentDoingRecipeWork = 0; curJob.bill.Notify_DoBillStarted(actor); } }; toil.tickAction = delegate() { Log.Message("tick delegated.", false); Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver curDriver = actor.jobs.curDriver; bool animal = actor.RaceProps.Animal; if (animal) { JobDriver_WPDoBill jobDriver_WPDoBill = curDriver as JobDriver_WPDoBill; UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; bool flag = unfinishedThing != null && unfinishedThing.Destroyed; if (flag) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); return; } jobDriver_WPDoBill.ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); IBillGiverWithTickAction billGiverWithTickAction = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction; bool flag2 = billGiverWithTickAction != null; if (flag2) { billGiverWithTickAction.UsedThisTick(); } float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f; Building_WorkTable building_WorkTable = jobDriver_WPDoBill.BillGiver as Building_WorkTable; bool flag3 = building_WorkTable != null; if (flag3) { num *= building_WorkTable.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor, true); } bool fastCrafting = DebugSettings.fastCrafting; if (fastCrafting) { num *= 30f; } jobDriver_WPDoBill.workLeft -= num; bool flag4 = unfinishedThing != null; if (flag4) { unfinishedThing.workLeft = jobDriver_WPDoBill.workLeft; } actor.GainComfortFromCellIfPossible(false); bool flag5 = jobDriver_WPDoBill.workLeft <= 0f; if (flag5) { jobDriver_WPDoBill.ReadyForNextToil(); } bool usesUnfinishedThing = curJob.bill.recipe.UsesUnfinishedThing; if (usesUnfinishedThing) { int num2 = Find.TickManager.TicksGame - jobDriver_WPDoBill.billStartTick; bool flag6 = num2 >= 3000 && num2 % 1000 == 0; if (flag6) { actor.jobs.CheckForJobOverride(); } } } bool flag7 = !actor.RaceProps.Animal; if (flag7) { JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; UnfinishedThing unfinishedThing2 = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; bool flag8 = unfinishedThing2 != null && unfinishedThing2.Destroyed; if (flag8) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); } else { jobDriver_DoBill.ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); IBillGiverWithTickAction billGiverWithTickAction2 = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction; bool flag9 = billGiverWithTickAction2 != null; if (flag9) { billGiverWithTickAction2.UsedThisTick(); } bool flag10 = curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing; if (flag10) { actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(0.11f * curJob.RecipeDef.workSkillLearnFactor, false); } float num3 = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f; Building_WorkTable building_WorkTable2 = jobDriver_DoBill.BillGiver as Building_WorkTable; bool flag11 = building_WorkTable2 != null; if (flag11) { num3 *= building_WorkTable2.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor, true); } bool fastCrafting2 = DebugSettings.fastCrafting; if (fastCrafting2) { num3 *= 30f; } jobDriver_DoBill.workLeft -= num3; bool flag12 = unfinishedThing2 != null; if (flag12) { unfinishedThing2.workLeft = jobDriver_DoBill.workLeft; } actor.GainComfortFromCellIfPossible(false); bool flag13 = jobDriver_DoBill.workLeft <= 0f; if (flag13) { jobDriver_DoBill.ReadyForNextToil(); } bool usesUnfinishedThing2 = curJob.bill.recipe.UsesUnfinishedThing; if (usesUnfinishedThing2) { int num4 = Find.TickManager.TicksGame - jobDriver_DoBill.billStartTick; bool flag14 = num4 >= 3000 && num4 % 1000 == 0; if (flag14) { 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; bool animal = actor.RaceProps.Animal; float result; if (animal) { result = 1f - ((JobDriver_WPDoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff); } else { result = 1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff); } return(result); }, false, -0.5f); toil.FailOn(() => toil.actor.CurJob.bill.suspended); __result = toil; }
public override IEnumerable <Toil> MakeNewToils() { AddEndCondition(delegate { Thing thing = 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 = job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } if (project == null) { Log.Warning("[HumanResources] " + pawn + " tried to document a null project."); TryMakePreToilReservations(true); return(true); } if (!techComp.homework.Contains(project)) { return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(gotoBillGiver); Toil document = new Toil(); document.initAction = delegate() { Pawn actor = document.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; jobDriver_DoBill.billStartTick = Find.TickManager.TicksGame; jobDriver_DoBill.ticksSpentDoingRecipeWork = 0; curJob.bill.Notify_DoBillStarted(actor); }; document.tickAction = delegate() { Pawn actor = document.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; jobDriver_DoBill.ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); IBillGiverWithTickAction billGiverWithTickAction = document.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction; if (billGiverWithTickAction != null) { billGiverWithTickAction.UsedThisTick(); } SkillDef skill = curJob.RecipeDef.workSkill != null ? curJob.RecipeDef.workSkill : SkillDefOf.Intellectual; actor.skills.Learn(skill, 0.1f * curJob.RecipeDef.workSkillLearnFactor, false); float num = (curJob.RecipeDef.workSpeedStat == null) ? 1f : actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true); 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; } project.Uploaded(num, TargetThingA); actor.GainComfortFromCellIfPossible(true); if (project.IsFinished) { curJob.bill.Notify_IterationCompleted(actor, new List <Thing>() { }); project.Unlock(jobDriver_DoBill.BillGiver as Thing, false); techComp.homework.Remove(project); jobDriver_DoBill.ReadyForNextToil(); return; } }; document.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell); document.WithEffect(EffecterDefOf.Research, TargetIndex.A); document.WithProgressBar(TargetIndex.A, delegate { if (project == null) { return(0f); } return(project.ProgressPercent); }, false, -0.5f); document.defaultCompleteMode = ToilCompleteMode.Delay; document.defaultDuration = 4000; document.activeSkill = (() => SkillDefOf.Intellectual); yield return(document); yield return(Toils_General.Wait(2, TargetIndex.None)); yield break; }
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 DoDissectionRecipeWork() { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver = (JobDriver_DoBill)actor.jobs.curDriver; jobDriver.workLeft = curJob.bill.recipe.WorkAmountTotal(null); jobDriver.billStartTick = Find.TickManager.TicksGame; jobDriver.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; jobDriver_DoBill.ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); if (toil.actor.CurJob.GetTarget(TargetIndex.A).Thing is IBillGiverWithTickAction billGiverWithTickAction) { billGiverWithTickAction.UsedThisTick(); } if (!curJob.playerForced) { } var passion = actor.skills.GetSkill(SkillDefOf.Medicine).passion; float workDone = 1f * actor.GetStatValue(StatDefOf.WorkSpeedGlobal, true); if (DebugSettings.fastCrafting) { workDone *= 30f; } jobDriver_DoBill.workLeft -= workDone; actor.GainComfortFromCellIfPossible(); if (jobDriver_DoBill.workLeft <= 0f) { jobDriver_DoBill.ReadyForNextToil(); } }; 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; return(1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(null)); }, false, -0.5f); toil.FailOn(() => toil.actor.CurJob.bill.suspended); toil.activeSkill = (() => toil.actor.CurJob.bill.recipe.workSkill); return(toil); }
public override IEnumerable <Toil> MakeNewToils() { AddEndCondition(delegate { Thing thing = 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 = job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } } if (inShelf && !bookOut && !shelf.innerContainer.Contains(book)) { return(true); } return(false); }); AddFinishAction(delegate { if (inShelf && bookOut) { shelf.CheckBookOut(book, true); } }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => 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(inShelf ? TakeFromShelf(TargetIndex.B) : Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); 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, false)); extract = null; getToHaulTarget = null; findPlaceTarget = null; yield return(gotoBillGiver); yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); Toil upload = new Toil(); upload.initAction = delegate() { Pawn actor = upload.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver; if (curJob.RecipeDef.workSkill != null) { float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.1f * curJob.RecipeDef.workSkillLearnFactor; actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false); } project.Unlock(TargetThingA, false); Thing scanned = TargetB.Thing; if (scanned.def == TechDefOf.TechDrive) { Toils_Recipe_Patch.ConsumeIngredients(new List <Thing> { scanned }, curJob.RecipeDef, actor.Map); } curJob.bill.Notify_IterationCompleted(actor, new List <Thing>()); }; yield return(upload); //Put it back! if (inShelf) { yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnDestroyedOrNull(TargetIndex.B)); Toil handOver = Toils_Haul.DepositHauledThingInContainer(TargetIndex.B, TargetIndex.A); handOver.AddPreInitAction(delegate { bookOut = false; }); yield return(handOver); } yield return(new Toil() { initAction = delegate() { pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true, true); } }); yield break; }
// stats recalculation routine public void updateColonistStats(Pawn colonist) { if (!stats_dict.ContainsKey(colonist)) { stats_dict.Add(colonist, new PawnStats()); } PawnStats pawnStats = stats_dict[colonist]; /////////////////////////////////////////////////////////////// pawnStats.isNudist = false; foreach (Trait trait in colonist.story.traits.allTraits) { switch (trait.def.defName) { case "Nudist": pawnStats.isNudist = true; break; } } // efficiency float efficiency = 10; foreach (PawnCapacityDef act in pawnCapacities) { if (act != PawnCapacityDefOf.Consciousness) { efficiency = Math.Min(efficiency, colonist.health.capacities.GetEfficiency(act)); } } if (efficiency < 0) { efficiency = 0; } pawnStats.total_efficiency = efficiency; // target pawnStats.targetPos = Vector3.zero; if (colonist.jobs.curJob != null) { JobDriver curDriver = colonist.jobs.curDriver; Job curJob = colonist.jobs.curJob; TargetInfo tp = curJob.targetA; if (curDriver is JobDriver_HaulToContainer || curDriver is JobDriver_HaulToCell || curDriver is JobDriver_FoodDeliver || curDriver is JobDriver_FoodFeedPatient || curDriver is JobDriver_TakeToBed) { tp = curJob.targetB; } if (curDriver is JobDriver_DoBill) { JobDriver_DoBill bill = (JobDriver_DoBill)curDriver; if (bill.workLeft == 0.0f) { tp = curJob.targetA; } else if (bill.workLeft <= 0.01f) { tp = curJob.targetB; } //Log.Message("" + ((JobDriver_DoBill)colonist.jobs.curDriver).workLeft); } if (curDriver is JobDriver_Hunt) { if (colonist.carryHands != null && colonist.carryHands.CarriedThing != null) { tp = curJob.targetB; } } if (curJob.def == JobDefOf.Wait) { tp = null; } if (curDriver is JobDriver_Ingest) { tp = null; } if (curJob.def == JobDefOf.LayDown && colonist.InBed()) { tp = null; } if (!curJob.playerForced && curJob.def == JobDefOf.Goto) { tp = null; } //Log.Message(colonist.jobs.curJob.def.ToString()+" "+colonist.jobs.curDriver.GetType().ToString()); if (tp != null && tp.Cell != null) { Vector3 pos = tp.Cell.ToVector3Shifted(); pawnStats.targetPos = pos + new Vector3(0.0f, 3.0f, 0.0f); } } // temperature float temper = GenTemperature.GetTemperatureForCell(colonist.Position); pawnStats.tooCold = (colonist.ComfortableTemperatureRange().min - settings.limit_tempComfortOffset - temper) / 10.0f; pawnStats.tooHot = (temper - colonist.ComfortableTemperatureRange().max - settings.limit_tempComfortOffset) / 10.0f; pawnStats.tooCold = Mathf.Clamp(pawnStats.tooCold, 0, 2); pawnStats.tooHot = Mathf.Clamp(pawnStats.tooHot, 0, 2); // diseases pawnStats.diseaseDisappearance = 1; pawnStats.drunkness = DrugUtility.DrunknessPercent(colonist); using (IEnumerator <Hediff_Staged> enumerator = colonist.health.hediffSet.GetDiseases().GetEnumerator()) { while (enumerator.MoveNext()) { Hediff_Staged disease = enumerator.Current; if (disease == null || disease.FullyImmune || !disease.Visible) { continue; } if (disease.CurStage != null && !disease.CurStage.everVisible) { continue; } if (!disease.def.Treatable && !disease.def.naturallyHealed) { continue; } pawnStats.diseaseDisappearance = Math.Min(pawnStats.diseaseDisappearance, disease.Immunity); } } // apparel problems float worstApparel = 999f; List <Apparel> apparelListForReading = colonist.apparel.WornApparel; for (int index = 0; index < apparelListForReading.Count; ++index) { float curApparel = (float)apparelListForReading[index].HitPoints / (float)apparelListForReading[index].MaxHitPoints; if (curApparel >= 0 && curApparel < worstApparel) { worstApparel = curApparel; } } pawnStats.apparelHealth = worstApparel; // bloodloss pawnStats.bleedRate = Mathf.Clamp01(colonist.health.hediffSet.BleedingRate * settings.limit_bleedMult); //////////////////////////////////////////////////// stats_dict[colonist] = pawnStats; }
static bool Prefix(ref Toil __result) { Toil toil = new Toil(); toil.initAction = (Action)(() => { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill curDriver = (JobDriver_DoBill)actor.jobs.curDriver; UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (unfinishedThing != null && unfinishedThing.Initialized) { curDriver.workLeft = unfinishedThing.workLeft; } else { curDriver.workLeft = curJob.bill.recipe.WorkAmountTotal(unfinishedThing?.Stuff); if (unfinishedThing != null) { unfinishedThing.workLeft = curDriver.workLeft; } } curDriver.billStartTick = Find.TickManager.TicksGame; curDriver.ticksSpentDoingRecipeWork = 0; curJob.bill.Notify_DoBillStarted(actor); }); toil.tickAction = (Action)(() => { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; JobDriver_DoBill curDriver = (JobDriver_DoBill)actor.jobs.curDriver; UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; if (unfinishedThing != null && unfinishedThing.Destroyed) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); } else { ++curDriver.ticksSpentDoingRecipeWork; curJob.bill.Notify_PawnDidWork(actor); if (toil.actor.CurJob.GetTarget(TargetIndex.A).Thing is IBillGiverWithTickAction thing2) { thing2.UsedThisTick(); } if (curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing) { actor.skills.Learn(curJob.RecipeDef.workSkill, 0.1f * curJob.RecipeDef.workSkillLearnFactor); } float num1 = curJob.RecipeDef.workSpeedStat == null ? 1f : actor.GetStatValue(curJob.RecipeDef.workSpeedStat); num1 *= RefcellRespeedConfig.currentTimeMultiplier;//작업속도 조절 부분 Building_WorkTable billGiver = curDriver.BillGiver as Building_WorkTable; if (curJob.RecipeDef.workTableSpeedStat != null) { num1 *= billGiver.GetStatValue(curJob.RecipeDef.workTableSpeedStat); } if (DebugSettings.fastCrafting) { num1 *= 30f; } curDriver.workLeft -= num1; if (unfinishedThing != null) { unfinishedThing.workLeft = curDriver.workLeft; } actor.GainComfortFromCellIfPossible(true); if ((double)curDriver.workLeft <= 0.0) { curDriver.ReadyForNextToil(); } else { if (!curJob.bill.recipe.UsesUnfinishedThing) { return; } int num2 = Find.TickManager.TicksGame - curDriver.billStartTick; if (num2 < 3000 || num2 % 1000 != 0) { return; } actor.jobs.CheckForJobOverride(); } } }); toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect((Func <EffecterDef>)(() => toil.actor.CurJob.bill.recipe.effectWorking), TargetIndex.A); toil.PlaySustainerOrSound((Func <SoundDef>)(() => toil.actor.CurJob.bill.recipe.soundWorking)); toil.WithProgressBar(TargetIndex.A, (Func <float>)(() => { Pawn actor = toil.actor; Job curJob = actor.CurJob; UnfinishedThing thing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing; return((float)(1.0 - (double)((JobDriver_DoBill)actor.jobs.curDriver).workLeft / (double)curJob.bill.recipe.WorkAmountTotal(thing?.Stuff))); })); toil.FailOn <Toil>((Func <bool>)(() => { RecipeDef recipeDef = toil.actor.CurJob.RecipeDef; if (recipeDef != null && recipeDef.interruptIfIngredientIsRotting) { LocalTargetInfo target = toil.actor.CurJob.GetTarget(TargetIndex.B); if (target.HasThing && target.Thing.GetRotStage() > RotStage.Fresh) { return(true); } } return(toil.actor.CurJob.bill.suspended); })); toil.activeSkill = (Func <SkillDef>)(() => toil.actor.CurJob.bill.recipe.workSkill); __result = toil; return(false); }