Decompiled source of UpgradeOptimizer v1.0.1

BepInEx/plugins/UpgradeOptimizer.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using Pigeon.Math;
using Pigeon.Movement;
using Sparroh.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("UpgradeOptimizer")]
[assembly: AssemblyTitle("UpgradeOptimizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class ConfigManager
{
	private const float DebounceSeconds = 0.25f;

	private static ConfigFile _config;

	private static ManualLogSource _logger;

	private static FileSystemWatcher _configWatcher;

	private static volatile bool _reloadPending;

	private static float _reloadAt = -1f;

	public static ConfigEntry<bool> EnableBoost { get; private set; }

	public static ConfigEntry<bool> EnablePatternBrowser { get; private set; }

	public static ConfigEntry<bool> EnableMaxRolls { get; private set; }

	public static ConfigEntry<Key> BoostHotkey { get; private set; }

	public static ConfigEntry<Key> PatternBrowserHotkey { get; private set; }

	public static void Initialize(ConfigFile configFile, ManualLogSource log)
	{
		_config = configFile;
		_logger = log;
		EnableBoost = _config.Bind<bool>("Features", "Enable Boost", true, "Enable free boost/turbocharge toggle on hovered upgrades.");
		EnablePatternBrowser = _config.Bind<bool>("Features", "Enable Pattern Browser", true, "Enable the freeform pattern browser for override infusion.");
		EnableMaxRolls = _config.Bind<bool>("Features", "Enable Max Rolls", true, "Force turbocharged upgrades to always roll best property values.");
		BoostHotkey = _config.Bind<Key>("Hotkeys", "Boost Key", (Key)29, "Hotkey that toggles boost/turbocharge on the currently hovered upgrade.");
		PatternBrowserHotkey = _config.Bind<Key>("Hotkeys", "Pattern Browser Key", (Key)30, "Hotkey that opens/closes the pattern browser on the currently hovered upgrade.");
		_config.SettingChanged += OnSettingChanged;
		try
		{
			SetupFileWatcher();
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("Config file watcher unavailable: " + ex.Message));
		}
	}

	public static void Tick()
	{
		if (_reloadPending)
		{
			_reloadPending = false;
			_reloadAt = Time.unscaledTime + 0.25f;
		}
		if (_reloadAt < 0f || Time.unscaledTime < _reloadAt)
		{
			return;
		}
		_reloadAt = -1f;
		try
		{
			_config.Reload();
			_logger.LogInfo((object)"Config reloaded from disk.");
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("Config reload failed: " + ex.Message));
		}
	}

	public static void Dispose()
	{
		if (_config != null)
		{
			_config.SettingChanged -= OnSettingChanged;
		}
		if (_configWatcher != null)
		{
			try
			{
				_configWatcher.EnableRaisingEvents = false;
				_configWatcher.Changed -= OnConfigFileChanged;
				_configWatcher.Created -= OnConfigFileChanged;
				_configWatcher.Renamed -= OnConfigFileChanged;
				_configWatcher.Dispose();
			}
			catch
			{
			}
			_configWatcher = null;
		}
	}

	private static void SetupFileWatcher()
	{
		string configFilePath = _config.ConfigFilePath;
		if (string.IsNullOrEmpty(configFilePath))
		{
			_configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.upgradeoptimizer.cfg");
		}
		else
		{
			string directoryName = Path.GetDirectoryName(configFilePath);
			string fileName = Path.GetFileName(configFilePath);
			if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(fileName))
			{
				return;
			}
			if (!File.Exists(configFilePath))
			{
				_config.Save();
			}
			_configWatcher = new FileSystemWatcher(directoryName, fileName);
		}
		_configWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
		_configWatcher.Changed += OnConfigFileChanged;
		_configWatcher.Created += OnConfigFileChanged;
		_configWatcher.Renamed += OnConfigFileChanged;
		_configWatcher.EnableRaisingEvents = true;
		_logger.LogInfo((object)("Config hot-reload watching: " + _configWatcher.Path + _configWatcher.Filter));
	}

	private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
	{
		_reloadPending = true;
	}

	private static void OnSettingChanged(object sender, SettingChangedEventArgs e)
	{
		if (e.ChangedSetting != null)
		{
			if ((object)e.ChangedSetting == EnablePatternBrowser && !EnablePatternBrowser.Value && PatternBrowser.IsOpen)
			{
				PatternBrowser.Close();
			}
			_logger.LogInfo((object)$"Config updated: [{e.ChangedSetting.Definition.Section}] {e.ChangedSetting.Definition.Key} = {e.ChangedSetting.BoxedValue}");
		}
	}
}
internal static class FreeBoostFeature
{
	public static void TryHandleHotkey(Keyboard keyboard, Key hotkey)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		if (!PlayerInput.IsMenuEnabled || !UpgradeOptimizerPlugin.WasHotkeyPressed(keyboard, hotkey))
		{
			return;
		}
		UpgradeInstance hoveredUpgrade = UpgradeHoverTracker.HoveredUpgrade;
		if (hoveredUpgrade != null && !((Object)(object)hoveredUpgrade.Upgrade == (Object)null))
		{
			if (hoveredUpgrade.IsTurbocharged)
			{
				hoveredUpgrade.IsTurbocharged = false;
				RefreshUpgradeUI(hoveredUpgrade);
				UpgradeOptimizerPlugin.Log.LogInfo((object)("Removed boost from '" + hoveredUpgrade.Upgrade.Name + "'."));
			}
			else if (!CanAutoBoost(hoveredUpgrade))
			{
				UpgradeOptimizerPlugin.Log.LogInfo((object)("Upgrade '" + hoveredUpgrade.Upgrade.Name + "' cannot be boosted."));
			}
			else
			{
				hoveredUpgrade.IsTurbocharged = true;
				RefreshUpgradeUI(hoveredUpgrade);
				PlayBoostFeedback(hoveredUpgrade);
				UpgradeOptimizerPlugin.Log.LogInfo((object)("Boosted '" + hoveredUpgrade.Upgrade.Name + "'."));
			}
		}
	}

	private static bool CanAutoBoost(UpgradeInstance upgrade)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Invalid comparison between Unknown and I4
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Invalid comparison between Unknown and I4
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Invalid comparison between Unknown and I4
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Invalid comparison between Unknown and I4
		Upgrade upgrade2 = upgrade.Upgrade;
		if (upgrade2 == null)
		{
			return false;
		}
		if (!upgrade.IsUnlocked)
		{
			return false;
		}
		if (upgrade.RemoveAfterMission)
		{
			return false;
		}
		Rarity rarity = upgrade2.Rarity;
		if ((int)rarity > 3)
		{
			return false;
		}
		if ((int)rarity == 3)
		{
			return (upgrade2.Flags & 0x2000) > 0;
		}
		if (upgrade2.IsSkin())
		{
			return false;
		}
		return (upgrade2.Flags & 0x40020) == 0;
	}

	private static void RefreshUpgradeUI(UpgradeInstance upgrade)
	{
		if ((Object)(object)HoverInfoDisplay.Instance != (Object)null)
		{
			HoverInfoDisplay.Instance.Refresh();
		}
		GearUpgradeUI val = default(GearUpgradeUI);
		if (UIRaycaster.RaycastForComponent<GearUpgradeUI>(ref val) && (Object)(object)val != (Object)null && ((HoverInfoUpgrade)val).Upgrade == upgrade)
		{
			val.SetUpgrade(upgrade, false);
		}
		GearDetailsWindow val2 = null;
		if ((Object)(object)Menu.Instance != (Object)null && Menu.Instance.IsOpen)
		{
			Window top = Menu.Instance.WindowSystem.GetTop();
			val2 = (GearDetailsWindow)(object)((top is GearDetailsWindow) ? top : null);
		}
		if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeSelf && upgrade.IsEquipped(val2.UpgradablePrefab))
		{
			val2.RefreshUpgrade(upgrade);
		}
	}

	private static void PlayBoostFeedback(UpgradeInstance upgrade)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)PlayerLook.Instance == (Object)null))
		{
			Global.GetRarity(upgrade.Upgrade.Rarity).raritySwitch.SetValue(((Component)PlayerLook.Instance).gameObject);
			Global.Instance.UpgradeUnlockSound.Post(((Component)PlayerLook.Instance).gameObject);
			Global.Instance.UpgradeDropSound.Post(((Component)PlayerLook.Instance).gameObject);
		}
	}
}
internal static class MaxRollsPatches
{
	[HarmonyPatch]
	internal static class RangeFloatGetValuePatch
	{
		private static MethodBase TargetMethod()
		{
			return FindGetValue(typeof(Range<float>));
		}

