protected override IEnumerable <Toil> MakeNewToils() { base.AddEndCondition(delegate() { var thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile <JobDriver_DoBill>(TargetIndex.A); this.FailOn <JobDriver_DoBill>(delegate() { if (!(this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver)) { return(false); } if (this.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } return(false); }); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell)); var tableThing = this.job.GetTarget(TargetIndex.A).Thing as Building_СontainmentBreach; CompRefuelable refuelableComp = tableThing.GetComp <CompRefuelable>(); Toil toil = new Toil(); toil.initAction = delegate() { this.job.bill.Notify_DoBillStarted(this.pawn); this.workCycleProgress = this.job.bill.recipe.workAmount; }; toil.tickAction = delegate() { this.workCycleProgress -= StatExtension.GetStatValue(this.pawn, StatDefOf.WorkToMake, true); tableThing.UsedThisTick(); if (!tableThing.CurrentlyUsableForBills() || (refuelableComp != null && !refuelableComp.HasFuel)) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); } if (this.workCycleProgress <= 0f) { SkillDef workSkill = this.job.bill.recipe.workSkill; if (workSkill != null) { SkillRecord skill = this.pawn.skills.GetSkill(workSkill); if (skill != null) { skill.Learn(0.11f * this.job.bill.recipe.workSkillLearnFactor, false); } } GenSpawn.Spawn(tableThing.GetKorsolianToxin(this.job.bill.recipe), tableThing.InteractionCell, tableThing.Map, 0); Toils_Reserve.Release(TargetIndex.A); PawnUtility.GainComfortFromCellIfPossible(this.pawn, false); this.job.bill.Notify_IterationCompleted(this.pawn, null); this.ReadyForNextToil(); } }; toil.defaultCompleteMode = ToilCompleteMode.Never; ToilEffects.WithEffect(toil, () => this.job.bill.recipe.effectWorking, TargetIndex.A); ToilEffects.PlaySustainerOrSound(toil, () => toil.actor.CurJob.bill.recipe.soundWorking); ToilEffects.WithProgressBar(toil, TargetIndex.A, delegate() { return(PurpleIvyUtils.GetPercentageFromPartWhole (this.job.bill.recipe.workAmount - this.workCycleProgress, (int)this.job.bill.recipe.workAmount) / 100f); }, false, 0.5f); ToilFailConditions.FailOn <Toil>(toil, delegate() { IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver; return(this.job.bill.suspended || this.job.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills())); }); yield return(toil); yield break; }
protected override Toil DoBill() { var tableThing = job.GetTarget(BillGiverInd).Thing as Building_WorkTable; var refuelableComp = tableThing.GetComp <CompRefuelable>(); var toil = new Toil(); toil.initAction = delegate { var objectThing = job.GetTarget(IngredientInd).Thing; job.bill.Notify_DoBillStarted(pawn); costHitPointsPerCycle = (int)(objectThing.MaxHitPoints * Settings.costFromMaxHitPoints); workCycleProgress = workCycle = Math.Max(job.bill.recipe.workAmount, 10f); }; toil.tickAction = delegate { var objectThing = job.GetTarget(IngredientInd).Thing; if (objectThing == null || objectThing.Destroyed) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } workCycleProgress -= StatExtension.GetStatValue(pawn, StatDefOf.WorkToMake, true); tableThing.UsedThisTick(); if (!(tableThing.CurrentlyUsableForBills() && (refuelableComp == null || refuelableComp.HasFuel))) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } if (workCycleProgress <= 0) { int remainingHitPoints = objectThing.MaxHitPoints - objectThing.HitPoints; if (remainingHitPoints > 0) { objectThing.HitPoints += (int)Math.Min(remainingHitPoints, costHitPointsPerCycle); } float skillPerc = 0.5f; var skillDef = job.RecipeDef.workSkill; if (skillDef != null) { var skill = pawn.skills.GetSkill(skillDef); if (skill != null) { skillPerc = (float)skill.Level / 20f; skill.Learn(0.11f * job.RecipeDef.workSkillLearnFactor); } } if (Settings.chances[objectThing.def.techLevel] > 1 - Mathf.Pow(Rand.Value, 1 + skillPerc * 3f)) { objectThing.HitPoints -= Rand.RangeInclusive(costHitPointsPerCycle, costHitPointsPerCycle * 4); MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "Failed"); } pawn.GainComfortFromCellIfPossible(); if (objectThing.HitPoints <= 0) { // recycling whats left... float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc); var list = JobDriverUtils.Reclaim(objectThing, skillFactor * 0.1f); pawn.Map.reservationManager.Release(job.targetB, pawn, job); objectThing.Destroy(DestroyMode.Vanish); if (list.Count > 1) { for (int j = 1; j < list.Count; j++) { if (!GenPlace.TryPlaceThing(list [j], pawn.Position, pawn.Map, ThingPlaceMode.Near, null)) { Log.Error("MendAndRecycle :: " + pawn + " could not drop recipe product " + list [j] + " near " + pawn.Position); } } } list[0].SetPositionDirect(pawn.Position); job.targetB = list[0]; job.bill.Notify_IterationCompleted(pawn, list); pawn.Map.reservationManager.Reserve(pawn, job, job.targetB, 1); ReadyForNextToil(); } else if (objectThing.HitPoints == objectThing.MaxHitPoints) { // fixed! if (Settings.removesDeadman && objectThing is Apparel mendApparel) { ApparelWornByCorpseInt.SetValue(mendApparel, false); } var list = new List <Thing> (); list.Add(objectThing); job.bill.Notify_IterationCompleted(pawn, list); ReadyForNextToil(); } else if (objectThing.HitPoints > objectThing.MaxHitPoints) { Log.Error("MendAndRecycle :: This should never happen! HitPoints > MaxHitPoints"); pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } workCycleProgress = workCycle; } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect(() => job.bill.recipe.effectWorking, BillGiverInd); toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking); toil.WithProgressBar(BillGiverInd, () => { var objectThing = job.GetTarget(IngredientInd).Thing; return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints); }, false, 0.5f); toil.FailOn(() => { var billGiver = job.GetTarget(BillGiverInd).Thing as IBillGiver; return(job.bill.suspended || job.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills())); }); return(toil); }
// Token: 0x06000028 RID: 40 RVA: 0x00003048 File Offset: 0x00001248 public void addHediffToPawn(Pawn p, HediffDef _heddiff, float _addhediffChance, float _hediffseverity, bool onlylungs) { bool flag = !Rand.Chance(_addhediffChance); if (!flag) { Hediff hediff = HediffMaker.MakeHediff(_heddiff, p, null); hediff.Severity = _hediffseverity; bool flag2 = onlylungs && p.health.capacities.CapableOf(PawnCapacityDefOf.Breathing); if (flag2) { List <BodyPartRecord> list = new List <BodyPartRecord>(); float num = 0.028758334f; num *= StatExtension.GetStatValue(p, StatDefOf.ToxicSensitivity, true); bool flag3 = num != 0f; if (flag3) { float num2 = Mathf.Lerp(0.85f, 1.15f, Rand.ValueSeeded(p.thingIDNumber ^ 74374237)); num *= num2; } float statValue = StatExtension.GetStatValue(p, StatDefOf.ToxicSensitivity, true); hediff.Severity = _hediffseverity * statValue; foreach (BodyPartRecord bodyPartRecord in p.health.hediffSet.GetNotMissingParts(0, BodyPartDepth.Inside, null, null)) { bool flag4 = bodyPartRecord.def.tags.Contains(BodyPartTagDefOf.BreathingSource); if (flag4) { list.Add(bodyPartRecord); } } bool flag5 = list.Count > 0; if (flag5) { for (int i = 0; i < list.Count; i++) { Hediff hediff2; if (p == null) { hediff2 = null; } else { Pawn_HealthTracker health = p.health; if (health == null) { hediff2 = null; } else { HediffSet hediffSet = health.hediffSet; hediff2 = (hediffSet?.GetFirstHediffOfDef(_heddiff, false)); } } Hediff hediff3 = hediff2; float num3 = Rand.Range(0.1f, 0.2f); bool flag6 = hediff3 != null; if (flag6) { hediff3.Severity += num3 * statValue; } else { p.health.AddHediff(hediff, list[i], null, null); } } } } else { Hediff hediff4; if (p == null) { hediff4 = null; } else { Pawn_HealthTracker health2 = p.health; if (health2 == null) { hediff4 = null; } else { HediffSet hediffSet2 = health2.hediffSet; hediff4 = (hediffSet2?.GetFirstHediffOfDef(_heddiff, false)); } } Hediff hediff5 = hediff4; float num4 = Rand.Range(0.1f, 0.2f); float statValue2 = StatExtension.GetStatValue(p, StatDefOf.ToxicSensitivity, true); bool flag7 = hediff5 != null; if (flag7) { hediff5.Severity += num4 * statValue2; } else { hediff.Severity = _hediffseverity * statValue2; p.health.AddHediff(hediff, null, null, null); } } } }
public static IEnumerable <Thing> ButcherCorpseProducts(Corpse corpse, Pawn butcher) { bool flag = corpse.def.butcherProducts != null; bool flag6 = flag; if (flag6) { IEnumerator <Thing> enumerator = corpse.InnerPawn.ButcherProducts(butcher, 1f).GetEnumerator(); try { while (enumerator.MoveNext()) { Thing thing2 = enumerator.Current; yield return(thing2); } } finally { enumerator.Dispose(); } enumerator = null; enumerator = null; } else { bool isFlesh = corpse.InnerPawn.RaceProps.IsFlesh; bool flag7 = isFlesh; if (flag7) { FilthMaker.TryMakeFilth(butcher.Position, butcher.Map, ThingDefOf.Filth_Blood, corpse.InnerPawn.LabelCap, 1); } } bool flag2 = corpse.InnerPawn.RaceProps.meatDef != null; bool flag8 = flag2; if (flag8) { FilthMaker.TryMakeFilth(butcher.Position, butcher.Map, ThingDefOf.Filth_Blood, corpse.InnerPawn.LabelCap, 1); int num = GenMath.RoundRandom(StatExtension.GetStatValue(corpse.InnerPawn, StatDefOf.MeatAmount, true) * 0f); } bool flag3 = corpse.InnerPawn.def.race.leatherDef != null; bool flag9 = flag3; if (flag9) { int num2 = GenMath.RoundRandom(StatExtension.GetStatValue(corpse.InnerPawn, StatDefOf.LeatherAmount, true) * 0f); bool flag4 = num2 > 0; bool flag10 = flag4; if (flag10) { Thing thing = ThingMaker.MakeThing(corpse.InnerPawn.def.race.leatherDef, null); bool flag5 = thing != null; bool flag11 = flag5; if (flag11) { thing.stackCount = num2; yield return(thing); } thing = null; thing = null; } } yield break; }
public static void bleedRatePostfix(ref float __result, HediffSet __instance) { __result *= StatExtension.GetStatValue((Thing)__instance.pawn, StatDef.Named("BleedRate"), true); }
Toil SowSeedToil() { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Never; toil.initAction = delegate { var actor = toil.actor; if (IsActorCarryingAppropriateSeed(actor, job.plantDefToSow)) { var plant = (Plant)GenSpawn.Spawn(job.plantDefToSow, TargetLocA, actor.Map); plant.Growth = 0; plant.sown = true; job.targetC = plant; actor.Reserve(job.targetC, job, 1); sowWorkDone = 0; } else { EndJobWith(JobCondition.Incompletable); } }; toil.tickAction = delegate { var actor = toil.actor; var plant = (Plant)job.targetC.Thing; if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Plants, 0.22f); } if (plant.LifeStage != PlantLifeStage.Sowing) { Log.Error(this + " getting sowing work while not in Sowing life stage."); } sowWorkDone += StatExtension.GetStatValue(actor, StatDefOf.PlantWorkSpeed, true); if (sowWorkDone >= plant.def.plant.sowWork) { if (!IsActorCarryingAppropriateSeed(actor, job.plantDefToSow)) { EndJobWith(JobCondition.Incompletable); return; } if (actor.carryTracker.CarriedThing.stackCount <= 1) { actor.carryTracker.CarriedThing.Destroy(DestroyMode.Cancel); } else { actor.carryTracker.CarriedThing.stackCount--; } plant.Growth = 0.05f; plant.Map.mapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things); actor.records.Increment(RecordDefOf.PlantsSown); ReadyForNextToil(); } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.FailOnDespawnedNullOrForbidden(targetCellIndex); toil.FailOnCannotTouch(targetCellIndex, PathEndMode.Touch); toil.WithEffect(EffecterDefOf.Sow, targetCellIndex); toil.WithProgressBar(targetCellIndex, () => sowWorkDone / job.plantDefToSow.plant.sowWork, true, -0.5f); toil.PlaySustainerOrSound(() => SoundDefOf.Interact_Sow); toil.AddFinishAction(delegate { var actor = toil.actor; var thing = job.targetC.Thing; if (thing != null) { var plant = (Plant)thing; if (sowWorkDone < plant.def.plant.sowWork && !thing.Destroyed) { thing.Destroy(DestroyMode.Vanish); } actor.Map.reservationManager.Release(job.targetC, actor, job); job.targetC = null; } }); toil.activeSkill = (() => SkillDefOf.Plants); return(toil); }
// Token: 0x0600002F RID: 47 RVA: 0x00002870 File Offset: 0x00000A70 public static void DoTend(Pawn doctor, Pawn patient, Cloakgen medkit) { bool flag = patient.health.HasHediffsNeedingTend(false); if (flag) { bool flag2 = medkit != null && medkit.Destroyed; if (flag2) { // Log.Warning("Tried to use destroyed medkit.", false); medkit = null; } float num = HealthShardTendUtility.CalculateBaseTendQuality(doctor, patient, medkit.kitComp.Props.medicine ?? null); HealthShardTendUtility.GetOptimalHediffsToTendWithSingleTreatment(patient, medkit.kitComp.Props.medicine != null, HealthShardTendUtility.tmpHediffsToTend, null); for (int i = 0; i < HealthShardTendUtility.tmpHediffsToTend.Count; i++) { HealthShardTendUtility.tmpHediffsToTend[i].Tended(num, i); } bool flag3 = doctor != null && doctor.Faction == Faction.OfPlayer && patient.Faction != doctor.Faction && !patient.IsPrisoner && patient.Faction != null; if (flag3) { patient.mindState.timesGuestTendedToByPlayer++; } bool flag4 = doctor != null && doctor.IsColonistPlayerControlled; if (flag4) { patient.records.AccumulateStoryEvent(StoryEventDefOf.TendedByPlayer); } bool flag5 = doctor != null && doctor.RaceProps.Humanlike && patient.RaceProps.Animal; if (flag5) { bool flag6 = RelationsUtility.TryDevelopBondRelation(doctor, patient, 0.004f); if (flag6) { bool flag7 = doctor.Faction != null && doctor.Faction != patient.Faction; if (flag7) { InteractionWorker_RecruitAttempt.DoRecruit(doctor, patient, 1f, false); } } } patient.records.Increment(RecordDefOf.TimesTendedTo); bool flag8 = doctor != null; if (flag8) { doctor.records.Increment(RecordDefOf.TimesTendedOther); } bool flag9 = doctor == patient && !doctor.Dead; if (flag9) { doctor.mindState.Notify_SelfTended(); } bool flag10 = medkit.kitComp.Props.medicine != null; if (flag10) { bool flag11 = patient.Spawned || (doctor != null && doctor.Spawned); if (flag11) { bool flag12 = medkit.kitComp.Props.medicine != null && StatExtension.GetStatValueAbstract(medkit.kitComp.Props.medicine, StatDefOf.MedicalPotency, null) > StatExtension.GetStatValueAbstract(ThingDefOf.MedicineIndustrial, StatDefOf.MedicalPotency, null); if (flag12) { SoundStarter.PlayOneShot(SoundDefOf.TechMedicineUsed, new TargetInfo(patient.Position, patient.Map, false)); } } } } }
public void ChangeTheGraphics() { if (this.Map != null) { if ((this.Position.GetTerrain(this.Map) == TerrainDef.Named("Ice")) || (this.Position.GetSnowDepth(this.Map) > 0) || (this.Map.mapTemperature.OutdoorTemp < -10f)) { LongEventHandler.ExecuteWhenFinished(delegate { Vector2 vector = this.ageTracker.CurKindLifeStage.bodyGraphicData.drawSize; Graphic_Multi nakedGraphic = (Graphic_Multi)GraphicDatabase.Get <Graphic_Multi>(this.ageTracker.CurKindLifeStage.bodyGraphicData.texPath + "Winter", ShaderDatabase.Cutout, vector, Color.white); this.pawn_renderer.graphics.nakedGraphic = nakedGraphic; (this.pawn_renderer.graphics.nakedGraphic.data = new GraphicData()).shadowData = this.ageTracker.CurKindLifeStage.bodyGraphicData.shadowData; StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMin, -60f); StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMax, 10f); }); woolType = 1; } else if ((this.Position.GetTerrain(this.Map) == TerrainDef.Named("MossyTerrain")) || (this.Position.GetTerrain(this.Map) == TerrainDef.Named("MarshyTerrain")) || (this.Position.GetTerrain(this.Map) == TerrainDef.Named("SoilRich")) || (this.Position.GetTerrain(this.Map).IsWater)) { LongEventHandler.ExecuteWhenFinished(delegate { Vector2 vector = this.ageTracker.CurKindLifeStage.bodyGraphicData.drawSize; Graphic_Multi nakedGraphic = (Graphic_Multi)GraphicDatabase.Get <Graphic_Multi>(this.ageTracker.CurKindLifeStage.bodyGraphicData.texPath + "Jungle", ShaderDatabase.Cutout, vector, Color.white); this.pawn_renderer.graphics.nakedGraphic = nakedGraphic; (this.pawn_renderer.graphics.nakedGraphic.data = new GraphicData()).shadowData = this.ageTracker.CurKindLifeStage.bodyGraphicData.shadowData; StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMin, -10f); StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMax, 35f); }); woolType = 2; } else if ((this.Position.GetTerrain(this.Map) == TerrainDef.Named("Sand")) || (this.Position.GetTerrain(this.Map) == TerrainDef.Named("SoftSand"))) { LongEventHandler.ExecuteWhenFinished(delegate { Vector2 vector = this.ageTracker.CurKindLifeStage.bodyGraphicData.drawSize; Graphic_Multi nakedGraphic = (Graphic_Multi)GraphicDatabase.Get <Graphic_Multi>(this.ageTracker.CurKindLifeStage.bodyGraphicData.texPath + "Desert", ShaderDatabase.Cutout, vector, Color.white); this.pawn_renderer.graphics.nakedGraphic = nakedGraphic; (this.pawn_renderer.graphics.nakedGraphic.data = new GraphicData()).shadowData = this.ageTracker.CurKindLifeStage.bodyGraphicData.shadowData; StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMin, 0f); StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMax, 65f); }); woolType = 3; } else { LongEventHandler.ExecuteWhenFinished(delegate { Vector2 vector = this.ageTracker.CurKindLifeStage.bodyGraphicData.drawSize; Graphic_Multi nakedGraphic = (Graphic_Multi)GraphicDatabase.Get <Graphic_Multi>(this.ageTracker.CurKindLifeStage.bodyGraphicData.texPath, ShaderDatabase.Cutout, vector, Color.white); this.pawn_renderer.graphics.nakedGraphic = nakedGraphic; (this.pawn_renderer.graphics.nakedGraphic.data = new GraphicData()).shadowData = this.ageTracker.CurKindLifeStage.bodyGraphicData.shadowData; StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMin, -10f); StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMax, 35f); }); woolType = 0; } } else { StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMin, -60f); StatExtension.SetStatBaseValue(this.def, StatDefOf.ComfyTemperatureMax, 60f); } }
protected override Toil DoBill() { var objectThing = job.GetTarget(objectTI).Thing; var tableThing = job.GetTarget(tableTI).Thing as Building_WorkTable; var toil = new Toil(); toil.initAction = delegate { job.bill.Notify_DoBillStarted(pawn); failChance = ChanceDef.GetFor(objectThing); workCycleProgress = workCycle = Math.Max(job.bill.recipe.workAmount, 10f); }; toil.tickAction = delegate { if (objectThing == null || objectThing.Destroyed) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } workCycleProgress -= StatExtension.GetStatValue(pawn, StatDefOf.WorkToMake, true); tableThing.UsedThisTick(); if (!tableThing.UsableNow) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } if (workCycleProgress <= 0) { int remainingHitPoints = objectThing.MaxHitPoints - objectThing.HitPoints; if (remainingHitPoints > 0) { objectThing.HitPoints += (int)Math.Min(remainingHitPoints, fixedHitPointsPerCycle); } float skillPerc = 0.5f; var skillDef = job.RecipeDef.workSkill; if (skillDef != null) { var skill = pawn.skills.GetSkill(skillDef); if (skill != null) { skillPerc = (float)skill.Level / 20f; skill.Learn(0.11f * job.RecipeDef.workSkillLearnFactor); } } var qualityComponent = objectThing.TryGetComp <CompQuality>(); if (qualityComponent != null && qualityComponent.Quality > QualityCategory.Awful) { var qc = qualityComponent.Quality; float skillFactor = Mathf.Lerp(1.5f, 0f, skillPerc); if (failChance != null && Rand.Value < failChance.Chance(qc) * skillFactor) { objectThing.HitPoints -= fixedFailedDamage; MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "Failed"); } } pawn.GainComfortFromCellIfPossible(); if (objectThing.HitPoints <= 0) { // recycling whats left... float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc); var list = JobDriverUtils.Reclaim(objectThing, skillFactor * 0.1f); pawn.Map.reservationManager.Release(job.targetB, pawn, job); objectThing.Destroy(DestroyMode.Vanish); if (list.Count > 1) { for (int j = 1; j < list.Count; j++) { if (!GenPlace.TryPlaceThing(list [j], pawn.Position, pawn.Map, ThingPlaceMode.Near, null)) { Log.Error("Mending :: " + pawn + " could not drop recipe product " + list [j] + " near " + pawn.Position); } } } list[0].SetPositionDirect(pawn.Position); job.targetB = list[0]; job.bill.Notify_IterationCompleted(pawn, list); pawn.Map.reservationManager.Reserve(pawn, job, job.targetB, 1); ReadyForNextToil(); } else if (objectThing.HitPoints == objectThing.MaxHitPoints) { // fixed! var mendApparel = objectThing as Apparel; if (mendApparel != null) { ApparelWornByCorpseInt.SetValue(mendApparel, false); } var list = new List <Thing> (); list.Add(objectThing); job.bill.Notify_IterationCompleted(pawn, list); ReadyForNextToil(); } else if (objectThing.HitPoints > objectThing.MaxHitPoints) { Log.Error("Mending :: This should never happen! HitPoints > MaxHitPoints"); pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } workCycleProgress = workCycle; } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect(() => job.bill.recipe.effectWorking, tableTI); toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking); toil.WithProgressBar(tableTI, delegate { return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints); }, false, 0.5f); toil.FailOn(() => { var billGiver = job.GetTarget(tableTI).Thing as IBillGiver; return(job.bill.suspended || job.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills())); }); return(toil); }
public static int EstimatedMeatCount(this Pawn p) { return((int)(StatExtension.GetStatValue(p, StatDefOf.MeatAmount))); }
protected override IEnumerable <Toil> MakeNewToils() { base.AddEndCondition(delegate() { var thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile <JobDriver_DoBill>(TargetIndex.A); this.FailOn <JobDriver_DoBill>(delegate() { if (!(this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver)) { return(false); } if (this.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } return(false); }); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell)); var tableThing = this.job.GetTarget(TargetIndex.A).Thing as Building_СontainmentBreach; CompRefuelable refuelableComp = tableThing.GetComp <CompRefuelable>(); Toil toil = new Toil(); toil.initAction = delegate() { this.job.bill.Notify_DoBillStarted(this.pawn); this.workCycleProgress = this.job.bill.recipe.workAmount; }; toil.tickAction = delegate() { this.workCycleProgress -= StatExtension.GetStatValue(this.pawn, StatDefOf.WorkToMake, true); tableThing.UsedThisTick(); if (!tableThing.CurrentlyUsableForBills() || (refuelableComp != null && !refuelableComp.HasFuel)) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true, true); } if (this.workCycleProgress <= 0f) { SkillDef workSkill = this.job.bill.recipe.workSkill; if (workSkill != null) { SkillRecord skill = this.pawn.skills.GetSkill(workSkill); if (skill != null) { skill.Learn(0.11f * this.job.bill.recipe.workSkillLearnFactor, false); } } var research = PurpleIvyData.AlienStudy.Where(x => x.TechprintsApplied == 0 && GetActor().Map.listerThings.ThingsOfDef (ThingDef.Named("Techprint_" + x.defName)).Count == 0).RandomElement(); if (research != null) { GenSpawn.Spawn(ThingDef.Named("Techprint_" + research.defName), GetActor().Position, GetActor().Map); } job.bill.Notify_PawnDidWork(GetActor()); Bill_Production bill_Production = this.pawn.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { this.Map.resourceCounter.UpdateResourceCounts(); } Toils_Recipe.FinishRecipeAndStartStoringProduct(); job.bill.Notify_IterationCompleted(GetActor(), null); Toils_Reserve.Release(TargetIndex.A); PawnUtility.GainComfortFromCellIfPossible(this.pawn, false); this.ReadyForNextToil(); } }; toil.defaultCompleteMode = ToilCompleteMode.Never; ToilEffects.WithEffect(toil, () => this.job.bill.recipe.effectWorking, TargetIndex.A); ToilEffects.PlaySustainerOrSound(toil, () => toil.actor.CurJob.bill.recipe.soundWorking); ToilEffects.WithProgressBar(toil, TargetIndex.A, delegate() { return(PurpleIvyUtils.GetPercentageFromPartWhole (this.job.bill.recipe.workAmount - this.workCycleProgress, (int)this.job.bill.recipe.workAmount) / 100f); }, false, 0.5f); ToilFailConditions.FailOn <Toil>(toil, delegate() { IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver; return(this.job.bill.suspended || this.job.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills())); }); yield return(toil); yield break; }
protected override Toil DoBill() { Pawn actor = GetActor(); SkillRecord skill = actor.skills.GetSkill(SkillDefOf.Crafting); Job curJob = actor.jobs.curJob; Thing objectThing = curJob.GetTarget(objectTI).Thing; CompQuality qualityComponent = objectThing.TryGetComp <CompQuality>(); Building_WorkTable tableThing = curJob.GetTarget(tableTI).Thing as Building_WorkTable; CompPowerTrader tablePowerTraderComp = tableThing.GetComp <CompPowerTrader>(); Toil toil = new Toil(); toil.initAction = delegate { curJob.bill.Notify_DoBillStarted(); this.processedHitPoints = 0; this.failChance = ChanceDef.GetFor(objectThing); this.workCycleProgress = this.workCycle = Math.Max(curJob.bill.recipe.workAmount, 10f); }; toil.tickAction = delegate { if (objectThing == null || objectThing.Destroyed) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); } workCycleProgress -= StatExtension.GetStatValue(actor, StatDefOf.WorkToMake, true); tableThing.Tick(); if (!tableThing.UsableNow) { actor.jobs.EndCurrentJob(JobCondition.Incompletable); } if (workCycleProgress <= 0) { objectThing.HitPoints -= fixedHitPointsPerCycle; if (tablePowerTraderComp != null && tablePowerTraderComp.PowerOn) { processedHitPoints += fixedHitPointsPerCycle; } else { processedHitPoints += fixedHitPointsPerCycle / 2; } if (skill == null) { Log.Error("Mending :: This should never happen! skill == null"); actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } float skillPerc = (float)skill.Level / 20f; skill.Learn(0.33f); if (qualityComponent != null && qualityComponent.Quality > QualityCategory.Awful) { QualityCategory qc = qualityComponent.Quality; float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc); if (failChance != null && Rand.Value < failChance.Chance(qc) * skillFactor) { objectThing.HitPoints -= fixedFailedDamage; MoteMaker.ThrowText(actor.DrawPos, actor.Map, "Failed"); } } actor.GainComfortFromCellIfPossible(); if (objectThing.HitPoints <= 0) { pawn.Map.reservationManager.Release(curJob.targetB, pawn); objectThing.Destroy(DestroyMode.Vanish); float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc); float healthPerc = (float)processedHitPoints / (float)objectThing.MaxHitPoints; float healthFactor = Mathf.Lerp(0f, 0.4f, healthPerc); var list = JobDriverUtils.Reclaim(objectThing, skillFactor * healthFactor); 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("Mending :: " + actor + " could not drop recipe product " + list [j] + " near " + actor.Position); } } } list[0].SetPositionDirect(actor.Position); curJob.bill.Notify_IterationCompleted(actor, list); curJob.targetB = list[0]; pawn.Map.reservationManager.Reserve(pawn, curJob.targetB, 1); ReadyForNextToil(); } workCycleProgress = workCycle; } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect(() => curJob.bill.recipe.effectWorking, tableTI); toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking); toil.WithProgressBar(tableTI, delegate { return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints); }, false, 0.5f); toil.FailOn(() => { return(toil.actor.CurJob.bill.suspended || !tableThing.UsableNow); }); return(toil); }
protected override Toil DoBill() { var tableThing = job.GetTarget(BillGiverInd).Thing as Building_WorkTable; var tablePowerTraderComp = tableThing.GetComp <CompPowerTrader> (); var toil = new Toil(); toil.initAction = delegate { var objectThing = job.GetTarget(IngredientInd).Thing; job.bill.Notify_DoBillStarted(pawn); costHitPointsPerCycle = (int)(objectThing.MaxHitPoints * Settings.costFromMaxHitPoints); processedHitPoints = 0; workCycleProgress = workCycle = Math.Max(job.bill.recipe.workAmount, 10f); }; toil.tickAction = delegate { var objectThing = job.GetTarget(IngredientInd).Thing; if (objectThing == null || objectThing.Destroyed) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } workCycleProgress -= StatExtension.GetStatValue(pawn, StatDefOf.WorkToMake, true); tableThing.UsedThisTick(); if (!tableThing.CurrentlyUsableForBills()) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } if (workCycleProgress <= 0) { objectThing.HitPoints -= costHitPointsPerCycle; if (tablePowerTraderComp != null && tablePowerTraderComp.PowerOn) { processedHitPoints += costHitPointsPerCycle; } else { processedHitPoints += costHitPointsPerCycle / 2; } float skillPerc = 0.5f; var skillDef = job.RecipeDef.workSkill; if (skillDef != null) { var skill = pawn.skills.GetSkill(skillDef); if (skill != null) { skillPerc = (float)skill.Level / 20f; skill.Learn(0.11f * job.RecipeDef.workSkillLearnFactor); } } if (Settings.chances[objectThing.def.techLevel] > 1 - Mathf.Pow(Rand.Value, 1 + skillPerc * 3f)) { objectThing.HitPoints -= Rand.RangeInclusive(costHitPointsPerCycle, costHitPointsPerCycle * 4); MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "Failed"); } pawn.GainComfortFromCellIfPossible(); if (objectThing.HitPoints <= 0) { pawn.Map.reservationManager.Release(job.targetB, pawn, job); objectThing.Destroy(DestroyMode.Vanish); float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc); float healthPerc = (float)processedHitPoints / (float)objectThing.MaxHitPoints; float healthFactor = Mathf.Lerp(0f, 0.4f, healthPerc); var list = JobDriverUtils.Reclaim(objectThing, skillFactor * healthFactor); if (list.Count > 1) { for (int j = 1; j < list.Count; j++) { if (!GenPlace.TryPlaceThing(list [j], pawn.Position, pawn.Map, ThingPlaceMode.Near, null)) { Log.Error("MendAndRecycle :: " + pawn + " could not drop recipe product " + list [j] + " near " + pawn.Position); } } } if (list.Count >= 1) { list [0].SetPositionDirect(pawn.Position); job.bill.Notify_IterationCompleted(pawn, list); job.SetTarget(IngredientInd, list[0]); pawn.Map.reservationManager.Reserve(pawn, job, job.GetTarget(IngredientInd), 1); ReadyForNextToil(); } else { Log.Message("MendAndRecycle :: " + pawn + " could not reclaim anything from " + objectThing); pawn.jobs.EndCurrentJob(JobCondition.Succeeded); } } workCycleProgress = workCycle; } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect(() => job.bill.recipe.effectWorking, BillGiverInd); toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking); toil.WithProgressBar(BillGiverInd, delegate { var objectThing = job.GetTarget(IngredientInd).Thing; return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints); }, false, 0.5f); toil.FailOn(() => { return(toil.actor.CurJob.bill.suspended || !tableThing.CurrentlyUsableForBills()); }); return(toil); }