Decompiled source of ImpactfulSkills v0.3.9

plugins/ImpactfulSkills.dll

Decompiled 11 hours 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.3.9")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.9.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> EnableStealth;

		public static ConfigEntry<float> SneakSpeedFactor;

		public static ConfigEntry<float> SneakNoiseReductionLevel;

		public static ConfigEntry<float> SneakNoiseReductionFactor;

		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> 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);
			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);
			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);
			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", 0.02f, "How much gathering range is increased based on your gathering level. Amount applied per level, 0.5 will make level 100 gathering give 50% more range.", advanced: false, 0.001f, 1f);
			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", 25, "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.3.9")]
	[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.3.9";

		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($"original 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)
			{
				if (ValConfig.EnableBloodMagic.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					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;
	}
	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);
			}
		}
	}
	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
				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).ThrowIfNotMatch("Unable remove vanilla pickable luckydrop.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		[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 GahteringLuckPatch
		{
			private static bool pickable;

			private static void Prefix(ref bool __result, Humanoid character, Pickable __instance)
			{
				if (ValConfig.EnableGathering.Value && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)character == (Object)(object)Player.m_localPlayer && !__instance.m_picked)
				{
					pickable = true;
				}
			}

			private static void Postfix(ref bool __result, Humanoid character, Pickable __instance)
			{
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_0116: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0153: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ab: 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))
				{
					return;
				}
				if (UnallowedPickables.Contains(((Object)__instance.m_itemPrefab).name))
				{
					Logger.LogDebug("Pickable is not a gathering item.");
				}
				else
				{
					if (!pickable)
					{
						return;
					}
					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++;
							Logger.LogDebug($"Gathering Luck lvl ({luck_level}) added, 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);
						for (int i = 0; i < num3; i++)
						{
							__instance.m_bonusEffect.Create(val, Quaternion.identity, (Transform)null, 1f, -1);
							Object.Instantiate<GameObject>(__instance.m_itemPrefab, val, ((Component)__instance).transform.rotation);
						}
					}
					if (skillFactor * 100f > (float)ValConfig.FarmingRangeRequiredLevel.Value)
					{
						Logger.LogDebug("Triggering AoE gathering");
						float num4 = ValConfig.GatheringRangeFactor.Value * (skillFactor * 100f);
						Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, num4, pickableMask);
						if (array.Length <= 5)
						{
							Collider[] array2 = array;
							foreach (Collider val2 in array2)
							{
								Pickable val3 = ((Component)val2).GetComponent<Pickable>() ?? ((Component)val2).GetComponentInParent<Pickable>();
								if ((Object)(object)val3 != (Object)null)
								{
									Logger.LogDebug("Checking " + ((Object)((Component)val3).gameObject).name + " in harvest range.");
									if (!UnallowedPickables.Contains(((Object)val3.m_itemPrefab).name) && val3.CanBePicked())
									{
										val3.m_nview.ClaimOwnership();
										val3.Interact((Humanoid)(object)Player.m_localPlayer, false, false);
									}
								}
							}
						}
						else
						{
							((MonoBehaviour)__instance).StartCoroutine(PickAOE(array));
						}
					}
					((Character)Player.m_localPlayer).RaiseSkill((SkillType)106, (float)(1 + num3));
				}
			}
		}

		[CompilerGenerated]
		private sealed class <PickAOE>d__10 : 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__10(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_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0083;
				}
				<>1__state = -1;
				<iterations>5__2 = 0;
				<>7__wrap2 = targets;
				<>7__wrap3 = 0;
				goto IL_0124;
				IL_0083:
				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)
					{
						Logger.LogDebug("Checking " + ((Object)((Component)val).gameObject).name + " in harvest range.");
						if (!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_0124;
				IL_0124:
				if (<>7__wrap3 < <>7__wrap2.Length)
				{
					<obj_collider>5__5 = <>7__wrap2[<>7__wrap3];
					<iterations>5__2++;
					if (<iterations>5__2 % 5 == 0)
					{
						<>2__current = (object)new WaitForSeconds(0.1f);
						<>1__state = 1;
						return true;
					}
					goto IL_0083;
				}
				<>7__wrap2 = 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 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 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;
		}

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

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

			private object <>2__current;

			public Collider[] mine_targets;

			public HitData aoedmg;

			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 <MineAoeDamage>d__6(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_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Expected O, but got Unknown
				//IL_00cb: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0083;
				}
				<>1__state = -1;
				<iterations>5__2 = 0;
				<>7__wrap2 = mine_targets;
				<>7__wrap3 = 0;
				goto IL_0196;
				IL_0083:
				if (!((Object)(object)<obj_collider>5__5 == (Object)null))
				{
					Logger.LogDebug("AOE hit on: " + ((Object)<obj_collider>5__5).name);
					MineRock componentInParent = ((Component)<obj_collider>5__5).gameObject.GetComponentInParent<MineRock>();
					HitData obj = aoedmg;
					Bounds bounds = <obj_collider>5__5.bounds;
					obj.m_point = ((Bounds)(ref bounds)).center;
					aoedmg.m_hitCollider = <obj_collider>5__5;
					if ((Object)(object)componentInParent != (Object)null)
					{
						Logger.LogDebug("AOE Damage applying to minerock");
						componentInParent.m_nview.ClaimOwnership();
						componentInParent.Damage(aoedmg);
					}
					else
					{
						MineRock5 componentInParent2 = ((Component)<obj_collider>5__5).gameObject.GetComponentInParent<MineRock5>();
						if ((Object)(object)componentInParent2 != (Object)null)
						{
							Logger.LogDebug("AOE Damage applying to minerock5");
							int areaIndex = componentInParent2.GetAreaIndex(<obj_collider>5__5);
							Logger.LogDebug($"AOE Damage applying to minerock5 index: {areaIndex}");
							componentInParent2.m_nview.ClaimOwnership();
							componentInParent2.DamageArea(areaIndex, aoedmg);
						}
					}
					<obj_collider>5__5 = null;
				}
				<>7__wrap3++;
				goto IL_0196;
				IL_0196:
				if (<>7__wrap3 < <>7__wrap2.Length)
				{
					<obj_collider>5__5 = <>7__wrap2[<>7__wrap3];
					<iterations>5__2++;
					if (<iterations>5__2 % 5 == 0)
					{
						<>2__current = (object)new WaitForSeconds(0.1f);
						<>1__state = 1;
						return true;
					}
					goto IL_0083;
				}
				<>7__wrap2 = null;
				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;

		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_00d4: 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)
			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) && 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));
				}
			}
		}

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

		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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: 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)
			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);
			Dictionary<GameObject, int> dictionary = new Dictionary<GameObject, int>();
			foreach (DropData drop in drops.m_drops)
			{
				float value = Random.value;
				Logger.LogDebug($"Mining rock check roll: {value} < {1f - drops.m_dropChance}");
				if (value < 1f - drops.m_dropChance)
				{
					Logger.LogDebug("Mining rock drop increase: " + ((Object)drop.m_item).name + " failed drop roll");
				}
				else
				{
					dictionary.Add(drop.m_item, drop.m_stackMin);
				}
			}
			int num2 = 0;
			Logger.LogDebug($"Mining rock drop current: {drops.m_dropMin}, max_drop: {drops.m_dropMax}");
			float num3 = (float)drops.m_dropMin * (ValConfig.MiningLootFactor.Value * (skillFactor * 100f)) / 100f;
			float num4 = (float)drops.m_dropMax * (ValConfig.MiningLootFactor.Value * (skillFactor * 100f)) / 100f;
			if (num3 > 0f && num4 > 0f && num3 != num4)
			{
				num2 = Random.Range((int)num3, (int)num4);
			}
			else if (num3 == num4)
			{
				num2 = (int)Math.Round(num3, 0);
			}
			Logger.LogDebug($"Mining rock drop increase min_drop: {num3}, max_drop: {num4} drop amount: {num2}");
			foreach (KeyValuePair<GameObject, int> item in dictionary)
			{
				Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
				int maxStackSize = item.Key.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize;
				if (num2 > maxStackSize)
				{
					int num5 = num2 / maxStackSize;
					for (int i = 0; i < num5; i++)
					{
						Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = maxStackSize;
					}
					num2 -= maxStackSize * num5;
				}
				else
				{
					Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = num2;
				}
			}
		}
	}
	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 && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					float skillFactor = ((Character)Player.m_localPlayer).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 Voyaging
	{
		[HarmonyPatch(typeof(Ship), "GetSailForce")]
		public static class VoyagerSpeedPatch
		{
			private static void Postfix(ref Vector3 __result, float dt)
			{
				//IL_009d: 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_00cb: 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_007e: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableVoyager.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					current_update_time += dt;
					if (((Character)Player.m_localPlayer).IsAttachedToShip() && update_timer <= current_update_time)
					{
						Logger.LogDebug($"Raising player voyager skill: {update_timer} <= {current_update_time}");
						update_timer += dt * (float)ValConfig.VoyagerSkillXPCheckFrequency.Value;
						((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_005b: 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_0055: 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 * (1f + 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.1f;
			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 references)
				//IL_00a4: Expected O, but got Unknown
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Expected O, but got Unknown
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[8]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)0.33f, (string)null),
					new CodeMatch((OpCode?)OpCodes.Mul, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_1, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Mul, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Sub, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Stloc_0, (object)null, (string)null)
				}).Advance(1).RemoveInstructions(6)
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldloc_1, (object)null),
						Transpilers.EmitDelegate<Func<float, float, float>>((Func<float, float, float>)ModifyWeaponStaminaCostBySkillLevels)
					})
					.ThrowIfNotMatch("Unable to patch tooltip display for stamina cost reduction.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		private static void BuildStringForItemDescription(StringBuilder sb, ItemData instance)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableWeaponSkill.Value)
			{
				sb.Append("\n$item_staminause: <color=orange>" + instance.m_shared.m_attack.m_attackStamina + " (" + ModifyWeaponStaminaCostBySkillLevels(instance.m_shared.m_attack.m_attackStamina, ((Character)Player.m_localPlayer).GetSkillFactor(instance.m_shared.m_skillType)) * -1f + ")</color>");
			}
			else
			{
				sb.Append("\n$item_staminause: <color=orange>" + instance.m_shared.m_attack.m_attackStamina + "</color>");
			}
		}

		private static float ModifyStaminaDrainCostForBow()
		{
			if (!ValConfig.EnableWeaponSkill.Value || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return 0.33f;
			}
			return ValConfig.WeaponSkillBowDrawStaminaCostReduction.Value;
		}

		private static float ModifyWeaponStaminaCostBySkillLevels(float stam_cost, float skillfactor)
		{
			if (!ValConfig.EnableWeaponSkill.Value || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				float num = stam_cost * 0.33f * skillfactor;
				return stam_cost - num;
			}
			float num2 = stam_cost * ValConfig.WeaponSkillStaminaReduction.Value * skillfactor;
			return stam_cost - num2;
		}

		private static void ExtraXPForParryBlock()
		{
			if (ValConfig.EnableWeaponSkill.Value && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).RaiseSkill((SkillType)6, ValConfig.WeaponSkillParryBonus.Value);
			}
		}
	}
	public static class Woodcutting
	{
		[HarmonyPatch(typeof(TreeLog), "Damage")]
		public static class IncreaseTreeLogDamage
		{
			private static void Prefix(HitData hit)
			{
				ModifyChop(hit);
			}
		}

		[HarmonyPatch(typeof(TreeBase), "Damage")]
		public static class IncreaseTreeBaseDamage
		{
			private static void Prefix(HitData hit)
			{
				ModifyChop(hit);
			}
		}

		[HarmonyPatch(typeof(Destructible), "Damage")]
		public static class DestructibleIncreaseChopDamage
		{
			private static void Prefix(Destructible __instance, HitData hit)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Invalid comparison between Unknown and I4
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				if ((ValConfig.EnableWoodcutting.Value && (int)__instance.m_destructibleType == 2) || ((int)__instance.m_destructibleType == 1 && ((Object)((Component)__instance).gameObject).name == "shrub_2"))
				{
					ModifyChop(hit);
				}
			}
		}

		[HarmonyPatch(typeof(TreeLog), "Destroy")]
		public static class IncreaseDropsFromTree
		{
			private static void Postfix(TreeLog __instance, HitData hitData)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.EnableWoodcutting.Value && hitData != null && (Object)(object)Player.m_localPlayer != (Object)null && hitData.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
				{
					IncreaseTreeLogDrops(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Destructible), "Destroy")]
		public static class IncreaseDropsFromDestructibleTree
		{
			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.EnableWoodcutting.Value && (int)__instance.m_destructibleType == 2 && hit != null && (Object)(object)Player.m_localPlayer != (Object)null && hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
				{
					IncreaseDestructibleTreeDrops(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(TreeBase))]
		public static class DamageHandler_Apply_Patch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("RPC_Damage")]
			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_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null)
				}).Advance(3).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					Transpilers.EmitDelegate<Action<TreeBase>>((Action<TreeBase>)IncreaseTreeDrops)
				})
					.ThrowIfNotMatch("Unable to patch drop increase for trees.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}
		}

		public static void ModifyChop(HitData hit)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableWoodcutting.Value && hit != null && (Object)(object)Player.m_localPlayer != (Object)null && hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
			{
				float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)13);
				Logger.LogDebug($"Player skillfactor: {skillFactor}");
				float num = 1f + ValConfig.WoodCuttingDmgMod.Value * (skillFactor * 100f) / 100f;
				Logger.LogDebug($"Player woodcutting dmg multiplier: {num}");
				hit.m_damage.m_chop *= num;
			}
		}

		public static void IncreaseDestructibleTreeDrops(Destructible dtree)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)dtree).transform.position;
			IncreaseWoodDrops(((Component)dtree).GetComponent<DropOnDestroyed>().m_dropWhenDestroyed, position);
		}

		public static void IncreaseTreeLogDrops(TreeLog tree)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)tree).transform.position;
			IncreaseWoodDrops(tree.m_dropWhenDestroyed, position);
		}

		public static void IncreaseTreeDrops(TreeBase tree)
		{
			//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)
			if (ValConfig.EnableWoodcutting.Value)
			{
				Vector3 position = ((Component)tree).transform.position;
				IncreaseWoodDrops(tree.m_dropWhenDestroyed, position);
			}
		}

		public static void IncreaseWoodDrops(DropTable drops, Vector3 position)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<GameObject, int> dictionary = new Dictionary<GameObject, int>();
			foreach (DropData drop in drops.m_drops)
			{
				dictionary.Add(drop.m_item, drop.m_stackMin);
			}
			int num = 0;
			float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)13);
			float num2 = (float)drops.m_dropMin * (ValConfig.WoodCuttingLootFactor.Value * (skillFactor * 100f)) / 100f;
			float num3 = (float)drops.m_dropMax * (ValConfig.WoodCuttingLootFactor.Value * (skillFactor * 100f)) / 100f;
			if (num2 <= 1f || num3 <= 1f)
			{
				return;
			}
			if (num2 > 0f && num3 > 0f && num2 != num3)
			{
				num = Random.Range((int)num2, (int)num3);
			}
			else if (num2 == num3)
			{
				num = (int)Math.Round(num2, 0);
			}
			Logger.LogDebug($"Tree drop increase min_drop: ({drops.m_dropMin}) {num2}, max_drop: ({drops.m_dropMax}) {num3} drop amount: {num}");
			if (dictionary.Count <= 0)
			{
				return;
			}
			foreach (KeyValuePair<GameObject, int> item in dictionary)
			{
				Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
				int maxStackSize = item.Key.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize;
				if (num > maxStackSize)
				{
					int num4 = num / maxStackSize;
					for (int i = 0; i < num4; i++)
					{
						Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = maxStackSize;
						Logger.LogDebug($"Dropping {maxStackSize} of {((Object)item.Key).name} to the world.");
					}
					num -= maxStackSize * num4;
				}
				else
				{
					Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = num;
					Logger.LogDebug($"Dropping {num} of {((Object)item.Key).name} to the world.");
				}
			}
		}
	}
}