Decompiled source of StaminaExtended v1.0.11

StaminaExtended.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using ConditionalConfigSync;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Stamina Extended")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Stamina Extended")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("566e4d45-1d36-47c7-8a5e-ab19706121bd")]
[assembly: AssemblyFileVersion("1.0.11")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.11.0")]
[module: UnverifiableCode]
namespace StaminaExtended;

internal static class ExtraStamina
{
	[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
	public static class Player_GetTotalFoodValue_BaseStaminaIncrease
	{
		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, out float? __state)
		{
			__state = null;
			if (StaminaExtended.modEnabled.Value && StaminaExtended.baseStamina.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				__state = __instance.m_baseStamina;
				__instance.m_baseStamina += GetAdditionalBaseStamina(__instance);
			}
		}

		[HarmonyPriority(700)]
		public static void Postfix(Player __instance, ref float? __state)
		{
			Restore(__instance, ref __state);
		}

		private static void Finalizer(Player __instance, ref float? __state)
		{
			Restore(__instance, ref __state);
		}

		private static void Restore(Player player, ref float? state)
		{
			if (state.HasValue)
			{
				player.m_baseStamina = state.Value;
				state = null;
			}
		}
	}

	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int),
		typeof(bool)
	})]
	public static class ItemDrop_ItemData_GetTooltip_StaminaRegenTooltipForFoodRegen
	{
		private static string[] tooltipTokens = new string[4] { "$item_food_regen", "$item_food_duration", "$item_food_eitr", "$item_food_stamina" };

		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "shudnal.MyLittleUI" })]
		private static void Postfix(ItemData item, ref string __result)
		{
			if (!StaminaExtended.modEnabled.Value || !IsFoodItemForExtraStaminaRegeneration(item, out var foodStamina))
			{
				return;
			}
			int num = -1;
			string[] array = tooltipTokens;
			foreach (string value in array)
			{
				num = __result.IndexOf(value, StringComparison.InvariantCulture);
				if (num != -1)
				{
					break;
				}
			}
			if (num != -1)
			{
				string text = $"\n$se_staminaregen: <color=#ffff80ff>{GetStaminaRegenerationValueFromStaminaPoints(foodStamina):P1}</color> ($item_current:<color=yellow>{GetMultiplier(Player.m_localPlayer):P1}</color>)";
				int num2 = __result.IndexOf("\n", num, StringComparison.InvariantCulture);
				if (num2 != -1)
				{
					__result = __result.Insert(num2, text);
				}
				else
				{
					__result += text;
				}
			}
		}
	}

	[HarmonyPatch(typeof(TextsDialog), "AddActiveEffects")]
	public static class TextsDialog_AddActiveEffects_SeasonTooltipWhenBuffDisabled
	{
		private static void Postfix(TextsDialog __instance)
		{
			if (StaminaExtended.modEnabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
			{
				float multiplier = GetMultiplier(Player.m_localPlayer);
				if (!(multiplier < 0.01f))
				{
					TextInfo obj = __instance.m_texts[0];
					obj.m_text += Localization.instance.Localize(string.Format("\n$se_staminaregen ({0}): <color=orange>{1:P1}</color>", StaminaExtended.extraStaminaRegenerationOnlyFood.Value ? "$item_food" : "$hud_misc", multiplier));
				}
			}
		}
	}

	public static float GetMultiplier(Player player)
	{
		float maxStamina = default(float);
		if (StaminaExtended.extraStaminaRegenerationOnlyFood.Value)
		{
			float num = default(float);
			float num2 = default(float);
			player.GetTotalFoodValue(ref num, ref maxStamina, ref num2);
		}
		else
		{
			maxStamina = ((Character)player).GetMaxStamina();
		}
		return GetStaminaRegenerationValueFromStaminaPoints(maxStamina - player.m_baseStamina - GetAdditionalBaseStamina(player));
	}

	private static float GetStaminaRegenerationValueFromStaminaPoints(float points)
	{
		return StaminaExtended.extraStaminaRegenerationPercent.Value / 100f * points / (float)StaminaExtended.extraStaminaRegenerationPoints.Value;
	}

	private static bool IsFoodItemForExtraStaminaRegeneration(ItemData item, out float foodStamina)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Invalid comparison between Unknown and I4
		foodStamina = 0f;
		if (!StaminaExtended.extraStaminaRegeneration.Value || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return false;
		}
		if ((int)item.m_shared.m_itemType == 2)
		{
			foodStamina = item.m_shared.m_foodStamina;
		}
		return foodStamina > 0f || ((Object)(object)item.m_shared.m_appendToolTip != (Object)null && IsFoodItemForExtraStaminaRegeneration(item.m_shared.m_appendToolTip.m_itemData, out foodStamina));
	}

	private static float GetAdditionalBaseStamina(Player player)
	{
		if (!StaminaExtended.baseStamina.Value)
		{
			return 0f;
		}
		return GetSkillFactor(player, (SkillType)102) * StaminaExtended.runBaseStaminaIncrease.Value + GetSkillFactor(player, (SkillType)103) * StaminaExtended.swimBaseStaminaIncrease.Value + GetSkillFactor(player, (SkillType)104) * StaminaExtended.fishingBaseStaminaIncrease.Value + GetSkillFactor(player, (SkillType)101) * StaminaExtended.sneakBaseStaminaIncrease.Value + GetSkillFactor(player, (SkillType)100) * StaminaExtended.jumpBaseStaminaIncrease.Value + GetSkillFactor(player, (SkillType)11) * StaminaExtended.handsBaseStaminaIncrease.Value;
	}

	public static float GetSkillFactor(Player player, SkillType skillType)
	{
		//IL_000c: 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)
		return ((Character)player).GetSkills().m_skillData.ContainsKey(skillType) ? ((Character)player).GetSkillFactor(skillType) : 0f;
	}
}
internal static class StaminaMultipliers
{
	[HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })]
	public static class Player_UpdateStats_StaminaRegenMultiplier
	{
		public struct UpdateState
		{
			public bool Applied;

			public float EncumberedDrain;

			public float RegenTimeMultiplier;

			public float Regen;
		}

		private static float GetBlockRegenMultiplier()
		{
			return StaminaExtended.modEnabled.Value ? StaminaExtended.blockStaminaRegen.Value : 0.8f;
		}

		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, float dt, out UpdateState __state)
		{
			__state = default(UpdateState);
			if (!StaminaExtended.modEnabled.Value || ((Character)__instance).InIntro() || ((Character)__instance).IsTeleporting())
			{
				return;
			}
			__state = new UpdateState
			{
				Applied = true,
				EncumberedDrain = __instance.m_encumberedStaminaDrain,
				RegenTimeMultiplier = __instance.m_staminaRegenTimeMultiplier,
				Regen = __instance.m_staminaRegen
			};
			if (StaminaExtended.extraStaminaRegeneration.Value && StaminaExtended.extraStaminaRegenerationPercent.Value > 0f && StaminaExtended.extraStaminaRegenerationPoints.Value > 0)
			{
				__instance.m_staminaRegen *= 1f + ExtraStamina.GetMultiplier(__instance);
			}
			if (StaminaExtended.sneakingStamina.Value && ((Character)__instance).IsSneaking())
			{
				__instance.m_staminaRegen *= 1f + StaminaExtended.sneakingStaminaRegenerationMultiplier.Value * ExtraStamina.GetSkillFactor(__instance, (SkillType)101);
			}
			float value = StaminaExtended.linearRegenerationThreshold.Value;
			float value2 = StaminaExtended.linearRegenerationMultiplier.Value;
			if (StaminaExtended.linearRegeneration.Value && value > 0f && value < 1f && value2 > 0f)
			{
				float maxStamina = ((Character)__instance).GetMaxStamina();
				if (maxStamina != 0f)
				{
					float staminaPercentage = ((Character)__instance).GetStaminaPercentage();
					float num = __instance.GetStamina() / maxStamina;
					if (staminaPercentage < value)
					{
						__instance.m_staminaRegenTimeMultiplier = Mathf.Lerp(value2, __instance.m_staminaRegenTimeMultiplier, Mathf.Clamp01(num / value));
					}
					else if (staminaPercentage > value)
					{
						__instance.m_staminaRegenTimeMultiplier = Mathf.Lerp(1f / value2, __instance.m_staminaRegenTimeMultiplier, Mathf.Clamp01((1f - num) / (1f - value)));
					}
				}
			}
			if (!StaminaExtended.encumberedStamina.Value || !((Character)__instance).IsEncumbered())
			{
				return;
			}
			__instance.m_encumberedStaminaDrain *= StaminaExtended.encumberedStaminaDrainMultiplier.Value;
			if (StaminaExtended.encumberedStaminaRegeneration.Value && ((Vector3)(ref ((Character)__instance).m_moveDir)).magnitude <= 0.1f && __instance.m_staminaRegenTimer <= 0f)
			{
				float maxStamina2 = ((Character)__instance).GetMaxStamina();
				if (__instance.GetStamina() < maxStamina2)
				{
					__instance.m_stamina = Mathf.Min(maxStamina2, __instance.m_stamina + StaminaExtended.encumberedStaminaRegenerationMultiplier.Value * __instance.m_staminaRegen * dt * Game.m_staminaRegenRate);
				}
			}
		}

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo operand = AccessTools.Method(typeof(Player_UpdateStats_StaminaRegenMultiplier), "GetBlockRegenMultiplier", (Type[])null, (Type[])null);
			FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_staminaRegen");
			foreach (CodeInstruction item in list)
			{
				if (CodeInstructionExtensions.LoadsField(item, fieldInfo, false))
				{
					break;
				}
				if (item.opcode == OpCodes.Ldc_R4 && item.operand is float num && num == 0.8f)
				{
					item.opcode = OpCodes.Call;
					item.operand = operand;
					return list;
				}
			}
			Debug.LogWarning((object)"[StaminaExtended] Could not locate the blocking stamina regeneration multiplier.");
			return list;
		}

		[HarmonyPriority(700)]
		public static void Postfix(Player __instance, ref UpdateState __state)
		{
			Restore(__instance, ref __state);
		}

		[HarmonyFinalizer]
		private static void Finalizer(Player __instance, ref UpdateState __state)
		{
			Restore(__instance, ref __state);
		}

		private static void Restore(Player player, ref UpdateState state)
		{
			if (state.Applied)
			{
				state.Applied = false;
				player.m_staminaRegenTimeMultiplier = state.RegenTimeMultiplier;
				player.m_encumberedStaminaDrain = state.EncumberedDrain;
				player.m_staminaRegen = state.Regen;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "OnSwimming")]
	public static class Player_OnSwimming_SwimmingStamina
	{
		public static void Prefix(Player __instance, Vector3 targetVel, float dt)
		{
			if (StaminaExtended.modEnabled.Value && StaminaExtended.swimmingStaminaRegeneration.Value && ((Vector3)(ref targetVel)).magnitude <= 0.1f)
			{
				__instance.m_staminaRegenTimer -= dt;
				if (__instance.GetStamina() < ((Character)__instance).GetMaxStamina() && __instance.m_staminaRegenTimer <= 0f - StaminaExtended.swimmingStaminaRegenerationDelay.Value)
				{
					float skillFactor = ExtraStamina.GetSkillFactor(__instance, (SkillType)103);
					__instance.m_stamina = Mathf.Min(((Character)__instance).GetMaxStamina(), __instance.m_stamina + (1f + skillFactor) * StaminaExtended.swimmingStaminaRegenerationMultiplier.Value * __instance.m_staminaRegen * dt * Game.m_staminaRegenRate);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Character), "UpdateSwimming")]
	public static class Character_UpdateSwimming_SwimmingStamina
	{
		public struct SwimState
		{
			public Player Player;

			public float DrainMinSkill;

			public float DrainMaxSkill;

			public float Speed;
		}

		internal static float shiftSwimDownTime;

		internal static bool shiftSwimStaminaDepleted;

		[HarmonyPriority(100)]
		public static void Prefix(Character __instance, float dt, out SwimState __state)
		{
			__state = default(SwimState);
			if (!StaminaExtended.modEnabled.Value || !StaminaExtended.swimmingStamina.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || __instance.IsOnGround())
			{
				return;
			}
			__state = new SwimState
			{
				Player = Player.m_localPlayer,
				DrainMinSkill = Player.m_localPlayer.m_swimStaminaDrainMinSkill,
				DrainMaxSkill = Player.m_localPlayer.m_swimStaminaDrainMaxSkill,
				Speed = __instance.m_swimSpeed
			};
			Player localPlayer = Player.m_localPlayer;
			localPlayer.m_swimStaminaDrainMinSkill *= StaminaExtended.swimmingStaminaDrainMultiplier.Value;
			Player localPlayer2 = Player.m_localPlayer;
			localPlayer2.m_swimStaminaDrainMaxSkill *= StaminaExtended.swimmingStaminaDrainMultiplier.Value;
			if (!StaminaExtended.swimmingRun.Value)
			{
				return;
			}
			shiftSwimStaminaDepleted = shiftSwimStaminaDepleted || !((Character)Player.m_localPlayer).HaveStamina(0f);
			if (ZInput.GetButton("Run") || ZInput.GetButton("JoyRun"))
			{
				shiftSwimDownTime += dt;
				if (!shiftSwimStaminaDepleted)
				{
					float num = Math.Abs(Mathf.Min(StaminaExtended.swimmingRunMaximumSpeed.Value - 1f, shiftSwimDownTime / 10f));
					__instance.m_swimSpeed *= 1f + num;
					Player localPlayer3 = Player.m_localPlayer;
					localPlayer3.m_swimStaminaDrainMinSkill *= 1f + num;
					Player localPlayer4 = Player.m_localPlayer;
					localPlayer4.m_swimStaminaDrainMaxSkill *= 1f + num;
				}
			}
			else
			{
				shiftSwimDownTime = 0f;
				shiftSwimStaminaDepleted = false;
			}
		}

		[HarmonyPriority(700)]
		public static void Postfix(ref SwimState __state)
		{
			Restore(ref __state);
		}

		[HarmonyFinalizer]
		private static void Finalizer(ref SwimState __state)
		{
			Restore(ref __state);
		}

		private static void Restore(ref SwimState state)
		{
			Player player = state.Player;
			state.Player = null;
			if (Object.op_Implicit((Object)(object)player))
			{
				((Character)player).m_swimSpeed = state.Speed;
				player.m_swimStaminaDrainMinSkill = state.DrainMinSkill;
				player.m_swimStaminaDrainMaxSkill = state.DrainMaxSkill;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "OnSneaking")]
	public static class Player_OnSneaking_SneakingStamina
	{
		public static bool IsEnemyInRange(Character me)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			foreach (BaseAI baseAIInstance in BaseAI.BaseAIInstances)
			{
				if (!BaseAI.IsEnemy(me, baseAIInstance.m_character) || !(Vector3.Distance(((Component)me).transform.position, ((Component)baseAIInstance).transform.position) < Math.Max(baseAIInstance.m_viewRange, (baseAIInstance.IsAlerted() ? 1.5f : 1f) * StaminaExtended.sneakingStaminaNoEnemiesRange.Value)))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, out float? __state)
		{
			__state = null;
			if (StaminaExtended.modEnabled.Value && StaminaExtended.sneakingStamina.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				__state = __instance.m_sneakStaminaDrain;
				__instance.m_sneakStaminaDrain *= ((StaminaExtended.sneakingStaminaNoEnemies.Value && !IsEnemyInRange((Character)(object)__instance)) ? 0f : GetSneakStaminaDrainMultiplier());
				if (__instance.m_sneakStaminaDrain == 0f)
				{
					__instance.m_staminaRegenTimer = __instance.m_staminaRegenDelay;
				}
			}
		}

		[HarmonyPriority(700)]
		public static void Postfix(Player __instance, ref float? __state)
		{
			Restore(__instance, ref __state);
		}

		[HarmonyFinalizer]
		private static void Finalizer(Player __instance, ref float? __state)
		{
			Restore(__instance, ref __state);
		}

		private static void Restore(Player player, ref float? state)
		{
			if (state.HasValue)
			{
				player.m_sneakStaminaDrain = state.Value;
				state = null;
			}
		}
	}

	[HarmonyPatch(typeof(FishingFloat), "Awake")]
	public static class FishingFloat_Awake_FishingStaminaDrainMultipliers
	{
		private static void Postfix(FishingFloat __instance)
		{
			if (StaminaExtended.modEnabled.Value)
			{
				__instance.m_pullStaminaUse *= StaminaExtended.pullStaminaUse.Value;
				__instance.m_pullStaminaUseMaxSkillMultiplier *= StaminaExtended.pullStaminaUse.Value;
				__instance.m_hookedStaminaPerSec *= StaminaExtended.hookedStaminaPerSec.Value;
				__instance.m_hookedStaminaPerSecMaxSkill *= StaminaExtended.hookedStaminaPerSec.Value;
			}
		}
	}

	[HarmonyPatch(typeof(FishingFloat), "SetCatch")]
	public static class FishingFloat_ASetCatch_FishingStaminaDrainMultipliers
	{
		private static void Postfix(Fish fish)
		{
			if (StaminaExtended.modEnabled.Value && Object.op_Implicit((Object)(object)fish))
			{
				fish.m_staminaUse *= StaminaExtended.fishStaminaUse.Value;
				fish.m_escapeStaminaUse *= StaminaExtended.fishStaminaUse.Value;
			}
		}
	}

	[HarmonyPatch(typeof(SE_Harpooned), "Setup")]
	public static class SE_Harpooned_Setup_HarpoonedStaminaDrainMultiplier
	{
		private static void Postfix(SE_Harpooned __instance)
		{
			if (StaminaExtended.modEnabled.Value)
			{
				__instance.m_staminaDrain *= StaminaExtended.harpoonedStaminaDrain.Value;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "UpdatePlacement")]
	public static class Player_UpdatePlacement_ToolsStaminaDrainMultiplier
	{
		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, bool takeInput, ref float __state)
		{
			if (StaminaExtended.modEnabled.Value)
			{
				ItemData rightItem = ((Humanoid)__instance).GetRightItem();
				if (((Character)__instance).InPlaceMode() && !((Character)__instance).IsDead() && takeInput && rightItem != null)
				{
					__state = rightItem.m_shared.m_attack.m_attackStamina;
					Attack attack = rightItem.m_shared.m_attack;
					attack.m_attackStamina *= StaminaExtended.toolStaminaDrain.Value;
				}
			}
		}

		[HarmonyPriority(700)]
		private static void Postfix(Player __instance, float __state)
		{
			if (StaminaExtended.modEnabled.Value && __state != 0f && ((Humanoid)__instance).GetRightItem() != null)
			{
				((Humanoid)__instance).GetRightItem().m_shared.m_attack.m_attackStamina = __state;
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
	public static class Humanoid_BlockAttack_BlockStaminaDrainMultiplier
	{
		private static float GetBlockingMultiplier(Humanoid human)
		{
			ItemData currentBlocker = human.GetCurrentBlocker();
			if (currentBlocker != null && currentBlocker.m_shared.m_timedBlockBonus > 1f && human.m_blockTimer != -1f && human.m_blockTimer < 0.25f)
			{
				return StaminaExtended.perfectParryStaminaDrain.Value;
			}
			return StaminaExtended.blockStaminaDrain.Value;
		}

		[HarmonyPriority(100)]
		public static void Prefix(Humanoid __instance, ref float __state)
		{
			if (StaminaExtended.modEnabled.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				__state = __instance.m_blockStaminaDrain;
				__instance.m_blockStaminaDrain *= GetBlockingMultiplier(__instance);
				if (StaminaExtended.blockStaminaSkill.Value)
				{
					__instance.m_blockStaminaDrain *= 1f - 0.33f * ExtraStamina.GetSkillFactor((Player)(object)((__instance is Player) ? __instance : null), (SkillType)6);
				}
			}
		}

		[HarmonyPriority(700)]
		private static void Postfix(Humanoid __instance, float __state)
		{
			if (StaminaExtended.modEnabled.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && __state != 0f)
			{
				__instance.m_blockStaminaDrain = __state;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "CheckRun")]
	public static class Player_CheckRun_RunStaminaDrainMultiplier
	{
		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, ref float __state)
		{
			if (StaminaExtended.modEnabled.Value)
			{
				__state = __instance.m_runStaminaDrain;
				__instance.m_runStaminaDrain *= GetRunStaminaDrainMultiplier();
			}
		}

		[HarmonyPriority(700)]
		private static void Postfix(Player __instance, float __state)
		{
			if (StaminaExtended.modEnabled.Value && __state != 0f)
			{
				__instance.m_runStaminaDrain = __state;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "UpdateDodge")]
	public static class Player_UpdateDodge_DodgeStaminaDrainMultiplier
	{
		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, float dt, out float? __state)
		{
			__state = null;
			if (StaminaExtended.modEnabled.Value && !(__instance.m_queuedDodgeTimer <= dt))
			{
				__state = __instance.m_dodgeStaminaUsage;
				__instance.m_dodgeStaminaUsage *= GetDodgeStaminaDrainMultiplier();
				if (StaminaExtended.dodgeStaminaSkill.Value)
				{
					__instance.m_dodgeStaminaUsage *= 1f - 0.33f * ExtraStamina.GetSkillFactor(__instance, (SkillType)100);
				}
				if (StaminaExtended.groundsEnabled.Value)
				{
					__instance.m_dodgeStaminaUsage *= SE_Surface.GetSurfaceMaterialStaminaDrain(SurfaceStaminaSpeed.currentSurface);
				}
			}
		}

		[HarmonyPriority(700)]
		private static void Postfix(Player __instance, ref float? __state)
		{
			Restore(__instance, ref __state);
		}

		private static void Finalizer(Player __instance, ref float? __state)
		{
			Restore(__instance, ref __state);
		}

		private static void Restore(Player player, ref float? state)
		{
			if (state.HasValue)
			{
				player.m_dodgeStaminaUsage = state.Value;
				state = null;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "OnJump")]
	public static class Player_OnJump_JumpStaminaDrainMultiplier
	{
		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, ref float __state)
		{
			if (StaminaExtended.modEnabled.Value)
			{
				__state = ((Character)__instance).m_jumpStaminaUsage;
				((Character)__instance).m_jumpStaminaUsage = ((Character)__instance).m_jumpStaminaUsage * GetJumpStaminaDrainMultiplier();
				if (StaminaExtended.jumpStaminaSkill.Value)
				{
					((Character)__instance).m_jumpStaminaUsage = ((Character)__instance).m_jumpStaminaUsage * (1f - 0.33f * ExtraStamina.GetSkillFactor(__instance, (SkillType)100));
				}
			}
		}

		[HarmonyPriority(700)]
		private static void Postfix(Player __instance, float __state)
		{
			if (StaminaExtended.modEnabled.Value && __state != 0f)
			{
				((Character)__instance).m_jumpStaminaUsage = __state;
			}
		}
	}

	private static bool IsOutOfCombat()
	{
		return (Object)(object)Player.m_localPlayer != (Object)null && !Player.m_localPlayer.IsSensed() && !Player.m_localPlayer.IsTargeted() && Player.m_localPlayer.CanSwitchPVP();
	}

	private static float GetSneakStaminaDrainMultiplier()
	{
		return Math.Max((StaminaExtended.sneakingStaminaDrainMultiplier.Value == StaminaExtended.sneakingStaminaUsageOutOfCombat.Value || !IsOutOfCombat()) ? StaminaExtended.sneakingStaminaDrainMultiplier.Value : StaminaExtended.sneakingStaminaUsageOutOfCombat.Value, 0.01f);
	}

	private static float GetRunStaminaDrainMultiplier()
	{
		return Math.Max((StaminaExtended.runStaminaDrain.Value == StaminaExtended.runStaminaDrainOutOfCombat.Value || !IsOutOfCombat()) ? StaminaExtended.runStaminaDrain.Value : StaminaExtended.runStaminaDrainOutOfCombat.Value, 0.01f);
	}

	private static float GetDodgeStaminaDrainMultiplier()
	{
		return Math.Max((StaminaExtended.dodgeStaminaUsage.Value == StaminaExtended.dodgeStaminaUsageOutOfCombat.Value || !IsOutOfCombat()) ? StaminaExtended.dodgeStaminaUsage.Value : StaminaExtended.dodgeStaminaUsageOutOfCombat.Value, 0.01f);
	}

	private static float GetJumpStaminaDrainMultiplier()
	{
		return Math.Max((StaminaExtended.jumpStaminaUsage.Value == StaminaExtended.jumpStaminaUsageOutOfCombat.Value || !IsOutOfCombat()) ? StaminaExtended.jumpStaminaUsage.Value : StaminaExtended.jumpStaminaUsageOutOfCombat.Value, 0.01f);
	}
}
public class SE_Surface : SE_Stats
{
	public static Sprite statusEffectIcon;

	private SurfaceStaminaSpeed.SurfaceMaterial surfaceMaterial = SurfaceStaminaSpeed.SurfaceMaterial.None;

	public override void UpdateStatusEffect(float dt)
	{
		if (surfaceMaterial != SurfaceStaminaSpeed.currentSurface)
		{
			((StatusEffect)this).Setup(((StatusEffect)this).m_character);
		}
		else
		{
			((SE_Stats)this).UpdateStatusEffect(dt);
		}
	}

	public override void Setup(Character character)
	{
		surfaceMaterial = SurfaceStaminaSpeed.currentSurface;
		UpdateSurfaceStatusEffect();
		((SE_Stats)this).Setup(character);
	}

	public void UpdateSurfaceStatusEffect()
	{
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		((StatusEffect)this).m_name = GetSurfaceMaterialName(surfaceMaterial);
		((StatusEffect)this).m_icon = (StaminaExtended.groundsShowStatusEffect.Value ? statusEffectIcon : null);
		base.m_runStaminaDrainModifier = GetSurfaceMaterialStaminaDrain(surfaceMaterial) - 1f;
		base.m_jumpStaminaUseModifier = GetSurfaceMaterialStaminaDrain(surfaceMaterial) - 1f;
		base.m_staminaRegenMultiplier = GetSurfaceMaterialStaminaRegen(surfaceMaterial);
		base.m_speedModifier = GetSurfaceMaterialSpeed(surfaceMaterial) - 1f;
		base.m_jumpModifier = new Vector3(0f, GetSurfaceMaterialJump(surfaceMaterial) - 1f, 0f);
	}

	public static void UpdateSurfaceStatusEffectStats()
	{
		if (!((Object)(object)ObjectDB.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null))
		{
			SE_Surface obj = ((Character)Player.m_localPlayer).GetSEMan().GetStatusEffect(StaminaExtended.statusEffectSurfaceHash) as SE_Surface;
			if (obj != null)
			{
				((StatusEffect)obj).Setup((Character)(object)Player.m_localPlayer);
			}
		}
	}

	public static float GetSurfaceMaterialSpeed(SurfaceStaminaSpeed.SurfaceMaterial surfaceMaterial)
	{
		if (surfaceMaterial == SurfaceStaminaSpeed.SurfaceMaterial.None)
		{
			return 1f;
		}
		return StaminaExtended.instance.GetFloatConfig($"groundsSpeed{surfaceMaterial}");
	}

	public static float GetSurfaceMaterialJump(SurfaceStaminaSpeed.SurfaceMaterial surfaceMaterial)
	{
		if (surfaceMaterial == SurfaceStaminaSpeed.SurfaceMaterial.None)
		{
			return 1f;
		}
		return StaminaExtended.instance.GetFloatConfig($"groundsJump{surfaceMaterial}");
	}

	public static float GetSurfaceMaterialStaminaDrain(SurfaceStaminaSpeed.SurfaceMaterial surfaceMaterial)
	{
		if (surfaceMaterial == SurfaceStaminaSpeed.SurfaceMaterial.None)
		{
			return 1f;
		}
		return StaminaExtended.instance.GetFloatConfig($"groundsStaminaDrain{surfaceMaterial}");
	}

	public static float GetSurfaceMaterialStaminaRegen(SurfaceStaminaSpeed.SurfaceMaterial surfaceMaterial)
	{
		if (surfaceMaterial == SurfaceStaminaSpeed.SurfaceMaterial.None)
		{
			return 1f;
		}
		return StaminaExtended.instance.GetFloatConfig($"groundsStaminaRegen{surfaceMaterial}");
	}

	public static string GetSurfaceMaterialName(SurfaceStaminaSpeed.SurfaceMaterial surfaceMaterial)
	{
		return StaminaExtended.instance.GetStringConfig("groundsName" + ((surfaceMaterial == SurfaceStaminaSpeed.SurfaceMaterial.None) ? "Default" : surfaceMaterial.ToString()));
	}
}
public class SurfaceStaminaSpeed
{
	public enum SurfaceMaterial
	{
		None,
		Grass,
		Mud,
		Snow,
		Wood,
		HardWood,
		Stone,
		Marble,
		Metal,
		Cultivated,
		Cleared,
		Paved,
		Ash,
		Lava,
		Ice
	}

	[HarmonyPatch(typeof(FootStep), "GetGroundMaterial")]
	private static class FootStep_GetGroundMaterial_GroundDetection
	{
		private static void Postfix(Character character, Vector3 point, GroundMaterial __result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Invalid comparison between Unknown and I4
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Invalid comparison between Unknown and I4
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected I4, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Invalid comparison between Unknown and I4
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Invalid comparison between Unknown and I4
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Invalid comparison between Unknown and I4
			//IL_0222: 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: Invalid comparison between Unknown and I4
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Invalid comparison between Unknown and I4
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Invalid comparison between Unknown and I4
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Invalid comparison between Unknown and I4
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			if (!StaminaExtended.modEnabled.Value || (Object)(object)character != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Collider collider = character.GetLastGroundCollider();
			if ((Object)(object)collider == (Object)null)
			{
				currentSurface = SurfaceMaterial.None;
				return;
			}
			if ((int)__result <= 256)
			{
				if ((int)__result <= 32)
				{
					switch ((int)__result)
					{
					case 0:
					case 2:
						goto IL_0145;
					case 8:
						currentSurface = (IsUpgradedMaterial(collider) ? SurfaceMaterial.HardWood : SurfaceMaterial.Wood);
						return;
					case 4:
						currentSurface = (IsUpgradedMaterial(collider) ? SurfaceMaterial.Marble : SurfaceMaterial.Stone);
						return;
					case 1:
					{
						WearNTear piece = GetPiece(collider);
						currentSurface = (((Object)(object)piece != (Object)null) ? GetSurfaceMaterial(piece.m_materialType) : SurfaceMaterial.None);
						return;
					}
					case 3:
					case 5:
					case 6:
					case 7:
						goto IL_027d;
					}
					if ((int)__result == 16)
					{
						goto IL_0168;
					}
					if ((int)__result == 32)
					{
						currentSurface = GetModifiedGround(collider, point);
						if (currentSurface == SurfaceMaterial.None)
						{
							currentSurface = SurfaceMaterial.Mud;
						}
						return;
					}
				}
				else
				{
					if ((int)__result == 64)
					{
						currentSurface = GetModifiedGround(collider, point);
						if (currentSurface == SurfaceMaterial.None)
						{
							currentSurface = SurfaceMaterial.Grass;
						}
						return;
					}
					if ((int)__result == 128)
					{
						currentSurface = GetModifiedGround(collider, point);
						if (currentSurface == SurfaceMaterial.None && IsPlainsGrass())
						{
							currentSurface = SurfaceMaterial.Grass;
						}
						return;
					}
					if ((int)__result == 256)
					{
						currentSurface = SurfaceMaterial.Metal;
						return;
					}
				}
			}
			else if ((int)__result <= 2048)
			{
				if ((int)__result == 512)
				{
					goto IL_0145;
				}
				if ((int)__result == 1024)
				{
					currentSurface = SurfaceMaterial.Ash;
					return;
				}
				if ((int)__result == 2048)
				{
					currentSurface = SurfaceMaterial.Lava;
					return;
				}
			}
			else
			{
				if ((int)__result == 4096 || (int)__result == 8192)
				{
					goto IL_0168;
				}
				if ((int)__result == 16384)
				{
					currentSurface = SurfaceMaterial.Ice;
					return;
				}
			}
			goto IL_027d;
			IL_0168:
			currentSurface = SurfaceMaterial.Snow;
			return;
			IL_027d:
			currentSurface = SurfaceMaterial.None;
			return;
			IL_0145:
			currentSurface = SurfaceMaterial.None;
			bool IsPlainsGrass()
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Invalid comparison between Unknown and I4
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				Heightmap heightmap = GetHeightmap(collider);
				if ((Object)(object)heightmap == (Object)null)
				{
					return false;
				}
				if ((int)heightmap.GetBiome(point, 0.02f, false) != 16)
				{
					return false;
				}
				return Mathf.Acos(Mathf.Clamp01(character.GetLastGroundNormal().y)) * 57.29578f < 40f;
			}
		}
	}

	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	public static class ObjectDB_Awake_AddStatusEffects
	{
		public static void AddCustomStatusEffects(ObjectDB odb)
		{
			if (odb.m_StatusEffects.Count > 0 && !odb.m_StatusEffects.Any((StatusEffect se) => ((Object)se).name == "Surface"))
			{
				SE_Surface sE_Surface = ScriptableObject.CreateInstance<SE_Surface>();
				((Object)sE_Surface).name = "Surface";
				((StatusEffect)sE_Surface).m_nameHash = StaminaExtended.statusEffectSurfaceHash;
				((StatusEffect)sE_Surface).m_icon = SE_Surface.statusEffectIcon;
				odb.m_StatusEffects.Add((StatusEffect)(object)sE_Surface);
			}
		}

		private static void Postfix(ObjectDB __instance)
		{
			AddCustomStatusEffects(__instance);
		}
	}

	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	public static class ObjectDB_CopyOtherDB_SE_Season
	{
		private static void Postfix(ObjectDB __instance)
		{
			ObjectDB_Awake_AddStatusEffects.AddCustomStatusEffects(__instance);
		}
	}

	[HarmonyPatch(typeof(Skills), "Awake")]
	public static class Skills_Awake_SE_Season
	{
		private static void Postfix(Skills __instance)
		{
			if ((Object)(object)SE_Surface.statusEffectIcon == (Object)null)
			{
				CollectionExtensions.DoIf<SkillDef>((IEnumerable<SkillDef>)__instance.m_skills, (Func<SkillDef, bool>)((SkillDef skill) => (int)skill.m_skill == 102), (Action<SkillDef>)delegate(SkillDef skill)
				{
					SE_Surface.statusEffectIcon = skill.m_icon;
				});
			}
		}
	}

	[HarmonyPatch(typeof(TextsDialog), "AddActiveEffects")]
	public static class TextsDialog_AddActiveEffects_StatusTooltipWhenBuffDisabled
	{
		public static bool isActiveEffectsListCall;

		private static void Prefix()
		{
			isActiveEffectsListCall = StaminaExtended.groundsEnabled.Value && !StaminaExtended.groundsShowStatusEffect.Value;
		}

		private static void Postfix()
		{
			isActiveEffectsListCall = false;
		}
	}

	[HarmonyPatch(typeof(SEMan), "GetHUDStatusEffects")]
	public static class SEMan_GetHUDStatusEffects_SeasonTooltipWhenBuffDisabled
	{
		private static void Postfix(Character ___m_character, List<StatusEffect> ___m_statusEffects, List<StatusEffect> effects)
		{
			if (TextsDialog_AddActiveEffects_StatusTooltipWhenBuffDisabled.isActiveEffectsListCall && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)___m_character == (Object)(object)Player.m_localPlayer && !effects.Any((StatusEffect effect) => effect is SE_Surface))
			{
				StatusEffect val = ___m_statusEffects.Find((StatusEffect se) => se is SE_Surface);
				if ((Object)(object)val != (Object)null)
				{
					effects.Add(val);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Character), "UpdateGroundContact")]
	public static class Character_UpdateGroundContact_GroundDetectionOnContact
	{
		private static void Prefix(Character __instance, float ___m_maxAirAltitude, ref float __state)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (StaminaExtended.groundsEnabled.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				__state = Mathf.Max(0f, ___m_maxAirAltitude - ((Component)__instance).transform.position.y);
			}
		}

		private static void Postfix(Character __instance, float ___m_maxAirAltitude, float __state)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (__state != 0f && __state >= 0.2f && ___m_maxAirAltitude == ((Component)__instance).transform.position.y && __instance.IsOnGround() && currentSurface == SurfaceMaterial.None)
			{
				CheckCurrentGround(__instance);
			}
		}
	}

	public static SurfaceMaterial currentSurface = SurfaceMaterial.None;

	public static Dictionary<Collider, WearNTear> colliderPieces = new Dictionary<Collider, WearNTear>();

	public static Dictionary<Collider, Heightmap> colliderHeightmaps = new Dictionary<Collider, Heightmap>();

	public static int colliderCacheCleared = 0;

	public static int pieceLayer;

	private static bool IsUpgradedMaterial(Collider collider)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Invalid comparison between Unknown and I4
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Invalid comparison between Unknown and I4
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Invalid comparison between Unknown and I4
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Invalid comparison between Unknown and I4
		WearNTear piece = GetPiece(collider);
		return (Object)(object)piece != (Object)null && ((int)piece.m_materialType == 3 || (int)piece.m_materialType == 4 || (int)piece.m_materialType == 5 || (int)piece.m_materialType == 6);
	}

	private static WearNTear GetPiece(Collider collider)
	{
		if ((int)(ZNet.instance.GetTimeSeconds() / 300.0) != colliderCacheCleared)
		{
			colliderCacheCleared = (int)(ZNet.instance.GetTimeSeconds() / 300.0);
			colliderPieces.Clear();
			colliderHeightmaps.Clear();
		}
		if ((Object)(object)collider == (Object)null)
		{
			return null;
		}
		if (pieceLayer == 0)
		{
			pieceLayer = LayerMask.NameToLayer("piece");
		}
		if (((Component)collider).gameObject.layer != pieceLayer)
		{
			return null;
		}
		if (!colliderPieces.ContainsKey(collider))
		{
			colliderPieces.Add(collider, ((Component)collider).GetComponentInParent<WearNTear>());
		}
		return colliderPieces[collider];
	}

	private static Heightmap GetHeightmap(Collider collider)
	{
		if ((int)(ZNet.instance.GetTimeSeconds() / 300.0) != colliderCacheCleared)
		{
			colliderCacheCleared = (int)(ZNet.instance.GetTimeSeconds() / 300.0);
			colliderPieces.Clear();
			colliderHeightmaps.Clear();
		}
		if ((Object)(object)collider == (Object)null)
		{
			return null;
		}
		if (!colliderHeightmaps.ContainsKey(collider))
		{
			colliderHeightmaps.Add(collider, ((Component)collider).GetComponent<Heightmap>());
		}
		return colliderHeightmaps[collider];
	}

	private static SurfaceMaterial GetModifiedGround(Collider collider, Vector3 worldPos)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		Heightmap heightmap = GetHeightmap(collider);
		if ((Object)(object)heightmap == (Object)null)
		{
			return SurfaceMaterial.None;
		}
		int num = default(int);
		int num2 = default(int);
		heightmap.WorldToVertex(worldPos, ref num, ref num2);
		if (heightmap.m_paintMask.GetPixel(num, num2).g > 0.5f)
		{
			return SurfaceMaterial.Cultivated;
		}
		worldPos.x = (float)((double)worldPos.x - 0.5);
		worldPos.z = (float)((double)worldPos.z - 0.5);
		heightmap.WorldToVertex(worldPos, ref num, ref num2);
		Color pixel = heightmap.m_paintMask.GetPixel(num, num2);
		if (pixel.r > 0.5f)
		{
			return SurfaceMaterial.Cleared;
		}
		if (pixel.b > 0.5f)
		{
			return SurfaceMaterial.Paved;
		}
		if (pixel.g > 0.5f)
		{
			return SurfaceMaterial.Cultivated;
		}
		return SurfaceMaterial.None;
	}

	private static void CheckCurrentGround(Character character)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		Collider lastGroundCollider = character.GetLastGroundCollider();
		if ((Object)(object)lastGroundCollider == (Object)null)
		{
			return;
		}
		currentSurface = GetModifiedGround(lastGroundCollider, ((Component)character).transform.position);
		if (currentSurface != SurfaceMaterial.None)
		{
			return;
		}
		if (pieceLayer == 0)
		{
			pieceLayer = LayerMask.NameToLayer("piece");
		}
		if (((Component)lastGroundCollider).gameObject.layer == pieceLayer)
		{
			WearNTear piece = GetPiece(lastGroundCollider);
			if ((Object)(object)piece != (Object)null)
			{
				currentSurface = GetSurfaceMaterial(piece.m_materialType);
			}
		}
	}

	public static SurfaceMaterial GetSurfaceMaterial(MaterialType materialType)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected I4, but got Unknown
		if (1 == 0)
		{
		}
		SurfaceMaterial result = (int)materialType switch
		{
			0 => SurfaceMaterial.Wood, 
			1 => SurfaceMaterial.Stone, 
			4 => SurfaceMaterial.Marble, 
			3 => SurfaceMaterial.HardWood, 
			2 => SurfaceMaterial.Metal, 
			5 => SurfaceMaterial.Marble, 
			6 => SurfaceMaterial.Marble, 
			7 => SurfaceMaterial.Ice, 
			_ => SurfaceMaterial.None, 
		};
		if (1 == 0)
		{
		}
		return result;
	}
}
[BepInPlugin("shudnal.StaminaExtended", "Stamina Extended", "1.0.11")]
[BepInDependency("_shudnal.ConditionalConfigSync", "1.0.5")]
public class StaminaExtended : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Hud), "UpdateStamina")]
	public class Hud_UpdateStamina_HideStaminaValue
	{
		public static void Prefix(Hud __instance)
		{
			if (!((Object)(object)__instance.m_staminaText == (Object)null))
			{
				((Component)__instance.m_staminaText).gameObject.SetActive(modEnabled.Value && !hideStaminaValue.Value);
			}
		}
	}

	public const string pluginID = "shudnal.StaminaExtended";

	public const string pluginName = "Stamina Extended";

	public const string pluginVersion = "1.0.11";

	private readonly Harmony harmony = new Harmony("shudnal.StaminaExtended");

	internal static readonly ConfigSync configSync = new ConfigSync("shudnal.StaminaExtended")
	{
		DisplayName = "Stamina Extended",
		CurrentVersion = "1.0.11",
		MinimumRequiredVersion = "1.0.11"
	};

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<bool> configLocked;

	public static ConfigEntry<bool> loggingEnabled;

	public static ConfigEntry<bool> linearRegeneration;

	public static ConfigEntry<float> linearRegenerationMultiplier;

	public static ConfigEntry<float> linearRegenerationThreshold;

	public static ConfigEntry<bool> extraStaminaRegeneration;

	public static ConfigEntry<float> extraStaminaRegenerationPercent;

	public static ConfigEntry<int> extraStaminaRegenerationPoints;

	public static ConfigEntry<bool> extraStaminaRegenerationOnlyFood;

	public static ConfigEntry<bool> encumberedStamina;

	public static ConfigEntry<float> encumberedStaminaDrainMultiplier;

	public static ConfigEntry<bool> encumberedStaminaRegeneration;

	public static ConfigEntry<float> encumberedStaminaRegenerationMultiplier;

	public static ConfigEntry<bool> swimmingStamina;

	public static ConfigEntry<float> swimmingStaminaDrainMultiplier;

	public static ConfigEntry<bool> swimmingStaminaRegeneration;

	public static ConfigEntry<float> swimmingStaminaRegenerationMultiplier;

	public static ConfigEntry<float> swimmingStaminaRegenerationDelay;

	public static ConfigEntry<bool> swimmingRun;

	public static ConfigEntry<float> swimmingRunMaximumSpeed;

	public static ConfigEntry<bool> sneakingStamina;

	public static ConfigEntry<float> sneakingStaminaDrainMultiplier;

	public static ConfigEntry<float> sneakingStaminaRegenerationMultiplier;

	public static ConfigEntry<bool> sneakingStaminaNoEnemies;

	public static ConfigEntry<float> sneakingStaminaNoEnemiesRange;

	public static ConfigEntry<bool> baseStamina;

	public static ConfigEntry<float> runBaseStaminaIncrease;

	public static ConfigEntry<float> swimBaseStaminaIncrease;

	public static ConfigEntry<float> fishingBaseStaminaIncrease;

	public static ConfigEntry<float> sneakBaseStaminaIncrease;

	public static ConfigEntry<float> jumpBaseStaminaIncrease;

	public static ConfigEntry<float> handsBaseStaminaIncrease;

	public static ConfigEntry<float> pullStaminaUse;

	public static ConfigEntry<float> hookedStaminaPerSec;

	public static ConfigEntry<float> fishStaminaUse;

	public static ConfigEntry<float> harpoonedStaminaDrain;

	public static ConfigEntry<float> toolStaminaDrain;

	public static ConfigEntry<float> blockStaminaDrain;

	public static ConfigEntry<float> runStaminaDrain;

	public static ConfigEntry<float> dodgeStaminaUsage;

	public static ConfigEntry<float> jumpStaminaUsage;

	public static ConfigEntry<float> sneakingStaminaUsageOutOfCombat;

	public static ConfigEntry<float> runStaminaDrainOutOfCombat;

	public static ConfigEntry<float> dodgeStaminaUsageOutOfCombat;

	public static ConfigEntry<float> jumpStaminaUsageOutOfCombat;

	public static ConfigEntry<bool> hideStaminaValue;

	public static ConfigEntry<bool> blockStaminaSkill;

	public static ConfigEntry<bool> dodgeStaminaSkill;

	public static ConfigEntry<bool> jumpStaminaSkill;

	public static ConfigEntry<float> blockStaminaRegen;

	public static ConfigEntry<float> perfectParryStaminaDrain;

	public static ConfigEntry<bool> groundsEnabled;

	public static ConfigEntry<bool> groundsShowStatusEffect;

	public static ConfigEntry<string> groundsNameDefault;

	public static ConfigEntry<float> groundsSpeedSnow;

	public static ConfigEntry<float> groundsJumpSnow;

	public static ConfigEntry<float> groundsStaminaDrainSnow;

	public static ConfigEntry<float> groundsStaminaRegenSnow;

	public static ConfigEntry<string> groundsNameSnow;

	public static ConfigEntry<float> groundsSpeedMud;

	public static ConfigEntry<float> groundsJumpMud;

	public static ConfigEntry<float> groundsStaminaDrainMud;

	public static ConfigEntry<float> groundsStaminaRegenMud;

	public static ConfigEntry<string> groundsNameMud;

	public static ConfigEntry<float> groundsSpeedGrass;

	public static ConfigEntry<float> groundsJumpGrass;

	public static ConfigEntry<float> groundsStaminaDrainGrass;

	public static ConfigEntry<float> groundsStaminaRegenGrass;

	public static ConfigEntry<string> groundsNameGrass;

	public static ConfigEntry<float> groundsSpeedWood;

	public static ConfigEntry<float> groundsJumpWood;

	public static ConfigEntry<float> groundsStaminaDrainWood;

	public static ConfigEntry<float> groundsStaminaRegenWood;

	public static ConfigEntry<string> groundsNameWood;

	public static ConfigEntry<float> groundsSpeedHardWood;

	public static ConfigEntry<float> groundsJumpHardWood;

	public static ConfigEntry<float> groundsStaminaDrainHardWood;

	public static ConfigEntry<float> groundsStaminaRegenHardWood;

	public static ConfigEntry<string> groundsNameHardWood;

	public static ConfigEntry<float> groundsSpeedStone;

	public static ConfigEntry<float> groundsJumpStone;

	public static ConfigEntry<float> groundsStaminaDrainStone;

	public static ConfigEntry<float> groundsStaminaRegenStone;

	public static ConfigEntry<string> groundsNameStone;

	public static ConfigEntry<float> groundsSpeedMarble;

	public static ConfigEntry<float> groundsJumpMarble;

	public static ConfigEntry<float> groundsStaminaDrainMarble;

	public static ConfigEntry<float> groundsStaminaRegenMarble;

	public static ConfigEntry<string> groundsNameMarble;

	public static ConfigEntry<float> groundsSpeedMetal;

	public static ConfigEntry<float> groundsJumpMetal;

	public static ConfigEntry<float> groundsStaminaDrainMetal;

	public static ConfigEntry<float> groundsStaminaRegenMetal;

	public static ConfigEntry<string> groundsNameMetal;

	public static ConfigEntry<float> groundsSpeedCultivated;

	public static ConfigEntry<float> groundsJumpCultivated;

	public static ConfigEntry<float> groundsStaminaDrainCultivated;

	public static ConfigEntry<float> groundsStaminaRegenCultivated;

	public static ConfigEntry<string> groundsNameCultivated;

	public static ConfigEntry<float> groundsSpeedCleared;

	public static ConfigEntry<float> groundsJumpCleared;

	public static ConfigEntry<float> groundsStaminaDrainCleared;

	public static ConfigEntry<float> groundsStaminaRegenCleared;

	public static ConfigEntry<string> groundsNameCleared;

	public static ConfigEntry<float> groundsSpeedPaved;

	public static ConfigEntry<float> groundsJumpPaved;

	public static ConfigEntry<float> groundsStaminaDrainPaved;

	public static ConfigEntry<float> groundsStaminaRegenPaved;

	public static ConfigEntry<string> groundsNamePaved;

	public static ConfigEntry<float> groundsSpeedAsh;

	public static ConfigEntry<float> groundsJumpAsh;

	public static ConfigEntry<float> groundsStaminaDrainAsh;

	public static ConfigEntry<float> groundsStaminaRegenAsh;

	public static ConfigEntry<string> groundsNameAsh;

	public static ConfigEntry<float> groundsSpeedLava;

	public static ConfigEntry<float> groundsJumpLava;

	public static ConfigEntry<float> groundsStaminaDrainLava;

	public static ConfigEntry<float> groundsStaminaRegenLava;

	public static ConfigEntry<string> groundsNameLava;

	public static ConfigEntry<float> groundsSpeedIce;

	public static ConfigEntry<float> groundsJumpIce;

	public static ConfigEntry<float> groundsStaminaDrainIce;

	public static ConfigEntry<float> groundsStaminaRegenIce;

	public static ConfigEntry<string> groundsNameIce;

	public static StaminaExtended instance;

	public const string statusEffectSurfaceName = "Surface";

	public static int statusEffectSurfaceHash = StringExtensionMethods.GetStableHashCode("Surface");

	private void Awake()
	{
		harmony.PatchAll();
		instance = this;
		ConfigInit();
		((ConditionalConfigSync)configSync).AddLockingConfigEntry<bool>(configLocked);
		Game.isModded = true;
	}

	private void FixedUpdate()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			if (groundsEnabled.Value && !((Character)localPlayer).GetSEMan().HaveStatusEffect(statusEffectSurfaceHash))
			{
				((Character)localPlayer).GetSEMan().AddStatusEffect(statusEffectSurfaceHash, false, 0, 0f, (short)(-1));
			}
			else if (!groundsEnabled.Value && ((Character)localPlayer).GetSEMan().HaveStatusEffect(statusEffectSurfaceHash))
			{
				((Character)localPlayer).GetSEMan().RemoveStatusEffect(statusEffectSurfaceHash, true);
			}
		}
	}

	private void OnDestroy()
	{
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
		instance = null;
	}

	private void ConfigInit()
	{
		modEnabled = config("1 - General", "Enabled", defaultValue: true, "Mod alters stamina behavior");
		configLocked = config("1 - General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only.");
		loggingEnabled = config("1 - General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false);
		linearRegeneration = config("2 - Linear regeneration change", "Enabled", defaultValue: true, "Enable linear change of stamina regeneration rate. Overall time to regenerate stamina to 100% is still almost the same.");
		linearRegenerationMultiplier = config("2 - Linear regeneration change", "Multiplier", 3f, "Multiplier of regeneration rate when stamina is 0.\nIf value is above 1. Stamina will regenerate faster at lower values and proportionally slower at higher values.\nIf value is below 1. Stamina will regenerate slower at lower values and proportionally higher at higher values.");
		linearRegenerationThreshold = config("2 - Linear regeneration change", "Regeneration threshold", 0.5f, "Inflection point of stamina regeneration rate. Stamina regeneration rate is normal only in that point.\nIn that point regeneration rate changes its sign.\nIf set value is outside of 0-1 range stamina will regenerate normally");
		extraStaminaRegeneration = config("3 - Extra stamina regeneration", "Enabled", defaultValue: true, "Enable increased stamina regeneration by X% per every Y point of additional stamina");
		extraStaminaRegenerationPercent = config("3 - Extra stamina regeneration", "Percent", 1f, "Stamina regeneration increased by X%");
		extraStaminaRegenerationPoints = config("3 - Extra stamina regeneration", "Points", 10, "Stamina regeneration increased per every Y points of additional stamina");
		extraStaminaRegenerationOnlyFood = config("3 - Extra stamina regeneration", "Stamina from food only", defaultValue: true, "Only stamina gain from food is counted for increased regeneration");
		encumberedStamina = config("4 - Encumbered stamina", "Enabled", defaultValue: true, "Enable encumbered stamina control");
		encumberedStaminaDrainMultiplier = config("4 - Encumbered stamina", "Stamina drain multiplier", 2f, "Encumbered stamina drain multiplier. Set 0 to disable stamina usage while encumbered");
		encumberedStaminaRegeneration = config("4 - Encumbered stamina", "Stamina regeneration while encumbered", defaultValue: true, "Stamina will regenerate while encumbered");
		encumberedStaminaRegenerationMultiplier = config("4 - Encumbered stamina", "Stamina regeneration multiplier", 0.2f, "Stamina regeneration multiplier of normal stamina regeneration rate");
		swimmingStamina = config("5 - Swimming stamina", "Enabled", defaultValue: true, "Enable swimming stamina control");
		swimmingStaminaDrainMultiplier = config("5 - Swimming stamina", "Stamina drain multiplier", 1f, "Swimming stamina drain multiplier. Set 0 to disable stamina usage while swimming");
		swimmingStaminaRegeneration = config("5 - Swimming stamina", "Stamina regeneration while swimming", defaultValue: true, "Stamina will regenerate while encumbered");
		swimmingStaminaRegenerationMultiplier = config("5 - Swimming stamina", "Stamina regeneration multiplier", 0.2f, "Stamina regeneration multiplier of normal stamina regeneration rate");
		swimmingStaminaRegenerationDelay = config("5 - Swimming stamina", "Stamina regeneration delay", 2f, "Additional delay in seconds before stamina begins to regenerate while not moving");
		swimmingRun = config("5 - Swimming stamina", "Swimming acceleration", defaultValue: true, "Press Run hotkey to swim faster depleting proportionally more stamina. Swimming speed will gradually increase until maximum speed is reached.");
		swimmingRunMaximumSpeed = config("5 - Swimming stamina", "Swimming acceleration maximum speed", 2f, "Maximum speed of swimming acceleration in proportion to normal swim speed.");
		sneakingStamina = config("6 - Sneaking stamina", "Enabled", defaultValue: true, "Enable sneaking stamina regeneration control");
		sneakingStaminaDrainMultiplier = config("6 - Sneaking stamina", "Stamina drain multiplier", 1f, "Sneaking stamina drain multiplier");
		sneakingStaminaRegenerationMultiplier = config("6 - Sneaking stamina", "Stamina regeneration while sneaking", 0.5f, "Set additional stamina regen rate. Stamina will regenerate faster while sneaking depending on the Sneak skill\n0.5 with 40 sneak skill means stamina will regenerate 20% faster while sneaking and not moving");
		sneakingStaminaNoEnemies = config("6 - Sneaking stamina", "Stamina is not spent if no enemy in range", defaultValue: true, "Stamina regeneration multiplier of normal stamina regeneration rate");
		sneakingStaminaNoEnemiesRange = config("6 - Sneaking stamina", "Stamina is not spent range", 20f, "Distance to nearby enemy to activate stamina usage while sneaking");
		baseStamina = config("7 - Base stamina", "Enabled", defaultValue: true, "Base stamina will be increased proportionally to skills where set value reached at skill level 100.");
		runBaseStaminaIncrease = config("7 - Base stamina", "Run", 20f, "Base stamina will be increased by set value when Run skill is level 100");
		swimBaseStaminaIncrease = config("7 - Base stamina", "Swim", 20f, "Base stamina will be increased by set value when Swim skill is level 100");
		fishingBaseStaminaIncrease = config("7 - Base stamina", "Fishing", 20f, "Base stamina will be increased by set value when Fishing skill is level 100");
		sneakBaseStaminaIncrease = config("7 - Base stamina", "Sneak", 20f, "Base stamina will be increased by set value when Sneak skill is level 100");
		jumpBaseStaminaIncrease = config("7 - Base stamina", "Jump", 20f, "Base stamina will be increased by set value when Jump skill is level 100");
		handsBaseStaminaIncrease = config("7 - Base stamina", "Unarmed", 0f, "Base stamina will be increased by set value when Unarmed skill is level 100");
		pullStaminaUse = config("8 - Various multipliers", "Fishing pull stamina", 1f, "Stamina required to reel");
		hookedStaminaPerSec = config("8 - Various multipliers", "Fishing hooked stamina", 1f, "Stamina required to keep a fish on the line");
		fishStaminaUse = config("8 - Various multipliers", "Fishing escape stamina use", 1f, "Stamina required to fight fish trying to escape");
		harpoonedStaminaDrain = config("8 - Various multipliers", "Harpooned pull stamina", 1f, "Stamina required to pull harpooned target");
		toolStaminaDrain = config("8 - Various multipliers", "Tools stamina drain", 1f, "Stamina required to use tools such as hammer, hoe, cultivator");
		blockStaminaDrain = config("8 - Various multipliers", "Block stamina drain", 1f, "Stamina required to block");
		runStaminaDrain = config("8 - Various multipliers", "Run stamina drain", 1f, "Stamina required to run");
		dodgeStaminaUsage = config("8 - Various multipliers", "Dodge stamina usage", 1f, "Stamina required to dodge");
		jumpStaminaUsage = config("8 - Various multipliers", "Jump stamina usage", 1f, "Stamina required to jump");
		runStaminaDrainOutOfCombat = config("8 - Various multipliers - Out of combat", "Run stamina drain", 1f, "Stamina required to run");
		dodgeStaminaUsageOutOfCombat = config("8 - Various multipliers - Out of combat", "Dodge stamina usage", 1f, "Stamina required to dodge");
		jumpStaminaUsageOutOfCombat = config("8 - Various multipliers - Out of combat", "Jump stamina usage", 1f, "Stamina required to jump");
		sneakingStaminaUsageOutOfCombat = config("8 - Various multipliers - Out of combat", "Sneak stamina usage", 1f, "Stamina required to sneak");
		hideStaminaValue = config("9 - Misc", "Hide stamina text", defaultValue: false, "Hide stamina text value on stamina bar");
		blockStaminaSkill = config("9 - Misc", "Block stamina usage depends on skill", defaultValue: true, "Amount of stamina needed to block is reduced by 33% when Block skill is 100");
		dodgeStaminaSkill = config("9 - Misc", "Dodge stamina usage depends on Jump skill", defaultValue: true, "Amount of stamina needed to dodge is reduced by 33% when Dodge skill is 100");
		jumpStaminaSkill = config("9 - Misc", "Jump stamina usage depends on Jump skill", defaultValue: true, "Amount of stamina needed to jump is reduced by 33% when Jump skill is 100");
		blockStaminaRegen = config("9 - Misc", "Stamina regen multiplier while blocking", 0.8f, "Stamina regeneration rate while holding block");
		perfectParryStaminaDrain = config("9 - Misc", "Stamina usage multiplier on perfect parry", 0.5f, "Amount of stamina needed to block if it is perfect parry.");
		groundsEnabled = config("Grounds", "Enabled", defaultValue: true, "Enable change of movement speed, run, jump and dodge stamina consumption on different surfaces");
		groundsShowStatusEffect = config("Grounds", "Show status effect", defaultValue: false, "Show status effect of current surface. Status effect will still be shown in Raven menu if disabled.");
		groundsNameDefault = config("Grounds", "Status name by default", "Default", "Localized default name for status effect");
		groundsEnabled.SettingChanged += delegate
		{
			SE_Surface.UpdateSurfaceStatusEffectStats();
		};
		groundsShowStatusEffect.SettingChanged += delegate
		{
			SE_Surface.UpdateSurfaceStatusEffectStats();
		};
		groundsSpeedSnow = config("Grounds - Snow", "Speed multiplier", 1f, "Movement speed multiplier");
		groundsJumpSnow = config("Grounds - Snow", "Jump multiplier", 1f, "Jump height multiplier");
		groundsStaminaDrainSnow = config("Grounds - Snow", "Stamina drain multiplier", 1f, "Stamina drain multiplier");
		groundsStaminaRegenSnow = config("Grounds - Snow", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNameSnow = config("Grounds - Snow", "Status effect name", "Snow", "Localized name for status effect");
		groundsSpeedMud = config("Grounds - Mud", "Speed multiplier", 1f, "Movement speed multiplier (swamps ground)");
		groundsJumpMud = config("Grounds - Mud", "Jump multiplier", 1f, "Jump height multiplier (swamps ground)");
		groundsStaminaDrainMud = config("Grounds - Mud", "Stamina drain multiplier", 1f, "Stamina drain multiplier (swamps ground)");
		groundsStaminaRegenMud = config("Grounds - Mud", "Stamina regen multiplier", 1f, "Stamina regen multiplier (swamps ground)");
		groundsNameMud = config("Grounds - Mud", "Status effect name", "Mud", "Localized name for status effect (swamps ground)");
		groundsSpeedGrass = config("Grounds - Grass", "Speed multiplier", 1f, "Movement speed multiplier (meadows and black forest)");
		groundsJumpGrass = config("Grounds - Grass", "Jump multiplier", 1f, "Jump height multiplier");
		groundsStaminaDrainGrass = config("Grounds - Grass", "Stamina drain multiplier", 1f, "Stamina drain multiplier (meadows and black forest)");
		groundsStaminaRegenGrass = config("Grounds - Grass", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNameGrass = config("Grounds - Grass", "Status effect name", "Grass", "Localized name for status effect (meadows and black forest)");
		groundsSpeedWood = config("Grounds - Wood", "Speed multiplier", 1.15f, "Movement speed multiplier");
		groundsJumpWood = config("Grounds - Wood", "Jump multiplier", 1.05f, "Jump height multiplier");
		groundsStaminaDrainWood = config("Grounds - Wood", "Stamina drain multiplier", 0.85f, "Stamina drain multiplier");
		groundsStaminaRegenWood = config("Grounds - Wood", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNameWood = config("Grounds - Wood", "Status effect name", "Wood", "Localized name for status effect");
		groundsSpeedHardWood = config("Grounds - HardWood", "Speed multiplier", 1.2f, "Movement speed multiplier");
		groundsJumpHardWood = config("Grounds - HardWood", "Jump multiplier", 1.05f, "Jump height multiplier");
		groundsStaminaDrainHardWood = config("Grounds - HardWood", "Stamina drain multiplier", 0.85f, "Stamina drain multiplier");
		groundsStaminaRegenHardWood = config("Grounds - HardWood", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNameHardWood = config("Grounds - HardWood", "Status effect name", "Hardwood", "Localized name for status effect");
		groundsSpeedStone = config("Grounds - Stone", "Speed multiplier", 1.25f, "Movement speed multiplier");
		groundsJumpStone = config("Grounds - Stone", "Jump multiplier", 1.1f, "Jump height multiplier");
		groundsStaminaDrainStone = config("Grounds - Stone", "Stamina drain multiplier", 0.8f, "Stamina drain multiplier");
		groundsStaminaRegenStone = config("Grounds - Stone", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNameStone = config("Grounds - Stone", "Status effect name", "Stone", "Localized name for status effect");
		groundsSpeedMarble = config("Grounds - Marble", "Speed multiplier", 1.3f, "Movement speed multiplier (dverger marble, ashstone and ancient)");
		groundsJumpMarble = config("Grounds - Marble", "Jump multiplier", 1.1f, "Jump height multiplier (dverger marble, ashstone and ancient)");
		groundsStaminaDrainMarble = config("Grounds - Marble", "Stamina drain multiplier", 0.75f, "Stamina drain multiplier (dverger marble, ashstone and ancient)");
		groundsStaminaRegenMarble = config("Grounds - Marble", "Stamina regen multiplier", 1f, "Stamina regen multiplier (dverger marble, ashstone and ancient)");
		groundsNameMarble = config("Grounds - Marble", "Status effect name", "Marble", "Localized name for status effect (dverger marble, ashstone and ancient)");
		groundsSpeedMetal = config("Grounds - Metal", "Speed multiplier", 1.25f, "Movement speed multiplier");
		groundsJumpMetal = config("Grounds - Metal", "Jump multiplier", 1.05f, "Jump height multiplier");
		groundsStaminaDrainMetal = config("Grounds - Metal", "Stamina drain multiplier", 0.8f, "Stamina drain multiplier");
		groundsStaminaRegenMetal = config("Grounds - Metal", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNameMetal = config("Grounds - Metal", "Status effect name", "Metal", "Localized name for status effect");
		groundsSpeedCultivated = config("Grounds - Cultivated", "Speed multiplier", 0.9f, "Movement speed multiplier");
		groundsJumpCultivated = config("Grounds - Cultivated", "Jump multiplier", 0.9f, "Jump height multiplier");
		groundsStaminaDrainCultivated = config("Grounds - Cultivated", "Stamina drain multiplier", 1.1f, "Stamina drain multiplier");
		groundsStaminaRegenCultivated = config("Grounds - Cultivated", "Stamina regen multiplier", 1.1f, "Stamina regen multiplier");
		groundsNameCultivated = config("Grounds - Cultivated", "Status effect name", "Cultivated", "Localized name for status effect");
		groundsSpeedCleared = config("Grounds - Cleared", "Speed multiplier", 1.1f, "Movement speed multiplier");
		groundsJumpCleared = config("Grounds - Cleared", "Jump multiplier", 1f, "Jump height multiplier");
		groundsStaminaDrainCleared = config("Grounds - Cleared", "Stamina drain multiplier", 0.9f, "Stamina drain multiplier");
		groundsStaminaRegenCleared = config("Grounds - Cleared", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNameCleared = config("Grounds - Cleared", "Status effect name", "Cleared", "Localized name for status effect");
		groundsSpeedPaved = config("Grounds - Paved", "Speed multiplier", 1.2f, "Movement speed multiplier");
		groundsJumpPaved = config("Grounds - Paved", "Jump multiplier", 1.05f, "Jump height multiplier");
		groundsStaminaDrainPaved = config("Grounds - Paved", "Stamina drain multiplier", 0.85f, "Stamina drain multiplier");
		groundsStaminaRegenPaved = config("Grounds - Paved", "Stamina regen multiplier", 1f, "Stamina regen multiplier");
		groundsNamePaved = config("Grounds - Paved", "Status effect name", "Paved", "Localized name for status effect");
		groundsSpeedAsh = config("Grounds - Ash", "Speed multiplier", 1f, "Movement speed multiplier (Ashlands ground)");
		groundsJumpAsh = config("Grounds - Ash", "Jump multiplier", 1f, "Jump height multiplier (Ashlands ground)");
		groundsStaminaDrainAsh = config("Grounds - Ash", "Stamina drain multiplier", 1f, "Stamina drain multiplier (Ashlands ground)");
		groundsStaminaRegenAsh = config("Grounds - Ash", "Stamina regen multiplier", 1f, "Stamina regen multiplier (Ashlands ground)");
		groundsNameAsh = config("Grounds - Ash", "Status effect name", "Ash", "Localized name for status effect (Ashlands ground)");
		groundsSpeedLava = config("Grounds - Lava", "Speed multiplier", 1f, "Movement speed multiplier (lava in Ashlands)");
		groundsJumpLava = config("Grounds - Lava", "Jump multiplier", 1f, "Jump height multiplier (lava in Ashlands)");
		groundsStaminaDrainLava = config("Grounds - Lava", "Stamina drain multiplier", 1f, "Stamina drain multiplier (lava in Ashlands)");
		groundsStaminaRegenLava = config("Grounds - Lava", "Stamina regen multiplier", 1f, "Stamina regen multiplier (lava in Ashlands)");
		groundsNameLava = config("Grounds - Lava", "Status effect name", "Lava", "Localized name for status effect (lava in Ashlands)");
		groundsSpeedIce = config("Grounds - Ice", "Speed multiplier", 1f, "Movement speed multiplier on ice");
		groundsJumpIce = config("Grounds - Ice", "Jump multiplier", 1f, "Jump height multiplier on ice");
		groundsStaminaDrainIce = config("Grounds - Ice", "Stamina drain multiplier", 1f, "Stamina drain multiplier on ice");
		groundsStaminaRegenIce = config("Grounds - Ice", "Stamina regen multiplier", 1f, "Stamina regen multiplier on ice");
		groundsNameIce = config("Grounds - Ice", "Status effect name", "Ice", "Localized name for the ice status effect");
	}

	private ConfigEntry<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true)
	{
		ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, description);
		((ConditionalConfigSync)configSync).AddConfigEntry<T>(val, (ConfigSyncMode)1, synchronizedSetting);
		return val;
	}

	private ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
	}

	public static void LogInfo(object message)
	{
		if (loggingEnabled.Value)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo(message);
		}
	}

	public static void LogWarning(object data)
	{
		if (loggingEnabled.Value)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning(data);
		}
	}

	public string GetStringConfig(string fieldName)
	{
		return (((object)this).GetType().GetField(fieldName).GetValue(this) as ConfigEntry<string>).Value;
	}

	public float GetFloatConfig(string fieldName)
	{
		return (((object)this).GetType().GetField(fieldName).GetValue(this) as ConfigEntry<float>).Value;
	}
}