Decompiled source of BetterArchery v1.9.8

BetterArchery/plugins/BetterArchery.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Auga;
using BepInEx;
using BepInEx.Configuration;
using Common;
using HarmonyLib;
using JetBrains.Annotations;
using LitJson;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: Guid("04f6ef99-721d-41d7-86e2-59ced874c902")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyProduct("BetterArchery")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("BetterArchery")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
namespace Common
{
	[Serializable]
	public class RecipeRequirementConfig
	{
		public string item = "";

		public int amount = 1;
	}
	[Serializable]
	public class RecipeConfig
	{
		public string name = "";

		public string item = "";

		public int amount = 1;

		public string craftingStation = "";

		public int minStationLevel = 1;

		public bool enabled = true;

		public string repairStation = "";

		public List<RecipeRequirementConfig> resources = new List<RecipeRequirementConfig>();
	}
	[Serializable]
	public class RecipesConfig
	{
		public List<RecipeConfig> recipes = new List<RecipeConfig>();
	}
	internal class CustomSlotItem : MonoBehaviour
	{
		public string m_slotName;
	}
	public static class CustomSlotCreator
	{
		public static readonly Dictionary<Humanoid, Dictionary<string, ItemData>> customSlotItemData = new Dictionary<Humanoid, Dictionary<string, ItemData>>();

		public static string GetCustomSlotName(ItemData item)
		{
			return item.m_dropPrefab.GetComponent<CustomSlotItem>().m_slotName;
		}

		public static bool IsCustomSlotItem(ItemData item)
		{
			return item != null && Object.op_Implicit((Object)(object)item.m_dropPrefab) && Object.op_Implicit((Object)(object)item.m_dropPrefab.GetComponent<CustomSlotItem>());
		}

		public static ItemData GetPrefabItemData(Humanoid humanoid, string slotName)
		{
			if (!DoesSlotExist(humanoid, slotName))
			{
				return null;
			}
			return customSlotItemData[humanoid][slotName].m_dropPrefab.GetComponent<ItemDrop>().m_itemData;
		}

		public static ItemData GetSlotItem(Humanoid humanoid, string slotName)
		{
			if (DoesSlotExist(humanoid, slotName))
			{
				return customSlotItemData[humanoid][slotName];
			}
			return null;
		}

		public static void SetSlotItem(Humanoid humanoid, string slotName, ItemData item)
		{
			customSlotItemData[humanoid][slotName] = item;
		}

		public static bool DoesSlotExist(Humanoid humanoid, string slotName)
		{
			return customSlotItemData[humanoid] != null && customSlotItemData[humanoid].ContainsKey(slotName);
		}

		public static bool IsSlotOccupied(Humanoid humanoid, string slotName)
		{
			return customSlotItemData[humanoid] != null && customSlotItemData[humanoid].ContainsKey(slotName) && customSlotItemData[humanoid][slotName] != null;
		}

		public static void ApplyCustomSlotItem(GameObject prefab, string slotName)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)prefab))
			{
				if (!Object.op_Implicit((Object)(object)prefab.GetComponent<CustomSlotItem>()))
				{
					prefab.AddComponent<CustomSlotItem>();
				}
				prefab.GetComponent<CustomSlotItem>().m_slotName = slotName;
				prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_itemType = (ItemType)0;
				Debug.Log((object)("[CustomSlotCreator] Created " + slotName + " slot for " + ((Object)prefab).name + "."));
			}
		}
	}
	public static class PrefabCreator
	{
		public static Dictionary<string, CraftingStation> CraftingStations;

		public static T RequireComponent<T>(GameObject go) where T : Component
		{
			T val = go.GetComponent<T>();
			if ((Object)(object)val == (Object)null)
			{
				val = go.AddComponent<T>();
			}
			return val;
		}

		public static void Reset()
		{
			CraftingStations = null;
		}

		private static void InitCraftingStations()
		{
			if (CraftingStations != null)
			{
				return;
			}
			CraftingStations = new Dictionary<string, CraftingStation>();
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if ((Object)(object)recipe.m_craftingStation != (Object)null && !CraftingStations.ContainsKey(((Object)recipe.m_craftingStation).name))
				{
					CraftingStations.Add(((Object)recipe.m_craftingStation).name, recipe.m_craftingStation);
				}
			}
		}

		public static Recipe CreateRecipe(string name, string itemId, RecipeConfig recipeConfig)
		{
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Expected O, but got Unknown
			InitCraftingStations();
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemId);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				Debug.LogWarning((object)("[PrefabCreator] Could not find item prefab (" + itemId + ")"));
				return null;
			}
			Recipe val = ScriptableObject.CreateInstance<Recipe>();
			((Object)val).name = name;
			val.m_amount = recipeConfig.amount;
			val.m_minStationLevel = recipeConfig.minStationLevel;
			val.m_item = itemPrefab.GetComponent<ItemDrop>();
			val.m_enabled = recipeConfig.enabled;
			if (!string.IsNullOrEmpty(recipeConfig.craftingStation))
			{
				if (!CraftingStations.ContainsKey(recipeConfig.craftingStation))
				{
					Debug.LogWarning((object)("[PrefabCreator] Could not find crafting station (" + itemId + "): " + recipeConfig.craftingStation));
					string text = string.Join(", ", CraftingStations.Keys);
					Debug.Log((object)("[PrefabCreator] Available Stations: " + text));
				}
				else
				{
					val.m_craftingStation = CraftingStations[recipeConfig.craftingStation];
				}
			}
			if (!string.IsNullOrEmpty(recipeConfig.repairStation))
			{
				if (!CraftingStations.ContainsKey(recipeConfig.repairStation))
				{
					Debug.LogWarning((object)("[PrefabCreator] Could not find repair station (" + itemId + "): " + recipeConfig.repairStation));
					string text2 = string.Join(", ", CraftingStations.Keys);
					Debug.Log((object)("[PrefabCreator] Available Stations: " + text2));
				}
				else
				{
					val.m_repairStation = CraftingStations[recipeConfig.repairStation];
				}
			}
			List<Requirement> list = new List<Requirement>();
			foreach (RecipeRequirementConfig resource in recipeConfig.resources)
			{
				GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(resource.item);
				if ((Object)(object)itemPrefab2 == (Object)null)
				{
					Debug.LogError((object)("[PrefabCreator] Could not find requirement item (" + itemId + "): " + resource.item));
					continue;
				}
				list.Add(new Requirement
				{
					m_amount = resource.amount,
					m_resItem = itemPrefab2.GetComponent<ItemDrop>()
				});
			}
			val.m_resources = list.ToArray();
			return val;
		}

		public static Recipe AddNewRecipe(string name, string itemId, RecipeConfig recipeConfig)
		{
			Recipe val = CreateRecipe(name, itemId, recipeConfig);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)("[PrefabCreator] Failed to create recipe (" + name + ")"));
				return null;
			}
			return AddNewRecipe(val);
		}

		public static Recipe AddNewRecipe(Recipe recipe)
		{
			int num = ObjectDB.instance.m_recipes.RemoveAll((Recipe x) => ((Object)x).name == ((Object)recipe).name);
			if (num > 0)
			{
				Debug.Log((object)$"[PrefabCreator] Removed recipe ({((Object)recipe).name}): {num}");
			}
			ObjectDB.instance.m_recipes.Add(recipe);
			Debug.Log((object)("[PrefabCreator] Added recipe: " + ((Object)recipe).name));
			return recipe;
		}
	}
	public static class Utils
	{
		public static void PrintObject(object o)
		{
			if (o == null)
			{
				Debug.Log((object)"null");
			}
			else
			{
				Debug.Log((object)(o?.ToString() + ":\n" + GetObjectString(o, "  ")));
			}
		}

		public static string GetObjectString(object obj, string indent)
		{
			string text = "";
			Type type = obj.GetType();
			IEnumerable<FieldInfo> enumerable = from f in type.GetFields()
				where f.IsPublic
				select f;
			foreach (FieldInfo item in enumerable)
			{
				object value = item.GetValue(obj);
				string text2 = ((value == null) ? "null" : value.ToString());
				text = text + "\n" + indent + item.Name + ": " + text2;
			}
			return text;
		}

		public static Sprite LoadSpriteFromFile(string spritePath)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_004e: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			spritePath = Path.Combine(Paths.PluginPath, spritePath);
			if (File.Exists(spritePath))
			{
				byte[] array = File.ReadAllBytes(spritePath);
				Texture2D val = new Texture2D(20, 20);
				if (ImageConversion.LoadImage(val, array))
				{
					return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), default(Vector2), 100f);
				}
			}
			return null;
		}

		public static Sprite LoadSpriteFromFile(string modFolder, string iconName)
		{
			string spritePath = Path.Combine(modFolder, iconName);
			return LoadSpriteFromFile(spritePath);
		}

		public static bool IsServer()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			return ZNet.instance.IsServer() || ZNet.instance.IsDedicated() || (int)SystemInfo.graphicsDeviceType == 4;
		}
	}
}
namespace BetterArchery
{
	public class Arrow
	{
		public string Name { get; set; }

		public float SpawnChance { get; set; }