		private static bool Prefix(ref Range<float> __instance, ref Random rand, UpgradeInstance upgrade, BoostParams boostParams, ref float __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!ShouldForceBest(upgrade, boostParams))
			{
				return true;
			}
			__result = __instance.GetValue(ref rand, GetBestAddT(boostParams));
			return false;
		}
	}

	[HarmonyPatch]
	internal static class RangeIntGetValuePatch
	{
		private static MethodBase TargetMethod()
		{
			return FindGetValue(typeof(Range<int>));
		}

		private static bool Prefix(ref Range<int> __instance, ref Random rand, UpgradeInstance upgrade, BoostParams boostParams, ref int __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!ShouldForceBest(upgrade, boostParams))
			{
				return true;
			}
			__result = __instance.GetValue(ref rand, GetBestAddT(boostParams));
			return false;
		}
	}

	[HarmonyPatch]
	internal static class RangeVector2GetValuePatch
	{
		private static MethodBase TargetMethod()
		{
			return FindGetValue(typeof(Range<Vector2>));
		}

		private static bool Prefix(ref Range<Vector2> __instance, ref Random rand, UpgradeInstance upgrade, BoostParams boostParams, ref Vector2 __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!ShouldForceBest(upgrade, boostParams))
			{
				return true;
			}
			__result = __instance.GetValue(ref rand, GetBestAddT(boostParams));
			return false;
		}
	}

	[HarmonyPatch]
	internal static class GetUniformRandomValuePatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(Range<Vector2>), "GetUniformRandomValue", new Type[4]
			{
				typeof(Range<Vector2>),
				typeof(Random).MakeByRefType(),
				typeof(UpgradeInstance),
				typeof(BoostParams)
			}, (Type[])null);
		}

		private static bool Prefix(Range<Vector2> range, ref Random rand, UpgradeInstance upgrade, BoostParams boostParams, ref Vector2 __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (!ShouldForceBest(upgrade, boostParams))
			{
				return true;
			}
			__result = Vector2.Lerp(range.min, range.max, ((Random)(ref rand)).NextFloat() + GetBestAddT(boostParams));
			return false;
		}
	}

	private static bool ShouldForceBest(UpgradeInstance upgrade, BoostParams boostParams)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Invalid comparison between Unknown and I4
		if (!ConfigManager.EnableMaxRolls.Value)
		{
			return false;
		}
		if (upgrade == null || !upgrade.IsTurbocharged)
		{
			return false;
		}
		if (!boostParams.cannotBeBoosted)
		{
			return true;
		}
		Upgrade upgrade2 = upgrade.Upgrade;
		if (upgrade2 != null)
		{
			return (int)upgrade2.Rarity == 3;
		}
		return false;
	}

	private static float GetBestAddT(BoostParams boostParams)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		if (!boostParams.minIsBetter)
		{
			return 1f;
		}
		return -1f;
	}

	private static MethodBase FindGetValue(Type rangeType)
	{
		return AccessTools.Method(rangeType, "GetValue", new Type[3]
		{
			typeof(Random).MakeByRefType(),
			typeof(UpgradeInstance),
			typeof(BoostParams)
		}, (Type[])null);
	}
}
public static class PatternBrowser
{
	private static UpgradeInstance _target;

