private static void GenerateTraits(Pawn pawn, PawnGenerationRequest request) { if (pawn.story == null) { return; } if (request.ForcedTraits != null) { foreach (TraitDef forcedTrait in request.ForcedTraits) { if (forcedTrait != null) { pawn.story.traits.GainTrait(new Trait(forcedTrait, 0, forced: true)); } } } if (pawn.story.childhood.forcedTraits != null) { List <TraitEntry> forcedTraits = pawn.story.childhood.forcedTraits; for (int i = 0; i < forcedTraits.Count; i++) { TraitEntry traitEntry = forcedTraits[i]; if (traitEntry.def == null) { Log.Error("Null forced trait def on " + pawn.story.childhood); } else if ((request.KindDef.disallowedTraits == null || !request.KindDef.disallowedTraits.Contains(traitEntry.def)) && !pawn.story.traits.HasTrait(traitEntry.def) && (request.ProhibitedTraits == null || !request.ProhibitedTraits.Contains(traitEntry.def))) { pawn.story.traits.GainTrait(new Trait(traitEntry.def, traitEntry.degree)); } } } if (pawn.story.adulthood != null && pawn.story.adulthood.forcedTraits != null) { List <TraitEntry> forcedTraits2 = pawn.story.adulthood.forcedTraits; for (int j = 0; j < forcedTraits2.Count; j++) { TraitEntry traitEntry2 = forcedTraits2[j]; if (traitEntry2.def == null) { Log.Error("Null forced trait def on " + pawn.story.adulthood); } else if ((request.KindDef.disallowedTraits == null || !request.KindDef.disallowedTraits.Contains(traitEntry2.def)) && !pawn.story.traits.HasTrait(traitEntry2.def) && (request.ProhibitedTraits == null || !request.ProhibitedTraits.Contains(traitEntry2.def))) { pawn.story.traits.GainTrait(new Trait(traitEntry2.def, traitEntry2.degree)); } } } int num = Rand.RangeInclusive(2, 3); if (request.AllowGay && (LovePartnerRelationUtility.HasAnyLovePartnerOfTheSameGender(pawn) || LovePartnerRelationUtility.HasAnyExLovePartnerOfTheSameGender(pawn))) { Trait trait = new Trait(TraitDefOf.Gay, RandomTraitDegree(TraitDefOf.Gay)); pawn.story.traits.GainTrait(trait); } while (pawn.story.traits.allTraits.Count < num) { TraitDef newTraitDef = DefDatabase <TraitDef> .AllDefsListForReading.RandomElementByWeight((TraitDef tr) => tr.GetGenderSpecificCommonality(pawn.gender)); if (pawn.story.traits.HasTrait(newTraitDef) || (request.KindDef.disallowedTraits != null && request.KindDef.disallowedTraits.Contains(newTraitDef)) || (request.KindDef.requiredWorkTags != 0 && (newTraitDef.disabledWorkTags & request.KindDef.requiredWorkTags) != 0) || (newTraitDef == TraitDefOf.Gay && (!request.AllowGay || LovePartnerRelationUtility.HasAnyLovePartnerOfTheOppositeGender(pawn) || LovePartnerRelationUtility.HasAnyExLovePartnerOfTheOppositeGender(pawn))) || (request.ProhibitedTraits != null && request.ProhibitedTraits.Contains(newTraitDef)) || (request.Faction != null && Faction.OfPlayerSilentFail != null && request.Faction.HostileTo(Faction.OfPlayer) && !newTraitDef.allowOnHostileSpawn) || pawn.story.traits.allTraits.Any((Trait tr) => newTraitDef.ConflictsWith(tr)) || (newTraitDef.requiredWorkTypes != null && pawn.OneOfWorkTypesIsDisabled(newTraitDef.requiredWorkTypes)) || pawn.WorkTagIsDisabled(newTraitDef.requiredWorkTags) || (newTraitDef.forcedPassions != null && pawn.workSettings != null && newTraitDef.forcedPassions.Any((SkillDef p) => p.IsDisabled(pawn.story.DisabledWorkTagsBackstoryAndTraits, pawn.GetDisabledWorkTypes(permanentOnly: true))))) { continue; } int degree = RandomTraitDegree(newTraitDef); if (!pawn.story.childhood.DisallowsTrait(newTraitDef, degree) && (pawn.story.adulthood == null || !pawn.story.adulthood.DisallowsTrait(newTraitDef, degree))) { Trait trait2 = new Trait(newTraitDef, degree); if (pawn.mindState == null || pawn.mindState.mentalBreaker == null || !((pawn.mindState.mentalBreaker.BreakThresholdMinor + trait2.OffsetOfStat(StatDefOf.MentalBreakThreshold)) * trait2.MultiplierOfStat(StatDefOf.MentalBreakThreshold) > 0.5f)) { pawn.story.traits.GainTrait(trait2); } } } }
private static IEnumerable InfectionSimulatorWorker() { int trials = 2; List <Pawn> doctors = DebugOutputsInfection.GenerateDoctorArray(); List <int> testSkill = new List <int> { 4, 10, 16 }; List <ThingDef> testMedicine = new List <ThingDef> { null, ThingDefOf.MedicineHerbal, ThingDefOf.MedicineIndustrial, ThingDefOf.MedicineUltratech }; PawnGenerationRequest pawngen = new PawnGenerationRequest(PawnKindDefOf.Colonist, Faction.OfPlayer, PawnGenerationContext.NonPlayer, -1, false, false, false, false, true, false, 1f, false, true, true, false, false, false, false, null, null, null, null, null, null, null, null); int originalTicks = Find.TickManager.TicksGame; List <DebugOutputsInfection.InfectionSimRow> results = new List <DebugOutputsInfection.InfectionSimRow>(); int totalTests = DebugOutputsInfection.InfectionList().Count <HediffDef>() * testMedicine.Count <ThingDef>() * testSkill.Count <int>() * trials; int currentTest = 0; foreach (HediffDef hediff in DebugOutputsInfection.InfectionList()) { foreach (ThingDef meds in testMedicine) { foreach (int skill in testSkill) { DebugOutputsInfection.InfectionSimRow result = default(DebugOutputsInfection.InfectionSimRow); result.illness = hediff; result.skill = skill; result.medicine = meds; Pawn doctor = doctors[skill]; int i = 0; while (i < trials) { Pawn patient = PawnGenerator.GeneratePawn(pawngen); int startTicks = Find.TickManager.TicksGame; patient.health.AddHediff(result.illness, null, null, null); Hediff activeHediff = patient.health.hediffSet.GetFirstHediffOfDef(result.illness, false); while (!patient.Dead && patient.health.hediffSet.HasHediff(result.illness, false)) { if (activeHediff.TendableNow(false)) { activeHediff.Tended(TendUtility.CalculateBaseTendQuality(doctor, patient, meds), 0); result.medicineUsed += 1f; } foreach (Hediff current in patient.health.hediffSet.GetHediffsTendable()) { current.Tended(TendUtility.CalculateBaseTendQuality(doctor, patient, meds), 0); } Find.TickManager.DebugSetTicksGame(Find.TickManager.TicksGame + 1); patient.health.HealthTick(); if (Find.TickManager.TicksGame % 900 == 0) { yield return(null); } } if (patient.Dead) { result.deathChance += 1f; } else { result.recoveryTimeDays += (Find.TickManager.TicksGame - startTicks).TicksToDays(); } currentTest++; LongEventHandler.SetCurrentEventText(string.Format("Simulating ({0}/{1})", currentTest, totalTests)); yield return(null); } result.recoveryTimeDays /= (float)trials - result.deathChance; result.deathChance /= (float)trials; result.medicineUsed /= (float)trials; results.Add(result); } } } IEnumerable <DebugOutputsInfection.InfectionSimRow> arg_6D8_0 = results; TableDataGetter <DebugOutputsInfection.InfectionSimRow>[] expr_5DC = new TableDataGetter <DebugOutputsInfection.InfectionSimRow> [6]; expr_5DC[0] = new TableDataGetter <DebugOutputsInfection.InfectionSimRow>("defName", (DebugOutputsInfection.InfectionSimRow isr) => isr.illness.defName); expr_5DC[1] = new TableDataGetter <DebugOutputsInfection.InfectionSimRow>("meds", (DebugOutputsInfection.InfectionSimRow isr) => (isr.medicine == null) ? "(none)" : isr.medicine.defName); expr_5DC[2] = new TableDataGetter <DebugOutputsInfection.InfectionSimRow>("skill", (DebugOutputsInfection.InfectionSimRow isr) => isr.skill.ToString()); expr_5DC[3] = new TableDataGetter <DebugOutputsInfection.InfectionSimRow>("death chance", (DebugOutputsInfection.InfectionSimRow isr) => isr.deathChance.ToStringPercent()); expr_5DC[4] = new TableDataGetter <DebugOutputsInfection.InfectionSimRow>("recovery time (days)", (DebugOutputsInfection.InfectionSimRow isr) => isr.recoveryTimeDays.ToString("F1")); expr_5DC[5] = new TableDataGetter <DebugOutputsInfection.InfectionSimRow>("medicine used", (DebugOutputsInfection.InfectionSimRow isr) => isr.medicineUsed.ToString()); DebugTables.MakeTablesDialog <DebugOutputsInfection.InfectionSimRow>(arg_6D8_0, expr_5DC); Find.TickManager.DebugSetTicksGame(originalTicks); }
private static void GenerateRandomAge(Pawn pawn, PawnGenerationRequest request) { if (request.FixedBiologicalAge.HasValue && request.FixedChronologicalAge.HasValue && request.FixedBiologicalAge > request.FixedChronologicalAge) { Log.Warning(string.Concat("Tried to generate age for pawn ", pawn, ", but pawn generation request demands biological age (", request.FixedBiologicalAge, ") to be greater than chronological age (", request.FixedChronologicalAge, ").")); } if (request.Newborn) { pawn.ageTracker.AgeBiologicalTicks = 0L; } else if (request.FixedBiologicalAge.HasValue) { pawn.ageTracker.AgeBiologicalTicks = (long)(request.FixedBiologicalAge.Value * 3600000f); } else { float num = 0f; int num2 = 0; do { num = ((pawn.RaceProps.ageGenerationCurve != null) ? ((float)Mathf.RoundToInt(Rand.ByCurve(pawn.RaceProps.ageGenerationCurve))) : ((!pawn.RaceProps.IsMechanoid) ? (Rand.ByCurve(DefaultAgeGenerationCurve) * pawn.RaceProps.lifeExpectancy) : Rand.Range(0f, 2500f))); num2++; if (num2 > 300) { Log.Error("Tried 300 times to generate age for " + pawn); break; } }while (num > (float)pawn.kindDef.maxGenerationAge || num < (float)pawn.kindDef.minGenerationAge); pawn.ageTracker.AgeBiologicalTicks = (long)(num * 3600000f) + Rand.Range(0, 3600000); } if (request.Newborn) { pawn.ageTracker.AgeChronologicalTicks = 0L; } else if (request.FixedChronologicalAge.HasValue) { pawn.ageTracker.AgeChronologicalTicks = (long)(request.FixedChronologicalAge.Value * 3600000f); } else { int num3; if (request.CertainlyBeenInCryptosleep || Rand.Value < pawn.kindDef.backstoryCryptosleepCommonality) { float value = Rand.Value; if (value < 0.7f) { num3 = Rand.Range(0, 100); } else if (value < 0.95f) { num3 = Rand.Range(100, 1000); } else { int max = GenDate.Year(GenTicks.TicksAbs, 0f) - 2026 - pawn.ageTracker.AgeBiologicalYears; num3 = Rand.Range(1000, max); } } else { num3 = 0; } long num4 = GenTicks.TicksAbs - pawn.ageTracker.AgeBiologicalTicks; num4 -= (long)num3 * 3600000L; pawn.ageTracker.BirthAbsTicks = num4; } if (pawn.ageTracker.AgeBiologicalTicks > pawn.ageTracker.AgeChronologicalTicks) { pawn.ageTracker.AgeChronologicalTicks = pawn.ageTracker.AgeBiologicalTicks; } }
private static void GenerateGearFor(Pawn pawn, PawnGenerationRequest request) { PawnApparelGenerator.GenerateStartingApparelFor(pawn, request); PawnWeaponGenerator.TryGenerateWeaponFor(pawn, request); PawnInventoryGenerator.GenerateInventoryFor(pawn, request); }
private static Pawn TryGenerateNewPawnInternal(ref PawnGenerationRequest request, out string error, bool ignoreScenarioRequirements, bool ignoreValidator) { error = null; Pawn pawn = (Pawn)ThingMaker.MakeThing(request.KindDef.race); pawnsBeingGenerated.Add(new PawnGenerationStatus(pawn, null)); try { pawn.kindDef = request.KindDef; pawn.SetFactionDirect(request.Faction); PawnComponentsUtility.CreateInitialComponents(pawn); if (request.FixedGender.HasValue) { pawn.gender = request.FixedGender.Value; } else if (pawn.RaceProps.hasGenders) { if (Rand.Value < 0.5f) { pawn.gender = Gender.Male; } else { pawn.gender = Gender.Female; } } else { pawn.gender = Gender.None; } GenerateRandomAge(pawn, request); pawn.needs.SetInitialLevels(); if (!request.Newborn && request.CanGeneratePawnRelations) { GeneratePawnRelations(pawn, ref request); } if (pawn.RaceProps.Humanlike) { Faction faction; FactionDef factionType = ((request.Faction != null) ? request.Faction.def : ((!Find.FactionManager.TryGetRandomNonColonyHumanlikeFaction_NewTemp(out faction, tryMedievalOrBetter: false, allowDefeated: true)) ? Faction.OfAncients.def : faction.def)); pawn.story.melanin = (request.FixedMelanin.HasValue ? request.FixedMelanin.Value : PawnSkinColors.RandomMelanin(request.Faction)); pawn.story.crownType = ((Rand.Value < 0.5f) ? CrownType.Average : CrownType.Narrow); pawn.story.hairColor = PawnHairColors.RandomHairColor(pawn.story.SkinColor, pawn.ageTracker.AgeBiologicalYears); PawnBioAndNameGenerator.GiveAppropriateBioAndNameTo(pawn, request.FixedLastName, factionType); if (pawn.story != null) { if (request.FixedBirthName != null) { pawn.story.birthLastName = request.FixedBirthName; } else if (pawn.Name is NameTriple) { pawn.story.birthLastName = ((NameTriple)pawn.Name).Last; } } pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(pawn, factionType); GenerateTraits(pawn, request); GenerateBodyType_NewTemp(pawn, request); GenerateSkills(pawn); } if (pawn.RaceProps.Animal && request.Faction != null && request.Faction.IsPlayer) { pawn.training.SetWantedRecursive(TrainableDefOf.Tameness, checkOn: true); pawn.training.Train(TrainableDefOf.Tameness, null, complete: true); } GenerateInitialHediffs(pawn, request); if (!request.ForbidAnyTitle) { RoyalTitleDef royalTitleDef = request.FixedTitle; if (royalTitleDef == null) { if (request.KindDef.titleRequired != null) { royalTitleDef = request.KindDef.titleRequired; } else if (!request.KindDef.titleSelectOne.NullOrEmpty() && Rand.Chance(request.KindDef.royalTitleChance)) { royalTitleDef = request.KindDef.titleSelectOne.RandomElementByWeight((RoyalTitleDef t) => t.commonality); } } if (request.KindDef.minTitleRequired != null && (royalTitleDef == null || royalTitleDef.seniority < request.KindDef.minTitleRequired.seniority)) { royalTitleDef = request.KindDef.minTitleRequired; } if (royalTitleDef != null) { Faction faction2 = ((request.Faction != null && request.Faction.def.HasRoyalTitles) ? request.Faction : Find.FactionManager.RandomRoyalFaction()); pawn.royalty.SetTitle(faction2, royalTitleDef, grantRewards: false); if (request.Faction != null && !request.Faction.IsPlayer) { PurchasePermits(pawn, faction2); } int amount = 0; if (royalTitleDef.GetNextTitle(faction2) != null) { amount = Rand.Range(0, royalTitleDef.GetNextTitle(faction2).favorCost - 1); } pawn.royalty.SetFavor_NewTemp(faction2, amount); if (royalTitleDef.maxPsylinkLevel > 0) { Hediff_ImplantWithLevel hediff_ImplantWithLevel = HediffMaker.MakeHediff(HediffDefOf.PsychicAmplifier, pawn, pawn.health.hediffSet.GetBrain()) as Hediff_ImplantWithLevel; pawn.health.AddHediff(hediff_ImplantWithLevel); hediff_ImplantWithLevel.SetLevelTo(royalTitleDef.maxPsylinkLevel); } } } if (pawn.royalty != null) { pawn.royalty.allowRoomRequirements = request.KindDef.allowRoyalRoomRequirements; pawn.royalty.allowApparelRequirements = request.KindDef.allowRoyalApparelRequirements; } if (pawn.workSettings != null && request.Faction != null && request.Faction.IsPlayer) { pawn.workSettings.EnableAndInitialize(); } if (request.Faction != null && pawn.RaceProps.Animal) { pawn.GenerateNecessaryName(); } if (Find.Scenario != null) { Find.Scenario.Notify_NewPawnGenerating(pawn, request.Context); } if (!request.AllowDead && (pawn.Dead || pawn.Destroyed)) { DiscardGeneratedPawn(pawn); error = "Generated dead pawn."; return(null); } if (!request.AllowDowned && pawn.Downed) { DiscardGeneratedPawn(pawn); error = "Generated downed pawn."; return(null); } if (request.MustBeCapableOfViolence && ((pawn.story != null && pawn.WorkTagIsDisabled(WorkTags.Violent)) || (pawn.RaceProps.ToolUser && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)))) { DiscardGeneratedPawn(pawn); error = "Generated pawn incapable of violence."; return(null); } if (request.KindDef != null && !request.KindDef.skills.NullOrEmpty()) { List <SkillRange> skills = request.KindDef.skills; for (int i = 0; i < skills.Count; i++) { if (pawn.skills.GetSkill(skills[i].Skill).TotallyDisabled) { error = "Generated pawn incapable of required skill: " + skills[i].Skill.defName; return(null); } } } if (request.KindDef.requiredWorkTags != 0 && (pawn.CombinedDisabledWorkTags & request.KindDef.requiredWorkTags) != 0) { DiscardGeneratedPawn(pawn); error = "Generated pawn with disabled requiredWorkTags."; return(null); } if (!ignoreScenarioRequirements && request.Context == PawnGenerationContext.PlayerStarter && Find.Scenario != null && !Find.Scenario.AllowPlayerStartingPawn(pawn, tryingToRedress: false, request)) { DiscardGeneratedPawn(pawn); error = "Generated pawn doesn't meet scenario requirements."; return(null); } if (!ignoreValidator && request.ValidatorPreGear != null && !request.ValidatorPreGear(pawn)) { DiscardGeneratedPawn(pawn); error = "Generated pawn didn't pass validator check (pre-gear)."; return(null); } if (!request.Newborn) { GenerateGearFor(pawn, request); } if (!ignoreValidator && request.ValidatorPostGear != null && !request.ValidatorPostGear(pawn)) { DiscardGeneratedPawn(pawn); error = "Generated pawn didn't pass validator check (post-gear)."; return(null); } for (int j = 0; j < pawnsBeingGenerated.Count - 1; j++) { if (pawnsBeingGenerated[j].PawnsGeneratedInTheMeantime == null) { pawnsBeingGenerated[j] = new PawnGenerationStatus(pawnsBeingGenerated[j].Pawn, new List <Pawn>()); } pawnsBeingGenerated[j].PawnsGeneratedInTheMeantime.Add(pawn); } return(pawn); } finally { pawnsBeingGenerated.RemoveLast(); } }
private static bool IsValidCandidateToRedress(Pawn pawn, PawnGenerationRequest request) { if (pawn.def != request.KindDef.race) { return(false); } if (!request.WorldPawnFactionDoesntMatter && pawn.Faction != request.Faction) { return(false); } if (!request.AllowDead) { if (pawn.Dead || pawn.Destroyed) { return(false); } if (pawn.health.hediffSet.GetBrain() == null) { return(false); } } if (!request.AllowDowned && pawn.Downed) { return(false); } if (pawn.health.hediffSet.BleedRateTotal > 0.001f) { return(false); } if (!request.CanGeneratePawnRelations && pawn.RaceProps.IsFlesh && pawn.relations.RelatedToAnyoneOrAnyoneRelatedToMe) { return(false); } if (!request.AllowGay && pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOf.Gay)) { return(false); } if (!request.AllowAddictions && AddictionUtility.AddictedToAnything(pawn)) { return(false); } if (request.ProhibitedTraits != null && request.ProhibitedTraits.Any((TraitDef t) => pawn.story.traits.HasTrait(t))) { return(false); } List <SkillRange> skills = request.KindDef.skills; if (skills != null) { for (int i = 0; i < skills.Count; i++) { SkillRecord skill = pawn.skills.GetSkill(skills[i].Skill); if (skill.TotallyDisabled) { return(false); } if (skill.Level < skills[i].Range.min || skill.Level > skills[i].Range.max) { return(false); } } } if (request.ForcedTraits != null) { foreach (TraitDef forcedTrait in request.ForcedTraits) { if (!pawn.story.traits.HasTrait(forcedTrait)) { return(false); } } } if (request.ValidatorPreGear != null && !request.ValidatorPreGear(pawn)) { return(false); } if (request.ValidatorPostGear != null && !request.ValidatorPostGear(pawn)) { return(false); } if (request.FixedBiologicalAge.HasValue && pawn.ageTracker.AgeBiologicalYearsFloat != request.FixedBiologicalAge) { return(false); } if (request.FixedChronologicalAge.HasValue && (float)pawn.ageTracker.AgeChronologicalYears != request.FixedChronologicalAge) { return(false); } if (request.FixedGender.HasValue && pawn.gender != request.FixedGender) { return(false); } if (request.FixedLastName != null && (!(pawn.Name is NameTriple) || ((NameTriple)pawn.Name).Last != request.FixedLastName)) { return(false); } if (request.FixedMelanin.HasValue && pawn.story != null && pawn.story.melanin != request.FixedMelanin) { return(false); } if (request.FixedTitle != null && (pawn.royalty == null || !pawn.royalty.HasTitle(request.FixedTitle))) { return(false); } if (request.KindDef.minTitleRequired != null) { if (pawn.royalty == null) { return(false); } RoyalTitleDef royalTitleDef = pawn.royalty.MainTitle(); if (royalTitleDef == null || royalTitleDef.seniority < request.KindDef.minTitleRequired.seniority) { return(false); } } if (request.Context == PawnGenerationContext.PlayerStarter && Find.Scenario != null && !Find.Scenario.AllowPlayerStartingPawn(pawn, tryingToRedress: true, request)) { return(false); } if (request.MustBeCapableOfViolence) { if (pawn.WorkTagIsDisabled(WorkTags.Violent)) { return(false); } if (pawn.RaceProps.ToolUser && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { return(false); } } if (request.RedressValidator != null && !request.RedressValidator(pawn)) { return(false); } if (request.KindDef.requiredWorkTags != 0 && pawn.kindDef != request.KindDef && (pawn.CombinedDisabledWorkTags & request.KindDef.requiredWorkTags) != 0) { return(false); } return(true); }
private static IEnumerable InfectionSimulatorWorker() { int trials = 2; List <Pawn> doctors = GenerateDoctorArray(); List <int> testSkill = new List <int> { 4, 10, 16 }; List <ThingDef> testMedicine = new List <ThingDef> { null, ThingDefOf.MedicineHerbal, ThingDefOf.MedicineIndustrial, ThingDefOf.MedicineUltratech }; PawnGenerationRequest pawngen = new PawnGenerationRequest(PawnKindDefOf.Colonist, Faction.OfPlayer); int originalTicks = Find.TickManager.TicksGame; List <InfectionSimRow> results = new List <InfectionSimRow>(); int totalTests = InfectionList().Count() * testMedicine.Count() * testSkill.Count() * trials; int currentTest = 0; foreach (HediffDef hediff in InfectionList()) { foreach (ThingDef meds in testMedicine) { foreach (int item in testSkill) { InfectionSimRow result = default(InfectionSimRow); result.illness = hediff; result.skill = item; result.medicine = meds; Pawn doctor = doctors[item]; int i = 0; while (i < trials) { Pawn patient = PawnGenerator.GeneratePawn(pawngen); int startTicks = Find.TickManager.TicksGame; patient.health.AddHediff(result.illness); Hediff activeHediff = patient.health.hediffSet.GetFirstHediffOfDef(result.illness); while (!patient.Dead && patient.health.hediffSet.HasHediff(result.illness)) { if (activeHediff.TendableNow()) { activeHediff.Tended(TendUtility.CalculateBaseTendQuality(doctor, patient, meds)); result.medicineUsed += 1f; } foreach (Hediff item2 in patient.health.hediffSet.GetHediffsTendable()) { item2.Tended(TendUtility.CalculateBaseTendQuality(doctor, patient, meds)); } Find.TickManager.DebugSetTicksGame(Find.TickManager.TicksGame + 1); patient.health.HealthTick(); if (Find.TickManager.TicksGame % 900 == 0) { yield return(null); } } if (patient.Dead) { result.deathChance += 1f; } else { result.recoveryTimeDays += (Find.TickManager.TicksGame - startTicks).TicksToDays(); } int num = currentTest + 1; currentTest = num; LongEventHandler.SetCurrentEventText($"Simulating ({currentTest}/{totalTests})"); yield return(null); num = i + 1; i = num; } result.recoveryTimeDays /= (float)trials - result.deathChance; result.deathChance /= trials; result.medicineUsed /= trials; results.Add(result); result = default(InfectionSimRow); } } } DebugTables.MakeTablesDialog(results, new TableDataGetter <InfectionSimRow>("defName", (InfectionSimRow isr) => isr.illness.defName), new TableDataGetter <InfectionSimRow>("meds", (InfectionSimRow isr) => (isr.medicine == null) ? "(none)" : isr.medicine.defName), new TableDataGetter <InfectionSimRow>("skill", (InfectionSimRow isr) => isr.skill.ToString()), new TableDataGetter <InfectionSimRow>("death chance", (InfectionSimRow isr) => isr.deathChance.ToStringPercent()), new TableDataGetter <InfectionSimRow>("recovery time (days)", (InfectionSimRow isr) => isr.recoveryTimeDays.ToString("F1")), new TableDataGetter <InfectionSimRow>("medicine used", (InfectionSimRow isr) => isr.medicineUsed.ToString())); Find.TickManager.DebugSetTicksGame(originalTicks); }