using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ItemSpawnerEnhanced.Api; using ItemSpawnerEnhanced.Core; using ItemSpawnerEnhanced.Localization; using ItemSpawnerEnhanced.UI; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.UI; using Zorro.Core; [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("ItemSpawnerEnhanced")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.0.0")] [assembly: AssemblyInformationalVersion("1.3.0+868a403036ec2b476d1ba1a4dba1c5a0bb24d6c5")] [assembly: AssemblyProduct("ItemSpawnerEnhanced")] [assembly: AssemblyTitle("ItemSpawnerEnhanced")] [assembly: AssemblyVersion("1.3.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 ItemSpawnerEnhanced { internal sealed class FavoriteStore { private readonly ConfigEntry _entry; private readonly ManualLogSource _logger; private HashSet _itemNames; public FavoriteStore(ConfigEntry entry, ManualLogSource logger) { _entry = entry; _logger = logger; _itemNames = Deserialize(entry.Value); } public bool IsFavorite(string itemName) { return _itemNames.Contains(itemName); } public bool TryToggle(string itemName, out bool isFavorite) { HashSet hashSet = new HashSet(_itemNames, StringComparer.Ordinal); isFavorite = !hashSet.Remove(itemName); if (isFavorite) { hashSet.Add(itemName); } string value = FavoriteItemCodec.Serialize(hashSet); string value2 = _entry.Value; try { _entry.Value = value; } catch (Exception arg) { try { _entry.Value = value2; } catch { } isFavorite = _itemNames.Contains(itemName); _logger.LogError((object)$"Failed to save favorite items: {arg}"); return false; } _itemNames = hashSet; return true; } private HashSet Deserialize(string serialized) { try { return FavoriteItemCodec.Deserialize(serialized); } catch (Exception ex) { _logger.LogWarning((object)("Favorite item configuration is invalid and will be ignored: " + ex.Message)); return new HashSet(StringComparer.Ordinal); } } } internal sealed class GameItemCatalog { private readonly ManualLogSource _logger; private readonly Func _showAllItems; private readonly Func _isFavorite; private SearchIndex _index = new SearchIndex(Array.Empty<(GameItemRecord, IEnumerable)>()); private Item[] _sourceItems = Array.Empty(); private bool _sourceShowAllItems; public IReadOnlyList Items { get; private set; } = Array.Empty(); public GameItemCatalog(ManualLogSource logger, Func showAllItems, Func isFavorite) { _logger = logger; _showAllItems = showAllItems; _isFavorite = isFavorite; } public bool IsCurrent() { if (((DatabaseAsset)(object)SingletonAsset.Instance).Objects.Where((Item item) => (Object)(object)item != (Object)null).ToArray().SequenceEqual(_sourceItems)) { return _showAllItems() == _sourceShowAllItems; } return false; } public void RebuildItems() { IEnumerator enumerator = RebuildItemsIncrementally(double.MaxValue); while (enumerator.MoveNext()) { } } public IEnumerator RebuildItemsIncrementally(double timeBudgetMilliseconds) { if (timeBudgetMilliseconds <= 0.0) { throw new ArgumentOutOfRangeException("timeBudgetMilliseconds"); } Item[] sourceItems = ((DatabaseAsset)(object)SingletonAsset.Instance).Objects.Where((Item item) => (Object)(object)item != (Object)null).ToArray(); bool showAllItems = _showAllItems(); List items = new List(sourceItems.Length); long timestamp = Stopwatch.GetTimestamp(); for (int index = 0; index < sourceItems.Length; index++) { Item val = sourceItems[index]; if (VanillaItemVisibility.IsVisible(((Object)val).name, showAllItems, _isFavorite(((Object)val).name))) { string fallback = val.UIData?.itemName ?? ((Object)val).name; items.Add(new GameItemRecord(val, SafeLocalizedName(val, fallback), ItemCategoryResolver.Resolve(val))); } if (index + 1 < sourceItems.Length && ElapsedMilliseconds(timestamp) >= timeBudgetMilliseconds) { yield return null; timestamp = Stopwatch.GetTimestamp(); } } Items = items.ToArray(); _sourceItems = sourceItems; _sourceShowAllItems = showAllItems; _index = new SearchIndex(Array.Empty<(GameItemRecord, IEnumerable)>()); } public IEnumerator RebuildSearchIndexIncrementally(double timeBudgetMilliseconds) { if (timeBudgetMilliseconds <= 0.0) { throw new ArgumentOutOfRangeException("timeBudgetMilliseconds"); } string languageCode = GameLanguage.CurrentCode; IReadOnlyList readOnlyList = SearchAliasRegistry.Snapshot(); List activeProviders = new List(readOnlyList.Count); foreach (ISearchAliasProvider item2 in readOnlyList) { try { if (item2.SupportsLanguage(languageCode)) { activeProviders.Add(item2); } } catch (Exception arg) { _logger.LogError((object)$"Search alias provider '{item2.Id}' failed while checking language '{languageCode}': {arg}"); } } SearchIndex.Builder indexBuilder = new SearchIndex.Builder(); long timestamp = Stopwatch.GetTimestamp(); for (int itemIndex = 0; itemIndex < Items.Count; itemIndex++) { GameItemRecord gameItemRecord = Items[itemIndex]; Item item = gameItemRecord.Item; string text = item.UIData?.itemName ?? ((Object)item).name; string text2 = SafeEnglishName(text); SearchAliasContext context = new SearchAliasContext(((Object)item).name, text, gameItemRecord.DisplayName, text2, languageCode); List list = new List { new SearchAliasValue(gameItemRecord.DisplayName, SearchAliasPriority.Display), new SearchAliasValue(text2, SearchAliasPriority.English), new SearchAliasValue(((Object)item).name, SearchAliasPriority.Internal), new SearchAliasValue(text, SearchAliasPriority.Internal) }; foreach (ISearchAliasProvider item3 in activeProviders) { try { list.AddRange(from alias in item3.GetAliases(context) where !string.IsNullOrWhiteSpace(alias) select new SearchAliasValue(alias, SearchAliasPriority.Provider)); } catch (Exception arg2) { _logger.LogError((object)$"Search alias provider '{item3.Id}' failed for '{((Object)item).name}': {arg2}"); } } indexBuilder.Add(gameItemRecord, list); if (itemIndex + 1 < Items.Count && ElapsedMilliseconds(timestamp) >= timeBudgetMilliseconds) { yield return null; timestamp = Stopwatch.GetTimestamp(); } } _index = indexBuilder.Build(); } public IReadOnlyList Search(string query) { return _index.Search(query); } private static string SafeLocalizedName(Item item, string fallback) { try { string name = item.GetName(); return IsUsable(name) ? name : fallback; } catch { return fallback; } } private static string SafeEnglishName(string rawName) { try { string text = LocalizedText.GetText(LocalizedText.GetNameIndex(rawName), (Language)0); return IsUsable(text) ? text : rawName; } catch { return rawName; } } private static bool IsUsable(string? value) { if (!string.IsNullOrWhiteSpace(value)) { return !value.StartsWith("LOC:", StringComparison.OrdinalIgnoreCase); } return false; } private static double ElapsedMilliseconds(long started) { return (double)(Stopwatch.GetTimestamp() - started) * 1000.0 / (double)Stopwatch.Frequency; } } internal sealed class GameItemRecord { public Item Item { get; } public string DisplayName { get; } public ItemFilterTag Tags { get; } public GameItemRecord(Item item, string displayName, ItemFilterTag tags) { Item = item; DisplayName = displayName; Tags = tags; } } internal sealed class ItemBrowserSession { public ItemFilterTag SelectedTags { get; set; } } internal static class ItemCategoryResolver { public static ItemFilterTag Resolve(Item item) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) //IL_009e: Unknown result type (might be due to invalid IL or missing references) ItemFilterTag itemFilterTag = VanillaItemCategories.Resolve(((Object)item).name); if (((Enum)item.itemTags).HasFlag((Enum)(object)(ItemTags)1)) { itemFilterTag |= ItemFilterTag.Mystical; } bool flag = ((Component)item).GetComponentsInChildren(true).Length != 0; bool flag2 = ((Component)item).GetComponentsInChildren(true).Any((Action_ModifyStatus action) => (int)action.statusType == 1); bool flag3 = ((Component)item).GetComponentsInChildren(true).Length != 0; bool flag4 = ((Enum)item.itemTags).HasFlag((Enum)(object)(ItemTags)2) || ((Enum)item.itemTags).HasFlag((Enum)(object)(ItemTags)4) || ((Enum)item.itemTags).HasFlag((Enum)(object)(ItemTags)8); itemFilterTag = ItemCategoryPolicy.ApplyConsumptionTags(itemFilterTag, flag, flag4 || flag3 || (flag && flag2)); itemFilterTag = ItemCategoryPolicy.NormalizeConsumableTag(itemFilterTag); itemFilterTag = ItemCategoryPolicy.NormalizeEquipmentTag(itemFilterTag); if (itemFilterTag == ItemFilterTag.None) { itemFilterTag = ItemFilterTag.Other; } return itemFilterTag; } } internal sealed class ItemSpawnerController : IDisposable { private readonly ManualLogSource _logger; private readonly ModConfig _settings; private readonly FavoriteStore _favorites; private readonly ItemSpawnerInput _input; private readonly ItemBrowserSession _browserSession = new ItemBrowserSession(); private ItemSpawnerWindow? _window; public ItemSpawnerController(ModConfig settings, ManualLogSource logger) { _logger = logger; _settings = settings; _favorites = new FavoriteStore(settings.FavoriteItemNamesEntry, logger); _input = new ItemSpawnerInput(settings, logger); } public void Attach() { if ((Object)(object)_window != (Object)null) { return; } try { _window = ItemSpawnerWindow.Create(_logger, _settings, _favorites, _browserSession); } catch (Exception arg) { _logger.LogError((object)$"Failed to create item spawner UI: {arg}"); } } public void Tick() { ItemSpawnerInputSnapshot input = _input.ReadSnapshot(); if ((Object)(object)_window == (Object)null) { return; } if (input.ControllerToggle) { if (_window.IsOpen || CanOpenWithController()) { _window.ToggleWindow(WindowInputSource.Controller); } } else if (input.KeyboardToggle) { _window.ToggleWindow(WindowInputSource.Keyboard); } else if (_window.IsOpen) { _window.HandleControllerInput(input); } } public void Dispose() { if ((Object)(object)_window != (Object)null) { _window.Shutdown(); Object.Destroy((Object)(object)((Component)_window).gameObject); } _window = null; _input.Dispose(); } private static bool CanOpenWithController() { GUIManager instance = GUIManager.instance; if (Time.timeScale > 0f && (Object)(object)instance != (Object)null && !instance.windowBlockingInput) { return !instance.wheelActive; } return false; } } internal readonly struct ItemSpawnerInputSnapshot { public bool KeyboardToggle { get; } public bool ControllerToggle { get; } public Vector2 Navigation { get; } public bool ConfirmPressed { get; } public bool ConfirmHeld { get; } public bool ConfirmReleased { get; } public bool CancelPressed { get; } public bool FavoritePressed { get; } public bool PreviousTargetPressed { get; } public bool NextTargetPressed { get; } public bool MouseActivity { get; } public bool ControllerActivity { get { //IL_0009: 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) if (!ControllerToggle) { Vector2 navigation = Navigation; if (!(((Vector2)(ref navigation)).sqrMagnitude >= 0.25f) && !ConfirmPressed && !CancelPressed && !FavoritePressed && !PreviousTargetPressed) { return NextTargetPressed; } } return true; } } public ItemSpawnerInputSnapshot(bool keyboardToggle, bool controllerToggle, Vector2 navigation, bool confirmPressed, bool confirmHeld, bool confirmReleased, bool cancelPressed, bool favoritePressed, bool previousTargetPressed, bool nextTargetPressed, bool mouseActivity) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) KeyboardToggle = keyboardToggle; ControllerToggle = controllerToggle; Navigation = navigation; ConfirmPressed = confirmPressed; ConfirmHeld = confirmHeld; ConfirmReleased = confirmReleased; CancelPressed = cancelPressed; FavoritePressed = favoritePressed; PreviousTargetPressed = previousTargetPressed; NextTargetPressed = nextTargetPressed; MouseActivity = mouseActivity; } } internal sealed class ItemSpawnerInput : IDisposable { private readonly ModConfig _config; private readonly ManualLogSource _logger; private InputAction? _controllerToggleAction; private string _bindingSignature = string.Empty; public ItemSpawnerInput(ModConfig config, ManualLogSource logger) { _config = config; _logger = logger; } public ItemSpawnerInputSnapshot ReadSnapshot() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00d6: Unknown result type (might be due to invalid IL or missing references) EnsureActions(); Gamepad current = Gamepad.current; Mouse current2 = Mouse.current; Vector2 navigation = ((current == null) ? Vector2.zero : Vector2.ClampMagnitude(((InputControl)(object)current.leftStick).ReadValue() + ((InputControl)(object)current.dpad).ReadValue(), 1f)); int num; if (current2 != null) { Vector2 val = ((InputControl)(object)((Pointer)current2).delta).ReadValue(); if (!(((Vector2)(ref val)).sqrMagnitude > 0.25f) && !current2.leftButton.wasPressedThisFrame && !current2.rightButton.wasPressedThisFrame && !current2.middleButton.wasPressedThisFrame) { val = ((InputControl)(object)current2.scroll).ReadValue(); num = ((((Vector2)(ref val)).sqrMagnitude > 0.01f) ? 1 : 0); } else { num = 1; } } else { num = 0; } bool mouseActivity = (byte)num != 0; KeyCode toggleKey = _config.ToggleKey; bool keyboardToggle = (int)toggleKey != 0 && Input.GetKeyDown(toggleKey); InputAction? controllerToggleAction = _controllerToggleAction; return new ItemSpawnerInputSnapshot(keyboardToggle, controllerToggleAction != null && controllerToggleAction.WasPressedThisFrame(), navigation, current != null && current.buttonSouth.wasPressedThisFrame, current != null && current.buttonSouth.isPressed, current != null && current.buttonSouth.wasReleasedThisFrame, Input.GetKeyDown((KeyCode)27) || (current != null && current.buttonEast.wasPressedThisFrame), current != null && current.buttonWest.wasPressedThisFrame, current != null && current.leftShoulder.wasPressedThisFrame, current != null && current.rightShoulder.wasPressedThisFrame, mouseActivity); } public void Dispose() { DisposeAction(); _bindingSignature = string.Empty; } private void EnsureActions() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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) string text = ControllerBindingRules.NormalizeBindingPath(_config.ControllerChordModifierPath.Value); string text2 = ControllerBindingRules.NormalizeBindingPath(_config.ControllerTogglePath.Value); string text3 = text + "\n" + text2; if (text3 == _bindingSignature) { return; } DisposeAction(); _bindingSignature = text3; if (text2.Length == 0) { return; } try { _controllerToggleAction = new InputAction("ItemSpawnerEnhanced Controller Toggle", (InputActionType)1, (string)null, (string)null, (string)null, (string)null); if (text.Length == 0) { InputActionSetupExtensions.AddBinding(_controllerToggleAction, text2, (string)null, (string)null, (string)null); } else { CompositeSyntax val = InputActionSetupExtensions.AddCompositeBinding(_controllerToggleAction, "OneModifier", (string)null, (string)null); val = ((CompositeSyntax)(ref val)).With("modifier", text, (string)null, (string)null); ((CompositeSyntax)(ref val)).With("binding", text2, (string)null, (string)null); } _controllerToggleAction.Enable(); } catch (Exception ex) { DisposeAction(); _logger.LogWarning((object)("Controller window binding is invalid and has been disabled: " + ex.Message)); } } private void DisposeAction() { if (_controllerToggleAction != null) { _controllerToggleAction.Disable(); _controllerToggleAction.Dispose(); _controllerToggleAction = null; } } } internal sealed class ModConfig { private static readonly string[] ControllerPathOptions = new string[18] { "/select", "/start", "/leftShoulder", "/rightShoulder", "/buttonSouth", "/buttonEast", "/buttonWest", "/buttonNorth", "/leftTrigger", "/rightTrigger", "/leftStickPress", "/rightStickPress", "/dpad/up", "/dpad/down", "/dpad/left", "/dpad/right", "None", "" }; private readonly ConfigEntry _toggleKey; private readonly ConfigEntry _showAllItems; private readonly ConfigEntry _singleTagSelection; private readonly ConfigEntry _tagMatchMode; private readonly ConfigEntry _favoriteItemNames; public KeyCode ToggleKey => _toggleKey.Value; public ConfigEntry ControllerChordModifierPath { get; } public ConfigEntry ControllerTogglePath { get; } public bool ShowAllItems => _showAllItems.Value; public bool SingleTagSelection => _singleTagSelection.Value; public TagMatchMode TagMatchMode => _tagMatchMode.Value; public ConfigEntry SingleTagSelectionEntry => _singleTagSelection; public ConfigEntry TagMatchModeEntry => _tagMatchMode; public ConfigEntry FavoriteItemNamesEntry => _favoriteItemNames; public ModConfig(ConfigFile config) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown _toggleKey = config.Bind("General", "ToggleKey", (KeyCode)286, "The keyboard key used to open and close the item spawner."); ControllerChordModifierPath = config.Bind("Controls", "ControllerChordModifierPath", "/select", new ConfigDescription("Controller button held as the optional modifier for the item spawner shortcut. Default: /select (Xbox View / PlayStation Share). Leave empty or set to None for a single-button shortcut.", (AcceptableValueBase)(object)new AcceptableValueList(ControllerPathOptions), Array.Empty())); ControllerTogglePath = config.Bind("Controls", "ControllerTogglePath", "/rightTrigger", new ConfigDescription("Controller button pressed with the optional modifier to open or close the item spawner. Default: /rightTrigger (Xbox RT / PlayStation R2). Leave empty or set to None to disable.", (AcceptableValueBase)(object)new AcceptableValueList(ControllerPathOptions), Array.Empty())); _showAllItems = config.Bind("Catalog", "ShowAllItems", false, "Show every item prefab registered by PEAK, including unused, test, cheat, and internal duplicate items."); _singleTagSelection = config.Bind("Filtering", "SingleTagSelection", true, "Allow only one selected filter tag at a time. Selecting another tag clears the current selection."); _tagMatchMode = config.Bind("Filtering", "TagMatchMode", TagMatchMode.And, "How selected tags are combined. And requires every selected tag; Or requires any selected tag."); _favoriteItemNames = config.Bind("Favorites", "ItemNames", "[]", "Favorite item prefab names stored as a JSON array. Manage these in the item spawner UI."); } } internal static class PatchInstaller { public static bool Install(Harmony harmony, ManualLogSource logger) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(typeof(GUIManager), "Start", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(PatchCallbacks), "GuiManagerStartPostfix", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { return false; } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); return true; } catch (Exception arg) { logger.LogError((object)$"Failed to patch GUIManager.Start: {arg}"); return false; } } } internal static class PatchCallbacks { public static void GuiManagerStartPostfix() { Plugin.Instance?.Attach(); } } internal sealed class PlayerTargetService { private static readonly MethodInfo? SpawnItemMethod = AccessTools.Method(typeof(CharacterItems), "SpawnItemInHand", new Type[1] { typeof(string) }, (Type[])null); private readonly ManualLogSource _logger; public PlayerTargetService(ManualLogSource logger) { _logger = logger; } public PlayerTargetSnapshot Capture() { Character[] playerCharacters = GetPlayerCharacters(); Character specCharacter = MainCameraMovement.specCharacter; List list = new List(playerCharacters.Length); TargetCandidate[] array = new TargetCandidate[playerCharacters.Length]; for (int i = 0; i < playerCharacters.Length; i++) { Character val = playerCharacters[i]; int actorId = GetActorId(val); bool canReceiveItem = CanReceiveItem(val); bool isLocal = (Object)(object)val == (Object)(object)Character.localCharacter; bool isSpectated = (Object)(object)val == (Object)(object)specCharacter; bool isSelectable = IsSelectable(actorId, canReceiveItem); array[i] = new TargetCandidate(actorId, isLocal, isSpectated, isSelectable, canReceiveItem); if (actorId > 0) { list.Add(new PlayerTarget(actorId, val.characterName, isLocal, isSpectated, isSelectable)); } } PlayerTarget[] targets = list.OrderByDescending((PlayerTarget target) => target.IsLocal).ThenBy((PlayerTarget target) => target.Name, StringComparer.OrdinalIgnoreCase).ToArray(); return new PlayerTargetSnapshot(playerCharacters, array, targets); } public bool TrySpawn(Item item, int? manualActorId, out string errorKey) { if (!PhotonNetwork.IsConnected) { errorKey = "notConnected"; return false; } Character val = Capture().Resolve(manualActorId); if ((Object)(object)val == (Object)null) { errorKey = "noTarget"; return false; } try { if (SpawnItemMethod == null) { throw new MissingMethodException(typeof(CharacterItems).FullName, "SpawnItemInHand"); } SpawnItemMethod.Invoke(val.refs.items, new object[1] { ((Object)item).name }); _logger.LogInfo((object)("Spawned '" + ((Object)item).name + "' for '" + val.characterName + "'.")); errorKey = string.Empty; return true; } catch (Exception arg) { _logger.LogError((object)$"Failed to spawn '{((Object)item).name}': {arg}"); errorKey = "spawnFailed"; return false; } } private static bool IsPlayerCharacter(Character? character) { if ((Object)(object)character != (Object)null) { return !character.isBot; } return false; } private static Character[] GetPlayerCharacters() { return PlayerHandler.GetAllPlayerCharacters().Where(IsPlayerCharacter).ToArray(); } private static bool CanReceiveItem(Character? character) { if (IsPlayerCharacter(character) && character.refs != null) { return (Object)(object)character.refs.items != (Object)null; } return false; } private static bool IsSelectable(int actorId, bool canReceiveItem) { return actorId > 0 && canReceiveItem; } private static int GetActorId(Character character) { try { PhotonView photonView = ((MonoBehaviourPun)character).photonView; return (photonView != null) ? photonView.OwnerActorNr : (-1); } catch { return -1; } } } internal sealed class PlayerTargetSnapshot { private readonly Character[] _characters; private readonly TargetCandidate[] _candidates; public IReadOnlyList Targets { get; } public PlayerTargetSnapshot(Character[] characters, TargetCandidate[] candidates, IReadOnlyList targets) { _characters = characters; _candidates = candidates; Targets = targets; } public Character? Resolve(int? manualActorId) { int? num = TargetResolver.ResolveIndex(_candidates, manualActorId); if (!num.HasValue) { return null; } return _characters[num.Value]; } } internal readonly struct PlayerTarget { public int ActorId { get; } public string Name { get; } public bool IsLocal { get; } public bool IsSpectated { get; } public bool IsSelectable { get; } public PlayerTarget(int actorId, string name, bool isLocal, bool isSpectated, bool isSelectable) { ActorId = actorId; Name = name; IsLocal = isLocal; IsSpectated = isSpectated; IsSelectable = isSelectable; } } [BepInPlugin("com.github.lllei.ItemSpawnerEnhanced", "ItemSpawnerEnhanced", "1.3.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.github.lllei.ItemSpawnerEnhanced"; public const string PluginName = "ItemSpawnerEnhanced"; private Harmony? _harmony; private ItemSpawnerController? _controller; internal static Plugin? Instance { get; private set; } private void Awake() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown Instance = this; ModConfig settings = new ModConfig(((BaseUnityPlugin)this).Config); _controller = new ItemSpawnerController(settings, ((BaseUnityPlugin)this).Logger); _harmony = new Harmony("com.github.lllei.ItemSpawnerEnhanced"); if (!PatchInstaller.Install(_harmony, ((BaseUnityPlugin)this).Logger)) { ((BaseUnityPlugin)this).Logger.LogError((object)"Item spawner UI is disabled because GUIManager.Start could not be patched."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"ItemSpawnerEnhanced 1.3.0 loaded for PEAK 2.1.a baseline."); } private void Update() { _controller?.Tick(); } internal void Attach() { _controller?.Attach(); } private void OnDestroy() { _controller?.Dispose(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } RuntimeUiAssets.Release(); Instance = null; } } internal static class BuildInfo { internal const string Version = "1.3.0"; } } namespace ItemSpawnerEnhanced.UI { internal sealed class ControlInteractionState : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler { public bool Focused { get; private set; } public bool Hovered { get; private set; } public bool Pressed { get; private set; } public event Action? Changed; public void SetFocused(bool focused) { if (Focused != focused) { Focused = focused; this.Changed?.Invoke(); } } public void SetControllerPressed(bool pressed) { if (Pressed != pressed) { Pressed = pressed; this.Changed?.Invoke(); } } public void OnPointerEnter(PointerEventData eventData) { Hovered = true; this.Changed?.Invoke(); } public void OnPointerExit(PointerEventData eventData) { Hovered = false; Pressed = false; this.Changed?.Invoke(); } public void OnPointerDown(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)eventData.button == 0) { Pressed = true; this.Changed?.Invoke(); } } public void OnPointerUp(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)eventData.button == 0) { Pressed = false; this.Changed?.Invoke(); if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)EventSystem.current.currentSelectedGameObject == (Object)(object)((Component)this).gameObject) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } } private void OnDisable() { Focused = false; Hovered = false; Pressed = false; this.Changed?.Invoke(); } } internal sealed class ActionButtonVisual { private readonly Button _button; private readonly Image _background; private readonly Graphic _foreground; private readonly Image _focusFrame; private readonly ControlInteractionState _interaction; private bool _enabled = true; public Button Button => _button; public bool Enabled => _enabled; public ActionButtonVisual(Button button, Image background, Graphic foreground) { _button = button; _background = background; _foreground = foreground; _focusFrame = RuntimeUiFactory.CreateFocusFrame(((Component)button).transform); _interaction = ((Component)button).gameObject.AddComponent(); _interaction.Changed += Render; ((Selectable)_button).transition = (Transition)0; Render(); } public void SetEnabled(bool enabled) { _enabled = enabled; ((Selectable)_button).interactable = enabled; Render(); } public void SetFocused(bool focused) { _interaction.SetFocused(focused && _enabled); } public void SetControllerPressed(bool pressed) { _interaction.SetControllerPressed(pressed && _enabled); } private void Render() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) ControlVisualState controlVisualState = ControllerVisualState.ForAction(_enabled, _interaction.Focused, _interaction.Hovered, _interaction.Pressed); ((Graphic)_background).color = RuntimeUiFactory.ResolvePalette(controlVisualState.Background); _foreground.color = (Color)(_enabled ? RuntimeUiFactory.ResolvePalette(controlVisualState.Foreground) : new Color(RuntimeUiFactory.TextMuted.r, RuntimeUiFactory.TextMuted.g, RuntimeUiFactory.TextMuted.b, 0.35f)); ((Component)_focusFrame).gameObject.SetActive(controlVisualState.ShowFocus); } } internal sealed class ControllerFocusCoordinator { private const float NavigationDeadZone = 0.55f; private const float InitialRepeatDelay = 0.35f; private const float RepeatInterval = 0.1f; private readonly ItemSpawnerView _view; private readonly Action _close; private ControllerFocusLocation _focus; private ControllerFocusLocation _lastFocus; private ControllerFocusLocation _lastTagFocus; private ControllerFocusLocation _lastItemFocus; private ControllerNavigationDirection? _heldDirection; private float _nextNavigationAt; private TagToggle? _pressedTag; private ItemTile? _pressedTile; private bool _tagClearPressed; private bool _controllerMode; private bool _windowOpen; public ControllerFocusCoordinator(ItemSpawnerView view, Action close) { _view = view; _close = close; } public void OpenWithController() { _windowOpen = true; _controllerMode = true; _heldDirection = null; ClearEventSystemSelection(); RestoreFocus(preferFirstItem: true); } public void OpenWithoutController() { _windowOpen = true; _controllerMode = false; _heldDirection = null; ClearFocusVisual(_focus); } public void Close() { ReleasePressedControl(); if (_view.TargetDropdown.Dropdown.IsExpanded) { _view.TargetDropdown.Dropdown.Hide(); } _view.TargetDropdown.SetExpanded(expanded: false); ClearFocusVisual(_focus); ClearDropdownOptionFocus(); _view.HideTooltip(); _windowOpen = false; _controllerMode = false; _heldDirection = null; if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)EventSystem.current.currentSelectedGameObject != (Object)null && EventSystem.current.currentSelectedGameObject.transform.IsChildOf(_view.Root.transform)) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } public void Tick(ItemSpawnerInputSnapshot input) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (!_windowOpen) { return; } SyncDropdownState(); if (input.MouseActivity) { SetControllerMode(controllerMode: false); } if (input.ControllerActivity) { SetControllerMode(controllerMode: true); } ValidateFocus(); if (input.CancelPressed) { if (_view.TargetDropdown.Expanded) { CollapseDropdown(); } else { _close(); } } else { if (!_controllerMode) { return; } if (input.ConfirmPressed) { ClearEventSystemSelection(); } ControllerNavigationDirection? direction = ReadDirection(input.Navigation); if (ShouldNavigate(direction)) { Move(direction.Value); } if (!_view.TargetDropdown.Expanded) { if (input.PreviousTargetPressed) { SwitchRegion(-1); } if (input.NextTargetPressed) { SwitchRegion(1); } if (input.FavoritePressed) { ToggleFocusedFavorite(); } } if (input.ConfirmPressed) { ActivateFocusedControl(); } if (input.ConfirmReleased || !input.ConfirmHeld) { ReleasePressedControl(); } } } private void SetControllerMode(bool controllerMode) { if (_controllerMode != controllerMode) { _controllerMode = controllerMode; if (controllerMode) { ClearEventSystemSelection(); RestoreFocus(preferFirstItem: false); return; } ReleasePressedControl(); ClearFocusVisual(_focus); ClearDropdownOptionFocus(); _view.HideTooltip(); } } private void RestoreFocus(bool preferFirstItem) { if (_focus.Kind != ControllerFocusKind.None) { ApplyFocus(_focus, remember: false); return; } if (!preferFirstItem && _lastFocus.Kind != ControllerFocusKind.None) { ApplyFocus(_lastFocus, remember: false); return; } IReadOnlyList visibleTiles = _view.VisibleTiles; ApplyFocus((visibleTiles.Count > 0) ? ControllerFocusLocation.ForItem(0, ((Object)visibleTiles[0].Record.Item).name) : ControllerFocusLocation.PendingFirstItem(), remember: false); } private void ValidateFocus() { if (!_controllerMode) { return; } switch (_focus.Kind) { case ControllerFocusKind.Item: { IReadOnlyList visibleTiles = _view.VisibleTiles; if (visibleTiles.Count == 0) { ClearFocusVisual(_focus); _view.HideTooltip(); break; } int num = FindFocusedItemIndex(visibleTiles); if (num >= 0) { if (num != _focus.Index) { _focus = ControllerFocusLocation.ForItem(num, _focus.ItemName); } } else { int index = ControllerNavigation.ResolveFallbackIndex(_focus.Index, visibleTiles.Count); ApplyFocus(ControllerFocusLocation.ForItem(index, ((Object)visibleTiles[index].Record.Item).name), remember: true); } break; } case ControllerFocusKind.ClearTags: if (!_view.TagClear.Enabled) { ApplyFocus(ControllerFocusLocation.ForTag(_view.TagToggles.Count - 1), remember: true); } break; case ControllerFocusKind.DropdownOption: if (!_view.TargetDropdown.Expanded) { ApplyFocus(ControllerFocusLocation.Target(), remember: true); } break; case ControllerFocusKind.None: RestoreFocus(preferFirstItem: true); break; case ControllerFocusKind.Target: case ControllerFocusKind.Tag: break; } } private bool ShouldNavigate(ControllerNavigationDirection? direction) { if (!direction.HasValue) { _heldDirection = null; return false; } float unscaledTime = Time.unscaledTime; if (_heldDirection != direction) { _heldDirection = direction; _nextNavigationAt = unscaledTime + 0.35f; return true; } if (unscaledTime < _nextNavigationAt) { return false; } _nextNavigationAt = unscaledTime + 0.1f; return true; } private void Move(ControllerNavigationDirection direction) { if (_view.TargetDropdown.Expanded) { switch (direction) { case ControllerNavigationDirection.Up: MoveDropdownOption(-1); break; case ControllerNavigationDirection.Down: MoveDropdownOption(1); break; } return; } switch (_focus.Kind) { case ControllerFocusKind.Target: if (direction == ControllerNavigationDirection.Down) { FocusNearestTag(GetHorizontalCenter(((Component)_view.TargetDropdown.Dropdown).transform)); } break; case ControllerFocusKind.Tag: MoveFromTag(direction); break; case ControllerFocusKind.ClearTags: MoveFromClearTags(direction); break; case ControllerFocusKind.Item: MoveFromItem(direction); break; default: RestoreFocus(preferFirstItem: true); break; } } private void MoveFromTag(ControllerNavigationDirection direction) { int num = Math.Clamp(_focus.Index, 0, _view.TagToggles.Count - 1); switch (direction) { case ControllerNavigationDirection.Left: if (num > 0) { ApplyFocus(ControllerFocusLocation.ForTag(num - 1), remember: true); } break; case ControllerNavigationDirection.Right: if (num + 1 < _view.TagToggles.Count) { ApplyFocus(ControllerFocusLocation.ForTag(num + 1), remember: true); } else if (_view.TagClear.Enabled) { ApplyFocus(ControllerFocusLocation.ClearTags(), remember: true); } break; case ControllerNavigationDirection.Up: ApplyFocus(ControllerFocusLocation.Target(), remember: true); break; case ControllerNavigationDirection.Down: FocusNearestItem(GetHorizontalCenter(((Component)_view.TagToggles[num].Toggle).transform)); break; } } private void MoveFromClearTags(ControllerNavigationDirection direction) { switch (direction) { case ControllerNavigationDirection.Left: ApplyFocus(ControllerFocusLocation.ForTag(_view.TagToggles.Count - 1), remember: true); break; case ControllerNavigationDirection.Up: ApplyFocus(ControllerFocusLocation.Target(), remember: true); break; case ControllerNavigationDirection.Down: FocusNearestItem(GetHorizontalCenter(((Component)_view.TagClear.Button).transform)); break; case ControllerNavigationDirection.Right: break; } } private void MoveFromItem(ControllerNavigationDirection direction) { IReadOnlyList visibleTiles = _view.VisibleTiles; int num = FindFocusedItemIndex(visibleTiles); if (num < 0) { return; } int num2 = CalculateColumnCount(); if (direction == ControllerNavigationDirection.Up && num < num2) { FocusNearestTag(GetHorizontalCenter((Transform)(object)visibleTiles[num].RectTransform)); return; } int num3 = ControllerNavigation.MoveInGrid(num, visibleTiles.Count, num2, direction); if (num3 != num) { ApplyFocus(ControllerFocusLocation.ForItem(num3, ((Object)visibleTiles[num3].Record.Item).name), remember: true); } } private void FocusNearestTag(float horizontalPosition) { List list = _view.TagToggles.Select((TagToggle tag) => GetHorizontalCenter(((Component)tag.Toggle).transform)).ToList(); if (_view.TagClear.Enabled) { list.Add(GetHorizontalCenter(((Component)_view.TagClear.Button).transform)); } int num = ControllerNavigation.FindNearest(horizontalPosition, list); if (num >= 0) { ApplyFocus((num < _view.TagToggles.Count) ? ControllerFocusLocation.ForTag(num) : ControllerFocusLocation.ClearTags(), remember: true); } } private void FocusNearestItem(float horizontalPosition) { IReadOnlyList visibleTiles = _view.VisibleTiles; if (visibleTiles.Count != 0) { int count = Math.Min(CalculateColumnCount(), visibleTiles.Count); float[] candidates = (from tile in visibleTiles.Take(count) select GetHorizontalCenter((Transform)(object)tile.RectTransform)).ToArray(); int index = ControllerNavigation.FindNearest(horizontalPosition, candidates); ApplyFocus(ControllerFocusLocation.ForItem(index, ((Object)visibleTiles[index].Record.Item).name), remember: true); } } private void ActivateFocusedControl() { switch (_focus.Kind) { case ControllerFocusKind.Target: ExpandDropdown(); break; case ControllerFocusKind.Tag: if (_focus.Index >= 0 && _focus.Index < _view.TagToggles.Count) { TagToggle tagToggle = _view.TagToggles[_focus.Index]; tagToggle.SetControllerPressed(pressed: true); _pressedTag = tagToggle; tagToggle.Toggle.isOn = !tagToggle.Toggle.isOn; } break; case ControllerFocusKind.ClearTags: if (_view.TagClear.Enabled) { _view.TagClear.SetControllerPressed(pressed: true); _tagClearPressed = true; ((UnityEvent)_view.TagClear.Button.onClick).Invoke(); ValidateFocus(); } break; case ControllerFocusKind.Item: { ItemTile itemTile = ResolveFocusedItem(); if (itemTile != null && itemTile.CanSpawn) { itemTile.BeginControllerSubmit(); _pressedTile = itemTile; } break; } case ControllerFocusKind.DropdownOption: SelectDropdownOption(); break; } } private void ReleasePressedControl() { if (_pressedTag != null) { _pressedTag.SetControllerPressed(pressed: false); } if (_tagClearPressed) { _view.TagClear.SetControllerPressed(pressed: false); } if (_pressedTile != null && (Object)(object)_pressedTile.GameObject != (Object)null) { _pressedTile.EndControllerSubmit(); } _pressedTag = null; _pressedTile = null; _tagClearPressed = false; } private void ToggleFocusedFavorite() { ItemTile? itemTile = ResolveFocusedItem(); if (itemTile != null && itemTile.TryToggleFavorite()) { ValidateFocus(); } } private void SwitchRegion(int direction) { bool[] availableRegions = new bool[3] { _view.TargetDropdown.Enabled, _view.TagToggles.Count > 0, _view.VisibleTiles.Count > 0 }; int num; switch (_focus.Kind) { case ControllerFocusKind.Target: case ControllerFocusKind.DropdownOption: num = 0; break; case ControllerFocusKind.Tag: case ControllerFocusKind.ClearTags: num = 1; break; case ControllerFocusKind.Item: num = 2; break; default: num = 2; break; } int num2 = num; int num3 = ControllerNavigation.MoveRegion(num2, direction, availableRegions); if (num3 >= 0 && num3 != num2) { switch (num3) { case 0: ApplyFocus(ControllerFocusLocation.Target(), remember: true); break; case 1: RestoreTagRegionFocus(); break; case 2: RestoreItemRegionFocus(); break; } } } private void RestoreTagRegionFocus() { if (_lastTagFocus.Kind == ControllerFocusKind.ClearTags && _view.TagClear.Enabled) { ApplyFocus(_lastTagFocus, remember: true); return; } int index = ((_lastTagFocus.Kind == ControllerFocusKind.Tag) ? Math.Clamp(_lastTagFocus.Index, 0, _view.TagToggles.Count - 1) : 0); ApplyFocus(ControllerFocusLocation.ForTag(index), remember: true); } private void RestoreItemRegionFocus() { IReadOnlyList visibleTiles = _view.VisibleTiles; if (visibleTiles.Count != 0) { int num = FindItemIndex(visibleTiles, _lastItemFocus); if (num < 0) { num = ControllerNavigation.ResolveFallbackIndex(_lastItemFocus.Index, visibleTiles.Count); } ApplyFocus(ControllerFocusLocation.ForItem(num, ((Object)visibleTiles[num].Record.Item).name), remember: true); } } private void ExpandDropdown() { TMP_Dropdown dropdown = _view.TargetDropdown.Dropdown; if (((UIBehaviour)dropdown).IsActive() && ((Selectable)dropdown).IsInteractable()) { dropdown.Show(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } Canvas.ForceUpdateCanvases(); _view.TargetDropdown.SetExpanded(dropdown.IsExpanded); if (dropdown.IsExpanded) { int index = Math.Clamp(dropdown.value, 0, Math.Max(0, dropdown.options.Count - 1)); ApplyFocus(ControllerFocusLocation.DropdownOption(index), remember: false); } } } private void CollapseDropdown() { _view.TargetDropdown.Dropdown.Hide(); _view.TargetDropdown.SetExpanded(expanded: false); ClearDropdownOptionFocus(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } ApplyFocus(ControllerFocusLocation.Target(), remember: true); } private void MoveDropdownOption(int delta) { IReadOnlyList visibleOptions = _view.TargetDropdown.GetVisibleOptions(); if (visibleOptions.Count != 0) { int num = Math.Clamp(_focus.Index + delta, 0, visibleOptions.Count - 1); if (num != _focus.Index) { ApplyFocus(ControllerFocusLocation.DropdownOption(num), remember: false); } } } private void SelectDropdownOption() { TMP_Dropdown dropdown = _view.TargetDropdown.Dropdown; if (_focus.Index >= 0 && _focus.Index < dropdown.options.Count) { dropdown.value = _focus.Index; } CollapseDropdown(); } private void SyncDropdownState() { bool isExpanded = _view.TargetDropdown.Dropdown.IsExpanded; if (isExpanded != _view.TargetDropdown.Expanded) { _view.TargetDropdown.SetExpanded(isExpanded); if (!isExpanded && _focus.Kind == ControllerFocusKind.DropdownOption) { ApplyFocus(ControllerFocusLocation.Target(), remember: true); } } } private void ApplyFocus(ControllerFocusLocation next, bool remember) { ReleasePressedControl(); ClearFocusVisual(_focus); ClearDropdownOptionFocus(); _view.HideTooltip(); _focus = next; ControllerFocusKind kind = next.Kind; if ((uint)(kind - 2) <= 1u) { _lastTagFocus = next; } else if (next.Kind == ControllerFocusKind.Item) { _lastItemFocus = next; } if (remember && next.Kind != ControllerFocusKind.DropdownOption) { _lastFocus = next; } if (_controllerMode) { SetFocusVisual(next); } } private void SetFocusVisual(ControllerFocusLocation location) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown switch (location.Kind) { case ControllerFocusKind.Target: _view.TargetDropdown.SetFocused(focused: true); break; case ControllerFocusKind.Tag: if (location.Index >= 0 && location.Index < _view.TagToggles.Count) { _view.TagToggles[location.Index].SetFocused(focused: true); } break; case ControllerFocusKind.ClearTags: if (_view.TagClear.Enabled) { _view.TagClear.SetFocused(focused: true); } break; case ControllerFocusKind.Item: { ItemTile itemTile = ResolveFocusedItem(); if (itemTile != null) { itemTile.SetFocused(focused: true); EnsureItemVisible(itemTile); if (itemTile.HasTruncatedName()) { _view.ShowControllerTooltip(itemTile); } } break; } case ControllerFocusKind.DropdownOption: { IReadOnlyList visibleOptions = _view.TargetDropdown.GetVisibleOptions(); if (location.Index >= 0 && location.Index < visibleOptions.Count) { visibleOptions[location.Index].SetFocused(focused: true); ScrollRect componentInParent = ((Component)visibleOptions[location.Index]).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { EnsureVisible(componentInParent, (RectTransform)((Component)visibleOptions[location.Index]).transform); } } break; } } } private void ClearFocusVisual(ControllerFocusLocation location) { switch (location.Kind) { case ControllerFocusKind.Target: _view.TargetDropdown.SetFocused(focused: false); break; case ControllerFocusKind.Tag: if (location.Index >= 0 && location.Index < _view.TagToggles.Count) { _view.TagToggles[location.Index].SetFocused(focused: false); } break; case ControllerFocusKind.ClearTags: _view.TagClear.SetFocused(focused: false); break; case ControllerFocusKind.Item: ResolveFocusedItem()?.SetFocused(focused: false); break; } } private void ClearDropdownOptionFocus() { foreach (DropdownOptionVisual visibleOption in _view.TargetDropdown.GetVisibleOptions()) { visibleOption.SetFocused(focused: false); } } private ItemTile? ResolveFocusedItem() { IReadOnlyList visibleTiles = _view.VisibleTiles; int num = FindFocusedItemIndex(visibleTiles); if (num < 0) { return null; } return visibleTiles[num]; } private int FindFocusedItemIndex(IReadOnlyList tiles) { return FindItemIndex(tiles, _focus); } private static int FindItemIndex(IReadOnlyList tiles, ControllerFocusLocation location) { if (!string.IsNullOrEmpty(location.ItemName)) { if (location.Index >= 0 && location.Index < tiles.Count && string.Equals(((Object)tiles[location.Index].Record.Item).name, location.ItemName, StringComparison.Ordinal)) { return location.Index; } for (int i = 0; i < tiles.Count; i++) { if (string.Equals(((Object)tiles[i].Record.Item).name, location.ItemName, StringComparison.Ordinal)) { return i; } } } return -1; } private int CalculateColumnCount() { //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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) Canvas.ForceUpdateCanvases(); GridLayoutGroup component = ((Component)_view.ItemContent).GetComponent(); Rect rect = _view.ItemContent.rect; float num = ((Rect)(ref rect)).width - (float)((LayoutGroup)component).padding.horizontal; return Math.Max(1, Mathf.FloorToInt((num + component.spacing.x) / (component.cellSize.x + component.spacing.x))); } private void EnsureItemVisible(ItemTile tile) { EnsureVisible(_view.ItemScroll, tile.RectTransform); } private static void EnsureVisible(ScrollRect scroll, RectTransform target) { //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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) Canvas.ForceUpdateCanvases(); RectTransform viewport = scroll.viewport; RectTransform content = scroll.content; Bounds val = RectTransformUtility.CalculateRelativeRectTransformBounds((Transform)(object)viewport, (Transform)(object)target); float num = content.anchoredPosition.y; float y = ((Bounds)(ref val)).min.y; Rect rect = viewport.rect; if (y < ((Rect)(ref rect)).yMin) { float num2 = num; rect = viewport.rect; num = num2 + (((Rect)(ref rect)).yMin - ((Bounds)(ref val)).min.y); } else { float y2 = ((Bounds)(ref val)).max.y; rect = viewport.rect; if (y2 > ((Rect)(ref rect)).yMax) { float num3 = num; float y3 = ((Bounds)(ref val)).max.y; rect = viewport.rect; num = num3 - (y3 - ((Rect)(ref rect)).yMax); } } rect = content.rect; float height = ((Rect)(ref rect)).height; rect = viewport.rect; float num4 = Math.Max(0f, height - ((Rect)(ref rect)).height); content.anchoredPosition = new Vector2(content.anchoredPosition.x, Mathf.Clamp(num, 0f, num4)); } private static float GetHorizontalCenter(Transform transform) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val == null) { return transform.position.x; } Vector3[] array = (Vector3[])(object)new Vector3[4]; val.GetWorldCorners(array); return (array[0].x + array[2].x) * 0.5f; } private static ControllerNavigationDirection? ReadDirection(Vector2 navigation) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) if (((Vector2)(ref navigation)).sqrMagnitude < 0.3025f) { return null; } if (Mathf.Abs(navigation.x) > Mathf.Abs(navigation.y)) { return (!(navigation.x < 0f)) ? ControllerNavigationDirection.Right : ControllerNavigationDirection.Left; } return (navigation.y < 0f) ? ControllerNavigationDirection.Down : ControllerNavigationDirection.Up; } private void ClearEventSystemSelection() { if (!((Object)(object)EventSystem.current == (Object)null) && !((Object)(object)EventSystem.current.currentSelectedGameObject == (Object)null) && EventSystem.current.currentSelectedGameObject.transform.IsChildOf(_view.Root.transform)) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } } internal enum ControllerFocusKind { None, Target, Tag, ClearTags, Item, DropdownOption } internal readonly struct ControllerFocusLocation { public ControllerFocusKind Kind { get; } public int Index { get; } public string? ItemName { get; } private ControllerFocusLocation(ControllerFocusKind kind, int index, string? itemName) { Kind = kind; Index = index; ItemName = itemName; } public static ControllerFocusLocation Target() { return new ControllerFocusLocation(ControllerFocusKind.Target, 0, null); } public static ControllerFocusLocation ForTag(int index) { return new ControllerFocusLocation(ControllerFocusKind.Tag, index, null); } public static ControllerFocusLocation ClearTags() { return new ControllerFocusLocation(ControllerFocusKind.ClearTags, 0, null); } public static ControllerFocusLocation ForItem(int index, string? itemName) { return new ControllerFocusLocation(ControllerFocusKind.Item, index, itemName); } public static ControllerFocusLocation PendingFirstItem() { return ForItem(0, null); } public static ControllerFocusLocation DropdownOption(int index) { return new ControllerFocusLocation(ControllerFocusKind.DropdownOption, index, null); } } internal static class ItemBrowserControlFactory { public static TagToggle CreateTagToggle(Transform parent, TMP_FontAsset font, ItemFilterTag tag) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0147: Unknown result type (might be due to invalid IL or missing references) RectTransform val = RuntimeUiFactory.CreateRect(tag.ToString(), parent, typeof(Image), typeof(Toggle), typeof(LayoutElement)); LayoutElement component = ((Component)val).GetComponent(); component.minHeight = 52f; component.flexibleWidth = 1f; Image component2 = ((Component)val).GetComponent(); RuntimeUiFactory.ApplyRoundedCorners(component2); Toggle component3 = ((Component)val).GetComponent(); ((Selectable)component3).targetGraphic = (Graphic)(object)component2; component3.graphic = null; TextMeshProUGUI val2 = RuntimeUiFactory.CreateText("Label", (Transform)(object)val, font, 17f, RuntimeUiFactory.TextPrimary, (TextAlignmentOptions)514); ((TMP_Text)val2).maxVisibleLines = 2; RawImage val3 = null; if (tag == ItemFilterTag.Favorite) { RectTransform obj = RuntimeUiFactory.CreateRect("Heart", (Transform)(object)val, typeof(RawImage)); obj.anchorMin = new Vector2(0f, 0.5f); obj.anchorMax = new Vector2(0f, 0.5f); obj.pivot = new Vector2(0f, 0.5f); obj.anchoredPosition = new Vector2(11f, 0f); obj.sizeDelta = new Vector2(18f, 18f); val3 = ((Component)obj).GetComponent(); val3.texture = (Texture)(object)RuntimeUiAssets.HeartTexture; ((Graphic)val3).color = RuntimeUiFactory.TextPrimary; ((Graphic)val3).raycastTarget = false; RuntimeUiFactory.Stretch(((TMP_Text)val2).rectTransform, 28f, 5f, 2f, 2f); } else { RuntimeUiFactory.Stretch(((TMP_Text)val2).rectTransform, 5f, 5f, 2f, 2f); } TagToggle tagToggle = new TagToggle(tag, component3, component2, (TMP_Text)(object)val2, val3); tagToggle.SetActive(active: false); return tagToggle; } public static ItemNameTooltip CreateItemTooltip(RectTransform parent, TMP_FontAsset font) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) RectTransform val = RuntimeUiFactory.CreateRect("ItemTooltip", (Transform)(object)parent, typeof(Image)); val.anchorMin = new Vector2(0.5f, 0.5f); val.anchorMax = new Vector2(0.5f, 0.5f); val.pivot = new Vector2(0f, 1f); Image component = ((Component)val).GetComponent(); RuntimeUiFactory.ApplyRoundedCorners(component); ((Graphic)component).color = new Color(0.27f, 0.29f, 0.3f, 0.98f); ((Graphic)component).raycastTarget = false; TextMeshProUGUI val2 = RuntimeUiFactory.CreateText("Label", (Transform)(object)val, font, 20f, RuntimeUiFactory.TextPrimary, (TextAlignmentOptions)4097); ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; RuntimeUiFactory.Stretch(((TMP_Text)val2).rectTransform, 12f, 12f, 8f, 8f); ItemNameTooltip itemNameTooltip = ((Component)parent).gameObject.AddComponent(); itemNameTooltip.Configure(parent, val, val2); return itemNameTooltip; } public static ItemTile CreateItemTile(Transform parent, TMP_FontAsset font, GameItemRecord record, UnityAction onClick, UnityAction onFavorite, bool isFavorite, ItemNameTooltip tooltip) { //IL_0040: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) RectTransform val = RuntimeUiFactory.CreateRect(((Object)record.Item).name, parent, typeof(Image), typeof(Button)); Image component = ((Component)val).GetComponent(); RuntimeUiFactory.ApplyRoundedCorners(component); ((Graphic)component).color = RuntimeUiFactory.Surface; Button component2 = ((Component)val).GetComponent