	private static string _search = "";

	private static bool _sameGearOnly;

	private static int _rarityFilterIndex;

	private static PatternCatalog.SortMode _sortMode = PatternCatalog.SortMode.Name;

	private static int _selectedIndex = -1;

	private static string _status = "";

	private static int _targetCellCount;

	private static UIWindow _window;

	private static UIInputField _searchField;

	private static UIToggle _sameGearToggle;

	private static UIDragList _unused;

	private static RectTransform _listContent;

	private static UIScrollView _listScroll;

	private static UIText _headerText;

	private static UIText _currentPatternText;

	private static UIText _previewText;

	private static UIText _statusText;

	private static UIText _countText;

	private static UIButton _sortButton;

	private static UIButton _rarityButton;

	private static readonly List<UIButton> _listButtons = new List<UIButton>();

	private static readonly string[] RarityFilterLabels = new string[7] { "All", "Standard", "Rare", "Epic", "Exotic", "Oddity", "Contraband" };

	public static bool IsOpen { get; private set; }

	public static void Open(UpgradeInstance target)
	{
		if (target == null)
		{
			return;
		}
		_target = target;
		IsOpen = true;
		_selectedIndex = -1;
		_status = "";
		_targetCellCount = PatternCatalog.SafeCellCount(target.Upgrade);
		try
		{
			HexMap pattern = target.GetPattern(false);
			if (pattern != null)
			{
				_targetCellCount = pattern.GetCellCount();
			}
		}
		catch
		{
		}
		PatternCatalog.Rebuild(target);
		RefreshFilters();
		EnsureWindow();
		RefreshUi();
		_window.Show();
		ManualLogSource log = UpgradeOptimizerPlugin.Log;
		Upgrade upgrade = target.Upgrade;
		log.LogInfo((object)("Opened pattern browser for " + ((upgrade != null) ? upgrade.Name : null)));
	}

	public static void Close()
	{
		IsOpen = false;
		_target = null;
		_selectedIndex = -1;
		_status = "";
		if (_window != null)
		{
			_window.Hide(true);
		}
	}

	public static void Draw()
	{
	}

