/// <summary>
        /// Use this to create or modify a Status Effect.
        /// </summary>
        /// <param name="template">The SL_StatusEffect template.</param>
        /// <returns>The new or existing StatusEffect.</returns>
        public static StatusEffect CreateCustomStatus(SL_StatusEffect template)
        {
            var original = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(template.TargetStatusIdentifier);

            if (!original)
            {
                SL.Log($"CreateCustomStatus - Could not find any status with the Identifier '{template.TargetStatusIdentifier}' (or none was set).");
                return(null);
            }

            var preset = original.GetComponent <EffectPreset>();

            if (!preset && template.NewStatusID < -1 || template.NewStatusID > 0)
            {
                preset = original.gameObject.AddComponent <EffectPreset>();
                At.SetField(preset, "m_StatusEffectID", template.NewStatusID);
            }

            StatusEffect status;

            if (template.TargetStatusIdentifier == template.StatusIdentifier)
            {
                // editing orig status
                if (!OrigStatusEffects.ContainsKey(template.TargetStatusIdentifier))
                {
                    // instantiate and cache original
                    var cached = GameObject.Instantiate(original.gameObject).GetComponent <StatusEffect>();
                    cached.gameObject.SetActive(false);
                    GameObject.DontDestroyOnLoad(cached.gameObject);
                    OrigStatusEffects.Add(template.TargetStatusIdentifier, cached);
                }

                status = original;
            }
            else
            {
                // instantiate original and use that as newEffect
                status = GameObject.Instantiate(original.gameObject).GetComponent <StatusEffect>();
                status.gameObject.SetActive(false);

                // Set Status identifier
                At.SetField(status, "m_identifierName", template.StatusIdentifier);

                if (preset && (template.NewStatusID < -1 || template.NewStatusID > 0))
                {
                    At.SetField(preset, "m_StatusEffectID", template.NewStatusID);
                }

                // Fix localization
                GetStatusLocalization(original, out string name, out string desc);
                SetStatusLocalization(status, name, desc);

                // Fix status data and stack
                At.SetField(status, "m_statusStack", null);
                At.SetField(status, "m_amplifiedStatus", null);
            }

            var gameType = Serializer.GetGameType(template.GetType());

            if (gameType != status.GetType())
            {
                status = (StatusEffect)UnityHelpers.FixComponentType(gameType, status);
            }

            int presetID = status.GetComponent <EffectPreset>()?.PresetID ?? -1;
            var id       = "";

            if (presetID < -1 || presetID > 0)
            {
                id += presetID + "_";
            }
            status.gameObject.name = id + status.IdentifierName;

            // fix RPM_STATUS_EFFECTS dictionary
            if (!References.RPM_STATUS_EFFECTS.ContainsKey(status.IdentifierName))
            {
                References.RPM_STATUS_EFFECTS.Add(status.IdentifierName, status);
            }
            else
            {
                References.RPM_STATUS_EFFECTS[status.IdentifierName] = status;
            }

            // fix RPM_Presets dictionary
            if (template.NewStatusID < -1 || template.NewStatusID > 0)
            {
                if (!References.RPM_EFFECT_PRESETS.ContainsKey(template.NewStatusID))
                {
                    References.RPM_EFFECT_PRESETS.Add(template.NewStatusID, status.GetComponent <EffectPreset>());
                }
                else
                {
                    References.RPM_EFFECT_PRESETS[template.NewStatusID] = status.GetComponent <EffectPreset>();
                }
            }

            // Always do this
            GameObject.DontDestroyOnLoad(status.gameObject);

            return(status);
        }
        /// <summary>
        /// Clones an item prefab and returns the clone to you. Caches the original prefab for other mods or other custom items to reference.
        /// </summary>
        /// <param name="cloneTargetID">The Item ID of the Item you want to clone from</param>
        /// <param name="newID">The new Item ID for your cloned item. Can be the same as the target, will overwrite.</param>
        /// <param name="name">Only used for the gameObject name, not the actual Item Name. This is the name thats used in Debug Menus.</param>
        /// <param name="template">[Optional] If provided, the item component may be changed to match the type of the template if necessary.</param>
        /// <returns>Your cloned Item prefab</returns>
        public static Item CreateCustomItem(int cloneTargetID, int newID, string name, SL_Item template = null)
        {
            Item original = GetOriginalItemPrefab(cloneTargetID);

            if (!original)
            {
                SL.LogError("CustomItems.CreateCustomItem - Error! Could not find the clone target Item ID: " + cloneTargetID);
                return(null);
            }

            Item item;

            original.transform.ResetLocal();

            // modifying an existing item
            if (newID == cloneTargetID)
            {
                // Modifying the original prefab for the first time. Cache it in case someone else wants the true original.
                if (!OrigItemPrefabs.ContainsKey(newID))
                {
                    var cached = GameObject.Instantiate(original.gameObject).GetComponent <Item>();
                    cached.gameObject.SetActive(false);
                    GameObject.DontDestroyOnLoad(cached.gameObject);
                    cached.transform.parent = SL.CloneHolder;
                    OrigItemPrefabs.Add(cached.ItemID, cached);
                }

                // apply to the original item prefab. this ensures direct prefab references to this item reflect the changes.
                item = original;
            }
            else // making a new item
            {
                item = GameObject.Instantiate(original.gameObject).GetComponent <Item>();
                item.gameObject.SetActive(false);
                item.gameObject.name = newID + "_" + name;

                // fix for name and description localization
                SetNameAndDescription(item, original.Name, original.Description);
            }

            if (template != null)
            {
                var gameType = Serializer.GetGameType(template.GetType());
                if (gameType != item.GetType())
                {
                    item = UnityHelpers.FixComponentType(gameType, item) as Item;
                }
            }

            item.ItemID = newID;
            SetItemID(newID, item);

            // Do this so that any changes we make are not destroyed on scene changes.
            // This is needed whether this is a clone or a new item.
            GameObject.DontDestroyOnLoad(item.gameObject);

            item.transform.parent = SL.CloneHolder;
            item.gameObject.SetActive(true);

            return(item);
        }