// Token: 0x06000030 RID: 48 RVA: 0x00002B04 File Offset: 0x00000D04 public static float CalculateBaseTendQuality(Pawn doctor, Pawn patient, ThingDef medicine) { float medicinePotency = (medicine == null) ? 0.3f : StatExtension.GetStatValueAbstract(medicine, StatDefOf.MedicalPotency, null); float medicineQualityMax = (medicine == null) ? 0.7f : StatExtension.GetStatValueAbstract(medicine, StatDefOf.MedicalQualityMax, null); return(HealthShardTendUtility.CalculateBaseTendQuality(doctor, patient, medicinePotency, medicineQualityMax)); }
// Token: 0x06000026 RID: 38 RVA: 0x000026A3 File Offset: 0x000008A3 protected override IEnumerable <Toil> MakeNewToils() { base.AddEndCondition(delegate() { if (this.pawn.Faction == Faction.OfPlayer && HealthAIUtility.ShouldBeTendedNowByPlayer(this.pawn)) { return(JobCondition.Ongoing); } if (this.pawn.Faction != Faction.OfPlayer && this.pawn.health.HasHediffsNeedingTend(false)) { return(JobCondition.Ongoing); } return(JobCondition.Succeeded); }); int ticks = (int)(1f / StatExtension.GetStatValue(this.pawn, StatDefOf.MedicalTendSpeed, true) * 600f); yield return(ToilEffects.PlaySustainerOrSound(ToilEffects.WithProgressBarToilDelay(Toils_General.Wait(ticks, 0), (TargetIndex)1, false, -0.5f), SoundDefOf.Interact_Tend)); Toil toil = new Toil(); toil.initAction = delegate() { Pawn actor = toil.actor; Cloakgen medkit = actor.apparel.WornApparel.OfType <Cloakgen>().FirstOrDefault <Cloakgen>(); float num = (!actor.RaceProps.Animal) ? 500f : 175f; float num2 = (medkit != null) ? medkit.kitComp.Props.medicine.MedicineTendXpGainFactor : 0.5f; actor.skills.Learn(SkillDefOf.Medicine, num * num2, false); HealthShardTendUtility.DoTend(actor, actor, medkit); }; toil.defaultCompleteMode = (ToilCompleteMode)1; yield return(toil); yield break; }
// Token: 0x06004BC9 RID: 19401 RVA: 0x00236874 File Offset: 0x00234C74 private static void GiveRandomSurgeryInjuries(Pawn p, int totalDamage, BodyPartRecord operatedPart) { IEnumerable <BodyPartRecord> source; if (operatedPart == null) { source = from x in p.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null) where !x.def.conceptual select x; } else { source = from x in p.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null) where !x.def.conceptual select x into pa where pa == operatedPart || pa.parent == operatedPart || (operatedPart != null && operatedPart.parent == pa) select pa; } source = from x in source where HealthShardTendUtility.GetMinHealthOfPartsWeWantToAvoidDestroying(x, p) >= 2f select x; BodyPartRecord brain = p.health.hediffSet.GetBrain(); if (brain != null) { float maxBrainHealth = brain.def.GetMaxHealth(p); source = from x in source where x != brain || p.health.hediffSet.GetPartHealth(x) >= maxBrainHealth * 0.5f + 1f select x; } while (totalDamage > 0 && source.Any <BodyPartRecord>()) { BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); float partHealth = p.health.hediffSet.GetPartHealth(bodyPartRecord); int num = Mathf.Max(3, GenMath.RoundRandom(partHealth * Rand.Range(0.5f, 1f))); float minHealthOfPartsWeWantToAvoidDestroying = HealthShardTendUtility.GetMinHealthOfPartsWeWantToAvoidDestroying(bodyPartRecord, p); if (minHealthOfPartsWeWantToAvoidDestroying - (float)num < 1f) { num = Mathf.RoundToInt(minHealthOfPartsWeWantToAvoidDestroying - 1f); } if (bodyPartRecord == brain && partHealth - (float)num < brain.def.GetMaxHealth(p) * 0.5f) { num = Mathf.Max(Mathf.RoundToInt(partHealth - brain.def.GetMaxHealth(p) * 0.5f), 1); } if (num <= 0) { break; } DamageDef damageDef = XenomorphDefOf.RRY_AcidBurn; Thing p2 = p; DamageDef def = damageDef; float amount = (float)num; BodyPartRecord hitPart = bodyPartRecord; p2.TakeDamage(new DamageInfo(def, amount, 0f, -1f, null, hitPart, null, DamageInfo.SourceCategory.ThingOrUnknown, null)); totalDamage -= num; } }
// Token: 0x06004BCA RID: 19402 RVA: 0x00236B00 File Offset: 0x00234F00 private static float GetMinHealthOfPartsWeWantToAvoidDestroying(BodyPartRecord part, Pawn pawn) { float num = 999999f; while (part != null) { if (HealthShardTendUtility.ShouldRandomSurgeryInjuriesAvoidDestroying(part, pawn)) { num = Mathf.Min(num, pawn.health.hediffSet.GetPartHealth(part)); } part = part.parent; } return(num); }
// Token: 0x06004BCB RID: 19403 RVA: 0x00236B4C File Offset: 0x00234F4C private static bool ShouldRandomSurgeryInjuriesAvoidDestroying(BodyPartRecord part, Pawn pawn) { if (part == pawn.RaceProps.body.corePart) { return(true); } if (part.def.tags.Any((BodyPartTagDef x) => x.vital)) { return(true); } for (int i = 0; i < part.parts.Count; i++) { if (HealthShardTendUtility.ShouldRandomSurgeryInjuriesAvoidDestroying(part.parts[i], pawn)) { return(true); } } return(false); }
// Token: 0x0600002F RID: 47 RVA: 0x00002870 File Offset: 0x00000A70 public static void UseShard(Pawn doctor, Pawn patient, Cloakgen medkit) { bool flag = patient.health.HasHediffsNeedingTend(false); Log.Message(string.Format("UseShard flag: {0}, doctor: {1}, patient: {2}", flag, doctor, patient)); if (flag) { Hediff hediff = HealthShardTendUtility.FindLifeThreateningHediff(patient); if (hediff != null) { Log.Message(string.Format("hediff: {0}", hediff)); medkit.UseKit(); HealthShardTendUtility.Cure(hediff); return; } if (HealthUtility.TicksUntilDeathDueToBloodLoss(patient) < 2500) { Log.Message(string.Format("TicksUntilDeathDueToBloodLoss: {0}", HealthUtility.TicksUntilDeathDueToBloodLoss(patient))); Hediff hediff2 = HealthShardTendUtility.FindMostBleedingHediff(patient); if (hediff2 != null) { Log.Message(string.Format("hediff2: {0}", hediff2)); medkit.UseKit(); HealthShardTendUtility.Cure(hediff2); return; } } Hediff_Injury hediff_Injury3 = HealthShardTendUtility.FindInjury(patient, null); if (hediff_Injury3 != null) { Log.Message(string.Format("hediff2: {0}", hediff_Injury3)); medkit.UseKit(); HealthShardTendUtility.Cure(hediff_Injury3); return; } } }
// Token: 0x06001465 RID: 5221 RVA: 0x0009C6B4 File Offset: 0x0009AAB4 protected virtual bool CheckSurgeryFail(Pawn surgeon, Pawn patient, List <Thing> ingredients, BodyPartRecord part, Bill bill) { IntVec3 patientLoc = patient.Position; Map patientMap = patient.Map; float num = 1f; if (!patient.RaceProps.IsMechanoid) { num *= surgeon.GetStatValue(StatDefOf.MedicalSurgerySuccessChance, true); } if (patient.InBed()) { num *= patient.CurrentBed().GetStatValue(StatDefOf.SurgerySuccessChanceFactor, true); } num *= Recipe_Surgery_RRY.MedicineMedicalPotencyToSurgeryChanceFactor.Evaluate(this.GetAverageMedicalPotency(ingredients, bill)); num *= this.recipe.surgerySuccessChanceFactor; if (surgeon.InspirationDef == InspirationDefOf.Inspired_Surgery && !patient.RaceProps.IsMechanoid) { num *= 2f; surgeon.mindState.inspirationHandler.EndInspiration(InspirationDefOf.Inspired_Surgery); } num = Mathf.Min(num, 0.98f); if (!Rand.Chance(num)) { if (Rand.Chance(this.recipe.deathOnFailedSurgeryChance)) { HealthShardTendUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); if (!patient.Dead) { patient.Kill(null, null); } Messages.Message("RRYMessageMedicalOperationFailureFatal".Translate(surgeon.LabelShort, patient.LabelShort, this.recipe.LabelCap, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent, true); } else if (Rand.Chance(0.5f)) { if (Rand.Chance(0.1f)) { surgeon.health.AddHediff(patient.health.hediffSet.GetFirstHediffOfDef(XenomorphDefOf.RRY_FaceHuggerInfection), patient.health.hediffSet.GetFirstHediffOfDef(XenomorphDefOf.RRY_FaceHuggerInfection).Part); patient.health.RemoveHediff(patient.health.hediffSet.GetFirstHediffOfDef(XenomorphDefOf.RRY_FaceHuggerInfection)); Messages.Message("RRYMessageMedicalOperationFailureRidiculous".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent, true); HealthShardTendUtility.GiveInjuriesOperationFailureRidiculous(patient); } else { if (Rand.Chance(0.15f)) { surgeon.health.AddHediff(patient.health.hediffSet.GetFirstHediffOfDef(XenomorphDefOf.RRY_FaceHuggerInfection), patient.health.hediffSet.GetFirstHediffOfDef(XenomorphDefOf.RRY_FaceHuggerInfection).Part); patient.health.RemoveHediff(patient.health.hediffSet.GetFirstHediffOfDef(XenomorphDefOf.RRY_FaceHuggerInfection)); } else if (Rand.Chance(0.35f)) { GenSpawn.Spawn(ThingMaker.MakeThing(XenomorphDefOf.RRY_FilthBloodXenomorph), surgeon.Position, surgeon.Map); } int a = Rand.Range(0, 5); for (int i = 0; i < a; i++) { GenSpawn.Spawn(ThingMaker.MakeThing(XenomorphDefOf.RRY_FilthBloodXenomorph), patientLoc.RandomAdjacentCell8Way(), surgeon.Map); } Messages.Message("RRYMessageMedicalOperationFailureCatastrophic".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent, true); HealthShardTendUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); } } else { if (Rand.Chance(0.35f)) { if (Rand.Chance(0.35f)) { GenSpawn.Spawn(ThingMaker.MakeThing(XenomorphDefOf.RRY_FilthBloodXenomorph), surgeon.Position, surgeon.Map); } else { GenSpawn.Spawn(ThingMaker.MakeThing(XenomorphDefOf.RRY_FilthBloodXenomorph), patientLoc.RandomAdjacentCell8Way(), surgeon.Map); } Messages.Message("RRYMessageMedicalOperationFailureMinorB".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent, true); HealthShardTendUtility.GiveInjuriesOperationFailureMinor(patient, part); } else { Messages.Message("RRYMessageMedicalOperationFailureMinorA".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent, true); HealthShardTendUtility.GiveInjuriesOperationFailureMinor(patient, part); } } if (!patient.Dead) { this.TryGainBotchedSurgeryThought(patient, surgeon); } return(true); } return(false); }
// Token: 0x06004BC7 RID: 19399 RVA: 0x00236750 File Offset: 0x00234B50 public static void GiveInjuriesOperationFailureRidiculous(Pawn p) { HealthShardTendUtility.GiveRandomSurgeryInjuries(p, 65, null); }
// Token: 0x06004BC6 RID: 19398 RVA: 0x00236745 File Offset: 0x00234B45 public static void GiveInjuriesOperationFailureCatastrophic(Pawn p, BodyPartRecord part) { HealthShardTendUtility.GiveRandomSurgeryInjuries(p, 65, part); }
// Token: 0x06004BC5 RID: 19397 RVA: 0x0023673A File Offset: 0x00234B3A public static void GiveInjuriesOperationFailureMinor(Pawn p, BodyPartRecord part) { HealthShardTendUtility.GiveRandomSurgeryInjuries(p, 20, part); }
// Token: 0x06000032 RID: 50 RVA: 0x00002BD8 File Offset: 0x00000DD8 public static void GetOptimalHediffsToTendWithSingleTreatment(Pawn patient, bool usingMedicine, List <Hediff> outHediffsToTend, List <Hediff> tendableHediffsInTendPriorityOrder = null) { outHediffsToTend.Clear(); HealthShardTendUtility.tmpHediffs.Clear(); bool flag = tendableHediffsInTendPriorityOrder != null; if (flag) { HealthShardTendUtility.tmpHediffs.AddRange(tendableHediffsInTendPriorityOrder); } else { List <Hediff> hediffs = patient.health.hediffSet.hediffs; for (int i = 0; i < hediffs.Count; i++) { bool flag2 = hediffs[i].TendableNow(false); if (flag2) { HealthShardTendUtility.tmpHediffs.Add(hediffs[i]); } } HealthShardTendUtility.SortByTendPriority(HealthShardTendUtility.tmpHediffs); } bool flag3 = GenCollection.Any <Hediff>(HealthShardTendUtility.tmpHediffs); if (flag3) { Hediff hediff = HealthShardTendUtility.tmpHediffs[0]; outHediffsToTend.Add(hediff); HediffCompProperties_TendDuration hediffCompProperties_TendDuration = hediff.def.CompProps <HediffCompProperties_TendDuration>(); bool flag4 = hediffCompProperties_TendDuration != null && hediffCompProperties_TendDuration.tendAllAtOnce; if (flag4) { for (int j = 0; j < HealthShardTendUtility.tmpHediffs.Count; j++) { bool flag5 = HealthShardTendUtility.tmpHediffs[j] != hediff && HealthShardTendUtility.tmpHediffs[j].def == hediff.def; if (flag5) { outHediffsToTend.Add(HealthShardTendUtility.tmpHediffs[j]); } } } else { bool flag6 = hediff is Hediff_Injury && usingMedicine; if (flag6) { float num = hediff.Severity; for (int k = 0; k < HealthShardTendUtility.tmpHediffs.Count; k++) { bool flag7 = HealthShardTendUtility.tmpHediffs[k] != hediff; if (flag7) { Hediff_Injury hediff_Injury = HealthShardTendUtility.tmpHediffs[k] as Hediff_Injury; bool flag8 = hediff_Injury != null; if (flag8) { float severity = hediff_Injury.Severity; bool flag9 = num + severity <= 20f; if (flag9) { num += severity; outHediffsToTend.Add(hediff_Injury); } } } } } } HealthShardTendUtility.tmpHediffs.Clear(); } }
// Token: 0x0600002F RID: 47 RVA: 0x00002870 File Offset: 0x00000A70 public static void DoTend(Pawn doctor, Pawn patient, Cloakgen medkit) { bool flag = patient.health.HasHediffsNeedingTend(false); if (flag) { bool flag2 = medkit != null && medkit.Destroyed; if (flag2) { Log.Warning("Tried to use destroyed medkit.", false); medkit = null; } float num = HealthShardTendUtility.CalculateBaseTendQuality(doctor, patient, medkit.kitComp.Props.medicine ?? null); HealthShardTendUtility.GetOptimalHediffsToTendWithSingleTreatment(patient, medkit.kitComp.Props.medicine != null, HealthShardTendUtility.tmpHediffsToTend, null); for (int i = 0; i < HealthShardTendUtility.tmpHediffsToTend.Count; i++) { HealthShardTendUtility.tmpHediffsToTend[i].Tended(num, i); } bool flag3 = doctor != null && doctor.Faction == Faction.OfPlayer && patient.Faction != doctor.Faction && !patient.IsPrisoner && patient.Faction != null; if (flag3) { patient.mindState.timesGuestTendedToByPlayer++; } bool flag4 = doctor != null && doctor.IsColonistPlayerControlled; if (flag4) { patient.records.AccumulateStoryEvent(StoryEventDefOf.TendedByPlayer); } bool flag5 = doctor != null && doctor.RaceProps.Humanlike && patient.RaceProps.Animal; if (flag5) { bool flag6 = RelationsUtility.TryDevelopBondRelation(doctor, patient, 0.004f); if (flag6) { bool flag7 = doctor.Faction != null && doctor.Faction != patient.Faction; if (flag7) { InteractionWorker_RecruitAttempt.DoRecruit(doctor, patient, 1f, false); } } } patient.records.Increment(RecordDefOf.TimesTendedTo); bool flag8 = doctor != null; if (flag8) { doctor.records.Increment(RecordDefOf.TimesTendedOther); } bool flag9 = doctor == patient && !doctor.Dead; if (flag9) { doctor.mindState.Notify_SelfTended(); } bool flag10 = medkit.kitComp.Props.medicine != null; if (flag10) { bool flag11 = patient.Spawned || (doctor != null && doctor.Spawned); if (flag11) { bool flag12 = medkit.kitComp.Props.medicine != null && StatExtension.GetStatValueAbstract(medkit.kitComp.Props.medicine, StatDefOf.MedicalPotency, null) > StatExtension.GetStatValueAbstract(ThingDefOf.MedicineIndustrial, StatDefOf.MedicalPotency, null); if (flag12) { SoundStarter.PlayOneShot(SoundDefOf.TechMedicineUsed, new TargetInfo(patient.Position, patient.Map, false)); } } } } }