Decompiled source of DynamiteUpgrades v1.0.0

DynamiteUpgrades.dll

Decompiled 15 hours ago
using System;
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.Configuration;
using BepInEx.Logging;
using FishNet.Object;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DynamiteUpgrades
{
	[BepInPlugin("justresearch.dynamiteupgrades", "Dynamite Upgrades", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "justresearch.dynamiteupgrades";

		internal static ManualLogSource Log;

		internal static Tier[] Tiers;

		internal static int MaxTier => Tiers.Length - 1;

		private void Awake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Tiers = new Tier[4]
			{
				Tier.Normal,
				new Tier(((BaseUnityPlugin)this).Config, "Strong", 3, 30, 1.6f, 1.3f, 1.3f, 1.5f, 1.3f, new Color(1f, 0.55f, 0f)),
				new Tier(((BaseUnityPlugin)this).Config, "Super", 4, 50, 3f, 1.75f, 1.8f, 2.5f, 1.8f, new Color(0.2f, 0.45f, 1f)),
				new Tier(((BaseUnityPlugin)this).Config, "Mega", 5, 80, 5f, 2.2f, 2.4f, 4f, 2.4f, new Color(0.7f, 0.2f, 1f))
			};
			new Harmony("justresearch.dynamiteupgrades").PatchAll();
			Log.LogInfo((object)"Dynamite Upgrades loaded");
		}
	}
	internal class Tier
	{
		public static readonly Tier Normal = new Tier();

		public string Name = "";

		public ConfigEntry<int> Island;

		public ConfigEntry<int> Cost;

		public ConfigEntry<float> Damage;

		public ConfigEntry<float> Radius;

		public ConfigEntry<float> Force;

		public ConfigEntry<float> Fish;

		public ConfigEntry<float> Shake;

		public ConfigEntry<Color> Color;

		private Tier()
		{
		}

		public Tier(ConfigFile cfg, string name, int island, int cost, float damage, float radius, float force, float fish, float shake, Color color)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			Name = name;
			string text = name + " Dynamite";
			Island = cfg.Bind<int>(text, "AvailableFromIsland", island, "First island (1-5) whose shop counter offers this upgrade, like the gun upgrades");
			Cost = cfg.Bind<int>(text, "Cost", cost, "Price of this upgrade at the bullet upgrade counter (a stick of dynamite costs $25)");
			Damage = cfg.Bind<float>(text, "DamageMultiplier", damage, "Explosion damage multiplier");
			Radius = cfg.Bind<float>(text, "RadiusMultiplier", radius, "Damage and push radius multiplier");
			Force = cfg.Bind<float>(text, "ForceMultiplier", force, "How hard items, players and boats get thrown");
			Fish = cfg.Bind<float>(text, "FishMultiplier", fish, "How many fish an underwater blast brings up");
			Shake = cfg.Bind<float>(text, "ScreenShakeMultiplier", shake, "Screen shake multiplier (cosmetic)");
			Color = cfg.Bind<Color>(text, "Color", color, "Color of the stick. Its hue replaces the red of normal dynamite; white and grey parts stay as they are");
		}
	}
	internal static class DynamiteTier
	{
		private const float Step = 0.0001f;

		public static int CurrentIsland
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)OnlineIslandManager.Instance))
				{
					return 0;
				}
				return OnlineIslandManager.CurIsland + 1;
			}
		}

		public static int Get(Item item)
		{
			if (!Object.op_Implicit((Object)(object)item))
			{
				return 0;
			}
			return Decode(item._syncedRandomWeight.Value);
		}

		public static int Decode(float w)
		{
			int num = Mathf.RoundToInt((w - 1f) / 0.0001f);
			if (num <= 0 || num > Plugin.MaxTier || Mathf.Abs(w - (1f + (float)num * 0.0001f)) > 2.5E-05f)
			{
				return 0;
			}
			return num;
		}

		public static bool IsUnlocked(int tier)
		{
			return CurrentIsland >= Plugin.Tiers[tier].Island.Value;
		}

		public static float Encode(int tier)
		{
			return 1f + (float)tier * 0.0001f;
		}

		public static void ServerSet(Item item, int tier)
		{
			item._syncedRandomWeight.Value = Encode(tier);
		}

		public static (int cost, Currency currency) CostFor(Item item, int tier)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Tier tier2 = Plugin.Tiers[tier];
			return (cost: Mathf.Max(0, tier2.Cost.Value), currency: item._currency);
		}

		public static bool TryGetHeld(Player player, out Explosive dynamite)
		{
			dynamite = null;
			if (!Object.op_Implicit((Object)(object)player))
			{
				return false;
			}
			Item val = (Object.op_Implicit((Object)(object)player.Holding) ? player.Holding.HeldItem : null);
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val.SyncedHolder != (Object)(object)player)
			{
				return false;
			}
			dynamite = (Explosive)(object)((val is Explosive) ? val : null);
			return Object.op_Implicit((Object)(object)dynamite);
		}

		public static Explosive FindHeldOnServer(Player player)
		{
			Explosive[] array = Object.FindObjectsByType<Explosive>();
			foreach (Explosive val in array)
			{
				if ((Object)(object)((Item)val).SyncedHolder == (Object)(object)player)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class Scaling
	{
		private static readonly MethodInfo Clone = AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null);

		private static readonly ConditionalWeakTable<ExplosionInfo, object> Scaled = new ConditionalWeakTable<ExplosionInfo, object>();

		public static bool IsScaled(ExplosionInfo info)
		{
			object value;
			return Scaled.TryGetValue(info, out value);
		}

		public static ExplosionInfo Scale(ExplosionInfo src, int tier)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			Tier tier2 = Plugin.Tiers[tier];
			ExplosionInfo val = (ExplosionInfo)Clone.Invoke(src, null);
			val._damage = Mathf.RoundToInt((float)val._damage * tier2.Damage.Value);
			val.damageRadius *= tier2.Radius.Value;
			val._forceRadius *= tier2.Radius.Value;
			val._itemForce *= tier2.Force.Value;
			val._boatForce *= tier2.Force.Value;
			val._playerForce *= tier2.Force.Value;
			val._underwaterFishMinMax = new Vector2Int(Mathf.RoundToInt((float)((Vector2Int)(ref val._underwaterFishMinMax)).x * tier2.Fish.Value), Mathf.RoundToInt((float)((Vector2Int)(ref val._underwaterFishMinMax)).y * tier2.Fish.Value));
			val._screenShakeAmount *= tier2.Shake.Value;
			Scaled.Add(val, null);
			return val;
		}
	}
	[HarmonyPatch(typeof(ExplosionManager), "ServerExplode")]
	internal static class ServerExplodePatch
	{
		private static void Prefix(Item item, ref ExplosionInfo info, out ExplosionInfo __state)
		{
			__state = null;
			if (item is Explosive && info != null && !Scaling.IsScaled(info))
			{
				int num = DynamiteTier.Get(item);
				if (num != 0)
				{
					__state = info;
					info = Scaling.Scale(info, num);
				}
			}
		}

		private static void Postfix(ref ExplosionInfo info, ExplosionInfo __state)
		{
			if (__state != null && info != null)
			{
				__state.HasExploded = info.HasExploded;
			}
		}
	}
	[HarmonyPatch]
	internal static class ObserverExplodePatch
	{
		internal static Item Current;

		private static MethodBase TargetMethod()
		{
			return AccessTools.GetDeclaredMethods(typeof(ExplosionManager)).First((MethodInfo m) => m.Name.StartsWith("RpcLogic___ObserverExplode"));
		}

		private static void Prefix(Item __0)
		{
			Current = __0;
		}

		private static void Finalizer()
		{
			Current = null;
		}
	}
	[HarmonyPatch(typeof(ExplosionManager), "ExplodeEffects")]
	internal static class ExplodeEffectsPatch
	{
		private static void Prefix(ref ExplosionInfo info)
		{
			int num = DynamiteTier.Get(ObserverExplodePatch.Current);
			if (num > 0 && info != null && !Scaling.IsScaled(info))
			{
				info = Scaling.Scale(info, num);
			}
		}
	}
	[HarmonyPatch]
	internal static class BaseCalls
	{
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Purchasable), "Hover")]
		public static void PurchasableHover(Purchasable instance)
		{
			throw new NotImplementedException("stub");
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Interactable), "Interact")]
		public static void InteractableInteract(Interactable instance, Player player)
		{
			throw new NotImplementedException("stub");
		}
	}
	[HarmonyPatch(typeof(BulletPurchasable), "Hover")]
	internal static class CounterHoverPatch
	{
		private static bool Prefix(BulletPurchasable __instance)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Invalid comparison between Unknown and I4
			Player localPlayer = Player.LocalPlayer;
			if (__instance._forArrows || !DynamiteTier.TryGetHeld(localPlayer, out var dynamite))
			{
				return true;
			}
			int num = DynamiteTier.Get((Item)(object)dynamite);
			string text = "";
			string text2 = "";
			__instance._upgrade = "Upgrade Dynamite";
			if (num < Plugin.MaxTier && !DynamiteTier.IsUnlocked(num + 1))
			{
				((Purchasable)__instance)._customCanBuy = false;
				text = "(Max for this island)";
				__instance._fullDescription = "Max for this island";
			}
			else if (num < Plugin.MaxTier)
			{
				Tier tier = Plugin.Tiers[num + 1];
				(int cost, Currency currency) tuple = DynamiteTier.CostFor((Item)(object)dynamite, num + 1);
				int item = tuple.cost;
				Currency item2 = tuple.currency;
				((Purchasable)__instance)._customCost = item;
				((Purchasable)__instance)._customCurrency = item2;
				((Purchasable)__instance)._customCanBuy = true;
				text2 = $"\n{(((int)item2 == 1) ? '€' : '$')}{item}";
				__instance._fullDescription = ((num == 0) ? "Dynamite" : (Plugin.Tiers[num].Name + " Dynamite")) + " -> " + tier.Name + " Dynamite\n" + $"Damage x{tier.Damage.Value:0.##}   Radius x{tier.Radius.Value:0.##}\n" + $"Fish from underwater blasts x{tier.Fish.Value:0.##}";
			}
			else
			{
				((Purchasable)__instance)._customCanBuy = false;
				text = "(Max power)";
				__instance._fullDescription = "This dynamite can't get any stronger.";
			}
			string text3 = (((Purchasable)__instance)._isFree ? (__instance._upgrade + "\n" + SpriteManager.GetPickUpInput()) : (__instance._upgrade + " " + text + text2 + "\n" + SpriteManager.GetPickUpInput()));
			if (text3 != ((Purchasable)__instance)._hoverString)
			{
				((Interactable)__instance)._isHovering = false;
				((Purchasable)__instance)._hoverString = text3;
			}
			BaseCalls.PurchasableHover((Purchasable)(object)__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(BulletPurchasable), "Interact")]
	internal static class CounterInteractPatch
	{
		internal const byte UpgradeDynamiteCode = 215;

		private static bool Prefix(BulletPurchasable __instance, Player player)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			if (__instance._forArrows || !DynamiteTier.TryGetHeld(player, out var dynamite))
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)Server.Instance))
			{
				return false;
			}
			BaseCalls.InteractableInteract((Interactable)(object)__instance, player);
			int num = DynamiteTier.Get((Item)(object)dynamite);
			if (num >= Plugin.MaxTier || !DynamiteTier.IsUnlocked(num + 1))
			{
				((Purchasable)__instance).CantBuyEffects();
				return false;
			}
			var (num2, val) = DynamiteTier.CostFor((Item)(object)dynamite, num + 1);
			if (!MoneyManager.CanAfford(num2, val))
			{
				((Purchasable)__instance).CantBuyEffects();
				return false;
			}
			Server.Instance.BuyBait(player, (byte)215, num2);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class ServerBuyBaitPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.GetDeclaredMethods(typeof(Server)).First((MethodInfo m) => m.Name.StartsWith("RpcLogic___BuyBait"));
		}

		private static bool Prefix(Player __0, byte __1)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			if (__1 != 215)
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)__0) || ((NetworkBehaviour)__0).IsDeinitializing)
			{
				return false;
			}
			Explosive val = DynamiteTier.FindHeldOnServer(__0);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			int num = DynamiteTier.Get((Item)(object)val);
			if (num >= Plugin.MaxTier || !DynamiteTier.IsUnlocked(num + 1))
			{
				return false;
			}
			var (num2, val2) = DynamiteTier.CostFor((Item)(object)val, num + 1);
			if (!MoneyManager.CanAfford(num2, val2))
			{
				return false;
			}
			MoneyManager.RemoveMoney(num2, __0, val2);
			DynamiteTier.ServerSet((Item)(object)val, num + 1);
			Plugin.Log.LogInfo((object)$"{__0.SteamName} upgraded dynamite to {Plugin.Tiers[num + 1].Name} for {num2}");
			return false;
		}
	}
	[HarmonyPatch(typeof(SaveManager), "ItemToSavedItem")]
	internal static class SaveTierPatch
	{
		private static void Postfix(Item item, SavedItem __result)
		{
			if (__result != null && item is Explosive)
			{
				int num = DynamiteTier.Get(item);
				if (num > 0)
				{
					__result.Weight = DynamiteTier.Encode(num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Item), "LoadFromSave")]
	internal static class LoadTierPatch
	{
		private static void Postfix(Item __instance, SavedItem savedItem)
		{
			if (savedItem != null && __instance is Explosive)
			{
				int num = DynamiteTier.Decode(savedItem.Weight);
				if (num > 0)
				{
					DynamiteTier.ServerSet(__instance, num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Item), "GetName")]
	internal static class ItemNamePatch
	{
		private static void Postfix(Item __instance, ref string __result)
		{
			if (__instance is Explosive)
			{
				int num = DynamiteTier.Get(__instance);
				if (num > 0)
				{
					__result = Plugin.Tiers[num].Name + " " + __result;
				}
			}
		}
	}
	internal static class Recolor
	{
		private static readonly Dictionary<(Texture, int), Texture2D> Cache = new Dictionary<(Texture, int), Texture2D>();

		private static readonly ConditionalWeakTable<Material, Dictionary<string, Texture>> Originals = new ConditionalWeakTable<Material, Dictionary<string, Texture>>();

		private static bool _loggedShader;

		public static void Apply(Renderer renderer, int tier)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return;
			}
			Material[] materials = renderer.materials;
			foreach (Material val in materials)
			{
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				foreach (KeyValuePair<string, Texture> item in Originals.GetValue(val, Capture))
				{
					val.SetTexture(item.Key, (Texture)((tier == 0) ? ((object)item.Value) : ((object)Tinted(item.Value, tier))));
				}
			}
		}

		private static Dictionary<string, Texture> Capture(Material mat)
		{
			if (!_loggedShader)
			{
				_loggedShader = true;
				Shader sh = mat.shader;
				IEnumerable<string> values = from i in Enumerable.Range(0, sh.GetPropertyCount())
					select $"{sh.GetPropertyName(i)}:{sh.GetPropertyType(i)}";
				Plugin.Log.LogInfo((object)("Dynamite shader '" + ((Object)sh).name + "' properties: " + string.Join(", ", values)));
			}
			Dictionary<string, Texture> dictionary = new Dictionary<string, Texture>();
			string[] texturePropertyNames = mat.GetTexturePropertyNames();
			foreach (string text in texturePropertyNames)
			{
				Texture texture = mat.GetTexture(text);
				string text2 = text.ToLowerInvariant();
				if (texture is Texture2D && !text2.Contains("normal") && !text2.Contains("bump"))
				{
					dictionary[text] = texture;
					Plugin.Log.LogInfo((object)$"Recoloring texture {text} = '{((Object)texture).name}' ({texture.width}x{texture.height})");
				}
			}
			return dictionary;
		}

		private static Texture2D Tinted(Texture src, int tier)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00b8: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			if (Cache.TryGetValue((src, tier), out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			int width = src.width;
			int height = src.height;
			RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Graphics.Blit(src, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			bool flag = src.mipmapCount > 1;
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, flag, false)
			{
				name = ((Object)src).name + "_" + Plugin.Tiers[tier].Name,
				filterMode = src.filterMode,
				wrapMode = src.wrapMode,
				anisoLevel = src.anisoLevel
			};
			val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0, false);
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(Plugin.Tiers[tier].Color.Value, ref num, ref num2, ref num3);
			Color32[] pixels = val.GetPixels32();
			float num4 = default(float);
			float num5 = default(float);
			for (int i = 0; i < pixels.Length; i++)
			{
				Color val2 = Color32.op_Implicit(pixels[i]);
				Color.RGBToHSV(val2, ref num3, ref num4, ref num5);
				if (!(num4 < 0.2f))
				{
					Color val3 = Color.HSVToRGB(num, Mathf.Lerp(num4, num2, 0.5f), num5);
					val3.a = val2.a;
					pixels[i] = Color32.op_Implicit(val3);
				}
			}
			val.SetPixels32(pixels);
			val.Apply(flag, false);
			Cache[(src, tier)] = val;
			return val;
		}
	}
	[HarmonyPatch(typeof(Explosive), "Update")]
	internal static class TintPatch
	{
		private class Seen
		{
			public int Tier;
		}

		private static readonly ConditionalWeakTable<Explosive, Seen> Applied = new ConditionalWeakTable<Explosive, Seen>();

		private static void Postfix(Explosive __instance)
		{
			int num = DynamiteTier.Get((Item)(object)__instance);
			Seen orCreateValue = Applied.GetOrCreateValue(__instance);
			if (orCreateValue.Tier == num)
			{
				return;
			}
			orCreateValue.Tier = num;
			foreach (Renderer renderer in ((Item)__instance)._renderers)
			{
				Recolor.Apply(renderer, num);
			}
			InventoryTintPatch.RefreshSlotsShowing((Item)(object)__instance);
		}
	}
	[HarmonyPatch(typeof(InventorySlot), "ApplySkin")]
	internal static class InventoryTintPatch
	{
		private static readonly HashSet<InventorySlot> Tinted = new HashSet<InventorySlot>();

		private static void Postfix(InventorySlot __instance, Item item)
		{
			Refresh(__instance, item);
		}

		private static void Refresh(InventorySlot slot, Item item)
		{
			if (!Object.op_Implicit((Object)(object)slot) || !Object.op_Implicit((Object)(object)slot._renderer))
			{
				return;
			}
			int num = ((item is Explosive) ? DynamiteTier.Get(item) : 0);
			if (num != 0 || Tinted.Contains(slot))
			{
				Recolor.Apply(slot._renderer, num);
				if (num > 0)
				{
					Tinted.Add(slot);
				}
				else
				{
					Tinted.Remove(slot);
				}
			}
		}

		public static void RefreshSlotsShowing(Item item)
		{
			Player localPlayer = Player.LocalPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)localPlayer.Inventory) || localPlayer.Inventory._itemSlots == null)
			{
				return;
			}
			foreach (InventorySlot itemSlot in localPlayer.Inventory._itemSlots)
			{
				if (Object.op_Implicit((Object)(object)itemSlot) && (Object)(object)itemSlot.Item == (Object)(object)item)
				{
					Refresh(itemSlot, item);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}