示例#1
0
        public override void TryExecute()
        {
            pawn.story.traits.GainTrait(trait);

            TraitDegreeData traitDegreeData = traitDef.DataAtDegree(buyableTrait.degree);

            if (traitDegreeData != null)
            {
                if (traitDegreeData.skillGains != null)
                {
                    foreach (KeyValuePair <SkillDef, int> pair in traitDegreeData.skillGains)
                    {
                        SkillRecord skill = pawn.skills.GetSkill(pair.Key);
                        int         num   = TraitHelpers.FinalLevelOfSkill(pawn, pair.Key);
                        skill.Level = num;
                    }
                }
            }

            Viewer.TakeViewerCoins(storeIncident.cost);
            Viewer.CalculateNewKarma(storeIncident.karmaType, storeIncident.cost);
            VariablesHelpers.SendPurchaseMessage($"@{Viewer.username} just added the trait " + trait.Label + " to " + pawn.Name + ".");
            string text = $"{Viewer.username} has purchased " + trait.LabelCap + " for " + pawn.Name + ".";

            Current.Game.letterStack.ReceiveLetter("Trait", text, LetterDefOf.PositiveEvent, pawn);
        }
示例#2
0
        public TraitDegreeDataStats(TraitDegreeData d)
        {
            this.label                   = d.label;
            this.degree                  = d.degree;
            this.commonality             = d.commonality;
            this.socialFightChanceFactor = d.socialFightChanceFactor;
            this.marketValueFactorOffset = d.marketValueFactorOffset;
            this.randomDiseaseMtbDays    = d.randomDiseaseMtbDays;

            if (d.randomMentalStateMtbDaysMoodCurve != null)
            {
                this.randomMentalStateMtbDaysMoodCurve = new SimpleCurveStats(d.randomMentalStateMtbDaysMoodCurve);
            }

            Util.AssignDefStat(d.thinkTree, out this.thinkTree);
            Util.AssignDefStat(d.randomMentalState, out this.randomMentalState);

            this.disallowedMentalStates     = Util.CreateDefStatList(d.disallowedMentalStates);
            this.disallowedInspirations     = Util.CreateDefStatList(d.disallowedInspirations);
            this.theOnlyAllowedMentalBreaks = Util.CreateDefStatList(d.theOnlyAllowedMentalBreaks);

            Util.Populate(out this.skillGains, d.skillGains, (def, v) => new IntValueDefStat <SkillDef>(def, v));
            Util.Populate(out this.statOffsets, d.statOffsets, (v) => new FloatValueDefStat <StatDef>(v.stat, v.value));
            Util.Populate(out this.statFactors, d.statFactors, (v) => new FloatValueDefStat <StatDef>(v.stat, v.value));
        }
示例#3
0
 public static bool TraitTipString_Prefix(ref string __result, Trait __instance, Pawn pawn)
 {
     if (__instance?.def != null && __instance.def == SyrTraitDefOf.SlowLearner)
     {
         StringBuilder   stringBuilder = new StringBuilder();
         TraitDegreeData currentData   = __instance.CurrentData;
         stringBuilder.Append(currentData.description.Formatted(pawn.Named("PAWN")).AdjustedFor(pawn, "PAWN", true).Resolve());
         if (pawn.skills != null && pawn.def.statBases != null)
         {
             float num = 0f;
             foreach (SkillRecord skillRecord in pawn.skills.skills)
             {
                 num += skillRecord.levelInt;
             }
             float  val   = (SyrTraitDefOf.SlowLearner.degreeDatas.First().statOffsets.Find((StatModifier x) => x?.stat != null && x.stat == StatDefOf.GlobalLearningFactor).value + 0.02f * Mathf.Clamp(num, 40, 140)) * 100;
             string value = "    " + StatDefOf.GlobalLearningFactor.LabelCap + " " + val.ToStringWithSign() + "%";
             stringBuilder.AppendLine();
             stringBuilder.AppendLine();
             stringBuilder.AppendLine(value);
         }
         __result = stringBuilder.ToString();
         return(false);
     }
     return(true);
 }
示例#4
0
        public override void TryExecute()
        {
            Trait traitToRemove = pawn.story.traits.allTraits.Find(s => s.def.defName == buyableTrait.def.defName);

            if (traitToRemove != null)
            {
                pawn.story.traits.allTraits.Remove(traitToRemove);

                TraitDegreeData traitDegreeData = traitToRemove.def.DataAtDegree(buyableTrait.degree);

                if (traitDegreeData != null)
                {
                    if (traitDegreeData.skillGains != null)
                    {
                        foreach (KeyValuePair <SkillDef, int> pair in traitDegreeData.skillGains)
                        {
                            SkillRecord skill = pawn.skills.GetSkill(pair.Key);
                            skill.Level -= pair.Value;
                        }
                    }
                }
            }
            else
            {
                return;
            }
            Viewer.TakeViewerCoins(storeIncident.cost);
            Viewer.CalculateNewKarma(storeIncident.karmaType, storeIncident.cost);
            VariablesHelpers.SendPurchaseMessage($"@{Viewer.username} just removed the trait " + buyableTrait.label.CapitalizeFirst() + " from " + pawn.Name + ".");
            string text = $"{Viewer.username} has purchased trait removal of " + buyableTrait.label.CapitalizeFirst() + " from " + pawn.Name + ".";

            Current.Game.letterStack.ReceiveLetter("Trait", text, LetterDefOf.PositiveEvent, pawn);
        }
