Decompiled source of HexTweaks v1.0.3

HexTweaks.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using LookingGlass.ItemStatsNameSpace;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.CharacterAI;
using On.RoR2.Items;
using R2API;
using RoR2;
using RoR2.CharacterAI;
using RoR2.Items;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;

[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("HexTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ac23d316688581c8604a709c82fc1aa989f6f821")]
[assembly: AssemblyProduct("HexTweaks")]
[assembly: AssemblyTitle("HexTweaks")]
[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 HexTweaks
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("kaitorque.HexTweaks", "HexTweaks", "1.0.3")]
	public class HexTweaksPlugin : BaseUnityPlugin
	{
		private enum IconPixel : byte
		{
			Transparent,
			Stone,
			Rune,
			Outline
		}

		private class RecoloredMaterial
		{
			public Material material;

			public Material original;

			public HexColor hex;

			public bool isRunes;
		}

		private class HexColor
		{
			public string name;

			public Func<ItemDef> getItem;

			public ConfigEntry<Color> stone;

			public ConfigEntry<RuneColor> runeColor;

			public ItemDef item;

			public Sprite originalIcon;

			public AssetReferenceT<Sprite> originalIconReference;

			public Sprite icon;

			public Color32[] originalIconPixels;

			public IconPixel[] iconClasses;
		}

		public enum RuneColor
		{
			Auto,
			White,
			Black
		}

		private class HolderOnlyMarker : MonoBehaviour
		{
			public FogDamageController controller;

			public float originalRamp;
		}

		private class NonHolderSafeZone : IZone
		{
			private readonly TeamIndex team;

			public NonHolderSafeZone(TeamIndex team)
			{
				//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)
				this.team = team;
			}

			public bool IsInBounds(Vector3 position)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				IReadOnlyList<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(team);
				for (int i = 0; i < teamMembers.Count; i++)
				{
					TeamComponent val = teamMembers[i];
					if (Object.op_Implicit((Object)(object)val) && !(((Component)val).transform.position != position))
					{
						CharacterBody body = val.body;
						Inventory val2 = (Object.op_Implicit((Object)(object)body) ? body.inventory : null);
						if (Object.op_Implicit((Object)(object)val2))
						{
							return val2.GetItemCountEffective(Items.OutOfTPRadius) <= 0;
						}
						return true;
					}
				}
				return false;
			}
		}

		private static class LookingGlassStats
		{
			public static void Register(HexTweaksPlugin p)
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Expected I4, but got Unknown
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Expected O, but got Unknown
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Expected I4, but got Unknown
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Expected O, but got Unknown
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Expected I4, but got Unknown
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Expected O, but got Unknown
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c8: Expected I4, but got Unknown
				if (p.rainEnabled.Value && Object.op_Implicit((Object)(object)Items.IncreasedDifficulty))
				{
					ItemStatsDef val = new ItemStatsDef();
					AddStat(val, "Damage Taken: ", (ValueType)11, (MeasurementUnits)1);
					AddStat(val, "Less Damage Dealt: ", (ValueType)11, (MeasurementUnits)1);
					AddStat(val, "Cooldown Increase: ", (ValueType)11, (MeasurementUnits)1);
					AddStat(val, "Attack Speed Reduction: ", (ValueType)11, (MeasurementUnits)1);
					AddStat(val, "Move Speed Reduction: ", (ValueType)11, (MeasurementUnits)1);
					val.calculateValuesFlat = (int count) => new List<float>
					{
						p.rainDamagePerStack.Value * (float)count,
						MultiplicativeReduction(p.rainDamageDealtReductionPerStack.Value, count),
						p.rainCooldownPerStack.Value * (float)count,
						1f - 1f / (1f + p.rainAttackSpeedReductionPerStack.Value * (float)count),
						1f - 1f / (1f + p.rainMoveSpeedReductionPerStack.Value * (float)count)
					};
					ItemDefinitions.allItemDefinitions[(int)Items.IncreasedDifficulty.itemIndex] = val;
				}
				if (p.strifeEnabled.Value && Object.op_Implicit((Object)(object)Items.HexMountain))
				{
					ItemStatsDef val2 = new ItemStatsDef();
					AddStat(val2, "Boss Damage Taken: ", (ValueType)11, (MeasurementUnits)1);
					AddStat(val2, "Less Damage Dealt to Bosses: ", (ValueType)11, (MeasurementUnits)1);
					val2.calculateValuesFlat = (int count) => new List<float>
					{
						p.strifeDamagePerStack.Value * (float)count,
						MultiplicativeReduction(p.strifeBossDamageDealtReductionPerStack.Value, count)
					};
					ItemDefinitions.allItemDefinitions[(int)Items.HexMountain.itemIndex] = val2;
				}
				if (p.ossificationEnabled.Value && Object.op_Implicit((Object)(object)Items.BarrierEnemiesOnKill))
				{
					ItemStatsDef val3 = new ItemStatsDef();
					AddStat(val3, "Less Damage Dealt After Kill: ", (ValueType)11, (MeasurementUnits)1);
					AddStat(val3, "Duration: ", (ValueType)2, (MeasurementUnits)6);
					val3.calculateValuesFlat = (int count) => new List<float>
					{
						Mathf.Clamp01(p.ossificationDamageReduction.Value),
						p.ossificationDuration.Value + p.ossificationDurationPerStack.Value * (float)(count - 1)
					};
					ItemDefinitions.allItemDefinitions[(int)Items.BarrierEnemiesOnKill.itemIndex] = val3;
				}
				if (p.greedEnabled.Value && Object.op_Implicit((Object)(object)Items.ShareItemsWithEnemies))
				{
					ItemStatsDef val4 = new ItemStatsDef();
					AddStat(val4, "Gold Reduction: ", (ValueType)16, (MeasurementUnits)1);
					val4.calculateValuesFlat = (int count) => new List<float> { MultiplicativeReduction(p.greedGoldReductionPerStack.Value, count) };
					ItemDefinitions.allItemDefinitions[(int)Items.ShareItemsWithEnemies.itemIndex] = val4;
				}
			}

			private static void AddStat(ItemStatsDef def, string description, ValueType valueType, MeasurementUnits units)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				def.descriptions.Add(description);
				def.valueTypes.Add(valueType);
				def.measurementUnits.Add(units);
			}

			private static float MultiplicativeReduction(float perStack, int count)
			{
				return 1f - Mathf.Pow(Mathf.Clamp01(1f - perStack), (float)count);
			}
		}

		public const string PluginGuid = "kaitorque.HexTweaks";

		public const string PluginName = "HexTweaks";

		public const string PluginVersion = "1.0.3";

		private static readonly FieldInfo PatienceControllersField = typeof(OutOfTPRadiusManager).GetField("_teamIndextoFogDamageController", BindingFlags.Static | BindingFlags.NonPublic);

		private static readonly FieldInfo FogStacksField = typeof(FogDamageController).GetField("characterBodyToStacks", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo FogExponentialField = typeof(FogDamageController).GetField("incrementExponentially", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo FogTickPeriodField = typeof(FogDamageController).GetField("tickPeriodSeconds", BindingFlags.Instance | BindingFlags.NonPublic);

		private static HolderOnlyMarker tickingPatienceController;

		private static BuffDef ossificationBuff;

		private static readonly Dictionary<BaseAI, CharacterMaster> mimicOwners = new Dictionary<BaseAI, CharacterMaster>();

		private ConfigEntry<bool> rainEnabled;

		private ConfigEntry<float> rainDamagePerStack;

		private ConfigEntry<float> rainDamageDealtReductionPerStack;

		private ConfigEntry<float> rainCooldownPerStack;

		private ConfigEntry<float> rainAttackSpeedReductionPerStack;

		private ConfigEntry<float> rainMoveSpeedReductionPerStack;

		private ConfigEntry<float> strifeBossDamageDealtReductionPerStack;

		private ConfigEntry<bool> patienceEnabled;

		private ConfigEntry<bool> strifeEnabled;

		private ConfigEntry<float> strifeDamagePerStack;

		private ConfigEntry<bool> ossificationEnabled;

		private ConfigEntry<float> ossificationDamageReduction;

		private ConfigEntry<float> ossificationDuration;

		private ConfigEntry<float> ossificationDurationPerStack;

		private ConfigEntry<bool> greedEnabled;

		private ConfigEntry<float> greedGoldReductionPerStack;

		private ConfigEntry<bool> mimicryEnabled;

		private ConfigEntry<bool> hexColorsEnabled;

		private ConfigEntry<bool> logHexMaterials;

		private ConfigEntry<float> stoneGlow;

		private ConfigEntry<float> runeGlow;

		private static readonly int ColorId = Shader.PropertyToID("_Color");

		private static readonly int EmColorId = Shader.PropertyToID("_EmColor");

		private static readonly int EmTexId = Shader.PropertyToID("_EmTex");

		private static readonly int EmPowerId = Shader.PropertyToID("_EmPower");

		private static readonly int MainTexId = Shader.PropertyToID("_MainTex");

		private static readonly Color WhiteRuneAlbedo = new Color(0.45f, 0.45f, 0.45f);

		private const float AutoRuneLuminanceThreshold = 0.45f;

		private readonly List<HexColor> hexColors = new List<HexColor>();

		private readonly Dictionary<ItemIndex, HexColor> hexColorsByItem = new Dictionary<ItemIndex, HexColor>();

		private readonly Dictionary<(ItemIndex, Material), RecoloredMaterial> recoloredMaterials = new Dictionary<(ItemIndex, Material), RecoloredMaterial>();

		private readonly HashSet<Material> recoloredMaterialSet = new HashSet<Material>();

		private FileSystemWatcher configWatcher;

		private volatile bool configFileChanged;

		private float configReloadTime;

		private readonly HashSet<ItemIndex> loggedHexes = new HashSet<ItemIndex>();

		private const string LookingGlassGuid = "droppod.lookingglass";

		private void Awake()
		{
			//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Expected O, but got Unknown
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_060d: Expected O, but got Unknown
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Expected O, but got Unknown
			//IL_0625: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Expected O, but got Unknown
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_0640: Expected O, but got Unknown
			//IL_0647: Unknown result type (might be due to invalid IL or missing references)
			//IL_0651: Expected O, but got Unknown
			//IL_0658: Unknown result type (might be due to invalid IL or missing references)
			//IL_0662: Expected O, but got Unknown
			//IL_0669: Unknown result type (might be due to invalid IL or missing references)
			//IL_0673: Expected O, but got Unknown
			//IL_067a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Expected O, but got Unknown
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			//IL_071d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0727: Expected O, but got Unknown
			//IL_072e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0738: Expected O, but got Unknown
			//IL_073f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Expected O, but got Unknown
			//IL_0750: Unknown result type (might be due to invalid IL or missing references)
			//IL_075a: Expected O, but got Unknown
			rainEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex of Rain", "Enabled", true, "Hex of Rain no longer raises the run's difficulty. Instead, the holder gets weaker in every way.");
			rainDamagePerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Rain", "Damage Taken Per Stack", 0.15f, "Extra damage taken by the holder per stack. 0.15 = +15% per stack.");
			rainDamageDealtReductionPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Rain", "Damage Dealt Reduction Per Stack", 0.2f, "Holder's damage reduction per stack, applied multiplicatively. 0.2 = 20% less damage with 1 stack, 36% less with 2.");
			rainCooldownPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Rain", "Cooldown Increase Per Stack", 0.15f, "Holder's skill cooldowns are longer by this much per stack. 0.15 = +15% per stack.");
			rainAttackSpeedReductionPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Rain", "Attack Speed Reduction Per Stack", 0.1f, "Holder's attack speed reduction per stack. Works like other slows: 0.1 per stack divides attack speed by 1.1, 1.2, ...");
			rainMoveSpeedReductionPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Rain", "Move Speed Reduction Per Stack", 0.1f, "Holder's movement speed reduction per stack. Works like other slows: 0.1 per stack divides movement speed by 1.1, 1.2, ...");
			patienceEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex of Patience", "Enabled", true, "Hex of Patience only hurts the players holding it, and each holder's damage ramps with their own stacks only.");
			strifeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex of Strife", "Enabled", true, "Hex of Strife no longer adds Shrine of the Mountain effects to the teleporter. Instead, bosses deal more damage to the holder.");
			strifeDamagePerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Strife", "Boss Damage Taken Per Stack", 0.3f, "Extra damage the holder takes from bosses per stack. 0.3 = +30% per stack.");
			strifeBossDamageDealtReductionPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Strife", "Boss Damage Dealt Reduction Per Stack", 0.25f, "Holder deals less damage to bosses per stack, applied multiplicatively. 0.25 = 25% less with 1 stack, 44% less with 2.");
			ossificationEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex of Ossification", "Enabled", true, "Hex of Ossification no longer gives enemies barrier. Instead, after the holder kills an enemy, the holder deals less damage for a few seconds.");
			ossificationDamageReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Ossification", "Damage Reduction", 0.3f, "How much less damage the holder deals after a kill. 0.3 = 30% less.");
			ossificationDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Ossification", "Duration", 5f, "Seconds the reduction lasts after a kill, with 1 stack.");
			ossificationDurationPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Ossification", "Duration Per Extra Stack", 2f, "Extra seconds per additional stack.");
			greedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex of Greed", "Enabled", true, "Hex of Greed no longer gives your items to enemies. Instead, the holder earns less gold.");
			greedGoldReductionPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Hex of Greed", "Gold Reduction Per Stack", 0.25f, "Gold reduction per stack, applied multiplicatively. 0.25 = 25% less gold with 1 stack, 44% less with 2.");
			mimicryEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex of Mimicry", "Enabled", true, "Mimics spawned by Hex of Mimicry only target the player who spawned them.");
			hexColorsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex Colors", "Enabled", true, "Recolors each hex pickup's stone and runes so they can be told apart.");
			stoneGlow = ((BaseUnityPlugin)this).Config.Bind<float>("Hex Colors", "Stone Glow", 4.5f, "How strongly the stone glows in its own color. The glow scales with the stone color's brightness, so darker colors glow less. 0 = no glow, tint only.");
			runeGlow = ((BaseUnityPlugin)this).Config.Bind<float>("Hex Colors", "White Rune Glow", 1.5f, "Glow strength of white runes. Raise it if the runes are hard to see against the stone.");
			logHexMaterials = ((BaseUnityPlugin)this).Config.Bind<bool>("Hex Colors", "Log Materials", false, "Logs each hex pickup's renderers and material properties once per session. Debug aid.");
			BindHexColor("Hex of Patience", () => Items.OutOfTPRadius, "#E02020");
			BindHexColor("Hex of Pain", () => Items.HexCurse, "#6A0F1A");
			BindHexColor("Hex of Rain", () => Items.IncreasedDifficulty, "#2040E0");
			BindHexColor("Hex of Acceleration", () => Items.SlipperyGround, "#20B0C0");
			BindHexColor("Hex of Strife", () => Items.HexMountain, "#7A20D8");
			BindHexColor("Hex of Leaping", () => Items.WeakAssHamstring, "#609A00");
			BindHexColor("Hex of Ossification", () => Items.BarrierEnemiesOnKill, "#D0D0D0");
			BindHexColor("Hex of Loss", () => Items.RoamingItemDisable, "#707070");
			BindHexColor("Hex of Greed", () => Items.ShareItemsWithEnemies, "#FFCC00");
			BindHexColor("Hex of Misfortune", () => Items.RandomDebuffOnInteract, "#FF6000");
			BindHexColor("Hex of Mimicry", () => Items.Mimicry, "#20A030");
			BindHexColor("Hex of Famine", () => Items.LowerHealing, "#D010D0");
			BindHexColor("Hex of Haunting", () => Items.HexHaunting, "#FF60B0");
			BindHexColor("Hex of Blindness", () => Items.Blindness, "#1A1A1A");
			((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)IndexHexColors);
			((ResourceAvailability)(ref PickupCatalog.availability)).CallWhenAvailable((Action)LoadHexIcons);
			if (Chainloader.PluginInfos.ContainsKey("droppod.lookingglass"))
			{
				((ResourceAvailability)(ref PickupCatalog.availability)).CallWhenAvailable((Action)RegisterLookingGlassStats);
			}
			PickupDisplay.OnModelInstanceDiscovered += new hook_OnModelInstanceDiscovered(PickupDisplay_OnModelInstanceDiscovered);
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				ApplyAllHexColors();
			};
			WatchConfigFile();
			Util.GetTotalItemCountFromTeam += new hook_GetTotalItemCountFromTeam(Util_GetTotalItemCountFromTeam);
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(RecalculateStatsAPI_GetStatCoefficients);
			GlobalEventManager.ProcBarrierEnemiesOnKill += new hook_ProcBarrierEnemiesOnKill(GlobalEventManager_ProcBarrierEnemiesOnKill);
			ShareItemsWithEnemiesBehaviour.FixedUpdate += new hook_FixedUpdate(ShareItemsWithEnemiesBehaviour_FixedUpdate);
			CharacterMaster.GiveMoney_uint_bool += new hook_GiveMoney_uint_bool(CharacterMaster_GiveMoney);
			CharacterMaster.AddDeployable += new hook_AddDeployable(CharacterMaster_AddDeployable);
			BaseAI.ManagedFixedUpdate += new hook_ManagedFixedUpdate(BaseAI_ManagedFixedUpdate);
			BaseAI.FindEnemyHurtBox += new hook_FindEnemyHurtBox(BaseAI_FindEnemyHurtBox);
			Stage.onServerStageBegin += delegate
			{
				mimicOwners.Clear();
			};
			ossificationBuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)ossificationBuff).name = "bdHexTweaksOssification";
			ossificationBuff.buffColor = new Color(0.85f, 0.82f, 0.7f);
			ossificationBuff.canStack = false;
			ossificationBuff.isDebuff = true;
			ContentAddition.AddBuffDef(ossificationBuff);
			((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)LoadOssificationIcon);
			HealthComponent.TakeDamageProcess += new hook_TakeDamageProcess(HealthComponent_TakeDamageProcess);
			OutOfTPRadiusManager.InstantiateDamagerForTeam += new hook_InstantiateDamagerForTeam(OutOfTPRadiusManager_InstantiateDamagerForTeam);
			FogDamageController.MyFixedUpdate += new hook_MyFixedUpdate(FogDamageController_MyFixedUpdate);
			Language.GetLocalizedStringByToken += new hook_GetLocalizedStringByToken(Language_GetLocalizedStringByToken);
		}

		private void RecalculateStatsAPI_GetStatCoefficients(CharacterBody body, StatHookEventArgs args)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (rainEnabled.Value && Object.op_Implicit((Object)(object)body.inventory) && Object.op_Implicit((Object)(object)Items.IncreasedDifficulty))
			{
				int itemCountTotal = body.inventory.GetItemCountTotal(Items.IncreasedDifficulty.itemIndex);
				if (itemCountTotal > 0)
				{
					args.allSkills.cooldownMultAdd += rainCooldownPerStack.Value * (float)itemCountTotal;
					args.attackSpeedReductionMultAdd += rainAttackSpeedReductionPerStack.Value * (float)itemCountTotal;
					args.moveSpeedReductionMultAdd += rainMoveSpeedReductionPerStack.Value * (float)itemCountTotal;
					args.damageTotalMult *= Mathf.Pow(Mathf.Clamp01(1f - rainDamageDealtReductionPerStack.Value), (float)itemCountTotal);
				}
			}
		}

		private void LoadOssificationIcon()
		{
			//IL_0037: 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)
			ItemDef barrierEnemiesOnKill = Items.BarrierEnemiesOnKill;
			if (!Object.op_Implicit((Object)(object)barrierEnemiesOnKill))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Hex of Ossification item not found; buff will have no icon.");
				return;
			}
			AssetReferenceT<Sprite> iconReference = barrierEnemiesOnKill.GetIconReference();
			if (iconReference != null && ((AssetReference)iconReference).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Sprite> val = Addressables.LoadAssetAsync<Sprite>(((AssetReference)iconReference).RuntimeKey);
				val.Completed += delegate(AsyncOperationHandle<Sprite> handle)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Invalid comparison between Unknown and I4
					if ((int)handle.Status == 1 && !Object.op_Implicit((Object)(object)ossificationBuff.iconSprite))
					{
						ossificationBuff.iconSprite = handle.Result;
					}
				};
			}
			else
			{
				ossificationBuff.iconSprite = barrierEnemiesOnKill.pickupIconSprite;
			}
		}

		private int Util_GetTotalItemCountFromTeam(orig_GetTotalItemCountFromTeam orig, GetTotalItemCountFromTeamArgs args)
		{
			//IL_005b: 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_001a: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (rainEnabled.Value && Object.op_Implicit((Object)(object)Items.IncreasedDifficulty) && args.itemIndex == Items.IncreasedDifficulty.itemIndex)
			{
				return 0;
			}
			if (strifeEnabled.Value && Object.op_Implicit((Object)(object)Items.HexMountain) && args.itemIndex == Items.HexMountain.itemIndex)
			{
				return 0;
			}
			return orig.Invoke(args);
		}

		private void GlobalEventManager_ProcBarrierEnemiesOnKill(orig_ProcBarrierEnemiesOnKill orig, DamageReport damageReport, int itemStacks, CharacterBody victimBody, TeamIndex attackerTeamIndex)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!ossificationEnabled.Value)
			{
				orig.Invoke(damageReport, itemStacks, victimBody, attackerTeamIndex);
				return;
			}
			CharacterBody attackerBody = damageReport.attackerBody;
			if (Object.op_Implicit((Object)(object)attackerBody) && Object.op_Implicit((Object)(object)ossificationBuff))
			{
				float num = ossificationDuration.Value + ossificationDurationPerStack.Value * (float)(itemStacks - 1);
				attackerBody.ClearTimedBuffs(ossificationBuff);
				attackerBody.AddTimedBuff(ossificationBuff, num);
			}
		}

		private void ShareItemsWithEnemiesBehaviour_FixedUpdate(orig_FixedUpdate orig, ShareItemsWithEnemiesBehaviour self)
		{
			if (!greedEnabled.Value)
			{
				orig.Invoke(self);
			}
		}

		private void CharacterMaster_GiveMoney(orig_GiveMoney_uint_bool orig, CharacterMaster self, uint amount, bool bypassStatManager)
		{
			if (greedEnabled.Value && Object.op_Implicit((Object)(object)self.inventory) && Object.op_Implicit((Object)(object)Items.ShareItemsWithEnemies))
			{
				int itemCountEffective = self.inventory.GetItemCountEffective(Items.ShareItemsWithEnemies);
				if (itemCountEffective > 0)
				{
					float num = Mathf.Pow(Mathf.Clamp01(1f - greedGoldReductionPerStack.Value), (float)itemCountEffective);
					amount = (uint)Mathf.RoundToInt((float)amount * num);
				}
			}
			orig.Invoke(self, amount, bypassStatManager);
		}

		private void CharacterMaster_AddDeployable(orig_AddDeployable orig, CharacterMaster self, Deployable deployable, DeployableSlot slot)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			orig.Invoke(self, deployable, slot);
			if (mimicryEnabled.Value && (int)slot == 37 && Object.op_Implicit((Object)(object)deployable))
			{
				CharacterBody component = ((Component)deployable).GetComponent<CharacterBody>();
				BaseAI val = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.master)) ? ((Component)component.master).GetComponent<BaseAI>() : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					mimicOwners[val] = self;
				}
			}
		}

		private void BaseAI_ManagedFixedUpdate(orig_ManagedFixedUpdate orig, BaseAI self, float deltaTime)
		{
			if (mimicOwners.TryGetValue(self, out var value))
			{
				CharacterBody val = (Object.op_Implicit((Object)(object)value) ? value.GetBody() : null);
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.healthComponent) && val.healthComponent.alive)
				{
					if ((Object)(object)self.currentEnemy.gameObject != (Object)(object)((Component)val).gameObject)
					{
						self.currentEnemy.Reset();
						self.currentEnemy.gameObject = ((Component)val).gameObject;
						self.currentEnemy.bestHurtBox = val.mainHurtBox;
					}
					self.enemyAttention = Mathf.Max(self.enemyAttention, 1f);
				}
				else if (Object.op_Implicit((Object)(object)self.currentEnemy.gameObject))
				{
					self.currentEnemy.Reset();
				}
			}
			orig.Invoke(self, deltaTime);
		}

		private HurtBox BaseAI_FindEnemyHurtBox(orig_FindEnemyHurtBox orig, BaseAI self, float maxDistance, bool full360Vision, bool filterByLoS)
		{
			if (mimicOwners.TryGetValue(self, out var value))
			{
				CharacterBody val = (Object.op_Implicit((Object)(object)value) ? value.GetBody() : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.healthComponent) || !val.healthComponent.alive)
				{
					return null;
				}
				return val.mainHurtBox;
			}
			return orig.Invoke(self, maxDistance, full360Vision, filterByLoS);
		}

		private void HealthComponent_TakeDamageProcess(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo damageInfo)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)tickingPatienceController) && Object.op_Implicit((Object)(object)self.body))
			{
				damageInfo.damage *= GetOwnStacksPatienceMultiplier(tickingPatienceController, self.body);
			}
			Inventory val = (Object.op_Implicit((Object)(object)self.body) ? self.body.inventory : null);
			if (rainEnabled.Value && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)Items.IncreasedDifficulty))
			{
				int itemCountTotal = val.GetItemCountTotal(Items.IncreasedDifficulty.itemIndex);
				if (itemCountTotal > 0)
				{
					damageInfo.damage *= 1f + rainDamagePerStack.Value * (float)itemCountTotal;
				}
			}
			CharacterBody val2 = (Object.op_Implicit((Object)(object)damageInfo.attacker) ? damageInfo.attacker.GetComponent<CharacterBody>() : null);
			if (strifeEnabled.Value && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && val2.isBoss && Object.op_Implicit((Object)(object)Items.HexMountain))
			{
				int itemCountEffective = val.GetItemCountEffective(Items.HexMountain);
				if (itemCountEffective > 0)
				{
					damageInfo.damage *= 1f + strifeDamagePerStack.Value * (float)itemCountEffective;
				}
			}
			if (strifeEnabled.Value && Object.op_Implicit((Object)(object)self.body) && self.body.isBoss && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.inventory) && Object.op_Implicit((Object)(object)Items.HexMountain))
			{
				int itemCountEffective2 = val2.inventory.GetItemCountEffective(Items.HexMountain);
				if (itemCountEffective2 > 0)
				{
					damageInfo.damage *= Mathf.Pow(Mathf.Clamp01(1f - strifeBossDamageDealtReductionPerStack.Value), (float)itemCountEffective2);
				}
			}
			if (ossificationEnabled.Value && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)ossificationBuff) && val2.HasBuff(ossificationBuff))
			{
				damageInfo.damage *= Mathf.Clamp01(1f - ossificationDamageReduction.Value);
			}
			orig.Invoke(self, damageInfo);
		}

		private void OutOfTPRadiusManager_InstantiateDamagerForTeam(orig_InstantiateDamagerForTeam orig, IZone safeZone, TeamIndex affectedTeam, int itemCount)
		{
			//IL_0002: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(safeZone, affectedTeam, itemCount);
			if (patienceEnabled.Value && !(PatienceControllersField == null) && PatienceControllersField.GetValue(null) is IDictionary dictionary && dictionary.Contains(affectedTeam))
			{
				object obj = dictionary[affectedTeam];
				object? obj2 = obj.GetType().GetField("fogDamageControllerInstance")?.GetValue(obj);
				FogDamageController val = (FogDamageController)((obj2 is FogDamageController) ? obj2 : null);
				object obj3 = obj.GetType().GetField("originalHealthFractionRampCoefficientPerSecond")?.GetValue(obj);
				if (Object.op_Implicit((Object)(object)val) && obj3 is float && !Object.op_Implicit((Object)(object)((Component)val).GetComponent<HolderOnlyMarker>()))
				{
					HolderOnlyMarker holderOnlyMarker = ((Component)val).gameObject.AddComponent<HolderOnlyMarker>();
					holderOnlyMarker.controller = val;
					holderOnlyMarker.originalRamp = (float)obj3;
					val.AddSafeZone((IZone)(object)new NonHolderSafeZone(affectedTeam));
				}
			}
		}

		private void FogDamageController_MyFixedUpdate(orig_MyFixedUpdate orig, FogDamageController self, float deltaTime)
		{
			tickingPatienceController = ((Component)self).GetComponent<HolderOnlyMarker>();
			try
			{
				orig.Invoke(self, deltaTime);
			}
			finally
			{
				tickingPatienceController = null;
			}
		}

		private static float GetOwnStacksPatienceMultiplier(HolderOnlyMarker marker, CharacterBody body)
		{
			FogDamageController controller = marker.controller;
			if (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)body.inventory) || !(FogStacksField?.GetValue(controller) is Dictionary<CharacterBody, int> dictionary) || !dictionary.TryGetValue(body, out var value))
			{
				return 1f;
			}
			int itemCountEffective = body.inventory.GetItemCountEffective(Items.OutOfTPRadius);
			if (itemCountEffective <= 0)
			{
				return 1f;
			}
			float healthFractionRampCoefficientPerSecond = controller.healthFractionRampCoefficientPerSecond;
			float num = marker.originalRamp + marker.originalRamp % 1f * (float)(itemCountEffective - 1);
			int num2 = value - 1;
			if (num2 <= 0 || Mathf.Approximately(healthFractionRampCoefficientPerSecond, num))
			{
				return 1f;
			}
			if (FogExponentialField != null && (bool)FogExponentialField.GetValue(controller))
			{
				return Mathf.Pow(num / healthFractionRampCoefficientPerSecond, (float)num2);
			}
			float num3 = ((FogTickPeriodField != null) ? ((float)FogTickPeriodField.GetValue(controller)) : 1f);
			return (1f + (float)num2 * num * num3) / (1f + (float)num2 * healthFractionRampCoefficientPerSecond * num3);
		}

		private string Language_GetLocalizedStringByToken(orig_GetLocalizedStringByToken orig, Language self, string token)
		{
			switch (token)
			{
			case "ITEM_INCREASEDDIFFICULTY_PICKUP":
				if (rainEnabled.Value)
				{
					return "Petrichor V <style=cDeath>weighs you down</style>.";
				}
				break;
			case "ITEM_INCREASEDDIFFICULTY_DESC":
				if (rainEnabled.Value)
				{
					return "You take <style=cDeath>" + Pct(rainDamagePerStack.Value) + "</style> more damage, deal <style=cDeath>" + Pct(rainDamageDealtReductionPerStack.Value) + "</style> less damage, have <style=cDeath>" + Pct(rainCooldownPerStack.Value) + "</style> longer skill cooldowns, <style=cDeath>" + Pct(rainAttackSpeedReductionPerStack.Value) + "</style> lower attack speed, and <style=cDeath>" + Pct(rainMoveSpeedReductionPerStack.Value) + "</style> lower movement speed <style=cStack>(all increase per stack)</style>.";
				}
				break;
			case "ITEM_OUTOFTPRADIUS_PICKUP":
				if (patienceEnabled.Value)
				{
					return "Standing outside of the Teleporter's radius <style=cDeath>hurts</style> you.";
				}
				break;
			case "ITEM_OUTOFTPRADIUS_DESC":
				if (patienceEnabled.Value)
				{
					return orig.Invoke(self, token).Replace("\n<style=cHumanObjective>This effect applies to your allies as well</style>.", "").Trim();
				}
				break;
			case "ITEM_HEXMOUNTAIN_PICKUP":
				if (strifeEnabled.Value)
				{
					return "Bosses <style=cDeath>hit you harder</style> and <style=cDeath>resist your attacks</style>.";
				}
				break;
			case "ITEM_HEXMOUNTAIN_DESC":
				if (strifeEnabled.Value)
				{
					string text = Pct(strifeDamagePerStack.Value);
					string text2 = Pct(strifeBossDamageDealtReductionPerStack.Value);
					return "You take <style=cDeath>" + text + "</style> <style=cStack>(+" + text + " per stack)</style> more damage from <style=cDeath>bosses</style>, and deal <style=cDeath>" + text2 + "</style> <style=cStack>(+" + text2 + " per stack)</style> less damage to them.";
				}
				break;
			case "ITEM_BARRIERENEMIES_PICKUP":
				if (ossificationEnabled.Value)
				{
					return "After killing an enemy, you <style=cDeath>deal less damage</style> for a short time.";
				}
				break;
			case "ITEM_BARRIERENEMIES_DESC":
				if (ossificationEnabled.Value)
				{
					string arg = Mathf.RoundToInt(ossificationDamageReduction.Value * 100f) + "%";
					return $"After killing an enemy, you deal <style=cDeath>{arg}</style> less damage for <style=cIsUtility>{ossificationDuration.Value:0.#}s</style> <style=cStack>(+{ossificationDurationPerStack.Value:0.#}s per stack)</style>.";
				}
				break;
			case "ITEM_SHAREITEMS_PICKUP":
				if (greedEnabled.Value)
				{
					return "You <style=cDeath>earn less gold</style>.";
				}
				break;
			case "ITEM_SHAREITEMS_DESC":
				if (greedEnabled.Value)
				{
					string text3 = Mathf.RoundToInt(greedGoldReductionPerStack.Value * 100f) + "%";
					return "You earn <style=cDeath>" + text3 + "</style> <style=cStack>(+" + text3 + " per stack, multiplicative)</style> less gold.";
				}
				break;
			case "ITEM_MIMICRY_PICKUP":
				if (mimicryEnabled.Value)
				{
					return orig.Invoke(self, token) + " It only hunts <style=cDeath>you</style>.";
				}
				break;
			case "ITEM_MIMICRY_DESC":
				if (mimicryEnabled.Value)
				{
					return orig.Invoke(self, token) + " The Mimic only targets <style=cDeath>you</style>.";
				}
				break;
			}
			return orig.Invoke(self, token);
		}

		private static string Pct(float value)
		{
			return Mathf.RoundToInt(value * 100f) + "%";
		}

		private void BindHexColor(string section, Func<ItemDef> getItem, string stoneHex)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			ColorUtility.TryParseHtmlString(stoneHex, ref val);
			hexColors.Add(new HexColor
			{
				name = section,
				getItem = getItem,
				stone = ((BaseUnityPlugin)this).Config.Bind<Color>(section, "Stone Color", val, "Stone tint and glow color. Each hex has its own hue so they can be told apart from a distance."),
				runeColor = ((BaseUnityPlugin)this).Config.Bind<RuneColor>(section, "Rune Color", RuneColor.Auto, "Auto picks black runes on light stones and white runes on dark ones.")
			});
		}

		private void IndexHexColors()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			foreach (HexColor hexColor in hexColors)
			{
				ItemDef val = hexColor.getItem();
				if (Object.op_Implicit((Object)(object)val) && (int)val.itemIndex != -1)
				{
					hexColorsByItem[val.itemIndex] = hexColor;
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)(hexColor.name + " item not found; it won't be recolored."));
				}
			}
		}

		private void PickupDisplay_OnModelInstanceDiscovered(orig_OnModelInstanceDiscovered orig, PickupDisplay self, bool isNew)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, isNew);
			List<Renderer> modelRenderers = self.modelRenderers;
			if (modelRenderers == null || modelRenderers.Count == 0)
			{
				return;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(self.GetPickupIndex());
			if (pickupDef == null || !hexColorsByItem.TryGetValue(pickupDef.itemIndex, out var value))
			{
				return;
			}
			if (logHexMaterials.Value && loggedHexes.Add(pickupDef.itemIndex))
			{
				LogHexMaterials(value.name, modelRenderers);
			}
			foreach (Renderer item in modelRenderers)
			{
				if (!(item is MeshRenderer) && !(item is SkinnedMeshRenderer))
				{
					continue;
				}
				Material[] sharedMaterials = item.sharedMaterials;
				for (int i = 0; i < sharedMaterials.Length; i++)
				{
					if (Object.op_Implicit((Object)(object)sharedMaterials[i]))
					{
						sharedMaterials[i] = GetRecoloredMaterial(pickupDef.itemIndex, value, sharedMaterials[i]);
					}
				}
				item.sharedMaterials = sharedMaterials;
			}
		}

		private Material GetRecoloredMaterial(ItemIndex itemIndex, HexColor hex, Material original)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (recoloredMaterials.TryGetValue((itemIndex, original), out var value))
			{
				return value.material;
			}
			if (recoloredMaterialSet.Contains(original))
			{
				return original;
			}
			value = new RecoloredMaterial
			{
				material = new Material(original)
				{
					name = ((Object)original).name + " (" + hex.name + ")"
				},
				original = original,
				hex = hex,
				isRunes = ((Object)original).name.Contains("Rune")
			};
			ApplyHexColor(value);
			recoloredMaterials[(itemIndex, original)] = value;
			recoloredMaterialSet.Add(value.material);
			return value.material;
		}

		private void ApplyHexColor(RecoloredMaterial entry)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			Material material = entry.material;
			if (!Object.op_Implicit((Object)(object)material) || !Object.op_Implicit((Object)(object)entry.original))
			{
				return;
			}
			material.CopyPropertiesFromMaterial(entry.original);
			if (!hexColorsEnabled.Value)
			{
				return;
			}
			if (entry.isRunes)
			{
				if (ResolveRuneColor(entry.hex) == RuneColor.White)
				{
					material.SetColor(ColorId, WhiteRuneAlbedo);
					material.SetColor(EmColorId, Color.white * runeGlow.Value);
				}
				else
				{
					material.SetColor(ColorId, Color.black);
					material.SetColor(EmColorId, Color.black);
				}
				return;
			}
			material.SetColor(ColorId, entry.hex.stone.Value);
			if (stoneGlow.Value > 0f)
			{
				material.SetTexture(EmTexId, entry.original.GetTexture(MainTexId));
				material.SetColor(EmColorId, entry.hex.stone.Value * stoneGlow.Value);
				material.SetFloat(EmPowerId, 1f);
			}
		}

		private void ApplyAllHexColors()
		{
			foreach (RecoloredMaterial value in recoloredMaterials.Values)
			{
				ApplyHexColor(value);
			}
			foreach (HexColor hexColor in hexColors)
			{
				ApplyHexIcon(hexColor);
			}
		}

		private void LoadHexIcons()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			foreach (HexColor hex in hexColors)
			{
				ItemDef item = hex.getItem();
				if (!Object.op_Implicit((Object)(object)item))
				{
					continue;
				}
				AssetReferenceT<Sprite> iconReference = item.GetIconReference();
				if (iconReference != null && ((AssetReference)iconReference).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Sprite> val = Addressables.LoadAssetAsync<Sprite>(((AssetReference)iconReference).RuntimeKey);
					val.Completed += delegate(AsyncOperationHandle<Sprite> handle)
					{
						//IL_0002: Unknown result type (might be due to invalid IL or missing references)
						//IL_0008: Invalid comparison between Unknown and I4
						if ((int)handle.Status == 1)
						{
							SetupHexIcon(hex, item, handle.Result);
						}
					};
				}
				else
				{
					SetupHexIcon(hex, item, item.pickupIconSprite);
				}
			}
		}

		private void SetupHexIcon(HexColor hex, ItemDef item, Sprite original)
		{
			//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_007a: 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_00a2: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)original))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)(hex.name + " icon not found; it won't be recolored."));
				return;
			}
			Rect textureRect = original.textureRect;
			int num = Mathf.RoundToInt(((Rect)(ref textureRect)).width);
			int num2 = Mathf.RoundToInt(((Rect)(ref textureRect)).height);
			Texture texture = (Texture)(object)original.texture;
			RenderTexture temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Graphics.Blit(texture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false)
			{
				name = ((Object)original).name + " (" + hex.name + ")"
			};
			val.ReadPixels(new Rect(((Rect)(ref textureRect)).x, ((Rect)(ref textureRect)).y, (float)num, (float)num2), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			hex.originalIconPixels = val.GetPixels32();
			hex.iconClasses = ClassifyIcon(hex.originalIconPixels, num, num2);
			hex.originalIcon = original;
			hex.originalIconReference = item.pickupIconSpriteReference;
			hex.icon = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), original.pixelsPerUnit);
			((Object)hex.icon).name = ((Object)val).name;
			hex.item = item;
			ApplyHexIcon(hex);
			if (logHexMaterials.Value)
			{
				string text = Path.Combine(Paths.ConfigPath, "HexTweaksIcons");
				Directory.CreateDirectory(text);
				Texture2D val2 = new Texture2D(num, num2, (TextureFormat)4, false);
				val2.SetPixels32(hex.originalIconPixels);
				File.WriteAllBytes(Path.Combine(text, hex.name + " original.png"), ImageConversion.EncodeToPNG(val2));
				File.WriteAllBytes(Path.Combine(text, hex.name + " recolored.png"), ImageConversion.EncodeToPNG(val));
				Object.Destroy((Object)(object)val2);
			}
		}

		private void ApplyHexIcon(HexColor hex)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)hex.icon) && hex.originalIconPixels != null)
			{
				bool value = hexColorsEnabled.Value;
				Sprite val = (value ? hex.icon : hex.originalIcon);
				if (value)
				{
					Texture2D texture = hex.icon.texture;
					texture.SetPixels32(RecolorIcon(hex.originalIconPixels, hex.iconClasses, hex.stone.Value, ResolveRuneColor(hex) == RuneColor.White));
					texture.Apply();
				}
				hex.item.pickupIconSprite = val;
				hex.item.pickupIconSpriteReference = (value ? new AssetReferenceT<Sprite>("") : (hex.originalIconReference ?? new AssetReferenceT<Sprite>("")));
				PickupDef pickupDef = PickupCatalog.GetPickupDef(PickupCatalog.FindPickupIndex(hex.item.itemIndex));
				if (pickupDef != null)
				{
					pickupDef.iconSprite = val;
					pickupDef.iconTexture = (Texture)(object)val.texture;
					pickupDef.iconSpriteReference = hex.item.pickupIconSpriteReference;
				}
				if (Object.op_Implicit((Object)(object)ossificationBuff) && (Object)(object)hex.item == (Object)(object)Items.BarrierEnemiesOnKill)
				{
					ossificationBuff.iconSprite = val;
				}
			}
		}

		private static IconPixel[] ClassifyIcon(Color32[] source, int width, int height)
		{
			//IL_001f: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			IconPixel[] array = new IconPixel[source.Length];
			float num2 = default(float);
			float num3 = default(float);
			float num4 = default(float);
			for (int i = 0; i < height; i++)
			{
				for (int j = 0; j < width; j++)
				{
					int num = i * width + j;
					Color32 val = source[num];
					if (val.a == 0)
					{
						array[num] = IconPixel.Transparent;
						continue;
					}
					Color.RGBToHSV(Color32.op_Implicit(val), ref num2, ref num3, ref num4);
					if (!(num3 > 0.35f) || !(num2 > 0.12f) || !(num2 < 0.36f))
					{
						array[num] = IconPixel.Stone;
						continue;
					}
					bool flag = false;
					for (int k = -6; k <= 6; k++)
					{
						if (flag)
						{
							break;
						}
						for (int l = -6; l <= 6; l++)
						{
							int num5 = j + l;
							int num6 = i + k;
							if (num5 < 0 || num6 < 0 || num5 >= width || num6 >= height || source[num6 * width + num5].a < 40)
							{
								flag = true;
								break;
							}
						}
					}
					array[num] = (flag ? IconPixel.Outline : IconPixel.Rune);
				}
			}
			return array;
		}

		private static Color32[] RecolorIcon(Color32[] source, IconPixel[] classes, Color stone, bool whiteRunes)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_007e: 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)
			Color32[] array = (Color32[])(object)new Color32[source.Length];
			Color val = Color.Lerp(stone, Color.white, 0.35f);
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			for (int i = 0; i < source.Length; i++)
			{
				Color32 val2 = source[i];
				Color.RGBToHSV(Color32.op_Implicit(val2), ref num, ref num2, ref num3);
				Color val3;
				switch (classes[i])
				{
				case IconPixel.Transparent:
					array[i] = val2;
					continue;
				case IconPixel.Rune:
					val3 = (whiteRunes ? Color.Lerp(Color.white * 0.75f, Color.white, num3) : Color.Lerp(Color.black, Color.white * 0.12f, num3));
					break;
				case IconPixel.Outline:
					val3 = val * Mathf.Clamp01(0.4f + num3 * 0.8f);
					break;
				default:
					val3 = stone * Mathf.Clamp01(0.55f + num3 * 1.5f);
					break;
				}
				val3.a = (float)(int)val2.a / 255f;
				array[i] = Color32.op_Implicit(val3);
			}
			return array;
		}

		private RuneColor ResolveRuneColor(HexColor hex)
		{
			//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)
			RuneColor runeColor = hex.runeColor.Value;
			if (runeColor == RuneColor.Auto)
			{
				Color value = hex.stone.Value;
				runeColor = ((!(((Color)(ref value)).grayscale > 0.45f)) ? RuneColor.White : RuneColor.Black);
			}
			return runeColor;
		}

		private void Update()
		{
			if (configFileChanged)
			{
				configFileChanged = false;
				configReloadTime = Time.unscaledTime + 0.3f;
			}
			if (configReloadTime > 0f && Time.unscaledTime >= configReloadTime)
			{
				configReloadTime = 0f;
				try
				{
					((BaseUnityPlugin)this).Config.Reload();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Couldn't reload config: " + ex.Message));
				}
				ApplyAllHexColors();
			}
		}

		private void WatchConfigFile()
		{
			try
			{
				configWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath))
				{
					NotifyFilter = (NotifyFilters.Size | NotifyFilters.LastWrite)
				};
				configWatcher.Changed += delegate
				{
					configFileChanged = true;
				};
				configWatcher.Created += delegate
				{
					configFileChanged = true;
				};
				configWatcher.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Couldn't watch the config file; color changes need a restart: " + ex.Message));
			}
		}

		private void OnDestroy()
		{
			configWatcher?.Dispose();
		}

		private void LogHexMaterials(string hexName, List<Renderer> renderers)
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected I4, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine($"[Hex Colors] {hexName}: {renderers.Count} renderer(s)");
			foreach (Renderer renderer in renderers)
			{
				if (!Object.op_Implicit((Object)(object)renderer))
				{
					continue;
				}
				stringBuilder.AppendLine("  " + ((object)renderer).GetType().Name + " '" + ((Object)renderer).name + "' (root '" + ((Object)((Component)renderer).transform.root).name + "')");
				Material[] sharedMaterials = renderer.sharedMaterials;
				foreach (Material val in sharedMaterials)
				{
					if (!Object.op_Implicit((Object)(object)val))
					{
						continue;
					}
					Shader shader = val.shader;
					stringBuilder.AppendLine("    material '" + ((Object)val).name + "', shader '" + (Object.op_Implicit((Object)(object)shader) ? ((Object)shader).name : "none") + "'");
					if (!Object.op_Implicit((Object)(object)shader))
					{
						continue;
					}
					for (int j = 0; j < shader.GetPropertyCount(); j++)
					{
						string propertyName = shader.GetPropertyName(j);
						ShaderPropertyType propertyType = shader.GetPropertyType(j);
						string text;
						switch ((int)propertyType)
						{
						case 0:
							text = ((object)val.GetColor(propertyName)/*cast due to .constrained prefix*/).ToString();
							break;
						case 4:
						{
							Texture texture = val.GetTexture(propertyName);
							text = (Object.op_Implicit((Object)(object)texture) ? ((Object)texture).name : "none");
							break;
						}
						case 1:
							text = ((object)val.GetVector(propertyName)/*cast due to .constrained prefix*/).ToString();
							break;
						default:
							text = val.GetFloat(propertyName).ToString("0.###");
							break;
						}
						stringBuilder.AppendLine("      " + propertyName + " = " + text);
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)stringBuilder.ToString());
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void RegisterLookingGlassStats()
		{
			LookingGlassStats.Register(this);
		}
	}
}