	private static void EnsureWindow()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Expected O, but got Unknown
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d5: Expected O, but got Unknown
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: Expected O, but got Unknown
		//IL_040d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_054b: Unknown result type (might be due to invalid IL or missing references)
		//IL_055a: Expected O, but got Unknown
		if (_window != null)
		{
			return;
		}
		UITheme.Initialize();
		_window = UIWindow.Create("PatternBrowser", (Vector2?)new Vector2(720f, 520f), "UpgradeOptimizer — Pattern Browser", false, true, (int?)(UITheme.WindowSortingOrder + 10));
		_window.OnClose((Action)Close);
		Transform content = _window.Content;
		UIFactory.AddVerticalLayout(((Component)content).gameObject, UITheme.S(6f), UITheme.ScaledPadding(10, 10, 8, 8), (TextAnchor)0, true, false, true, true);
		_headerText = UIText.Create(content, "Header", "", UITheme.ScaledFontBody, (Color?)UIColors.TextPrimary, (TextAlignmentOptions)513, false);
		GameObject gameObject = _headerText.GameObject;
		float? num = UITheme.S(22f);
		UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, (float?)null);
		_currentPatternText = UIText.Create(content, "Current", "", UITheme.ScaledFontSmall, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)513, false);
		GameObject gameObject2 = _currentPatternText.GameObject;
		num = UITheme.S(20f);
		UIHelpers.EnsureLayoutElement(gameObject2, (float?)null, num, (float?)null);
		RectTransform val = UIFactory.CreateRect("SearchRow", content);
		GameObject gameObject3 = ((Component)val).gameObject;
		num = UITheme.ScaledInputHeight + UITheme.S(4f);
		UIHelpers.EnsureLayoutElement(gameObject3, (float?)null, num, (float?)null);
		UIFactory.AddHorizontalLayout(((Component)val).gameObject, UITheme.S(8f), new RectOffset(0, 0, 0, 0), (TextAnchor)3, false, false, true, true);
		UIText.Create((Transform)(object)val, "SearchLbl", "Search", UITheme.ScaledFontSmall, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)513, false);
		_searchField = UIInputField.Create((Transform)(object)val, _search, "Filter patterns...", (Action<string>)delegate(string s)
		{
			_search = s ?? "";
			RefreshFilters();
			RebuildList();
		}, "InputField");
		UIHelpers.EnsureLayoutElement(_searchField.GameObject, (float?)UITheme.S(220f), (float?)null, (float?)null);
		UIText.Create((Transform)(object)val, "LockedFilters", "Same gear · same rarity", UITheme.ScaledFontSmall, (Color?)UIColors.TextMuted, (TextAlignmentOptions)513, false);
		RectTransform val2 = UIFactory.CreateRect("FilterRow", content);
		GameObject gameObject4 = ((Component)val2).gameObject;
		num = UITheme.ScaledButtonHeight;
		UIHelpers.EnsureLayoutElement(gameObject4, (float?)null, num, (float?)null);
		UIFactory.AddHorizontalLayout(((Component)val2).gameObject, UITheme.S(8f), new RectOffset(0, 0, 0, 0), (TextAnchor)3, true, false, true, true);
		_sortButton = UIButton.Create((Transform)(object)val2, "Sort: Name", (Action)delegate
		{
			_sortMode = (PatternCatalog.SortMode)((int)(_sortMode + 1) % 4);
			RefreshFilters();
			RebuildList();
			RefreshFilterButtons();
		}, (UIButtonStyle)0, (string)null, (float?)null).SetWidth(UITheme.S(170f));
		_countText = UIText.Create((Transform)(object)val2, "Count", "0 patterns", UITheme.ScaledFontSmall, (Color?)UIColors.TextMuted, (TextAlignmentOptions)513, false);
		RectTransform obj = UIFactory.CreateRect("Mid", content);
		GameObject gameObject5 = ((Component)obj).gameObject;
		num = UITheme.S(280f);
		UIHelpers.EnsureLayoutElement(gameObject5, (float?)null, (float?)null, num).flexibleHeight = 1f;
		UIFactory.AddHorizontalLayout(((Component)obj).gameObject, UITheme.S(10f), new RectOffset(0, 0, 0, 0), (TextAnchor)0, true, true, true, true);
		_listScroll = UIScrollView.Create((Transform)(object)obj, "PatternList", true, false);
		UIHelpers.EnsureLayoutElement(_listScroll.GameObject, (float?)null, (float?)null, (float?)null).flexibleWidth = 1.2f;
		_listContent = _listScroll.Content;
		UIPanel obj2 = UIPanel.Create((Transform)(object)obj, "Preview", (Color?)UIColors.Surface, true);
		UIHelpers.EnsureLayoutElement(obj2.GameObject, (float?)null, (float?)null, (float?)null).flexibleWidth = 1f;
		_previewText = UIText.Create(obj2.Content, "PreviewText", "Select a pattern", UITheme.ScaledFontSmall, (Color?)UIColors.TextSecondary, (TextAlignmentOptions)257, true);
		UIHelpers.SetFillParent(_previewText.Rect, UITheme.S(8f));
		_statusText = UIText.Create(content, "Status", "", UITheme.ScaledFontSmall, (Color?)UIColors.Sky, (TextAlignmentOptions)513, false);
		GameObject gameObject6 = _statusText.GameObject;
		num = UITheme.S(20f);
		UIHelpers.EnsureLayoutElement(gameObject6, (float?)null, num, (float?)null);
		RectTransform obj3 = UIFactory.CreateRect("Footer", content);
		GameObject gameObject7 = ((Component)obj3).gameObject;
		num = UITheme.ScaledButtonHeight + UITheme.S(4f);
		UIHelpers.EnsureLayoutElement(gameObject7, (float?)null, num, (float?)null);
		UIFactory.AddHorizontalLayout(((Component)obj3).gameObject, UITheme.S(8f), new RectOffset(0, 0, 0, 0), (TextAnchor)3, true, false, true, true);
		UIButton.Create((Transform)(object)obj3, "Clear Override", (Action)delegate
		{
			ApplyOverride(null);
		}, (UIButtonStyle)2, (string)null, (float?)null).SetWidth(UITheme.S(130f));
		UIButton.Create((Transform)(object)obj3, "Apply", (Action)delegate
		{
			if (_selectedIndex >= 0 && _selectedIndex < PatternCatalog.CurrentFiltered.Count)
			{
				ApplyOverride(PatternCatalog.CurrentFiltered[_selectedIndex].Upgrade);
			}
		}, (UIButtonStyle)1, (string)null, (float?)null).SetWidth(UITheme.S(100f));
		UIButton.Create((Transform)(object)obj3, "Close", (Action)Close, (UIButtonStyle)0, (string)null, (float?)null).SetWidth(UITheme.S(90f));
	}

	private static void RefreshFilterButtons()
	{
		if (_sortButton != null)
		{
			_sortButton.SetText($"Sort: {_sortMode}");
		}
		if (_rarityButton != null)
		{
			_rarityButton.SetText("Rarity: " + RarityFilterLabels[_rarityFilterIndex]);
		}
		if (_countText != null)
		{
			_countText.Text = $"{PatternCatalog.CurrentFiltered.Count} patterns";
		}
	}

	private static void RefreshUi()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		if (_headerText != null && _target != null)
		{
			string text = _target.Upgrade.GetInstanceName(_target) ?? _target.Upgrade.Name;
			_headerText.Text = "Target: " + text;
		}
		if (_currentPatternText != null && _target != null)
		{
			UpgradeID overriddenPattern = _target.OverriddenPattern;
			if (overriddenPattern.ID != 0)
			{
				Upgrade upgradeFromID = PlayerData.GetUpgradeFromID(overriddenPattern);
				_currentPatternText.Text = (((Object)(object)upgradeFromID != (Object)null) ? $"Current pattern: {upgradeFromID.Name} ({PatternCatalog.SafeCellCount(upgradeFromID)} cells)" : $"Current pattern: ID {overriddenPattern.ID}");
			}
			else
			{
				_currentPatternText.Text = $"Current pattern: Original ({_targetCellCount} cells)";
			}
		}
		if (_searchField != null)
		{
			_searchField.Text = _search ?? "";
		}
		if (_sameGearToggle != null)
		{
			_sameGearToggle.IsOn = _sameGearOnly;
		}
		if (_statusText != null)
		{
			_statusText.Text = _status ?? "";
		}
		RebuildList();
		RefreshFilterButtons();
		UpdatePreview();
	}

	private static void RebuildList()
	{
		if ((Object)(object)_listContent == (Object)null)
		{
			return;
		}
		UIHelpers.DestroyChildren((Transform)(object)_listContent);
		_listButtons.Clear();
		IReadOnlyList<PatternEntry> currentFiltered = PatternCatalog.CurrentFiltered;
		for (int i = 0; i < currentFiltered.Count; i++)
		{
			int index = i;
			PatternEntry patternEntry = currentFiltered[i];
			int num = patternEntry.CellCount - _targetCellCount;
			string text = ((num > 0) ? $" (+{num})" : ((num < 0) ? $" ({num})" : " (=)"));
			string text2 = (_sameGearOnly ? patternEntry.UpgradeName : patternEntry.DisplayName);
			string text3 = "";
			string text4 = $"{text2}{text3}  {patternEntry.CellCount}c{text}";
			UIButton item = UIButton.Create((Transform)(object)_listContent, text4, (Action)delegate
			{
				_selectedIndex = index;
				UpdatePreview();
			}, (UIButtonStyle)((index == _selectedIndex) ? 3 : 0), (string)null, (float?)UITheme.S(26f));
			_listButtons.Add(item);
		}
		if (_countText != null)
		{
			_countText.Text = $"{currentFiltered.Count} patterns";
		}
	}

	private static void UpdatePreview()
	{
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		if (_previewText == null)
		{
			return;
		}
		if (_selectedIndex < 0 || _selectedIndex >= PatternCatalog.CurrentFiltered.Count)
		{
			_previewText.Text = "Select a pattern to preview";
			return;
		}
		PatternEntry patternEntry = PatternCatalog.CurrentFiltered[_selectedIndex];
		HexMap val = PatternCatalog.SafePattern(patternEntry.Upgrade);
		int num = ((val != null) ? val.GetCellCount() : patternEntry.CellCount);
		int num2 = ((val != null) ? val.Width : 0);
		int num3 = ((val != null) ? val.Height : 0);
		string text = "";
		if (val != null)
		{
			for (int i = 0; i < val.Height; i++)
			{
				for (int j = 0; j < val.Width; j++)
				{
					text += (val[j, i].enabled ? "■ " : "· ");
				}
				text += "\n";
			}
		}
		_previewText.Text = $"{patternEntry.UpgradeName}\n{patternEntry.GearName} · {patternEntry.Rarity} · {num} cells ({num2}x{num3})\n\n{text}";
	}

	private static void RefreshFilters()
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		bool filterByRarity = false;
		Rarity val = (Rarity)(-1);
		_sameGearOnly = true;
		UpgradeInstance target = _target;
		if ((Object)(object)((target != null) ? target.Upgrade : null) != (Object)null)
		{
			filterByRarity = true;
			val = _target.Upgrade.Rarity;
			_rarityFilterIndex = RarityToFilterIndex(val);
		}
		IUpgradable targetGear = ((_target != null) ? _target.Gear : null);
		PatternCatalog.ApplyFilters(_search, _sameGearOnly, targetGear, filterByRarity, val, _sortMode, _targetCellCount);
		if (_selectedIndex >= PatternCatalog.CurrentFiltered.Count)
		{
			_selectedIndex = PatternCatalog.CurrentFiltered.Count - 1;
		}
	}

	private unsafe static int RarityToFilterIndex(Rarity rarity)
	{
		string b = ((object)(*(Rarity*)(&rarity))/*cast due to .constrained prefix*/).ToString();
		for (int i = 0; i < RarityFilterLabels.Length; i++)
		{
			if (string.Equals(RarityFilterLabels[i], b, StringComparison.OrdinalIgnoreCase))
			{
				return i;
			}
		}
		return 0;
	}

	private static void ApplyOverride(Upgrade patternSource)
	{
		if (_target == null)
		{
			return;
		}
		_status = PatternOverride.Apply(_target, patternSource);
		if (_statusText != null)
		{
			_statusText.Text = _status;
		}
		if (_status != null && _status.StartsWith("Applied:", StringComparison.Ordinal))
		{
			try
			{
				HexMap pattern = _target.GetPattern(false);
				_targetCellCount = ((pattern != null) ? pattern.GetCellCount() : PatternCatalog.SafeCellCount(_target.Upgrade));
			}
			catch
			{
				_targetCellCount = PatternCatalog.SafeCellCount(_target.Upgrade);
			}
			RefreshFilters();
			RefreshUi();
		}
	}
}
public sealed class PatternEntry
{
	public int CellCount;