示例#5
0
        static void Postfix()
        {
            if (!valid)
            {
                greatMemory = DefDatabase <TraitDef> .GetNamed("GreatMemory");

                greatMemoryDegreeDatasBackup = (List <TraitDegreeData>)greatMemoryDegreeDatasField.GetValue(greatMemory);

                StatModifier modifier = new StatModifier();
                modifier.stat = DefDatabase <StatDef> .GetNamed("GlobalLearningFactor");

                modifier.value = 0.25f;
                TraitDegreeData data = new TraitDegreeData();
                data.statOffsets = new List <StatModifier>
                {
                    modifier
                };
                data.label                = greatMemoryDegreeDatasBackup[0].label;
                data.description          = "MadSkills_AlternativeGreatMemoryDescription".Translate();
                greatMemoryDegreeDatasNew = new List <TraitDegreeData>
                {
                    data
                };

                valid = true;
            }
            ApplyChanges(ModSettings.greatMemoryAltered);
        }
        public void DoWindowContents(Rect rect)
        {
            this.Init();

            float x = rect.xMin, y = rect.yMin;

            Widgets.Label(new Rect(x, y, 200, 32), "ConsolidatedTraits.EditTraits".Translate());
            y += 40;

            x += 20;
            string label = (this.selected == null) ? "ConsolidatedTraits.SelectTrait".Translate().ToString() : this.selected.defName;

            if (Widgets.ButtonText(new Rect(x, y, 200, 32), label))
            {
                this.DrawFloatingOptions();
            }
            y += 60;

            if (this.selected != null)
            {
                x += 10;

                Widgets.Label(new Rect(x, y, 200, 32), this.selected.defName);
                y += 40;

                float commonality = (float)TraitStat.CommonalityFI.GetValue(this.selected);
                Widgets.TextFieldNumericLabeled(
                    new Rect(0, y, 300, 32),
                    "ConsolidatedTraits.Commonality".Translate() + " ", ref commonality, ref this.comBuffer[0], 0f, 10f);
                TraitStat.CommonalityFI.SetValue(this.selected, commonality);
                y += 60;

                for (int i = 0; i < this.selected.degreeDatas.Count && i + 1 < this.comBuffer.Length; ++i)
                {
                    TraitDegreeData d = this.selected.degreeDatas[i];

                    Widgets.Label(new Rect(x, y, 200, 32), "    " + d.label);
                    y += 30;
                    Widgets.TextFieldNumericLabeled(
                        new Rect(x, y, 300, 32),
                        "    " + "ConsolidatedTraits.Commonality".Translate() + " ", ref d.commonality, ref this.comBuffer[i + 1], 0f, 10f);
                    y += 40;
                }

                y += 60;
                if (Widgets.ButtonText(new Rect(x, y, 100, 32), "Reset"))
                {
                    this.ResetTrait(this.selected);
                }
            }


            if (Widgets.ButtonText(new Rect(rect.xMax - 132, rect.yMax - 32, 100, 32), "ConsolidatedTraits.ResetAll".Translate()))
            {
                foreach (TraitDef d in this.TraitDefs.Values)
                {
                    this.ResetTrait(d);
                }
            }
        }
示例#7
0
        public string TipString(Pawn pawn)
        {
            StringBuilder   stringBuilder = new StringBuilder();
            TraitDegreeData currentData   = this.SoulCurrentData;

            stringBuilder.Append(currentData.description.AdjustedFor(pawn));
            return(stringBuilder.ToString());
        }
示例#8
0
 public TraitData(TraitEntry entry, TraitDegreeData data, int status)
 {
     traitDef    = entry.def;
     degreeInt   = entry.degree;
     this.status = status;
     trait       = entry;
     degreeData  = data;
 }
 public bool ApplyStats(TraitDegreeData d)
 {
     if (!this.DefName.Equals(d.label))
     {
         Log.Warning("Trying to apply stats [" + this.DefName + "] to wrong TraitDegreeData: [" + d.label + "]");
         return(false);
     }
     d.commonality = this.Value;
     return(true);
 }
示例#10
0
 public void MentalBreakerTick()
 {
     if (this.CanDoRandomMentalBreaks && this.pawn.MentalStateDef == null && this.pawn.IsHashIntervalTick(150))
     {
         if (!DebugSettings.enableRandomMentalStates)
         {
             return;
         }
         if (this.CurMood < this.BreakThresholdExtreme)
         {
             this.ticksBelowExtreme += 150;
         }
         else
         {
             this.ticksBelowExtreme = 0;
         }
         if (this.CurMood < this.BreakThresholdMajor)
         {
             this.ticksBelowMajor += 150;
         }
         else
         {
             this.ticksBelowMajor = 0;
         }
         if (this.CurMood < this.BreakThresholdMinor)
         {
             this.ticksBelowMinor += 150;
         }
         else
         {
             this.ticksBelowMinor = 0;
         }
         if (this.TestMoodMentalBreak() && this.TryDoRandomMoodCausedMentalBreak())
         {
             return;
         }
         if (this.pawn.story != null)
         {
             List <Trait> allTraits = this.pawn.story.traits.allTraits;
             for (int i = 0; i < allTraits.Count; i++)
             {
                 TraitDegreeData currentData = allTraits[i].CurrentData;
                 if (currentData.randomMentalState != null)
                 {
                     float mtb = currentData.randomMentalStateMtbDaysMoodCurve.Evaluate(this.CurMood);
                     if (Rand.MTBEventOccurs(mtb, 60000f, 150f) && currentData.randomMentalState.Worker.StateCanOccur(this.pawn) && this.pawn.mindState.mentalStateHandler.TryStartMentalState(currentData.randomMentalState, null, false, false, null))
                     {
                         return;
                     }
                 }
             }
         }
     }
 }
示例#11
0
        public BackStoryCreator(Backstory b)
        {
            resizeable = false;
            onlyCreate = false;

            story = b;

            workStatus.Clear();
            traitEntrys.Clear();

            foreach (WorkTags tag in Enum.GetValues(typeof(WorkTags)))
            {
                if ((b.workDisables & tag) == tag)
                {
                    workStatus.Add(tag, 1);
                }
                else
                if ((b.requiredWorkTags & tag) == tag)
                {
                    workStatus.Add(tag, 2);
                }
                else
                {
                    workStatus.Add(tag, 0);
                }
            }

            if (story.forcedTraits != null)
            {
                foreach (var t in story.forcedTraits)
                {
                    TraitDegreeData data = t.def.degreeDatas[t.degree];
                    traitEntrys.Add(new TraitData(t, data, 1));
                }
            }

            if (story.disallowedTraits != null)
            {
                foreach (var t in story.disallowedTraits)
                {
                    TraitDegreeData data = t.def.degreeDatas[t.degree];
                    traitEntrys.Add(new TraitData(t, data, 2));
                }
            }

            edit = true;
        }
示例#12
0
        public void ApplyStats(TraitDegreeData to)
        {
            to.label                   = this.label;
            to.degree                  = this.degree;
            to.commonality             = this.commonality;
            to.socialFightChanceFactor = this.socialFightChanceFactor;
            to.marketValueFactorOffset = this.marketValueFactorOffset;
            to.randomDiseaseMtbDays    = this.randomDiseaseMtbDays;

            if (to.randomMentalStateMtbDaysMoodCurve != null &&
                this.randomMentalStateMtbDaysMoodCurve != null)
            {
                this.randomMentalStateMtbDaysMoodCurve.ApplyStats(to.randomMentalStateMtbDaysMoodCurve);
            }

            Util.AssignDef(this.thinkTree, out to.thinkTree);
            Util.AssignDef(this.randomMentalState, out to.randomMentalState);

            Util.Populate(out to.disallowedMentalStates, this.disallowedMentalStates, (v) => v.Def);
            Util.Populate(out to.disallowedInspirations, this.disallowedInspirations, (v) => v.Def);
            Util.Populate(out to.theOnlyAllowedMentalBreaks, this.theOnlyAllowedMentalBreaks, (v) => v.Def);

            to.skillGains?.Clear();
            if (this.skillGains != null)
            {
                if (to.skillGains == null)
                {
                    to.skillGains = new Dictionary <SkillDef, int>();
                }
                this.skillGains.ForEach(v => to.skillGains.Add(v.Def, v.value));
            }

            to.statOffsets?.Clear();
            Util.Populate(out to.statOffsets, this.statOffsets, (v) => new StatModifier()
            {
                stat = v.Def, value = v.value
            });

            to.statFactors?.Clear();
            Util.Populate(out to.statFactors, this.statFactors, (v) => new StatModifier()
            {
                stat = v.Def, value = v.value
            });
        }
