Decompiled source of GoosCombatOverhaul v2.0.2

BepInEx/plugins/GooCombatOverhaul/GooCombatOverhaul.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ConditionalConfigSync;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("GooCombatOverhaul")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GooCombatOverhaul")]
[assembly: AssemblyTitle("GooCombatOverhaul")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace GooCombatOverhaul
{
	[BepInDependency("_shudnal.ConditionalConfigSync", "1.0.8")]
	[BepInPlugin("goo.valheim.gooscombatoverhaul", "Goo's Combat Overhaul", "2.0.2")]
	public sealed class GooCombatOverhaulPlugin : BaseUnityPlugin
	{
		private enum DamageBonusKind
		{
			Backstab,
			StaggeredEnemy,
			Flanking,
			CounterDamage
		}

		private enum ModFeature
		{
			Damage,
			Staggering,
			HyperArmor,
			CounterDamage,
			HitStop,
			AttackMovement,
			Animation,
			AttackRotation,
			HitRay,
			StealthAttributes,
			MultiTargetPenalty,
			Pvp,
			Resources,
			Blocking
		}

		private enum IncomingParryStaggerSource
		{
			None,
			Ranged,
			Aoe
		}

		[Flags]
		private enum RuntimeRefreshFlags
		{
			None = 0,
			Attack = 1,
			Blocking = 2,
			Staff = 4,
			Character = 8,
			Player = 0x10,
			EquipmentVisual = 0x20
		}

		private enum ArmorWeightClass
		{
			Light,
			Medium,
			Heavy
		}

		private sealed class SoulsLikeBlockStaminaState
		{
			public readonly ItemData Blocker;

			public readonly float StaminaCost;

			public readonly float ValidUntil;

			public bool Consumed;

			public SoulsLikeBlockStaminaState(ItemData blocker, float staminaCost, float validUntil)
			{
				Blocker = blocker;
				StaminaCost = staminaCost;
				ValidUntil = validUntil;
			}
		}

		private sealed class SoulsLikeBlockBreakState
		{
			public readonly ItemData Blocker;

			public readonly float StaminaBefore;

			public readonly float StaminaCost;

			public readonly bool StaminaWillBeCleared;

			public readonly float ValidUntil;

			public SoulsLikeBlockBreakState(ItemData blocker, float staminaBefore, float staminaCost, bool staminaWillBeCleared, float validUntil)
			{
				Blocker = blocker;
				StaminaBefore = staminaBefore;
				StaminaCost = staminaCost;
				StaminaWillBeCleared = staminaWillBeCleared;
				ValidUntil = validUntil;
			}
		}

		private sealed class DirectSledgeHitPoint
		{
			public GameObject Go = null;

			public Collider Collider = null;

			public Vector3 Point;

			public float Distance;
		}

		private static class DurabilityPatches
		{
			public static void AttackDurabilityPrefix(Attack __instance, ref DurabilityPatchState? __state)
			{
				if (AlternateEnvironmentHitRayPassDepth > 0)
				{
					__state = null;
					return;
				}
				__state = CaptureDurabilityState((__instance != null) ? __instance.GetWeapon() : null);
			}

			public static void SingleItemDurabilityPrefix(ItemData toolItem, ref DurabilityPatchState? __state)
			{
				__state = CaptureDurabilityState(toolItem);
			}

			public static void BlockDurabilityPrefix(Humanoid __instance, ref DurabilityPatchState? __state)
			{
				ItemData val = GetEquippedItem(__instance, "m_leftItem") ?? ((__instance != null) ? __instance.GetCurrentWeapon() : null);
				__state = CaptureDurabilityState(val);
			}

			public static void ArmorDurabilityPrefix(Player __instance, ref DurabilityPatchState? __state)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					__state = null;
					return;
				}
				__state = CaptureDurabilityState(GetEquippedItem((Humanoid)(object)__instance, "m_chestItem"), GetEquippedItem((Humanoid)(object)__instance, "m_legItem"), GetEquippedItem((Humanoid)(object)__instance, "m_helmetItem"), GetEquippedItem((Humanoid)(object)__instance, "m_shoulderItem"));
			}

			public static void GetPlaceDurabilityPostfix(ItemData tool, ref float __result)
			{
				if (ModActive && tool != null && !(__result <= 0f))
				{
					bool unbreakable;
					float durabilityConsumptionMultiplier = GetDurabilityConsumptionMultiplier(tool, out unbreakable);
					__result = (unbreakable ? 0f : (__result * durabilityConsumptionMultiplier));
				}
			}

			public static Exception? DurabilityFinalizer(Exception? __exception, DurabilityPatchState? __state)
			{
				ApplyDurabilityState(__state);
				return __exception;
			}
		}

		internal sealed class GearDurabilityConfig
		{
			public ConfigEntry<bool> Unbreakable { get; }

			public ConfigEntry<float> DurabilityConsumptionMultiplier { get; }

			public ConfigEntry<float> BaseDurabilityMultiplier { get; }

			public ConfigEntry<float> DurabilityMultiplier { get; }

			public GearDurabilityConfig(ConfigEntry<bool> unbreakable, ConfigEntry<float> durabilityConsumptionMultiplier, ConfigEntry<float> baseDurabilityMultiplier, ConfigEntry<float> durabilityMultiplier)
			{
				Unbreakable = unbreakable;
				DurabilityConsumptionMultiplier = durabilityConsumptionMultiplier;
				BaseDurabilityMultiplier = baseDurabilityMultiplier;
				DurabilityMultiplier = durabilityMultiplier;
			}
		}

		public sealed class DurabilityPatchState
		{
			public readonly Dictionary<ItemData, float> Before = new Dictionary<ItemData, float>();

			public DurabilityPatchState(IEnumerable<ItemData> items)
			{
				foreach (ItemData item in items)
				{
					if (item != null && item.m_shared != null && ItemUsesDurability(item) && !Before.ContainsKey(item))
					{
						Before[item] = item.m_durability;
					}
				}
			}
		}

		public sealed class FoodFreezePatchState
		{
			public readonly List<FoodSnapshot> FoodSnapshots = new List<FoodSnapshot>();

			public bool Restored { get; set; }
		}

		private sealed class WeaponVisualSuppressionState
		{
			private readonly List<WeaponParticleSystemState> _systems;

			private readonly List<WeaponTrailRendererState> _trailRenderers;

			private readonly List<WeaponMeleeTrailState> _meleeTrails;

			private readonly List<WeaponLightState> _lights;

			private WeaponVisualSuppressionState(GameObject root)
			{
				_systems = (from system in root.GetComponentsInChildren<ParticleSystem>(true)
					where (Object)(object)system != (Object)null
					select new WeaponParticleSystemState(system)).ToList();
				_trailRenderers = (from trail in root.GetComponentsInChildren<TrailRenderer>(true)
					where (Object)(object)trail != (Object)null
					select new WeaponTrailRendererState(trail)).ToList();
				_meleeTrails = (from trail in root.GetComponentsInChildren<MeleeWeaponTrail>(true)
					where (Object)(object)trail != (Object)null
					select new WeaponMeleeTrailState(trail)).ToList();
				_lights = (from light in root.GetComponentsInChildren<Light>(true)
					where (Object)(object)light != (Object)null
					select new WeaponLightState(light)).ToList();
			}

			public static WeaponVisualSuppressionState Capture(GameObject root)
			{
				return new WeaponVisualSuppressionState(root);
			}

			public void Disable()
			{
				foreach (WeaponParticleSystemState system in _systems)
				{
					system.Disable();
				}
				foreach (WeaponTrailRendererState trailRenderer in _trailRenderers)
				{
					trailRenderer.Disable();
				}
				foreach (WeaponMeleeTrailState meleeTrail in _meleeTrails)
				{
					meleeTrail.Disable();
				}
				foreach (WeaponLightState light in _lights)
				{
					light.Disable();
				}
			}

			public void Restore()
			{
				foreach (WeaponParticleSystemState system in _systems)
				{
					system.Restore();
				}
				foreach (WeaponTrailRendererState trailRenderer in _trailRenderers)
				{
					trailRenderer.Restore();
				}
				foreach (WeaponMeleeTrailState meleeTrail in _meleeTrails)
				{
					meleeTrail.Restore();
				}
				foreach (WeaponLightState light in _lights)
				{
					light.Restore();
				}
			}
		}

		private sealed class WeaponMeleeTrailState
		{
			private readonly MeleeWeaponTrail _trail;

			private readonly bool _emit;

			public WeaponMeleeTrailState(MeleeWeaponTrail trail)
			{
				_trail = trail;
				_emit = (Object)(object)trail != (Object)null && MeleeWeaponTrailEmitRef.Invoke(trail);
			}

			public void Disable()
			{
				if ((Object)(object)_trail != (Object)null)
				{
					_trail.Emit = false;
				}
			}

			public void Restore()
			{
				if ((Object)(object)_trail != (Object)null)
				{
					_trail.Emit = _emit;
				}
			}
		}

		private sealed class WeaponLightState
		{
			private readonly Light _light;

			private readonly bool _enabled;

			public WeaponLightState(Light light)
			{
				_light = light;
				_enabled = ((Behaviour)light).enabled;
			}

			public void Disable()
			{
				if ((Object)(object)_light != (Object)null)
				{
					((Behaviour)_light).enabled = false;
				}
			}

			public void Restore()
			{
				if ((Object)(object)_light != (Object)null)
				{
					((Behaviour)_light).enabled = _enabled;
				}
			}
		}

		private sealed class WeaponTrailRendererState
		{
			private readonly TrailRenderer _renderer;

			private readonly bool _enabled;

			public WeaponTrailRendererState(TrailRenderer renderer)
			{
				_renderer = renderer;
				_enabled = ((Renderer)renderer).enabled;
			}

			public void Disable()
			{
				if ((Object)(object)_renderer != (Object)null)
				{
					((Renderer)_renderer).enabled = false;
				}
			}

			public void Restore()
			{
				if ((Object)(object)_renderer != (Object)null)
				{
					((Renderer)_renderer).enabled = _enabled;
				}
			}
		}

		private sealed class WeaponParticleSystemState
		{
			private readonly ParticleSystem _system;

			private readonly ParticleSystemRenderer? _renderer;

			private readonly bool _emissionEnabled;

			private readonly bool _rendererEnabled;

			private readonly bool _wasPlaying;

			private readonly bool _wasPaused;

			public WeaponParticleSystemState(ParticleSystem system)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				_system = system;
				_renderer = ((Component)system).GetComponent<ParticleSystemRenderer>();
				EmissionModule emission = system.emission;
				_emissionEnabled = ((EmissionModule)(ref emission)).enabled;
				_rendererEnabled = (Object)(object)_renderer != (Object)null && ((Renderer)_renderer).enabled;
				_wasPlaying = system.isPlaying;
				_wasPaused = system.isPaused;
			}

			public void Disable()
			{
				//IL_0019: 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)
				if (!((Object)(object)_system == (Object)null))
				{
					EmissionModule emission = _system.emission;
					((EmissionModule)(ref emission)).enabled = false;
					_system.Stop(true, (ParticleSystemStopBehavior)0);
					if ((Object)(object)_renderer != (Object)null)
					{
						((Renderer)_renderer).enabled = false;
					}
				}
			}

			public void Restore()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_system == (Object)null)
				{
					return;
				}
				EmissionModule emission = _system.emission;
				((EmissionModule)(ref emission)).enabled = _emissionEnabled;
				if ((Object)(object)_renderer != (Object)null)
				{
					((Renderer)_renderer).enabled = _rendererEnabled;
				}
				if (((Component)_system).gameObject.activeInHierarchy)
				{
					if (_wasPaused)
					{
						_system.Pause(true);
					}
					else if (_wasPlaying)
					{
						_system.Play(true);
					}
				}
			}
		}

		private sealed class EquipmentMovementModifierCache
		{
			public float Total { get; }

			public EquipmentMovementModifierCache(float total)
			{
				Total = total;
			}
		}

		public sealed class FoodSnapshot
		{
			public readonly Food Food;

			private readonly float _time;

			public FoodSnapshot(Food food)
			{
				Food = food;
				_time = food.m_time;
			}

			public void RestoreTimeAndRecalculateValues()
			{
				Food.m_time = _time;
				SharedData val = Food.m_item?.m_shared;
				if (val != null)
				{
					float num = 1f;
					if (val.m_foodBurnTime > 0f)
					{
						num = Mathf.Pow(Mathf.Clamp01(Food.m_time / val.m_foodBurnTime), 0.3f);
					}
					Food.m_health = val.m_food * num;
					Food.m_stamina = val.m_foodStamina * num;
					Food.m_eitr = val.m_foodEitr * num;
				}
			}
		}

		internal sealed class BlockedHitDamageTakenConfig
		{
			public ConfigEntry<float> Generic { get; }

			public ConfigEntry<float> Blunt { get; }

			public ConfigEntry<float> Slash { get; }

			public ConfigEntry<float> Pierce { get; }

			public ConfigEntry<float> Chop { get; }

			public ConfigEntry<float> Pickaxe { get; }

			public ConfigEntry<float> Fire { get; }

			public ConfigEntry<float> Frost { get; }

			public ConfigEntry<float> Lightning { get; }

			public ConfigEntry<float> Poison { get; }

			public ConfigEntry<float> Spirit { get; }

			public BlockedHitDamageTakenConfig(ConfigEntry<float> generic, ConfigEntry<float> blunt, ConfigEntry<float> slash, ConfigEntry<float> pierce, ConfigEntry<float> chop, ConfigEntry<float> pickaxe, ConfigEntry<float> fire, ConfigEntry<float> frost, ConfigEntry<float> lightning, ConfigEntry<float> poison, ConfigEntry<float> spirit)
			{
				Generic = generic;
				Blunt = blunt;
				Slash = slash;
				Pierce = pierce;
				Chop = chop;
				Pickaxe = pickaxe;
				Fire = fire;
				Frost = frost;
				Lightning = lightning;
				Poison = poison;
				Spirit = spirit;
			}
		}

		internal sealed class WeaponBlockExtraConfig
		{
			public ConfigEntry<bool> CanParry { get; }

			public ConfigEntry<float> ParryBonusMultiplier { get; }

			public ConfigEntry<float> ParryWindowTimeMultiplier { get; }

			public ConfigEntry<float> PvpParryBonusMultiplier { get; }

			public ConfigEntry<float> PvpBlockForceMultiplier { get; }

			public ConfigEntry<float> PvpBlockBreakThresholdMultiplier { get; }

			public ConfigEntry<bool> SoulsLikeBlockBreak { get; }

			public ConfigEntry<bool> SoulsLikeBlockStaminaMode { get; }

			public ConfigEntry<float> SoulsLikeBlockStaminaBaseRate { get; }

			public ConfigEntry<float> KnockbackTakenWhileBlockingMultiplier { get; }

			public ConfigEntry<float> BlockingMovementSpeedMultiplier { get; }

			public ConfigEntry<bool> EnableRunningWhileBlocking { get; }

			public ConfigEntry<float> RunningWhileBlockingMovementSpeedMultiplier { get; }

			public WeaponBlockExtraConfig(ConfigEntry<bool> canParry, ConfigEntry<float> parryBonusMultiplier, ConfigEntry<float> parryWindowTimeMultiplier, ConfigEntry<float> pvpParryBonusMultiplier, ConfigEntry<float> pvpBlockForceMultiplier, ConfigEntry<float> pvpBlockBreakThresholdMultiplier, ConfigEntry<bool> soulsLikeBlockBreak, ConfigEntry<bool> soulsLikeBlockStaminaMode, ConfigEntry<float> soulsLikeBlockStaminaBaseRate, ConfigEntry<float> knockbackTakenWhileBlockingMultiplier, ConfigEntry<float> blockingMovementSpeedMultiplier, ConfigEntry<bool> enableRunningWhileBlocking, ConfigEntry<float> runningWhileBlockingMovementSpeedMultiplier)
			{
				CanParry = canParry;
				ParryBonusMultiplier = parryBonusMultiplier;
				ParryWindowTimeMultiplier = parryWindowTimeMultiplier;
				PvpParryBonusMultiplier = pvpParryBonusMultiplier;
				PvpBlockForceMultiplier = pvpBlockForceMultiplier;
				PvpBlockBreakThresholdMultiplier = pvpBlockBreakThresholdMultiplier;
				SoulsLikeBlockBreak = soulsLikeBlockBreak;
				SoulsLikeBlockStaminaMode = soulsLikeBlockStaminaMode;
				SoulsLikeBlockStaminaBaseRate = soulsLikeBlockStaminaBaseRate;
				KnockbackTakenWhileBlockingMultiplier = knockbackTakenWhileBlockingMultiplier;
				BlockingMovementSpeedMultiplier = blockingMovementSpeedMultiplier;
				EnableRunningWhileBlocking = enableRunningWhileBlocking;
				RunningWhileBlockingMovementSpeedMultiplier = runningWhileBlockingMovementSpeedMultiplier;
			}
		}

		internal sealed class ShieldTypeBlockConfig
		{
			public ConfigEntry<bool> CanParry { get; }

			public ConfigEntry<float> BlockArmorMultiplier { get; }

			public ConfigEntry<float> BlockForceMultiplier { get; }

			public ConfigEntry<float> ParryBonusMultiplier { get; }

			public ConfigEntry<float> ParryWindowTimeMultiplier { get; }

			public ConfigEntry<float> ParryAdrenalineMultiplier { get; }

			public ConfigEntry<float> BlockStaminaConsumptionRate { get; }

			public ConfigEntry<float> BlockingStaminaRegenMultiplier { get; }

			public ConfigEntry<float> BlockBreakThresholdMultiplier { get; }

			public ConfigEntry<float> PvpBlockArmorMultiplier { get; }

			public ConfigEntry<float> PvpBlockForceMultiplier { get; }

			public ConfigEntry<float> PvpParryBonusMultiplier { get; }

			public ConfigEntry<float> PvpBlockBreakThresholdMultiplier { get; }

			public ConfigEntry<bool> SoulsLikeBlockBreak { get; }

			public ConfigEntry<bool> SoulsLikeBlockStaminaMode { get; }

			public ConfigEntry<float> SoulsLikeBlockStaminaBaseRate { get; }

			public ConfigEntry<float> KnockbackTakenWhileBlockingMultiplier { get; }

			public ConfigEntry<float> MovementModifierPercent { get; }

			public ConfigEntry<float> BlockingMovementSpeedMultiplier { get; }

			public ConfigEntry<bool> EnableRunningWhileBlocking { get; }

			public ConfigEntry<float> RunningWhileBlockingMovementSpeedMultiplier { get; }

			public ShieldTypeBlockConfig(ConfigEntry<bool> canParry, ConfigEntry<float> blockArmorMultiplier, ConfigEntry<float> blockForceMultiplier, ConfigEntry<float> parryBonusMultiplier, ConfigEntry<float> parryWindowTimeMultiplier, ConfigEntry<float> parryAdrenalineMultiplier, ConfigEntry<float> blockStaminaConsumptionRate, ConfigEntry<float> blockingStaminaRegenMultiplier, ConfigEntry<float> blockBreakThresholdMultiplier, ConfigEntry<float> pvpBlockArmorMultiplier, ConfigEntry<float> pvpBlockForceMultiplier, ConfigEntry<float> pvpParryBonusMultiplier, ConfigEntry<float> pvpBlockBreakThresholdMultiplier, ConfigEntry<bool> soulsLikeBlockBreak, ConfigEntry<bool> soulsLikeBlockStaminaMode, ConfigEntry<float> soulsLikeBlockStaminaBaseRate, ConfigEntry<float> knockbackTakenWhileBlockingMultiplier, ConfigEntry<float> movementModifierPercent, ConfigEntry<float> blockingMovementSpeedMultiplier, ConfigEntry<bool> enableRunningWhileBlocking, ConfigEntry<float> runningWhileBlockingMovementSpeedMultiplier)
			{
				CanParry = canParry;
				BlockArmorMultiplier = blockArmorMultiplier;
				BlockForceMultiplier = blockForceMultiplier;
				ParryBonusMultiplier = parryBonusMultiplier;
				ParryWindowTimeMultiplier = parryWindowTimeMultiplier;
				ParryAdrenalineMultiplier = parryAdrenalineMultiplier;
				BlockStaminaConsumptionRate = blockStaminaConsumptionRate;
				BlockingStaminaRegenMultiplier = blockingStaminaRegenMultiplier;
				BlockBreakThresholdMultiplier = blockBreakThresholdMultiplier;
				PvpBlockArmorMultiplier = pvpBlockArmorMultiplier;
				PvpBlockForceMultiplier = pvpBlockForceMultiplier;
				PvpParryBonusMultiplier = pvpParryBonusMultiplier;
				PvpBlockBreakThresholdMultiplier = pvpBlockBreakThresholdMultiplier;
				SoulsLikeBlockBreak = soulsLikeBlockBreak;
				SoulsLikeBlockStaminaMode = soulsLikeBlockStaminaMode;
				SoulsLikeBlockStaminaBaseRate = soulsLikeBlockStaminaBaseRate;
				KnockbackTakenWhileBlockingMultiplier = knockbackTakenWhileBlockingMultiplier;
				MovementModifierPercent = movementModifierPercent;
				BlockingMovementSpeedMultiplier = blockingMovementSpeedMultiplier;
				EnableRunningWhileBlocking = enableRunningWhileBlocking;
				RunningWhileBlockingMovementSpeedMultiplier = runningWhileBlockingMovementSpeedMultiplier;
			}
		}

		internal sealed class StaffBlockConfig
		{
			public ConfigEntry<bool> CanParry { get; }

			public ConfigEntry<float> BlockArmorMultiplier { get; }

			public ConfigEntry<float> BlockForceMultiplier { get; }

			public ConfigEntry<float> ParryBonusMultiplier { get; }

			public ConfigEntry<float> ParryWindowTimeMultiplier { get; }

			public ConfigEntry<float> ParryAdrenalineMultiplier { get; }

			public ConfigEntry<float> BlockStaminaConsumptionRate { get; }

			public ConfigEntry<float> BlockingStaminaRegenMultiplier { get; }

			public ConfigEntry<float> BlockBreakThresholdMultiplier { get; }

			public ConfigEntry<float> PvpBlockArmorMultiplier { get; }

			public ConfigEntry<float> PvpBlockForceMultiplier { get; }

			public ConfigEntry<float> PvpParryBonusMultiplier { get; }

			public ConfigEntry<float> PvpBlockBreakThresholdMultiplier { get; }

			public ConfigEntry<bool> SoulsLikeBlockBreak { get; }

			public ConfigEntry<bool> SoulsLikeBlockStaminaMode { get; }

			public ConfigEntry<float> SoulsLikeBlockStaminaBaseRate { get; }

			public ConfigEntry<float> KnockbackTakenWhileBlockingMultiplier { get; }

			public ConfigEntry<bool> EnableRunningWhileBlocking { get; }

			public ConfigEntry<float> RunningWhileBlockingMovementSpeedMultiplier { get; }

			public ConfigEntry<float> AttackMovementModifier { get; }

			public ConfigEntry<float> AttackRotationFactor { get; }

			public StaffBlockConfig(ConfigEntry<bool> canParry, ConfigEntry<float> blockArmorMultiplier, ConfigEntry<float> blockForceMultiplier, ConfigEntry<float> parryBonusMultiplier, ConfigEntry<float> parryWindowTimeMultiplier, ConfigEntry<float> parryAdrenalineMultiplier, ConfigEntry<float> blockStaminaConsumptionRate, ConfigEntry<float> blockingStaminaRegenMultiplier, ConfigEntry<float> blockBreakThresholdMultiplier, ConfigEntry<float> pvpBlockArmorMultiplier, ConfigEntry<float> pvpBlockForceMultiplier, ConfigEntry<float> pvpParryBonusMultiplier, ConfigEntry<float> pvpBlockBreakThresholdMultiplier, ConfigEntry<bool> soulsLikeBlockBreak, ConfigEntry<bool> soulsLikeBlockStaminaMode, ConfigEntry<float> soulsLikeBlockStaminaBaseRate, ConfigEntry<float> knockbackTakenWhileBlockingMultiplier, ConfigEntry<bool> enableRunningWhileBlocking, ConfigEntry<float> runningWhileBlockingMovementSpeedMultiplier, ConfigEntry<float> attackMovementModifier, ConfigEntry<float> attackRotationFactor)
			{
				CanParry = canParry;
				BlockArmorMultiplier = blockArmorMultiplier;
				BlockForceMultiplier = blockForceMultiplier;
				ParryBonusMultiplier = parryBonusMultiplier;
				ParryWindowTimeMultiplier = parryWindowTimeMultiplier;
				ParryAdrenalineMultiplier = parryAdrenalineMultiplier;
				BlockStaminaConsumptionRate = blockStaminaConsumptionRate;
				BlockingStaminaRegenMultiplier = blockingStaminaRegenMultiplier;
				BlockBreakThresholdMultiplier = blockBreakThresholdMultiplier;
				PvpBlockArmorMultiplier = pvpBlockArmorMultiplier;
				PvpBlockForceMultiplier = pvpBlockForceMultiplier;
				PvpParryBonusMultiplier = pvpParryBonusMultiplier;
				PvpBlockBreakThresholdMultiplier = pvpBlockBreakThresholdMultiplier;
				SoulsLikeBlockBreak = soulsLikeBlockBreak;
				SoulsLikeBlockStaminaMode = soulsLikeBlockStaminaMode;
				SoulsLikeBlockStaminaBaseRate = soulsLikeBlockStaminaBaseRate;
				KnockbackTakenWhileBlockingMultiplier = knockbackTakenWhileBlockingMultiplier;
				EnableRunningWhileBlocking = enableRunningWhileBlocking;
				RunningWhileBlockingMovementSpeedMultiplier = runningWhileBlockingMovementSpeedMultiplier;
				AttackMovementModifier = attackMovementModifier;
				AttackRotationFactor = attackRotationFactor;
			}
		}

		internal sealed class StaffSummonConfig
		{
			public ConfigEntry<bool> AttackPlayersInPvp { get; }

			public ConfigEntry<float> SizeMultiplier { get; }

			public ConfigEntry<float> AttackSpeedMultiplier { get; }

			public ConfigEntry<int> Level { get; }

			public ConfigEntry<float>? HealthMultiplier { get; }

			public ConfigEntry<float> HealthConsumptionRate { get; }

			public ConfigEntry<int> BaseSpawnCapLevel1 { get; }

			public ConfigEntry<int> BaseSpawnCapLevel2 { get; }

			public ConfigEntry<int> BaseSpawnCapLevel3 { get; }

			public ConfigEntry<int> BaseSpawnCapLevel4 { get; }

			public StaffSummonConfig(ConfigEntry<bool> attackPlayersInPvp, ConfigEntry<float> sizeMultiplier, ConfigEntry<float> attackSpeedMultiplier, ConfigEntry<int> level, ConfigEntry<float>? healthMultiplier, ConfigEntry<float> healthConsumptionRate, ConfigEntry<int> baseSpawnCapLevel1, ConfigEntry<int> baseSpawnCapLevel2, ConfigEntry<int> baseSpawnCapLevel3, ConfigEntry<int> baseSpawnCapLevel4)
			{
				AttackPlayersInPvp = attackPlayersInPvp;
				SizeMultiplier = sizeMultiplier;
				AttackSpeedMultiplier = attackSpeedMultiplier;
				Level = level;
				HealthMultiplier = healthMultiplier;
				HealthConsumptionRate = healthConsumptionRate;
				BaseSpawnCapLevel1 = baseSpawnCapLevel1;
				BaseSpawnCapLevel2 = baseSpawnCapLevel2;
				BaseSpawnCapLevel3 = baseSpawnCapLevel3;
				BaseSpawnCapLevel4 = baseSpawnCapLevel4;
			}
		}

		internal sealed class StaffShieldActiveConfig
		{
			public ConfigEntry<float> HealthConsumptionRate { get; }

			public ConfigEntry<float> StaggerMitigationMultiplier { get; }

			public ConfigEntry<float> PvpStaggerMitigationMultiplier { get; }

			public ConfigEntry<float> KnockbackMitigationMultiplier { get; }

			public ConfigEntry<float> PvpKnockbackMitigationMultiplier { get; }

			public ConfigEntry<float> ActiveParryBonusMultiplier { get; }

			public StaffShieldActiveConfig(ConfigEntry<float> healthConsumptionRate, ConfigEntry<float> staggerMitigationMultiplier, ConfigEntry<float> pvpStaggerMitigationMultiplier, ConfigEntry<float> knockbackMitigationMultiplier, ConfigEntry<float> pvpKnockbackMitigationMultiplier, ConfigEntry<float> activeParryBonusMultiplier)
			{
				HealthConsumptionRate = healthConsumptionRate;
				StaggerMitigationMultiplier = staggerMitigationMultiplier;
				PvpStaggerMitigationMultiplier = pvpStaggerMitigationMultiplier;
				KnockbackMitigationMultiplier = knockbackMitigationMultiplier;
				PvpKnockbackMitigationMultiplier = pvpKnockbackMitigationMultiplier;
				ActiveParryBonusMultiplier = activeParryBonusMultiplier;
			}
		}

		internal sealed class StaffConfig
		{
			public string PrefabName { get; }

			public bool DirectAttack { get; }

			public ConfigEntry<float>? DamageMultiplier { get; }

			public ConfigEntry<float>? StaggerMultiplier { get; }

			public ConfigEntry<float> AttackAnimationSpeedMultiplier { get; }

			public ConfigEntry<float> EitrRateMultiplier { get; }

			public ConfigEntry<float> AttackStartNoiseMultiplier { get; }

			public ConfigEntry<float> AttackHitNoiseMultiplier { get; }

			public ConfigEntry<float> BackstabDamageMultiplier { get; }

			public ConfigEntry<float>? PvpDamageMultiplier { get; }

			public ConfigEntry<float>? PvpStaggerMultiplier { get; }

			public ConfigEntry<float>? PvpKnockbackForceMultiplier { get; }

			public ConfigEntry<float>? ProjectileSpeedMultiplier { get; }

			public ConfigEntry<float>? AoeRadiusMultiplier { get; }

			public ConfigEntry<float>? SpreadMultiplier { get; }

			public ConfigEntry<float>? ShieldHealthMultiplier { get; }

			public ConfigEntry<float>? DamageTakenFromPlayersMultiplier { get; }

			public StaffConfig(string prefabName, bool directAttack, ConfigEntry<float>? damageMultiplier, ConfigEntry<float>? staggerMultiplier, ConfigEntry<float> attackAnimationSpeedMultiplier, ConfigEntry<float> eitrRateMultiplier, ConfigEntry<float> attackStartNoiseMultiplier, ConfigEntry<float> attackHitNoiseMultiplier, ConfigEntry<float> backstabDamageMultiplier, ConfigEntry<float>? pvpDamageMultiplier, ConfigEntry<float>? pvpStaggerMultiplier, ConfigEntry<float>? pvpKnockbackForceMultiplier, ConfigEntry<float>? projectileSpeedMultiplier, ConfigEntry<float>? aoeRadiusMultiplier, ConfigEntry<float>? spreadMultiplier, ConfigEntry<float>? shieldHealthMultiplier, ConfigEntry<float>? damageTakenFromPlayersMultiplier)
			{
				PrefabName = prefabName;
				DirectAttack = directAttack;
				DamageMultiplier = damageMultiplier;
				StaggerMultiplier = staggerMultiplier;
				AttackAnimationSpeedMultiplier = attackAnimationSpeedMultiplier;
				EitrRateMultiplier = eitrRateMultiplier;
				AttackStartNoiseMultiplier = attackStartNoiseMultiplier;
				AttackHitNoiseMultiplier = attackHitNoiseMultiplier;
				BackstabDamageMultiplier = backstabDamageMultiplier;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				ProjectileSpeedMultiplier = projectileSpeedMultiplier;
				AoeRadiusMultiplier = aoeRadiusMultiplier;
				SpreadMultiplier = spreadMultiplier;
				ShieldHealthMultiplier = shieldHealthMultiplier;
				DamageTakenFromPlayersMultiplier = damageTakenFromPlayersMultiplier;
			}
		}

		internal sealed class Setting<T>
		{
			private readonly ConfigEntry<T>? _entry;

			private T _value;

			public T Value
			{
				get
				{
					return (_entry != null) ? _entry.Value : _value;
				}
				set
				{
					if (_entry != null)
					{
						_entry.Value = value;
					}
					else
					{
						_value = value;
					}
				}
			}

			public T DefaultValue => (_entry != null) ? ((T)((ConfigEntryBase)_entry).DefaultValue) : _value;

			public Setting(ConfigEntry<T> entry)
			{
				_entry = entry;
				_value = entry.Value;
			}

			public Setting(T value)
			{
				_entry = null;
				_value = value;
			}
		}

		internal sealed class RoleSettings<T>
		{
			public Setting<T> Primary1 { get; }

			public Setting<T> Primary2 { get; }

			public Setting<T> Primary3 { get; }

			public Setting<T> Primary4 { get; }

			public Setting<T> Secondary { get; }

			public RoleSettings(Setting<T> primary1, Setting<T> primary2, Setting<T> primary3, Setting<T> secondary, Setting<T>? primary4 = null)
			{
				Primary1 = primary1;
				Primary2 = primary2;
				Primary3 = primary3;
				Primary4 = primary4 ?? primary3;
				Secondary = secondary;
			}

			public Setting<T> Get(AttackRole role)
			{
				if (1 == 0)
				{
				}
				Setting<T> result = role switch
				{
					AttackRole.Primary2 => Primary2, 
					AttackRole.Primary3 => Primary3, 
					AttackRole.Primary4 => Primary4, 
					AttackRole.Secondary => Secondary, 
					_ => Primary1, 
				};
				if (1 == 0)
				{
				}
				return result;
			}

			public void SetPrimary(T value)
			{
				Primary1.Value = value;
				Primary2.Value = value;
				Primary3.Value = value;
				Primary4.Value = value;
			}

			public void SetAll(T primary, T secondary)
			{
				SetPrimary(primary);
				Secondary.Value = secondary;
			}
		}

		internal sealed class RunningAttackConfig
		{
			public ConfigEntry<bool> Enabled { get; }

			public ConfigEntry<float> MinimumVelocity { get; }

			public ConfigEntry<RunningAttackUsed> UsedAttack { get; }

			public ConfigEntry<float> DamageMultiplier { get; }

			public ConfigEntry<float> StaggerMultiplier { get; }

			public ConfigEntry<float> StaminaRateMultiplier { get; }

			public ConfigEntry<float> AnimationSpeedMultiplier { get; }

			public ConfigEntry<float> RecoveryAnimationSpeedMultiplier { get; }

			public ConfigEntry<BlockCancelMode> BlockCancelMode { get; }

			public ConfigEntry<float> BlockCancelAnimationSpeedMultiplier { get; }

			public ConfigEntry<HyperArmorMode> HyperArmorMode { get; }

			public ConfigEntry<float> DamageTakenMultiplier { get; }

			public ConfigEntry<float> StaggerTakenMultiplier { get; }

			public ConfigEntry<float> KnockbackTakenMultiplier { get; }

			public ConfigEntry<float> PvpDamageTakenMultiplier { get; }

			public ConfigEntry<float> PvpStaggerTakenMultiplier { get; }

			public ConfigEntry<float> PvpKnockbackTakenMultiplier { get; }

			public ConfigEntry<bool> CounterDamageEnabled { get; }

			public ConfigEntry<float> CounterDamageMultiplier { get; }

			public ConfigEntry<float> PvpCounterDamageMultiplier { get; }

			public ConfigEntry<float> HitStopDurationMultiplier { get; }

			public ConfigEntry<float> PvpHitStopDurationMultiplier { get; }

			public ConfigEntry<float> ChopDamageMultiplier { get; }

			public ConfigEntry<float> PickaxeDamageMultiplier { get; }

			public ConfigEntry<float> BackstabDamageMultiplier { get; }

			public ConfigEntry<float> MovementSpeedMultiplier { get; }

			public ConfigEntry<AttackMovementApplicationMode> MovementApplicationMode { get; }

			public ConfigEntry<float> RotationFactor { get; }

			public ConfigEntry<bool> LockRotationAfterAttackTrigger { get; }

			public ConfigEntry<float> PvpDamageMultiplier { get; }

			public ConfigEntry<float> PvpStaggerMultiplier { get; }

			public ConfigEntry<float> PvpStaggerDurationSeconds { get; }

			public ConfigEntry<float> PvpKnockbackForceMultiplier { get; }

			public ConfigEntry<float> KnockbackForceMultiplier { get; }

			public ConfigEntry<float> AdrenalineMultiplier { get; }

			public ConfigEntry<float> LungeDistanceMultiplier { get; }

			public ConfigEntry<LungeApplicationMode> LungeApplicationMode { get; }

			public ConfigEntry<float> StartNoiseMultiplier { get; }

			public ConfigEntry<float> HitNoiseMultiplier { get; }

			public ConfigEntry<float> RangeMultiplier { get; }

			public ConfigEntry<float> RayWidthMultiplier { get; }

			public ConfigEntry<float> HitboxHeightMultiplier { get; }

			public ConfigEntry<float> OffsetMultiplier { get; }

			public ConfigEntry<AttackHitboxType> HitboxType { get; }

			public ConfigEntry<float> AngleMultiplier { get; }

			public ConfigEntry<AttackMultiTargetDamagePenaltyMode> MultiTargetDamagePenalty { get; }

			public RunningAttackConfig(ConfigEntry<bool> enabled, ConfigEntry<float> minimumVelocity, ConfigEntry<RunningAttackUsed> usedAttack, ConfigEntry<float> damageMultiplier, ConfigEntry<float> staggerMultiplier, ConfigEntry<float> staminaRateMultiplier, ConfigEntry<float> animationSpeedMultiplier, ConfigEntry<float> recoveryAnimationSpeedMultiplier, ConfigEntry<BlockCancelMode> blockCancelMode, ConfigEntry<float> blockCancelAnimationSpeedMultiplier, ConfigEntry<HyperArmorMode> hyperArmorMode, ConfigEntry<float> damageTakenMultiplier, ConfigEntry<float> staggerTakenMultiplier, ConfigEntry<float> knockbackTakenMultiplier, ConfigEntry<float> pvpDamageTakenMultiplier, ConfigEntry<float> pvpStaggerTakenMultiplier, ConfigEntry<float> pvpKnockbackTakenMultiplier, ConfigEntry<bool> counterDamageEnabled, ConfigEntry<float> counterDamageMultiplier, ConfigEntry<float> pvpCounterDamageMultiplier, ConfigEntry<float> hitStopDurationMultiplier, ConfigEntry<float> pvpHitStopDurationMultiplier, ConfigEntry<float> chopDamageMultiplier, ConfigEntry<float> pickaxeDamageMultiplier, ConfigEntry<float> backstabDamageMultiplier, ConfigEntry<float> movementSpeedMultiplier, ConfigEntry<AttackMovementApplicationMode> movementApplicationMode, ConfigEntry<float> rotationFactor, ConfigEntry<bool> lockRotationAfterAttackTrigger, ConfigEntry<float> pvpDamageMultiplier, ConfigEntry<float> pvpStaggerMultiplier, ConfigEntry<float> pvpStaggerDurationSeconds, ConfigEntry<float> pvpKnockbackForceMultiplier, ConfigEntry<float> knockbackForceMultiplier, ConfigEntry<float> adrenalineMultiplier, ConfigEntry<float> lungeDistanceMultiplier, ConfigEntry<LungeApplicationMode> lungeApplicationMode, ConfigEntry<float> startNoiseMultiplier, ConfigEntry<float> hitNoiseMultiplier, ConfigEntry<float> rangeMultiplier, ConfigEntry<float> rayWidthMultiplier, ConfigEntry<float> hitboxHeightMultiplier, ConfigEntry<float> offsetMultiplier, ConfigEntry<AttackHitboxType> hitboxType, ConfigEntry<float> angleMultiplier, ConfigEntry<AttackMultiTargetDamagePenaltyMode> multiTargetDamagePenalty)
			{
				Enabled = enabled;
				MinimumVelocity = minimumVelocity;
				UsedAttack = usedAttack;
				DamageMultiplier = damageMultiplier;
				StaggerMultiplier = staggerMultiplier;
				StaminaRateMultiplier = staminaRateMultiplier;
				AnimationSpeedMultiplier = animationSpeedMultiplier;
				RecoveryAnimationSpeedMultiplier = recoveryAnimationSpeedMultiplier;
				BlockCancelMode = blockCancelMode;
				BlockCancelAnimationSpeedMultiplier = blockCancelAnimationSpeedMultiplier;
				HyperArmorMode = hyperArmorMode;
				DamageTakenMultiplier = damageTakenMultiplier;
				StaggerTakenMultiplier = staggerTakenMultiplier;
				KnockbackTakenMultiplier = knockbackTakenMultiplier;
				PvpDamageTakenMultiplier = pvpDamageTakenMultiplier;
				PvpStaggerTakenMultiplier = pvpStaggerTakenMultiplier;
				PvpKnockbackTakenMultiplier = pvpKnockbackTakenMultiplier;
				CounterDamageEnabled = counterDamageEnabled;
				CounterDamageMultiplier = counterDamageMultiplier;
				PvpCounterDamageMultiplier = pvpCounterDamageMultiplier;
				HitStopDurationMultiplier = hitStopDurationMultiplier;
				PvpHitStopDurationMultiplier = pvpHitStopDurationMultiplier;
				ChopDamageMultiplier = chopDamageMultiplier;
				PickaxeDamageMultiplier = pickaxeDamageMultiplier;
				BackstabDamageMultiplier = backstabDamageMultiplier;
				MovementSpeedMultiplier = movementSpeedMultiplier;
				MovementApplicationMode = movementApplicationMode;
				RotationFactor = rotationFactor;
				LockRotationAfterAttackTrigger = lockRotationAfterAttackTrigger;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpStaggerDurationSeconds = pvpStaggerDurationSeconds;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				KnockbackForceMultiplier = knockbackForceMultiplier;
				AdrenalineMultiplier = adrenalineMultiplier;
				LungeDistanceMultiplier = lungeDistanceMultiplier;
				LungeApplicationMode = lungeApplicationMode;
				StartNoiseMultiplier = startNoiseMultiplier;
				HitNoiseMultiplier = hitNoiseMultiplier;
				RangeMultiplier = rangeMultiplier;
				RayWidthMultiplier = rayWidthMultiplier;
				HitboxHeightMultiplier = hitboxHeightMultiplier;
				OffsetMultiplier = offsetMultiplier;
				HitboxType = hitboxType;
				AngleMultiplier = angleMultiplier;
				MultiTargetDamagePenalty = multiTargetDamagePenalty;
			}
		}

		internal sealed class JumpAttackUsedSetting
		{
			private readonly WeaponCategory _category;

			private readonly ConfigEntry<JumpAttackUsed>? _fullEntry;

			private readonly ConfigEntry<JumpAttackUsedBasic>? _basicEntry;

			public JumpAttackUsed Value
			{
				get
				{
					if (_fullEntry != null)
					{
						return NormalizeJumpAttackUsed(_category, _fullEntry.Value);
					}
					return (_basicEntry != null) ? ToFullJumpAttackUsed(_basicEntry.Value) : DefaultJumpAttackUsed(_category);
				}
				set
				{
					JumpAttackUsed jumpAttackUsed = NormalizeJumpAttackUsed(_category, value);
					if (_fullEntry != null)
					{
						_fullEntry.Value = jumpAttackUsed;
					}
					else if (_basicEntry != null)
					{
						_basicEntry.Value = ToBasicJumpAttackUsed(jumpAttackUsed);
					}
				}
			}

			public JumpAttackUsedSetting(WeaponCategory category, ConfigEntry<JumpAttackUsed> fullEntry)
			{
				_category = category;
				_fullEntry = fullEntry;
			}

			public JumpAttackUsedSetting(WeaponCategory category, ConfigEntry<JumpAttackUsedBasic> basicEntry)
			{
				_category = category;
				_basicEntry = basicEntry;
			}
		}

		internal sealed class JumpAttackConfig
		{
			public ConfigEntry<bool> Enabled { get; }

			public JumpAttackUsedSetting UsedAttack { get; }

			public ConfigEntry<float> DamageMultiplier { get; }

			public ConfigEntry<float> StaggerMultiplier { get; }

			public ConfigEntry<float> StaminaRateMultiplier { get; }

			public ConfigEntry<float> AnimationSpeedMultiplier { get; }

			public ConfigEntry<float> RecoveryAnimationSpeedMultiplier { get; }

			public ConfigEntry<BlockCancelMode> BlockCancelMode { get; }

			public ConfigEntry<float> BlockCancelAnimationSpeedMultiplier { get; }

			public ConfigEntry<HyperArmorMode> HyperArmorMode { get; }

			public ConfigEntry<float> DamageTakenMultiplier { get; }

			public ConfigEntry<float> StaggerTakenMultiplier { get; }

			public ConfigEntry<float> KnockbackTakenMultiplier { get; }

			public ConfigEntry<float> PvpDamageTakenMultiplier { get; }

			public ConfigEntry<float> PvpStaggerTakenMultiplier { get; }

			public ConfigEntry<float> PvpKnockbackTakenMultiplier { get; }

			public ConfigEntry<bool> CounterDamageEnabled { get; }

			public ConfigEntry<float> CounterDamageMultiplier { get; }

			public ConfigEntry<float> PvpCounterDamageMultiplier { get; }

			public ConfigEntry<float> HitStopDurationMultiplier { get; }

			public ConfigEntry<float> PvpHitStopDurationMultiplier { get; }

			public ConfigEntry<float> ChopDamageMultiplier { get; }

			public ConfigEntry<float> PickaxeDamageMultiplier { get; }

			public ConfigEntry<float> BackstabDamageMultiplier { get; }

			public ConfigEntry<float> MovementSpeedMultiplier { get; }

			public ConfigEntry<AttackMovementApplicationMode> MovementApplicationMode { get; }

			public ConfigEntry<float> RotationFactor { get; }

			public ConfigEntry<bool> LockRotationAfterAttackTrigger { get; }

			public ConfigEntry<float> PvpDamageMultiplier { get; }

			public ConfigEntry<float> PvpStaggerMultiplier { get; }

			public ConfigEntry<float> PvpStaggerDurationSeconds { get; }

			public ConfigEntry<float> PvpKnockbackForceMultiplier { get; }

			public ConfigEntry<float> KnockbackForceMultiplier { get; }

			public ConfigEntry<float> AdrenalineMultiplier { get; }

			public ConfigEntry<float> LungeDistanceMultiplier { get; }

			public ConfigEntry<LungeApplicationMode> LungeApplicationMode { get; }

			public ConfigEntry<float> StartNoiseMultiplier { get; }

			public ConfigEntry<float> HitNoiseMultiplier { get; }

			public ConfigEntry<float> RangeMultiplier { get; }

			public ConfigEntry<float> RayWidthMultiplier { get; }

			public ConfigEntry<float> HitboxHeightMultiplier { get; }

			public ConfigEntry<float> OffsetMultiplier { get; }

			public ConfigEntry<AttackHitboxType> HitboxType { get; }

			public ConfigEntry<float> AngleMultiplier { get; }

			public ConfigEntry<AttackMultiTargetDamagePenaltyMode> MultiTargetDamagePenalty { get; }

			public JumpAttackConfig(ConfigEntry<bool> enabled, JumpAttackUsedSetting usedAttack, ConfigEntry<float> damageMultiplier, ConfigEntry<float> staggerMultiplier, ConfigEntry<float> staminaRateMultiplier, ConfigEntry<float> animationSpeedMultiplier, ConfigEntry<float> recoveryAnimationSpeedMultiplier, ConfigEntry<BlockCancelMode> blockCancelMode, ConfigEntry<float> blockCancelAnimationSpeedMultiplier, ConfigEntry<HyperArmorMode> hyperArmorMode, ConfigEntry<float> damageTakenMultiplier, ConfigEntry<float> staggerTakenMultiplier, ConfigEntry<float> knockbackTakenMultiplier, ConfigEntry<float> pvpDamageTakenMultiplier, ConfigEntry<float> pvpStaggerTakenMultiplier, ConfigEntry<float> pvpKnockbackTakenMultiplier, ConfigEntry<bool> counterDamageEnabled, ConfigEntry<float> counterDamageMultiplier, ConfigEntry<float> pvpCounterDamageMultiplier, ConfigEntry<float> hitStopDurationMultiplier, ConfigEntry<float> pvpHitStopDurationMultiplier, ConfigEntry<float> chopDamageMultiplier, ConfigEntry<float> pickaxeDamageMultiplier, ConfigEntry<float> backstabDamageMultiplier, ConfigEntry<float> movementSpeedMultiplier, ConfigEntry<AttackMovementApplicationMode> movementApplicationMode, ConfigEntry<float> rotationFactor, ConfigEntry<bool> lockRotationAfterAttackTrigger, ConfigEntry<float> pvpDamageMultiplier, ConfigEntry<float> pvpStaggerMultiplier, ConfigEntry<float> pvpStaggerDurationSeconds, ConfigEntry<float> pvpKnockbackForceMultiplier, ConfigEntry<float> knockbackForceMultiplier, ConfigEntry<float> adrenalineMultiplier, ConfigEntry<float> lungeDistanceMultiplier, ConfigEntry<LungeApplicationMode> lungeApplicationMode, ConfigEntry<float> startNoiseMultiplier, ConfigEntry<float> hitNoiseMultiplier, ConfigEntry<float> rangeMultiplier, ConfigEntry<float> rayWidthMultiplier, ConfigEntry<float> hitboxHeightMultiplier, ConfigEntry<float> offsetMultiplier, ConfigEntry<AttackHitboxType> hitboxType, ConfigEntry<float> angleMultiplier, ConfigEntry<AttackMultiTargetDamagePenaltyMode> multiTargetDamagePenalty)
			{
				Enabled = enabled;
				UsedAttack = usedAttack;
				DamageMultiplier = damageMultiplier;
				StaggerMultiplier = staggerMultiplier;
				StaminaRateMultiplier = staminaRateMultiplier;
				AnimationSpeedMultiplier = animationSpeedMultiplier;
				RecoveryAnimationSpeedMultiplier = recoveryAnimationSpeedMultiplier;
				BlockCancelMode = blockCancelMode;
				BlockCancelAnimationSpeedMultiplier = blockCancelAnimationSpeedMultiplier;
				HyperArmorMode = hyperArmorMode;
				DamageTakenMultiplier = damageTakenMultiplier;
				StaggerTakenMultiplier = staggerTakenMultiplier;
				KnockbackTakenMultiplier = knockbackTakenMultiplier;
				PvpDamageTakenMultiplier = pvpDamageTakenMultiplier;
				PvpStaggerTakenMultiplier = pvpStaggerTakenMultiplier;
				PvpKnockbackTakenMultiplier = pvpKnockbackTakenMultiplier;
				CounterDamageEnabled = counterDamageEnabled;
				CounterDamageMultiplier = counterDamageMultiplier;
				PvpCounterDamageMultiplier = pvpCounterDamageMultiplier;
				HitStopDurationMultiplier = hitStopDurationMultiplier;
				PvpHitStopDurationMultiplier = pvpHitStopDurationMultiplier;
				ChopDamageMultiplier = chopDamageMultiplier;
				PickaxeDamageMultiplier = pickaxeDamageMultiplier;
				BackstabDamageMultiplier = backstabDamageMultiplier;
				MovementSpeedMultiplier = movementSpeedMultiplier;
				MovementApplicationMode = movementApplicationMode;
				RotationFactor = rotationFactor;
				LockRotationAfterAttackTrigger = lockRotationAfterAttackTrigger;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpStaggerDurationSeconds = pvpStaggerDurationSeconds;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				KnockbackForceMultiplier = knockbackForceMultiplier;
				AdrenalineMultiplier = adrenalineMultiplier;
				LungeDistanceMultiplier = lungeDistanceMultiplier;
				LungeApplicationMode = lungeApplicationMode;
				StartNoiseMultiplier = startNoiseMultiplier;
				HitNoiseMultiplier = hitNoiseMultiplier;
				RangeMultiplier = rangeMultiplier;
				RayWidthMultiplier = rayWidthMultiplier;
				HitboxHeightMultiplier = hitboxHeightMultiplier;
				OffsetMultiplier = offsetMultiplier;
				HitboxType = hitboxType;
				AngleMultiplier = angleMultiplier;
				MultiTargetDamagePenalty = multiTargetDamagePenalty;
			}
		}

		internal sealed class CategoryConfig
		{
			public Setting<float> BaseDamageMultiplier { get; }

			public RoleSettings<StaggerApplicationMode> StaggerMode { get; }

			public RoleSettings<float> StaggerPowerValue { get; }

			public RoleSettings<float> DamageToStaggeredEnemyMultiplier { get; }

			public RoleSettings<HyperArmorMode> HyperArmorMode { get; }

			public RoleSettings<float> DamageTakenMultiplier { get; }

			public RoleSettings<float> StaggerTakenMultiplier { get; }

			public RoleSettings<float> KnockbackTakenMultiplier { get; }

			public RoleSettings<float> PvpDamageTakenMultiplierDuringHyperArmor { get; }

			public RoleSettings<float> PvpStaggerTakenMultiplierDuringHyperArmor { get; }

			public RoleSettings<float> PvpKnockbackTakenMultiplierDuringHyperArmor { get; }

			public RoleSettings<float> HitStopDurationMultiplier { get; }

			public RoleSettings<float> PvpHitStopDurationMultiplier { get; }

			public RoleSettings<bool> CounterDamageEnabled { get; }

			public RoleSettings<float> CounterDamageMultiplier { get; }

			public RoleSettings<float> PvpCounterDamageMultiplier { get; }

			public RoleSettings<float> DamageRateMultiplier { get; }

			public RoleSettings<float> ChopDamageMultiplier { get; }

			public RoleSettings<float> PickaxeDamageMultiplier { get; }

			public RoleSettings<float> AirborneDamageMultiplier { get; }

			public RoleSettings<float> AirborneStaggerMultiplier { get; }

			public RoleSettings<float> AirborneRotationFactor { get; }

			public RoleSettings<float> StaminaRateMultiplier { get; }

			public RoleSettings<float> EitrRateMultiplier { get; }

			public RoleSettings<float> AttackMovementModifier { get; }

			public RoleSettings<AttackMovementApplicationMode> AttackMovementApplicationMode { get; }

			public RoleSettings<float> LungeDistanceMultiplier { get; }

			public RoleSettings<LungeApplicationMode> LungeApplicationMode { get; }

			public RoleSettings<float> AttackAnimationSpeedMultiplier { get; }

			public RoleSettings<float> RecoveryAnimationSpeedMultiplier { get; }

			public RoleSettings<float> AttackRotationFactor { get; }

			public RoleSettings<bool> LockRotationAfterAttackTrigger { get; }

			public RoleSettings<float> AdrenalineMultiplier { get; }

			public RoleSettings<float> PvpDamageMultiplier { get; }

			public RoleSettings<float> PvpStaggerMultiplier { get; }

			public RoleSettings<float> PvpStaggerDurationSeconds { get; }

			public RoleSettings<float> PvpKnockbackForceMultiplier { get; }

			public RoleSettings<float> KnockbackForceMultiplier { get; }

			public Setting<float> PvpBlockArmorMultiplier { get; }

			public Setting<float> BlockArmorMultiplier { get; }

			public Setting<float> BlockForceMultiplier { get; }

			public Setting<float> BlockStaminaConsumptionRate { get; }

			public Setting<float> BlockingStaminaRegenMultiplier { get; }

			public Setting<float> BlockBreakThresholdMultiplier { get; }

			public RoleSettings<BlockCancelMode> BlockCancelMode { get; }

			public RoleSettings<float> BlockCancelAnimationSpeedMultiplier { get; }

			public WeaponCategory Category { get; }

			public Setting<StaggerApplicationMode> PrimaryStaggerMode => StaggerMode.Primary1;

			public Setting<float> PrimaryStaggerPowerValue => StaggerPowerValue.Primary1;

			public Setting<StaggerApplicationMode> SecondaryStaggerMode => StaggerMode.Secondary;

			public Setting<float> SecondaryStaggerPowerValue => StaggerPowerValue.Secondary;

			public Setting<HyperArmorMode> PrimaryHyperArmorMode => HyperArmorMode.Primary1;

			public Setting<HyperArmorMode> SecondaryHyperArmorMode => HyperArmorMode.Secondary;

			public Setting<float> PrimaryDamageTakenMultiplier => DamageTakenMultiplier.Primary1;

			public Setting<float> SecondaryDamageTakenMultiplier => DamageTakenMultiplier.Secondary;

			public Setting<float> PrimaryStaggerTakenMultiplier => StaggerTakenMultiplier.Primary1;

			public Setting<float> SecondaryStaggerTakenMultiplier => StaggerTakenMultiplier.Secondary;

			public Setting<float> PrimaryKnockbackTakenMultiplier => KnockbackTakenMultiplier.Primary1;

			public Setting<float> SecondaryKnockbackTakenMultiplier => KnockbackTakenMultiplier.Secondary;

			public Setting<float> PrimaryPvpDamageTakenMultiplierDuringHyperArmor => PvpDamageTakenMultiplierDuringHyperArmor.Primary1;

			public Setting<float> SecondaryPvpDamageTakenMultiplierDuringHyperArmor => PvpDamageTakenMultiplierDuringHyperArmor.Secondary;

			public Setting<float> PrimaryPvpStaggerTakenMultiplierDuringHyperArmor => PvpStaggerTakenMultiplierDuringHyperArmor.Primary1;

			public Setting<float> SecondaryPvpStaggerTakenMultiplierDuringHyperArmor => PvpStaggerTakenMultiplierDuringHyperArmor.Secondary;

			public Setting<float> PrimaryPvpKnockbackTakenMultiplierDuringHyperArmor => PvpKnockbackTakenMultiplierDuringHyperArmor.Primary1;

			public Setting<float> SecondaryPvpKnockbackTakenMultiplierDuringHyperArmor => PvpKnockbackTakenMultiplierDuringHyperArmor.Secondary;

			public Setting<bool> PrimaryCounterDamageEnabled => CounterDamageEnabled.Primary1;

			public Setting<float> PrimaryCounterDamageMultiplier => CounterDamageMultiplier.Primary1;

			public Setting<bool> SecondaryCounterDamageEnabled => CounterDamageEnabled.Secondary;

			public Setting<float> SecondaryCounterDamageMultiplier => CounterDamageMultiplier.Secondary;

			public Setting<float> PrimaryPvpCounterDamageMultiplier => PvpCounterDamageMultiplier.Primary1;

			public Setting<float> SecondaryPvpCounterDamageMultiplier => PvpCounterDamageMultiplier.Secondary;

			public Setting<float> PrimaryDamageRateMultiplier => DamageRateMultiplier.Primary1;

			public Setting<float> SecondaryDamageRateMultiplier => DamageRateMultiplier.Secondary;

			public Setting<float> PrimaryChopDamageMultiplier => ChopDamageMultiplier.Primary1;

			public Setting<float> SecondaryChopDamageMultiplier => ChopDamageMultiplier.Secondary;

			public Setting<float> PrimaryPickaxeDamageMultiplier => PickaxeDamageMultiplier.Primary1;

			public Setting<float> SecondaryPickaxeDamageMultiplier => PickaxeDamageMultiplier.Secondary;

			public Setting<float> PrimaryAirborneDamageMultiplier => AirborneDamageMultiplier.Primary1;

			public Setting<float> SecondaryAirborneDamageMultiplier => AirborneDamageMultiplier.Secondary;

			public Setting<float> PrimaryAirborneStaggerMultiplier => AirborneStaggerMultiplier.Primary1;

			public Setting<float> SecondaryAirborneStaggerMultiplier => AirborneStaggerMultiplier.Secondary;

			public Setting<float> PrimaryAirborneRotationFactor => AirborneRotationFactor.Primary1;

			public Setting<float> SecondaryAirborneRotationFactor => AirborneRotationFactor.Secondary;

			public Setting<float> PrimaryStaminaRateMultiplier => StaminaRateMultiplier.Primary1;

			public Setting<float> SecondaryStaminaRateMultiplier => StaminaRateMultiplier.Secondary;

			public Setting<float> PrimaryEitrRateMultiplier => EitrRateMultiplier.Primary1;

			public Setting<float> SecondaryEitrRateMultiplier => EitrRateMultiplier.Secondary;

			public Setting<float> PrimaryAttackMovementModifier => AttackMovementModifier.Primary1;

			public Setting<float> SecondaryAttackMovementModifier => AttackMovementModifier.Secondary;

			public Setting<float> PrimaryLungeDistanceMultiplier => LungeDistanceMultiplier.Primary1;

			public Setting<float> SecondaryLungeDistanceMultiplier => LungeDistanceMultiplier.Secondary;

			public Setting<float> PrimaryAttackAnimationSpeedMultiplier => AttackAnimationSpeedMultiplier.Primary1;

			public Setting<float> SecondaryAttackAnimationSpeedMultiplier => AttackAnimationSpeedMultiplier.Secondary;

			public Setting<float> PrimaryRecoveryAnimationSpeedMultiplier => RecoveryAnimationSpeedMultiplier.Primary1;

			public Setting<float> SecondaryRecoveryAnimationSpeedMultiplier => RecoveryAnimationSpeedMultiplier.Secondary;

			public Setting<float> PrimaryAttackRotationFactor => AttackRotationFactor.Primary1;

			public Setting<float> SecondaryAttackRotationFactor => AttackRotationFactor.Secondary;

			public Setting<bool> PrimaryLockRotationAfterAttackTrigger => LockRotationAfterAttackTrigger.Primary1;

			public Setting<bool> SecondaryLockRotationAfterAttackTrigger => LockRotationAfterAttackTrigger.Secondary;

			public Setting<float> PrimaryAdrenalineMultiplier => AdrenalineMultiplier.Primary1;

			public Setting<float> SecondaryAdrenalineMultiplier => AdrenalineMultiplier.Secondary;

			public Setting<float> PrimaryPvpDamageMultiplier => PvpDamageMultiplier.Primary1;

			public Setting<float> SecondaryPvpDamageMultiplier => PvpDamageMultiplier.Secondary;

			public Setting<float> PrimaryPvpStaggerMultiplier => PvpStaggerMultiplier.Primary1;

			public Setting<float> SecondaryPvpStaggerMultiplier => PvpStaggerMultiplier.Secondary;

			public Setting<float> PrimaryPvpStaggerDurationSeconds => PvpStaggerDurationSeconds.Primary1;

			public Setting<float> SecondaryPvpStaggerDurationSeconds => PvpStaggerDurationSeconds.Secondary;

			public Setting<float> PrimaryPvpKnockbackForceMultiplier => PvpKnockbackForceMultiplier.Primary1;

			public Setting<float> SecondaryPvpKnockbackForceMultiplier => PvpKnockbackForceMultiplier.Secondary;

			public Setting<float> PrimaryKnockbackForceMultiplier => KnockbackForceMultiplier.Primary1;

			public Setting<float> SecondaryKnockbackForceMultiplier => KnockbackForceMultiplier.Secondary;

			public Setting<BlockCancelMode> PrimaryBlockCancelMode => BlockCancelMode.Primary1;

			public Setting<BlockCancelMode> SecondaryBlockCancelMode => BlockCancelMode.Secondary;

			public CategoryConfig(WeaponCategory category, Setting<float> baseDamageMultiplier, RoleSettings<StaggerApplicationMode> staggerMode, RoleSettings<float> staggerPowerValue, RoleSettings<float> damageToStaggeredEnemyMultiplier, RoleSettings<HyperArmorMode> hyperArmorMode, RoleSettings<float> damageTakenMultiplier, RoleSettings<float> staggerTakenMultiplier, RoleSettings<float> knockbackTakenMultiplier, RoleSettings<float> pvpDamageTakenMultiplierDuringHyperArmor, RoleSettings<float> pvpStaggerTakenMultiplierDuringHyperArmor, RoleSettings<float> pvpKnockbackTakenMultiplierDuringHyperArmor, RoleSettings<float> hitStopDurationMultiplier, RoleSettings<float> pvpHitStopDurationMultiplier, RoleSettings<bool> counterDamageEnabled, RoleSettings<float> counterDamageMultiplier, RoleSettings<float> pvpCounterDamageMultiplier, RoleSettings<float> damageRateMultiplier, RoleSettings<float> chopDamageMultiplier, RoleSettings<float> pickaxeDamageMultiplier, RoleSettings<float> airborneDamageMultiplier, RoleSettings<float> airborneStaggerMultiplier, RoleSettings<float> airborneRotationFactor, RoleSettings<float> staminaRateMultiplier, RoleSettings<float> eitrRateMultiplier, RoleSettings<float> attackMovementSpeedMultiplier, RoleSettings<AttackMovementApplicationMode> attackMovementApplicationMode, RoleSettings<float> lungeDistanceMultiplier, RoleSettings<LungeApplicationMode> lungeApplicationMode, RoleSettings<float> attackAnimationSpeedMultiplier, RoleSettings<float> recoveryAnimationSpeedMultiplier, RoleSettings<float> attackRotationFactor, RoleSettings<bool> lockRotationAfterAttackTrigger, RoleSettings<float> adrenalineMultiplier, RoleSettings<float> pvpDamageMultiplier, RoleSettings<float> pvpStaggerMultiplier, RoleSettings<float> pvpStaggerDurationSeconds, RoleSettings<float> pvpKnockbackForceMultiplier, RoleSettings<float> knockbackForceMultiplier, Setting<float> pvpBlockArmorMultiplier, Setting<float> blockPowerMultiplier, Setting<float> deflectionForceMultiplier, Setting<float> blockStaminaConsumptionRate, Setting<float> blockingStaminaRegenMultiplier, Setting<float> blockBreakThresholdMultiplier, RoleSettings<BlockCancelMode> blockCancelMode, RoleSettings<float> blockCancelAnimationSpeedMultiplier)
			{
				Category = category;
				BaseDamageMultiplier = baseDamageMultiplier;
				StaggerMode = staggerMode;
				StaggerPowerValue = staggerPowerValue;
				DamageToStaggeredEnemyMultiplier = damageToStaggeredEnemyMultiplier;
				HyperArmorMode = hyperArmorMode;
				DamageTakenMultiplier = damageTakenMultiplier;
				StaggerTakenMultiplier = staggerTakenMultiplier;
				KnockbackTakenMultiplier = knockbackTakenMultiplier;
				PvpDamageTakenMultiplierDuringHyperArmor = pvpDamageTakenMultiplierDuringHyperArmor;
				PvpStaggerTakenMultiplierDuringHyperArmor = pvpStaggerTakenMultiplierDuringHyperArmor;
				PvpKnockbackTakenMultiplierDuringHyperArmor = pvpKnockbackTakenMultiplierDuringHyperArmor;
				HitStopDurationMultiplier = hitStopDurationMultiplier;
				PvpHitStopDurationMultiplier = pvpHitStopDurationMultiplier;
				CounterDamageEnabled = counterDamageEnabled;
				CounterDamageMultiplier = counterDamageMultiplier;
				PvpCounterDamageMultiplier = pvpCounterDamageMultiplier;
				DamageRateMultiplier = damageRateMultiplier;
				ChopDamageMultiplier = chopDamageMultiplier;
				PickaxeDamageMultiplier = pickaxeDamageMultiplier;
				AirborneDamageMultiplier = airborneDamageMultiplier;
				AirborneStaggerMultiplier = airborneStaggerMultiplier;
				AirborneRotationFactor = airborneRotationFactor;
				StaminaRateMultiplier = staminaRateMultiplier;
				EitrRateMultiplier = eitrRateMultiplier;
				AttackMovementModifier = attackMovementSpeedMultiplier;
				AttackMovementApplicationMode = attackMovementApplicationMode;
				LungeDistanceMultiplier = lungeDistanceMultiplier;
				LungeApplicationMode = lungeApplicationMode;
				AttackAnimationSpeedMultiplier = attackAnimationSpeedMultiplier;
				RecoveryAnimationSpeedMultiplier = recoveryAnimationSpeedMultiplier;
				AttackRotationFactor = attackRotationFactor;
				LockRotationAfterAttackTrigger = lockRotationAfterAttackTrigger;
				AdrenalineMultiplier = adrenalineMultiplier;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpStaggerDurationSeconds = pvpStaggerDurationSeconds;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				KnockbackForceMultiplier = knockbackForceMultiplier;
				PvpBlockArmorMultiplier = pvpBlockArmorMultiplier;
				BlockArmorMultiplier = blockPowerMultiplier;
				BlockForceMultiplier = deflectionForceMultiplier;
				BlockStaminaConsumptionRate = blockStaminaConsumptionRate;
				BlockingStaminaRegenMultiplier = blockingStaminaRegenMultiplier;
				BlockBreakThresholdMultiplier = blockBreakThresholdMultiplier;
				BlockCancelMode = blockCancelMode;
				BlockCancelAnimationSpeedMultiplier = blockCancelAnimationSpeedMultiplier;
			}

			public float GetBaseDamageMultiplier()
			{
				return IsFeatureApplied(Category, ModFeature.Damage) ? BaseDamageMultiplier.Value : 1f;
			}

			public float GetBlockStaminaConsumptionRate()
			{
				return IsFeatureApplied(Category, ModFeature.Blocking) ? BlockStaminaConsumptionRate.Value : 1f;
			}

			public float GetBlockingStaminaRegenMultiplier()
			{
				return IsFeatureApplied(Category, ModFeature.Blocking) ? BlockingStaminaRegenMultiplier.Value : 1f;
			}

			public float GetBlockBreakThresholdMultiplier()
			{
				return IsFeatureApplied(Category, ModFeature.Blocking) ? BlockBreakThresholdMultiplier.Value : 1f;
			}

			public StaggerApplicationMode GetStaggerMode(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Staggering) ? StaggerMode.Get(role).Value : StaggerApplicationMode.MultiplyVanilla;
			}

			public float GetStaggerPowerValue(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Staggering) ? StaggerPowerValue.Get(role).Value : 1f;
			}

			public float GetDamageToStaggeredEnemyMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Staggering) ? DamageToStaggeredEnemyMultiplier.Get(role).Value : 1f;
			}

			public HyperArmorMode GetHyperArmorMode(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HyperArmor) ? HyperArmorMode.Get(role).Value : GooCombatOverhaul.HyperArmorMode.Off;
			}

			public float GetDamageTakenMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HyperArmor) ? DamageTakenMultiplier.Get(role).Value : 1f;
			}

			public float GetStaggerTakenMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HyperArmor) ? StaggerTakenMultiplier.Get(role).Value : 1f;
			}

			public float GetKnockbackTakenMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HyperArmor) ? KnockbackTakenMultiplier.Get(role).Value : 1f;
			}

			public float GetPvpDamageTakenMultiplierDuringHyperArmor(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HyperArmor) ? PvpDamageTakenMultiplierDuringHyperArmor.Get(role).Value : 1f;
			}

			public float GetPvpStaggerTakenMultiplierDuringHyperArmor(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HyperArmor) ? PvpStaggerTakenMultiplierDuringHyperArmor.Get(role).Value : 1f;
			}

			public float GetPvpKnockbackTakenMultiplierDuringHyperArmor(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HyperArmor) ? PvpKnockbackTakenMultiplierDuringHyperArmor.Get(role).Value : 1f;
			}

			public bool GetHitStopOnHit(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HitStop) && GetHitStopDurationMultiplier(role) > 0f;
			}

			public float GetHitStopDurationMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HitStop) ? HitStopDurationMultiplier.Get(role).Value : 1f;
			}

			public float GetPvpHitStopDurationMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.HitStop) ? PvpHitStopDurationMultiplier.Get(role).Value : 1f;
			}

			public bool GetCounterDamageEnabled(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.CounterDamage) && CounterDamageEnabled.Get(role).Value;
			}

			public float GetCounterDamageMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.CounterDamage) ? CounterDamageMultiplier.Get(role).Value : 1f;
			}

			public float GetPvpCounterDamageMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.CounterDamage) ? PvpCounterDamageMultiplier.Get(role).Value : 1f;
			}

			public float GetDamageRateMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Damage) ? DamageRateMultiplier.Get(role).Value : 1f;
			}

			public float GetChopDamageMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Damage) ? ChopDamageMultiplier.Get(role).Value : DefaultChopDamageMultiplier(Category);
			}

			public float GetPickaxeDamageMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Damage) ? PickaxeDamageMultiplier.Get(role).Value : VanillaPickaxeDamageMultiplier(Category);
			}

			public float GetAirborneDamageMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Damage) ? AirborneDamageMultiplier.Get(role).Value : 1f;
			}

			public float GetAirborneStaggerMultiplier(AttackRole role)
			{
				return IsWeaponCategoryApplied(Category) ? AirborneStaggerMultiplier.Get(role).Value : 1f;
			}

			public float GetAirborneRotationFactor(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.AttackRotation) ? AirborneRotationFactor.Get(role).Value : 1f;
			}

			public float GetStaminaRateMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Resources) ? StaminaRateMultiplier.Get(role).Value : 1f;
			}

			public float GetEitrRateMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Resources) ? EitrRateMultiplier.Get(role).Value : 1f;
			}

			public float GetAttackMovementModifier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.AttackMovement) ? AttackMovementModifier.Get(role).Value : 1f;
			}

			public AttackMovementApplicationMode GetAttackMovementApplicationMode(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.AttackMovement) ? AttackMovementApplicationMode.Get(role).Value : GooCombatOverhaul.AttackMovementApplicationMode.FullAnimation;
			}

			public float GetLungeDistanceMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.AttackMovement) ? LungeDistanceMultiplier.Get(role).Value : 1f;
			}

			public LungeApplicationMode GetLungeApplicationMode(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.AttackMovement) ? LungeApplicationMode.Get(role).Value : GooCombatOverhaul.LungeApplicationMode.BeforeHitbox;
			}

			public float GetAttackAnimationSpeedMultiplier(AttackRole role)
			{
				return IsAnimationFeatureApplied(Category) ? AttackAnimationSpeedMultiplier.Get(role).Value : 1f;
			}

			public float GetRecoveryAnimationSpeedMultiplier(AttackRole role)
			{
				return IsAnimationFeatureApplied(Category) ? RecoveryAnimationSpeedMultiplier.Get(role).Value : 1f;
			}

			public float GetAttackRotationFactor(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.AttackRotation) ? Mathf.Max(0f, (AttackRotationFactor.Get(role).Value < 0f) ? 1f : AttackRotationFactor.Get(role).Value) : 1f;
			}

			public bool GetLockRotationAfterAttackTrigger(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.AttackRotation) && LockRotationAfterAttackTrigger.Get(role).Value;
			}

			public float GetAdrenalineMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Resources) ? AdrenalineMultiplier.Get(role).Value : 1f;
			}

			public float GetPvpDamageMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpDamageMultiplier.Get(role).Value : 1f;
			}

			public float GetPvpStaggerMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpStaggerMultiplier.Get(role).Value : 1f;
			}

			public float GetPvpStaggerDurationSeconds(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpStaggerDurationSeconds.Get(role).Value : DefaultPvpStaggerDuration(Category, role);
			}

			public float GetPvpKnockbackForceMultiplier(AttackRole role)
			{
				return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpKnockbackForceMultiplier.Get(role).Value : 1f;
			}

			public float GetKnockbackForceMultiplier(AttackRole role)
			{
				return IsWeaponCategoryApplied(Category) ? KnockbackForceMultiplier.Get(role).Value : 1f;
			}

			public BlockCancelMode GetBlockCancelMode(AttackRole role)
			{
				return IsWeaponCategoryApplied(Category) ? BlockCancelMode.Get(role).Value : GooCombatOverhaul.BlockCancelMode.Disabled;
			}

			public float GetBlockCancelAnimationSpeedMultiplier(AttackRole role)
			{
				return IsWeaponCategoryApplied(Category) ? BlockCancelAnimationSpeedMultiplier.Get(role).Value : 1f;
			}
		}

		private sealed class ParryStaggerSuppressionState
		{
			private Character? _attacker;

			private bool _originalStaggerWhenBlocked;

			public void Suppress(Character attacker)
			{
				if (!((Object)(object)attacker == (Object)null) && !((Object)(object)_attacker != (Object)null))
				{
					_attacker = attacker;
					_originalStaggerWhenBlocked = attacker.m_staggerWhenBlocked;
				}
			}

			public void Restore()
			{
				if (!((Object)(object)_attacker == (Object)null))
				{
					_attacker.m_staggerWhenBlocked = _originalStaggerWhenBlocked;
					_attacker = null;
				}
			}
		}

		private readonly struct SuppressedFieldValue
		{
			public object Target { get; }

			public FieldInfo Field { get; }

			public object? OriginalValue { get; }

			public SuppressedFieldValue(object target, FieldInfo field, object? originalValue)
			{
				Target = target;
				Field = field;
				OriginalValue = originalValue;
			}
		}

		private readonly struct CounterVulnerableState
		{
			public object? AttackInstance { get; }

			public CounterVulnerableState(object? attackInstance)
			{
				AttackInstance = attackInstance;
			}
		}

		private readonly struct AttackRuntimeState
		{
			public WeaponCategory Category { get; }

			public AttackRole Role { get; }

			public object? AttackInstance { get; }

			public bool StartedAirborne { get; }

			public AttackRuntimeState(WeaponCategory category, AttackRole role, object? attackInstance, bool startedAirborne = false)
			{
				Category = category;
				Role = role;
				AttackInstance = attackInstance;
				StartedAirborne = startedAirborne;
			}
		}

		private readonly struct MeleeHitStopRuntimeState
		{
			public WeaponCategory Category { get; }

			public AttackRole Role { get; }

			public float EndTime { get; }

			public object? AttackInstance { get; }

			public bool IsPvpHitStop { get; }

			public MeleeHitStopRuntimeState(WeaponCategory category, AttackRole role, float endTime, object? attackInstance, bool isPvpHitStop = false)
			{
				Category = category;
				Role = role;
				EndTime = endTime;
				AttackInstance = attackInstance;
				IsPvpHitStop = isPvpHitStop;
			}
		}

		private readonly struct PendingAttackRoleState
		{
			public AttackRole Role { get; }

			public float EndTime { get; }

			public PendingAttackRoleState(AttackRole role, float endTime)
			{
				Role = role;
				EndTime = endTime;
			}
		}

		private readonly struct HyperArmorRuntimeState
		{
			public WeaponCategory Category { get; }

			public AttackRole Role { get; }

			public HyperArmorMode Mode { get; }

			public object? AttackInstance { get; }

			public HyperArmorRuntimeState(WeaponCategory category, AttackRole role, HyperArmorMode mode, object? attackInstance)
			{
				Category = category;
				Role = role;
				Mode = mode;
				AttackInstance = attackInstance;
			}
		}

		private sealed class OwnedFloatRuntimeValue
		{
			private float _original;

			private float _lastApplied;

			private bool _owns;

			public float Original => _original;

			public OwnedFloatRuntimeValue(float original)
			{
				_original = original;
				_lastApplied = original;
			}

			public float GetBase(float current)
			{
				ObserveExternal(current);
				return _original;
			}

			public void Apply(ref float field, float target)
			{
				ObserveExternal(field);
				if (Mathf.Approximately(target, _original))
				{
					Restore(ref field);
					return;
				}
				if (!Mathf.Approximately(field, target))
				{
					field = target;
				}
				_lastApplied = target;
				_owns = true;
			}

			public void Restore(ref float field)
			{
				if (!_owns)
				{
					_original = field;
					return;
				}
				if (Mathf.Approximately(field, _lastApplied))
				{
					field = _original;
				}
				else
				{
					_original = field;
				}
				_owns = false;
			}

			private void ObserveExternal(float current)
			{
				if (_owns)
				{
					if (!Mathf.Approximately(current, _lastApplied))
					{
						_original = current;
						_owns = false;
					}
				}
				else
				{
					_original = current;
				}
			}
		}

		private sealed class OwnedVector3RuntimeValue
		{
			private Vector3 _original;

			private Vector3 _lastApplied;

			private bool _owns;

			public OwnedVector3RuntimeValue(Vector3 original)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				_original = original;
				_lastApplied = original;
			}

			public Vector3 GetBase(Vector3 current)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//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_0012: Unknown result type (might be due to invalid IL or missing references)
				ObserveExternal(current);
				return _original;
			}

			public void Apply(Transform transform, Vector3 target)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: 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_0024: 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_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)transform == (Object)null)
				{
					return;
				}
				Vector3 localScale = transform.localScale;
				ObserveExternal(localScale);
				Vector3 val = target - _original;
				if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f)
				{
					Restore(transform);
					return;
				}
				val = localScale - target;
				if (((Vector3)(ref val)).sqrMagnitude > 1E-06f)
				{
					transform.localScale = target;
				}
				_lastApplied = target;
				_owns = true;
			}

			public void Restore(Transform transform)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)transform == (Object)null)
				{
					return;
				}
				Vector3 localScale = transform.localScale;
				if (!_owns)
				{
					_original = localScale;
					return;
				}
				Vector3 val = localScale - _lastApplied;
				if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f)
				{
					transform.localScale = _original;
				}
				else
				{
					_original = localScale;
				}
				_owns = false;
			}

			private void ObserveExternal(Vector3 current)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				if (_owns)
				{
					Vector3 val = current - _lastApplied;
					if (((Vector3)(ref val)).sqrMagnitude > 1E-06f)
					{
						_original = current;
						_owns = false;
					}
				}
				else
				{
					_original = current;
				}
			}
		}

		private sealed class CharacterRuntimeDefaults
		{
			private readonly OwnedVector3RuntimeValue _localScale;

			private readonly OwnedFloatRuntimeValue _jogSpeed;

			private readonly OwnedFloatRuntimeValue _walkSpeed;

			private readonly OwnedFloatRuntimeValue _runSpeed;

			public CharacterRuntimeDefaults(Character character)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				_localScale = new OwnedVector3RuntimeValue(((Component)character).transform.localScale);
				_jogSpeed = new OwnedFloatRuntimeValue(character.m_speed);
				_walkSpeed = new OwnedFloatRuntimeValue(character.m_walkSpeed);
				_runSpeed = new OwnedFloatRuntimeValue(character.m_runSpeed);
			}

			public void ApplyScale(Character character, float multiplier)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = _localScale.GetBase(((Component)character).transform.localScale);
				_localScale.Apply(((Component)character).transform, val * Mathf.Clamp(multiplier, 0.2f, 5f));
			}

			public void ApplyMovementSpeeds(Character character, float multiplier)
			{
				multiplier = Mathf.Clamp(multiplier, 0.05f, 10f);
				float num = _jogSpeed.GetBase(character.m_speed);
				float num2 = _walkSpeed.GetBase(character.m_walkSpeed);
				float num3 = _runSpeed.GetBase(character.m_runSpeed);
				_jogSpeed.Apply(ref character.m_speed, num * multiplier);
				_walkSpeed.Apply(ref character.m_walkSpeed, num2 * multiplier);
				_runSpeed.Apply(ref character.m_runSpeed, num3 * multiplier);
			}

			public void Restore(Character character)
			{
				_localScale.Restore(((Component)character).transform);
				_jogSpeed.Restore(ref character.m_speed);
				_walkSpeed.Restore(ref character.m_walkSpeed);
				_runSpeed.Restore(ref character.m_runSpeed);
			}
		}

		private sealed class PlayerRuntimeDefaults
		{
			private readonly OwnedFloatRuntimeValue _baseHealth;

			private readonly OwnedFloatRuntimeValue _baseStamina;

			private readonly OwnedFloatRuntimeValue _carryWeight;

			private readonly OwnedFloatRuntimeValue _eitrRegen;

			private readonly OwnedFloatRuntimeValue _jumpForce;

			private readonly OwnedFloatRuntimeValue _jumpStaminaUsage;

			private readonly OwnedFloatRuntimeValue _runStaminaDrain;

			private readonly OwnedFloatRuntimeValue _dodgeStaminaUsage;

			private readonly OwnedFloatRuntimeValue _sneakStaminaDrain;

			private readonly OwnedFloatRuntimeValue _runSpeed;

			private readonly OwnedFloatRuntimeValue _jogSpeed;

			private readonly OwnedFloatRuntimeValue _walkSpeed;

			private readonly OwnedFloatRuntimeValue _crouchSpeed;

			private readonly OwnedFloatRuntimeValue _staminaRegen;

			private readonly OwnedFloatRuntimeValue _staminaRegenTimeMultiplier;

			public float BaseHealth => _baseHealth.Original;

			public float BaseStamina => _baseStamina.Original;

			public float CarryWeight => _carryWeight.Original;

			public float EitrRegen => _eitrRegen.Original;

			public float JumpForce => _jumpForce.Original;

			public float JumpStaminaUsage => _jumpStaminaUsage.Original;

			public float RunStaminaDrain => _runStaminaDrain.Original;

			public float DodgeStaminaUsage => _dodgeStaminaUsage.Original;

			public float SneakStaminaDrain => _sneakStaminaDrain.Original;

			public float RunSpeed => _runSpeed.Original;

			public float JogSpeed => _jogSpeed.Original;

			public float WalkSpeed => _walkSpeed.Original;

			public float CrouchSpeed => _crouchSpeed.Original;

			public float StaminaRegen => _staminaRegen.Original;

			public PlayerRuntimeDefaults(Player player)
			{
				_baseHealth = new OwnedFloatRuntimeValue(player.m_baseHP);
				_baseStamina = new OwnedFloatRuntimeValue(player.m_baseStamina);
				_carryWeight = new OwnedFloatRuntimeValue(player.m_maxCarryWeight);
				_eitrRegen = new OwnedFloatRuntimeValue(player.m_eiterRegen);
				_jumpForce = new OwnedFloatRuntimeValue(((Character)player).m_jumpForce);
				_jumpStaminaUsage = new OwnedFloatRuntimeValue(((Character)player).m_jumpStaminaUsage);
				_runStaminaDrain = new OwnedFloatRuntimeValue(player.m_runStaminaDrain);
				_dodgeStaminaUsage = new OwnedFloatRuntimeValue(player.m_dodgeStaminaUsage);
				_sneakStaminaDrain = new OwnedFloatRuntimeValue(player.m_sneakStaminaDrain);
				_runSpeed = new OwnedFloatRuntimeValue(((Character)player).m_runSpeed);
				_jogSpeed = new OwnedFloatRuntimeValue(((Character)player).m_speed);
				_walkSpeed = new OwnedFloatRuntimeValue(((Character)player).m_walkSpeed);
				_crouchSpeed = new OwnedFloatRuntimeValue(((Character)player).m_crouchSpeed);
				_staminaRegen = new OwnedFloatRuntimeValue(player.m_staminaRegen);
				_staminaRegenTimeMultiplier = new OwnedFloatRuntimeValue(player.m_staminaRegenTimeMultiplier);
			}

			public void ApplyStatic(Player player)
			{
				_baseHealth.Apply(ref player.m_baseHP, Mathf.Max(1f, PlayerBaseHealth.Value));
				_baseStamina.Apply(ref player.m_baseStamina, Mathf.Max(1f, PlayerBaseStamina.Value));
				_carryWeight.Apply(ref player.m_maxCarryWeight, Mathf.Max(0f, PlayerBaseCarryWeight.Value));
				float num = _eitrRegen.GetBase(player.m_eiterRegen);
				_eitrRegen.Apply(ref player.m_eiterRegen, num * Mathf.Clamp(PlayerBaseEitrRegenRate.Value, 0f, 10f));
				float num2 = _jumpForce.GetBase(((Character)player).m_jumpForce);
				float num3 = _jumpStaminaUsage.GetBase(((Character)player).m_jumpStaminaUsage);
				float num4 = _runStaminaDrain.GetBase(player.m_runStaminaDrain);
				float num5 = _dodgeStaminaUsage.GetBase(player.m_dodgeStaminaUsage);
				float num6 = _sneakStaminaDrain.GetBase(player.m_sneakStaminaDrain);
				float num7 = _runSpeed.GetBase(((Character)player).m_runSpeed);
				float num8 = _jogSpeed.GetBase(((Character)player).m_speed);
				float num9 = _walkSpeed.GetBase(((Character)player).m_walkSpeed);
				float num10 = _crouchSpeed.GetBase(((Character)player).m_crouchSpeed);
				_jumpForce.Apply(ref ((Character)player).m_jumpForce, num2 * Mathf.Clamp(PlayerJumpForceMultiplier.Value, 0.05f, 10f));
				_jumpStaminaUsage.Apply(ref ((Character)player).m_jumpStaminaUsage, num3 * Mathf.Clamp(JumpStaminaConsumptionRate.Value, 0f, 10f));
				_runStaminaDrain.Apply(ref player.m_runStaminaDrain, num4 * Mathf.Clamp(RunStaminaConsumptionRate.Value, 0f, 10f));
				_dodgeStaminaUsage.Apply(ref player.m_dodgeStaminaUsage, num5 * Mathf.Clamp(RollStaminaConsumptionRate.Value, 0f, 10f));
				_sneakStaminaDrain.Apply(ref player.m_sneakStaminaDrain, num6 * Mathf.Clamp(CrouchStaminaConsumptionRate.Value, 0f, 10f));
				_runSpeed.Apply(ref ((Character)player).m_runSpeed, num7 * Mathf.Clamp(PlayerRunSpeedMultiplier.Value, 0.05f, 10f));
				_jogSpeed.Apply(ref ((Character)player).m_speed, num8 * Mathf.Clamp(PlayerJogSpeedMultiplier.Value, 0.05f, 10f));
				_walkSpeed.Apply(ref ((Character)player).m_walkSpeed, num9 * Mathf.Clamp(PlayerWalkSpeedMultiplier.Value, 0.05f, 10f));
				_crouchSpeed.Apply(ref ((Character)player).m_crouchSpeed, num10 * Mathf.Clamp(PlayerCrouchSpeedMultiplier.Value, 0.05f, 10f));
			}

			public float GetStaminaRegenBase(Player player)
			{
				return _staminaRegen.GetBase(player.m_staminaRegen);
			}

			public float GetStaminaRegenTimeMultiplierBase(Player player)
			{
				return _staminaRegenTimeMultiplier.GetBase(player.m_staminaRegenTimeMultiplier);
			}

			public void ApplyStaminaRegen(Player player, float regen, float timeMultiplier)
			{
				_staminaRegen.Apply(ref player.m_staminaRegen, regen);
				_staminaRegenTimeMultiplier.Apply(ref player.m_staminaRegenTimeMultiplier, timeMultiplier);
			}

			public void RestoreStaminaRegen(Player player)
			{
				_staminaRegen.Restore(ref player.m_staminaRegen);
				_staminaRegenTimeMultiplier.Restore(ref player.m_staminaRegenTimeMultiplier);
			}

			public void Restore(Player player)
			{
				_baseHealth.Restore(ref player.m_baseHP);
				_baseStamina.Restore(ref player.m_baseStamina);
				_carryWeight.Restore(ref player.m_maxCarryWeight);
				_eitrRegen.Restore(ref player.m_eiterRegen);
				_jumpForce.Restore(ref ((Character)player).m_jumpForce);
				_jumpStaminaUsage.Restore(ref ((Character)player).m_jumpStaminaUsage);
				_runStaminaDrain.Restore(ref player.m_runStaminaDrain);
				_dodgeStaminaUsage.Restore(ref player.m_dodgeStaminaUsage);
				_sneakStaminaDrain.Restore(ref player.m_sneakStaminaDrain);
				_runSpeed.Restore(ref ((Character)player).m_runSpeed);
				_jogSpeed.Restore(ref ((Character)player).m_speed);
				_walkSpeed.Restore(ref ((Character)player).m_walkSpeed);
				_crouchSpeed.Restore(ref ((Character)player).m_crouchSpeed);
				RestoreStaminaRegen(player);
			}
		}

		private sealed class MeadStatusEffectClassification
		{
			public bool IsMead { get; }

			public MeadStatusEffectClassification(bool isMead)
			{
				IsMead = isMead;
			}
		}

		private sealed class AttackRuntimeContextHolder
		{
			public AttackRuntimeState State { get; }

			public AttackRuntimeContextHolder(AttackRuntimeState state)
			{
				State = state;
			}
		}

		private sealed class IncomingParryStaggerSourceHolder
		{
			public IncomingParryStaggerSource Source { get; }

			public IncomingParryStaggerSourceHolder(IncomingParryStaggerSource source)
			{
				Source = source;
			}
		}

		public sealed class BlockingMovementSpeedPatchState
		{
			private readonly Player _player;

			private readonly float _speed;

			private readonly float _walkSpeed;

			private readonly float _runSpeed;

			private readonly float _crouchSpeed;

			private readonly float _acceleration;

			private bool _restored;

			public bool PreservePhysicalAirborneMomentumBaseline { get; }

			public BlockingMovementSpeedPatchState(Player player, float speed, float walkSpeed, float runSpeed, float crouchSpeed, float acceleration, bool preservePhysicalAirborneMomentumBaseline)
			{
				_player = player;
				_speed = speed;
				_walkSpeed = walkSpeed;
				_runSpeed = runSpeed;
				_crouchSpeed = crouchSpeed;
				_acceleration = acceleration;
				PreservePhysicalAirborneMomentumBaseline = preservePhysicalAirborneMomentumBaseline;
			}

			public void Restore()
			{
				if (!_restored && !((Object)(object)_player == (Object)null))
				{
					_restored = true;
					((Character)_player).m_speed = _speed;
					((Character)_player).m_walkSpeed = _walkSpeed;
					((Character)_player).m_runSpeed = _runSpeed;
					((Character)_player).m_crouchSpeed = _crouchSpeed;
					((Character)_player).m_acceleration = _acceleration;
				}
			}
		}

		private sealed class AttackAnimatorSpeedState
		{
			private readonly Animator _animator;

			private float _nativeSpeed;

			private float _multiplier;

			private bool _pendingPostFreezeReapply;

			private float _lastAppliedSpeed;

			public AttackAnimatorSpeedState(Animator animator, float nativeSpeed, float multiplier)
			{
				_animator = animator;
				_nativeSpeed = Mathf.Clamp(nativeSpeed, 0.0001f, 20f);
				_multiplier = Mathf.Clamp(multiplier, 0.05f, 20f);
				_lastAppliedSpeed = _nativeSpeed;
				ApplyCurrentMultiplier();
			}

			public bool IsFor(Animator animator)
			{
				return _animator == animator;
			}

			public float ApplyNativeSpeed(float nativeSpeed, float multiplier)
			{
				_nativeSpeed = Mathf.Clamp(nativeSpeed, 0.0001f, 20f);
				_multiplier = Mathf.Clamp(multiplier, 0.05f, 20f);
				_pendingPostFreezeReapply = false;
				_lastAppliedSpeed = Mathf.Clamp(_nativeSpeed * _multiplier, 0.0001f, 20f);
				return _lastAppliedSpeed;
			}

			public void SetMultiplier(float multiplier)
			{
				_multiplier = Mathf.Clamp(multiplier, 0.05f, 20f);
				if (!((Object)(object)_animator == (Object)null))
				{
					if (_animator.speed <= 0.001f)
					{
						_pendingPostFreezeReapply = true;
					}
					else
					{
						ApplyCurrentMultiplier();
					}
				}
			}

			public void EnsureApplied()
			{
				if (!((Object)(object)_animator == (Object)null) && !(_animator.speed <= 0.001f))
				{
					if (_pendingPostFreezeReapply)
					{
						_pendingPostFreezeReapply = false;
					}
					if (!Mathf.Approximately(_animator.speed, _lastAppliedSpeed))
					{
						_animator.speed = _lastAppliedSpeed;
					}
				}
			}

			public void Restore()
			{
				if (!((Object)(object)_animator == (Object)null) && !(_animator.speed <= 0.001f) && Mathf.Approximately(_animator.speed, _lastAppliedSpeed))
				{
					_animator.speed = _nativeSpeed;
				}
			}

			private void ApplyCurrentMultiplier()
			{
				if (!((Object)(object)_animator == (Object)null))
				{
					_lastAppliedSpeed = Mathf.Clamp(_nativeSpeed * _multiplier, 0.0001f, 20f);
					_animator.speed = _lastAppliedSpeed;
				}
			}
		}

		private readonly struct AnimatorSpeedValue
		{
			private readonly Animator _animator;

			private readonly float _originalSpeed;

			private readonly float _multiplier;

			public AnimatorSpeedValue(Animator animator, float originalSpeed, float multiplier)
			{
				_animator = animator;
				_originalSpeed = originalSpeed;
				_multiplier = multiplier;
			}

			public bool IsFor(Animator animator)
			{
				return _animator == animator;
			}

			public void Restore()
			{
				if ((Object)(object)_animator != (Object)null)
				{
					_animator.speed = _originalSpeed;
				}
			}

			public void Reapply()
			{
				if ((Object)(object)_animator != (Object)null && _animator.speed > 0.001f)
				{
					_animator.speed = _originalSpeed * _multiplier;
				}
			}
		}

		private sealed class StaffGreenRootSpawnRecord
		{
			public Character Character { get; }

			public long SpawnTicks { get; }

			public StaffGreenRootSpawnRecord(Character character, long spawnTicks)
			{
				Character = character;
				SpawnTicks = spawnTicks;
			}
		}

		private sealed class StaffRuntimeTweakState
		{
			private Vector3 _originalScale;

			private Vector3 _lastAppliedScale;

			private bool _ownsScale;

			private float _lastAppliedMaxHealth;

			private bool _ownsMaxHealth;

			public StaffRuntimeTweakState(Vector3 originalScale)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				_originalScale = originalScale;
				_lastAppliedScale = originalScale;
			}

			public void ApplyScale(Character character, float multiplier)
			{
				//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_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: 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_0059: 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_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: 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_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: 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_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)character == (Object)null)
				{
					return;
				}
				Vector3 localScale = ((Component)character).transform.localScale;
				Vector3 val;
				if (_ownsScale)
				{
					val = localScale - _lastAppliedScale;
					if (((Vector3)(ref val)).sqrMagnitude > 1E-06f)
					{
						_originalScale = localScale;
						_ownsScale = false;
					}
				}
				Vector3 val2 = _originalScale * Mathf.Clamp(multiplier, 0.05f, 10f);
				val = localScale - val2;
				if (((Vector3)(ref val)).sqrMagnitude > 1E-06f)
				{
					((Component)character).transform.localScale = val2;
				}
				_lastAppliedScale = val2;
				_ownsScale = true;
			}

			public void ApplyMaxHealth(Character character, float multiplier)
			{
				if ((Object)(object)character == (Object)null)
				{
					return;
				}
				ZNetView component = ((Component)character).GetComponent<ZNetView>();
				if (!((Object)(object)component != (Object)null) || !component.IsValid() || component.IsOwner())
				{
					float num = Mathf.Max(0.01f, character.GetMaxHealthBase() * (float)Mathf.Max(1, character.GetLevel()));
					float num2 = num * Mathf.Clamp(multiplier, 0.01f, 20f);
					float maxHealth = character.GetMaxHealth();
					if (!Mathf.Approximately(maxHealth, num2))
					{
						float num3 = ((maxHealth > 0f) ? Mathf.Clamp01(character.GetHealth() / maxHealth) : 1f);
						character.SetMaxHealth(num2);
						character.SetHealth(Mathf.Clamp(num2 * num3, 0f, num2));
					}
					_lastAppliedMaxHealth = num2;
					_ownsMaxHealth = true;
				}
			}

			public void Restore(Character character)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: 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)
				if ((Object)(object)character == (Object)null)
				{
					return;
				}
				if (_ownsScale)
				{
					Vector3 localScale = ((Component)character).transform.localScale;
					Vector3 val = localScale - _lastAppliedScale;
					if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f)
					{
						((Component)character).transform.localScale = _originalScale;
					}
					_ownsScale = false;
				}
				if (!_ownsMaxHealth)
				{
					return;
				}
				ZNetView component = ((Component)character).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid() || component.IsOwner())
				{
					float maxHealth = character.GetMaxHealth();
					if (Mathf.Approximately(maxHealth, _lastAppliedMaxHealth))
					{
						float num = Mathf.Max(0.01f, character.GetMaxHealthBase() * (float)Mathf.Max(1, character.GetLevel()));
						float num2 = ((maxHealth > 0f) ? Mathf.Clamp01(character.GetHealth() / maxHealth) : 1f);
						character.SetMaxHealth(num);
						character.SetHealth(Mathf.Clamp(num * num2, 0f, num));
					}
				}
				_ownsMaxHealth = false;
			}
		}

		private sealed class StaffSpawnOrigin
		{
			public Character? Owner { get; private set; }

			public long OwnerPlayerId { get; }

			public string StaffPrefabName { get; }

			public bool IsGreenRoots { get; }

			public bool IsSkeleton { get; }

			public bool IsSpiritCaller { get; }

			public float CreatedTime { get; }

			public StaffSpawnOrigin(Character owner, StaffConfig staffConfig, ItemData? item = null)
			{
				Owner = owner;
				Player val = (Player)(object)((owner is Player) ? owner : null);
				OwnerPlayerId = ((val != null) ? val.GetPlayerID() : 0);
				StaffPrefabName = staffConfig.PrefabName;
				IsGreenRoots = IsStaffGreenRoots(staffConfig);
				IsSkeleton = IsStaffSkeleton(staffConfig);
				IsSpiritCaller = IsStaffSpiritCaller(staffConfig);
				CreatedTime = Time.time;
			}

			public StaffSpawnOrigin(long ownerPlayerId, string staffPrefabName)
			{
				OwnerPlayerId = ownerPlayerId;
				StaffPrefabName = staffPrefabName ?? string.Empty;
				IsGreenRoots = string.Equals(StaffPrefabName, "StaffGreenRoots", StringComparison.OrdinalIgnoreCase);
				IsSkeleton = string.Equals(StaffPrefabName, "StaffSkeleton", StringComparison.OrdinalIgnoreCase);
				IsSpiritCaller = string.Equals(StaffPrefabName, "StaffSpiritCaller", StringComparison.OrdinalIgnoreCase);
				Owner = (Character?)(object)((ownerPlayerId != 0L) ? Player.GetPlayer(ownerPlayerId) : null);
				CreatedTime = Time.time;
			}

			public Player? ResolveOwnerPlayer()
			{
				Character? owner = Owner;
				Player val = (Player)(object)((owner is Player) ? owner : null);
				if (val != null && (OwnerPlayerId == 0L || val.GetPlayerID() == OwnerPlayerId))
				{
					return val;
				}
				if (OwnerPlayerId == 0)
				{
					return null;
				}
				Player player = Player.GetPlayer(OwnerPlayerId);
				if ((Object)(object)player != (Object)null)
				{
					Owner = (Character?)(object)player;
				}
				return player;
			}
		}

		private sealed class DamageBonusStackState
		{
			public static readonly DamageBonusStackState Empty = new DamageBonusStackState(1f, 1f, 1f, 1f);

			public float BackstabMultiplier { get; }

			public float StaggeredEnemyMultiplier { get; }

			public float FlankingMultiplier { get; }

			public float CounterDamageMultiplier { get; }

			public DamageBonusStackState(float backstabMultiplier, float staggeredEnemyMultiplier, float flankingMultiplier, float counterDamageMultiplier)
			{
				BackstabMultiplier = backstabMultiplier;
				StaggeredEnemyMultiplier = staggeredEnemyMultiplier;
				FlankingMultiplier = flankingMultiplier;
				CounterDamageMultiplier = counterDamageMultiplier;
			}

			public bool IsActive(DamageBonusKind kind)
			{
				return !Mathf.Approximately(Ge