	public string DisplayName;

	public IUpgradable Gear;

	public string GearName;

	public Rarity Rarity;

	public string SearchText;

	public Upgrade Upgrade;

	public string UpgradeName;
}
public static class PatternCatalog
{
	public enum SortMode
	{
		Name,
		Rarity,
		CellCount,
		CellDelta
	}

	private static readonly List<PatternEntry> AllEntries = new List<PatternEntry>(256);

	private static readonly List<PatternEntry> Filtered = new List<PatternEntry>(256);

	public static IReadOnlyList<PatternEntry> CurrentFiltered => Filtered;

	public static void Rebuild(UpgradeInstance target)
	{
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		AllEntries.Clear();
		if (target == null || PlayerData.Instance == null || PlayerData.Instance.collectedGear == null)
		{
			Filtered.Clear();
			return;
		}
		Upgrade upgrade = target.Upgrade;
		foreach (GearData value in PlayerData.Instance.collectedGear.Values)
		{
			if (((value != null) ? value.Gear : null) == null || !value.IsUnlocked || (Object)(object)value.Gear.Info == (Object)null)
			{
				continue;
			}
			IUpgradable gear = value.Gear;
			string text = gear.Info.Name;
			if (string.IsNullOrEmpty(text))
			{
				text = "Unknown Gear";
			}
			List<Upgrade> upgrades = gear.Info.Upgrades;
			if (upgrades == null)
			{
				continue;
			}
			foreach (Upgrade item in upgrades)
			{
				if (item != null && item != upgrade && !item.IsSkin())
				{
					int cellCount = SafeCellCount(item);
					string text2 = item.Name ?? item.APIName ?? "Upgrade";
					string text3 = text + " - " + text2;
					AllEntries.Add(new PatternEntry
					{
						Upgrade = item,
						Gear = gear,
						GearName = text,
						UpgradeName = text2,
						DisplayName = text3,
						Rarity = item.Rarity,
						CellCount = cellCount,
						SearchText = text3.ToLowerInvariant()
					});
				}
			}
		}
		AllEntries.Sort((PatternEntry a, PatternEntry b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase));
	}

