Decompiled source of ImpactfulSkills v0.5.3

plugins/ImpactfulSkills.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ImpactfulSkills.patches;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ImpactfulSkills")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ImpactfulSkills")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.5.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.5.3.0")]
namespace ImpactfulSkills
{
	internal class ValConfig
	{
		public static ConfigFile cfg;

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<bool> EnableWoodcutting;

		public static ConfigEntry<float> WoodCuttingDmgMod;

		public static ConfigEntry<float> WoodCuttingLootFactor;

		public static ConfigEntry<bool> EnableMining;

		public static ConfigEntry<float> MiningDmgMod;

		public static ConfigEntry<float> MiningLootFactor;

		public static ConfigEntry<float> MiningAOERange;

		public static ConfigEntry<float> MiningAOELevel;

		public static ConfigEntry<bool> EnableMiningAOE;

		public static ConfigEntry<bool> EnableMiningRockBreaker;

		public static ConfigEntry<float> RockBreakerMaxChance;

		public static ConfigEntry<int> RockBreakerRequiredLevel;

		public static ConfigEntry<float> RockBreakerDamage;

		public static ConfigEntry<int> MinehitsPerInterval;

		public static ConfigEntry<bool> EnableStealth;

		public static ConfigEntry<float> SneakSpeedFactor;

		public static ConfigEntry<float> SneakNoiseReductionLevel;

		public static ConfigEntry<float> SneakNoiseReductionFactor;

		public static ConfigEntry<bool> EnableSneakBonusDamage;

		public static ConfigEntry<int> SneakBackstabBonusLevel;

		public static ConfigEntry<float> SneakBackstabBonusFactor;

		public static ConfigEntry<bool> EnableRun;

		public static ConfigEntry<float> RunSpeedFactor;

		public static ConfigEntry<bool> EnableAnimalWhisper;

		public static ConfigEntry<float> AnimalTamingSpeedFactor;

		public static ConfigEntry<float> TamedAnimalLootIncreaseFactor;

		public static ConfigEntry<bool> EnableGathering;

		public static ConfigEntry<float> GatheringLuckFactor;

		public static ConfigEntry<float> GatheringRangeFactor;

		public static ConfigEntry<int> FarmingRangeRequiredLevel;

		public static ConfigEntry<string> GatheringLuckLevels;

		public static ConfigEntry<string> GatheringDisallowedItems;

		public static ConfigEntry<bool> EnableVoyager;

		public static ConfigEntry<int> VoyagerSkillXPCheckFrequency;

		public static ConfigEntry<float> VoyagerReduceCuttingStart;

		public static ConfigEntry<float> VoyagerSailingSpeedFactor;

		public static ConfigEntry<float> VoyagerIncreaseExplorationRadius;

		public static ConfigEntry<float> VoyagerPaddleSpeedBonus;

		public static ConfigEntry<float> VoyagerPaddleSpeedBonusLevel;

		public static ConfigEntry<bool> EnableWeaponSkill;

		public static ConfigEntry<float> WeaponSkillStaminaReduction;

		public static ConfigEntry<float> WeaponSkillBowDrawStaminaCostReduction;

		public static ConfigEntry<float> WeaponSkillParryBonus;

		public static ConfigEntry<bool> EnableCooking;

		public static ConfigEntry<float> CookingBurnReduction;

		public static ConfigEntry<bool> EnableCrafting;

		public static ConfigEntry<int> CraftingMaxBonus;

		public static ConfigEntry<float> CraftingBonusChance;

		public static ConfigEntry<bool> EnableBonusItemCrafting;

		public static ConfigEntry<bool> EnableCraftBonusAsFraction;

		public static ConfigEntry<float> CraftBonusFractionOfCraftNumber;

		public static ConfigEntry<int> CraftingBonusCraftsLevel;

		public static ConfigEntry<bool> EnableMaterialReturns;

		public static ConfigEntry<int> CraftingMaterialReturnsLevel;

		public static ConfigEntry<float> MaxCraftingMaterialReturnPercent;

		public static ConfigEntry<float> ChanceForMaterialReturn;

		public static ConfigEntry<bool> EnableBloodMagic;

		public static ConfigEntry<float> BloodMagicXPForShieldDamageRatio;

		public static ConfigEntry<float> BloodMagicXP;

		public static ConfigEntry<bool> EnableKnowledgeSharing;

		public static ConfigEntry<float> AnimalTamingSkillGainRate;

		public static ConfigEntry<float> VoyagerSkillGainRate;

		public static ConfigEntry<float> SharedKnowledgeSkillBonusRate;

		public static ConfigEntry<float> SharedKnowledgeCap;

		public static ConfigEntry<string> SharedKnowledgeIgnoreList;

		public ValConfig(ConfigFile cf)
		{
			cfg = cf;
			cfg.SaveOnConfigSet = true;
			CreateConfigValues(cf);
			Logger.setDebugLogging(EnableDebugMode.Value);
		}

