public static void Log(string msg)
 {
     if (logger != null)
     {
         logger.Log(msg);
     }
 }
Пример #2
0
 internal static void DebugLog(string msg)
 {
     if (logger != null)
     {
         logger.Log(msg);
     }
 }
Пример #3
0
 internal static void DebugError(Exception ex)
 {
     if (logger != null)
     {
         logger.Log(ex.ToString() + "\n" + ex.StackTrace);
     }
 }
Пример #4
0
 public static void CommandBatch(string parameters)
 {
     parameters = parameters.Remove(0, 4);
     if (File.Exists(Storage.modEntryPath + parameters))
     {
         try
         {
             var i        = 0;
             var commands = File.ReadAllLines(Storage.modEntryPath + parameters);
             foreach (var s in commands)
             {
                 SmartConsole.WriteLine($"[{i}]: {s}");
                 SmartConsole.ExecuteLine(s);
                 i++;
             }
         }
         catch (Exception e)
         {
             modLogger.Log(e.ToString());
         }
     }
     else
     {
         SmartConsole.WriteLine($"'{parameters}' {Strings.GetText("error_NotFound")}");
     }
 }
Пример #5
0
 static bool Load(UnityModManager.ModEntry modEntry)
 {
     try
     {
         logger  = modEntry.Logger;
         harmony = Harmony12.HarmonyInstance.Create(modEntry.Info.Id);
         harmony.PatchAll(Assembly.GetExecutingAssembly());
         logger.Log("Do I at least make it here?");
     }
     catch (Exception ex)
     {
         DebugError(ex);
         throw ex;
     }
     return(true);
 }
Пример #6
0
        public static void Update()
        {
            CheckNewCheatCategoryElement("SpawnUnitsMenu");
            CheckNewCheatCategoryElement("BeneathTheStolenLands");

            if (CompareVersionStrings(settings.modVersion, "1.9.0") == -1)
            {
                if (File.Exists(Storage.modEntryPath + Storage.favouritesFolder + "\\" + Storage.favouritesTogglesFileOld))
                {
                    try
                    {
                        File.Move(Storage.modEntryPath + Storage.favouritesFolder + "\\" + Storage.favouritesTogglesFileOld, Storage.modEntryPath + Storage.favouritesFolder + "\\" + Storage.favouritesTogglesFile);
                        modLogger.Log($"{Storage.favouritesTogglesFileOld} {Strings.GetText("message_RenamedTo")} {Storage.favouritesTogglesFile}.");
                    }
                    catch (Exception e)
                    {
                        modLogger.Log(e.ToString());
                    }
                }
            }

            if (CompareVersionStrings(settings.modVersion, "1.14.2") != -1)
            {
                return;
            }
            if (Storage.togglesFavourites.Contains("toggleArmourChecksPenalty0,buttonToggle_ArmourChecksPenalty0,tooltip_ArmourChecksPenalty0"))
            {
                modLogger.Log("toggleArmourChecksPenalty0 - favourites update start");
                modLogger.Log($"--- {Storage.togglesFavourites.Count}");
                Storage.togglesFavourites.RemoveAll(IsToggleArmourChecksPenalty0);
                modLogger.Log($"--- {Storage.togglesFavourites.Count}");
                Storage.togglesFavourites.Add("ArmourChecksPenalty0");
                modLogger.Log($"--- {Storage.togglesFavourites.Count}");
                modLogger.Log("toggleArmourChecksPenalty0 - favourites update end");
            }

            if (!Storage.togglesFavourites.Contains("toggleArcaneSpellFailureRoll,buttonToggle_NoArcaneSpellFailure,tooltip_NoArcaneSpellFailure"))
            {
                return;
            }
            modLogger.Log("toggleArcaneSpellFailureRoll - favourites update start");
            modLogger.Log($"--- {Storage.togglesFavourites.Count}");
            Storage.togglesFavourites.RemoveAll(IsToggleArcaneSpellFailureRoll);
            modLogger.Log($"--- {Storage.togglesFavourites.Count}");
            Storage.togglesFavourites.Add("ArcaneSpellFailureRoll");
            modLogger.Log($"--- {Storage.togglesFavourites.Count}");
            modLogger.Log("toggleArcaneSpellFailureRoll - favourites update end");
        }
