Пример #1
0
        // Token: 0x06000026 RID: 38 RVA: 0x000026A3 File Offset: 0x000008A3
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddEndCondition(delegate()
            {
                if (this.pawn.Faction == Faction.OfPlayer && HealthAIUtility.ShouldBeTendedNowByPlayer(this.pawn))
                {
                    return(JobCondition.Ongoing);
                }
                if (this.pawn.Faction != Faction.OfPlayer && this.pawn.health.HasHediffsNeedingTend(false))
                {
                    return(JobCondition.Ongoing);
                }
                return(JobCondition.Succeeded);
            });
            int ticks = (int)(1f / StatExtension.GetStatValue(this.pawn, StatDefOf.MedicalTendSpeed, true) * 600f);

            yield return(ToilEffects.PlaySustainerOrSound(ToilEffects.WithProgressBarToilDelay(Toils_General.Wait(ticks, 0), (TargetIndex)1, false, -0.5f), SoundDefOf.Interact_Tend));

            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Pawn     actor  = toil.actor;
                Cloakgen medkit = actor.apparel.WornApparel.OfType <Cloakgen>().FirstOrDefault <Cloakgen>();
                float    num    = (!actor.RaceProps.Animal) ? 500f : 175f;
                float    num2   = (medkit != null) ? medkit.kitComp.Props.medicine.MedicineTendXpGainFactor : 0.5f;
                actor.skills.Learn(SkillDefOf.Medicine, num * num2, false);
                HealthShardTendUtility.DoTend(actor, actor, medkit);
            };
            toil.defaultCompleteMode = (ToilCompleteMode)1;
            yield return(toil);

            yield break;
        }
Пример #2
0
        // Token: 0x06000031 RID: 49 RVA: 0x00002B50 File Offset: 0x00000D50
        public static float CalculateBaseTendQuality(Pawn doctor, Pawn patient, float medicinePotency, float medicineQualityMax)
        {
            bool  flag = doctor != null;
            float num;

            if (flag)
            {
                num = StatExtension.GetStatValue(doctor, StatDefOf.MedicalTendQuality, true);
            }
            else
            {
                num = 0.75f;
            }
            num *= medicinePotency;
            Building_Bed building_Bed = (patient != null) ? RestUtility.CurrentBed(patient) : null;
            bool         flag2        = building_Bed != null;

            if (flag2)
            {
                num += StatExtension.GetStatValue(building_Bed, StatDefOf.MedicalTendQualityOffset, true);
            }
            bool flag3 = doctor == patient && doctor != null;

            if (flag3)
            {
                num *= 0.7f;
            }
            return(Mathf.Clamp(num, 0f, medicineQualityMax));
        }
Пример #3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ///
            //Set fail conditions
            ///

            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.AddEndCondition(() => { return(this.Deliveree.health.ShouldBeTendedNow ? JobCondition.Ongoing : JobCondition.Succeeded); });
            //Note we only fail on forbidden if the target doesn't start that way
            //This helps haul-aside jobs on forbidden items



            ///
            //Define Toil
            ///



            ///
            //Toils Start
            ///

            //Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.Reserve(TargetIndex.A));


            StatWorker statWorker = new StatWorker();

            statWorker.InitSetStat(StatDefOf.BaseHealingQuality);

            Toil toilApplyMedicine = new Toil();

            toilApplyMedicine.initAction = () =>
            {
                Thing dummy;
                Medicine.holder.TryDrop(Medicine, pawn.Position + IntVec3.North.RotatedBy(pawn.Rotation), ThingPlaceMode.Direct, out dummy);
            };
            yield return(toilApplyMedicine);

            yield return(Toils_Tend.PickupMedicine(TargetIndex.B, Deliveree));

            Toil toilGoTodeliveree = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);

            yield return(toilGoTodeliveree);

            int  duration          = (int)(1.0 / (double)StatExtension.GetStatValue((Thing)pawn, StatDefOf.HealingSpeed, true) * 600.0);
            Toil toilDelivereeWait = new Toil();

            toilDelivereeWait.initAction = () =>
            {
                Deliveree.drafter.TakeOrderedJob(new Job(JobDefOf.Wait, duration));
            };

            yield return(Toils_General.Wait(duration));

            yield return(Toils_Tend.FinalizeTend(Deliveree));

            yield return(Toils_Jump.Jump(toilGoTodeliveree));
        }
        public string DesignationLabel(Designation designation)
        {
            // label, dist, yield.
            var thing = designation.target.Thing;

            return("Fluffy.Manager.DesignationLabel".Translate(
                       thing.LabelCap,
                       Distance(thing, manager.map.GetBaseCenter()).ToString("F0"),
                       StatExtension.GetStatValue(thing, StatDefOf.MeatAmount).ToString("F0"),
                       thing.def.race.meatDef.LabelCap));
        }