		private void CreateConfigValues(ConfigFile Config)
		{
			//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_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
			EnableDebugMode.SettingChanged += Logger.enableDebugLogging;
			EnableWoodcutting = BindServerConfig("Woodcutting", "EnableWoodcutting", value: true, "Enable woodcutting skill changes.");
			WoodCuttingDmgMod = BindServerConfig("Woodcutting", "WoodCuttingDmgMod", 1.2f, "How much skill levels impact your chop damage.");
			WoodCuttingLootFactor = BindServerConfig("Woodcutting", "WoodCuttingLootFactor", 3f, "How much the woodcutting skill provides additional loot. 2 is 2x the loot at level 100.", advanced: false, 1f, 10f);
			EnableMining = BindServerConfig("Mining", "EnableMining", value: true, "Enable mining skill changes.");
			MiningDmgMod = BindServerConfig("Mining", "MiningDmgMod", 1.2f, "How much your skill levels impact mining damage.");
			MiningLootFactor = BindServerConfig("Mining", "MiningLootFactor", 2f, "How much the mining skill provides additional loot. 2 is 2x the loot at level 100.");
			EnableMiningAOE = BindServerConfig("Mining", "EnableMiningAOE", value: true, "Enable AOE mining skill changes.");
			MiningAOERange = BindServerConfig("Mining", "MiningAOERange", 2f, "How far away the mining AOE is applied. How far away an AOE hit is applied.", advanced: false, 0.5f, 10f);
			MiningAOELevel = BindServerConfig("Mining", "MiningAOELevel", 50f, "The level that AOE mining requires to activate. What skill level Mining AOE is enabled at.", advanced: false, 0f, 100f);
			EnableMiningRockBreaker = BindServerConfig("Mining", "EnableMiningRockBreaker", value: true, "Enable mining whole veins, by a (small) chance.");
			RockBreakerMaxChance = BindServerConfig("Mining", "RockBreakerMaxChance", 0.05f, "The maximum chance to break a whole vein. 0.05 is 5% chance to break a whole vein at level 100. This is checked on each hit.", advanced: false, 0f, 1f);
			RockBreakerRequiredLevel = BindServerConfig("Mining", "RockBreakerRequiredLevel", 75, "The level that vein breaking requires to activate. What skill level whole rocks breaking is enabled at.", advanced: false, 0, 100);
			RockBreakerDamage = BindServerConfig("Mining", "RockBreakerDamage", 300f, "Veinbreakers damage, small damage numbers will mean triggering this will not destroy a whole vein, but massively weaken it. Large numbers will ensure the whole vein is destroyed.", advanced: false, 0f, 10000f);
			MinehitsPerInterval = BindServerConfig("Mining", "MinehitsPerInterval", 2, "The number of pieces per interval to break when mining large rocks.", advanced: true, 1, 100);
			EnableRun = BindServerConfig("Run", "EnableRun", value: true, "Enable run skill changes.");
			RunSpeedFactor = BindServerConfig("Run", "RunSpeedFactor", 0.005f, "How much the run speed is increased based on your run level. Amount applied per level, 0.005 will make level 100 run give 50% faster running.", advanced: false, 0.001f, 0.06f);
			EnableCrafting = BindServerConfig("Crafting", "EnableCrafting", value: true, "Enable crafting skill changes.");
			EnableBonusItemCrafting = BindServerConfig("Crafting", "EnableBonusItemCrafting", value: true, "Enables crafting bonus items.");
			CraftingBonusCraftsLevel = BindServerConfig("Crafting", "CraftingBonusCraftsLevel", 25, "The level at which you can start getting bonus crafts.", advanced: false, 0, 100);
			CraftingMaxBonus = BindServerConfig("Crafting", "CraftingMaxBonus", 3, "The maximum number of additional bonus crafts you can get from crafting an item");
			CraftingBonusChance = BindServerConfig("Crafting", "CraftingBonusChance", 0.3f, "The chance to get a bonus craft when crafting an item. 0.5 is a 50% chance to get a bonus craft at level 100. Bonus crafting success can stack up to the CraftingMaxBonus times.");
			EnableCraftBonusAsFraction = BindServerConfig("Crafting", "EnableCraftBonusAsFraction", value: true, "Enable crafting bonus as a fraction of the number crafted (for recipes where the result is more than 1). If disabled, the bonus is always 1 item.");
			CraftBonusFractionOfCraftNumber = BindServerConfig("Crafting", "CraftBonusFractionOfCraftNumber", 0.25f, "If the number of items crafted by the recipe is greater than 1, a percentage of the number crafted is used for the bonus. This determines that percentage. Eg: craft 20 arrows (1 craft) a .25 value would give you 5 arrows for 1 bonus craft.");
			EnableMaterialReturns = BindServerConfig("Crafting", "EnableMaterialReturns", value: true, "Enable material returns from crafting.");
			CraftingMaterialReturnsLevel = BindServerConfig("Crafting", "CraftingMaterialReturnsLevel", 50, "The level at which material returns start being applied based on your skill", advanced: false, 0, 100);
			MaxCraftingMaterialReturnPercent = BindServerConfig("Crafting", "MaxCraftingMaterialReturnPercent", 0.3f, "The maximum percentage of materials that can be returned from crafting. 0.5 is 50% at level 100.", advanced: false, 0f, 1f);
			ChanceForMaterialReturn = BindServerConfig("Crafting", "ChanceForMaterialReturn", 0.15f, "The chance to return materials when crafting an item. 0.25 is a 25% chance to return materials at level 100.", advanced: false, 0f, 1f);
			EnableCooking = BindServerConfig("Cooking", "EnableCooking", value: true, "Enable cooking skill changes.");
			CookingBurnReduction = BindServerConfig("Cooking", "CookingBurnReduction", 0.5f, "How much offset is applied to diminishing returns for food, scaled by the players cooking skill. At 1 and cooking 100 food never degrades.", advanced: false, 0.1f, 1f);
			EnableBloodMagic = BindServerConfig("BloodMagic", "EnableBloodMagic", value: true, "Enable blood magic skill changes.");
			BloodMagicXPForShieldDamageRatio = BindServerConfig("BloodMagic", "BloodMagicXPForShieldDamageRatio", 50f, "How much XP is gained for shield damage. 50 is once every 50 damage.", advanced: false, 1f, 200f);
			BloodMagicXP = BindServerConfig("BloodMagic", "BloodMagicXP", 1f, "How much XP is gained, used by other blood magic skill settings.", advanced: false, 0.1f, 10f);
			EnableStealth = BindServerConfig("Sneak", "EnableStealth", value: true, "Enable sneak skill changes.");
			SneakSpeedFactor = BindServerConfig("Sneak", "SneakSpeedFactor", 0.03f, "How much sneak speed is increased based on your sneak level. Amount applied per level, 0.03 will make level 100 sneak give normal walkspeed while sneaking.", advanced: false, 0.001f, 0.06f);
			SneakNoiseReductionLevel = BindServerConfig("Sneak", "SneakNoiseReductionLevel", 50f, "The level at which noise reduction starts being applied based on your skill", advanced: false, 0f, 100f);
			SneakNoiseReductionFactor = BindServerConfig("Sneak", "SneakNoiseReductionFactor", 0.5f, "How much noise is reduced based on your sneak level. Amount applied per level, 0.5 will make level 100 sneak give 50% less noise.", advanced: false, 0.1f, 1f);
			EnableSneakBonusDamage = BindServerConfig("Sneak", "EnableSneakBonusDamage", value: true, "Enable sneak bonus damage changes.");
			SneakBackstabBonusLevel = BindServerConfig("Sneak", "SneakBackstabBonusLevel", 25, "The level at which backstab damage starts being applied based on your skill", advanced: false, 0, 100);
			SneakBackstabBonusFactor = BindServerConfig("Sneak", "SneakBackstabBonusFactor", 2f, "How much backstab damage is increased based on your sneak level. 1 is a 100% bonus backstab damage at skill level 100.", advanced: false, 0.1f, 10f);
			EnableAnimalWhisper = BindServerConfig("AnimalHandling", "EnableAnimalWhisper", value: true, "Enable animal handling skill changes.");
			AnimalTamingSpeedFactor = BindServerConfig("AnimalHandling", "AnimalTamingSpeedFactor", 6f, "How much your animal handling skill impacts taming speed. 6 is 6x taming speed at level 100 (5 minutes vs 30 minutes default)", advanced: false, 1f, 10f);
			TamedAnimalLootIncreaseFactor = BindServerConfig("AnimalHandling", "TamedAnimalLootIncreaseFactor", 3f, "How much the animal handling skill improves your loot from tamed creatures. 3 is 3x the loot at level 100", advanced: false, 1f, 10f);
			EnableGathering = BindServerConfig("Farming", "EnableGathering", value: true, "Enable gathering skill changes.");
			GatheringLuckFactor = BindServerConfig("Farming", "GatheringLuckFactor", 0.5f, "How much luck impacts gathering. Each level gives you a small chance to get better loot.", advanced: false, 0.1f, 5f);
			GatheringRangeFactor = BindServerConfig("Farming", "GatheringRangeFactor", 5f, "AOE gathering range you have at level 100.", advanced: false, 3f, 25f);
			FarmingRangeRequiredLevel = BindServerConfig("Farming", "GatheringRangeRequiredLevel", 50, "The level that AOE gathering requires to activate.", advanced: false, 0, 100);
			GatheringLuckLevels = BindServerConfig("Farming", "GatheringLuckLevels", "30,50,70,90,100", "The Luck levels that you can roll additional loot at. These should be between 0-100. But can be assigned in any way or number- such as 0,10,10,10,100.");
			GatheringDisallowedItems = BindServerConfig("Farming", "GatheringDisallowedItems", "SurtlingCore,Flint,Wood,Branch,Stone,Amber,AmberPearl,Coins,Ruby,CryptRemains,Obsidian,Crystal,Pot_Shard,DragonEgg,DvergrLantern,DvergrMineTreasure,SulfurRock,VoltureEgg,Swordpiece,MoltenCore,Hairstrands,Tar,BlackCore", "Items which can be picked, but do not get a luck roll for multiple loot and will not be auto-picked.");
			EnableVoyager = BindServerConfig("Voyager", "EnableVoyager", value: true, "Enable voyager skill changes.");
			VoyagerSkillXPCheckFrequency = BindServerConfig("Voyager", "VoyagerSkillXPCheckFrequency", 5, "How often Voyager skill can be increased while sailing. Rate varies based on your game physics engine speed.", advanced: false, 5, 200);
			VoyagerReduceCuttingStart = BindServerConfig("Voyager", "VoyagerReduceCuttingStart", 50f, "The level that the player starts to reduce the penalty of not having the wind at your back.", advanced: false, 0f, 100f);
			VoyagerSailingSpeedFactor = BindServerConfig("Voyager", "VoyagerSailingSpeedFactor", 1f, "How much the sailing speed is increased based on your voyager level. Amount applied per level, 2 will make level 100 voyager give 100% faster sailing.", advanced: false, 1f, 20f);
			VoyagerIncreaseExplorationRadius = BindServerConfig("Voyager", "VoyagerIncreaseExplorationRadius", 1.5f, "How much the exploration radius is increased based on your voyager level. Amount applied per level, 1 will make level 100 voyager give 100% more exploration radius.", advanced: false, 0f, 20f);
			VoyagerPaddleSpeedBonus = BindServerConfig("Voyager", "VoyagerPaddleSpeedBonus", 2f, "How much the paddle speed is increased based on your voyager level. 1 is a 100% bonus at level 100", advanced: false, 0.01f, 5f);
			VoyagerPaddleSpeedBonusLevel = BindServerConfig("Voyager", "VoyagerPaddleSpeedBonusLevel", 25f, "The level that the player starts to get a bonus to paddle speed.", advanced: false, 0f, 100f);
			EnableWeaponSkill = BindServerConfig("WeaponSkills", "EnableWeaponSkill", value: true, "Enable weapon skill changes.");
			WeaponSkillStaminaReduction = BindServerConfig("WeaponSkills", "WeaponSkillStaminaReduction", 0.5f, "How much stamina is reduced based on your weapon skill level at level 100. 0.5 will make level 100 weapon skill give 50% less stamina cost.", advanced: false, 0f, 1f);
			WeaponSkillParryBonus = BindServerConfig("WeaponSkills", "WeaponSkillParryBonus", 1f, "How much extra XP you get for parrying an attack", advanced: false, 0f, 10f);
			WeaponSkillBowDrawStaminaCostReduction = BindServerConfig("WeaponSkills", "WeaponSkillBowDrawStaminaCostReduction", 0.5f, "How much stamina is reduced based on your weapon skill level at level 100. 0.5 will make level 100 weapon skill give 50% less stamina cost. Vanilla is .33", advanced: false, 0f, 1f);
			EnableKnowledgeSharing = BindServerConfig("SkillRates", "EnableKnowledgeSharing", value: true, "Enable shared knowledge, this allows you to gain faster experiance in low skills if you already have other high skills (eg switching primary weapon skill).");
			AnimalTamingSkillGainRate = BindServerConfig("SkillRates", "AnimalTamingSkillGainRate", 1f, "How fast the skill is gained.", advanced: false, 1f, 10f);
			VoyagerSkillGainRate = BindServerConfig("SkillRates", "VoyagerSkillGainRate", 1f, "How fast the skill is gained.", advanced: false, 1f, 10f);
			SharedKnowledgeSkillBonusRate = BindServerConfig("SkillRates", "SharedKnowledgeSkillBonusRate", 1.5f, "How strong at maximum the xp bonus from shared knowledge will be when catching up skills lower than your highest.", advanced: false, 0f, 10f);
			SharedKnowledgeCap = BindServerConfig("SkillRates", "SharedKnowledgeCap", 5f, "The number of levels below your maximum skill that shared knowledge stops providing a bonus at. Eg: max skill 90, at 5 any skills 85+ will not recieve an xp bonus.", advanced: true, 0f, 50f);
			SharedKnowledgeIgnoreList = BindServerConfig("SkillRates", "SharedKnowledgeIgnoreList", "", "Comma separated list of skills to ignore when calculating shared knowledge. This is useful for skills that have vastly different XP curves or that you simply do not want an accelerated growth rate in. Invalid skill names will be ignored.");
			SharedKnowledgeIgnoreList.SettingChanged += SharedKnowledge.UnallowedSharedXPSkillTypesChanged;
		}

