Decompiled source of ElPopeAdventures v1.5.0

ElPopeAdventures.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ElPopeAdventures.Blades;
using ElPopeAdventures.Blades.Patches;
using ElPopeAdventures.Building;
using ElPopeAdventures.Building.Patches;
using ElPopeAdventures.Creatures;
using ElPopeAdventures.Creatures.Patches;
using ElPopeAdventures.InventoryQoL;
using ElPopeAdventures.InventoryQoL.Patches;
using ElPopeAdventures.Mage;
using ElPopeAdventures.Mage.Patches;
using ElPopeAdventures.Masterwork;
using ElPopeAdventures.Masterwork.Patches;
using ElPopeAdventures.Rogue;
using ElPopeAdventures.Rogue.Patches;
using GUIFramework;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ElPopeAdventures")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0")]
[assembly: AssemblyProduct("ElPopeAdventures")]
[assembly: AssemblyTitle("ElPopeAdventures")]
[assembly: AssemblyVersion("1.5.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 ElPopeAdventures
{
	internal sealed class FollowTransform : MonoBehaviour
	{
		internal Transform Target;

		internal void Snap()
		{
			//IL_001a: 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)
			if ((Object)(object)Target != (Object)null)
			{
				((Component)this).transform.SetPositionAndRotation(Target.position, Target.rotation);
			}
		}

		private void LateUpdate()
		{
			Snap();
		}
	}
	internal interface IModule
	{
		string Name { get; }

		string Description { get; }

		Type[] PatchClasses { get; }

		void Initialize();

		void Bind(ConfigFile config);

		void OnSettingChanged();

		void Update();
	}
	[BepInPlugin("ElPope.ElPopeAdventures", "ElPopeAdventures", "1.5.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "ElPope.ElPopeAdventures";

		public const string ModName = "ElPopeAdventures";

		public const string ModVersion = "1.5.0";

		internal static ManualLogSource Log;

		private readonly List<IModule> _active = new List<IModule>();

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("ElPope.ElPopeAdventures");
			IModule[] array = new IModule[7]
			{
				new MageModule(),
				new RogueModule(),
				new BladesModule(),
				new CreaturesModule(),
				new MasterworkModule(),
				new InventoryModule(),
				new BuildCameraModule()
			};
			foreach (IModule module in array)
			{
				if (!((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable" + module.Name, true, new ConfigDescription(module.Description + " Requires a game restart. In multiplayer, everyone should use the same setting.", (AcceptableValueBase)null, Array.Empty<object>())).Value)
				{
					Log.LogInfo((object)(module.Name + " module is switched off in the config."));
					continue;
				}
				try
				{
					module.Bind(((BaseUnityPlugin)this).Config);
					module.Initialize();
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"{module.Name} module could not start and stays off: {arg}");
					continue;
				}
				int num = 0;
				Type[] patchClasses = module.PatchClasses;
				foreach (Type type in patchClasses)
				{
					try
					{
						_harmony.CreateClassProcessor(type).Patch();
						num++;
					}
					catch (Exception ex)
					{
						Log.LogWarning((object)(module.Name + ": patch " + type.Name + " was not applied (" + ex.GetType().Name + ": " + ex.Message + "). The feature that needs it stays off; the rest of the game is unaffected."));
					}
				}
				_active.Add(module);
				Log.LogInfo((object)$"{module.Name} module loaded ({num}/{module.PatchClasses.Length} patches applied).");
			}
			((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
			Log.LogInfo((object)"ElPopeAdventures 1.5.0 loaded.");
		}

		private void Update()
		{
			foreach (IModule item in _active)
			{
				try
				{
					item.Update();
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"{item.Name}: {arg}");
				}
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs e)
		{
			foreach (IModule item in _active)
			{
				try
				{
					item.OnSettingChanged();
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)(item.Name + ": could not apply the changed settings: " + ex.Message));
				}
			}
		}
	}
	internal static class TextureTools
	{
		internal static Texture2D Recolor(Texture source, Rect region, Func<Color32, Color32> recolor, bool mipmaps)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int width;
			int height;
			Color32[] array = ReadPixels(source, region, out width, out height);
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = recolor(array[i]);
			}
			return FromPixels(array, width, height, mipmaps);
		}

		internal static Color32[] ReadPixels(Texture source, Rect region, out int width, out int height)
		{
			//IL_0089: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			width = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref region)).width));
			height = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref region)).height));
			RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			RenderTexture active = RenderTexture.active;
			Texture2D val = null;
			try
			{
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(((Rect)(ref region)).width / (float)source.width, ((Rect)(ref region)).height / (float)source.height);
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(((Rect)(ref region)).x / (float)source.width, ((Rect)(ref region)).y / (float)source.height);
				Graphics.Blit(source, temporary, val2, val3);
				RenderTexture.active = temporary;
				val = new Texture2D(width, height, (TextureFormat)4, false);
				val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
				return val.GetPixels32();
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		internal static Texture2D FromPixels(Color32[] pixels, int width, int height, bool mipmaps)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, mipmaps);
			val.SetPixels32(pixels);
			val.Apply(mipmaps, true);
			((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
			return val;
		}

		internal static float Step(float a, float b, float x)
		{
			return Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(a, b, x));
		}
	}
}
namespace ElPopeAdventures.Rogue
{
	internal static class RogueClass
	{
		private const string ClassKey = "ElPope.Rogue";

		private const string ClassValue = "Rogue";

		private static float s_nextRefusal;

		private static float s_nextEffectCheck;

		internal static bool IsRogue(Player player)
		{
			if ((Object)(object)player != (Object)null && player.m_customData != null && player.m_customData.TryGetValue("ElPope.Rogue", out var value))
			{
				return value == "Rogue";
			}
			return false;
		}

		internal static bool DaggersLocked(Player player)
		{
			if (Settings.DaggersRequireRogue && (Object)(object)player != (Object)null)
			{
				return !IsRogue(player);
			}
			return false;
		}

		internal static bool RefuseDagger(Player player)
		{
			if ((Object)(object)player != (Object)(object)Player.m_localPlayer || !DaggersLocked(player) || !RogueItems.IsDagger(((Humanoid)player).GetCurrentWeapon()))
			{
				return false;
			}
			Refuse(player, "Only a Rogue can fight with these. Use a Rogue's Shadowstone first.");
			return true;
		}

		internal static void Refuse(Player player, string message)
		{
			if (Time.time >= s_nextRefusal)
			{
				s_nextRefusal = Time.time + 2f;
				((Character)player).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
		}

		internal static bool RefuseTome(Player player, ItemData item)
		{
			if (!RogueItems.IsTome(item) || !IsRogue(player))
			{
				return false;
			}
			((Character)player).Message((MessageType)2, "You are already a Rogue.", 0, (Sprite)null, false);
			return true;
		}

		internal static void OnConsumed(Player player, ItemData item)
		{
			if (RogueItems.IsTome(item) && !IsRogue(player))
			{
				player.m_customData["ElPope.Rogue"] = "Rogue";
				KeepEffect(player, force: true);
				((Character)player).Message((MessageType)2, "You have become a Rogue!", 0, (Sprite)null, false);
				RogueModule.Log.LogInfo((object)(player.GetPlayerName() + " became a Rogue."));
			}
		}

		internal static void KeepEffect(Player player, bool force = false)
		{
			if (!force && Time.time < s_nextEffectCheck)
			{
				return;
			}
			s_nextEffectCheck = Time.time + 1f;
			SE_Stats rogueEffect = RogueItems.RogueEffect;
			if (!((Object)(object)player == (Object)null) && !((Object)(object)rogueEffect == (Object)null) && !((Character)player).IsDead() && IsRogue(player))
			{
				SEMan sEMan = ((Character)player).GetSEMan();
				if (sEMan != null && !sEMan.HaveStatusEffect(((StatusEffect)rogueEffect).NameHash()))
				{
					sEMan.AddStatusEffect((StatusEffect)(object)rogueEffect, false, 0, 0f, (short)(-1));
				}
			}
		}
	}
	internal sealed class DaggerDef
	{
		internal string Id;

		internal string Name;

		internal string Description;

		internal int Tier;

		internal string Station;

		internal int StationLevel = 1;

		internal string DefaultRecipe;

		internal float Damage;

		internal float Spirit;

		internal float Stamina;

		internal DaggerPalette Palette;

		internal string ConfigKey => Id.Substring("ElPopeRogue_".Length);
	}
	internal static class RogueContent
	{
		internal const string IdPrefix = "ElPopeRogue_";

		internal const string TomeId = "ElPopeRogue_Shadowstone";

		internal const string TomeName = "Rogue's Shadowstone";

		internal const string TomeDescription = "A stone that swallows the light around it. Hold it close to learn the ways of shadow and become a Rogue: you move quieter and harder to spot, sneaking tires you less, your daggers strike harder, and you can craft and wield dual daggers.";

		internal const string TomeRecipe = "LeatherScraps:4,Flint:6,Mushroom:3";

		internal static readonly string[] TomeSources = new string[2] { "Thunderstone", "Flint" };

		internal const string DaggerSource = "KnifeSkollAndHati";

		internal const float SourceDamage = 45f;

		internal const float SourceStamina = 42f;

		internal static readonly string[] Biomes = new string[5] { "Meadows", "Black Forest", "Swamp", "Mountain", "Plains" };

		private const string Workbench = "$piece_workbench";

		private const string Forge = "$piece_forge";

