public static void Postfix(ImmunityRecord __instance, ref float __result, Pawn pawn) { if (true && pawn.IsValidWildlifeOrWorldPawn() && pawn.IsSkippingTicks()) { __result *= pawn.GetDeltaT(); } }
public IEnumerable <ImmunityRecord> ImmunitiesToSet(Pawn p) { foreach (Hediff h in p.health.hediffSet.hediffs) { ImmunityRecord ir = p.health.immunity.GetImmunityRecord(h.def); if (ir != null) { yield return(ir); } } }
public static bool ImmunityHandlerTick(ImmunityHandler __instance) { List <ImmunityInfo> list = __instance.NeededImmunitiesNow(); for (int i = 0; i < list.Count; i++) { __instance.TryAddImmunityRecord(list[i].immunity, list[i].source); } lock (__instance) { List <ImmunityRecord> newImmunityList = new List <ImmunityRecord>(__instance.immunityList); for (int j = 0; j < __instance.immunityList.Count; j++) { ImmunityRecord immunityRecord = newImmunityList[j]; Hediff firstHediffOfDef = __instance.pawn.health.hediffSet.GetFirstHediffOfDef(immunityRecord.hediffDef); immunityRecord.ImmunityTick(__instance.pawn, firstHediffOfDef != null, firstHediffOfDef); } for (int num = newImmunityList.Count - 1; num >= 0; num--) { if (newImmunityList[num].immunity <= 0f) { bool flag = false; for (int k = 0; k < list.Count; k++) { if (list[k].immunity == newImmunityList[num].hediffDef) { flag = true; break; } } if (!flag) { newImmunityList.RemoveAt(num); } } } __instance.immunityList = newImmunityList; } return(false); }
private static void HealIfPossible(Pawn p) { PawnBanishUtility.tmpHediffs.Clear(); PawnBanishUtility.tmpHediffs.AddRange(p.health.hediffSet.hediffs); for (int i = 0; i < PawnBanishUtility.tmpHediffs.Count; i++) { Hediff_Injury hediff_Injury = PawnBanishUtility.tmpHediffs[i] as Hediff_Injury; if (hediff_Injury != null && !hediff_Injury.IsPermanent()) { p.health.RemoveHediff(hediff_Injury); } else { ImmunityRecord immunityRecord = p.health.immunity.GetImmunityRecord(PawnBanishUtility.tmpHediffs[i].def); if (immunityRecord != null) { immunityRecord.immunity = 1f; } } } }
public static void update_immunodeficiency(Pawn p) { float min_bf_for_id = 1.0f - std.immunodeficiency.minSeverity; Hediff id = p.health.hediffSet.GetFirstHediffOfDef(std.immunodeficiency); float bf = p.health.capacities.GetLevel(PawnCapacityDefOf.BloodFiltration); bool has = id != null; bool should_have = bf <= min_bf_for_id; if (has && !should_have) { p.health.RemoveHediff(id); id = null; } else if (!has && should_have) { p.health.AddHediff(std.immunodeficiency); id = p.health.hediffSet.GetFirstHediffOfDef(std.immunodeficiency); } if (id == null) { return; } id.Severity = 1.0f - bf; // Roll for and apply opportunistic infections: // Pawns will have a 90% chance for at least one infection each year at 0% filtration, and a 0% // chance at 40% filtration, scaling linearly. // Let x = chance infected per roll // Then chance not infected per roll = 1 - x // And chance not infected on any roll in one day = (1 - x) ^ (60000 / 150) = (1 - x) ^ 400 // And chance not infected on any roll in one year = (1 - x) ^ (400 * 60) = (1 - x) ^ 24000 // So 0.10 = (1 - x) ^ 24000 // log (0.10) = 24000 log (1 - x) // x = 0.00009593644334648975435114691213 = ~96 in 1 million // Important Note: // this function is called from Need_Sex::NeedInterval(), where it involves a needsex_tick and a std_tick to actually trigger this update_immunodeficiency. // j(this is not exactly the same as the value in Need_Sex, that value is 0, but here j should be 1) std_ticks per this function called, k needsex_ticks per std_tick, 150 ticks per needsex_tick, and x is the chance per 150 ticks, // The new equation should be .1 = (1-x)^(24000/kj) // log(.1) = (24000/kj) log(1-x), so log(1-x)= (kj/24000) log(.1), 1-x = .1^(kj/24000), x= 1-.1^(kj/24000) // Since k=10,j=1, so kj=10, new x is 1-.1^(10/24000)=0.0009589504, let it be 959/1000000 //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); if (Rand.RangeInclusive(1, 1000000) <= 959 && Rand.Value < bf / min_bf_for_id) { BodyPartRecord part; { float rv = Rand.Value; var parts = p.RaceProps.body.AllParts; if (rv < 0.25f) { part = parts.Find(bpr => string.Equals(bpr.def.defName, "Jaw")); } else if (rv < 0.50f) { part = parts.Find(bpr => string.Equals(bpr.def.defName, "Lung")); } else if (rv < 0.75f) { part = parts.FindLast(bpr => string.Equals(bpr.def.defName, "Lung")); } else { part = parts.RandomElement(); } } if (part != null && !p.health.hediffSet.PartIsMissing(part) && !p.health.hediffSet.HasDirectlyAddedPartFor(part) && p.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.WoundInfection) == null && // If the pawn already has a wound infection, we can't properly set the immunity for the new one p.health.immunity.GetImmunity(HediffDefOf.WoundInfection) <= 0.0f) { // Dont spawn infection if pawn already has immunity p.health.AddHediff(HediffDefOf.WoundInfection, part); p.health.HealthTick(); // Creates the immunity record ImmunityRecord ir = p.health.immunity.GetImmunityRecord(HediffDefOf.WoundInfection); if (ir != null) { ir.immunity = xxx.config.opp_inf_initial_immunity; } const string message_title = "Opportunistic Infection"; string message_text = "RJW_Opportunistic_Infection_Message".Translate(xxx.get_pawnname(p)); Find.LetterStack.ReceiveLetter(message_title, message_text, LetterDefOf.ThreatSmall); } } }
private static void DoDebugOptions(Rect rightRect, Pawn pawn) { Widgets.CheckboxLabeled(new Rect(rightRect.x, rightRect.y - 25f, 110f, 30f), "Dev: AllDiffs", ref showAllHediffs); Widgets.CheckboxLabeled(new Rect(rightRect.x + 115f, rightRect.y - 25f, 120f, 30f), "DiffsDebugInfo", ref showHediffsDebugInfo); if (!Widgets.ButtonText(new Rect(rightRect.x + 240f, rightRect.y - 27f, 115f, 25f), "Debug info")) { return; } List <FloatMenuOption> list = new List <FloatMenuOption>(); list.Add(new FloatMenuOption("Parts hit chance (this part or any child node)", delegate { StringBuilder stringBuilder13 = new StringBuilder(); foreach (BodyPartRecord item2 in pawn.RaceProps.body.AllParts.OrderByDescending((BodyPartRecord x) => x.coverageAbsWithChildren)) { stringBuilder13.AppendLine(item2.LabelCap + " " + item2.coverageAbsWithChildren.ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder13.ToString())); })); list.Add(new FloatMenuOption("Parts hit chance (exactly this part)", delegate { StringBuilder stringBuilder12 = new StringBuilder(); float num2 = 0f; foreach (BodyPartRecord item3 in pawn.RaceProps.body.AllParts.OrderByDescending((BodyPartRecord x) => x.coverageAbs)) { stringBuilder12.AppendLine(item3.LabelCap + " " + item3.coverageAbs.ToStringPercent()); num2 += item3.coverageAbs; } stringBuilder12.AppendLine(); stringBuilder12.AppendLine("Total " + num2.ToStringPercent()); Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder12.ToString())); })); list.Add(new FloatMenuOption("Per-part efficiency", delegate { StringBuilder stringBuilder11 = new StringBuilder(); foreach (BodyPartRecord allPart in pawn.RaceProps.body.AllParts) { stringBuilder11.AppendLine(allPart.LabelCap + " " + PawnCapacityUtility.CalculatePartEfficiency(pawn.health.hediffSet, allPart).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder11.ToString())); })); list.Add(new FloatMenuOption("BodyPartGroup efficiency (of only natural parts)", delegate { StringBuilder stringBuilder10 = new StringBuilder(); foreach (BodyPartGroupDef item4 in DefDatabase <BodyPartGroupDef> .AllDefs.Where((BodyPartGroupDef x) => pawn.RaceProps.body.AllParts.Any((BodyPartRecord y) => y.groups.Contains(x)))) { stringBuilder10.AppendLine(item4.LabelCap + " " + PawnCapacityUtility.CalculateNaturalPartsAverageEfficiency(pawn.health.hediffSet, item4).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder10.ToString())); })); list.Add(new FloatMenuOption("IsSolid", delegate { StringBuilder stringBuilder9 = new StringBuilder(); foreach (BodyPartRecord notMissingPart in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder9.AppendLine(notMissingPart.LabelCap + " " + notMissingPart.def.IsSolid(notMissingPart, pawn.health.hediffSet.hediffs)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder9.ToString())); })); list.Add(new FloatMenuOption("IsSkinCovered", delegate { StringBuilder stringBuilder8 = new StringBuilder(); foreach (BodyPartRecord notMissingPart2 in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder8.AppendLine(notMissingPart2.LabelCap + " " + notMissingPart2.def.IsSkinCovered(notMissingPart2, pawn.health.hediffSet)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder8.ToString())); })); list.Add(new FloatMenuOption("Immunities", delegate { StringBuilder stringBuilder7 = new StringBuilder(); foreach (HediffDef item5 in DefDatabase <HediffDef> .AllDefsListForReading) { ImmunityRecord immunityRecord = pawn.health.immunity.GetImmunityRecord(item5); if (immunityRecord != null) { stringBuilder7.AppendLine(string.Concat("Hediff: ", immunityRecord.hediffDef, ", Source: ", immunityRecord.source, ", Immunity: ", immunityRecord.immunity)); } } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder7.ToString())); })); list.Add(new FloatMenuOption("does have added parts", delegate { StringBuilder stringBuilder6 = new StringBuilder(); foreach (BodyPartRecord notMissingPart3 in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder6.AppendLine(notMissingPart3.LabelCap + " " + pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(notMissingPart3)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder6.ToString())); })); list.Add(new FloatMenuOption("GetNotMissingParts", delegate { StringBuilder stringBuilder5 = new StringBuilder(); foreach (BodyPartRecord notMissingPart4 in pawn.health.hediffSet.GetNotMissingParts()) { stringBuilder5.AppendLine(notMissingPart4.LabelCap); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder5.ToString())); })); list.Add(new FloatMenuOption("GetCoverageOfNotMissingNaturalParts", delegate { StringBuilder stringBuilder4 = new StringBuilder(); foreach (BodyPartRecord item6 in pawn.RaceProps.body.AllParts.OrderByDescending((BodyPartRecord x) => pawn.health.hediffSet.GetCoverageOfNotMissingNaturalParts(x))) { stringBuilder4.AppendLine(item6.LabelCap + ": " + pawn.health.hediffSet.GetCoverageOfNotMissingNaturalParts(item6).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder4.ToString())); })); list.Add(new FloatMenuOption("parts nutrition (assuming adult)", delegate { StringBuilder stringBuilder3 = new StringBuilder(); float totalCorpseNutrition = StatDefOf.Nutrition.Worker.GetValueAbstract(pawn.RaceProps.corpseDef); foreach (BodyPartRecord item7 in pawn.RaceProps.body.AllParts.OrderByDescending((BodyPartRecord x) => FoodUtility.GetBodyPartNutrition(totalCorpseNutrition, pawn, x))) { stringBuilder3.AppendLine(item7.LabelCap + ": " + FoodUtility.GetBodyPartNutrition(totalCorpseNutrition, pawn, item7)); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder3.ToString())); })); list.Add(new FloatMenuOption("HediffGiver_Birthday chance at age", delegate { List <FloatMenuOption> list2 = new List <FloatMenuOption>(); HediffGiver_Birthday hLocal = default(HediffGiver_Birthday); foreach (HediffGiverSetDef hediffGiverSet in pawn.RaceProps.hediffGiverSets) { foreach (HediffGiver_Birthday item8 in hediffGiverSet.hediffGivers.OfType <HediffGiver_Birthday>()) { hLocal = item8; FloatMenuOption item = new FloatMenuOption(hediffGiverSet.defName + " - " + item8.hediff.defName, delegate { StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.AppendLine("% of pawns which will have at least 1 " + hLocal.hediff.label + " at age X:"); stringBuilder2.AppendLine(); for (int j = 1; (float)j < pawn.RaceProps.lifeExpectancy + 20f; j++) { stringBuilder2.AppendLine(j + ": " + hLocal.DebugChanceToHaveAtAge(pawn, j).ToStringPercent()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder2.ToString())); }); list2.Add(item); } } Find.WindowStack.Add(new FloatMenu(list2)); })); list.Add(new FloatMenuOption("HediffGiver_Birthday count at age", delegate { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Average hediffs count (from HediffGiver_Birthday) at age X:"); stringBuilder.AppendLine(); for (int i = 1; (float)i < pawn.RaceProps.lifeExpectancy + 20f; i++) { float num = 0f; foreach (HediffGiverSetDef hediffGiverSet2 in pawn.RaceProps.hediffGiverSets) { foreach (HediffGiver_Birthday item9 in hediffGiverSet2.hediffGivers.OfType <HediffGiver_Birthday>()) { num += item9.DebugChanceToHaveAtAge(pawn, i); } } stringBuilder.AppendLine(i + ": " + num.ToStringDecimalIfSmall()); } Find.WindowStack.Add(new Dialog_MessageBox(stringBuilder.ToString())); })); Find.WindowStack.Add(new FloatMenu(list)); }
public override void DoCell(Rect rect, Pawn pawn, PawnTable table) { if (pawn.Dead || pawn.health?.hediffSet == null || !pawn.health.hediffSet.HasImmunizableNotImmuneHediff()) { return; } HediffWithComps mostSevere = FindMostSevereHediff(pawn); if (mostSevere == null) { return; } float deltaSeverity = GetTextFor(mostSevere); GUI.color = GetPrettyColorFor(deltaSeverity); Rect rect2 = new Rect(rect.x, rect.y, rect.width, Mathf.Min(rect.height, 30f)); Text.Font = GameFont.Small; Text.Anchor = TextAnchor.MiddleCenter; Text.WordWrap = false; Widgets.Label(rect2, GetTextFor(mostSevere).ToStringPercent()); Text.WordWrap = true; Text.Anchor = TextAnchor.UpperLeft; string tip = GetTip(pawn, mostSevere); if (!tip.NullOrEmpty()) { TooltipHandler.TipRegion(rect2, tip); } float severityChangePerDayFromImmu = (float)AccessTools.Method(typeof(HediffComp_Immunizable), "SeverityChangePerDay") .Invoke(mostSevere.TryGetComp <HediffComp_Immunizable>(), null); float severityChangePerDayFromTendD = 0f; if (mostSevere.TryGetComp <HediffComp_TendDuration>()?.IsTended ?? false) { severityChangePerDayFromTendD = mostSevere.TryGetComp <HediffComp_TendDuration>().TProps.severityPerDayTended * mostSevere.TryGetComp <HediffComp_TendDuration>().tendQuality; } float immunityPerDay = 0f; ImmunityRecord immunityRecord = pawn.health.immunity.GetImmunityRecord(mostSevere.def); if (immunityRecord != null) { immunityPerDay = immunityRecord.ImmunityChangePerTick(pawn, true, mostSevere) * GenDate.TicksPerDay; } GUI.color = Color.white; bool redFlag = !(severityChangePerDayFromTendD + severityChangePerDayFromImmu > immunityPerDay); Texture2D texture2D = redFlag ? StaticConstructorOnGameStart.SortingIcon : StaticConstructorOnGameStart.SortingDescendingIcon; GUI.color = redFlag ? HealthUtility.GoodConditionColor : HealthUtility.RedColor; Rect position2 = new Rect(rect.xMax - texture2D.width - 1f, rect.yMax - texture2D.height - 1f, texture2D.width, texture2D.height); GUI.DrawTexture(position2, texture2D); GUI.color = Color.white; }
/// <summary> /// Event on immunity ticker /// </summary> /// <param name="pawn"></param> /// <param name="sick"></param> /// <param name="diseaseInstance"></param> public static void ImmunityTicking(Pawn pawn, bool sick, Hediff diseaseInstance, ImmunityRecord __instance) { foreach (var card in AchievementPointManager.GetCards <ImmunityHediffTracker>()) { try { if ((card.tracker as ImmunityHediffTracker).Trigger(diseaseInstance, __instance.immunity)) { card.UnlockCard(); } } catch (Exception ex) { Log.Error($"Unable to trigger event for card validation. To avoid further errors {card.def.LabelCap} has been automatically unlocked.\n\nException={ex.Message}"); card.UnlockCard(); } } }