public static void CreateAndAddNotification(GermExposureMonitor.Instance monitor, string sicknessName) { string text = string.Format(DUPE_EXPOSED_TO_GERMS_NOTIFICATION, sicknessName); Notification.ClickCallback callback = new Notification.ClickCallback(Notification_Callback); MinionIdentity minion = monitor.gameObject.GetComponent <MinionIdentity>(); ShowLocationObject slo = new ShowLocationObject(minion); slo.ShowLocation = MinionsLoaded && showLocation; Notification notification = new Notification(text, NotificationType.BadMinor, HashedString.Invalid, (List <Notification> n, object d) => string.Format(DUPE_EXPOSED_TO_GERMS_TOOLTIP, sicknessName) + n.ReduceMessages(true), null, false, 0, callback, slo); monitor.gameObject.AddOrGet <Notifier>().Add(notification); Action <object> act = null; act = x => { monitor.gameObject.AddOrGet <Notifier>().Remove(notification); monitor.Unsubscribe((int)GameHashes.SleepFinished, act); monitor.Unsubscribe((int)GameHashes.DuplicantDied, act); }; monitor.Subscribe((int)GameHashes.SleepFinished, act); monitor.Subscribe((int)GameHashes.DuplicantDied, act); }
protected override void OnCompleteWork(Worker worker) { Storage component1 = GetComponent <Storage>(); SimUtil.DiseaseInfo disease_info1; float aggregate_temperature; component1.ConsumeAndGetDisease(SimHashes.Ethanol.CreateTag(), champagneFiller.ethanolMassPerUse, out disease_info1, out aggregate_temperature); SimUtil.DiseaseInfo disease_info2; component1.ConsumeAndGetDisease(champagneFiller.ingredientTag, champagneFiller.ingredientMassPerUse, out disease_info2, out aggregate_temperature); GermExposureMonitor.Instance smi = worker.GetSMI <GermExposureMonitor.Instance>(); if (smi != null) { smi.TryInjectDisease(disease_info1.idx, disease_info1.count, SimHashes.Ethanol.CreateTag(), Sickness.InfectionVector.Digestion); smi.TryInjectDisease(disease_info2.idx, disease_info2.count, champagneFiller.ingredientTag, Sickness.InfectionVector.Digestion); } Effects component2 = worker.GetComponent <Effects>(); if (!string.IsNullOrEmpty(champagneFiller.specificEffect)) { component2.Add(champagneFiller.specificEffect, true); } if (string.IsNullOrEmpty(champagneFiller.trackingEffect)) { return; } component2.Add(champagneFiller.trackingEffect, true); }
/// <summary> /// Applied before OnSleepFinished runs. /// </summary> internal static bool Prefix(GermExposureMonitor.Instance __instance) { var manager = __instance.gameObject?.AddOrGet <GermIntegrator>(); if (manager != null) { manager.OnSleepFinished(__instance); } return(manager == null); }
/// <summary> /// Applied before InjectDisease runs. /// </summary> internal static bool Prefix(GermExposureMonitor.Instance __instance, int count, Disease disease, Tag source, Sickness.InfectionVector vector) { var manager = __instance.gameObject?.AddOrGet <GermIntegrator>(); if (manager != null) { manager.InjectDisease(__instance, disease, count, source, vector); } return(manager == null); }
public static bool Prefix(GermExposureMonitor.Instance __instance, Disease disease, int count, Tag source, Sickness.InfectionVector vector) { var isExposureValidForTraits = AccessTools.Method(__instance.GetType(), "IsExposureValidForTraits"); if (isExposureValidForTraits == null) { return(false); } foreach (var exposureType in GermExposureMonitor.exposureTypes) { if (disease.id == (HashedString)exposureType.germ_id && count * 1.5 > exposureType.exposure_threshold && (bool)isExposureValidForTraits.Invoke(__instance, new object[] { exposureType })) { var totalValue = Db.Get().Attributes.GermResistance.Lookup(__instance.gameObject) .GetTotalValue(); var contractionChance = (float)(0.5 - 0.5 * Math.Tanh(0.5 * (exposureType.base_resistance + totalValue))); __instance.lastDiseaseSources[disease.id] = new DiseaseSourceInfo(source, vector, contractionChance); __instance.SetExposureState(exposureType.germ_id, GermExposureMonitor.ExposureState.Exposed); var amount = Mathf.Clamp01(contractionChance); GermExposureTracker.Instance.AddExposure(exposureType, amount); float addCount = count; if (vector == Sickness.InfectionVector.Inhalation) { addCount *= 1.0f; } var hostedGerms = __instance.gameObject.GetComponent <GermHost>().GetGerms(disease); if (hostedGerms > 0 && addCount * 11 < hostedGerms) { addCount = addCount * (addCount * 11 / hostedGerms); } __instance.gameObject.GetComponent <GermHost>().AddGerms(disease, addCount); //Debug.Log("added " + count + " germs to a dupe. "); } } var refreshStatusItems = AccessTools.Method(__instance.GetType(), "RefreshStatusItems"); refreshStatusItems?.Invoke(__instance, new object[] { }); return(false); }
private static string ReduceNotifications(List <Notification> list, object tooltipData) { string text = ""; foreach (Notification n in list) { MinionIdentity minion = (MinionIdentity)n.customClickData; string sickness_id = (string)tooltipData; string name = n.NotifierName; ExposureType type = TUNING.GERM_EXPOSURE.TYPES.First(x => x.sickness_id == sickness_id); GermExposureMonitor.Instance smi = minion.GetSMI <GermExposureMonitor.Instance>(); float chance = ((!type.infect_immediately) ? GermExposureMonitor.GetContractionChance(smi.GetResistanceToExposureType(type, -1f)) : 1f); string contractionChance = GameUtil.GetFormattedPercent(chance * 100); text = text + $"\n{name} - {contractionChance}"; } return(text); }
public static void Postfix() { if (Helper.MinionsLoaded) { return; } List <MinionIdentity> minions = Components.LiveMinionIdentities?.Items; if (minions == null || minions.Count == 0) { return; } try { ConfigSettings settings = ConfigReader <ConfigSettings> .GetConfig(); Helper.showLocation = settings == null ? false : settings.ShowLocation; } catch (Exception) { Helper.showLocation = false; } try { foreach (MinionIdentity minion in minions) { GermExposureMonitor.Instance monitor = minion.gameObject.GetSMI <GermExposureMonitor.Instance>(); foreach (GermExposureMonitor.ExposureType exposure in GermExposureMonitor.exposureTypes) { GermExposureMonitor.ExposureState state = monitor.GetExposureState(exposure.germ_id); if (state == GermExposureMonitor.ExposureState.Contracted || state == GermExposureMonitor.ExposureState.Exposed) { Sickness sickness = Db.Get().Sicknesses.Get(exposure.sickness_id); string sicknessName = sickness != null ? sickness.Name : "a disease"; Helper.CreateAndAddNotification(monitor, sicknessName); } } } } catch (Exception) { //Do nothing. Can't be sure why this error occurred, but hopefully will only happen this time. } Helper.MinionsLoaded = true; }
// Called by GermExposureMonitor when a Duplicant encounters germs. internal void InjectDisease(GermExposureMonitor.Instance monitor, Disease disease, int count, Tag source, Sickness.InfectionVector vector) { var sicknesses = Db.Get().Sicknesses; foreach (var exposure in TUNING.GERM_EXPOSURE.TYPES) { if (disease.id == exposure.germ_id && IsExposureValidForTraits(exposure)) { // Null sickness ID for smelled flowers string id = exposure.sickness_id; var sickness = (id == null) ? null : sicknesses.Get(id); if (sickness == null || sickness.infectionVectors.Contains(vector)) { DoInjectDisease(monitor, disease, count, source, new GermExposure( vector, exposure)); } } } }
public void AddExposure(ExposureType exposure_type, float amount) { accumulation.TryGetValue(exposure_type.germ_id, out float value); float num = value + amount; if (num > 1f) { foreach (MinionIdentity item in Components.LiveMinionIdentities.Items) { GermExposureMonitor.Instance sMI = item.GetSMI <GermExposureMonitor.Instance>(); if (sMI.GetExposureState(exposure_type.germ_id) == GermExposureMonitor.ExposureState.Exposed) { GermExposureMonitor.Instance sMI2 = item.GetSMI <GermExposureMonitor.Instance>(); float exposureWeight = sMI2.GetExposureWeight(exposure_type.germ_id); if (exposureWeight > 0f) { exposure_candidates.Add(new WeightedExposure { weight = exposureWeight, monitor = sMI }); } } } while (num > 1f) { num -= 1f; if (exposure_candidates.Count > 0) { WeightedExposure weightedExposure = WeightedRandom.Choose(exposure_candidates, rng); exposure_candidates.Remove(weightedExposure); weightedExposure.monitor.ContractGerms(exposure_type.germ_id); } } } accumulation[exposure_type.germ_id] = num; exposure_candidates.Clear(); }
protected override void OnCompleteWork(Worker worker) { Storage component = GetComponent <Storage>(); component.ConsumeAndGetDisease(GameTags.Water, EspressoMachine.WATER_MASS_PER_USE, out SimUtil.DiseaseInfo disease_info, out float aggregate_temperature); component.ConsumeAndGetDisease(EspressoMachine.INGREDIENT_TAG, EspressoMachine.INGREDIENT_MASS_PER_USE, out SimUtil.DiseaseInfo disease_info2, out aggregate_temperature); GermExposureMonitor.Instance sMI = worker.GetSMI <GermExposureMonitor.Instance>(); if (sMI != null) { sMI.TryInjectDisease(disease_info.idx, disease_info.count, GameTags.Water, Sickness.InfectionVector.Digestion); sMI.TryInjectDisease(disease_info2.idx, disease_info2.count, EspressoMachine.INGREDIENT_TAG, Sickness.InfectionVector.Digestion); } Effects component2 = worker.GetComponent <Effects>(); if (!string.IsNullOrEmpty(specificEffect)) { component2.Add(specificEffect, true); } if (!string.IsNullOrEmpty(trackingEffect)) { component2.Add(trackingEffect, true); } }
public static void Postfix() { if (MinionsLoaded) { return; } List <MinionIdentity> minions = Components.LiveMinionIdentities?.Items; if (minions == null || minions.Count == 0) { return; } try { foreach (MinionIdentity minion in minions) { GermExposureMonitor.Instance monitor = minion.gameObject.GetSMI <GermExposureMonitor.Instance>(); foreach (ExposureType exposure in TUNING.GERM_EXPOSURE.TYPES) { GermExposureMonitor.ExposureState state = monitor.GetExposureState(exposure.germ_id); if (state == GermExposureMonitor.ExposureState.Contracted || state == GermExposureMonitor.ExposureState.Exposed) { Sickness sickness = Db.Get().Sicknesses.Get(exposure.sickness_id); string sicknessName = sickness != null ? sickness.Name : "a disease"; CreateAndAddNotification(monitor, sicknessName, exposure.sickness_id); } } } } catch (Exception) { //Do nothing. Can't be sure why this error occurred, but hopefully will only happen this time. } MinionsLoaded = true; }
// Performs the dirty work of counting germs on a Duplicant. private void DoInjectDisease(GermExposureMonitor.Instance monitor, Disease disease, int count, Tag source, GermExposure ge) { var exposure = ge.Exposure; int threshold = GermExposureTuning.ThresholdsFor(exposure).GetThreshold(ge.Vector); if (threshold > 0 && gameObject != null) { string germ = ge.GermID; var state = monitor.GetExposureState(germ); // Eligible addition to the integrated exposure calculations if (integratedExposure.TryGetValue(ge, out int total)) { total += count; } else { total = count; } #if DEBUG PUtil.LogDebug("{0} has {1:D} germs of {2} by {3} (threshold = {4:D})".F( gameObject.name, count, germ, ge.Vector, threshold)); #endif integratedExposure[ge] = total; // Resistance is required to move the thresholds which is used for tier // calculation float resist = GetResistance(exposure), adjThres = AdjustedThreshold( threshold, resist), tier = total / adjThres; switch (state) { case ExposureState.None: case ExposureState.Contact: // Update location where they encountered the germ monitor.lastDiseaseSources[disease.id] = new DiseaseSourceInfo(source, ge.Vector, GetInfectionChance(ge, total, resist), transform. GetPosition()); if (total > adjThres) { if (exposure.infect_immediately) { // The ultimate evil flag #if DEBUG PUtil.LogDebug("Infecting {0} with {1}".F(gameObject.name, germ)); #endif monitor.InfectImmediately(exposure); } else { // "Exposed to slimelung" monitor.SetExposureState(germ, ExposureState.Exposed); monitor.SetExposureTier(germ, tier); #if DEBUG PUtil.LogDebug("{0} exposed to {1} tier {2:F1}".F(gameObject.name, germ, tier)); #endif } } else if (state == ExposureState.None) { // "Contact with slimelung" monitor.SetExposureState(germ, ExposureState.Contact); } break; case ExposureState.Exposed: // Upgrade the visual tier if (total > threshold && tier > monitor.GetExposureTier(germ)) { monitor.SetExposureTier(germ, tier); #if DEBUG PUtil.LogDebug("{0} exposure of {1} upgraded to {2:F1}".F(gameObject. name, germ, tier)); #endif } break; case ExposureState.Contracted: case ExposureState.Sick: // Already sick break; default: break; } } }
public static void Postfix(string germ_id, GermExposureMonitor.ExposureState exposure_state, GermExposureMonitor.Instance __instance) { if (exposure_state == GermExposureMonitor.ExposureState.Exposed) { ExposureType exposure_type = null; foreach (ExposureType type in TUNING.GERM_EXPOSURE.TYPES) { if (germ_id == type.germ_id) { exposure_type = type; break; } } Sickness sickness = exposure_type?.sickness_id != null?Db.Get().Sicknesses.Get(exposure_type.sickness_id) : null; string sicknessName = sickness != null ? sickness.Name : "a disease"; string text = string.Format(DUPE_EXPOSED_TO_GERMS_POPFX, sicknessName); PopFXManager.Instance.SpawnFX(PopFXManager.Instance.sprite_Negative, text, __instance.gameObject.transform, 3f, true); CreateAndAddNotification(__instance, sicknessName, exposure_type.sickness_id); } }
private bool CreateImmuneInfo() { GermExposureMonitor.Instance sMI = selectedTarget.GetSMI <GermExposureMonitor.Instance>(); if (sMI != null) { immuneSystemPanel.SetTitle(UI.DETAILTABS.DISEASE.CONTRACTION_RATES); immuneSystemPanel.SetLabel("germ_resistance", Db.Get().Attributes.GermResistance.Name + ": " + sMI.GetGermResistance(), DUPLICANTS.ATTRIBUTES.GERMRESISTANCE.DESC); for (int i = 0; i < Db.Get().Diseases.Count; i++) { Disease disease = Db.Get().Diseases[i]; ExposureType exposureTypeForDisease = GameUtil.GetExposureTypeForDisease(disease); Sickness sicknessForDisease = GameUtil.GetSicknessForDisease(disease); bool flag = true; List <string> list = new List <string>(); if (exposureTypeForDisease.required_traits != null && exposureTypeForDisease.required_traits.Count > 0) { for (int j = 0; j < exposureTypeForDisease.required_traits.Count; j++) { if (!selectedTarget.GetComponent <Traits>().HasTrait(exposureTypeForDisease.required_traits[j])) { list.Add(exposureTypeForDisease.required_traits[j]); } } if (list.Count > 0) { flag = false; } } bool flag2 = false; List <string> list2 = new List <string>(); if (exposureTypeForDisease.excluded_effects != null && exposureTypeForDisease.excluded_effects.Count > 0) { for (int k = 0; k < exposureTypeForDisease.excluded_effects.Count; k++) { if (selectedTarget.GetComponent <Effects>().HasEffect(exposureTypeForDisease.excluded_effects[k])) { list2.Add(exposureTypeForDisease.excluded_effects[k]); } } if (list2.Count > 0) { flag2 = true; } } bool flag3 = false; List <string> list3 = new List <string>(); if (exposureTypeForDisease.excluded_traits != null && exposureTypeForDisease.excluded_traits.Count > 0) { for (int l = 0; l < exposureTypeForDisease.excluded_traits.Count; l++) { if (selectedTarget.GetComponent <Traits>().HasTrait(exposureTypeForDisease.excluded_traits[l])) { list3.Add(exposureTypeForDisease.excluded_traits[l]); } } if (list3.Count > 0) { flag3 = true; } } string text = string.Empty; float num; if (!flag) { num = 0f; string text2 = string.Empty; for (int m = 0; m < list.Count; m++) { if (text2 != string.Empty) { text2 += ", "; } text2 += Db.Get().traits.Get(list[m]).Name; } text += string.Format(DUPLICANTS.DISEASES.IMMUNE_FROM_MISSING_REQUIRED_TRAIT, text2); } else if (flag3) { num = 0f; string text3 = string.Empty; for (int n = 0; n < list3.Count; n++) { if (text3 != string.Empty) { text3 += ", "; } text3 += Db.Get().traits.Get(list3[n]).Name; } if (text != string.Empty) { text += "\n"; } text += string.Format(DUPLICANTS.DISEASES.IMMUNE_FROM_HAVING_EXLCLUDED_TRAIT, text3); } else if (flag2) { num = 0f; string text4 = string.Empty; for (int num2 = 0; num2 < list2.Count; num2++) { if (text4 != string.Empty) { text4 += ", "; } text4 += Db.Get().effects.Get(list2[num2]).Name; } if (text != string.Empty) { text += "\n"; } text += string.Format(DUPLICANTS.DISEASES.IMMUNE_FROM_HAVING_EXCLUDED_EFFECT, text4); } else { num = ((!exposureTypeForDisease.infect_immediately) ? GermExposureMonitor.GetContractionChance(sMI.GetResistanceToExposureType(exposureTypeForDisease, 3f)) : 1f); } string arg = (!(text != string.Empty)) ? string.Format(DUPLICANTS.DISEASES.CONTRACTION_PROBABILITY, GameUtil.GetFormattedPercent(num * 100f, GameUtil.TimeSlice.None), selectedTarget.GetProperName(), sicknessForDisease.Name) : text; immuneSystemPanel.SetLabel("disease_" + disease.Id, " • " + disease.Name + ": " + GameUtil.GetFormattedPercent(num * 100f, GameUtil.TimeSlice.None), string.Format(DUPLICANTS.DISEASES.RESISTANCES_PANEL_TOOLTIP, arg, sicknessForDisease.Name)); } return(true); } return(false); }
public static bool Prefix(GermExposureMonitor.Instance __instance) { return(false); }
// When the Duplicant wakes up, check the chances and infect with valid diseases internal void OnSleepFinished(GermExposureMonitor.Instance monitor) { SeededRandom random; // Use the same state as the vanilla game does var inst = GermExposureTracker.Instance; if (inst == null) { random = new SeededRandom(GameClock.Instance.GetCycle()); } else { random = Traverse.Create(inst).GetField <SeededRandom>("rng"); } foreach (var pair in integratedExposure) { var ge = pair.Key; var exposure = ge.Exposure; // Avoid double dipping on zombie spores if (!exposure.infect_immediately && gameObject != null) { string germ = ge.GermID; int total = pair.Value; #if DEBUG PUtil.LogDebug("{0} waking up with {1:D} total exposure to {2} via {3}".F( gameObject.name, total, germ, ge.Vector)); #endif switch (monitor.GetExposureState(germ)) { case ExposureState.Exposed: // Calculate resistance now if (IsExposureValidForTraits(exposure) && random.NextDouble() < GetInfectionChance(ge, total, GetResistance(exposure))) { // Gotcha! #if DEBUG PUtil.LogDebug("Infecting {0} with {1}".F(gameObject.name, germ)); #endif monitor.SetExposureState(germ, ExposureState.Sick); monitor.InfectImmediately(exposure); } else { // Not this time... monitor.SetExposureState(germ, ExposureState.None); } monitor.SetExposureTier(germ, 0.0f); break; case ExposureState.Contracted: // Make them sick to avoid getting stuck here (e.g. if DR was installed // on an existing save) monitor.SetExposureState(germ, ExposureState.Sick); monitor.SetExposureTier(germ, 0.0f); monitor.InfectImmediately(exposure); break; case ExposureState.Sick: // Already sick break; case ExposureState.Contact: // Reset state to none if contact and no exposure monitor.SetExposureState(germ, ExposureState.None); break; default: // None = continue on break; } } } ResetExposure(); }
private void CreateStatusItems() { Func <string, object, string> resolveStringCallback = delegate(string str, object data) { Workable workable3 = (Workable)data; if ((UnityEngine.Object)workable3 != (UnityEngine.Object)null) { str = str.Replace("{Target}", workable3.GetComponent <KSelectable>().GetName()); } return(str); }; Func <string, object, string> resolveStringCallback2 = delegate(string str, object data) { Workable workable2 = (Workable)data; if ((UnityEngine.Object)workable2 != (UnityEngine.Object)null) { str = str.Replace("{Target}", workable2.GetComponent <KSelectable>().GetName()); ComplexFabricatorWorkable complexFabricatorWorkable = workable2 as ComplexFabricatorWorkable; if ((UnityEngine.Object)complexFabricatorWorkable != (UnityEngine.Object)null) { ComplexRecipe currentWorkingOrder = complexFabricatorWorkable.CurrentWorkingOrder; if (currentWorkingOrder != null) { str = str.Replace("{Item}", currentWorkingOrder.FirstResult.ProperName()); } } } return(str); }; BedUnreachable = CreateStatusItem("BedUnreachable", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); BedUnreachable.AddNotification(null, null, null, 0f); DailyRationLimitReached = CreateStatusItem("DailyRationLimitReached", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); DailyRationLimitReached.AddNotification(null, null, null, 0f); HoldingBreath = CreateStatusItem("HoldingBreath", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Hungry = CreateStatusItem("Hungry", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Unhappy = CreateStatusItem("Unhappy", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Unhappy.AddNotification(null, null, null, 0f); NervousBreakdown = CreateStatusItem("NervousBreakdown", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Bad, false, OverlayModes.None.ID, true, 2); NervousBreakdown.AddNotification(null, null, null, 0f); NoRationsAvailable = CreateStatusItem("NoRationsAvailable", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Bad, false, OverlayModes.None.ID, true, 2); PendingPacification = CreateStatusItem("PendingPacification", "DUPLICANTS", "status_item_pending_pacification", StatusItem.IconType.Custom, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); QuarantineAreaUnassigned = CreateStatusItem("QuarantineAreaUnassigned", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); QuarantineAreaUnassigned.AddNotification(null, null, null, 0f); QuarantineAreaUnreachable = CreateStatusItem("QuarantineAreaUnreachable", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); QuarantineAreaUnreachable.AddNotification(null, null, null, 0f); Quarantined = CreateStatusItem("Quarantined", "DUPLICANTS", "status_item_quarantined", StatusItem.IconType.Custom, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); RationsUnreachable = CreateStatusItem("RationsUnreachable", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); RationsUnreachable.AddNotification(null, null, null, 0f); RationsNotPermitted = CreateStatusItem("RationsNotPermitted", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); RationsNotPermitted.AddNotification(null, null, null, 0f); Rotten = CreateStatusItem("Rotten", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Starving = CreateStatusItem("Starving", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Bad, false, OverlayModes.None.ID, true, 2); Starving.AddNotification(null, null, null, 0f); Suffocating = CreateStatusItem("Suffocating", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.DuplicantThreatening, false, OverlayModes.None.ID, true, 2); Suffocating.AddNotification(null, null, null, 0f); Tired = CreateStatusItem("Tired", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Idle = CreateStatusItem("Idle", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Idle.AddNotification(null, null, null, 0f); Pacified = CreateStatusItem("Pacified", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Dead = CreateStatusItem("Dead", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Dead.resolveStringCallback = delegate(string str, object data) { Death death = (Death)data; return(str.Replace("{Death}", death.Name)); }; MoveToSuitNotRequired = CreateStatusItem("MoveToSuitNotRequired", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); DroppingUnusedInventory = CreateStatusItem("DroppingUnusedInventory", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); MovingToSafeArea = CreateStatusItem("MovingToSafeArea", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); ToiletUnreachable = CreateStatusItem("ToiletUnreachable", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); ToiletUnreachable.AddNotification(null, null, null, 0f); NoUsableToilets = CreateStatusItem("NoUsableToilets", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); NoUsableToilets.AddNotification(null, null, null, 0f); NoToilets = CreateStatusItem("NoToilets", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); NoToilets.AddNotification(null, null, null, 0f); BreathingO2 = CreateStatusItem("BreathingO2", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 130); BreathingO2.resolveStringCallback = delegate(string str, object data) { OxygenBreather oxygenBreather2 = (OxygenBreather)data; float averageRate = Game.Instance.accumulators.GetAverageRate(oxygenBreather2.O2Accumulator); return(str.Replace("{ConsumptionRate}", GameUtil.GetFormattedMass(0f - averageRate, GameUtil.TimeSlice.PerSecond, GameUtil.MetricMassFormat.UseThreshold, true, "{0:0.#}"))); }; EmittingCO2 = CreateStatusItem("EmittingCO2", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 130); EmittingCO2.resolveStringCallback = delegate(string str, object data) { OxygenBreather oxygenBreather = (OxygenBreather)data; return(str.Replace("{EmittingRate}", GameUtil.GetFormattedMass(oxygenBreather.CO2EmitRate, GameUtil.TimeSlice.PerSecond, GameUtil.MetricMassFormat.UseThreshold, true, "{0:0.#}"))); }; Vomiting = CreateStatusItem("Vomiting", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Coughing = CreateStatusItem("Coughing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); LowOxygen = CreateStatusItem("LowOxygen", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); LowOxygen.AddNotification(null, null, null, 0f); RedAlert = CreateStatusItem("RedAlert", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Sleeping = CreateStatusItem("Sleeping", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Sleeping.resolveTooltipCallback = delegate(string str, object data) { if (data is SleepChore.StatesInstance) { SleepChore.StatesInstance statesInstance2 = (SleepChore.StatesInstance)data; string stateChangeNoiseSource = statesInstance2.stateChangeNoiseSource; if (!string.IsNullOrEmpty(stateChangeNoiseSource)) { string text5 = DUPLICANTS.STATUSITEMS.SLEEPING.TOOLTIP; text5 = text5.Replace("{Disturber}", stateChangeNoiseSource); str += text5; } } return(str); }; SleepingInterruptedByNoise = CreateStatusItem("SleepingInterruptedByNoise", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); SleepingInterruptedByLight = CreateStatusItem("SleepingInterruptedByLight", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Eating = CreateStatusItem("Eating", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Eating.resolveStringCallback = resolveStringCallback; Digging = CreateStatusItem("Digging", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Cleaning = CreateStatusItem("Cleaning", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Cleaning.resolveStringCallback = resolveStringCallback; PickingUp = CreateStatusItem("PickingUp", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); PickingUp.resolveStringCallback = resolveStringCallback; Mopping = CreateStatusItem("Mopping", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Cooking = CreateStatusItem("Cooking", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Cooking.resolveStringCallback = resolveStringCallback2; Mushing = CreateStatusItem("Mushing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Mushing.resolveStringCallback = resolveStringCallback2; Researching = CreateStatusItem("Researching", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Researching.resolveStringCallback = delegate(string str, object data) { TechInstance activeResearch = Research.Instance.GetActiveResearch(); if (activeResearch != null) { return(str.Replace("{Tech}", activeResearch.tech.Name)); } return(str); }; Tinkering = CreateStatusItem("Tinkering", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Tinkering.resolveStringCallback = delegate(string str, object data) { Tinkerable tinkerable = (Tinkerable)data; if ((UnityEngine.Object)tinkerable != (UnityEngine.Object)null) { return(string.Format(str, tinkerable.tinkerMaterialTag.ProperName())); } return(str); }; Storing = CreateStatusItem("Storing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Storing.resolveStringCallback = delegate(string str, object data) { Workable workable = (Workable)data; if ((UnityEngine.Object)workable != (UnityEngine.Object)null && (UnityEngine.Object)workable.worker != (UnityEngine.Object)null) { KSelectable component = workable.GetComponent <KSelectable>(); if ((bool)component) { str = str.Replace("{Target}", component.GetName()); } Pickupable pickupable = workable.worker.workCompleteData as Pickupable; if ((UnityEngine.Object)workable.worker != (UnityEngine.Object)null && (bool)pickupable) { KSelectable component2 = pickupable.GetComponent <KSelectable>(); if ((bool)component2) { str = str.Replace("{Item}", component2.GetName()); } } } return(str); }; Building = CreateStatusItem("Building", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Building.resolveStringCallback = resolveStringCallback; Equipping = CreateStatusItem("Equipping", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Equipping.resolveStringCallback = resolveStringCallback; WarmingUp = CreateStatusItem("WarmingUp", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); WarmingUp.resolveStringCallback = resolveStringCallback; GeneratingPower = CreateStatusItem("GeneratingPower", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); GeneratingPower.resolveStringCallback = resolveStringCallback; Harvesting = CreateStatusItem("Harvesting", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Harvesting.resolveStringCallback = resolveStringCallback; Uprooting = CreateStatusItem("Uprooting", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Uprooting.resolveStringCallback = resolveStringCallback; Emptying = CreateStatusItem("Emptying", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Emptying.resolveStringCallback = resolveStringCallback; Toggling = CreateStatusItem("Toggling", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Toggling.resolveStringCallback = resolveStringCallback; Deconstructing = CreateStatusItem("Deconstructing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Deconstructing.resolveStringCallback = resolveStringCallback; Disinfecting = CreateStatusItem("Disinfecting", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Disinfecting.resolveStringCallback = resolveStringCallback; Upgrading = CreateStatusItem("Upgrading", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Upgrading.resolveStringCallback = resolveStringCallback; Fabricating = CreateStatusItem("Fabricating", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Fabricating.resolveStringCallback = resolveStringCallback2; Processing = CreateStatusItem("Processing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Processing.resolveStringCallback = resolveStringCallback2; Clearing = CreateStatusItem("Clearing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Clearing.resolveStringCallback = resolveStringCallback; GeneratingPower = CreateStatusItem("GeneratingPower", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); GeneratingPower.resolveStringCallback = resolveStringCallback; Cold = CreateStatusItem("Cold", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Cold.resolveTooltipCallback = delegate(string str, object data) { str = str.Replace("{StressModification}", GameUtil.GetFormattedPercent(Db.Get().effects.Get("ColdAir").SelfModifiers[0].Value, GameUtil.TimeSlice.PerCycle)); float dtu_s2 = ((ExternalTemperatureMonitor.Instance)data).temperatureTransferer.average_kilowatts_exchanged.GetWeightedAverage * 1000f; str = str.Replace("{currentTransferWattage}", GameUtil.GetFormattedHeatEnergyRate(dtu_s2, GameUtil.HeatEnergyFormatterUnit.Automatic)); AttributeInstance attributeInstance3 = ((ExternalTemperatureMonitor.Instance)data).attributes.Get("ThermalConductivityBarrier"); string text3 = "<b>" + attributeInstance3.GetFormattedValue() + "</b>"; for (int j = 0; j != attributeInstance3.Modifiers.Count; j++) { AttributeModifier attributeModifier2 = attributeInstance3.Modifiers[j]; text3 += "\n"; string text4 = text3; text3 = text4 + " • " + attributeModifier2.GetDescription() + " <b>" + attributeModifier2.GetFormattedString(attributeInstance3.gameObject) + "</b>"; } str = str.Replace("{conductivityBarrier}", text3); return(str); }; Hot = CreateStatusItem("Hot", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); Hot.resolveTooltipCallback = delegate(string str, object data) { str = str.Replace("{StressModification}", GameUtil.GetFormattedPercent(Db.Get().effects.Get("WarmAir").SelfModifiers[0].Value, GameUtil.TimeSlice.PerCycle)); float dtu_s = ((ExternalTemperatureMonitor.Instance)data).temperatureTransferer.average_kilowatts_exchanged.GetWeightedAverage * 1000f; str = str.Replace("{currentTransferWattage}", GameUtil.GetFormattedHeatEnergyRate(dtu_s, GameUtil.HeatEnergyFormatterUnit.Automatic)); AttributeInstance attributeInstance2 = ((ExternalTemperatureMonitor.Instance)data).attributes.Get("ThermalConductivityBarrier"); string text = "<b>" + attributeInstance2.GetFormattedValue() + "</b>"; for (int i = 0; i != attributeInstance2.Modifiers.Count; i++) { AttributeModifier attributeModifier = attributeInstance2.Modifiers[i]; text += "\n"; string text2 = text; text = text2 + " • " + attributeModifier.GetDescription() + " <b>" + attributeModifier.GetFormattedString(attributeInstance2.gameObject) + "</b>"; } str = str.Replace("{conductivityBarrier}", text); return(str); }; BodyRegulatingHeating = CreateStatusItem("BodyRegulatingHeating", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); BodyRegulatingHeating.resolveStringCallback = delegate(string str, object data) { WarmBlooded.StatesInstance statesInstance = (WarmBlooded.StatesInstance)data; return(str.Replace("{TempDelta}", GameUtil.GetFormattedTemperature(statesInstance.TemperatureDelta, GameUtil.TimeSlice.PerSecond, GameUtil.TemperatureInterpretation.Relative, true, false))); }; BodyRegulatingCooling = CreateStatusItem("BodyRegulatingCooling", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); BodyRegulatingCooling.resolveStringCallback = BodyRegulatingHeating.resolveStringCallback; EntombedChore = CreateStatusItem("EntombedChore", "DUPLICANTS", "status_item_entombed", StatusItem.IconType.Custom, NotificationType.DuplicantThreatening, false, OverlayModes.None.ID, true, 2); EntombedChore.AddNotification(null, null, null, 0f); EarlyMorning = CreateStatusItem("EarlyMorning", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); NightTime = CreateStatusItem("NightTime", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); PoorDecor = CreateStatusItem("PoorDecor", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); PoorQualityOfLife = CreateStatusItem("PoorQualityOfLife", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); PoorFoodQuality = CreateStatusItem("PoorFoodQuality", DUPLICANTS.STATUSITEMS.POOR_FOOD_QUALITY.NAME, DUPLICANTS.STATUSITEMS.POOR_FOOD_QUALITY.TOOLTIP, string.Empty, StatusItem.IconType.Exclamation, NotificationType.Neutral, false, OverlayModes.None.ID, 2); GoodFoodQuality = CreateStatusItem("GoodFoodQuality", DUPLICANTS.STATUSITEMS.GOOD_FOOD_QUALITY.NAME, DUPLICANTS.STATUSITEMS.GOOD_FOOD_QUALITY.TOOLTIP, string.Empty, StatusItem.IconType.Exclamation, NotificationType.Neutral, false, OverlayModes.None.ID, 2); Arting = CreateStatusItem("Arting", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Arting.resolveStringCallback = resolveStringCallback; SevereWounds = CreateStatusItem("SevereWounds", "DUPLICANTS", "status_item_broken", StatusItem.IconType.Custom, NotificationType.Bad, false, OverlayModes.None.ID, true, 2); SevereWounds.AddNotification(null, null, null, 0f); Incapacitated = CreateStatusItem("Incapacitated", "DUPLICANTS", "status_item_broken", StatusItem.IconType.Custom, NotificationType.DuplicantThreatening, false, OverlayModes.None.ID, true, 2); Incapacitated.AddNotification(null, null, null, 0f); Incapacitated.resolveStringCallback = delegate(string str, object data) { IncapacitationMonitor.Instance instance = (IncapacitationMonitor.Instance)data; float bleedLifeTime = instance.GetBleedLifeTime(instance); str = str.Replace("{CauseOfIncapacitation}", instance.GetCauseOfIncapacitation().Name); return(str.Replace("{TimeUntilDeath}", GameUtil.GetFormattedTime(bleedLifeTime))); }; Relocating = CreateStatusItem("Relocating", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Relocating.resolveStringCallback = resolveStringCallback; Fighting = CreateStatusItem("Fighting", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Bad, false, OverlayModes.None.ID, true, 2); Fighting.AddNotification(null, null, null, 0f); Fleeing = CreateStatusItem("Fleeing", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Bad, false, OverlayModes.None.ID, true, 2); Fleeing.AddNotification(null, null, null, 0f); Stressed = CreateStatusItem("Stressed", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Stressed.AddNotification(null, null, null, 0f); LashingOut = CreateStatusItem("LashingOut", "DUPLICANTS", string.Empty, StatusItem.IconType.Exclamation, NotificationType.Bad, false, OverlayModes.None.ID, true, 2); LashingOut.AddNotification(null, null, null, 0f); LowImmunity = CreateStatusItem("LowImmunity", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.BadMinor, false, OverlayModes.None.ID, true, 2); LowImmunity.AddNotification(null, null, null, 0f); Studying = CreateStatusItem("Studying", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 2); Socializing = CreateStatusItem("Socializing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Good, false, OverlayModes.None.ID, true, 2); Dancing = CreateStatusItem("Dancing", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Good, false, OverlayModes.None.ID, true, 2); Gaming = CreateStatusItem("Gaming", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Good, false, OverlayModes.None.ID, true, 2); Mingling = CreateStatusItem("Mingling", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Good, false, OverlayModes.None.ID, true, 2); ContactWithGerms = CreateStatusItem("ContactWithGerms", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, true, OverlayModes.Disease.ID, true, 2); ContactWithGerms.resolveStringCallback = delegate(string str, object data) { GermExposureMonitor.ExposureStatusData exposureStatusData4 = (GermExposureMonitor.ExposureStatusData)data; string name2 = Db.Get().Sicknesses.Get(exposureStatusData4.exposure_type.sickness_id).Name; str = str.Replace("{Sickness}", name2); return(str); }; ContactWithGerms.statusItemClickCallback = delegate(object data) { GermExposureMonitor.ExposureStatusData exposureStatusData3 = (GermExposureMonitor.ExposureStatusData)data; Vector3 lastExposurePosition2 = exposureStatusData3.owner.GetLastExposurePosition(exposureStatusData3.exposure_type.germ_id); CameraController.Instance.CameraGoTo(lastExposurePosition2, 2f, true); if (OverlayScreen.Instance.mode == OverlayModes.None.ID) { OverlayScreen.Instance.ToggleOverlay(OverlayModes.Disease.ID, true); } }; ExposedToGerms = CreateStatusItem("ExposedToGerms", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, true, OverlayModes.Disease.ID, true, 2); ExposedToGerms.resolveStringCallback = delegate(string str, object data) { GermExposureMonitor.ExposureStatusData exposureStatusData2 = (GermExposureMonitor.ExposureStatusData)data; string name = Db.Get().Sicknesses.Get(exposureStatusData2.exposure_type.sickness_id).Name; AttributeInstance attributeInstance = Db.Get().Attributes.GermResistance.Lookup(exposureStatusData2.owner.gameObject); string lastDiseaseSource = exposureStatusData2.owner.GetLastDiseaseSource(exposureStatusData2.exposure_type.germ_id); GermExposureMonitor.Instance sMI = exposureStatusData2.owner.GetSMI <GermExposureMonitor.Instance>(); float num = (float)exposureStatusData2.exposure_type.base_resistance + GERM_EXPOSURE.EXPOSURE_TIER_RESISTANCE_BONUSES[0]; float totalValue = attributeInstance.GetTotalValue(); float resistanceToExposureType = sMI.GetResistanceToExposureType(exposureStatusData2.exposure_type, -1f); float contractionChance = GermExposureMonitor.GetContractionChance(resistanceToExposureType); float exposureTier = sMI.GetExposureTier(exposureStatusData2.exposure_type.germ_id); float num2 = GERM_EXPOSURE.EXPOSURE_TIER_RESISTANCE_BONUSES[(int)exposureTier - 1] - GERM_EXPOSURE.EXPOSURE_TIER_RESISTANCE_BONUSES[0]; str = str.Replace("{Severity}", DUPLICANTS.STATUSITEMS.EXPOSEDTOGERMS.EXPOSURE_TIERS[(int)exposureTier - 1]); str = str.Replace("{Sickness}", name); str = str.Replace("{Source}", lastDiseaseSource); str = str.Replace("{Base}", GameUtil.GetFormattedSimple(num, GameUtil.TimeSlice.None, null)); str = str.Replace("{Dupe}", GameUtil.GetFormattedSimple(totalValue, GameUtil.TimeSlice.None, null)); str = str.Replace("{Total}", GameUtil.GetFormattedSimple(resistanceToExposureType, GameUtil.TimeSlice.None, null)); str = str.Replace("{ExposureLevelBonus}", GameUtil.GetFormattedSimple(num2, GameUtil.TimeSlice.None, null)); str = str.Replace("{Chance}", GameUtil.GetFormattedPercent(contractionChance * 100f, GameUtil.TimeSlice.None)); return(str); }; ExposedToGerms.statusItemClickCallback = delegate(object data) { GermExposureMonitor.ExposureStatusData exposureStatusData = (GermExposureMonitor.ExposureStatusData)data; Vector3 lastExposurePosition = exposureStatusData.owner.GetLastExposurePosition(exposureStatusData.exposure_type.germ_id); CameraController.Instance.CameraGoTo(lastExposurePosition, 2f, true); if (OverlayScreen.Instance.mode == OverlayModes.None.ID) { OverlayScreen.Instance.ToggleOverlay(OverlayModes.Disease.ID, true); } }; LightWorkEfficiencyBonus = CreateStatusItem("LightWorkEfficiencyBonus", "DUPLICANTS", string.Empty, StatusItem.IconType.Info, NotificationType.Good, false, OverlayModes.None.ID, true, 2); }