Пример #5
0
        /*
         * //maybe change?
         * protected abstract int GatherResourcesIntervalDays
         * {
         *      get;
         * }
         *
         * //add breastsize modifier?
         * protected abstract int ResourceAmount
         * {
         *      get;
         * }
         * //add more  milks?
         * protected abstract ThingDef ResourceDef
         * {
         *      get;
         * }
         */

        protected override IEnumerable <Toil> MakeNewToils()
        {
            ToilFailConditions.FailOnDespawnedNullOrForbidden <JobDriver_GatherHumanBodyResources>(this, TargetIndex.A);
            ToilFailConditions.FailOnNotCasualInterruptible <JobDriver_GatherHumanBodyResources>(this, TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil wait = new Toil();

            wait.initAction = delegate
            {
                Pawn            milker  = base.pawn;
                LocalTargetInfo target  = base.job.GetTarget(TargetIndex.A);
                Pawn            target2 = (Pawn)target.Thing;
                milker.pather.StopDead();
                PawnUtility.ForceWait(target2, 15000, null, true);
            };
            wait.tickAction = delegate
            {
                Pawn milker = base.pawn;
                milker.skills.Learn(SkillDefOf.Animals, 0.13f, false);
                gatherProgress += StatExtension.GetStatValue(milker, StatDefOf.AnimalGatherSpeed, true);
                if (gatherProgress >= WorkTotal)
                {
                    GetComp((Pawn)base.job.GetTarget(TargetIndex.A)).Gathered(base.pawn);
                    milker.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                }
            };
            wait.AddFinishAction((Action) delegate
            {
                Pawn milker            = base.pawn;
                LocalTargetInfo target = base.job.GetTarget(TargetIndex.A);
                Pawn target2           = (Pawn)target.Thing;
                if (target2 != null && target2.CurJobDef == JobDefOf.Wait_MaintainPosture)
                {
                    milker.jobs.EndCurrentJob(JobCondition.InterruptForced, true);
                }
            });
            ToilFailConditions.FailOnDespawnedOrNull <Toil>(wait, TargetIndex.A);
            ToilFailConditions.FailOnCannotTouch <Toil>(wait, TargetIndex.A, PathEndMode.Touch);
            wait.AddEndCondition((Func <JobCondition>) delegate
            {
                if (GetComp((Pawn)base.job.GetTarget(TargetIndex.A)).ActiveAndFull)
                {
                    return(JobCondition.Ongoing);
                }
                return(JobCondition.Incompletable);
            });
            wait.defaultCompleteMode = ToilCompleteMode.Never;
            ToilEffects.WithProgressBar(wait, TargetIndex.A, (Func <float>)(() => gatherProgress / WorkTotal), false, -0.5f);
            wait.activeSkill = (() => SkillDefOf.Animals);
            yield return(wait);
        }
Пример #6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ToilFailConditions.FailOnDespawnedNullOrForbidden(this, TargetIndex.A);
            ToilFailConditions.FailOnNotCasualInterruptible(this, TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil wait = new Toil();

            wait.initAction = delegate()
            {
                Pawn actor = wait.actor;
                Pawn pawn  = (Pawn)job.GetTarget(TargetIndex.A).Thing;
                actor.pather.StopDead();
                PawnUtility.ForceWait(pawn, 15000, null, true);
            };
            wait.tickAction = delegate()
            {
                Pawn actor = wait.actor;
                actor.skills.Learn(SkillDefOf.Animals, 0.13f, false);
                gatherProgress += StatExtension.GetStatValue(actor, StatDefOf.AnimalGatherSpeed, true);
                if (gatherProgress >= WorkTotal)
                {
                    GetComp((Pawn)((Thing)job.GetTarget(TargetIndex.A))).Gathered(this.pawn);
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                }
            };
            wait.AddFinishAction(delegate()
            {
                Pawn pawn = (Pawn)job.GetTarget(TargetIndex.A).Thing;
                if (pawn != null && pawn.CurJobDef == JobDefOf.Wait_MaintainPosture)
                {
                    pawn.jobs.EndCurrentJob(JobCondition.InterruptForced, true);
                }
            });
            ToilFailConditions.FailOnDespawnedOrNull <Toil>(wait, TargetIndex.A);
            ToilFailConditions.FailOnCannotTouch <Toil>(wait, TargetIndex.A, PathEndMode.Touch);
            wait.AddEndCondition(delegate()
            {
                if (!GetComp((Pawn)((Thing)this.job.GetTarget(TargetIndex.A))).ActiveAndFull)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            wait.defaultCompleteMode = ToilCompleteMode.Never;
            ToilEffects.WithProgressBar(wait, TargetIndex.A, () => this.gatherProgress / this.WorkTotal, false, -0.5f);
            wait.activeSkill = (() => SkillDefOf.Animals);
            yield return(wait);

            yield break;
        }
Пример #7
0
        // Token: 0x06000016 RID: 22 RVA: 0x000024F8 File Offset: 0x000006F8
        protected virtual float SpringChance(Pawn p)
        {
            float num;

            if (this.KnowsOfTrap(p))
            {
                num = 0.004f;
            }
            else
            {
                num = StatExtension.GetStatValue(this, StatDefOf.TrapSpringChance, true);
            }
            num *= GenMath.LerpDouble(0.4f, 0.8f, 0f, 1f, p.BodySize);
            return(Mathf.Clamp01(num));
        }
Пример #8
0
 private static float WeaponScoreGain(Thing weapon, StatDef accuracyDef)
 {
     if (weapon.def.IsRangedWeapon)
     {
         var    verbProperties = weapon.def.Verbs.Where(x => x.range > 0).First();
         double num            = (verbProperties.defaultProjectile.projectile.GetDamageAmount(weapon, null) * (float)verbProperties.burstShotCount);
         float  num2           = (StatExtension.GetStatValue(weapon, StatDefOf.RangedWeapon_Cooldown, true) + verbProperties.warmupTime) * 60f;
         float  num3           = (verbProperties.burstShotCount * verbProperties.ticksBetweenBurstShots);
         float  num4           = (num2 + num3) / 60f;
         var    dps            = (float)Math.Round(num / num4, 2);
         var    accuracy       = StatExtension.GetStatValue(weapon, accuracyDef, true) * 100f;
         return((float)Math.Round(dps * accuracy / 100f, 1));
     }
     else if (weapon.def.IsMeleeWeapon)
     {
         return(StatExtension.GetStatValue(weapon, StatDefOf.MeleeWeapon_AverageDPS, true));
     }
     return(0f);
 }
        // Token: 0x06000025 RID: 37 RVA: 0x00002904 File Offset: 0x00000B04
        private void DamagePawn(Pawn p)
        {
            float value = Rand.Value;
            float num   = StatExtension.GetStatValue(this, StatDefOf.TrapMeleeDamage, true) * Building_TrapRearmable.TrapDamageFactor.RandomInRange / (float)Building_TrapRearmable.DamageCount.RandomInRange;
            float num2  = num * 0.015f;
            int   num3  = 0;

            while ((float)num3 < (float)Building_TrapRearmable.DamageCount.RandomInRange)
            {
                DamageInfo damageInfo;
                damageInfo = new DamageInfo(DamageDefOf.Stab, num, num2, -1f, this, null, null, 0, null);
                DamageWorker.DamageResult damageResult = p.TakeDamage(damageInfo);
                if (num3 == 0)
                {
                    BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(p, RulePackDefOf.DamageEvent_TrapSpike, null);
                    Find.BattleLog.Add(battleLogEntry_DamageTaken);
                    damageResult.AssociateWithLog(battleLogEntry_DamageTaken);
                }
                num3++;
            }
        }
        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;
        }
Пример #11
0
        protected override Toil DoBill()
        {
            var objectThing          = job.GetTarget(objectTI).Thing;
            var qualityComponent     = objectThing.TryGetComp <CompQuality> ();
            var tableThing           = job.GetTarget(tableTI).Thing as Building_WorkTable;
            var tablePowerTraderComp = tableThing.GetComp <CompPowerTrader> ();

            var toil = new Toil();

            toil.initAction = delegate {
                job.bill.Notify_DoBillStarted(pawn);

                processedHitPoints = 0;
                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)
                {
                    objectThing.HitPoints -= fixedHitPointsPerCycle;

                    if (tablePowerTraderComp != null && tablePowerTraderComp.PowerOn)
                    {
                        processedHitPoints += fixedHitPointsPerCycle;
                    }
                    else
                    {
                        processedHitPoints += fixedHitPointsPerCycle / 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 (qualityComponent != null && qualityComponent.Quality > QualityCategory.Awful)
                    {
                        var 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(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("Mending :: " + pawn + " could not drop recipe product " + list [j] + " near " + pawn.Position);
                                }
                            }
                        }
                        else if (list.Count == 1)
                        {
                            list [0].SetPositionDirect(pawn.Position);

                            job.bill.Notify_IterationCompleted(pawn, list);
                            job.targetB = list [0];

                            pawn.Map.reservationManager.Reserve(pawn, job, job.targetB, 1);
                        }
                        else
                        {
                            Log.Message("Mending :: " + pawn + " could not reclaim anything from " + objectThing);
                        }

                        ReadyForNextToil();
                    }

                    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(() => {
                return(toil.actor.CurJob.bill.suspended || !tableThing.UsableNow);
            });
            return(toil);
        }
Пример #12
0
        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);

                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.CurrentlyUsableForBills())
                {
                    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 (!SuccessChanceUtil.SuccessOnAction(pawn, skillFactor, objectThing))
                        {
                            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);
        }