Пример #7
0
 internal static Exception Error(String message)
 {
     logger?.Log(message);
     return(new InvalidOperationException(message));
 }
Пример #8
0
        public static void Functions(int index)
        {
            switch (index)
            {
            case 0:
                break;

            case 1:
                GameInfo();
                break;

            case 2:
                KillFunctions();
                break;

            case 3:
                Common.ResurrectAndFullRestore(Common.GetUnitUnderMouse());
                break;

            case 4:
                Common.Buff(Common.GetUnitUnderMouse(),
                            Storage.buffFavouritesGuids[Main.Settings.actionKeyBuffIndex]);
                break;

            case 5:
                editUnit = Common.GetUnitUnderMouse();
                break;

            case 6:
                teleportUnit = Common.GetUnitUnderMouse();
                if (teleportUnit != null && Strings.ToBool(Main.Settings.toggleAddToLog))
                {
                    Common.AddLogEntry(Strings.GetText("label_TeleportUnit") + $": {teleportUnit.CharacterName}",
                                       Color.black);
                }
                break;

            case 7:
                if (settings.actionKeySpawnRandomEnemy && Strings.ToBool(settings.toggleActionKeyExperimental))
                {
                    try
                    {
                        Common.SpawnHostileUnit(Common.MousePositionLocalMap(),
                                                ResourcesLibrary.GetBlueprints <BlueprintUnit>().RandomElement());
                    }
                    catch (Exception e)
                    {
                        modLogger.Log(e.ToString());
                    }
                }
                else
                {
                    Common.SpawnHostileUnit(Common.MousePositionLocalMap(), banditsGuids[banidtCrIndex]);
                }

                break;

            case 8:
                rotateUnit = Common.GetUnitUnderMouse();
                if (rotateUnit != null && Strings.ToBool(Main.Settings.toggleAddToLog))
                {
                    Common.AddLogEntry(
                        Strings.GetText("arrayItem_ActionKeyMain_RotateUnit") + $": {rotateUnit.CharacterName}",
                        Color.black);
                }
                break;

            case 9:
                Common.GetUnitUnderMouse().View.AnimationManager.Execute(animationTypes[animationTypesIndex]);
                break;

            case 10:
                FxHelper.SpawnFxOnPoint(BlueprintRoot.Instance.Cheats.SillyCheatBlood,
                                        Common.MousePositionLocalMap());
                break;

            case 11:
                Common.Charm(Common.GetUnitUnderMouse());
                break;

            case 12:
                Common.AddToParty(Common.GetUnitUnderMouse());
                break;

            case 13:
                Common.GetUnitUnderMouse().Descriptor.Recreate = true;
                break;
            }
        }