示例#13
0
        public static void RemoveTraitFromPawn([NotNull] Pawn pawn, [NotNull] Trait trait)
        {
            pawn.story.traits.allTraits.Remove(trait);

            TraitDegreeData val = trait.CurrentData;

            if (val?.skillGains == null)
            {
                return;
            }

            foreach (KeyValuePair <SkillDef, int> pair in val.skillGains)
            {
                SkillDef    skillDef = pair.Key;
                int         value    = pair.Value;
                SkillRecord skill    = pawn.skills.GetSkill(skillDef);

                if (skill.TotallyDisabled)
                {
                    continue;
                }

                skill.Level -= value;
            }

            List <WorkTypeDef> disabledWorkTypes = trait.GetDisabledWorkTypes().ToList();

            if (disabledWorkTypes.Count <= 0)
            {
                return;
            }

            pawn.Notify_DisabledWorkTypesChanged();

            foreach (WorkTypeDef workType in disabledWorkTypes)
            {
                pawn.workSettings.SetPriority(workType, 3);
            }
        }
示例#14
0
        public static void GivePawnTrait([NotNull] Pawn pawn, [NotNull] Trait trait)
        {
            ForciblyGivePawnTrait(pawn, trait);

            TraitDegreeData val = trait.CurrentData;

            if (val?.skillGains == null)
            {
                return;
            }

            foreach (KeyValuePair <SkillDef, int> skillGain in val.skillGains)
            {
                SkillRecord skill = pawn.skills.GetSkill(skillGain.Key);

                if (skill.TotallyDisabled)
                {
                    continue;
                }

                skill.Level += skillGain.Value;
            }

            List <WorkTypeDef> disabledWorkTypes = trait.GetDisabledWorkTypes().ToList();

            if (disabledWorkTypes.Count <= 0)
            {
                return;
            }

            pawn.Notify_DisabledWorkTypesChanged();

            foreach (WorkTypeDef workType in disabledWorkTypes.Where(workType => !pawn.WorkTypeIsDisabled(workType)))
            {
                pawn.workSettings.Disable(workType);
            }
        }
