public static void IngestedCalculateAmounts(this Corpse corpse, Pawn ingester, BodyPartRecord bodyPartRecord, out int numTaken, out float nutritionIngested) { if (bodyPartRecord == null) { Log.Error(string.Concat(new object[] { ingester, " ate ", corpse, " but no body part was found. Replacing with core part." })); bodyPartRecord = corpse.InnerPawn.RaceProps.body.corePart; } float bodyPartNutrition = FoodUtility.GetBodyPartNutrition(corpse, bodyPartRecord); if (bodyPartRecord == corpse.InnerPawn.RaceProps.body.corePart) { if (PawnUtility.ShouldSendNotificationAbout(corpse.InnerPawn) && corpse.InnerPawn.RaceProps.Humanlike) { Messages.Message("MessageEatenByPredator".Translate(corpse.InnerPawn.LabelShort, ingester.Named("PREDATOR"), corpse.InnerPawn.Named("EATEN")).CapitalizeFirst(), ingester, MessageTypeDefOf.NegativeEvent, true); } numTaken = 1; } else { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, corpse.InnerPawn, bodyPartRecord); hediff_MissingPart.lastInjury = HediffDefOf.Bite; hediff_MissingPart.IsFresh = true; corpse.InnerPawn.health.AddHediff(hediff_MissingPart, null, null, null); numTaken = 0; } nutritionIngested = bodyPartNutrition; }
// Token: 0x06004BC8 RID: 19400 RVA: 0x0023675C File Offset: 0x00234B5C public static void HealNonPermanentInjuriesAndRestoreLegs(Pawn p) { if (p.Dead) { return; } HealthShardTendUtility.tmpHediffs.Clear(); HealthShardTendUtility.tmpHediffs.AddRange(p.health.hediffSet.hediffs); for (int i = 0; i < HealthShardTendUtility.tmpHediffs.Count; i++) { Hediff_Injury hediff_Injury = HealthShardTendUtility.tmpHediffs[i] as Hediff_Injury; if (hediff_Injury != null && !hediff_Injury.IsPermanent()) { p.health.RemoveHediff(hediff_Injury); } else { Hediff_MissingPart hediff_MissingPart = HealthShardTendUtility.tmpHediffs[i] as Hediff_MissingPart; if (hediff_MissingPart != null && hediff_MissingPart.Part.def.tags.Contains(BodyPartTagDefOf.MovingLimbCore) && (hediff_MissingPart.Part.parent == null || p.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null).Contains(hediff_MissingPart.Part.parent))) { p.health.RestorePart(hediff_MissingPart.Part, null, true); } } } HealthShardTendUtility.tmpHediffs.Clear(); }
public bool RemoveChildParts(Hediff_MissingPart mphd) { IEnumerable <Hediff> hediffList = this.Pawn.health.hediffSet.GetHediffs <Hediff>(); foreach (var hediff in hediffList) { Hediff_MissingPart mpChild = hediff as Hediff_MissingPart; if (mpChild != null && mpChild != this.parent && mpChild != mphd && mpChild.Part != null) { if (mphd.Part == mpChild.Part.parent) { if (RemoveChildParts(mpChild)) { return(true); } else { this.Pawn.health.RemoveHediff(hediff); return(true); } } } } return(false); }
public override void PostAdd(DamageInfo?dinfo) { if (base.Part == null) { Log.Error("Part is null. It should be set before PostAdd for " + this.def + ".", false); return; } this.pawn.health.RestorePart(base.Part, this, false); for (int i = 0; i < base.Part.parts.Count; i++) { if (base.Part.Index == 1) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, this.pawn, null); hediff_MissingPart.IsFresh = true; hediff_MissingPart.lastInjury = HediffDefOf.SurgicalCut; hediff_MissingPart.Part = base.Part.parts[i]; this.pawn.health.hediffSet.AddDirect(hediff_MissingPart, null, null); } else { Hediff_BodyPartModule hediff_BodyPartModule = (Hediff_BodyPartModule)HediffMaker.MakeHediff(MSE_HediffDefOf.MSE_BodyPartModule, this.pawn, null); hediff_BodyPartModule.Part = base.Part.parts[i]; this.pawn.health.hediffSet.AddDirect(hediff_BodyPartModule, null, null); } } }
public bool RemoveChildParts(Hediff_MissingPart mphd) { List <Hediff> hediffList = this.Pawn.health.hediffSet.GetHediffs <Hediff>().ToList(); for (int i = 0; i < hediffList.Count; i++) { Hediff_MissingPart mpChild = hediffList[i] as Hediff_MissingPart; if (mpChild != null && mpChild != this.parent && mpChild != mphd && mpChild.Part != null) { if (mphd.Part == mpChild.Part.parent) { if (RemoveChildParts(mpChild)) { return(true); } else { this.Pawn.health.RemoveHediff(hediffList[i]); return(true); } } } } return(false); }
public void SpecialPostAdd(DamageInfo?dinfo) { base.CompPostPostAdd(dinfo); this.parent.pawn.health.RestorePart(this.parent.Part, this.parent, false); for (int i = 0; i < this.parent.Part.parts.Count; i++) { if (this.parent.Part.Index == 1) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, this.parent.pawn, null); hediff_MissingPart.IsFresh = true; hediff_MissingPart.lastInjury = HediffDefOf.SurgicalCut; hediff_MissingPart.Part = this.parent.Part.parts[i]; this.parent.pawn.health.hediffSet.AddDirect(hediff_MissingPart, null, null); } else if (this.Props.generateModule) { HediffWithComps hediff_BodyPartModule = (HediffWithComps)HediffMaker.MakeHediff(MSE_HediffDefOf.MSE_BodyPartModule, this.parent.pawn, null); hediff_BodyPartModule.Part = this.parent.Part.parts[i]; this.parent.pawn.health.hediffSet.AddDirect(hediff_BodyPartModule, null, null); } } MSE_VanillaExtender.HediffApplyHediffs(this.parent, this.parent.pawn, this.parent.Part); }
public static void RemoveCommUnit(X2_AIRobot pawn) { // Do not remove, if one of the following work types: if (pawn.workSettings.GetPriority(WorkTypeDefOf.Doctor) > 0 || pawn.workSettings.GetPriority(WorkTypeDefOf.Handling) > 0 || pawn.workSettings.GetPriority(WorkTypeDefOf.Warden) > 0) { return; } PawnCapacityDef activity = PawnCapacityDefOf.Talking; if (pawn.health.capacities.CapableOf(activity)) { HediffSet hediffSet = pawn.health.hediffSet; IEnumerable <BodyPartRecord> notMissingParts = hediffSet.GetNotMissingParts(); BodyPartRecord bodyPart = notMissingParts.Where(p => p.def.defName == "AIRobot_CommUnit").FirstOrDefault(); if (bodyPart != null) { DamageInfo damageInfo = new DamageInfo(DamageDefOf.EMP, Mathf.RoundToInt(hediffSet.GetPartHealth(bodyPart)), 0f, -1f, null, bodyPart, null, DamageInfo.SourceCategory.ThingOrUnknown, null); //pawn.TakeDamage(damageInfo); Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null); hediff_MissingPart.IsFresh = false; hediff_MissingPart.lastInjury = null; pawn.health.AddHediff(hediff_MissingPart, bodyPart, damageInfo); pawn.health.Notify_HediffChanged(hediff_MissingPart); pawn.apparel.Notify_LostBodyPart(); } } }
public virtual void Repair(Building_RepairStation repairStation) { List <Hediff_Injury> allInjuries = health.hediffSet.GetHediffs <Hediff_Injury>().ToList(); List <Hediff_MissingPart> allMissingParts = health.hediffSet.GetHediffs <Hediff_MissingPart>().ToList(); float num = Rand.Value; if ((allInjuries.Count == 0 || num > 0.6) && allMissingParts.Count > 0 && repairStation != null && repairStation.HasEnoughOf(repairStation.Def.repairThingDef, repairStation.Def.repairCostAmount)) { Hediff_MissingPart hediff = allMissingParts.RandomElement(); if (repairStation.TakeSomeOf(repairStation.Def.repairThingDef, repairStation.Def.repairCostAmount)) { health.hediffSet.RestorePart(hediff.Part.HighestMissingPart(this)); } } else if (allInjuries.Count > 0) { Hediff_Injury hediff = allInjuries.RandomElement(); if (hediff.def.injuryProps.fullyHealableOnlyByTreatment) { HediffComp_Treatable treatable = hediff.TryGetComp <HediffComp_Treatable>(); if (treatable != null && !treatable.treatedWithMedicine) { treatable.NewlyTreated(1f, ThingDefOf.Medicine); } } hediff.DirectHeal(repairStation.Def.repairAmount); } }
// Token: 0x06004378 RID: 17272 RVA: 0x001E8A2C File Offset: 0x001E6E2C public override bool OnHediffAdded(Pawn pawn, Hediff hediff) { if (hediff is Hediff_Injury && !pawn.health.hediffSet.PartIsMissing(hediff.Part.parent) && !pawn.health.hediffSet.PartIsMissing(hediff.Part)) { Hediff_Injury injury = hediff as Hediff_Injury; //float oldChance = injury.def.chanceToCauseNoPain; //injury.def.chanceToCauseNoPain = 70000f; injury.PostMake(); injury.ageTicks = 70000000; //injury.def.chanceToCauseNoPain = oldChance; } else if (hediff is Hediff_MissingPart && !pawn.health.hediffSet.PartIsMissing(hediff.Part.parent)) { Hediff_MissingPart missing = hediff as Hediff_MissingPart; //float oldChance = missing.def.chanceToCauseNoPain; //missing.def.chanceToCauseNoPain = 70000f; missing.PostMake(); missing.ageTicks = 70000000; //missing.def.chanceToCauseNoPain = oldChance; } if (pawn.health.Downed && !pawn.health.InPainShock) { DamageInfo info = new DamageInfo(DamageDefOf.Rotting, 17f, 0f, 0f, null, pawn.health.hediffSet.GetBrain()); pawn.Kill(info); } return(false); }
public static bool CacheMissingPartsCommonAncestors(HediffSet __instance) { if (__instance.cachedMissingPartsCommonAncestors == null) { __instance.cachedMissingPartsCommonAncestors = new List <Hediff_MissingPart>(); } else { __instance.cachedMissingPartsCommonAncestors.Clear(); } missingPartsCommonAncestorsQueue.Clear(); missingPartsCommonAncestorsQueue.Enqueue(__instance.pawn.def.race.body.corePart); while (missingPartsCommonAncestorsQueue.Count != 0) { BodyPartRecord node = missingPartsCommonAncestorsQueue.Dequeue(); if (!__instance.PartOrAnyAncestorHasDirectlyAddedParts(node)) { Hediff_MissingPart hediffMissingPart = __instance.GetHediffs <Hediff_MissingPart>().Where <Hediff_MissingPart>((Func <Hediff_MissingPart, bool>)(x => x.Part == node)).FirstOrDefault <Hediff_MissingPart>(); if (hediffMissingPart != null) { __instance.cachedMissingPartsCommonAncestors.Add(hediffMissingPart); } else { for (int index = 0; index < node.parts.Count; ++index) { missingPartsCommonAncestorsQueue.Enqueue(node.parts[index]); } } } } return(false); }
// // Static Methods // public static void GenerateRandomOldAgeInjuries(Pawn pawn, bool tryNotToKillPawn) { int num = 0; for (int i = 10; i < Mathf.Min(pawn.ageTracker.AgeBiologicalYears, 120); i += 10) { if (Rand.Value < 0.15f) { num++; } } for (int j = 0; j < num; j++) { IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined) where x.depth == BodyPartDepth.Outside && !Mathf.Approximately(x.def.oldInjuryBaseChance, 0f) && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x) select x; if (source.Any <BodyPartRecord>()) { BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); DamageDef dam = AgeInjuryUtility.RandomOldInjuryDamageType(bodyPartRecord.def.frostbiteVulnerability > 0f && pawn.RaceProps.ToolUser); HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dam, pawn, bodyPartRecord); if (bodyPartRecord.def.oldInjuryBaseChance > 0f && hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsOld)) != null) { if (Rand.Chance(bodyPartRecord.def.amputateIfGeneratedInjuredChance)) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null); hediff_MissingPart.lastInjury = hediffDefFromDamage; hediff_MissingPart.TryGetComp <HediffComp_GetsOld>().IsOld = true; pawn.health.AddHediff(hediff_MissingPart, bodyPartRecord, null); if (pawn.RaceProps.Humanlike && (bodyPartRecord.def == BodyPartDefOf.LeftLeg || bodyPartRecord.def == BodyPartDefOf.RightLeg) && Rand.Chance(0.5f)) { RecipeDefOf.InstallPegLeg.Worker.ApplyOnPawn(pawn, bodyPartRecord, null, AgeInjuryUtility.emptyIngredientsList, null); } } else { Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Severity = (float)Rand.RangeInclusive(2, 6); hediff_Injury.TryGetComp <HediffComp_GetsOld>().IsOld = true; pawn.health.AddHediff(hediff_Injury, bodyPartRecord, null); } } } } for (int k = 1; k < pawn.ageTracker.AgeBiologicalYears; k++) { foreach (HediffGiver_Birthday current in AgeInjuryUtility.RandomHediffsToGainOnBirthday(pawn, k)) { current.TryApplyAndSimulateSeverityChange(pawn, (float)k, tryNotToKillPawn); if (pawn.Dead) { break; } } if (pawn.Dead) { break; } } }
public static void PostFix(Hediff_MissingPart __instance, ref float __result) { if (__result > 0) { // Scales it down by (Real HP : Displayed HP) __result = __result * __instance.Part.def.GetRawMaxHealth(__instance.pawn) / __instance.Part.def.GetMaxHealth(__instance.pawn, __instance.Part); } }
public static bool Prefix(Hediff_MissingPart __instance, ref bool __result) { var hediff = Traverse.Create(__instance); __result = Current.ProgramState != ProgramState.Entry && __instance.IsFresh && !__instance.Part.def.IsSolid(__instance.Part, __instance.pawn.health.hediffSet.hediffs) && !hediff.Property("ParentIsMissing").GetValue <bool>(); return(false); }
/// <summary> /// Removes random body parts from the corpse. Has a chance of destroying the body. /// </summary> /// <param name="actor">The pawn performing the dissection. His skill determines the chance of destroying the body.</param> /// <param name="corpse">The corpse being dissected.</param> /// <returns>True if the body was destroyed, False otherwise.</returns> private static bool RemoveDissectedBodyParts(Pawn actor, Corpse corpse) { // There is a chance the whole body is destroyed in the process bool destroyBody = Dissection.Singleton.AlwaysDetroyBodies; if (!destroyBody) { float skillLevelMultiplier = 1.0f - (float)actor.skills.GetSkill(SkillDefOf.Medicine).Level / SkillRecord.MaxLevel; float chance = Dissection.Singleton.DestroyBodyChance * skillLevelMultiplier * skillLevelMultiplier; float rand = Rand.Range(0.0f, 1.0f); destroyBody = rand <= chance; } if (destroyBody) { if (PawnUtility.ShouldSendNotificationAbout(corpse.InnerPawn) && corpse.InnerPawn.RaceProps.Humanlike) { Messages.Message( "Dissection_MessageDestroyedByDoctor" .Translate(corpse.InnerPawn.LabelShort, actor.LabelIndefinite()) .CapitalizeFirst(), actor, MessageTypeDefOf.NegativeEvent); } Log.Message($"Destroyed {corpse.InnerPawn.Name}'s body while dissecting."); corpse.Destroy(); return(true); } IEnumerable <BodyPartRecord> source = from x in corpse.InnerPawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined) where DissectionUtility.DissectableBodyParts.Contains(x.def) select x; int numBodyPartsToDissect = (Rand.RangeInclusive(0, DissectionUtility.DissectableBodyParts.Count) + Rand.RangeInclusive(0, DissectionUtility.DissectableBodyParts.Count) + Rand.RangeInclusive(0, DissectionUtility.DissectableBodyParts.Count)); numBodyPartsToDissect = Mathf.RoundToInt(numBodyPartsToDissect / 3.0f); numBodyPartsToDissect = Mathf.Min(source.Count(), numBodyPartsToDissect); var bodyParts = source.InRandomOrder().ToArray(); for (int i = 0; i < numBodyPartsToDissect; ++i) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, corpse.InnerPawn, bodyParts[i]); hediff_MissingPart.lastInjury = HediffDefOf.SurgicalCut; hediff_MissingPart.IsFresh = true; corpse.InnerPawn.health.AddHediff(hediff_MissingPart); } Hediff dissectedHediff = HediffMaker.MakeHediff(DissectionDefOf.DissectedHediff, corpse.InnerPawn); corpse.InnerPawn.health.AddHediff(dissectedHediff); return(false); }
private bool ParentIsMissing(Pawn pawn, BodyPartRecord part) { for (int i = 0; i < pawn.health.hediffSet.hediffs.Count; i++) { Hediff_MissingPart hediff_MissingPart = pawn.health.hediffSet.hediffs[i] as Hediff_MissingPart; if (hediff_MissingPart != null && hediff_MissingPart.Part == part.parent) { return(true); } } return(false); }
public static bool HasParentMissing(this BodyPartRecord part, Pawn pawn) { for (int i = 0; i < pawn.health.hediffSet.hediffs.Count; i++) { Hediff_MissingPart hediff_MissingPart = pawn.health.hediffSet.hediffs[i] as Hediff_MissingPart; if (hediff_MissingPart != null && hediff_MissingPart.Part == part.parent) { return(true); } } return(false); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.OnCell)); Toil extractStack = Toils_General.Wait(120, 0); ToilEffects.WithProgressBarToilDelay(extractStack, TargetIndex.A, false, -0.5f); ToilFailConditions.FailOnDespawnedNullOrForbidden <Toil>(extractStack, TargetIndex.A); ToilFailConditions.FailOnCannotTouch <Toil>(extractStack, TargetIndex.A, PathEndMode.OnCell); yield return(extractStack); yield return(new Toil { initAction = delegate() { Corpse corpse = (Corpse)TargetThingA; Hediff_CorticalStack hediff = corpse.InnerPawn.health.hediffSet.hediffs.FirstOrDefault((Hediff x) => x.def.defName == "AC_CorticalStack") as Hediff_CorticalStack; if (hediff != null) { if (hediff.def.spawnThingOnRemoved != null) { var corticalStack = ThingMaker.MakeThing(hediff.def.spawnThingOnRemoved) as CorticalStack; if (hediff.hasPawn) { corticalStack.SavePawnFromHediff(hediff); } else { corticalStack.SavePawnToCorticalStack(corpse.InnerPawn); } GenPlace.TryPlaceThing(corticalStack, TargetThingA.Position, GetActor().Map, ThingPlaceMode.Near); ACUtils.ACTracker.RegisterStack(corticalStack); ACUtils.ACTracker.RegisterSleeve(corpse.InnerPawn, corticalStack.stackGroupID); } var head = corpse.InnerPawn.health.hediffSet.GetNotMissingParts().FirstOrDefault((BodyPartRecord x) => x.def == BodyPartDefOf.Head); if (head != null) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, corpse.InnerPawn, head); hediff_MissingPart.lastInjury = HediffDefOf.SurgicalCut; hediff_MissingPart.IsFresh = true; corpse.InnerPawn.health.AddHediff(hediff_MissingPart); } corpse.InnerPawn.health.RemoveHediff(hediff); if (pawn.Map.designationManager.DesignationOn(corpse).def == AlteredCarbonDefOf.AC_ExtractStackDesignation) { pawn.Map.designationManager.TryRemoveDesignationOn(corpse, AlteredCarbonDefOf.AC_ExtractStackDesignation); } } } }); }
public static void Blind(this Pawn pawn) { foreach (BodyPartRecord part in pawn.RaceProps.body.GetPartsWithTag(BodyPartTagDefOf.SightSource)) { if (!pawn.health.hediffSet.PartIsMissing(part)) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null); hediff_MissingPart.lastInjury = HediffDefOf.Cut; hediff_MissingPart.Part = part; hediff_MissingPart.IsFresh = false; pawn.health.AddHediff(hediff_MissingPart, part, null, null); } } }
public static BodyPartRecord HighestMissingPart(this BodyPartRecord part, Pawn pawn) { if (part.HasParentMissing(pawn)) { for (int i = 0; i < pawn.health.hediffSet.hediffs.Count; i++) { Hediff_MissingPart missingPart = pawn.health.hediffSet.hediffs[i] as Hediff_MissingPart; if (missingPart != null && missingPart.Part == part.parent) { return(missingPart.Part.HighestMissingPart(pawn)); } } } return(part); }
public bool HasParentPart(Hediff_MissingPart mphd) { bool hasMissingParent = false; if (mphd.Part.parent != null) { List <Hediff_MissingPart> hediffList = this.Pawn.health.hediffSet.GetHediffs <Hediff_MissingPart>().ToList(); for (int i = 0; i < hediffList.Count; i++) { if (mphd.Part.parent == hediffList[i].Part) { } } } return(hasMissingParent); }
public void RegenerateTick() { base.Tick(); if (!pawn.IsHashIntervalTick(def.periodTicks)) { return; } var injured = pawn.health.hediffSet.GetInjuredParts(); var missing = pawn.health.hediffSet.GetMissingPartsCommonAncestors(); var potential = missing.Where(x => x.Part != null && ( x.Part.parent == null || ( !injured.Contains(x.Part.parent) && !injured.Intersect(x.Part.parent.GetDirectChildParts()).Any() ) ) ); Hediff_MissingPart hediff = potential.RandomElementWithFallback(); if (hediff == null) { return; } BodyPartRecord part = hediff.Part; pawn.health.hediffSet.hediffs.Remove(hediff); foreach (var subpart in part.GetDirectChildParts()) { Hediff_MissingPart missingPart = HediffMaker.MakeHediff(RimWorld.HediffDefOf.MissingBodyPart, pawn, subpart) as Hediff_MissingPart; pawn.health.hediffSet.hediffs.Add(missingPart); } Hediff_Injury injury = HediffMaker.MakeHediff(RimWorld.HediffDefOf.Shredded, pawn, part) as Hediff_Injury; injury.Severity = part.def.hitPoints - 1; pawn.health.hediffSet.hediffs.Add(injury); pawn.health.hediffSet.DirtyCache(); RadiologyEffectSpawnerDef.Spawn(def.effectRegeration, pawn); }
public override void Effect(Pawn target) { base.Effect(target); /// Restores all missing parts when transforming List <Hediff_MissingPart> missingParts = new List <Hediff_MissingPart>().Concat(target?.health?.hediffSet?.GetMissingPartsCommonAncestors()).ToList(); if (!missingParts.NullOrEmpty()) { Hediff_MissingPart partToRestore = missingParts.RandomElement(); target.health.RestorePart(partToRestore.Part); Messages.Message("ROM_WerewolfLimbRegen".Translate(new object[] { target.LabelShort, partToRestore.Label }), MessageSound.Benefit); } }
public static bool CacheMissingPartsCommonAncestors(HediffSet __instance) { if (cachedMissingPartsCommonAncestors(__instance) == null) { cachedMissingPartsCommonAncestors(__instance) = new List <Hediff_MissingPart>(); } lock (cachedMissingPartsCommonAncestors(__instance)) { cachedMissingPartsCommonAncestors(__instance).Clear(); missingPartsCommonAncestorsQueue(__instance).Clear(); missingPartsCommonAncestorsQueue(__instance).Enqueue(__instance.pawn.def.race.body.corePart); while (missingPartsCommonAncestorsQueue(__instance).Count != 0) { BodyPartRecord node = missingPartsCommonAncestorsQueue(__instance).Dequeue(); if (node != null) { if (__instance.PartOrAnyAncestorHasDirectlyAddedParts(node)) { continue; } Hediff_MissingPart hediff_MissingPart = (from x in __instance.GetHediffs <Hediff_MissingPart>() where x.Part == node select x).FirstOrDefault(); if (hediff_MissingPart != null) { cachedMissingPartsCommonAncestors(__instance).Add(hediff_MissingPart); continue; } for (int i = 0; i < node.parts.Count; i++) { lock (missingPartsCommonAncestorsQueue(__instance)) { missingPartsCommonAncestorsQueue(__instance).Enqueue(node.parts[i]); } } } } } return(false); }
/// Nothing should happen. public override void PostAdd(DamageInfo?dinfo) { if (base.Part == null) { Log.Error("Part is null. It should be set before PostAdd for " + this.def + "."); return; } this.pawn.health.RestorePart(base.Part, this, false); temporarilyRemovedParts.Clear(); for (int i = 0; i < base.Part.parts.Count; i++) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, this.pawn, null); hediff_MissingPart.IsFresh = false; hediff_MissingPart.lastInjury = null; hediff_MissingPart.Part = base.Part.parts[i]; this.pawn.health.hediffSet.AddDirect(hediff_MissingPart, null); temporarilyRemovedParts.Add(hediff_MissingPart); } }
//almost literal copy vanilla CompUseEffect_FixWorstHealthCondition.FindBiggestMissingBodyPart, only returns the hediff instead. private static Hediff_MissingPart FindBiggestMissingBodyPart(Pawn pawn, float minCoverage = 0f) { Hediff_MissingPart hediff = null; foreach (Hediff_MissingPart current in pawn.health.hediffSet.GetMissingPartsCommonAncestors()) { if (current.Part.coverageAbsWithChildren >= minCoverage) { if (!pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(current.Part)) { if (hediff == null || current.Part.coverageAbsWithChildren > hediff.Part.coverageAbsWithChildren) { hediff = current; } } } } return(hediff); }
private static void TryRegeneratePart(Pawn pawn, Building_BaseMechanoidPlatform platform) { Hediff_MissingPart hediff = FindBiggestMissingBodyPart(pawn); if (hediff == null || pawn.health.hediffSet.HasHediff(WTH_DefOf.WTH_RegeneratedPart)) { return; } pawn.health.RemoveHediff(hediff); float partHealth = hediff.Part.def.GetMaxHealth(pawn); float fuelNeeded = Math.Min(4f, partHealth / 5f);//body parts with less health need less parts to regenerate, capped at 4. platform.refuelableComp.ConsumeFuel(fuelNeeded); //Hediff_Injury injury = new Hediff_Injury(); DamageWorker_AddInjury addInjury = new DamageWorker_AddInjury(); addInjury.Apply(new DamageInfo(WTH_DefOf.WTH_RegeneratedPartDamage, hediff.Part.def.GetMaxHealth(pawn) - 1, 0, -1, pawn, hediff.Part), pawn); }
public static bool Notify_Resurrected(Pawn_HealthTracker __instance) { lock (__instance.hediffSet) //added { List <Hediff> newHediffs = new List <Hediff>(__instance.hediffSet.hediffs); //added __instance.healthState = PawnHealthState.Mobile; newHediffs.RemoveAll((Predicate <Hediff>)(x => x.def.everCurableByItem && x.TryGetComp <HediffComp_Immunizable>() != null)); newHediffs.RemoveAll((Predicate <Hediff>)(x => x.def.everCurableByItem && x is Hediff_Injury && !x.IsPermanent())); newHediffs.RemoveAll((Predicate <Hediff>)(x => { if (!x.def.everCurableByItem) { return(false); } if ((double)x.def.lethalSeverity >= 0.0) { return(true); } return(x.def.stages != null && x.def.stages.Any <HediffStage>((Predicate <HediffStage>)(y => y.lifeThreatening))); })); newHediffs.RemoveAll((Predicate <Hediff>)(x => x.def.everCurableByItem && x is Hediff_Injury && x.IsPermanent() && (double)__instance.hediffSet.GetPartHealth(x.Part) <= 0.0)); __instance.hediffSet.hediffs = newHediffs; //added while (true) { Hediff_MissingPart hediffMissingPart = __instance.hediffSet.GetMissingPartsCommonAncestors().Where <Hediff_MissingPart>((Func <Hediff_MissingPart, bool>)(x => !__instance.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x.Part))).FirstOrDefault <Hediff_MissingPart>(); if (hediffMissingPart != null) { __instance.RestorePart(hediffMissingPart.Part, checkStateChange: false); } else { break; } } __instance.hediffSet.DirtyCache(); if (__instance.ShouldBeDead()) { __instance.hediffSet.hediffs.RemoveAll((Predicate <Hediff>)(h => !h.def.keepOnBodyPartRestoration)); } __instance.Notify_HediffChanged((Hediff)null); } return(false); }
//Handles the spawning of pawns public override void GiveBirth() { Pawn mother = pawn; if (mother == null) { return; } if (!babies.NullOrEmpty()) { foreach (Pawn baby in babies) { baby.Discard(true); } } Faction spawn_faction = null; if (!is_hacked) { spawn_faction = Faction.OfMechanoids; } PawnGenerationRequest request = new PawnGenerationRequest( kind: PawnKindDef.Named("Mech_Scyther"), faction: spawn_faction, forceGenerateNewPawn: true, newborn: true ); Pawn mech = PawnGenerator.GeneratePawn(request); PawnUtility.TrySpawnHatchedOrBornPawn(mech, mother); if (!is_hacked) { LordJob_MechanoidsDefend lordJob = new LordJob_MechanoidsDefend(); Lord lord = LordMaker.MakeNewLord(mech.Faction, lordJob, mech.Map); lord.AddPawn(mech); } FilthMaker.TryMakeFilth(mech.PositionHeld, mech.MapHeld, mother.RaceProps.BloodDef, mother.LabelIndefinite()); IEnumerable <BodyPartRecord> source = from x in mother.health.hediffSet.GetNotMissingParts() where x.IsInGroup(BodyPartGroupDefOf.Torso) && !x.IsCorePart //&& x.groups.Contains(BodyPartGroupDefOf.Torso) //&& x.depth == BodyPartDepth.Inside //&& x.height == BodyPartHeight.Bottom //someday include depth filter //so it doesnt cut out external organs (breasts)? //vag is genital part and genital is external //anal is internal //make sep part of vag? //&& x.depth == BodyPartDepth.Inside select x; if (source.Any()) { foreach (BodyPartRecord part in source) { mother.health.DropBloodFilth(); } foreach (BodyPartRecord part in source) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, mother, part); hediff_MissingPart.lastInjury = HediffDefOf.Cut; hediff_MissingPart.IsFresh = true; mother.health.AddHediff(hediff_MissingPart); } } mother.health.RemoveHediff(this); }
private void ReverseHediff(Pawn pawn, int ticks) { float totalBleedRate = 0; using (IEnumerator <Hediff> enumerator = pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator()) { while (enumerator.MoveNext()) { Hediff rec = enumerator.Current; if (rec != null) { HediffComp_Immunizable immuneComp = rec.TryGetComp <HediffComp_Immunizable>(); if (immuneComp != null) { if (immuneComp.Def.CompProps <HediffCompProperties_Immunizable>() != null) { float immuneSevDay = immuneComp.Def.CompProps <HediffCompProperties_Immunizable>().severityPerDayNotImmune; if (immuneSevDay != 0 && !rec.FullyImmune()) { rec.Severity -= ((immuneSevDay * ticks * this.parent.Severity) / (2500)); } } } HediffComp_SeverityPerDay sevDayComp = rec.TryGetComp <HediffComp_SeverityPerDay>(); if (sevDayComp != null) { if (sevDayComp.Def.CompProps <HediffCompProperties_SeverityPerDay>() != null) { float sevDay = sevDayComp.Def.CompProps <HediffCompProperties_SeverityPerDay>().severityPerDay; if (sevDay != 0) { bool drugTolerance = false; HediffComp_DrugEffectFactor drugEffectComp = rec.TryGetComp <HediffComp_DrugEffectFactor>(); if (drugEffectComp != null) { if (drugEffectComp.Def.CompProps <HediffCompProperties_DrugEffectFactor>().chemical != null) { drugTolerance = true; } } if (!drugTolerance) { rec.Severity -= ((sevDay * ticks * this.parent.Severity) / (1000)); } } } } HediffComp_Disappears tickComp = rec.TryGetComp <HediffComp_Disappears>(); if (tickComp != null) { int ticksToDisappear = Traverse.Create(root: tickComp).Field(name: "ticksToDisappear").GetValue <int>(); if (ticksToDisappear != 0) { Traverse.Create(root: tickComp).Field(name: "ticksToDisappear").SetValue(ticksToDisappear + (Mathf.RoundToInt(ticks * this.parent.Severity))); } } if (rec.Bleeding) { totalBleedRate += rec.BleedRate; } } } if (totalBleedRate != 0) { HealthUtility.AdjustSeverity(pawn, HediffDefOf.BloodLoss, -(totalBleedRate * ticks * this.parent.Severity) / (24 * 2500)); } } List <Hediff> hediffList = pawn.health.hediffSet.GetHediffs <Hediff>().ToList(); if (hediffList != null && hediffList.Count > 0) { for (int i = 0; i < hediffList.Count; i++) { Hediff rec = hediffList[i]; if (rec != null && rec != this.parent) { if (rec.def.scenarioCanAdd || rec.def.isBad) { if ((rec.ageTicks - 1000) < 0) { if (rec.def.defName.Contains("TM_")) { if (rec.def.isBad && rec.def != TorannMagicDefOf.TM_ResurrectionHD) { this.Pawn.health.RemoveHediff(rec); break; } } else { List <BodyPartRecord> bpList = pawn.RaceProps.body.AllParts; List <BodyPartRecord> replacementList = new List <BodyPartRecord>(); replacementList.Clear(); for (int j = 0; j < bpList.Count; j++) { BodyPartRecord record = bpList[j]; if (pawn.health.hediffSet.hediffs.Any((Hediff x) => x.Part == record) && (record.parent == null || pawn.health.hediffSet.GetNotMissingParts().Contains(record.parent)) && (!pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(record) || pawn.health.hediffSet.HasDirectlyAddedPartFor(record))) { replacementList.Add(record); } } Hediff_MissingPart mphd = rec as Hediff_MissingPart; if (mphd != null && mphd.Part != null) { if (replacementList.Contains(mphd.Part)) { if (RemoveChildParts(mphd)) { break; } else { if (this.Pawn.needs != null && this.Pawn.needs.mood != null && this.Pawn.needs.mood.thoughts != null && this.Pawn.needs.mood.thoughts.memories != null) { this.Pawn.needs.mood.thoughts.memories.TryGainMemory(TorannMagicDefOf.TM_PhantomLimb); } } } else { goto IgnoreHediff; } } this.Pawn.health.RemoveHediff(rec); i = hediffList.Count; break; IgnoreHediff :; } } else { rec.ageTicks -= 1000; } } } } } //using (IEnumerator<Hediff> enumerator = pawn.health.hediffSet.GetHediffs<Hediff>().GetEnumerator()) //{ // while (enumerator.MoveNext()) // { // Hediff rec = enumerator.Current; // if (rec != null && rec != this.parent) // { // if ((rec.ageTicks - 2500) < 0) // { // if (rec.def.defName.Contains("TM_")) // { // if (rec.def.isBad) // { // this.Pawn.health.RemoveHediff(rec); // } // } // else // { // this.Pawn.health.RemoveHediff(rec); // } // } // else // { // rec.ageTicks -= 2500; // } // } // } //} }
// supported self healing of missing limbs private void DoHealMissingBodyPart(bool enhancedAI) { List <Hediff_MissingPart> missingBodyParts = GetMissingBodyparts(); if (missingBodyParts == null || missingBodyParts.Count == 0) { return; } // 40% chance that a missing limb will be healed if (Rand.Value < 0.40f) { return; } Building_AIPawnRechargeStation rechargeStation; if (IsInAIRechargeStation(Map, out rechargeStation)) { IEnumerable <Thing> things = rechargeStation.AllItemsInHopper; if (things == null || things.Count() == 0) { return; } // Get count of all items int stackCountAll = 0; for (int i = 0; i < things.Count(); i++) { stackCountAll += things.ElementAt(i).stackCount; } if (stackCountAll < neededMaterialPerRecreatedBodyPart) { return; } // Enough material available, reduce it int neededAmmount = neededMaterialPerRecreatedBodyPart; for (int i = 0; i < things.Count(); i++) { neededAmmount -= things.ElementAt(i).stackCount; if (neededAmmount >= 0) { things.ElementAt(i).Destroy(); } else { things.ElementAt(i).stackCount -= neededMaterialPerRecreatedBodyPart; } if (neededAmmount <= 0) { break; } } // Get random part Hediff_MissingPart missingBodyPart = missingBodyParts.RandomElement(); //Log.Error("Restore missingBodyPart:" + missingBodyPart.ToString()); // restore random part BodyPartRecord part = missingBodyPart.Part; this.health.RestorePart(part, null, true); // Do damage to restored part, so that the health of it is 1 float maxDamage = health.hediffSet.GetPartHealth(part); int applyDamage = (int)maxDamage / 2; this.TakeDamage(new DamageInfo(DamageDefOf.Cut, applyDamage, 0f, -1f, null, part, null)); } }