Пример #13
0
        protected override Toil DoBill()
        {
            Pawn  actor                   = GetActor();
            Job   curJob                  = actor.jobs.curJob;
            Thing objectThing             = curJob.GetTarget(objectTI).Thing;
            Building_WorkTable tableThing = curJob.GetTarget(tableTI).Thing as Building_WorkTable;

            Toil toil = new Toil();

            toil.initAction = delegate
            {
                curJob.bill.Notify_DoBillStarted(actor);
                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.UsedThisTick();
                //if (!tableThing.UsableNow)
                //{
                //    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                //}

                if (workCycleProgress <= 0)
                {
                    float skillPerc = 0.5f;

                    SkillDef skillDef = curJob.RecipeDef.workSkill;
                    if (skillDef != null)
                    {
                        SkillRecord skill = actor.skills.GetSkill(skillDef);

                        if (skill != null)
                        {
                            skillPerc = (float)skill.Level / 20f;

                            skill.Learn(0.11f * curJob.RecipeDef.workSkillLearnFactor);
                        }
                    }

                    actor.GainComfortFromCellIfPossible();

                    Apparel mendApparel = objectThing as Apparel;
                    if (mendApparel != null)
                    {
                        ApparelWornByCorpseInt.SetValue(mendApparel, false);
                    }

                    List <Thing> list = new List <Thing>();
                    list.Add(objectThing);
                    curJob.bill.Notify_IterationCompleted(actor, list);

                    workCycleProgress = workCycle;
                    ReadyForNextToil();
                }
            };


            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(() =>
            {
                IBillGiver billGiver = curJob.GetTarget(tableTI).Thing as IBillGiver;

                return(curJob.bill.suspended || curJob.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills()));
            });
            return(toil);
        }
        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.", false);
                }

                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(TargetIndex.A);
            toil.WithEffect(EffecterDefOf.Sow, TargetIndex.A);
            toil.WithProgressBar(TargetIndex.A, () => 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;
                }
            });
            return(toil);
        }