		internal static readonly DaggerDef[] Daggers = new DaggerDef[5]
		{
			new DaggerDef
			{
				Id = "ElPopeRogue_FlintFangs",
				Name = "Flint Fangs",
				Tier = 0,
				Station = "$piece_workbench",
				StationLevel = 2,
				DefaultRecipe = "Wood:4,Flint:10,LeatherScraps:4",
				Damage = 7f,
				Stamina = 12f,
				Description = "A pair of knapped flint blades bound in leather. Quick, quiet and cruel.",
				Palette = new DaggerPalette(28f, 0.55f, 1.6f, 30f, 0.08f, 0.7f)
			},
			new DaggerDef
			{
				Id = "ElPopeRogue_BronzeFangs",
				Name = "Bronze Fangs",
				Tier = 1,
				Station = "$piece_forge",
				StationLevel = 1,
				DefaultRecipe = "Wood:4,Bronze:8,DeerHide:4",
				Damage = 14f,
				Stamina = 18f,
				Description = "Twin bronze daggers, balanced for throwing your weight behind every cut.",
				Palette = new DaggerPalette(20f, 0.5f, 1.3f, 32f, 0.6f, 0.85f)
			},
			new DaggerDef
			{
				Id = "ElPopeRogue_IronFangs",
				Name = "Iron Fangs",
				Tier = 2,
				Station = "$piece_forge",
				StationLevel = 2,
				DefaultRecipe = "ElderBark:4,Iron:10,LeatherScraps:6",
				Damage = 20f,
				Stamina = 24f,
				Description = "Iron daggers wrapped in blood-dark leather. They find the gaps in any armour.",
				Palette = new DaggerPalette(355f, 0.55f, 1.4f, 210f, 0.08f, 0.75f)
			},
			new DaggerDef
			{
				Id = "ElPopeRogue_SilverFangs",
				Name = "Silver Fangs",
				Tier = 3,
				Station = "$piece_forge",
				StationLevel = 3,
				DefaultRecipe = "ElderBark:4,Silver:12,WolfPelt:2",
				Damage = 26f,
				Spirit = 10f,
				Stamina = 30f,
				Description = "Silver bites the undead. Wolf-pelt grips keep your hands warm on the mountain.",
				Palette = new DaggerPalette(205f, 0.35f, 2f, 200f, 0.06f, 1f)
			},
			new DaggerDef
			{
				Id = "ElPopeRogue_BlackmetalFangs",
				Name = "Blackmetal Fangs",
				Tier = 4,
				Station = "$piece_forge",
				StationLevel = 4,
				DefaultRecipe = "FineWood:4,BlackMetal:12,LinenThread:6",
				Damage = 34f,
				Stamina = 36f,
				Description = "Fuling black metal with gilded grips. The last word before Skoll and Hati.",
				Palette = new DaggerPalette(44f, 0.6f, 2.6f, 160f, 0.25f, 0.35f)
			}
		};
	}
	internal readonly struct DaggerPalette
	{
		private readonly float _handleHue;

		private readonly float _handleSaturation;

		private readonly float _handleValue;

		private readonly float _bladeHue;

		private readonly float _bladeSaturation;

		private readonly float _bladeValue;

		internal DaggerPalette(float handleHue, float handleSaturation, float handleValue, float bladeHue, float bladeSaturation, float bladeValue)
		{
			_handleHue = handleHue / 360f;
			_handleSaturation = handleSaturation;
			_handleValue = handleValue;
			_bladeHue = bladeHue / 360f;
			_bladeSaturation = bladeSaturation;
			_bladeValue = bladeValue;
		}

		internal Color32 Apply(Color32 pixel)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_00f5: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float x = default(float);
			float num2 = default(float);
			Color.RGBToHSV(Color32.op_Implicit(pixel), ref num, ref x, ref num2);
			float num3 = num * 360f;
			float num4 = (1f - TextureTools.Step(35f, 55f, Mathf.Abs(num3 - 128f))) * TextureTools.Step(0.1f, 0.2f, x);
			float num5 = (1f - TextureTools.Step(15f, 30f, Mathf.Abs(num3 - 25f))) * TextureTools.Step(0.25f, 0.4f, x);
			Color val;
			float num6;
			if (num4 > 0f)
			{
				val = Color.HSVToRGB(_handleHue, _handleSaturation, Mathf.Clamp01(num2 * _handleValue));
				num6 = num4;
			}
			else
			{
				if (!(num5 > 0f))
				{
					return pixel;
				}
				val = Color.HSVToRGB(_bladeHue, _bladeSaturation, Mathf.Clamp01(num2 * _bladeValue));
				num6 = num5;
			}
			Color32 result = Color32.op_Implicit(Color.Lerp(Color32.op_Implicit(pixel), val, num6));
			result.a = pixel.a;
			return result;
		}
	}
	internal static class RogueItems
	{
		private const string RecipePrefix = "Recipe_ElPopeRogue_";

		private static readonly MethodInfo s_updateRegisters = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null);

		private static readonly FieldInfo s_namedPrefabs = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs");

		private static readonly HashSet<string> s_warned = new HashSet<string>();

		private static readonly Dictionary<string, ItemDrop> s_items = new Dictionary<string, ItemDrop>();

		private static readonly Dictionary<string, DaggerDef> s_daggerDefs = RogueContent.Daggers.ToDictionary((DaggerDef d) => d.Id);

		private static readonly Dictionary<(int, int), Material> s_materials = new Dictionary<(int, int), Material>();

		private static readonly Dictionary<(int, int), Sprite> s_icons = new Dictionary<(int, int), Sprite>();

		private static GameObject s_container;

		internal static SE_Stats RogueEffect { get; private set; }

		internal static bool IsTome(ItemData item)
		{
			return Is(item, "ElPopeRogue_Shadowstone");
		}

		internal static DaggerDef DaggerDef(ItemData item)
		{
			if (item == null)
			{
				return null;
			}
			DaggerDef[] daggers = RogueContent.Daggers;
			foreach (DaggerDef daggerDef in daggers)
			{
				if (Is(item, daggerDef.Id))
				{
					return daggerDef;
				}
			}
			return null;
		}

		internal static bool IsDagger(ItemData item)
		{
			return DaggerDef(item) != null;
		}

		private static bool Is(ItemData item, string id)
		{
			if (item != null && s_items.TryGetValue(id, out var value) && (Object)(object)value != (Object)null)
			{
				if (item.m_shared != value.m_itemData.m_shared)
				{
					if ((Object)(object)item.m_dropPrefab != (Object)null)
					{
						return ((Object)item.m_dropPrefab).name == id;
					}
					return false;
				}
				return true;
			}
			return false;
		}

