Decompiled source of BowPlugin v1.7.5

BowPlugin.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BowPlugin.Functions;
using BowPlugin.Utils;
using HarmonyLib;
using ItemManager;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BowPlugin")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyFileVersion("1.7.5")]
[assembly: Guid("41D93860-4B27-485D-AE3B-D29CA9B28F03")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyProduct("BowPlugin")]
[assembly: AssemblyCompany("blacks7ar")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("https://valheim.thunderstore.io/package/blacks7ar/BowPlugin/")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.5.0")]
[module: UnverifiableCode]
[module: <94c1c1a2-f94c-4dc3-a0f8-42abd6c3d5e7>RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<36b9b213-46a8-4363-99ef-30b70e5863ca>Embedded]
	internal sealed class <36b9b213-46a8-4363-99ef-30b70e5863ca>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[<36b9b213-46a8-4363-99ef-30b70e5863ca>Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class <94c1c1a2-f94c-4dc3-a0f8-42abd6c3d5e7>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <94c1c1a2-f94c-4dc3-a0f8-42abd6c3d5e7>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BowPlugin
{
	[BepInPlugin("blacks7ar.BowPlugin", "BowPlugin", "1.7.5")]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "blacks7ar.BowPlugin";

		public const string modName = "BowPlugin";

		public const string modAuthor = "blacks7ar";

		public const string modVersion = "1.7.5";

		public const string tsLink = "https://valheim.thunderstore.io/package/blacks7ar/BowPlugin/";

		private static string configFileName = "blacks7ar.BowPlugin.cfg";

		private static string configFileFullPath;

		public static readonly ManualLogSource BPLogger;

		private static readonly Harmony _harmony;

		private static readonly ConfigSync _configSync;

		private static ConfigEntry<BowPlugin.Utils.Toggle> _serverConfigLocked;

		private static ConfigEntry<KeyCode> _nextArrowKey;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _autoEquipbow;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _arrowSelection;

		public static ConfigEntry<float> _accuracyMultiplier;

		public static ConfigEntry<float> _velocityMultiplier;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _enableExpMultiplier;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _scaleByBowLevel;

		public static ConfigEntry<float> _bowDrawSpeed;

		public static ConfigEntry<float> _bowDrawSpeedFactor;

		public static ConfigEntry<float> _bowZoomSpeedFactor;

		public static ConfigEntry<float> _bowExpMultiplier;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _scaleByXbowLevel;

		public static ConfigEntry<float> _xbowReloadSpeed;

		public static ConfigEntry<float> _xbowReloadSpeedFactor;

		public static ConfigEntry<float> _xbowRecoil;

		public static ConfigEntry<float> _xbowExpMultiplier;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _displayExpGained;

		public static ConfigEntry<float> _sneakAttackMultiplier;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _enableRotation;

		public static ConfigEntry<float> _critChance;

		public static ConfigEntry<float> _critBonus;

		public static ConfigEntry<CrosshairSelection> _crosshairSelection;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _enableBowZoom;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _enableAutoZoom;

		public static ConfigEntry<Color> _crosshairColor;

		public static ConfigEntry<KeyCode> _zoomKey;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _enableXbowZoom;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _enableXbowSpeedRdction;

		public static ConfigEntry<float> _bowLaunchAngle;

		public static ConfigEntry<float> _xbowLaunchAngle;

		public static ConfigEntry<float> _spawnChance;

		public static ConfigEntry<BowPlugin.Utils.Toggle> _bowSpeedReduction;

		public static float _zoomIntimer;

		public static float _zoomOutTimer;

		public static float _zoomOutDelayTimer;

		public static float _defaultZoom;

		public static float _previousZoom;

		public static float _currentZoom;

		public static float _bowZoomFactor;

		public static float _stayInZoomTime;

		public static float _spineTimer;

		public static Transform _spine;

		public static bool _onBowDrawing;

		public static ZoomLevel _zoomLevel;

		public static GameObject _PrefabContainer;

		public static Plugin _Instance;

		private const string GeneralSection = "2- General";

		private const string BowSection = "3- Bows";

		private const string CrossbowSection = "4- Crossbows";

		private const string SkillExpSection = "5- Skill Exp";

		private const string OtherFeatures = "6- Other Features";

		public static bool _IsBBHInstalled;

		public ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedConfig = true)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			ConfigDescription val = new ConfigDescription(description.Description + (synchronizedConfig ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags);
			ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val);
			_configSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedConfig;
			return val2;
		}

		private void ConfigWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, configFileName);
			fileSystemWatcher.Changed += OnConfigChanged;
			fileSystemWatcher.Created += OnConfigChanged;
			fileSystemWatcher.Renamed += OnConfigChanged;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void OnConfigChanged(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(configFileFullPath))
			{
				return;
			}
			try
			{
				Logging.LogDebug("OnConfigChanged called..");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				Logging.LogError("There was an issue loading your " + configFileName);
				Logging.LogError("Please check your config entries for spelling and format!");
			}
		}

		public void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Expected O, but got Unknown
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Expected O, but got Unknown
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Expected O, but got Unknown
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Expected O, but got Unknown
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Expected O, but got Unknown
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Expected O, but got Unknown
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Expected O, but got Unknown
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Expected O, but got Unknown
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Expected O, but got Unknown
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Expected O, but got Unknown
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Expected O, but got Unknown
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Expected O, but got Unknown
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0569: Expected O, but got Unknown
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Expected O, but got Unknown
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b7: Expected O, but got Unknown
			//IL_05d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Expected O, but got Unknown
			//IL_061f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0629: Expected O, but got Unknown
			//IL_0645: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Expected O, but got Unknown
			//IL_066c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Expected O, but got Unknown
			_Instance = this;
			Localizer.Load();
			_serverConfigLocked = config("1- ServerSync", "Lock Configuration", BowPlugin.Utils.Toggle.On, new ConfigDescription("If On, the configuration is locked and can be changed by server admins only.", (AcceptableValueBase)null, Array.Empty<object>()));
			_configSync.AddLockingConfigEntry<BowPlugin.Utils.Toggle>(_serverConfigLocked);
			_accuracyMultiplier = config("2- General", "Accuracy Multiplier", 0f, new ConfigDescription("Projectiles accuracy multiplier.\nRecommended: 0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1]
			{
				new BowPlugin.Utils.ConfigurationManagerAttributes
				{
					ShowRangeAsPercent = false
				}
			}));
			_velocityMultiplier = config("2- General", "Velocity Multiplier", 4f, new ConfigDescription("Projectiles velocity multiplier.\nRecommended: 3", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			_spawnChance = config("2- General", "Retrieve Chance", 0.25f, new ConfigDescription("Arrow and bolt retrieve chance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_bowLaunchAngle = config("3- Bows", "Launch Angle", -1f, new ConfigDescription("The vertical angle at which the projectile leaves the bow after being fired.\nVanilla: 0", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-5f, 0f), Array.Empty<object>()));
			_bowDrawSpeed = config("3- Bows", "Draw Speed", 1f, new ConfigDescription("Bows draw speed value if ScaleBySkillLevel is set to Off.\nVanilla: 2.5", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			_bowDrawSpeedFactor = config("3- Bows", "Bow Draw Speed Factor", 0.6f, new ConfigDescription("Bow draw speed factor at bow skill level 100\nIf Scale By Skill Level is On\nRecommended: 0.6", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_bowZoomSpeedFactor = config("3- Bows", "Bow Zoom Speed Factor", 1.4f, new ConfigDescription("Bow zoom speed factor at bow skill level 100.\nRecommended: 1.4", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.2f, 2f), Array.Empty<object>()));
			_scaleByBowLevel = config("3- Bows", "Scale By Skill Level", BowPlugin.Utils.Toggle.On, new ConfigDescription("If On, bow draw speed is scaled by bows skill level.", (AcceptableValueBase)null, Array.Empty<object>()));
			_bowSpeedReduction = config("3- Bows", "BowDraw MovementSpeed Reduction", BowPlugin.Utils.Toggle.On, new ConfigDescription("If On, speed will be reduced while aiming/drawing a bow", (AcceptableValueBase)null, Array.Empty<object>()));
			_xbowRecoil = config("4- Crossbows", "Recoil", 0f, new ConfigDescription("Crossbows pushback amount.\nVanilla: 40", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			_xbowReloadSpeed = config("4- Crossbows", "Reload Speed", 0.6f, new ConfigDescription("Crossbows reload time value if ScaleBySkillLevel is set to Off.\nVanilla: 3.5", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			_xbowReloadSpeedFactor = config("4- Crossbows", "Reload Speed Factor", 2f, new ConfigDescription("Crossbow reload speed factor at crossbow skill level 100\nIf Scale By Skill Level is On", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3.5f), Array.Empty<object>()));
			_scaleByXbowLevel = config("4- Crossbows", "Scale By Skill Level", BowPlugin.Utils.Toggle.On, new ConfigDescription("If On, crossbows reload time is scaled by crossbows skill level.", (AcceptableValueBase)null, Array.Empty<object>()));
			_xbowLaunchAngle = config("4- Crossbows", "Launch Angle", -1f, new ConfigDescription("The vertical angle at which the projectile leaves the crossbow after being fired.\nVanilla: -1", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-5f, 0f), Array.Empty<object>()));
			_enableExpMultiplier = config("5- Skill Exp", "Enable Exp Multiplier", BowPlugin.Utils.Toggle.On, new ConfigDescription("Enable/Disables exp multiplier for both bows and crossbows.", (AcceptableValueBase)null, Array.Empty<object>()));
			_bowExpMultiplier = config("5- Skill Exp", "Bows Exp Multiplier", 1f, new ConfigDescription("Exp multiplier for bow skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			_xbowExpMultiplier = config("5- Skill Exp", "Crossbows Exp Multiplier", 1f, new ConfigDescription("Exp multiplier for crossbow skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			_displayExpGained = config("5- Skill Exp", "Display Exp Gained", BowPlugin.Utils.Toggle.On, new ConfigDescription("Enable/Disables exp gained notification for both bows and crossbows.", (AcceptableValueBase)null, Array.Empty<object>()));
			_nextArrowKey = config<KeyCode>("6- Other Features", "Next Arrow Hotkey", (KeyCode)103, new ConfigDescription("Key to press to change arrows.", (AcceptableValueBase)null, Array.Empty<object>()));
			_autoEquipbow = config("6- Other Features", "Auto Equip Bow", BowPlugin.Utils.Toggle.On, new ConfigDescription("When NextArrowHotkey is pressed, bow is auto equip.\n(Only works if there's only one type of bow in the inventory.", (AcceptableValueBase)null, Array.Empty<object>()));
			_arrowSelection = config("6- Other Features", "Display Equipped Arrow Message", BowPlugin.Utils.Toggle.On, new ConfigDescription("Enable/Disables notification when NextArrowHotkey is pressed.", (AcceptableValueBase)null, Array.Empty<object>()));
			_sneakAttackMultiplier = config("6- Other Features", "Sneak Attack Multiplier", 1f, new ConfigDescription("Bonus damage multiplier to creatures with a successful sneak attack.\nRecommended: 1", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_enableRotation = config("6- Other Features", "Enable Character Rotation", BowPlugin.Utils.Toggle.On, new ConfigDescription("If On, character always faces the direction of your crosshair.", (AcceptableValueBase)null, Array.Empty<object>()));
			_critChance = config("2- General", "Critical Chance", 25f, new ConfigDescription("Percentage chance to make a custom critical hit using bows or crossbows.\nSet to 0 to disable\nNeeds logout to take effect", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			_critBonus = config("2- General", "Critical Damage Multiplier", 3f, new ConfigDescription("Damage multiplier for a successful custom critical hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			_crosshairSelection = config("2- General", "Crosshair Options", CrosshairSelection.Default, new ConfigDescription("Custom crosshair selection for bows crosshair.", (AcceptableValueBase)null, Array.Empty<object>()));
			_enableBowZoom = config("3- Bows", "Enable Zooming", BowPlugin.Utils.Toggle.On, new ConfigDescription("Enable/Disables bow draw zooming.", (AcceptableValueBase)null, Array.Empty<object>()));
			_enableAutoZoom = config("3- Bows", "Auto Zoom In", BowPlugin.Utils.Toggle.On, new ConfigDescription("Enable/Disables auto zooming in when drawing a bow.", (AcceptableValueBase)null, Array.Empty<object>()));
			_crosshairColor = config<Color>("2- General", "Crosshair Color", new Color(255f, 0f, 0f), new ConfigDescription("Crosshair color selection.", (AcceptableValueBase)null, Array.Empty<object>()));
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			_zoomKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("2- General", "Zoom Key", (KeyCode)120, new ConfigDescription("Key to press to zoom-in while drawing a bow when auto zoom is disabled.", (AcceptableValueBase)null, Array.Empty<object>()));
			_enableXbowZoom = config("4- Crossbows", "Enable Zooming", BowPlugin.Utils.Toggle.On, new ConfigDescription("Enable/Disables crossbow zooming.", (AcceptableValueBase)null, Array.Empty<object>()));
			_enableXbowSpeedRdction = config("4- Crossbows", "Speed Reduction", BowPlugin.Utils.Toggle.On, new ConfigDescription("If On, reduce walking speed when reloading a crossbow.", (AcceptableValueBase)null, Array.Empty<object>()));
			_IsBBHInstalled = Helper.CheckBBHMod();
			SetupPrefabs.Init();
			CustomCrosshairs.Init();
			PrefabContainerInit();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			ConfigWatcher();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void Update()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "main")
			{
				return;
			}
			Chat instance = Chat.instance;
			if (ZInput.instance != null && (!((Object)(object)instance != (Object)null) || !instance.IsChatDialogWindowVisible()) && !Minimap.InTextInput() && !Console.IsVisible() && !TextInput.IsVisible() && !Game.IsPaused() && !ZNet.instance.InPasswordDialog() && _nextArrowKey != null)
			{
				Player localPlayer = Player.m_localPlayer;
				if (Input.GetKeyDown(_nextArrowKey.Value) && ((Character)localPlayer).TakeInput())
				{
					BowFeature.SwitchArrow();
				}
				if (_zoomLevel == ZoomLevel.ZoomedIn && Input.GetKeyDown((KeyCode)114) && ((Character)localPlayer).TakeInput())
				{
					GameCamera.instance.m_fov = _defaultZoom;
					_zoomLevel = ZoomLevel.FixedZoom;
					_zoomOutDelayTimer = 0f;
					_zoomIntimer = 0f;
					_zoomOutTimer = 0f;
					((Character)localPlayer).SetWalk(false);
				}
			}
		}

		public static void PrefabContainerInit()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (!_IsBBHInstalled)
			{
				_PrefabContainer = new GameObject("ArrowContainer");
				_PrefabContainer.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_PrefabContainer);
			}
		}

		static Plugin()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			configFileFullPath = configPath + directorySeparatorChar + configFileName;
			BPLogger = Logger.CreateLogSource("BowPlugin");
			_harmony = new Harmony("blacks7ar.BowPlugin");
			_configSync = new ConfigSync("blacks7ar.BowPlugin")
			{
				DisplayName = "BowPlugin",
				CurrentVersion = "1.7.5",
				MinimumRequiredVersion = "1.7.5"
			};
			_currentZoom = 0f;
			_bowZoomFactor = 2f;
			_stayInZoomTime = 2f;
			_spineTimer = 0.5f;
		}
	}
}
namespace BowPlugin.Utils
{
	public class ConfigurationManagerAttributes
	{
		[UsedImplicitly]
		public bool? ShowRangeAsPercent;
	}
	public static class Helper
	{
		public static double DiminishingReturn(float value, float min, float max)
		{
			float num = max - min;
			float num2 = (value - min) / num;
			return Math.Sin(Math.PI / 2.0 * (double)num2);
		}

		public static bool IsBow(ItemData item)
		{
			return item.m_shared.m_name.ToLower().Contains("bow");
		}

		public static bool IsArrow(ItemData item)
		{
			if (!item.m_shared.m_name.Contains("_arrow"))
			{
				return item.m_shared.m_name.Contains("_bolt");
			}
			return true;
		}

		public static bool CheckBBHMod()
		{
			return Chainloader.PluginInfos.ContainsKey("Azumatt.BowsBeforeHoes");
		}

		public static GameObject Clone(this GameObject gameObject, string name)
		{
			GameObject obj = Object.Instantiate<GameObject>(gameObject, Plugin._PrefabContainer.transform, false);
			((Object)obj).name = name;
			obj.transform.SetParent(Plugin._PrefabContainer.transform, false);
			return obj;
		}

		public static void AddClonedObject(this ZNetScene zNetScene, GameObject gameObject, bool overWrite = true)
		{
			GameObject prefab;
			if ((Object)(object)(prefab = zNetScene.GetPrefab(((Object)gameObject).name)) != (Object)null)
			{
				if (!overWrite)
				{
					return;
				}
				zNetScene.m_prefabs.Remove(prefab);
				zNetScene.m_namedPrefabs.Remove(StringExtensionMethods.GetStableHashCode(((Object)gameObject).name));
			}
			zNetScene.m_prefabs.Add(gameObject);
			zNetScene.m_namedPrefabs.Add(StringExtensionMethods.GetStableHashCode(((Object)gameObject).name), gameObject);
		}

		public static float tFloat(this float value, int digits)
		{
			double num = Math.Pow(10.0, digits);
			return (float)Math.Truncate(num * (double)value / num);
		}

		public static float BackstabBonusMultiplier(float backstabBonus, float skillFactor)
		{
			float num = backstabBonus;
			num = (1f + skillFactor) * backstabBonus / 2f;
			Plugin._sneakAttackMultiplier.SettingChanged += delegate
			{
				num *= Plugin._sneakAttackMultiplier.Value;
			};
			num *= Plugin._sneakAttackMultiplier.Value;
			return Mathf.Max(num, 1f);
		}

		public static void UpdateBackstabMultiplier(ref int index, ref string tooltip, ItemData item)
		{
			string text = $"$item_backstab: <color=orange>{item.m_shared.m_backstabBonus}x</color>";
			index = tooltip.IndexOf(text);
			if (index > -1)
			{
				Player localPlayer = Player.m_localPlayer;
				float num = BackstabBonusMultiplier(item.m_shared.m_backstabBonus, ((Character)localPlayer).GetSkillFactor((SkillType)101));
				string text2 = $"$item_backstab: <color=orange>{item.m_shared.m_backstabBonus}x</color> <color=yellow>({num:#.##}x)</color>";
				tooltip = tooltip.Replace(text, text2);
				index += text2.Length;
			}
		}

		public static void UpdateCriticalMultiplier(ref int index, ref string tooltip, ItemData item)
		{
			float num = 0f;
			float num2 = 0f;
			Plugin._critChance.SettingChanged += delegate
			{
				num = Plugin._critChance.Value;
			};
			num = Plugin._critChance.Value;
			Plugin._critBonus.SettingChanged += delegate
			{
				num2 = Plugin._critBonus.Value;
			};
			num2 = Plugin._critBonus.Value;
			string text = $"\n$bbp_critical_chance: <color=orange>{num}%</color>" + $"\n$bbp_critical_damage: <color=orange>{num2}x</color>";
			tooltip = tooltip.Insert(index, text);
			index += text.Length;
		}

		public static void ApplyWeaponStaggerChanges(ItemDrop item)
		{
			if (IsBow(item.m_itemData))
			{
				item.m_itemData.m_shared.m_attack.m_staggerMultiplier = 0.9f;
			}
		}

		public static void AddClonedObject(this ObjectDB objectDB, GameObject gameObject, bool overWrite = true)
		{
			GameObject itemPrefab;
			if ((Object)(object)(itemPrefab = objectDB.GetItemPrefab(((Object)gameObject).name)) != (Object)null)
			{
				if (!overWrite)
				{
					return;
				}
				objectDB.m_items.Remove(itemPrefab);
				objectDB.m_itemByHash.Remove(StringExtensionMethods.GetStableHashCode(((Object)gameObject).name));
			}
			objectDB.m_items.Add(gameObject);
			objectDB.m_itemByHash.Add(StringExtensionMethods.GetStableHashCode(((Object)gameObject).name), gameObject);
		}

		public static void AddRecipe(this ObjectDB objectDB, Recipe recipe, bool overWrite = true)
		{
			if (objectDB.m_recipes.Contains(recipe))
			{
				if (!overWrite)
				{
					return;
				}
				objectDB.m_recipes.Remove(recipe);
			}
			objectDB.m_recipes.Add(recipe);
		}

		public static bool ObjectDBAwake()
		{
			if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0)
			{
				return (Object)(object)ObjectDB.instance.GetItemPrefab("Wood") != (Object)null;
			}
			return false;
		}

		public static bool ZNetSceneAwake()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs.Count != 0)
			{
				return (Object)(object)ZNetScene.instance.GetPrefab("piece_workbench") != (Object)null;
			}
			return false;
		}
	}
	public class Logging
	{
		public static void LogDebug(string debug)
		{
			Plugin.BPLogger.LogDebug((object)debug);
		}

		public static void LogInfo(string info)
		{
			Plugin.BPLogger.LogInfo((object)info);
		}

		public static void LogWarning(string warning)
		{
			Plugin.BPLogger.LogWarning((object)warning);
		}

		public static void LogError(string error)
		{
			Plugin.BPLogger.LogError((object)error);
		}
	}
	public enum Toggle
	{
		On = 1,
		Off = 0
	}
}
namespace BowPlugin.Patches
{
	[HarmonyPatch]
	public static class AttackPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
		public static bool FireProjectileBurst_Prefix(Attack __instance)
		{
			//IL_0051: 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)
			if (!__instance.m_bowDraw || !__instance.m_requiresReload)
			{
				return true;
			}
			for (int i = 0; i < __instance.m_projectiles; i++)
			{
				if (__instance.m_destroyPreviousProjectile && Object.op_Implicit((Object)(object)__instance.m_weapon.m_lastProjectile))
				{
					ZNetScene.instance.Destroy(__instance.m_weapon.m_lastProjectile);
					__instance.m_weapon.m_lastProjectile = null;
				}
				new HitData().m_backstabBonus = Helper.BackstabBonusMultiplier(__instance.m_weapon.m_shared.m_backstabBonus, ((Character)__instance.m_character).GetSkillFactor((SkillType)101));
			}
			return true;
		}

		[HarmonyPatch(typeof(Attack), "Start")]
		[HarmonyPrefix]
		public static void AttackStart_Prefix(Attack __instance, Humanoid character)
		{
			//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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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)
			if ((__instance == null && !((Character)character).IsPlayer()) || (((Character)character).m_name != "Human" && (Object)(object)character != (Object)(object)Player.m_localPlayer) || (!__instance.m_bowDraw && !__instance.m_requiresReload) || !((Character)character).GetSEMan().HaveStatusEffect("BowMastery"))
			{
				return;
			}
			SE_Critical sE_Critical = ((Character)character).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("BowMastery")) as SE_Critical;
			if (!((float)new Random().Next(1, 100) <= sE_Critical.GetCritChance()))
			{
				return;
			}
			Attack obj = __instance;
			obj.m_damageMultiplier *= sE_Critical.GetCritBonus();
			foreach (Vector3 item in from item in new List<HitPoint>()
				let go = item.go
				let vector = item.avgPoint / (float)item.count
				select (Vector3)((int)__instance.m_hitPointtype switch
				{
					1 => vector, 
					2 => item.firstPoint, 
					0 => item.closestPoint, 
					_ => vector, 
				}))
			{
				__instance.m_weapon.m_shared.m_hitEffect.Create(item, Quaternion.identity, (Transform)null, 1f, -1);
				__instance.m_hitEffect.Create(item, Quaternion.identity, (Transform)null, 1f, -1);
				Object.Instantiate<GameObject>(SetupPrefabs._fxBowCrit, item, Quaternion.identity);
			}
			((Character)character).Message((MessageType)1, "<color=orange>Critical Hit!</color>", 0, (Sprite)null);
			Debug.Log((object)"Critical Hit!");
		}

		[HarmonyPatch(typeof(Attack), "Start")]
		[HarmonyPostfix]
		public static void AttackStart_Postfix(Attack __instance)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Invalid comparison between Unknown and I4
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Invalid comparison between Unknown and I4
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Invalid comparison between Unknown and I4
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Invalid comparison between Unknown and I4
			if (__instance == null)
			{
				return;
			}
			Humanoid character = __instance.m_character;
			Player val = (Player)(object)((character is Player) ? character : null);
			if (val == null || (((Character)val).m_name != "Human" && (Object)(object)val != (Object)(object)Player.m_localPlayer))
			{
				return;
			}
			ItemData ammoItem = ((Humanoid)val).GetAmmoItem();
			if (ammoItem != null && ammoItem.m_shared.m_name.ToLower().Contains("bait"))
			{
				return;
			}
			bool flag = ((Humanoid)val).GetCurrentWeapon() == null;
			if (!flag)
			{
				SkillType skillType = ((Humanoid)val).GetCurrentWeapon().m_shared.m_skillType;
				bool flag2 = (((int)skillType == 8 || (int)skillType == 14) ? true : false);
				flag = !flag2;
			}
			if (flag)
			{
				return;
			}
			Plugin._velocityMultiplier.SettingChanged += delegate
			{
				Attack obj7 = __instance;
				obj7.m_projectileVel *= Plugin._velocityMultiplier.Value;
				Attack obj8 = __instance;
				obj8.m_projectileVelMin *= Plugin._velocityMultiplier.Value;
			};
			Attack obj = __instance;
			obj.m_projectileVel *= Plugin._velocityMultiplier.Value;
			Attack obj2 = __instance;
			obj2.m_projectileVelMin *= Plugin._velocityMultiplier.Value;
			Plugin._accuracyMultiplier.SettingChanged += delegate
			{
				Attack obj5 = __instance;
				obj5.m_projectileAccuracy *= Plugin._accuracyMultiplier.Value;
				Attack obj6 = __instance;
				obj6.m_projectileAccuracyMin *= Plugin._accuracyMultiplier.Value;
			};
			Attack obj3 = __instance;
			obj3.m_projectileAccuracy *= Plugin._accuracyMultiplier.Value;
			Attack obj4 = __instance;
			obj4.m_projectileAccuracyMin *= Plugin._accuracyMultiplier.Value;
			if ((int)((Humanoid)val).GetCurrentWeapon().m_shared.m_skillType == 8)
			{
				Plugin._bowLaunchAngle.SettingChanged += delegate
				{
					__instance.m_launchAngle = Plugin._bowLaunchAngle.Value;
				};
				__instance.m_launchAngle = Plugin._bowLaunchAngle.Value;
			}
			else if ((int)((Humanoid)val).GetCurrentWeapon().m_shared.m_skillType == 14)
			{
				Plugin._xbowLaunchAngle.SettingChanged += delegate
				{
					__instance.m_launchAngle = Plugin._xbowLaunchAngle.Value;
				};
				__instance.m_launchAngle = Plugin._xbowLaunchAngle.Value;
			}
		}
	}
	[HarmonyPatch]
	public static class CharacterPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Character), "UpdateStagger")]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Is(instruction, OpCodes.Ldc_R4, (object)3f))
				{
					instruction.operand = 4f;
				}
			}
			return instructions;
		}
	}
	[HarmonyPatch]
	public static class GameCameraPatch
	{
		[HarmonyPriority(100)]
		[HarmonyPatch(typeof(GameCamera), "GetCameraPosition")]
		[HarmonyPostfix]
		private static void GetCameraPosition_Postfix(GameCamera __instance, float dt, Vector3 pos, Quaternion rot)
		{
			if ((Object)(object)__instance != (Object)null && Plugin._enableBowZoom.Value == BowPlugin.Utils.Toggle.On && Plugin._defaultZoom == 0f)
			{
				Plugin._defaultZoom = __instance.m_fov;
			}
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		public static void UpdateCamera_Prefix(GameCamera __instance)
		{
			bool flag = Plugin._enableBowZoom.Value == BowPlugin.Utils.Toggle.On;
			if (flag)
			{
				ZoomLevel zoomLevel = Plugin._zoomLevel;
				bool flag2 = (uint)(zoomLevel - 1) <= 1u;
				flag = flag2;
			}
			if (flag)
			{
				__instance.m_fov = Plugin._currentZoom;
			}
		}
	}
	[HarmonyPatch]
	public static class HudPatch
	{
		private static bool _justWalk;

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
		public static void UpdateCrosshair_Postfix(Hud __instance, Player player, float bowDrawPercentage)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00c7: 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_010f: 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_015c: Invalid comparison between Unknown and I4
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			if (((Humanoid)player).GetCurrentWeapon() == null)
			{
				return;
			}
			Plugin._onBowDrawing = bowDrawPercentage > 0.1f;
			if (bowDrawPercentage > 0.1f)
			{
				if (Plugin._bowSpeedReduction.Value == BowPlugin.Utils.Toggle.On)
				{
					((Character)player).SetWalk(true);
					_justWalk = true;
				}
				((Graphic)__instance.m_crosshair).color = Color.Lerp(new Color(1f, 1f, 1f), Plugin._crosshairColor.Value, 0.5f);
				float num = Mathf.Lerp(1f, 0.15f, bowDrawPercentage);
				((Component)__instance.m_crosshairBow).gameObject.SetActive(true);
				((Component)__instance.m_crosshairBow).transform.localScale = new Vector3(num, num, num);
				((Graphic)__instance.m_crosshairBow).color = Color.Lerp(new Color(1f, 1f, 1f), Plugin._crosshairColor.Value, bowDrawPercentage);
			}
			else if (((Character)player).GetWalk() && _justWalk)
			{
				_justWalk = false;
				((Character)player).SetWalk(false);
				((Graphic)__instance.m_crosshair).color = new Color(1f, 1f, 1f, 0.5f);
				((Component)__instance.m_crosshairBow).gameObject.SetActive(false);
			}
			if (Plugin._enableBowZoom.Value == BowPlugin.Utils.Toggle.Off || Plugin._defaultZoom == 0f)
			{
				return;
			}
			if (((Humanoid)player).GetCurrentWeapon() == null || (int)((Humanoid)player).GetCurrentWeapon().m_shared.m_itemType != 4)
			{
				ZoomedOut();
				return;
			}
			double num2 = 2.5 * ((double)Plugin._bowZoomSpeedFactor.Value - Helper.DiminishingReturn(((Character)player).GetSkillLevel((SkillType)8), 0f, 100f));
			float num3 = Mathf.InverseLerp(0.1f, (float)num2, Plugin._zoomIntimer);
			if (Plugin._enableAutoZoom.Value == BowPlugin.Utils.Toggle.On)
			{
				if (bowDrawPercentage > 0.01f)
				{
					Plugin._zoomIntimer += Time.deltaTime;
					Plugin._zoomLevel = ZoomLevel.ZoomedIn;
					GameCamera.instance.m_fov = (Plugin._previousZoom = Mathf.Lerp(Plugin._defaultZoom, Plugin._defaultZoom / Plugin._bowZoomFactor, num3));
					Plugin._currentZoom = (Plugin._previousZoom = Mathf.Lerp(Plugin._defaultZoom, Plugin._defaultZoom / Plugin._bowZoomFactor, num3));
					return;
				}
				ZoomedOut();
			}
			if (Input.GetKey(Plugin._zoomKey.Value))
			{
				if (!(bowDrawPercentage > 0.01f))
				{
					Plugin._zoomOutDelayTimer += Time.deltaTime;
					if (Plugin._zoomOutDelayTimer > Plugin._stayInZoomTime)
					{
						ZoomedOut();
					}
				}
				else
				{
					Plugin._zoomIntimer += Time.deltaTime;
					Plugin._zoomOutDelayTimer = 0f;
					Plugin._zoomLevel = ZoomLevel.ZoomedIn;
					GameCamera.instance.m_fov = (Plugin._previousZoom = Mathf.Lerp(Plugin._defaultZoom, Plugin._defaultZoom / Plugin._bowZoomFactor, num3));
					Plugin._currentZoom = (Plugin._previousZoom = Mathf.Lerp(Plugin._defaultZoom, Plugin._defaultZoom / Plugin._bowZoomFactor, num3));
				}
			}
			else
			{
				Plugin._zoomOutDelayTimer = 1f;
				ZoomedOut();
			}
			if (((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_requiresReload && Plugin._enableXbowZoom.Value == BowPlugin.Utils.Toggle.On)
			{
				if (Input.GetKey(Plugin._zoomKey.Value) && ((Humanoid)player).IsWeaponLoaded())
				{
					Plugin._zoomLevel = ZoomLevel.ZoomedIn;
					GameCamera.instance.m_fov = 30f;
					Plugin._currentZoom = 30f;
				}
				else
				{
					ZoomedOut();
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Hud), "Awake")]
		public static bool HudAwake_Prefix(Hud __instance)
		{
			if ((Object)(object)__instance.m_crosshair == (Object)null)
			{
				return false;
			}
			Sprite _default = ((IEnumerable<Sprite>)Resources.FindObjectsOfTypeAll<Sprite>()).FirstOrDefault((Func<Sprite, bool>)((Sprite x) => ((Object)x).name == "crosshair_bow"));
			Plugin._crosshairSelection.SettingChanged += delegate
			{
				Image crosshairBow2 = __instance.m_crosshairBow;
				crosshairBow2.sprite = (Sprite)(Plugin._crosshairSelection.Value switch
				{
					CrosshairSelection.PistolTarget => CustomCrosshairs._pistolTarget, 
					CrosshairSelection.SimpleCrosshair => CustomCrosshairs._simpleCrosshair, 
					CrosshairSelection.TargetDesign => CustomCrosshairs._targetDesign, 
					CrosshairSelection.TriangularCrosshair => CustomCrosshairs._triangularCrosshair, 
					CrosshairSelection.CircularGunTarget => CustomCrosshairs._circularGunTarget, 
					CrosshairSelection.DartBoardTarget => CustomCrosshairs._dartBoardTarget, 
					CrosshairSelection.DeviceFocusPoint => CustomCrosshairs._deviceFocusPoint, 
					CrosshairSelection.EyeWideOpen => CustomCrosshairs._eyeWideOpen, 
					CrosshairSelection.FightingWeaponTarget => CustomCrosshairs._fightingWeaponTarget, 
					CrosshairSelection.RoundTargetSymbol => CustomCrosshairs._roundTargetSymbol, 
					CrosshairSelection.SharpDecoratedTarget => CustomCrosshairs._sharpDecoratedTarget, 
					CrosshairSelection.ShootTargetPoint => CustomCrosshairs._shootTargetPoint, 
					CrosshairSelection.Default => _default, 
					_ => __instance.m_crosshairBow.sprite, 
				});
			};
			Image crosshairBow = __instance.m_crosshairBow;
			crosshairBow.sprite = (Sprite)(Plugin._crosshairSelection.Value switch
			{
				CrosshairSelection.PistolTarget => CustomCrosshairs._pistolTarget, 
				CrosshairSelection.SimpleCrosshair => CustomCrosshairs._simpleCrosshair, 
				CrosshairSelection.TargetDesign => CustomCrosshairs._targetDesign, 
				CrosshairSelection.TriangularCrosshair => CustomCrosshairs._triangularCrosshair, 
				CrosshairSelection.CircularGunTarget => CustomCrosshairs._circularGunTarget, 
				CrosshairSelection.DartBoardTarget => CustomCrosshairs._dartBoardTarget, 
				CrosshairSelection.DeviceFocusPoint => CustomCrosshairs._deviceFocusPoint, 
				CrosshairSelection.EyeWideOpen => CustomCrosshairs._eyeWideOpen, 
				CrosshairSelection.FightingWeaponTarget => CustomCrosshairs._fightingWeaponTarget, 
				CrosshairSelection.RoundTargetSymbol => CustomCrosshairs._roundTargetSymbol, 
				CrosshairSelection.SharpDecoratedTarget => CustomCrosshairs._sharpDecoratedTarget, 
				CrosshairSelection.ShootTargetPoint => CustomCrosshairs._shootTargetPoint, 
				CrosshairSelection.Default => _default, 
				_ => __instance.m_crosshairBow.sprite, 
			});
			return true;
		}

		private static void ZoomedOut()
		{
			if (Plugin._zoomLevel != 0)
			{
				if (Plugin._zoomLevel == ZoomLevel.ZoomedIn)
				{
					Plugin._zoomLevel = ZoomLevel.ZoomedOut;
					Plugin._zoomOutTimer = 0f;
					Plugin._zoomIntimer = 0f;
				}
				else
				{
					Plugin._zoomOutTimer += Time.deltaTime;
					if (Plugin._zoomOutTimer > 1f)
					{
						GameCamera.instance.m_fov = Plugin._defaultZoom;
						Plugin._zoomLevel = ZoomLevel.FixedZoom;
						Plugin._zoomOutDelayTimer = 0f;
						return;
					}
				}
				float num = Mathf.InverseLerp(0f, 0.3f, Plugin._zoomOutTimer);
				GameCamera.instance.m_fov = Mathf.Lerp(Plugin._previousZoom, Plugin._defaultZoom, num);
				Plugin._currentZoom = Mathf.Lerp(Plugin._previousZoom, Plugin._defaultZoom, num);
			}
			else if (GameCamera.instance.m_fov != Plugin._defaultZoom)
			{
				GameCamera.instance.m_fov = Plugin._defaultZoom;
			}
		}
	}
	[HarmonyPatch]
	public static class ItemDataPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float)
		})]
		public static void GetTooltip_Postfix(ref string __result, ItemData item, int qualityLevel, bool crafting)
		{
			try
			{
				if (Helper.IsBow(item))
				{
					int index = -1;
					Helper.UpdateBackstabMultiplier(ref index, ref __result, item);
					if (!(Plugin._critChance.Value <= 0f))
					{
						Helper.UpdateCriticalMultiplier(ref index, ref __result, item);
					}
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch]
	public static class ObjectDBPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ObjectDB), "UpdateItemHashes")]
		public static void UpdateItemHashes_Postfix(ObjectDB __instance)
		{
			foreach (ItemDrop item in from item in __instance.m_items
				select item.GetComponent<ItemDrop>() into component
				where Object.op_Implicit((Object)(object)component) && Helper.IsBow(component.m_itemData) && component.m_itemData.m_shared.m_attack.m_bowDraw
				select component)
			{
				Helper.ApplyWeaponStaggerChanges(item);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static void ObjectDBAwake_Postfix(ObjectDB __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			foreach (ItemDrop item in __instance.m_items.Select((GameObject item) => item.GetComponent<ItemDrop>()))
			{
				if (Helper.IsBow(item.m_itemData))
				{
					SE_Critical se_critical = ScriptableObject.CreateInstance<SE_Critical>();
					Plugin._critChance.SettingChanged += delegate
					{
						se_critical.SetCritChance(Plugin._critChance.Value);
					};
					se_critical.SetCritChance(Plugin._critChance.Value);
					Plugin._critBonus.SettingChanged += delegate
					{
						se_critical.SetCritBonus(Plugin._critBonus.Value);
					};
					se_critical.SetCritBonus(Plugin._critBonus.Value);
					if (Plugin._critChance.Value <= 0f)
					{
						break;
					}
					item.m_itemData.m_shared.m_equipStatusEffect = (StatusEffect)(object)se_critical;
				}
				if (Plugin._IsBBHInstalled)
				{
					break;
				}
				SwitchProjectile.Init(item);
				if (!Helper.IsArrow(item.m_itemData))
				{
					continue;
				}
				Projectile projectile = item.m_itemData.m_shared.m_attack.m_attackProjectile.GetComponent<Projectile>();
				if (Object.op_Implicit((Object)(object)projectile))
				{
					projectile.m_spawnOnHit = ((Component)item).gameObject;
					Plugin._spawnChance.SettingChanged += delegate
					{
						projectile.m_spawnOnHitChance = Plugin._spawnChance.Value;
					};
					projectile.m_spawnOnHitChance = Plugin._spawnChance.Value;
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		[HarmonyPrefix]
		public static void Awake_Prefix(ref ObjectDB __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			foreach (Recipe item in __instance.m_recipes.Where((Recipe recipe) => ((Object)recipe).name == "Recipe_ArrowWood"))
			{
				item.m_craftingStation = null;
			}
		}
	}
	[HarmonyPatch]
	public static class PlayerPatch
	{
		private static bool _justWalk;

		[HarmonyPatch(typeof(Player), "AlwaysRotateCamera")]
		[HarmonyPrefix]
		public static bool AlwaysRotateCamera_Prefix(Player __instance, ref bool __result)
		{
			if (Plugin._enableRotation.Value == BowPlugin.Utils.Toggle.On && ((Humanoid)__instance).GetCurrentWeapon() != null && ((Humanoid)__instance).GetCurrentWeapon() != ((Humanoid)__instance).m_unarmedWeapon.m_itemData && !((Character)__instance).IsRunning() && !((Character)__instance).InEmote())
			{
				__result = true;
				return false;
			}
			__result = false;
			return true;
		}

		[HarmonyPatch(typeof(Player), "PlayerAttackInput")]
		[HarmonyPrefix]
		public static bool PlayerAttackInput_Prefix(Player __instance, float dt)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (((Humanoid)__instance).GetCurrentWeapon() != null && ((Humanoid)__instance).GetCurrentWeapon().m_shared.m_attack.m_bowDraw)
			{
				Plugin._scaleByBowLevel.SettingChanged += delegate
				{
					ToggleScaleByBowLevel(__instance);
				};
				ToggleScaleByBowLevel(__instance);
			}
			if (((Humanoid)__instance).GetCurrentWeapon() != null && ((Humanoid)__instance).GetCurrentWeapon().m_shared.m_attack.m_requiresReload)
			{
				Plugin._xbowRecoil.SettingChanged += delegate
				{
					((Humanoid)__instance).GetCurrentWeapon().m_shared.m_attack.m_recoilPushback = Plugin._xbowRecoil.Value;
				};
				((Humanoid)__instance).GetCurrentWeapon().m_shared.m_attack.m_recoilPushback = Plugin._xbowRecoil.Value;
				Plugin._scaleByXbowLevel.SettingChanged += delegate
				{
					ToggleScaleByXbowLevel(__instance);
				};
				ToggleScaleByXbowLevel(__instance);
			}
			return true;
		}

		[HarmonyPatch(typeof(Player), "UseHotbarItem")]
		[HarmonyPrefix]
		public static bool UseHotbarItem_Prefix(Player __instance)
		{
			if (Plugin._zoomLevel != ZoomLevel.ZoomedIn)
			{
				return true;
			}
			GameCamera.instance.m_fov = Plugin._defaultZoom;
			Plugin._zoomLevel = ZoomLevel.FixedZoom;
			Plugin._zoomOutDelayTimer = 0f;
			Plugin._zoomIntimer = 0f;
			Plugin._zoomOutTimer = 0f;
			return true;
		}

		[HarmonyPatch(typeof(Player), "QueueReloadAction")]
		[HarmonyPrefix]
		public static void QueueReloadAction_Prefix(Player __instance)
		{
			//IL_0047: 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_0053: 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_005a: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00ce: Expected O, but got Unknown
			if (__instance.IsReloadActionQueued())
			{
				return;
			}
			ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon();
			if (currentWeapon != null && currentWeapon.m_shared.m_attack.m_requiresReload)
			{
				if (Plugin._enableXbowSpeedRdction.Value == BowPlugin.Utils.Toggle.On)
				{
					((Character)__instance).SetWalk(true);
					_justWalk = true;
				}
				MinorActionData item = new MinorActionData
				{
					m_item = currentWeapon,
					m_type = (ActionType)2,
					m_duration = currentWeapon.GetWeaponLoadingTime(),
					m_progressText = "$hud_reloading " + currentWeapon.m_shared.m_name,
					m_animation = currentWeapon.m_shared.m_attack.m_reloadAnimation,
					m_doneAnimation = currentWeapon.m_shared.m_attack.m_reloadAnimation + "_done",
					m_staminaDrain = currentWeapon.m_shared.m_attack.m_reloadStaminaDrain
				};
				__instance.m_actionQueue.Add(item);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "IsWeaponLoaded")]
		public static void IsWeaponLoaded_Postfix(Player __instance, ref bool __result)
		{
			if (__result && ((Character)__instance).GetWalk() && _justWalk && Plugin._enableXbowSpeedRdction.Value == BowPlugin.Utils.Toggle.On)
			{
				((Character)__instance).SetWalk(false);
				_justWalk = false;
			}
		}

		private static void ToggleScaleByBowLevel(Player player)
		{
			if (Plugin._scaleByBowLevel.Value == BowPlugin.Utils.Toggle.On)
			{
				((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_drawDurationMin = 2.5f;
				double num = (double)Plugin._bowDrawSpeedFactor.Value * Helper.DiminishingReturn(((Character)player).GetSkillLevel((SkillType)8), 0f, 100f);
				((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_drawDurationMin = 2.5f - (float)num;
				return;
			}
			((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_drawDurationMin = 2.5f;
			Plugin._bowDrawSpeed.SettingChanged += delegate
			{
				((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_drawDurationMin = Plugin._bowDrawSpeed.Value;
			};
			((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_drawDurationMin = Plugin._bowDrawSpeed.Value;
		}

		private static void ToggleScaleByXbowLevel(Player player)
		{
			if (Plugin._scaleByXbowLevel.Value == BowPlugin.Utils.Toggle.On)
			{
				((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_reloadTime = 3.5f;
				double num = (double)Plugin._xbowReloadSpeedFactor.Value * Helper.DiminishingReturn(((Character)player).GetSkillLevel((SkillType)8), 0f, 100f);
				((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_reloadTime = 3.5f - (float)num;
				return;
			}
			((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_reloadTime = 3.5f;
			Plugin._xbowReloadSpeed.SettingChanged += delegate
			{
				((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_reloadTime = Plugin._xbowReloadSpeed.Value;
			};
			((Humanoid)player).GetCurrentWeapon().m_shared.m_attack.m_reloadTime = Plugin._xbowReloadSpeed.Value;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "LateUpdate")]
		private static void LateUpdate_Postfix(Player __instance, Transform ___m_head, ref Rigidbody ___m_body, ref VisEquipment ___m_visEquipment, ItemData ___m_rightItem, ItemData ___m_leftItem)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if ((Object)(object)Plugin._spine == (Object)null)
			{
				Plugin._spine = ((IEnumerable<Transform>)((Humanoid)__instance).m_visEquipment.m_bodyModel.bones).SingleOrDefault((Func<Transform, bool>)((Transform x) => ((Object)x).name == "Spine"));
			}
			Quaternion rotation;
			if (___m_leftItem != null && (int)___m_leftItem.m_shared.m_itemType == 4 && Object.op_Implicit((Object)(object)___m_body) && Plugin._onBowDrawing)
			{
				Plugin._spineTimer = 0.5f;
				rotation = ((Component)((Character)__instance).m_eye).transform.rotation;
				float num = ((Quaternion)(ref rotation)).eulerAngles.y + 90f;
				Transform spine = Plugin._spine;
				rotation = Plugin._spine.rotation;
				float x2 = ((Quaternion)(ref rotation)).eulerAngles.x;
				rotation = ((Component)((Character)__instance).m_eye).transform.rotation;
				spine.rotation = Quaternion.Euler(x2, num, ((Quaternion)(ref rotation)).eulerAngles.x);
			}
			else if (Plugin._spineTimer > 0f)
			{
				Plugin._spineTimer -= Time.deltaTime;
				rotation = ((Component)((Character)__instance).m_eye).transform.rotation;
				float num2 = ((Quaternion)(ref rotation)).eulerAngles.y + 90f;
				Transform spine2 = Plugin._spine;
				rotation = Plugin._spine.rotation;
				float x3 = ((Quaternion)(ref rotation)).eulerAngles.x;
				rotation = ((Component)((Character)__instance).m_eye).transform.rotation;
				spine2.rotation = Quaternion.Euler(x3, num2, ((Quaternion)(ref rotation)).eulerAngles.x);
			}
		}
	}
	[HarmonyPatch]
	public static class ProjectilePatch
	{
		[HarmonyPatch(typeof(Projectile), "OnHit")]
		[HarmonyPrefix]
		public static void ProjectileOnHit_Prefix(Projectile __instance, Collider collider, Vector3 hitPoint, bool water)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			ItemData currentWeapon = ((Humanoid)Player.m_localPlayer).GetCurrentWeapon();
			if (currentWeapon == null || (Object)(object)Player.m_localPlayer == (Object)null || !currentWeapon.m_shared.m_attack.m_bowDraw || !currentWeapon.m_shared.m_attack.m_requiresReload)
			{
				return;
			}
			GameObject val = (Object.op_Implicit((Object)(object)collider) ? Projectile.FindHitObject(collider) : null);
			IDestructible val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<IDestructible>() : null);
			bool flag = false;
			bool flag2 = false;
			if (__instance.m_aoe > 0f)
			{
				__instance.DoAOE(hitPoint, ref flag2, ref flag);
			}
			else if (val2 != null)
			{
				if (!__instance.IsValidTarget(val2))
				{
					return;
				}
				flag = true;
			}
			Character val3 = (Character)(object)((val2 is Character) ? val2 : null);
			if (Object.op_Implicit((Object)(object)val3) && (Object)(object)__instance.m_owner != (Object)null && flag && __instance.m_owner.IsPlayer() && __instance.m_backstabBonus > 1f && (Object)(object)val3.m_baseAI != (Object)null && !val3.m_baseAI.IsAlerted() && Time.time - val3.m_backstabTime > 300f)
			{
				__instance.m_owner.RaiseSkill((SkillType)101, 3f);
			}
		}
	}
	[HarmonyPatch]
	public static class SkillsPatch
	{
		[HarmonyPatch(typeof(Skills), "RaiseSkill")]
		public static class RaiseSkillPatch
		{
			public static void Prefix(ref SkillType skillType, ref float factor)
			{
				//IL_0010: 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_0013: Invalid comparison between Unknown and I4
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Invalid comparison between Unknown and I4
				if (Plugin._enableExpMultiplier.Value != BowPlugin.Utils.Toggle.On)
				{
					return;
				}
				SkillType val = skillType;
				if ((int)val != 8)
				{
					if ((int)val == 14)
					{
						factor *= Plugin._xbowExpMultiplier.Value;
					}
				}
				else
				{
					factor *= Plugin._bowExpMultiplier.Value;
				}
			}

			public static void Postfix(Skills __instance, SkillType skillType)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Invalid comparison between Unknown and I4
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				if (Plugin._enableExpMultiplier.Value != BowPlugin.Utils.Toggle.On || Plugin._displayExpGained.Value != BowPlugin.Utils.Toggle.On || ((int)skillType != 8 && (int)skillType != 14))
				{
					return;
				}
				try
				{
					if (__instance.GetSkillLevel((SkillType)8) < 100f && __instance.GetSkillLevel((SkillType)14) < 100f)
					{
						Skill skill = __instance.GetSkill(skillType);
						float value = skill.m_accumulator / (skill.GetNextLevelRequirement() / 100f);
						((Character)__instance.m_player).Message((MessageType)1, $"Level {skill.m_level.tFloat(0)} {((object)(SkillType)(ref skill.m_info.m_skill)).ToString()} [{skill.m_accumulator.tFloat(2)}/{skill.GetNextLevelRequirement().tFloat(2)} ({value.tFloat(0)}%)", 0, skill.m_info.m_icon);
					}
				}
				catch
				{
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	public class ZNetScenePatch
	{
		public static void Postfix(ZNetScene __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				List<GameObject> prefabs = __instance.m_prefabs;
				if (prefabs != null && prefabs.Count > 0 && !Plugin._IsBBHInstalled)
				{
					Plugin.PrefabContainerInit();
					ArrowProjectile.Init(__instance);
				}
			}
		}
	}
}
namespace BowPlugin.Functions
{
	public static class ArrowProjectile
	{
		public static void Init(ZNetScene zNetScene)
		{
			FlintArrow(zNetScene);
			BronzeArrow(zNetScene);
			IronArrow(zNetScene);
			ObsidianArrow(zNetScene);
			SilverArrow(zNetScene);
			BlackMetalBolt(zNetScene);
			IronBolt(zNetScene);
		}

		private static void FlintArrow(ZNetScene zNetScene)
		{
			GameObject gameObject = zNetScene.GetPrefab("bow_projectile").Clone("bow_projectile_flint");
			zNetScene.AddClonedObject(gameObject);
		}

		private static void BronzeArrow(ZNetScene zNetScene)
		{
			GameObject gameObject = zNetScene.GetPrefab("bow_projectile").Clone("bow_projectile_bronze");
			zNetScene.AddClonedObject(gameObject);
		}

		private static void IronArrow(ZNetScene zNetScene)
		{
			GameObject gameObject = zNetScene.GetPrefab("bow_projectile").Clone("bow_projectile_iron");
			zNetScene.AddClonedObject(gameObject);
		}

		private static void ObsidianArrow(ZNetScene zNetScene)
		{
			GameObject gameObject = zNetScene.GetPrefab("bow_projectile").Clone("bow_projectile_obsidian");
			zNetScene.AddClonedObject(gameObject);
		}

		private static void SilverArrow(ZNetScene zNetScene)
		{
			GameObject gameObject = zNetScene.GetPrefab("bow_projectile").Clone("bow_projectile_silver");
			zNetScene.AddClonedObject(gameObject);
		}

		private static void BlackMetalBolt(ZNetScene zNetScene)
		{
			GameObject gameObject = zNetScene.GetPrefab("arbalest_projectile_carapace").Clone("arbalest_projectile_blackmetal");
			zNetScene.AddClonedObject(gameObject);
		}

		private static void IronBolt(ZNetScene zNetScene)
		{
			GameObject gameObject = zNetScene.GetPrefab("arbalest_projectile_carapace").Clone("arbalest_projectile_iron");
			zNetScene.AddClonedObject(gameObject);
		}
	}
	public enum CrosshairSelection
	{
		Default,
		CircularGunTarget,
		SimpleCrosshair,
		DartBoardTarget,
		DeviceFocusPoint,
		EyeWideOpen,
		FightingWeaponTarget,
		PistolTarget,
		RoundTargetSymbol,
		SharpDecoratedTarget,
		ShootTargetPoint,
		TargetDesign,
		TriangularCrosshair
	}
	public static class BowFeature
	{
		public static void SwitchArrow()
		{
			Player localPlayer = Player.m_localPlayer;
			if (CheckIfBowExist())
			{
				((Humanoid)localPlayer).EquipItem(EquipNextArrow(), true);
				ShowArrowEquipped();
			}
		}

		private static bool CheckIfBowExist()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "main")
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if (string.IsNullOrEmpty(((Humanoid)localPlayer).GetCurrentWeapon().m_shared.m_ammoType))
			{
				List<ItemData> list = new List<ItemData>();
				((Humanoid)localPlayer).GetInventory().GetAllItems((ItemType)4, list);
				switch (list.Count)
				{
				case 0:
					if (Plugin._arrowSelection.Value == BowPlugin.Utils.Toggle.On)
					{
						((Character)localPlayer).Message((MessageType)2, "<size=28>There's no bow in your inventory.</size>", 0, (Sprite)null);
					}
					break;
				case 1:
					if (Plugin._autoEquipbow.Value == BowPlugin.Utils.Toggle.On)
					{
						((Humanoid)localPlayer).EquipItem(list[0], true);
					}
					ShowArrowEquipped();
					break;
				}
				return false;
			}
			switch (CountArrowStacks())
			{
			case 0:
				if (Plugin._arrowSelection.Value == BowPlugin.Utils.Toggle.On)
				{
					((Character)localPlayer).Message((MessageType)2, "<size=28>There's no arrow in your inventory.</size>", 0, (Sprite)null);
				}
				return false;
			case 1:
				if (Plugin._arrowSelection.Value == BowPlugin.Utils.Toggle.On)
				{
					((Character)localPlayer).Message((MessageType)2, "<size=28>You only have one type of arrow.</size>", 0, (Sprite)null);
				}
				return false;
			default:
				return true;
			}
		}

		private static void ShowArrowEquipped()
		{
			if (Plugin._arrowSelection.Value == BowPlugin.Utils.Toggle.On)
			{
				Player localPlayer = Player.m_localPlayer;
				((Character)localPlayer).Message((MessageType)2, "<size=28><color=red>" + ((Humanoid)localPlayer).GetAmmoItem()?.m_shared.m_name + "</color> equipped.</size>", 0, (Sprite)null);
			}
		}

		private static int CountArrowStacks()
		{
			int num = 0;
			List<string> list = new List<string>();
			foreach (ItemData item in from item in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems()
				where (int)item.m_shared.m_itemType == 9 && !list.Contains(item.m_shared.m_name)
				select item)
			{
				list.Add(item.m_shared.m_name);
				num++;
			}
			return num;
		}

		private static ItemData EquipNextArrow()
		{
			Player player = Player.m_localPlayer;
			ItemData ammoItem = ((Humanoid)player).GetAmmoItem();
			List<string> list = new List<string>();
			if (ammoItem == null)
			{
				return ((Humanoid)player).GetInventory().GetAmmoItem(((Humanoid)player).GetCurrentWeapon().m_shared.m_ammoType, (string)null);
			}
			int num = CalculateArrows(((Humanoid)player).GetAmmoItem());
			int num2 = -1;
			ItemData result = null;
			foreach (ItemData item in ((Humanoid)player).GetInventory().GetAllItems().Where(delegate(ItemData item)
			{
				//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_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Invalid comparison between Unknown and I4
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				ItemType itemType = item.m_shared.m_itemType;
				bool flag = (((int)itemType == 2 || (int)itemType == 9) ? true : false);
				return flag && item.m_shared.m_ammoType == ((Humanoid)player).GetCurrentWeapon().m_shared.m_ammoType && !list.Contains(item.m_shared.m_name);
			}))
			{
				list.Add(item.m_shared.m_name);
				int num3 = CalculateArrows(item);
				if (num3 > num && num2 == -1)
				{
					num2 = num3;
					result = item;
				}
				else if (num3 < num2 && num3 > num)
				{
					num2 = num3;
					result = item;
				}
			}
			if (num2 != -1)
			{
				return result;
			}
			return ((Humanoid)player).GetInventory().GetAmmoItem(((Humanoid)player).GetCurrentWeapon().m_shared.m_ammoType, (string)null);
		}

		private static int CalculateArrows(ItemData item)
		{
			return item.m_gridPos.y * ((Humanoid)Player.m_localPlayer).GetInventory().GetWidth() + item.m_gridPos.x;
		}
	}
	public static class CustomCrosshairs
	{
		public static Sprite _circularGunTarget;

		public static Sprite _simpleCrosshair;

		public static Sprite _dartBoardTarget;

		public static Sprite _deviceFocusPoint;

		public static Sprite _eyeWideOpen;

		public static Sprite _fightingWeaponTarget;

		public static Sprite _pistolTarget;

		public static Sprite _roundTargetSymbol;

		public static Sprite _sharpDecoratedTarget;

		public static Sprite _shootTargetPoint;

		public static Sprite _targetDesign;

		public static Sprite _triangularCrosshair;

		public static void Init()
		{
			_circularGunTarget = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/circular-gun-target.png");
			_simpleCrosshair = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/crosshair.png");
			_dartBoardTarget = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/dart-board-target.png");
			_deviceFocusPoint = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/device-focus-point.png");
			_eyeWideOpen = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/eye-wide-open.png");
			_fightingWeaponTarget = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/fighting-weapon-target.png");
			_pistolTarget = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/pistol-target.png");
			_roundTargetSymbol = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/round-target-symbol.png");
			_sharpDecoratedTarget = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/sharp-decorated-target.png");
			_shootTargetPoint = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/shoot-target-point.png");
			_targetDesign = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/target-design.png");
			_triangularCrosshair = SetupPrefabs._bowBundle.LoadAsset<Sprite>("Assets/CustomAsset/Sprite/triangular-cross-hair.png");
		}
	}
	public static class SetupPrefabs
	{
		public static AssetBundle _bowBundle;

		public static GameObject _fxBowCrit;

		public static void Init()
		{
			_bowBundle = PrefabManager.RegisterAssetBundle("bowpluginbundle");
			Arrows();
			Bows();
			Effects();
		}

		private static void Arrows()
		{
			Item item = new Item(_bowBundle, "BBP_Bolt_Bronze");
			item.Crafting.Add(CraftingTable.Forge, 1);
			item.CraftAmount = 20;
			item.RequiredItems.Add("Bronze", 5);
			item.RequiredItems.Add("Resin", 8);
			item.RequiredItems.Add("RoundLog", 10);
			item.RequiredItems.Add("Feathers", 5);
			item.Configurable = Configurability.Full;
			Item item2 = new Item(_bowBundle, "BBP_Bolt_Flint");
			item2.Crafting.Add(CraftingTable.Workbench, 1);
			item2.CraftAmount = 20;
			item2.RequiredItems.Add("Flint", 3);
			item2.RequiredItems.Add("Stone", 5);
			item2.RequiredItems.Add("Wood", 8);
			item2.Configurable = Configurability.Full;
			Item item3 = new Item(_bowBundle, "BBP_Bolt_Wood");
			item3.Crafting.Add(CraftingTable.Inventory, 1);
			item3.CraftAmount = 20;
			item3.RequiredItems.Add("Wood", 10);
			item3.Configurable = Configurability.Full;
			Item item4 = new Item(_bowBundle, "BBP_ExplodingArrow_Fire");
			item4.Crafting.Add(CraftingTable.Forge, 1);
			item4.CraftAmount = 20;
			item4.RequiredItems.Add("BlackMetal", 20);
			item4.RequiredItems.Add("YggdrasilWood", 20);
			item4.RequiredItems.Add("Feathers", 20);
			item4.RequiredItems.Add("Resin", 20);
			item4.Configurable = Configurability.Full;
			Item item5 = new Item(_bowBundle, "BBP_ExplodingArrow_Frost");
			item5.Crafting.Add(CraftingTable.Forge, 1);
			item5.CraftAmount = 20;
			item5.RequiredItems.Add("BlackMetal", 20);
			item5.RequiredItems.Add("YggdrasilWood", 20);
			item5.RequiredItems.Add("Feathers", 20);
			item5.RequiredItems.Add("FreezeGland", 20);
			item5.Configurable = Configurability.Full;
			Item item6 = new Item(_bowBundle, "BBP_ExplodingArrow_Poison");
			item6.Crafting.Add(CraftingTable.Forge, 1);
			item6.CraftAmount = 20;
			item6.RequiredItems.Add("BlackMetal", 20);
			item6.RequiredItems.Add("YggdrasilWood", 20);
			item6.RequiredItems.Add("Feathers", 20);
			item6.RequiredItems.Add("Guck", 20);
			item6.Configurable = Configurability.Full;
			Item item7 = new Item(_bowBundle, "BBP_ExplodingBolt_Fire");
			item7.Crafting.Add(CraftingTable.Forge, 1);
			item7.CraftAmount = 20;
			item7.RequiredItems.Add("BlackMetal", 20);
			item7.RequiredItems.Add("YggdrasilWood", 20);
			item7.RequiredItems.Add("Feathers", 20);
			item7.RequiredItems.Add("Resin", 20);
			item7.Configurable = Configurability.Full;
			Item item8 = new Item(_bowBundle, "BBP_ExplodingBolt_Frost");
			item8.Crafting.Add(CraftingTable.Forge, 1);
			item8.CraftAmount = 20;
			item8.RequiredItems.Add("BlackMetal", 20);
			item8.RequiredItems.Add("YggdrasilWood", 20);
			item8.RequiredItems.Add("Feathers", 20);
			item8.RequiredItems.Add("FreezeGland", 20);
			item8.Configurable = Configurability.Full;
			Item item9 = new Item(_bowBundle, "BBP_ExplodingBolt_Poison");
			item9.Crafting.Add(CraftingTable.Forge, 1);
			item9.CraftAmount = 20;
			item9.RequiredItems.Add("BlackMetal", 20);
			item9.RequiredItems.Add("YggdrasilWood", 20);
			item9.RequiredItems.Add("Feathers", 20);
			item9.RequiredItems.Add("Guck", 20);
			item9.Configurable = Configurability.Full;
		}

		private static void Bows()
		{
			Item item = new Item(_bowBundle, "BBP_Crossbow_BlackMetal");
			item.Crafting.Add(CraftingTable.Forge, 1);
			item.RequiredItems.Add("BBP_Crossbow_Silver", 1);
			item.RequiredItems.Add("BlackMetal", 64);
			item.RequiredItems.Add("FineWood", 44);
			item.RequiredItems.Add("Chain", 6);
			item.RequiredUpgradeItems.Add("BlackMetal", 32);
			item.RequiredUpgradeItems.Add("FineWood", 22);
			item.RequiredUpgradeItems.Add("Chain", 3);
			item.Configurable = Configurability.Full;
			Item item2 = new Item(_bowBundle, "BBP_Crossbow_Bronze");
			item2.Crafting.Add(CraftingTable.Forge, 1);
			item2.RequiredItems.Add("BBP_Crossbow_Flint", 1);
			item2.RequiredItems.Add("Bronze", 12);
			item2.RequiredItems.Add("RoundLog", 4);
			item2.RequiredItems.Add("Tin", 8);
			item2.RequiredUpgradeItems.Add("Bronze", 6);
			item2.RequiredUpgradeItems.Add("RoundLog", 2);
			item2.RequiredUpgradeItems.Add("Tin", 4);
			item2.Configurable = Configurability.Full;
			Item item3 = new Item(_bowBundle, "BBP_Crossbow_Flint");
			item3.Crafting.Add(CraftingTable.Workbench, 1);
			item3.RequiredItems.Add("Flint", 8);
			item3.RequiredItems.Add("RoundLog", 2);
			item3.RequiredItems.Add("Wood", 10);
			item3.RequiredItems.Add("BoneFragments", 4);
			item3.RequiredUpgradeItems.Add("RoundLog", 1);
			item3.RequiredUpgradeItems.Add("Wood", 5);
			item3.RequiredUpgradeItems.Add("BoneFragments", 2);
			item3.Configurable = Configurability.Full;
			Item item4 = new Item(_bowBundle, "BBP_Crossbow_Iron");
			item4.Crafting.Add(CraftingTable.Forge, 1);
			item4.RequiredItems.Add("BBP_Crossbow_Bronze", 1);
			item4.RequiredItems.Add("Iron", 28);
			item4.RequiredItems.Add("ElderBark", 12);
			item4.RequiredItems.Add("FineWood", 8);
			item4.RequiredUpgradeItems.Add("Iron", 14);
			item4.RequiredUpgradeItems.Add("ElderBark", 6);
			item4.RequiredUpgradeItems.Add("FineWood", 4);
			item4.Configurable = Configurability.Full;
			Item item5 = new Item(_bowBundle, "BBP_Crossbow_Silver");
			item5.Crafting.Add(CraftingTable.Forge, 1);
			item5.RequiredItems.Add("BBP_Crossbow_Iron", 1);
			item5.RequiredItems.Add("Silver", 40);
			item5.RequiredItems.Add("FineWood", 32);
			item5.RequiredItems.Add("WolfFang", 10);
			item5.RequiredUpgradeItems.Add("Silver", 20);
			item5.RequiredUpgradeItems.Add("FineWood", 16);
			item5.RequiredUpgradeItems.Add("WolfFang", 5);
			item5.Configurable = Configurability.Full;
			Item item6 = new Item(_bowBundle, "BBP_BoneBow");
			item6.Crafting.Add(CraftingTable.Workbench, 1);
			item6.RequiredItems.Add("BoneFragments", 8);
			item6.RequiredItems.Add("DeerHide", 10);
			item6.RequiredItems.Add("LeatherScraps", 10);
			item6.RequiredItems.Add("Wood", 12);
			item6.RequiredUpgradeItems.Add("DeerHide", 5);
			item6.RequiredUpgradeItems.Add("LeatherScraps", 5);
			item6.RequiredUpgradeItems.Add("Wood", 6);
			item6.Configurable = Configurability.Full;
			Item item7 = new Item(_bowBundle, "BBP_ElvenBow");
			item7.Crafting.Add(CraftingTable.Forge, 1);
			item7.RequiredItems.Add("Thunderstone", 10);
			item7.RequiredItems.Add("Eitr", 52);
			item7.RequiredItems.Add("Iron", 44);
			item7.RequiredItems.Add("LinenThread", 28);
			item7.RequiredUpgradeItems.Add("Eitr", 26);
			item7.RequiredUpgradeItems.Add("Iron", 22);
			item7.RequiredUpgradeItems.Add("LinenThread", 14);
			item7.Configurable = Configurability.Full;
			Item item8 = new Item(_bowBundle, "BBP_SeekerBow");
			item8.Crafting.Add(CraftingTable.Forge, 1);
			item8.RequiredItems.Add("TrophySeeker", 2);
			item8.RequiredItems.Add("BlackMetal", 32);
			item8.RequiredItems.Add("Mandible", 22);
			item8.RequiredItems.Add("Eitr", 32);
			item8.RequiredUpgradeItems.Add("BlackMetal", 16);
			item8.RequiredUpgradeItems.Add("Mandible", 11);
			item8.RequiredUpgradeItems.Add("Eitr", 16);
			item8.Configurable = Configurability.Full;
			Item item9 = new Item(_bowBundle, "BBP_BlackMetalBow");
			item9.Crafting.Add(CraftingTable.Forge, 1);
			item9.RequiredItems.Add("BlackMetal", 56);
			item9.RequiredItems.Add("Iron", 16);
			item9.RequiredItems.Add("LinenThread", 24);
			item9.RequiredItems.Add("FineWood", 12);
			item9.RequiredUpgradeItems.Add("BlackMetal", 23);
			item9.RequiredUpgradeItems.Add("LinenThread", 12);
			item9.RequiredUpgradeItems.Add("FineWood", 6);
			item9.Configurable = Configurability.Full;
			Item item10 = new Item(_bowBundle, "BBP_SilverBow");
			item10.Crafting.Add(CraftingTable.Forge, 1);
			item10.RequiredItems.Add("Silver", 32);
			item10.RequiredItems.Add("ElderBark", 26);
			item10.RequiredItems.Add("Iron", 24);
			item10.RequiredItems.Add("LeatherScraps", 12);
			item10.RequiredUpgradeItems.Add("Silver", 16);
			item10.RequiredUpgradeItems.Add("ElderBark", 13);
			item10.RequiredUpgradeItems.Add("LeatherScraps", 6);
			item10.Configurable = Configurability.Full;
		}

		private static void Effects()
		{
			_fxBowCrit = PrefabManager.RegisterPrefab(_bowBundle, "bbp_vfx_bowplugin_crit");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_arbalest_projectile_bronze");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_arbalest_projectile_flint");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_arbalest_projectile_wood");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_exploding_projectile_fire");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_exploding_projectile_frost");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_exploding_projectile_poison");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_explodingbolt_fire_projectile");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_explodingbolt_frost_projectile");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_explodingbolt_poison_projectile");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_fx_block_camshake");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_fx_exploding_arrow_fire_explosion");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_fx_exploding_arrow_frost_explosion");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_fx_exploding_arrow_poison_explosion");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_fx_swing_camshake");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_sfx_arbalest_fire");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_sfx_arrow_hit");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_sfx_bow_draw");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_sfx_bow_fire");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_sfx_metal_blocked");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_sfx_wood_blocked");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_vfx_arbalest_fire");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_vfx_arrowhit");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_vfx_blocked");
			PrefabManager.RegisterPrefab(_bowBundle, "bbp_vfx_bow_fire");
		}
	}
	public class SE_Critical : StatusEffect
	{
		public float m_critChance;

		public float m_critBonus;

		public void Awake()
		{
			base.m_name = "BowMastery";
			((Object)this).name = base.m_name;
			base.m_tooltip = $"<color=orange>{Mathf.FloorToInt(m_critChance)}%</color> chance to get a <color=red>Critical Hit</color> using <color=orange>Bows</color> and <color=orange>Crossbow</color> Weapons." + $"\nIncrease damage by <color=orange>{Mathf.FloorToInt(m_critBonus)}x</color>";
		}

		public void SetCritChance(float bonus)
		{
			m_critChance = bonus;
			base.m_tooltip = $"<color=orange>{Mathf.FloorToInt(m_critChance)}%</color> chance to get a <color=red>Critical Hit</color> using <color=orange>Bows</color> and <color=orange>Crossbow</color> Weapons." + $"\nIncrease damage by <color=orange>{Mathf.FloorToInt(m_critBonus)}x</color>";
		}

		public float GetCritChance()
		{
			return m_critChance;
		}

		public void SetCritBonus(float bonus)
		{
			m_critBonus = bonus;
			base.m_tooltip = $"<color=orange>{Mathf.FloorToInt(m_critChance)}%</color> chance to get a <color=red>Critical Hit</color> using <color=orange>Bows</color> and <color=orange>Crossbow</color> Weapons." + $"\nIncrease damage by <color=orange>{Mathf.FloorToInt(m_critBonus)}x</color>";
		}

		public float GetCritBonus()
		{
			return m_critBonus;
		}
	}
	public static class SwitchProjectile
	{
		public static void Init(ItemDrop component)
		{
			if (component.m_itemData.m_shared.m_name.Contains("arrow_flint"))
			{
				component.m_itemData.m_shared.m_attack.m_attackProjectile = null;
				component.m_itemData.m_shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab("bow_projectile_flint");
			}
			if (component.m_itemData.m_shared.m_name.Contains("arrow_bronze"))
			{
				component.m_itemData.m_shared.m_attack.m_attackProjectile = null;
				component.m_itemData.m_shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab("bow_projectile_bronze");
			}
			if (component.m_itemData.m_shared.m_name.Contains("arrow_iron"))
			{
				component.m_itemData.m_shared.m_attack.m_attackProjectile = null;
				component.m_itemData.m_shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab("bow_projectile_iron");
			}
			if (component.m_itemData.m_shared.m_name.Contains("arrow_obsidian"))
			{
				component.m_itemData.m_shared.m_attack.m_attackProjectile = null;
				component.m_itemData.m_shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab("bow_projectile_obsidian");
			}
			if (component.m_itemData.m_shared.m_name.Contains("arrow_silver"))
			{
				component.m_itemData.m_shared.m_attack.m_attackProjectile = null;
				component.m_itemData.m_shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab("bow_projectile_silver");
			}
			if (component.m_itemData.m_shared.m_name.Contains("bolt_blackmetal"))
			{
				component.m_itemData.m_shared.m_attack.m_attackProjectile = null;
				component.m_itemData.m_shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab("arbalest_projectile_blackmetal");
			}
			if (component.m_itemData.m_shared.m_name.Contains("bolt_iron"))
			{
				component.m_itemData.m_shared.m_attack.m_attackProjectile = null;
				component.m_itemData.m_shared.m_attack.m_attackProjectile = ZNetScene.instance.GetPrefab("arbalest_projectile_iron");
			}
		}
	}
	public enum ZoomLevel
	{
		FixedZoom,
		ZoomedIn,
		ZoomedOut
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<c17c4ba4-b280-4365-a277-59151870b328>Embedded]
	internal sealed class <c17c4ba4-b280-4365-a277-59151870b328>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[<c17c4ba4-b280-4365-a277-59151870b328>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class <ddb3a782-1628-468e-887f-5913277b8ee1>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <ddb3a782-1628-468e-887f-5913277b8ee1>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <ddb3a782-1628-468e-887f-5913277b8ee1>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[<c17c4ba4-b280-4365-a277-59151870b328>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class <80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[<c17c4ba4-b280-4365-a277-59151870b328>Embedded]
	[CompilerGenerated]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class <6bd8f1c9-af11-4097-8dcb-304357c83596>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <6bd8f1c9-af11-4097-8dcb-304357c83596>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ItemManager
{
	[PublicAPI]
	internal enum CraftingTable
	{
		Disabled,
		Inventory,
		[InternalName("piece_workbench")]
		Workbench,
		[InternalName("piece_cauldron")]
		Cauldron,
		[InternalName("forge")]
		Forge,
		[InternalName("piece_artisanstation")]
		ArtisanTable,
		[InternalName("piece_stonecutter")]
		StoneCutter,
		[InternalName("piece_magetable")]
		MageTable,
		[InternalName("blackforge")]
		BlackForge,
		Custom
	}
	[PublicAPI]
	internal enum ConversionPiece
	{
		Disabled,
		[InternalName("smelter")]
		Smelter,
		[InternalName("charcoal_kiln")]
		CharcoalKiln,
		[InternalName("blastfurnace")]
		BlastFurnace,
		[InternalName("windmill")]
		Windmill,
		[InternalName("piece_spinningwheel")]
		SpinningWheel,
		[InternalName("eitrrefinery")]
		EitrRefinery,
		Custom
	}
	[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(1)]
	[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
	internal class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
	[PublicAPI]
	[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(1)]
	internal class RequiredResourceList
	{
		public readonly List<Requirement> Requirements = new List<Requirement>();

		public bool Free;

		public void Add(string itemName, int amount, int quality = 0)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amount = amount,
				quality = quality
			});
		}

		public void Add(string itemName, ConfigEntry<int> amountConfig, int quality = 0)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amountConfig = amountConfig,
				quality = quality
			});
		}
	}
	[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
	[PublicAPI]
	[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(1)]
	internal class CraftingStationList
	{
		public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>();

		public void Add(CraftingTable table, int level)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = table,
				level = level
			});
		}

		public void Add(string customTable, int level)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = CraftingTable.Custom,
				level = level,
				custom = customTable
			});
		}
	}
	[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(1)]
	[PublicAPI]
	[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
	internal class ItemRecipe
	{
		public readonly RequiredResourceList RequiredItems = new RequiredResourceList();

		public readonly RequiredResourceList RequiredUpgradeItems = new RequiredResourceList();

		public readonly CraftingStationList Crafting = new CraftingStationList();

		public int CraftAmount = 1;

		public bool RequireOnlyOneIngredient;

		public float QualityResultAmountMultiplier = 1f;

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(2)]
		public ConfigEntryBase RecipeIsActive;
	}
	[PublicAPI]
	internal class Trade
	{
		public Trader Trader;

		public uint Price;

		public uint Stack = 1u;

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(2)]
		public string RequiredGlobalKey;
	}
	[PublicAPI]
	[Flags]
	internal enum Trader
	{
		None = 0,
		Haldor = 1,
		Hildir = 2
	}
	internal struct Requirement
	{
		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(1)]
		public string itemName;

		public int amount;

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(2)]
		public ConfigEntry<int> amountConfig;

		[Description("Set to a non-zero value to apply the requirement only for a specific quality")]
		public int quality;
	}
	internal struct CraftingStationConfig
	{
		public CraftingTable Table;

		public int level;

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(2)]
		public string custom;
	}
	[Flags]
	internal enum Configurability
	{
		Disabled = 0,
		Recipe = 1,
		Stats = 2,
		Drop = 4,
		Trader = 8,
		Full = 0xF
	}
	[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
	[PublicAPI]
	[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(1)]
	internal class DropTargets
	{
		public readonly List<DropTarget> Drops = new List<DropTarget>();

		public void Add(string creatureName, float chance, int min = 1, int? max = null, bool levelMultiplier = true)
		{
			Drops.Add(new DropTarget
			{
				creature = creatureName,
				chance = chance,
				min = min,
				max = max.GetValueOrDefault(min),
				levelMultiplier = levelMultiplier
			});
		}
	}
	internal struct DropTarget
	{
		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(1)]
		public string creature;

		public int min;

		public int max;

		public float chance;

		public bool levelMultiplier;
	}
	internal enum Toggle
	{
		On = 1,
		Off = 0
	}
	[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(1)]
	[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
	[PublicAPI]
	internal class Item
	{
		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
		private class ItemConfig
		{
			[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(new byte[] { 2, 1 })]
			public ConfigEntry<string> craft;

			[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(new byte[] { 2, 1 })]
			public ConfigEntry<string> upgrade;

			public ConfigEntry<CraftingTable> table;

			public ConfigEntry<int> tableLevel;

			public ConfigEntry<string> customTable;

			[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(2)]
			public ConfigEntry<int> maximumTableLevel;

			public ConfigEntry<Toggle> requireOneIngredient;

			public ConfigEntry<float> qualityResultAmountMultiplier;
		}

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
		private class TraderConfig
		{
			public ConfigEntry<Trader> trader;

			public ConfigEntry<uint> price;

			public ConfigEntry<uint> stack;

			public ConfigEntry<string> requiredGlobalKey;
		}

		[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)]
		private class RequirementQuality
		{
			public int quality;
		}

		[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(2)]
		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			public string Category;

			[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(new byte[] { 2, 1 })]
			[UsedImplicitly]
			public Action<ConfigEntryBase> CustomDrawer;

			public Func<bool> browsability;
		}

		[PublicAPI]
		[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)]
		public enum DamageModifier
		{
			Normal,
			Resistant,
			Weak,
			Immune,
			Ignore,
			VeryResistant,
			VeryWeak,
			None
		}

		[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)]
		private delegate void setDmgFunc(ref DamageTypes dmg, float value);

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
		private class SerializedRequirements
		{
			public readonly List<Requirement> Reqs;

			public SerializedRequirements(List<Requirement> reqs)
			{
				Reqs = reqs;
			}

			public SerializedRequirements(string reqs)
				: this(reqs.Split(new char[1] { ',' }).Select([<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)] (string r) =>
				{
					string[] array = r.Split(new char[1] { ':' });
					Requirement result = default(Requirement);
					result.itemName = array[0];
					result.amount = ((array.Length <= 1 || !int.TryParse(array[1], out var result2)) ? 1 : result2);
					result.quality = ((array.Length > 2 && int.TryParse(array[2], out var result3)) ? result3 : 0);
					return result;
				}).ToList())
			{
			}

			public override string ToString()
			{
				return string.Join(",", Reqs.Select([<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)] (Requirement r) => $"{r.itemName}:{r.amount}" + ((r.quality > 0) ? $":{r.quality}" : "")));
			}

			[return: <ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(2)]
			public static ItemDrop fetchByName(ObjectDB objectDB, string name)
			{
				GameObject itemPrefab = objectDB.GetItemPrefab(name);
				ItemDrop obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)obj == (Object)null)
				{
					Debug.LogWarning((object)("The required item '" + name + "' does not exist."));
				}
				return obj;
			}

			public static Requirement[] toPieceReqs(ObjectDB objectDB, SerializedRequirements craft, SerializedRequirements upgrade)
			{
				//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_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				//IL_017d: 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_018c: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Expected O, but got Unknown
				//IL_0194: Expected O, but got Unknown
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Expected O, but got Unknown
				Dictionary<string, Requirement> dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func<Requirement, string>)([<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)] (Requirement r) => r.itemName), (Func<Requirement, Requirement>)([<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)] (Requirement r) =>
				{
					//IL_000d: 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_002f: 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_003e: Expected O, but got Unknown
					ItemDrop val6 = ResItem(r);
					return (val6 != null) ? new Requirement
					{
						m_amount = (r.amountConfig?.Value ?? r.amount),
						m_resItem = val6,
						m_amountPerLevel = 0
					} : ((Requirement)null);
				}));
				List<Requirement> list = dictionary.Values.Where([<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)] (Requirement v) => v != null).ToList();
				foreach (Requirement item in upgrade.Reqs.Where((Requirement r) => r.itemName != ""))
				{
					if (item.quality > 0)
					{
						ItemDrop val = ResItem(item);
						if (val != null)
						{
							Requirement val2 = new Requirement
							{
								m_resItem = val,
								m_amountPerLevel = (item.amountConfig?.Value ?? item.amount),
								m_amount = 0
							};
							list.Add(val2);
							requirementQuality.Add(val2, new RequirementQuality
							{
								quality = item.quality
							});
						}
						continue;
					}
					if (!dictionary.TryGetValue(item.itemName, out var value) || value == null)
					{
						ItemDrop val3 = ResItem(item);
						if (val3 != null)
						{
							string itemName = item.itemName;
							Requirement val4 = new Requirement
							{
								m_resItem = val3,
								m_amount = 0
							};
							Requirement val5 = val4;
							dictionary[itemName] = val4;
							value = val5;
							list.Add(value);
						}
					}
					if (value != null)
					{
						value.m_amountPerLevel = item.amountConfig?.Value ?? item.amount;
					}
				}
				return list.ToArray();
				[<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(2)]
				ItemDrop ResItem(Requirement r)
				{
					return fetchByName(objectDB, r.itemName);
				}
			}
		}

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(0)]
		private class SerializedDrop
		{
			public readonly List<DropTarget> Drops;

			public SerializedDrop(List<DropTarget> drops)
			{
				Drops = drops;
			}

			public SerializedDrop(string drops)
			{
				Drops = ((drops == "") ? ((IEnumerable<string>)Array.Empty<string>()) : ((IEnumerable<string>)drops.Split(new char[1] { ',' }))).Select([<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)] (string r) =>
				{
					string[] array = r.Split(new char[1] { ':' });
					if (array.Length <= 2 || !int.TryParse(array[2], out var result))
					{
						result = 1;
					}
					if (array.Length <= 3 || !int.TryParse(array[3], out var result2))
					{
						result2 = result;
					}
					bool levelMultiplier = array.Length <= 4 || array[4] != "0";
					DropTarget result3 = default(DropTarget);
					result3.creature = array[0];
					result3.chance = ((array.Length > 1 && float.TryParse(array[1], out var result4)) ? result4 : 1f);
					result3.min = result;
					result3.max = result2;
					result3.levelMultiplier = levelMultiplier;
					return result3;
				}).ToList();
			}

			public override string ToString()
			{
				return string.Join(",", Drops.Select([<80d9078a-5536-4d58-b337-7f317b1e9c1d>NullableContext(0)] (DropTarget r) => $"{r.creature}:{r.chance.ToString(CultureInfo.InvariantCulture)}:{r.min}:" + ((r.min == r.max) ? "" : $"{r.max}") + (r.levelMultiplier ? "" : ":0")));
			}

			[return: <ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(2)]
			private static Character fetchByName(ZNetScene netScene, string name)
			{
				GameObject prefab = netScene.GetPrefab(name);
				Character obj = ((prefab != null) ? prefab.GetComponent<Character>() : null);
				if ((Object)(object)obj == (Object)null)
				{
					Debug.LogWarning((object)("The drop target character '" + name + "' does not exist."));
				}
				return obj;
			}

			public Dictionary<Character, Drop> toCharacterDrops(ZNetScene netScene, GameObject item)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: 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_006f: Expected O, but got Unknown
				Dictionary<Character, Drop> dictionary = new Dictionary<Character, Drop>();
				foreach (DropTarget drop in Drops)
				{
					Character val = fetchByName(netScene, drop.creature);
					if (val != null)
					{
						dictionary[val] = new Drop
						{
							m_prefab = item,
							m_amountMin = drop.min,
							m_amountMax = drop.max,
							m_chance = drop.chance,
							m_levelMultiplier = drop.levelMultiplier
						};
					}
				}
				return dictionary;
			}
		}

		private static readonly List<Item> registeredItems = new List<Item>();

		private static readonly Dictionary<ItemDrop, Item> itemDropMap = new Dictionary<ItemDrop, Item>();

		private static Dictionary<Item, Dictionary<string, List<Recipe>>> activeRecipes = new Dictionary<Item, Dictionary<string, List<Recipe>>>();

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(new byte[] { 1, 1, 2 })]
		private static Dictionary<Recipe, ConfigEntryBase> hiddenCraftRecipes = new Dictionary<Recipe, ConfigEntryBase>();

		[<ddb3a782-1628-468e-887f-5913277b8ee1>Nullable(new byte[] { 1, 1, 2 })]
		private static Dictionary<Recipe, ConfigEntryBase> hiddenUpgradeRecipes = new Dictionary<Recipe, ConfigEntryBase>();

		private static Dictionary<Item, Dictionary<string, ItemConfig>> itemCraftConfigs = new Dictionary<Item, Dictionary<string, ItemConfig>>();

		private static Dictionary<Item, ConfigEntry<string>> itemDropConfigs = new Dictionary<Item, ConfigEntry<string>>();

		private Dictionary<CharacterDrop, Drop> characterDrops = new Dictionary<CharacterDrop, Drop>();

		private readonly Dictionary<ConfigEntryBase, Action> statsConfigs = new Dictionary<ConfigEntryBase, Action>();

		private static readonly ConditionalWeakTable<Requirement, RequirementQuality> requirementQuality = new ConditionalWeakTable<Requirement, RequirementQuality>();

		public static Configurability DefaultConfigurability = Configurability.Full;

		public Configurability? Configurable;

		p