Beispiel #1
0
        private static IEnumerator DelayRebuildConfigMenus()
        {
            yield return(new WaitForEndOfFrame());

            GadgetModConfigs.ResetAllConfigMenus();
            yield break;
        }
        private static void BuildModMenu()
        {
            GadgetCore.CoreLogger.Log("Injecting Mod Menu into Main Menu");

            ModMenu = new GameObject("MODMENU");
            ModMenu.SetActive(false);
            ModMenuBackButtonBeam      = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("beamm").gameObject, ModMenu.transform);
            ModMenuBackButtonBeam.name = "beamm";
            ModMenuBackButtonBeam.transform.localScale = new Vector3(30, 0, 1);
            ModMenuBackButtonBeam.transform.position   = new Vector3(0, -13.5f, 1);
            ModMenuBackButtonHolder      = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("BUTTONHOLDER").gameObject, ModMenu.transform);
            ModMenuBackButtonHolder.name = "BUTTONHOLDER";
            ModMenuBackButtonHolder.transform.position = new Vector3(0, -13.5f, 0);
            ModMenuBackButtonHolder.GetComponent <Animation>().RemoveClip("bbbac2");
            ModMenuBackButtonHolder.GetComponent <Animation>().AddClip(BuildModMenuButtonAnimClip(true), "bbbac2");
            ModMenuBackButtonHolder.GetComponent <Animation>().clip = ModMenuBackButtonHolder.GetComponent <Animation>().GetClip("bbbac2");
            ModMenuCanvas = new GameObject("Mod Menu Canvas", typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster), typeof(CanvasGroup)).GetComponent <Canvas>();
            ModMenuCanvas.GetComponent <CanvasGroup>().alpha          = 0;
            ModMenuCanvas.GetComponent <CanvasGroup>().interactable   = false;
            ModMenuCanvas.GetComponent <CanvasGroup>().blocksRaycasts = false;
            ModMenuCanvas.GetComponent <RectTransform>().pivot        = new Vector2(0.5f, 0.5f);
            ModMenuCanvas.renderMode   = RenderMode.ScreenSpaceOverlay;
            ModMenuCanvas.pixelPerfect = true;
            CanvasScaler scaler = ModMenuCanvas.GetComponent <CanvasScaler>();

            scaler.scaleFactor                        = 2;
            scaler.referencePixelsPerUnit             = 100;
            ModConfigMenuText                         = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("txt0").gameObject, ModMenu.transform);
            ModConfigMenuText.name                    = "txt0";
            ModConfigMenuText.transform.localPosition = new Vector3(0, 14, -1);
            Array.ForEach(ModConfigMenuText.GetComponentsInChildren <TextMesh>(), x => { x.text = "MOD CONFIG MENU"; x.anchor = TextAnchor.UpperCenter; });
            GameObject restartRequiredText = UnityEngine.Object.Instantiate(ModConfigMenuText, ModMenu.transform);

            restartRequiredText.SetActive(false);
            restartRequiredText.name = "Restart Required Text";
            restartRequiredText.transform.localPosition = new Vector3(0, -10.5f, -1);
            restartRequiredText.transform.localScale   *= 0.75f;
            Array.ForEach(restartRequiredText.GetComponentsInChildren <TextMesh>(), x => { x.text = "Restart Required!"; x.anchor = TextAnchor.UpperCenter; });
            ModMenuPanel = new GameObject("Panel", typeof(RectTransform), typeof(ModMenuController)).GetComponent <ModMenuController>();
            ModMenuPanel.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
            ModMenuPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.15f, 0.15f);
            ModMenuPanel.GetComponent <RectTransform>().anchorMax = new Vector2(0.85f, 0.85f);
            ModMenuPanel.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            ModMenuPanel.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            ModConfigMenus = new GameObject("Mod Config Menus", typeof(RectTransform)).GetComponent <RectTransform>();
            ModConfigMenus.SetParent(ModMenuCanvas.transform);
            ModConfigMenus.anchorMin = new Vector2(0.15f, 0.15f);
            ModConfigMenus.anchorMax = new Vector2(0.85f, 0.85f);
            ModConfigMenus.offsetMin = Vector2.zero;
            ModConfigMenus.offsetMax = Vector2.zero;
            Image background = new GameObject("Background", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();

            background.transform.SetParent(ModMenuPanel.transform);
            background.rectTransform.anchorMin = new Vector2(0f, 0f);
            background.rectTransform.anchorMax = new Vector2(01f, 1f);
            background.rectTransform.offsetMin = Vector2.zero;
            background.rectTransform.offsetMax = Vector2.zero;
            background.type       = Image.Type.Sliced;
            background.fillCenter = true;
            background.sprite     = BoxSprite;

            ModMenuDescPanel = new GameObject("Mod Desc Panel", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(ScrollRect)).GetComponent <ScrollRect>();
            ModMenuDescPanel.GetComponent <RectTransform>().SetParent(ModMenuPanel.transform);
            ModMenuDescPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.4f, 0.25f);
            ModMenuDescPanel.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            ModMenuDescPanel.GetComponent <RectTransform>().offsetMin = new Vector2(0, 5);
            ModMenuDescPanel.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuDescPanel.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.GetComponent <Image>().fillCenter = true;
            Mask modMenuDescPanelMask = new GameObject("Mask", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <Mask>();

            modMenuDescPanelMask.GetComponent <RectTransform>().SetParent(ModMenuDescPanel.transform);
            modMenuDescPanelMask.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            modMenuDescPanelMask.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            modMenuDescPanelMask.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            modMenuDescPanelMask.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            modMenuDescPanelMask.GetComponent <Image>().sprite            = BoxMask;
            modMenuDescPanelMask.GetComponent <Image>().type       = Image.Type.Sliced;
            modMenuDescPanelMask.GetComponent <Image>().fillCenter = true;
            modMenuDescPanelMask.showMaskGraphic = false;
            RectTransform modMenuDescViewport = new GameObject("Viewport", typeof(RectTransform)).GetComponent <RectTransform>();

            modMenuDescViewport.SetParent(modMenuDescPanelMask.transform);
            modMenuDescViewport.anchorMin = new Vector2(0f, 0f);
            modMenuDescViewport.anchorMax = new Vector2(1f, 1f);
            modMenuDescViewport.offsetMin = new Vector2(10, 10);
            modMenuDescViewport.offsetMax = new Vector2(-10, -10);
            Text modMenuDescText = new GameObject("Description", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text), typeof(ContentSizeFitter)).GetComponent <Text>();

            modMenuDescText.rectTransform.SetParent(modMenuDescViewport);
            modMenuDescText.rectTransform.anchorMin = new Vector2(0f, 0f);
            modMenuDescText.rectTransform.anchorMax = new Vector2(1f, 1f);
            modMenuDescText.rectTransform.offsetMin = Vector2.zero;
            modMenuDescText.rectTransform.offsetMax = Vector2.zero;
            modMenuDescText.rectTransform.pivot     = new Vector2(0.5f, 1f);
            modMenuDescText.font               = ModConfigMenuText.GetComponent <TextMesh>().font;
            modMenuDescText.fontSize           = 12;
            modMenuDescText.horizontalOverflow = HorizontalWrapMode.Wrap;
            modMenuDescText.GetComponent <ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            ModMenuDescPanel.GetComponent <ScrollRect>().content           = modMenuDescText.rectTransform;
            ModMenuDescPanel.GetComponent <ScrollRect>().horizontal        = false;
            ModMenuDescPanel.GetComponent <ScrollRect>().scrollSensitivity = 5;
            ModMenuDescPanel.GetComponent <ScrollRect>().viewport          = modMenuDescViewport;
            ModMenuPanel.descText            = modMenuDescText;
            ModMenuPanel.restartRequiredText = restartRequiredText;
            Image modMenuButtonPanel = new GameObject("Button Panel", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();

            modMenuButtonPanel.GetComponent <RectTransform>().SetParent(ModMenuPanel.transform);
            modMenuButtonPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.4f, 0f);
            modMenuButtonPanel.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 0.25f);
            modMenuButtonPanel.GetComponent <RectTransform>().offsetMin = new Vector2(0, 10);
            modMenuButtonPanel.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -5);
            modMenuButtonPanel.GetComponent <Image>().sprite            = BoxSprite;
            modMenuButtonPanel.GetComponent <Image>().type       = Image.Type.Sliced;
            modMenuButtonPanel.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.enableButton = new GameObject("Enable Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuPanel.enableButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().anchorMax = new Vector2(1f / 3f, 1f);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuPanel.enableButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuPanel.enableButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuPanel.enableButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuPanel.enableButton.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.enableButton.targetGraphic = ModMenuPanel.enableButton.GetComponent <Image>();
            ModMenuPanel.enableButton.onClick.AddListener(ModMenuPanel.EnableButton);
            Text enableButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            enableButtonText.rectTransform.SetParent(ModMenuPanel.enableButton.transform);
            enableButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            enableButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            enableButtonText.rectTransform.offsetMin = Vector2.zero;
            enableButtonText.rectTransform.offsetMax = Vector2.zero;
            enableButtonText.alignment = TextAnchor.MiddleCenter;
            enableButtonText.font      = modMenuDescText.font;
            enableButtonText.fontSize  = 12;
            enableButtonText.text      = "Enable";
            ModMenuPanel.reloadButton  = new GameObject("Reload Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().anchorMin = new Vector2(1f / 3f, 0f);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().anchorMax = new Vector2(2f / 3f, 1f);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuPanel.reloadButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuPanel.reloadButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuPanel.reloadButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuPanel.reloadButton.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.reloadButton.targetGraphic = ModMenuPanel.reloadButton.GetComponent <Image>();
            ModMenuPanel.reloadButton.onClick.AddListener(ModMenuPanel.ReloadButton);
            Text reloadButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            reloadButtonText.rectTransform.SetParent(ModMenuPanel.reloadButton.transform);
            reloadButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            reloadButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            reloadButtonText.rectTransform.offsetMin = Vector2.zero;
            reloadButtonText.rectTransform.offsetMax = Vector2.zero;
            reloadButtonText.alignment = TextAnchor.MiddleCenter;
            reloadButtonText.font      = modMenuDescText.font;
            reloadButtonText.fontSize  = 12;
            reloadButtonText.text      = "Reload";
            ModMenuPanel.configButton  = new GameObject("Config Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuPanel.configButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuPanel.configButton.GetComponent <RectTransform>().anchorMin = new Vector2(2f / 3f, 0f);
            ModMenuPanel.configButton.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            ModMenuPanel.configButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuPanel.configButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuPanel.configButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuPanel.configButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuPanel.configButton.GetComponent <Image>().fillCenter = true;
            ModMenuPanel.configButton.targetGraphic = ModMenuPanel.configButton.GetComponent <Image>();
            ModMenuPanel.configButton.onClick.AddListener(ModMenuPanel.ConfigButton);
            Text configButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            configButtonText.rectTransform.SetParent(ModMenuPanel.configButton.transform);
            configButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            configButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            configButtonText.rectTransform.offsetMin = Vector2.zero;
            configButtonText.rectTransform.offsetMax = Vector2.zero;
            configButtonText.alignment = TextAnchor.MiddleCenter;
            configButtonText.font      = modMenuDescText.font;
            configButtonText.fontSize  = 12;
            configButtonText.text      = "Configure";
            if (GadgetCoreAPI.GetUMFAPI() != null)
            {
                ModMenuPanel.umfConfigButton = new GameObject("UMF Config Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().anchorMin = new Vector2(0.025f, 0.4f);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().anchorMax = new Vector2(0.125f, 0.6f);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().offsetMin = new Vector2(0, 0);
                ModMenuPanel.umfConfigButton.GetComponent <RectTransform>().offsetMax = new Vector2(0, 0);
                ModMenuPanel.umfConfigButton.GetComponent <Image>().sprite            = BoxSprite;
                ModMenuPanel.umfConfigButton.GetComponent <Image>().type       = Image.Type.Sliced;
                ModMenuPanel.umfConfigButton.GetComponent <Image>().fillCenter = true;
                ModMenuPanel.umfConfigButton.targetGraphic = ModMenuPanel.umfConfigButton.GetComponent <Image>();
                ModMenuPanel.umfConfigButton.onClick.AddListener(ModMenuPanel.UMFConfigButton);
                Text umfConfigButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();
                umfConfigButtonText.rectTransform.SetParent(ModMenuPanel.umfConfigButton.transform);
                umfConfigButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
                umfConfigButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
                umfConfigButtonText.rectTransform.offsetMin = Vector2.zero;
                umfConfigButtonText.rectTransform.offsetMax = Vector2.zero;
                umfConfigButtonText.alignment = TextAnchor.MiddleCenter;
                umfConfigButtonText.font      = modMenuDescText.font;
                umfConfigButtonText.fontSize  = 12;
                umfConfigButtonText.text      = "Configure UMF";
            }
            Button configReloadButton = new GameObject("Config Reload Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();

            configReloadButton.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
            configReloadButton.GetComponent <RectTransform>().anchorMin = new Vector2(0.875f, 0.4f);
            configReloadButton.GetComponent <RectTransform>().anchorMax = new Vector2(0.975f, 0.6f);
            configReloadButton.GetComponent <RectTransform>().offsetMin = new Vector2(0, 0);
            configReloadButton.GetComponent <RectTransform>().offsetMax = new Vector2(0, 0);
            configReloadButton.GetComponent <Image>().sprite            = BoxSprite;
            configReloadButton.GetComponent <Image>().type       = Image.Type.Sliced;
            configReloadButton.GetComponent <Image>().fillCenter = true;
            configReloadButton.targetGraphic = configReloadButton.GetComponent <Image>();
            configReloadButton.onClick.AddListener(() =>
            {
                foreach (GadgetInfo gadget in Gadgets.ListAllEnabledGadgetInfos())
                {
                    if (gadget.Attribute.AllowConfigReloading)
                    {
                        gadget.Gadget.ReloadConfig();
                    }
                }
                if (GadgetCore.UMFAPI != null)
                {
                    foreach (string mod in GadgetCore.UMFAPI.GetModNames())
                    {
                        GadgetCore.UMFAPI.SendCommand("cfgReload " + mod);
                    }
                }
                GadgetModConfigs.ResetAllConfigMenus();
            });
            Text configReloadButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            configReloadButtonText.rectTransform.SetParent(configReloadButton.transform);
            configReloadButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            configReloadButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            configReloadButtonText.rectTransform.offsetMin = Vector2.zero;
            configReloadButtonText.rectTransform.offsetMax = Vector2.zero;
            configReloadButtonText.alignment = TextAnchor.MiddleCenter;
            configReloadButtonText.font      = modMenuDescText.font;
            configReloadButtonText.fontSize  = 12;
            configReloadButtonText.text      = "Reload Configs";

            GadgetModConfigs.ConfigMenus.Clear();
        }
Beispiel #3
0
        internal void Build()
        {
            string modInfo = null;

            foreach (GadgetMod mod in GadgetMods.ListAllMods().Where(x => x.LoadedGadgets.Count > 0))
            {
                if (mod.Name == "GadgetCore")
                {
                    modInfo = CoreMod.GadgetCoreMod.GetDesc();
                }
                else if (mod.HasModFile("ModInfo.txt"))
                {
                    using (GadgetModFile infoFile = mod.GetModFile("ModInfo.txt")) modInfo = infoFile.ReadAllText();
                }
                if (string.IsNullOrEmpty(modInfo) || modInfo == "Insert the description for your mod here!")
                {
                    modInfo = "This Gadget mod does not have a ModInfo file.";
                }
                Dictionary <string, string> info = new Dictionary <string, string>
                {
                    ["Name"]         = mod.Name,
                    ["Version"]      = mod.Version.ToString(),
                    ["File Name"]    = Path.GetFileName(mod.ModPath),
                    ["Dependencies"] = mod.ModDependencies.Count > 0 ? mod.ModDependencies.Concat() : "None",
                    ["Gadgets"]      = mod.LoadedGadgets.Select(x => x.Attribute.Name).Concat()
                };
                if (mod.UnloadedGadgets.Count > 0)
                {
                    info.Add("Unloaded/Errored Gadgets", mod.UnloadedGadgets.Select(x => x.Attribute.Name).Concat());
                }
                using (GadgetModFile infoFile = mod.GetModFile("ModInfo.txt"))
                    modEntries.Add(new ModMenuEntry(mod.Name, ModMenuEntryType.GADGET, modInfo, info, mod.LoadedGadgets.ToArray()));
            }
            foreach (GadgetMod mod in GadgetLoader.EmptyMods)
            {
                if (mod.Name == "GadgetCore")
                {
                    modInfo = CoreMod.GadgetCoreMod.GetDesc();
                }
                else if (mod.HasModFile("ModInfo.txt"))
                {
                    using (GadgetModFile infoFile = mod.GetModFile("ModInfo.txt")) modInfo = infoFile.ReadAllText();
                }
                if (string.IsNullOrEmpty(modInfo) || modInfo == "Insert the description for your mod here!")
                {
                    modInfo = "This Gadget mod does not have a ModInfo file.";
                }
                Dictionary <string, string> info = new Dictionary <string, string>
                {
                    ["Name"]         = mod.Name,
                    ["Version"]      = mod.Version.ToString(),
                    ["File Name"]    = Path.GetFileName(mod.ModPath),
                    ["Dependencies"] = mod.ModDependencies.Count > 0 ? mod.ModDependencies.Concat() : "None",
                };
                if (mod.UnloadedGadgets.Count > 0)
                {
                    info.Add("Unloaded/Errored Gadgets", mod.UnloadedGadgets.Select(x => x.Attribute.Name).Concat());
                }
                modEntries.Add(new ModMenuEntry(mod.Name, ModMenuEntryType.EMPTY_GADGET, modInfo, info));
            }
            foreach (GadgetMod mod in GadgetLoader.IncompatibleMods)
            {
                if (mod.Name == "GadgetCore")
                {
                    modInfo = CoreMod.GadgetCoreMod.GetDesc();
                }
                else if (mod.HasModFile("ModInfo.txt"))
                {
                    using (GadgetModFile infoFile = mod.GetModFile("ModInfo.txt")) modInfo = infoFile.ReadAllText();
                }
                if (string.IsNullOrEmpty(modInfo) || modInfo == "Insert the description for your mod here!")
                {
                    modInfo = "This Gadget mod does not have a ModInfo file.";
                }
                Dictionary <string, string> info = new Dictionary <string, string>
                {
                    ["Name"]         = mod.Name,
                    ["Version"]      = mod.Version.ToString(),
                    ["File Name"]    = Path.GetFileName(mod.ModPath),
                    ["Dependencies"] = mod.ModDependencies.Count > 0 ? mod.ModDependencies.Concat() : "None"
                };
                modEntries.Add(new ModMenuEntry(mod.Name, ModMenuEntryType.INCOMPATIBLE_GADGET, modInfo, info));
            }
            foreach (GadgetMod mod in GadgetMods.ListAllMods().Where(x => x.LoadedGadgets.Count == 0))
            {
                if (mod.Name == "GadgetCore")
                {
                    modInfo = CoreMod.GadgetCoreMod.GetDesc();
                }
                else if (mod.HasModFile("ModInfo.txt"))
                {
                    using (GadgetModFile infoFile = mod.GetModFile("ModInfo.txt")) modInfo = infoFile.ReadAllText();
                }
                if (string.IsNullOrEmpty(modInfo) || modInfo == "Insert the description for your mod here!")
                {
                    modInfo = "This Gadget mod does not have a ModInfo file.";
                }
                Dictionary <string, string> info = new Dictionary <string, string>
                {
                    ["Name"]         = mod.Name,
                    ["Version"]      = mod.Version.ToString(),
                    ["File Name"]    = Path.GetFileName(mod.ModPath),
                    ["Dependencies"] = mod.ModDependencies.Count > 0 ? mod.ModDependencies.Concat() : "None",
                };
                if (mod.UnloadedGadgets.Count > 0)
                {
                    info.Add("Unloaded/Errored Gadgets", mod.UnloadedGadgets.Select(x => x.Attribute.Name).Concat());
                }
                modEntries.Add(new ModMenuEntry(mod.Name, ModMenuEntryType.ERRORED_GADGET, modInfo, info));
            }
            foreach (Tuple <string, string> mod in GadgetLoader.ErroredMods)
            {
                if (mod.Item1 == "GadgetCore")
                {
                    modInfo = CoreMod.GadgetCoreMod.GetDesc();
                }
                modInfo = "As there was an error loading this mod, its description could not be loaded.\nThe error that prevented this mod from loading should be in the log.\nYou should report this to the mod author.";
                Dictionary <string, string> info = new Dictionary <string, string>
                {
                    ["Name"]      = mod.Item1,
                    ["File Name"] = Path.GetFileName(mod.Item2)
                };
                modEntries.Add(new ModMenuEntry(mod.Item1, ModMenuEntryType.ERRORED_GADGET, modInfo, info));
            }
            if (GadgetCoreAPI.GetUMFAPI() != null)
            {
                foreach (string mod in GadgetCoreAPI.GetUMFAPI().GetModNames())
                {
                    try
                    {
                        modInfo = File.ReadAllText(GadgetCoreAPI.GetUMFAPI().GetModInfosPath() + "/" + mod + "_v" + GadgetCoreAPI.GetUMFAPI().GetModVersion(mod) + "_ModInfo.txt");
                    }
                    catch (Exception) { }
                    if (string.IsNullOrEmpty(modInfo) || modInfo == "A UMF Mod(umodframework.com) for Roguelands")
                    {
                        modInfo = "This UMF mod does not have a ModInfo file.";
                    }
                    Dictionary <string, string> info = new Dictionary <string, string>()
                    {
                        ["Name"]        = mod,
                        ["Version"]     = GadgetCoreAPI.GetUMFAPI().GetModVersion(mod).ToString(),
                        ["Description"] = GadgetCoreAPI.GetUMFAPI().GetModDescription(mod),
                    };
                    if (GadgetCoreAPI.GetUMFAPI().GetModNamesEnabled().Contains(mod))
                    {
                        modEntries.Add(new ModMenuEntry(mod, ModMenuEntryType.UMF, modInfo, info));
                    }
                    else
                    {
                        modEntries.Add(new ModMenuEntry(mod, ModMenuEntryType.DISABLED_UMF, modInfo, info));
                    }
                    umfModEntries.Add(modEntries[modEntries.Count - 1]);
                }
                foreach (string mod in GadgetCoreAPI.GetUMFAPI().GetModNamesMissingDependencies())
                {
                    try
                    {
                        modInfo = File.ReadAllText(GadgetCoreAPI.GetUMFAPI().GetModInfosPath() + "/" + mod + "_v" + GadgetCoreAPI.GetUMFAPI().GetModVersion(mod) + "_ModInfo.txt");
                    }
                    catch (Exception) { }
                    if (string.IsNullOrEmpty(modInfo) || modInfo == "A UMF Mod(umodframework.com) for Roguelands")
                    {
                        modInfo = "This UMF mod does not have a ModInfo file.";
                    }
                    Dictionary <string, string> info = new Dictionary <string, string>()
                    {
                        ["Name"]        = mod,
                        ["Version"]     = GadgetCoreAPI.GetUMFAPI().GetModVersion(mod).ToString(),
                        ["Description"] = GadgetCoreAPI.GetUMFAPI().GetModDescription(mod),
                    };
                    modEntries.Add(new ModMenuEntry(mod, ModMenuEntryType.INCOMPATIBLE_UMF, modInfo, info));
                }
            }

            int modCount = modEntries.Count + modEntries.Where(x => x.Type == ModMenuEntryType.GADGET).SelectMany(x => x.Gadgets).Count();

            ScrollRect modListScrollView = new GameObject("Scroll View", typeof(RectTransform), typeof(ScrollRect), typeof(CanvasRenderer), typeof(Image)).GetComponent <ScrollRect>();

            modListScrollView.GetComponent <RectTransform>().SetParent(transform);
            modListScrollView.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            modListScrollView.GetComponent <RectTransform>().anchorMax = new Vector2(0.3f, 1f);
            modListScrollView.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            modListScrollView.GetComponent <RectTransform>().offsetMax = new Vector2(0, -10);
            modListScrollView.GetComponent <Image>().sprite            = SceneInjector.BoxSprite;
            modListScrollView.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollView.GetComponent <Image>().fillCenter = true;
            Mask modListScrollViewMask = new GameObject("Mask", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <Mask>();

            modListScrollViewMask.GetComponent <RectTransform>().SetParent(modListScrollView.transform);
            modListScrollViewMask.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            modListScrollViewMask.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            modListScrollViewMask.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            modListScrollViewMask.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            modListScrollViewMask.GetComponent <Image>().sprite            = SceneInjector.BoxMask;
            modListScrollViewMask.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollViewMask.GetComponent <Image>().fillCenter = true;
            modListScrollViewMask.showMaskGraphic = false;
            RectTransform modListViewport = new GameObject("Viewport", typeof(RectTransform)).GetComponent <RectTransform>();

            modListViewport.SetParent(modListScrollViewMask.transform);
            modListViewport.anchorMin = new Vector2(0f, 0f);
            modListViewport.anchorMax = new Vector2(1f, 1f);
            modListViewport.offsetMin = new Vector2(10, 10);
            modListViewport.offsetMax = new Vector2(-10, -10);
            RectTransform modList = new GameObject("ModList", typeof(RectTransform), typeof(ToggleGroup)).GetComponent <RectTransform>();

            modList.SetParent(modListViewport);
            modList.anchorMin = new Vector2(0f, modCount <= 6 ? 0f : (1f - (modCount / 6f)));
            modList.anchorMax = new Vector2(1f, 1f);
            modList.offsetMin = Vector2.zero;
            modList.offsetMax = Vector2.zero;
            Scrollbar modListScrollBar = new GameObject("Scrollbar", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Scrollbar)).GetComponent <Scrollbar>();

            modListScrollBar.GetComponent <RectTransform>().SetParent(modListScrollView.transform);
            modListScrollBar.GetComponent <RectTransform>().anchorMin = new Vector2(1f, 0f);
            modListScrollBar.GetComponent <RectTransform>().anchorMax = new Vector2(1.25f, 1f);
            modListScrollBar.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            modListScrollBar.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            modListScrollBar.GetComponent <Image>().sprite            = SceneInjector.BoxSprite;
            modListScrollBar.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollBar.GetComponent <Image>().fillCenter = true;
            RectTransform modListScrollBarHandle = new GameObject("Handle", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <RectTransform>();

            modListScrollBarHandle.SetParent(modListScrollBar.transform);
            modListScrollBarHandle.anchorMin = new Vector2(0.05f, 0.05f);
            modListScrollBarHandle.anchorMax = new Vector2(0.95f, 0.95f);
            modListScrollBarHandle.offsetMin = Vector2.zero;
            modListScrollBarHandle.offsetMax = Vector2.zero;
            modListScrollBarHandle.GetComponent <Image>().sprite     = SceneInjector.BoxSprite;
            modListScrollBarHandle.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollBarHandle.GetComponent <Image>().fillCenter = true;
            modListScrollBar.targetGraphic = modListScrollBarHandle.GetComponent <Image>();
            modListScrollBar.handleRect    = modListScrollBarHandle;
            modListScrollBar.direction     = Scrollbar.Direction.BottomToTop;
            if (modCount <= 5)
            {
                modListScrollBar.interactable = false;
            }
            modListScrollView.content           = modList;
            modListScrollView.horizontal        = false;
            modListScrollView.scrollSensitivity = 5;
            modListScrollView.movementType      = ScrollRect.MovementType.Clamped;
            modListScrollView.viewport          = modListViewport;
            modListScrollView.verticalScrollbar = modListScrollBar;
            float  entryHeight    = modCount <= 6 ? (1f / 6f) : (1f / modCount);
            Toggle selectedToggle = null;
            int    bonusOffset    = 0;

            for (int i = 0; i < modEntries.Count; i++)
            {
                ModMenuEntry modEntry = modEntries[i];
                if (modEntry.Gadgets.Length > 0)
                {
                    int           gadgetCount  = modEntry.Gadgets.Count();
                    float         gadgetHeight = 1f / (gadgetCount + 1);
                    RectTransform modEntryRect = new GameObject("Gadget-Containing Mod Entry: " + modEntry.Name, typeof(RectTransform), typeof(Toggle), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <RectTransform>();
                    modEntryRect.SetParent(modList);
                    modEntryRect.anchorMin = new Vector2(0f, 1 - ((i + bonusOffset + 1 + gadgetCount) * entryHeight));
                    modEntryRect.anchorMax = new Vector2(1f, 1 - ((i + bonusOffset) * entryHeight));
                    modEntryRect.offsetMin = Vector2.zero;
                    modEntryRect.offsetMax = Vector2.zero;
                    Toggle modToggle   = modEntryRect.GetComponent <Toggle>();
                    Image  modSelected = new GameObject("Selected", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();
                    modSelected.rectTransform.SetParent(modEntryRect);
                    modSelected.rectTransform.anchorMin = new Vector2(0f, 0f);
                    modSelected.rectTransform.anchorMax = new Vector2(1f, 1f);
                    modSelected.rectTransform.offsetMin = Vector2.zero;
                    modSelected.rectTransform.offsetMax = Vector2.zero;
                    modSelected.sprite = SceneInjector.BoxSprite;
                    modSelected.type   = Image.Type.Sliced;
                    Text modLabel = new GameObject("Label", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();
                    modLabel.rectTransform.SetParent(modEntryRect);
                    modLabel.rectTransform.anchorMin = new Vector2(0f, 1f - gadgetHeight);
                    modLabel.rectTransform.anchorMax = new Vector2(1f, 1f);
                    modLabel.rectTransform.offsetMin = new Vector2(10, 10);
                    modLabel.rectTransform.offsetMax = new Vector2(-10, -10);
                    modLabel.font                           = SceneInjector.ModConfigMenuText.GetComponent <TextMesh>().font;
                    modLabel.fontSize                       = 12;
                    modLabel.horizontalOverflow             = HorizontalWrapMode.Overflow;
                    modLabel.verticalOverflow               = VerticalWrapMode.Overflow;
                    modLabel.alignment                      = TextAnchor.MiddleLeft;
                    modToggle.GetComponent <Image>().sprite = SceneInjector.BoxSprite;
                    modToggle.GetComponent <Image>().type   = Image.Type.Sliced;
                    modToggle.transition                    = Selectable.Transition.None;
                    modToggle.isOn                          = i == modIndex && gadgetIndex == -1;
                    modToggle.toggleTransition              = Toggle.ToggleTransition.None;
                    modToggle.graphic                       = modSelected;
                    modToggle.group                         = modList.GetComponent <ToggleGroup>();
                    int toggleIndex = i;
                    if (i == modIndex)
                    {
                        selectedToggle = modToggle;
                    }
                    modToggle.onValueChanged.AddListener((toggled) => { if (toggled)
                                                                        {
                                                                            UpdateInfo(modToggle, toggleIndex); GadgetCoreAPI.CloseDialog();
                                                                        }
                                                         });

                    switch (modEntry.Type)
                    {
                    case ModMenuEntryType.GADGET:
                        modSelected.color = new Color(1f, 1f, 0.5f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(1f, 1f, 0.5f, 0.25f);
                        modLabel.color = new Color(1f, 1f, 1f, 1f);
                        modLabel.text  = modEntry.Name + "\nGadget Mod";
                        break;

                    case ModMenuEntryType.EMPTY_GADGET:
                        modSelected.color = new Color(0.5f, 0.5f, 0.125f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(0.5f, 0.5f, 0.125f, 0.25f);
                        modLabel.color = new Color(1f, 1f, 1f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nEmpty Gadget Mod";
                        break;

                    case ModMenuEntryType.INCOMPATIBLE_GADGET:
                        modSelected.color = new Color(1f, 0.5f, 0f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(1f, 0.5f, 0f, 0.25f);
                        modLabel.color = new Color(1f, 1f, 1f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nIncompatible Gadget Mod";
                        break;

                    case ModMenuEntryType.ERRORED_GADGET:
                        modSelected.color = new Color(1f, 0f, 0f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(1f, 0f, 0f, 0.25f);
                        modLabel.color = new Color(1f, 1f, 1f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nErrored Gadget Mod";
                        break;

                    case ModMenuEntryType.UMF:
                        modSelected.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 0.25f);
                        modLabel.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 1f);
                        modLabel.text  = modEntry.Name + "\nUMF Mod";
                        break;

                    case ModMenuEntryType.DISABLED_UMF:
                        modSelected.color = new Color(69 / 255f, 34 / 255f, 9 / 255f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(69 / 255f, 34 / 255f, 9 / 255f, 0.25f);
                        modLabel.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nDisabled UMF Mod";
                        break;

                    case ModMenuEntryType.INCOMPATIBLE_UMF:
                        modSelected.color = new Color(210 / 255f, 105 / 255f, 30 / 255f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(210 / 255f, 105 / 255f, 30 / 255f, 0.25f);
                        modLabel.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nIncompatible UMF Mod";
                        break;
                    }

                    for (int g = 0; g < gadgetCount; g++)
                    {
                        GadgetInfo    gadget     = modEntry.Gadgets[g];
                        RectTransform gadgetRect = new GameObject("Gadget: " + gadget.Attribute.Name, typeof(RectTransform), typeof(Toggle), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <RectTransform>();
                        gadgetRect.SetParent(modEntryRect);
                        gadgetRect.anchorMin = new Vector2(0f, 1 - ((g + 2) * gadgetHeight));
                        gadgetRect.anchorMax = new Vector2(1f, 1 - ((g + 1) * gadgetHeight));
                        gadgetRect.offsetMin = new Vector2(10f, 10f);
                        gadgetRect.offsetMax = new Vector2(-10f, 10f);
                        Toggle gadgetToggle   = gadgetRect.GetComponent <Toggle>();
                        Image  gadgetSelected = new GameObject("Selected", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();
                        gadgetSelected.rectTransform.SetParent(gadgetRect);
                        gadgetSelected.rectTransform.anchorMin = new Vector2(0f, 0f);
                        gadgetSelected.rectTransform.anchorMax = new Vector2(1f, 1f);
                        gadgetSelected.rectTransform.offsetMin = Vector2.zero;
                        gadgetSelected.rectTransform.offsetMax = Vector2.zero;
                        gadgetSelected.sprite = SceneInjector.BoxSprite;
                        gadgetSelected.type   = Image.Type.Sliced;
                        gadgetSelected.color  = new Color(1f, 1f, 0.5f, 1f);
                        Text gadgetLabel = new GameObject("Label", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();
                        gadgetLabel.rectTransform.SetParent(gadgetRect);
                        gadgetLabel.rectTransform.anchorMin = new Vector2(0f, 0f);
                        gadgetLabel.rectTransform.anchorMax = new Vector2(1f, 1f);
                        gadgetLabel.rectTransform.offsetMin = new Vector2(10, 10);
                        gadgetLabel.rectTransform.offsetMax = new Vector2(-10, -10);
                        gadgetLabel.font                           = SceneInjector.ModConfigMenuText.GetComponent <TextMesh>().font;
                        gadgetLabel.fontSize                       = 12;
                        gadgetLabel.horizontalOverflow             = HorizontalWrapMode.Overflow;
                        gadgetLabel.verticalOverflow               = VerticalWrapMode.Overflow;
                        gadgetLabel.alignment                      = TextAnchor.MiddleLeft;
                        gadgetLabel.text                           = gadget.Attribute.Name + "\n" + (gadget.Gadget.Enabled ? "Enabled" : "Disabled");
                        gadgetLabel.color                          = gadget.Gadget.Enabled ? new Color(1f, 1f, 1f, 1f) : new Color(1f, 1f, 1f, 0.5f);
                        gadgetToggle.GetComponent <Image>().sprite = SceneInjector.BoxSprite;
                        gadgetToggle.GetComponent <Image>().type   = Image.Type.Sliced;
                        gadgetToggle.transition                    = Selectable.Transition.None;
                        gadgetToggle.isOn                          = i == modIndex && g == this.gadgetIndex;
                        gadgetToggle.toggleTransition              = Toggle.ToggleTransition.None;
                        gadgetToggle.graphic                       = gadgetSelected;
                        gadgetToggle.group                         = modList.GetComponent <ToggleGroup>();
                        gadgetToggle.GetComponent <Image>().color  = new Color(1f, 1f, 0.5f, 0.25f);
                        int gadgetIndex = g;
                        gadgetToggle.onValueChanged.AddListener((toggled) => { if (toggled)
                                                                               {
                                                                                   UpdateInfo(modToggle, toggleIndex, gadgetIndex); GadgetCoreAPI.CloseDialog();
                                                                               }
                                                                });
                        bonusOffset++;
                    }
                }
                else
                {
                    RectTransform modEntryRect = new GameObject("Mod Entry: " + modEntry.Name, typeof(RectTransform), typeof(Toggle), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <RectTransform>();
                    modEntryRect.SetParent(modList);
                    modEntryRect.anchorMin = new Vector2(0f, 1 - ((i + bonusOffset + 1) * entryHeight));
                    modEntryRect.anchorMax = new Vector2(1f, 1 - ((i + bonusOffset) * entryHeight));
                    modEntryRect.offsetMin = Vector2.zero;
                    modEntryRect.offsetMax = Vector2.zero;
                    Toggle modToggle   = modEntryRect.GetComponent <Toggle>();
                    Image  modSelected = new GameObject("Selected", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();
                    modSelected.rectTransform.SetParent(modEntryRect);
                    modSelected.rectTransform.anchorMin = new Vector2(0f, 0f);
                    modSelected.rectTransform.anchorMax = new Vector2(1f, 1f);
                    modSelected.rectTransform.offsetMin = Vector2.zero;
                    modSelected.rectTransform.offsetMax = Vector2.zero;
                    modSelected.sprite = SceneInjector.BoxSprite;
                    modSelected.type   = Image.Type.Sliced;
                    Text modLabel = new GameObject("Label", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();
                    modLabel.rectTransform.SetParent(modEntryRect);
                    modLabel.rectTransform.anchorMin = new Vector2(0f, 0f);
                    modLabel.rectTransform.anchorMax = new Vector2(1f, 1f);
                    modLabel.rectTransform.offsetMin = new Vector2(10, 10);
                    modLabel.rectTransform.offsetMax = new Vector2(-10, -10);
                    modLabel.font                           = SceneInjector.ModConfigMenuText.GetComponent <TextMesh>().font;
                    modLabel.fontSize                       = 12;
                    modLabel.horizontalOverflow             = HorizontalWrapMode.Overflow;
                    modLabel.verticalOverflow               = VerticalWrapMode.Overflow;
                    modLabel.alignment                      = TextAnchor.MiddleLeft;
                    modToggle.GetComponent <Image>().sprite = SceneInjector.BoxSprite;
                    modToggle.GetComponent <Image>().type   = Image.Type.Sliced;
                    modToggle.transition                    = Selectable.Transition.None;
                    modToggle.isOn                          = i == modIndex;
                    modToggle.toggleTransition              = Toggle.ToggleTransition.None;
                    modToggle.graphic                       = modSelected;
                    modToggle.group                         = modList.GetComponent <ToggleGroup>();
                    int toggleIndex = i;
                    if (i == modIndex)
                    {
                        selectedToggle = modToggle;
                    }
                    modToggle.onValueChanged.AddListener((toggled) => { if (toggled)
                                                                        {
                                                                            UpdateInfo(modToggle, toggleIndex); GadgetCoreAPI.CloseDialog();
                                                                        }
                                                         });

                    switch (modEntry.Type)
                    {
                    case ModMenuEntryType.EMPTY_GADGET:
                        modSelected.color = new Color(0.5f, 0.5f, 0.125f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(0.5f, 0.5f, 0.125f, 0.25f);
                        modLabel.color = new Color(1f, 1f, 1f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nEmpty Gadget Mod";
                        break;

                    case ModMenuEntryType.INCOMPATIBLE_GADGET:
                        modSelected.color = new Color(1f, 0.5f, 0f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(1f, 0.5f, 0f, 0.25f);
                        modLabel.color = new Color(1f, 1f, 1f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nIncompatible Gadget Mod";
                        break;

                    case ModMenuEntryType.ERRORED_GADGET:
                        modSelected.color = new Color(1f, 0f, 0f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(1f, 0f, 0f, 0.25f);
                        modLabel.color = new Color(1f, 1f, 1f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nErrored Gadget Mod";
                        break;

                    case ModMenuEntryType.UMF:
                        modSelected.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 0.25f);
                        modLabel.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 1f);
                        modLabel.text  = modEntry.Name + "\nUMF Mod";
                        break;

                    case ModMenuEntryType.DISABLED_UMF:
                        modSelected.color = new Color(69 / 255f, 34 / 255f, 9 / 255f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(69 / 255f, 34 / 255f, 9 / 255f, 0.25f);
                        modLabel.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nDisabled UMF Mod";
                        break;

                    case ModMenuEntryType.INCOMPATIBLE_UMF:
                        modSelected.color = new Color(210 / 255f, 105 / 255f, 30 / 255f, 1f);
                        modToggle.GetComponent <Image>().color = new Color(210 / 255f, 105 / 255f, 30 / 255f, 0.25f);
                        modLabel.color = new Color(139 / 255f, 69 / 255f, 19 / 255f, 0.5f);
                        modLabel.text  = modEntry.Name + "\nIncompatible UMF Mod";
                        break;
                    }
                }
            }

            modListScrollView.GetComponent <RectTransform>().localScale = Vector3.one;
            if (scrollPositionCache >= 0)
            {
                modListScrollView.verticalNormalizedPosition = 1 - (scrollPositionCache / (modList.anchorMax.y - modList.anchorMin.y));
            }
            scrollPositionCache = -1;

            if (GadgetModConfigs.GetConfigMenuObject(0) != null)
            {
                GadgetModConfigs.ResetAllConfigMenus();
            }
            else
            {
                GadgetModConfigs.BuildConfigMenus(SceneInjector.ModConfigMenus);
            }

            if (modCount > 0)
            {
                UpdateInfo(selectedToggle, modIndex, gadgetIndex);
            }
        }
        private static void BuildModMenu()
        {
            ModMenu = new GameObject("MODMENU");
            ModMenu.SetActive(false);
            ModMenuBackButtonBeam      = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("beamm").gameObject, ModMenu.transform);
            ModMenuBackButtonBeam.name = "beamm";
            ModMenuBackButtonBeam.transform.localScale = new Vector3(30, 0, 1);
            ModMenuBackButtonBeam.transform.position   = new Vector3(0, -13.5f, 1);
            ModMenuBackButtonHolder      = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("BUTTONHOLDER").gameObject, ModMenu.transform);
            ModMenuBackButtonHolder.name = "BUTTONHOLDER";
            ModMenuBackButtonHolder.transform.position = new Vector3(0, -13.5f, 0);
            ModMenuBackButtonHolder.GetComponent <Animation>().RemoveClip("bbbac2");
            ModMenuBackButtonHolder.GetComponent <Animation>().AddClip(BuildModMenuButtonAnimClip(true), "bbbac2");
            ModMenuBackButtonHolder.GetComponent <Animation>().clip = ModMenuBackButtonHolder.GetComponent <Animation>().GetClip("bbbac2");
            ModMenuCanvas = new GameObject("Mod Menu Canvas", typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster), typeof(CanvasGroup)).GetComponent <Canvas>();
            ModMenuCanvas.GetComponent <CanvasGroup>().alpha          = 0;
            ModMenuCanvas.GetComponent <CanvasGroup>().interactable   = false;
            ModMenuCanvas.GetComponent <CanvasGroup>().blocksRaycasts = false;
            ModMenuCanvas.GetComponent <RectTransform>().pivot        = new Vector2(0.5f, 0.5f);
            ModMenuCanvas.renderMode   = RenderMode.ScreenSpaceOverlay;
            ModMenuCanvas.pixelPerfect = true;
            CanvasScaler scaler = ModMenuCanvas.GetComponent <CanvasScaler>();

            scaler.scaleFactor                        = 2;
            scaler.referencePixelsPerUnit             = 100;
            ModConfigMenuText                         = UnityEngine.Object.Instantiate(InstanceTracker.Menuu.menuOptions.transform.Find("txt0").gameObject, ModMenu.transform);
            ModConfigMenuText.name                    = "txt0";
            ModConfigMenuText.transform.localPosition = new Vector3(0, 14, -1);
            Array.ForEach(ModConfigMenuText.GetComponentsInChildren <TextMesh>(), x => { x.text = "MOD CONFIG MENU"; x.anchor = TextAnchor.UpperCenter; });
            GameObject restartRequiredText = UnityEngine.Object.Instantiate(ModConfigMenuText, ModMenu.transform);

            restartRequiredText.SetActive(false);
            restartRequiredText.name = "Restart Required Text";
            restartRequiredText.transform.localPosition = new Vector3(0, -10.5f, -1);
            restartRequiredText.transform.localScale   *= 0.75f;
            Array.ForEach(restartRequiredText.GetComponentsInChildren <TextMesh>(), x => { x.text = "Restart Required!"; x.anchor = TextAnchor.UpperCenter; });
            ModMenuPanel = new GameObject("Panel", typeof(RectTransform)).GetComponent <RectTransform>();
            ModMenuPanel.SetParent(ModMenuCanvas.transform);
            ModMenuPanel.anchorMin = new Vector2(0.15f, 0.15f);
            ModMenuPanel.anchorMax = new Vector2(0.85f, 0.85f);
            ModMenuPanel.offsetMin = Vector2.zero;
            ModMenuPanel.offsetMax = Vector2.zero;
            ModConfigMenus         = new GameObject("Mod Config Menus", typeof(RectTransform)).GetComponent <RectTransform>();
            ModConfigMenus.SetParent(ModMenuCanvas.transform);
            ModConfigMenus.anchorMin = new Vector2(0.15f, 0.15f);
            ModConfigMenus.anchorMax = new Vector2(0.85f, 0.85f);
            ModConfigMenus.offsetMin = Vector2.zero;
            ModConfigMenus.offsetMax = Vector2.zero;
            Image background = new GameObject("Background", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();

            background.transform.SetParent(ModMenuPanel);
            background.rectTransform.anchorMin = new Vector2(0f, 0f);
            background.rectTransform.anchorMax = new Vector2(01f, 1f);
            background.rectTransform.offsetMin = Vector2.zero;
            background.rectTransform.offsetMax = Vector2.zero;
            background.type       = Image.Type.Sliced;
            background.fillCenter = true;
            Texture2D boxTex = GadgetCoreAPI.LoadTexture2D("boxsprite.png");

            boxTex.filterMode = FilterMode.Point;
            Texture2D boxMaskTex = GadgetCoreAPI.LoadTexture2D("boxmask.png");

            boxMaskTex.filterMode = FilterMode.Point;
            Texture2D barTex = GadgetCoreAPI.LoadTexture2D("barsprite.png");

            barTex.filterMode = FilterMode.Point;
            BoxSprite         = Sprite.Create(boxTex, new Rect(0, 0, boxTex.width, boxTex.height), new Vector2(0.5f, 0.5f), 100, 1, SpriteMeshType.Tight, new Vector4(15, 15, 15, 15));
            BoxMask           = Sprite.Create(boxMaskTex, new Rect(0, 0, boxMaskTex.width, boxMaskTex.height), new Vector2(0.5f, 0.5f), 100, 1, SpriteMeshType.Tight, new Vector4(15, 15, 15, 15));
            BarSprite         = Sprite.Create(barTex, new Rect(0, 0, barTex.width, barTex.height), new Vector2(0.5f, 0.5f), 100, 1, SpriteMeshType.Tight, new Vector4(1, 1, 1, 1));
            background.sprite = BoxSprite;

            EventSystem           eventSystem = new GameObject("EventSystem", typeof(EventSystem), typeof(StandaloneInputModule)).GetComponent <EventSystem>();
            StandaloneInputModule inputModule = eventSystem.GetComponent <StandaloneInputModule>();

            inputModule.horizontalAxis = "Horizontal1";
            inputModule.verticalAxis   = "Vertical1";
            inputModule.submitButton   = "Jump";
            inputModule.cancelButton   = "Cancel";

            GadgetModConfigs.BuildConfigMenus(ModConfigMenus);

            ModMenuDescPanel = new GameObject("Mod Desc Panel", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(ModDescPanelController), typeof(ScrollRect)).GetComponent <ModDescPanelController>();
            ModMenuDescPanel.GetComponent <RectTransform>().SetParent(ModMenuPanel);
            ModMenuDescPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.4f, 0.25f);
            ModMenuDescPanel.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            ModMenuDescPanel.GetComponent <RectTransform>().offsetMin = new Vector2(0, 5);
            ModMenuDescPanel.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuDescPanel.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.GetComponent <Image>().fillCenter = true;
            Mask modMenuDescPanelMask = new GameObject("Mask", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <Mask>();

            modMenuDescPanelMask.GetComponent <RectTransform>().SetParent(ModMenuDescPanel.transform);
            modMenuDescPanelMask.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            modMenuDescPanelMask.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            modMenuDescPanelMask.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            modMenuDescPanelMask.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            modMenuDescPanelMask.GetComponent <Image>().sprite            = BoxMask;
            modMenuDescPanelMask.GetComponent <Image>().type       = Image.Type.Sliced;
            modMenuDescPanelMask.GetComponent <Image>().fillCenter = true;
            modMenuDescPanelMask.showMaskGraphic = false;
            RectTransform modMenuDescViewport = new GameObject("Viewport", typeof(RectTransform)).GetComponent <RectTransform>();

            modMenuDescViewport.SetParent(modMenuDescPanelMask.transform);
            modMenuDescViewport.anchorMin = new Vector2(0f, 0f);
            modMenuDescViewport.anchorMax = new Vector2(1f, 1f);
            modMenuDescViewport.offsetMin = new Vector2(10, 10);
            modMenuDescViewport.offsetMax = new Vector2(-10, -10);
            Text modMenuDescText = new GameObject("Description", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text), typeof(ContentSizeFitter)).GetComponent <Text>();

            modMenuDescText.rectTransform.SetParent(modMenuDescViewport);
            modMenuDescText.rectTransform.anchorMin = new Vector2(0f, 0f);
            modMenuDescText.rectTransform.anchorMax = new Vector2(1f, 1f);
            modMenuDescText.rectTransform.offsetMin = Vector2.zero;
            modMenuDescText.rectTransform.offsetMax = Vector2.zero;
            modMenuDescText.rectTransform.pivot     = new Vector2(0.5f, 1f);
            modMenuDescText.font               = ModConfigMenuText.GetComponent <TextMesh>().font;
            modMenuDescText.fontSize           = 12;
            modMenuDescText.horizontalOverflow = HorizontalWrapMode.Wrap;
            modMenuDescText.GetComponent <ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            ModMenuDescPanel.GetComponent <ScrollRect>().content           = modMenuDescText.rectTransform;
            ModMenuDescPanel.GetComponent <ScrollRect>().horizontal        = false;
            ModMenuDescPanel.GetComponent <ScrollRect>().scrollSensitivity = 5;
            ModMenuDescPanel.GetComponent <ScrollRect>().viewport          = modMenuDescViewport;
            ModMenuDescPanel.descText            = modMenuDescText;
            ModMenuDescPanel.restartRequiredText = restartRequiredText;
            Image modMenuButtonPanel = new GameObject("Button Panel", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();

            modMenuButtonPanel.GetComponent <RectTransform>().SetParent(ModMenuPanel);
            modMenuButtonPanel.GetComponent <RectTransform>().anchorMin = new Vector2(0.4f, 0f);
            modMenuButtonPanel.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 0.25f);
            modMenuButtonPanel.GetComponent <RectTransform>().offsetMin = new Vector2(0, 10);
            modMenuButtonPanel.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -5);
            modMenuButtonPanel.GetComponent <Image>().sprite            = BoxSprite;
            modMenuButtonPanel.GetComponent <Image>().type       = Image.Type.Sliced;
            modMenuButtonPanel.GetComponent <Image>().fillCenter = true;
            ModMenuDescPanel.configButton = new GameObject("Config Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuDescPanel.configButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuDescPanel.configButton.GetComponent <RectTransform>().anchorMin = new Vector2(2f / 3f, 0f);
            ModMenuDescPanel.configButton.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            ModMenuDescPanel.configButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuDescPanel.configButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuDescPanel.configButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.configButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.configButton.GetComponent <Image>().fillCenter = true;
            ModMenuDescPanel.configButton.targetGraphic = ModMenuDescPanel.configButton.GetComponent <Image>();
            ModMenuDescPanel.configButton.onClick.AddListener(ModMenuDescPanel.ConfigButton);
            Text configButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            configButtonText.rectTransform.SetParent(ModMenuDescPanel.configButton.transform);
            configButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            configButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            configButtonText.rectTransform.offsetMin = Vector2.zero;
            configButtonText.rectTransform.offsetMax = Vector2.zero;
            configButtonText.alignment       = TextAnchor.MiddleCenter;
            configButtonText.font            = modMenuDescText.font;
            configButtonText.fontSize        = 12;
            configButtonText.text            = "Configure";
            ModMenuDescPanel.umfConfigButton = new GameObject("UMF Config Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuDescPanel.umfConfigButton.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
            ModMenuDescPanel.umfConfigButton.GetComponent <RectTransform>().anchorMin = new Vector2(0.025f, 0.4f);
            ModMenuDescPanel.umfConfigButton.GetComponent <RectTransform>().anchorMax = new Vector2(0.125f, 0.6f);
            ModMenuDescPanel.umfConfigButton.GetComponent <RectTransform>().offsetMin = new Vector2(0, 0);
            ModMenuDescPanel.umfConfigButton.GetComponent <RectTransform>().offsetMax = new Vector2(0, 0);
            ModMenuDescPanel.umfConfigButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.umfConfigButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.umfConfigButton.GetComponent <Image>().fillCenter = true;
            ModMenuDescPanel.umfConfigButton.targetGraphic = ModMenuDescPanel.umfConfigButton.GetComponent <Image>();
            ModMenuDescPanel.umfConfigButton.onClick.AddListener(ModMenuDescPanel.UMFConfigButton);
            Text umfConfigButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            umfConfigButtonText.rectTransform.SetParent(ModMenuDescPanel.umfConfigButton.transform);
            umfConfigButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            umfConfigButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            umfConfigButtonText.rectTransform.offsetMin = Vector2.zero;
            umfConfigButtonText.rectTransform.offsetMax = Vector2.zero;
            umfConfigButtonText.alignment = TextAnchor.MiddleCenter;
            umfConfigButtonText.font      = modMenuDescText.font;
            umfConfigButtonText.fontSize  = 12;
            umfConfigButtonText.text      = "Configure UMF";
            Button configReloadButton = new GameObject("Config Reload Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();

            configReloadButton.GetComponent <RectTransform>().SetParent(ModMenuCanvas.transform);
            configReloadButton.GetComponent <RectTransform>().anchorMin = new Vector2(0.875f, 0.4f);
            configReloadButton.GetComponent <RectTransform>().anchorMax = new Vector2(0.975f, 0.6f);
            configReloadButton.GetComponent <RectTransform>().offsetMin = new Vector2(0, 0);
            configReloadButton.GetComponent <RectTransform>().offsetMax = new Vector2(0, 0);
            configReloadButton.GetComponent <Image>().sprite            = BoxSprite;
            configReloadButton.GetComponent <Image>().type       = Image.Type.Sliced;
            configReloadButton.GetComponent <Image>().fillCenter = true;
            configReloadButton.targetGraphic = configReloadButton.GetComponent <Image>();
            configReloadButton.onClick.AddListener(() =>
            {
                foreach (string mod in UMFData.ModNames)
                {
                    UMFGUI.SendCommand("cfgReload " + mod);
                }
                GadgetModConfigs.ResetAllConfigMenus();
            });
            Text configReloadButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            configReloadButtonText.rectTransform.SetParent(configReloadButton.transform);
            configReloadButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            configReloadButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            configReloadButtonText.rectTransform.offsetMin = Vector2.zero;
            configReloadButtonText.rectTransform.offsetMax = Vector2.zero;
            configReloadButtonText.alignment = TextAnchor.MiddleCenter;
            configReloadButtonText.font      = modMenuDescText.font;
            configReloadButtonText.fontSize  = 12;
            configReloadButtonText.text      = "Reload Configs";
            ModMenuDescPanel.enableUMFButton = new GameObject("Enable UMF Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuDescPanel.enableUMFButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuDescPanel.enableUMFButton.GetComponent <RectTransform>().anchorMin = new Vector2(1f / 3f, 0f);
            ModMenuDescPanel.enableUMFButton.GetComponent <RectTransform>().anchorMax = new Vector2(2f / 3f, 1f);
            ModMenuDescPanel.enableUMFButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuDescPanel.enableUMFButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuDescPanel.enableUMFButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.enableUMFButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.enableUMFButton.GetComponent <Image>().fillCenter = true;
            ModMenuDescPanel.enableUMFButton.targetGraphic = ModMenuDescPanel.enableUMFButton.GetComponent <Image>();
            ModMenuDescPanel.enableUMFButton.onClick.AddListener(ModMenuDescPanel.EnableUMFButton);
            Text enableUMFButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            enableUMFButtonText.rectTransform.SetParent(ModMenuDescPanel.enableUMFButton.transform);
            enableUMFButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            enableUMFButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            enableUMFButtonText.rectTransform.offsetMin = Vector2.zero;
            enableUMFButtonText.rectTransform.offsetMax = Vector2.zero;
            enableUMFButtonText.alignment = TextAnchor.MiddleCenter;
            enableUMFButtonText.font      = modMenuDescText.font;
            enableUMFButtonText.material  = configButtonText.font.material;
            enableUMFButtonText.fontSize  = 12;
            enableUMFButtonText.text      = "Enable Mod";
            ModMenuDescPanel.enableButton = new GameObject("Enable UMF Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuDescPanel.enableButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuDescPanel.enableButton.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            ModMenuDescPanel.enableButton.GetComponent <RectTransform>().anchorMax = new Vector2(1f / 3f, 1f);
            ModMenuDescPanel.enableButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            ModMenuDescPanel.enableButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, -10);
            ModMenuDescPanel.enableButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.enableButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.enableButton.GetComponent <Image>().fillCenter = true;
            ModMenuDescPanel.enableButton.targetGraphic = ModMenuDescPanel.enableButton.GetComponent <Image>();
            ModMenuDescPanel.enableButton.onClick.AddListener(ModMenuDescPanel.EnableButton);
            Text enableButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            enableButtonText.rectTransform.SetParent(ModMenuDescPanel.enableButton.transform);
            enableButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            enableButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            enableButtonText.rectTransform.offsetMin = Vector2.zero;
            enableButtonText.rectTransform.offsetMax = Vector2.zero;
            enableButtonText.alignment    = TextAnchor.MiddleCenter;
            enableButtonText.font         = modMenuDescText.font;
            enableButtonText.fontSize     = 12;
            enableButtonText.text         = "Enable Gadget";
            ModMenuDescPanel.unpackButton = new GameObject("Unpack Button", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button)).GetComponent <Button>();
            ModMenuDescPanel.unpackButton.GetComponent <RectTransform>().SetParent(modMenuButtonPanel.transform);
            ModMenuDescPanel.unpackButton.GetComponent <RectTransform>().anchorMin = new Vector2(2f / 3f, 1f);
            ModMenuDescPanel.unpackButton.GetComponent <RectTransform>().anchorMax = new Vector2(1, 2f);
            ModMenuDescPanel.unpackButton.GetComponent <RectTransform>().offsetMin = new Vector2(10, 20);
            ModMenuDescPanel.unpackButton.GetComponent <RectTransform>().offsetMax = new Vector2(-10, 0);
            ModMenuDescPanel.unpackButton.GetComponent <Image>().sprite            = BoxSprite;
            ModMenuDescPanel.unpackButton.GetComponent <Image>().type       = Image.Type.Sliced;
            ModMenuDescPanel.unpackButton.GetComponent <Image>().fillCenter = true;
            ModMenuDescPanel.unpackButton.targetGraphic = ModMenuDescPanel.unpackButton.GetComponent <Image>();
            ModMenuDescPanel.unpackButton.onClick.AddListener(ModMenuDescPanel.UnpackButton);
            Text unpackButtonText = new GameObject("Text", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();

            unpackButtonText.rectTransform.SetParent(ModMenuDescPanel.unpackButton.transform);
            unpackButtonText.rectTransform.anchorMin = new Vector2(0f, 0f);
            unpackButtonText.rectTransform.anchorMax = new Vector2(1f, 1f);
            unpackButtonText.rectTransform.offsetMin = Vector2.zero;
            unpackButtonText.rectTransform.offsetMax = Vector2.zero;
            unpackButtonText.alignment = TextAnchor.MiddleCenter;
            unpackButtonText.font      = modMenuDescText.font;
            unpackButtonText.fontSize  = 12;
            unpackButtonText.text      = "Unpack Mod";

            GadgetModInfo[] gadgetMods           = GadgetMods.ListAllModInfos();
            string[]        allMods              = gadgetMods.Select(x => x.Attribute.Name).Concat(GadgetCore.nonGadgetMods).Concat(GadgetCore.disabledMods).Concat(GadgetCore.incompatibleMods).Concat(GadgetCore.packedMods).ToArray();
            int             gadgetModCount       = GadgetMods.CountMods();
            int             normalModCount       = GadgetCore.nonGadgetMods.Count;
            int             disabledModCount     = GadgetCore.disabledMods.Count;
            int             incompatibleModCount = GadgetCore.incompatibleMods.Count;
            ScrollRect      modListScrollView    = new GameObject("Scroll View", typeof(RectTransform), typeof(ScrollRect), typeof(CanvasRenderer), typeof(Image)).GetComponent <ScrollRect>();

            modListScrollView.GetComponent <RectTransform>().SetParent(ModMenuPanel);
            modListScrollView.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            modListScrollView.GetComponent <RectTransform>().anchorMax = new Vector2(0.3f, 1f);
            modListScrollView.GetComponent <RectTransform>().offsetMin = new Vector2(10, 10);
            modListScrollView.GetComponent <RectTransform>().offsetMax = new Vector2(0, -10);
            modListScrollView.GetComponent <Image>().sprite            = BoxSprite;
            modListScrollView.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollView.GetComponent <Image>().fillCenter = true;
            Mask modListScrollViewMask = new GameObject("Mask", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <Mask>();

            modListScrollViewMask.GetComponent <RectTransform>().SetParent(modListScrollView.transform);
            modListScrollViewMask.GetComponent <RectTransform>().anchorMin = new Vector2(0f, 0f);
            modListScrollViewMask.GetComponent <RectTransform>().anchorMax = new Vector2(1f, 1f);
            modListScrollViewMask.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            modListScrollViewMask.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            modListScrollViewMask.GetComponent <Image>().sprite            = BoxMask;
            modListScrollViewMask.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollViewMask.GetComponent <Image>().fillCenter = true;
            modListScrollViewMask.showMaskGraphic = false;
            RectTransform modListViewport = new GameObject("Viewport", typeof(RectTransform)).GetComponent <RectTransform>();

            modListViewport.SetParent(modListScrollViewMask.transform);
            modListViewport.anchorMin = new Vector2(0f, 0f);
            modListViewport.anchorMax = new Vector2(1f, 1f);
            modListViewport.offsetMin = new Vector2(10, 10);
            modListViewport.offsetMax = new Vector2(-10, -10);
            RectTransform modList = new GameObject("ModList", typeof(RectTransform), typeof(ToggleGroup)).GetComponent <RectTransform>();

            modList.SetParent(modListViewport);
            modList.anchorMin = new Vector2(0f, allMods.Length <= 6 ? 0f : (1f - (allMods.Length / 6f)));
            modList.anchorMax = new Vector2(1f, 1f);
            modList.offsetMin = Vector2.zero;
            modList.offsetMax = Vector2.zero;
            Scrollbar modListScrollBar = new GameObject("Scrollbar", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Scrollbar)).GetComponent <Scrollbar>();

            modListScrollBar.GetComponent <RectTransform>().SetParent(modListScrollView.transform);
            modListScrollBar.GetComponent <RectTransform>().anchorMin = new Vector2(1f, 0f);
            modListScrollBar.GetComponent <RectTransform>().anchorMax = new Vector2(1.25f, 1f);
            modListScrollBar.GetComponent <RectTransform>().offsetMin = Vector2.zero;
            modListScrollBar.GetComponent <RectTransform>().offsetMax = Vector2.zero;
            modListScrollBar.GetComponent <Image>().sprite            = BoxSprite;
            modListScrollBar.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollBar.GetComponent <Image>().fillCenter = true;
            RectTransform modListScrollBarHandle = new GameObject("Handle", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <RectTransform>();

            modListScrollBarHandle.SetParent(modListScrollBar.transform);
            modListScrollBarHandle.anchorMin = new Vector2(0.05f, 0.05f);
            modListScrollBarHandle.anchorMax = new Vector2(0.95f, 0.95f);
            modListScrollBarHandle.offsetMin = Vector2.zero;
            modListScrollBarHandle.offsetMax = Vector2.zero;
            modListScrollBarHandle.GetComponent <Image>().sprite     = BoxSprite;
            modListScrollBarHandle.GetComponent <Image>().type       = Image.Type.Sliced;
            modListScrollBarHandle.GetComponent <Image>().fillCenter = true;
            modListScrollBar.targetGraphic = modListScrollBarHandle.GetComponent <Image>();
            modListScrollBar.handleRect    = modListScrollBarHandle;
            modListScrollBar.direction     = Scrollbar.Direction.BottomToTop;
            if (allMods.Length <= 5)
            {
                modListScrollBar.interactable = false;
            }
            modListScrollView.content           = modList;
            modListScrollView.horizontal        = false;
            modListScrollView.scrollSensitivity = 5;
            modListScrollView.movementType      = ScrollRect.MovementType.Clamped;
            modListScrollView.viewport          = modListViewport;
            modListScrollView.verticalScrollbar = modListScrollBar;
            float  entryHeight = allMods.Length <= 6 ? (1f / 6f) : (1f / allMods.Length);
            Toggle firstToggle = null;

            for (int i = 0; i < allMods.Length; i++)
            {
                RectTransform modEntry = new GameObject("Mod Entry: " + allMods[i], typeof(RectTransform), typeof(Toggle), typeof(CanvasRenderer), typeof(Image), typeof(Mask)).GetComponent <RectTransform>();
                modEntry.SetParent(modList);
                modEntry.anchorMin = new Vector2(0f, 1 - ((i + 1) * entryHeight));
                modEntry.anchorMax = new Vector2(1f, 1 - (i * entryHeight));
                modEntry.offsetMin = Vector2.zero;
                modEntry.offsetMax = Vector2.zero;
                Toggle modToggle   = modEntry.GetComponent <Toggle>();
                Image  modSelected = new GameObject("Selected", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).GetComponent <Image>();
                modSelected.rectTransform.SetParent(modEntry);
                modSelected.rectTransform.anchorMin = new Vector2(0f, 0f);
                modSelected.rectTransform.anchorMax = new Vector2(1f, 1f);
                modSelected.rectTransform.offsetMin = Vector2.zero;
                modSelected.rectTransform.offsetMax = Vector2.zero;
                modSelected.sprite = BoxSprite;
                modSelected.type   = Image.Type.Sliced;
                modSelected.color  = i < gadgetModCount ? new Color(1f, 1f, 0.25f, 1f) : i >= gadgetModCount + normalModCount + disabledModCount + incompatibleModCount ? new Color(0.5f, 0.5f, 0.5f, 1f) : i >= gadgetModCount + normalModCount + disabledModCount ? new Color(1f, 0f, 0f, 1f) : i >= gadgetModCount + normalModCount ? new Color(0.25f, 0.25f, 0.25f, 1f) : new Color(1f, 1f, 1f, 1f);
                Text modLabel = new GameObject("Label", typeof(RectTransform), typeof(CanvasRenderer), typeof(Text)).GetComponent <Text>();
                modLabel.rectTransform.SetParent(modEntry);
                modLabel.rectTransform.anchorMin = new Vector2(0f, 0f);
                modLabel.rectTransform.anchorMax = new Vector2(1f, 1f);
                modLabel.rectTransform.offsetMin = new Vector2(10, 10);
                modLabel.rectTransform.offsetMax = new Vector2(-10, -10);
                modLabel.font               = ModConfigMenuText.GetComponent <TextMesh>().font;
                modLabel.fontSize           = 12;
                modLabel.horizontalOverflow = HorizontalWrapMode.Overflow;
                modLabel.verticalOverflow   = VerticalWrapMode.Overflow;
                modLabel.alignment          = TextAnchor.MiddleLeft;
                modLabel.text               = (i < gadgetModCount + normalModCount + disabledModCount + incompatibleModCount ? allMods[i] : Path.GetFileNameWithoutExtension(allMods[i])) + Environment.NewLine + (i < gadgetModCount ? ("Gadget Mod (" + GadgetMods.GetModInfo(allMods[i]).UMFName + ")") : (i < gadgetModCount + normalModCount ? "Non-Gadget Mod" : i < gadgetModCount + normalModCount + disabledModCount ? "Disabled" : i < gadgetModCount + normalModCount + disabledModCount + incompatibleModCount ? "Incompatible" : "Packed Mod"));
                if ((i < gadgetModCount && !gadgetMods[i].Mod.Enabled) || i >= gadgetModCount + GadgetCore.nonGadgetMods.Count)
                {
                    modLabel.color = new Color(1f, 1f, 1f, 0.5f);
                }
                modToggle.GetComponent <Image>().sprite = BoxSprite;
                modToggle.GetComponent <Image>().type   = Image.Type.Sliced;
                modToggle.GetComponent <Image>().color  = i < gadgetModCount ? new Color(1f, 1f, 0.25f, 0.25f) : i >= gadgetModCount + normalModCount + disabledModCount + incompatibleModCount ? new Color(0.5f, 0.5f, 0.5f, 0.25f) : i >= gadgetModCount + normalModCount + disabledModCount ? new Color(1f, 0f, 0f, 0.25f) : i >= gadgetModCount + normalModCount ? new Color(0.25f, 0.25f, 0.25f, 0.25f) : new Color(1f, 1f, 1f, 0.25f);
                modToggle.transition       = Selectable.Transition.None;
                modToggle.isOn             = i == 0;
                modToggle.toggleTransition = Toggle.ToggleTransition.None;
                modToggle.graphic          = modSelected;
                modToggle.group            = modList.GetComponent <ToggleGroup>();
                int toggleIndex = i;
                if (i == 0)
                {
                    firstToggle = modToggle;
                }
                modToggle.onValueChanged.AddListener((toggled) => { if (toggled)
                                                                    {
                                                                        ModMenuDescPanel.UpdateInfo(modToggle, toggleIndex);
                                                                    }
                                                     });
            }

            if (allMods.Length > 0)
            {
                ModMenuDescPanel.UpdateInfo(firstToggle, 0);
            }
        }