Пример #15
0
 public static int EstimatedMeatCount(this Pawn p)
 {
     return((int)(StatExtension.GetStatValue(p, StatDefOf.MeatAmount)));
 }
        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);
        }
Пример #17
0
        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();
            Job   curJob                  = actor.jobs.curJob;
            Thing objectThing             = curJob.GetTarget(objectTI).Thing;
            Building_WorkTable tableThing = curJob.GetTarget(tableTI).Thing as Building_WorkTable;

            Toil toil = new Toil();

            toil.initAction = delegate {
                curJob.bill.Notify_DoBillStarted();

                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);

                if (!tableThing.UsableNow)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                if (workCycleProgress <= 0)
                {
                    int remainingHitPoints = objectThing.MaxHitPoints - objectThing.HitPoints;
                    if (remainingHitPoints > 0)
                    {
                        objectThing.HitPoints += (int)Math.Min(remainingHitPoints, fixedHitPointsPerCycle);
                    }

                    SkillRecord skill = actor.skills.GetSkill(SkillDefOf.Crafting);

                    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);

                    CompQuality qualityComponent = objectThing.TryGetComp <CompQuality>();
                    if (qualityComponent != null && qualityComponent.Quality > QualityCategory.Awful)
                    {
                        QualityCategory 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(actor.DrawPos, actor.Map, "Failed");
                        }
                    }

                    actor.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(curJob.targetB, pawn);
                        objectThing.Destroy(DestroyMode.Vanish);

                        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.targetB = list[0];
                        curJob.bill.Notify_IterationCompleted(actor, list);

                        pawn.Map.reservationManager.Reserve(pawn, curJob.targetB, 1);

                        ReadyForNextToil();
                    }
                    else if (objectThing.HitPoints == objectThing.MaxHitPoints)
                    {
                        // fixed!

                        Apparel mendApparel = objectThing as Apparel;
                        if (mendApparel != null)
                        {
                            ApparelWornByCorpseInt.SetValue(mendApparel, false);
                        }

                        List <Thing> list = new List <Thing> ();
                        list.Add(objectThing);
                        curJob.bill.Notify_IterationCompleted(actor, list);

                        ReadyForNextToil();
                    }
                    else if (objectThing.HitPoints > objectThing.MaxHitPoints)
                    {
                        Log.Error("Mending :: This should never happen! HitPoints > MaxHitPoints");
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    }

                    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(() => {
                IBillGiver billGiver = curJob.GetTarget(tableTI).Thing as IBillGiver;

                return(curJob.bill.suspended || curJob.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsable()));
            });
            return(toil);
        }