		public static ConfigEntry<float[]> BindServerConfig(string catagory, string key, float[] value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float[]>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<int> BindServerConfig(string catagory, string key, int value, string description, bool advanced = false, int valmin = 0, int valmax = 150)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<int>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_0016: 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)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void setDebugLogging(bool state)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (state)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				ImpactfulSkills.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				ImpactfulSkills.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				ImpactfulSkills.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				ImpactfulSkills.Log.LogError((object)message);
			}
		}
	}
	[BepInPlugin("MidnightsFX.ImpactfulSkills", "ImpactfulSkills", "0.5.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("blacks7ar.SNEAKer")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class ImpactfulSkills : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.ImpactfulSkills";

		public const string PluginName = "ImpactfulSkills";

		public const string PluginVersion = "0.5.3";

		public ValConfig cfg;

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		internal static AssetBundle EmbeddedResourceBundle;

		public static ManualLogSource Log;

		public void Awake()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("ImpactfulSkills.AssetsEmbedded.impactfulskills", typeof(ImpactfulSkills).Assembly);
			AddLocalizations();
			Gathering.SetupGatherables();
			AnimalWhisper.SetupAnimalSkill();
			Voyaging.SetupSailingSkill();
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			new Harmony("MidnightsFX.ImpactfulSkills").PatchAll(executingAssembly);
		}

		private void AddLocalizations()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading Localizations.");
			string[] manifestResourceNames = typeof(ImpactfulSkills).Assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (text.Contains("Localizations"))
				{
					string text2 = Regex.Replace(ReadEmbeddedResourceFile(text), "\\/\\/.*", "");
					string[] array = text.Split(new char[1] { '.' });
					((BaseUnityPlugin)this).Logger.LogDebug((object)("Adding localization: " + array[2]));
					localization.AddJsonFile(array[2], text2);
				}
			}
		}

		internal static string ReadEmbeddedResourceFile(string filename)
		{
			using Stream stream = typeof(ImpactfulSkills).Assembly.GetManifestResourceStream(filename);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}
	}
}
namespace ImpactfulSkills.patches
{
	public static class AnimalWhisper
	{
		[HarmonyPatch(typeof(Tameable), "DecreaseRemainingTime")]
		public static class IncreaseTamingSpeed
		{
			private static void Prefix(Tameable __instance, ref float time)
			{
				//IL_0029: 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_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableAnimalWhisper.Value && (Object)(object)Player.m_localPlayer != (Object)null && Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)__instance).transform.position) <= 30f)
				{
					float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(AnimalHandling);
					float num = time * (skillFactor * ValConfig.AnimalTamingSpeedFactor.Value + 1f);
					Logger.LogDebug($"animal taming remaining time {time}, modified: {num}");
					time = num;
					((Character)Player.m_localPlayer).RaiseSkill(AnimalHandling, ValConfig.AnimalTamingSkillGainRate.Value);
				}
			}
		}

		[HarmonyPatch(typeof(Tameable), "OnDeath")]
		public static class IncreaseTamedAnimalYield
		{
			private static void Postfix(Tameable __instance)
			{
				//IL_0029: 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_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				if (!ValConfig.EnableAnimalWhisper.Value || !((Object)(object)Player.m_localPlayer != (Object)null) || !(Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)__instance).transform.position) <= 20f))
				{
					return;
				}
				Character component = ((Component)__instance).gameObject.GetComponent<Character>();
				if (component == null || !component.m_tamed)
				{
					return;
				}
				CharacterDrop component2 = ((Component)__instance).gameObject.GetComponent<CharacterDrop>();
				if (!((Object)(object)component2 != (Object)null))
				{
					return;
				}
				float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(AnimalHandling);
				foreach (Drop drop in component2.m_drops)
				{
					int num = 0;
					float num2 = (float)drop.m_amountMin * (ValConfig.TamedAnimalLootIncreaseFactor.Value * (skillFactor * 100f)) / 100f;
					float num3 = (float)drop.m_amountMax * (ValConfig.TamedAnimalLootIncreaseFactor.Value * (skillFactor * 100f)) / 100f;
					if (num2 > 0f && num3 > 0f && num2 != num3)
					{
						num = Random.Range((int)num2, (int)num3);
					}
					else if (num2 == num3)
					{
						num = (int)Math.Round(num2, 0);
					}
					if (drop.m_chance == 1f || !(Random.value > drop.m_chance))
					{
						Logger.LogDebug($"AnimalWhisper extra drops {num} {((Object)drop.m_prefab).name}");
						Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
						for (int i = 0; i < num; i++)
						{
							Object.Instantiate<GameObject>(drop.m_prefab, ((Component)__instance).transform.position, val);
						}
					}
				}
			}
		}

		public static SkillType AnimalHandling;