Пример #9
0
        public static void Functions(int index)
        {
            switch (index)
            {
            case 0:
                break;

            case 1:
                GameInfo();
                break;

            case 2:
                KillFunctions();
                break;

            case 3:
                UnitEntityDataUtils.ResurrectAndFullRestore(Common.GetUnitUnderMouse());
                break;

            case 4:
                UnitEntityDataUtils.Buff(Common.GetUnitUnderMouse(), FavouritesFactory.GetFavouriteBuffs.FavouritesList[Main.settings.actionKeyBuffIndex]);
                break;

            case 5:
                editUnit = Common.GetUnitUnderMouse();
                break;

            case 6:
                teleportUnit = Common.GetUnitUnderMouse();
                if (teleportUnit != null && StringUtils.ToToggleBool(Main.settings.toggleAddToLog))
                {
                    Common.AddLogEntry(Strings.GetText("label_TeleportUnit") + $": {teleportUnit.CharacterName}", Color.black);
                }
                break;

            case 7:
                if (StringUtils.ToToggleBool(settings.toggleSpawnEnemiesFromUnitFavourites))
                {
                    try {
                        Vector3 pos = Common.MousePositionLocalMap();
                        float   x   = 0.0f;
                        float   z   = 0.0f;
                        foreach (string guid in SpawnUnits.GetStoredGUIDs)
                        {
                            Vector3 finalPos = new Vector3(pos.x + 1.5f * x, pos.y, pos.z + 1.5f * z);
                            SpawnUnits.UnitSpawner(finalPos, guid);
                            x++;
                            if (x > 10f)
                            {
                                x = 0.0f;
                                z++;
                            }
                        }
                    }
                    catch (Exception e) {
                        modLogger.Log(e.ToString());
                    }
                }
                else if (settings.actionKeySpawnRandomEnemy && StringUtils.ToToggleBool(settings.toggleActionKeyExperimental))
                {
                    try {
                        Common.SpawnHostileUnit(Common.MousePositionLocalMap(), ResourcesLibrary.GetBlueprints <BlueprintUnit>().RandomElement());
                    }
                    catch (Exception e) {
                        modLogger.Log(e.ToString());
                    }
                }
                else
                {
                    Common.SpawnHostileUnit(Common.MousePositionLocalMap(), banditsGuids[banidtCrIndex]);
                }
                break;

            case 8:
                rotateUnit = Common.GetUnitUnderMouse();
                if (rotateUnit != null && StringUtils.ToToggleBool(Main.settings.toggleAddToLog))
                {
                    Common.AddLogEntry(Strings.GetText("arrayItem_ActionKeyMain_RotateUnit") + $": {rotateUnit.CharacterName}", Color.black);
                }
                break;

            case 9:
                Common.GetUnitUnderMouse().View.AnimationManager.Execute(animationTypes[animationTypesIndex]);
                break;

            case 10:
                FxHelper.SpawnFxOnPoint(BlueprintRoot.Instance.Cheats.SillyCheatBlood, Common.MousePositionLocalMap());
                break;

            case 11:
                UnitEntityDataUtils.Charm(Common.GetUnitUnderMouse());
                break;

            case 12:
                UnitEntityDataUtils.AddToParty(Common.GetUnitUnderMouse());
                break;

            case 13:
                Common.GetUnitUnderMouse().Descriptor.Recreate = true;
                break;
            }
        }
        public static void Render()
        {
            GL.BeginVertical("box");
            GL.BeginHorizontal();
            settings.showPartyStatisticsCategory = GL.Toggle(settings.showPartyStatisticsCategory, RichTextUtils.MainCategoryFormat(Strings.GetText("mainCategory_PartyStats")), GL.ExpandWidth(false));
            if (!settings.showPartyStatisticsCategory)
            {
                GL.EndHorizontal();
            }
            else
            {
                MenuTools.FlexibleSpaceCategoryMenuElementsEndHorizontal("PartyOptions");

                GL.Space(10);

                MenuTools.ToggleButton(ref settings.toggleAccessRemoteCharacters, "buttonToggle_AccessRemoteCharacters", "tooltip_AccessRemoteCharacters", nameof(settings.toggleAccessRemoteCharacters));

                MenuTools.ToggleButtonActions(ref settings.toggleShowAllPartyPortraits, GroupControllerUtils.NaviBlockShowAllPartyMembers, GroupControllerUtils.NaviBlockShowDefault, "buttonToggle_ShowAllPartyPortraits", "tooltip_ShowAllPartyPortraits", nameof(settings.toggleShowAllPartyPortraits));

                GL.Space(10);

                GL.BeginHorizontal();
                Storage.statsFilterUnitEntityDataIndex = GL.SelectionGrid(Storage.statsFilterUnitEntityDataIndex, unitEntityDataFiltersArray, 3);
                GL.EndHorizontal();
                Player player = Game.Instance.Player;
                switch (Storage.statsFilterUnitEntityDataIndex)
                {
                case 0:
                    Storage.statsUnitEntityData = player.Party;
                    break;

                case 1:
                    Storage.statsUnitEntityData = player.ControllableCharacters;
                    break;

                case 2:
                    Storage.statsUnitEntityData = player.ActiveCompanions;
                    break;

                case 3:
                    Storage.statsUnitEntityData = player.AllCharacters;
                    break;

                case 4:
                    Storage.statsUnitEntityData = PartyUtils.GetRemoteCompanions();
                    break;

                case 5:
                    Storage.statsUnitEntityData = PartyUtils.GetCustomCompanions();
                    break;

                case 6:
                    Storage.statsUnitEntityData = PartyUtils.GetPets();
                    break;
                }
                if (Storage.statsFilterUnitEntityDataIndex != Storage.statsFilterUnitEntityDataIndexOld)
                {
                    Storage.reloadPartyStats = true;
                    Storage.statsFilterUnitEntityDataIndexOld = Storage.statsFilterUnitEntityDataIndex;
                }

                GL.Space(10);

                if (Storage.statsUnitEntityData.Any())
                {
                    if (Storage.reloadPartyStats)
                    {
                        Storage.statsSelectedControllableCharacterIndex = 0;
                        Storage.statsPartyMembers = Storage.statsUnitEntityData;
                        Storage.statsControllableCharacterNamesList.Clear();
                        foreach (UnitEntityData controllableCharacter in Storage.statsUnitEntityData)
                        {
                            Storage.statsControllableCharacterNamesList.Add(controllableCharacter.CharacterName);
                        }
                        Storage.reloadPartyStats = false;
                    }
                    if (!Storage.reloadPartyStats)
                    {
                        GL.BeginHorizontal();
                        Storage.statsSelectedControllableCharacterIndex = GL.SelectionGrid(Storage.statsSelectedControllableCharacterIndex, Storage.statsControllableCharacterNamesList.ToArray(), 6);
                        GL.EndHorizontal();

                        GL.Space(10);

                        GL.BeginVertical("box");
                        if (Storage.statsFilterUnitEntityDataIndex != 4)
                        {
                            MenuTools.SingleLineLabelGt("warning_SelectRemoteCharacters");
                        }
                        else
                        {
                            if (GL.Button(MenuTools.TextWithTooltip("button_AddRemoteCompanionToParty", "tooltip_AddRemoteCompanionToParty", false), GL.ExpandWidth(false)))
                            {
                                UnitEntityDataUtils.AddCompanion(Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex]);
                            }
                            GL.Space(10);
                            if (!StringUtils.ToToggleBool(settings.toggleShowAllPartyPortraits) && Game.Instance.Player.Party.Count > 6)
                            {
                                MenuTools.SingleLineLabelGt("warning_PartyLimitShowAllPartyPortraits");
                            }
                        }
                        GL.EndVertical();

                        GL.Space(10);

                        MainMenu.CurrentHitPointsOptions();

                        GL.Space(10);

                        MainMenu.ChangeName();

                        GL.Space(10);

                        MainMenu.ChangeGender();

                        GL.Space(10);


                        MainMenu.ClassData();

                        GL.Space(10);

                        //Menu.RaceData();

                        //GL.Space(10);

                        /*
                         * if (GL.Button(MenuTools.TextWithTooltip("button_RemoveEquippedItems", "tooltip_RemoveEquippedItems", false), GL.ExpandWidth(false)))
                         * {
                         *  foreach (ItemEntity itemEntity in Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Inventory.Items)
                         *  {
                         *      if (itemEntity.Owner == Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor)
                         *      {
                         *          itemEntity.HoldingSlot.RemoveItem();
                         *      }
                         *  }
                         * }
                         * GL.Space(10);*/

                        GL.BeginVertical("box");
                        GL.BeginHorizontal();
                        if (GL.Button(MenuTools.TextWithTooltip("button_ResetCharacterLevel", "tooltip_ResetCharacterLevel", false), GL.ExpandWidth(false)))
                        {
                            int level = 21;
                            int xp    = Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.Progression.Experience;
                            BlueprintStatProgression xpTable = BlueprintRoot.Instance.Progression.XPTable;

                            for (int i = 20; i >= 1; i--)
                            {
                                int xpBonus = xpTable.GetBonus(i);

                                modLogger.Log(i + ": " + xpBonus + " | " + xp);

                                if ((xp - xpBonus) >= 0)
                                {
                                    modLogger.Log(i + ": " + (xp - xpBonus));
                                    level = i;
                                    break;
                                }
                            }

                            Type         type         = Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.Progression.GetType();
                            PropertyInfo propertyInfo = type.GetProperty("CharacterLevel");
                            propertyInfo.SetValue(Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.Progression, level, null);
                        }
                        GL.EndHorizontal();

                        GL.Space(10);

                        GL.BeginHorizontal();
                        Storage.setCharLevel = GL.HorizontalSlider(Storage.setCharLevel, 1f, 20f, GL.Width(250f));
                        GL.Label($" {Mathf.RoundToInt(Storage.setCharLevel)}", GL.ExpandWidth(false));
                        GL.EndHorizontal();
                        GL.BeginHorizontal();
                        if (GL.Button(MenuTools.TextWithTooltip("button_SetCharacterLevel", "tooltip_SetCharacterLevel", "", $" {Mathf.RoundToInt(Storage.setCharLevel)}" + " " + StringUtils.PutInParenthesis(Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName)), GL.ExpandWidth(false)))
                        {
                            Type         type            = Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.Progression.GetType();
                            PropertyInfo propertyInfoLvl = type.GetProperty("CharacterLevel");
                            propertyInfoLvl.SetValue(Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.Progression, Mathf.RoundToInt(Storage.setCharLevel), null);

                            int          newXp          = BlueprintRoot.Instance.Progression.XPTable.GetBonus(Mathf.RoundToInt(Storage.setCharLevel));
                            PropertyInfo propertyInfoXp = type.GetProperty("Experience");
                            propertyInfoXp.SetValue(Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.Progression, newXp, null);
                        }
                        GL.EndHorizontal();
                        MenuTools.SingleLineLabel(Strings.GetText("warning_SetCharacterLevel"));
                        GL.EndVertical();

                        GL.Space(10);

                        MenuTools.UnitAlignment(Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex]);

                        GL.Space(10);

                        GL.BeginVertical("box");

                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_Size")));
                        GL.BeginHorizontal();
                        Storage.partySelectedSizeIndex = GL.SelectionGrid(Storage.partySelectedSizeIndex, Storage.charSizeArray, 4);
                        GL.EndHorizontal();
                        GL.Space(10);
                        GL.BeginHorizontal();
                        if (GL.Button(MenuTools.TextWithTooltip("button_SetSizeTo", "tooltip_SetSize", "", $" {Storage.charSizeArray[Storage.partySelectedSizeIndex]}"), GL.ExpandWidth(false)))
                        {
                            Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.State.Size = (Size)Storage.partySelectedSizeIndex;
                        }
                        GL.EndHorizontal();
                        GL.BeginHorizontal();
                        if (GL.Button(MenuTools.TextWithTooltip("button_SetToOriginalSize", "tooltip_SetToOriginalSize", "", $" ({Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.OriginalSize})"), GL.ExpandWidth(false)))
                        {
                            Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.State.Size = Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.OriginalSize;
                        }
                        GL.EndHorizontal();
                        MenuTools.SingleLineLabel(Strings.GetText("label_CurrentSize") + ": " + Common.SizeToString(Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.State.Size));
                        GL.EndVertical();

                        GL.Space(10);

                        GL.BeginHorizontal();
                        GL.Label(MenuTools.TextWithTooltip("header_Statistics", "tooltip_Statistics", true));
                        GL.EndHorizontal();

                        GL.BeginHorizontal();
                        settings.partyStatsAmount = GL.TextField(settings.partyStatsAmount, 10, GL.Width(85f));
                        MenuTools.SettingParse(ref settings.partyStatsAmount, ref settings.partyFinalStatsAmount);
                        GL.EndHorizontal();

                        CharacterStats charStats = Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].Descriptor.Stats;
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_AttributesBaseValues")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsAttributesDict)
                        {
                            MenuTools.CreateStatInterface(entry.Key, charStats, entry.Value, settings.partyFinalStatsAmount);
                        }
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_SkillsRanks")));

                        MenuTools.ToggleButton(ref settings.toggleShowOnlyClassSkills, "buttonToggle_ShowOnlyClassSkills", "tooltip_ShowOnlyClassSkills");

                        foreach (KeyValuePair <string, StatType> entry in Storage.statsSkillsDict)
                        {
                            if (StringUtils.ToToggleBool(settings.toggleShowOnlyClassSkills))
                            {
                                ModifiableValueSkill stat = charStats.GetStat(entry.Value) as ModifiableValueSkill;
                                if (stat.ClassSkill && stat.BaseValue > 0)
                                {
                                    MenuTools.CreateStatInterface(entry.Key, charStats, entry.Value, settings.partyFinalStatsAmount);
                                }
                            }
                            else
                            {
                                MenuTools.CreateStatInterface(entry.Key, charStats, entry.Value, settings.partyFinalStatsAmount, true);
                            }
                        }

                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_SocialSkillsBaseValues")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsSocialSkillsDict)
                        {
                            MenuTools.CreateStatInterface(entry.Key, charStats, entry.Value, settings.partyFinalStatsAmount);
                        }
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_StatsSaves")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsSavesDict)
                        {
                            MenuTools.CreateStatInterface(entry.Key, charStats, entry.Value, settings.partyFinalStatsAmount);
                        }
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_StatsCombat")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsCombatDict)
                        {
                            MenuTools.CreateStatInterface(entry.Key, charStats, entry.Value, settings.partyFinalStatsAmount);
                        }
                        GL.Space(10);

                        GL.BeginHorizontal();
                        GL.Label(MenuTools.TextWithTooltip("header_PartyMultipliers", "tooltip_PartyMultipliers", true));
                        GL.EndHorizontal();

                        GL.BeginHorizontal();
                        settings.partyStatMultiplier = GL.HorizontalSlider(settings.partyStatMultiplier, 0.1f, 10f, GL.Width(300f));
                        GL.Label($" {Math.Round(settings.partyStatMultiplier, 1)}", GL.ExpandWidth(false));
                        GL.EndHorizontal();
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_Attributes")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsAttributesDict)
                        {
                            MenuTools.CreateStatMultiplierInterface(entry.Key, charStats, entry.Value, Storage.statsPartyMembers, settings.partyStatMultiplier);
                        }
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_Skills")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsSkillsDict)
                        {
                            MenuTools.CreateStatMultiplierInterface(entry.Key, charStats, entry.Value, Storage.statsPartyMembers, settings.partyStatMultiplier);
                        }
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_SocialSkills")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsSocialSkillsDict)
                        {
                            MenuTools.CreateStatMultiplierInterface(entry.Key, charStats, entry.Value, Storage.statsPartyMembers, settings.partyStatMultiplier);
                        }
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_Saves")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsSavesDict)
                        {
                            MenuTools.CreateStatMultiplierInterface(entry.Key, charStats, entry.Value, Storage.statsPartyMembers, settings.partyStatMultiplier);
                        }
                        MenuTools.SingleLineLabel(RichTextUtils.Bold(Strings.GetText("header_Combat")));
                        foreach (KeyValuePair <string, StatType> entry in Storage.statsCombatDict)
                        {
                            MenuTools.CreateStatMultiplierInterface(entry.Key, charStats, entry.Value, Storage.statsPartyMembers, settings.partyStatMultiplier);
                        }

                        GL.BeginHorizontal();

                        if (GL.Button(MenuTools.TextWithTooltip("button_ExportCharInfo", "tooltip_ExportCharInfo", false), GL.ExpandWidth(false)))
                        {
                            List <string> charInfoTxt = new List <string>();
                            charInfoTxt.Add($"{Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName}");
                            charInfoTxt.Add("");
                            charInfoTxt.Add(Strings.GetText("header_AttributesBaseValues"));
                            foreach (KeyValuePair <string, StatType> entry in Storage.statsAttributesDict)
                            {
                                charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                            }
                            charInfoTxt.Add("");
                            charInfoTxt.Add(Strings.GetText("header_SkillsRanks"));
                            foreach (KeyValuePair <string, StatType> entry in Storage.statsSkillsDict)
                            {
                                charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                            }
                            charInfoTxt.Add("");
                            charInfoTxt.Add(Strings.GetText("header_SocialSkillsBaseValues"));
                            foreach (KeyValuePair <string, StatType> entry in Storage.statsSocialSkillsDict)
                            {
                                charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                            }
                            charInfoTxt.Add("");
                            charInfoTxt.Add(Strings.GetText("header_StatsSaves"));
                            foreach (KeyValuePair <string, StatType> entry in Storage.statsSavesDict)
                            {
                                charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                            }
                            charInfoTxt.Add("");
                            charInfoTxt.Add(Strings.GetText("header_StatsCombat"));
                            foreach (KeyValuePair <string, StatType> entry in Storage.statsCombatDict)
                            {
                                charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                            }

                            File.WriteAllLines(Path.Combine(Common.ExportPath(), $"{Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName}.txt"), charInfoTxt.ToArray());
                        }
                        GL.Label(" " + Strings.GetText("label_Location") + $": {Path.Combine(Common.ExportPath(), $"{Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName}.txt")}");
                        GL.EndHorizontal();

                        if (File.Exists(Storage.modEntryPath + Storage.charactersImportFolder + "\\" + Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName + ".txt"))
                        {
                            if (GL.Button(MenuTools.TextWithTooltip("button_ImportStatsFrom", "tooltip_ImportStatsFrom", "", $" { Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName}.txt"), GL.ExpandWidth(false)))
                            {
                                if (settings.settingCreateBackupBeforeImport)
                                {
                                    List <string> charInfoTxt = new List <string>();
                                    charInfoTxt.Add($"{Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName}");
                                    charInfoTxt.Add("");
                                    charInfoTxt.Add(Strings.GetText("header_AttributesBaseValues"));
                                    foreach (KeyValuePair <string, StatType> entry in Storage.statsAttributesDict)
                                    {
                                        charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                                    }
                                    charInfoTxt.Add("");
                                    charInfoTxt.Add(Strings.GetText("header_SkillsRanks"));
                                    foreach (KeyValuePair <string, StatType> entry in Storage.statsSkillsDict)
                                    {
                                        charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                                    }
                                    charInfoTxt.Add("");
                                    charInfoTxt.Add(Strings.GetText("header_SocialSkillsBaseValues"));
                                    foreach (KeyValuePair <string, StatType> entry in Storage.statsSocialSkillsDict)
                                    {
                                        charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                                    }
                                    charInfoTxt.Add("");
                                    charInfoTxt.Add(Strings.GetText("header_StatsSaves"));
                                    foreach (KeyValuePair <string, StatType> entry in Storage.statsSavesDict)
                                    {
                                        charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                                    }
                                    charInfoTxt.Add("");
                                    charInfoTxt.Add(Strings.GetText("header_StatsCombat"));
                                    foreach (KeyValuePair <string, StatType> entry in Storage.statsCombatDict)
                                    {
                                        charInfoTxt.Add(($"{entry.Key}: {charStats.GetStat(entry.Value).BaseValue} ({charStats.GetStat(entry.Value).ModifiedValue})"));
                                    }
                                    File.WriteAllLines(Path.Combine(Storage.modEntryPath + Storage.charactersImportFolder + "\\" + Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName + "_Backup.txt"), charInfoTxt.ToArray());
                                }

                                string[] lines = File.ReadAllLines(Storage.modEntryPath + Storage.charactersImportFolder + "\\" + Storage.statsPartyMembers[Storage.statsSelectedControllableCharacterIndex].CharacterName + ".txt");
                                lines = lines.Where(x => !string.IsNullOrEmpty(x)).ToArray();
                                lines = lines.Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();
                                for (int i = 0; i < lines.Length; i++)
                                {
                                    if (Regex.IsMatch(lines[i], @"[\x20A-Za-z()]+:\s*[0-9]+"))
                                    {
                                        Match match = Regex.Match(lines[i], @"[\x20A-Za-z()]+:\s*[0-9]+");
                                        lines[i] = match.Value;
                                        string[] splitLine = lines[i].Split(':');
                                        Dictionary <string, StatType> allStats = Storage.statsAttributesDict.Union(Storage.statsSkillsDict).Union(Storage.statsSocialSkillsDict).Union(Storage.statsSavesDict).Union(Storage.statsCombatDict).ToDictionary(k => k.Key, v => v.Value);
                                        if (allStats.TryGetValue(splitLine[0], out StatType statType) && int.TryParse(splitLine[1], out int baseValue))
                                        {
                                            charStats.GetStat(statType).BaseValue = baseValue;
                                        }
                                    }
                                    else
                                    {
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    MenuTools.SingleLineLabel(Strings.GetText("message_NoUnitFound"));
                }
            }
            GL.EndVertical();
        }