Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of QoLChests v1.3.1
QoLChests.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.Barrel; using Faust.QoLChests; using Faust.QoLChests.Components; using Faust.QoLChests.Configs; using Faust.QoLChests.Handlers; using Faust.QoLChests.Hooks; using Faust.Shared; using Faust.Shared.Compatability; using Microsoft.CodeAnalysis; using On.EntityStates.Barrel; using On.RoR2; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.ExpansionManagement; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [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("QoLChests")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5f23eeeb671dd7b17fbfe49684ff265481521fef")] [assembly: AssemblyProduct("QoLChests")] [assembly: AssemblyTitle("QoLChests")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } internal static class HunkCompatHandler { public static void Register() { InteractableRegistry.BlackList("HunkTerminal"); } } internal static class StarStorm2CompatHandler { public static void Register() { InteractableRegistry.Register("ShockDroneBroken", InteractableCategory.Drone); InteractableRegistry.Register("CloneDroneBroken", InteractableCategory.Drone); InteractableRegistry.Register("DroneTablePrefab", InteractableCategory.Duplicator); } } public static class InteractableStateHandler { private static List<GameObject> TrackedSceneInteractables { get; set; } = new List<GameObject>(); private static List<GameObject> TrackedInteractables { get; set; } = new List<GameObject>(); public static List<GameObject> InteractablesToHighlight { get; set; } = new List<GameObject>(); public static void Reset() { List<GameObject> interactablesToHighlight = InteractablesToHighlight; List<GameObject> trackedSceneInteractables = TrackedSceneInteractables; List<GameObject> trackedInteractables = TrackedInteractables; int num = 0; GameObject[] array = (GameObject[])(object)new GameObject[interactablesToHighlight.Count + trackedSceneInteractables.Count + trackedInteractables.Count]; foreach (GameObject item in interactablesToHighlight) { array[num] = item; num++; } foreach (GameObject item2 in trackedSceneInteractables) { array[num] = item2; num++; } foreach (GameObject item3 in trackedInteractables) { array[num] = item3; num++; } HighlightHandler.Disable(array); TrackedSceneInteractables.Clear(); InteractablesToHighlight.Clear(); TrackInteractables(); } public static void Init() { LoadHighlightableResources(); } private static void TrackInteractables() { if (InteractablesToHighlight.Count > 0) { Log.LogWarning("InteractablesToHighlight is not empty - Call Reset() before calling TrackInteractables()"); return; } GameObject[] array = (from x in Object.FindObjectsOfType<InteractableHighlightCategoryMarker>() select ((Component)x).gameObject).Concat(TrackedInteractables).ToArray(); Log.LogDebug($"Configuring highlights - {array.Length} tracked interactables"); GameObject[] array2 = array; foreach (GameObject val in array2) { if (Object.op_Implicit((Object)(object)val)) { InteractableHighlightCategoryMarker component = val.GetComponent<InteractableHighlightCategoryMarker>(); if (!Object.op_Implicit((Object)(object)component)) { Log.LogWarning("Interactable " + ((Object)val).name + " does not have a HighlightCategoryMarker - why are we tracking it?"); } else if (ModConfig.Instance.IsCategoryHighlightEnabled(component.Category)) { InteractablesToHighlight.Add(val); } } } Log.LogDebug($"Configuring highlights - {array.Length} tracked interactables out of which {InteractablesToHighlight.Count} will be highlighted"); foreach (GameObject item in InteractablesToHighlight) { HideWithDelay component2 = item.GetComponent<HideWithDelay>(); FadeWithDelay component3 = item.GetComponent<FadeWithDelay>(); InteractableUsed component4 = item.GetComponent<InteractableUsed>(); if (!Object.op_Implicit((Object)(object)component3) && !Object.op_Implicit((Object)(object)component2) && !Object.op_Implicit((Object)(object)component4)) { HighlightHandler.Enable(item); } } } private static void LoadHighlightableResources() { AddResourcesToHighlights(Constants.ChestResourcesPaths); AddResourcesToHighlights(Constants.LockboxResourcesPaths); AddResourcesToHighlights(Constants.StealthedChestResourcePaths); AddResourcesToHighlights(Constants.ShopResourcePaths); AddResourcesToHighlights(Constants.ScrapperResourcePaths); AddResourcesToHighlights(Constants.DuplicatorResourcesPaths); AddResourcesToHighlights(Constants.DroneResourcesPaths); AddResourcesToHighlights(Constants.TurrentResourcePaths); AddResourcesToHighlights(Constants.ArtifactOfDevotionResourcePaths); } private static void AddResourcesToHighlights(HighlightableResource[] resources) { //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) for (int i = 0; i < resources.Length; i++) { HighlightableResource highlightableResource = resources[i]; GameObject val = Addressables.LoadAssetAsync<GameObject>((object)highlightableResource.ResourcePath).WaitForCompletion(); if (Object.op_Implicit((Object)(object)val)) { val.AddComponent<InteractableHighlightCategoryMarker>().SetCategory(highlightableResource.Category); TrackedInteractables.Add(val); } } } } public static class CharacterHooks { private const int DrifterSurvivorIndex = 17; public static void Register() { CharacterBody.onBodyStartGlobal += IsPlayingAsDrifter; } private static void IsPlayingAsDrifter(CharacterBody body) { //IL_0088: 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_0094: Invalid comparison between Unknown and I4 if (!body.isPlayerControlled) { return; } CharacterMaster master = body.master; if (!Object.op_Implicit((Object)(object)master)) { return; } PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController; if (!Object.op_Implicit((Object)(object)playerCharacterMasterController)) { return; } NetworkUser networkUser = playerCharacterMasterController.networkUser; if (Object.op_Implicit((Object)(object)networkUser)) { if (!LocalUserManager.readOnlyLocalUsersList.Any((LocalUser lu) => (Object)(object)lu.currentNetworkUser == (Object)(object)networkUser)) { Log.LogDebug($"CharacterBody.onBodyStartGlobal - Not the local player - Skipping Drifter check - isClient: {((NetworkBehaviour)body).isClient} - isServer: {((NetworkBehaviour)body).isServer}"); } else if ((int)SurvivorCatalog.GetSurvivorIndexFromBodyIndex(body.bodyIndex) == 17) { CharacterStateHandler.SetIsDrifter(isDrifter: true); Log.LogDebug($"CharacterBody.onBodyStartGlobal - Drifter run detected - localPlayer: {((NetworkBehaviour)body).isLocalPlayer} - isClient: {((NetworkBehaviour)body).isClient} - isServer: {((NetworkBehaviour)body).isServer}"); } } } } public static class GeneralHooks { public static void Register(ConfigFile config) { RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(InteractableStateHandler.Init)); config.SettingChanged += delegate { InteractableStateHandler.Reset(); }; } } public static class InteractableSpawnHooks { [CompilerGenerated] private static class <>O { public static hook_Start <0>__ClassicStageInfoStart; } public static void Register() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__ClassicStageInfoStart; if (obj == null) { hook_Start val = ClassicStageInfoStart; <>O.<0>__ClassicStageInfoStart = val; obj = (object)val; } ClassicStageInfo.Start += (hook_Start)obj; } private static void ClassicStageInfoStart(orig_Start orig, ClassicStageInfo self) { orig.Invoke(self); Category[] poolCategories = self.interactableDccsPool.poolCategories; IEnumerable<DirectorCardCategorySelection> enumerable = poolCategories.SelectMany((Category x) => x.alwaysIncluded.Select((PoolEntry x) => x.dccs)); bool flag = false; foreach (ConditionalPoolEntry[] item in poolCategories.Select((Category x) => x.includedIfConditionsMet)) { if (item.SelectMany((ConditionalPoolEntry x) => x.requiredExpansions).Distinct().All((Func<ExpansionDef, bool>)Run.instance.IsExpansionEnabled)) { enumerable = enumerable.Concat(item.Select((ConditionalPoolEntry x) => ((PoolEntry)x).dccs)); flag = true; } } if (!flag) { enumerable = enumerable.Concat(poolCategories.SelectMany((Category x) => x.includedIfNoConditionsMet.Select((PoolEntry x) => x.dccs))); } foreach (InteractableSpawnCard item2 in (from x in enumerable.SelectMany((DirectorCardCategorySelection x) => x.categories).SelectMany((Category x) => x.cards) select x.spawnCard into x where x is InteractableSpawnCard select x).Cast<InteractableSpawnCard>().ToHashSet()) { if (!((Object)(object)((SpawnCard)item2).prefab == (Object)null) && InteractableRegistry.IsRegistered(((Object)((SpawnCard)item2).prefab).name, out var category) && !Object.op_Implicit((Object)(object)((SpawnCard)item2).prefab.GetComponent<InteractableHighlightCategoryMarker>())) { ((SpawnCard)item2).prefab.AddComponent<InteractableHighlightCategoryMarker>().SetCategory(category); Log.LogDebug($"Added category marker for registered modded interactable - {((Object)((SpawnCard)item2).prefab).name} - Category: ({category})"); } } } } namespace Faust.Shared { public static class Log { internal static ManualLogSource _logSource; public static void Init(ManualLogSource logSource) { _logSource = logSource; } public static void LogDebug(object data) { } public static void LogError(object data) { _logSource.LogError(data); } public static void LogFatal(object data) { _logSource.LogFatal(data); } public static void LogInfo(object data) { _logSource.LogInfo(data); } public static void LogMessage(object data) { _logSource.LogMessage(data); } public static void LogWarning(object data) { _logSource.LogWarning(data); } } } namespace Faust.Shared.Compatability { public class HunkCompat { public const string PluginGUID = "com.rob.Hunk"; public static bool IsInstalled => Chainloader.PluginInfos.ContainsKey("com.rob.Hunk"); } public class RiskOfOptionsCompat { public const string PluginGUID = "com.rune580.riskofoptions"; public static bool IsInstalled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); public static void SetModDescription(string description) { ModSettingsManager.SetModDescription(description); } public static void AddCheckboxOptions(params ConfigEntry<bool>[] configEntries) { AddCheckboxOptions(restartRequired: false, configEntries); } public static void AddCheckboxOptions(bool restartRequired = false, params ConfigEntry<bool>[] configEntries) { //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) //IL_001a: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown for (int i = 0; i < configEntries.Length; i++) { ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(configEntries[i], new CheckBoxConfig { restartRequired = restartRequired })); } } public static void AddSliderNumberOptions(params ConfigEntry<float>[] configEntries) { AddSliderNumberOptions(restartRequired: false, 0f, 100f, configEntries); } public static void AddSliderNumberOptions(bool restartRequired = false, float min = 0f, float max = 100f, params ConfigEntry<float>[] configEntries) { //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) //IL_0015: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown for (int i = 0; i < configEntries.Length; i++) { ModSettingsManager.AddOption((BaseOption)new SliderOption(configEntries[i], new SliderConfig { min = min, max = max, formatString = "{0:0.#}", restartRequired = restartRequired })); } } public static void AddSliderToPercentageOptionsDecimal(params ConfigEntry<float>[] configEntries) { AddSliderToPercentageOptionsDecimal(restartRequired: false, configEntries); } public static void AddSliderToPercentageOptionsDecimal(bool restartRequired = false, params ConfigEntry<float>[] configEntries) { //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) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown for (int i = 0; i < configEntries.Length; i++) { ModSettingsManager.AddOption((BaseOption)new StepSliderOption(configEntries[i], new StepSliderConfig { min = 0f, max = 1f, formatString = "{0:P}", increment = 0.01f, restartRequired = restartRequired })); } } public static void AddDropdownOptions<T>(bool restartRequired = false, params ConfigEntry<T>[] configEntries) where T : Enum { //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) //IL_001a: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown for (int i = 0; i < configEntries.Length; i++) { ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)configEntries[i], new ChoiceConfig { restartRequired = restartRequired })); } } public static void AddSliderPercentageOptions(bool restartRequired = false, params ConfigEntry<float>[] configEntries) { //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) //IL_001a: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown for (int i = 0; i < configEntries.Length; i++) { ModSettingsManager.AddOption((BaseOption)new SliderOption(configEntries[i], new SliderConfig { restartRequired = restartRequired })); } } public static void AddStringOptions(bool restartRequired = false, params ConfigEntry<string>[] configEntries) { //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) //IL_001a: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown for (int i = 0; i < configEntries.Length; i++) { ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(configEntries[i], new InputFieldConfig { restartRequired = restartRequired })); } } } public class StarStorm2Compat { public const string PluginGUID = "com.TeamMoonstorm"; public static bool IsInstalled => Chainloader.PluginInfos.ContainsKey("com.TeamMoonstorm"); } } namespace Faust.QoLChests { public static class Constants { public static HighlightableResource[] ChestResourcesPaths = new HighlightableResource[14] { new HighlightableResource("RoR2/Base/Barrel1/Barrel1.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/CasinoChest/CasinoChest.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/CategoryChest/CategoryChestDamage.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/CategoryChest/CategoryChestHealing.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/CategoryChest/CategoryChestUtility.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/Chest1/Chest1.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/Chest2/Chest2.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/EquipmentBarrel/EquipmentBarrel.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/GoldChest/GoldChest.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/Base/LunarChest/LunarChest.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/DLC1/CategoryChest2/CategoryChest2Damage Variant.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/DLC1/CategoryChest2/CategoryChest2Healing Variant.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/DLC1/CategoryChest2/CategoryChest2Utility Variant.prefab", InteractableCategory.Chest), new HighlightableResource("RoR2/DLC1/VoidChest/VoidChest.prefab", InteractableCategory.Chest) }; public static HighlightableResource[] LockboxResourcesPaths = new HighlightableResource[2] { new HighlightableResource("RoR2/Base/TreasureCache/Lockbox.prefab", InteractableCategory.Lockbox), new HighlightableResource("RoR2/DLC1/TreasureCacheVoid/LockboxVoid.prefab", InteractableCategory.Lockbox) }; public static HighlightableResource[] StealthedChestResourcePaths = new HighlightableResource[1] { new HighlightableResource("RoR2/Base/Chest1StealthedVariant/Chest1StealthedVariant.prefab", InteractableCategory.StealthedChest) }; public static HighlightableResource[] ShopResourcePaths = new HighlightableResource[8] { new HighlightableResource("RoR2/Base/LunarShopTerminal/LunarShopTerminal.prefab", InteractableCategory.Shop), new HighlightableResource("RoR2/Base/MultiShopEquipmentTerminal/MultiShopEquipmentTerminal.prefab", InteractableCategory.Shop), new HighlightableResource("RoR2/Base/MultiShopLargeTerminal/MultiShopLargeTerminal.prefab", InteractableCategory.Shop), new HighlightableResource("RoR2/Base/MultiShopTerminal/MultiShopTerminal.prefab", InteractableCategory.Shop), new HighlightableResource("RoR2/Base/MultiShopTerminal/ShopTerminal.prefab", InteractableCategory.Shop), new HighlightableResource("RoR2/DLC1/FreeChestTerminalShippingDrone/FreeChestTerminalShippingDrone.prefab", InteractableCategory.Shop), new HighlightableResource("RoR2/DLC3/TripleDroneShopTerminal/TripleDroneShopTerminal.prefab", InteractableCategory.Shop), new HighlightableResource("RoR2/DLC3/TemporaryItemsDistributor/TemporaryItemsShopTerminal.prefab", InteractableCategory.Shop) }; public static HighlightableResource[] ScrapperResourcePaths = new HighlightableResource[2] { new HighlightableResource("RoR2/Base/Scrapper/Scrapper.prefab", InteractableCategory.Scrapper), new HighlightableResource("RoR2/DLC3/DroneScrapper/DroneScrapper.prefab", InteractableCategory.Scrapper) }; public static HighlightableResource[] DuplicatorResourcesPaths = new HighlightableResource[4] { new HighlightableResource("RoR2/Base/Duplicator/Duplicator.prefab", InteractableCategory.Duplicator), new HighlightableResource("RoR2/Base/DuplicatorLarge/DuplicatorLarge.prefab", InteractableCategory.Duplicator), new HighlightableResource("RoR2/Base/DuplicatorMilitary/DuplicatorMilitary.prefab", InteractableCategory.Duplicator), new HighlightableResource("RoR2/Base/DuplicatorWild/DuplicatorWild.prefab", InteractableCategory.Duplicator) }; public static HighlightableResource[] DroneResourcesPaths = new HighlightableResource[16] { new HighlightableResource("RoR2/Base/Drones/Drone1Broken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/Base/Drones/Drone2Broken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/Base/Drones/EmergencyDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/Base/Drones/EquipmentDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/Base/Drones/FlameDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/Base/Drones/MegaDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/Base/Drones/MissileDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/Drones/BombardmentDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/Drones/CleanupDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/Drones/CopycatDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/Drones/HaulerDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/Drones/JailerDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/Drones/JunkDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/Drones/RechargeDroneBroken.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/DroneCombinerStation/DroneCombinerStation.prefab", InteractableCategory.Drone), new HighlightableResource("RoR2/DLC3/DroneAssemblyStation/DroneAssemblyStation.prefab", InteractableCategory.Drone) }; public static HighlightableResource[] TurrentResourcePaths = new HighlightableResource[1] { new HighlightableResource("RoR2/Base/Drones/Turret1Broken.prefab", InteractableCategory.Turret) }; public static HighlightableResource[] ArtifactOfDevotionResourcePaths = new HighlightableResource[1] { new HighlightableResource("RoR2/CU8/LemurianEgg/LemurianEgg.prefab", InteractableCategory.Drone) }; private static Color32 Yellow => new Color32(byte.MaxValue, byte.MaxValue, (byte)1, byte.MaxValue); private static Color32 Red => new Color32(byte.MaxValue, (byte)1, (byte)1, byte.MaxValue); private static Color32 Blue => new Color32((byte)1, (byte)1, byte.MaxValue, byte.MaxValue); private static Color32 Pink => new Color32(byte.MaxValue, (byte)1, (byte)127, byte.MaxValue); private static Color32 Orange => new Color32(byte.MaxValue, (byte)128, (byte)1, byte.MaxValue); private static Color32 Green => new Color32((byte)1, byte.MaxValue, (byte)1, byte.MaxValue); private static Color32 Cyan => new Color32((byte)1, byte.MaxValue, byte.MaxValue, byte.MaxValue); private static Color32 Violet => new Color32((byte)127, (byte)1, byte.MaxValue, byte.MaxValue); private static Color32 Magenta => new Color32(byte.MaxValue, (byte)1, byte.MaxValue, byte.MaxValue); private static Color32 Gray => new Color32((byte)128, (byte)128, (byte)128, byte.MaxValue); private static Color32 White => new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); public static Color32 GetColor(ConfigHighlightColor color) { //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_003c: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) return (Color32)(color switch { ConfigHighlightColor.Yellow => Yellow, ConfigHighlightColor.Red => Red, ConfigHighlightColor.Blue => Blue, ConfigHighlightColor.Pink => Pink, ConfigHighlightColor.Orange => Orange, ConfigHighlightColor.Green => Green, ConfigHighlightColor.Cyan => Cyan, ConfigHighlightColor.Violet => Violet, ConfigHighlightColor.Magenta => Magenta, ConfigHighlightColor.Gray => Gray, ConfigHighlightColor.White => White, _ => Yellow, }); } } public record struct HighlightableResource(string ResourcePath, InteractableCategory Category); [BepInPlugin("Faust.QoLChests", "QoLChests", "1.3.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class QoLChests : BaseUnityPlugin { public const string PluginGUID = "Faust.QoLChests"; public const string PluginAuthor = "Faust"; public const string PluginName = "QoLChests"; public const string PluginVersion = "1.3.1"; protected void Awake() { Stopwatch stopwatch = Stopwatch.StartNew(); Log.Init(((BaseUnityPlugin)this).Logger); ModConfig.Init(((BaseUnityPlugin)this).Config); GeneralHooks.Register(((BaseUnityPlugin)this).Config); ChestHooks.Register(); ShopHooks.Register(); SceneHooks.Register(); InteractableSpawnHooks.Register(); StarStorm2CompatHandler.Register(); HunkCompatHandler.Register(); stopwatch.Stop(); Log.LogDebug(string.Format("{0} took {1}ms", "Awake", stopwatch.ElapsedMilliseconds)); } } public static class Utils { public static Renderer[] GetRenderers(GameObject gameObject) { ModelLocator component = gameObject.GetComponent<ModelLocator>(); object obj; if (component == null) { obj = null; } else { Transform modelTransform = component.modelTransform; obj = ((modelTransform != null) ? ((Component)modelTransform).GetComponentsInChildren<Renderer>() : null); } if (obj == null) { obj = gameObject.GetComponentsInChildren<Renderer>(); } Renderer[] array = (Renderer[])obj; object obj2; if (component == null) { obj2 = null; } else { Transform modelTransform2 = component.modelTransform; obj2 = ((modelTransform2 != null) ? ((Component)modelTransform2).GetComponents<Renderer>() : null); } if (obj2 == null) { obj2 = gameObject.GetComponents<Renderer>(); } Renderer[] array2 = (Renderer[])obj2; Renderer[] array3 = array; int num = 0; Renderer[] array4 = (Renderer[])(object)new Renderer[array2.Length + array3.Length]; ReadOnlySpan<Renderer> readOnlySpan = new ReadOnlySpan<Renderer>(array2); readOnlySpan.CopyTo(new Span<Renderer>(array4).Slice(num, readOnlySpan.Length)); num += readOnlySpan.Length; ReadOnlySpan<Renderer> readOnlySpan2 = new ReadOnlySpan<Renderer>(array3); readOnlySpan2.CopyTo(new Span<Renderer>(array4).Slice(num, readOnlySpan2.Length)); num += readOnlySpan2.Length; return array4; } public static Renderer[] DisableRenderers(GameObject gameObject) { Renderer[] renderers = GetRenderers(gameObject); List<Renderer> list = new List<Renderer>(renderers.Length); Renderer[] array = renderers; foreach (Renderer val in array) { if (Object.op_Implicit((Object)(object)val)) { Log.LogDebug("Disabling renderer " + ((Object)val).name); val.enabled = false; list.Add(val); } } return list.ToArray(); } public static Collider[] DisableColliders(GameObject gameObject) { Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(); List<Collider> list = new List<Collider>(componentsInChildren.Length); Collider[] array = componentsInChildren; foreach (Collider val in array) { if (Object.op_Implicit((Object)(object)val)) { Log.LogDebug("Disabling collider " + ((Object)val).name); val.enabled = false; list.Add(val); } } return list.ToArray(); } public static void DisableCommonVisualEffects(GameObject gameObject) { SetParticleSystem(gameObject, active: false); SetTrailRenderer(gameObject, enabled: false); SetLights(gameObject, enabled: false); } private static ParticleSystem[] SetParticleSystem(GameObject gameObject, bool active) { ParticleSystem[] componentsInChildren = gameObject.GetComponentsInChildren<ParticleSystem>(); ParticleSystem[] array = componentsInChildren; foreach (ParticleSystem val in array) { Log.LogDebug("Disabling particle system " + ((Object)val).name); val.Stop(); ((Component)val).gameObject.SetActive(active); } return componentsInChildren; } private static TrailRenderer[] SetTrailRenderer(GameObject gameObject, bool enabled) { TrailRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<TrailRenderer>(); TrailRenderer[] array = componentsInChildren; foreach (TrailRenderer val in array) { Log.LogDebug("Disabling trail renderer " + ((Object)val).name); ((Renderer)val).enabled = enabled; } return componentsInChildren; } private static Light[] SetLights(GameObject gameObject, bool enabled) { Light[] componentsInChildren = gameObject.GetComponentsInChildren<Light>(); Light[] array = componentsInChildren; foreach (Light val in array) { Log.LogDebug("Disabling light " + ((Object)val).name); ((Behaviour)val).enabled = enabled; } return componentsInChildren; } } public static class PluginInfo { public const string PLUGIN_GUID = "QoLChests"; public const string PLUGIN_NAME = "QoLChests"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace Faust.QoLChests.Hooks { public static class ChestHooks { [CompilerGenerated] private static class <>O { public static hook_OnEnter <0>__BarrelOpened; public static hook_OnEnter <1>__RouletteOpened; public static hook_ResetChestForDelusion <2>__ResetChestForDelusion; } public static void Register() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: 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_003b: Expected O, but got Unknown //IL_0050: 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_005b: Expected O, but got Unknown object obj = <>O.<0>__BarrelOpened; if (obj == null) { hook_OnEnter val = BarrelOpened; <>O.<0>__BarrelOpened = val; obj = (object)val; } Opened.OnEnter += (hook_OnEnter)obj; object obj2 = <>O.<1>__RouletteOpened; if (obj2 == null) { hook_OnEnter val2 = RouletteOpened; <>O.<1>__RouletteOpened = val2; obj2 = (object)val2; } Opened.OnEnter += (hook_OnEnter)obj2; object obj3 = <>O.<2>__ResetChestForDelusion; if (obj3 == null) { hook_ResetChestForDelusion val3 = ResetChestForDelusion; <>O.<2>__ResetChestForDelusion = val3; obj3 = (object)val3; } DelusionChestController.ResetChestForDelusion += (hook_ResetChestForDelusion)obj3; } private static void BarrelOpened(orig_OnEnter orig, Opened self) { orig.Invoke(self); if (!InteractableRegistry.IsBlackListed(((Object)((Component)((EntityState)self).outer).gameObject).name)) { ((Component)((EntityState)self).outer).gameObject.AddComponent<InteractableUsed>(); VisibilityHandler.Hide(InteractableCategory.Chest, ((Component)((EntityState)self).outer).gameObject, ((Component)((EntityState)self).outer.commonComponents.modelLocator.modelTransform).gameObject); if (ModConfig.Instance.RemoveHighlightFromUsed.Value) { HighlightHandler.Disable(((Component)((EntityState)self).outer).gameObject); } } } private static void RouletteOpened(orig_OnEnter orig, Opened self) { orig.Invoke(self); if (!InteractableRegistry.IsBlackListed(((Object)((Component)((EntityState)self).outer).gameObject).name)) { ((Component)((EntityState)self).outer).gameObject.AddComponent<InteractableUsed>(); VisibilityHandler.Hide(InteractableCategory.Chest, ((Component)((EntityState)self).outer).gameObject); if (ModConfig.Instance.RemoveHighlightFromUsed.Value) { HighlightHandler.Disable(((Component)((EntityState)self).outer).gameObject); } } } private static void ResetChestForDelusion(orig_ResetChestForDelusion orig, DelusionChestController self) { orig.Invoke(self); VisibilityHandler.Show(((Component)self).gameObject); if (ModConfig.Instance.HighlightChests.Value) { HighlightHandler.Enable(((Component)self).gameObject, ignoreUsed: true); } } } public static class SceneHooks { [CompilerGenerated] private static class <>O { public static hook_Start <0>__Start; } public static void Register() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__Start; if (obj == null) { hook_Start val = Start; <>O.<0>__Start = val; obj = (object)val; } SceneDirector.Start += (hook_Start)obj; } private static void Start(orig_Start orig, SceneDirector self) { orig.Invoke(self); AddCustomHandlingOfSpecialScenes(); InteractableStateHandler.Reset(); Log.LogDebug($"SceneDirector.Start - {InteractableStateHandler.InteractablesToHighlight.Count} interactables highlighted"); } private static void AddCustomHandlingOfSpecialScenes() { GameObject holder = GameObject.Find("Chests"); GameObject holder2 = GameObject.Find("HOLDER: Preplaced Goodies"); AddInteractableMarkerToChildren(holder, InteractableCategory.Chest); AddInteractableMarkerToChildren(holder2, InteractableCategory.Chest); } private static void AddInteractableMarkerToChildren(GameObject holder, InteractableCategory category) { if (!Object.op_Implicit((Object)(object)holder)) { return; } Highlight[] componentsInChildren = holder.GetComponentsInChildren<Highlight>(); InteractableHighlightCategoryMarker interactableHighlightCategoryMarker = default(InteractableHighlightCategoryMarker); foreach (Highlight val in componentsInChildren) { if (!((Component)val).gameObject.TryGetComponent<InteractableHighlightCategoryMarker>(ref interactableHighlightCategoryMarker)) { ((Component)val).gameObject.AddComponent<InteractableHighlightCategoryMarker>().SetCategory(category); Log.LogDebug("AddInteractableMarkerToChildren - Adding interactable marker for " + ((Object)((Component)val).gameObject).name); } } } } public static class ShopHooks { [CompilerGenerated] private static class <>O { public static hook_SetHasBeenPurchased <0>__SetHasBeenPurchased; public static hook_OnInteractionBegin <1>__PurchaseInteractionOnInteractionBegin; public static hook_OnPurchase <2>__MultiShopControllerOnPurchase; } public static void Register() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: 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_003b: Expected O, but got Unknown //IL_0050: 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_005b: Expected O, but got Unknown object obj = <>O.<0>__SetHasBeenPurchased; if (obj == null) { hook_SetHasBeenPurchased val = SetHasBeenPurchased; <>O.<0>__SetHasBeenPurchased = val; obj = (object)val; } ShopTerminalBehavior.SetHasBeenPurchased += (hook_SetHasBeenPurchased)obj; object obj2 = <>O.<1>__PurchaseInteractionOnInteractionBegin; if (obj2 == null) { hook_OnInteractionBegin val2 = PurchaseInteractionOnInteractionBegin; <>O.<1>__PurchaseInteractionOnInteractionBegin = val2; obj2 = (object)val2; } PurchaseInteraction.OnInteractionBegin += (hook_OnInteractionBegin)obj2; object obj3 = <>O.<2>__MultiShopControllerOnPurchase; if (obj3 == null) { hook_OnPurchase val3 = MultiShopControllerOnPurchase; <>O.<2>__MultiShopControllerOnPurchase = val3; obj3 = (object)val3; } MultiShopController.OnPurchase += (hook_OnPurchase)obj3; } private static void PurchaseInteractionOnInteractionBegin(orig_OnInteractionBegin orig, PurchaseInteraction self, Interactor activator) { orig.Invoke(self, activator); Log.LogDebug("PurchaseInteraction_OnInteractionBegin called"); if (InteractableRegistry.IsBlackListed(((Object)((Component)self).gameObject).name)) { return; } Log.LogDebug($"PurchaseInteraction_OnInteractionBegin - {((Object)((Component)self).gameObject).name} - Cost: {self.cost} - NetworkAvailable: {self.Networkavailable}"); if (self.Networkavailable) { return; } InteractableHighlightCategoryMarker component = ((Component)self).GetComponent<InteractableHighlightCategoryMarker>(); if (!Object.op_Implicit((Object)(object)component)) { return; } Log.LogDebug($"PurchaseInteraction_OnInteractionBegin - Hiding interactable of category: {component.Category}"); if (component.Category == InteractableCategory.Shop && ((Object)((Component)self).gameObject).name.Contains("TripleDroneShopTerminal")) { DroneVendorMultiShopController val = FindDroneMultishopController(self); if (!Object.op_Implicit((Object)(object)val)) { return; } ModelLocator component2 = ((Component)val).GetComponent<ModelLocator>(); if (!Object.op_Implicit((Object)(object)component2)) { return; } ((Component)val).gameObject.AddComponent<InteractableUsed>(); VisibilityHandler.Hide(component.Category, ((Component)self).gameObject, ((Component)val).gameObject, ((Component)component2.modelTransform).gameObject); } VisibilityHandler.Hide(component.Category, ((Component)self).gameObject); if (!Object.op_Implicit((Object)(object)((Component)self).gameObject.GetComponent<InteractableUsed>())) { ((Component)self).gameObject.AddComponent<InteractableUsed>(); } if (ModConfig.Instance.RemoveHighlightFromUsed.Value) { Log.LogDebug("PurchaseInteraction_OnInteractionBegin - Removing highlight from used interactable: " + ((Object)((Component)self).gameObject).name); Highlight[] array = HighlightHandler.Disable(((Component)self).gameObject); Log.LogDebug($"PurchaseInteraction_OnInteractionBegin - Disabled {array.Length} highlights"); } } private static DroneVendorMultiShopController FindDroneMultishopController(PurchaseInteraction terminalBehavior) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) DroneVendorMultiShopController[] array = Object.FindObjectsOfType<DroneVendorMultiShopController>(); DroneVendorMultiShopController val = null; float num = float.MaxValue; float num2 = 4.3f; DroneVendorMultiShopController[] array2 = array; foreach (DroneVendorMultiShopController val2 in array2) { Log.LogDebug($"Checking DroneVendorMultiShopController: {((Object)((Component)val2).gameObject).name} - Available: {val2.available} - NetworkAvailable: {val2.Networkavailable}"); float num3 = Vector3.Distance(((Component)terminalBehavior).transform.position, ((Component)val2).transform.position); if (num3 < num2 && num3 < num) { num = num3; val = val2; } } Log.LogDebug($"Found closest DroneVendorMultiShopController: {((val != null) ? ((Object)((Component)val).gameObject).name : null)} - Distance: {num}"); return val; } private static void MultiShopControllerOnPurchase(orig_OnPurchase orig, MultiShopController self, PayCostContext payCostContext, PayCostResults payCostResult) { orig.Invoke(self, payCostContext, payCostResult); if (InteractableRegistry.IsBlackListed(((Object)((Component)self).gameObject).name)) { return; } Log.LogDebug("MultiShopController_OnPurchase - " + $"Available: {self.available} NetworkAvailable: {self.Networkavailable} " + $"IsActiveAndEnabled: {((Behaviour)self).isActiveAndEnabled}"); if (!self.Networkavailable) { GameObject[] array = self.terminalGameObjects.Select((GameObject x) => x).Concat(new <>z__ReadOnlySingleElementList<GameObject>(((Component)self).gameObject)).ToArray(); VisibilityHandler.Hide(InteractableCategory.Shop, array); GameObject[] array2 = array; for (int i = 0; i < array2.Length; i++) { array2[i].AddComponent<InteractableUsed>(); } if (ModConfig.Instance.RemoveHighlightFromUsed.Value) { HighlightHandler.Disable(array); } } } private static void SetHasBeenPurchased(orig_SetHasBeenPurchased orig, ShopTerminalBehavior self, bool newHasBeenPurchased) { orig.Invoke(self, newHasBeenPurchased); if (InteractableRegistry.IsBlackListed(((Object)((Component)self).gameObject).name)) { return; } MultiShopController val = FindMultiShopControllerForTerminal(self); if (!Object.op_Implicit((Object)(object)val)) { return; } IEnumerable<GameObject> source = from x in FindOtherShopTerminals(self) select ((Component)x).gameObject; if (val.Networkavailable) { RecheckShopAvailableAfterDelay recheckShopAvailableAfterDelay = ((Component)val).gameObject.AddComponent<RecheckShopAvailableAfterDelay>().SetMultiShopController(val); List<GameObject> list = new List<GameObject>(); list.AddRange(source.Select((GameObject x) => x.gameObject)); list.Add(((Component)self).gameObject); RecheckShopAvailableAfterDelay recheckShopAvailableAfterDelay2 = recheckShopAvailableAfterDelay.SetTerminalObjects(list.ToArray()); if (ModConfig.Instance.RemoveHighlightFromUsed.Value) { recheckShopAvailableAfterDelay2.RemoveHighlightAfterDelay(); } recheckShopAvailableAfterDelay2.RecheckShopAvailabilityAfterDelay(); } else { List<GameObject> list2 = new List<GameObject>(); list2.AddRange(source.Select((GameObject x) => x.gameObject)); list2.Add(((Component)self).gameObject); list2.Add(((Component)val).gameObject); GameObject[] array = list2.ToArray(); VisibilityHandler.Hide(InteractableCategory.Shop, array); if (ModConfig.Instance.RemoveHighlightFromUsed.Value) { HighlightHandler.Disable(array); } } } private static MultiShopController FindMultiShopControllerForTerminal(ShopTerminalBehavior terminalBehavior) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) MultiShopController[] array = Object.FindObjectsOfType<MultiShopController>(); MultiShopController val = null; float num = float.MaxValue; float num2 = 4.3f; MultiShopController[] array2 = array; foreach (MultiShopController val2 in array2) { Log.LogDebug($"Checking MultiShopController: {((Object)((Component)val2).gameObject).name} - Available: {val2.available} - NetworkAvailable: {val2.Networkavailable}"); float num3 = Vector3.Distance(((Component)terminalBehavior).transform.position, ((Component)val2).transform.position); if (num3 < num2 && num3 < num) { num = num3; val = val2; } } Log.LogDebug($"Found closest MultiShopController: {((val != null) ? ((Object)((Component)val).gameObject).name : null)} - Distance: {num}"); return val; } private static List<ShopTerminalBehavior> FindOtherShopTerminals(ShopTerminalBehavior self) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) List<ShopTerminalBehavior> list = new List<ShopTerminalBehavior>(); float num = 3.3f; ShopTerminalBehavior[] array = Object.FindObjectsOfType<ShopTerminalBehavior>(); foreach (ShopTerminalBehavior val in array) { if (!((Object)(object)val == (Object)(object)self)) { float num2 = Vector3.Distance(((Component)self).transform.position, ((Component)val).transform.position); if (num2 <= num) { Log.LogDebug($"Found nearby terminal: {((Object)((Component)val).gameObject).name} - Distance: {num2}"); list.Add(val); } } } return list; } } } namespace Faust.QoLChests.Handlers { public static class CharacterStateHandler { public static bool IsDrifter { get; private set; } = true; public static void SetIsDrifter(bool isDrifter) { IsDrifter = true; } } public static class HighlightHandler { public static void Enable(GameObject[] interactable) { for (int i = 0; i < interactable.Length; i++) { Enable(interactable[i]); } } public static void Enable(GameObject interactable, bool ignoreUsed = false) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)interactable)) { return; } Highlight component = interactable.GetComponent<Highlight>(); if (!Object.op_Implicit((Object)(object)component)) { return; } if (ModConfig.Instance.RemoveHighlightFromUsed.Value && !ignoreUsed && Object.op_Implicit((Object)(object)interactable.GetComponent<InteractableUsed>())) { Log.LogInfo("HighlightHandler.Enable: Interactable has been used, disabling highlight"); return; } InteractableHighlightCategoryMarker component2 = interactable.GetComponent<InteractableHighlightCategoryMarker>(); if (!Object.op_Implicit((Object)(object)component2)) { Log.LogWarning("GameObject " + ((Object)interactable).name + " does not have a HighlightCategoryMarker - why are we trying to highlight it?"); return; } ConfigHighlightColor value = ModConfig.Instance.GetCategoryHighlightColorConfig(component2.Category).Value; component.isOn = true; ((Behaviour)component).enabled = true; component.highlightColor = (HighlightColor)3; component.CustomColor = Color32.op_Implicit(Constants.GetColor(value)); } public static Highlight[] Disable(GameObject[] gameObject) { List<Highlight> list = new List<Highlight>(); foreach (GameObject gameObject2 in gameObject) { list.AddRange(Disable(gameObject2)); } return list.ToArray(); } public static Highlight[] Disable(GameObject gameObject) { return DisableHighlights(gameObject); } public static Highlight[] GetHighlights(GameObject gameObject) { if (!Object.op_Implicit((Object)(object)gameObject)) { return Array.Empty<Highlight>(); } Highlight component = gameObject.GetComponent<Highlight>(); return (Highlight[])(object)new Highlight[1] { component }; } private static Highlight[] DisableHighlights(GameObject gameObject) { if (!Object.op_Implicit((Object)(object)gameObject)) { return Array.Empty<Highlight>(); } Highlight[] highlights = GetHighlights(gameObject); List<Highlight> list = new List<Highlight>(highlights.Length); Highlight[] array = highlights; foreach (Highlight val in array) { if (Object.op_Implicit((Object)(object)val)) { val.isOn = false; ((Behaviour)val).enabled = false; list.Add(val); } } return list.ToArray(); } } public static class InteractableRegistry { private static readonly Dictionary<string, InteractableCategory> RegisteredInteractables = new Dictionary<string, InteractableCategory>(); private static readonly HashSet<string> BlackListedInteractables = new HashSet<string>(); public static void Register(string interactableName, InteractableCategory category) { RegisteredInteractables.TryAdd(interactableName, category); if (!interactableName.EndsWith("(Clone)")) { string key = interactableName + "(Clone)"; RegisteredInteractables.TryAdd(key, category); } } public static bool IsRegistered(string interactableName, out InteractableCategory category) { return RegisteredInteractables.TryGetValue(interactableName, out category); } public static void BlackList(string interactableName) { BlackListedInteractables.Add(interactableName); if (!interactableName.EndsWith("(Clone)")) { string item = interactableName + "(Clone)"; BlackListedInteractables.Add(item); } } public static bool IsBlackListed(string interactableName) { return BlackListedInteractables.Contains(interactableName); } } public static class VisibilityHandler { public static void Hide(InteractableCategory category, params GameObject[] gameObjects) { bool flag = ModConfig.Instance.DoNotHideAsDrifter.Value && CharacterStateHandler.IsDrifter; Log.LogDebug($"VisibilityHandler.Hide - Category: {category} - DoNotHideAsDrifter: {flag} - IsDrifter: {CharacterStateHandler.IsDrifter}"); if (ModConfig.Instance.IsCategoryHideEnabled(category) && !flag) { Hide(gameObjects); } } private static void Hide(params GameObject[] gameObjects) { GameObject[] array; if (ModConfig.Instance.FadeInsteadOfHide.Value) { array = gameObjects; foreach (GameObject val in array) { if (!Object.op_Implicit((Object)(object)val.GetComponent<FadeWithDelay>())) { val.AddComponent<FadeWithDelay>().SetDelay(ModConfig.Instance.HideTime.Value).DisableRendererAfterDelay(); } } return; } array = gameObjects; foreach (GameObject val2 in array) { if (!Object.op_Implicit((Object)(object)val2.GetComponent<HideWithDelay>())) { val2.AddComponent<HideWithDelay>().SetDelay(ModConfig.Instance.HideTime.Value).DisableRendererAfterDelay(); } } } public static void Show(params GameObject[] gameObjects) { for (int i = 0; i < gameObjects.Length; i++) { Show(gameObjects[i]); } } private static void Show(GameObject interactable) { ModelLocator component = interactable.gameObject.GetComponent<ModelLocator>(); if (Object.op_Implicit((Object)(object)component)) { HideWithDelay component2 = ((Component)component.modelTransform).gameObject.GetComponent<HideWithDelay>(); FadeWithDelay component3 = ((Component)component.modelTransform).gameObject.GetComponent<FadeWithDelay>(); InteractableUsed component4 = ((Component)component.modelTransform).gameObject.GetComponent<InteractableUsed>(); if (Object.op_Implicit((Object)(object)component4)) { Object.Destroy((Object)(object)component4); } if (Object.op_Implicit((Object)(object)component2)) { Object.Destroy((Object)(object)component2); } if (Object.op_Implicit((Object)(object)component3)) { Object.Destroy((Object)(object)component3); } } InteractableUsed component5 = interactable.gameObject.GetComponent<InteractableUsed>(); if (Object.op_Implicit((Object)(object)component5)) { Object.Destroy((Object)(object)component5); } HideWithDelay component6 = interactable.gameObject.GetComponent<HideWithDelay>(); if (Object.op_Implicit((Object)(object)component6)) { Object.Destroy((Object)(object)component6); } FadeWithDelay component7 = interactable.gameObject.GetComponent<FadeWithDelay>(); if (Object.op_Implicit((Object)(object)component7)) { Object.Destroy((Object)(object)component7); } } } } namespace Faust.QoLChests.Configs { public enum ConfigHighlightColor { Yellow, Red, Blue, Pink, Orange, Green, Cyan, Violet, Magenta, Gray, White } public enum InteractableCategory { Chest, Shop, Scrapper, Duplicator, Drone, Turret, StealthedChest, Shrine, Lockbox } public class ModConfig { private static ModConfig instance; public ConfigEntry<bool> HideEmptyChests; public ConfigEntry<bool> HideUsedShops; public ConfigEntry<bool> RemoveHighlightFromUsed; public ConfigEntry<bool> FadeInsteadOfHide; public ConfigEntry<bool> HighlightChests; public ConfigEntry<bool> HighlightShops; public ConfigEntry<bool> HighlightScrapper; public ConfigEntry<bool> HighlightDuplicator; public ConfigEntry<bool> HighlightDrones; public ConfigEntry<bool> HighlightTurrets; public ConfigEntry<bool> HighlightStealthedChests; public ConfigEntry<bool> HighlightLockboxes; public ConfigEntry<bool> DoNotHideAsDrifter; public ConfigEntry<float> HideTime; public ConfigEntry<ConfigHighlightColor> HighlightColor; public ConfigEntry<ConfigHighlightColor> HighlightChestColor; public ConfigEntry<ConfigHighlightColor> HighlightShopColor; public ConfigEntry<ConfigHighlightColor> HighlightScrapperColor; public ConfigEntry<ConfigHighlightColor> HighlightDuplicatorColor; public ConfigEntry<ConfigHighlightColor> HighlightDronesColor; public ConfigEntry<ConfigHighlightColor> HighlightTurretsColor; public ConfigEntry<ConfigHighlightColor> HighlightStealthedChestsColor; public ConfigEntry<ConfigHighlightColor> HighlightLockboxesColor; public static ModConfig Instance { get { if (instance == null) { throw new InvalidOperationException("ModConfig is not initialized. Call Init() first."); } return instance; } } public static void Init(ConfigFile config) { if (instance == null) { instance = new ModConfig(config); } } private ModConfig(ConfigFile config) { HideEmptyChests = config.Bind<bool>("Hide", "Chest", true, "Hides empty chests after a few seconds"); HideUsedShops = config.Bind<bool>("Hide", "Shops", true, "Hides used shops after a few seconds"); HideTime = config.Bind<float>("Hide", "Time", 1f, "Time before stuff is hidden"); FadeInsteadOfHide = config.Bind<bool>("Hide", "Fade", false, "Fade instead of hiding"); RemoveHighlightFromUsed = config.Bind<bool>("Highlight", "RemoveWhenUsed", false, "Remove highlight when used"); DoNotHideAsDrifter = config.Bind<bool>("Highlight", "DoNotHideAsDrifter", false, "Do not hide used chests as Drifter"); HighlightChests = config.Bind<bool>("Highlight", "Chest", true, "Highlight Chests (Chests, Barrels etc.)"); HighlightStealthedChests = config.Bind<bool>("Highlight", "Stealthed Chests", true, "Highlight stealthed chests"); HighlightLockboxes = config.Bind<bool>("Highlight", "Lockboxes", true, "Highlight Lockboxes"); HighlightDuplicator = config.Bind<bool>("Highlight", "Duplicator", true, "Highlight Duplicators"); HighlightScrapper = config.Bind<bool>("Highlight", "Scrapper", true, "Highlight Scrappers"); HighlightShops = config.Bind<bool>("Highlight", "Shops", true, "Highlight Shops"); HighlightDrones = config.Bind<bool>("Highlight", "Drones", true, "Highlight Drones"); HighlightTurrets = config.Bind<bool>("Highlight", "Turrets", true, "Highlight Turrets"); HighlightColor = config.Bind<ConfigHighlightColor>("Highlight", "Color", ConfigHighlightColor.Yellow, "Highlight color for interactables (Only used for backwards compatibility)"); HighlightChestColor = config.Bind<ConfigHighlightColor>("Highlight", "ChestColor", HighlightColor.Value, "Highlight color for chests"); HighlightShopColor = config.Bind<ConfigHighlightColor>("Highlight", "ShopColor", HighlightColor.Value, "Highlight color for shops"); HighlightScrapperColor = config.Bind<ConfigHighlightColor>("Highlight", "ScrapperColor", HighlightColor.Value, "Highlight color for scrappers"); HighlightDuplicatorColor = config.Bind<ConfigHighlightColor>("Highlight", "DuplicatorColor", HighlightColor.Value, "Highlight color for duplicators"); HighlightDronesColor = config.Bind<ConfigHighlightColor>("Highlight", "DronesColor", HighlightColor.Value, "Highlight color for drones"); HighlightTurretsColor = config.Bind<ConfigHighlightColor>("Highlight", "TurretsColor", HighlightColor.Value, "Highlight color for turrets"); HighlightStealthedChestsColor = config.Bind<ConfigHighlightColor>("Highlight", "StealthedChestsColor", HighlightColor.Value, "Highlight color for stealthed chests"); HighlightLockboxesColor = config.Bind<ConfigHighlightColor>("Highlight", "LockboxesColor", HighlightColor.Value, "Highlight color for lockboxes"); if (RiskOfOptionsCompat.IsInstalled) { RiskOfOptionsCompat.SetModDescription("Hides chests when they are empty." + Environment.NewLine + "Hides used shop terminals." + Environment.NewLine + "Highlights chests and interactables."); RiskOfOptionsCompat.AddCheckboxOptions(false, HideEmptyChests, HideUsedShops, FadeInsteadOfHide, RemoveHighlightFromUsed, DoNotHideAsDrifter); RiskOfOptionsCompat.AddCheckboxOptions(false, HighlightChests, HighlightDuplicator, HighlightScrapper, HighlightShops, HighlightDrones, HighlightTurrets, HighlightStealthedChests, HighlightLockboxes); RiskOfOptionsCompat.AddSliderNumberOptions(false, 0.1f, 5f, HideTime); RiskOfOptionsCompat.AddDropdownOptions(restartRequired: false, new ConfigEntry<ConfigHighlightColor>[9] { HighlightColor, HighlightChestColor, HighlightShopColor, HighlightScrapperColor, HighlightDuplicatorColor, HighlightDronesColor, HighlightTurretsColor, HighlightStealthedChestsColor, HighlightLockboxesColor }); } } internal ConfigEntry<ConfigHighlightColor> GetCategoryHighlightColorConfig(InteractableCategory category) { return (ConfigEntry<ConfigHighlightColor>)(category switch { InteractableCategory.Chest => HighlightChestColor, InteractableCategory.Shop => HighlightShopColor, InteractableCategory.Scrapper => HighlightScrapperColor, InteractableCategory.Duplicator => HighlightDuplicatorColor, InteractableCategory.Drone => HighlightDronesColor, InteractableCategory.Turret => HighlightTurretsColor, InteractableCategory.StealthedChest => HighlightStealthedChestsColor, InteractableCategory.Lockbox => HighlightLockboxesColor, InteractableCategory.Shrine => HighlightColor, _ => HighlightColor, }); } internal bool IsCategoryHighlightEnabled(InteractableCategory category) { return category switch { InteractableCategory.Chest => HighlightChests.Value, InteractableCategory.Shop => HighlightShops.Value, InteractableCategory.Scrapper => HighlightScrapper.Value, InteractableCategory.Duplicator => HighlightDuplicator.Value, InteractableCategory.Drone => HighlightDrones.Value, InteractableCategory.Turret => HighlightTurrets.Value, InteractableCategory.StealthedChest => HighlightStealthedChests.Value, InteractableCategory.Lockbox => HighlightLockboxes.Value, InteractableCategory.Shrine => false, _ => false, }; } internal bool IsCategoryHideEnabled(InteractableCategory category) { return category switch { InteractableCategory.Chest => HideEmptyChests.Value, InteractableCategory.StealthedChest => HideEmptyChests.Value, InteractableCategory.Shop => HideUsedShops.Value, _ => false, }; } } } namespace Faust.QoLChests.Components { public class FadeWithDelay : MonoBehaviour { [CompilerGenerated] private sealed class <DisableRendererCoroutine>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public FadeWithDelay <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DisableRendererCoroutine>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_00a5: 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) int num = <>1__state; FadeWithDelay fadeWithDelay = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(fadeWithDelay.<Delay>P); <>1__state = 1; return true; case 1: { <>1__state = -1; fadeWithDelay.renderers = Utils.DisableRenderers(((Component)fadeWithDelay).gameObject); fadeWithDelay.colliders = Utils.DisableColliders(((Component)fadeWithDelay).gameObject); Utils.DisableCommonVisualEffects(((Component)fadeWithDelay).gameObject); Highlight component = ((Component)fadeWithDelay).GetComponent<Highlight>(); if (Object.op_Implicit((Object)(object)component)) { component.isOn = true; ((Behaviour)component).enabled = true; component.CustomColor = Color32.op_Implicit(new Color32((byte)128, (byte)128, (byte)128, (byte)64)); component.highlightColor = (HighlightColor)3; } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private float <Delay>P; private Collider[] colliders; private Renderer[] renderers; public FadeWithDelay(float Delay = 1f) { <Delay>P = Delay; ((MonoBehaviour)this)..ctor(); } public void DisableRendererAfterDelay() { ((MonoBehaviour)this).StartCoroutine(DisableRendererCoroutine()); } public FadeWithDelay SetDelay(float delay) { <Delay>P = delay; return this; } [IteratorStateMachine(typeof(<DisableRendererCoroutine>d__6))] private IEnumerator DisableRendererCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DisableRendererCoroutine>d__6(0) { <>4__this = this }; } public void OnDestroy() { Collider[] array = colliders; foreach (Collider val in array) { if (Object.op_Implicit((Object)(object)val)) { val.enabled = true; } } Renderer[] array2 = renderers; foreach (Renderer val2 in array2) { if (Object.op_Implicit((Object)(object)val2)) { val2.enabled = true; } } } } public class HideWithDelay : MonoBehaviour { [CompilerGenerated] private sealed class <DisableRendererCoroutine>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public HideWithDelay <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DisableRendererCoroutine>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown int num = <>1__state; HideWithDelay hideWithDelay = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(hideWithDelay.<Delay>P); <>1__state = 1; return true; case 1: <>1__state = -1; hideWithDelay.renderers = Utils.DisableRenderers(((Component)hideWithDelay).gameObject); hideWithDelay.colliders = Utils.DisableColliders(((Component)hideWithDelay).gameObject); HighlightHandler.Disable(((Component)hideWithDelay).gameObject); Utils.DisableCommonVisualEffects(((Component)hideWithDelay).gameObject); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private float <Delay>P; private Collider[] colliders; private Renderer[] renderers; public HideWithDelay(float Delay = 1f) { <Delay>P = Delay; ((MonoBehaviour)this)..ctor(); } public void DisableRendererAfterDelay() { ((MonoBehaviour)this).StartCoroutine(DisableRendererCoroutine()); } public HideWithDelay SetDelay(float delay) { <Delay>P = delay; return this; } [IteratorStateMachine(typeof(<DisableRendererCoroutine>d__6))] private IEnumerator DisableRendererCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DisableRendererCoroutine>d__6(0) { <>4__this = this }; } public void OnDestroy() { Collider[] array = colliders; foreach (Collider val in array) { if (Object.op_Implicit((Object)(object)val)) { val.enabled = true; } } Renderer[] array2 = renderers; foreach (Renderer val2 in array2) { if (Object.op_Implicit((Object)(object)val2)) { val2.enabled = true; } } } } public class InteractableHighlightCategoryMarker : MonoBehaviour { public InteractableCategory Category; public InteractableHighlightCategoryMarker SetCategory(InteractableCategory category) { Category = category; return this; } } public class InteractableUsed : MonoBehaviour { } public class RecheckShopAvailableAfterDelay : MonoBehaviour { [CompilerGenerated] private sealed class <RecheckShopAfterDelay>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public RecheckShopAvailableAfterDelay <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RecheckShopAfterDelay>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown int num = <>1__state; RecheckShopAvailableAfterDelay recheckShopAvailableAfterDelay = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(recheckShopAvailableAfterDelay.<Delay>P); <>1__state = 1; return true; case 1: <>1__state = -1; if (Object.op_Implicit((Object)(object)recheckShopAvailableAfterDelay.MultiShopController) && !recheckShopAvailableAfterDelay.MultiShopController.Networkavailable) { GameObject gameObject = ((Component)recheckShopAvailableAfterDelay.MultiShopController).gameObject; GameObject[] terminalObjects = recheckShopAvailableAfterDelay.TerminalObjects; int num2 = 0; GameObject[] array = (GameObject[])(object)new GameObject[1 + terminalObjects.Length]; array[num2] = gameObject; num2++; ReadOnlySpan<GameObject> readOnlySpan = new ReadOnlySpan<GameObject>(terminalObjects); readOnlySpan.CopyTo(new Span<GameObject>(array).Slice(num2, readOnlySpan.Length)); num2 += readOnlySpan.Length; VisibilityHandler.Hide(InteractableCategory.Shop, array); if (recheckShopAvailableAfterDelay.RemoveHighlightFromUsed) { gameObject = ((Component)recheckShopAvailableAfterDelay.MultiShopController).gameObject; array = recheckShopAvailableAfterDelay.TerminalObjects; num2 = 0; terminalObjects = (GameObject[])(object)new GameObject[1 + array.Length]; terminalObjects[num2] = gameObject; num2++; readOnlySpan = new ReadOnlySpan<GameObject>(array); readOnlySpan.CopyTo(new Span<GameObject>(terminalObjects).Slice(num2, readOnlySpan.Length)); num2 += readOnlySpan.Length; HighlightHandler.Disable(terminalObjects); } } Object.Destroy((Object)(object)recheckShopAvailableAfterDelay); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private float <Delay>P; private MultiShopController MultiShopController; private GameObject[] TerminalObjects; private bool RemoveHighlightFromUsed; public RecheckShopAvailableAfterDelay(float Delay = 0.1f) { <Delay>P = Delay; TerminalObjects = Array.Empty<GameObject>(); ((MonoBehaviour)this)..ctor(); } public void RecheckShopAvailabilityAfterDelay() { ((MonoBehaviour)this).StartCoroutine(RecheckShopAfterDelay()); } public RecheckShopAvailableAfterDelay SetMultiShopController(MultiShopController multiShopController) { MultiShopController = multiShopController; return this; } public RecheckShopAvailableAfterDelay SetTerminalObjects(GameObject[] terminalObjects) { TerminalObjects = terminalObjects; return this; } public RecheckShopAvailableAfterDelay RemoveHighlightAfterDelay() { RemoveHighlightFromUsed = true; return this; } [IteratorStateMachine(typeof(<RecheckShopAfterDelay>d__9))] private IEnumerator RecheckShopAfterDelay() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RecheckShopAfterDelay>d__9(0) { <>4__this = this }; } } } [CompilerGenerated] internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T> { object IEnumerator.Current => _item; T IEnumerator<T>.Current => _item; public Enumerator(T item) { _item = item; } bool IEnumerator.MoveNext() { if (!_moveNextCalled) { return _moveNextCalled = true; } return false; } void IEnumerator.Reset() { _moveNextCalled = false; } void IDisposable.Dispose() { } } int ICollection.Count => 1; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => 1; T IReadOnlyList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } } int ICollection<T>.Count => 1; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return _item; } set { throw new NotSupportedException(); } } public <>z__ReadOnlySingleElementList(T item) { _item = item; } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_item); } void ICollection.CopyTo(Array array, int index) { array.SetValue(_item, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return EqualityComparer<T>.Default.Equals(_item, (T)value); } int IList.IndexOf(object value) { if (!EqualityComparer<T>.Default.Equals(_item, (T)value)) { return -1; } return 0; } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(_item); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return EqualityComparer<T>.Default.Equals(_item, item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { array[arrayIndex] = _item; } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { if (!EqualityComparer<T>.Default.Equals(_item, item)) { return -1; } return 0; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } }