protected bool CheckExperimentFail(Pawn tester, Thing weapon) { float num = 1f; float delta = 1f; CompKnowledge techComp = tester.TryGetComp <CompKnowledge>(); if (techComp != null) { delta = (int)techComp.techLevel / (int)weapon.def.techLevel; } float factor = WeaponExperimentChanceFactor.Evaluate(delta); num *= factor; num = Mathf.Min(num, 0.98f); if (Prefs.LogVerbose) { Log.Message($"[HumanResources] Experiment weapon calculation for {tester} vs. {weapon.def}: techLevel diff is {delta} -> chance factor is {num}"); } Job job = this.job; RecipeDef recipe = job.bill.recipe; if (!Rand.Chance(num)) //Determined by the tech level difference according to curve. { if (Rand.Chance(0.5f)) //50% chance the failure is harmless; { techComp?.AddWeaponTrauma(weapon.def); if (Rand.Chance(0.5f)) //25% chance the weapon just takes some damage; { if (Rand.Chance(0.2f)) //5% chance the weapon is destroyed; { Find.LetterStack.ReceiveLetter("LetterLabelWeaponTestFailed".Translate(weapon.def.Named("WEAPON")), "MessageMedicalWeaponTestFailureRidiculous".Translate(tester.LabelShort, tester.LabelShort, weapon.def.Named("WEAPON"), tester.Named("TESTER"), recipe.Named("RECIPE")), LetterDefOf.NegativeEvent, tester, null, null, null, null); Backfire(tester, weapon); weapon.Destroy(); } else //20% chance the weapon backfires. { Find.LetterStack.ReceiveLetter("LetterLabelWeaponTestFailed".Translate(weapon.def.Named("WEAPON")), "MessageWeaponTestFailureCatastrophic".Translate(tester.LabelShort, tester.LabelShort, weapon.def.Named("WEAPON"), tester.Named("TESTER"), recipe.Named("RECIPE")), LetterDefOf.NegativeEvent, tester, null, null, null, null); Backfire(tester, weapon); } } else { Find.LetterStack.ReceiveLetter("LetterLabelWeaponTestFailed".Translate(weapon.def.Named("WEAPON")), "MessageWeaponTestFailureMinor".Translate(tester.LabelShort, tester.LabelShort, weapon.def.Named("WEAPON"), tester.Named("TESTER"), recipe.Named("RECIPE")), LetterDefOf.NegativeEvent, tester, null, null, null, null); float damageFactor = 4 - delta; Scratch(weapon, damageFactor); } } else { Messages.Message("WeaponTestFail".Translate(tester, weapon.def), MessageTypeDefOf.NegativeEvent); } return(true); } return(false); }