public static void GiveInfection(this Recipe_Surgery s, Pawn patient, BodyPartRecord part, List <Thing> ingredients) { Hediff infection = null; var RemoveBodyPart = AccessTools.TypeByName("Recipe_RemoveBodyPart"); if (patient.health.immunity.DiseaseContractChanceFactor(HediffDefOf.WoundInfection, part) < 0.0001f) { return; } if (ingredients.Count == 0 && part.parent != null || part.parent != null) { infection = HediffMaker.MakeHediff(HediffDefOf.WoundInfection, patient, part.parent); } else if (RemoveBodyPart.IsInstanceOfType(s)) { infection = HediffMaker.MakeHediff(HediffDefOf.WoundInfection, patient, part); } if (infection != null) { patient.health.AddHediff(infection); } }
static void Postfix(bool __result, Recipe_Surgery __instance, Pawn surgeon, Pawn patient, List <Thing> ingredients, BodyPartRecord part, Bill bill) { if (!__result && IsClean(patient, part) && __instance.GetType().Name == "Recipe_RemoveBodyPart" && patient.RaceProps.Humanlike) { BadPeopleUtility.NotifyDoctorRemovedBodyPart(surgeon); } }
private static void GetReport(JobDriver_DoBill __instance) { bool isSurgery = (hasSurgeryAsJob(__instance.pawn)); //Log.Message("isSurgery:" + isSurgery + " (" + __instance.pawn.jobs.curJob.RecipeDef.workerClass + ")"); if (!isSurgery) { UIRoot_Play_UIRootOnGUI_Prefix.shouldDrawSurgeryRect = false; return; } Bill bill = __instance.pawn.jobs.curJob.bill; Recipe_Surgery surgery = bill.recipe.Worker as Recipe_Surgery; Pawn surgeon = __instance.pawn; Pawn patient = bill.billStack.billGiver as Pawn; if (surgeon != UIRoot_Play_UIRootOnGUI_Prefix.surgeon || patient != UIRoot_Play_UIRootOnGUI_Prefix.patient) { UIRoot_Play_UIRootOnGUI_Prefix.ResetToEmpty(); } Medicine medicine = null; BodyPartRecord part = (bill as Bill_Medical).Part; if (surgeon.CurJob.placedThings != null) { List <ThingStackPartClass> placedThings = surgeon.CurJob.placedThings; for (int i = 0; i < placedThings.Count; i++) { if (placedThings[i].thing is Medicine) { medicine = placedThings[i].thing as Medicine; break; } } } if (medicine == null) { if (surgeon.carryTracker.CarriedThing != null) { medicine = surgeon.carryTracker.CarriedThing as Medicine; } } if (medicine != null) { cachedMedicine = medicine; } SurgeryOdds data = new SurgeryOdds() { }; SurgeryFailChance(data, surgeon, patient, cachedMedicine, part, surgery); }
public static void RecipeApplyHediffs(Recipe_Surgery surgery, Pawn pawn, BodyPartRecord record) { if (surgery.recipe.HasModExtension <MSE_AdditionalHediff>()) { MSE_AdditionalHediff additionalHediffs = surgery.recipe.GetModExtension <MSE_AdditionalHediff>(); if (additionalHediffs != null && !additionalHediffs.hediffsToAdd.NullOrEmpty()) { List <HediffDef> hediffsToAdd = additionalHediffs.hediffsToAdd; for (int i = 0; i < hediffsToAdd.Count; i++) { pawn.health.AddHediff(hediffsToAdd[i], record, null, null); } } } return; }
public static bool CheckSurgeryFail(Recipe_Surgery __instance, ref bool __result, Pawn surgeon, Pawn patient, List <Thing> ingredients, BodyPartRecord part, Bill bill) { var num = 1f; if (!patient.RaceProps.IsMechanoid) { num *= surgeon.GetStatValue(StatDefOf.MedicalSurgerySuccessChance); } if (patient.InBed()) { num *= patient.CurrentBed().GetStatValue(StatDefOf.SurgerySuccessChanceFactor); } num *= Traverse.Create(__instance).Field("MedicineMedicalPotencyToSurgeryChanceFactor") .GetValue <SimpleCurve>().Evaluate(Traverse.Create(__instance) .Method("GetAverageMedicalPotency", new[] { typeof(List <Thing>), typeof(Bill) }) .GetValue <float>(ingredients, bill)); num *= __instance.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)) // Failed check { if (Rand.Chance(num)) // Successful check { //One more chance to get it right with minor injuries if (!Rand.Chance(Mathf.InverseLerp(0, 20, surgeon.skills.GetSkill(SkillDefOf.Medicine).Level) - (1f - surgeon.health.capacities.GetLevel(PawnCapacityDefOf.Consciousness)))) { // Failed check __instance.GiveInfection(patient, part, ingredients); } GiveNonLethalSurgeryInjuries(patient, part); //if (!patient.health.hediffSet.PartIsMissing(part)) //This was breaking some crap //{ __result = false; return(false); //} } if (!Rand.Chance(Mathf.InverseLerp(0, 20, surgeon.skills.GetSkill(SkillDefOf.Medicine).Level) - (1f - surgeon.health.capacities.GetLevel(PawnCapacityDefOf.Consciousness)))) { // Failed check //The surgeon has a chance based on their skill to avoid potentially lethal failures. if (!Rand.Chance(__instance.recipe.deathOnFailedSurgeryChance - num)) { //Failed surgery death chance is influenced by the surgery success chance. HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); if (!patient.Dead) { patient.Kill(null); } Messages.Message( "MessageMedicalOperationFailureFatal".Translate(surgeon.LabelShort, patient.LabelShort, __instance.recipe.LabelCap, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent); } else if (!Rand.Chance(num)) // Failed check { //Instead of a 50-50 chance, it's based on how likely you were to successfully complete the surgery. if (!Rand.Chance(surgeon.health.capacities.GetLevel(PawnCapacityDefOf.Consciousness))) { //Only impaired surgeons will ever perform ridiculous failures. Messages.Message( "MessageMedicalOperationFailureRidiculous".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureRidiculous(patient); } else { Messages.Message( "MessageMedicalOperationFailureCatastrophic".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); } } else { Messages.Message( "MessageMedicalOperationFailureMinor".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent); RecreateIngredient(surgeon, ingredients); } __instance.GiveInfection(patient, part, ingredients); } else { //Non-lethal surgery injuries. Messages.Message( "MessageMedicalOperationFailureMinor".Translate(surgeon.LabelShort, patient.LabelShort, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent); GiveNonLethalSurgeryInjuries(patient, part); __instance.GiveInfection(patient, part, ingredients); RecreateIngredient(surgeon, ingredients); } if (!patient.Dead) { Traverse.Create(__instance) .Method("TryGainBotchedSurgeryThought", new[] { typeof(Pawn), typeof(Pawn) }) .GetValue(patient, surgeon); } __result = true; return(false); } __result = false; return(false); }
private static void SurgeryFailChance(SurgeryOdds data, Pawn surgeon, Pawn patient, Medicine medicine, BodyPartRecord part, Recipe_Surgery surgery) { float num = 1f; num *= surgeon.GetStatValue((!patient.RaceProps.IsMechanoid) ? StatDefOf.MedicalSurgerySuccessChance : StatDefOf.MechanoidOperationSuccessChance, true); Room room = patient.GetRoom(RegionType.Set_Passable); if (room != null && !patient.RaceProps.IsMechanoid) { num *= room.GetStat(RoomStatDefOf.SurgerySuccessChanceFactor); } num *= GetMedicalPotency(medicine); num *= surgery.recipe.surgerySuccessChanceFactor; calculateChances(num, surgery.recipe.deathOnFailedSurgeryChance, ref data); SetSurgeryChancesForDisplay(data, surgeon, patient); }
internal static bool _CheckSurgeryFail(this Recipe_Surgery s, Pawn surgeon, Pawn patient, List <Thing> ingredients, BodyPartRecord part) { float num = 1f; float num2 = surgeon.GetStatValue(StatDefOf.SurgerySuccessChance, true); if (num2 < 1f) { num2 = Mathf.Pow(num2, s.recipe.surgeonSurgerySuccessChanceExponent); } num *= num2; Room room = surgeon.GetRoom(); if (room != null) { float num3 = room.GetStat(RoomStatDefOf.SurgerySuccessChanceFactor); if (num3 < 1f) { num3 = Mathf.Pow(num3, s.recipe.roomSurgerySuccessChanceFactorExponent); } num *= num3; } var GetAverageMedicalPotency = typeof(Recipe_Surgery).GetMethod("GetAverageMedicalPotency", BindingFlags.Instance | BindingFlags.NonPublic); if (GetAverageMedicalPotency != null) { num *= (float)GetAverageMedicalPotency.Invoke(s, new object[] { ingredients }); } num *= s.recipe.surgerySuccessChanceFactor; if (Rand.Value > num) { if (Rand.Value < s.recipe.deathOnFailedSurgeryChance) { int num4 = 0; while (!patient.Dead) { HealthUtility.GiveInjuriesOperationFailureRidiculous(patient); num4++; if (num4 > 300) { Log.Error("Could not kill patient."); break; } } } else if (Rand.Value < 0.5f) { if (Rand.Value < 0.1f) { Messages.Message("MessageMedicalOperationFailureRidiculous".Translate(new object[] { surgeon.LabelShort, patient.LabelShort }), patient, MessageSound.SeriousAlert); HealthUtility.GiveInjuriesOperationFailureRidiculous(patient); } else { Messages.Message("MessageMedicalOperationFailureCatastrophic".Translate(new object[] { surgeon.LabelShort, patient.LabelShort }), patient, MessageSound.SeriousAlert); HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); } } else { Messages.Message("MessageMedicalOperationFailureMinor".Translate(new object[] { surgeon.LabelShort, patient.LabelShort }), patient, MessageSound.Negative); HealthUtility.GiveInjuriesOperationFailureMinor(patient, part); } if (!patient.Dead) { var TryGainBotchedSurgeryThought = typeof(Recipe_Surgery).GetMethod("TryGainBotchedSurgeryThought", BindingFlags.Instance | BindingFlags.NonPublic); if (TryGainBotchedSurgeryThought != null) { TryGainBotchedSurgeryThought.Invoke(s, new object[] { patient, surgeon }); } else { Log.ErrorOnce("Unable to reflect Recipe_MedicalOperation.TryGainBotchedSurgeryThought!", 305432421); } } else { surgeon.needs.mood.thoughts.memories.TryGainMemoryThought(ThoughtDefOfPsychology.KilledPatientBleedingHeart, patient); } return(true); } return(false); }