Decompiled source of TextUpgradesUIScale v1.2.1

TextUpgradesUIScale.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using TextUpgradesUIScale.Patches;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("DarkSpider90")]
[assembly: Guid("a27adabc-310b-43d6-8584-f2e1ec7a34cb")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]
[assembly: AssemblyTitle("TextUpgradesUIScale")]
[assembly: AssemblyDescription("Resizes the R.E.P.O. upgrades UI text for large upgrade lists.")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyProduct("TextUpgradesUIScale")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.2.1.0")]
namespace TextUpgradesUIScale
{
	[BepInPlugin("DarkSpider90.TextUpgradesUIScale", "TextUpgradesUIScale", "1.2.1")]
	public class Plugin : BaseUnityPlugin
	{
		private const string ModGuid = "DarkSpider90.TextUpgradesUIScale";

		private const string ModName = "TextUpgradesUIScale";

		private const string ModVersion = "1.2.1";

		private readonly Harmony harmony = new Harmony("DarkSpider90.TextUpgradesUIScale");

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> ModEnabled { get; private set; }

		internal static ConfigEntry<int> StartShrinkingAfterUpgradesCount { get; private set; }

		internal static ConfigEntry<int> ShrinkEveryUpgrades { get; private set; }

		internal static ConfigEntry<float> ShrinkStep { get; private set; }

		internal static ConfigEntry<float> LineSpacing { get; private set; }

		internal static ConfigEntry<float> MaxTextWidthBeforeShrinking { get; private set; }

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			BindConfig();
			Log.LogInfo((object)"Loaded TextUpgradesUIScale 1.2.1 for R.E.P.O. v0.4.0 UI.");
			harmony.PatchAll(typeof(StatsUIPatch));
		}

		private void BindConfig()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable or disable the mod.");
			StartShrinkingAfterUpgradesCount = ((BaseUnityPlugin)this).Config.Bind<int>("Text fitting", "StartShrinkingAfterUpgradesCount", 10, new ConfigDescription("Start shrinking text after this many active upgrades.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[0]));
			ShrinkEveryUpgrades = ((BaseUnityPlugin)this).Config.Bind<int>("Text fitting", "ShrinkEveryUpgrades", 2, new ConfigDescription("Shrink text once per this many additional upgrades.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), new object[0]));
			ShrinkStep = ((BaseUnityPlugin)this).Config.Bind<float>("Text fitting", "ShrinkStep", 0.07f, new ConfigDescription("Text scale removed per shrink step. 0.07 means 7%.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f), new object[0]));
			LineSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "LineSpacing", -4f, new ConfigDescription("Extra vertical spacing between upgrade rows while scaled. Negative values make the list tighter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-30f, 30f), new object[0]));
			MaxTextWidthBeforeShrinking = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "MaxTextWidthBeforeShrinking", 0f, new ConfigDescription("Shrink text if the upgrade names become wider than this value. Set to 0 to disable width-based shrinking.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2000f), new object[0]));
		}
	}
}
namespace TextUpgradesUIScale.Patches
{
	[HarmonyPatch(typeof(StatsUI), "Fetch")]
	public static class StatsUIPatch
	{
		private const float TechnicalMinimumScale = 0.05f;

		private static readonly FieldInfo TextField = AccessTools.Field(typeof(StatsUI), "Text");

		private static readonly FieldInfo NumbersTextField = AccessTools.Field(typeof(StatsUI), "textNumbers");

		private static readonly FieldInfo PlayerUpgradesField = AccessTools.Field(typeof(StatsUI), "playerUpgrades");

		private static TextMeshProUGUI _cachedMainText;

		private static TextMeshProUGUI _cachedNumbersText;

		private static float _defaultFontSize;

		private static float _defaultNumbersFontSize;

		private static bool _defaultAutoSizing;

		private static bool _defaultNumbersAutoSizing;

		private static bool _defaultWordWrapping;

		private static bool _defaultNumbersWordWrapping;

		private static TextOverflowModes _defaultOverflowMode;

		private static TextOverflowModes _defaultNumbersOverflowMode;

		private static VerticalAlignmentOptions _defaultVerticalAlignment;

		private static VerticalAlignmentOptions _defaultNumbersVerticalAlignment;

		private static float _defaultLineSpacing;

		private static float _defaultNumbersLineSpacing;

		private static bool _defaultFontSizeInitialized;

		private static bool _loggedMissingFields;

		private static bool _loggedException;

		public static void Postfix(StatsUI __instance)
		{
			try
			{
				TextMeshProUGUI val = (TextMeshProUGUI)((TextField == null) ? null : /*isinst with value type is only supported in some contexts*/);
				TextMeshProUGUI val2 = (TextMeshProUGUI)((NumbersTextField == null) ? null : /*isinst with value type is only supported in some contexts*/);
				Dictionary<string, int> dictionary = ((PlayerUpgradesField == null) ? null : (PlayerUpgradesField.GetValue(__instance) as Dictionary<string, int>));
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || dictionary == null)
				{
					LogMissingFieldsOnce();
					return;
				}
				CaptureDefaultsIfNeeded(val, val2);
				if (!Plugin.ModEnabled.Value)
				{
					RestoreTextColumns(val, val2);
					return;
				}
				int activeUpgradesCount = CountActiveUpgrades(dictionary);
				float scaleForUpgradeCount = GetScaleForUpgradeCount(activeUpgradesCount);
				scaleForUpgradeCount = ApplyWidthLimit(val, scaleForUpgradeCount);
				if (scaleForUpgradeCount >= 0.999f)
				{
					RestoreTextColumns(val, val2);
					return;
				}
				ConfigureTextColumn(val, _defaultLineSpacing);
				ConfigureTextColumn(val2, _defaultNumbersLineSpacing);
				((TMP_Text)val).fontSize = _defaultFontSize * scaleForUpgradeCount;
				((TMP_Text)val2).fontSize = _defaultNumbersFontSize * scaleForUpgradeCount;
			}
			catch (Exception ex)
			{
				if (!_loggedException)
				{
					_loggedException = true;
					if (Plugin.Log != null)
					{
						Plugin.Log.LogWarning((object)("[TextUpgradesUIScale] Failed to resize StatsUI text: " + ex.Message));
					}
				}
			}
		}

		private static void CaptureDefaultsIfNeeded(TextMeshProUGUI mainText, TextMeshProUGUI numbersText)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!_defaultFontSizeInitialized || !((Object)(object)_cachedMainText == (Object)(object)mainText) || !((Object)(object)_cachedNumbersText == (Object)(object)numbersText))
			{
				_cachedMainText = mainText;
				_cachedNumbersText = numbersText;
				_defaultFontSize = ((TMP_Text)mainText).fontSize;
				_defaultNumbersFontSize = ((TMP_Text)numbersText).fontSize;
				_defaultAutoSizing = ((TMP_Text)mainText).enableAutoSizing;
				_defaultNumbersAutoSizing = ((TMP_Text)numbersText).enableAutoSizing;
				_defaultWordWrapping = ((TMP_Text)mainText).enableWordWrapping;
				_defaultNumbersWordWrapping = ((TMP_Text)numbersText).enableWordWrapping;
				_defaultOverflowMode = ((TMP_Text)mainText).overflowMode;
				_defaultNumbersOverflowMode = ((TMP_Text)numbersText).overflowMode;
				_defaultVerticalAlignment = ((TMP_Text)mainText).verticalAlignment;
				_defaultNumbersVerticalAlignment = ((TMP_Text)numbersText).verticalAlignment;
				_defaultLineSpacing = ((TMP_Text)mainText).lineSpacing;
				_defaultNumbersLineSpacing = ((TMP_Text)numbersText).lineSpacing;
				_defaultFontSizeInitialized = true;
			}
		}

		private static int CountActiveUpgrades(Dictionary<string, int> playerUpgrades)
		{
			int num = 0;
			foreach (KeyValuePair<string, int> playerUpgrade in playerUpgrades)
			{
				if (playerUpgrade.Value > 0)
				{
					num++;
				}
			}
			return num;
		}

		private static void ConfigureTextColumn(TextMeshProUGUI text, float defaultLineSpacing)
		{
			((TMP_Text)text).enableAutoSizing = false;
			((TMP_Text)text).enableWordWrapping = false;
			((TMP_Text)text).overflowMode = (TextOverflowModes)0;
			((TMP_Text)text).verticalAlignment = (VerticalAlignmentOptions)256;
			((TMP_Text)text).lineSpacing = defaultLineSpacing + Plugin.LineSpacing.Value;
		}

		private static void RestoreTextColumns(TextMeshProUGUI mainText, TextMeshProUGUI numbersText)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			RestoreTextColumn(mainText, _defaultFontSize, _defaultAutoSizing, _defaultWordWrapping, _defaultOverflowMode, _defaultVerticalAlignment, _defaultLineSpacing);
			RestoreTextColumn(numbersText, _defaultNumbersFontSize, _defaultNumbersAutoSizing, _defaultNumbersWordWrapping, _defaultNumbersOverflowMode, _defaultNumbersVerticalAlignment, _defaultNumbersLineSpacing);
		}

		private static void RestoreTextColumn(TextMeshProUGUI text, float fontSize, bool autoSizing, bool wordWrapping, TextOverflowModes overflowMode, VerticalAlignmentOptions verticalAlignment, float lineSpacing)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)text).fontSize = fontSize;
			((TMP_Text)text).enableAutoSizing = autoSizing;
			((TMP_Text)text).enableWordWrapping = wordWrapping;
			((TMP_Text)text).overflowMode = overflowMode;
			((TMP_Text)text).verticalAlignment = verticalAlignment;
			((TMP_Text)text).lineSpacing = lineSpacing;
		}

		private static float GetScaleForUpgradeCount(int activeUpgradesCount)
		{
			int num = Mathf.Max(0, Plugin.StartShrinkingAfterUpgradesCount.Value);
			if (activeUpgradesCount <= num)
			{
				return 1f;
			}
			int num2 = Mathf.Max(1, Plugin.ShrinkEveryUpgrades.Value);
			float num3 = Mathf.Clamp(Plugin.ShrinkStep.Value, 0.01f, 0.5f);
			int num4 = Mathf.Max(0, activeUpgradesCount - num);
			int num5 = Mathf.CeilToInt((float)num4 / (float)num2);
			return ClampScale(1f - (float)num5 * num3);
		}

		private static float ApplyWidthLimit(TextMeshProUGUI mainText, float currentScale)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			float value = Plugin.MaxTextWidthBeforeShrinking.Value;
			if (value <= 1f)
			{
				return currentScale;
			}
			ConfigureTextColumn(mainText, _defaultLineSpacing);
			((TMP_Text)mainText).fontSize = _defaultFontSize * currentScale;
			float x = ((TMP_Text)mainText).GetPreferredValues(((TMP_Text)mainText).text, float.PositiveInfinity, float.PositiveInfinity).x;
			if (x <= value)
			{
				return currentScale;
			}
			float num = 0.05f;
			float num2 = currentScale;
			for (int i = 0; i < 8; i++)
			{
				float num3 = (num + num2) * 0.5f;
				((TMP_Text)mainText).fontSize = _defaultFontSize * num3;
				float x2 = ((TMP_Text)mainText).GetPreferredValues(((TMP_Text)mainText).text, float.PositiveInfinity, float.PositiveInfinity).x;
				if (x2 <= value)
				{
					num = num3;
				}
				else
				{
					num2 = num3;
				}
			}
			return ClampScale(num);
		}

		private static float ClampScale(float scale)
		{
			return Mathf.Clamp(scale, 0.05f, 1f);
		}

		private static void LogMissingFieldsOnce()
		{
			if (!_loggedMissingFields)
			{
				_loggedMissingFields = true;
				if (Plugin.Log != null)
				{
					Plugin.Log.LogWarning((object)"[TextUpgradesUIScale] Could not access StatsUI text fields. The game UI may have changed.");
				}
			}
		}
	}
}