Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CommandQueueExtendedIconFix v1.2.0
CommandQueueIconFix.dll
Decompiled 3 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CommandQueueIconFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CommandQueueIconFix")] [assembly: AssemblyTitle("CommandQueueIconFix")] [assembly: AssemblyVersion("1.0.0.0")] [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; } } } namespace CommandQueueIconFix { [BepInPlugin("local.commandqueue.iconfix", "CommandQueueExtended Icon Fix", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class CommandQueueIconFixPlugin : BaseUnityPlugin { public enum TooltipPosition { BottomCenter, Cursor } public const string PluginGuid = "local.commandqueue.iconfix"; public const string PluginName = "CommandQueueExtended Icon Fix"; public const string PluginVersion = "1.2.0"; private const string OverlayName = "CommandQueueIconFix_ItemIcon"; private const string CountName = "CommandQueueIconFix_OwnedCount"; private const string HitAreaName = "CommandQueueIconFix_TooltipHitArea"; private const string IconResourceName = "CommandQueueIconFix.icon.png"; private const float RefreshInterval = 0.2f; private const float LookingGlassLookupInterval = 5f; private const BindingFlags DeclaredMethods = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static CommandQueueIconFixPlugin instance; private static GameObject vanillaItemIconPrefab; private static bool failedToFindPrefab; private static int exceptionCount; private static int tooltipExceptionCount; private static int hoverExceptionCount; private static int tooltipRecoveryLogCount; private static readonly Color UnownedCountColor = new Color(0.5f, 0.5f, 0.5f, 1f); [ThreadStatic] private static PickupDef currentPickup; private static readonly FieldInfo TooltipOwnerField = AccessTools.Field(typeof(TooltipController), "owner"); private readonly List<QueueChoiceTag> trackedChoices = new List<QueueChoiceTag>(); private ConfigEntry<TooltipPosition> tooltipPosition; private ConfigEntry<bool> ignoreEnableInspect; private Sprite riskOfOptionsIcon; private Texture2D riskOfOptionsIconTexture; private Harmony harmony; private MethodInfo lookingGlassDescription; private float nextRefresh; private float nextLookingGlassLookup; private bool loggedLookingGlassException; private bool loggedLookingGlassMismatch; private bool loggedCounterException; private void Awake() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown instance = this; tooltipPosition = ((BaseUnityPlugin)this).Config.Bind<TooltipPosition>("Tooltips", "Position", TooltipPosition.BottomCenter, "Position of item tooltips in the Command Queue item-selection grid. BottomCenter shows them at the bottom center of the screen; Cursor uses the game's normal tooltip position. Inspect tooltips are shown when Enable Inspect is enabled, or when IgnoreEnableInspect is enabled in this plugin."); ignoreEnableInspect = ((BaseUnityPlugin)this).Config.Bind<bool>("Tooltips", "IgnoreEnableInspect", false, "Show Command Queue item tooltips even when the game's Enable Inspect option is disabled. Does not change the game's own setting. Changes apply immediately; owned-item counters are unaffected."); tooltipPosition.SettingChanged += OnTooltipPositionChanged; ignoreEnableInspect.SettingChanged += OnIgnoreInspectChanged; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Tooltip position=" + tooltipPosition.Value.ToString() + "; ignore Enable Inspect=" + ignoreEnableInspect.Value + "; native inspect is still read from the local Risk of Rain 2 profile.")); RegisterRiskOfOptionsIfAvailable(); try { if (TooltipOwnerField == null) { throw new MissingFieldException("RoR2.UI.TooltipController", "owner"); } harmony = new Harmony("local.commandqueue.iconfix"); harmony.Patch((MethodBase)AccessTools.Method(typeof(TooltipController), "LateUpdate", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CommandQueueIconFixPlugin), "RepositionQueueTooltip", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Command Queue tooltip positioning patch installed."); MethodInfo methodInfo = AccessTools.Method(typeof(TooltipController), "RemoveTooltip", new Type[2] { typeof(MPEventSystem), typeof(TooltipProvider) }, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(CommandQueueIconFixPlugin), "KeepHoveredQueueTooltip", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Command Queue hovered-tooltip lifetime guard installed."); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Cannot patch native tooltip removal. Hover recovery remains available."); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Cannot install optional tooltip patches: " + ex)); } Type type = (from assembly in AppDomain.CurrentDomain.GetAssemblies() select assembly.GetType("CommandQueue.UIManager", throwOnError: false)).FirstOrDefault((Type type2) => type2 != null); if (type == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Cannot find CommandQueue.UIManager. Check that CommandQueueExtended 2.0.0 is installed and enabled."); return; } if (harmony == null) { harmony = new Harmony("local.commandqueue.iconfix"); } int num = 0; foreach (Type item in FindNestedTypes(type)) { MethodInfo[] methods = item.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name.Contains("<CreateQueueContainer>") && methodInfo2.GetMethodBody() != null) { try { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(CommandQueueIconFixPlugin), "ReplaceLegacyGridSprites", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); num++; } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("Cannot patch " + methodInfo2.Name + ": " + ex2)); } } } } ((BaseUnityPlugin)this).Logger.LogInfo((object)("v1.2.0 installed Harmony patches on " + num + " CreateQueueContainer callback(s).")); if (num == 0) { ((BaseUnityPlugin)this).Logger.LogError((object)"No matching callbacks found: this mod version may have changed."); } } private void OnTooltipPositionChanged(object sender, EventArgs args) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Tooltip position changed to " + tooltipPosition.Value.ToString() + " (effective immediately).")); } private void OnIgnoreInspectChanged(object sender, EventArgs args) { nextRefresh = 0f; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Ignore Enable Inspect changed to " + ignoreEnableInspect.Value + " (effective immediately; game setting unchanged).")); } private static string GetLocalizedInspectOptionName() { string[] array = new string[5] { "OPTION_ENABLE_INSPECT_NAME", "OPTION_GAMEPLAY_ENABLE_INSPECT_NAME", "OPTION_ENABLEINSPECT_NAME", "OPTION_INSPECT_NAME", "OPTION_GAMEPLAY_INSPECT_NAME" }; try { string[] array2 = array; foreach (string text in array2) { string text2 = Language.GetString(text); if (!string.IsNullOrWhiteSpace(text2) && !string.Equals(text2, text, StringComparison.Ordinal)) { return text2; } } } catch { } return "Enable Inspect"; } private void RegisterRiskOfOptionsIfAvailable() { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly2) => assembly2.GetType("RiskOfOptions.ModSettingsManager", throwOnError: false) != null); if (assembly == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions not installed; tooltip position and inspect override remain configurable through BepInEx."); return; } try { Type type = assembly.GetType("RiskOfOptions.ModSettingsManager", throwOnError: true); Type type2 = assembly.GetType("RiskOfOptions.Options.BaseOption", throwOnError: true); Type type3 = assembly.GetType("RiskOfOptions.Options.ChoiceOption", throwOnError: true); Type? type4 = assembly.GetType("RiskOfOptions.OptionConfigs.ChoiceConfig", throwOnError: true); object obj = Activator.CreateInstance(type4); type4.GetField("name").SetValue(obj, "Tooltip Position"); type4.GetField("category").SetValue(obj, "Tooltips"); type4.GetField("description").SetValue(obj, "Position of the item description when hovering over an available Command Queue item. Follows the game's Enable Inspect option unless Ignore Enable Inspect is enabled. Changes apply immediately."); type4.GetField("restartRequired").SetValue(obj, false); object obj2 = Activator.CreateInstance(type3, tooltipPosition, obj); MethodInfo method = type.GetMethod("AddOption", new Type[3] { type2, typeof(string), typeof(string) }); if (method == null) { throw new MissingMethodException("RiskOfOptions.ModSettingsManager", "AddOption"); } method.Invoke(null, new object[3] { obj2, "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" }); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions registered Tooltip Position dropdown (BottomCenter / Cursor); no restart required."); try { Type type5 = assembly.GetType("RiskOfOptions.Options.CheckBoxOption", throwOnError: true); Type? type6 = assembly.GetType("RiskOfOptions.OptionConfigs.CheckBoxConfig", throwOnError: true); object obj3 = Activator.CreateInstance(type6); type6.GetField("name").SetValue(obj3, "Ignore " + GetLocalizedInspectOptionName()); type6.GetField("category").SetValue(obj3, "Tooltips"); type6.GetField("description").SetValue(obj3, "When enabled, Command Queue item tooltips appear even if the game's Enable Inspect setting is off. The normal game setting is not modified. Changes apply immediately."); type6.GetField("restartRequired").SetValue(obj3, false); object obj4 = Activator.CreateInstance(type5, ignoreEnableInspect, obj3); method.Invoke(null, new object[3] { obj4, "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" }); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions registered Ignore Enable Inspect checkbox; no restart required."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not register optional RiskOfOptions Ignore Enable Inspect checkbox. The BepInEx setting still works: " + ex)); } try { RegisterRiskOfOptionsIcon(type); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not register optional RiskOfOptions icon: " + ex2)); } try { MethodInfo method2 = type.GetMethod("SetModDescription", new Type[3] { typeof(string), typeof(string), typeof(string) }); if (method2 != null) { method2.Invoke(null, new object[3] { "Restores CommandQueueExtended item icons and adds owned-item counters and inspect tooltips.", "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" }); } } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not set optional RiskOfOptions mod description: " + ex3)); } } catch (Exception ex4) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("RiskOfOptions detected, but Tooltip Position could not be registered. The .cfg setting still works: " + ex4)); } } private void RegisterRiskOfOptionsIcon(Type managerType) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) byte[] array = null; string text = null; Assembly executingAssembly = Assembly.GetExecutingAssembly(); using (Stream stream = executingAssembly.GetManifestResourceStream("CommandQueueIconFix.icon.png")) { if (stream != null) { using (MemoryStream memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } text = "embedded resource"; } } if (array == null) { string directoryName = Path.GetDirectoryName(executingAssembly.Location); if (!string.IsNullOrEmpty(directoryName)) { string text2 = Path.Combine(directoryName, "icon.png"); if (File.Exists(text2)) { array = File.ReadAllBytes(text2); text = text2; } } } if (array == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions icon not found. Put icon.png beside CommandQueueIconFix.dll, or put it in the project directory before building to embed it."); return; } if (array.Length > 4194304) { throw new InvalidDataException("RiskOfOptions icon PNG is larger than 4 MiB."); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); try { if (!ImageConversion.LoadImage(val, array, false)) { throw new InvalidDataException("RiskOfOptions icon.png is not a valid PNG."); } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("Could not create icon Sprite."); } MethodInfo method = managerType.GetMethod("SetModIcon", new Type[3] { typeof(Sprite), typeof(string), typeof(string) }); if (method == null) { Object.Destroy((Object)(object)val2); throw new MissingMethodException("RiskOfOptions.ModSettingsManager", "SetModIcon(Sprite, string, string)"); } try { method.Invoke(null, new object[3] { val2, "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" }); } catch { Object.Destroy((Object)(object)val2); throw; } riskOfOptionsIconTexture = val; riskOfOptionsIcon = val2; ((BaseUnityPlugin)this).Logger.LogInfo((object)("RiskOfOptions mod icon registered from " + text + ".")); } catch { if ((Object)(object)riskOfOptionsIconTexture != (Object)(object)val) { Object.Destroy((Object)(object)val); } throw; } } private static IEnumerable<Type> FindNestedTypes(Type type) { yield return type; Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic); foreach (Type type2 in nestedTypes) { foreach (Type item in FindNestedTypes(type2)) { yield return item; } } } public static IEnumerable<CodeInstruction> ReplaceLegacyGridSprites(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod) { MethodInfo capture = AccessTools.Method(typeof(CommandQueueIconFixPlugin), "CapturePickup", (Type[])null, (Type[])null); MethodInfo assign = AccessTools.Method(typeof(CommandQueueIconFixPlugin), "AssignItemIcon", (Type[])null, (Type[])null); int captures = 0; int assignments = 0; foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo fieldInfo && fieldInfo.DeclaringType == typeof(PickupDef) && fieldInfo.Name == "iconSprite") { instruction.opcode = OpCodes.Call; instruction.operand = capture; captures++; } else if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodInfo methodInfo && methodInfo.DeclaringType == typeof(Image) && methodInfo.Name == "set_sprite") { instruction.opcode = OpCodes.Call; instruction.operand = assign; assignments++; } yield return instruction; } if (captures <= 0 && assignments <= 0) { yield break; } CommandQueueIconFixPlugin commandQueueIconFixPlugin = instance; if (commandQueueIconFixPlugin != null) { ((BaseUnityPlugin)commandQueueIconFixPlugin).Logger.LogInfo((object)("Replaced icon calls in " + __originalMethod.DeclaringType?.FullName + "." + __originalMethod.Name + ": " + captures + " pickup capture(s), " + assignments + " Image.sprite setter(s).")); } if (captures != 1 || assignments < 1) { CommandQueueIconFixPlugin commandQueueIconFixPlugin2 = instance; if (commandQueueIconFixPlugin2 != null) { ((BaseUnityPlugin)commandQueueIconFixPlugin2).Logger.LogWarning((object)"Unexpected icon IL pattern. This patch is intended for CommandQueueExtended 2.0.0."); } } } public static Sprite CapturePickup(PickupDef definition) { currentPickup = definition; return definition?.iconSprite; } public static void AssignItemIcon(Image target, Sprite originalSprite) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) PickupDef val = currentPickup; currentPickup = null; if ((Object)(object)target == (Object)null) { return; } if (val == null || (int)val.itemIndex == -1 || (Object)(object)instance == (Object)null) { target.sprite = originalSprite; return; } try { if (!instance.TryInstallItemIcon(target, val.itemIndex)) { target.sprite = originalSprite; } } catch (Exception ex) { target.sprite = originalSprite; if (exceptionCount++ < 5) { ((BaseUnityPlugin)instance).Logger.LogError((object)("Failed ItemIcon for " + ((object)Unsafe.As<ItemIndex, ItemIndex>(ref val.itemIndex)/*cast due to .constrained prefix*/).ToString() + ": " + ex)); } } } private static GameObject FindItemIconPrefab() { if ((Object)(object)vanillaItemIconPrefab != (Object)null) { return vanillaItemIconPrefab; } if (failedToFindPrefab) { return null; } try { GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/HUDSimple"); HUD val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<HUD>() : null); ItemInventoryDisplay val3 = (((Object)(object)val2 != (Object)null) ? val2.itemInventoryDisplay : null); vanillaItemIconPrefab = (((Object)(object)val3 != (Object)null) ? val3.itemIconPrefab : null); if ((Object)(object)vanillaItemIconPrefab == (Object)null || (Object)(object)vanillaItemIconPrefab.GetComponent<ItemIcon>() == (Object)null) { CommandQueueIconFixPlugin commandQueueIconFixPlugin = instance; if (commandQueueIconFixPlugin != null) { ((BaseUnityPlugin)commandQueueIconFixPlugin).Logger.LogError((object)"HUDSimple itemIconPrefab is missing or does not have RoR2.UI.ItemIcon."); } failedToFindPrefab = true; return null; } CommandQueueIconFixPlugin commandQueueIconFixPlugin2 = instance; if (commandQueueIconFixPlugin2 != null) { ((BaseUnityPlugin)commandQueueIconFixPlugin2).Logger.LogInfo((object)("Reusing HUDSimple ItemIcon prefab: " + ((Object)vanillaItemIconPrefab).name)); } return vanillaItemIconPrefab; } catch (Exception ex) { failedToFindPrefab = true; CommandQueueIconFixPlugin commandQueueIconFixPlugin3 = instance; if (commandQueueIconFixPlugin3 != null) { ((BaseUnityPlugin)commandQueueIconFixPlugin3).Logger.LogError((object)("Cannot load HUDSimple ItemIcon prefab: " + ex)); } return null; } } private unsafe bool TryInstallItemIcon(Image legacyImage, ItemIndex itemIndex) { //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) GameObject val = FindItemIconPrefab(); if ((Object)(object)val == (Object)null) { return false; } Transform val2 = ((Component)legacyImage).transform.Find("CommandQueueIconFix_ItemIcon"); bool flag = false; ItemIcon component; if ((Object)(object)val2 != (Object)null) { GameObject gameObject = ((Component)val2).gameObject; component = gameObject.GetComponent<ItemIcon>(); if ((Object)(object)component == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Existing icon overlay has no ItemIcon: " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString())); return false; } } else { GameObject gameObject = Object.Instantiate<GameObject>(val, ((Component)legacyImage).transform, false); ((Object)gameObject).name = "CommandQueueIconFix_ItemIcon"; component = gameObject.GetComponent<ItemIcon>(); RectTransform component2 = gameObject.GetComponent<RectTransform>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)gameObject); ((BaseUnityPlugin)this).Logger.LogWarning((object)("Cannot create an ItemIcon and RectTransform for " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString())); return false; } component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.pivot = new Vector2(0.5f, 0.5f); component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; ((Transform)component2).localScale = Vector3.one; ((Transform)component2).localRotation = Quaternion.identity; gameObject.transform.SetAsLastSibling(); Graphic[] componentsInChildren = gameObject.GetComponentsInChildren<Graphic>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].raycastTarget = false; } CanvasGroup val3 = gameObject.GetComponent<CanvasGroup>(); if ((Object)(object)val3 == (Object)null) { val3 = gameObject.AddComponent<CanvasGroup>(); } val3.blocksRaycasts = false; val3.interactable = false; flag = true; } component.SetItemIndex(itemIndex, 1); legacyImage.sprite = null; legacyImage.overrideSprite = null; ((Behaviour)legacyImage).enabled = false; try { RegisterQueueChoice(legacyImage, component, itemIndex); } catch (Exception ex) { if (!loggedCounterException) { loggedCounterException = true; ((BaseUnityPlugin)this).Logger.LogError((object)("Could not attach Command Queue count/tooltip: " + ex)); } } if (flag) { ((MonoBehaviour)this).StartCoroutine(RebindItemIcon(component, itemIndex)); } return true; } private unsafe IEnumerator RebindItemIcon(ItemIcon icon, ItemIndex itemIndex) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) yield return null; if ((Object)(object)icon == (Object)null) { yield break; } try { icon.SetItemIndex(itemIndex, 1); } catch (Exception ex) { if (exceptionCount++ < 5) { ((BaseUnityPlugin)this).Logger.LogError((object)("ItemIcon.SetItemIndex failed for " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString() + ": " + ex)); } } } private unsafe void RegisterQueueChoice(Image legacyImage, ItemIcon icon, ItemIndex itemIndex) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) MPButton componentInParent = ((Component)legacyImage).GetComponentInParent<MPButton>(); if ((Object)(object)componentInParent == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Cannot find the Command Queue choice button for " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString())); return; } QueueChoiceTag queueChoiceTag = ((Component)componentInParent).GetComponent<QueueChoiceTag>(); if ((Object)(object)queueChoiceTag == (Object)null) { queueChoiceTag = ((Component)componentInParent).gameObject.AddComponent<QueueChoiceTag>(); queueChoiceTag.Hud = ((Component)componentInParent).GetComponentInParent<HUD>(); } if (!trackedChoices.Contains(queueChoiceTag)) { trackedChoices.Add(queueChoiceTag); } queueChoiceTag.ItemIndex = itemIndex; queueChoiceTag.Icon = icon; queueChoiceTag.Tooltip = ((Component)componentInParent).GetComponent<TooltipProvider>(); if ((Object)(object)queueChoiceTag.Tooltip == (Object)null) { queueChoiceTag.Tooltip = ((Component)componentInParent).gameObject.AddComponent<TooltipProvider>(); } queueChoiceTag.Tooltip.AllowTooltipOnNavigationSelect = false; queueChoiceTag.Tooltip.removeTooltipOnDeselect = false; EnsureTooltipHitArea(componentInParent); Transform val = ((Component)legacyImage).transform.Find("CommandQueueIconFix_OwnedCount"); if ((Object)(object)val != (Object)null) { queueChoiceTag.Counter = ((Component)val).GetComponent<TextMeshProUGUI>(); } if ((Object)(object)queueChoiceTag.Counter == (Object)null) { GameObject val2 = new GameObject("CommandQueueIconFix_OwnedCount", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }) { layer = ((Component)legacyImage).gameObject.layer }; val2.transform.SetParent(((Component)legacyImage).transform, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.one; component.anchorMax = Vector2.one; component.pivot = Vector2.one; component.anchoredPosition = new Vector2(-2f, -1f); component.sizeDelta = new Vector2(33f, 16f); TextMeshProUGUI component2 = val2.GetComponent<TextMeshProUGUI>(); if ((Object)(object)icon.stackText != (Object)null && (Object)(object)((TMP_Text)icon.stackText).font != (Object)null) { ((TMP_Text)component2).font = ((TMP_Text)icon.stackText).font; } ((TMP_Text)component2).fontSize = 13f; ((TMP_Text)component2).enableAutoSizing = true; ((TMP_Text)component2).fontSizeMin = 10f; ((TMP_Text)component2).fontSizeMax = 13f; ((TMP_Text)component2).fontStyle = (FontStyles)1; ((TMP_Text)component2).alignment = (TextAlignmentOptions)260; ((Graphic)component2).color = Color.white; ((TMP_Text)component2).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)component2).outlineWidth = 0.18f; ((Graphic)component2).raycastTarget = false; ((TMP_Text)component2).text = "x0"; queueChoiceTag.Counter = component2; } ((TMP_Text)queueChoiceTag.Counter).transform.SetAsLastSibling(); queueChoiceTag.LastCount = int.MinValue; RefreshChoice(queueChoiceTag); } private static void EnsureTooltipHitArea(MPButton button) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)button).transform.Find("CommandQueueIconFix_TooltipHitArea"); Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : null); if ((Object)(object)val2 == (Object)null) { GameObject val3 = new GameObject("CommandQueueIconFix_TooltipHitArea", new Type[2] { typeof(RectTransform), typeof(Image) }) { layer = ((Component)button).gameObject.layer }; val3.transform.SetParent(((Component)button).transform, false); RectTransform component = val3.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; val2 = val3.GetComponent<Image>(); } ((Graphic)val2).color = new Color(1f, 1f, 1f, 0f); ((Graphic)val2).raycastTarget = true; ((Component)val2).transform.SetAsLastSibling(); } private static MPEventSystem ResolveChoiceEventSystem(LocalUser user) { return (MPEventSystem)(((object)((user != null) ? user.eventSystem : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/)); } internal static void HandleChoicePointerEnter(QueueChoiceTag tag, PointerEventData eventData) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0109: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)instance == (Object)null || (Object)(object)tag == (Object)null) { return; } tag.Hovered = true; tag.PointerPosition = ((eventData != null) ? eventData.position : Vector2.zero); tag.RecoveryAttempts = 0; tag.NextRecoveryTime = 0f; try { LocalUser choiceUser = GetChoiceUser(tag); MPEventSystem val = (tag.LastEventSystem = ResolveChoiceEventSystem(choiceUser)); if (IsInspectEnabled(choiceUser) && !((Object)(object)tag.Tooltip == (Object)null) && ((Behaviour)tag.Tooltip).isActiveAndEnabled && !((Object)(object)val == (Object)null) && (!string.IsNullOrEmpty(tag.Tooltip.titleText) || !string.IsNullOrEmpty(tag.Tooltip.bodyText)) && (!((Object)(object)val.currentTooltipProvider == (Object)(object)tag.Tooltip) || !((Object)(object)val.currentTooltip != (Object)null))) { if ((Object)(object)val.currentTooltipProvider == (Object)(object)tag.Tooltip && (Object)(object)val.currentTooltip == (Object)null) { TooltipController.RemoveTooltip(val, tag.Tooltip); } TooltipController.SetTooltip(val, tag.Tooltip, tag.PointerPosition, (RectTransform)null); } } catch (Exception ex) { if (hoverExceptionCount++ < 5) { ((BaseUnityPlugin)instance).Logger.LogError((object)("Command Queue tooltip enter failed for " + ((object)Unsafe.As<ItemIndex, ItemIndex>(ref tag.ItemIndex)/*cast due to .constrained prefix*/).ToString() + ": " + ex)); } } } internal static void HandleChoicePointerExit(QueueChoiceTag tag, PointerEventData eventData) { if ((Object)(object)instance == (Object)null || (Object)(object)tag == (Object)null) { return; } tag.Hovered = false; tag.RecoveryAttempts = 0; try { MPEventSystem val = tag.LastEventSystem ?? ResolveChoiceEventSystem(GetChoiceUser(tag)); if ((Object)(object)val != (Object)null && (Object)(object)tag.Tooltip != (Object)null) { TooltipController.RemoveTooltip(val, tag.Tooltip); } } catch (Exception ex) { if (hoverExceptionCount++ < 5) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)("Command Queue tooltip exit failed: " + ex)); } } tag.LastEventSystem = null; } public static bool KeepHoveredQueueTooltip(MPEventSystem __0, TooltipProvider __1) { if ((Object)(object)instance == (Object)null || (Object)(object)__0 == (Object)null || (Object)(object)__1 == (Object)null) { return true; } QueueChoiceTag component = ((Component)__1).GetComponent<QueueChoiceTag>(); if ((Object)(object)component == (Object)null || (Object)(object)component.Tooltip != (Object)(object)__1 || !component.Hovered || !((Behaviour)component).isActiveAndEnabled || !((Behaviour)__1).isActiveAndEnabled || !((Component)component).gameObject.activeInHierarchy || !IsInspectEnabled(GetChoiceUser(component))) { return true; } if ((Object)(object)__0.currentTooltipProvider != (Object)(object)__1 || (Object)(object)__0.currentTooltip == (Object)null) { return true; } return false; } private void LateUpdate() { //IL_014b: Unknown result type (might be due to invalid IL or missing references) foreach (QueueChoiceTag trackedChoice in trackedChoices) { if ((Object)(object)trackedChoice == (Object)null || !trackedChoice.Hovered || (Object)(object)trackedChoice.Tooltip == (Object)null || !((Behaviour)trackedChoice.Tooltip).isActiveAndEnabled || !((Component)trackedChoice).gameObject.activeInHierarchy || !IsInspectEnabled(GetChoiceUser(trackedChoice))) { continue; } MPEventSystem val = trackedChoice.LastEventSystem ?? ResolveChoiceEventSystem(GetChoiceUser(trackedChoice)); if ((Object)(object)val == (Object)null || ((Object)(object)val.currentTooltipProvider == (Object)(object)trackedChoice.Tooltip && (Object)(object)val.currentTooltip != (Object)null) || ((Object)(object)val.currentTooltipProvider != (Object)(object)trackedChoice.Tooltip && (Object)(object)val.currentTooltip != (Object)null) || Time.unscaledTime < trackedChoice.NextRecoveryTime || trackedChoice.RecoveryAttempts >= 4) { continue; } trackedChoice.NextRecoveryTime = Time.unscaledTime + 0.2f; trackedChoice.RecoveryAttempts++; try { if ((Object)(object)val.currentTooltipProvider == (Object)(object)trackedChoice.Tooltip && (Object)(object)val.currentTooltip == (Object)null) { TooltipController.RemoveTooltip(val, trackedChoice.Tooltip); } TooltipController.SetTooltip(val, trackedChoice.Tooltip, trackedChoice.PointerPosition, (RectTransform)null); if (tooltipRecoveryLogCount++ < 3) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Recovered Command Queue tooltip for item=" + ((object)Unsafe.As<ItemIndex, ItemIndex>(ref trackedChoice.ItemIndex)/*cast due to .constrained prefix*/).ToString() + ", attempt=" + trackedChoice.RecoveryAttempts + ".")); } } catch (Exception ex) { if (tooltipExceptionCount++ < 3) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not recover hovered Command Queue tooltip: " + ex)); } } } } private static LocalUser GetChoiceUser(QueueChoiceTag tag) { if ((Object)(object)tag.Hud != (Object)null && tag.Hud.localUserViewer != null) { return tag.Hud.localUserViewer; } return LocalUserManager.GetFirstLocalUser(); } private static bool IsInspectEnabled(LocalUser user) { if (!((Object)(object)instance != (Object)null) || instance.ignoreEnableInspect == null || !instance.ignoreEnableInspect.Value) { if (user != null && user.userProfile != null) { return user.userProfile.useInspectFeature; } return false; } return true; } private void Update() { if (Time.unscaledTime < nextRefresh) { return; } nextRefresh = Time.unscaledTime + 0.2f; TryFindLookingGlass(); for (int num = trackedChoices.Count - 1; num >= 0; num--) { QueueChoiceTag queueChoiceTag = trackedChoices[num]; if ((Object)(object)queueChoiceTag == (Object)null || (Object)(object)queueChoiceTag.Tooltip == (Object)null || (Object)(object)queueChoiceTag.Counter == (Object)null) { trackedChoices.RemoveAt(num); } else { try { RefreshChoice(queueChoiceTag); } catch (Exception ex) { if (!loggedCounterException) { loggedCounterException = true; ((BaseUnityPlugin)this).Logger.LogError((object)("Error updating Command Queue items: " + ex)); } } } } } private void RefreshChoice(QueueChoiceTag tag) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) LocalUser choiceUser = GetChoiceUser(tag); CharacterMaster val = ((choiceUser != null) ? choiceUser.cachedMaster : null); Inventory val2 = (((Object)(object)val != (Object)null) ? val.inventory : null); int num = (((Object)(object)val2 != (Object)null) ? val2.GetItemCountEffective(tag.ItemIndex) : 0); if (tag.LastCount != num || (Object)(object)tag.LastMaster != (Object)(object)val || tag.UsingLookingGlass != (lookingGlassDescription != null)) { ((TMP_Text)tag.Counter).text = "x" + num; ((Graphic)tag.Counter).color = ((num == 0) ? UnownedCountColor : Color.white); tag.LastCount = num; tag.LastMaster = val; tag.UsingLookingGlass = lookingGlassDescription != null; ItemDef itemDef = ItemCatalog.GetItemDef(tag.ItemIndex); if ((Object)(object)itemDef != (Object)null) { tag.Tooltip.SetContent(new TooltipContent { titleToken = itemDef.nameToken, titleColor = Color32.op_Implicit(ColorCatalog.GetColor(itemDef.darkColorIndex)), bodyToken = itemDef.descriptionToken, bodyColor = Color.white, overrideTitleText = null, overrideBodyText = GetDescription(itemDef, num, val), disableTitleRichText = false, disableBodyRichText = false }); } } bool flag = IsInspectEnabled(choiceUser); if (((Behaviour)tag.Tooltip).enabled != flag) { ((Behaviour)tag.Tooltip).enabled = flag; } } private void TryFindLookingGlass() { if (lookingGlassDescription != null || Time.unscaledTime < nextLookingGlassLookup) { return; } nextLookingGlassLookup = Time.unscaledTime + 5f; Type type = (from assembly in AppDomain.CurrentDomain.GetAssemblies() select assembly.GetType("LookingGlass.ItemStatsNameSpace.ItemStats", throwOnError: false)).FirstOrDefault((Type candidate) => candidate != null); if (!(type == null)) { lookingGlassDescription = type.GetMethod("GetItemDescription", BindingFlags.Static | BindingFlags.Public, null, new Type[5] { typeof(ItemDef), typeof(int), typeof(CharacterMaster), typeof(bool), typeof(bool) }, null); if (lookingGlassDescription != null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"LookingGlass item descriptions are available."); } else if (!loggedLookingGlassMismatch) { loggedLookingGlassMismatch = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)"LookingGlass is loaded but its description API differs; using normal game descriptions."); } } } private string GetDescription(ItemDef definition, int count, CharacterMaster master) { if (lookingGlassDescription != null && (Object)(object)master != (Object)null) { try { string text = lookingGlassDescription.Invoke(null, new object[5] { definition, count, master, true, false }) as string; if (!string.IsNullOrEmpty(text)) { return text; } } catch (Exception ex) { if (!loggedLookingGlassException) { loggedLookingGlassException = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("LookingGlass description failed, using vanilla text: " + ex)); } } } string text2 = Language.GetString(definition.descriptionToken); if (string.IsNullOrEmpty(text2)) { text2 = Language.GetString(definition.pickupToken); } return text2; } public static void RepositionQueueTooltip(TooltipController __instance) { //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)instance == (Object)null || (Object)(object)__instance == (Object)null || TooltipOwnerField == null) { return; } object? value = TooltipOwnerField.GetValue(__instance); MPEventSystem val = (MPEventSystem)((value is MPEventSystem) ? value : null); if ((Object)(object)val == (Object)null || (Object)(object)val.currentTooltip != (Object)(object)__instance) { return; } TooltipProvider currentTooltipProvider = val.currentTooltipProvider; if ((Object)(object)currentTooltipProvider == (Object)null || (Object)(object)((Component)currentTooltipProvider).GetComponent<QueueChoiceTag>() == (Object)null) { return; } RectTransform tooltipFlipTransform = __instance.tooltipFlipTransform; RectTransform tooltipCenterTransform = __instance.tooltipCenterTransform; if ((Object)(object)tooltipFlipTransform == (Object)null || (Object)(object)tooltipCenterTransform == (Object)null) { return; } QueueTooltipLayoutState queueTooltipLayoutState = ((Component)__instance).GetComponent<QueueTooltipLayoutState>(); if (instance.tooltipPosition.Value == TooltipPosition.Cursor) { if ((Object)(object)queueTooltipLayoutState != (Object)null && queueTooltipLayoutState.Saved) { tooltipFlipTransform.anchorMin = queueTooltipLayoutState.OriginalMin; tooltipFlipTransform.anchorMax = queueTooltipLayoutState.OriginalMax; tooltipFlipTransform.pivot = queueTooltipLayoutState.OriginalPivot; tooltipFlipTransform.anchoredPosition = queueTooltipLayoutState.OriginalPosition; queueTooltipLayoutState.Saved = false; } return; } if ((Object)(object)queueTooltipLayoutState == (Object)null) { queueTooltipLayoutState = ((Component)__instance).gameObject.AddComponent<QueueTooltipLayoutState>(); } if (!queueTooltipLayoutState.Saved) { queueTooltipLayoutState.OriginalMin = tooltipFlipTransform.anchorMin; queueTooltipLayoutState.OriginalMax = tooltipFlipTransform.anchorMax; queueTooltipLayoutState.OriginalPivot = tooltipFlipTransform.pivot; queueTooltipLayoutState.OriginalPosition = tooltipFlipTransform.anchoredPosition; queueTooltipLayoutState.Saved = true; } Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0f); tooltipFlipTransform.anchorMin = val2; tooltipFlipTransform.anchorMax = val2; tooltipFlipTransform.pivot = val2; tooltipFlipTransform.anchoredPosition = Vector2.zero; ((Transform)tooltipCenterTransform).position = new Vector3((float)Screen.width * 0.5f, Mathf.Max(16f, (float)Screen.height * 0.02f), 0f); } catch (Exception ex) { if (tooltipExceptionCount++ < 3) { CommandQueueIconFixPlugin commandQueueIconFixPlugin = instance; if (commandQueueIconFixPlugin != null) { ((BaseUnityPlugin)commandQueueIconFixPlugin).Logger.LogError((object)("Command Queue tooltip positioning failed: " + ex)); } } } } private void OnDestroy() { if (tooltipPosition != null) { tooltipPosition.SettingChanged -= OnTooltipPositionChanged; } if (ignoreEnableInspect != null) { ignoreEnableInspect.SettingChanged -= OnIgnoreInspectChanged; } Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } instance = null; vanillaItemIconPrefab = null; trackedChoices.Clear(); } } public sealed class QueueChoiceTag : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public ItemIndex ItemIndex; public ItemIcon Icon; public TooltipProvider Tooltip; public TextMeshProUGUI Counter; public HUD Hud; public int LastCount = int.MinValue; public CharacterMaster LastMaster; public bool UsingLookingGlass; public bool Hovered; public MPEventSystem LastEventSystem; public Vector2 PointerPosition; public int RecoveryAttempts; public float NextRecoveryTime; public void OnPointerEnter(PointerEventData eventData) { CommandQueueIconFixPlugin.HandleChoicePointerEnter(this, eventData); } public void OnPointerExit(PointerEventData eventData) { CommandQueueIconFixPlugin.HandleChoicePointerExit(this, eventData); } } public sealed class QueueTooltipLayoutState : MonoBehaviour { public bool Saved; public Vector2 OriginalMin; public Vector2 OriginalMax; public Vector2 OriginalPivot; public Vector2 OriginalPosition; } }