示例#15
0
            static void DropDownThingMenu(object tab, Thing thing)
            {
                Pawn SelPawnForGear         = (Pawn)LSelPawnForGear.GetValue(tab);
                Pawn SelPawn                = (Pawn)LSelPawn.GetValue(tab);
                bool canControl             = (bool)LCanControl.GetValue(tab);
                List <FloatMenuOption> list = new List <FloatMenuOption>();

                list.Add(new FloatMenuOption("ThingInfo".Translate(), delegate()
                {
                    Find.WindowStack.Add(new Dialog_InfoCard(thing));
                }, MenuOptionPriority.Default, null, null, 0f, null, null));
                //bool canControl = this.CanControl;
                if (canControl)
                {
                    ThingWithComps eq     = thing as ThingWithComps;
                    bool           flag10 = eq != null && eq.TryGetComp <CompEquippable>() != null;
                    if (flag10)
                    {
                        object         comp           = SelPawnForGear.getCompInventory();
                        CompBiocodable compBiocodable = eq.TryGetComp <CompBiocodable>();
                        bool           flag11         = comp != null;
                        if (flag11)
                        {
                            string          value  = GenLabel.ThingLabel(eq.def, eq.Stuff, 1);
                            bool            flag12 = compBiocodable != null && compBiocodable.Biocoded && compBiocodable.CodedPawn != SelPawnForGear;
                            FloatMenuOption item;
                            if (flag12)
                            {
                                item = new FloatMenuOption("CannotEquip".Translate(value) + ": " + "BiocodedCodedForSomeoneElse".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null);
                            }
                            else
                            {
                                bool flag13 = SelPawnForGear.IsQuestLodger() && !EquipmentUtility.QuestLodgerCanEquip(eq, SelPawnForGear);
                                if (flag13)
                                {
                                    TaggedString t = SelPawnForGear.equipment.AllEquipmentListForReading.Contains(eq) ? "CE_CannotPutAway".Translate(value) : "CannotEquip".Translate(value);
                                    item = new FloatMenuOption(t + ": " + "CE_CannotChangeEquipment".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null);
                                }
                                else
                                {
                                    bool flag14 = SelPawnForGear.equipment.AllEquipmentListForReading.Contains(eq) && SelPawnForGear.inventory != null;
                                    if (flag14)
                                    {
                                        item = new FloatMenuOption("CE_PutAway".Translate(value), delegate()
                                        {
                                            SelPawnForGear.equipment.TryTransferEquipmentToContainer(SelPawnForGear.equipment.Primary, SelPawnForGear.inventory.innerContainer);
                                        }, MenuOptionPriority.Default, null, null, 0f, null, null);
                                    }
                                    else
                                    {
                                        bool flag15 = !SelPawnForGear.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation);
                                        if (flag15)
                                        {
                                            item = new FloatMenuOption("CannotEquip".Translate(value), null, MenuOptionPriority.Default, null, null, 0f, null, null);
                                        }
                                        else
                                        {
                                            string text4  = "Equip".Translate(value);
                                            bool   flag16 = eq.def.IsRangedWeapon && SelPawnForGear.story != null && SelPawnForGear.story.traits.HasTrait(TraitDefOf.Brawler);
                                            if (flag16)
                                            {
                                                text4 = text4 + " " + "EquipWarningBrawler".Translate();
                                            }
                                            item = new FloatMenuOption(text4, (SelPawnForGear.story != null && SelPawnForGear.WorkTagIsDisabled(WorkTags.Violent)) ? null : new Action(delegate()
                                            {
                                                CEAccess.trySwitchToWeapon(comp, eq);
                                            }), MenuOptionPriority.Default, null, null, 0f, null, null);
                                        }
                                    }
                                }
                            }
                            list.Add(item);
                        }
                    }
                    //Pawn selPawnForGear = SelPawnForGear;   //??
                    List <Apparel> list2;
                    if (SelPawnForGear == null)
                    {
                        list2 = null;
                    }
                    else
                    {
                        Pawn_ApparelTracker apparel2 = SelPawnForGear.apparel;
                        list2 = ((apparel2 != null) ? apparel2.WornApparel : null);
                    }
                    List <Apparel> list3 = list2;
                    using (List <Apparel> .Enumerator enumerator = list3.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            Apparel        apparel        = enumerator.Current;
                            CompReloadable compReloadable = apparel.TryGetComp <CompReloadable>();
                            bool           flag17         = compReloadable != null && compReloadable.AmmoDef == thing.def && compReloadable.NeedsReload(true);
                            if (flag17)
                            {
                                bool flag18 = !SelPawnForGear.Drafted;
                                if (flag18)
                                {
                                    FloatMenuOption item2 = new FloatMenuOption("CE_ReloadApparel".Translate(apparel.Label, thing.Label), delegate()
                                    {
                                        SelPawnForGear.jobs.TryTakeOrderedJob(JobMaker.MakeJob(JobDefOf.Reload, apparel, thing), JobTag.Misc);
                                    }, MenuOptionPriority.Default, null, null, 0f, null, null);
                                    list.Add(item2);
                                }
                            }
                        }
                    }
                    bool flag19 = canControl && thing.IngestibleNow && SelPawn.RaceProps.CanEverEat(thing);
                    if (flag19)
                    {
                        Action action = delegate()
                        {
                            SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                            LInterfaceIngest.Invoke(tab, new object[] { thing });
                        };
                        string text5  = thing.def.ingestible.ingestCommandString.NullOrEmpty() ? (string)"ConsumeThing".Translate(thing.LabelShort, thing) : string.Format(thing.def.ingestible.ingestCommandString, thing.LabelShort);
                        bool   flag20 = SelPawnForGear.IsTeetotaler() && thing.def.IsNonMedicalDrug;
                        if (flag20)
                        {
                            List <FloatMenuOption> list4    = list;
                            string          str             = text5;
                            string          str2            = ": ";
                            TraitDegreeData traitDegreeData = (from x in TraitDefOf.DrugDesire.degreeDatas
                                                               where x.degree == -1
                                                               select x).First <TraitDegreeData>();
                            list4.Add(new FloatMenuOption(str + str2 + ((traitDegreeData != null) ? traitDegreeData.label : null), null, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }
                        else
                        {
                            list.Add(new FloatMenuOption(text5, action, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }
                    }
                    bool flag21 = SelPawnForGear.isItemQuestLocked(eq);
                    if (flag21)
                    {
                        list.Add(new FloatMenuOption("CE_CannotDropThing".Translate() + ": " + "DropThingLocked".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null));
                        list.Add(new FloatMenuOption("CE_CannotDropThingHaul".Translate() + ": " + "DropThingLocked".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null));
                    }
                    else
                    {
                        list.Add(new FloatMenuOption("DropThing".Translate(), delegate()
                        {
                            SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                            LInterfaceDrop.Invoke(tab, new object[] { thing });
                        }, MenuOptionPriority.Default, null, null, 0f, null, null));
                        list.Add(new FloatMenuOption("CE_DropThingHaul".Translate(), delegate()
                        {
                            SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                            InterfaceDropHaul(SelPawnForGear, thing, SelPawn);
                        }, MenuOptionPriority.Default, null, null, 0f, null, null));
                    }
                    bool flag22 = canControl && (bool)LHoldTrackerIsHeld.Invoke(null, new object[] { SelPawnForGear, thing }); //SelPawnForGear.HoldTrackerIsHeld(thing);
                    if (flag22)
                    {
                        Action action2 = delegate()
                        {
                            SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                            LHoldTrackerForget.Invoke(null, new object[] { SelPawnForGear, thing }); //SelPawnForGear.HoldTrackerForget(thing);
                        };
                        list.Add(new FloatMenuOption("CE_HoldTrackerForget".Translate(), action2, MenuOptionPriority.Default, null, null, 0f, null, null));
                    }
                }
                FloatMenu window = new FloatMenu(list, thing.LabelCap, false);

                Find.WindowStack.Add(window);
            }
示例#16
0
        public override void DoWindowContents(Rect inRect)
        {
            Text.Font = GameFont.Small;

            Widgets.Label(new Rect(0, 15, 70, 20), Translator.Translate("BackstorySlotInfo"));
            if (Widgets.ButtonText(new Rect(80, 15, 250, 20), (story.slot == BackstorySlot.Adulthood) ? "Adulthood".Translate() : "Childhood".Translate()))
            {
                List <FloatMenuOption> list = new List <FloatMenuOption>()
                {
                    new FloatMenuOption("Childhood".Translate(), delegate
                    {
                        story.slot = BackstorySlot.Childhood;
                    }),
                    new FloatMenuOption("Adulthood".Translate(), delegate
                    {
                        story.slot = BackstorySlot.Adulthood;
                    })
                };
                Find.WindowStack.Add(new FloatMenu(list));
            }

            Widgets.Label(new Rect(0, 50, 170, 20), Translator.Translate("BackstoryTitle"));
            story.title = Widgets.TextField(new Rect(180, 50, 300, 20), story.title);

            Widgets.Label(new Rect(0, 80, 170, 20), Translator.Translate("BackstoryTitleFemale"));
            story.titleFemale = Widgets.TextField(new Rect(180, 80, 300, 20), story.titleFemale);

            Widgets.Label(new Rect(0, 110, 170, 20), Translator.Translate("BackstoryTitleShort"));
            story.titleShort = Widgets.TextField(new Rect(180, 110, 300, 20), story.titleShort);

            Widgets.Label(new Rect(0, 140, 170, 20), Translator.Translate("BackstoryTitleShortFemale"));
            story.titleShortFemale = Widgets.TextField(new Rect(180, 140, 300, 20), story.titleShortFemale);

            Widgets.Label(new Rect(0, 170, 170, 20), Translator.Translate("DescriptionBasic"));
            story.baseDesc = Widgets.TextAreaScrollable(new Rect(0, 195, 490, 290), story.baseDesc, ref scrollMaintext);

            Widgets.Label(new Rect(510, 15, 280, 20), Translator.Translate("GainsPerksInfo"));
            int  size               = story.skillGainsResolved.Count * 25;
            Rect scrollRectFact     = new Rect(510, 45, 300, 200);
            Rect scrollVertRectFact = new Rect(0, 0, scrollRectFact.x, size);

            Widgets.BeginScrollView(scrollRectFact, ref scroll, scrollVertRectFact);
            int x = 0;

            for (int i = 0; i < story.skillGainsResolved.Count; i++)
            {
                KeyValuePair <SkillDef, int> gainedSkill = story.skillGainsResolved.ElementAt(i);
                Widgets.Label(new Rect(0, x, 170, 20), $"{gainedSkill.Key.LabelCap}: {gainedSkill.Value}");
                if (Widgets.ButtonText(new Rect(180, x, 110, 20), Translator.Translate("DeleteTargetRelation")))
                {
                    story.skillGainsResolved.Remove(gainedSkill.Key);
                }
                x += 22;
            }
            Widgets.EndScrollView();

            if (Widgets.ButtonText(new Rect(510, 255, 300, 20), Translator.Translate("AddNewSkillGained")))
            {
                Find.WindowStack.Add(new SkillsMenu(story.skillGainsResolved));
            }

            int  size2               = Enum.GetValues(typeof(WorkTags)).Length * 25;
            Rect scrollRectFact2     = new Rect(510, 290, 300, 200);
            Rect scrollVertRectFact2 = new Rect(0, 0, scrollRectFact2.x, size2);

            Widgets.BeginScrollView(scrollRectFact2, ref scroll2, scrollVertRectFact2);
            x = 0;
            for (int i = 0; i < workStatus.Count; i++)
            {
                var tag   = workStatus.Keys.ElementAt(i);
                var value = workStatus.Values.ElementAt(i);

                Widgets.Label(new Rect(0, x, 150, 20), tag.ToString());
                if (Widgets.ButtonText(new Rect(160, x, 120, 20), TranslateSkillStatus(value)))
                {
                    switch (value)
                    {
                    case 0:
                    {
                        workStatus[tag] = 1;
                        break;
                    }

                    case 1:
                    {
                        workStatus[tag] = 2;
                        break;
                    }

                    case 2:
                    {
                        workStatus[tag] = 0;
                        break;
                    }
                    }
                }

                x += 22;
            }
            Widgets.EndScrollView();

            Widgets.Label(new Rect(820, 15, 170, 20), Translator.Translate("TraitsData"));
            int  size3               = traitEntrys.Count * 25;
            Rect scrollRectFact3     = new Rect(820, 40, 380, 470);
            Rect scrollVertRectFact3 = new Rect(0, 0, scrollRectFact3.x, size3);

            Widgets.BeginScrollView(scrollRectFact3, ref scroll3, scrollVertRectFact3);
            x = 0;
            for (int i = 0; i < traitEntrys.Count; i++)
            {
                TraitData trt = traitEntrys[i];
                Widgets.Label(new Rect(0, x, 150, 20), $"{trt.degreeData.label}");
                if (Widgets.ButtonText(new Rect(160, x, 160, 20), TranslateTraitStatus(trt.status)))
                {
                    switch (trt.status)
                    {
                    case 1:
                    {
                        traitEntrys[i].status = 2;
                        break;
                    }

                    case 2:
                    {
                        traitEntrys[i].status = 1;
                        break;
                    }
                    }
                }
                if (Widgets.ButtonText(new Rect(340, x, 20, 20), "X"))
                {
                    traitEntrys.Remove(trt);
                }
                x += 22;
            }
            Widgets.EndScrollView();

            if (Widgets.ButtonText(new Rect(820, 520, 380, 20), Translator.Translate("AddNewTrait")))
            {
                List <FloatMenuOption> list = new List <FloatMenuOption>();
                foreach (var tr in DefDatabase <TraitDef> .AllDefsListForReading)
                {
                    for (int i = 0; i < tr.degreeDatas.Count; i++)
                    {
                        TraitDegreeData deg = tr.degreeDatas[i];
                        list.Add(new FloatMenuOption(deg.label, delegate
                        {
                            traitEntrys.Add(new TraitData(new TraitEntry(tr, deg.degree), deg, 1));
                        }));
                    }
                }
                Find.WindowStack.Add(new FloatMenu(list));
            }

            if (Widgets.ButtonText(new Rect(0, 520, 810, 20), Translator.Translate("SaveBacktoryToWorld")))
            {
                SaveBacktoryToWorld();
            }
        }
        public static bool HealthTick(Pawn_HealthTracker __instance)
        {
            if (__instance.Dead)
            {
                return(false);
            }
            for (int index = __instance.hediffSet.hediffs.Count - 1; index >= 0; --index)
            {
                Hediff hediff = __instance.hediffSet.hediffs[index];
                try
                {
                    hediff.Tick();
                    hediff.PostTick();
                }
                catch (Exception ex1)
                {
                    Log.Error("Exception ticking hediff " + hediff.ToStringSafe <Hediff>() + " for pawn " + __instance.pawn.ToStringSafe <Pawn>() + ". Removing hediff... Exception: " + (object)ex1);
                    try
                    {
                        __instance.RemoveHediff(hediff);
                    }
                    catch (Exception ex2)
                    {
                        Log.Error("Error while removing hediff: " + (object)ex2);
                    }
                }
                if (__instance.Dead)
                {
                    return(false);
                }
            }
            bool flag1 = false;

            lock (__instance.hediffSet)                                                     //added
            {
                List <Hediff> newHediffs = new List <Hediff>(__instance.hediffSet.hediffs); //added
                for (int index = newHediffs.Count - 1; index >= 0; --index)                 //changed
                {
                    Hediff hediff = newHediffs[index];
                    if (hediff.ShouldRemove)
                    {
                        newHediffs.RemoveAt(index);                //changed
                        __instance.hediffSet.hediffs = newHediffs; //added
                        hediff.PostRemoved();
                        flag1 = true;
                    }
                }
            }
            if (flag1)
            {
                __instance.Notify_HediffChanged((Hediff)null);
            }
            if (__instance.Dead)
            {
                return(false);
            }
            __instance.immunity.ImmunityHandlerTick();
            if (__instance.pawn.RaceProps.IsFlesh && __instance.pawn.IsHashIntervalTick(600) && (__instance.pawn.needs.food == null || !__instance.pawn.needs.food.Starving))
            {
                bool flag2 = false;
                if (__instance.hediffSet.HasNaturallyHealingInjury())
                {
                    float num = 8f;
                    if (__instance.pawn.GetPosture() != PawnPosture.Standing)
                    {
                        num += 4f;
                        Building_Bed buildingBed = __instance.pawn.CurrentBed();
                        if (buildingBed != null)
                        {
                            num += buildingBed.def.building.bed_healPerDay;
                        }
                    }
                    foreach (Hediff hediff in __instance.hediffSet.hediffs)
                    {
                        HediffStage curStage = hediff.CurStage;
                        if (curStage != null && (double)curStage.naturalHealingFactor != -1.0)
                        {
                            num *= curStage.naturalHealingFactor;
                        }
                    }
                    __instance.hediffSet.GetHediffs <Hediff_Injury>().Where <Hediff_Injury>((Func <Hediff_Injury, bool>)(x => x.CanHealNaturally())).RandomElement <Hediff_Injury>().Heal((float)((double)num * (double)__instance.pawn.HealthScale * 0.00999999977648258) * __instance.pawn.GetStatValue(StatDefOf.InjuryHealingFactor));
                    flag2 = true;
                }
                if (__instance.hediffSet.HasTendedAndHealingInjury() && (__instance.pawn.needs.food == null || !__instance.pawn.needs.food.Starving))
                {
                    Hediff_Injury hd = __instance.hediffSet.GetHediffs <Hediff_Injury>().Where <Hediff_Injury>((Func <Hediff_Injury, bool>)(x => x.CanHealFromTending())).RandomElement <Hediff_Injury>();
                    hd.Heal((float)(8.0 * (double)GenMath.LerpDouble(0.0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(hd.TryGetComp <HediffComp_TendDuration>().tendQuality)) * (double)__instance.pawn.HealthScale * 0.00999999977648258) * __instance.pawn.GetStatValue(StatDefOf.InjuryHealingFactor));
                    flag2 = true;
                }
                if (flag2 && !__instance.HasHediffsNeedingTendByPlayer() && (!HealthAIUtility.ShouldSeekMedicalRest(__instance.pawn) && !__instance.hediffSet.HasTendedAndHealingInjury()) && PawnUtility.ShouldSendNotificationAbout(__instance.pawn))
                {
                    Messages.Message((string)"MessageFullyHealed".Translate((NamedArgument)__instance.pawn.LabelCap, (NamedArgument)(Thing)__instance.pawn), (LookTargets)(Thing)__instance.pawn, MessageTypeDefOf.PositiveEvent);
                }
            }
            if (__instance.pawn.RaceProps.IsFlesh && (double)__instance.hediffSet.BleedRateTotal >= 0.100000001490116)
            {
                float num = __instance.hediffSet.BleedRateTotal * __instance.pawn.BodySize;
                if ((double)Rand.Value < (__instance.pawn.GetPosture() != PawnPosture.Standing ? (double)(num * 0.0004f) : (double)(num * 0.004f)))
                {
                    __instance.DropBloodFilth();
                }
            }
            if (!__instance.pawn.IsHashIntervalTick(60))
            {
                return(false);
            }
            List <HediffGiverSetDef> hediffGiverSets = __instance.pawn.RaceProps.hediffGiverSets;

            if (hediffGiverSets != null)
            {
                for (int index1 = 0; index1 < hediffGiverSets.Count; ++index1)
                {
                    List <HediffGiver> hediffGivers = hediffGiverSets[index1].hediffGivers;
                    for (int index2 = 0; index2 < hediffGivers.Count; ++index2)
                    {
                        hediffGivers[index2].OnIntervalPassed(__instance.pawn, (Hediff)null);
                        if (__instance.pawn.Dead)
                        {
                            return(false);
                        }
                    }
                }
            }
            if (__instance.pawn.story == null)
            {
                return(false);
            }
            List <Trait> allTraits = __instance.pawn.story.traits.allTraits;

            for (int index = 0; index < allTraits.Count; ++index)
            {
                TraitDegreeData currentData = allTraits[index].CurrentData;
                if ((double)currentData.randomDiseaseMtbDays > 0.0 && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f))
                {
                    BiomeDef biome = __instance.pawn.Tile == -1 ? DefDatabase <BiomeDef> .GetRandom() : Find.WorldGrid[__instance.pawn.Tile].biome;

                    IncidentDef incidentDef = DefDatabase <IncidentDef> .AllDefs.Where <IncidentDef>((Func <IncidentDef, bool>)(d => d.category == IncidentCategoryDefOf.DiseaseHuman)).RandomElementByWeightWithFallback <IncidentDef>((Func <IncidentDef, float>)(d => biome.CommonalityOfDisease(d)));

                    if (incidentDef != null)
                    {
                        string      blockedInfo;
                        List <Pawn> pawns = ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle <Pawn>(__instance.pawn), out blockedInfo);
                        if (PawnUtility.ShouldSendNotificationAbout(__instance.pawn))
                        {
                            if (pawns.Contains(__instance.pawn))
                            {
                                Find.LetterStack.ReceiveLetter("LetterLabelTraitDisease".Translate((NamedArgument)incidentDef.diseaseIncident.label), "LetterTraitDisease".Translate((NamedArgument)__instance.pawn.LabelCap, (NamedArgument)incidentDef.diseaseIncident.label, __instance.pawn.Named("PAWN")).AdjustedFor(__instance.pawn), LetterDefOf.NegativeEvent, (LookTargets)(Thing)__instance.pawn);
                            }
                            else if (!blockedInfo.NullOrEmpty())
                            {
                                Messages.Message(blockedInfo, (LookTargets)(Thing)__instance.pawn, MessageTypeDefOf.NeutralEvent);
                            }
                        }
                    }
                }
            }
            return(false);
        }
        public TraitDegreeDataWidget(TraitDegreeData data)
        {
            if (data.disallowedMentalStates == null)
            {
                data.disallowedMentalStates = new List <MentalStateDef>();
            }
            if (data.disallowedInspirations == null)
            {
                data.disallowedInspirations = new List <InspirationDef>();
            }
            if (data.theOnlyAllowedMentalBreaks == null)
            {
                data.theOnlyAllowedMentalBreaks = new List <MentalBreakDef>();
            }

            this.data         = data;
            this.inputWidgets = new List <IInputWidget>()
            {
                //new IntInputWidget<TraitDegreeData>(this.data, "Degree", d => d.degree, (d, v) => d.degree = v),
                new FloatInputWidget <TraitDegreeData>(this.data, "Commonality", d => d.commonality, (d, v) => d.commonality = v),
                new FloatInputWidget <TraitDegreeData>(this.data, "Social Fight Chance Factor", d => d.socialFightChanceFactor, (d, v) => d.socialFightChanceFactor = v),
                new FloatInputWidget <TraitDegreeData>(this.data, "Market Value Factor Offset", d => d.marketValueFactorOffset, (d, v) => d.marketValueFactorOffset = v),
                new FloatInputWidget <TraitDegreeData>(this.data, "Random Disease Mtb Days", d => d.randomDiseaseMtbDays, (d, v) => d.randomDiseaseMtbDays          = v),
                new DefInputWidget <TraitDegreeData, ThinkTreeDef>(this.data, "Think Tree", 200, d => d.thinkTree, (d, v) => d.thinkTree = v, true),
                new DefInputWidget <TraitDegreeData, MentalStateDef>(this.data, "Random Mental State", 200, d => d.randomMentalState, (d, v) => d.randomMentalState = v, true),
                new DefPlusMinusInputWidget <InspirationDef>("Disallowed Inspirations", 200, this.data.disallowedInspirations),
                new DefPlusMinusInputWidget <MentalStateDef>("Disallowed Mental States", 200, this.data.disallowedMentalStates),
                new DefPlusMinusInputWidget <MentalBreakDef>("The Only Allowed Mental Breaks", 200, this.data.theOnlyAllowedMentalBreaks),
            };

            this.skillGainsArgs = new WindowUtil.PlusMinusArgs <SkillDef>()
            {
                getDisplayName = v => v.label,
                allItems       = DefDatabase <SkillDef> .AllDefs,
                beingUsed      = () =>
                {
                    List <SkillDef> l = new List <SkillDef>();
                    if (this.data.skillGains != null)
                    {
                        foreach (var kv in this.data.skillGains)
                        {
                            l.Add(kv.Key);
                        }
                    }
                    return(l);
                },
                onAdd = def =>
                {
                    this.data.skillGains.Add(def, 0);
                    this.skillGains.Add(this.CreateSkillGainInput(def));
                },
                onRemove = def =>
                {
                    this.skillGains.RemoveAll(v => v.Parent == def);
                    this.data.skillGains.Remove(def);
                }
            };

            this.statOffsetsArgs = new WindowUtil.PlusMinusArgs <StatDef>()
            {
                getDisplayName = v => v.label,
                allItems       = DefDatabase <StatDef> .AllDefs,
                beingUsed      = () =>
                {
                    List <StatDef> l = new List <StatDef>();
                    if (this.data.statOffsets != null)
                    {
                        foreach (var v in this.data.statOffsets)
                        {
                            l.Add(v.stat);
                        }
                    }
                    return(l);
                },
                onAdd = def =>
                {
                    StatModifier sm = new StatModifier()
                    {
                        stat = def, value = 0
                    };
                    this.data.statOffsets = Util.AddTo(this.data.statOffsets, sm);
                    this.statOffsets      = Util.AddTo(this.statOffsets, this.CreateStatModifierInput(sm));
                },
                onRemove = def =>
                {
                    this.statOffsets?.RemoveAll(v => v.Parent.stat == def);
                    this.data.statOffsets?.RemoveAll(v => v.stat == def);
                }
            };

            this.statFactorsArgs = new WindowUtil.PlusMinusArgs <StatDef>()
            {
                getDisplayName = v => v.label,
                allItems       = DefDatabase <StatDef> .AllDefs,
                beingUsed      = () =>
                {
                    List <StatDef> l = new List <StatDef>();
                    if (this.data.statFactors != null)
                    {
                        foreach (var v in this.data.statFactors)
                        {
                            l.Add(v.stat);
                        }
                    }
                    return(l);
                },
                onAdd = def =>
                {
                    StatModifier sm = new StatModifier()
                    {
                        stat = def, value = 0
                    };
                    this.data.statFactors = Util.AddTo(this.data.statFactors, sm);
                    this.statFactors      = Util.AddTo(this.statFactors, this.CreateStatModifierInput(sm));
                },
                onRemove = def =>
                {
                    this.statFactors?.RemoveAll(v => v.Parent.stat == def);
                    this.data.statFactors?.RemoveAll(v => v.stat == def);
                }
            };

            this.ResetBuffers();
        }
 public TraitStat(TraitDegreeData d)
 {
     this.DefName = d.label;
     this.Value   = d.commonality;
 }
 public void HealthTick()
 {
     if (!this.Dead)
     {
         for (int i = this.hediffSet.hediffs.Count - 1; i >= 0; i--)
         {
             Hediff hediff = this.hediffSet.hediffs[i];
             try
             {
                 hediff.Tick();
                 hediff.PostTick();
             }
             catch (Exception ex)
             {
                 Log.Error(string.Concat(new object[]
                 {
                     "Exception ticking hediff ",
                     hediff.ToStringSafe <Hediff>(),
                     " for pawn ",
                     this.pawn.ToStringSafe <Pawn>(),
                     ". Removing hediff... Exception: ",
                     ex
                 }), false);
                 try
                 {
                     this.RemoveHediff(hediff);
                 }
                 catch (Exception arg)
                 {
                     Log.Error("Error while removing hediff: " + arg, false);
                 }
             }
         }
         bool flag = false;
         for (int j = this.hediffSet.hediffs.Count - 1; j >= 0; j--)
         {
             Hediff hediff2 = this.hediffSet.hediffs[j];
             if (hediff2.ShouldRemove)
             {
                 this.hediffSet.hediffs.RemoveAt(j);
                 hediff2.PostRemoved();
                 flag = true;
             }
         }
         if (flag)
         {
             this.Notify_HediffChanged(null);
         }
         if (!this.Dead)
         {
             this.immunity.ImmunityHandlerTick();
             if (this.pawn.RaceProps.IsFlesh && this.pawn.IsHashIntervalTick(600) && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving))
             {
                 bool flag2 = false;
                 if (this.hediffSet.HasNaturallyHealingInjury())
                 {
                     float num = 8f;
                     if (this.pawn.GetPosture() != PawnPosture.Standing)
                     {
                         num += 4f;
                         Building_Bed building_Bed = this.pawn.CurrentBed();
                         if (building_Bed != null)
                         {
                             num += building_Bed.def.building.bed_healPerDay;
                         }
                     }
                     Hediff_Injury hediff_Injury = (from x in this.hediffSet.GetHediffs <Hediff_Injury>()
                                                    where x.CanHealNaturally()
                                                    select x).RandomElement <Hediff_Injury>();
                     hediff_Injury.Heal(num * this.pawn.HealthScale * 0.01f);
                     flag2 = true;
                 }
                 if (this.hediffSet.HasTendedAndHealingInjury() && (this.pawn.needs.food == null || !this.pawn.needs.food.Starving))
                 {
                     Hediff_Injury hediff_Injury2 = (from x in this.hediffSet.GetHediffs <Hediff_Injury>()
                                                     where x.CanHealFromTending()
                                                     select x).RandomElement <Hediff_Injury>();
                     float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality;
                     float num2        = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality));
                     hediff_Injury2.Heal(22f * num2 * this.pawn.HealthScale * 0.01f);
                     flag2 = true;
                 }
                 if (flag2 && !this.HasHediffsNeedingTendByPlayer(false) && !HealthAIUtility.ShouldSeekMedicalRest(this.pawn) && !this.hediffSet.HasTendedAndHealingInjury() && PawnUtility.ShouldSendNotificationAbout(this.pawn))
                 {
                     Messages.Message("MessageFullyHealed".Translate(new object[]
                     {
                         this.pawn.LabelCap
                     }), this.pawn, MessageTypeDefOf.PositiveEvent, true);
                 }
             }
             if (this.pawn.RaceProps.IsFlesh && this.hediffSet.BleedRateTotal >= 0.1f)
             {
                 float num3 = this.hediffSet.BleedRateTotal * this.pawn.BodySize;
                 if (this.pawn.GetPosture() == PawnPosture.Standing)
                 {
                     num3 *= 0.004f;
                 }
                 else
                 {
                     num3 *= 0.0004f;
                 }
                 if (Rand.Value < num3)
                 {
                     this.DropBloodFilth();
                 }
             }
             if (this.pawn.IsHashIntervalTick(60))
             {
                 List <HediffGiverSetDef> hediffGiverSets = this.pawn.RaceProps.hediffGiverSets;
                 if (hediffGiverSets != null)
                 {
                     for (int k = 0; k < hediffGiverSets.Count; k++)
                     {
                         List <HediffGiver> hediffGivers = hediffGiverSets[k].hediffGivers;
                         for (int l = 0; l < hediffGivers.Count; l++)
                         {
                             hediffGivers[l].OnIntervalPassed(this.pawn, null);
                             if (this.pawn.Dead)
                             {
                                 return;
                             }
                         }
                     }
                 }
                 if (this.pawn.story != null)
                 {
                     List <Trait> allTraits = this.pawn.story.traits.allTraits;
                     for (int m = 0; m < allTraits.Count; m++)
                     {
                         TraitDegreeData currentData = allTraits[m].CurrentData;
                         if (currentData.randomDiseaseMtbDays > 0f && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f))
                         {
                             BiomeDef biome;
                             if (this.pawn.Tile != -1)
                             {
                                 biome = Find.WorldGrid[this.pawn.Tile].biome;
                             }
                             else
                             {
                                 biome = DefDatabase <BiomeDef> .GetRandom();
                             }
                             IncidentDef incidentDef = (from d in DefDatabase <IncidentDef> .AllDefs
                                                        where d.category == IncidentCategoryDefOf.DiseaseHuman
                                                        select d).RandomElementByWeightWithFallback((IncidentDef d) => biome.CommonalityOfDisease(d), null);
                             if (incidentDef != null)
                             {
                                 ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle <Pawn>(this.pawn));
                             }
                         }
                     }
                 }
             }
         }
     }
 }