	public static void ApplyFilters(string search, bool sameGearOnly, IUpgradable targetGear, bool filterByRarity, Rarity rarityFilter, SortMode sortMode, int targetCellCount)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		Filtered.Clear();
		string text = (string.IsNullOrWhiteSpace(search) ? null : search.Trim().ToLowerInvariant());
		sameGearOnly = true;
		filterByRarity = true;
		foreach (PatternEntry allEntry in AllEntries)
		{
			if ((!sameGearOnly || targetGear == null || allEntry.Gear == targetGear) && (!filterByRarity || allEntry.Rarity == rarityFilter) && (text == null || allEntry.SearchText.IndexOf(text, StringComparison.Ordinal) >= 0))
			{
				Filtered.Add(allEntry);
			}
		}
		switch (sortMode)
		{
		case SortMode.Rarity:
			Filtered.Sort(delegate(PatternEntry a, PatternEntry b)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				ref Rarity rarity = ref b.Rarity;
				object target = a.Rarity;
				int num = ((Enum)Unsafe.As<Rarity, Rarity>(ref rarity)/*cast due to .constrained prefix*/).CompareTo(target);
				return (num == 0) ? string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase) : num;
			});
			break;
		case SortMode.CellCount:
			Filtered.Sort(delegate(PatternEntry a, PatternEntry b)
			{
				int num = b.CellCount.CompareTo(a.CellCount);
				return (num == 0) ? string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase) : num;
			});
			break;
		case SortMode.CellDelta:
			Filtered.Sort(delegate(PatternEntry a, PatternEntry b)
			{
				int num = Math.Abs(a.CellCount - targetCellCount);
				int value = Math.Abs(b.CellCount - targetCellCount);
				int num2 = num.CompareTo(value);
				if (num2 != 0)
				{
					return num2;
				}
				num2 = b.CellCount.CompareTo(a.CellCount);
				return (num2 == 0) ? string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase) : num2;
			});
			break;
		default:
			Filtered.Sort((PatternEntry a, PatternEntry b) => string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase));
			break;
		}
	}

	public static int SafeCellCount(Upgrade upgrade)
	{
		try
		{
			HexMap pattern = upgrade.GetPattern((UpgradeInstance)null, false);
			return (pattern != null) ? pattern.GetCellCount() : 0;
		}
		catch (Exception ex)
		{
			ManualLogSource log = UpgradeOptimizerPlugin.Log;
			if (log != null)
			{
				log.LogWarning((object)("Failed to read pattern for " + ((upgrade != null) ? upgrade.Name : null) + ": " + ex.Message));
			}
			return 0;
		}
	}

	public static HexMap SafePattern(Upgrade upgrade)
	{
		try
		{
			return (upgrade != null) ? upgrade.GetPattern((UpgradeInstance)null, false) : null;
		}
		catch
		{
			return null;
		}
	}
}
public static class PatternOverride
{
	public static string Apply(UpgradeInstance target, Upgrade patternSource)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (target == null)
		{
			return "";
		}
		if ((Object)(object)patternSource != (Object)null)
		{
			if (patternSource.IsSkin())
			{
				UpgradeOptimizerPlugin.Log.LogWarning((object)("SparrohMode=false blocked skin pattern override: " + patternSource.Name));
				return "Blocked: skin patterns disabled";
			}
			Rarity val = (Rarity)((!((Object)(object)target.Upgrade != (Object)null)) ? (-1) : ((int)target.Upgrade.Rarity));
			bool flag = patternSource.Rarity == val;
			bool flag2 = target.Gear == null || IsUpgradeOnGear(patternSource, target.Gear);
			if (!flag2 || !flag)
			{
				UpgradeOptimizerPlugin.Log.LogWarning((object)("SparrohMode=false blocked pattern override: " + patternSource.Name + " " + $"(rarity match={flag}, gear match={flag2})"));
				return "Blocked: same gear and rarity only";
			}
		}
		try
		{
			List<(IUpgradable, sbyte, sbyte, byte)> list = CaptureEquippedPositions(target);
			if (list.Count > 0)
			{
				PlayerData.UnequipFromAll(target);
			}
			target.OverridePattern(patternSource);
			int num = 0;
			foreach (var item in list)
			{
				if (CanOccupy(item.Item1, target, item.Item2, item.Item3, item.Item4))
				{
					target.Equip(item.Item1, item.Item2, item.Item3, item.Item4, true, false);
					num++;
				}
			}
			string text = (((Object)(object)patternSource != (Object)null) ? patternSource.Name : "Original");
			string result = ((list.Count == 0) ? ("Applied: " + text) : ((num == list.Count) ? ("Applied: " + text + " (re-equipped)") : ((num != 0) ? $"Applied: {text} (re-equipped {num}/{list.Count})" : ("Applied: " + text + " (unequipped — new shape doesn't fit)"))));
			ManualLogSource log = UpgradeOptimizerPlugin.Log;
			Upgrade upgrade = target.Upgrade;
			log.LogInfo((object)("Pattern override on " + ((upgrade != null) ? upgrade.Name : null) + " -> " + text));
			return result;
		}
		catch (Exception arg)
		{
			UpgradeOptimizerPlugin.Log.LogError((object)$"ApplyOverride failed: {arg}");
			return "Failed to apply override";
		}
	}

	public static List<(IUpgradable gear, sbyte x, sbyte y, byte rot)> CaptureEquippedPositions(UpgradeInstance instance)
	{
		List<(IUpgradable, sbyte, sbyte, byte)> list = new List<(IUpgradable, sbyte, sbyte, byte)>();
		if (instance == null || (Object)(object)Global.Instance == (Object)null)
		{
			return list;
		}
		try
		{
			if (Global.Instance.Characters != null)
			{
				Character[] characters = Global.Instance.Characters;
				sbyte item = default(sbyte);
				sbyte item2 = default(sbyte);
				byte item3 = default(byte);
				foreach (Character val in characters)
				{
					if ((Object)(object)val != (Object)null && instance.IsEquipped((IUpgradable)(object)val) && instance.GetPosition((IUpgradable)(object)val, ref item, ref item2, ref item3))
					{
						list.Add(((IUpgradable)(object)val, item, item2, item3));
					}
				}
			}
			if (Global.Instance.AllGear != null)
			{
				IUpgradable[] allGear = Global.Instance.AllGear;
				sbyte item4 = default(sbyte);
				sbyte item5 = default(sbyte);
				byte item6 = default(byte);
				foreach (IUpgradable val2 in allGear)
				{
					if (val2 != null && instance.IsEquipped(val2) && instance.GetPosition(val2, ref item4, ref item5, ref item6))
					{
						list.Add((val2, item4, item5, item6));
					}
				}
			}
		}
		catch (Exception ex)
		{
			UpgradeOptimizerPlugin.Log.LogWarning((object)("CaptureEquippedPositions: " + ex.Message));
		}
		return list;
	}

	public static bool CanOccupy(IUpgradable gear, UpgradeInstance upgrade, sbyte x, sbyte y, byte rotation)
	{
		try
		{
			HexMap pattern = upgrade.GetPattern(false);
			HexMap val = ((pattern != null) ? pattern.GetModifiedMap((int)rotation, (HexMap)null) : null);
			if (val == null)
			{
				return true;
			}
			int num = default(int);
			int num2 = default(int);
			gear.Info.GetUpgradeGridSize(ref num, ref num2, false);
			if (val.Width > num + 2 || val.Height > num2 + 2)
			{
				return false;
			}
			return true;
		}
		catch
		{
			return true;
		}
	}

	public static bool IsUpgradeOnGear(Upgrade upgrade, IUpgradable gear)
	{
		if (!((Object)(object)upgrade == (Object)null))
		{
			object obj;
			if (gear == null)
			{
				obj = null;
			}
			else
			{
				GearInfo info = gear.Info;
				obj = ((info != null) ? info.Upgrades : null);
			}
			if (obj != null)
			{
				foreach (Upgrade upgrade2 in gear.Info.Upgrades)
				{
					if (upgrade2 == upgrade)
					{
						return true;
					}
				}
				return false;
			}
		}
		return false;
	}
}
[BepInPlugin("sparroh.upgradeoptimizer", "UpgradeOptimizer", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class UpgradeOptimizerPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "sparroh.upgradeoptimizer";

	public const string PluginName = "UpgradeOptimizer";

	public const string PluginVersion = "1.0.1";

	internal const bool SparrohMode = false;

	private Harmony _harmony;

	internal static ManualLogSource Log { get; private set; }

	private void Awake()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0059: 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)
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Log);
		_harmony = new Harmony("sparroh.upgradeoptimizer");
		_harmony.PatchAll();
		Log.LogInfo((object)("UpgradeOptimizer v1.0.1 loaded. " + $"Boost={ConfigManager.EnableBoost.Value} ({ConfigManager.BoostHotkey.Value}), " + $"Patterns={ConfigManager.EnablePatternBrowser.Value} ({ConfigManager.PatternBrowserHotkey.Value}), " + $"MaxRolls={ConfigManager.EnableMaxRolls.Value}"));
	}

	private void Update()
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			ConfigManager.Tick();
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			UpgradeHoverTracker.Tick();
			if (IsTypingInSearchField())
			{
				if (ConfigManager.EnablePatternBrowser.Value && PatternBrowser.IsOpen && WasHotkeyPressed(current, (Key)60))
				{
					PatternBrowser.Close();
				}
				return;
			}
			if (ConfigManager.EnableBoost.Value)
			{
				FreeBoostFeature.TryHandleHotkey(current, ConfigManager.BoostHotkey.Value);
			}
			if (ConfigManager.EnablePatternBrowser.Value)
			{
				HandlePatternBrowserHotkeys(current);
			}
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Update error: " + ex));
		}
	}

	private void OnDestroy()
	{
		ConfigManager.Dispose();
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}

	private void OnGUI()
	{
		if (!ConfigManager.EnablePatternBrowser.Value)
		{
			return;
		}
		try
		{
			PatternBrowser.Draw();
		}
		catch (Exception ex)
		{
			Log.LogError((object)("OnGUI error: " + ex));
		}
	}

	private static void HandlePatternBrowserHotkeys(Keyboard keyboard)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		if (WasHotkeyPressed(keyboard, (Key)60) && PatternBrowser.IsOpen)
		{
			PatternBrowser.Close();
		}
		else if (WasHotkeyPressed(keyboard, ConfigManager.PatternBrowserHotkey.Value))
		{
			if (PatternBrowser.IsOpen)
			{
				PatternBrowser.Close();
			}
			else if (UpgradeHoverTracker.HoveredUpgrade != null && UpgradeHoverTracker.HoveredUpgrade.IsUnlocked)
			{
				PatternBrowser.Open(UpgradeHoverTracker.HoveredUpgrade);
			}
		}
	}

	internal static bool WasHotkeyPressed(Keyboard keyboard, Key key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			return ((ButtonControl)keyboard[key]).wasPressedThisFrame;
		}
		catch
		{
			return false;
		}
	}

	internal static bool IsTypingInSearchField()
	{
		EventSystem current = EventSystem.current;
		GameObject val = ((current != null) ? current.currentSelectedGameObject : null);
		if ((Object)(object)val != (Object)null)
		{
			return (Object)(object)val.GetComponent<TMP_InputField>() != (Object)null;
		}
		return false;
	}
}
internal static class UpgradeHoverTracker
{
	internal static UpgradeInstance HoveredUpgrade { get; private set; }

