private static void SetSurgeryChancesForDisplay(SurgeryOdds data, Pawn surgeon, Pawn patient) { UIRoot_Play_UIRootOnGUI_Prefix.shouldDrawSurgeryRect = true; UIRoot_Play_UIRootOnGUI_Prefix.sentSurgeryOdds = data; UIRoot_Play_UIRootOnGUI_Prefix.surgeon = surgeon; UIRoot_Play_UIRootOnGUI_Prefix.patient = patient; }
public SurgeryOdds addSpec(float addition) { float newChanceSuccess = chanceSuccess + addition; SurgeryOdds newOdds = new SurgeryOdds(); if (newChanceSuccess >= 1f) { newOdds.chanceSuccess = 1f; //div by 0 protection newOdds.chanceFailMinor = 0; newOdds.chanceFailCatastrophic = 0; newOdds.chanceFailRidiculous = 0; newOdds.chanceFailDeadly = 0; return(newOdds); } if (newChanceSuccess <= 0f) { newChanceSuccess = 0f; } float mult = (1f - newChanceSuccess) / (1f - chanceSuccess); newOdds.chanceSuccess = newChanceSuccess; newOdds.chanceFailMinor = chanceFailMinor * mult; newOdds.chanceFailCatastrophic = chanceFailCatastrophic * mult; newOdds.chanceFailRidiculous = chanceFailRidiculous * mult; newOdds.chanceFailDeadly = chanceFailDeadly * mult; return(newOdds); }
private static SurgeryOdds ModifiedOdds(SurgeryOdds surgeryOdds, Pawn surgeon, Pawn patient, out bool usesSpecialText, out bool usesSpecialColor, out string specialText, out Color specialColor) { if (!QOLTweaksPack.SurgeryEstimateAccountForTraits) { usesSpecialText = false; usesSpecialColor = false; specialText = ""; specialColor = Color.white; return(surgeryOdds); } else { //Log.Message("trait check"); float skillMod = ((20f - surgeon.skills.GetSkill(SkillDefOf.Medicine).Level) / 20f); //first apply modifiers /*foreach(Trait trait in surgeon.story.traits.allTraits) * { * Log.Message(trait.Label); * }*/ if (surgeon.story.traits.HasTrait(TraitDefOf.NaturalMood)) { float addition = (surgeon.story.traits.GetTrait(TraitDefOf.NaturalMood).Degree * 0.2f * skillMod); surgeryOdds = surgeryOdds.addSpec(addition); //Log.Message("modified odds by " + addition + " due to mood trait"); } if (surgeon.story.traits.HasTrait(TraitDefOf.Psychopath) || (surgeon.story.traits.HasTrait(TraitDefOf.Bloodlust) && patient.Faction != null && !patient.Faction.IsPlayer)) { usesSpecialText = true; usesSpecialColor = true; specialText = "SurgerySpecial_Psychopath"; specialColor = new Color(0.9f, 0.1f, 0.1f); float mult = skillMod; surgeryOdds = surgeryOdds.multSpec(mult); //Log.Message("modified odds by " + mult + " due to psychopath trait"); return(surgeryOdds); } usesSpecialText = false; usesSpecialColor = false; specialText = ""; specialColor = Color.white; return(surgeryOdds); } }
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 calculateChances(float randNum, float deathOdds, ref SurgeryOdds data) { if (randNum > 1f) { randNum = 1f; } data.chanceSuccess = randNum; data.chanceFailDeadly = (1f - data.chanceSuccess) * deathOdds; float evens = ((1f - data.chanceSuccess) * (1f - deathOdds)) / 2f; data.chanceFailRidiculous = evens * 0.1f; data.chanceFailCatastrophic = evens * 0.9f; data.chanceFailMinor = evens; }
public SurgeryOdds multSpec(float mod) { float newChanceSuccess = chanceSuccess + (1f - chanceSuccess) * mod; //float diff = newChanceSuccess - chanceSuccess; float mult = (1f - mod); SurgeryOdds newOdds = new SurgeryOdds(); newOdds.chanceSuccess = newChanceSuccess; newOdds.chanceFailMinor = chanceFailMinor * mult; newOdds.chanceFailCatastrophic = chanceFailCatastrophic * mult; newOdds.chanceFailRidiculous = chanceFailRidiculous * mult; newOdds.chanceFailDeadly = chanceFailDeadly * mult; return(newOdds); }
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); }
private static void DrawReport(Rect reportRect) { GameFont activeFont = Text.Font; Text.Font = GameFont.Small; bool detailed = false; switch (QOLTweaksPack.SurgeryEstimationMode.Value) { case QOLTweaksPack.SurgeryEstimateMode.AlwaysAccurate: detailed = true; break; case QOLTweaksPack.SurgeryEstimateMode.AccurateIfDoctor: detailed = (surgeon.skills.GetSkill(SkillDefOf.Medicine).Level >= 5) ? true : false; break; case QOLTweaksPack.SurgeryEstimateMode.AccurateIfGoodDoctor: detailed = (surgeon.skills.GetSkill(SkillDefOf.Medicine).Level >= 10) ? true : false; break; case QOLTweaksPack.SurgeryEstimateMode.AccurateIfAmazingDoctor: detailed = (surgeon.skills.GetSkill(SkillDefOf.Medicine).Level >= 15) ? true : false; break; case QOLTweaksPack.SurgeryEstimateMode.NeverAccurate: detailed = false; break; } //Log.Message("chances:" + surgeryOdds.chanceSuccess + " " + surgeryOdds.chanceFailMinor + " " + surgeryOdds.chanceFailCatastrophic + " " + surgeryOdds.chanceFailRidiculous + " " + surgeryOdds.chanceFailDeadly); Color textColor; string text; bool usesSpecialText; bool usesSpecialColor; SurgeryOdds surgeryOdds = ModifiedOdds(sentSurgeryOdds, surgeon, patient, out usesSpecialText, out usesSpecialColor, out text, out textColor); if (detailed) { float acc = 0; float diff = reportRect.width - ReportBarStart - ReportBarEnd; Rect reportTextRect = new Rect(reportRect.x, reportRect.y, reportRect.width, reportRect.height - (ReportBarHeight + ReportBarOffset * 2)); float oneTextWidth = (reportTextRect.width - 4) / 3f; float oneTextHeight = (reportTextRect.height - 4) / 2f; if (surgeryOdds.chanceSuccess > 0.0f) { GUI.color = BarColorSuccess; GUI.DrawTexture(new Rect(reportRect.x + ReportBarStart + (diff * acc), reportRect.yMax - (ReportBarHeight + ReportBarOffset), diff * surgeryOdds.chanceSuccess, ReportBarHeight), BaseContent.WhiteTex); GUI.color = TextColorSuccess; Rect localRect = new Rect(reportTextRect.x + ReportTextOffsetHori, reportTextRect.y + ReportTextOffsetVert, oneTextWidth, oneTextHeight); GUI.Label(localRect, ((Mathf.Round(surgeryOdds.chanceSuccess * 100)).ToString("F0") + "%")); TooltipHandler.TipRegion(localRect, "Surgery_detailedMouseover_OddsOfSuccess".Translate()); acc += surgeryOdds.chanceSuccess; } if (surgeryOdds.chanceFailMinor > 0.0f) { GUI.color = BarColorFailMinor; GUI.DrawTexture(new Rect(reportRect.x + ReportBarStart + (diff * acc), reportRect.yMax - (ReportBarHeight + ReportBarOffset), diff * surgeryOdds.chanceFailMinor, ReportBarHeight), BaseContent.WhiteTex); GUI.color = TextColorFailMinor; Rect localRect = new Rect(reportTextRect.x + ReportTextOffsetHori + oneTextWidth, reportTextRect.y + ReportTextOffsetVert, oneTextWidth, oneTextHeight); GUI.Label(localRect, ((Mathf.Round(surgeryOdds.chanceFailMinor * 100)).ToString("F0") + "%")); TooltipHandler.TipRegion(localRect, "Surgery_detailedMouseover_OddsOfFailMinor".Translate()); acc += surgeryOdds.chanceFailMinor; } if (surgeryOdds.chanceFailCatastrophic > 0.0f) { GUI.color = BarColorFailCatastrophic; GUI.DrawTexture(new Rect(reportRect.x + ReportBarStart + (diff * acc), reportRect.yMax - (ReportBarHeight + ReportBarOffset), diff * surgeryOdds.chanceFailCatastrophic, ReportBarHeight), BaseContent.WhiteTex); GUI.color = TextColorFailCatastrophic; Rect localRect = new Rect(reportTextRect.x + ReportTextOffsetHori + oneTextWidth * 2, reportTextRect.y + ReportTextOffsetVert, oneTextWidth, oneTextHeight); GUI.Label(localRect, ((Mathf.Round(surgeryOdds.chanceFailCatastrophic * 100)).ToString("F0") + "%")); TooltipHandler.TipRegion(localRect, "Surgery_detailedMouseover_OddsOfFailCatastrophic".Translate()); acc += surgeryOdds.chanceFailCatastrophic; } if (surgeryOdds.chanceFailRidiculous > 0.0f) { GUI.color = BarColorFailRidiculous; GUI.DrawTexture(new Rect(reportRect.x + ReportBarStart + (diff * acc), reportRect.yMax - (ReportBarHeight + ReportBarOffset), diff * surgeryOdds.chanceFailRidiculous, ReportBarHeight), BaseContent.WhiteTex); GUI.color = TextColorFailRidiculous; Rect localRect = new Rect(reportTextRect.x + ReportTextOffsetHori + oneTextWidth, reportTextRect.y + ReportTextOffsetVert + oneTextHeight, oneTextWidth, oneTextHeight); GUI.Label(localRect, ((Mathf.Round(surgeryOdds.chanceFailRidiculous * 100)).ToString("F0") + "%")); TooltipHandler.TipRegion(localRect, "Surgery_detailedMouseover_OddsOfFailRidiculous".Translate()); acc += surgeryOdds.chanceFailRidiculous; } if (surgeryOdds.chanceFailDeadly > 0.0f) { GUI.color = BarColorFailDeadly; GUI.DrawTexture(new Rect(reportRect.x + ReportBarStart + (diff * acc), reportRect.yMax - (ReportBarHeight + ReportBarOffset), diff * surgeryOdds.chanceFailDeadly, ReportBarHeight), BaseContent.WhiteTex); GUI.color = TextColorFailDeadly; Rect localRect = new Rect(reportTextRect.x + ReportTextOffsetHori + oneTextWidth * 2, reportTextRect.y + ReportTextOffsetVert + oneTextHeight, oneTextWidth, oneTextHeight); GUI.Label(localRect, ((Mathf.Round(surgeryOdds.chanceFailDeadly * 100)).ToString("F0") + "%")); TooltipHandler.TipRegion(localRect, "Surgery_detailedMouseover_OddsOfFailDeadly".Translate()); acc += surgeryOdds.chanceFailDeadly; } GUI.color = Color.white; } else { float assumedOdds = surgeryOdds.chanceSuccess + surgeryOdds.chanceFailMinor * MinorFailAllowanceMult; if (assumedOdds < ImpossibleOdds) { if (!usesSpecialText) { text = ImpossibleOddsText; } if (!usesSpecialColor) { textColor = ImpossibleOddsColor; } } else if (assumedOdds < TerribleOdds) { if (!usesSpecialText) { text = TerribleOddsText; } if (!usesSpecialColor) { textColor = TerribleOddsColor; } } else if (assumedOdds < BadOdds) { if (!usesSpecialText) { text = BadOddsText; } if (!usesSpecialColor) { textColor = BadOddsColor; } } else if (assumedOdds < AcceptableOdds) { if (!usesSpecialText) { text = AcceptableOddsText; } if (!usesSpecialColor) { textColor = AcceptableOddsColor; } } else if (assumedOdds < GoodOdds) { if (!usesSpecialText) { text = GoodOddsText; } if (!usesSpecialColor) { textColor = GoodOddsColor; } } else if (assumedOdds < GreatOdds) { if (!usesSpecialText) { text = GreatOddsText; } if (!usesSpecialColor) { textColor = GreatOddsColor; } } else { if (!usesSpecialText) { text = AmazingOddsText; } if (!usesSpecialColor) { textColor = AmazingOddsColor; } } float bottom; reportRect = reportRect.ContractedBy(2f); WidgetsExtensions.DrawGadgetWindowLabel(text.Translate(), reportRect, textColor, out bottom); } Text.Font = activeFont; }