示例#21
0
 public void HealthTick()
 {
     if (!Dead)
     {
         for (int num = hediffSet.hediffs.Count - 1; num >= 0; num--)
         {
             Hediff hediff = hediffSet.hediffs[num];
             try
             {
                 hediff.Tick();
                 hediff.PostTick();
             }
             catch (Exception ex)
             {
                 Log.Error("Exception ticking hediff " + hediff.ToStringSafe() + " for pawn " + pawn.ToStringSafe() + ". Removing hediff... Exception: " + ex);
                 try
                 {
                     RemoveHediff(hediff);
                 }
                 catch (Exception arg)
                 {
                     Log.Error("Error while removing hediff: " + arg);
                 }
             }
         }
         bool flag = false;
         for (int num2 = hediffSet.hediffs.Count - 1; num2 >= 0; num2--)
         {
             Hediff hediff2 = hediffSet.hediffs[num2];
             if (hediff2.ShouldRemove)
             {
                 hediffSet.hediffs.RemoveAt(num2);
                 hediff2.PostRemoved();
                 flag = true;
             }
         }
         if (flag)
         {
             Notify_HediffChanged(null);
         }
         if (!Dead)
         {
             immunity.ImmunityHandlerTick();
             if (pawn.RaceProps.IsFlesh && pawn.IsHashIntervalTick(600) && (pawn.needs.food == null || !pawn.needs.food.Starving))
             {
                 bool flag2 = false;
                 if (hediffSet.HasNaturallyHealingInjury())
                 {
                     float num3 = 8f;
                     if (pawn.GetPosture() != 0)
                     {
                         num3 += 4f;
                         Building_Bed building_Bed = pawn.CurrentBed();
                         if (building_Bed != null)
                         {
                             num3 += building_Bed.def.building.bed_healPerDay;
                         }
                     }
                     Hediff_Injury hediff_Injury = hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealNaturally).RandomElement();
                     hediff_Injury.Heal(num3 * pawn.HealthScale * 0.01f);
                     flag2 = true;
                 }
                 if (hediffSet.HasTendedAndHealingInjury() && (pawn.needs.food == null || !pawn.needs.food.Starving))
                 {
                     Hediff_Injury hediff_Injury2 = hediffSet.GetHediffs <Hediff_Injury>().Where(HediffUtility.CanHealFromTending).RandomElement();
                     float         tendQuality    = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality;
                     float         num4           = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality));
                     hediff_Injury2.Heal(8f * num4 * pawn.HealthScale * 0.01f);
                     flag2 = true;
                 }
                 if (flag2 && !HasHediffsNeedingTendByPlayer() && !HealthAIUtility.ShouldSeekMedicalRest(pawn) && !hediffSet.HasTendedAndHealingInjury() && PawnUtility.ShouldSendNotificationAbout(pawn))
                 {
                     Messages.Message("MessageFullyHealed".Translate(pawn.LabelCap, pawn), pawn, MessageTypeDefOf.PositiveEvent);
                 }
             }
             if (pawn.RaceProps.IsFlesh && hediffSet.BleedRateTotal >= 0.1f)
             {
                 float num5 = hediffSet.BleedRateTotal * pawn.BodySize;
                 num5 = ((pawn.GetPosture() != 0) ? (num5 * 0.0004f) : (num5 * 0.004f));
                 if (Rand.Value < num5)
                 {
                     DropBloodFilth();
                 }
             }
             if (pawn.IsHashIntervalTick(60))
             {
                 List <HediffGiverSetDef> hediffGiverSets = pawn.RaceProps.hediffGiverSets;
                 if (hediffGiverSets != null)
                 {
                     for (int i = 0; i < hediffGiverSets.Count; i++)
                     {
                         List <HediffGiver> hediffGivers = hediffGiverSets[i].hediffGivers;
                         for (int j = 0; j < hediffGivers.Count; j++)
                         {
                             hediffGivers[j].OnIntervalPassed(pawn, null);
                             if (pawn.Dead)
                             {
                                 return;
                             }
                         }
                     }
                 }
                 if (pawn.story != null)
                 {
                     List <Trait> allTraits = pawn.story.traits.allTraits;
                     for (int k = 0; k < allTraits.Count; k++)
                     {
                         TraitDegreeData currentData = allTraits[k].CurrentData;
                         if (currentData.randomDiseaseMtbDays > 0f && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f))
                         {
                             BiomeDef biome;
                             if (pawn.Tile != -1)
                             {
                                 biome = Find.WorldGrid[pawn.Tile].biome;
                             }
                             else
                             {
                                 biome = DefDatabase <BiomeDef> .GetRandom();
                             }
                             IncidentDef incidentDef = (from d in DefDatabase <IncidentDef> .AllDefs
                                                        where d.category == IncidentCategoryDefOf.DiseaseHuman
                                                        select d).RandomElementByWeightWithFallback((IncidentDef d) => biome.CommonalityOfDisease(d));
                             if (incidentDef != null)
                             {
                                 string      blockedInfo;
                                 List <Pawn> list = ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle(pawn), out blockedInfo);
                                 if (PawnUtility.ShouldSendNotificationAbout(pawn))
                                 {
                                     if (list.Contains(pawn))
                                     {
                                         Find.LetterStack.ReceiveLetter("LetterLabelTraitDisease".Translate(incidentDef.diseaseIncident.label), "LetterTraitDisease".Translate(pawn.LabelCap, incidentDef.diseaseIncident.label, pawn.Named("PAWN")).AdjustedFor(pawn), LetterDefOf.NegativeEvent, pawn);
                                     }
                                     else if (!blockedInfo.NullOrEmpty())
                                     {
                                         Messages.Message(blockedInfo, pawn, MessageTypeDefOf.NeutralEvent);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }