using 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Cray.SBGItemFramework.Internal; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Localization; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("SBGItemFramework")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b05c8ecd1dc994ba6a0215a8705814501bf7f713")] [assembly: AssemblyProduct("SBGItemFramework")] [assembly: AssemblyTitle("SBGItemFramework")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Cray.SBGItemFramework { public interface IItemHandler { void OnUse(PlayerInventory inventory); void OnEquip(PlayerInventory inventory); void OnUnequip(PlayerInventory inventory); } public abstract class ItemHandlerBase : IItemHandler { public abstract void OnUse(PlayerInventory inventory); public virtual void OnEquip(PlayerInventory inventory) { } public virtual void OnUnequip(PlayerInventory inventory) { } } public static class ItemKit { private static readonly Dictionary _items = new Dictionary(); public static IReadOnlyCollection All => _items.Values; public static bool IsRegistered(ItemType id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return _items.ContainsKey(id); } public static RegisteredItem Get(ItemType id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (!_items.TryGetValue(id, out var value)) { return null; } return value; } public static void Register(RegisteredItem item) { //IL_0014: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (item == null) { throw new ArgumentNullException("item"); } if (_items.ContainsKey(item.Id)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)($"SBGItemFramework: Register({item.Id}, '{item.DisplayName}') ignored — that id is already taken by '{_items[item.Id].DisplayName}'. " + "If two mods are claiming the same ItemType, the second registration loses; pick a different id.")); } return; } RegisteredItem registeredItem = ApplyConfigBindings(item); _items[registeredItem.Id] = registeredItem; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"SBGItemFramework: registered {registeredItem.Id} '{registeredItem.DisplayName}' (MaxUses={registeredItem.MaxUses})."); } CollectionInjector.NotifyRegistered(registeredItem); } private static RegisteredItem ApplyConfigBindings(RegisteredItem item) { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) if (item.ConsumerConfig == null) { return item; } int num = item.MaxUses; Dictionary dictionary = null; string text = "Item: " + item.DisplayName; if (item.BindMaxUsesToConfig) { ConfigEntry val = item.ConsumerConfig.Bind(text, "MaxUses", item.MaxUses, "Number of charges this item starts with. Set to 1 for single-use items."); num = Math.Max(1, val.Value); } if (item.BindSpawnWeightsToConfig && item.SpawnWeights != null) { dictionary = new Dictionary(); foreach (KeyValuePair spawnWeight in item.SpawnWeights) { string text2 = PoolLabel(spawnWeight.Key); ConfigEntry val2 = item.ConsumerConfig.Bind(text, "SpawnWeight." + text2, spawnWeight.Value, "Relative spawn weight of this item in pool '" + text2 + "' (0 disables)."); dictionary[spawnWeight.Key] = Math.Max(0f, val2.Value); } } if (num == item.MaxUses && dictionary == null) { return item; } RegisteredItem.Builder builder = RegisteredItem.Define(item.Id, item.DisplayName).WithHandler(item.Handler).WithMaxUses(num); if (item.IconSourceVanillaItem.HasValue) { builder.WithIconFromVanillaItem(item.IconSourceVanillaItem.Value); } if ((Object)(object)item.IconOverride != (Object)null) { builder.WithIconOverride(item.IconOverride); } if (item.IconTint.HasValue) { builder.WithIconTint(item.IconTint.Value); } if (!string.IsNullOrEmpty(item.Tooltip)) { builder.WithTooltip(item.Tooltip); } if (item.MimicVanillaItem.HasValue) { builder.WithMimicVanillaItem(item.MimicVanillaItem.Value); } else if (!item.SuppressVanillaSwingEligibility) { builder.AllowVanillaSwingEligibility(); } if (item.ItemDataPostInit != null) { builder.WithItemDataPostInit(item.ItemDataPostInit); } Dictionary dictionary2 = dictionary ?? ((item.SpawnWeights != null) ? new Dictionary(item.SpawnWeights) : null); if (dictionary2 != null) { foreach (KeyValuePair item2 in dictionary2) { builder.WithSpawnWeight(item2.Key, item2.Value); } } return builder.Done(); } internal static string PoolLabel(int poolIndex) { return poolIndex switch { 0 => "AheadOfOwnBall", 1 => "Far", 2 => "Mid", 3 => "Close", 4 => "Lead", 5 => "MobilityBoxes", _ => $"Pool{poolIndex}", }; } internal static IEnumerable Snapshot() { return _items.Values.ToList(); } } [BepInPlugin("cray.sbg.itemframework", "SBGItemFramework", "0.1.0")] public sealed class Plugin : BaseUnityPlugin { public const string ModGuid = "cray.sbg.itemframework"; public const string ModName = "SBGItemFramework"; public const string ModVersion = "0.1.0"; internal static ManualLogSource Log; internal static Plugin Instance; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; new Harmony("cray.sbg.itemframework").PatchAll(); GameObject val = new GameObject("SBGItemFramework.Host") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); val.AddComponent(); Log.LogInfo((object)"SBGItemFramework v0.1.0 loaded."); } } internal sealed class LocalizationSeederHost : MonoBehaviour { private void Update() { LocalizationSeeder.TryRunOnce(); } } public delegate void ItemDataPostInit(ItemData synthesized, ItemData source); public sealed class RegisteredItem { public sealed class Builder { internal readonly ItemType _id; internal readonly string _displayName; internal IItemHandler _handler; internal int _maxUses = 1; internal ItemType? _iconSource; internal Sprite _iconOverride; internal Color? _iconTint; internal string _tooltip; internal Dictionary _spawnWeights; internal bool _suppressVanillaSwing = true; internal ItemType? _mimicVanillaItem; internal ItemDataPostInit _itemDataPostInit; internal ConfigFile _consumerConfig; internal bool _bindMaxUsesToConfig; internal bool _bindSpawnWeightsToConfig; internal Builder(ItemType id, string displayName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((int)id <= 0) { throw new ArgumentException("Id must be a positive ItemType value (use a high integer like 1001+ to avoid colliding with vanilla item ids).", "id"); } if (string.IsNullOrWhiteSpace(displayName)) { throw new ArgumentException("displayName cannot be null or whitespace.", "displayName"); } _id = id; _displayName = displayName; } public Builder WithHandler(IItemHandler handler) { _handler = handler ?? throw new ArgumentNullException("handler"); return this; } public Builder WithMaxUses(int uses) { if (uses < 1) { throw new ArgumentOutOfRangeException("uses", "MaxUses must be >= 1."); } _maxUses = uses; return this; } public Builder WithIconFromVanillaItem(ItemType source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) _iconSource = source; return this; } public Builder WithIconOverride(Sprite sprite) { _iconOverride = sprite; return this; } public Builder WithIconTint(Color tint) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) _iconTint = tint; return this; } public Builder WithTooltip(string text) { _tooltip = text; return this; } public Builder WithSpawnWeight(int poolIndex, float weight) { if (poolIndex < 0 || poolIndex > 5) { throw new ArgumentOutOfRangeException("poolIndex", "Pool index must be 0..5 (see RegisteredItem.PoolAhead..PoolMobility)."); } if (weight < 0f) { throw new ArgumentOutOfRangeException("weight", "Weight must be >= 0."); } if (_spawnWeights == null) { _spawnWeights = new Dictionary(); } _spawnWeights[poolIndex] = weight; return this; } public Builder AllowVanillaSwingEligibility() { _suppressVanillaSwing = false; return this; } public Builder WithItemDataPostInit(ItemDataPostInit callback) { _itemDataPostInit = callback; return this; } public Builder WithMimicVanillaItem(ItemType mimic) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) _mimicVanillaItem = mimic; _suppressVanillaSwing = false; return this; } public Builder WithConfigBindings(ConfigFile consumerConfig, bool bindMaxUses = true, bool bindSpawnWeights = true) { _consumerConfig = consumerConfig ?? throw new ArgumentNullException("consumerConfig"); _bindMaxUsesToConfig = bindMaxUses; _bindSpawnWeightsToConfig = bindSpawnWeights; return this; } public RegisteredItem Done() { if (_handler == null) { throw new InvalidOperationException("RegisteredItem requires WithHandler(...) before Done()."); } if (_iconSource.HasValue && (Object)(object)_iconOverride != (Object)null) { throw new InvalidOperationException("WithIconFromVanillaItem and WithIconOverride are mutually exclusive — pick one."); } return new RegisteredItem(this); } } public const int PoolAhead = 0; public const int PoolFar = 1; public const int PoolMid = 2; public const int PoolClose = 3; public const int PoolLead = 4; public const int PoolMobility = 5; public ItemType Id { get; } public string DisplayName { get; } public IItemHandler Handler { get; } public int MaxUses { get; } public ItemType? IconSourceVanillaItem { get; } public Sprite IconOverride { get; } public Color? IconTint { get; } public string Tooltip { get; } public IReadOnlyDictionary SpawnWeights { get; } public bool SuppressVanillaSwingEligibility { get; } public ItemType? MimicVanillaItem { get; } public ItemDataPostInit ItemDataPostInit { get; } public ConfigFile ConsumerConfig { get; } public bool BindMaxUsesToConfig { get; } public bool BindSpawnWeightsToConfig { get; } private RegisteredItem(Builder b) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) Id = b._id; DisplayName = b._displayName; Handler = b._handler; MaxUses = b._maxUses; IconSourceVanillaItem = b._iconSource; IconOverride = b._iconOverride; IconTint = b._iconTint; Tooltip = b._tooltip; SpawnWeights = ((b._spawnWeights == null) ? null : new Dictionary(b._spawnWeights)); SuppressVanillaSwingEligibility = b._suppressVanillaSwing; MimicVanillaItem = b._mimicVanillaItem; ItemDataPostInit = b._itemDataPostInit; ConsumerConfig = b._consumerConfig; BindMaxUsesToConfig = b._bindMaxUsesToConfig; BindSpawnWeightsToConfig = b._bindSpawnWeightsToConfig; } public static Builder Define(ItemType id, string displayName) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new Builder(id, displayName); } } } namespace Cray.SBGItemFramework.Internal { internal static class IconTinter { private readonly struct TintCacheKey : IEquatable { private readonly int _textureId; private readonly int _packedRgba; public TintCacheKey(int textureId, Color tint) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) _textureId = textureId; Color32 val = Color32.op_Implicit(tint); _packedRgba = (val.r << 24) | (val.g << 16) | (val.b << 8) | val.a; } public bool Equals(TintCacheKey other) { if (_textureId == other._textureId) { return _packedRgba == other._packedRgba; } return false; } public override bool Equals(object obj) { if (obj is TintCacheKey other) { return Equals(other); } return false; } public override int GetHashCode() { return (_textureId * 397) ^ _packedRgba; } } private static readonly Dictionary _cache = new Dictionary(); private static Material _colourMulMaterial; public static Sprite ApplyTint(Sprite source, Color tint) { //IL_0026: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_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) //IL_009c: 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) if ((Object)(object)source == (Object)null || (Object)(object)source.texture == (Object)null) { return source; } TintCacheKey key = new TintCacheKey(((Object)source.texture).GetInstanceID(), tint); if (_cache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = (((Texture)source.texture).isReadable ? TintViaCpuPixels(source.texture, tint) : TintViaBlit(source.texture, tint)); if ((Object)(object)val == (Object)null) { return source; } Rect rect = source.rect; float x = source.pivot.x; Rect rect2 = source.rect; float num = x / ((Rect)(ref rect2)).width; float y = source.pivot.y; rect2 = source.rect; Sprite val2 = Sprite.Create(val, rect, new Vector2(num, y / ((Rect)(ref rect2)).height), source.pixelsPerUnit); ((Object)val2).name = ((Object)source).name + "__sbgkit_tinted"; _cache[key] = val2; return val2; } private static Texture2D TintViaCpuPixels(Texture2D source, Color tint) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) try { Color32[] pixels = source.GetPixels32(); Color32 val = Color32.op_Implicit(tint); for (int i = 0; i < pixels.Length; i++) { Color32 val2 = pixels[i]; pixels[i] = new Color32((byte)(val2.r * val.r / 255), (byte)(val2.g * val.g / 255), (byte)(val2.b * val.b / 255), val2.a); } Texture2D val3 = new Texture2D(((Texture)source).width, ((Texture)source).height, source.format, false) { wrapMode = ((Texture)source).wrapMode, filterMode = ((Texture)source).filterMode }; val3.SetPixels32(pixels); val3.Apply(false, false); return val3; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("SBGItemFramework: CPU-pixel tint of '" + ((Object)source).name + "' failed (" + ex.GetType().Name + "); attempting GPU blit.")); } return TintViaBlit(source, tint); } } private static Texture2D TintViaBlit(Texture2D source, Color tint) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown RenderTexture active = RenderTexture.active; RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0); try { RenderTexture.active = temporary; GL.Clear(false, true, new Color(0f, 0f, 0f, 0f)); Material val = TempColourMultiplyMaterial(tint); Graphics.Blit((Texture)(object)source, temporary, val); Texture2D val2 = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, false); val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0); val2.Apply(false, false); return val2; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("SBGItemFramework: GPU-blit tint of '" + ((Object)source).name + "' failed (" + ex.GetType().Name + "); icon will render untinted.")); } return null; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static Material TempColourMultiplyMaterial(Color tint) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if ((Object)(object)_colourMulMaterial == (Object)null) { _colourMulMaterial = new Material(Shader.Find("UI/Default") ?? Shader.Find("Sprites/Default")); } _colourMulMaterial.color = tint; return _colourMulMaterial; } } internal static class CollectionInjector { private static readonly FieldInfo ItemsField = AccessTools.Field(typeof(ItemCollection), "items"); private static readonly FieldInfo ItemDataTypeBacking = AccessTools.Field(typeof(ItemData), "k__BackingField"); private static readonly FieldInfo ItemDataIconBacking = AccessTools.Field(typeof(ItemData), "k__BackingField"); private static readonly FieldInfo ItemDataMaxUsesBacking = AccessTools.Field(typeof(ItemData), "k__BackingField"); private static readonly FieldInfo ItemDataPrefabBacking = AccessTools.Field(typeof(ItemData), "k__BackingField"); private static readonly FieldInfo ItemDataNonAimUseBacking = AccessTools.Field(typeof(ItemData), "k__BackingField"); private static readonly Dictionary _producedItemData = new Dictionary(); private static bool _initializeFired; private static ItemCollection _liveCollection; internal static void Apply(ItemCollection collection) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)collection == (Object)null || ItemsField == null || !(ItemsField.GetValue(collection) is ItemData[] array)) { return; } HashSet hashSet = new HashSet(); for (int i = 0; i < array.Length; i++) { if (array[i] != null) { hashSet.Add(array[i].Type); } } List list = null; foreach (RegisteredItem item in ItemKit.Snapshot()) { if (hashSet.Contains(item.Id)) { continue; } ItemData orBuildItemData = GetOrBuildItemData(item, array); if (orBuildItemData != null) { if (list == null) { list = new List(); } list.Add(orBuildItemData); } } if (list != null) { ItemData[] array2 = (ItemData[])(object)new ItemData[array.Length + list.Count]; Array.Copy(array, array2, array.Length); for (int j = 0; j < list.Count; j++) { array2[array.Length + j] = list[j]; } ItemsField.SetValue(collection, array2); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"SBGItemFramework: extended ItemCollection.items by {list.Count} entry(ies); total now {array2.Length}."); } } } private static ItemData GetOrBuildItemData(RegisteredItem reg, ItemData[] currentItems) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) if (_producedItemData.TryGetValue(reg.Id, out var value) && value != null) { Sprite val = ResolveIcon(reg, currentItems); if ((Object)(object)val != (Object)null) { ItemDataIconBacking?.SetValue(value, val); } ItemDataMaxUsesBacking?.SetValue(value, reg.MaxUses); return value; } ItemData val2 = new ItemData(); ItemDataTypeBacking?.SetValue(val2, reg.Id); ItemDataMaxUsesBacking?.SetValue(val2, reg.MaxUses); ItemDataNonAimUseBacking?.SetValue(val2, (object)(ItemNonAimingUse)0); ItemData val3 = ResolveSource(reg, currentItems); if (val3 != null) { if (ItemDataPrefabBacking != null) { ItemDataPrefabBacking.SetValue(val2, val3.Prefab); } Sprite val4 = ResolveIcon(reg, currentItems); if ((Object)(object)val4 != (Object)null) { ItemDataIconBacking?.SetValue(val2, val4); } } val2.Initialize(); _producedItemData[reg.Id] = val2; if (reg.ItemDataPostInit != null) { try { reg.ItemDataPostInit(val2, val3); } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"SBGItemFramework: ItemDataPostInit for {reg.Id} threw: {arg}"); } } } return val2; } private static ItemData ResolveSource(RegisteredItem reg, ItemData[] currentItems) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!reg.IconSourceVanillaItem.HasValue) { return null; } ItemType value = reg.IconSourceVanillaItem.Value; for (int i = 0; i < currentItems.Length; i++) { if (currentItems[i] != null && currentItems[i].Type == value) { return currentItems[i]; } } return null; } private static Sprite ResolveIcon(RegisteredItem reg, ItemData[] currentItems) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)reg.IconOverride != (Object)null) { if (!reg.IconTint.HasValue) { return reg.IconOverride; } return IconTinter.ApplyTint(reg.IconOverride, reg.IconTint.Value); } ItemData val = ResolveSource(reg, currentItems); if (val == null || (Object)(object)val.Icon == (Object)null) { return null; } if (!reg.IconTint.HasValue) { return val.Icon; } return IconTinter.ApplyTint(val.Icon, reg.IconTint.Value); } internal static void NotifyRegistered(RegisteredItem item) { if (_initializeFired && !((Object)(object)_liveCollection == (Object)null)) { DeferredApply.Schedule(_liveCollection); } } internal static void OnInitializeRan(ItemCollection collection) { _initializeFired = true; _liveCollection = collection; } } [HarmonyPatch(typeof(ItemCollection), "Initialize")] internal static class Patch_ItemCollection_Initialize { private static void Prefix(ItemCollection __instance) { CollectionInjector.Apply(__instance); } private static void Postfix(ItemCollection __instance) { CollectionInjector.OnInitializeRan(__instance); } } [HarmonyPatch(typeof(ItemCollection), "OnEnable")] internal static class Patch_ItemCollection_OnEnable { private static void Prefix(ItemCollection __instance) { CollectionInjector.Apply(__instance); } } internal static class DeferredApply { private sealed class Runner : MonoBehaviour { } private static GameObject _runner; private static bool _scheduled; public static void Schedule(ItemCollection collection) { if (!_scheduled) { EnsureRunner(); _scheduled = true; ((MonoBehaviour)_runner.GetComponent()).StartCoroutine(RunNext(collection)); } } private static IEnumerator RunNext(ItemCollection collection) { yield return null; _scheduled = false; if (!((Object)(object)collection == (Object)null)) { CollectionInjector.Apply(collection); AccessTools.Method(typeof(ItemCollection), "Initialize", (Type[])null, (Type[])null)?.Invoke(collection, null); } } private static void EnsureRunner() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_runner != (Object)null)) { _runner = new GameObject("SBGItemFramework.DeferredApplyRunner"); Object.DontDestroyOnLoad((Object)(object)_runner); ((Object)_runner).hideFlags = (HideFlags)61; _runner.AddComponent(); } } } [HarmonyPatch(typeof(PlayerInventory), "TryUseItem")] internal static class Patch_PlayerInventory_TryUseItem { private static readonly MethodInfo GetEffectiveSlotMethod = AccessTools.Method(typeof(PlayerInventory), "GetEffectiveSlot", (Type[])null, (Type[])null); private static bool Prefix(PlayerInventory __instance, ref bool __result) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) int equippedItemIndex = __instance.EquippedItemIndex; if (equippedItemIndex < 0 || GetEffectiveSlotMethod == null) { return true; } InventorySlot val; try { val = (InventorySlot)GetEffectiveSlotMethod.Invoke(__instance, new object[1] { equippedItemIndex }); } catch { return true; } RegisteredItem registeredItem = ItemKit.Get(val.itemType); if (registeredItem == null) { return true; } __result = true; try { registeredItem.Handler.OnUse(__instance); } catch (Exception arg) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)$"SBGItemFramework: handler for {val.itemType} threw on OnUse: {arg}"); } } return false; } } [HarmonyPatch(typeof(PlayerInventory), "GetEffectivelyEquippedItem")] internal static class Patch_PlayerInventory_GetEffectivelyEquippedItem { private static void Postfix(bool ignoreEquipmentHiding, ref ItemType __result) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown RegisteredItem registeredItem = ItemKit.Get(__result); if (registeredItem != null) { if (registeredItem.MimicVanillaItem.HasValue) { __result = (ItemType)(int)registeredItem.MimicVanillaItem.Value; } else if (!ignoreEquipmentHiding && registeredItem.SuppressVanillaSwingEligibility) { __result = (ItemType)0; } } } } [HarmonyPatch(typeof(LocalizedString), "GetLocalizedString", new Type[] { })] internal static class Patch_LocalizedString_GetLocalizedString { private static void Postfix(LocalizedString __instance, ref string __result) { if (!string.IsNullOrEmpty(__result) && __result.StartsWith("ITEM_", StringComparison.Ordinal) && int.TryParse(__result.Substring("ITEM_".Length), out var result)) { RegisteredItem registeredItem = ItemKit.Get((ItemType)result); if (registeredItem != null) { __result = registeredItem.DisplayName; } } } } [HarmonyPatch(typeof(HotkeyUi), "SetName")] internal static class Patch_HotkeyUi_SetName { private static void Prefix(ref LocalizedString localizedName) { if (localizedName != null) { _ = ((LocalizedReference)localizedName).IsEmpty; } } } [HarmonyPatch(typeof(PauseMenu), "UpdateItemProbabilites")] internal static class Patch_PauseMenu_UpdateItemProbabilites { private static readonly FieldInfo TilesField = AccessTools.Field(typeof(PauseMenu), "allItemProbabilities"); private static readonly FieldInfo TooltipField = AccessTools.Field(typeof(PauseMenu), "itemProbabilityTooltip"); private static readonly FieldInfo TooltipSourcesField = AccessTools.Field(typeof(UiTooltip), "tooltipSources"); private static void Postfix(PauseMenu __instance) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (TilesField == null || TooltipField == null) { return; } GameObject[] array = TilesField.GetValue(__instance) as GameObject[]; object? value = TooltipField.GetValue(__instance); UiTooltip val = (UiTooltip)((value is UiTooltip) ? value : null); if (array == null || (Object)(object)val == (Object)null) { return; } for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] == (Object)null) { continue; } ItemData val2 = (((Object)(object)GameManager.AllItems != (Object)null && i < GameManager.AllItems.Count) ? GameManager.AllItems.GetItemAtIndex(i) : null); if (val2 == null) { continue; } RegisteredItem registeredItem = ItemKit.Get(val2.Type); if (registeredItem != null && !string.IsNullOrEmpty(registeredItem.Tooltip)) { RectTransform component = array[i].GetComponent(); if (!((Object)(object)component == (Object)null)) { string text = TryReadExistingTooltip(val, component); string text2 = (string.IsNullOrEmpty(text) ? registeredItem.Tooltip : (text + "\n" + registeredItem.Tooltip + "")); val.RegisterTooltip(component, text2, (string)null); } } } } private static string TryReadExistingTooltip(UiTooltip tooltip, RectTransform rt) { if (TooltipSourcesField == null) { return null; } object value = TooltipSourcesField.GetValue(tooltip); if (value == null) { return null; } MethodInfo method = value.GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public); MethodInfo method2 = value.GetType().GetMethod("ContainsKey", BindingFlags.Instance | BindingFlags.Public); if (method == null || method2 == null) { return null; } if (!(bool)method2.Invoke(value, new object[1] { rt })) { return null; } object obj = method.Invoke(value, new object[1] { rt }); return obj.GetType().GetField("Item1")?.GetValue(obj) as string; } } [HarmonyPatch(typeof(ItemSpawnerSettings), "ResetRuntimeData")] internal static class Patch_ItemSpawnerSettings_ResetRuntimeData { private static readonly FieldInfo SpawnChancesField = AccessTools.Field(typeof(ItemPool), "spawnChances"); private static readonly FieldInfo TotalWeightField = AccessTools.Field(typeof(ItemPool), "totalSpawnChanceWeight"); private static void Postfix(ItemSpawnerSettings __instance) { //IL_0046: 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) if (SpawnChancesField == null || TotalWeightField == null) { return; } if ((Object)(object)__instance.AheadOfBallItemPool == (Object)null) { if (__instance.ItemPools != null && __instance.ItemPools.Count > 0) { InjectInto(__instance.ItemPools[0].pool, 5); } return; } InjectInto(__instance.AheadOfBallItemPool, 0); if (__instance.ItemPools != null) { for (int i = 0; i < __instance.ItemPools.Count; i++) { InjectInto(__instance.ItemPools[i].pool, i + 1); } } } private static void InjectInto(ItemPool pool, int poolIndex) { //IL_0052: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pool == (Object)null) { return; } List list = null; foreach (RegisteredItem item in ItemKit.All) { if (item.SpawnWeights != null && item.SpawnWeights.TryGetValue(poolIndex, out var value) && !(value <= 0f)) { if (list == null) { list = new List(); } list.Add(new ItemSpawnChance { item = item.Id, spawnChanceWeight = value }); } } if (list != null && list.Count != 0) { ItemSpawnChance[] array = (SpawnChancesField.GetValue(pool) as ItemSpawnChance[]) ?? Array.Empty(); ItemSpawnChance[] array2 = (ItemSpawnChance[])(object)new ItemSpawnChance[array.Length + list.Count]; Array.Copy(array, array2, array.Length); for (int i = 0; i < list.Count; i++) { array2[array.Length + i] = list[i]; } SpawnChancesField.SetValue(pool, array2); float num = 0f; for (int j = 0; j < array2.Length; j++) { num += array2[j].spawnChanceWeight; } TotalWeightField.SetValue(pool, num); } } } internal static class LocalizationSeeder { private static bool _seeded; public static void TryRunOnce() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected I4, but got Unknown if (_seeded) { return; } try { StringTable val = ((LocalizedDatabase)(object)LocalizationSettings.StringDatabase)?.GetTable(TableReference.op_Implicit("Data"), (Locale)null); if ((Object)(object)val == (Object)null) { return; } foreach (RegisteredItem item in ItemKit.All) { string text = "ITEM_" + (int)item.Id; if (((DetailedLocalizationTable)(object)val).GetEntry(text) == null) { ((DetailedLocalizationTable)(object)val).AddEntry(text, item.DisplayName); } } _seeded = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"SBGItemFramework: seeded Localization 'Data' table with custom item names."); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogDebug((object)("SBGItemFramework: localization seed deferred (" + ex.GetType().Name + ": " + ex.Message + "); will retry next frame.")); } } } } }