Пример #19
0
        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;
        }
Пример #20
0
 public static void bleedRatePostfix(ref float __result, HediffSet __instance)
 {
     __result *= StatExtension.GetStatValue((Thing)__instance.pawn, StatDef.Named("BleedRate"), true);
 }
Пример #21
0
        // Token: 0x06000028 RID: 40 RVA: 0x00003048 File Offset: 0x00001248
        public void addHediffToPawn(Pawn p, HediffDef _heddiff, float _addhediffChance, float _hediffseverity, bool onlylungs)
        {
            bool EyeProtection  = false;
            bool LungProtection = false;
            bool flag           = !Rand.Chance(_addhediffChance);

            if (!flag)
            {
                Hediff hediff = HediffMaker.MakeHediff(_heddiff, p, null);
                hediff.Severity = _hediffseverity;
                CompLungProtection clp;
                clp = p.GetComp <CompLungProtection>();
                if (clp != null)
                {
                    LungProtection = true;
                }
                CompEyeProtection cep;
                foreach (var a in p.apparel.WornApparel)
                {
                    if (a.def.apparel.tags.Contains("GasMask"))
                    {
                    }
                }

                cep = p.GetComp <CompEyeProtection>();
                if (cep != null)
                {
                    EyeProtection = true;
                }
                bool flag2 = onlylungs && p.health.capacities.CapableOf(PawnCapacityDefOf.Breathing);
                if (flag2)
                {
                    if (!LungProtection)
                    {
                        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 != null) ? hediffSet.GetFirstHediffOfDef(_heddiff, false) : null);
                                    }
                                }
                                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 != null) ? hediffSet2.GetFirstHediffOfDef(_heddiff, false) : null);
                        }
                    }
                    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);
                    }
                }
            }
        }
        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);
        }