private bool CheckHackingFail(Pawn hackee, Pawn hacker, BodyPartRecord part) { float successChance = 1.0f; successChance *= recipe.surgerySuccessChanceFactor; successChance *= hacker.GetStatValue(WTH_DefOf.WTH_HackingSuccessChance, true); System.Random r = new System.Random(DateTime.Now.Millisecond); float combatPowerFactorCapped = CalcCombatPowerFactorCapped(hackee); successChance *= combatPowerFactorCapped; if (!Rand.Chance(successChance)) { if (Rand.Chance(this.recipe.deathOnFailedSurgeryChance)) { HealthUtility.GiveInjuriesOperationFailureCatastrophic(hackee, part); if (!hackee.Dead) { hackee.Kill(null, null); } Messages.Message("MessageMedicalOperationFailureFatal".Translate(new object[] { hacker.LabelShort, hacker.LabelShort, this.recipe.LabelCap }), hackee, MessageTypeDefOf.NegativeHealthEvent, true); } else { HackingFailEvent(hackee, part, r); } return(true); } return(false); }
protected bool CheckSurgeryFailAndroid(Pawn surgeon, Pawn patient, List <Thing> ingredients, BodyPartRecord part, Bill bill) { float num = 1f; if (!patient.RaceProps.IsMechanoid) { num *= surgeon.GetStatValue(StatDefOf.AndroidSurgerySuccessChance, true); } if (patient.InBed()) { num *= patient.CurrentBed().GetStatValue(StatDefOf.AndroidSurgerySuccessChance, true); } num *= this.recipe.surgerySuccessChanceFactor; if (surgeon.InspirationDef == InspirationDefOf.Inspired_Surgery && !patient.RaceProps.IsMechanoid) { if (num < 1f) { num = 1f - (1f - num) * 0.1f; } surgeon.mindState.inspirationHandler.EndInspiration(InspirationDefOf.Inspired_Surgery); } if (!Rand.Chance(num)) { if (Rand.Chance(this.recipe.deathOnFailedSurgeryChance)) { HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); if (!patient.Dead) { patient.Kill(null, null); } Messages.Message("MessageMedicalOperationFailureFatalAndroid".Translate(surgeon.LabelShort, patient.LabelShort, this.recipe.label), patient, MessageTypeDefOf.NegativeHealthEvent); } else if (Rand.Chance(0.5f)) { if (Rand.Chance(0.1f)) { Messages.Message("MessageMedicalOperationFailureRidiculousAndroid".Translate(surgeon.LabelShort, patient.LabelShort), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureRidiculous(patient); } else { Messages.Message("MessageMedicalOperationFailureCatastrophicAndroid".Translate(surgeon.LabelShort, patient.LabelShort), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); } } else { Messages.Message("MessageMedicalOperationFailureMinorAndroid".Translate(surgeon.LabelShort, patient.LabelShort), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureMinor(patient, part); } if (!patient.Dead) { this.TryGainBotchedSurgeryThought(patient, surgeon); } return(true); } return(false); }
protected bool CheckSurgeryFail(Pawn surgeon, Pawn patient, List <Thing> ingredients, BodyPartRecord part, Bill bill) { float num = 1f; if (!patient.RaceProps.IsMechanoid) { num *= surgeon.GetStatValue(StatDefOf.MedicalSurgerySuccessChance); } if (patient.InBed()) { num *= patient.CurrentBed().GetStatValue(StatDefOf.SurgerySuccessChanceFactor); } num *= MedicineMedicalPotencyToSurgeryChanceFactor.Evaluate(GetAverageMedicalPotency(ingredients, bill)); num *= 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(recipe.deathOnFailedSurgeryChance)) { HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); if (!patient.Dead) { patient.Kill(null, null); } Messages.Message("MessageMedicalOperationFailureFatal".Translate(surgeon.LabelShort, patient.LabelShort, recipe.LabelCap, surgeon.Named("SURGEON"), patient.Named("PATIENT")), patient, MessageTypeDefOf.NegativeHealthEvent); } else if (Rand.Chance(0.5f)) { if (Rand.Chance(0.1f)) { 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); HealthUtility.GiveInjuriesOperationFailureMinor(patient, part); } if (!patient.Dead) { TryGainBotchedSurgeryThought(patient, surgeon); } return(true); } return(false); }
protected bool CheckSurgeryFail(Pawn surgeon, Pawn patient, List <Thing> ingredients, BodyPartRecord part, Bill bill) { float num = 1f; num *= surgeon.GetStatValue((!patient.RaceProps.IsMechanoid) ? StatDefOf.MedicalSurgerySuccessChance : StatDefOf.MechanoidOperationSuccessChance, true); if (patient.InBed()) { num *= patient.CurrentBed().GetStatValue(StatDefOf.SurgerySuccessChanceFactor, true); } num *= Recipe_Surgery.MedicineMedicalPotencyToSurgeryChanceFactor.Evaluate(this.GetAverageMedicalPotency(ingredients, bill)); num *= base.recipe.surgerySuccessChanceFactor; if (surgeon.InspirationDef == InspirationDefOf.InspiredSurgery && !patient.RaceProps.IsMechanoid) { if (num < 1.0) { num = (float)(1.0 - (1.0 - num) * 0.10000000149011612); } surgeon.mindState.inspirationHandler.EndInspiration(InspirationDefOf.InspiredSurgery); } if (!Rand.Chance(num)) { if (Rand.Chance(base.recipe.deathOnFailedSurgeryChance)) { HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); if (!patient.Dead) { patient.Kill(null, null); } Messages.Message("MessageMedicalOperationFailureFatal".Translate(surgeon.LabelShort, patient.LabelShort, base.recipe.label), patient, MessageTypeDefOf.NegativeHealthEvent); } else if (Rand.Chance(0.5f)) { if (Rand.Chance(0.1f)) { Messages.Message("MessageMedicalOperationFailureRidiculous".Translate(surgeon.LabelShort, patient.LabelShort), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureRidiculous(patient); } else { Messages.Message("MessageMedicalOperationFailureCatastrophic".Translate(surgeon.LabelShort, patient.LabelShort), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient, part); } } else { Messages.Message("MessageMedicalOperationFailureMinor".Translate(surgeon.LabelShort, patient.LabelShort), patient, MessageTypeDefOf.NegativeHealthEvent); HealthUtility.GiveInjuriesOperationFailureMinor(patient, part); } if (!patient.Dead) { this.TryGainBotchedSurgeryThought(patient, surgeon); } return(true); } return(false); }
public static void CauseIntendedMechanoidRaid(Pawn pawn, BodyPartRecord part, RecipeDef recipe) { CauseMechanoidRaid(pawn, part, recipe, 0.9f, 2000, 60000); Find.LetterStack.ReceiveLetter("WTH_Letter_CausedIntendedMechanoidRaid_Label".Translate(), "WTH_Letter_CausedIntendedMechanoidRaid_Description".Translate(), LetterDefOf.PositiveEvent, pawn); HealthUtility.GiveInjuriesOperationFailureCatastrophic(pawn, part); //Kill mech for balancing purposes. if (!pawn.Dead) { pawn.Kill(null, null); } }
public static void CauseIntendedMechanoidRaidTooLarge(Pawn pawn, BodyPartRecord part, RecipeDef recipe) { CauseMechanoidRaid(pawn, part, recipe, 1.35f, 2000, 10000); Find.LetterStack.ReceiveLetter("WTH_Letter_CausedIntendedMechanoidRaidTooLarge_Label".Translate(), "WTH_Letter_CausedIntendedMechanoidRaidTooLarge_Description".Translate(), LetterDefOf.ThreatBig, pawn); HealthUtility.GiveInjuriesOperationFailureCatastrophic(pawn, part); //Kill mech for balancing purposes. SoundDefOf.PsychicPulseGlobal.PlayOneShotOnCamera(pawn.Map); if (!pawn.Dead) { pawn.Kill(null, null); } }
private bool CheckHackingFail(Pawn hackee, Pawn hacker, BodyPartRecord part) { float successChance = 1.0f; successChance *= recipe.surgerySuccessChanceFactor; successChance *= hacker.GetStatValue(WTH_DefOf.WTH_HackingSuccessChance, true); System.Random r = new System.Random(DateTime.Now.Millisecond); float combatPowerFactorCapped = CalcCombatPowerFactorCapped(hackee); successChance *= combatPowerFactorCapped; if (recipe.GetModExtension <DefModExtension_Recipe> () is DefModExtension_Recipe ext && ext.surgerySuccessCap > 0) { if (successChance > 1.0f) { successChance = 1.0f; } successChance *= ext.surgerySuccessCap; Log.Message("succesChance was: " + successChance); } if (!Rand.Chance(successChance)) { MoteMaker.ThrowText((hacker.DrawPos + hackee.DrawPos) / 2f, hacker.Map, "WTH_TextMote_OperationFailed".Translate(new object[] { successChance.ToStringPercent() }), 8f); if (Rand.Chance(this.recipe.deathOnFailedSurgeryChance)) { HealthUtility.GiveInjuriesOperationFailureCatastrophic(hackee, part); if (!hackee.Dead) { hackee.Kill(null, null); } Messages.Message("MessageMedicalOperationFailureFatal".Translate(new object[] { hacker.LabelShort, hacker.LabelShort, this.recipe.LabelCap }), hackee, MessageTypeDefOf.NegativeHealthEvent, true); } else { HackingFailEvent(hacker, hackee, part, r); } return(true); } return(false); }
internal static bool _CheckSurgeryFail(this Recipe_MedicalOperation m, Pawn surgeon, Pawn patient, List <Thing> ingredients) { if (surgeon == null) { Log.Error("surgeon is null"); return(false); } if (patient == null) { Log.Error("patient is null"); return(false); } float num1 = 1f; float f1 = surgeon.GetStatValue(StatDefOf.SurgerySuccessChance, true); if ((double)f1 < 1.0) { f1 = Mathf.Pow(f1, m.recipe.surgeonSurgerySuccessChanceExponent); } float num2 = num1 * f1; Room room = surgeon.GetRoom(); if (room != null) { float f2 = room.GetStat(RoomStatDefOf.SurgerySuccessChanceFactor); if ((double)f2 < 1.0) { f2 = Mathf.Pow(f2, m.recipe.roomSurgerySuccessChanceFactorExponent); } num2 *= f2; } float potency = 0.0f; var GetAverageMedicalPotency = typeof(Recipe_MedicalOperation).GetMethod("GetAverageMedicalPotency", BindingFlags.Instance | BindingFlags.NonPublic); if (GetAverageMedicalPotency != null) { potency = (float)GetAverageMedicalPotency.Invoke(m, new object[] { ingredients }); } else { Log.ErrorOnce("Unable to reflect Recipe_MedicalOperation.GetAverageMedicalPotency!", 305432421); } if ((double)Rand.Value <= (double)(num2 * potency * m.recipe.surgerySuccessChanceFactor)) { return(false); } if ((double)Rand.Value < (double)m.recipe.deathOnFailedSurgeryChance) { int num3 = 0; while (!patient.Dead) { HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient); ++num3; if (num3 > 300) { Log.Error("Could not kill patient."); break; } } } else if ((double)Rand.Value < 0.5) { Messages.Message("MessageMedicalOperationFailureCatastrophic".Translate((object)surgeon.LabelShort, (object)patient.LabelShort), (TargetInfo)((Thing)patient), MessageSound.SeriousAlert); HealthUtility.GiveInjuriesOperationFailureCatastrophic(patient); } else { Messages.Message("MessageMedicalOperationFailureMinor".Translate((object)surgeon.LabelShort, (object)patient.LabelShort), (TargetInfo)((Thing)patient), MessageSound.Negative); HealthUtility.GiveInjuriesOperationFailureMinor(patient); } if (!patient.Dead) { var TryGainBotchedSurgeryThought = typeof(Recipe_MedicalOperation).GetMethod("TryGainBotchedSurgeryThought", BindingFlags.Instance | BindingFlags.NonPublic); if (TryGainBotchedSurgeryThought != null) { TryGainBotchedSurgeryThought.Invoke(m, 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); }
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); }
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); }