public override void Tick() { this.ageTicks++; if (this.pawn.IsHashIntervalTick(1000)) { if (this.pawn.needs.food != null && this.pawn.needs.food.CurCategory == HungerCategory.Starving && this.pawn.health.hediffSet.HasHediff(HediffDefOf.Malnutrition, false) && this.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Malnutrition, false).Severity > 0.25f && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageMiscarriedStarvation".Translate(this.pawn).CapitalizeFirst(), this.pawn, MessageTypeDefOf.NegativeHealthEvent, true); } this.Miscarry(); return; } if (this.IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageMiscarriedPoorHealth".Translate(this.pawn).CapitalizeFirst(), this.pawn, MessageTypeDefOf.NegativeHealthEvent, true); } this.Miscarry(); return; } } this.GestationProgress += 1f / (this.pawn.RaceProps.gestationPeriodDays * 60000f); if (this.GestationProgress >= 1f) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn)) { Messages.Message("MessageGaveBirth".Translate(this.pawn).CapitalizeFirst(), this.pawn, MessageTypeDefOf.PositiveEvent, true); } Hediff_Pregnant.DoBirthSpawn(this.pawn, this.father); this.pawn.health.RemoveHediff(this); } }
public override void CompPostTick(ref float severityAdjustment) { base.CompPostTick(ref severityAdjustment); if (base.Pawn.IsHashIntervalTick(5000) && Rand.MTBEventOccurs(100f, 60000f, 5000f)) { this.ChangeGrowthMode(); } }
public override void OnIntervalPassed(Pawn pawn, Hediff cause) { float x = (float)pawn.ageTracker.AgeBiologicalYears / pawn.RaceProps.lifeExpectancy; if (Rand.MTBEventOccurs(ageFractionMtbDaysCurve.Evaluate(x), 60000f, 60f) && (minPlayerPopulation <= 0 || pawn.Faction != Faction.OfPlayer || PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_FreeColonists_NoCryptosleep.Count() >= minPlayerPopulation) && TryApply(pawn)) { SendLetter(pawn, cause); } }
public override void OnIntervalPassed(Pawn pawn, Hediff cause) { float x = (float)pawn.ageTracker.AgeBiologicalYears / pawn.RaceProps.lifeExpectancy; if (Rand.MTBEventOccurs(this.ageFractionMtbDaysCurve.Evaluate(x), 60000f, 60f) && base.TryApply(pawn, null)) { base.SendLetter(pawn, cause); } }
public override void OnIntervalPassed(Pawn pawn, Hediff cause) { if (Rand.MTBEventOccurs(this.mtbDays, 60000f, 60f)) { if (base.TryApply(pawn, null)) { base.SendLetter(pawn, cause); } } }
internal static void LogRandTests() { StringBuilder stringBuilder = new StringBuilder(); int @int = Rand.Int; stringBuilder.AppendLine("Repeating single ValueSeeded with seed " + @int + ". This should give the same result:"); for (int i = 0; i < 4; i++) { stringBuilder.AppendLine(" " + Rand.ValueSeeded(@int)); } stringBuilder.AppendLine(); stringBuilder.AppendLine("Long-term tests"); for (int j = 0; j < 3; j++) { int num = 0; for (int k = 0; k < 5000000; k++) { if (Rand.MTBEventOccurs(250f, 60000f, 60f)) { num++; } } string value = "MTB=" + 250 + " days, MTBUnit=" + 60000 + ", check duration=" + 60 + " Simulated " + 5000 + " days (" + 5000000 + " tests). Got " + num + " events."; stringBuilder.AppendLine(value); } stringBuilder.AppendLine(); stringBuilder.AppendLine("Short-term tests"); for (int l = 0; l < 5; l++) { int num2 = 0; for (int m = 0; m < 10000; m++) { if (Rand.MTBEventOccurs(1f, 24000f, 12000f)) { num2++; } } string value2 = "MTB=" + 1f + " days, MTBUnit=" + 24000f + ", check duration=" + 12000f + ", " + 10000 + " tests got " + num2 + " events."; stringBuilder.AppendLine(value2); } for (int n = 0; n < 5; n++) { int num3 = 0; for (int num4 = 0; num4 < 10000; num4++) { if (Rand.MTBEventOccurs(2f, 24000f, 6000f)) { num3++; } } string value3 = "MTB=" + 2f + " days, MTBUnit=" + 24000f + ", check duration=" + 6000f + ", " + 10000 + " tests got " + num3 + " events."; stringBuilder.AppendLine(value3); } Log.Message(stringBuilder.ToString()); }
public override void OnIntervalPassed(Pawn pawn, Hediff cause) { if (cause.Severity < this.minSeverity) { return; } if (Rand.MTBEventOccurs(this.baseMtbDays, 60000f, 60f) && base.TryApply(pawn, null)) { base.SendLetter(pawn, cause); } }
public override void OnIntervalPassed(Pawn pawn, Hediff cause) { if (pawn.IsNestedHashIntervalTick(60, mtbCheckInterval) && Rand.MTBEventOccurs(mtbHours, 2500f, mtbCheckInterval)) { if (TryApply(pawn)) { SendLetter(pawn, cause); } pawn.health.hediffSet.GetFirstHediffOfDef(hediff).Severity += severityAmount; } }
public override void OnIntervalPassed(Pawn pawn, Hediff cause) { float x = (float)pawn.ageTracker.AgeBiologicalYears / pawn.RaceProps.lifeExpectancy; if (Rand.MTBEventOccurs(this.ageFractionMtbDaysCurve.Evaluate(x), 60000f, 60f)) { if (this.minPlayerPopulation > 0 && pawn.Faction == Faction.OfPlayer && PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_FreeColonists_NoCryptosleep.Count <Pawn>() < this.minPlayerPopulation) { return; } if (base.TryApply(pawn, null)) { base.SendLetter(pawn, cause); } } }
public override void Tick() { ageTicks++; if (pawn.IsHashIntervalTick(1000)) { if (pawn.needs.food != null && pawn.needs.food.CurCategory == HungerCategory.Starving && pawn.health.hediffSet.HasHediff(HediffDefOf.Malnutrition) && pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Malnutrition).Severity > 0.25f && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) { string value = pawn.Name.Numerical ? pawn.LabelShort : (pawn.LabelShort + " (" + pawn.kindDef.label + ")"); Messages.Message("MessageMiscarriedStarvation".Translate(value, pawn), pawn, MessageTypeDefOf.NegativeHealthEvent); } Miscarry(); return; } if (IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) { string value2 = pawn.Name.Numerical ? pawn.LabelShort : (pawn.LabelShort + " (" + pawn.kindDef.label + ")"); Messages.Message("MessageMiscarriedPoorHealth".Translate(value2, pawn), pawn, MessageTypeDefOf.NegativeHealthEvent); } Miscarry(); return; } } GestationProgress += 1f / (pawn.RaceProps.gestationPeriodDays * 60000f); if (GestationProgress >= 1f) { if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn)) { Messages.Message("MessageGaveBirth".Translate(pawn), pawn, MessageTypeDefOf.PositiveEvent); } DoBirthSpawn(pawn, father); pawn.health.RemoveHediff(this); } }
public override void CompPostTick(ref float severityAdjustment) { float mtbDays = Props.probabilityPerStage[parent.CurStageIndex].mtbDays; if (!(mtbDays > 0f) || !base.Pawn.IsHashIntervalTick(60)) { return; } ChangeImplantLevel_Probability changeImplantLevel_Probability = Props.probabilityPerStage[parent.CurStageIndex]; if ((lastChangeLevelTick < 0 || (float)(Find.TickManager.TicksGame - lastChangeLevelTick) >= changeImplantLevel_Probability.minIntervalDays * 60000f) && Rand.MTBEventOccurs(mtbDays, 60000f, 60f)) { Hediff_ImplantWithLevel hediff_ImplantWithLevel = parent.pawn.health.hediffSet.GetFirstHediffOfDef(Props.implant) as Hediff_ImplantWithLevel; if (hediff_ImplantWithLevel != null) { hediff_ImplantWithLevel.ChangeLevel(Props.levelOffset); lastChangeLevelTick = Find.TickManager.TicksGame; Messages.Message("MessageLostImplantLevelFromHediff".Translate(parent.pawn.Named("PAWN"), hediff_ImplantWithLevel.LabelBase, parent.Label), parent.pawn, MessageTypeDefOf.NegativeEvent); } } }
public override void Tick() { base.ageTicks++; if (base.pawn.IsHashIntervalTick(1000)) { if (base.pawn.needs.food != null && base.pawn.needs.food.CurCategory == HungerCategory.Starving && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(base.pawn)) { Messages.Message("MessageMiscarriedStarvation".Translate(base.pawn.LabelIndefinite()).CapitalizeFirst(), base.pawn, MessageTypeDefOf.NegativeHealthEvent); } this.Miscarry(); return; } if (this.IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, 60000f, 1000f)) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(base.pawn)) { Messages.Message("MessageMiscarriedPoorHealth".Translate(base.pawn.LabelIndefinite()).CapitalizeFirst(), base.pawn, MessageTypeDefOf.NegativeHealthEvent); } this.Miscarry(); return; } } this.GestationProgress += (float)(1.0 / (base.pawn.RaceProps.gestationPeriodDays * 60000.0)); if (this.GestationProgress >= 1.0) { if (this.Visible && PawnUtility.ShouldSendNotificationAbout(base.pawn)) { Messages.Message("MessageGaveBirth".Translate(base.pawn.LabelIndefinite()).CapitalizeFirst(), base.pawn, MessageTypeDefOf.PositiveEvent); } Hediff_Pregnant.DoBirthSpawn(base.pawn, this.father); base.pawn.health.RemoveHediff(this); } }
public virtual void Tick() { this.ageTicks++; if (this.def.hediffGivers != null && this.pawn.IsHashIntervalTick(60)) { for (int i = 0; i < this.def.hediffGivers.Count; i++) { this.def.hediffGivers[i].OnIntervalPassed(this.pawn, this); } } if (this.Visible && !this.visible) { this.visible = true; if (this.def.taleOnVisible != null) { TaleRecorder.RecordTale(this.def.taleOnVisible, new object[] { this.pawn, this.def }); } } HediffStage curStage = this.CurStage; if (curStage != null) { if (curStage.hediffGivers != null && this.pawn.IsHashIntervalTick(60)) { for (int j = 0; j < curStage.hediffGivers.Count; j++) { curStage.hediffGivers[j].OnIntervalPassed(this.pawn, this); } } if (curStage.mentalStateGivers != null && this.pawn.IsHashIntervalTick(60) && !this.pawn.InMentalState) { for (int k = 0; k < curStage.mentalStateGivers.Count; k++) { MentalStateGiver mentalStateGiver = curStage.mentalStateGivers[k]; if (Rand.MTBEventOccurs(mentalStateGiver.mtbDays, 60000f, 60f)) { this.pawn.mindState.mentalStateHandler.TryStartMentalState(mentalStateGiver.mentalState, "MentalStateReason_Hediff".Translate(this.Label), false, false, null, false); } } } MentalBreakDef mentalBreakDef; if (curStage.mentalBreakMtbDays > 0f && this.pawn.IsHashIntervalTick(60) && !this.pawn.InMentalState && Rand.MTBEventOccurs(curStage.mentalBreakMtbDays, 60000f, 60f) && (from x in DefDatabase <MentalBreakDef> .AllDefsListForReading where x.Worker.BreakCanOccur(this.pawn) select x).TryRandomElementByWeight((MentalBreakDef x) => x.Worker.CommonalityFor(this.pawn), out mentalBreakDef)) { mentalBreakDef.Worker.TryStart(this.pawn, "MentalStateReason_Hediff".Translate(this.Label), false); } if (curStage.vomitMtbDays > 0f && this.pawn.IsHashIntervalTick(600) && Rand.MTBEventOccurs(curStage.vomitMtbDays, 60000f, 600f) && this.pawn.Spawned && this.pawn.Awake()) { this.pawn.jobs.StartJob(new Job(JobDefOf.Vomit), JobCondition.InterruptForced, null, true, true, null, null, false); } Thought_Memory th; if (curStage.forgetMemoryThoughtMtbDays > 0f && this.pawn.needs.mood != null && this.pawn.IsHashIntervalTick(400) && Rand.MTBEventOccurs(curStage.forgetMemoryThoughtMtbDays, 60000f, 400f) && this.pawn.needs.mood.thoughts.memories.Memories.TryRandomElement(out th)) { this.pawn.needs.mood.thoughts.memories.RemoveMemory(th); } if (!this.recordedTale && curStage.tale != null) { TaleRecorder.RecordTale(curStage.tale, new object[] { this.pawn }); this.recordedTale = true; } if (curStage.destroyPart && this.Part != null && this.Part != this.pawn.RaceProps.body.corePart) { this.pawn.health.AddHediff(HediffDefOf.MissingBodyPart, this.Part, null, null); } if (curStage.deathMtbDays > 0f && this.pawn.IsHashIntervalTick(200) && Rand.MTBEventOccurs(curStage.deathMtbDays, 60000f, 200f)) { bool flag = PawnUtility.ShouldSendNotificationAbout(this.pawn); Caravan caravan = this.pawn.GetCaravan(); this.pawn.Kill(null, null); if (flag) { this.pawn.health.NotifyPlayerOfKilled(null, this, caravan); } return; } } }
public override void CompPostTick(ref float severityAdjustment) { if (Props.mtbDaysPerStage[parent.CurStageIndex] > 0f && base.Pawn.IsHashIntervalTick(60) && Rand.MTBEventOccurs(Props.mtbDaysPerStage[parent.CurStageIndex], 60000f, 60f)) { BodyPartRecord brain = base.Pawn.health.hediffSet.GetBrain(); if (brain != null) { int randomInRange = Props.damageAmount.RandomInRange; base.Pawn.TakeDamage(new DamageInfo(DamageDefOf.Burn, randomInRange, 0f, -1f, null, brain)); Messages.Message("MessageReceivedBrainDamageFromHediff".Translate(base.Pawn.Named("PAWN"), randomInRange, parent.Label), base.Pawn, MessageTypeDefOf.NegativeEvent); } } }
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)); } } } } } } } }
internal static void RandTests() { StringBuilder stringBuilder = new StringBuilder(); int @int = Rand.Int; stringBuilder.AppendLine("Repeating single ValueSeeded with seed " + @int + ". This should give the same result:"); for (int i = 0; i < 4; i++) { stringBuilder.AppendLine(" " + Rand.ValueSeeded(@int)); } stringBuilder.AppendLine(); stringBuilder.AppendLine("Long-term tests"); for (int j = 0; j < 3; j++) { int num = 0; for (int k = 0; k < 5000000; k++) { if (Rand.MTBEventOccurs(250f, 60000f, 60f)) { num++; } } string value = string.Concat(new object[] { "MTB=", 250, " days, MTBUnit=", 60000, ", check duration=", 60, " Simulated ", 5000, " days (", 5000000, " tests). Got ", num, " events." }); stringBuilder.AppendLine(value); } stringBuilder.AppendLine(); stringBuilder.AppendLine("Short-term tests"); for (int l = 0; l < 5; l++) { int num2 = 0; for (int m = 0; m < 10000; m++) { if (Rand.MTBEventOccurs(1f, 24000f, 12000f)) { num2++; } } string value2 = string.Concat(new object[] { "MTB=", 1f, " days, MTBUnit=", 24000f, ", check duration=", 12000f, ", ", 10000, " tests got ", num2, " events." }); stringBuilder.AppendLine(value2); } for (int n = 0; n < 5; n++) { int num3 = 0; for (int num4 = 0; num4 < 10000; num4++) { if (Rand.MTBEventOccurs(2f, 24000f, 6000f)) { num3++; } } string value3 = string.Concat(new object[] { "MTB=", 2f, " days, MTBUnit=", 24000f, ", check duration=", 6000f, ", ", 10000, " tests got ", num3, " events." }); stringBuilder.AppendLine(value3); } stringBuilder.AppendLine(); stringBuilder.AppendLine("Near seed tests"); DebugHistogram debugHistogram = new DebugHistogram(new float[] { 0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1f }); Rand.PushState(); for (int num5 = 0; num5 < 1000; num5++) { Rand.Seed = num5; debugHistogram.Add(Rand.Value); } Rand.PopState(); debugHistogram.Display(stringBuilder); Log.Message(stringBuilder.ToString(), false); }
public override void CompPostTick(ref float severityAdjustment) { if (Props.wanderMtbHours > 0f && base.Pawn.Spawned && !base.Pawn.Downed && base.Pawn.Awake() && base.Pawn.CurJobDef.suspendable && Props.wanderMtbHours > 0f && base.Pawn.IsHashIntervalTick(60) && Rand.MTBEventOccurs(Props.wanderMtbHours, 2500f, 60f) && base.Pawn.CurJob.def != JobDefOf.GotoMindControlled) { IntVec3 c2 = (from c in GenRadial.RadialCellsAround(base.Pawn.Position, Props.wanderRadius, useCenter: false) where c.Standable(base.Pawn.MapHeld) && base.Pawn.CanReach(c, PathEndMode.OnCell, Danger.Unspecified) select c).RandomElementWithFallback(IntVec3.Invalid); if (c2.IsValid) { MoteMaker.MakeThoughtBubble(base.Pawn, "Things/Mote/Disoriented"); Job job = JobMaker.MakeJob(JobDefOf.GotoMindControlled, c2); job.expiryInterval = Props.singleWanderDurationTicks; base.Pawn.jobs.StartJob(job, JobCondition.InterruptForced, null, resumeCurJobAfterwards: true); } } }
public override void CompPostTick(ref float severityAdjustment) { if (!base.Pawn.IsHashIntervalTick(60)) { return; } if (base.Pawn.RaceProps.Humanlike) { if (base.Pawn.mindState.mentalStateHandler.CurStateDef != Props.humanMentalState && Rand.MTBEventOccurs(Props.mtbDaysToCauseMentalState, 60000f, 60f) && base.Pawn.Awake() && base.Pawn.mindState.mentalStateHandler.TryStartMentalState(Props.humanMentalState, parent.def.LabelCap, forceWake: false, causedByMood: false, null, transitionSilently: true) && base.Pawn.Spawned) { SendLetter(Props.humanMentalState); } } else if (base.Pawn.RaceProps.Animal && base.Pawn.mindState.mentalStateHandler.CurStateDef != Props.animalMentalState && (Props.animalMentalStateAlias == null || base.Pawn.mindState.mentalStateHandler.CurStateDef != Props.animalMentalStateAlias) && Rand.MTBEventOccurs(Props.mtbDaysToCauseMentalState, 60000f, 60f) && base.Pawn.Awake() && base.Pawn.mindState.mentalStateHandler.TryStartMentalState(Props.animalMentalState, parent.def.LabelCap, forceWake: false, causedByMood: false, null, transitionSilently: true) && base.Pawn.Spawned) { SendLetter(Props.animalMentalState); } }
public virtual void Tick() { ageTicks++; if (def.hediffGivers != null && pawn.IsHashIntervalTick(60)) { for (int i = 0; i < def.hediffGivers.Count; i++) { def.hediffGivers[i].OnIntervalPassed(pawn, this); } } if (Visible && !visible) { visible = true; if (def.taleOnVisible != null) { TaleRecorder.RecordTale(def.taleOnVisible, pawn, def); } } HediffStage curStage = CurStage; if (curStage == null) { return; } if (curStage.hediffGivers != null && pawn.IsHashIntervalTick(60)) { for (int j = 0; j < curStage.hediffGivers.Count; j++) { curStage.hediffGivers[j].OnIntervalPassed(pawn, this); } } if (curStage.mentalStateGivers != null && pawn.IsHashIntervalTick(60) && !pawn.InMentalState) { for (int k = 0; k < curStage.mentalStateGivers.Count; k++) { MentalStateGiver mentalStateGiver = curStage.mentalStateGivers[k]; if (Rand.MTBEventOccurs(mentalStateGiver.mtbDays, 60000f, 60f)) { pawn.mindState.mentalStateHandler.TryStartMentalState(mentalStateGiver.mentalState, "MentalStateReason_Hediff".Translate(Label)); } } } if (curStage.mentalBreakMtbDays > 0f && pawn.IsHashIntervalTick(60) && !pawn.InMentalState && !pawn.Downed && Rand.MTBEventOccurs(curStage.mentalBreakMtbDays, 60000f, 60f)) { TryDoRandomMentalBreak(); } if (curStage.vomitMtbDays > 0f && pawn.IsHashIntervalTick(600) && Rand.MTBEventOccurs(curStage.vomitMtbDays, 60000f, 600f) && pawn.Spawned && pawn.Awake() && pawn.RaceProps.IsFlesh) { pawn.jobs.StartJob(JobMaker.MakeJob(JobDefOf.Vomit), JobCondition.InterruptForced, null, resumeCurJobAfterwards: true); } if (curStage.forgetMemoryThoughtMtbDays > 0f && pawn.needs != null && pawn.needs.mood != null && pawn.IsHashIntervalTick(400) && Rand.MTBEventOccurs(curStage.forgetMemoryThoughtMtbDays, 60000f, 400f) && pawn.needs.mood.thoughts.memories.Memories.TryRandomElement(out var result)) { pawn.needs.mood.thoughts.memories.RemoveMemory(result); } if (!recordedTale && curStage.tale != null) { TaleRecorder.RecordTale(curStage.tale, pawn); recordedTale = true; } if (curStage.destroyPart && Part != null && Part != pawn.RaceProps.body.corePart) { pawn.health.AddHediff(HediffDefOf.MissingBodyPart, Part); } if (curStage.deathMtbDays > 0f && pawn.IsHashIntervalTick(200) && Rand.MTBEventOccurs(curStage.deathMtbDays, 60000f, 200f)) { bool num = PawnUtility.ShouldSendNotificationAbout(pawn); Caravan caravan = pawn.GetCaravan(); pawn.Kill(null, null); if (num) { pawn.health.NotifyPlayerOfKilled(null, this, caravan); } } }
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); } } } } } } } } } }