	public static void Tick()
	{
		if ((Object)(object)HoverInfoDisplay.Instance != (Object)null)
		{
			HoverInfo selectedInfo = HoverInfoDisplay.Instance.SelectedInfo;
			HoverInfoUpgrade val = (HoverInfoUpgrade)(object)((selectedInfo is HoverInfoUpgrade) ? selectedInfo : null);
			if (val != null && val.Upgrade != null)
			{
				HoveredUpgrade = val.Upgrade;
				return;
			}
		}
		GearUpgradeUI val2 = default(GearUpgradeUI);
		UpgradeIcon val3 = default(UpgradeIcon);
		if (UIRaycaster.RaycastForComponent<GearUpgradeUI>(ref val2) && (Object)(object)val2 != (Object)null && ((HoverInfoUpgrade)val2).Upgrade != null)
		{
			HoveredUpgrade = ((HoverInfoUpgrade)val2).Upgrade;
		}
		else if (UIRaycaster.RaycastForComponent<UpgradeIcon>(ref val3) && (Object)(object)val3 != (Object)null && ((HoverInfoUpgrade)val3).Upgrade != null)
		{
			HoveredUpgrade = ((HoverInfoUpgrade)val3).Upgrade;
		}
		else
		{
			HoveredUpgrade = null;
		}
	}
}
namespace UpgradeOptimizer
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "UpgradeOptimizer";

		public const string PLUGIN_NAME = "UpgradeOptimizer";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}