		internal static bool IsRogueOnlyRecipe(Recipe recipe)
		{
			if ((Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null)
			{
				return s_daggerDefs.ContainsKey(((Object)recipe.m_item).name ?? "");
			}
			return false;
		}

		internal static void RegisterInObjectDB(ObjectDB db)
		{
			if ((Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0)
			{
				return;
			}
			EnsureBuilt((Func<string, GameObject>)db.GetItemPrefab);
			bool flag = false;
			foreach (ItemDrop item in s_items.Values.Where((ItemDrop i) => (Object)(object)i != (Object)null))
			{
				if (!db.m_items.Contains(((Component)item).gameObject))
				{
					db.m_items.Add(((Component)item).gameObject);
					flag = true;
				}
			}
			if ((Object)(object)RogueEffect != (Object)null && !db.m_StatusEffects.Contains((StatusEffect)(object)RogueEffect))
			{
				db.m_StatusEffects.Add((StatusEffect)(object)RogueEffect);
			}
			if (flag)
			{
				s_updateRegisters.Invoke(db, null);
			}
			ApplySettings();
			RebuildRecipes(db);
		}

		internal static void RegisterInScene(ZNetScene scene)
		{
			EnsureBuilt((Func<string, GameObject>)scene.GetPrefab);
			if (!(s_namedPrefabs?.GetValue(scene) is Dictionary<int, GameObject> dictionary))
			{
				Warn("scene", "Could not add the rogue items to the game's network prefab list; they cannot be dropped on the ground.");
				return;
			}
			foreach (ItemDrop item in s_items.Values.Where((ItemDrop i) => (Object)(object)i != (Object)null))
			{
				if (!scene.m_prefabs.Contains(((Component)item).gameObject))
				{
					scene.m_prefabs.Add(((Component)item).gameObject);
				}
				dictionary[StringExtensionMethods.GetStableHashCode(((Object)item).name)] = ((Component)item).gameObject;
			}
		}

		private static void EnsureBuilt(Func<string, GameObject> find)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)s_container == (Object)null)
			{
				s_container = new GameObject("ElPopeRogue_Prefabs");
				s_container.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)s_container);
			}
			if ((Object)(object)RogueEffect == (Object)null)
			{
				RogueEffect = CreateRogueEffect();
			}
			if (!s_items.ContainsKey("ElPopeRogue_Shadowstone"))
			{
				ItemDrop val = BuildTome(find);
				if ((Object)(object)val != (Object)null)
				{
					s_items["ElPopeRogue_Shadowstone"] = val;
				}
			}
			DaggerDef[] daggers = RogueContent.Daggers;
			foreach (DaggerDef daggerDef in daggers)
			{
				if (!s_items.ContainsKey(daggerDef.Id))
				{
					ItemDrop val2 = BuildDagger(daggerDef, find);
					if ((Object)(object)val2 != (Object)null)
					{
						s_items[daggerDef.Id] = val2;
					}
				}
			}
		}

		private static SE_Stats CreateRogueEffect()
		{
			//IL_0012: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			SE_Stats obj = ScriptableObject.CreateInstance<SE_Stats>();
			((Object)obj).name = "ElPopeRogue_Class";
			((Object)obj).hideFlags = (HideFlags)(((Object)obj).hideFlags | 0x20);
			((StatusEffect)obj).m_name = "Rogue";
			obj.m_modifyAttackSkill = (SkillType)2;
			return obj;
		}

		private static ItemDrop BuildTome(Func<string, GameObject> find)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			ItemDrop val = CloneItem(find, RogueContent.TomeSources, "ElPopeRogue_Shadowstone", "Rogue's Shadowstone", "A stone that swallows the light around it. Hold it close to learn the ways of shadow and become a Rogue: you move quieter and harder to spot, sneaking tires you less, your daggers strike harder, and you can craft and wield dual daggers.");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			SharedData shared = val.m_itemData.m_shared;
			shared.m_itemType = (ItemType)2;
			shared.m_food = 0f;
			shared.m_foodStamina = 0f;
			shared.m_foodEitr = 0f;
			shared.m_consumeStatusEffect = null;
			shared.m_questItem = false;
			shared.m_teleportable = true;
			shared.m_maxStackSize = 1;
			shared.m_maxQuality = 1;
			if ((Object)(object)RogueEffect != (Object)null && shared.m_icons != null && shared.m_icons.Length != 0)
			{
				((StatusEffect)RogueEffect).m_icon = shared.m_icons[0];
			}
			return val;
		}

		private static ItemDrop BuildDagger(DaggerDef def, Func<string, GameObject> find)
		{
			ItemDrop val = CloneItem(find, new string[1] { "KnifeSkollAndHati" }, def.Id, def.Name, def.Description);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			SharedData shared = val.m_itemData.m_shared;
			float num = def.Damage / 45f;
			((DamageTypes)(ref shared.m_damages)).Modify(num);
			shared.m_damages.m_spirit += def.Spirit;
			((DamageTypes)(ref shared.m_damagesPerLevel)).Modify(num);
			float num2 = def.Stamina / 42f;
			if (shared.m_attack != null)
			{
				Attack attack = shared.m_attack;
				attack.m_attackStamina *= num2;
			}
			if (!Shadowstep.MakeSecondary(shared, def.Stamina))
			{
				Warn(def.Id + " special", def.Name + " keeps the vanilla Skoll and Hati secondary attack.");
			}
			shared.m_description += "\n\nSecondary attack: Shadowstep. Vanish, reappear behind the enemy you are facing and strike it from behind.";
			try
			{
				Recolor(val, def);
			}
			catch (Exception ex)
			{
				Warn(def.Id + " look", "Could not recolour " + def.Name + ", so it looks like Skoll and Hati (" + ex.Message + ").");
			}
			return val;
		}

		private static void Recolor(ItemDrop item, DaggerDef def)
		{
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is ParticleSystemRenderer))
				{
					Material[] sharedMaterials = val.sharedMaterials;
					for (int j = 0; j < sharedMaterials.Length; j++)
					{
						sharedMaterials[j] = Recolored(sharedMaterials[j], def);
					}
					val.sharedMaterials = sharedMaterials;
				}
			}
			SharedData shared = item.m_itemData.m_shared;
			if (shared.m_icons != null && shared.m_icons.Length != 0)
			{
				shared.m_icons = shared.m_icons.Select((Sprite icon) => RecoloredIcon(icon, def)).ToArray();
			}
		}

		private static Material Recolored(Material source, DaggerDef def)
		{
			//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_007c: Expected O, but got Unknown
			//IL_007e: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)source == (Object)null) && source.HasProperty("_MainTex"))
			{
				Texture texture = source.GetTexture("_MainTex");
				Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null);
				if (val != null)
				{
					(int, int) key = (((Object)source).GetInstanceID(), def.Tier);
					if (s_materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
					{
						return value;
					}
					Material val2 = new Material(source)
					{
						name = ((Object)source).name + "_" + def.ConfigKey
					};
					((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20);
					Texture2D val3 = TextureTools.Recolor((Texture)(object)val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), def.Palette.Apply, ((Texture)val).mipmapCount > 1);
					((Object)val3).name = ((Object)val).name + "_" + def.ConfigKey;
					((Texture)val3).wrapMode = ((Texture)val).wrapMode;
					((Texture)val3).filterMode = ((Texture)val).filterMode;
					val2.SetTexture("_MainTex", (Texture)(object)val3);
					s_materials[key] = val2;
					return val2;
				}
			}
			return source;
		}

		private static Sprite RecoloredIcon(Sprite source, DaggerDef def)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_00b3: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)source == (Object)null)
			{
				return null;
			}
			(int, int) key = (((Object)source).GetInstanceID(), def.Tier);
			if (s_icons.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Rect textureRect;
			try
			{
				textureRect = source.textureRect;
			}
			catch (Exception)
			{
				return source;
			}
			Texture2D val = TextureTools.Recolor((Texture)(object)source.texture, textureRect, def.Palette.Apply, mipmaps: false);
			((Object)val).name = ((Object)source).name + "_" + def.ConfigKey;
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), source.pixelsPerUnit);
			((Object)val2).name = ((Object)val).name;
			((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20);
			s_icons[key] = val2;
			return val2;
		}

		private static ItemDrop CloneItem(Func<string, GameObject> find, string[] sources, string id, string name, string description)
		{
			foreach (string text in sources)
			{
				GameObject val = find(text);
				ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
				if (val2?.m_itemData?.m_shared != null)
				{
					GameObject val3 = Object.Instantiate<GameObject>(val, s_container.transform, false);
					((Object)val3).name = id;
					ItemDrop component = val3.GetComponent<ItemDrop>();
					SharedData shared = component.m_itemData.m_shared;
					SharedData shared2 = val2.m_itemData.m_shared;
					if (shared == shared2 || (shared.m_attack != null && shared.m_attack == shared2.m_attack) || (shared.m_secondaryAttack != null && shared.m_secondaryAttack == shared2.m_secondaryAttack))
					{
						Object.DestroyImmediate((Object)(object)val3);
						Warn(id, "Could not make an independent copy of '" + text + "', so " + name + " is unavailable.");
						return null;
					}
					component.m_itemData.m_dropPrefab = val3;
					shared.m_name = name;
					shared.m_description = description;
					return component;
				}
			}
			Warn(id, "None of the vanilla items " + string.Join(", ", sources) + " exist in this game version, so " + name + " is unavailable.");
			return null;
		}

		internal static void ApplySettings()
		{
			//IL_00d7: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)RogueEffect != (Object)null)
			{
				RogueEffect.m_damageModifier = 1f + Settings.DaggerDamageBonus;
				RogueEffect.m_sneakStaminaUseModifier = 0f - Settings.SneakStaminaReduction;
				RogueEffect.m_noiseModifier = 0f - Settings.StealthBonus;
				RogueEffect.m_stealthModifier = 0f - Settings.StealthBonus;
				((StatusEffect)RogueEffect).m_tooltip = $"Knives and daggers: +{Settings.DaggerDamageBonus * 100f:0}% damage, " + $"+{Settings.SneakAttackBonus * 100f:0}% sneak attack damage";
			}
			DaggerDef[] daggers = RogueContent.Daggers;
			foreach (DaggerDef daggerDef in daggers)
			{
				if (s_items.TryGetValue(daggerDef.Id, out var value) && (Object)(object)value != (Object)null)
				{
					DamageTypes damages = value.m_itemData.m_shared.m_damages;
					RogueModule.Log.LogInfo((object)($"{daggerDef.Name} ({RogueContent.Biomes[daggerDef.Tier]}): {damages.m_slash:0.#} slash + {damages.m_pierce:0.#} pierce" + ((damages.m_spirit > 0f) ? $" + {damages.m_spirit:0.#} spirit" : "") + $". Shadowstep: {Settings.ShadowstepDamage:0.#}x damage, {Shadowstep.StaminaOf(value.m_itemData):0} stamina, " + $"{Settings.ShadowstepRange:0} m."));
				}
			}
		}

		private static void RebuildRecipes(ObjectDB db)
		{
			Recipe[] array = db.m_recipes.Where((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name.StartsWith("Recipe_ElPopeRogue_")).ToArray();
			foreach (Recipe val in array)
			{
				db.m_recipes.Remove(val);
				Object.Destroy((Object)(object)val);
			}
			Dictionary<string, CraftingStation> dictionary = new Dictionary<string, CraftingStation>();
			foreach (Recipe recipe in db.m_recipes)
			{
				CraftingStation val2 = (((Object)(object)recipe != (Object)null) ? recipe.m_craftingStation : null);
				if ((Object)(object)val2 != (Object)null && !dictionary.ContainsKey(val2.m_name))
				{
					dictionary[val2.m_name] = val2;
				}
			}
			if (s_items.TryGetValue("ElPopeRogue_Shadowstone", out var value) && (Object)(object)value != (Object)null)
			{
				AddRecipe(db, dictionary, value, "Rogue's Shadowstone", "$piece_workbench", 1, RecipeSpec("Shadowstone", "LeatherScraps:4,Flint:6,Mushroom:3"), -1);
			}
			DaggerDef[] daggers = RogueContent.Daggers;
			foreach (DaggerDef daggerDef in daggers)
			{
				if (s_items.TryGetValue(daggerDef.Id, out var value2) && (Object)(object)value2 != (Object)null)
				{
					AddRecipe(db, dictionary, value2, daggerDef.Name, daggerDef.Station, daggerDef.StationLevel, RecipeSpec(daggerDef.ConfigKey, daggerDef.DefaultRecipe), daggerDef.Tier);
				}
			}
		}

		private static string RecipeSpec(string key, string fallback)
		{
			if (!Settings.Recipes.TryGetValue(key, out var value))
			{
				return fallback;
			}
			return value;
		}

		private static void AddRecipe(ObjectDB db, Dictionary<string, CraftingStation> stations, ItemDrop item, string name, string station, int stationLevel, string spec, int upgradeTier)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0091: 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_00a4: Expected O, but got Unknown
			List<Requirement> list = new List<Requirement>(ParseRequirements(db, spec, name));
			if (list.Count == 0)
			{
				Warn("recipe " + ((Object)item).name, "The recipe for " + name + " has no valid ingredients, so it cannot be crafted.");
				return;
			}
			if (upgradeTier >= 0)
			{
				GameObject itemPrefab = db.GetItemPrefab($"Upgrader{upgradeTier}Weapon");
				if ((Object)(object)itemPrefab != (Object)null && (Object)(object)itemPrefab.GetComponent<ItemDrop>() != (Object)null)
				{
					list.Add(new Requirement
					{
						m_resItem = itemPrefab.GetComponent<ItemDrop>(),
						m_amount = 1,
						m_amountPerLevel = 0,
						m_upgraderResource = true,
						m_recover = false
					});
				}
			}
			stations.TryGetValue(station ?? "", out var value);
			if ((Object)(object)value == (Object)null && !string.IsNullOrEmpty(station))
			{
				Warn("station " + station, "Crafting station " + station + " was not found; items that need it can be crafted without one.");
			}
			Recipe val = ScriptableObject.CreateInstance<Recipe>();
			((Object)val).name = "Recipe_" + ((Object)item).name;
			val.m_item = item;
			val.m_amount = 1;
			val.m_enabled = true;
			val.m_craftingStation = value;
			val.m_minStationLevel = stationLevel;
			val.m_resources = list.ToArray();
			db.m_recipes.Add(val);
		}

		private static IEnumerable<Requirement> ParseRequirements(ObjectDB db, string spec, string forItem)
		{
			string[] array = (spec ?? "").Split(new char[1] { ',' });
			foreach (string text in array)
			{
				string[] array2 = text.Split(new char[1] { ':' });
				string text2 = array2[0].Trim();
				if (text2.Length == 0)
				{
					continue;
				}
				int result = 1;
				int result2 = -1;
				if ((array2.Length > 1 && (!int.TryParse(array2[1].Trim(), out result) || result < 1)) || (array2.Length > 2 && (!int.TryParse(array2[2].Trim(), out result2) || result2 < 0)))
				{
					Warn(forItem + text, "Ingredient '" + text.Trim() + "' for " + forItem + " has an invalid amount; it is ignored.");
					continue;
				}
				GameObject itemPrefab = db.GetItemPrefab(text2);
				ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Warn(forItem + text2, "Ingredient '" + text2 + "' for " + forItem + " is not an item this game knows; it is ignored.");
					continue;
				}
				if (result2 < 0)
				{
					result2 = ((!text2.StartsWith("Trophy")) ? Mathf.Max(1, (result + 1) / 2) : 0);
				}
				yield return new Requirement
				{
					m_resItem = val,
					m_amount = result,
					m_amountPerLevel = result2,
					m_recover = true
				};
			}
		}

		internal static void Warn(string key, string message)
		{
			if (s_warned.Add(key))
			{
				RogueModule.Log.LogWarning((object)message);
			}
		}
	}
	internal sealed class RogueModule : IModule
	{
		internal static readonly ManualLogSource Log = Logger.CreateLogSource("ElPopeAdventures.Rogue");

		private ConfigEntry<bool> _daggersRequireRogue;

		private ConfigEntry<float> _daggerDamage;

		private ConfigEntry<float> _sneakAttack;

		private ConfigEntry<float> _sneakStamina;

		private ConfigEntry<float> _stealth;

		private ConfigEntry<float> _stepRange;

		private ConfigEntry<float> _stepDamage;

		private readonly Dictionary<string, ConfigEntry<string>> _recipes = new Dictionary<string, ConfigEntry<string>>();

		public string Name => "Rogue";

		public string Description => "The Rogue class: stealth and dagger bonuses, and dual daggers with Shadowstep for every biome up to the Plains.";

		public Type[] PatchClasses { get; } = new Type[9]
		{
			typeof(ElPopeAdventures.Rogue.Patches.ObjectDBAwake),
			typeof(ElPopeAdventures.Rogue.Patches.ObjectDBCopyOtherDB),
			typeof(ElPopeAdventures.Rogue.Patches.ZNetSceneAwake),
			typeof(ElPopeAdventures.Rogue.Patches.PlayerConsumeItem),
			typeof(ElPopeAdventures.Rogue.Patches.PlayerHaveRequirementsRecipe),
			typeof(ElPopeAdventures.Rogue.Patches.PlayerGetAvailableRecipes),
			typeof(ElPopeAdventures.Rogue.Patches.HumanoidStartAttack),
			typeof(ElPopeAdventures.Rogue.Patches.AttackOnAttackTrigger),
			typeof(ElPopeAdventures.Rogue.Patches.CharacterDamage)
		};

		public void Initialize()
		{
		}

		public void Bind(ConfigFile config)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			_daggersRequireRogue = config.Bind<bool>("Rogue - Class", "DaggersRequireRogue", true, "If true, dual dagger recipes only appear after the character uses a Rogue's Shadowstone, and only a Rogue can fight with them. Vanilla knives are never affected.");
			_daggerDamage = config.Bind<float>("Rogue - Class", "KnifeDamageBonus", 0.1f, new ConfigDescription("Extra damage a Rogue deals with every knife and dagger (0.1 = +10%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_sneakAttack = config.Bind<float>("Rogue - Class", "SneakAttackBonus", 0.5f, new ConfigDescription("Extra damage on a Rogue's sneak attacks with knives, on top of the knife's own sneak attack bonus (0.5 = +50%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			_sneakStamina = config.Bind<float>("Rogue - Class", "SneakStaminaReduction", 0.5f, new ConfigDescription("How much less stamina sneaking costs a Rogue (0.5 = half).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.9f), Array.Empty<object>()));
			_stealth = config.Bind<float>("Rogue - Class", "StealthBonus", 0.25f, new ConfigDescription("How much quieter and harder to spot a Rogue is (0.25 = 25%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.9f), Array.Empty<object>()));
			_stepRange = config.Bind<float>("Rogue - Shadowstep", "Range", 10f, new ConfigDescription("How far (in metres) Shadowstep reaches. It picks the enemy closest to where you are looking.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 25f), Array.Empty<object>()));
			_stepDamage = config.Bind<float>("Rogue - Shadowstep", "DamageMultiplier", 2.5f, new ConfigDescription("Shadowstep's strike deals this many times the daggers' normal damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
			_recipes["Shadowstone"] = config.Bind<string>("Rogue - Recipes", "Shadowstone", "LeatherScraps:4,Flint:6,Mushroom:3", "Rogue's Shadowstone. Ingredients as ItemName:Amount pairs. Applies on the next world load.");
			DaggerDef[] daggers = RogueContent.Daggers;
			foreach (DaggerDef daggerDef in daggers)
			{
				_recipes[daggerDef.ConfigKey] = config.Bind<string>("Rogue - Recipes", daggerDef.ConfigKey, daggerDef.DefaultRecipe, daggerDef.Name + ", dual daggers, " + RogueContent.Biomes[daggerDef.Tier] + ". Ingredients as ItemName:Amount pairs (optionally ItemName:Amount:PerUpgradeLevel). Applies on the next world load.");
			}
			PullSettings();
		}

		public void OnSettingChanged()
		{
			PullSettings();
			RogueItems.ApplySettings();
		}

		public void Update()
		{
			RogueClass.KeepEffect(Player.m_localPlayer);
		}

		private void PullSettings()
		{
			Settings.DaggersRequireRogue = _daggersRequireRogue.Value;
			Settings.DaggerDamageBonus = _daggerDamage.Value;
			Settings.SneakAttackBonus = _sneakAttack.Value;
			Settings.SneakStaminaReduction = _sneakStamina.Value;
			Settings.StealthBonus = _stealth.Value;
			Settings.ShadowstepRange = _stepRange.Value;
			Settings.ShadowstepDamage = _stepDamage.Value;
			foreach (KeyValuePair<string, ConfigEntry<string>> recipe in _recipes)
			{
				Settings.Recipes[recipe.Key] = recipe.Value.Value ?? "";
			}
		}
	}
	internal static class Settings
	{
		internal static bool DaggersRequireRogue = true;

		internal static float DaggerDamageBonus = 0.1f;

		internal static float SneakAttackBonus = 0.5f;

		internal static float SneakStaminaReduction = 0.5f;

		internal static float StealthBonus = 0.25f;

		internal static float ShadowstepRange = 10f;

		internal static float ShadowstepDamage = 2.5f;

		internal static readonly Dictionary<string, string> Recipes = new Dictionary<string, string>();
	}
	internal static class Shadowstep
	{
		private const float AimAngle = 50f;

		private const float StrikeReach = 3f;

		private const float StrikeTimeout = 3f;

		private const float MaxHeightDifference = 2.5f;

		private const string SmokeEffect = "vfx_odin_despawn";

		private const string StrikeEffect = "fx_backstab";

		private static readonly FieldInfo s_attackCharacter = AccessTools.Field(typeof(Attack), "m_character");

		private static readonly FieldInfo s_attackWeapon = AccessTools.Field(typeof(Attack), "m_weapon");

		private static readonly List<Character> s_nearby = new List<Character>();

		private static readonly Dictionary<string, GameObject> s_effects = new Dictionary<string, GameObject>();

		private static int s_sightMask;

		private static int s_solidMask;

		private static int s_groundMask;

		private static Character s_pendingTarget;

		private static Vector3 s_pendingDestination;

		private static Character s_target;

		private static float s_targetUntil;

		internal static bool MakeSecondary(SharedData shared, float stamina)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Attack secondaryAttack = shared.m_secondaryAttack;
			if (secondaryAttack == null || string.IsNullOrEmpty(secondaryAttack.m_attackAnimation))
			{
				return false;
			}
			Attack val = secondaryAttack.Clone();
			val.m_attackType = (AttackType)3;
			val.m_attackStamina = stamina;
			val.m_attackProjectile = null;
			val.m_spawnOnTrigger = null;
			shared.m_secondaryAttack = val;
			return true;
		}

		internal static float StaminaOf(ItemData item)
		{
			return item.m_shared.m_secondaryAttack?.m_attackStamina ?? 0f;
		}

		private static bool IsShadowstep(Attack attack, ItemData weapon)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if (weapon != null && attack != null && (int)attack.m_attackType == 3 && RogueItems.IsDagger(weapon))
			{
				return attack.m_attackAnimation == weapon.m_shared.m_secondaryAttack?.m_attackAnimation;
			}
			return false;
		}

		internal static bool BeforeStartAttack(Humanoid humanoid, bool secondaryAttack)
		{
			//IL_0061: 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)
			s_pendingTarget = null;
			if (secondaryAttack)
			{
				Player val = (Player)(object)((humanoid is Player) ? humanoid : null);
				if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && RogueItems.IsDagger(((Humanoid)val).GetCurrentWeapon()) && !((Character)val).InAttack())
				{
					EnsureMasks();
					Vector3 destination;
					Character val2 = FindTarget(val, out destination);
					if ((Object)(object)val2 == (Object)null)
					{
						RogueClass.Refuse(val, "No enemy in reach to Shadowstep behind.");
						return true;
					}
					s_pendingTarget = val2;
					s_pendingDestination = destination;
					return false;
				}
			}
			return false;
		}

		internal static void AfterStartAttack(Humanoid humanoid, bool started)
		{
			//IL_003b: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0089: 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_0082: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			Character val = s_pendingTarget;
			s_pendingTarget = null;
			if (!started || (Object)(object)val == (Object)null)
			{
				return;
			}
			Player val2 = (Player)(object)((humanoid is Player) ? humanoid : null);
			if (val2 != null && !((Object)(object)val2 != (Object)(object)Player.m_localPlayer))
			{
				SpawnEffect("vfx_odin_despawn", ((Component)val2).transform.position, Quaternion.identity);
				Vector3 val3 = s_pendingDestination;
				Vector3 val4 = ((Component)val).transform.position - val3;
				val4.y = 0f;
				Quaternion val5 = ((((Vector3)(ref val4)).sqrMagnitude > 0.001f) ? Quaternion.LookRotation(val4) : ((Component)val2).transform.rotation);
				Rigidbody component = ((Component)val2).GetComponent<Rigidbody>();
				((Component)val2).transform.SetPositionAndRotation(val3, val5);
				if ((Object)(object)component != (Object)null)
				{
					component.position = val3;
					component.rotation = val5;
					component.linearVelocity = Vector3.zero;
				}
				((Character)val2).SetLookDir(val5 * Vector3.forward, 0f);
				val2.SetMouseLookForward(false);
				SpawnEffect("vfx_odin_despawn", val3, Quaternion.identity);
				s_target = val;
				s_targetUntil = Time.time + 3f;
			}
		}

		internal static void OnTrigger(Attack attack)
		{
			//IL_008d: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_target == (Object)null)
			{
				return;
			}
			object? obj = s_attackCharacter?.GetValue(attack);
			Character val = (Character)((obj is Character) ? obj : null);
			object? obj2 = s_attackWeapon?.GetValue(attack);
			ItemData val2 = (ItemData)((obj2 is ItemData) ? obj2 : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && IsShadowstep(attack, val2))
			{
				Character val3 = s_target;
				s_target = null;
				if (!((Object)(object)val3 == (Object)null) && !val3.IsDead() && !(Time.time > s_targetUntil) && !(Vector3.Distance(((Component)val).transform.position, ((Component)val3).transform.position) > val3.GetRadius() + 3f))
				{
					Vector3 val4 = ((Component)val3).transform.position - ((Component)val).transform.position;
					val4.y = 0f;
					HitData val5 = new HitData
					{
						m_damage = val2.GetDamage(),
						m_point = val3.GetCenterPoint(),
						m_dir = ((((Vector3)(ref val4)).sqrMagnitude > 0.001f) ? ((Vector3)(ref val4)).normalized : ((Component)val).transform.forward),
						m_pushForce = val2.m_shared.m_attackForce,
						m_backstabBonus = 1f,
						m_staggerMultiplier = 1f,
						m_dodgeable = true,
						m_blockable = false,
						m_skill = (SkillType)2,
						m_skillRaiseAmount = 1f,
						m_toolTier = (short)val2.m_shared.m_toolTier,
						m_hitType = (HitType)2
					};
					((DamageTypes)(ref val5.m_damage)).Modify(Settings.ShadowstepDamage * val.GetRandomSkillFactor((SkillType)2));
					val5.SetAttacker(val);
					val.GetSEMan().ModifyAttack((SkillType)2, ref val5);
					val3.Damage(val5);
					SpawnEffect("fx_backstab", val5.m_point, Quaternion.identity);
					val.RaiseSkill((SkillType)2, 1f);
				}
			}
		}

		private static Character FindTarget(Player player, out Vector3 destination)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0040: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			destination = Vector3.zero;
			Vector3 position = ((Character)player).m_eye.position;
			Vector3 val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : ((Component)player).transform.forward);
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
			{
				val = ((Component)player).transform.forward;
			}
			s_nearby.Clear();
			Character.GetCharactersInRange(((Component)player).transform.position, Settings.ShadowstepRange, s_nearby);
			Character result = null;
			float num = float.MaxValue;
			foreach (Character item in s_nearby)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)player || item.IsDead() || !BaseAI.IsEnemy((Character)(object)player, item))
				{
					continue;
				}
				Vector3 centerPoint = item.GetCenterPoint();
				Vector3 val2 = centerPoint - position;
				val2.y = 0f;
				float num2 = Vector3.Angle(val, val2);
				if (!(num2 > 50f) && !Physics.Linecast(position, centerPoint, s_sightMask))
				{
					float num3 = num2 + ((Vector3)(ref val2)).magnitude * 2f;
					if (num3 < num && TryFindSpotBehind(item, out var spot))
					{
						result = item;
						num = num3;
						destination = spot;
					}
				}
			}
			return result;
		}

		private static bool TryFindSpotBehind(Character target, out Vector3 spot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_001c: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_008f: 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_0096: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)target).transform.position;
			Vector3 val = -((Component)target).transform.forward;
			val.y = 0f;
			val = ((((Vector3)(ref val)).sqrMagnitude > 0.001f) ? ((Vector3)(ref val)).normalized : Vector3.back);
			float num = target.GetRadius() + 0.9f;
			Vector3 centerPoint = target.GetCenterPoint();
			float[] array = new float[5] { 0f, 40f, -40f, 80f, -80f };
			RaycastHit val2 = default(RaycastHit);
			foreach (float num2 in array)
			{
				spot = position + Quaternion.Euler(0f, num2, 0f) * val * num;
				if (Physics.Raycast(spot + Vector3.up * 3f, Vector3.down, ref val2, 6f, s_groundMask))
				{
					spot.y = ((RaycastHit)(ref val2)).point.y;
					if (!(Mathf.Abs(spot.y - position.y) > 2.5f) && !Physics.CheckCapsule(spot + Vector3.up * 0.6f, spot + Vector3.up * 1.5f, 0.4f, s_solidMask) && !Physics.Linecast(centerPoint, spot + Vector3.up * 1f, s_sightMask))
					{
						return true;
					}
				}
			}
			spot = Vector3.zero;
			return false;
		}

		private static void EnsureMasks()
		{
			if (s_solidMask == 0)
			{
				s_sightMask = LayerMask.GetMask(new string[4] { "Default", "static_solid", "terrain", "piece" });
				s_solidMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "vehicle" });
				s_groundMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "Default_small" });
			}
		}

		private static void SpawnEffect(string name, Vector3 position, Quaternion rotation)
		{
			//IL_006a: 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)
			if (!s_effects.TryGetValue(name, out var value))
			{
				value = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null);
				s_effects[name] = value;
				if ((Object)(object)value == (Object)null)
				{
					RogueItems.Warn("effect " + name, "Effect " + name + " is missing from this game version; Shadowstep plays without it.");
				}
			}
			if ((Object)(object)value != (Object)null)
			{
				Object.Instantiate<GameObject>(value, position, rotation);
			}
		}
	}
}
namespace ElPopeAdventures.Rogue.Patches
{
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class ObjectDBAwake
	{
		private static void Postfix(ObjectDB __instance)
		{
			try
			{
				RogueItems.RegisterInObjectDB(__instance);
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogError((object)("Adding the rogue items failed; they are unavailable this session. " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	internal static class ObjectDBCopyOtherDB
	{
		private static void Postfix(ObjectDB __instance)
		{
			try
			{
				RogueItems.RegisterInObjectDB(__instance);
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogError((object)("Adding the rogue items failed; they are unavailable this session. " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetSceneAwake
	{
		private static void Postfix(ZNetScene __instance)
		{
			try
			{
				RogueItems.RegisterInScene(__instance);
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogError((object)("Registering the rogue items with the world failed. " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(Player), "ConsumeItem")]
	internal static class PlayerConsumeItem
	{
		private static bool Prefix(Player __instance, ItemData item, ref bool __result)
		{
			try
			{
				if (RogueClass.RefuseTome(__instance, item))
				{
					__result = false;
					return false;
				}
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogWarning((object)("Shadowstone check failed: " + ex.Message));
			}
			return true;
		}

		private static void Postfix(Player __instance, ItemData item, bool __result)
		{
			if (!__result)
			{
				return;
			}
			try
			{
				RogueClass.OnConsumed(__instance, item);
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogError((object)("Becoming a Rogue failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Recipe),
		typeof(bool),
		typeof(int),
		typeof(int)
	})]
	internal static class PlayerHaveRequirementsRecipe
	{
		private static bool Prefix(Player __instance, Recipe recipe, ref bool __result)
		{
			try
			{
				if (RogueClass.DaggersLocked(__instance) && RogueItems.IsRogueOnlyRecipe(recipe))
				{
					__result = false;
					return false;
				}
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogWarning((object)("Dagger recipe check failed: " + ex.Message));
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "GetAvailableRecipes")]
	internal static class PlayerGetAvailableRecipes
	{
		private static void Postfix(Player __instance, ref List<Recipe> available)
		{
			try
			{
				if (available != null && RogueClass.DaggersLocked(__instance))
				{
					available.RemoveAll(RogueItems.IsRogueOnlyRecipe);
				}
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogWarning((object)("Dagger recipe list check failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	internal static class HumanoidStartAttack
	{
		private static bool Prefix(Humanoid __instance, bool secondaryAttack, ref bool __result)
		{
			try
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if ((val != null && RogueClass.RefuseDagger(val)) || Shadowstep.BeforeStartAttack(__instance, secondaryAttack))
				{
					__result = false;
					return false;
				}
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogWarning((object)("Dagger attack check failed: " + ex.Message));
			}
			return true;
		}

		private static void Postfix(Humanoid __instance, bool __result)
		{
			try
			{
				Shadowstep.AfterStartAttack(__instance, __result);
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogError((object)("Shadowstep failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(Attack), "OnAttackTrigger")]
	internal static class AttackOnAttackTrigger
	{
		private static void Postfix(Attack __instance)
		{
			try
			{
				Shadowstep.OnTrigger(__instance);
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogError((object)("Shadowstep strike failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class CharacterDamage
	{
		private static void Prefix(HitData hit)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			try
			{
				if (hit != null && (int)hit.m_skill == 2 && hit.m_backstabBonus > 1f)
				{
					Character attacker = hit.GetAttacker();
					Player val = (Player)(object)((attacker is Player) ? attacker : null);
					if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && RogueClass.IsRogue(val))
					{
						hit.m_backstabBonus *= 1f + Settings.SneakAttackBonus;
					}
				}
			}
			catch (Exception ex)
			{
				RogueModule.Log.LogWarning((object)("Sneak attack bonus failed: " + ex.Message));
			}
		}
	}
}
namespace ElPopeAdventures.Masterwork
{
	internal static class GlowFx
	{
		private const string TemplateItem = "SwordIron";

		private const string TemplateName = "UpgraderGlow";

		private const float HandGlowRadius = 0.25f;

		private static GameObject s_template;

		private static bool s_templateMissing;

		internal static void OnAttach(VisEquipment visuals, GameObject instance, int itemHash, int quality, bool backAttach)
		{
			if (!Settings.Enabled || !Settings.Glow || (Object)(object)instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemHash);
			ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			ItemData item = (((Object)(object)val != (Object)null) ? val.m_itemData : null);
			GearKind gearKind = Masterwork.KindOf(item);
			if ((gearKind != GearKind.Weapon && gearKind != GearKind.Shield) || !Masterwork.Is(item, quality) || (Object)(object)instance.GetComponentInChildren<ParticleIntensityScaler>(true) != (Object)null)
			{
				return;
			}
			GameObject val2 = Template();
			if (!((Object)(object)val2 == (Object)null))
			{
				if ((Object)(object)instance.GetComponentInChildren<SkinnedMeshRenderer>(true) != (Object)null && !backAttach)
				{
					AddHandGlow(instance, val2, visuals.m_rightHand, quality);
					AddHandGlow(instance, val2, visuals.m_leftHand, quality);
				}
				else
				{
					AddBoxGlow(instance, val2, quality);
				}
			}
		}

		private static void AddHandGlow(GameObject instance, GameObject template, Transform hand, int quality)
		{
			//IL_002a: 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_0049: 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)
			if (!((Object)(object)hand == (Object)null))
			{
				GameObject val = Spawn(instance.transform, template);
				val.AddComponent<FollowTransform>().Target = hand;
				val.transform.SetPositionAndRotation(hand.position, hand.rotation);
				ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					ShapeModule shape = componentsInChildren[i].shape;
					((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
					((ShapeModule)(ref shape)).radius = 0.25f;
				}
				Light(val, quality);
			}
		}

		private static void AddBoxGlow(GameObject instance, GameObject template, int quality)
		{
			//IL_0093: 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_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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			Bounds? val = null;
			Renderer[] componentsInChildren = instance.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (!(val2 is ParticleSystemRenderer))
				{
					if (val.HasValue)
					{
						Bounds value = val.Value;
						((Bounds)(ref value)).Encapsulate(val2.bounds);
						val = value;
					}
					else
					{
						val = val2.bounds;
					}
				}
			}
			if (val.HasValue)
			{
				GameObject val3 = Spawn(instance.transform, template);
				Transform transform = instance.transform;
				Transform transform2 = val3.transform;
				Bounds value2 = val.Value;
				transform2.position = ((Bounds)(ref value2)).center;
				Vector3 lossyScale = transform.lossyScale;
				value2 = val.Value;
				Vector3 size = ((Bounds)(ref value2)).size;
				Vector3 val4 = default(Vector3);
				((Vector3)(ref val4))..ctor(size.x / Mathf.Max(0.01f, lossyScale.x), size.y / Mathf.Max(0.01f, lossyScale.y), size.z / Mathf.Max(0.01f, lossyScale.z));
				ParticleSystem[] componentsInChildren2 = val3.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					ShapeModule shape = componentsInChildren2[i].shape;
					((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5;
					((ShapeModule)(ref shape)).position = Vector3.zero;
					((ShapeModule)(ref shape)).rotation = Vector3.zero;
					((ShapeModule)(ref shape)).scale = Vector3.Max(val4 * 0.8f, Vector3.one * 0.05f);
				}
				Light(val3, quality);
			}
		}

		private static GameObject Spawn(Transform parent, GameObject template)
		{
			//IL_0019: 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)
			GameObject obj = Object.Instantiate<GameObject>(template, parent, false);
			((Object)obj).name = "UpgraderGlow";
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localRotation = Quaternion.identity;
			obj.SetActive(true);
			return obj;
		}

		private static void Light(GameObject glow, int quality)
		{
			ParticleIntensityScaler[] componentsInChildren = glow.GetComponentsInChildren<ParticleIntensityScaler>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].SetQuality(quality);
			}
		}

		private static GameObject Template()
		{
			if ((Object)(object)s_template != (Object)null || s_templateMissing)
			{
				return s_template;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron");
			Transform val = (((Object)(object)itemPrefab != (Object)null) ? Find(itemPrefab.transform, "UpgraderGlow") : null);
			if ((Object)(object)val == (Object)null)
			{
				s_templateMissing = true;
				MasterworkModule.Log.LogWarning((object)"The game's upgrade glow was not found; shields and dual weapons won't glow.");
				return null;
			}
			s_template = ((Component)val).gameObject;
			return s_template;
		}

		private static Transform Find(Transform parent, string name)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (((Object)val).name == name)
				{
					return val;
				}
				Transform val2 = Find(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}
	}
	internal enum GearKind
	{
		None,
		Weapon,
		Shield,
		Armor
	}
	internal static class Masterwork
	{
		internal static GearKind KindOf(ItemData item)
		{
			//IL_0023: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected I4, but got Unknown
			switch (item?.m_shared?.m_itemType)
			{
			case (ItemType)0L:
			case (ItemType)1L:
			case (ItemType)11L:
			case (ItemType)12L:
			case (ItemType)16L:
			case (ItemType)19L:
				return GearKind.Weapon;
			case (ItemType)2L:
				return GearKind.Shield;
			case (ItemType)3L:
			case (ItemType)4L:
			case (ItemType)8L:
			case (ItemType)14L:
				return GearKind.Armor;
			default:
				return GearKind.None;
			}
		}

		internal static bool Is(ItemData item, int quality)
		{
			if (item?.m_shared != null && item.m_shared.m_maxQuality > 1 && quality >= item.m_shared.m_maxQuality)
			{
				return KindOf(item) != GearKind.None;
			}
			return false;
		}

		internal static bool Is(ItemData item, int quality, GearKind kind)
		{
			if (Settings.Enabled && Is(item, quality))
			{
				return KindOf(item) == kind;
			}
			return false;
		}

		internal static string Describe(ItemData item)
		{
			return KindOf(item) switch
			{
				GearKind.Weapon => $"+{Settings.DamageBonus * 100f:0}% damage, {Settings.CritChance * 100f:0}% chance of a critical hit " + $"(x{Settings.CritMultiplier:0.#} damage)", 
				GearKind.Shield => $"+{Settings.BlockBonus * 100f:0}% block power", 
				GearKind.Armor => $"+{Settings.ArmorBonus * 100f:0}% armour, +{Settings.RegenPerPiece * 100f:0}% health regeneration", 
				_ => "", 
			};
		}

		internal static float RegenMultiplier(Player player)
		{
			if (!Settings.Enabled || Settings.RegenPerPiece <= 0f || (Object)(object)player == (Object)null)
			{
				return 1f;
			}
			int num = 0;
			foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems())
			{
				if (Is(equippedItem, equippedItem.m_quality) && KindOf(equippedItem) == GearKind.Armor)
				{
					num++;
				}
			}
			return 1f + (float)num * Settings.RegenPerPiece;
		}
	}
	internal sealed class MasterworkModule : IModule
	{
		internal static readonly ManualLogSource Log = Logger.CreateLogSource("ElPopeAdventures.Masterwork");

		private ConfigEntry<bool> _glow;

		private ConfigEntry<float> _damage;

		private ConfigEntry<float> _critChance;

		private ConfigEntry<float> _critMultiplier;

		private ConfigEntry<float> _block;

		private ConfigEntry<float> _armor;

		private ConfigEntry<float> _regen;

		public string Name => "Masterwork";

		public string Description => "Gear upgraded to its maximum level glows and gets a bonus: damage and critical hits for weapons, block power for shields, armour and health regeneration for armour.";

		public Type[] PatchClasses { get; } = new Type[8]
		{
			typeof(ItemDataGetDamage),
			typeof(ItemDataGetArmor),
			typeof(ItemDataGetBaseBlockPower),
			typeof(ItemDataGetTooltip),
			typeof(SEManModifyHealthRegen),
			typeof(ElPopeAdventures.Masterwork.Patches.CharacterDamage),
			typeof(ParticleIntensityScalerSetQuality),
			typeof(ElPopeAdventures.Masterwork.Patches.VisEquipmentAttachItem)
		};

		public void Initialize()
		{
		}

		public void Bind(ConfigFile config)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			_glow = config.Bind<bool>("Masterwork", "Glow", true, "Masterwork weapons and shields glow (in your hands, on your back and on the ground).");
			_damage = config.Bind<float>("Masterwork", "WeaponDamageBonus", 0.1f, new ConfigDescription("Extra damage of masterwork weapons, bows, staffs and tools (0.1 = +10%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_critChance = config.Bind<float>("Masterwork", "CriticalHitChance", 0.1f, new ConfigDescription("Chance that a hit on a creature with a masterwork weapon is a critical hit (0.1 = 10%). 0 turns critical hits off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_critMultiplier = config.Bind<float>("Masterwork", "CriticalHitMultiplier", 2f, new ConfigDescription("Damage multiplier of a critical hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			_block = config.Bind<float>("Masterwork", "ShieldBlockBonus", 0.2f, new ConfigDescription("Extra block power of masterwork shields (0.2 = +20%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_armor = config.Bind<float>("Masterwork", "ArmorBonus", 0.1f, new ConfigDescription("Extra armour of masterwork armour pieces and capes (0.1 = +10%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_regen = config.Bind<float>("Masterwork", "HealthRegenPerArmorPiece", 0.05f, new ConfigDescription("Extra health regeneration for each masterwork armour piece or cape you wear (0.05 = +5% each).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			PullSettings();
		}

		public void OnSettingChanged()
		{
			PullSettings();
		}

		public void Update()
		{
		}

		private void PullSettings()
		{
			Settings.Glow = _glow.Value;
			Settings.DamageBonus = _damage.Value;
			Settings.CritChance = _critChance.Value;
			Settings.CritMultiplier = _critMultiplier.Value;
			Settings.BlockBonus = _block.Value;
			Settings.ArmorBonus = _armor.Value;
			Settings.RegenPerPiece = _regen.Value;
		}
	}
	internal static class Settings
	{
		internal static bool Enabled = true;

		internal static bool Glow = true;

		internal static float DamageBonus = 0.1f;

		internal static float CritChance = 0.1f;

		internal static float CritMultiplier = 2f;

		internal static float BlockBonus = 0.2f;

		internal static float ArmorBonus = 0.1f;

		internal static float RegenPerPiece = 0.05f;
	}
}
namespace ElPopeAdventures.Masterwork.Patches
{
	[HarmonyPatch(typeof(ItemData), "GetDamage", new Type[]
	{
		typeof(int),
		typeof(float)
	})]
	internal static class ItemDataGetDamage
	{
		private static void Postfix(ItemData __instance, int quality, ref DamageTypes __result)
		{
			if (Masterwork.Is(__instance, quality, GearKind.Weapon))
			{
				((DamageTypes)(ref __result)).Modify(1f + Settings.DamageBonus);
			}
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetArmor", new Type[]
	{
		typeof(int),
		typeof(float)
	})]
	internal static class ItemDataGetArmor
	{
		private static void Postfix(ItemData __instance, int quality, ref float __result)
		{
			if (Masterwork.Is(__instance, quality, GearKind.Armor))
			{
				__result *= 1f + Settings.ArmorBonus;
			}
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetBaseBlockPower", new Type[] { typeof(int) })]
	internal static class ItemDataGetBaseBlockPower
	{
		private static void Postfix(ItemData __instance, int quality, ref float __result)
		{
			if (Masterwork.Is(__instance, quality, GearKind.Shield))
			{
				__result *= 1f + Settings.BlockBonus;
			}
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int),
		typeof(bool)
	})]
	internal static class ItemDataGetTooltip
	{
		private static void Postfix(ItemData item, int qualityLevel, ref string __result)
		{
			try
			{
				if (Settings.Enabled && Masterwork.Is(item, qualityLevel))
				{
					__result = __result + "\n<color=#FFB84D>Masterwork</color>: " + Masterwork.Describe(item);
				}
			}
			catch (Exception ex)
			{
				MasterworkModule.Log.LogWarning((object)("Masterwork tooltip failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(SEMan), "ModifyHealthRegen")]
	internal static class SEManModifyHealthRegen
	{
		private static readonly FieldRef<SEMan, Character> s_character = AccessTools.FieldRefAccess<SEMan, Character>("m_character");

		private static void Postfix(SEMan __instance, ref float regenMultiplier)
		{
			try
			{
				Character obj = s_character.Invoke(__instance);
				Player val = (Player)(object)((obj is Player) ? obj : null);
				if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer)
				{
					regenMultiplier *= Masterwork.RegenMultiplier(val);
				}
			}
			catch (Exception ex)
			{
				MasterworkModule.Log.LogWarning((object)("Masterwork regeneration failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class CharacterDamage
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			//IL_0053: 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_0093: 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_00a6: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (hit == null || Settings.CritChance <= 0f)
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer || (Object)(object)__instance == (Object)(object)val)
				{
					return;
				}
				ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
				if (currentWeapon != null && Masterwork.Is(currentWeapon, currentWeapon.m_quality, GearKind.Weapon) && hit.m_skill == currentWeapon.m_shared.m_skillType && !(Random.value >= Settings.CritChance))
				{
					((DamageTypes)(ref hit.m_damage)).Modify(Settings.CritMultiplier);
					EffectList critHitEffects = __instance.m_critHitEffects;
					if (critHitEffects != null)
					{
						critHitEffects.Create(hit.m_point, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
					}
					DamageText instance = DamageText.instance;
					if (instance != null)
					{
						instance.ShowText((TextType)7, hit.m_point + Vector3.up * 0.6f, "Critical!", false);
					}
				}
			}
			catch (Exception ex)
			{
				MasterworkModule.Log.LogWarning((object)("Masterwork critical hit failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(ParticleIntensityScaler), "SetQuality")]
	internal static class ParticleIntensityScalerSetQuality
	{
		private static void Prefix(ParticleIntensityScaler __instance, ref int quality)
		{
			if (Settings.Enabled && Settings.Glow && quality > 1 && quality >= __instance.maxQuality)
			{
				quality++;
			}
		}
	}
	[HarmonyPatch(typeof(VisEquipment), "AttachItem")]
	internal static class VisEquipmentAttachItem
	{
		private static void Postfix(VisEquipment __instance, GameObject __result, int itemHash, bool backAttach, int quality)
		{
			try
			{
				GlowFx.OnAttach(__instance, __result, itemHash, quality, backAttach);
			}
			catch (Exception ex)
			{
				MasterworkModule.Log.LogWarning((object)("Masterwork glow failed: " + ex.Message));
			}
		}
	}
}
namespace ElPopeAdventures.Mage
{
	internal static class ArmorLooks
	{
		private static readonly string[] s_colorTextures = new string[3] { "_MainTex", "_ChestTex", "_LegsTex" };

		private static readonly Dictionary<(int, int), Material> s_materials = new Dictionary<(int, int), Material>();

		private static readonly Dictionary<(int, int), Texture2D> s_textures = new Dictionary<(int, int), Texture2D>();

		private static readonly Dictionary<(int, int), Sprite> s_icons = new Dictionary<(int, int), Sprite>();

		internal static void Apply(ItemDrop item, int tier)
		{
			ArmorPalette palette = MageContent.ArmorPalettes[tier];
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					sharedMaterials[j] = Recolored(sharedMaterials[j], tier, palette);
				}
				val.sharedMaterials = sharedMaterials;
			}
			SharedData shared = item.m_itemData.m_shared;
			shared.m_armorMaterial = Recolored(shared.m_armorMaterial, tier, palette);
			if (shared.m_icons != null && shared.m_icons.Length != 0)
			{
				Sprite[] array = (Sprite[])(object)new Sprite[shared.m_icons.Length];
				for (int k = 0; k < array.Length; k++)
				{
					array[k] = RecoloredIcon(shared.m_icons[k], tier, palette);
				}
				shared.m_icons = array;
			}
		}

		private static Material Recolored(Material source, int tier, ArmorPalette palette)
		{
			//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_0057: Expected O, but got Unknown
			//IL_0059: 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)
			if ((Object)(object)source == (Object)null)
			{
				return null;
			}
			(int, int) key = (((Object)source).GetInstanceID(), tier);
			if (s_materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Material val = new Material(source)
			{
				name = ((Object)source).name + "_" + MageContent.ArmorSetNames[tier]
			};
			((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
			string[] array = s_colorTextures;
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					Texture texture = val.GetTexture(text);
					Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null);
					if (val2 != null)
					{
						val.SetTexture(text, (Texture)(object)RecoloredTexture(val2, tier, palette));
					}
				}
			}
			s_materials[key] = val;
			return val;
		}

		private static Texture2D RecoloredTexture(Texture2D source, int tier, ArmorPalette palette)
		{
			//IL_003f: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			(int, int) key = (((Object)source).GetInstanceID(), tier);
			if (!s_textures.TryGetValue(key, out var value) || (Object)(object)value == (Object)null)
			{
				value = Recolor((Texture)(object)source, new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), palette, mipmaps: true);
				((Object)value).name = ((Object)source).name + "_" + MageContent.ArmorSetNames[tier];
				((Texture)value).wrapMode = ((Texture)source).wrapMode;
				((Texture)value).filterMode = ((Texture)source).filterMode;
				s_textures[key] = value;
			}
			return value;
		}

		private static Sprite RecoloredIcon(Sprite source, int tier, ArmorPalette palette)
		{
			//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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)source == (Object)null)
			{
				return null;
			}
			(int, int) key = (((Object)source).GetInstanceID(), tier);
			if (s_icons.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Rect textureRect;
			try
			{
				textureRect = source.textureRect;
			}
			catch (Exception)
			{
				return source;
			}
			Texture2D val = Recolor((Texture)(object)source.texture, textureRect, palette, mipmaps: false);
			((Object)val).name = ((Object)source).name + "_" + MageContent.ArmorSetNames[tier];
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), source.pixelsPerUnit);
			((Object)val2).name = ((Object)val).name;
			((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20);
			s_icons[key] = val2;
			return val2;
		}

		private static Texture2D Recolor(Texture source, Rect region, ArmorPalette palette, bool mipmaps)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return TextureTools.Recolor(source, region, ((ArmorPalette)palette).Apply, mipmaps);
		}
	}
	internal readonly struct ArmorPalette
	{
		private readonly float _hue;

		private readonly float _saturation;

		private readonly float _value;

		private readonly float _leather;

		internal ArmorPalette(float hueDegrees, float saturation, float value, float leather)
		{
			_hue = hueDegrees / 360f;
			_saturation = saturation;
			_value = value;
			_leather = leather;
		}

		internal Color32 Apply(Color32 pixel)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0136: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(Color32.op_Implicit(pixel), ref num, ref num2, ref num3);
			float num4 = num * 360f;
			float num5 = Mathf.Min(num4, 360f - num4);
			float num6 = (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(18f, 35f, num5))) * Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.25f, 0.45f, num2));
			float num7 = Mathf.Abs(num4 - 25f);
			float num8 = (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(15f, 30f, num7))) * Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.12f, 0.25f, num2)) * (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.55f, 0.7f, num2))) * _leather;
			float num9 = Mathf.Max(num6, num8);
			if (num9 <= 0f)
			{
				return pixel;
			}
			Color val = Color.HSVToRGB(_hue, Mathf.Clamp01(num2 * _saturation), Mathf.Clamp01(num3 * _value));
			Color32 result = Color32.op_Implicit(Color.Lerp(Color32.op_Implicit(pixel), val, num9));
			result.a = pixel.a;
			return result;
		}
	}
	internal static class MageClass
	{
		private const string ClassKey = "FrostMage.Class";

		private const string ClassValue = "Mage";

		private static readonly MethodInfo s_updateFood = AccessTools.Method(typeof(Player), "UpdateFood", new Type[2]
		{
			typeof(float),
			typeof(bool)
		}, (Type[])null);

		private static readonly List<string> s_bossKeys = new List<string>();

		private static float s_nextRefusal;

		internal static bool IsMage(Player player)
		{
			if ((Object)(object)player != (Object)null && player.m_customData != null && player.m_customData.TryGetValue("FrostMage.Class", out var value))
			{
				return value == "Mage";
			}
			return false;
		}

		internal static bool StaffsLocked(Player player)
		{
			if (Settings.StaffsRequireMage && (Object)(object)player != (Object)null)
			{
				return !IsMage(player);
			}
			return false;
		}

		internal static bool RefuseStaff(Player player)
		{
			if ((Object)(object)player != (Object)(object)Player.m_localPlayer || !StaffsLocked(player) || !MageItems.IsStaff(((Humanoid)player).GetCurrentWeapon()))
			{
				return false;
			}
			if (Time.time >= s_nextRefusal)
			{
				s_nextRefusal = Time.time + 2f;
				((Character)player).Message((MessageType)2, "Only a Mage can use this staff. Read a Mage Tome first.", 0, (Sprite)null, false);
			}
			return true;
		}

		internal static float BonusMana(Player player)
		{
			if (!IsMage(player))
			{
				return 0f;
			}
			return Settings.BaseMana + Settings.ManaPerBoss * (float)BossesDefeated(player);
		}

		internal static void FindBosses(ZNetScene scene)
		{
			s_bossKeys.Clear();
			foreach (GameObject prefab in scene.m_prefabs)
			{
				Character val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Character>() : null);
				if ((Object)(object)val != (Object)null && val.m_boss && !string.IsNullOrEmpty(val.m_defeatSetGlobalKey) && !s_bossKeys.Contains(val.m_defeatSetGlobalKey))
				{
					s_bossKeys.Add(val.m_defeatSetGlobalKey);
				}
			}
			MageModule.Log.LogInfo((object)string.Format("Mage mana grows with {0} bosses: {1}.", s_bossKeys.Count, string.Join(", ", s_bossKeys.ToArray())));
		}

		private static int BossesDefeated(Player player)
		{
			ZoneSystem instance = ZoneSystem.instance;
			int num = 0;
			foreach (string s_bossKey in s_bossKeys)
			{
				if (((Object)(object)instance != (Object)null && instance.GetGlobalKey(s_bossKey)) || ((Humanoid)player).HaveUniqueKey(s_bossKey))
				{
					num++;
				}
			}
			return num;
		}

		internal static bool RefuseTome(Player player, ItemData item)
		{
			if (!MageItems.IsTome(item) || !IsMage(player))
			{
				return false;
			}
			((Character)player).Message((MessageType)2, "You are already a Mage.", 0, (Sprite)null, false);
			return true;
		}

		internal static bool RefuseCocktail(Player player, ItemData item)
		{
			if (!MageItems.IsCocktail(item) || ((Character)player).GetMaxEitr() > 0f)
			{
				return false;
			}
			((Character)player).Message((MessageType)2, "You have no mana to restore. Read a Mage Tome first.", 0, (Sprite)null, false);
			return true;
		}

		internal static void OnConsumed(Player player, ItemData item)
		{
			if (MageItems.IsTome(item) && !IsMage(player))
			{
				player.m_customData["FrostMage.Class"] = "Mage";
				float num = BonusMana(player);
				try
				{
					s_updateFood?.Invoke(player, new object[2] { 0f, true });
					((Character)player).AddEitr(num);
				}
				catch (Exception ex)
				{
					MageModule.Log.LogWarning((object)("Mana pool will appear within a second (" + ex.Message + ")."));
				}
				((Character)player).Message((MessageType)2, $"You have awakened as a Mage! ({num:0} mana)", 0, (Sprite)null, false);
				MageModule.Log.LogInfo((object)(player.GetPlayerName() + " became a Mage."));
			}
		}
	}
	internal enum ItemKind
	{
		Tome,
		Staff,
		Cocktail,
		Armor
	}
	internal enum ArmorSlot
	{
		Hood,
		Robe,
		Trousers
	}
	internal sealed class School
	{
		internal readonly string Name;

		internal readonly (string Prefab, int NativeTier)[] Sources;

		internal readonly Func<DamageTypes, DamageTypes> Convert;

		internal School(string name, (string, int)[] sources, Func<DamageTypes, DamageTypes> convert = null)
		{
			Name = name;
			Sources = sources;
			Convert = convert;
		}
	}
	internal sealed class MageItemDef
	{
		internal string Id;

		internal string Name;

		internal string Description;

		internal ItemKind Kind;

		internal int Tier;

		internal School Schoo