		public static void SetupAnimalSkill()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			SkillConfig val = new SkillConfig();
			val.Name = "$skill_AnimalHandling";
			val.Description = "$skill_AnimalHandling_description";
			val.Icon = ImpactfulSkills.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/skill_icons/animalWhisper.png");
			val.Identifier = "midnightsfx.animalwhisper";
			val.IncreaseStep = 0.1f;
			AnimalHandling = SkillManager.Instance.AddSkill(val);
		}
	}
	public static class BloodMagic
	{
		[HarmonyPatch(typeof(SE_Shield), "OnDamaged")]
		public static class VoyagerSpeedPatch
		{
			private static void Prefix(HitData hit, Character attacker, SE_Shield __instance)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableBloodMagic.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && (friendly_factions.Contains(((StatusEffect)__instance).m_character.m_faction) || ((StatusEffect)__instance).m_character.m_tamed))
				{
					shield_damage += hit.GetTotalDamage();
					if (shield_damage > ValConfig.BloodMagicXPForShieldDamageRatio.Value)
					{
						float num = shield_damage / ValConfig.BloodMagicXPForShieldDamageRatio.Value;
						shield_damage = 0f;
						Logger.LogDebug("BloodMagic adding XP from shield damage: " + num);
						((Character)Player.m_localPlayer).RaiseSkill((SkillType)10, num);
					}
				}
			}
		}

		private static float shield_damage = 0f;

		private static List<Faction> friendly_factions = new List<Faction>
		{
			(Faction)0,
			(Faction)11
		};
	}
	public static class Cooking
	{
		[HarmonyPatch(typeof(Player))]
		public static class CookEnjoysFoodLongerPatch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("UpdateFood")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Div, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Mathf), "Clamp01", (Type[])null, (Type[])null), (string)null)
				}).RemoveInstructions(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<float, float, float>>((Func<float, float, float>)ClampFoodWithBonus) })
					.ThrowIfNotMatch("Unable to patch Food degrading improvement.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			public static float ClampFoodWithBonus(float food_time_remaining, float food_burn_time)
			{
				if (ValConfig.EnableCooking.Value && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					float num = ValConfig.CookingBurnReduction.Value * ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)105);
					return Mathf.Clamp01(food_time_remaining / food_burn_time + num);
				}
				return Mathf.Clamp01(food_time_remaining / food_burn_time);
			}
		}
	}
	internal class Crafting
	{
		[HarmonyPatch(typeof(InventoryGui))]
		public static class CraftingItemBonusDropsPatch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("DoCrafting")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Expected O, but got Unknown
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Expected O, but got Unknown
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Expected O, but got Unknown
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldnull, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null)
				}).RemoveInstructions(45).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[4]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldloc_2, (object)null),
					Transpilers.EmitDelegate<Func<InventoryGui, int, int>>((Func<InventoryGui, int, int>)CraftableBonus),
					new CodeInstruction(OpCodes.Stloc_2, (object)null)
				})
					.ThrowIfNotMatch("Unable to patch Crafting bonus.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		[HarmonyPatch(typeof(InventoryGui))]
		public static class CraftingItemRefundPatch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("DoCrafting")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Expected O, but got Unknown
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Player), "ConsumeResources", (Type[])null, (Type[])null), (string)null)
				}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldloc_S, (object)14),
					Transpilers.EmitDelegate<Action<InventoryGui, int>>((Action<InventoryGui, int>)DetermineCraftingRefund)
				})
					.ThrowIfNotMatch("Unable to patch Crafting Refunds.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		private static int CraftableBonus(InventoryGui instance, int base_amount_crafted)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!ValConfig.EnableCrafting.Value || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return base_amount_crafted;
			}
			int num = base_amount_crafted;
			CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation();
			float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)107);
			float skillLevel = ((Character)Player.m_localPlayer).GetSkillLevel((SkillType)107);
			if ((Object)(object)currentCraftingStation != (Object)null && (int)currentCraftingStation.m_craftingSkill != 0 && instance.m_craftRecipe.m_item.m_itemData.m_shared.m_maxStackSize > 1)
			{
				num += GetCraftingItemBonusAmount(instance, base_amount_crafted, skillFactor, skillLevel);
			}
			if (num != base_amount_crafted)
			{
				Vector3 val = ((Component)Player.m_localPlayer).transform.position + Vector3.up;
				DamageText.instance.ShowText((TextType)7, val, $"+{num - base_amount_crafted}", true);
				instance.m_craftBonusEffect.Create(val, Quaternion.identity, (Transform)null, 1f, -1);
			}
			return num;
		}

		private static void DetermineCraftingRefund(InventoryGui instance, int num_recipe_crafted)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			float skillLevel = ((Character)Player.m_localPlayer).GetSkillLevel((SkillType)107);
			float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)107);
			if (!ValConfig.EnableMaterialReturns.Value || skillLevel < (float)ValConfig.CraftingMaterialReturnsLevel.Value)
			{
				return;
			}
			Dictionary<ItemDrop, int> dictionary = new Dictionary<ItemDrop, int>();
			if (instance.m_craftRecipe.m_requireOnlyOneIngredient)
			{
				Logger.LogDebug("Require any resource recipes do not get a refund.");
				return;
			}
			Requirement[] resources = instance.m_craftRecipe.m_resources;
			foreach (Requirement val in resources)
			{
				float value = Random.value;
				float num = ValConfig.ChanceForMaterialReturn.Value * skillFactor;
				Logger.LogDebug($"Checking refund chance for {((Object)val.m_resItem).name} {value} < {num}");
				if (!(value > num))
				{
					if (val.m_amount > 1)
					{
						int value2 = Mathf.RoundToInt((float)val.m_amount * (ValConfig.MaxCraftingMaterialReturnPercent.Value * skillFactor));
						dictionary.Add(val.m_resItem, value2);
					}
					else if (value < num / 2f)
					{
						dictionary.Add(val.m_resItem, 1);
					}
				}
			}
			if (dictionary.Count == 0)
			{
				return;
			}
			Vector3 val2 = ((Component)Player.m_localPlayer).transform.position + Vector3.up;
			DamageText.instance.ShowText((TextType)7, val2, LocalizationManager.Instance.TryTranslate("$craft_refund"), true);
			instance.m_craftBonusEffect.Create(val2, Quaternion.identity, (Transform)null, 1f, -1);
			foreach (KeyValuePair<ItemDrop, int> item in dictionary)
			{
				bool flag = ((Humanoid)Player.m_localPlayer).GetInventory().AddItem(((Component)item.Key).gameObject, item.Value);
				Logger.LogDebug($"Refund to add: {((Object)item.Key).name} {item.Value} | refunded? {flag}");
			}
		}

		private static int GetCraftingItemBonusAmount(InventoryGui instance, int base_amount_crafted, float skill_factor, float player_skill_level)
		{
			int num = 0;
			if (!ValConfig.EnableBonusItemCrafting.Value || player_skill_level < (float)ValConfig.CraftingBonusCraftsLevel.Value)
			{
				return num;
			}
			float num2 = ValConfig.CraftingBonusChance.Value * skill_factor;
			int num3 = 1;
			if (instance.m_craftRecipe.m_amount > 1 && ValConfig.EnableCraftBonusAsFraction.Value)
			{
				num3 = Mathf.RoundToInt((float)instance.m_craftRecipe.m_amount * ValConfig.CraftBonusFractionOfCraftNumber.Value);
				Logger.LogDebug($"Bonus updated now {num3}, using fraction of result.");
			}
			for (int i = 0; i <= ValConfig.CraftingMaxBonus.Value; i++)
			{
				float value = Random.value;
				Logger.LogDebug($"Bonus crafting roll {i}: {num2} >= {value}");
				if (!(num2 >= value))
				{
					break;
				}
				num += num3;
			}
			Logger.LogDebug($"Crafting {instance.m_craftRecipe.m_item.m_itemData.m_shared.m_name} with new total {base_amount_crafted} + (bonus) {num}.");
			return num;
		}
	}
	public static class Gathering
	{
		[HarmonyPatch(typeof(Pickable))]
		public static class DisableVanillaGatheringLuck
		{
			[HarmonyTranspiler]
			[HarmonyPatch("Interact")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Expected O, but got Unknown
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Expected O, but got Unknown
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Expected O, but got Unknown
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Expected O, but got Unknown
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_1, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Stloc_2, (object)null, (string)null)
				}).RemoveInstructions(43).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					Transpilers.EmitDelegate<Func<Pickable, int>>((Func<Pickable, int>)DetermineExtraDrops),
					new CodeInstruction(OpCodes.Stloc_0, (object)null)
				})
					.ThrowIfNotMatch("Unable remove vanilla pickable luckydrop.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			private static int DetermineExtraDrops(Pickable __instance)
			{
				//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: 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_0135: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					return 0;
				}
				float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)106);
				float num = ValConfig.GatheringLuckFactor.Value * skillFactor * 100f / 100f;
				float num2 = Random.Range(0f, 50f) + num;
				int num3 = 0;
				foreach (float luck_level in luck_levels)
				{
					Logger.LogDebug($"Gathering Luck roll: {num2} > {luck_level}");
					if (num2 > luck_level)
					{
						num3++;
						continue;
					}
					break;
				}
				Logger.LogDebug($"Gathering Luck, drop total: {num3}");
				if (num3 > 0)
				{
					Vector3 val = ((Component)__instance).transform.position + Vector3.up * __instance.m_spawnOffset;
					Logger.LogDebug($"Spawning extra drops {num3}");
					DamageText.instance.ShowText((TextType)7, ((Component)__instance).transform.position + Vector3.up * __instance.m_spawnOffset, $"+{num3}", true);
					__instance.m_bonusEffect.Create(val, Quaternion.identity, (Transform)null, 1f, -1);
				}
				((Character)Player.m_localPlayer).RaiseSkill((SkillType)106, (float)(1 + num3));
				return num3;
			}
		}

		[HarmonyPatch(typeof(Attack))]
		public static class HarvestRangeIncreasesScythe
		{
			[HarmonyTranspiler]
			[HarmonyPatch("DoMeleeAttack")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Attack), "m_harvestRadiusMaxLevel"), (string)null)
				}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<float, float>>((Func<float, float>)IncreaseHarvestWeaponRange) })
					.ThrowIfNotMatch("Unable to increase vanilla harvest max range.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		[HarmonyPatch(typeof(Pickable), "Interact")]
		public static class GatheringLuckPatch
		{
			[CompilerGenerated]
			private sealed class <PickAOE>d__1 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				public Collider[] targets;

				private int <iterations>5__2;

				private Collider[] <>7__wrap2;

				private int <>7__wrap3;

				private Collider <obj_collider>5__5;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <PickAOE>d__1(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>7__wrap2 = null;
					<obj_collider>5__5 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_006a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0074: Expected O, but got Unknown
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -1;
						goto IL_0084;
					}
					<>1__state = -1;
					<iterations>5__2 = 0;
					<>7__wrap2 = targets;
					<>7__wrap3 = 0;
					goto IL_0103;
					IL_0084:
					if (!((Object)(object)<obj_collider>5__5 == (Object)null))
					{
						Pickable val = ((Component)<obj_collider>5__5).GetComponent<Pickable>() ?? ((Component)<obj_collider>5__5).GetComponentInParent<Pickable>();
						if ((Object)(object)val != (Object)null && !UnallowedPickables.Contains(((Object)val.m_itemPrefab).name) && val.CanBePicked())
						{
							val.m_nview.ClaimOwnership();
							val.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
						}
						<obj_collider>5__5 = null;
					}
					<>7__wrap3++;
					goto IL_0103;
					IL_0103:
					if (<>7__wrap3 < <>7__wrap2.Length)
					{
						<obj_collider>5__5 = <>7__wrap2[<>7__wrap3];
						<iterations>5__2++;
						if (<iterations>5__2 % 10 == 0)
						{
							<>2__current = (object)new WaitForSeconds(0.1f);
							<>1__state = 1;
							return true;
						}
						goto IL_0084;
					}
					<>7__wrap2 = null;
					enabled_aoe_gathering = true;
					return false;
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			private static void Postfix(ref bool __result, Pickable __instance, Humanoid character)
			{
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				if (!ValConfig.EnableGathering.Value || !((Object)(object)Player.m_localPlayer != (Object)null) || !((Object)(object)character == (Object)(object)Player.m_localPlayer) || !((Object)(object)__instance != (Object)null))
				{
					return;
				}
				if (UnallowedPickables.Contains(((Object)__instance.m_itemPrefab).name))
				{
					Logger.LogDebug("Pickable is not a gathering item.");
					return;
				}
				float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)106);
				Logger.LogDebug($"Checking for AOE gathering {skillFactor * 100f > (float)ValConfig.FarmingRangeRequiredLevel.Value} && {enabled_aoe_gathering}");
				if (!(skillFactor * 100f > (float)ValConfig.FarmingRangeRequiredLevel.Value) || !enabled_aoe_gathering)
				{
					return;
				}
				float num = ValConfig.GatheringRangeFactor.Value * skillFactor;
				Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, num, pickableMask);
				Logger.LogDebug($"AOE Picking {array.Count()} in harvest range {num}.");
				if (array.Length <= 5)
				{
					Collider[] array2 = array;
					foreach (Collider val in array2)
					{
						Pickable val2 = ((Component)val).GetComponent<Pickable>() ?? ((Component)val).GetComponentInParent<Pickable>();
						if ((Object)(object)val2 != (Object)null)
						{
							Logger.LogDebug("Checking " + ((Object)((Component)val2).gameObject).name + " in harvest range.");
							if (!UnallowedPickables.Contains(((Object)val2.m_itemPrefab).name) && val2.CanBePicked())
							{
								val2.m_nview.ClaimOwnership();
								val2.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
							}
						}
					}
				}
				else
				{
					enabled_aoe_gathering = false;
					((MonoBehaviour)Player.m_localPlayer).StartCoroutine(PickAOE(array));
				}
			}

			[IteratorStateMachine(typeof(<PickAOE>d__1))]
			private static IEnumerator PickAOE(Collider[] targets)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <PickAOE>d__1(0)
				{
					targets = targets
				};
			}
		}

		private static readonly int pickableMask = LayerMask.GetMask(new string[3] { "piece_nonsolid", "item", "Default_small" });

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

		private static List<float> luck_levels = new List<float>();

		private static bool enabled_aoe_gathering = true;

		private static void PickableLuckLevelsChanged(object s, EventArgs e)
		{
			try
			{
				List<float> list = new List<float>();
				string[] array = ValConfig.GatheringLuckLevels.Value.Split(new char[1] { ',' });
				foreach (string s2 in array)
				{
					list.Add(float.Parse(s2));
				}
				if (list.Count > 0)
				{
					luck_levels = list;
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Error parsing GatheringLuckLevels: {arg}");
			}
		}

		private static void UnallowedPickablesChanged(object s, EventArgs e)
		{
			try
			{
				List<string> list = new List<string>();
				string[] array = ValConfig.GatheringDisallowedItems.Value.Split(new char[1] { ',' });
				foreach (string item in array)
				{
					list.Add(item);
				}
				if (list.Count > 0)
				{
					UnallowedPickables.Clear();
					UnallowedPickables.AddRange(list);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Error parsing GatheringDisallowedItems: {arg}");
			}
		}

		public static void SetupGatherables()
		{
			string[] array = ValConfig.GatheringLuckLevels.Value.Split(new char[1] { ',' });
			foreach (string s in array)
			{
				luck_levels.Add(float.Parse(s));
			}
			ValConfig.GatheringLuckLevels.SettingChanged += PickableLuckLevelsChanged;
			array = ValConfig.GatheringDisallowedItems.Value.Split(new char[1] { ',' });
			foreach (string item in array)
			{
				UnallowedPickables.Add(item);
			}
			ValConfig.GatheringDisallowedItems.SettingChanged += UnallowedPickablesChanged;
		}

		private static float IncreaseHarvestWeaponRange(float max_harvest_range)
		{
			if (ValConfig.EnableGathering.Value)
			{
				return ValConfig.GatheringRangeFactor.Value + max_harvest_range;
			}
			return max_harvest_range;
		}
	}
	public static class Mining
	{
		[HarmonyPatch(typeof(MineRock), "Damage")]
		public static class MinerockDmgPatch
		{
			private static void Prefix(HitData hit, MineRock __instance)
			{
				ModifyPickaxeDmg(hit, __instance);
			}
		}

		[HarmonyPatch(typeof(MineRock5), "Damage")]
		public static class Minerock5DmgPatch
		{
			private static void Prefix(HitData hit, MineRock5 __instance)
			{
				ModifyPickaxeDmg(hit, null, __instance);
			}
		}

		[HarmonyPatch(typeof(MineRock5), "RPC_SetAreaHealth")]
		public static class Minerock5DestroyPatch
		{
			private static void Postfix(MineRock5 __instance, long sender, int index, float health)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableMining.Value && (Object)(object)Player.m_localPlayer != (Object)null && health <= 0f)
				{
					IncreaseMiningDrops(__instance.m_dropItems, ((Component)__instance).gameObject.transform.position);
				}
			}
		}

		[HarmonyPatch(typeof(Destructible), "Destroy")]
		public static class IncreaseDropsFromDestructibleRock
		{
			private static void Prefix(Destructible __instance, HitData hit)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableMining.Value && (int)__instance.m_destructibleType == 1 && hit != null && (Object)(object)Player.m_localPlayer != (Object)null && hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
				{
					IncreaseDestructibleMineDrops(__instance);
				}
			}
		}

		[CompilerGenerated]
		private sealed class <DropItemsAsync>d__12 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Dictionary<GameObject, int> drops;

			public Vector3 centerPos;

			private int <obj_spawns>5__2;

			private Dictionary<GameObject, int>.Enumerator <>7__wrap2;

			private bool <set_stack_size>5__4;

			private int <max_stack_size>5__5;

			private GameObject <item>5__6;

			private int <amount>5__7;

			private int <i>5__8;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DropItemsAsync>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap2 = default(Dictionary<GameObject, int>.Enumerator);
				<item>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00ea: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Expected O, but got Unknown
				//IL_01f2: 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_01e3: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00e3;
					}
					<>1__state = -1;
					<obj_spawns>5__2 = 0;
					<>7__wrap2 = drops.GetEnumerator();
					<>1__state = -3;
					goto IL_022e;
					IL_022e:
					if (<>7__wrap2.MoveNext())
					{
						KeyValuePair<GameObject, int> current = <>7__wrap2.Current;
						<set_stack_size>5__4 = false;
						<max_stack_size>5__5 = 0;
						<item>5__6 = current.Key;
						<amount>5__7 = current.Value;
						Logger.LogDebug($"Dropping {((Object)<item>5__6).name} {<amount>5__7}");
						<i>5__8 = 0;
						goto IL_0216;
					}
					<>m__Finally1();
					<>7__wrap2 = default(Dictionary<GameObject, int>.Enumerator);
					return false;
					IL_0216:
					if (<i>5__8 < <amount>5__7)
					{
						if (<obj_spawns>5__2 > 0 && <obj_spawns>5__2 % 10 == 0)
						{
							<>2__current = (object)new WaitForSeconds(0.1f);
							<>1__state = 1;
							return true;
						}
						goto IL_00e3;
					}
					<item>5__6 = null;
					goto IL_022e;
					IL_00e3:
					GameObject obj = Object.Instantiate<GameObject>(<item>5__6, centerPos, Quaternion.identity);
					<obj_spawns>5__2++;
					ItemDrop component = obj.GetComponent<ItemDrop>();
					if (!<set_stack_size>5__4)
					{
						<set_stack_size>5__4 = true;
						if (Object.op_Implicit((Object)(object)component))
						{
							<max_stack_size>5__5 = component.m_itemData.m_shared.m_maxStackSize;
						}
					}
					if (component != null)
					{
						int num2 = <amount>5__7 - <i>5__8;
						if (num2 > 0)
						{
							if (<amount>5__7 > <max_stack_size>5__5)
							{
								component.m_itemData.m_stack = <max_stack_size>5__5;
								<i>5__8 += <max_stack_size>5__5;
							}
							else
							{
								component.m_itemData.m_stack = num2;
								<i>5__8 += num2;
							}
						}
						component.m_itemData.m_worldLevel = (byte)Game.m_worldLevel;
					}
					Rigidbody component2 = obj.GetComponent<Rigidbody>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						Vector3 insideUnitSphere = Random.insideUnitSphere;
						if (insideUnitSphere.y < 0f)
						{
							insideUnitSphere.y = 0f - insideUnitSphere.y;
						}
						component2.AddForce(insideUnitSphere * 5f, (ForceMode)2);
					}
					<i>5__8++;
					goto IL_0216;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap2).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <MineAoeDamage>d__9 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Collider[] mine_targets;

			public HitData aoedmg;

			private MineRock5 <minerock5>5__2;

			private MineRock <minerock>5__3;

			private int <iterations>5__4;

			private Collider[] <>7__wrap4;

			private int <>7__wrap5;

			private Collider <obj_collider>5__7;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <MineAoeDamage>d__9(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<minerock5>5__2 = null;
				<minerock>5__3 = null;
				<>7__wrap4 = null;
				<obj_collider>5__7 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0287: Unknown result type (might be due to invalid IL or missing references)
				//IL_0291: Expected O, but got Unknown
				//IL_016f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Expected O, but got Unknown
				int areaIndex;
				Bounds bounds;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<minerock5>5__2 = null;
					<minerock>5__3 = null;
					bool flag = true;
					<iterations>5__4 = 0;
					try
					{
						Collider[] array = mine_targets;
						foreach (Collider val in array)
						{
							MineRock componentInParent = ((Component)val).gameObject.GetComponentInParent<MineRock>();
							if ((Object)(object)componentInParent != (Object)null)
							{
								<minerock>5__3 = componentInParent;
								flag = true;
								break;
							}
							MineRock5 componentInParent2 = ((Component)val).gameObject.GetComponentInParent<MineRock5>();
							if ((Object)(object)componentInParent2 != (Object)null)
							{
								<minerock5>5__2 = componentInParent2;
								flag = false;
								break;
							}
						}
					}
					catch (Exception ex)
					{
						Logger.LogWarning("Exception trying to get minerock parent object, AOE mining skipped: " + ex.Message);
						rockbreaker_running = false;
						current_aoe_strike = null;
						return false;
					}
					if ((Object)(object)<minerock>5__3 == (Object)null && (Object)(object)<minerock5>5__2 == (Object)null)
					{
						rockbreaker_running = false;
						current_aoe_strike = null;
						return false;
					}
					if (mine_targets == null)
					{
						break;
					}
					if (flag)
					{
						<>7__wrap4 = mine_targets;
						<>7__wrap5 = 0;
						goto IL_0201;
					}
					<>7__wrap4 = mine_targets;
					<>7__wrap5 = 0;
					goto IL_0332;
				}
				case 1:
					<>1__state = -1;
					goto IL_0189;
				case 2:
					{
						<>1__state = -1;
						goto IL_02a1;
					}
					IL_01f3:
					<>7__wrap5++;
					goto IL_0201;
					IL_0332:
					if (<>7__wrap5 < <>7__wrap4.Length)
					{
						<obj_collider>5__7 = <>7__wrap4[<>7__wrap5];
						if (!((Object)(object)<obj_collider>5__7 == (Object)null))
						{
							<iterations>5__4++;
							if (<iterations>5__4 % ValConfig.MinehitsPerInterval.Value == 0)
							{
								<>2__current = (object)new WaitForSeconds(0.1f);
								<>1__state = 2;
								return true;
							}
							goto IL_02a1;
						}
						goto IL_0324;
					}
					<>7__wrap4 = null;
					break;
					IL_0324:
					<>7__wrap5++;
					goto IL_0332;
					IL_02a1:
					areaIndex = <minerock5>5__2.GetAreaIndex(<obj_collider>5__7);
					if (areaIndex >= 0)
					{
						Logger.LogDebug("AOE Damage applying to minerock5");
						Logger.LogDebug($"AOE Damage applying to minerock5 index: {areaIndex}");
						HitData obj = aoedmg;
						bounds = <obj_collider>5__7.bounds;
						obj.m_point = ((Bounds)(ref bounds)).center;
						aoedmg.m_hitCollider = <obj_collider>5__7;
						<minerock5>5__2.DamageArea(areaIndex, aoedmg);
						<obj_collider>5__7 = null;
					}
					goto IL_0324;
					IL_0189:
					if (ArrayContains(<minerock>5__3.m_hitAreas, <obj_collider>5__7))
					{
						Logger.LogDebug("AOE Damage applying to minerock");
						HitData obj2 = aoedmg;
						bounds = <obj_collider>5__7.bounds;
						obj2.m_point = ((Bounds)(ref bounds)).center;
						aoedmg.m_hitCollider = <obj_collider>5__7;
						<minerock>5__3.Damage(aoedmg);
					}
					<obj_collider>5__7 = null;
					goto IL_01f3;
					IL_0201:
					if (<>7__wrap5 < <>7__wrap4.Length)
					{
						<obj_collider>5__7 = <>7__wrap4[<>7__wrap5];
						if (!((Object)(object)<obj_collider>5__7 == (Object)null))
						{
							<iterations>5__4++;
							if (<iterations>5__4 % ValConfig.MinehitsPerInterval.Value == 0)
							{
								<>2__current = (object)new WaitForSeconds(0.2f);
								<>1__state = 1;
								return true;
							}
							goto IL_0189;
						}
						goto IL_01f3;
					}
					<>7__wrap4 = null;
					break;
				}
				rockbreaker_running = false;
				current_aoe_strike = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static readonly int rockmask = LayerMask.GetMask(new string[3] { "static_solid", "Default_small", "Default" });

		private static Collider[] current_aoe_strike = null;

		private static bool rockbreaker_running = false;

		public static void ModifyPickaxeDmg(HitData hit, MineRock instance = null, MineRock5 instance5 = null)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			if (!ValConfig.EnableMining.Value || hit == null || !((Object)(object)Player.m_localPlayer != (Object)null) || !(hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID()))
			{
				return;
			}
			float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)12);
			float num = 1f + ValConfig.MiningDmgMod.Value * (skillFactor * 100f) / 100f;
			Logger.LogDebug($"Player mining dmg multiplier: {num}");
			hit.m_damage.m_pickaxe *= num;
			if (hit.m_damage.m_pickaxe <= 0f)
			{
				return;
			}
			if (!rockbreaker_running && current_aoe_strike == null)
			{
				float value = Random.value;
				float num2 = skillFactor * ValConfig.RockBreakerMaxChance.Value;
				Logger.LogDebug($"Rock breaker roll: {value} <= {num2}");
				if (ValConfig.EnableMiningRockBreaker.Value && skillFactor * 100f >= (float)ValConfig.RockBreakerRequiredLevel.Value && value <= num2)
				{
					Logger.LogDebug("Rock breaker activated!");
					hit.m_damage.m_pickaxe = ValConfig.RockBreakerDamage.Value;
					rockbreaker_running = true;
					if ((Object)(object)instance != (Object)null)
					{
						Logger.LogDebug("Rock breaker activated on minerock");
						current_aoe_strike = instance.m_hitAreas;
						((MonoBehaviour)instance).StartCoroutine(MineAoeDamage(instance.m_hitAreas, hit));
					}
					if (!((Object)(object)instance5 != (Object)null))
					{
						return;
					}
					Logger.LogDebug("Rock breaker activated on minerock5");
					List<Collider> list = new List<Collider>();
					foreach (HitArea hitArea in instance5.m_hitAreas)
					{
						list.Add(hitArea.m_collider);
					}
					current_aoe_strike = list.ToArray();
					((MonoBehaviour)instance5).StartCoroutine(MineAoeDamage(list.ToArray(), hit));
					return;
				}
			}
			if (ValConfig.EnableMiningAOE.Value && skillFactor * 100f >= ValConfig.MiningAOELevel.Value && current_aoe_strike == null)
			{
				Logger.LogDebug("Player mining aoe activated");
				Vector3 point = hit.m_point;
				_ = hit.m_damage;
				Collider[] mine_targets = (current_aoe_strike = Physics.OverlapSphere(point, ValConfig.MiningAOERange.Value * skillFactor, rockmask));
				if ((Object)(object)instance != (Object)null)
				{
					((MonoBehaviour)instance).StartCoroutine(MineAoeDamage(mine_targets, hit));
				}
				if ((Object)(object)instance5 != (Object)null)
				{
					((MonoBehaviour)instance5).StartCoroutine(MineAoeDamage(mine_targets, hit));
				}
			}
		}

		public static bool ArrayContains(Collider[] group, Collider target)
		{
			for (int i = 0; i < group.Length; i++)
			{
				if ((Object)(object)group[i] == (Object)(object)target)
				{
					return true;
				}
			}
			return false;
		}

		[IteratorStateMachine(typeof(<MineAoeDamage>d__9))]
		private static IEnumerator MineAoeDamage(Collider[] mine_targets, HitData aoedmg)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <MineAoeDamage>d__9(0)
			{
				mine_targets = mine_targets,
				aoedmg = aoedmg
			};
		}

		public static void IncreaseDestructibleMineDrops(Destructible dmine)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)dmine.m_spawnWhenDestroyed != (Object)null))
			{
				Vector3 position = ((Component)dmine).transform.position;
				DropOnDestroyed component = ((Component)dmine).GetComponent<DropOnDestroyed>();
				if (!((Object)(object)component == (Object)null) && component.m_dropWhenDestroyed != null)
				{
					IncreaseMiningDrops(component.m_dropWhenDestroyed, position);
				}
			}
		}

		public static void IncreaseMiningDrops(DropTable drops, Vector3 position, HitData hitdata = null)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Distance(((Component)Player.m_localPlayer).transform.position, position);
			if (num > 15f)
			{
				Logger.LogDebug($"Player too far away from rock to get increased loot: {num}");
				return;
			}
			float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)12);
			float num2 = ValConfig.MiningLootFactor.Value * (skillFactor * 100f);
			Dictionary<GameObject, int> dictionary = new Dictionary<GameObject, int>();
			if (drops.m_drops != null)
			{
				foreach (DropData drop in drops.m_drops)
				{
					float value = Random.value;
					float num3 = num2 * (drops.m_dropChance * 2f) / 100f;
					if (num3 > 1f)
					{
						num3 = 1f;
					}
					Logger.LogDebug($"Mining rock check roll: {num3} <= {value}");
					if (num3 <= value)
					{
						Logger.LogDebug("Mining rock drop increase: " + ((Object)drop.m_item).name + " failed drop roll");
						continue;
					}
					int num4 = 0;
					Logger.LogDebug($"Mining rock drop current: {drops.m_dropMin}, max_drop: {drops.m_dropMax}");
					float num5 = (float)drops.m_dropMin * num2 / 100f;
					float num6 = (float)drops.m_dropMax * num2 / 100f;
					if (num5 > 0f && num6 > 0f && num5 != num6)
					{
						num4 = Random.Range((int)num5, (int)num6);
					}
					else if (num5 == num6)
					{
						num4 = (int)Math.Round(num5, 0);
					}
					Logger.LogDebug($"Mining rock drop increase min_drop: {num5}, max_drop: {num6} drop amount: {num4}");
					if (dictionary.ContainsKey(drop.m_item))
					{
						dictionary[drop.m_item] += num4;
					}
					else
					{
						dictionary.Add(drop.m_item, num4);
					}
				}
			}
			if (dictionary.Count != 0)
			{
				((MonoBehaviour)Player.m_localPlayer).StartCoroutine(DropItemsAsync(dictionary, position, 1f));
			}
		}

		[IteratorStateMachine(typeof(<DropItemsAsync>d__12))]
		private static IEnumerator DropItemsAsync(Dictionary<GameObject, int> drops, Vector3 centerPos, float dropArea)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DropItemsAsync>d__12(0)
			{
				drops = drops,
				centerPos = centerPos
			};
		}
	}
	public static class Running
	{
		[HarmonyPatch(typeof(Character))]
		public static class RunningSpeedPatch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("UpdateWalking")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Character), "m_runSpeed"), (string)null)
				}).RemoveInstruction().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<Character, float>>((Func<Character, float>)ModifyRunSpeedBySkill) })
					.ThrowIfNotMatch("Unable to patch Run skill movement increase.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			public static float ModifyRunSpeedBySkill(Character __instance)
			{
				if (ValConfig.EnableRun.Value && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)102);
					float num = ValConfig.RunSpeedFactor.Value * (skillFactor * 100f);
					return __instance.m_runSpeed + num;
				}
				return __instance.m_runSpeed;
			}
		}
	}
	public static class SharedKnowledge
	{
		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		public static class PatchSkillIncreaseHigherGainsForLowerSkills
		{
			private static void Prefix(SkillType skill, ref float value)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				time_since_start += Time.deltaTime;
				if (!ValConfig.EnableKnowledgeSharing.Value || !((Object)(object)Player.m_localPlayer != (Object)null) || skill_types_to_avoid_shared_xp.Contains(skill))
				{
					return;
				}
				if (time_since_start > last_skill_level_check || highest_skill_level == 0f)
				{
					if (!setup_avoid_skills)
					{
						SetupUnallowedSharedXPSkills();
						setup_avoid_skills = true;
					}
					highest_skill_level = UpdateHighestSkillLevel(Player.m_localPlayer);
					last_skill_level_check = time_since_start + Time.deltaTime * 100f;
					Logger.LogDebug($"Setting highest skill level {highest_skill_level} factor {highest_skill_factor}");
				}
				float skillLevel = ((Character)Player.m_localPlayer).GetSkillLevel(skill);
				if (skillLevel < highest_skill_level)
				{
					float num = Mathf.Lerp(0f, highest_skill_level, highest_skill_factor) / 100f;
					float num2 = ValConfig.SharedKnowledgeSkillBonusRate.Value * num;
					if (highest_skill_level <= skillLevel + ValConfig.SharedKnowledgeCap.Value)
					{
						num2 = 0f;
					}
					Logger.LogDebug($"Bonus skill gain from Knowledge {num2} for {((object)(SkillType)(ref skill)).ToString()}");
					value += num2;
				}
			}
		}

		private static float highest_skill_level = 0f;

		private static float highest_skill_factor = 0f;

		private static float time_since_start = 0f;

		private static float last_skill_level_check = 0f;

		private static bool setup_avoid_skills = false;

		private static List<SkillType> skill_types_to_avoid_shared_xp = new List<SkillType>();

		public static void UnallowedSharedXPSkillTypesChanged(object s, EventArgs e)
		{
			SetupUnallowedSharedXPSkills();
		}

		public static void SetupUnallowedSharedXPSkills()
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			List<SkillType> list = new List<SkillType>();
			List<SkillType> list2 = ((Character)Player.m_localPlayer).GetSkills().m_skillData.Keys.ToList();
			bool flag = false;
			if (ValConfig.SharedKnowledgeIgnoreList.Value != "")
			{
				string[] array = ValConfig.SharedKnowledgeIgnoreList.Value.Split(new char[1] { ',' });
				foreach (string text in array)
				{
					Logger.LogDebug("Checking " + text + " as skill enum");
					SkillDef skill = SkillManager.Instance.GetSkill(text);
					if (skill != null)
					{
						list.Add(skill.m_skill);
						continue;
					}
					try
					{
						foreach (SkillType item in list2)
						{
							SkillType current = item;
							if (((object)(SkillType)(ref current)).ToString().Equals(text, StringComparison.OrdinalIgnoreCase))
							{
								if (!list.Contains(current))
								{
									list.Add(current);
								}
								break;
							}
						}
					}
					catch (Exception arg)
					{
						Logger.LogError($"Error parsing {text} as skill enum: {arg}");
					}
				}
			}
			if (list.Count > 0)
			{
				skill_types_to_avoid_shared_xp.Clear();
				skill_types_to_avoid_shared_xp.AddRange(list);
			}
			if (flag)
			{
				Logger.LogWarning("Some of the skills you provided in the config are not valid skill types. Invalid skill types will be ignored. A comma seperated of valid skill names is recommended.");
				Logger.LogWarning("Valid skill types are: " + string.Join(", ", Skills.s_allSkills));
			}
			Logger.LogDebug("Unallowed shared xp skills: " + string.Join(", ", skill_types_to_avoid_shared_xp));
		}

		private static float UpdateHighestSkillLevel(Player player)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			foreach (Skill skill in ((Character)player).GetSkills().GetSkillList())
			{
				if (skill != null && skill.m_level > num)
				{
					num = skill.m_level;
					highest_skill_factor = ((Character)player).GetSkillFactor(skill.m_info.m_skill);
				}
			}
			return num;
		}
	}
	public static class Sneaking
	{
		[HarmonyPatch(typeof(Character))]
		public static class SneakSpeedPatch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("UpdateWalking")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Character), "m_crouchSpeed"), (string)null)
				}).RemoveInstruction().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<Character, float>>((Func<Character, float>)ModifyMovementSpeedBySkill) })
					.ThrowIfNotMatch("Unable to patch Sneak skill movement increase.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			public static float ModifyMovementSpeedBySkill(Character __instance)
			{
				if (ValConfig.EnableStealth.Value && !__instance.IsEncumbered())
				{
					float skillFactor = __instance.GetSkillFactor((SkillType)101);
					float num = ValConfig.SneakSpeedFactor.Value * (skillFactor * 100f);
					return __instance.m_crouchSpeed + num;
				}
				return __instance.m_crouchSpeed;
			}
		}

		public static class SneakingReducedNoisePatch
		{
			[HarmonyPatch(typeof(Character), "AddNoise")]
			public static class AddNoisePatch
			{
				public static void Prefix(Character __instance, ref float range)
				{
					if (ValConfig.EnableStealth.Value && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
					{
						float skillLevel = ((Character)Player.m_localPlayer).GetSkillLevel((SkillType)101);
						if (skillLevel >= ValConfig.SneakNoiseReductionLevel.Value)
						{
							float num = ValConfig.SneakNoiseReductionFactor.Value * skillLevel;
							float num2 = (100f - num) / 100f * range;
							range = num2;
						}
					}
				}
			}
		}

		public static class SneakingBackstabBonusDmg
		{
			[HarmonyPatch(typeof(Attack))]
			public static class AddMeleeBonusBackstab
			{
				[HarmonyTranspiler]
				[HarmonyPatch("DoMeleeAttack")]
				private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_0030: Unknown result type (might be due to invalid IL or missing references)
					//IL_0036: Expected O, but got Unknown
					//IL_0058: Unknown result type (might be due to invalid IL or missing references)
					//IL_005e: Expected O, but got Unknown
					CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
					val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(SharedData), "m_backstabBonus"), (string)null)
					}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)0f),
						Transpilers.EmitDelegate<Func<float, Attack, float>>((Func<float, Attack, float>)ModifyBackstab)
					})
						.ThrowIfNotMatch("Unable to patch Melee Backstab.", Array.Empty<CodeMatch>());
					return val.Instructions();
				}
			}

			[HarmonyPatch(typeof(Attack))]
			public static class AddRangedBonusBackstab
			{
				[HarmonyTranspiler]
				[HarmonyPatch("FireProjectileBurst")]
				private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_0030: Unknown result type (might be due to invalid IL or missing references)
					//IL_0036: Expected O, but got Unknown
					//IL_0058: Unknown result type (might be due to invalid IL or missing references)
					//IL_005e: Expected O, but got Unknown
					CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
					val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(SharedData), "m_backstabBonus"), (string)null)
					}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)0f),
						Transpilers.EmitDelegate<Func<float, Attack, float>>((Func<float, Attack, float>)ModifyBackstab)
					})
						.ThrowIfNotMatch("Unable to patch Ranged Backstab.", Array.Empty<CodeMatch>());
					return val.Instructions();
				}
			}

			public static float ModifyBackstab(float backstab_base, Attack attack_instance)
			{
				if (ValConfig.EnableSneakBonusDamage.Value && ((Character)attack_instance.m_character).IsPlayer() && (float)ValConfig.SneakBackstabBonusLevel.Value <= ((Character)attack_instance.m_character).GetSkillLevel((SkillType)101))
				{
					float skillFactor = ((Character)attack_instance.m_character).GetSkillFactor((SkillType)101);
					float num = backstab_base * (ValConfig.SneakBackstabBonusFactor.Value * skillFactor);
					float num2 = backstab_base + num;
					Logger.LogDebug($"Adding bonus backstab {num} = total ({num2})");
					return num2;
				}
				return backstab_base;
			}
		}
	}
	public static class Voyaging
	{
		[HarmonyPatch(typeof(Ship), "GetSailForce")]
		public static class VoyagerSpeedPatch
		{
			private static void Postfix(ref Vector3 __result, float dt)
			{
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				if (!ValConfig.EnableVoyager.Value || (Object)(object)Player.m_localPlayer == (Object)null)
				{
					return;
				}
				current_update_time += dt;
				if (((Character)Player.m_localPlayer).IsAttachedToShip() && update_timer <= current_update_time)
				{
					update_timer += ValConfig.VoyagerSkillXPCheckFrequency.Value;
					Vector3 velocity = ((Character)Player.m_localPlayer).GetVelocity();
					bool flag = Mathf.Abs(velocity.x) > 0.5f || Mathf.Abs(velocity.y) > 0.5f || Mathf.Abs(velocity.z) > 0.5f;
					Logger.LogDebug($"Checking to raise voyager: x-vel: {velocity.x}, y-vel: {velocity.y}, z-vel: {velocity.z} | skill gain speed? {flag}");
					if (flag)
					{
						Logger.LogDebug("Raising player voyager skill.");
						((Character)Player.m_localPlayer).RaiseSkill(VoyagingSkill, ValConfig.VoyagerSkillGainRate.Value * 1f);
					}
				}
				float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(VoyagingSkill);
				if (skillFactor > 0f)
				{
					float num = 1f + skillFactor * ValConfig.VoyagerSailingSpeedFactor.Value;
					__result *= num;
				}
			}
		}

		[HarmonyPatch(typeof(Ship))]
		public static class PaddlingIsFasterPatch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("CustomFixedUpdate")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Expected O, but got Unknown
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Expected O, but got Unknown
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Expected O, but got Unknown
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Expected O, but got Unknown
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Expected O, but got Unknown
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Expected O, but got Unknown
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[9]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_I4_2, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Ship), "ApplyEdgeForce", (Type[])null, (Type[])null), (string)null)
				}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<Vector3, Vector3>>((Func<Vector3, Vector3>)PaddleSpeedImprovement) })
					.ThrowIfNotMatch("Unable to patch ship paddle speed improvement.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			public static Vector3 PaddleSpeedImprovement(Vector3 ship_motion)
			{
				//IL_0055: 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_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableVoyager.Value && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					float skillLevel = ((Character)Player.m_localPlayer).GetSkillLevel(VoyagingSkill);
					if (skillLevel >= ValConfig.VoyagerPaddleSpeedBonusLevel.Value)
					{
						return ship_motion * (1f + ValConfig.VoyagerPaddleSpeedBonus.Value * (skillLevel / 100f));
					}
				}
				return ship_motion;
			}
		}

		[HarmonyPatch(typeof(Ship), "GetWindAngleFactor")]
		public static class VoyagerAnglePatch
		{
			private static void Postfix(ref float __result)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableVoyager.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					float skillLevel = ((Character)Player.m_localPlayer).GetSkillLevel(VoyagingSkill);
					if (skillLevel >= ValConfig.VoyagerReduceCuttingStart.Value && __result < 1f)
					{
						float num = skillLevel * 0.02f;
						float num2 = Mathf.Clamp(__result + num, __result, 1f);
						__result = num2;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
		{
			typeof(Vector3),
			typeof(float)
		})]
		private class VoyagerNotSoBlindWhileSailingPatch
		{
			private static void Prefix(ref float radius)
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableVoyager.Value && (Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.m_attachedToShip)
				{
					radius *= ((Character)Player.m_localPlayer).GetSkillFactor(VoyagingSkill) * ValConfig.VoyagerIncreaseExplorationRadius.Value + 1f;
				}
			}
		}

		public static SkillType VoyagingSkill;

		private static float update_timer;

		private static float current_update_time;

		public static void SetupSailingSkill()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			SkillConfig val = new SkillConfig();
			val.Name = "$skill_Voyager";
			val.Description = "$skill_Voyager_description";
			val.Icon = ImpactfulSkills.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/skill_icons/voyager.png");
			val.Identifier = "midnightsfx.voyager";
			val.IncreaseStep = 0.15f;
			VoyagingSkill = SkillManager.Instance.AddSkill(val);
		}
	}
	internal class WeaponSkill
	{
		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float),
			typeof(int)
		})]
		public static class ItemDisplay
		{
			public static void Postfix(ItemData item, ref string __result)
			{
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				if (!ValConfig.EnableWeaponSkill.Value || (Object)(object)Player.m_localPlayer == (Object)null)
				{
					return;
				}
				List<string> list = __result.Split(new char[1] { '\n' }).ToList();
				List<string> list2 = new List<string>(list);
				for (int i = 0; i < list.Count; i++)
				{
					if (list[i].Contains("item_staminause"))
					{
						float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(item.m_shared.m_skillType);
						list2[i] = "$item_staminause: <color=orange>" + item.m_shared.m_attack.m_attackStamina + "</color> <color=yellow>(" + Mathf.RoundToInt(ModifyWeaponStaminaCostBySkillLevels(item.m_shared.m_attack.m_attackStamina, skillFactor)) + ")</color>";
					}
					else if (list[i].Contains("item_staminahold"))
					{
						float skillFactor2 = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)8);
						list2[i] = "$item_staminahold: <color=orange>" + item.m_shared.m_attack.m_drawStaminaDrain + "</color> <color=yellow>(" + Mathf.RoundToInt(item.m_shared.m_attack.m_drawStaminaDrain - item.m_shared.m_attack.m_drawStaminaDrain * ValConfig.WeaponSkillBowDrawStaminaCostReduction.Value * skillFactor2) + ")</color>/s";
					}
				}
				__result = string.Join("\n", list2);
			}
		}

		[HarmonyPatch(typeof(ItemData))]
		public static class ModifyStaimaDrainBows
		{
			[HarmonyTranspiler]
			[HarmonyPatch("GetDrawStaminaDrain")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Dup, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)0.33f, (string)null)
				}).Advance(1).RemoveInstructions(1)
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<float>>((Func<float>)ModifyStaminaDrainCostForBow) })
					.ThrowIfNotMatch("Unable to patch Stamina reduction for bows.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		[HarmonyPatch(typeof(Humanoid))]
		public static class ParryGivesBonusXP
		{
			[HarmonyTranspiler]
			[HarmonyPatch("BlockAttack")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Humanoid), "m_perfectBlockEffect"), (string)null)
				}).Advance(2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action>((Action)ExtraXPForParryBlock) })
					.ThrowIfNotMatch("Unable to patch extra XP for Parry block.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		[HarmonyPatch(typeof(Attack))]
		public static class ModifyStaimaDrainWeapons
		{
			[HarmonyTranspiler]
			[HarmonyPatch("GetAttackStamina")]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Expected O, but got Unknown
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Expected O, but got Unknown
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Expected O, but got Unknown
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Expected O, but got Unknown
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Expected O, but got Unknown
				//IL_009e: Unknown result type (might be due to invalid IL or missing referenc