		public string SpawnArrow { get; set; }
	}
	[BepInPlugin("ishid4.mods.betterarchery", "Better Archery", "1.9.8")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BetterArchery : BaseUnityPlugin
	{
		public enum ZoomState
		{
			Fixed,
			ZoomingIn,
			ZoomingOut
		}

		public const int QuiverUseSlotCount = 3;

		public static bool ZoomSfx;

		public static Dictionary<string, Dictionary<string, AudioClip>> CustomSfxDict = new Dictionary<string, Dictionary<string, AudioClip>>();

		public static bool SpeedReduction;

		public static bool IsContainerOpen;

		public static float ZoomInTimer = 0.1f;

		public static float ZoomOutTimer;

		public static float ZoomOutDelayTimer = 0f;

		public static float __BaseFov;

		public static float __LastZoomFov;

		public static float __NewZoomFov = 0f;

		public static ZoomState __ZoomState;

		public static int QuiverRowIndex = 0;

		public static ConfigEntry<KeyboardShortcut> HoldingKeyCode;

		public static ConfigEntry<KeyboardShortcut>[] KeyCodes = new ConfigEntry<KeyboardShortcut>[3];

		public static ConfigEntry<float>[] ArrowRetrieveChance = new ConfigEntry<float>[17];

		public static ConfigEntry<string>[] ArrowRetrieveSpawnType = new ConfigEntry<string>[17];

		public static string[] ArrowTypes = new string[17]
		{
			"ArrowWood", "ArrowFlint", "ArrowBronze", "ArrowIron", "ArrowObsidian", "ArrowNeedle", "ArrowFire", "ArrowPoison", "ArrowSilver", "ArrowFrost",
			"ArrowCarapace", "ArrowCharred", "BoltBone", "BoltIron", "BoltBlackmetal", "BoltCarapace", "BoltCharred"
		};

		public static List<Arrow> ArrowRetrieves = new List<Arrow>();

		public static ConfigEntry<float> ArrowDisappearTime;

		public static ConfigEntry<bool> ArrowDisappearOnHit;

		public static ConfigEntry<bool> ArrowAutoPickup;

		public static ConfigEntry<Vector2> InventoryQuiverSlotLocation;

		public static ConfigEntry<Vector2> InventoryQuiverSlotLocationWithContainer;

		public static ConfigEntry<bool> QuiverHudEnabled;

		public static ConfigEntry<Vector3> QuiverModelRotation;

		public static ConfigEntry<Vector3> QuiverModelScale;

		public static ConfigEntry<Vector3> QuiverModelPosition;

		public static ConfigEntry<float> ArrowVelocity;

		public static ConfigEntry<float> ArrowGravity;

		public static ConfigEntry<float> ArrowAccuracy;

		public static ConfigEntry<Vector3> ArrowAimDir;

		public static ConfigEntry<bool> ConfigQuiverEnabled;

		public static ConfigEntry<bool> ConfigArrowImprovementsEnabled;

		public static ConfigEntry<bool> ConfigRetrievableArrowsEnabled;

		public static ConfigEntry<bool> ConfigBowZoomEnabled;

		public static ConfigEntry<KeyboardShortcut> BowDrawCancelKey;

		public static ConfigEntry<float> BowZoomFactor;

		public static ConfigEntry<bool> AutomaticBowZoom;

		public static ConfigEntry<KeyboardShortcut> BowZoomKey;

		public static ConfigEntry<float> BowZoomConstantTime;

		public static ConfigEntry<bool> BowZoomSFXEnabled;

		public static ConfigEntry<float> StayInZoomTime;

		public static ConfigEntry<bool> IsCrosshairVisible;

		public static ConfigEntry<bool> IsBowCrosshairVisible;

		public static ConfigEntry<bool> ShowSneakDamage;

		public static ConfigEntry<bool> BowDrawMovementSpeedReductionEnabled;

		public static ConfigEntry<int> DebugLevel;

		public static RecipesConfig Recipes;

		public static ConfigEntry<bool> WoodenArrowEverywhereEnabled;

		public static readonly Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>();

		public static GameObject QuiverGO;

		public static ConfigEntry<int> NexusID;

		public static AudioSource PlayerAudioSource;

		public static BetterArchery _instance;

		private Harmony _harmony;

		public static bool HasAuga { get; private set; }

		private void Awake()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			_instance = this;
			ConfigQuiverEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Quiver", "Enable Quiver", true, "Enable the quiver. Don't change this value while in the game. If you disable this while arrows are in the quiver, you will LOSE ALL OF THEM!");
			InventoryQuiverSlotLocation = ((BaseUnityPlugin)this).Config.Bind<Vector2>("Quiver", "Change location of inventory quiver slot", new Vector2(3f, -25f), "Change quiver slot inventory location. For 'More Slots' you can use this location, 'x:3.0, y:-167.0'.");
			InventoryQuiverSlotLocationWithContainer = ((BaseUnityPlugin)this).Config.Bind<Vector2>("Quiver", "Change location of inventory quiver slot when a chest opened", new Vector2(3f, -425f), "Change quiver slot inventory location when a chest opened.");
			QuiverModelRotation = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Quiver", "Change Quiver Model Rotation", new Vector3(270f, 90f, -10f), "Change the quiver model rotation. Default is 'x:270.0, y:90.0, z:-10.0'");
			QuiverModelScale = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Quiver", "Change Quiver Model Scale", new Vector3(2f, 2f, 2f), "Change the quiver model scale. Default is 'x:2.0, y:2.0, z:2.0'");
			QuiverModelPosition = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Quiver", "Change Quiver Model Position", new Vector3(0.001f, 0f, 0.003f), "Change the quiver model position. Default is 'x:0.001, y:0.0, z:0.003'");
			QuiverHudEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Quiver", "Enable Quiver Hud", true, "Enable the quiver's hotbar on the screen/hud. This doesn't affect inventory.");
			HoldingKeyCode = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Quiver", "Quiver slot hotkey holding key", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Change holding key. For the inputs: https://docs.unity3d.com/ScriptReference/KeyCode.html");
			KeyCodes[0] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Quiver", "Quiver slot hotkey 1", new KeyboardShortcut((KeyCode)49, Array.Empty<KeyCode>()), "Hotkey for Quiver Slot 1. For the inputs: https://docs.unity3d.com/ScriptReference/KeyCode.html");
			KeyCodes[1] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Quiver", "Quiver slot hotkey 2", new KeyboardShortcut((KeyCode)50, Array.Empty<KeyCode>()), "Hotkey for Quiver Slot 2. For the inputs: https://docs.unity3d.com/ScriptReference/KeyCode.html");
			KeyCodes[2] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Quiver", "Quiver slot hotkey 3", new KeyboardShortcut((KeyCode)51, Array.Empty<KeyCode>()), "Hotkey for Quiver Slot 3. For the inputs: https://docs.unity3d.com/ScriptReference/KeyCode.html");
			ConfigArrowImprovementsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Arrow Improvements", "Enable Arrow Improvements", true, "Arrow improvements including aim problems fixes, gravity changes.");
			ArrowVelocity = ((BaseUnityPlugin)this).Config.Bind<float>("Arrow Improvements", "Set Arrow Velocity", 70f, "Change the arrow's velocity. Vanilla is '60'.");
			ArrowGravity = ((BaseUnityPlugin)this).Config.Bind<float>("Arrow Improvements", "Set Arrow Gravity", 15f, "Change the arrow's gravity. Vanilla is '5'.");
			ArrowAccuracy = ((BaseUnityPlugin)this).Config.Bind<float>("Arrow Improvements", "Set Arrow Accuracy", 0f, "Change the arrow's accuracy. Vanilla is '-1'.");
			ArrowAimDir = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Arrow Improvements", "Set Aim Direction", new Vector3(0f, 0.05f, 0f), "Change the aim direction. Vanilla is 'x:0.0, y:0.0, z: 0.0'.");
			ConfigBowZoomEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Bow Zoom", "Enable Bow Zoom", true, "Enable the zooming with bow.");
			AutomaticBowZoom = ((BaseUnityPlugin)this).Config.Bind<bool>("Bow Zoom", "Automatic Bow Zoom", false, "Zoom while drawing bow automatically.");
			BowZoomSFXEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Bow Zoom", "Enable Bow Zoom SFX", true, "Sound effects for zoom-in and zoom-out.");
			BowZoomFactor = ((BaseUnityPlugin)this).Config.Bind<float>("Bow Zoom", "Zoom Factor", 2f, "Max zoom.");
			BowZoomConstantTime = ((BaseUnityPlugin)this).Config.Bind<float>("Bow Zoom", "Bow Zoom Constant Time", -1f, "Change this value to '-1' if you don't want constant time while zooming. '1' is recommended.");
			BowZoomKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Bow Zoom", "Bow Zoom Hotkey", new KeyboardShortcut((KeyCode)324, Array.Empty<KeyCode>()), "Mouse0: Left Click, Mouse1: Right Click, Mouse2: Middle Click. For the other inputs: https://docs.unity3d.com/ScriptReference/KeyCode.html");
			BowDrawCancelKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Bow Zoom", "Bow Draw Cancel Hotkey", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Mouse0: Left Click, Mouse1: Right Click, Mouse2: Middle Click. For the other inputs: https://docs.unity3d.com/ScriptReference/KeyCode.html");
			StayInZoomTime = ((BaseUnityPlugin)this).Config.Bind<float>("Bow Zoom", "Stay In-Zoom Time", 2f, "Set the max time of staying on zoom while holding RMB after releasing an arrow.");
			IsCrosshairVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Other", "Enable Crosshair", true, "You can hide your crosshair.");
			IsBowCrosshairVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Other", "Enable Bow Crosshair", true, "You can hide your bow crosshair, circle one.");
			ShowSneakDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Other", "Enable Sneak Damage Showing", true, "Show sneak damage at top left.");
			BowDrawMovementSpeedReductionEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Other", "Enable Bow Draw Movement Speed Reduction", true, "Set walk speed while drawing bow.");
			WoodenArrowEverywhereEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Other", "Enable Crafting Wooden Arrow Everywhere", true, "Enable to crafting wooden arrows without a crafting table.");
			ConfigRetrievableArrowsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Retrievable Arrows", "Enable Retrievable Arrows", true, "Enable the retrievable arrows.");
			ArrowDisappearTime = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "Arrow Disappear Time", 60f, "Set arrow's disappear countdown time.");
			ArrowDisappearOnHit = ((BaseUnityPlugin)this).Config.Bind<bool>("Retrievable Arrows", "Arrow Disappear On Hit", false, "Make arrows disappear when they are not retrievable.");
			ArrowAutoPickup = ((BaseUnityPlugin)this).Config.Bind<bool>("Retrievable Arrows", "Arrow Auto Pickup", false, "Automatically pick up near arrows when they are retrievable.");
			ArrowRetrieveChance[0] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Wooden Arrow", 0.2f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[1] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Flint Arrow", 0.3f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[2] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Bronze Arrow", 0.5f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[3] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Iron Arrow", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[4] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Obsidian Arrow", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[5] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Needle Arrow", 0.1f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[6] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Fire Arrow", 0f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[7] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Poison Arrow", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[8] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Silver Arrow", 0.5f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[9] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Frost Arrow", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[10] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Carapace Arrow", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[11] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Charred Arrow", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[12] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Bone Bolt", 0.3f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[13] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Iron Bolt", 0.5f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[14] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Blackmetal Bolt", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[15] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Carapace Bolt", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveChance[16] = ((BaseUnityPlugin)this).Config.Bind<float>("Retrievable Arrows", "ArrowRetrieveChance for Charred Bolt", 0.7f, "Example: 0.9 for 90% chance to retrieve.");
			ArrowRetrieveSpawnType[0] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Wooden Arrow", "ArrowWood", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[1] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Flint Arrow", "ArrowFlint", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[2] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Bronze Arrow", "ArrowBronze", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[3] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Iron Arrow", "ArrowIron", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[4] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Obsidian Arrow", "ArrowObsidian", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[5] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Needle Arrow", "ArrowNeedle", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[6] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Fire Arrow", "ArrowFire", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[7] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Poison Arrow", "ArrowObsidian", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[8] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Silver Arrow", "ArrowSilver", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[9] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Frost Arrow", "ArrowObsidian", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[10] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Carapace Arrow", "ArrowCarapace", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[11] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Charred Arrow", "ArrowCharred", "https://valheim.fandom.com/wiki/Category:Arrows use internal ids.");
			ArrowRetrieveSpawnType[12] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Bone Bolt", "BoltBone", "https://valheim.fandom.com/wiki/Category:Bolts use internal ids.");
			ArrowRetrieveSpawnType[13] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Iron Bolt", "BoltIron", "https://valheim.fandom.com/wiki/Category:Bolts use internal ids.");
			ArrowRetrieveSpawnType[14] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Blackmetal Bolt", "BoltBlackmetal", "https://valheim.fandom.com/wiki/Category:Bolts use internal ids.");
			ArrowRetrieveSpawnType[15] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Carapace Bolt", "BoltCarapace", "https://valheim.fandom.com/wiki/Category:Bolts use internal ids.");
			ArrowRetrieveSpawnType[16] = ((BaseUnityPlugin)this).Config.Bind<string>("Retrievable Arrows", "ArrowRetrieveSpawnType for Charred Bolt", "BoltCharred", "https://valheim.fandom.com/wiki/Category:Bolts use internal ids.");
			for (int i = 0; i < ArrowRetrieveSpawnType.Length; i++)
			{
				ArrowRetrieves.Add(new Arrow
				{
					Name = ArrowTypes[i],
					SpawnChance = ArrowRetrieveChance[i].Value,
					SpawnArrow = ArrowRetrieveSpawnType[i].Value
				});
			}
			NexusID = ((BaseUnityPlugin)this).Config.Bind<int>("Other", "NexusID", 348, "Nexus mod ID for updates.");
			DebugLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Other", "Set Debug Log Level", 1, "0: Nothing, 1: Only Errors, 2: Errors and Warnings, 3: Everything");
			Recipes = LoadJsonFile<RecipesConfig>("BetterArcheryRecipes.json");
			if (ConfigQuiverEnabled.Value)
			{
				AssetBundle val = LoadAssetBundle("quiverassets");
				if (Recipes != null && (Object)(object)val != (Object)null)
				{
					foreach (RecipeConfig recipe in Recipes.recipes)
					{
						if (val.Contains(recipe.item))
						{
							GameObject value = val.LoadAsset<GameObject>(recipe.item);
							Prefabs.Add(recipe.item, value);
						}
					}
				}
				if (val != null)
				{
					val.Unload(false);
				}
			}
			Dictionary<string, object> dictionary = LoadTranslationJsonFile<Dictionary<string, object>>("ishid4_translations.json");
			if (dictionary.Count > 0)
			{
				LoadTranslations(dictionary);
			}
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			HasAuga = API.IsLoaded();
		}

		public void Start()
		{
			HasAuga = API.IsLoaded();
			if (HasAuga)
			{
				Log("Auga Loaded.");
			}
		}

		private void Update()
		{
			if (!ConfigQuiverEnabled.Value)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer) && ((Character)localPlayer).TakeInput())
			{
				for (int i = 0; i < 3; i++)
				{
					CheckQuiverUseInput(localPlayer, i);
				}
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			foreach (GameObject value in Prefabs.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			Prefabs.Clear();
		}

		public static void Log(string str = "", int warningType = 2)
		{
			if (DebugLevel.Value == 0)
			{
				return;
			}
			if (warningType == 0)
			{
				Debug.LogError((object)("[" + typeof(BetterArchery).Namespace + "]: " + str));
			}
			if (DebugLevel.Value > 1)
			{
				if (warningType == 1)
				{
					Debug.LogWarning((object)("[" + typeof(BetterArchery).Namespace + "]: " + str));
				}
				if (DebugLevel.Value > 2 && warningType == 2)
				{
					Debug.Log((object)("[" + typeof(BetterArchery).Namespace + "]: " + str));
				}
			}
		}

		private static void LoadTranslations(Dictionary<string, object> translations)
		{
			if (translations == null)
			{
				Log("Could not parse ishid4_translations.json!", 3);
				return;
			}
			List<KeyValuePair<string, string>> list = Localization.instance.m_translations.Where((KeyValuePair<string, string> instanceMTranslation) => instanceMTranslation.Key.StartsWith("mod_betterarchery_")).ToList();
			foreach (KeyValuePair<string, string> item in list)
			{
				Localization.instance.m_translations.Remove(item.Key);
			}
			foreach (KeyValuePair<string, object> translation in translations)
			{
				Localization.instance.AddWord(translation.Key, translation.Value.ToString());
			}
		}

		public static string GetBindingLabel(int index)
		{
			//IL_000c: 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)
			index = Mathf.Clamp(index, 0, 2);
			KeyCode bindingKeycode = GetBindingKeycode(index);
			if (((object)(KeyCode)(ref bindingKeycode)).ToString().Contains("Alpha"))
			{
				return ((object)(KeyCode)(ref bindingKeycode)).ToString().Replace("Alpha", "");
			}
			return ((object)(KeyCode)(ref bindingKeycode)).ToString().ToUpperInvariant();
		}

		public static KeyCode GetBindingKeycode(int index)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			index = Mathf.Clamp(index, 0, 2);
			KeyboardShortcut value = KeyCodes[index].Value;
			return ((KeyboardShortcut)(ref value)).MainKey;
		}

		public static int GetBonusInventoryRowIndex()
		{
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && QuiverRowIndex != 0)
			{
				return QuiverRowIndex;
			}
			return 0;
		}

		public static void CheckQuiverUseInput(Player player, int index)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			KeyCode bindingKeycode = GetBindingKeycode(index);
			KeyboardShortcut value = HoldingKeyCode.Value;
			bool flag;
			if (!string.IsNullOrEmpty(((KeyboardShortcut)(ref value)).Serialize()))
			{
				value = HoldingKeyCode.Value;
				if (((KeyboardShortcut)(ref value)).Serialize() != "None")
				{
					value = HoldingKeyCode.Value;
					flag = Input.GetKey(((KeyboardShortcut)(ref value)).MainKey) && Input.GetKeyDown(bindingKeycode);
					goto IL_0070;
				}
			}
			flag = Input.GetKeyDown(bindingKeycode);
			goto IL_0070;
			IL_0070:
			if (flag)
			{
				int bonusInventoryRowIndex = GetBonusInventoryRowIndex();
				ItemData itemAt = ((Humanoid)player).GetInventory().GetItemAt(index, bonusInventoryRowIndex);
				if (itemAt != null)
				{
					((Humanoid)player).UseItem((Inventory)null, itemAt, false);
				}
			}
		}

		public static bool IsQuiverSlot(Vector2i pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return IsQuiverSlot(pos.x, pos.y);
		}

		public static bool IsQuiverSlot(int x, int y)
		{
			int bonusInventoryRowIndex = GetBonusInventoryRowIndex();
			return y == bonusInventoryRowIndex && x >= 0 && x < 3;
		}

		public static Vector2i GetQuiverSlotPosition(int index)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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)
			int bonusInventoryRowIndex = GetBonusInventoryRowIndex();
			return new Vector2i(index, bonusInventoryRowIndex);
		}

		public static bool IsQuiverEquipped()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			return CustomSlotCreator.IsSlotOccupied((Humanoid)(object)Player.m_localPlayer, "quiver");
		}

		private static T LoadJsonFile<T>(string filename) where T : class
		{
			string assetPath = GetAssetPath(filename);
			if (!string.IsNullOrEmpty(assetPath))
			{
				string json = File.ReadAllText(assetPath);
				return JsonMapper.ToObject<T>(json);
			}
			return null;
		}

		private static Dictionary<string, object> LoadTranslationJsonFile<T>(string filename) where T : class
		{
			string assetPath = GetAssetPath(filename);
			if (!string.IsNullOrEmpty(assetPath))
			{
				string json = File.ReadAllText(assetPath);
				return JsonMapper.ToObject<Dictionary<string, object>>(json);
			}
			return null;
		}

		public static AssetBundle LoadAssetBundle(string filename)
		{
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			AssetBundle result = AssetBundle.LoadFromStream(callingAssembly.GetManifestResourceStream(callingAssembly.GetName().Name + "." + filename));
			Log("Loaded AssetBundle (" + filename + ").", 3);
			Log(callingAssembly.GetName().Name);
			return result;
		}

		public static string GetAssetPath(string assetName, bool isDirectory = false)
		{
			string text = Path.Combine(Paths.PluginPath, "BetterArchery", assetName);
			if (isDirectory)
			{
				if (!Directory.Exists(text))
				{
					Assembly assembly = typeof(BetterArchery).Assembly;
					text = Path.Combine(Path.GetDirectoryName(assembly.Location), assetName);
					if (!Directory.Exists(text))
					{
						Log("Could not find directory (" + assetName + ").", 1);
						return null;
					}
				}
				return text;
			}
			if (!File.Exists(text))
			{
				Assembly assembly2 = typeof(BetterArchery).Assembly;
				text = Path.Combine(Path.GetDirectoryName(assembly2.Location), assetName);
				if (!File.Exists(text))
				{
					Log("Could not find asset (" + assetName + ").", 1);
					return null;
				}
			}
			return text;
		}

		public static void TryCreateCustomSlot(ZNetScene zNetScene)
		{
			if (!((Object)(object)zNetScene == (Object)null) && ConfigQuiverEnabled.Value)
			{
				GameObject prefab = zNetScene.GetPrefab("LeatherQuiver");
				CustomSlotCreator.ApplyCustomSlotItem(prefab, "quiver");
			}
		}

		public static void TryCreateCustomSFX()
		{
			if (!ConfigBowZoomEnabled.Value || !BowZoomSFXEnabled.Value)
			{
				return;
			}
			string assetPath = GetAssetPath("SFX", isDirectory: true);
			if (string.IsNullOrEmpty(assetPath))
			{
				Log("SFX folder not found.");
				return;
			}
			Log("path: " + assetPath);
			string[] directories = Directory.GetDirectories(assetPath);
			foreach (string path in directories)
			{
				Log("Checking folder " + Path.GetFileName(path));
				CustomSfxDict[Path.GetFileName(path)] = new Dictionary<string, AudioClip>();
				string[] files = Directory.GetFiles(path);
				foreach (string path2 in files)
				{
					if (Path.GetExtension(path2).ToLower().Equals(".wav"))
					{
						Log("Checking file " + Path.GetFileName(path2));
						((MonoBehaviour)_instance).StartCoroutine(LoadSFXCoroutine(path2, CustomSfxDict[Path.GetFileName(path)]));
					}
				}
			}
		}

		public static void PlayCustomSFX(string name, bool checkIfPlaying = true)
		{
			if ((Object)(object)PlayerAudioSource == (Object)null || !BowZoomSFXEnabled.Value)
			{
				return;
			}
			ZSFX component = ((Component)PlayerAudioSource).GetComponent<ZSFX>();
			if (!(component.IsPlaying() && checkIfPlaying))
			{
				if (CustomSfxDict.TryGetValue(name, out var value))
				{
					component.m_audioClips = value.Values.ToArray();
					component.Play();
				}
				else
				{
					Log("SFX not found.", 0);
				}
			}
		}

		public static IEnumerator LoadSFXCoroutine(string path, Dictionary<string, AudioClip> dict)
		{
			path = "file:///" + path;
			UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path, (AudioType)20);
			try
			{
				yield return www.SendWebRequest();
				if (www == null)
				{
					Log("ww error.", 0);
					yield break;
				}
				DownloadHandlerAudioClip dh = (DownloadHandlerAudioClip)www.downloadHandler;
				if (dh != null)
				{
					AudioClip ac = dh.audioClip;
					if ((Object)(object)ac != (Object)null)
					{
						((Object)ac).name = Path.GetFileNameWithoutExtension(path);
						if (!dict.ContainsKey(((Object)ac).name))
						{
							dict[((Object)ac).name] = ac;
						}
						Log("Added " + ((Object)ac).name + " SFX.");
						yield break;
					}
				}
				Log("Error while adding custom SFX.", 0);
			}
			finally
			{
				((IDisposable)www)?.Dispose();
			}
		}

		public static void TryRegisterPrefabs(ZNetScene zNetScene)
		{
			if ((Object)(object)zNetScene == (Object)null)
			{
				return;
			}
			foreach (GameObject value in Prefabs.Values)
			{
				if (!ConfigQuiverEnabled.Value)
				{
					Log(((Object)value).name);
					if (((Object)value).name.Contains("Quiver"))
					{
						Debug.Log((object)("[PrefabCreator] " + ((Object)value).name + " prefab skipped."));
						continue;
					}
				}
				if (!zNetScene.m_prefabs.Contains(value))
				{
					zNetScene.m_prefabs.Add(value);
				}
			}
		}

		public static bool IsObjectDBReady()
		{
			return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null;
		}

		public static void TryRegisterItems()
		{
			if (!IsObjectDBReady())
			{
				return;
			}
			foreach (GameObject value in Prefabs.Values)
			{
				ItemDrop component = value.GetComponent<ItemDrop>();
				if (!((Object)(object)component == (Object)null))
				{
					if (!ConfigQuiverEnabled.Value && ((Object)component.m_itemData.m_dropPrefab).name.Contains("Quiver"))
					{
						Debug.Log((object)("[PrefabCreator] Skipped prefab: " + ((Object)component.m_itemData.m_dropPrefab).name));
					}
					else if ((Object)(object)ObjectDB.instance.GetItemPrefab(StringExtensionMethods.GetStableHashCode(((Object)value).name)) == (Object)null)
					{
						component.m_itemData.m_dropPrefab = value;
						ObjectDB.instance.m_items.Add(value);
					}
				}
			}
			ObjectDB.instance.UpdateRegisters();
		}

		public static void TryRegisterRecipes()
		{
			if (!IsObjectDBReady())
			{
				return;
			}
			PrefabCreator.Reset();
			foreach (RecipeConfig recipe in Recipes.recipes)
			{
				if (!ConfigQuiverEnabled.Value && recipe.item.Contains("Quiver"))
				{
					Debug.Log((object)("[PrefabCreator] Skipped recipe: " + recipe.name));
				}
				else if (!WoodenArrowEverywhereEnabled.Value && recipe.name == "Recipe_ArrowWoodAnywhere")
				{
					Debug.Log((object)("[PrefabCreator] Skipped recipe: " + recipe.name));
				}
				else
				{
					PrefabCreator.AddNewRecipe(recipe.name, recipe.item, recipe);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public static class TerminalAwake_Patch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				//IL_0206: Unknown result type (might be due to invalid IL or missing references)
				if (args.Length < 2)
				{
					args.Context.AddString("Syntax: ba [action]");
					return;
				}
				switch (args.FullLine.Substring(args[0].Length + 1))
				{
				case "reload":
					((BaseUnityPlugin)BetterArchery._instance).Config.Reload();
					args.Context.AddString("Better Archery Reloaded.");
					args.Context.AddString(Localization.instance.Localize("$mod_betterarchery_test"));
					break;
				case "drop":
				{
					Inventory inventory = ((Humanoid)Player.m_localPlayer).m_inventory;
					for (int num = inventory.m_inventory.Count - 1; num >= 0; num--)
					{
						ItemData val = inventory.m_inventory[num];
						if (val.m_gridPos.y >= 5 && !BetterArchery.IsQuiverSlot(val.m_gridPos))
						{
							BetterArchery.Log($"Found {((Object)val.m_dropPrefab).name} x {val.m_stack} in invisible slots; attempting to drop.");
							((Humanoid)Player.m_localPlayer).DropItem(inventory, val, val.m_stack);
						}
					}
					break;
				}
				case "god":
					Player.m_localPlayer.SetGodMode(!Player.m_localPlayer.m_godMode);
					Player.m_localPlayer.SetNoPlacementCost(!Player.m_localPlayer.m_noPlacementCost);
					Player.m_localPlayer.m_staminaRegenDelay = 0.05f;
					Player.m_localPlayer.m_staminaRegen = 999f;
					Player.m_localPlayer.m_runStaminaDrain = 0f;
					Player.m_localPlayer.SetMaxStamina(9999f, true);
					((Character)Player.m_localPlayer).AddStamina(999f);
					break;
				case "clear":
					((Humanoid)Player.m_localPlayer).GetInventory().RemoveAll();
					break;
				case "sfx":
					BetterArchery.PlayCustomSFX("exhale");
					break;
				case "kill":
					((Character)Player.m_localPlayer).SetHealth(0f);
					break;
				case "removequivermodel":
					ZNetScene.instance.Destroy(BetterArchery.QuiverGO);
					break;
				case "fill":
				{
					for (int i = 0; i < 32; i++)
					{
						((Humanoid)Player.m_localPlayer).m_inventory.AddItem(ObjectDB.instance.GetItemPrefab("Wood"), 100);
					}
					break;
				}
				default:
					args.Context.AddString("Syntax: ba [action]");
					break;
				}
			}
		}

		public static void Postfix()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					//IL_0206: Unknown result type (might be due to invalid IL or missing references)
					if (args.Length < 2)
					{
						args.Context.AddString("Syntax: ba [action]");
					}
					else
					{
						switch (args.FullLine.Substring(args[0].Length + 1))
						{
						case "reload":
							((BaseUnityPlugin)BetterArchery._instance).Config.Reload();
							args.Context.AddString("Better Archery Reloaded.");
							args.Context.AddString(Localization.instance.Localize("$mod_betterarchery_test"));
							break;
						case "drop":
						{
							Inventory inventory = ((Humanoid)Player.m_localPlayer).m_inventory;
							for (int num = inventory.m_inventory.Count - 1; num >= 0; num--)
							{
								ItemData val3 = inventory.m_inventory[num];
								if (val3.m_gridPos.y >= 5 && !BetterArchery.IsQuiverSlot(val3.m_gridPos))
								{
									BetterArchery.Log($"Found {((Object)val3.m_dropPrefab).name} x {val3.m_stack} in invisible slots; attempting to drop.");
									((Humanoid)Player.m_localPlayer).DropItem(inventory, val3, val3.m_stack);
								}
							}
							break;
						}
						case "god":
							Player.m_localPlayer.SetGodMode(!Player.m_localPlayer.m_godMode);
							Player.m_localPlayer.SetNoPlacementCost(!Player.m_localPlayer.m_noPlacementCost);
							Player.m_localPlayer.m_staminaRegenDelay = 0.05f;
							Player.m_localPlayer.m_staminaRegen = 999f;
							Player.m_localPlayer.m_runStaminaDrain = 0f;
							Player.m_localPlayer.SetMaxStamina(9999f, true);
							((Character)Player.m_localPlayer).AddStamina(999f);
							break;
						case "clear":
							((Humanoid)Player.m_localPlayer).GetInventory().RemoveAll();
							break;
						case "sfx":
							BetterArchery.PlayCustomSFX("exhale");
							break;
						case "kill":
							((Character)Player.m_localPlayer).SetHealth(0f);
							break;
						case "removequivermodel":
							ZNetScene.instance.Destroy(BetterArchery.QuiverGO);
							break;
						case "fill":
						{
							for (int i = 0; i < 32; i++)
							{
								((Humanoid)Player.m_localPlayer).m_inventory.AddItem(ObjectDB.instance.GetItemPrefab("Wood"), 100);
							}
							break;
						}
						default:
							args.Context.AddString("Syntax: ba [action]");
							break;
						}
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			ConsoleCommand val2 = new ConsoleCommand("ba", "[action]", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false)
			{
				IsCheat = false
			};
		}
	}
	[HarmonyPatch]
	public class Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemData), "IsEquipable")]
		private static void IsEquipablePostfix(ref bool __result, ref ItemData __instance)
		{
			__result = __result || CustomSlotCreator.IsCustomSlotItem(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Humanoid), "Awake")]
		private static void HumanoidEntryPostfix(ref Humanoid __instance)
		{
			CustomSlotCreator.customSlotItemData[__instance] = new Dictionary<string, ItemData>();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "Load")]
		private static void InventoryLoadPostfix(ref Player __instance)
		{
			foreach (ItemData equippedItem in ((Humanoid)__instance).m_inventory.GetEquippedItems())
			{
				if (CustomSlotCreator.IsCustomSlotItem(equippedItem))
				{
					string customSlotName = CustomSlotCreator.GetCustomSlotName(equippedItem);
					CustomSlotCreator.SetSlotItem((Humanoid)(object)__instance, customSlotName, equippedItem);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Humanoid), "EquipItem")]
		private static void EquipItemPostfix(ref bool __result, ref Humanoid __instance, ItemData item, bool triggerEquipEffects = true)
		{
			if (CustomSlotCreator.IsCustomSlotItem(item))
			{
				string customSlotName = CustomSlotCreator.GetCustomSlotName(item);
				if (CustomSlotCreator.IsSlotOccupied(__instance, customSlotName))
				{
					__instance.UnequipItem(CustomSlotCreator.GetSlotItem(__instance, customSlotName), triggerEquipEffects);
				}
				CustomSlotCreator.SetSlotItem(__instance, customSlotName, item);
				if (__instance.IsItemEquiped(item))
				{
					item.m_equipped = true;
				}
				__instance.SetupEquipment();
				if (triggerEquipEffects)
				{
					__instance.TriggerEquipEffect(item);
				}
				if (BetterArchery.IsQuiverEquipped())
				{
					CreateQuiverBackAttachment(__instance, item);
				}
				__result = true;
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
		[HarmonyPostfix]
		private static void UnequipItemPostfix(ref Humanoid __instance, ItemData item, bool triggerEquipEffects = true)
		{
			if (CustomSlotCreator.IsCustomSlotItem(item))
			{
				string customSlotName = CustomSlotCreator.GetCustomSlotName(item);
				if (item == CustomSlotCreator.GetSlotItem(__instance, customSlotName))
				{
					CustomSlotCreator.SetSlotItem(__instance, customSlotName, null);
				}
				if (!BetterArchery.IsQuiverEquipped())
				{
					RemoveQuiverBackAttachment(item);
				}
				__instance.UpdateEquipmentStatusEffects();
			}
		}

		public static void CreateQuiverBackAttachment(Humanoid __instance, ItemData item)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			if (item == null)
			{
				return;
			}
			if ((Object)(object)BetterArchery.QuiverGO != (Object)null)
			{
				try
				{
					ZNetScene.instance.Destroy(BetterArchery.QuiverGO);
				}
				catch
				{
					Object.DestroyImmediate((Object)(object)BetterArchery.QuiverGO);
				}
			}
			Transform val = Utils.FindChild(((Component)__instance).transform, "BackBow_attach", (IterativeSearchType)0);
			GameObject gameObject = ((Component)Utils.FindChild(ZNetScene.instance.GetPrefab(((Object)item.m_dropPrefab.gameObject).name).transform, "attach", (IterativeSearchType)0)).gameObject;
			BetterArchery.QuiverGO = Object.Instantiate<GameObject>(gameObject, val.position, val.rotation, ((Component)val).transform);
			BetterArchery.Log("Quiver model " + ((Object)item.m_dropPrefab.gameObject).name + " created.");
			BetterArchery.QuiverGO.transform.localPosition = new Vector3(BetterArchery.QuiverModelPosition.Value.x, BetterArchery.QuiverModelPosition.Value.y, BetterArchery.QuiverModelPosition.Value.z);
			BetterArchery.QuiverGO.transform.localScale = new Vector3(0.01f * BetterArchery.QuiverModelScale.Value.x, 0.01f * BetterArchery.QuiverModelScale.Value.y, 0.01f * BetterArchery.QuiverModelScale.Value.z);
			BetterArchery.QuiverGO.transform.localEulerAngles = new Vector3(BetterArchery.QuiverModelRotation.Value.x, BetterArchery.QuiverModelRotation.Value.y, BetterArchery.QuiverModelRotation.Value.z);
			Object.DestroyImmediate((Object)(object)((Component)BetterArchery.QuiverGO.transform).GetComponent<BoxCollider>());
		}

		public static void RemoveQuiverBackAttachment(ItemData item)
		{
			if ((Object)(object)BetterArchery.QuiverGO != (Object)null)
			{
				BetterArchery.Log("Quiver model " + ((Object)item.m_dropPrefab.gameObject).name + " unequipped.");
				try
				{
					ZNetScene.instance.Destroy(BetterArchery.QuiverGO);
				}
				catch
				{
					Object.DestroyImmediate((Object)(object)BetterArchery.QuiverGO);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "IsItemEquiped")]
		[HarmonyPostfix]
		private static void IsItemEquipedPostfix(ref bool __result, ref Humanoid __instance, ItemData item)
		{
			if (CustomSlotCreator.IsCustomSlotItem(item))
			{
				string customSlotName = CustomSlotCreator.GetCustomSlotName(item);
				bool flag = CustomSlotCreator.DoesSlotExist(__instance, customSlotName) && CustomSlotCreator.GetSlotItem(__instance, customSlotName) == item;
				__result |= flag;
			}
		}

		[HarmonyPatch(typeof(Humanoid), "GetEquipmentWeight")]
		[HarmonyPostfix]
		private static void GetEquipmentWeightPostfix(ref float __result, ref Humanoid __instance)
		{
			foreach (string key in CustomSlotCreator.customSlotItemData[__instance].Keys)
			{
				if (CustomSlotCreator.IsSlotOccupied(__instance, key))
				{
					__result += CustomSlotCreator.GetSlotItem(__instance, key).m_shared.m_weight;
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipAllItems")]
		[HarmonyPostfix]
		private static void UnequipAllItemsPostfix(ref Humanoid __instance)
		{
			foreach (string item in CustomSlotCreator.customSlotItemData[__instance].Keys.ToList())
			{
				if (CustomSlotCreator.IsSlotOccupied(__instance, item))
				{
					__instance.UnequipItem(CustomSlotCreator.GetSlotItem(__instance, item), false);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "GetSetCount")]
		[HarmonyPostfix]
		private static void GetSetCountPostfix(ref int __result, ref Humanoid __instance, string setName)
		{
			foreach (string item in CustomSlotCreator.customSlotItemData[__instance].Keys.ToList())
			{
				if (CustomSlotCreator.IsSlotOccupied(__instance, item) && CustomSlotCreator.GetSlotItem(__instance, item).m_shared.m_setName == setName)
				{
					__result++;
				}
			}
		}

		public static HashSet<StatusEffect> GetStatusEffectsFromCustomSlotItems(Humanoid __instance)
		{
			HashSet<StatusEffect> hashSet = new HashSet<StatusEffect>();
			foreach (string key in CustomSlotCreator.customSlotItemData[__instance].Keys)
			{
				if (CustomSlotCreator.IsSlotOccupied(__instance, key))
				{
					if (Object.op_Implicit((Object)(object)CustomSlotCreator.GetSlotItem(__instance, key).m_shared.m_equipStatusEffect))
					{
						StatusEffect equipStatusEffect = CustomSlotCreator.GetSlotItem(__instance, key).m_shared.m_equipStatusEffect;
						hashSet.Add(equipStatusEffect);
					}
					if (__instance.HaveSetEffect(CustomSlotCreator.GetSlotItem(__instance, key)))
					{
						StatusEffect setStatusEffect = CustomSlotCreator.GetSlotItem(__instance, key).m_shared.m_setStatusEffect;
						hashSet.Add(setStatusEffect);
					}
				}
			}
			return hashSet;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "OnLeftClick")]
	public static class InventoryGrid_OnLeftClick_Patch
	{
		public static bool Prefix(InventoryGrid __instance, UIInputHandler clickHandler)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterArchery.ConfigQuiverEnabled.Value)
			{
				return true;
			}
			GameObject gameObject = ((Component)clickHandler).gameObject;
			Vector2i buttonPos = __instance.GetButtonPos(gameObject);
			ItemData itemAt = __instance.m_inventory.GetItemAt(buttonPos.x, buttonPos.y);
			if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && itemAt != null && itemAt.m_equipped && ((Object)itemAt.m_dropPrefab).name.Contains("Quiver"))
			{
				MessageHud.instance.ShowMessage((MessageType)2, "$mod_betterarchery_quiver_equipped_error", 0, (Sprite)null);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateGui", new Type[]
	{
		typeof(Player),
		typeof(ItemData)
	})]
	public static class InventoryGrid_UpdateGui_Patch
	{
		public static Vector2 customLocation;

		private static void Postfix(InventoryGrid __instance, Player player, ItemData dragItem, List<Element> ___m_elements)
		{
			if (((Object)__instance).name != "PlayerGrid" || !BetterArchery.ConfigQuiverEnabled.Value)
			{
				return;
			}
			if (__instance.GetInventory().GetHeight() > 5)
			{
				if (GetElement(___m_elements, 7, __instance.GetInventory().GetHeight() - 1).m_go.activeSelf)
				{
					for (int i = __instance.GetInventory().GetHeight() - 2; i < __instance.GetInventory().GetHeight(); i++)
					{
						for (int j = 0; j < 8; j++)
						{
							Element element = GetElement(___m_elements, j, i);
							element.m_go.SetActive(false);
						}
					}
				}
			}
			else if (GetElement(___m_elements, 7, __instance.GetInventory().GetHeight() - 1).m_go.activeSelf)
			{
				for (int k = __instance.GetInventory().GetHeight() - 1; k < __instance.GetInventory().GetHeight(); k++)
				{
					for (int l = 0; l < 8; l++)
					{
						Element element2 = GetElement(___m_elements, l, k);
						element2.m_go.SetActive(false);
					}
				}
			}
			if (BetterArchery.IsQuiverEquipped())
			{
				CreateQuiverSlots(__instance, ___m_elements);
			}
			else
			{
				RemoveQuiverSlots(__instance, ___m_elements);
			}
		}

		public static void CreateQuiverSlots(InventoryGrid __instance, List<Element> ___m_elements)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = (BetterArchery.IsContainerOpen ? BetterArchery.InventoryQuiverSlotLocationWithContainer.Value : BetterArchery.InventoryQuiverSlotLocation.Value);
			Transform val2 = ((Component)__instance).transform.parent.Find("QuiverSlotBkg");
			if (Object.op_Implicit((Object)(object)val2) && customLocation == val)
			{
				return;
			}
			int bonusInventoryRowIndex = BetterArchery.GetBonusInventoryRowIndex();
			customLocation = (BetterArchery.IsContainerOpen ? BetterArchery.InventoryQuiverSlotLocationWithContainer.Value : BetterArchery.InventoryQuiverSlotLocation.Value);
			KeyboardShortcut value;
			KeyCode mainKey;
			if (BetterArchery.HasAuga)
			{
				int num;
				Element element;
				Vector2 val3;
				Vector2 val4 = default(Vector2);
				Transform transform;
				for (int i = 0; i < 3; val3 = customLocation, ((Vector2)(ref val4))..ctor((float)num * __instance.m_elementSpace, 4f * (0f - __instance.m_elementSpace) + 30f), transform = element.m_go.transform, ((RectTransform)((transform is RectTransform) ? transform : null)).anchoredPosition = val3 + val4, i++)
				{
					num = i;
					element = GetElement(___m_elements, num, bonusInventoryRowIndex);
					element.m_go.SetActive(true);
					TMP_Text component = ((Component)element.m_go.transform.Find("binding")).GetComponent<TMP_Text>();
					((Behaviour)component).enabled = true;
					component.overflowMode = (TextOverflowModes)0;
					component.fontSize = 11f;
					component.autoSizeTextContainer = true;
					component.rectTransform.anchoredPosition = new Vector2(1f, 14f);
					value = BetterArchery.HoldingKeyCode.Value;
					if (!string.IsNullOrEmpty(((KeyboardShortcut)(ref value)).Serialize()))
					{
						value = BetterArchery.HoldingKeyCode.Value;
						if (!(((KeyboardShortcut)(ref value)).Serialize() == "None"))
						{
							value = BetterArchery.HoldingKeyCode.Value;
							mainKey = ((KeyboardShortcut)(ref value)).MainKey;
							component.text = ((object)(KeyCode)(ref mainKey)).ToString() + " + " + BetterArchery.GetBindingLabel(i);
							continue;
						}
					}
					component.text = BetterArchery.GetBindingLabel(i);
				}
				RectTransform orCreateBackground = GetOrCreateBackground(__instance, "QuiverSlotBkg");
				orCreateBackground.anchoredPosition = new Vector2(-174f + customLocation.x, -235f + customLocation.y);
				orCreateBackground.SetSizeWithCurrentAnchors((Axis)0, 235f);
				orCreateBackground.SetSizeWithCurrentAnchors((Axis)1, 90f);
				((Transform)orCreateBackground).localScale = new Vector3(1f, 1f, 1f);
				return;
			}
			int num2;
			Element element2;
			Vector2 val5;
			Vector2 val6 = default(Vector2);
			Transform transform2;
			for (int j = 0; j < 3; val5 = customLocation, ((Vector2)(ref val6))..ctor((float)num2 * __instance.m_elementSpace, 4f * (0f - __instance.m_elementSpace)), transform2 = element2.m_go.transform, ((RectTransform)((transform2 is RectTransform) ? transform2 : null)).anchoredPosition = val5 + val6, j++)
			{
				num2 = j;
				element2 = GetElement(___m_elements, num2, bonusInventoryRowIndex);
				element2.m_go.SetActive(true);
				TMP_Text component2 = ((Component)element2.m_go.transform.Find("binding")).GetComponent<TMP_Text>();
				((Behaviour)component2).enabled = true;
				component2.overflowMode = (TextOverflowModes)0;
				component2.horizontalAlignment = (HorizontalAlignmentOptions)2;
				component2.fontSize = 11f;
				component2.autoSizeTextContainer = true;
				component2.rectTransform.anchoredPosition = new Vector2(28f, -7f);
				value = BetterArchery.HoldingKeyCode.Value;
				if (!string.IsNullOrEmpty(((KeyboardShortcut)(ref value)).Serialize()))
				{
					value = BetterArchery.HoldingKeyCode.Value;
					if (!(((KeyboardShortcut)(ref value)).Serialize() == "None"))
					{
						value = BetterArchery.HoldingKeyCode.Value;
						mainKey = ((KeyboardShortcut)(ref value)).MainKey;
						component2.text = ((object)(KeyCode)(ref mainKey)).ToString() + " + " + BetterArchery.GetBindingLabel(j);
						continue;
					}
				}
				component2.text = BetterArchery.GetBindingLabel(j);
			}
			RectTransform orCreateBackground2 = GetOrCreateBackground(__instance, "QuiverSlotBkg");
			float num3 = 3f - customLocation.x;
			float num4 = -25f - customLocation.y;
			orCreateBackground2.anchoredPosition = new Vector2(-176f + (0f - num3), -200f + (0f - num4));
			orCreateBackground2.SetSizeWithCurrentAnchors((Axis)0, 235f);
			orCreateBackground2.SetSizeWithCurrentAnchors((Axis)1, 90f);
			((Transform)orCreateBackground2).localScale = new Vector3(1f, 1f, 1f);
		}

		public static void RemoveQuiverSlots(InventoryGrid __instance, List<Element> ___m_elements)
		{
			int bonusInventoryRowIndex = BetterArchery.GetBonusInventoryRowIndex();
			for (int i = 0; i < 3; i++)
			{
				int x = i;
				Element element = GetElement(___m_elements, x, bonusInventoryRowIndex);
				element.m_go.SetActive(false);
			}
			Transform val = ((Component)__instance).transform.parent.Find("QuiverSlotBkg");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private static RectTransform GetOrCreateBackground(InventoryGrid __instance, string name)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)__instance).transform.parent.Find(name);
			if ((Object)(object)val != (Object)null)
			{
				return (RectTransform)(object)((val is RectTransform) ? val : null);
			}
			if (BetterArchery.HasAuga)
			{
				BetterArchery.Log("GetOrCreateBackground: Auga is Active!");
				Transform parent = ((Component)__instance).transform.parent;
				GameObject val2 = API.Panel_Create(((Component)parent).transform, new Vector2(10f, 10f), name, withCornerDecoration: true);
				Transform val3 = ((Component)__instance).transform.Find("Main");
				((Behaviour)((Component)val3).GetComponent<RectMask2D>()).enabled = false;
				((Behaviour)((Component)((Component)val3).transform.Find("Grid")).GetComponent<GridLayoutGroup>()).enabled = false;
				if (val3.localPosition.y > -40f)
				{
					val3.localPosition = Vector2.op_Implicit(new Vector2(val3.localPosition.x, -64f));
				}
				val2.transform.SetSiblingIndex(((Component)val3).transform.GetSiblingIndex() + 1);
				val = val2.transform;
				return (RectTransform)(object)((val is RectTransform) ? val : null);
			}
			GameObject gameObject = ((Component)((Component)__instance).transform.parent.Find("Bkg")).gameObject;
			GameObject val4 = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
			((Object)val4).name = name;
			val4.transform.SetSiblingIndex(gameObject.transform.GetSiblingIndex() + 1);
			val = val4.transform;
			return (RectTransform)(object)((val is RectTransform) ? val : null);
		}

		private static Element GetElement(List<Element> elements, int x, int y)
		{
			int width = ((Humanoid)Player.m_localPlayer).GetInventory().GetWidth();
			return elements[y * width + x];
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem", new Type[]
	{
		typeof(InventoryGrid),
		typeof(ItemData),
		typeof(Vector2i),
		typeof(Modifier)
	})]
	public static class InventoryGui_OnSelectedItem_Patch
	{
		public static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod, GameObject ___m_dragGo, ItemData ___m_dragItem)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Invalid comparison between Unknown and I4
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterArchery.ConfigQuiverEnabled.Value)
			{
				return true;
			}
			BetterArchery.IsContainerOpen = __instance.IsContainerOpen();
			if (grid.m_inventory.m_name.Equals("Inventory") && BetterArchery.IsQuiverSlot(pos))
			{
				if (___m_dragItem != null && (int)___m_dragItem.m_shared.m_itemType == 9)
				{
					return true;
				}
				if (___m_dragItem != null && (int)___m_dragItem.m_shared.m_itemType != 9)
				{
					MessageHud.instance.ShowMessage((MessageType)2, "$mod_betterarchery_quiver_wrong_item_error", 0, (Sprite)null);
					return false;
				}
			}
			if (Object.op_Implicit((Object)(object)__instance.m_dragGo))
			{
				if (item != null && item.m_equipped && __instance.m_dragInventory != grid.GetInventory())
				{
					MessageHud.instance.ShowMessage((MessageType)2, "$mod_betterarchery_quiver_transfer_chest_error", 0, (Sprite)null);
					return false;
				}
				if (item != null && (int)___m_dragItem.m_shared.m_itemType == 9 && BetterArchery.IsQuiverSlot(___m_dragItem.m_gridPos))
				{
					BetterArchery.Log("$mod_betterarchery_quiver_item_swap_error");
					return false;
				}
			}
			if (___m_dragItem != null && ___m_dragItem.m_equipped && __instance.m_dragInventory != grid.GetInventory())
			{
				MessageHud.instance.ShowMessage((MessageType)2, "$mod_betterarchery_quiver_swap_chest_error", 0, (Sprite)null);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
	public static class InventoryGui_UpdateContainer_Patch
	{
		public static bool Prefix(InventoryGui __instance, Player player)
		{
			if (!BetterArchery.ConfigQuiverEnabled.Value)
			{
				return true;
			}
			BetterArchery.IsContainerOpen = Object.op_Implicit((Object)(object)__instance.m_currentContainer) && __instance.m_currentContainer.IsOwner();
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnDropOutside")]
	public static class InventoryGui_OnDropOutside_Patch
	{
		public static bool Prefix(GameObject ___m_dragGo, ItemData ___m_dragItem)
		{
			if (___m_dragItem != null && ___m_dragItem.m_equipped && BetterArchery.ConfigQuiverEnabled.Value && ((Object)___m_dragItem.m_dropPrefab).name.Contains("Quiver"))
			{
				MessageHud.instance.ShowMessage((MessageType)2, "$mod_betterarchery_quiver_drop_outside_error", 0, (Sprite)null);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnCraftPressed")]
	public static class InventoryGui_OnCraftPressed_Patch
	{
		public static void Prefix(InventoryGui __instance)
		{
			if (Object.op_Implicit((Object)(object)((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe))
			{
				__instance.m_craftRecipe = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe;
				if ((Object)(object)__instance.m_craftRecipe != (Object)null && ((Object)__instance.m_craftRecipe).name == "Recipe_ArrowWoodAnywhere")
				{
					__instance.m_craftDuration = 7f;
				}
				else
				{
					__instance.m_craftDuration = 2f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")]
	public static class InventoryGui_UpdateRecipeList_Patch
	{
		public static void Prefix(InventoryGui __instance, List<Recipe> recipes)
		{
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer.GetCurrentCraftingStation()))
			{
				Recipe val = recipes.Find((Recipe e) => ((Object)e).name == "Recipe_ArrowWoodAnywhere");
				if ((Object)(object)val != (Object)null)
				{
					recipes.Remove(val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Inventory), "HaveEmptySlot")]
	public static class Inventory_HaveEmptySlot_Patch
	{
		[HarmonyPriority(800)]
		public static bool Prefix(Inventory __instance, ref bool __result)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.GetName() != "Inventory" || !BetterArchery.ConfigQuiverEnabled.Value)
			{
				return true;
			}
			int num = __instance.m_width * __instance.m_height - 3 - 5;
			if (__instance.GetHeight() > 5)
			{
				num -= 8;
			}
			int num2 = __instance.m_inventory.Count;
			for (int i = 0; i < 3; i++)
			{
				Vector2i quiverSlotPosition = BetterArchery.GetQuiverSlotPosition(i);
				ItemData itemAt = __instance.GetItemAt(quiverSlotPosition.x, quiverSlotPosition.y);
				num2 -= ((itemAt != null) ? 1 : 0);
			}
			__result = num2 < num;
			return false;
		}
	}
	[HarmonyPatch(typeof(Inventory), "FindEmptySlot")]
	public static class Inventory_FindEmptySlot_Patch
	{
		[HarmonyPriority(800)]
		public static bool Prefix(Inventory __instance, ref Vector2i __result, bool topFirst, int ___m_height, int ___m_width)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.GetName() != "Inventory" || !BetterArchery.ConfigQuiverEnabled.Value)
			{
				return true;
			}
			if (topFirst)
			{
				int num = __instance.GetHeight() - 1;
				if (__instance.GetHeight() > 5)
				{
					num--;
				}
				for (int i = 0; i < num; i++)
				{
					for (int j = 0; j < ___m_width; j++)
					{
						if (__instance.GetItemAt(j, i) == null)
						{
							__result = new Vector2i(j, i);
							return false;
						}
					}
				}
			}
			else
			{
				int num2 = __instance.GetHeight() - 1;
				if (__instance.GetHeight() > 5)
				{
					num2--;
				}
				for (int k = 1; k < num2; k++)
				{
					for (int l = 0; l < ___m_width; l++)
					{
						if (__instance.GetItemAt(l, k) == null)
						{
							__result = new Vector2i(l, k);
							return false;
						}
					}
				}
			}
			__result = new Vector2i(-1, -1);
			return false;
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	public static class ObjectDB_CopyOtherDB_Patch
	{
		public static void Postfix()
		{
			BetterArchery.TryRegisterItems();
			BetterArchery.TryRegisterRecipes();
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	public static class ObjectDB_Awake_Patch
	{
		public static void Postfix()
		{
			BetterArchery.TryRegisterItems();
			BetterArchery.TryRegisterRecipes();
		}
	}
	public static class PlayerBody
	{
		public static Transform spine;

		public static Transform leftHand;

		public static bool onBowDrawing;
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	public static class Player_Awake_Patch
	{
		[HarmonyPriority(0)]
		private static void Prefix(ref Player __instance)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if (BetterArchery.ConfigQuiverEnabled.Value)
			{
				Traverse.Create((object)__instance).Field("m_inventory").SetValue((object)new Inventory("Inventory", (Sprite)null, 8, ((Humanoid)__instance).m_inventory.m_height + 2));
				BetterArchery.Log($"Inventory h: {((Humanoid)__instance).m_inventory.m_height}");
				BetterArchery.QuiverRowIndex = ((Humanoid)__instance).m_inventory.m_height - 1;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	public static class ModifyOnSpawned
	{
		private static void Prefix(Player __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			TutorialText item = new TutorialText
			{
				m_label = "BetterArchery",
				m_name = "betterarchery",
				m_text = "Thank you for using this mod! Don't forget to change configurations to get your own taste!",
				m_topic = "Welcome to BetterArchery"
			};
			if (!Tutorial.instance.m_texts.Contains(item))
			{
				Tutorial.instance.m_texts.Add(item);
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			localPlayer.ShowTutorial("betterarchery", false);
			if (BetterArchery.ConfigQuiverEnabled.Value)
			{
				foreach (ItemData equippedItem in ((Humanoid)__instance).m_inventory.GetEquippedItems())
				{
					if (CustomSlotCreator.IsCustomSlotItem(equippedItem))
					{
						equippedItem.m_equipped = true;
					}
					equippedItem.m_equipped = true;
				}
			}
			if (!BetterArchery.BowZoomSFXEnabled.Value)
			{
				return;
			}
			try
			{
				BetterArchery.PlayerAudioSource = ((Component)((Component)localPlayer).transform).gameObject.AddComponent<AudioSource>();
				((Component)((Component)localPlayer).transform).gameObject.AddComponent<ZSFX>();
			}
			catch (Exception ex)
			{
				BetterArchery.Log(ex.ToString(), 0);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "LateUpdate")]
	public static class Player_LateUpdate_Patch
	{
		public static float spineTimer = 0.5f;

		private static void Postfix(Player __instance, Transform ___m_head, ref Rigidbody ___m_body, ref VisEquipment ___m_visEquipment, ItemData ___m_rightItem, ItemData ___m_leftItem)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Invalid comparison between Unknown and I4
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: 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)
			if ((Object)(object)Player.m_localPlayer != (Object)(object)__instance)
			{
				return;
			}
			if ((Object)(object)PlayerBody.spine == (Object)null)
			{
				PlayerBody.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) && PlayerBody.onBowDrawing)
			{
				spineTimer = 0.5f;
				rotation = ((Component)((Character)__instance).m_eye).transform.rotation;
				float num = ((Quaternion)(ref rotation)).eulerAngles.y + 90f;
				Transform spine = PlayerBody.spine;
				rotation = PlayerBody.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 (spineTimer > 0f)
			{
				spineTimer -= Time.deltaTime;
				rotation = ((Component)((Character)__instance).m_eye).transform.rotation;
				float num2 = ((Quaternion)(ref rotation)).eulerAngles.y + 90f;
				Transform spine2 = PlayerBody.spine;
				rotation = PlayerBody.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(typeof(Player), "UseHotbarItem")]
	public static class Player_UseHotbarItem_Patch
	{
		public static bool Prefix(Player __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterArchery.ConfigQuiverEnabled.Value)
			{
				return true;
			}
			KeyboardShortcut value = BetterArchery.HoldingKeyCode.Value;
			if (!string.IsNullOrEmpty(((KeyboardShortcut)(ref value)).Serialize()))
			{
				value = BetterArchery.HoldingKeyCode.Value;
				if (((KeyboardShortcut)(ref value)).Serialize() != "None")
				{
					value = BetterArchery.HoldingKeyCode.Value;
					if (Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
					{
						return false;
					}
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "QueueUnequipAction")]
	public static class Player_QueueUnequipAction_Patch
	{
		public static bool Prefix(ItemData item, Player __instance)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterArchery.ConfigQuiverEnabled.Value)
			{
				return true;
			}
			if (((Object)item.m_dropPrefab).name.Contains("Quiver"))
			{
				Inventory inventory = ((Humanoid)Player.m_localPlayer).m_inventory;
				foreach (ItemData item2 in inventory.m_inventory)
				{
					if (BetterArchery.IsQuiverSlot(item2.m_gridPos) && item2.GetWeight(-1) > 0f)
					{
						MessageHud.instance.ShowMessage((MessageType)2, "$mod_betterarchery_quiver_unequip_error", 0, (Sprite)null);
						return false;
					}
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "SetControls")]
	public static class Player_SetControls_Patch
	{
		private static void Prefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool block, ref bool blockHold, ref bool jump, ref bool crouch, ref bool run, ref bool autoRun)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterArchery.ConfigBowZoomEnabled.Value)
			{
				return;
			}
			if (attackHold)
			{
				KeyboardShortcut value = BetterArchery.BowDrawCancelKey.Value;
				if (Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
				{
					blockHold = true;
				}
				else
				{
					blockHold = false;
				}
			}
			else
			{
				ItemData leftItem = ((Humanoid)__instance).GetLeftItem();
				if (leftItem != null && ((Object)leftItem.m_dropPrefab).name.Contains("Bow") && BetterArchery.__ZoomState == BetterArchery.ZoomState.ZoomingIn)
				{
					blockHold = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "GetCameraPosition")]
	public static class Player_GameCamera_Patch
	{
		[HarmonyPriority(100)]
		private static void Postfix(GameCamera __instance, float dt, Vector3 pos, Quaternion rot)
		{
			if (!((Object)(object)__instance == (Object)null) && BetterArchery.ConfigBowZoomEnabled.Value && BetterArchery.__BaseFov == 0f)
			{
				BetterArchery.__BaseFov = __instance.m_fov;
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
	public static class Player_GameCamera_UpdateCamera
	{
		[HarmonyPriority(0)]
		public static void Prefix(GameCamera __instance)
		{
			if (BetterArchery.ConfigBowZoomEnabled.Value && (BetterArchery.__ZoomState == BetterArchery.ZoomState.ZoomingOut || BetterArchery.__ZoomState == BetterArchery.ZoomState.ZoomingIn))
			{
				__instance.m_fov = BetterArchery.__NewZoomFov;
			}
		}
	}
	[HarmonyPriority(0)]
	[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
	public static class Player_UpdateCrosshair_Patch
	{
		private static void Postfix(Hud __instance, Player player, float bowDrawPercentage)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Invalid comparison between Unknown and I4
			//IL_0137: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			if (((Behaviour)__instance.m_crosshair).enabled != BetterArchery.IsCrosshairVisible.Value)
			{
				((Behaviour)__instance.m_crosshair).enabled = BetterArchery.IsCrosshairVisible.Value;
			}
			if (((Behaviour)__instance.m_crosshairBow).enabled != BetterArchery.IsBowCrosshairVisible.Value)
			{
				((Behaviour)__instance.m_crosshairBow).enabled = BetterArchery.IsBowCrosshairVisible.Value;
			}
			PlayerBody.onBowDrawing = bowDrawPercentage > 0.1f;
			if (BetterArchery.BowDrawMovementSpeedReductionEnabled.Value)
			{
				if (PlayerBody.onBowDrawing)
				{
					((Character)player).SetWalk(true);
					BetterArchery.SpeedReduction = true;
				}
				else if (((Character)player).GetWalk() && BetterArchery.SpeedReduction)
				{
					BetterArchery.SpeedReduction = false;
					((Character)player).SetWalk(false);
				}
			}
			if (!BetterArchery.ConfigBowZoomEnabled.Value || BetterArchery.__BaseFov == 0f)
			{
				return;
			}
			ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
			if (currentWeapon == null || (int)currentWeapon.m_shared.m_itemType != 4)
			{
				ZoomOut();
				return;
			}
			float skillFactor = ((Character)player).GetSkillFactor(currentWeapon.m_shared.m_skillType);
			float num = 2f * (1f - skillFactor);
			if (num <= 0.1f)
			{
				num = 0.1f;
			}
			KeyboardShortcut value = BetterArchery.BowZoomKey.Value;
			bool key = Input.GetKey(((KeyboardShortcut)(ref value)).MainKey);
			if (BetterArchery.__ZoomState == BetterArchery.ZoomState.ZoomingIn && !BetterArchery.ZoomSfx)
			{
				BetterArchery.PlayCustomSFX("inhale", checkIfPlaying: false);
				BetterArchery.ZoomSfx = true;
			}
			else if (BetterArchery.__ZoomState == BetterArchery.ZoomState.ZoomingOut && BetterArchery.ZoomSfx)
			{
				BetterArchery.PlayCustomSFX("exhale", checkIfPlaying: false);
				BetterArchery.ZoomSfx = false;
			}
			if (BetterArchery.AutomaticBowZoom.Value)
			{
				if (bowDrawPercentage > 0.01f)
				{
					BetterArchery.ZoomInTimer += Time.deltaTime;
					BetterArchery.__ZoomState = BetterArchery.ZoomState.ZoomingIn;
					float num2 = ((!(BetterArchery.BowZoomConstantTime.Value > 0f)) ? Mathf.InverseLerp(0.05f, num, BetterArchery.ZoomInTimer) : Mathf.InverseLerp(0.05f, BetterArchery.BowZoomConstantTime.Value, BetterArchery.ZoomInTimer));
					GameCamera.instance.m_fov = (BetterArchery.__LastZoomFov = Mathf.Lerp(BetterArchery.__BaseFov, BetterArchery.__BaseFov / BetterArchery.BowZoomFactor.Value, num2));
					BetterArchery.__NewZoomFov = (BetterArchery.__LastZoomFov = Mathf.Lerp(BetterArchery.__BaseFov, BetterArchery.__BaseFov / BetterArchery.BowZoomFactor.Value, num2));
					return;
				}
				ZoomOut();
			}
			if (key)
			{
				if (!PlayerBody.onBowDrawing)
				{
					BetterArchery.ZoomOutDelayTimer += Time.deltaTime;
					if (BetterArchery.ZoomOutDelayTimer > BetterArchery.StayInZoomTime.Value)
					{
						ZoomOut();
					}
				}
				else
				{
					BetterArchery.ZoomInTimer += Time.deltaTime;
					BetterArchery.ZoomOutDelayTimer = 0f;
					BetterArchery.__ZoomState = BetterArchery.ZoomState.ZoomingIn;
					float num3 = ((!(BetterArchery.BowZoomConstantTime.Value > 0f)) ? Mathf.InverseLerp(0.05f, num, BetterArchery.ZoomInTimer) : Mathf.InverseLerp(0.05f, BetterArchery.BowZoomConstantTime.Value, BetterArchery.ZoomInTimer));
					GameCamera.instance.m_fov = (BetterArchery.__LastZoomFov = Mathf.Lerp(BetterArchery.__BaseFov, BetterArchery.__BaseFov / BetterArchery.BowZoomFactor.Value, num3));
					BetterArchery.__NewZoomFov = (BetterArchery.__LastZoomFov = Mathf.Lerp(BetterArchery.__BaseFov, BetterArchery.__BaseFov / BetterArchery.BowZoomFactor.Value, num3));
				}
			}
			else
			{
				BetterArchery.ZoomOutDelayTimer = 1f;
				ZoomOut();
			}
		}

		public static void ZoomOut()
		{
			if (BetterArchery.__ZoomState != 0)
			{
				if (BetterArchery.__ZoomState == BetterArchery.ZoomState.ZoomingIn)
				{
					BetterArchery.__ZoomState = BetterArchery.ZoomState.ZoomingOut;
					BetterArchery.ZoomOutTimer = 0f;
					BetterArchery.ZoomInTimer = 0f;
				}
				else
				{
					BetterArchery.ZoomOutTimer += Time.deltaTime;
					if (BetterArchery.ZoomOutTimer > 1f)
					{
						GameCamera.instance.m_fov = BetterArchery.__BaseFov;
						BetterArchery.__ZoomState = BetterArchery.ZoomState.Fixed;
						BetterArchery.ZoomOutDelayTimer = 0f;
						return;
					}
				}
				float num = Mathf.InverseLerp(0f, 0.3f, BetterArchery.ZoomOutTimer);
				GameCamera.instance.m_fov = Mathf.Lerp(BetterArchery.__LastZoomFov, BetterArchery.__BaseFov, num);
				BetterArchery.__NewZoomFov = Mathf.Lerp(BetterArchery.__LastZoomFov, BetterArchery.__BaseFov, num);
			}
			else if (GameCamera.instance.m_fov != BetterArchery.__BaseFov)
			{
				GameCamera.instance.m_fov = BetterArchery.__BaseFov;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "CreateTombStone")]
	public static class Player_CreateTombStone_Patch
	{
		public static bool Prefix(Player __instance)
		{
			//IL_0041: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			if (((Humanoid)__instance).GetInventory().GetAllItems().Count == 0)
			{
				return true;
			}
			if (!BetterArchery.IsQuiverEquipped())
			{
				return true;
			}
			GameObject val = Object.Instantiate<GameObject>(__instance.m_tombstone, ((Character)__instance).GetCenterPoint() + Vector3.up + ((Component)__instance).transform.forward * -0.5f, ((Component)__instance).transform.rotation);
			TombStone component = val.GetComponent<TombStone>();
			PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
			string name = playerProfile.GetName();
			long playerID = playerProfile.GetPlayerID();
			component.Setup(name + "'s Quiver", playerID);
			Container component2 = val.GetComponent<Container>();
			Inventory inventory = component2.GetInventory();
			Inventory inventory2 = ((Humanoid)__instance).GetInventory();
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData item in inventory2.m_inventory)
			{
				if (!BetterArchery.IsQuiverSlot(item.m_gridPos))
				{
					list.Add(item);
					continue;
				}
				Vector2i val2 = inventory.FindEmptySlot(false);
				inventory.AddItem(item, item.m_stack, val2.x, val2.y);
			}
			inventory2.m_inventory = list;
			inventory2.Changed();
			inventory.Changed();
			return true;
		}
	}
	[HarmonyPatch(typeof(Projectile), "Setup")]
	public static class RetrieveArrows
	{
		public static bool Prefix(ref Projectile __instance, Character owner, Vector3 velocity, float hitNoise, HitData hitData, ItemData item)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Invalid comparison between Unknown and I4
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || item == null)
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)owner != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if ((!((Object)__instance).name.Contains("bow_projectile") && !((Object)__instance).name.Contains("arbalest_projectile")) || (int)item.m_shared.m_itemType != 4)
			{
				return true;
			}
			if (BetterArchery.ConfigArrowImprovementsEnabled.Value)
			{
				__instance.m_gravity = BetterArchery.ArrowGravity.Value;
			}
			if (!BetterArchery.ConfigRetrievableArrowsEnabled.Value)
			{
				return true;
			}
			string arrowType = ((Object)((Humanoid)localPlayer).GetAmmoItem().m_dropPrefab).name;
			if (string.IsNullOrEmpty(arrowType))
			{
				return true;
			}
			Arrow arrow = BetterArchery.ArrowRetrieves.Find((Arrow e) => e.Name == arrowType);
			if (arrow == null)
			{
				return true;
			}
			float num = Random.Range(0f, 1f);
			BetterArchery.Log($"m_dropPrefab: {arrowType}, x.SpawnChance: {arrow.SpawnChance}, x.SpawnArrow: {arrow.SpawnArrow}");
			BetterArchery.Log($"spawnChance: {num}, currentArrow.SpawnChance: {arrow.SpawnChance}, spawned: {num < arrow.SpawnChance}");
			if (num < arrow.SpawnChance)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(arrow.SpawnArrow);
				if (BetterArchery.ArrowAutoPickup.Value)
				{
					__instance.m_spawnRandomRotation = false;
					__instance.m_spawnFacingRotation = false;
					Projectile obj = __instance;
					obj.m_spawnOffset += new Vector3(0f, 0.5f, 0f);
					__instance.m_spawnOnHitChance = 1f;
					__instance.m_spawnOnHit = itemPrefab;
					__instance.m_hideOnHit = ((Component)__instance).gameObject;
				}
				else
				{
					Pickable val = ((Component)__instance).gameObject.AddComponent<Pickable>();
					val.m_hideWhenPicked = ((Component)__instance).gameObject;
					val.m_amount = 1;
					val.m_itemPrefab = itemPrefab;
				}
			}
			else if (BetterArchery.ArrowDisappearOnHit.Value)
			{
				__instance.m_hideOnHit = ((Component)__instance).gameObject;
			}
			else
			{
				__instance.m_stayTTL = BetterArchery.ArrowDisappearTime.Value;
				if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponentInChildren<MeshRenderer>()))
				{
					((Renderer)((Component)__instance).GetComponentInChildren<MeshRenderer>()).material.color = Color.black;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnHit")]
	public static class Projectile_OnHit_Patch
	{
		public static void Prefix(Projectile __instance, Collider collider, Vector3 hitPoint, bool water)
		{
			if (!BetterArchery.ConfigRetrievableArrowsEnabled.Value || !Object.op_Implicit((Object)(object)((Component)__instance).gameObject.GetComponent<Pickable>()) || (!((Object)__instance).name.Contains("bow_projectile") && !((Object)__instance).name.Contains("arbalest_projectile")))
			{
				return;
			}
			GameObject val = (Object.op_Implicit((Object)(object)collider) ? Projectile.FindHitObject(collider) : null);
			bool flag = false;
			IDestructible val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<IDestructible>() : null);
			if (val2 != null)
			{
				flag = val2 is Character;
				if (!__instance.IsValidTarget(val2))
				{
					return;
				}
			}
			BoxCollider val3 = null;
			val3 = ((((Object)__instance).name == "bow_projectile_needle(Clone)") ? ((Component)((Component)((Component)__instance).transform.GetChild(0)).gameObject.transform.GetChild(0)).gameObject.AddComponent<BoxCollider>() : ((!(((Object)__instance).name == "bow_projectile_frost(Clone)")) ? ((Component)((Component)__instance).transform.GetChild(0)).gameObject.AddComponent<BoxCollider>() : ((Component)((Component)__instance).transform.GetChild(3)).gameObject.AddComponent<BoxCollider>()));
			if ((Object)(object)val3 != (Object)null)
			{
				((Collider)val3).enabled = true;
				__instance.m_stayTTL = BetterArchery.ArrowDisappearTime.Value;
			}
		}
	}
	[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
	public static class Attack_FireProjectileBurst_Patch
	{
		public static bool Prefix(ref Attack __instance)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			if (!((Character)__instance.m_character).IsPlayer() || !BetterArchery.ConfigArrowImprovementsEnabled.Value)
			{
				return true;
			}
			ItemData ammoItem = ((Humanoid)Player.m_localPlayer).m_ammoItem;
			ItemData leftItem = ((Humanoid)Player.m_localPlayer).GetLeftItem();
			if (leftItem == null)
			{
				return true;
			}