Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
            /// <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);
            }
Ejemplo n.º 4
0
            /// <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);
            }
Ejemplo n.º 5
0
            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;
            }
Ejemplo n.º 8
0
        // 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;
            }
Ejemplo n.º 12
0
        // 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);
 }
Ejemplo n.º 15
0
 public static bool Prefix(GermExposureMonitor.Instance __instance)
 {
     return(false);
 }
Ejemplo n.º 16
0
        // 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();
        }
Ejemplo n.º 17
0
        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);
        }